Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JEventProcessor_highlevel_online.cc
Go to the documentation of this file.
2 using namespace jana;
3 
4 #include <DAQ/Df250PulseData.h>
5 
6 #include <START_COUNTER/DSCHit.h>
7 #include <TAGGER/DTAGMHit.h>
8 #include <TAGGER/DTAGHHit.h>
9 #include <TOF/DTOFHit.h>
10 #include <BCAL/DBCALUnifiedHit.h>
11 #include <RF/DRFTime.h>
12 #include <DAQ/DF1TDCHit.h>
13 #include <DAQ/DCODAEventInfo.h>
14 #include <DAQ/DEPICSvalue.h>
15 
16 
17 // Routine used to create our JEventProcessor
18 #include <JANA/JApplication.h>
19 #include <JANA/JFactory.h>
20 extern "C"{
21  void InitPlugin(JApplication *app){
22  InitJANAPlugin(app);
23  app->AddProcessor(new JEventProcessor_highlevel_online());
24  }
25 } // "C"
26 
27 
28 // Hit types that include F1TDC information
29 #define F1Types(X) \
30  X(DRFTime) \
31  X(DSCHit) \
32  X(DFDCHit) \
33  X(DBCALUnifiedHit)
34 
35 // We need to access the tagger hits differently in order to get at
36 // the "raw" (i.e. unmerged) hits.
37 #define F1TaggerTypes(X) \
38  X(DTAGHHit) \
39  X(DTAGMHit) \
40 
41 //.......................................................
42 // These templates are used by the FillF1Hist method below
43 // to accomodate the different member names
44 template<typename T> static bool F1Check(const T* hit); // return true if all info (TDC and ADC) is present
45 template<typename T> static bool F1CheckADCOnly(const T* hit); // return true if only ADC info is present
46 template<typename T> static bool F1CheckTDCOnly(const T* hit); // return true if only TDC info is present
47 template<typename T> static double F1tdiff(const T* hit); // return time difference between TDC and ADC
48 template<typename T> static double F1tdiff2(const T* hit,const T* hit2); // return time difference between TDC and ADC times stored in two different hits
49 template<typename T> static bool F1CheckSameChannel(const T* hit,const T* hit2); // return true if both hits are on the same channel
50 
51 template<> bool F1Check<DRFTime >(const DRFTime* hit){ return true; }
52 template<> bool F1CheckADCOnly<DRFTime >(const DRFTime* hit){ return false; }
53 template<> bool F1CheckTDCOnly<DRFTime >(const DRFTime* hit){ return false; }
54 template<> double F1tdiff<DRFTime >(const DRFTime* hit){ return hit->dTime; }
55 template<> double F1tdiff2<DRFTime >(const DRFTime* hit,const DRFTime* hit2) { return hit->dTime; } // dummy functions
56 template<> bool F1CheckSameChannel<DRFTime >(const DRFTime* hit,const DRFTime* hit2){ return true; }
57 
58 
59 template<> bool F1Check<DSCHit >(const DSCHit* hit){ return hit->has_fADC && hit->has_TDC; }
60 template<> bool F1CheckADCOnly<DSCHit >(const DSCHit* hit){ return hit->has_fADC && !hit->has_TDC; }
61 template<> bool F1CheckTDCOnly<DSCHit >(const DSCHit* hit){ return !hit->has_fADC && hit->has_TDC; }
62 template<> double F1tdiff<DSCHit >(const DSCHit* hit){ return hit->t_TDC - hit->t_fADC; }
63 template<> double F1tdiff2<DSCHit >(const DSCHit* hit, const DSCHit* hit2){ return hit->t_TDC - hit2->t_fADC; }
64 template<> bool F1CheckSameChannel<DSCHit >(const DSCHit* hit,const DSCHit* hit2){ return hit->sector==hit2->sector; }
65 
66 template<> bool F1Check<DTAGHHit >(const DTAGHHit* hit){ return hit->has_fADC && hit->has_TDC; }
67 template<> bool F1CheckADCOnly<DTAGHHit>(const DTAGHHit* hit){ return hit->has_fADC && !(hit->has_TDC); }
68 template<> bool F1CheckTDCOnly<DTAGHHit>(const DTAGHHit* hit){ return !(hit->has_fADC) && hit->has_TDC; }
69 template<> double F1tdiff<DTAGHHit >(const DTAGHHit* hit){ return hit->time_tdc - hit->time_fadc;}
70 template<> double F1tdiff2<DTAGHHit >(const DTAGHHit* hit, const DTAGHHit* hit2) { return hit->time_tdc - hit2->time_fadc; }
71 template<> bool F1CheckSameChannel<DTAGHHit >(const DTAGHHit* hit,const DTAGHHit* hit2){ return hit->counter_id==hit2->counter_id; }
72 
73 template<> bool F1Check<DTAGMHit >(const DTAGMHit* hit){ return hit->has_fADC && hit->has_TDC; }
74 template<> bool F1CheckADCOnly<DTAGMHit>(const DTAGMHit* hit){ return hit->has_fADC && !(hit->has_TDC); }
75 template<> bool F1CheckTDCOnly<DTAGMHit>(const DTAGMHit* hit){ return !(hit->has_fADC) && hit->has_TDC; }
76 template<> double F1tdiff<DTAGMHit >(const DTAGMHit* hit){ return hit->time_tdc - hit->time_fadc;}
77 template<> double F1tdiff2<DTAGMHit >(const DTAGMHit* hit, const DTAGMHit* hit2){ return hit->time_tdc - hit2->time_fadc; }
78 template<> bool F1CheckSameChannel<DTAGMHit >(const DTAGMHit* hit,const DTAGMHit* hit2)
79  { return (hit->row==hit2->row) && (hit->column==hit2->column); }
80 
81 template<> bool F1Check<DFDCHit >(const DFDCHit* hit){ return true; }
82 template<> bool F1CheckADCOnly<DFDCHit >(const DFDCHit* hit){ return false; }
83 template<> bool F1CheckTDCOnly<DFDCHit >(const DFDCHit* hit){ return false; }
84 template<> double F1tdiff<DFDCHit >(const DFDCHit* hit){ return hit->t/50.0; }
85 template<> double F1tdiff2<DFDCHit >(const DFDCHit* hit, const DFDCHit* hit2){ return hit->t/50.0; } // dummy
86 template<> bool F1CheckSameChannel<DFDCHit >(const DFDCHit* hit, const DFDCHit* hit2)
87  { return (hit->gPlane==hit2->gPlane) && (hit->element==hit2->element); }
88 
89 template<> bool F1Check<DBCALUnifiedHit>(const DBCALUnifiedHit* hit){ return hit->has_TDC_hit; }
90 // right now we don't use a window to restrict ADC/TDC hit matching like we do in other detectors
91 // so if there are hits in the ADC and TDC for a given channel, they will always match
92 // and we won't have to fall into the other loop
93 template<> bool F1CheckADCOnly<DBCALUnifiedHit >(const DBCALUnifiedHit* hit){ return false; }
94 template<> bool F1CheckTDCOnly<DBCALUnifiedHit >(const DBCALUnifiedHit* hit){ return false; }
95 template<> double F1tdiff<DBCALUnifiedHit>(const DBCALUnifiedHit* hit){ return hit->t_TDC - hit->t_ADC; }
96 template<> double F1tdiff2<DBCALUnifiedHit>(const DBCALUnifiedHit* hit, const DBCALUnifiedHit* hit2)
97  { return hit->t_TDC - hit2->t_ADC; }
99  { return (hit->module==hit2->module) && (hit->layer==hit2->layer)
100  && (hit->sector==hit2->sector) && (hit->end==hit2->end); }
101 //.......................................................
102 
103 
104 //------------------
105 // FillF1Hist
106 //
107 // Template routine used to fill dF1TDC_fADC_tdiff for all types in F1Types.
108 //------------------
109 template<typename T>
111 {
112  for(auto hit : hits){
113  // Check hits where the ADC and TDC hits have been matched
114  if( F1Check(hit) ) {
115  vector<const DF1TDCHit*> f1hits;
116  hit->Get(f1hits);
117  for(auto f1hit : f1hits){
118  pair<int,int> rocid_slot(f1hit->rocid, f1hit->slot);
119  double fbin = f1tdc_bin_map[rocid_slot];
120  double tdiff = F1tdiff(hit);
121  dF1TDC_fADC_tdiff->Fill(fbin, tdiff);
122  }
123  }
124 
125  // Check hits where the ADC and TDC hits were not matched
126  // We have to manually loop over these hits, since the calibrated hits
127  // only have matched ADC & TDC information within a certain window
128  // which is detector-specific but generally smaller than the 32 ns shifts
129  // (which are peculiar to the F1TDC) that we want to detect
130  if( F1CheckADCOnly(hit) ) {
131  for(auto hit2 : hits) {
132  if( F1CheckTDCOnly(hit2) ) {
133  if( F1CheckSameChannel(hit, hit2) ) {
134  vector<const DF1TDCHit*> f1hits;
135  hit2->Get(f1hits);
136  for(auto f1hit : f1hits){
137  pair<int,int> rocid_slot(f1hit->rocid, f1hit->slot);
138  double fbin = f1tdc_bin_map[rocid_slot];
139  double tdiff = F1tdiff2(hit2,hit);
140  dF1TDC_fADC_tdiff->Fill(fbin, tdiff);
141  }
142  }
143  }
144  }
145  }
146  }
147 }
148 
149 //------------------
150 // init
151 //------------------
153 {
154  //timing cuts
155  dTimingCutMap[Gamma][SYS_BCAL] = 3.0;
156  dTimingCutMap[Gamma][SYS_FCAL] = 5.0;
157  dTimingCutMap[Proton][SYS_NULL] = -1.0;
158  dTimingCutMap[Proton][SYS_TOF] = 2.5;
159  dTimingCutMap[Proton][SYS_BCAL] = 2.5;
160  dTimingCutMap[Proton][SYS_FCAL] = 3.0;
161  dTimingCutMap[PiPlus][SYS_NULL] = -1.0;
162  dTimingCutMap[PiPlus][SYS_TOF] = 2.0;
163  dTimingCutMap[PiPlus][SYS_BCAL] = 2.5;
164  dTimingCutMap[PiPlus][SYS_FCAL] = 3.0;
165  dTimingCutMap[PiMinus][SYS_NULL] = -1.0;
166  dTimingCutMap[PiMinus][SYS_TOF] = 2.0;
167  dTimingCutMap[PiMinus][SYS_BCAL] = 2.5;
168  dTimingCutMap[PiMinus][SYS_FCAL] = 3.0;
169  dTimingCutMap[Electron][SYS_NULL] = -1.0;
170  dTimingCutMap[Electron][SYS_TOF] = 2.0;
171  dTimingCutMap[Electron][SYS_BCAL] = 2.5;
172  dTimingCutMap[Electron][SYS_FCAL] = 3.0;
173  dTimingCutMap[Positron][SYS_NULL] = -1.0;
174  dTimingCutMap[Positron][SYS_TOF] = 2.0;
175  dTimingCutMap[Positron][SYS_BCAL] = 2.5;
176  dTimingCutMap[Positron][SYS_FCAL] = 3.0;
177 
178  japp->RootWriteLock();
179 
180  // All histograms go in the "highlevel" directory
181  TDirectory *main = gDirectory;
182 
183  gDirectory->mkdir("highlevel")->cd();
184 
185  /************************************************************** Event Info ************************************************************/
186  last_timestamp = 0.0;
187  unix_offset = 0.0;
188  dHist_EventInfo = new TH1D("EventInfo", "Misc. event info used to communicate event time to macros", 2, 0.0 , 2.0);
189 
190  /***************************************************************** RF *****************************************************************/
191 
192  int NRFbins = 1024;
193  double ns_per_bin = 0.2;
194  double RFlo = 0.0;
195  double RFhi = RFlo + ns_per_bin*(double)NRFbins;
196  double dft_min = 50.0; // min frequency in Mhz
197  double dft_max = 900.0; // max frequency in Mhz
198  int Ndft_bins = (1.0/dft_min - 1.0/dft_max)*1000.0/ns_per_bin;
199  dHist_BeamBunchPeriod = new TH1I("RFBeamBunchPeriod", "RF Beam Bunch Period;TAGH #Deltat (Within Same Counter) (ns)", NRFbins, RFlo, RFhi);
200  dHist_BeamBunchPeriod_DFT = new TH1F("RFBeamBunchPeriod_DFT", "Fourier Transform of RF Beam Bunch Period;Beam bunch frequency (MHz)", Ndft_bins, dft_min, dft_max);
201 
202  /*************************************************************** TRIGGER **************************************************************/
203 
204  dNumHadronicTriggers_CoherentPeak_RFSignal.assign(33, 0.0);
205  dNumHadronicTriggers_CoherentPeak_RFSideband.assign(33, 0.0);
206 
207  dRFSidebandBunchRange = pair<int, int>(3, 5);
208  dShowerEOverPCut = 0.75;
209 
210  dHist_NumTriggers = new TH2I("NumTriggers", ";Trigger Bit", 33, 0.5, 33.5, 4, 0.5, 4.5); //"bit" 33: Total
211  dHist_NumTriggers->GetYaxis()->SetBinLabel(1, "# Triggers");
212  dHist_NumTriggers->GetYaxis()->SetBinLabel(2, "# Front Panel Triggers");
213  dHist_NumTriggers->GetYaxis()->SetBinLabel(3, "# Hadronic Triggers");
214  dHist_NumTriggers->GetYaxis()->SetBinLabel(4, "# Hadronic Triggers, Coherent Peak");
215  for(int loc_i = 1; loc_i <= 32; ++loc_i)
216  {
217  ostringstream locBinStream;
218  locBinStream << loc_i;
219  dHist_NumTriggers->GetXaxis()->SetBinLabel(loc_i, locBinStream.str().c_str());
220  }
221  dHist_NumTriggers->GetXaxis()->SetBinLabel(33, "Total");
222 
223  dHist_BCALVsFCAL_TrigBit1 = new TH2I("BCALVsFCAL_TrigBit1","TRIG BIT 1;E (FCAL) (count);E (BCAL) (count)", 200, 0., 10000, 200, 0., 50000);
224 
225  dHist_L1bits_gtp = new TH1I("L1bits_gtp", "L1 trig bits from GTP;Trig. bit (1-32)", 34, 0.5, 34.5);
226  dHist_L1bits_fp = new TH1I("L1bits_fp", "L1 trig bits from FP;Trig. bit (1-32)", 32, 0.5, 32.5);
227 
228  /****************************************************** NUM RECONSTRUCTED OBJECTS *****************************************************/
229 
230  //2D Summary
231  dHist_NumHighLevelObjects = new TH2I("NumHighLevelObjects", ";;# Objects / Event", 12, 0.5, 12.5, 101, -0.5, 100.5);
232  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(1, "DSCHit");
233  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(2, "DTOFPoint");
234  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(3, "DBCALShower");
235  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(4, "DFCALShower");
236  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(5, "DTimeBasedTrack");
237  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(6, "TrackSCMatches");
238  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(7, "TrackTOFMatches");
239  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(8, "TrackBCALMatches");
240  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(9, "TrackFCALMatches");
241  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(10, "DBeamPhoton");
242  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(11, "DChargedTrack");
243  dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(12, "DNeutralShower");
244 
245  /************************************************************* KINEMATICS *************************************************************/
246 
247  // Beam Energy from tagger
248  dHist_BeamEnergy = new TH1I("BeamEnergy", "Reconstructed Tagger Beam Energy;Beam Energy (GeV)", 240, 0.0, 12.0);
249 
250  // Beam Energy from PS
251  dHist_PSPairEnergy = new TH1I("PSPairEnergy", "Reconstructed PS Beam Energy;Beam Energy (GeV)", 250, 7.0, 12.0);
252 
253  // PVsTheta Time-Based Tracks
254  dHist_PVsTheta_Tracks = new TH2I("PVsTheta_Tracks", "P vs. #theta for time-based tracks;#theta#circ;p (GeV/c)", 280, 0.0, 140.0, 150, 0.0, 12.0);
255 
256  // PhiVsTheta Time-Based Tracks
257  dHist_PhiVsTheta_Tracks = new TH2I("PhiVsTheta_Tracks", "#phi vs. #theta for time-based tracks;#theta#circ;#phi#circ", 280, 0.0, 140.0, 60, -180.0, 180.0);
258 
259  /*************************************************************** VERTEX ***************************************************************/
260 
261  // Event Vertex-Z
262  dEventVertexZ = new TH1I("EventVertexZ", "Reconstructed Event Vertex Z;Event Vertex-Z (cm)", 600, 0.0, 200.0);
263 
264  // Event Vertex-Y Vs Vertex-X
265  dEventVertexYVsX = new TH2I("EventVertexYVsX", "Reconstructed Event Vertex X/Y;Event Vertex-X (cm);Event Vertex-Y (cm)", 400, -10.0, 10.0, 400, -10.0, 10.0);
266 
267  /*************************************************************** 2 gamma inv. mass ***************************************************************/
268  // 2-gamma inv. mass
269  d2gamma = new TH1I("TwoGammaMass", "2#gamma inv. mass;2#gamma inv. mass (GeV)", 400, 0.0, 1.2);
270 
271  // pi+ pi-
272  dpip_pim = new TH1I("PiPlusPiMinus", "#pi^{+}#pi^{-} inv. mass w/ identified proton;#pi^{+}#pi^{-} inv. mass (GeV)", 400, 0.0, 2.0);
273 
274  // K+ K-
275  dKp_Km = new TH1I("KPlusKMinus", "K^{+}K^{-} inv. mass w/ identified proton;K^{+}K^{-} inv. mass (GeV)", 400, 0.0, 2.0);
276 
277  // pi+ pi- pi0
278  dpip_pim_pi0 = new TH1I("PiPlusPiMinusPiZero", "#pi^{+}#pi^{-}#pi^{o} inv. mass w/ identified proton;#pi^{+}#pi^{-}#pi^{o} inv. mass (GeV)", 200, 0.035, 2.0);
279  dptrans = new TH1I("PiPlusPiMinusPiZeroProton_t", ";#pi^{+}#pi^{-}#pi^{o}p transverse momentum(GeV)", 500, 0.0, 1.0);
280 
281  dbeta_vs_p = new TH2I("BetaVsP", "#beta vs. p (best FOM all charged tracks);p (GeV);#beta", 200, 0.0, 2.0, 100, 0.0, 1.2);
282 
283  /*************************************************************** F1 TDC - fADC time ***************************************************************/
284 
285  // first, fill map of rocid/slot combos that have F1TDC's
286  map<int, set<int>> f1tdc_rocid_slot;
287  for(int slot=3; slot<=17; slot++){
288  if( slot==11 || slot==12) continue;
289  if( slot<=16 ) f1tdc_rocid_slot[75].insert(slot); // TAGMH
290  if( slot<=4 ) f1tdc_rocid_slot[95].insert(slot); // STPSC1
291  if( slot<=13 ) f1tdc_rocid_slot[36].insert(slot); // BCAL6
292  if( slot<=13 ) f1tdc_rocid_slot[33].insert(slot); // BCAL3
293  if( slot<=13 ) f1tdc_rocid_slot[39].insert(slot); // BCAL9
294  if( slot<=13 ) f1tdc_rocid_slot[42].insert(slot); // BCAL12
295  if( slot<=17 ) f1tdc_rocid_slot[51].insert(slot); // FDC1
296  if( slot<=16 ) f1tdc_rocid_slot[54].insert(slot); // FDC4
297  if( slot<=16 ) f1tdc_rocid_slot[63].insert(slot); // FDC13
298  if( slot<=16 ) f1tdc_rocid_slot[64].insert(slot); // FDC14
299  }
300 
301  // Create map that can be used to find the correct bin given the rocid,slot
302  for(auto p : f1tdc_rocid_slot){
303  int rocid = p.first;
304  for(int slot : p.second){
305  f1tdc_bin_map[ pair<int,int>(rocid,slot) ] = (double)f1tdc_bin_map.size();
306  }
307  }
308 
309  // Create histogram with bin labels
310  dF1TDC_fADC_tdiff = new TH2D("F1TDC_fADC_tdiff", "F1TDC - fADC Time diff", f1tdc_bin_map.size(), 0.5, 0.5+(double)f1tdc_bin_map.size(), 64, -64.0, 64.0);
311  dF1TDC_fADC_tdiff->SetStats(0);
312  dF1TDC_fADC_tdiff->SetYTitle("TDC - ADC in ns (or TDC/50 time for FDC)");
313  for(auto p : f1tdc_bin_map){
314  int rocid = p.first.first;
315  int slot = p.first.second;
316  int jbin = p.second;
317  char str[256];
318  sprintf(str, "rocid%d slot%d", rocid, slot);
319  dF1TDC_fADC_tdiff->GetXaxis()->SetBinLabel(jbin, str);
320  }
321 
322 
323  // back to main dir
324  main->cd();
325 
326  japp->RootUnLock();
327 
328  return NOERROR;
329 }
330 
331 //------------------
332 // brun
333 //------------------
334 jerror_t JEventProcessor_highlevel_online::brun(JEventLoop *locEventLoop, int32_t runnumber)
335 {
336  // This is called whenever the run number changes
337  vector<double> locBeamPeriodVector;
338  locEventLoop->GetCalib("PHOTON_BEAM/RF/beam_period", locBeamPeriodVector);
339  dBeamBunchPeriod = locBeamPeriodVector[0];
340 
341  dCoherentPeakRange = pair<double, double>(8.4, 9.0);
342  map<string, double> photon_beam_param;
343  if(locEventLoop->GetCalib("/ANALYSIS/beam_asymmetry/coherent_energy", photon_beam_param) == false)
344  dCoherentPeakRange = pair<double, double>(photon_beam_param["cohmin_energy"], photon_beam_param["cohedge_energy"]);
345 
346  fcal_cell_thr = 64;
347  bcal_cell_thr = 20;
348 
349  fcal_row_mask_min = 26;
350  fcal_row_mask_max = 32;
351  fcal_col_mask_min = 26;
352  fcal_col_mask_max = 32;
353 
354  if( runnumber < 11127 )
355  {
356  fcal_row_mask_min = 24;
357  fcal_row_mask_max = 34;
358  fcal_col_mask_min = 24;
359  fcal_col_mask_max = 34;
360  }
361 
362  return NOERROR;
363 }
364 
365 //------------------
366 // evnt
367 //------------------
368 jerror_t JEventProcessor_highlevel_online::evnt(JEventLoop *locEventLoop, uint64_t eventnumber)
369 {
370  vector<const DTrackTimeBased*> locTrackTimeBasedVector;
371  locEventLoop->Get(locTrackTimeBasedVector);
372 
373  vector<const DBeamPhoton*> locBeamPhotons;
374  locEventLoop->Get(locBeamPhotons);
375 
376  vector<const DPSPair*> locPSPairs;
377  locEventLoop->Get(locPSPairs);
378 
379  vector<const DPSCPair*> locPSCPairs;
380  locEventLoop->Get(locPSCPairs);
381 
382  vector<const DFCALShower*> locFCALShowers;
383  locEventLoop->Get(locFCALShowers);
384 
385  vector<const DBCALShower*> locBCALShowers;
386  locEventLoop->Get(locBCALShowers);
387 
388  vector<const DNeutralShower*> locNeutralShowers;
389  locEventLoop->Get(locNeutralShowers);
390 
391  vector<const DNeutralParticle*> locNeutralParticles;
392  locEventLoop->Get(locNeutralParticles, "PreSelect");
393 
394  vector<const DTOFPoint*> locTOFPoints;
395  locEventLoop->Get(locTOFPoints);
396 
397  vector<const DSCHit*> locSCHits;
398  locEventLoop->Get(locSCHits);
399 
400  vector<const DTAGHHit*> locTAGHHits;
401  locEventLoop->Get(locTAGHHits);
402 
403  vector<const DBCALDigiHit*> locBCALDigiHits;
404  locEventLoop->Get(locBCALDigiHits);
405 
406  vector<const DFCALDigiHit*> locFCALDigiHits;
407  locEventLoop->Get(locFCALDigiHits);
408 
409  const DCODAEventInfo* locCODAEventInfo = NULL;
410  try {locEventLoop->GetSingle(locCODAEventInfo);}catch(...){}
411 
412  const DEPICSvalue* locEPICSvalue = NULL;
413  try {locEventLoop->GetSingle(locEPICSvalue);}catch(...){}
414 
415  const DDetectorMatches* locDetectorMatches = NULL;
416  locEventLoop->GetSingle(locDetectorMatches);
417 
418  const DEventRFBunch* locEventRFBunch = NULL;
419  locEventLoop->GetSingle(locEventRFBunch);
420 
421  const DVertex* locVertex = NULL;
422  locEventLoop->GetSingle(locVertex);
423 
424  vector<const DL1Trigger*> locL1Triggers;
425  locEventLoop->Get(locL1Triggers);
426  const DL1Trigger* locL1Trigger = locL1Triggers.empty() ? NULL : locL1Triggers[0];
427 
428  vector<const DChargedTrack*> locChargedTracks;
429  locEventLoop->Get(locChargedTracks, "PreSelect");
430 
431  // The following declares containers for all types in F1Types
432  // (defined at top of this file) and fills them.
433  #define GetVect(A) \
434  vector<const A*> v##A; \
435  locEventLoop->Get(v##A);
436  #define GetTaggerVect(A) \
437  vector<const A*> v##A; \
438  locEventLoop->Get(v##A,"Calib");
439  F1Types(GetVect)
441 
442 
443  /************************************************************** Prepare Timestamp ************************************************************/
444 
445  // This is a way for us to pass the unix time of the event to the macros
446  // so they can make entries in the HDTSDB (time series DB) based on the
447  // time the event was acquired. This turns out to be a lot trickier than
448  // you might think due to the unix timestamp only going into the data
449  // stream on special event types. The 250MHz system clock is available
450  // for physics events but needs the offset to the unix time of the start
451  // of the event. It is also not available in the special events (EPICS,
452  // scaler, and control).
453  //
454  // We handle this in the following way:
455  //
456  // 1. remember last 250MHz clock time seen
457  // 2. when special event with unix time is seen, assume it is
458  // the same time and calculate offset. Remember it so it
459  // can be used to calculate unix time from 250MHz clock on
460  // subsequent events. Always assume 250MHz is exact freq.
461  //
462  // This should be good to within a couple of seconds. One drawback
463  // is that no unix time will be available until a special event
464  // is seen. Those should be produced at about 1Hz, but in the
465  // online farm with 20 nodes, that would be roughly 1 every 20seconds.
466  // Thus, is could conceivably be a couple of minutes before all
467  // nodes get initialized.
468  //
469  // Because RootSpy will automatically add
470  // histograms, we use 2 bins: bin 1 always has "1" so that the macro can
471  // know how many numbers were added. bin 2 contains the actual unix time
472  // stamp. The macro will have to take an average and that will get skewed
473  // if a node drops out mid-run.
474  double unix_time = 0;
475  if(locL1Trigger){
476  // TS scaler event
477  unix_time = locL1Trigger->unix_time; // usually will be zero
478  }
479  if(locEPICSvalue && (unix_time==0)){
480  // EPICS event
481  unix_time = locEPICSvalue->timestamp;
482  }
483 
484  double timestamp = 0.0; // in seconds from 250MHz clock
485  if(locCODAEventInfo) timestamp = (double)locCODAEventInfo->avg_timestamp / 250.0E6;
486 
487  if(timestamp != 0.0) last_timestamp = timestamp;
488  if(unix_time!=0.0 && last_timestamp!=0.0) unix_offset = (double)unix_time - last_timestamp;
489  if( (unix_time==0) && (timestamp!=0.0) && (unix_offset!=0.0) ) unix_time = (unix_offset + timestamp);
490 
491  /********************************************************* PREPARE RF ********************************************************/
492 
493  // Do discrete Fourier transform for selected frequency range
494  double *rf_dft = NULL;
495  if(dHist_BeamBunchPeriod->GetEntries() > 100){
496 
497  int NRF_bins = dHist_BeamBunchPeriod->GetNbinsX();
498  int Ndft_bins = dHist_BeamBunchPeriod_DFT->GetNbinsX();
499  double ns_per_bin = dHist_BeamBunchPeriod->GetBinWidth(1);
500  double rfdomain = ns_per_bin*(double)NRF_bins;
501  rf_dft = new double[Ndft_bins];
502  for(int ibin=1; ibin<=Ndft_bins; ibin++){
503 
504  // n.b. the factor of 1000 below is to convert from MHz to GHz
505  double f = dHist_BeamBunchPeriod_DFT->GetXaxis()->GetBinCenter(ibin);
506  double k = rfdomain/(1000.0/f); // k is number of oscillations in whole x-range for this freq.
507 
508  double dphi = TMath::TwoPi()*k/(double)NRF_bins;
509 
510  double sumc = 0.0;
511  double sums = 0.0;
512  for(int jbin=1; jbin<=(int)NRF_bins; jbin++){
513 
514  double v = dHist_BeamBunchPeriod->GetBinContent(jbin);
515  double theta = (double)jbin*dphi;
516  sumc += v*cos(theta);
517  sums += v*sin(theta);
518  }
519 
520  rf_dft[ibin-1] = sqrt(sumc*sumc + sums*sums);
521  }
522  }
523 
524  /********************************************************* PREPARE TAGGER HITS ********************************************************/
525 
526  //organize TAGH hits
527  map<int, set<double> > locTAGHHitMap; //double: TAGH tdc times (set allows time sorting)
528  for(size_t loc_i = 0; loc_i < locTAGHHits.size(); ++loc_i)
529  {
530  if(locTAGHHits[loc_i]->has_TDC)
531  locTAGHHitMap[locTAGHHits[loc_i]->counter_id].insert(locTAGHHits[loc_i]->time_tdc);
532  }
533 
534  //collect TAGH delta-t's for RF beam bunch histogram
535  map<int, set<double> >::iterator locTAGHIterator = locTAGHHitMap.begin();
536  vector<double> locTAGHDeltaTs;
537  for(; locTAGHIterator != locTAGHHitMap.end(); ++locTAGHIterator)
538  {
539  set<double>& locCounterHits = locTAGHIterator->second;
540  if(locCounterHits.size() < 2)
541  continue;
542  set<double>::iterator locSetIterator = locCounterHits.begin();
543  set<double>::iterator locPreviousSetIterator = locSetIterator;
544  for(++locSetIterator; locSetIterator != locCounterHits.end(); ++locSetIterator, ++locPreviousSetIterator)
545  locTAGHDeltaTs.push_back(*locSetIterator - *locPreviousSetIterator);
546  }
547 
548  /********************************************************* PREPARE TRIGGER INFO *******************************************************/
549 
550  vector<unsigned int> locgtpTrigBits(32, 0); //bit 1 -> 32 is index 0 -> 31
551  vector<unsigned int> locfpTrigBits(32, 0); //bit 1 -> 32 is index 0 -> 31
552 
553  if(locL1Trigger != NULL)
554  {
555  for(unsigned int bit = 0; bit < 32; ++bit){
556  locgtpTrigBits[bit] = (locL1Trigger->trig_mask & (1 << bit)) ? 1 : 0;
557  locfpTrigBits[bit] = (locL1Trigger->fp_trig_mask & (1 << bit)) ? 1 : 0;
558  }
559  }
560 
561  //Get total FCAL energy
562  int fcal_tot_en = 0;
563  for( auto fcal_hit : locFCALDigiHits){
564  int row = fcal_hit->row;
565  int col = fcal_hit->column;
566  if( (row >= fcal_row_mask_min) && (row <= fcal_row_mask_max) ){
567  if( (col >= fcal_col_mask_min) && (col <= fcal_col_mask_max) ) continue;
568  }
569 
570  if( ((int32_t)fcal_hit->pulse_peak-100) <= fcal_cell_thr) continue;
571 
572  uint32_t adc_time = (fcal_hit->pulse_time >> 6) & 0x1FF; // consider only course time
573  if((adc_time < 15) || (adc_time > 50)) continue; // changed from 20 and 70 based on run 30284 2/5/2017 DL
574 
575  Int_t pulse_int = fcal_hit->pulse_integral - fcal_hit->nsamples_integral*100;
576  if(pulse_int < 0) continue;
577  fcal_tot_en += pulse_int;
578  }
579 
580  //Get total BCAL energy
581  int bcal_tot_en = 0;
582  for(auto bcal_hit : locBCALDigiHits){
583  if( ((int32_t)bcal_hit->pulse_peak-100) <= bcal_cell_thr) continue;
584  Int_t pulse_int = bcal_hit->pulse_integral - bcal_hit->nsamples_integral*100;
585  if(pulse_int < 0) continue;
586  bcal_tot_en += pulse_int;
587  }
588 
589  /********************************************************* PREPARE BEAM PHOTONS *******************************************************/
590 
591  vector<const DBeamPhoton*> locBeamPhotons_InTime;
592  for(auto locBeamPhoton : locBeamPhotons)
593  {
594  double locDeltaT = locBeamPhoton->time() - locEventRFBunch->dTime;
595  if(fabs(locDeltaT) <= 0.5*dBeamBunchPeriod)
596  locBeamPhotons_InTime.push_back(locBeamPhoton);
597  }
598 
599  vector<double> Eps; // pair energy in PS
600  if(!locPSCPairs.empty()){
601  for(auto pspair : locPSPairs){
602  auto flhit = pspair->ee.first;
603  auto frhit = pspair->ee.second;
604  double E = flhit->E + frhit->E;
605  Eps.push_back(E);
606  }
607  }
608 
609  /********************************************************* PREPARE HADRONIC TRIGGER *******************************************************/
610 
611  bool locIsHadronicEventFlag = false;
612  for(auto locTrack : locChargedTracks)
613  {
614  //make sure at least one track isn't a lepton!! (read: e+/-. assume all muons come from pion decays)
615  auto locChargedHypo = locTrack->Get_BestTrackingFOM();
616 
617  //timing cut: is it consistent with an e+/-??
618  auto locDetector = locChargedHypo->t1_detector();
619  double locDeltaT = locChargedHypo->time() - locChargedHypo->t0();
620  if(fabs(locDeltaT) > dTimingCutMap[Electron][locDetector])
621  {
622  locIsHadronicEventFlag = true; //not an electron!!
623  break;
624  }
625 
626  //compute shower-E/p, cut
627  double locP = locChargedHypo->momentum().Mag();
628  double locShowerEOverP = 0.0;
629  auto locFCALShowerMatchParams = locChargedHypo->Get_FCALShowerMatchParams();
630  auto locBCALShowerMatchParams = locChargedHypo->Get_BCALShowerMatchParams();
631  if(locFCALShowerMatchParams != NULL)
632  {
633  const DFCALShower* locFCALShower = locFCALShowerMatchParams->dFCALShower;
634  locShowerEOverP = locFCALShower->getEnergy()/locP;
635  }
636  else if(locBCALShowerMatchParams != NULL)
637  {
638  const DBCALShower* locBCALShower = locBCALShowerMatchParams->dBCALShower;
639  locShowerEOverP = locBCALShower->E/locP;
640  }
641  else //not matched to a shower
642  {
643  locIsHadronicEventFlag = true; //assume not an electron!!
644  break;
645  }
646 
647  if(locShowerEOverP < dShowerEOverPCut)
648  {
649  locIsHadronicEventFlag = true; //not an electron!!
650  break;
651  }
652  }
653 
654  int locNumHadronicTriggers_CoherentPeak_RFSignal = 0;
655  int locNumHadronicTriggers_CoherentPeak_RFSideband = 0;
656  double locNumRFSidebandBunches = 2.0*double(dRFSidebandBunchRange.second - dRFSidebandBunchRange.first);
657  if(locIsHadronicEventFlag)
658  {
659  //see if is in coherent peak
660  for(auto& locBeamPhoton : locBeamPhotons)
661  {
662  if(std::isnan(locEventRFBunch->dTime))
663  break; //RF sideband background too high: ignore
664  if((locBeamPhoton->energy() < dCoherentPeakRange.first) || (locBeamPhoton->energy() > dCoherentPeakRange.second))
665  continue; //not in coherent peak
666 
667  //delta-t sideband range
668  double locSidebandMinDeltaT = dBeamBunchPeriod*(double(dRFSidebandBunchRange.first) - 0.5);
669  double locSidebandMaxDeltaT = dBeamBunchPeriod*(double(dRFSidebandBunchRange.first) + 0.5);
670 
671  double locBeamRFDeltaT = locBeamPhoton->time() - locEventRFBunch->dTime;
672  if(fabs(locBeamRFDeltaT) <= 0.5*dBeamBunchPeriod)
673  ++locNumHadronicTriggers_CoherentPeak_RFSignal;
674  else if((fabs(locBeamRFDeltaT) >= locSidebandMinDeltaT) && (fabs(locBeamRFDeltaT) <= locSidebandMaxDeltaT))
675  ++locNumHadronicTriggers_CoherentPeak_RFSideband;
676  }
677  }
678 
679 
680  /*************************************************************** F1 TDC - fADC time ***************************************************************/
681  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
682 
683  // The following fills the dF1TDC_fADC_tdiff histo for
684  // all detectors that use F1TDC modules. See the templates
685  // at the top of this file for details.
686  #define F1Fill(A) FillF1Hist(v##A);
687  F1Types(F1Fill)
689 
690  /************************************************************** Event Info ************************************************************/
691 
692  if( unix_time!=0 ){
693  dHist_EventInfo->SetBinContent(1, 1);
694  dHist_EventInfo->SetBinContent(2, unix_time);
695  }
696 
697  /***************************************************************** RF *****************************************************************/
698 
699  for(size_t loc_i = 0; loc_i < locTAGHDeltaTs.size(); ++loc_i)
700  dHist_BeamBunchPeriod->Fill(locTAGHDeltaTs[loc_i]);
701 
702  if(rf_dft){
703  for(int i=0; i<dHist_BeamBunchPeriod_DFT->GetNbinsX(); i++){
704  dHist_BeamBunchPeriod_DFT->SetBinContent(i+1, rf_dft[i]);
705  }
706  delete[] rf_dft;
707  }
708 
709  /*************************************************************** TRIGGER **************************************************************/
710 
711  if(locL1Trigger != NULL)
712  {
713  if(locgtpTrigBits[0] == 1) //bit 1
714  dHist_BCALVsFCAL_TrigBit1->Fill(Float_t(fcal_tot_en), Float_t(bcal_tot_en));
715 
716  // trigger bits
717  for(int bit=1; bit<=32; bit++){
718  if(locgtpTrigBits[bit-1]) dHist_L1bits_gtp->Fill(bit);
719  if(locfpTrigBits[bit-1] ) dHist_L1bits_fp->Fill(bit);
720  }
721 
722  // Keep counts of events with any physics trigger as bit 33
723  if( locgtpTrigBits[1-1] | locgtpTrigBits[3-1] ) dHist_L1bits_gtp->Fill(33);
724 
725  // #triggers: total
726  if(locL1Trigger->trig_mask > 0)
727  dHist_NumTriggers->Fill(33, 1);
728  if(locL1Trigger->fp_trig_mask > 0)
729  dHist_NumTriggers->Fill(33, 2);
730 
731  // #triggers: by bit
732  for(int locTriggerBit = 1; locTriggerBit <= 32; ++locTriggerBit)
733  {
734  if(locgtpTrigBits[locTriggerBit - 1]) //gtp (normal)
735  dHist_NumTriggers->Fill(locTriggerBit, 1);
736  if(locfpTrigBits[locTriggerBit - 1]) //front panel
737  dHist_NumTriggers->Fill(locTriggerBit, 2);
738  }
739 
740  // #hadronic triggers
741  if(locIsHadronicEventFlag)
742  {
743  //total
744  if(locL1Trigger->trig_mask > 0)
745  {
746  dHist_NumTriggers->Fill(33, 3);
747 
748  //coherent peak
749  dNumHadronicTriggers_CoherentPeak_RFSignal[32] += double(locNumHadronicTriggers_CoherentPeak_RFSignal);
750  dNumHadronicTriggers_CoherentPeak_RFSideband[32] += double(locNumHadronicTriggers_CoherentPeak_RFSideband);
751  int locNumHadronicTriggers_CoherentPeak = int(dNumHadronicTriggers_CoherentPeak_RFSignal[32] - dNumHadronicTriggers_CoherentPeak_RFSideband[32]/locNumRFSidebandBunches + 0.5); //+0.5: round
752  dHist_NumTriggers->SetBinContent(33, 4, locNumHadronicTriggers_CoherentPeak); //# hadronic triggers
753  }
754 
755  //by bit
756  for(int locTriggerBit = 1; locTriggerBit <= 32; ++locTriggerBit)
757  {
758  if(!locgtpTrigBits[locTriggerBit - 1])
759  continue;
760 
761  //all hadronic
762  dHist_NumTriggers->Fill(locTriggerBit, 3);
763 
764  //coherent peak: must subtract RF sidebands to determine the actual beam energy
765  dNumHadronicTriggers_CoherentPeak_RFSignal[locTriggerBit - 1] += double(locNumHadronicTriggers_CoherentPeak_RFSignal);
766  dNumHadronicTriggers_CoherentPeak_RFSideband[locTriggerBit - 1] += double(locNumHadronicTriggers_CoherentPeak_RFSideband);
767  double locNumHadronicTriggers_CoherentPeak = dNumHadronicTriggers_CoherentPeak_RFSignal[locTriggerBit - 1] - dNumHadronicTriggers_CoherentPeak_RFSideband[locTriggerBit - 1]/locNumRFSidebandBunches;
768  dHist_NumTriggers->SetBinContent(locTriggerBit, 4, locNumHadronicTriggers_CoherentPeak); //# hadronic triggers
769  }
770 
771  //coherent peak rate
772  double locHadronicCoherentPeakRate = dHist_NumTriggers->GetBinContent(33, 4)/dHist_NumTriggers->GetBinContent(33, 1);
773 
774  ostringstream locHistTitle;
775  locHistTitle << "Total Hadronic Coherent Peak Rate = " << locHadronicCoherentPeakRate;
776  dHist_NumTriggers->SetTitle(locHistTitle.str().c_str());
777  }
778  }
779 
780  // DON'T DO HIGHER LEVEL PROCESSING FOR FRONT PANEL TRIGGER EVENTS, OR NON-TRIGGER EVENTS
781  if(!locL1Trigger || (locL1Trigger && (locL1Trigger->fp_trig_mask>0))) {
782  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
783  return NOERROR;
784  }
785 
786  /****************************************************** NUM RECONSTRUCTED OBJECTS *****************************************************/
787 
788  //# High-Level Objects
789  dHist_NumHighLevelObjects->Fill(1, (Double_t)locSCHits.size());
790  dHist_NumHighLevelObjects->Fill(2, (Double_t)locTOFPoints.size());
791  dHist_NumHighLevelObjects->Fill(3, (Double_t)locBCALShowers.size());
792  dHist_NumHighLevelObjects->Fill(4, (Double_t)locFCALShowers.size());
793  dHist_NumHighLevelObjects->Fill(5, (Double_t)locTrackTimeBasedVector.size());
794  dHist_NumHighLevelObjects->Fill(6, (Double_t)locDetectorMatches->Get_NumTrackSCMatches());
795  dHist_NumHighLevelObjects->Fill(7, (Double_t)locDetectorMatches->Get_NumTrackTOFMatches());
796  dHist_NumHighLevelObjects->Fill(8, (Double_t)locDetectorMatches->Get_NumTrackBCALMatches());
797  dHist_NumHighLevelObjects->Fill(9, (Double_t)locDetectorMatches->Get_NumTrackFCALMatches());
798  dHist_NumHighLevelObjects->Fill(10, (Double_t)locBeamPhotons.size());
799  dHist_NumHighLevelObjects->Fill(11, (Double_t)locChargedTracks.size());
800  dHist_NumHighLevelObjects->Fill(12, (Double_t)locNeutralShowers.size());
801 
802  /************************************************************* KINEMATICS *************************************************************/
803 
804  for(size_t loc_i = 0; loc_i < locBeamPhotons.size(); ++loc_i)
805  dHist_BeamEnergy->Fill(locBeamPhotons[loc_i]->energy());
806 
807  for(auto E : Eps) dHist_PSPairEnergy->Fill(E);
808 
809  for(size_t loc_i = 0; loc_i < locChargedTracks.size(); ++loc_i)
810  {
811  auto locChargedHypo = locChargedTracks[loc_i]->Get_BestTrackingFOM();
812  if(locChargedHypo->t1_detector() == SYS_NULL) continue; // skip tracks with artificial betas
813  double locP = locChargedHypo->momentum().Mag();
814  double locTheta = locChargedHypo->momentum().Theta()*180.0/TMath::Pi();
815  double locPhi = locChargedHypo->momentum().Phi()*180.0/TMath::Pi();
816  double locBeta = locChargedHypo->measuredBeta();
817  dHist_PVsTheta_Tracks->Fill(locTheta, locP);
818  dHist_PhiVsTheta_Tracks->Fill(locTheta, locPhi);
819  dbeta_vs_p->Fill(locP, locBeta);
820  }
821 
822  /*************************************************************** VERTEX ***************************************************************/
823 
824  if(locChargedTracks.size() >= 2)
825  {
826  dEventVertexZ->Fill(locVertex->dSpacetimeVertex.Z());
827  dEventVertexYVsX->Fill(locVertex->dSpacetimeVertex.X(), locVertex->dSpacetimeVertex.Y());
828  }
829 
830  /*************************************************************** 2 gamma inv. mass ***************************************************************/
831 
832  vector<DLorentzVector> pi0s;
833  for(uint32_t i=0; i<locNeutralParticles.size(); i++){
834 
835  auto hypoth1 = locNeutralParticles[i]->Get_Hypothesis(Gamma);
836  if(!hypoth1) continue;
837 
838  //timing cut
839  auto dectector1 = hypoth1->t1_detector();
840  double locDeltaT = hypoth1->time() - hypoth1->t0();
841  if(fabs(locDeltaT) > dTimingCutMap[Gamma][dectector1])
842  continue;
843 
844  const DLorentzVector &v1 = hypoth1->lorentzMomentum();
845 
846  for(uint32_t j=i+1; j<locNeutralParticles.size(); j++){
847 
848  auto hypoth2 = locNeutralParticles[j]->Get_Hypothesis(Gamma);
849  if(!hypoth2) continue;
850 
851  //timing cut
852  auto dectector2 = hypoth2->t1_detector();
853  locDeltaT = hypoth2->time() - hypoth2->t0();
854  if(fabs(locDeltaT) > dTimingCutMap[Gamma][dectector2])
855  continue;
856 
857  const DLorentzVector &v2 = hypoth2->lorentzMomentum();
858 
859  DLorentzVector ptot(v1+v2);
860  double mass = ptot.M();
861  d2gamma->Fill(mass);
862  if(mass>0.1 && mass<0.17) pi0s.push_back(ptot);
863  }
864  }
865 
866  /*************************************************************** pi+ pi- pi0 ***************************************************************/
867 
868  for(auto t1 : locChargedTracks){
869  //look for pi+
870  auto hypoth1 = t1->Get_Hypothesis(PiPlus);
871  if(!hypoth1) continue;
872 
873  //timing cut
874  auto dectector1 = hypoth1->t1_detector();
875  double locDeltaT = hypoth1->time() - hypoth1->t0();
876  if(fabs(locDeltaT) > dTimingCutMap[PiPlus][dectector1])
877  continue;
878 
879  const DLorentzVector &pipmom = hypoth1->lorentzMomentum();
880 
881  for(auto t2 : locChargedTracks){
882  if(t2 == t1) continue;
883 
884  //look for pi-
885  auto hypoth2 = t2->Get_Hypothesis(PiMinus);
886  if(!hypoth2) continue;
887 
888  //timing cut
889  auto dectector2 = hypoth2->t1_detector();
890  locDeltaT = hypoth2->time() - hypoth2->t0();
891  if(fabs(locDeltaT) > dTimingCutMap[PiMinus][dectector2])
892  continue;
893 
894  const DLorentzVector &pimmom = hypoth2->lorentzMomentum();
895 
896  for(auto t3 : locChargedTracks){
897  if(t3 == t1) continue;
898  if(t3 == t2) continue;
899 
900  //look for proton
901  auto hypoth3 = t3->Get_Hypothesis(Proton);
902  if(!hypoth3) continue;
903 
904  //timing cut
905  auto dectector3 = hypoth3->t1_detector();
906  locDeltaT = hypoth3->time() - hypoth3->t0();
907  if(fabs(locDeltaT) > dTimingCutMap[Proton][dectector3])
908  continue;
909 
910  const DLorentzVector &protonmom = hypoth3->lorentzMomentum();
911 
912  //for rho: require at least one beam photon in time with missing mass squared near 0
913  DLorentzVector rhomom(pipmom + pimmom);
914  DLorentzVector locFinalStateP4 = rhomom + protonmom;
915  DLorentzVector locTargetP4(0.0, 0.0, 0.0, ParticleMass(Proton));
916  for(auto locBeamPhoton : locBeamPhotons_InTime)
917  {
918  DLorentzVector locMissingP4 = locBeamPhoton->lorentzMomentum() + locTargetP4 - locFinalStateP4;
919  if(fabs(locMissingP4.M2()) > 0.01)
920  continue;
921  dpip_pim->Fill(rhomom.M());
922  break;
923  }
924 
925  for(uint32_t i=0; i<pi0s.size(); i++){
926  DLorentzVector &pi0mom = pi0s[i];
927 
928  //for omega: require at least one beam photon in time with missing mass squared near 0
929  DLorentzVector omegamom(pi0mom + rhomom);
930  locFinalStateP4 = omegamom + protonmom;
931  for(auto locBeamPhoton : locBeamPhotons_InTime)
932  {
933  DLorentzVector locMissingP4 = locBeamPhoton->lorentzMomentum() + locTargetP4 - locFinalStateP4;
934  if(fabs(locMissingP4.M2()) > 0.01)
935  continue;
936  dpip_pim_pi0->Fill(omegamom.M());
937  break;
938  }
939 
940  double ptrans = locFinalStateP4.Perp();
941  dptrans->Fill(ptrans);
942  if(ptrans > 0.1) continue;
943  }
944  }
945  }
946  }
947 
948  /*************************************************************** K+ K- ***************************************************************/
949 
950  for(auto t1 : locChargedTracks){
951  //look for K+
952  auto hypoth1 = t1->Get_Hypothesis(KPlus);
953  if(!hypoth1) continue;
954 
955  //timing cut
956  auto dectector1 = hypoth1->t1_detector();
957  double locDeltaT = hypoth1->time() - hypoth1->t0();
958  if(fabs(locDeltaT) > dTimingCutMap[PiPlus][dectector1]) // use same timing cuts as pion
959  continue;
960 
961  const DLorentzVector &Kpmom = hypoth1->lorentzMomentum();
962 
963  for(auto t2 : locChargedTracks){
964  if(t2 == t1) continue;
965 
966  //look for pi-
967  auto hypoth2 = t2->Get_Hypothesis(KMinus);
968  if(!hypoth2) continue;
969 
970  //timing cut
971  auto dectector2 = hypoth2->t1_detector();
972  locDeltaT = hypoth2->time() - hypoth2->t0();
973  if(fabs(locDeltaT) > dTimingCutMap[PiMinus][dectector2]) // use same timing cuts as pion
974  continue;
975 
976  const DLorentzVector &Kmmom = hypoth2->lorentzMomentum();
977 
978  for(auto t3 : locChargedTracks){
979  if(t3 == t1) continue;
980  if(t3 == t2) continue;
981 
982  //look for proton
983  auto hypoth3 = t3->Get_Hypothesis(Proton);
984  if(!hypoth3) continue;
985 
986  //timing cut
987  auto dectector3 = hypoth3->t1_detector();
988  locDeltaT = hypoth3->time() - hypoth3->t0();
989  if(fabs(locDeltaT) > dTimingCutMap[Proton][dectector3])
990  continue;
991 
992  const DLorentzVector &protonmom = hypoth3->lorentzMomentum();
993 
994  // for phi: require at least one beam photon in time with missing mass squared near 0
995  DLorentzVector phimom(Kpmom + Kmmom);
996  DLorentzVector locFinalStateP4 = phimom + protonmom;
997  DLorentzVector locTargetP4(0.0, 0.0, 0.0, ParticleMass(Proton));
998  for(auto locBeamPhoton : locBeamPhotons_InTime)
999  {
1000  DLorentzVector locMissingP4 = locBeamPhoton->lorentzMomentum() + locTargetP4 - locFinalStateP4;
1001  if(fabs(locMissingP4.M2()) > 0.01)
1002  continue;
1003  dKp_Km->Fill(phimom.M());
1004  break;
1005  }
1006  }
1007  }
1008  }
1009 
1010 
1011  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
1012 
1013  return NOERROR;
1014 }
1015 
1016 //------------------
1017 // erun
1018 //------------------
1020 {
1021  // This is called whenever the run number changes, before it is
1022  // changed to give you a chance to clean up before processing
1023  // events from the next run number.
1024 
1025  return NOERROR;
1026 }
1027 
1028 //------------------
1029 // fini
1030 //------------------
1032 {
1033  // Called before program exit after event processing is finished.
1034  return NOERROR;
1035 }
1036 
double getEnergy() const
Definition: DFCALShower.h:156
#define F1Fill(A)
double F1tdiff2< DBCALUnifiedHit >(const DBCALUnifiedHit *hit, const DBCALUnifiedHit *hit2)
#define F1Types(X)
bool F1CheckTDCOnly< DSCHit >(const DSCHit *hit)
static double F1tdiff(const T *hit)
char str[256]
double F1tdiff2< DSCHit >(const DSCHit *hit, const DSCHit *hit2)
double F1tdiff2< DTAGHHit >(const DTAGHHit *hit, const DTAGHHit *hit2)
Definition: GlueX.h:16
uint32_t trig_mask
Definition: DL1Trigger.h:18
uint32_t fp_trig_mask
Definition: DL1Trigger.h:19
sprintf(text,"Post KinFit Cut")
bool F1Check< DFDCHit >(const DFDCHit *hit)
bool F1CheckADCOnly< DTAGHHit >(const DTAGHHit *hit)
double F1tdiff< DBCALUnifiedHit >(const DBCALUnifiedHit *hit)
double F1tdiff2< DFDCHit >(const DFDCHit *hit, const DFDCHit *hit2)
bool F1CheckADCOnly< DRFTime >(const DRFTime *hit)
bool F1CheckSameChannel< DSCHit >(const DSCHit *hit, const DSCHit *hit2)
size_t Get_NumTrackFCALMatches(void) const
size_t Get_NumTrackSCMatches(void) const
TLorentzVector DLorentzVector
#define GetVect(A)
double F1tdiff2< DRFTime >(const DRFTime *hit, const DRFTime *hit2)
Definition: GlueX.h:19
JApplication * japp
TF1 * f
Definition: FitGains.C:21
#define GetTaggerVect(A)
static bool F1CheckTDCOnly(const T *hit)
bool F1CheckADCOnly< DBCALUnifiedHit >(const DBCALUnifiedHit *hit)
Definition: DSCHit.h:14
bool F1CheckSameChannel< DFDCHit >(const DFDCHit *hit, const DFDCHit *hit2)
static bool F1CheckSameChannel(const T *hit, const T *hit2)
bool F1CheckTDCOnly< DBCALUnifiedHit >(const DBCALUnifiedHit *hit)
bool F1Check< DTAGHHit >(const DTAGHHit *hit)
uint64_t avg_timestamp
bool F1CheckTDCOnly< DFDCHit >(const DFDCHit *hit)
double F1tdiff< DTAGMHit >(const DTAGMHit *hit)
jerror_t evnt(jana::JEventLoop *locEventLoop, uint64_t eventnumber)
InitPlugin_t InitPlugin
Definition: GlueX.h:20
double F1tdiff2< DTAGMHit >(const DTAGMHit *hit, const DTAGMHit *hit2)
TLatex * t1
bool F1Check< DSCHit >(const DSCHit *hit)
Definition: GlueX.h:22
double F1tdiff< DFDCHit >(const DFDCHit *hit)
bool F1CheckSameChannel< DBCALUnifiedHit >(const DBCALUnifiedHit *hit, const DBCALUnifiedHit *hit2)
bool F1Check< DRFTime >(const DRFTime *hit)
double F1tdiff< DTAGHHit >(const DTAGHHit *hit)
DLorentzVector dSpacetimeVertex
Definition: DVertex.h:28
static double F1tdiff2(const T *hit, const T *hit2)
static bool F1Check(const T *hit)
bool F1CheckSameChannel< DTAGHHit >(const DTAGHHit *hit, const DTAGHHit *hit2)
static double ParticleMass(Particle_t p)
bool F1CheckTDCOnly< DRFTime >(const DRFTime *hit)
double sqrt(double)
bool F1CheckADCOnly< DTAGMHit >(const DTAGMHit *hit)
bool F1CheckTDCOnly< DTAGMHit >(const DTAGMHit *hit)
double unix_time
double sin(double)
bool F1CheckADCOnly< DSCHit >(const DSCHit *hit)
size_t Get_NumTrackBCALMatches(void) const
size_t Get_NumTrackTOFMatches(void) const
bool F1CheckADCOnly< DFDCHit >(const DFDCHit *hit)
static bool F1CheckADCOnly(const T *hit)
bool F1CheckSameChannel< DRFTime >(const DRFTime *hit, const DRFTime *hit2)
bool F1CheckTDCOnly< DTAGHHit >(const DTAGHHit *hit)
#define F1TaggerTypes(X)
bool F1Check< DTAGMHit >(const DTAGMHit *hit)
time_t timestamp
Definition: DEPICSvalue.h:62
double F1tdiff< DRFTime >(const DRFTime *hit)
bool F1Check< DBCALUnifiedHit >(const DBCALUnifiedHit *hit)
bool F1CheckSameChannel< DTAGMHit >(const DTAGMHit *hit, const DTAGMHit *hit2)
uint32_t unix_time
Definition: DL1Trigger.h:27
int main(int argc, char *argv[])
Definition: gendoc.cc:6
A DEPICSvalue object holds information for a single EPICS value read from the data stream...
Definition: DEPICSvalue.h:37
double F1tdiff< DSCHit >(const DSCHit *hit)
jerror_t brun(jana::JEventLoop *locEventLoop, int32_t runnumber)
class DFDCHit: definition for a basic FDC hit data type.
Definition: DFDCHit.h:20