diff --git a/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_time.groovy b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_time.groovy index 979b1f9d1..8d6304274 100644 --- a/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_time.groovy +++ b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_time.groovy @@ -20,9 +20,11 @@ def has_data = new AtomicBoolean(false) (0..<11).collect{component-> def h1 = dir.getObject(String.format('/ALERT/ATOF_Time_component%02d', component)) if(h1!=null) { - if (h1.getBinContent(h1.getMaximumBin()) > 30 && h1.getEntries()>300){ + if (h1.getBinContent(h1.getMaximumBin()) > 3 && h1.getEntries()>10){ data[run].put(String.format('atof_time_%02d', component), h1) - def f1 = ALERTFitter.atof_time_fitter(h1,component) + double fit_min = h1.getXaxis().getBinCenter(1) + double fit_max = h1.getXaxis().getBinCenter(h1.getXaxis().getNBins()) + def f1 = ALERTFitter.atof_time_fitter(h1, component, fit_min, fit_max) data[run].put(String.format('fit_atof_time_%02d', component), f1) data[run].put(String.format('peak_location_atof_time_%02d', component), f1.getParameter(1)) data[run].put(String.format('sigma_atof_time_%02d', component), f1.getParameter(2).abs()) diff --git a/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_time_sl.groovy b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_time_sl.groovy new file mode 100644 index 000000000..c87480048 --- /dev/null +++ b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_time_sl.groovy @@ -0,0 +1,75 @@ +package org.jlab.clas.timeline.analysis +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean +import org.jlab.groot.data.TDirectory +import org.jlab.groot.data.GraphErrors +import org.jlab.clas.timeline.fitter.ALERTFitter + +class alert_atof_time_sl { + + def data = new ConcurrentHashMap() + def has_data = new AtomicBoolean(false) + int sector + int layer + + alert_atof_time_sl(int sector, int layer) { + this.sector = sector + this.layer = layer + } + + def getName() { + return String.format("%s_sector%02d_layer%d", this.class.simpleName, sector, layer) + } + + def processRun(dir, run) { + data[run] = [run:run] + (0..<11).each { component -> + def h1 = dir.getObject(String.format('/ALERT/ATOF_Time_sector%02d_layer%02d_component%02d', sector, layer, component)) + if (h1 != null) { + if (h1.getBinContent(h1.getMaximumBin()) > 3 && h1.getEntries() > 10) { + def name = String.format('atof_time_sl_s%02d_l%d_c%02d', sector, layer, component) + data[run].put(name, h1) + double fit_min = h1.getXaxis().getBinCenter(1) + double fit_max = h1.getXaxis().getBinCenter(h1.getXaxis().getNBins()) + def f1 = ALERTFitter.atof_time_fitter(h1, component, fit_min, fit_max) + data[run].put('fit_' + name, f1) + data[run].put('peak_location_' + name, f1.getParameter(1)) + data[run].put('sigma_' + name, f1.getParameter(2).abs()) + has_data.set(true) + } + } + } + } + + def write() { + if (!has_data.get()) { + System.err.println "WARNING: no data for this timeline, not producing" + return + } + ['peak_location', 'sigma'].each { variable -> + TDirectory out = new TDirectory() + out.mkdir('/timelines') + (0..<11).each { component -> + def name = String.format('atof_time_sl_s%02d_l%d_c%02d', sector, layer, component) + def gr = new GraphErrors(name) + gr.setTitle(String.format("ATOF Time %s Sector %02d Layer %d", variable.replace('_', ' '), sector, layer)) + gr.setTitleY(String.format("ATOF Time %s (ns)", variable.replace('_', ' '))) + gr.setTitleX("run number") + data.sort { it.key }.each { run, it -> + out.mkdir('/' + it.run) + out.cd('/' + it.run) + if (it.containsKey(name)) { + out.addDataSet(it[name]) + out.addDataSet(it['fit_' + name]) + gr.addPoint(it.run, it[variable + '_' + name], 0, 0) + } else if (variable == 'peak_location') { + println(String.format("run %d: %s either does not exist or does not have enough statistics.", it.run, name)) + } + } + out.cd('/timelines') + out.addDataSet(gr) + } + out.writeFile(String.format('alert_atof_time_sl_%s_sector%02d_layer%d.hipo', variable, sector, layer)) + } + } +} diff --git a/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z.groovy b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z.groovy new file mode 100644 index 000000000..c97fe1c1b --- /dev/null +++ b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z.groovy @@ -0,0 +1,50 @@ +package org.jlab.clas.timeline.analysis +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean +import org.jlab.groot.data.TDirectory +import org.jlab.groot.data.GraphErrors + +class alert_atof_z { + + def data = new ConcurrentHashMap() + def has_data = new AtomicBoolean(false) + + def processRun(dir, run) { + data[run] = [run:run] + def h1 = dir.getObject('/ALERT/ATOF_z_combined') + if (h1 != null) { + if (h1.getEntries() > 10) { + data[run].put('atof_z_combined', h1) + data[run].put('rms_atof_z_combined', h1.getRMS()) + has_data.set(true) + } + } + } + + def write() { + if (!has_data.get()) { + System.err.println "WARNING: no data for this timeline, not producing" + return + } + TDirectory out = new TDirectory() + out.mkdir('/timelines') + def name = 'atof_z_combined' + def gr = new GraphErrors(name) + gr.setTitle("ATOF z RMS") + gr.setTitleY("ATOF z RMS (cm)") + gr.setTitleX("run number") + data.sort { it.key }.each { run, it -> + out.mkdir('/' + it.run) + out.cd('/' + it.run) + if (it.containsKey(name)) { + out.addDataSet(it[name]) + gr.addPoint(it.run, it['rms_' + name], 0, 0) + } else { + println(String.format("run %d: %s either does not exist or does not have enough statistics.", it.run, name)) + } + } + out.cd('/timelines') + out.addDataSet(gr) + out.writeFile('alert_atof_z_rms.hipo') + } +} diff --git a/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_c4.groovy b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_c4.groovy new file mode 100644 index 000000000..7499e8f12 --- /dev/null +++ b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_c4.groovy @@ -0,0 +1,57 @@ +package org.jlab.clas.timeline.analysis +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean +import org.jlab.groot.data.TDirectory +import org.jlab.groot.data.GraphErrors +import org.jlab.clas.timeline.fitter.ALERTFitter + +class alert_atof_z_c4 { + + def data = new ConcurrentHashMap() + def has_data = new AtomicBoolean(false) + + def processRun(dir, run) { + data[run] = [run:run] + def h1 = dir.getObject('/ALERT/ATOF_z_combined_c4') + if (h1 != null) { + if (h1.getBinContent(h1.getMaximumBin()) > 3 && h1.getEntries() > 10) { + data[run].put('atof_z_c4_combined', h1) + def f1 = ALERTFitter.atof_z_fitter(h1) + data[run].put('fit_atof_z_c4_combined', f1) + data[run].put('peak_location_atof_z_c4_combined', f1.getParameter(1)) + data[run].put('sigma_atof_z_c4_combined', f1.getParameter(2).abs()) + has_data.set(true) + } + } + } + + def write() { + if (!has_data.get()) { + System.err.println "WARNING: no data for this timeline, not producing" + return + } + ['peak_location', 'sigma'].each { variable -> + TDirectory out = new TDirectory() + out.mkdir('/timelines') + def name = 'atof_z_c4_combined' + def gr = new GraphErrors(name) + gr.setTitle(String.format("ATOF z c4 %s", variable.replace('_', ' '))) + gr.setTitleY(String.format("ATOF z c4 %s (cm)", variable.replace('_', ' '))) + gr.setTitleX("run number") + data.sort { it.key }.each { run, it -> + out.mkdir('/' + it.run) + out.cd('/' + it.run) + if (it.containsKey(name)) { + out.addDataSet(it[name]) + out.addDataSet(it['fit_' + name]) + gr.addPoint(it.run, it[variable + '_' + name], 0, 0) + } else if (variable == 'peak_location') { + println(String.format("run %d: %s either does not exist or does not have enough statistics.", it.run, name)) + } + } + out.cd('/timelines') + out.addDataSet(gr) + out.writeFile(String.format('alert_atof_z_c4_%s.hipo', variable)) + } + } +} diff --git a/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_c4_sl.groovy b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_c4_sl.groovy new file mode 100644 index 000000000..7203f3ec5 --- /dev/null +++ b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_c4_sl.groovy @@ -0,0 +1,69 @@ +package org.jlab.clas.timeline.analysis +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean +import org.jlab.groot.data.TDirectory +import org.jlab.groot.data.GraphErrors +import org.jlab.clas.timeline.fitter.ALERTFitter + +class alert_atof_z_c4_sl { + + def data = new ConcurrentHashMap() + def has_data = new AtomicBoolean(false) + int sector + int layer + + alert_atof_z_c4_sl(int sector, int layer) { + this.sector = sector + this.layer = layer + } + + def getName() { + return String.format("%s_sector%02d_layer%d", this.class.simpleName, sector, layer) + } + + def processRun(dir, run) { + data[run] = [run:run] + def h1 = dir.getObject(String.format('/ALERT/ATOF_z_c4_sector%02d_layer%02d', sector, layer)) + if (h1 != null) { + if (h1.getBinContent(h1.getMaximumBin()) > 3 && h1.getEntries() > 10) { + def name = String.format('atof_z_c4_sl_s%02d_l%d', sector, layer) + data[run].put(name, h1) + def f1 = ALERTFitter.atof_z_fitter(h1) + data[run].put('fit_' + name, f1) + data[run].put('peak_location_' + name, f1.getParameter(1)) + data[run].put('sigma_' + name, f1.getParameter(2).abs()) + has_data.set(true) + } + } + } + + def write() { + if (!has_data.get()) { + System.err.println "WARNING: no data for this timeline, not producing" + return + } + ['peak_location', 'sigma'].each { variable -> + TDirectory out = new TDirectory() + out.mkdir('/timelines') + def name = String.format('atof_z_c4_sl_s%02d_l%d', sector, layer) + def gr = new GraphErrors(name) + gr.setTitle(String.format("ATOF z c4 %s Sector %02d Layer %d", variable.replace('_', ' '), sector, layer)) + gr.setTitleY(String.format("ATOF z c4 %s (cm)", variable.replace('_', ' '))) + gr.setTitleX("run number") + data.sort { it.key }.each { run, it -> + out.mkdir('/' + it.run) + out.cd('/' + it.run) + if (it.containsKey(name)) { + out.addDataSet(it[name]) + out.addDataSet(it['fit_' + name]) + gr.addPoint(it.run, it[variable + '_' + name], 0, 0) + } else if (variable == 'peak_location') { + println(String.format("run %d: %s either does not exist or does not have enough statistics.", it.run, name)) + } + } + out.cd('/timelines') + out.addDataSet(gr) + out.writeFile(String.format('alert_atof_z_c4_sl_%s_sector%02d_layer%d.hipo', variable, sector, layer)) + } + } +} diff --git a/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_sl.groovy b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_sl.groovy new file mode 100644 index 000000000..35f3eaa38 --- /dev/null +++ b/src/main/java/org/jlab/clas/timeline/analysis/alert/alert_atof_z_sl.groovy @@ -0,0 +1,62 @@ +package org.jlab.clas.timeline.analysis +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean +import org.jlab.groot.data.TDirectory +import org.jlab.groot.data.GraphErrors + +class alert_atof_z_sl { + + def data = new ConcurrentHashMap() + def has_data = new AtomicBoolean(false) + int sector + int layer + + alert_atof_z_sl(int sector, int layer) { + this.sector = sector + this.layer = layer + } + + def getName() { + return String.format("%s_sector%02d_layer%d", this.class.simpleName, sector, layer) + } + + def processRun(dir, run) { + data[run] = [run:run] + def h1 = dir.getObject(String.format('/ALERT/ATOF_z_sector%02d_layer%02d', sector, layer)) + if (h1 != null) { + if (h1.getEntries() > 10) { + def name = String.format('atof_z_sl_s%02d_l%d', sector, layer) + data[run].put(name, h1) + data[run].put('rms_' + name, h1.getRMS()) + has_data.set(true) + } + } + } + + def write() { + if (!has_data.get()) { + System.err.println "WARNING: no data for this timeline, not producing" + return + } + TDirectory out = new TDirectory() + out.mkdir('/timelines') + def name = String.format('atof_z_sl_s%02d_l%d', sector, layer) + def gr = new GraphErrors(name) + gr.setTitle(String.format("ATOF z RMS Sector %02d Layer %d", sector, layer)) + gr.setTitleY("ATOF z RMS (cm)") + gr.setTitleX("run number") + data.sort { it.key }.each { run, it -> + out.mkdir('/' + it.run) + out.cd('/' + it.run) + if (it.containsKey(name)) { + out.addDataSet(it[name]) + gr.addPoint(it.run, it['rms_' + name], 0, 0) + } else { + println(String.format("run %d: %s either does not exist or does not have enough statistics.", it.run, name)) + } + } + out.cd('/timelines') + out.addDataSet(gr) + out.writeFile(String.format('alert_atof_z_sl_rms_sector%02d_layer%d.hipo', sector, layer)) + } +} diff --git a/src/main/java/org/jlab/clas/timeline/fitter/ALERTFitter.groovy b/src/main/java/org/jlab/clas/timeline/fitter/ALERTFitter.groovy index 11bf938be..e511092c7 100644 --- a/src/main/java/org/jlab/clas/timeline/fitter/ALERTFitter.groovy +++ b/src/main/java/org/jlab/clas/timeline/fitter/ALERTFitter.groovy @@ -34,9 +34,9 @@ class ALERTFitter{ } - static F1D atof_time_fitter(H1F h1, int component){ + static F1D atof_time_fitter(H1F h1, int component, double fit_min, double fit_max){ if(component>9){//bars - def f1 =new F1D("fit:"+h1.getName(),"[amp]*gaus(x,[mean],[sigma])+[cst]", -5.0, 5.0); + def f1 =new F1D("fit:"+h1.getName(),"[amp]*gaus(x,[mean],[sigma])+[cst]", fit_min, fit_max); f1.setLineColor(33); f1.setLineWidth(10); f1.setOptStat("1111"); @@ -182,6 +182,33 @@ class ALERTFitter{ } } + static F1D atof_z_fitter(H1F h1){ + double maxz = h1.getBinContent(h1.getMaximumBin()) + double peak = h1.getAxis().getBinCenter(h1.getMaximumBin()) + int bin_low = h1.getAxis().getBin(peak - 10.0) + int bin_high = h1.getAxis().getBin(peak + 10.0) + double sigma = ALERTFitter.getRestrictedRMS(h1, bin_low, bin_high) + if (sigma <= 0 || Double.isNaN(sigma)) sigma = 5.0 + + def f1 = new F1D("fit:" + h1.getName(), "[amp]*gaus(x,[mean],[sigma])", peak - 2*sigma, peak + 2*sigma) + f1.setLineColor(33) + f1.setLineWidth(10) + f1.setOptStat("1111") + f1.setParameter(0, maxz) + f1.setParameter(1, peak) + f1.setParameter(2, sigma) + if (maxz > 0) f1.setParLimits(0, maxz * 0.5, maxz * 1.5) + f1.setParLimits(1, peak - 5.0, peak + 5.0) + f1.setParLimits(2, 0.01, 10.0) + + PrintStream original = System.out + System.setOut(new PrintStream(OutputStream.nullOutputStream())) + DataFitter.fit(f1, h1, "RQ") + System.setOut(original) + + return f1 + } + static F1D residual_fitter(H1F h1){ def f1 =new F1D("fit:"+h1.getName(),"[amp]*gaus(x,[mean],[sigma])+[cst]", -5.0, 5.0); f1.setLineColor(33); diff --git a/src/main/java/org/jlab/clas/timeline/histograms/ALERT.java b/src/main/java/org/jlab/clas/timeline/histograms/ALERT.java index a30075e17..ef15441f1 100644 --- a/src/main/java/org/jlab/clas/timeline/histograms/ALERT.java +++ b/src/main/java/org/jlab/clas/timeline/histograms/ALERT.java @@ -26,7 +26,7 @@ public class ALERT { public int rf_large_integer; //Hodoscope - public H1F[] ATOF_Time; + public H1F[] ATOF_Time, ATOF_Time_sl, ATOF_z, ATOF_z_sl, ATOF_z_c4, ATOF_z_c4_sl; public H1F[] ADC, AHDC_RESIDUAL, AHDC_TIME;//AHDC-related-histograms private H1F bits; @@ -58,14 +58,51 @@ public ALERT(int reqrunNum, String reqOutputDir, float reqEb, boolean reqTimeBas rf_large_integer = 1000; ATOF_Time = new H1F[11];// ATOF Time Histograms - + ATOF_Time_sl = new H1F[660];// ATOF Time Histograms + ATOF_z = new H1F[1];// ATOF Time Histograms + ATOF_z_c4 = new H1F[1];// ATOF Time Histograms + ATOF_z_sl = new H1F[60];// ATOF z Histograms + ATOF_z_c4_sl = new H1F[60];// ATOF z Histograms + for (int component = 0; component < 11; component++) { - ATOF_Time[component] = new H1F(String.format("ATOF_Time_component%02d", component), String.format("ATOF Time component%02d", component), 200, -5, 5); ATOF_Time[component].setTitleX("ATOF Time (ns)"); ATOF_Time[component].setTitleY("Counts"); ATOF_Time[component].setFillColor(4); } + ATOF_z[0]= new H1F(String.format("ATOF_z_combined"), String.format("ATOF z"), 250,-30,20); + ATOF_z[0].setTitleX("ATOF z (ns)"); + ATOF_z[0].setTitleY("Counts"); + ATOF_z[0].setFillColor(4); + ATOF_z_c4[0]= new H1F(String.format("ATOF_z_combined_c4"), String.format("ATOF z with c4"), 250,-30,20); + ATOF_z_c4[0].setTitleX("ATOF z (ns)"); + ATOF_z_c4[0].setTitleY("Counts"); + ATOF_z_c4[0].setFillColor(4); + for(int sector=0;sector<15;sector++){ + for(int layer=0;layer<4;layer++){ + int gsector=sector*4+layer; + ATOF_z_sl[gsector] = new H1F(String.format("ATOF_z_sector%02d_layer%02d", sector,layer), String.format("ATOF z sector%02d layer %2d", sector,layer), 250,-30,20); + ATOF_z_sl[gsector].setTitleX("ATOF z (ns)"); + ATOF_z_sl[gsector].setTitleY("Counts"); + ATOF_z_sl[gsector].setFillColor(4); + + ATOF_z_c4_sl[gsector] = new H1F(String.format("ATOF_z_c4_sector%02d_layer%02d", sector,layer), String.format("ATOF z with C4 sector%02d layer %2d", sector,layer), 250,-30,20); + ATOF_z_c4_sl[gsector].setTitleX("ATOF z (ns)"); + ATOF_z_c4_sl[gsector].setTitleY("Counts"); + ATOF_z_c4_sl[gsector].setFillColor(4); + + for (int component = 0; component < 11; component++) { + int gcomponent = gsector*11+component; + ATOF_Time_sl[gcomponent] = new H1F(String.format("ATOF_Time_sector%02d_layer%02d_component%02d",sector,layer, component), String.format("ATOF Time sector%02d layer%02d component%02d", sector,layer,component), 200, -5, 5); + ATOF_Time_sl[gcomponent].setTitleX("ATOF Time (ns)"); + ATOF_Time_sl[gcomponent].setTitleY("Counts"); + ATOF_Time_sl[gcomponent].setFillColor(4); + } + + + } + } + //AHDC ADC Histograms ADC = new H1F[576]; @@ -146,13 +183,38 @@ public void fillAHDC_hits(DataBank ahdc_hits) { public void fillATOF_hits(DataBank atof_hits) { int rows = atof_hits.rows(); + + // First pass: collect which gsectors have a hit on component 4 + Set gsectors_with_c4 = new HashSet<>(); for (int loop = 0; loop < rows; loop++) { + if (atof_hits.getInt("component", loop) == 4) { + int sector = atof_hits.getInt("sector", loop); + int layer = atof_hits.getInt("layer", loop); + gsectors_with_c4.add(sector * 4 + layer); + } + } - int component = atof_hits.getInt("component", loop); - float time = atof_hits.getFloat("time", loop); + // Second pass: fill all histograms + for (int loop = 0; loop < rows; loop++) { + int sector = atof_hits.getInt("sector", loop); + int layer = atof_hits.getInt("layer", loop); + int component = atof_hits.getInt("component", loop); + float time = atof_hits.getFloat("time", loop); + int gsector = sector * 4 + layer; + int gcomponent = gsector * 11 + component; ATOF_Time[component].fill(time); - + ATOF_Time_sl[gcomponent].fill(time); + + if (component == 10) { + float z = atof_hits.getFloat("z", loop); + ATOF_z[0].fill(z); + ATOF_z_sl[gsector].fill(z); + if (gsectors_with_c4.contains(gsector)) { + ATOF_z_c4[0].fill(z); + ATOF_z_c4_sl[gsector].fill(z); + } + } } } @@ -225,6 +287,15 @@ public void write() { for (int component = 0; component < 11; component++) { dirout.addDataSet(ATOF_Time[component]); } + dirout.addDataSet(ATOF_z[0]); + dirout.addDataSet(ATOF_z_c4[0]); + for (int gsector = 0; gsector < 60; gsector++) { + dirout.addDataSet(ATOF_z_sl[gsector]); + dirout.addDataSet(ATOF_z_c4_sl[gsector]); + } + for (int gcomponent = 0; gcomponent < 660; gcomponent++) { + dirout.addDataSet(ATOF_Time_sl[gcomponent]); + } for (int index = 0; index < 576; index++) { dirout.addDataSet(ADC[index], AHDC_TIME[index]); } diff --git a/src/main/java/org/jlab/clas/timeline/run_analysis.groovy b/src/main/java/org/jlab/clas/timeline/run_analysis.groovy index 738be13b8..e7f408160 100644 --- a/src/main/java/org/jlab/clas/timeline/run_analysis.groovy +++ b/src/main/java/org/jlab/clas/timeline/run_analysis.groovy @@ -10,6 +10,11 @@ def engines = [ new alert_ahdc_residual(), *(1..8).collect {ahdc_layer_number -> new alert_ahdc_time (ahdc_layer_number) }, new alert_atof_time(), + *(0..<15).collectMany { s -> (0..<4).collect { l -> new alert_atof_time_sl(s, l) } }, + new alert_atof_z(), + *(0..<15).collectMany { s -> (0..<4).collect { l -> new alert_atof_z_sl(s, l) } }, + new alert_atof_z_c4(), + *(0..<15).collectMany { s -> (0..<4).collect { l -> new alert_atof_z_c4_sl(s, l) } }, ], out_BAND: [ new band_adccor(),