Bug Summary

File:alld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h
Warning:line 398, column 7
Null pointer passed to 2nd parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -main-file-name DHistogramActions_Independent.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0 -D HAVE_CCDB -D HAVE_RCDB -D HAVE_EVIO -D HAVE_TMVA=1 -D RCDB_MYSQL=1 -D RCDB_SQLITE=1 -D SQLITE_USE_LEGACY_STRUCT=ON -I .Linux_CentOS7.7-x86_64-gcc4.8.5/libraries/ANALYSIS -I libraries/ANALYSIS -I . -I libraries -I libraries/include -I /w/halld-scifs17exp/home/sdobbs/clang/halld_recon/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I external/xstream/include -I /usr/include/tirpc -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/root/root-6.08.06/include -I /w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/ccdb/ccdb_1.06.06/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/rcdb/rcdb_0.06.00/cpp/include -I /usr/include/mysql -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlitecpp/SQLiteCpp-2.2.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlite/sqlite-3.13.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/hdds/hdds-4.9.0/Linux_CentOS7.7-x86_64-gcc4.8.5/src -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/xerces-c/xerces-c-3.1.4/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/evio/evio-4.4.6/Linux-x86_64/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward -internal-isystem /usr/local/include -internal-isystem /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /home/sdobbs/work/clang/halld_recon/src -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-01-21-110224-160369-1 -x c++ libraries/ANALYSIS/DHistogramActions_Independent.cc

libraries/ANALYSIS/DHistogramActions_Independent.cc

1
2#include <unistd.h>
3
4#include "ANALYSIS/DHistogramActions.h"
5#include "TOF/DTOFGeometry.h"
6
7void DHistogramAction_ObjectMemory::Initialize(JEventLoop* locEventLoop)
8{
9 //setup binning
10 vector<string> locBinLabels = {"TMatrixFSym", "DKinematicInfo", "Charged DTimingInfo", "DTrackingInfo", "Neutral DTimingInfo", "KinematicDatas", "Charged Hypos", "Neutral Hypos", "Beam Photons",
11 "Combo RF Bunches", "Source Combos", "Source Combo Vectors", "Particle Combos", "Particle Combo Steps",
12 "DKinFitParticle", "DKinFitChainStep", "DKinFitChain", "DKinFitResults", "DKinFitConstraint_Mass", "DKinFitConstraint_P4", "DKinFitConstraint_Vertex", "DKinFitConstraint_Spacetime"};
13 for(size_t loc_i = 0; loc_i < locBinLabels.size(); ++loc_i)
14 dBinMap[locBinLabels[loc_i]] = loc_i + 1;
15
16 //CREATE THE HISTOGRAMS
17 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
18 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
19 {
20 CreateAndChangeTo_ActionDirectory();
21
22 dVirtualMemoryVsEventNumber = new TH1F("VirtualMemoryVsEventNumber", ";Event Counter;Virtual Memory (MB)", dMaxNumEvents, 0.5, (double)dMaxNumEvents + 0.5);
23 dResidentMemoryVsEventNumber = new TH1F("ResidentMemoryVsEventNumber", ";Event Counter;Resident Memory (MB)", dMaxNumEvents, 0.5, (double)dMaxNumEvents + 0.5);
24
25 // Total Memory
26 string locHistName = "TotalMemory";
27 string locHistTitle = ";Event Counter;Total Memory (MB)";
28 dHist_TotalMemory = GetOrCreate_Histogram<TH1F>(locHistName, locHistTitle, dMaxNumEvents, 0.5, float(dMaxNumEvents) + 0.5);
29
30 // # Objects
31 locHistName = "NumObjects2D";
32 locHistTitle = "# Objects;Event Counter";
33 dHist_NumObjects = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dMaxNumEvents, 0.5, float(dMaxNumEvents) + 0.5, locBinLabels.size(), 0.5, float(locBinLabels.size()) + 0.5);
34 for(size_t loc_i = 0; loc_i < locBinLabels.size(); ++loc_i)
35 dHist_NumObjects->GetYaxis()->SetBinLabel(1 + loc_i, locBinLabels[loc_i].c_str());
36
37 // Object Memory
38 locHistName = "Memory2D";
39 locHistTitle = "Memory (MB);Event Counter";
40 dHist_Memory = GetOrCreate_Histogram<TH2F>(locHistName, locHistTitle, dMaxNumEvents, 0.5, float(dMaxNumEvents) + 0.5, locBinLabels.size(), 0.5, float(locBinLabels.size()) + 0.5);
41 for(size_t loc_i = 0; loc_i < locBinLabels.size(); ++loc_i)
42 dHist_Memory->GetYaxis()->SetBinLabel(1 + loc_i, locBinLabels[loc_i].c_str());
43
44 //Return to the base directory
45 ChangeTo_BaseDirectory();
46 }
47 japp->RootUnLock(); //RELEASE ROOT LOCK!!
48}
49
50bool DHistogramAction_ObjectMemory::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
51{
52 if(Get_CalledPriorWithComboFlag())
53 return true; //else double-counting!
54
55 if(dEventCounter > dMaxNumEvents)
56 return true;
57
58 if(locParticleCombo != nullptr)
59 return true; // Protect against infinite recursion (see below)
60
61 //THIS IS EXTREMELY DANGEROUS, AND SHOULD BE AVOIDED UNLESS YOU KNOW !!!!EXACTLY!!!! WHAT YOU ARE DOING
62 //And if you're doing this, you probably don't
63 //This will result in a infinite-recursion crash if it is called by DAnalysisResults_factory.
64 //This action should only be used directly in an event processsor
65 //This casuses the analysis to run, generating the objects needed for histogramming below.
66 vector<const DAnalysisResults*> locAnalysisResults;
67 locEventLoop->Get(locAnalysisResults);
68
69 map<int, size_t> locNumObjectsMap; //int is bin
70 map<int, double> locMemoryMap; //int is bin
71 double locTotalMemory = 0.0;
72
73 /******************************************************* COMPONENT OBJECTS *******************************************************/
74
75 //TMatrixFSym
76 auto locBin = dBinMap["TMatrixFSym"];
77 locNumObjectsMap[locBin] = dResourcePool_TMatrixFSym.Get_NumObjectsAllThreads();
78 auto locMemory = (sizeof(TMatrixDSym) + 7*7*4)*locNumObjectsMap[locBin]; //assume 7x7 matrix of floats (4)
79 locMemoryMap[locBin] = locMemory;
80 locTotalMemory += locMemory;
81
82 //DKinematicData::DKinematicInfo
83 locBin = dBinMap["DKinematicInfo"];
84 locNumObjectsMap[locBin] = dResourcePool_KinematicInfo.Get_NumObjectsAllThreads();
85 locMemory = sizeof(DKinematicData::DKinematicInfo)*locNumObjectsMap[locBin];
86 locMemoryMap[locBin] = locMemory;
87 locTotalMemory += locMemory;
88
89 //DChargedTrackHypothesis::DTimingInfo
90 locBin = dBinMap["Charged DTimingInfo"];
91 locNumObjectsMap[locBin] = dResourcePool_ChargedHypoTimingInfo.Get_NumObjectsAllThreads();
92 locMemory = sizeof(DChargedTrackHypothesis::DTimingInfo)*locNumObjectsMap[locBin];
93 locMemoryMap[locBin] = locMemory;
94 locTotalMemory += locMemory;
95
96 //DChargedTrackHypothesis::DTrackingInfo
97 locBin = dBinMap["DTrackingInfo"];
98 locNumObjectsMap[locBin] = dResourcePool_ChargedHypoTrackingInfo.Get_NumObjectsAllThreads();
99 locMemory = sizeof(DChargedTrackHypothesis::DTrackingInfo)*locNumObjectsMap[locBin];
100 locMemoryMap[locBin] = locMemory;
101 locTotalMemory += locMemory;
102
103 //DNeutralParticleHypothesis::DTimingInfo
104 locBin = dBinMap["Neutral DTimingInfo"];
105 locNumObjectsMap[locBin] = dResourcePool_NeutralHypoTimingInfo.Get_NumObjectsAllThreads();
106 locMemory = sizeof(DNeutralParticleHypothesis::DTimingInfo)*locNumObjectsMap[locBin];
107 locMemoryMap[locBin] = locMemory;
108 locTotalMemory += locMemory;
109
110 /******************************************************* KINEMATIC DATA OBJECTS *******************************************************/
111
112 //DKinematicData
113 locBin = dBinMap["KinematicDatas"];
114 locNumObjectsMap[locBin] = dResourcePool_KinematicData.Get_NumObjectsAllThreads();
115 locMemory = sizeof(DKinematicData)*locNumObjectsMap[locBin];
116 locMemoryMap[locBin] = locMemory;
117 locTotalMemory += locMemory;
118
119 //DChargedTrackHypothesis
120 locBin = dBinMap["Charged Hypos"];
121 locNumObjectsMap[locBin] = dResourcePool_ChargedTrackHypothesis.Get_NumObjectsAllThreads();
122 locMemory = sizeof(DChargedTrackHypothesis)*locNumObjectsMap[locBin];
123 locMemoryMap[locBin] = locMemory;
124 locTotalMemory += locMemory;
125
126 //DNeutralParticleHypothesis
127 locBin = dBinMap["Neutral Hypos"];
128 locNumObjectsMap[locBin] = dResourcePool_NeutralParticleHypothesis.Get_NumObjectsAllThreads();
129 locMemory = sizeof(DNeutralParticleHypothesis)*locNumObjectsMap[locBin];
130 locMemoryMap[locBin] = locMemory;
131 locTotalMemory += locMemory;
132
133 //DBeamPhoton
134 locBin = dBinMap["Beam Photons"];
135 locNumObjectsMap[locBin] = dResourcePool_BeamPhotons.Get_NumObjectsAllThreads();
136 locMemory = sizeof(DBeamPhoton)*locNumObjectsMap[locBin];
137 locMemoryMap[locBin] = locMemory;
138 locTotalMemory += locMemory;
139
140 /******************************************************* COMBO OBJECTS *******************************************************/
141
142 //DEventRFBunch
143 locBin = dBinMap["Combo RF Bunches"];
144 locNumObjectsMap[locBin] = dResourcePool_EventRFBunch.Get_NumObjectsAllThreads();
145 locMemory = sizeof(DEventRFBunch)*locNumObjectsMap[locBin];
146 locMemoryMap[locBin] = locMemory;
147 locTotalMemory += locMemory;
148
149 //DSourceCombo
150 locBin = dBinMap["Source Combos"];
151 locNumObjectsMap[locBin] = dResourcePool_SourceCombo.Get_NumObjectsAllThreads();
152 locMemory = sizeof(DSourceCombo)*locNumObjectsMap[locBin];
153 locMemoryMap[locBin] = locMemory;
154 locTotalMemory += locMemory;
155
156 //DSourceCombo Vectors
157 locBin = dBinMap["Source Combo Vectors"];
158 locNumObjectsMap[locBin] = dResourcePool_SourceComboVector.Get_NumObjectsAllThreads();
159 locMemory = sizeof(vector<const DSourceCombo*>)*locNumObjectsMap[locBin];
160 locMemoryMap[locBin] = locMemory;
161 locTotalMemory += locMemory;
162
163 //DParticleCombo
164 locBin = dBinMap["Particle Combos"];
165 locNumObjectsMap[locBin] = dResourcePool_ParticleCombo.Get_NumObjectsAllThreads();
166 locMemory = sizeof(DParticleCombo)*locNumObjectsMap[locBin];
167 locMemoryMap[locBin] = locMemory;
168 locTotalMemory += locMemory;
169
170 //DParticleComboStep
171 locBin = dBinMap["Particle Combo Steps"];
172 locNumObjectsMap[locBin] = dResourcePool_ParticleComboStep.Get_NumObjectsAllThreads();
173 locMemory = sizeof(DParticleComboStep)*locNumObjectsMap[locBin];
174 locMemoryMap[locBin] = locMemory;
175 locTotalMemory += locMemory;
176
177 /******************************************************* KINFIT OBJECTS *******************************************************/
178
179 //DKinFitParticle
180 locBin = dBinMap["DKinFitParticle"];
181 locNumObjectsMap[locBin] = dResourcePool_KinFitParticle.Get_NumObjectsAllThreads();
182 locMemory = sizeof(DKinFitParticle)*locNumObjectsMap[locBin];
183 locMemoryMap[locBin] = locMemory;
184 locTotalMemory += locMemory;
185
186 //DKinFitChainStep
187 locBin = dBinMap["DKinFitChainStep"];
188 locNumObjectsMap[locBin] = dResourcePool_KinFitChainStep.Get_NumObjectsAllThreads();
189 locMemory = sizeof(DKinFitChainStep)*locNumObjectsMap[locBin];
190 locMemoryMap[locBin] = locMemory;
191 locTotalMemory += locMemory;
192
193 //DKinFitChain
194 locBin = dBinMap["DKinFitChain"];
195 locNumObjectsMap[locBin] = dResourcePool_KinFitChain.Get_NumObjectsAllThreads();
196 locMemory = sizeof(DKinFitChain)*locNumObjectsMap[locBin];
197 locMemoryMap[locBin] = locMemory;
198 locTotalMemory += locMemory;
199
200 //DKinFitResults
201 locBin = dBinMap["DKinFitResults"];
202 locNumObjectsMap[locBin] = dResourcePool_KinFitResults.Get_NumObjectsAllThreads();
203 locMemory = sizeof(DKinFitResults)*locNumObjectsMap[locBin];
204 locMemoryMap[locBin] = locMemory;
205 locTotalMemory += locMemory;
206
207 /******************************************************* KINFIT CONSTRAINTS *******************************************************/
208
209 //DKinFitConstraint_Mass
210 locBin = dBinMap["DKinFitConstraint_Mass"];
211 locNumObjectsMap[locBin] = dResourcePool_MassConstraint.Get_NumObjectsAllThreads();
212 locMemory = sizeof(DKinFitConstraint_Mass)*locNumObjectsMap[locBin];
213 locMemoryMap[locBin] = locMemory;
214 locTotalMemory += locMemory;
215
216 //DKinFitConstraint_P4
217 locBin = dBinMap["DKinFitConstraint_P4"];
218 locNumObjectsMap[locBin] = dResourcePool_P4Constraint.Get_NumObjectsAllThreads();
219 locMemory = sizeof(DKinFitConstraint_P4)*locNumObjectsMap[locBin];
220 locMemoryMap[locBin] = locMemory;
221 locTotalMemory += locMemory;
222
223 //DKinFitConstraint_Vertex
224 locBin = dBinMap["DKinFitConstraint_Vertex"];
225 locNumObjectsMap[locBin] = dResourcePool_VertexConstraint.Get_NumObjectsAllThreads();
226 locMemory = sizeof(DKinFitConstraint_Vertex)*locNumObjectsMap[locBin];
227 locMemoryMap[locBin] = locMemory;
228 locTotalMemory += locMemory;
229
230 //DKinFitConstraint_Spacetime
231 locBin = dBinMap["DKinFitConstraint_Spacetime"];
232 locNumObjectsMap[locBin] = dResourcePool_SpacetimeConstraint.Get_NumObjectsAllThreads();
233 locMemory = sizeof(DKinFitConstraint_Spacetime)*locNumObjectsMap[locBin];
234 locMemoryMap[locBin] = locMemory;
235 locTotalMemory += locMemory;
236
237 //Convert to MB
238 for(auto& locMemoryPair : locMemoryMap)
239 locMemoryPair.second /= (1024.0*1024.0);
240 locTotalMemory /= (1024.0*1024.0); //convert to MB
241
242 //FILL HISTOGRAMS
243 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
244 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
245 Lock_Action(); //ACQUIRE ROOT LOCK!!
246 {
247 ++dEventCounter;
248 if(dEventCounter <= dMaxNumEvents)
249 {
250 for(auto& locNumObjectsPair : locNumObjectsMap)
251 {
252 int locObjectBin = locNumObjectsPair.first;
253 dHist_NumObjects->SetBinContent(dEventCounter, locObjectBin, locNumObjectsMap[locObjectBin]);
254 dHist_Memory->SetBinContent(dEventCounter, locObjectBin, locMemoryMap[locObjectBin]);
255 }
256 dHist_TotalMemory->SetBinContent(dEventCounter, locTotalMemory);
257
258 double vm, rss;
259 Read_MemoryUsage(vm, rss);
260 dVirtualMemoryVsEventNumber->SetBinContent(dEventCounter, vm / 1024.0);
261 dResidentMemoryVsEventNumber->SetBinContent(dEventCounter, rss / 1024.0);
262 }
263 }
264 Unlock_Action(); //RELEASE ROOT LOCK!!
265
266 return true;
267}
268
269void DHistogramAction_ObjectMemory::Read_MemoryUsage(double& vm_usage, double& resident_set)
270{
271 vm_usage = 0.0;
272 resident_set = 0.0;
273
274 // 'file' stat seems to give the most reliable results
275 ifstream stat_stream("/proc/self/stat",ios_base::in);
276
277 // dummy vars for leading entries in stat that we don't care about
278 string pid, comm, state, ppid, pgrp, session, tty_nr;
279 string tpgid, flags, minflt, cminflt, majflt, cmajflt;
280 string utime, stime, cutime, cstime, priority, nice;
281 string O, itrealvalue, starttime;
282
283 // the two fields we want
284 unsigned long vsize;
285 long rss;
286
287 stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
288 >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
289 >> utime >> stime >> cutime >> cstime >> priority >> nice
290 >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
291
292 stat_stream.close();
293
294 long page_size_kb = sysconf(_SC_PAGE_SIZE_SC_PAGESIZE) / 1024; // in case x86-64 is configured to use 2MB pages
295 vm_usage = vsize / 1024.0;
296 resident_set = rss * page_size_kb;
297}
298
299void DHistogramAction_Reconstruction::Initialize(JEventLoop* locEventLoop)
300{
301 //Create any histograms/trees/etc. within a ROOT lock.
302 //This is so that when running multithreaded, only one thread is writing to the ROOT file at a time.
303
304 //When creating a reaction-independent action, only modify member variables within a ROOT lock.
305 //Objects created within a plugin (such as reaction-independent actions) can be accessed by many threads simultaneously.
306
307 string locHistName, locHistTitle;
308
309 //Check if is REST event (high-level objects only)
310 bool locIsRESTEvent = locEventLoop->GetJEvent().GetStatusBit(kSTATUS_REST);
311
312 Run_Update(locEventLoop);
313
314 vector<const DMCThrown*> locMCThrowns;
315 locEventLoop->Get(locMCThrowns);
316
317 //CREATE THE HISTOGRAMS
318 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
319 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
320 {
321 //Required: Create a folder in the ROOT output file that will contain all of the output ROOT objects (if any) for this action.
322 //If another thread has already created the folder, it just changes to it.
323 CreateAndChangeTo_ActionDirectory();
324
325 //FCAL
326 locHistName = "FCALShowerYVsX";
327 dHist_FCALShowerYVsX = GetOrCreate_Histogram<TH2I>(locHistName, ";FCAL Shower X (cm);FCAL Shower Y (cm)", dNumFCALTOFXYBins, -130.0, 130.0, dNumFCALTOFXYBins, -130.0, 130.0);
328 locHistName = "FCALShowerEnergy";
329 dHist_FCALShowerEnergy = GetOrCreate_Histogram<TH1I>(locHistName, ";FCAL Shower Energy (GeV)", dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
330
331 //CCAL
332 locHistName = "CCALShowerYVsX";
333 dHist_CCALShowerYVsX = GetOrCreate_Histogram<TH2I>(locHistName, ";CCAL Shower X (cm);CCAL Shower Y (cm)", dNumFCALTOFXYBins, -130.0, 130.0, dNumFCALTOFXYBins, -130.0, 130.0);
334 locHistName = "CCALShowerEnergy";
335 dHist_CCALShowerEnergy = GetOrCreate_Histogram<TH1I>(locHistName, ";CCAL Shower Energy (GeV)", dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
336
337 //BCAL
338 locHistName = "BCALShowerEnergy";
339 dHist_BCALShowerEnergy = GetOrCreate_Histogram<TH1I>(locHistName, ";BCAL Shower Energy (GeV)", dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
340 locHistName = "BCALShowerPhi";
341 dHist_BCALShowerPhi = GetOrCreate_Histogram<TH1I>(locHistName, ";BCAL Shower #phi#circ", dNumPhiBins, dMinPhi, dMaxPhi);
342 locHistName = "BCALShowerPhiVsZ";
343 dHist_BCALShowerPhiVsZ = GetOrCreate_Histogram<TH2I>(locHistName, ";BCAL Shower Z (cm);BCAL Shower #phi#circ", dNum2DBCALZBins, 0.0, 450.0, dNum2DPhiBins, dMinPhi, dMaxPhi);
344
345 //TOF
346 locHistName = "TOFPointEnergy";
347 dHist_TOFPointEnergy = GetOrCreate_Histogram<TH1I>(locHistName, ";TOF Point Energy (MeV)", dNumHitEnergyBins, dMinHitEnergy, dMaxHitEnergy);
348 locHistName = "TOFPointEnergyP1";
349 dHist_TOFPointEnergyP1 = GetOrCreate_Histogram<TH1I>(locHistName, ";TOF Point Energy Plane 1 (MeV)", dNumHitEnergyBins, dMinHitEnergy, dMaxHitEnergy);
350 locHistName = "TOFPointEnergyP2";
351 dHist_TOFPointEnergyP2 = GetOrCreate_Histogram<TH1I>(locHistName, ";TOF Point Energy Plane 2 (MeV)", dNumHitEnergyBins, dMinHitEnergy, dMaxHitEnergy);
352 locHistName = "TOFPointYVsX";
353 dHist_TOFPointYVsX = GetOrCreate_Histogram<TH2I>(locHistName, ";TOF Point X (cm);TOF Point Y (cm)", dNumFCALTOFXYBins, -130.0, 130.0, dNumFCALTOFXYBins, -130.0, 130.0);
354
355 //SC
356 locHistName = "SCHitSector";
357 dHist_SCHitSector = GetOrCreate_Histogram<TH1I>(locHistName, ";SC Hit Sector", 30, 0.5, 30.5);
358 locHistName = "SCHitEnergy";
359 dHist_SCHitEnergy = GetOrCreate_Histogram<TH1I>(locHistName, ";SC Hit Energy (MeV)", dNumHitEnergyBins, dMinHitEnergy, dMaxHitEnergy);
360 locHistName = "SCHitEnergyVsSector";
361 dHist_SCHitEnergyVsSector = GetOrCreate_Histogram<TH2I>(locHistName, ";SC Hit Sector;SC Hit Energy (MeV)", 30, 0.5, 30.5, dNum2DHitEnergyBins, dMinHitEnergy, dMaxHitEnergy);
362 locHistName = "SCRFDeltaTVsSector";
363 dHist_SCRFDeltaTVsSector = GetOrCreate_Histogram<TH2I>(locHistName, ";SC Hit Sector;SC - RF #Deltat (ns)", 30, 0.5, 30.5, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
364
365 //TAGH, TAGM
366 locHistName = "TAGMRFDeltaTVsColumn";
367 dHist_TAGMRFDeltaTVsColumn = GetOrCreate_Histogram<TH2I>(locHistName, ";TAGM Column;TAGM - RF #Deltat (ns)", 102, 0.5, 102.5, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
368 locHistName = "TAGHRFDeltaTVsCounter";
369 dHist_TAGHRFDeltaTVsCounter = GetOrCreate_Histogram<TH2I>(locHistName, ";TAGH Counter;TAGH - RF #Deltat (ns)", 274, 0.5, 274.5, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
370
371 //TRACKING
372 CreateAndChangeTo_Directory("Tracking", "Tracking");
373 locHistName = "NumDCHitsPerTrack";
374 dHist_NumDCHitsPerTrack = GetOrCreate_Histogram<TH1I>(locHistName, ";# Track Hits", 50, 0.5, 50.5);
375 locHistName = "NumPossDCHitsPerTrack";
376 dHist_NumPossDCHitsPerTrack = GetOrCreate_Histogram<TH1I>(locHistName, ";# Possible Track Hits", 50, 0.5, 50.5);
377 locHistName = "TrackHitFraction";
378 dHist_TrackHitFraction = GetOrCreate_Histogram<TH1I>(locHistName, ";# Track Hits/# Possible Track Hits", 50, 0.0, 1.0);
379 locHistName = "NumDCHitsPerTrackVsTheta";
380 dHist_NumDCHitsPerTrackVsTheta = GetOrCreate_Histogram<TH2I>(locHistName, ";#theta#circ;# Track Hits", dNum2DThetaBins, dMinTheta, dMaxTheta, 46, 4.5, 50.5);
381 locHistName = "NumPossDCHitsPerTrackVsTheta";
382 dHist_NumPossDCHitsPerTrackVsTheta = GetOrCreate_Histogram<TH2I>(locHistName, ";#theta#circ;# Possible Track Hits", dNum2DThetaBins, dMinTheta, dMaxTheta, 46, 4.5, 50.5);
383 locHistName = "TrackHitFractionVsTheta";
384 dHist_TrackHitFractionVsTheta = GetOrCreate_Histogram<TH2I>(locHistName, ";#theta#circ;# Track Hits/# Possible Track Hits", dNum2DThetaBins, dMinTheta, dMaxTheta, 50, 0.0, 1.0);
385 locHistName = "TrackingFOM_WireBased";
386 dHist_TrackingFOM_WireBased = GetOrCreate_Histogram<TH1I>(locHistName, ";Confidence Level", dNumFOMBins, 0.0, 1.0);
387 locHistName = "TrackingFOM";
388 dHist_TrackingFOM = GetOrCreate_Histogram<TH1I>(locHistName, ";Confidence Level", dNumFOMBins, 0.0, 1.0);
389 locHistName = "TrackingFOMVsP";
390 dHist_TrackingFOMVsP = GetOrCreate_Histogram<TH2I>(locHistName, ";p (GeV/c);Confidence Level", dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
391 locHistName = "TrackingFOMVsTheta";
392 dHist_TrackingFOMVsTheta = GetOrCreate_Histogram<TH2I>(locHistName, ";#theta#circ;Confidence Level", dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DFOMBins, 0.0, 1.0);
393 locHistName = "TrackingFOMVsNumHits";
394 dHist_TrackingFOMVsNumHits = GetOrCreate_Histogram<TH2I>(locHistName, ";# Track Hits;Confidence Level", 46, 4.5, 50.5, dNum2DFOMBins, 0.0, 1.0);
395
396 if(!locIsRESTEvent)
397 {
398 locHistName = "CDCRingVsTheta_Candidates";
399 dHist_CDCRingVsTheta_Candidates = GetOrCreate_Histogram<TH2I>(locHistName, "Hits on Track Candidates;#theta#circ;CDC Ring", dNum2DThetaBins, dMinTheta, dMaxTheta, 28, 0.5, 28.5);
400 locHistName = "CDCRingVsTheta_WireBased";
401 dHist_CDCRingVsTheta_WireBased = GetOrCreate_Histogram<TH2I>(locHistName, "Hits on Wire-Based Tracks;#theta#circ;CDC Ring", dNum2DThetaBins, dMinTheta, dMaxTheta, 28, 0.5, 28.5);
402 }
403
404 locHistName = "CDCRingVsTheta_TimeBased";
405 dHist_CDCRingVsTheta_TimeBased = GetOrCreate_Histogram<TH2I>(locHistName, "Hits on Time-Based Tracks;#theta#circ;CDC Ring", dNum2DThetaBins, dMinTheta, dMaxTheta, 28, 0.5, 28.5);
406 locHistName = "CDCRingVsTheta_TimeBased_GoodTrackFOM";
407 dHist_CDCRingVsTheta_TimeBased_GoodTrackFOM = GetOrCreate_Histogram<TH2I>(locHistName, "Hits on Good FOM Time-Based Tracks;#theta#circ;CDC Ring", dNum2DThetaBins, dMinTheta, dMaxTheta, 28, 0.5, 28.5);
408
409 if(!locIsRESTEvent)
410 {
411 locHistName = "FDCPlaneVsTheta_Candidates";
412 dHist_FDCPlaneVsTheta_Candidates = GetOrCreate_Histogram<TH2I>(locHistName, "Hits on Track Candidates;p (GeV/c);FDC Plane", dNum2DThetaBins, dMinTheta, dMaxTheta, 24, 0.5, 24.5);
413 locHistName = "FDCPlaneVsTheta_WireBased";
414 dHist_FDCPlaneVsTheta_WireBased = GetOrCreate_Histogram<TH2I>(locHistName, "Hits on Wire-Based Tracks;p (GeV/c);FDC Plane", dNum2DThetaBins, dMinTheta, dMaxTheta, 24, 0.5, 24.5);
415 }
416
417 locHistName = "FDCPlaneVsTheta_TimeBased";
418 dHist_FDCPlaneVsTheta_TimeBased = GetOrCreate_Histogram<TH2I>(locHistName, "Hits on Time-Based Tracks;p (GeV/c);FDC Plane", dNum2DThetaBins, dMinTheta, dMaxTheta, 24, 0.5, 24.5);
419 locHistName = "FDCPlaneVsTheta_TimeBased_GoodTrackFOM";
420 dHist_FDCPlaneVsTheta_TimeBased_GoodTrackFOM = GetOrCreate_Histogram<TH2I>(locHistName, "Hits on Good FOM Time-Based Tracks;p (GeV/c);FDC Plane", dNum2DThetaBins, dMinTheta, dMaxTheta, 24, 0.5, 24.5);
421
422 if(!locMCThrowns.empty())
423 {
424 locHistName = "MCMatchedHitsVsTheta";
425 dHist_MCMatchedHitsVsTheta = GetOrCreate_Histogram<TH2I>(locHistName, "Fraction of Track Hits Matched to MC;#theta#circ;", dNum2DThetaBins, dMinTheta, dMaxTheta, 100, 0.0, 1.0);
426 locHistName = "MCMatchedHitsVsP";
427 dHist_MCMatchedHitsVsP = GetOrCreate_Histogram<TH2I>(locHistName, "Fraction of Track Hits Matched to MC;p (GeV/c);", dNum2DPBins, dMinP, dMaxP, 100, 0.0, 1.0);
428 }
429
430 for(int locCharge = -1; locCharge <= 1; locCharge += 2)
431 {
432 string locParticleROOTName = (locCharge == -1) ? "#it{q}^{-}" : "#it{q}^{+}";
433 string locParticleName = (locCharge == -1) ? "q-" : "q+";
434 CreateAndChangeTo_Directory(locParticleName, locParticleName);
435
436 if(!locIsRESTEvent)
437 {
438 // PVsTheta Track Candidates
439 locHistName = string("PVsTheta_Candidates_") + locParticleName;
440 locHistTitle = locParticleROOTName + string(" Track Candidates;#theta#circ;p (GeV/c)");
441 dHistMap_PVsTheta_Candidates[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
442
443 // PVsTheta Wire-Based Tracks
444 locHistName = string("PVsTheta_WireBased_") + locParticleName;
445 locHistTitle = locParticleROOTName + string(" Wire-Based Tracks;#theta#circ;p (GeV/c)");
446 dHistMap_PVsTheta_WireBased[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
447 }
448
449 // PVsTheta Time-Based Tracks
450 locHistName = string("PVsTheta_TimeBased_") + locParticleName;
451 locHistTitle = locParticleROOTName + string(" Time-Based Tracks;#theta#circ;p (GeV/c)");
452 dHistMap_PVsTheta_TimeBased[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
453
454 // PVsTheta Time-Based Tracks Good Track FOM
455 locHistName = string("PVsTheta_TimeBased_GoodTrackFOM_") + locParticleName;
456 locHistTitle = locParticleROOTName + string(" Time-Based Tracks, Good Tracking FOM;#theta#circ;p (GeV/c)");
457 dHistMap_PVsTheta_TimeBased_GoodTrackFOM[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
458
459 // PVsTheta Time-Based Tracks Low Track FOM
460 locHistName = string("PVsTheta_TimeBased_LowTrackFOM_") + locParticleName;
461 locHistTitle = locParticleROOTName + string(" Time-Based Tracks, Low Tracking FOM;#theta#circ;p (GeV/c)");
462 dHistMap_PVsTheta_TimeBased_LowTrackFOM[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
463
464 // PVsTheta Time-Based Tracks High Track FOM
465 locHistName = string("PVsTheta_TimeBased_HighTrackFOM_") + locParticleName;
466 locHistTitle = locParticleROOTName + string(" Time-Based Tracks, High Tracking FOM;#theta#circ;p (GeV/c)");
467 dHistMap_PVsTheta_TimeBased_HighTrackFOM[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
468
469 if(!locIsRESTEvent)
470 {
471 // PVsTheta: Good Wire-Based, Good Time-Based
472 locHistName = string("PVsTheta_GoodWireBased_GoodTimeBased_") + locParticleName;
473 locHistTitle = locParticleROOTName + string(" Good Wire-Based, Good Time-Based;#theta#circ;p (GeV/c)");
474 dHistMap_PVsTheta_GoodWireBased_GoodTimeBased[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
475
476 // PVsTheta: Good Wire-Based, Bad Time-Based
477 locHistName = string("PVsTheta_GoodWireBased_BadTimeBased_") + locParticleName;
478 locHistTitle = locParticleROOTName + string(" Good Wire-Based, Bad Time-Based;#theta#circ;p (GeV/c)");
479 dHistMap_PVsTheta_GoodWireBased_BadTimeBased[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
480 }
481
482 gDirectory(TDirectory::CurrentDirectory())->cd(".."); //end of charge
483 }
484 gDirectory(TDirectory::CurrentDirectory())->cd(".."); //End of "Tracking"
485
486 //Return to the base directory
487 ChangeTo_BaseDirectory();
488 }
489 japp->RootUnLock(); //RELEASE ROOT LOCK!!
490}
491
492void DHistogramAction_Reconstruction::Run_Update(JEventLoop* locEventLoop)
493{
494 DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
495 DGeometry* locGeometry = locApplication->GetDGeometry(locEventLoop->GetJEvent().GetRunNumber());
496 double locTargetZCenter = 0.0;
497 locGeometry->GetTargetZ(locTargetZCenter);
498
499 if(dTargetCenter.Z() < -9.8E9)
500 dTargetCenter.SetXYZ(0.0, 0.0, locTargetZCenter);
501}
502
503bool DHistogramAction_Reconstruction::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
504{
505 //Expect locParticleCombo to be NULL since this is a reaction-independent action.
506
507 if(Get_CalledPriorWithComboFlag())
508 return true; //else double-counting!
509
510 bool locIsRESTEvent = locEventLoop->GetJEvent().GetStatusBit(kSTATUS_REST);
511
512 vector<const DBCALShower*> locBCALShowers;
513 locEventLoop->Get(locBCALShowers);
514
515 vector<const DFCALShower*> locFCALShowers;
516 locEventLoop->Get(locFCALShowers);
517
518 vector<const DCCALShower*> locCCALShowers;
519 locEventLoop->Get(locCCALShowers);
520
521 vector<const DTOFPoint*> locTOFPoints;
522 locEventLoop->Get(locTOFPoints);
523
524 vector<const DSCHit*> locSCHits;
525 locEventLoop->Get(locSCHits);
526
527 vector<const DBeamPhoton*> locBeamPhotons;
528 locEventLoop->Get(locBeamPhotons);
529
530 const DDetectorMatches* locDetectorMatches = NULL__null;
531 locEventLoop->GetSingle(locDetectorMatches);
532
533 vector<const DTrackTimeBased*> locTrackTimeBasedVector;
534 locEventLoop->Get(locTrackTimeBasedVector);
535
536 vector<const DMCThrownMatching*> locMCThrownMatchingVector;
537 locEventLoop->Get(locMCThrownMatchingVector);
538
539 vector<const DMCThrown*> locMCThrowns;
540 locEventLoop->Get(locMCThrowns, "FinalState");
541
542 const DParticleID* locParticleID = NULL__null;
543 locEventLoop->GetSingle(locParticleID);
544
545 const DEventRFBunch* locEventRFBunch = NULL__null;
546 locEventLoop->GetSingle(locEventRFBunch);
547
548 const DDetectorMatches* locDetectorMatches_WireBased = NULL__null;
549 vector<const DTrackCandidate*> locTrackCandidates;
550 vector<const DTrackWireBased*> locTrackWireBasedVector;
551 if(!locIsRESTEvent)
552 {
553 vector<const DDetectorMatches*> locDetectorMatchesVector_WireBased;
554 locEventLoop->Get(locDetectorMatchesVector_WireBased, "WireBased");
555 if(!locDetectorMatchesVector_WireBased.empty())
556 locDetectorMatches_WireBased = locDetectorMatchesVector_WireBased[0];
557 locEventLoop->Get(locTrackCandidates);
558 locEventLoop->Get(locTrackWireBasedVector);
559 }
560
561 //select the best DTrackWireBased for each track: use best tracking FOM
562 map<JObject::oid_t, const DTrackWireBased*> locBestTrackWireBasedMap; //lowest tracking FOM for each candidate id
563 for(size_t loc_i = 0; loc_i < locTrackWireBasedVector.size(); ++loc_i)
564 {
565 JObject::oid_t locCandidateID = locTrackWireBasedVector[loc_i]->candidateid;
566 if(locBestTrackWireBasedMap.find(locCandidateID) == locBestTrackWireBasedMap.end())
567 locBestTrackWireBasedMap[locCandidateID] = locTrackWireBasedVector[loc_i];
568 else if(locTrackWireBasedVector[loc_i]->FOM > locBestTrackWireBasedMap[locCandidateID]->FOM)
569 locBestTrackWireBasedMap[locCandidateID] = locTrackWireBasedVector[loc_i];
570 }
571
572 //select the best DTrackTimeBased for each track: use best tracking FOM
573 //also, make map from WBT -> TBT (if not rest)
574 //also, select best sc matches for each track
575 map<JObject::oid_t, const DTrackTimeBased*> locBestTrackTimeBasedMap; //lowest tracking FOM for each candidate id
576 map<const DTrackWireBased*, const DTrackTimeBased*> locWireToTimeBasedTrackMap;
577 map<const DTrackTimeBased*, shared_ptr<const DSCHitMatchParams>> locTimeBasedToBestSCMatchMap;
578 for(size_t loc_i = 0; loc_i < locTrackTimeBasedVector.size(); ++loc_i)
579 {
580 //Best SC Match Params
581 shared_ptr<const DSCHitMatchParams> locSCHitMatchParams;
582 if(locParticleID->Get_BestSCMatchParams(locTrackTimeBasedVector[loc_i], locDetectorMatches, locSCHitMatchParams))
583 locTimeBasedToBestSCMatchMap[locTrackTimeBasedVector[loc_i]] = locSCHitMatchParams;
584
585 JObject::oid_t locCandidateID = locTrackTimeBasedVector[loc_i]->candidateid;
586 if(locBestTrackTimeBasedMap.find(locCandidateID) == locBestTrackTimeBasedMap.end())
587 locBestTrackTimeBasedMap[locCandidateID] = locTrackTimeBasedVector[loc_i];
588 else if(locTrackTimeBasedVector[loc_i]->FOM > locBestTrackTimeBasedMap[locCandidateID]->FOM)
589 locBestTrackTimeBasedMap[locCandidateID] = locTrackTimeBasedVector[loc_i];
590 if(locIsRESTEvent)
591 continue;
592 const DTrackWireBased* locTrackWireBased = NULL__null;
593 locTrackTimeBasedVector[loc_i]->GetSingle(locTrackWireBased);
594 locWireToTimeBasedTrackMap[locTrackWireBased] = locTrackTimeBasedVector[loc_i];
595 }
596
597 //FILL HISTOGRAMS
598 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
599 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
600 Lock_Action(); //ACQUIRE ROOT LOCK!!
601 {
602 //FCAL
603 for(size_t loc_i = 0; loc_i < locFCALShowers.size(); ++loc_i)
604 {
605 dHist_FCALShowerEnergy->Fill(locFCALShowers[loc_i]->getEnergy());
606 dHist_FCALShowerYVsX->Fill(locFCALShowers[loc_i]->getPosition().X(), locFCALShowers[loc_i]->getPosition().Y());
607 }
608
609 //CCAL
610 for(size_t loc_i = 0; loc_i < locCCALShowers.size(); ++loc_i)
611 {
612 dHist_CCALShowerEnergy->Fill(locCCALShowers[loc_i]->E);
613 dHist_CCALShowerYVsX->Fill(locCCALShowers[loc_i]->x, locCCALShowers[loc_i]->y);
614 }
615
616 //BCAL
617 for(size_t loc_i = 0; loc_i < locBCALShowers.size(); ++loc_i)
618 {
619 dHist_BCALShowerEnergy->Fill(locBCALShowers[loc_i]->E);
620
621 DVector3 locBCALPosition(locBCALShowers[loc_i]->x, locBCALShowers[loc_i]->y, locBCALShowers[loc_i]->z);
622 double locBCALPhi = locBCALPosition.Phi()*180.0/TMath::Pi();
623 dHist_BCALShowerPhi->Fill(locBCALPhi);
624 dHist_BCALShowerPhiVsZ->Fill(locBCALPosition.Z(), locBCALPhi);
625 }
626
627 //TOF
628 for(size_t loc_i = 0; loc_i < locTOFPoints.size(); ++loc_i)
629 {
630 dHist_TOFPointEnergy->Fill(locTOFPoints[loc_i]->dE*1.0E3);
631 dHist_TOFPointEnergyP1->Fill(locTOFPoints[loc_i]->dE1*1.0E3);
632 dHist_TOFPointEnergyP2->Fill(locTOFPoints[loc_i]->dE2*1.0E3);
633 dHist_TOFPointYVsX->Fill(locTOFPoints[loc_i]->pos.X(), locTOFPoints[loc_i]->pos.Y());
634 }
635
636 //SC
637 for(size_t loc_i = 0; loc_i < locSCHits.size(); ++loc_i)
638 {
639 dHist_SCHitSector->Fill(locSCHits[loc_i]->sector);
640 dHist_SCHitEnergy->Fill(locSCHits[loc_i]->dE*1.0E3);
641 dHist_SCHitEnergyVsSector->Fill(locSCHits[loc_i]->sector, locSCHits[loc_i]->dE*1.0E3);
642 }
643
644 //TAGM, TAGH
645 for(size_t loc_i = 0; loc_i < locBeamPhotons.size(); ++loc_i)
646 {
647 double locDeltaT = locBeamPhotons[loc_i]->time() - locEventRFBunch->dTime;
648 if(locBeamPhotons[loc_i]->dSystem == SYS_TAGM)
649 dHist_TAGMRFDeltaTVsColumn->Fill(locBeamPhotons[loc_i]->dCounter, locDeltaT);
650 else
651 dHist_TAGHRFDeltaTVsCounter->Fill(locBeamPhotons[loc_i]->dCounter, locDeltaT);
652 }
653
654 //TRACK CANDIDATES
655 for(size_t loc_i = 0; loc_i < locTrackCandidates.size(); ++loc_i)
656 {
657 int locCharge = (locTrackCandidates[loc_i]->charge() > 0.0) ? 1 : -1;
658 double locTheta = locTrackCandidates[loc_i]->momentum().Theta()*180.0/TMath::Pi();
659 double locP = locTrackCandidates[loc_i]->momentum().Mag();
660 dHistMap_PVsTheta_Candidates[locCharge]->Fill(locTheta, locP);
661
662 set<int> locCDCRings;
663 locParticleID->Get_CDCRings(locTrackCandidates[loc_i]->dCDCRings, locCDCRings);
664 for(set<int>::iterator locIterator = locCDCRings.begin(); locIterator != locCDCRings.end(); ++locIterator)
665 dHist_CDCRingVsTheta_Candidates->Fill(locTheta, *locIterator);
666
667 set<int> locFDCPlanes;
668 locParticleID->Get_FDCPlanes(locTrackCandidates[loc_i]->dFDCPlanes, locFDCPlanes);
669 for(set<int>::iterator locIterator = locFDCPlanes.begin(); locIterator != locFDCPlanes.end(); ++locIterator)
670 dHist_FDCPlaneVsTheta_Candidates->Fill(locTheta, *locIterator);
671 }
672
673 //WIRE-BASED TRACKS
674 map<JObject::oid_t, const DTrackWireBased*>::iterator locWireBasedIterator = locBestTrackWireBasedMap.begin();
675 for(; locWireBasedIterator != locBestTrackWireBasedMap.end(); ++locWireBasedIterator)
676 {
677 const DTrackWireBased* locTrackWireBased = locWireBasedIterator->second;
678 int locCharge = (locTrackWireBased->charge() > 0.0) ? 1 : -1;
679 double locTheta = locTrackWireBased->momentum().Theta()*180.0/TMath::Pi();
680 double locP = locTrackWireBased->momentum().Mag();
681 dHistMap_PVsTheta_WireBased[locCharge]->Fill(locTheta, locP);
682
683 set<int> locCDCRings;
684 locParticleID->Get_CDCRings(locTrackWireBased->dCDCRings, locCDCRings);
685 for(set<int>::iterator locIterator = locCDCRings.begin(); locIterator != locCDCRings.end(); ++locIterator)
686 dHist_CDCRingVsTheta_WireBased->Fill(locTheta, *locIterator);
687
688 set<int> locFDCPlanes;
689 locParticleID->Get_FDCPlanes(locTrackWireBased->dFDCPlanes, locFDCPlanes);
690 for(set<int>::iterator locIterator = locFDCPlanes.begin(); locIterator != locFDCPlanes.end(); ++locIterator)
691 dHist_FDCPlaneVsTheta_WireBased->Fill(locTheta, *locIterator);
692
693 dHist_TrackingFOM_WireBased->Fill(locTrackWireBased->FOM);
694 }
695
696 //TIME-BASED TRACKS
697 map<JObject::oid_t, const DTrackTimeBased*>::iterator locTimeBasedIterator = locBestTrackTimeBasedMap.begin();
698 for(; locTimeBasedIterator != locBestTrackTimeBasedMap.end(); ++locTimeBasedIterator)
699 {
700 const DTrackTimeBased* locTrackTimeBased = locTimeBasedIterator->second;
701 int locCharge = (locTrackTimeBased->charge() > 0.0) ? 1 : -1;
702 double locTheta = locTrackTimeBased->momentum().Theta()*180.0/TMath::Pi();
703 double locP = locTrackTimeBased->momentum().Mag();
704 int locPossibleHits = locTrackTimeBased->potential_cdc_hits_on_track + locTrackTimeBased->potential_fdc_hits_on_track;
705 double locTrackHitFraction = (locTrackTimeBased->Ndof + 5)/(double)locPossibleHits;
706
707 dHistMap_PVsTheta_TimeBased[locCharge]->Fill(locTheta, locP);
708 dHist_NumDCHitsPerTrack->Fill(locTrackTimeBased->Ndof + 5);
709 dHist_NumPossDCHitsPerTrack->Fill(locPossibleHits);
710 dHist_TrackHitFraction->Fill(locTrackHitFraction);
711 dHist_NumDCHitsPerTrackVsTheta->Fill(locTheta, locTrackTimeBased->Ndof + 5);
712 dHist_NumPossDCHitsPerTrackVsTheta->Fill(locTheta, locPossibleHits);
713 dHist_TrackHitFractionVsTheta->Fill(locTheta, locTrackHitFraction);
714
715 dHist_TrackingFOM->Fill(locTrackTimeBased->FOM);
716 dHist_TrackingFOMVsTheta->Fill(locTheta, locTrackTimeBased->FOM);
717 dHist_TrackingFOMVsP->Fill(locP, locTrackTimeBased->FOM);
718 dHist_TrackingFOMVsNumHits->Fill(locTrackTimeBased->Ndof + 5, locTrackTimeBased->FOM);
719
720 //CDC
721 set<int> locCDCRings;
722 locParticleID->Get_CDCRings(locTrackTimeBased->dCDCRings, locCDCRings);
723 for(set<int>::iterator locIterator = locCDCRings.begin(); locIterator != locCDCRings.end(); ++locIterator)
724 {
725 dHist_CDCRingVsTheta_TimeBased->Fill(locTheta, *locIterator);
726 if(locTrackTimeBased->FOM > dGoodTrackFOM)
727 dHist_CDCRingVsTheta_TimeBased_GoodTrackFOM->Fill(locTheta, *locIterator);
728 }
729
730 //FDC
731 set<int> locFDCPlanes;
732 locParticleID->Get_FDCPlanes(locTrackTimeBased->dFDCPlanes, locFDCPlanes);
733 for(set<int>::iterator locIterator = locFDCPlanes.begin(); locIterator != locFDCPlanes.end(); ++locIterator)
734 {
735 dHist_FDCPlaneVsTheta_TimeBased->Fill(locTheta, *locIterator);
736 if(locTrackTimeBased->FOM > dGoodTrackFOM)
737 dHist_FDCPlaneVsTheta_TimeBased_GoodTrackFOM->Fill(locTheta, *locIterator);
738 }
739
740 //FOM
741 if(locTrackTimeBased->FOM > dGoodTrackFOM)
742 dHistMap_PVsTheta_TimeBased_GoodTrackFOM[locCharge]->Fill(locTheta, locP);
743 else
744 dHistMap_PVsTheta_TimeBased_LowTrackFOM[locCharge]->Fill(locTheta, locP);
745 if(locTrackTimeBased->FOM > dHighTrackFOM)
746 dHistMap_PVsTheta_TimeBased_HighTrackFOM[locCharge]->Fill(locTheta, locP);
747
748 //SC/RF DELTA-T
749 auto locSCIterator = locTimeBasedToBestSCMatchMap.find(locTrackTimeBased);
750 if(locSCIterator != locTimeBasedToBestSCMatchMap.end())
751 {
752 auto& locSCHitMatchParams = locSCIterator->second;
753 double locPropagatedSCTime = locSCHitMatchParams->dHitTime - locSCHitMatchParams->dFlightTime + (dTargetCenter.Z() - locTrackTimeBased->z())/29.9792458;
754 double locDeltaT = locPropagatedSCTime - locEventRFBunch->dTime;
755 dHist_SCRFDeltaTVsSector->Fill(locSCHitMatchParams->dSCHit->sector, locDeltaT);
756 }
757 }
758
759 // If "Good" WBT, see if TBT is good
760 locWireBasedIterator = locBestTrackWireBasedMap.begin();
761 for(; locWireBasedIterator != locBestTrackWireBasedMap.end(); ++locWireBasedIterator)
762 {
763 if(locDetectorMatches_WireBased == NULL__null)
764 continue;
765 const DTrackWireBased* locTrackWireBased = locWireBasedIterator->second;
766 if(locTrackWireBased->FOM < dGoodTrackFOM)
767 continue; //no good
768 if(!locDetectorMatches_WireBased->Get_IsMatchedToHit(locTrackWireBased))
769 continue; //no good
770
771 int locCharge = (locTrackWireBased->charge() > 0.0) ? 1 : -1;
772 double locTheta = locTrackWireBased->momentum().Theta()*180.0/TMath::Pi();
773 double locP = locTrackWireBased->momentum().Mag();
774
775 map<const DTrackWireBased*, const DTrackTimeBased*>::iterator locReconIterator = locWireToTimeBasedTrackMap.find(locTrackWireBased);
776 if(locReconIterator == locWireToTimeBasedTrackMap.end())
777 {
778 dHistMap_PVsTheta_GoodWireBased_BadTimeBased[locCharge]->Fill(locTheta, locP);
779 continue; //no time-based
780 }
781
782 const DTrackTimeBased* locTrackTimeBased = locReconIterator->second;
783 if((locTrackTimeBased->FOM < dGoodTrackFOM) || (!locDetectorMatches->Get_IsMatchedToHit(locTrackTimeBased)))
784 dHistMap_PVsTheta_GoodWireBased_BadTimeBased[locCharge]->Fill(locTheta, locP);
785 else
786 dHistMap_PVsTheta_GoodWireBased_GoodTimeBased[locCharge]->Fill(locTheta, locP);
787 }
788
789 //THROWN
790 for(size_t loc_i = 0; loc_i < locMCThrowns.size(); ++loc_i)
791 {
792 if(fabs(locMCThrowns[loc_i]->charge()) < 0.9)
793 continue;
794
795 double locMatchFOM;
796 const DChargedTrackHypothesis* locChargedTrackHypothesis = locMCThrownMatchingVector[0]->Get_MatchingChargedHypothesis(locMCThrowns[loc_i], locMatchFOM);
797 if(locChargedTrackHypothesis == NULL__null)
798 continue;
799
800 auto locTrackTimeBased = locChargedTrackHypothesis->Get_TrackTimeBased();
801 double locHitFraction = 1.0*locTrackTimeBased->dNumHitsMatchedToThrown/(locTrackTimeBased->Ndof + 5);
802 dHist_MCMatchedHitsVsTheta->Fill(locTrackTimeBased->momentum().Theta()*180.0/TMath::Pi(), locHitFraction);
803 dHist_MCMatchedHitsVsP->Fill(locTrackTimeBased->momentum().Mag(), locHitFraction);
804 }
805 }
806 Unlock_Action(); //RELEASE ROOT LOCK!!
807
808 return true; //return false if you want to use this action to apply a cut (and it fails the cut!)
809}
810
811void DHistogramAction_DetectorMatching::Initialize(JEventLoop* locEventLoop)
812{
813 //Create any histograms/trees/etc. within a ROOT lock.
814 //This is so that when running multithreaded, only one thread is writing to the ROOT file at a time.
815
816 //When creating a reaction-independent action, only modify member variables within a ROOT lock.
817 //Objects created within a plugin (such as reaction-independent actions) can be accessed by many threads simultaneously.
818 string locHistName, locHistTitle;
819
820 bool locIsRESTEvent = locEventLoop->GetJEvent().GetStatusBit(kSTATUS_REST);
821
822 Run_Update(locEventLoop);
823
824 //CREATE THE HISTOGRAMS
825 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
826 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
827 {
828
829 //Required: Create a folder in the ROOT output file that will contain all of the output ROOT objects (if any) for this action.
830 //If another thread has already created the folder, it just changes to it.
831 CreateAndChangeTo_ActionDirectory();
832
833 //Loop over filling for time-based and wire-based tracks
834 for(unsigned int locDummy = 0; locDummy < 2; ++locDummy)
835 {
836 bool locIsTimeBased = (locDummy == 0);
837 if(locIsRESTEvent && (!locIsTimeBased))
838 continue;
839
840 string locDirectoryName = locIsTimeBased ? "TimeBased" : "WireBased";
841 CreateAndChangeTo_Directory(locDirectoryName.c_str(), locDirectoryName.c_str());
842 string locTrackString = locIsTimeBased ? "Time-Based Tracks" : "Wire-Based Tracks";
843
844 //Kinematics of has (no) hit
845 vector<DetectorSystem_t> locDetectorSystems;
846 locDetectorSystems.push_back(SYS_START); locDetectorSystems.push_back(SYS_BCAL);
847 locDetectorSystems.push_back(SYS_TOF); locDetectorSystems.push_back(SYS_FCAL);
848 //locDetectorSystems.push_back(SYS_CCAL);
849 for(size_t loc_i = 0; loc_i < locDetectorSystems.size(); ++loc_i)
850 {
851 DetectorSystem_t locSystem = locDetectorSystems[loc_i];
852
853 double locMaxTheta = ((locSystem == SYS_FCAL) || (locSystem == SYS_TOF) /*|| (locSystem == SYS_CCAL)*/) ? 12.0 : dMaxTheta;
854 double locMaxP = (locSystem == SYS_BCAL) ? 3.0 : dMaxP;
855
856 string locSystemName = SystemName(locSystem);
857 if(locSystemName == "ST")
858 locSystemName = "SC";
859 string locDirName = locSystemName;
860 if(locSystemName == "TOF")
861 locDirName = "TOFPoint";
862
863 CreateAndChangeTo_Directory(locDirName, locDirName);
864
865 // PVsTheta Has Hit
866 locHistName = "PVsTheta_HasHit";
867 locHistTitle = locTrackString + string(", Has Other Match, ") + locSystemName + string(" Has Hit;#theta#circ;p (GeV/c)");
868 dHistMap_PVsTheta_HasHit[locSystem][locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, locMaxTheta, dNum2DPBins, dMinP, locMaxP);
869
870 // PVsTheta Has No Hit
871 locHistName = "PVsTheta_NoHit";
872 locHistTitle = locTrackString + string(", Has Other Match, ") + locSystemName + string(" No Hit;#theta#circ;p (GeV/c)");
873 dHistMap_PVsTheta_NoHit[locSystem][locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, locMaxTheta, dNum2DPBins, dMinP, locMaxP);
874
875 // PhiVsTheta Has Hit
876 locHistName = "PhiVsTheta_HasHit";
877 locHistTitle = locTrackString + string(", Has Other Match, ") + locSystemName + string(" Has Hit;#theta#circ;#phi#circ");
878 dHistMap_PhiVsTheta_HasHit[locSystem][locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, locMaxTheta, dNum2DPhiBins, dMinPhi, dMaxPhi);
879
880 // PhiVsTheta Has No Hit
881 locHistName = "PhiVsTheta_NoHit";
882 locHistTitle = locTrackString + string(", Has Other Match, ") + locSystemName + string(" No Hit;#theta#circ;#phi#circ");
883 dHistMap_PhiVsTheta_NoHit[locSystem][locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, locMaxTheta, dNum2DPhiBins, dMinPhi, dMaxPhi);
884
885 gDirectory(TDirectory::CurrentDirectory())->cd("..");
886 }
887
888 //SC
889 CreateAndChangeTo_Directory("SC", "SC");
890 locHistName = "SCPaddleVsTheta_HasHit";
891 locHistTitle = locTrackString + string(", Has Other Match, SC Has Hit;#theta#circ;Projected SC Paddle");
892 dHistMap_SCPaddleVsTheta_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, 30, 0.5, 30.5);
893
894 locHistName = "SCPaddleVsTheta_NoHit";
895 locHistTitle = locTrackString + string(", Has Other Match, SC No Hit;#theta#circ;Projected SC Paddle");
896 dHistMap_SCPaddleVsTheta_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, 30, 0.5, 30.5);
897
898 locHistName = "SCPaddleVsZ_HasHit";
899 locHistTitle = locTrackString + string(", Has Other Match, SC Has Hit;Projected SC Hit-Z (cm);Projected SC Paddle");
900 dHistMap_SCPaddleVsZ_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DSCZBins, 0.0, 120.0, 30, 0.5, 30.5);
901
902 locHistName = "SCPaddleVsZ_NoHit";
903 locHistTitle = locTrackString + string(", Has Other Match, SC No Hit;Projected SC Hit-Z (cm);Projected SC Paddle");
904 dHistMap_SCPaddleVsZ_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DSCZBins, 0.0, 120.0, 30, 0.5, 30.5);
905
906 locHistName = "SCPaddle_BarrelRegion_HasHit";
907 locHistTitle = locTrackString + string(", Has Other Match, SC Barrel Region Has Hit;Projected SC Paddle");
908 dHistMap_SCPaddle_BarrelRegion_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, 30, 0.5, 30.5);
909
910 locHistName = "SCPaddle_BarrelRegion_NoHit";
911 locHistTitle = locTrackString + string(", Has Other Match, SC Barrel Region No Hit;Projected SC Paddle");
912 dHistMap_SCPaddle_BarrelRegion_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, 30, 0.5, 30.5);
913
914 locHistName = "SCPaddle_NoseRegion_HasHit";
915 locHistTitle = locTrackString + string(", Has Other Match, SC Front Region Has Hit;Projected SC Paddle");
916 dHistMap_SCPaddle_NoseRegion_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, 30, 0.5, 30.5);
917
918 locHistName = "SCPaddle_NoseRegion_NoHit";
919 locHistTitle = locTrackString + string(", Has Other Match, SC Front Region No Hit;Projected SC Paddle");
920 dHistMap_SCPaddle_NoseRegion_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, 30, 0.5, 30.5);
921
922 locHistName = "SCTrackDeltaPhiVsP";
923 locHistTitle = locTrackString + string(";p (GeV/c);SC / Track #Delta#phi#circ");
924 dHistMap_SCTrackDeltaPhiVsP[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaPhiBins, dSCMatchMinDeltaPhi, dSCMatchMaxDeltaPhi);
925
926 locHistName = "SCTrackDeltaPhiVsTheta";
927 locHistTitle = locTrackString + string(";#theta#circ;SC / Track #Delta#phi#circ");
928 dHistMap_SCTrackDeltaPhiVsTheta[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DDeltaPhiBins, dSCMatchMinDeltaPhi, dSCMatchMaxDeltaPhi);
929
930 locHistName = "SCTrackDeltaPhiVsZ";
931 locHistTitle = locTrackString + string(";Projected SC Hit-Z (cm);SC / Track #Delta#phi#circ");
932 dHistMap_SCTrackDeltaPhiVsZ[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DSCZBins, 0.0, 120.0, dNum2DDeltaPhiBins, dSCMatchMinDeltaPhi, dSCMatchMaxDeltaPhi);
933 gDirectory(TDirectory::CurrentDirectory())->cd("..");
934
935 //TOFPaddle
936 CreateAndChangeTo_Directory("TOFPaddle", "TOFPaddle");
937 locHistName = "VerticalPaddleTrackDeltaX";
938 locHistTitle = locTrackString + string(";Vertical TOF Paddle / Track |#DeltaX| (cm)");
939 dHistMap_TOFPaddleTrackDeltaX[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTrackDOCABins/2, 0.0, dMaxTrackMatchDOCA);
940
941 locHistName = "HorizontalPaddleTrackDeltaY";
942 locHistTitle = locTrackString + string(";Horizontal TOF Paddle / Track |#DeltaY| (cm)");
943 dHistMap_TOFPaddleTrackDeltaY[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTrackDOCABins/2, 0.0, dMaxTrackMatchDOCA);
944
945 locHistName = "TrackYVsVerticalPaddle_HasHit";
946 locHistTitle = locTrackString + string(", Has Other Match, TOF Paddle Has Hit;Projected Vertical Paddle;Projected TOF Hit Y (cm)");
947 dHistMap_TOFPaddleTrackYVsVerticalPaddle_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 46, 0.5, 46.5, dNumFCALTOFXYBins, -130.0, 130.0);
948
949 locHistName = "TrackYVsVerticalPaddle_NoHit";
950 locHistTitle = locTrackString + string(", Has Other Match, TOF Paddle No Hit;Projected Vertical Paddle;Projected TOF Hit Y (cm)");
951 dHistMap_TOFPaddleTrackYVsVerticalPaddle_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 46, 0.5, 46.5, dNumFCALTOFXYBins, -130.0, 130.0);
952
953 locHistName = "HorizontalPaddleVsTrackX_HasHit";
954 locHistTitle = locTrackString + string(", Has Other Match, TOF Paddle Has Hit;Projected TOF Hit X (cm);Projected Horizontal Paddle");
955 dHistMap_TOFPaddleHorizontalPaddleVsTrackX_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumFCALTOFXYBins, -130.0, 130.0, 46, 0.5, 46.5);
956
957 locHistName = "HorizontalPaddleVsTrackX_NoHit";
958 locHistTitle = locTrackString + string(", Has Other Match, TOF Paddle No Hit;Projected TOF Hit X (cm);Projected Horizontal Paddle");
959 dHistMap_TOFPaddleHorizontalPaddleVsTrackX_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumFCALTOFXYBins, -130.0, 130.0, 46, 0.5, 46.5);
960 gDirectory(TDirectory::CurrentDirectory())->cd("..");
961
962 //TOFPoint
963 CreateAndChangeTo_Directory("TOFPoint", "TOFPoint");
964 locHistName = "TrackTOFYVsX_HasHit";
965 locHistTitle = locTrackString + string(", Has Other Match, TOF Has Hit;Projected TOF Hit X (cm);Projected TOF Hit Y (cm)");
966 dHistMap_TrackTOFYVsX_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumFCALTOFXYBins, -130.0, 130.0, dNumFCALTOFXYBins, -130.0, 130.0);
967
968 locHistName = "TrackTOFYVsX_NoHit";
969 locHistTitle = locTrackString + string(", Has Other Match, TOF No Hit;Projected TOF Hit X (cm);Projected TOF Hit Y (cm)");
970 dHistMap_TrackTOFYVsX_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumFCALTOFXYBins, -130.0, 130.0, dNumFCALTOFXYBins, -130.0, 130.0);
971
972 locHistName = "TrackTOF2DPaddles_HasHit";
973 locHistTitle = locTrackString + string(", Has Other Match, TOF Has Hit;Projected Vertical TOF Paddle;Projected Horizontal TOF Paddle");
974 dHistMap_TrackTOF2DPaddles_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 46, 0.5, 46.5, 46, 0.5, 46.5);
975
976 locHistName = "TrackTOF2DPaddles_NoHit";
977 locHistTitle = locTrackString + string(", Has Other Match, TOF No Hit;Projected Vertical TOF Paddle;Projected Horizontal TOF Paddle");
978 dHistMap_TrackTOF2DPaddles_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 46, 0.5, 46.5, 46, 0.5, 46.5);
979
980 locHistName = "TrackTOFP_HasHit";
981 locHistTitle = locTrackString + string(", Has Other Match, TOF Has Hit;p (GeV/c)");
982 dHistMap_TrackTOFP_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPBins, dMinP, dMaxP);
983
984 locHistName = "TrackTOFP_NoHit";
985 locHistTitle = locTrackString + string(", Has Other Match, TOF No Hit;p (GeV/c)");
986 dHistMap_TrackTOFP_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPBins, dMinP, dMaxP);
987
988 locHistName = "TrackTOFR_HasHit";
989 locHistTitle = locTrackString + string(", Has Other Match, TOF Has Hit;Projected TOF Hit R (cm)");
990 dHistMap_TrackTOFR_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTOFRBins, 0.0, 180);
991
992 locHistName = "TrackTOFR_NoHit";
993 locHistTitle = locTrackString + string(", Has Other Match, TOF No Hit;Projected TOF Hit R (cm)");
994 dHistMap_TrackTOFR_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTOFRBins, 0.0, 180);
995
996 locHistName = "TOFTrackDistanceVsP";
997 locHistTitle = locTrackString + string(";p (GeV/c);TOF / Track Distance (cm)");
998 dHistMap_TOFPointTrackDistanceVsP[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DTrackDOCABins, dMinTrackDOCA, dMaxTrackMatchDOCA);
999
1000 locHistName = "TOFTrackDistanceVsTheta";
1001 locHistTitle = locTrackString + string(";#theta#circ;TOF / Track Distance (cm)");
1002 dHistMap_TOFPointTrackDistanceVsTheta[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, 20.0, dNum2DTrackDOCABins, dMinTrackDOCA, dMaxTrackMatchDOCA);
1003
1004 locHistName = "TOFTrackDeltaXVsHorizontalPaddle";
1005 locHistTitle = locTrackString + string(";TOF Horizontal Paddle;TOF / Track #DeltaX (cm)");
1006 dHistMap_TOFPointTrackDeltaXVsHorizontalPaddle[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 46, 0.5, 46.5, dNum2DTrackDOCABins, -1.0*dMaxTrackMatchDOCA, dMaxTrackMatchDOCA);
1007
1008 locHistName = "TOFTrackDeltaXVsVerticalPaddle";
1009 locHistTitle = locTrackString + string(";TOF Vertical Paddle;TOF / Track #DeltaX (cm)");
1010 dHistMap_TOFPointTrackDeltaXVsVerticalPaddle[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 46, 0.5, 46.5, dNum2DTrackDOCABins, -1.0*dMaxTrackMatchDOCA, dMaxTrackMatchDOCA);
1011
1012 locHistName = "TOFTrackDeltaYVsHorizontalPaddle";
1013 locHistTitle = locTrackString + string(";TOF Horizontal Paddle;TOF / Track #DeltaY (cm)");
1014 dHistMap_TOFPointTrackDeltaYVsHorizontalPaddle[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 46, 0.5, 46.5, dNum2DTrackDOCABins, -1.0*dMaxTrackMatchDOCA, dMaxTrackMatchDOCA);
1015
1016 locHistName = "TOFTrackDeltaYVsVerticalPaddle";
1017 locHistTitle = locTrackString + string(";TOF Vertical Paddle;TOF / Track #DeltaY (cm)");
1018 dHistMap_TOFPointTrackDeltaYVsVerticalPaddle[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 46, 0.5, 46.5, dNum2DTrackDOCABins, -1.0*dMaxTrackMatchDOCA, dMaxTrackMatchDOCA);
1019
1020 locHistName = "TOFTrackDistance_BothPlanes";
1021 locHistTitle = locTrackString + string("TOF Hit in Both Planes;TOF / Track Distance (cm)");
1022 dHistMap_TOFPointTrackDistance_BothPlanes[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTrackDOCABins, dMinTrackDOCA, dMaxTrackMatchDOCA);
1023
1024 locHistName = "TOFTrackDistance_OnePlane";
1025 locHistTitle = locTrackString + string("TOF Hit in One Plane;TOF / Track Distance (cm)");
1026 dHistMap_TOFPointTrackDistance_OnePlane[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTrackDOCABins, dMinTrackDOCA, dMaxTrackMatchDOCA);
1027 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1028
1029 //FCAL
1030 CreateAndChangeTo_Directory("FCAL", "FCAL");
1031 locHistName = "TrackFCALYVsX_HasHit";
1032 locHistTitle = locTrackString + string(", Has Other Match, FCAL Has Hit;Projected FCAL Hit X (cm);Projected FCAL Hit Y (cm)");
1033 dHistMap_TrackFCALYVsX_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumFCALTOFXYBins, -130.0, 130.0, dNumFCALTOFXYBins, -130.0, 130.0);
1034
1035 locHistName = "TrackFCALYVsX_NoHit";
1036 locHistTitle = locTrackString + string(", Has Other Match, FCAL No Hit;Projected FCAL Hit X (cm);Projected FCAL Hit Y (cm)");
1037 dHistMap_TrackFCALYVsX_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumFCALTOFXYBins, -130.0, 130.0, dNumFCALTOFXYBins, -130.0, 130.0);
1038
1039 locHistName = "TrackFCALP_HasHit";
1040 locHistTitle = locTrackString + string(", Has Other Match, FCAL Has Hit;p (GeV/c)");
1041 dHistMap_TrackFCALP_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPBins, dMinP, dMaxP);
1042
1043 locHistName = "TrackFCALP_NoHit";
1044 locHistTitle = locTrackString + string(", Has Other Match, FCAL No Hit;p (GeV/c)");
1045 dHistMap_TrackFCALP_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPBins, dMinP, dMaxP);
1046
1047 locHistName = "TrackFCALR_HasHit";
1048 locHistTitle = locTrackString + string(", Has Other Match, FCAL Has Hit;Projected FCAL Hit R (cm)");
1049 dHistMap_TrackFCALR_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumFCALTOFXYBins, 0.0, 130);
1050
1051 locHistName = "TrackFCALR_NoHit";
1052 locHistTitle = locTrackString + string(", Has Other Match, FCAL No Hit;Projected FCAL Hit R (cm)");
1053 dHistMap_TrackFCALR_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumFCALTOFXYBins, 0.0, 130);
1054
1055 locHistName = "TrackFCALRowVsColumn_HasHit";
1056 locHistTitle = locTrackString + string(", Has Other Match, FCAL Has Hit;Projected FCAL Hit Column;Projected FCAL Hit Row");
1057 dHistMap_TrackFCALRowVsColumn_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 59, -0.5, 58.5, 59, -0.5, 58.5);
1058
1059 locHistName = "TrackFCALRowVsColumn_NoHit";
1060 locHistTitle = locTrackString + string(", Has Other Match, FCAL No Hit;Projected FCAL Hit Column;Projected FCAL Hit Row");
1061 dHistMap_TrackFCALRowVsColumn_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, 59, -0.5, 58.5, 59, -0.5, 58.5);
1062
1063 locHistName = "FCALTrackDistanceVsP";
1064 locHistTitle = locTrackString + string(";p (GeV/c);FCAL / Track Distance (cm)");
1065 dHistMap_FCALTrackDistanceVsP[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DTrackDOCABins, dMinTrackDOCA, dMaxTrackMatchDOCA);
1066
1067 locHistName = "FCALTrackDistanceVsTheta";
1068 locHistTitle = locTrackString + string(";#theta#circ;FCAL / Track Distance (cm)");
1069 dHistMap_FCALTrackDistanceVsTheta[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, 20.0, dNum2DTrackDOCABins, dMinTrackDOCA, dMaxTrackMatchDOCA);
1070 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1071
1072
1073 //BCAL
1074 CreateAndChangeTo_Directory("BCAL", "BCAL");
1075 locHistName = "TrackBCALModuleVsZ_HasHit";
1076 locHistTitle = locTrackString + string(", Has Other Match, BCAL Has Hit;Projected BCAL Hit Z (cm);Projected BCAL Hit Module");
1077 dHistMap_TrackBCALModuleVsZ_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DBCALZBins, 0.0, 450.0, 48, 0.5, 48.5);
1078
1079 locHistName = "TrackBCALModuleVsZ_NoHit";
1080 locHistTitle = locTrackString + string(", Has Other Match, BCAL No Hit;Projected BCAL Hit Z (cm);Projected BCAL Hit Module");
1081 dHistMap_TrackBCALModuleVsZ_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DBCALZBins, 0.0, 450.0, 48, 0.5, 48.5);
1082
1083 locHistName = "TrackBCALPhiVsZ_HasHit";
1084 locHistTitle = locTrackString + string(", Has Other Match, BCAL Has Hit;Projected BCAL Hit Z (cm);Projected BCAL Hit #phi#circ");
1085 dHistMap_TrackBCALPhiVsZ_HasHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DBCALZBins, 0.0, 450.0, dNum2DPhiBins, dMinPhi, dMaxPhi);
1086
1087 locHistName = "TrackBCALPhiVsZ_NoHit";
1088 locHistTitle = locTrackString + string(", Has Other Match, BCAL No Hit;Projected BCAL Hit Z (cm);Projected BCAL Hit #phi#circ");
1089 dHistMap_TrackBCALPhiVsZ_NoHit[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DBCALZBins, 0.0, 450.0, dNum2DPhiBins, dMinPhi, dMaxPhi);
1090
1091 locHistName = "BCALDeltaPhiVsP";
1092 locHistTitle = locTrackString + string(";p (GeV/c);BCAL / Track #Delta#phi#circ");
1093 dHistMap_BCALDeltaPhiVsP[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, 4.0, dNum2DDeltaPhiBins, dMinDeltaPhi, dMaxDeltaPhi);
1094
1095 locHistName = "BCALDeltaPhiVsZ";
1096 locHistTitle = locTrackString + string(";Projected BCAL Hit-Z (cm);BCAL / Track #Delta#phi#circ");
1097 dHistMap_BCALDeltaPhiVsZ[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DBCALZBins, 0.0, 450.0, dNum2DDeltaPhiBins, dMinDeltaPhi, dMaxDeltaPhi);
1098
1099 locHistName = "BCALDeltaZVsTheta";
1100 locHistTitle = locTrackString + string(";#theta#circ;BCAL / Track #Deltaz (cm)");
1101 dHistMap_BCALDeltaZVsTheta[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DDeltaZBins, dMinDeltaZ, dMaxDeltaZ);
1102
1103 locHistName = "BCALDeltaZVsZ";
1104 locHistTitle = locTrackString + string(";Projected BCAL Hit-Z (cm);BCAL / Track #Deltaz (cm)");
1105 dHistMap_BCALDeltaZVsZ[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DBCALZBins, 0.0, 450.0, dNum2DDeltaZBins, dMinDeltaZ, dMaxDeltaZ);
1106 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1107
1108 //TRACKING
1109 locHistName = "PVsTheta_NoHitMatch";
1110 locHistTitle = locTrackString + string(", No Hit Match;#theta#circ;p (GeV/c)");
1111 dHistMap_TrackPVsTheta_NoHitMatch[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
1112
1113 locHistName = "PVsTheta_HitMatch";
1114 locHistTitle = locTrackString + string(", Hit Match;#theta#circ;p (GeV/c)");
1115 dHistMap_TrackPVsTheta_HitMatch[locIsTimeBased] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
1116
1117 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1118 }
1119
1120 //Return to the base directory
1121 ChangeTo_BaseDirectory();
1122 }
1123 japp->RootUnLock(); //RELEASE ROOT LOCK!!
1124}
1125
1126void DHistogramAction_DetectorMatching::Run_Update(JEventLoop* locEventLoop)
1127{
1128 map<string, double> tofparms;
1129 const DTOFGeometry *locTOFGeometry = nullptr;
1130 locEventLoop->GetSingle(locTOFGeometry);
1131 string locTOFParmsTable = locTOFGeometry->Get_CCDB_DirectoryName() + "/tof_parms";
1132 locEventLoop->GetCalib(locTOFParmsTable.c_str(), tofparms);
1133 TOF_E_THRESHOLD = tofparms["TOF_E_THRESHOLD"];
1134}
1135
1136bool DHistogramAction_DetectorMatching::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
1137{
1138 //Expect locParticleCombo to be NULL since this is a reaction-independent action.
1139
1140 if(Get_CalledPriorWithComboFlag())
1141 return true; //else double-counting!
1142
1143 bool locIsRESTEvent = locEventLoop->GetJEvent().GetStatusBit(kSTATUS_REST);
1144
1145 Fill_MatchingHists(locEventLoop, true); //Time-based tracks
1146 if(!locIsRESTEvent)
1147 Fill_MatchingHists(locEventLoop, false); //Wire-based tracks
1148
1149 return true; //return false if you want to use this action to apply a cut (and it fails the cut!)
1150}
1151
1152void DHistogramAction_DetectorMatching::Fill_MatchingHists(JEventLoop* locEventLoop, bool locIsTimeBased)
1153{
1154 const DParticleID* locParticleID = NULL__null;
1155 locEventLoop->GetSingle(locParticleID);
1
Calling 'JEventLoop::GetSingle'
1156
1157 //can't make this a class member: may cause race condition
1158 DCutAction_TrackHitPattern locCutAction_TrackHitPattern(NULL__null, dMinHitRingsPerCDCSuperlayer, dMinHitPlanesPerFDCPackage);
1159 locCutAction_TrackHitPattern.Initialize(locEventLoop);
1160
1161 //get the best tracks for each candidate id, based on good hit pattern & tracking FOM
1162 map<JObject::oid_t, const DTrackingData*> locBestTrackMap; //lowest tracking FOM for each candidate id
1163 if(locIsTimeBased)
1164 {
1165 vector<const DTrackTimeBased*> locTrackTimeBasedVector;
1166 locEventLoop->Get(locTrackTimeBasedVector);
1167
1168 //select the best DTrackTimeBased for each track: of tracks with good hit pattern, use best tracking FOM
1169 for(size_t loc_i = 0; loc_i < locTrackTimeBasedVector.size(); ++loc_i)
1170 {
1171 if(locTrackTimeBasedVector[loc_i]->FOM < dMinTrackingFOM)
1172 continue;
1173 if(!locCutAction_TrackHitPattern.Cut_TrackHitPattern(locParticleID, locTrackTimeBasedVector[loc_i]))
1174 continue;
1175 JObject::oid_t locCandidateID = locTrackTimeBasedVector[loc_i]->candidateid;
1176 if(locBestTrackMap.find(locCandidateID) == locBestTrackMap.end())
1177 locBestTrackMap[locCandidateID] = locTrackTimeBasedVector[loc_i];
1178 else if(locTrackTimeBasedVector[loc_i]->FOM > (dynamic_cast<const DTrackTimeBased*>(locBestTrackMap[locCandidateID]))->FOM)
1179 locBestTrackMap[locCandidateID] = locTrackTimeBasedVector[loc_i];
1180 }
1181 }
1182 else
1183 {
1184 vector<const DTrackWireBased*> locTrackWireBasedVector;
1185 locEventLoop->Get(locTrackWireBasedVector);
1186
1187 //select the best DTrackWireBased for each track: of tracks with good hit pattern, use best tracking FOM
1188 for(size_t loc_i = 0; loc_i < locTrackWireBasedVector.size(); ++loc_i)
1189 {
1190 if(locTrackWireBasedVector[loc_i]->FOM < dMinTrackingFOM)
1191 continue;
1192 if(!locCutAction_TrackHitPattern.Cut_TrackHitPattern(locParticleID, locTrackWireBasedVector[loc_i]))
1193 continue;
1194 JObject::oid_t locCandidateID = locTrackWireBasedVector[loc_i]->candidateid;
1195 if(locBestTrackMap.find(locCandidateID) == locBestTrackMap.end())
1196 locBestTrackMap[locCandidateID] = locTrackWireBasedVector[loc_i];
1197 else if(locTrackWireBasedVector[loc_i]->FOM > (dynamic_cast<const DTrackWireBased*>(locBestTrackMap[locCandidateID]))->FOM)
1198 locBestTrackMap[locCandidateID] = locTrackWireBasedVector[loc_i];
1199 }
1200 }
1201
1202 vector<const DBCALShower*> locBCALShowers;
1203 locEventLoop->Get(locBCALShowers);
1204
1205 vector<const DFCALShower*> locFCALShowers;
1206 locEventLoop->Get(locFCALShowers);
1207
1208 vector<const DCCALShower*> locCCALShowers;
1209 locEventLoop->Get(locCCALShowers);
1210
1211 vector<const DTOFPoint*> locTOFPoints;
1212 locEventLoop->Get(locTOFPoints);
1213
1214 vector<const DTOFPaddleHit*> locTOFPaddleHits;
1215 locEventLoop->Get(locTOFPaddleHits);
1216
1217 vector<const DSCHit*> locSCHits;
1218 locEventLoop->Get(locSCHits);
1219
1220 const DEventRFBunch* locEventRFBunch = nullptr;
1221 locEventLoop->GetSingle(locEventRFBunch);
1222
1223 string locDetectorMatchesTag = locIsTimeBased ? "" : "WireBased";
1224 const DDetectorMatches* locDetectorMatches = NULL__null;
1225 locEventLoop->GetSingle(locDetectorMatches, locDetectorMatchesTag.c_str());
1226
1227 //TRACK / BCAL CLOSEST MATCHES
1228 map<const DTrackingData*, pair<shared_ptr<const DBCALShowerMatchParams>, double> > locBCALTrackDistanceMap; //double = z
1229 for(auto locTrackIterator = locBestTrackMap.begin(); locTrackIterator != locBestTrackMap.end(); ++locTrackIterator)
1230 {
1231 map<DetectorSystem_t,vector<DTrackFitter::Extrapolation_t> >extrapolations;
1232 Get_Extrapolations(locTrackIterator->second,extrapolations);
1233
1234 if(extrapolations.size()<2)
1235 break; //e.g. REST data: no trajectory
1236
1237 double locStartTime = locTrackIterator->second->t0();
1238 double locStartTimeVariance = 0.0;
1239 DVector3 locProjPos, locProjMom;
1240
1241 shared_ptr<const DBCALShowerMatchParams> locBestMatchParams;
1242 if(locParticleID->Get_ClosestToTrack(extrapolations.at(SYS_BCAL), locBCALShowers, false, locStartTime, locBestMatchParams, &locStartTimeVariance, &locProjPos, &locProjMom))
1243 locBCALTrackDistanceMap[locTrackIterator->second] = std::make_pair(locBestMatchParams, locProjPos.Z());
1244 }
1245
1246 //TRACK / FCAL CLOSEST MATCHES
1247 map<const DTrackingData*, shared_ptr<const DFCALShowerMatchParams>> locFCALTrackDistanceMap;
1248 for(auto locTrackIterator = locBestTrackMap.begin(); locTrackIterator != locBestTrackMap.end(); ++locTrackIterator)
1249 {
1250 map<DetectorSystem_t,vector<DTrackFitter::Extrapolation_t> >extrapolations;
1251 Get_Extrapolations(locTrackIterator->second,extrapolations);
1252
1253 if(extrapolations.size()<2)
1254 break; //e.g. REST data: no trajectory
1255
1256 double locStartTime = locTrackIterator->second->t0();
1257 shared_ptr<const DFCALShowerMatchParams> locBestMatchParams;
1258 if(locParticleID->Get_ClosestToTrack(extrapolations.at(SYS_FCAL), locFCALShowers, false, locStartTime, locBestMatchParams))
1259 locFCALTrackDistanceMap.emplace(locTrackIterator->second, locBestMatchParams);
1260 }
1261
1262 //TRACK / SC CLOSEST MATCHES
1263 map<const DTrackingData*, pair<shared_ptr<const DSCHitMatchParams>, double> > locSCTrackDistanceMap; //double = z
1264 for(auto locTrackIterator = locBestTrackMap.begin(); locTrackIterator != locBestTrackMap.end(); ++locTrackIterator)
1265 {
1266 map<DetectorSystem_t,vector<DTrackFitter::Extrapolation_t> >extrapolations;
1267 Get_Extrapolations(locTrackIterator->second,extrapolations);
1268
1269 if(extrapolations.size()<2)
1270 break; //e.g. REST data: no trajectory
1271
1272 double locStartTime = locTrackIterator->second->t0();
1273 double locStartTimeVariance = 0.0;
1274 DVector3 locProjPos, locProjMom;
1275
1276 shared_ptr<const DSCHitMatchParams> locBestMatchParams;
1277 if(locParticleID->Get_ClosestToTrack(extrapolations.at(SYS_START), locSCHits, locIsTimeBased, false, locStartTime, locBestMatchParams, &locStartTimeVariance, &locProjPos, &locProjMom))
1278 locSCTrackDistanceMap[locTrackIterator->second] = std::make_pair(locBestMatchParams, locProjPos.Z());
1279 }
1280
1281 //TRACK / TOF POINT CLOSEST MATCHES
1282 map<const DTrackingData*, shared_ptr<const DTOFHitMatchParams>> locTOFPointTrackDistanceMap;
1283 for(auto locTrackIterator = locBestTrackMap.begin(); locTrackIterator != locBestTrackMap.end(); ++locTrackIterator)
1284 {
1285 map<DetectorSystem_t,vector<DTrackFitter::Extrapolation_t> >extrapolations;
1286 Get_Extrapolations(locTrackIterator->second,extrapolations);
1287
1288 if(extrapolations.size()<2)
1289 break; //e.g. REST data: no trajectory
1290
1291 double locStartTime = locTrackIterator->second->t0();
1292 shared_ptr<const DTOFHitMatchParams> locBestMatchParams;
1293 if(locParticleID->Get_ClosestToTrack(extrapolations.at(SYS_TOF), locTOFPoints, false, locStartTime, locBestMatchParams))
1294 locTOFPointTrackDistanceMap.emplace(locTrackIterator->second, locBestMatchParams);
1295 }
1296
1297 //TRACK / TOF PADDLE CLOSEST MATCHES
1298 map<const DTrackingData*, pair<const DTOFPaddleHit*, pair<double, double> > > locHorizontalTOFPaddleTrackDistanceMap; //doubles: delta-y, distance
1299 map<const DTrackingData*, pair<const DTOFPaddleHit*, pair<double, double> > > locVerticalTOFPaddleTrackDistanceMap; //doubles: delta-x, distance
1300 for(auto locTrackIterator = locBestTrackMap.begin(); locTrackIterator != locBestTrackMap.end(); ++locTrackIterator)
1301 {
1302 const DKinematicData* locKinematicData = locTrackIterator->second;
1303 map<DetectorSystem_t,vector<DTrackFitter::Extrapolation_t> >extrapolations;
1304 Get_Extrapolations(locTrackIterator->second,extrapolations);
1305
1306 if(extrapolations.size()<2)
1307 break; //e.g. REST data: no trajectory
1308
1309 double locBestDeltaX = 999.9, locBestDeltaY = 999.9, locBestDistance_Vertical = 999.9, locBestDistance_Horizontal = 999.9;
1310 double locStartTime = locParticleID->Calc_PropagatedRFTime(locKinematicData, locEventRFBunch);
1311
1312 const DTOFPaddleHit* locClosestTOFPaddleHit_Vertical = locParticleID->Get_ClosestTOFPaddleHit_Vertical(extrapolations.at(SYS_TOF), locTOFPaddleHits, locStartTime, locBestDeltaX, locBestDistance_Vertical);
1313 pair<double, double> locDistancePair_Vertical(locBestDeltaX, locBestDistance_Vertical);
1314 if(locClosestTOFPaddleHit_Vertical != NULL__null)
1315 locVerticalTOFPaddleTrackDistanceMap[locTrackIterator->second] = pair<const DTOFPaddleHit*, pair<double, double> >(locClosestTOFPaddleHit_Vertical, locDistancePair_Vertical);
1316
1317 const DTOFPaddleHit* locClosestTOFPaddleHit_Horizontal = locParticleID->Get_ClosestTOFPaddleHit_Horizontal(extrapolations.at(SYS_TOF), locTOFPaddleHits, locStartTime, locBestDeltaY, locBestDistance_Horizontal);
1318 pair<double, double> locDistancePair_Horizontal(locBestDeltaY, locBestDistance_Horizontal);
1319 if(locClosestTOFPaddleHit_Horizontal != NULL__null)
1320 locHorizontalTOFPaddleTrackDistanceMap[locTrackIterator->second] = pair<const DTOFPaddleHit*, pair<double, double> >(locClosestTOFPaddleHit_Horizontal, locDistancePair_Horizontal);
1321 }
1322
1323 //PROJECTED HIT POSITIONS
1324 map<const DTrackingData*, pair<int, bool> > locProjectedSCPaddleMap; //pair: paddle, hit-barrel-flag (false if bend/nose)
1325 map<const DTrackingData*, pair<int, int> > locProjectedTOF2DPaddlesMap; //pair: vertical, horizontal
1326 map<const DTrackingData*, pair<float, float> > locProjectedTOFXYMap; //pair: x, y
1327 map<const DTrackingData*, pair<int, int> > locProjectedFCALRowColumnMap; //pair: column, row
1328 map<const DTrackingData*, pair<float, float> > locProjectedFCALXYMap; //pair: x, y
1329 map<const DTrackingData*, pair<float, int> > locProjectedBCALModuleSectorMap; //pair: z, module
1330 map<const DTrackingData*, pair<float, float> > locProjectedBCALPhiZMap; //pair: z, phi
1331 for(auto locTrackIterator = locBestTrackMap.begin(); locTrackIterator != locBestTrackMap.end(); ++locTrackIterator)
1332 {
1333 const DTrackingData* locTrack = locTrackIterator->second;
1334 map<DetectorSystem_t,vector<DTrackFitter::Extrapolation_t> >extrapolations;
1335 Get_Extrapolations(locTrackIterator->second,extrapolations);
1336
1337 if(extrapolations.size()<2)
1338 break; //e.g. REST data: no trajectory
1339
1340 //SC
1341 DVector3 locSCIntersection;
1342 bool locProjBarrelFlag = false;
1343 unsigned int locProjectedSCPaddle = locParticleID->PredictSCSector(extrapolations.at(SYS_START), &locSCIntersection, &locProjBarrelFlag);
1344 if(locProjectedSCPaddle != 0)
1345 locProjectedSCPaddleMap[locTrack] = pair<int, bool>(locProjectedSCPaddle, locProjBarrelFlag);
1346
1347 //TOF
1348 DVector3 locTOFIntersection;
1349 unsigned int locHorizontalBar = 0, locVerticalBar = 0;
1350 if(locParticleID->PredictTOFPaddles(extrapolations.at(SYS_TOF), locHorizontalBar, locVerticalBar, &locTOFIntersection))
1351 {
1352 locProjectedTOF2DPaddlesMap[locTrack] = pair<int, int>(locVerticalBar, locHorizontalBar);
1353 locProjectedTOFXYMap[locTrack] = pair<float, float>(locTOFIntersection.X(), locTOFIntersection.Y());
1354 }
1355
1356 //FCAL
1357 DVector3 locFCALIntersection;
1358 unsigned int locRow = 0, locColumn = 0;
1359 if(locParticleID->PredictFCALHit(extrapolations.at(SYS_FCAL), locRow, locColumn, &locFCALIntersection))
1360 {
1361 locProjectedFCALRowColumnMap[locTrack] = pair<int, int>(locColumn, locRow);
1362 locProjectedFCALXYMap[locTrack] = pair<float, float>(locFCALIntersection.X(), locFCALIntersection.Y());
1363 }
1364
1365 //BCAL
1366 DVector3 locBCALIntersection;
1367 unsigned int locModule = 0, locSector = 0;
1368 if(locParticleID->PredictBCALWedge(extrapolations.at(SYS_BCAL), locModule, locSector, &locBCALIntersection))
1369 {
1370 locProjectedBCALModuleSectorMap[locTrack] = pair<float, int>(locBCALIntersection.Z(), locModule);
1371 locProjectedBCALPhiZMap[locTrack] = pair<float, float>(locBCALIntersection.Z(), locBCALIntersection.Phi()*180.0/TMath::Pi());
1372 }
1373 }
1374
1375 //FILL HISTOGRAMS
1376 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
1377 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
1378 Lock_Action(); //ACQUIRE ROOT LOCK!!
1379 {
1380 /********************************************************** MATCHING DISTANCE **********************************************************/
1381
1382 //BCAL
1383 for(auto locMapPair : locBCALTrackDistanceMap)
1384 {
1385 auto locTrack = locMapPair.first;
1386 auto locMatchParams = locMapPair.second.first;
1387 double locDeltaPhi = locMatchParams->dDeltaPhiToShower*180.0/TMath::Pi();
1388 double locProjectedZ = locMapPair.second.second;
1389 dHistMap_BCALDeltaPhiVsP[locIsTimeBased]->Fill(locTrack->momentum().Mag(), locDeltaPhi);
1390 dHistMap_BCALDeltaZVsTheta[locIsTimeBased]->Fill(locTrack->momentum().Theta()*180.0/TMath::Pi(), locMatchParams->dDeltaZToShower);
1391
1392 dHistMap_BCALDeltaPhiVsZ[locIsTimeBased]->Fill(locProjectedZ, locDeltaPhi);
1393 dHistMap_BCALDeltaZVsZ[locIsTimeBased]->Fill(locProjectedZ, locMatchParams->dDeltaZToShower);
1394 }
1395
1396 //FCAL
1397 for(auto locMapPair : locFCALTrackDistanceMap)
1398 {
1399 auto locTrack = locMapPair.first;
1400 dHistMap_FCALTrackDistanceVsP[locIsTimeBased]->Fill(locTrack->momentum().Mag(), locMapPair.second->dDOCAToShower);
1401 dHistMap_FCALTrackDistanceVsTheta[locIsTimeBased]->Fill(locTrack->momentum().Theta()*180.0/TMath::Pi(), locMapPair.second->dDOCAToShower);
1402 }
1403
1404 //TOF Paddle
1405 //Horizontal
1406 auto locTOFPaddleIterator = locHorizontalTOFPaddleTrackDistanceMap.begin();
1407 for(; locTOFPaddleIterator != locHorizontalTOFPaddleTrackDistanceMap.end(); ++locTOFPaddleIterator)
1408 {
1409 double locDeltaY = locTOFPaddleIterator->second.second.first;
1410 dHistMap_TOFPaddleTrackDeltaY[locIsTimeBased]->Fill(locDeltaY);
1411 }
1412 //Vertical
1413 locTOFPaddleIterator = locVerticalTOFPaddleTrackDistanceMap.begin();
1414 for(; locTOFPaddleIterator != locVerticalTOFPaddleTrackDistanceMap.end(); ++locTOFPaddleIterator)
1415 {
1416 double locDeltaX = locTOFPaddleIterator->second.second.first;
1417 dHistMap_TOFPaddleTrackDeltaX[locIsTimeBased]->Fill(locDeltaX);
1418 }
1419
1420 //TOF Point
1421 for(auto locMapPair : locTOFPointTrackDistanceMap)
1422 {
1423 auto locTrack = locMapPair.first;
1424 const DTOFPoint* locTOFPoint = locMapPair.second->dTOFPoint;
1425 double locDeltaX = locMapPair.second->dDeltaXToHit;
1426 double locDeltaY = locMapPair.second->dDeltaYToHit;
1427
1428 double locDistance = sqrt(locDeltaX*locDeltaX + locDeltaY*locDeltaY);
1429 if((fabs(locDeltaX) < 500.0) && (fabs(locDeltaY) < 500.0)) //else position not well-defined
1430 {
1431 dHistMap_TOFPointTrackDistanceVsP[locIsTimeBased]->Fill(locTrack->momentum().Mag(), locDistance);
1432 dHistMap_TOFPointTrackDistanceVsTheta[locIsTimeBased]->Fill(locTrack->momentum().Theta()*180.0/TMath::Pi(), locDistance);
1433 if((locTOFPoint->dHorizontalBar != 0) && (locTOFPoint->dVerticalBar != 0))
1434 dHistMap_TOFPointTrackDistance_BothPlanes[locIsTimeBased]->Fill(locDistance);
1435 else
1436 dHistMap_TOFPointTrackDistance_OnePlane[locIsTimeBased]->Fill(locDistance);
1437 }
1438
1439 dHistMap_TOFPointTrackDeltaXVsHorizontalPaddle[locIsTimeBased]->Fill(locTOFPoint->dHorizontalBar, locDeltaX);
1440 dHistMap_TOFPointTrackDeltaXVsVerticalPaddle[locIsTimeBased]->Fill(locTOFPoint->dVerticalBar, locDeltaX);
1441
1442 dHistMap_TOFPointTrackDeltaYVsHorizontalPaddle[locIsTimeBased]->Fill(locTOFPoint->dHorizontalBar, locDeltaY);
1443 dHistMap_TOFPointTrackDeltaYVsVerticalPaddle[locIsTimeBased]->Fill(locTOFPoint->dVerticalBar, locDeltaY);
1444 }
1445
1446 //SC
1447 if(locSCHits.size() <= 4) //don't fill if every paddle fired!
1448 {
1449 for(auto locMapPair : locSCTrackDistanceMap)
1450 {
1451 auto locTrack = locMapPair.first;
1452 auto locMatchParams = locMapPair.second.first;
1453 double locDeltaPhi = locMatchParams->dDeltaPhiToHit*180.0/TMath::Pi();
1454 double locProjectedZ = locMapPair.second.second;
1455 dHistMap_SCTrackDeltaPhiVsP[locIsTimeBased]->Fill(locTrack->momentum().Mag(), locDeltaPhi);
1456 dHistMap_SCTrackDeltaPhiVsTheta[locIsTimeBased]->Fill(locTrack->momentum().Theta()*180.0/TMath::Pi(), locDeltaPhi);
1457 dHistMap_SCTrackDeltaPhiVsZ[locIsTimeBased]->Fill(locProjectedZ, locDeltaPhi);
1458 }
1459 }
1460
1461 /********************************************************* MATCHING EFFICINECY *********************************************************/
1462
1463 //Does-it-match, by detector
1464 for(auto locMapPair : locBestTrackMap)
1465 {
1466 auto locTrack = locMapPair.second;
1467 double locTheta = locTrack->momentum().Theta()*180.0/TMath::Pi();
1468 double locPhi = locTrack->momentum().Phi()*180.0/TMath::Pi();
1469 double locP = locTrack->momentum().Mag();
1470
1471 //BCAL
1472 if(locDetectorMatches->Get_IsMatchedToDetector(locTrack, SYS_START))
1473 {
1474 if(locDetectorMatches->Get_IsMatchedToDetector(locTrack, SYS_BCAL))
1475 {
1476 dHistMap_PVsTheta_HasHit[SYS_BCAL][locIsTimeBased]->Fill(locTheta, locP);
1477 dHistMap_PhiVsTheta_HasHit[SYS_BCAL][locIsTimeBased]->Fill(locTheta, locPhi);
1478 if(locProjectedBCALModuleSectorMap.find(locTrack) != locProjectedBCALModuleSectorMap.end())
1479 {
1480 pair<float, float>& locPositionPair = locProjectedBCALPhiZMap[locTrack];
1481 dHistMap_TrackBCALPhiVsZ_HasHit[locIsTimeBased]->Fill(locPositionPair.first, locPositionPair.second);
1482 pair<float, int>& locElementPair = locProjectedBCALModuleSectorMap[locTrack];
1483 dHistMap_TrackBCALModuleVsZ_HasHit[locIsTimeBased]->Fill(locElementPair.first, locElementPair.second);
1484 }
1485 }
1486 else
1487 {
1488 dHistMap_PVsTheta_NoHit[SYS_BCAL][locIsTimeBased]->Fill(locTheta, locP);
1489 dHistMap_PhiVsTheta_NoHit[SYS_BCAL][locIsTimeBased]->Fill(locTheta, locPhi);
1490 if(locProjectedBCALModuleSectorMap.find(locTrack) != locProjectedBCALModuleSectorMap.end())
1491 {
1492 pair<float, float>& locPositionPair = locProjectedBCALPhiZMap[locTrack];
1493 dHistMap_TrackBCALPhiVsZ_NoHit[locIsTimeBased]->Fill(locPositionPair.first, locPositionPair.second);
1494 pair<float, int>& locElementPair = locProjectedBCALModuleSectorMap[locTrack];
1495 dHistMap_TrackBCALModuleVsZ_NoHit[locIsTimeBased]->Fill(locElementPair.first, locElementPair.second);
1496 }
1497 }
1498 }
1499
1500 //FCAL
1501 if(locDetectorMatches->Get_IsMatchedToDetector(locTrack, SYS_FCAL))
1502 {
1503 dHistMap_PVsTheta_HasHit[SYS_FCAL][locIsTimeBased]->Fill(locTheta, locP);
1504 if(locP > 1.0)
1505 dHistMap_PhiVsTheta_HasHit[SYS_FCAL][locIsTimeBased]->Fill(locTheta, locPhi);
1506 if(locProjectedFCALRowColumnMap.find(locTrack) != locProjectedFCALRowColumnMap.end())
1507 {
1508 dHistMap_TrackFCALP_HasHit[locIsTimeBased]->Fill(locP);
1509 if(locP > 1.0)
1510 {
1511 pair<float, float>& locPositionPair = locProjectedFCALXYMap[locTrack];
1512 dHistMap_TrackFCALYVsX_HasHit[locIsTimeBased]->Fill(locPositionPair.first, locPositionPair.second);
1513 float locFCALR = sqrt(locPositionPair.first*locPositionPair.first + locPositionPair.second*locPositionPair.second);
1514 dHistMap_TrackFCALR_HasHit[locIsTimeBased]->Fill(locFCALR);
1515 pair<int, int>& locElementPair = locProjectedFCALRowColumnMap[locTrack];
1516 dHistMap_TrackFCALRowVsColumn_HasHit[locIsTimeBased]->Fill(locElementPair.first, locElementPair.second);
1517 }
1518 }
1519 }
1520 else
1521 {
1522 dHistMap_PVsTheta_NoHit[SYS_FCAL][locIsTimeBased]->Fill(locTheta, locP);
1523 if(locP > 1.0)
1524 dHistMap_PhiVsTheta_NoHit[SYS_FCAL][locIsTimeBased]->Fill(locTheta, locPhi);
1525 if(locProjectedFCALRowColumnMap.find(locTrack) != locProjectedFCALRowColumnMap.end())
1526 {
1527 dHistMap_TrackFCALP_NoHit[locIsTimeBased]->Fill(locP);
1528 if(locP > 1.0)
1529 {
1530 pair<float, float>& locPositionPair = locProjectedFCALXYMap[locTrack];
1531 dHistMap_TrackFCALYVsX_NoHit[locIsTimeBased]->Fill(locPositionPair.first, locPositionPair.second);
1532 float locFCALR = sqrt(locPositionPair.first*locPositionPair.first + locPositionPair.second*locPositionPair.second);
1533 dHistMap_TrackFCALR_NoHit[locIsTimeBased]->Fill(locFCALR);
1534 pair<int, int>& locElementPair = locProjectedFCALRowColumnMap[locTrack];
1535 dHistMap_TrackFCALRowVsColumn_NoHit[locIsTimeBased]->Fill(locElementPair.first, locElementPair.second);
1536 }
1537 }
1538 }
1539
1540 //TOF Paddle
1541 if((locP > 1.0) && (locProjectedTOFXYMap.find(locTrack) != locProjectedTOFXYMap.end()))
1542 {
1543 pair<float, float>& locPositionPair = locProjectedTOFXYMap[locTrack];
1544 pair<int, int>& locPaddlePair = locProjectedTOF2DPaddlesMap[locTrack]; //vertical, horizontal
1545
1546 //Horizontal
1547 if(locHorizontalTOFPaddleTrackDistanceMap.find(locTrack) != locHorizontalTOFPaddleTrackDistanceMap.end())
1548 {
1549 auto& locMatch = locHorizontalTOFPaddleTrackDistanceMap[locTrack];
1550 const DTOFPaddleHit* locTOFPaddleHit = locMatch.first;
1551 bool locDoubleEndedHitFlag = ((locTOFPaddleHit->E_north > TOF_E_THRESHOLD) && (locTOFPaddleHit->E_south > TOF_E_THRESHOLD));
1552 double locDistance = locDoubleEndedHitFlag ? locMatch.second.second : locMatch.second.first;
1553 if(locDistance <= dMinTOFPaddleMatchDistance) //match
1554 dHistMap_TOFPaddleHorizontalPaddleVsTrackX_HasHit[locIsTimeBased]->Fill(locPositionPair.first, locPaddlePair.second);
1555 else //no match
1556 dHistMap_TOFPaddleHorizontalPaddleVsTrackX_NoHit[locIsTimeBased]->Fill(locPositionPair.first, locPaddlePair.second);
1557 }
1558 else // no match
1559 dHistMap_TOFPaddleHorizontalPaddleVsTrackX_NoHit[locIsTimeBased]->Fill(locPositionPair.first, locPaddlePair.second);
1560
1561 //Vertical
1562 if(locVerticalTOFPaddleTrackDistanceMap.find(locTrack) != locVerticalTOFPaddleTrackDistanceMap.end())
1563 {
1564 auto& locMatch = locVerticalTOFPaddleTrackDistanceMap[locTrack];
1565 const DTOFPaddleHit* locTOFPaddleHit = locMatch.first;
1566 bool locDoubleEndedHitFlag = ((locTOFPaddleHit->E_north > TOF_E_THRESHOLD) && (locTOFPaddleHit->E_south > TOF_E_THRESHOLD));
1567 double locDistance = locDoubleEndedHitFlag ? locMatch.second.second : locMatch.second.first;
1568 if(locDistance <= dMinTOFPaddleMatchDistance) //match
1569 dHistMap_TOFPaddleTrackYVsVerticalPaddle_HasHit[locIsTimeBased]->Fill(locPaddlePair.first, locPositionPair.second);
1570 else //no match
1571 dHistMap_TOFPaddleTrackYVsVerticalPaddle_NoHit[locIsTimeBased]->Fill(locPaddlePair.first, locPositionPair.second);
1572 }
1573 else // no match
1574 dHistMap_TOFPaddleTrackYVsVerticalPaddle_NoHit[locIsTimeBased]->Fill(locPaddlePair.first, locPositionPair.second);
1575 }
1576
1577 //TOF Point
1578 if(locDetectorMatches->Get_IsMatchedToDetector(locTrack, SYS_TOF))
1579 {
1580 dHistMap_PVsTheta_HasHit[SYS_TOF][locIsTimeBased]->Fill(locTheta, locP);
1581 if(locP > 1.0)
1582 dHistMap_PhiVsTheta_HasHit[SYS_TOF][locIsTimeBased]->Fill(locTheta, locPhi);
1583 if(locProjectedTOFXYMap.find(locTrack) != locProjectedTOFXYMap.end())
1584 {
1585 dHistMap_TrackTOFP_HasHit[locIsTimeBased]->Fill(locP);
1586 if(locP > 1.0)
1587 {
1588 pair<float, float>& locPositionPair = locProjectedTOFXYMap[locTrack];
1589 dHistMap_TrackTOFYVsX_HasHit[locIsTimeBased]->Fill(locPositionPair.first, locPositionPair.second);
1590 float locTOFR = sqrt(locPositionPair.first*locPositionPair.first + locPositionPair.second*locPositionPair.second);
1591 dHistMap_TrackTOFR_HasHit[locIsTimeBased]->Fill(locTOFR);
1592 pair<int, int>& locElementPair = locProjectedTOF2DPaddlesMap[locTrack];
1593 dHistMap_TrackTOF2DPaddles_HasHit[locIsTimeBased]->Fill(locElementPair.first, locElementPair.second);
1594 }
1595 }
1596 }
1597 else
1598 {
1599 dHistMap_PVsTheta_NoHit[SYS_TOF][locIsTimeBased]->Fill(locTheta, locP);
1600 if(locP > 1.0)
1601 dHistMap_PhiVsTheta_NoHit[SYS_TOF][locIsTimeBased]->Fill(locTheta, locPhi);
1602 if(locProjectedTOFXYMap.find(locTrack) != locProjectedTOFXYMap.end())
1603 {
1604 dHistMap_TrackTOFP_NoHit[locIsTimeBased]->Fill(locP);
1605 if(locP > 1.0)
1606 {
1607 pair<float, float>& locPositionPair = locProjectedTOFXYMap[locTrack];
1608 dHistMap_TrackTOFYVsX_NoHit[locIsTimeBased]->Fill(locPositionPair.first, locPositionPair.second);
1609 float locTOFR = sqrt(locPositionPair.first*locPositionPair.first + locPositionPair.second*locPositionPair.second);
1610 dHistMap_TrackTOFR_NoHit[locIsTimeBased]->Fill(locTOFR);
1611 pair<int, int>& locElementPair = locProjectedTOF2DPaddlesMap[locTrack];
1612 dHistMap_TrackTOF2DPaddles_NoHit[locIsTimeBased]->Fill(locElementPair.first, locElementPair.second);
1613 }
1614 }
1615 }
1616
1617 //SC
1618 if(locDetectorMatches->Get_IsMatchedToDetector(locTrack, SYS_BCAL) || locDetectorMatches->Get_IsMatchedToDetector(locTrack, SYS_FCAL) || locDetectorMatches->Get_IsMatchedToDetector(locTrack, SYS_TOF))
1619 {
1620 if(locDetectorMatches->Get_IsMatchedToDetector(locTrack, SYS_START))
1621 {
1622 dHistMap_PVsTheta_HasHit[SYS_START][locIsTimeBased]->Fill(locTheta, locP);
1623 dHistMap_PhiVsTheta_HasHit[SYS_START][locIsTimeBased]->Fill(locTheta, locPhi);
1624 if(locProjectedSCPaddleMap.find(locTrack) != locProjectedSCPaddleMap.end())
1625 {
1626 dHistMap_SCPaddleVsTheta_HasHit[locIsTimeBased]->Fill(locTheta, locProjectedSCPaddleMap[locTrack].first);
1627 if(locProjectedSCPaddleMap[locTrack].second)
1628 dHistMap_SCPaddle_BarrelRegion_HasHit[locIsTimeBased]->Fill(locProjectedSCPaddleMap[locTrack].first);
1629 else
1630 dHistMap_SCPaddle_NoseRegion_HasHit[locIsTimeBased]->Fill(locProjectedSCPaddleMap[locTrack].first);
1631 if(locSCTrackDistanceMap.find(locTrack) != locSCTrackDistanceMap.end())
1632 {
1633 double locProjectedZ = locSCTrackDistanceMap[locTrack].second;
1634 dHistMap_SCPaddleVsZ_HasHit[locIsTimeBased]->Fill(locProjectedZ, locProjectedSCPaddleMap[locTrack].first);
1635 }
1636 }
1637 }
1638 else
1639 {
1640 dHistMap_PVsTheta_NoHit[SYS_START][locIsTimeBased]->Fill(locTheta, locP);
1641 dHistMap_PhiVsTheta_NoHit[SYS_START][locIsTimeBased]->Fill(locTheta, locPhi);
1642 if(locProjectedSCPaddleMap.find(locTrack) != locProjectedSCPaddleMap.end())
1643 {
1644 dHistMap_SCPaddleVsTheta_NoHit[locIsTimeBased]->Fill(locTheta, locProjectedSCPaddleMap[locTrack].first);
1645 if(locProjectedSCPaddleMap[locTrack].second)
1646 dHistMap_SCPaddle_BarrelRegion_NoHit[locIsTimeBased]->Fill(locProjectedSCPaddleMap[locTrack].first);
1647 else
1648 dHistMap_SCPaddle_NoseRegion_NoHit[locIsTimeBased]->Fill(locProjectedSCPaddleMap[locTrack].first);
1649 if(locSCTrackDistanceMap.find(locTrack) != locSCTrackDistanceMap.end())
1650 {
1651 double locProjectedZ = locSCTrackDistanceMap[locTrack].second;
1652 dHistMap_SCPaddleVsZ_NoHit[locIsTimeBased]->Fill(locProjectedZ, locProjectedSCPaddleMap[locTrack].first);
1653 }
1654 }
1655 }
1656 }
1657 }
1658
1659 //Is-Matched to Something
1660 for(auto locMapPair : locBestTrackMap)
1661 {
1662 auto locTrack = locMapPair.second;
1663 double locTheta = locTrack->momentum().Theta()*180.0/TMath::Pi();
1664 double locP = locTrack->momentum().Mag();
1665 if(locDetectorMatches->Get_IsMatchedToHit(locTrack))
1666 dHistMap_TrackPVsTheta_HitMatch[locIsTimeBased]->Fill(locTheta, locP);
1667 else
1668 dHistMap_TrackPVsTheta_NoHitMatch[locIsTimeBased]->Fill(locTheta, locP);
1669 }
1670 }
1671 Unlock_Action(); //RELEASE ROOT LOCK!!
1672}
1673
1674void DHistogramAction_DetectorPID::Initialize(JEventLoop* locEventLoop)
1675{
1676 //Create any histograms/trees/etc. within a ROOT lock.
1677 //This is so that when running multithreaded, only one thread is writing to the ROOT file at a time.
1678
1679 //When creating a reaction-independent action, only modify member variables within a ROOT lock.
1680 //Objects created within a plugin (such as reaction-independent actions) can be accessed by many threads simultaneously.
1681
1682 string locHistName, locHistTitle, locParticleROOTName;
1683
1684 string locTrackSelectionTag = "NotATag", locShowerSelectionTag = "NotATag";
1685 if(gPARMS->Exists("COMBO:TRACK_SELECT_TAG"))
1686 gPARMS->GetParameter("COMBO:TRACK_SELECT_TAG", locTrackSelectionTag);
1687 if(gPARMS->Exists("COMBO:SHOWER_SELECT_TAG"))
1688 gPARMS->GetParameter("COMBO:SHOWER_SELECT_TAG", locShowerSelectionTag);
1689
1690 //CREATE THE HISTOGRAMS
1691 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
1692 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
1693 {
1694 //So: Default tag is "", User can set it to something else
1695 //In here, if tag is "", get from gparms, if not, leave it alone
1696 //If gparms value does not exist, set it to (and use) "PreSelect"
1697 if(dTrackSelectionTag == "NotATag")
1698 dTrackSelectionTag = (locTrackSelectionTag == "NotATag") ? "PreSelect" : locTrackSelectionTag;
1699 if(dShowerSelectionTag == "NotATag")
1700 dShowerSelectionTag = (locShowerSelectionTag == "NotATag") ? "PreSelect" : locShowerSelectionTag;
1701
1702 //Required: Create a folder in the ROOT output file that will contain all of the output ROOT objects (if any) for this action.
1703 //If another thread has already created the folder, it just changes to it.
1704 CreateAndChangeTo_ActionDirectory();
1705
1706 //q = 0
1707 locParticleROOTName = ParticleName_ROOT(Gamma);
1708 //BCAL
1709 CreateAndChangeTo_Directory("BCAL", "BCAL");
1710
1711 locHistName = "BetaVsP_q0";
1712 locHistTitle = "BCAL q^{0};Shower Energy (GeV);#beta";
1713 dHistMap_BetaVsP[SYS_BCAL][0] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxBCALP, dNum2DBetaBins, dMinBeta, dMaxBeta);
1714
1715 locHistName = "DeltaTVsShowerE_Photon";
1716 locHistTitle = string("BCAL q^{0}") + locParticleROOTName + string(";Shower Energy (GeV);#Deltat_{BCAL - RF}");
1717 dHistMap_DeltaTVsP[SYS_BCAL][Gamma] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
1718
1719/*
1720 //Uncomment when ready!
1721 locHistName = "TimePullVsShowerE_Photon";
1722 locHistTitle = string("BCAL ") + locParticleROOTName + string(";Shower Energy (GeV);#Deltat/#sigma_{#Deltat}");
1723 dHistMap_TimePullVsP[SYS_BCAL][Gamma] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPullBins, dMinPull, dMaxPull);
1724
1725 locHistName = "TimeFOMVsShowerE_Photon";
1726 locHistTitle = string("BCAL ") + locParticleROOTName + string(";Shower Energy (GeV);Timing PID Confidence Level");
1727 dHistMap_TimeFOMVsP[SYS_BCAL][Gamma] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
1728*/
1729 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1730
1731 //FCAL
1732 CreateAndChangeTo_Directory("FCAL", "FCAL");
1733
1734 locHistName = "BetaVsP_q0";
1735 locHistTitle = "FCAL q^{0};Shower Energy (GeV);#beta";
1736 dHistMap_BetaVsP[SYS_FCAL][0] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DBetaBins, dMinBeta, dMaxBeta);
1737
1738 locHistName = "DeltaTVsShowerE_Photon";
1739 locHistTitle = string("FCAL ") + locParticleROOTName + string(";Shower Energy (GeV);#Deltat_{FCAL - RF}");
1740 dHistMap_DeltaTVsP[SYS_FCAL][Gamma] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
1741
1742/*
1743 //Uncomment when ready!
1744 locHistName = "TimePullVsShowerE_Photon";
1745 locHistTitle = string("FCAL ") + locParticleROOTName + string(";Shower Energy (GeV);#Deltat/#sigma_{#Deltat}");
1746 dHistMap_TimePullVsP[SYS_FCAL][Gamma] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPullBins, dMinPull, dMaxPull);
1747
1748 locHistName = "TimeFOMVsShowerE_Photon";
1749 locHistTitle = string("FCAL ") + locParticleROOTName + string(";Shower Energy (GeV);Timing PID Confidence Level");
1750 dHistMap_TimeFOMVsP[SYS_FCAL][Gamma] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
1751*/
1752
1753 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1754
1755 //CCAL
1756 CreateAndChangeTo_Directory("CCAL", "CCAL");
1757
1758 locHistName = "BetaVsP_q0";
1759 locHistTitle = "CCAL q^{0};Shower Energy (GeV);#beta";
1760 dHistMap_BetaVsP[SYS_CCAL][0] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DBetaBins, dMinBeta, dMaxBeta);
1761
1762 locHistName = "DeltaTVsShowerE_Photon";
1763 locHistTitle = string("CCAL ") + locParticleROOTName + string(";Shower Energy (GeV);#Deltat_{CCAL - RF}");
1764 dHistMap_DeltaTVsP[SYS_CCAL][Gamma] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
1765
1766 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1767
1768 //q +/-
1769 for(int locCharge = -1; locCharge <= 1; locCharge += 2)
1770 {
1771 string locParticleName = (locCharge == -1) ? "q-" : "q+";
1772 string locParticleROOTName = (locCharge == -1) ? "q^{-}" : "q^{+}";
1773
1774 //SC
1775 CreateAndChangeTo_Directory("SC", "SC");
1776
1777 locHistName = string("dEdXVsP_") + locParticleName;
1778 locHistTitle = locParticleROOTName + ";p (GeV/c);SC dE/dX (MeV/cm)";
1779 dHistMap_dEdXVsP[SYS_START][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DdEdxBins, dMindEdX, dMaxdEdX);
1780
1781 locHistName = string("BetaVsP_") + locParticleName;
1782 locHistTitle = string("SC ") + locParticleROOTName + string(";p (GeV/c);#beta");
1783 dHistMap_BetaVsP[SYS_START][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DBetaBins, dMinBeta, dMaxBeta);
1784
1785 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1786
1787 //TOF
1788 CreateAndChangeTo_Directory("TOF", "TOF");
1789
1790 locHistName = string("dEdXVsP_") + locParticleName;
1791 locHistTitle = locParticleROOTName + ";p (GeV/c);TOF dE/dX (MeV/cm)";
1792 dHistMap_dEdXVsP[SYS_TOF][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DdEdxBins, dMindEdX, dMaxdEdX);
1793
1794 locHistName = string("BetaVsP_") + locParticleName;
1795 locHistTitle = string("TOF ") + locParticleROOTName + string(";p (GeV/c);#beta");
1796 dHistMap_BetaVsP[SYS_TOF][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DBetaBins, dMinBeta, dMaxBeta);
1797
1798 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1799
1800 //BCAL
1801 CreateAndChangeTo_Directory("BCAL", "BCAL");
1802
1803 locHistName = string("BetaVsP_") + locParticleName;
1804 locHistTitle = string("BCAL ") + locParticleROOTName + string(";p (GeV/c);#beta");
1805 dHistMap_BetaVsP[SYS_BCAL][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxBCALP, dNum2DBetaBins, dMinBeta, dMaxBeta);
1806
1807 locHistName = string("EOverPVsP_") + locParticleName;
1808 locHistTitle = string("BCAL ") + locParticleROOTName + string(";p (GeV/c);E_{Shower}/p_{Track} (c);");
1809 dHistMap_BCALEOverPVsP[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxBCALP, dNum2DEOverPBins, dMinEOverP, dMaxEOverP);
1810
1811 locHistName = string("EOverPVsTheta_") + locParticleName;
1812 locHistTitle = string("BCAL ") + locParticleROOTName + string(";#theta#circ;E_{Shower}/p_{Track} (c);");
1813 dHistMap_BCALEOverPVsTheta[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DBCALThetaBins, dMinBCALTheta, dMaxBCALTheta, dNum2DEOverPBins, dMinEOverP, dMaxEOverP);
1814
1815 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1816
1817 //FCAL
1818 CreateAndChangeTo_Directory("FCAL", "FCAL");
1819
1820 locHistName = string("BetaVsP_") + locParticleName;
1821 locHistTitle = string("FCAL ") + locParticleROOTName + string(";p (GeV/c);#beta");
1822 dHistMap_BetaVsP[SYS_FCAL][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DBetaBins, dMinBeta, dMaxBeta);
1823
1824 locHistName = string("EOverPVsP_") + locParticleName;
1825 locHistTitle = string("FCAL ") + locParticleROOTName + string(";p (GeV/c);E_{Shower}/p_{Track} (c);");
1826 dHistMap_FCALEOverPVsP[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DEOverPBins, dMinEOverP, dMaxEOverP);
1827
1828 locHistName = string("EOverPVsTheta_") + locParticleName;
1829 locHistTitle = string("FCAL ") + locParticleROOTName + string(";#theta#circ;E_{Shower}/p_{Track} (c);");
1830 dHistMap_FCALEOverPVsTheta[locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DFCALThetaBins, dMinFCALTheta, dMaxFCALTheta, dNum2DEOverPBins, dMinEOverP, dMaxEOverP);
1831
1832 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1833
1834 //CDC
1835 CreateAndChangeTo_Directory("CDC", "CDC");
1836
1837 locHistName = string("dEdXVsP_Int_") + locParticleName;
1838 locHistTitle = locParticleROOTName + string(";p (GeV/c);CDC dE/dx [Integral-based] (keV/cm)");
1839 dHistMap_dEdXVsP[SYS_CDC][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DdEdxBins, dMindEdX, dMaxdEdX);
1840 locHistName = string("dEdXVsP_Amp_") + locParticleName;
1841 locHistTitle = locParticleROOTName + string(";p (GeV/c);CDC dE/dx [Amplitude-based] (keV/cm)");
1842 dHistMap_dEdXVsP[SYS_CDC_AMP][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DdEdxBins, dMindEdX, dMaxdEdX);
1843
1844 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1845
1846 //FDC
1847 CreateAndChangeTo_Directory("FDC", "FDC");
1848
1849 locHistName = string("dEdXVsP_") + locParticleName;
1850 locHistTitle = locParticleROOTName + string(";p (GeV/c);FDC dE/dx (keV/cm)");
1851 dHistMap_dEdXVsP[SYS_FDC][locCharge] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DdEdxBins, dMindEdX, dMaxdEdX);
1852
1853 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1854 }
1855
1856 //delta's by PID
1857 for(size_t loc_i = 0; loc_i < dFinalStatePIDs.size(); ++loc_i)
1858 {
1859 Particle_t locPID = dFinalStatePIDs[loc_i];
1860 string locParticleName = ParticleType(locPID);
1861 string locParticleROOTName = ParticleName_ROOT(locPID);
1862
1863 //SC
1864 CreateAndChangeTo_Directory("SC", "SC");
1865
1866 locHistName = string("DeltadEdXVsP_") + locParticleName;
1867 locHistTitle = locParticleROOTName + " Candidates;p (GeV/c);SC #Delta(dE/dX) (MeV/cm)";
1868 dHistMap_DeltadEdXVsP[SYS_START][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltadEdxBins, dMinDeltadEdx, dMaxDeltadEdx);
1869
1870 locHistName = string("DeltaBetaVsP_") + locParticleName;
1871 locHistTitle = string("SC ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Delta#beta");
1872 dHistMap_DeltaBetaVsP[SYS_START][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaBetaBins, dMinDeltaBeta, dMaxDeltaBeta);
1873
1874 locHistName = string("DeltaTVsP_") + locParticleName;
1875 locHistTitle = string("SC ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat_{SC - RF}");
1876 dHistMap_DeltaTVsP[SYS_START][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
1877
1878/*
1879 //Uncomment when ready!
1880 locHistName = string("TimePullVsP_") + locParticleName;
1881 locHistTitle = string("SC ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat/#sigma_{#Deltat}");
1882 dHistMap_TimePullVsP[SYS_START][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPullBins, dMinPull, dMaxPull);
1883
1884 locHistName = string("TimeFOMVsP_") + locParticleName;
1885 locHistTitle = string("SC ") + locParticleROOTName + string(" Candidates;p (GeV/c);Timing PID Confidence Level");
1886 dHistMap_TimeFOMVsP[SYS_START][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
1887*/
1888 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1889
1890 //TOF
1891 CreateAndChangeTo_Directory("TOF", "TOF");
1892
1893 locHistName = string("DeltadEdXVsP_") + locParticleName;
1894 locHistTitle = locParticleROOTName + " Candidates;p (GeV/c);TOF #Delta(dE/dX) (MeV/cm)";
1895 dHistMap_DeltadEdXVsP[SYS_TOF][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltadEdxBins, dMinDeltadEdx, dMaxDeltadEdx);
1896
1897 locHistName = string("DeltaBetaVsP_") + locParticleName;
1898 locHistTitle = string("TOF ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Delta#beta");
1899 dHistMap_DeltaBetaVsP[SYS_TOF][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaBetaBins, dMinDeltaBeta, dMaxDeltaBeta);
1900
1901 locHistName = string("DeltaTVsP_") + locParticleName;
1902 locHistTitle = string("TOF ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat_{TOF - RF}");
1903 dHistMap_DeltaTVsP[SYS_TOF][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
1904
1905/*
1906 //Uncomment when ready!
1907 locHistName = string("TimePullVsP_") + locParticleName;
1908 locHistTitle = string("TOF ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat/#sigma_{#Deltat}");
1909 dHistMap_TimePullVsP[SYS_TOF][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPullBins, dMinPull, dMaxPull);
1910
1911 locHistName = string("TimeFOMVsP_") + locParticleName;
1912 locHistTitle = string("TOF ") + locParticleROOTName + string(" Candidates;p (GeV/c);Timing PID Confidence Level");
1913 dHistMap_TimeFOMVsP[SYS_TOF][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
1914*/
1915 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1916
1917 //BCAL
1918 CreateAndChangeTo_Directory("BCAL", "BCAL");
1919
1920 locHistName = string("DeltaBetaVsP_") + locParticleName;
1921 locHistTitle = string("BCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Delta#beta");
1922 dHistMap_DeltaBetaVsP[SYS_BCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxBCALP, dNum2DDeltaBetaBins, dMinDeltaBeta, dMaxDeltaBeta);
1923
1924 locHistName = string("DeltaTVsP_") + locParticleName;
1925 locHistTitle = string("BCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat_{BCAL - RF}");
1926 dHistMap_DeltaTVsP[SYS_BCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
1927
1928/*
1929 //Uncomment when ready!
1930 locHistName = string("TimePullVsP_") + locParticleName;
1931 locHistTitle = string("BCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat/#sigma_{#Deltat}");
1932 dHistMap_TimePullVsP[SYS_BCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPullBins, dMinPull, dMaxPull);
1933
1934 locHistName = string("TimeFOMVsP_") + locParticleName;
1935 locHistTitle = string("BCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);Timing PID Confidence Level");
1936 dHistMap_TimeFOMVsP[SYS_BCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
1937*/
1938 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1939
1940 //FCAL
1941 CreateAndChangeTo_Directory("FCAL", "FCAL");
1942
1943 locHistName = string("DeltaBetaVsP_") + locParticleName;
1944 locHistTitle = string("FCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Delta#beta");
1945 dHistMap_DeltaBetaVsP[SYS_FCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaBetaBins, dMinDeltaBeta, dMaxDeltaBeta);
1946
1947 locHistName = string("DeltaTVsP_") + locParticleName;
1948 locHistTitle = string("FCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat_{FCAL - RF}");
1949 dHistMap_DeltaTVsP[SYS_FCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
1950
1951/*
1952 //Uncomment when ready!
1953 locHistName = string("TimePullVsP_") + locParticleName;
1954 locHistTitle = string("FCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat/#sigma_{#Deltat}");
1955 dHistMap_TimePullVsP[SYS_FCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPullBins, dMinPull, dMaxPull);
1956
1957 locHistName = string("TimeFOMVsP_") + locParticleName;
1958 locHistTitle = string("FCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);Timing PID Confidence Level");
1959 dHistMap_TimeFOMVsP[SYS_FCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
1960*/
1961
1962 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1963
1964 //CCAL
1965 CreateAndChangeTo_Directory("CCAL", "CCAL");
1966
1967 locHistName = string("DeltaBetaVsP_") + locParticleName;
1968 locHistTitle = string("CCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Delta#beta");
1969 dHistMap_DeltaBetaVsP[SYS_CCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaBetaBins, dMinDeltaBeta, dMaxDeltaBeta);
1970
1971 locHistName = string("DeltaTVsP_") + locParticleName;
1972 locHistTitle = string("CCAL ") + locParticleROOTName + string(" Candidates;p (GeV/c);#Deltat_{CCAL - RF}");
1973 dHistMap_DeltaTVsP[SYS_CCAL][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
1974
1975 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1976
1977 //CDC
1978 CreateAndChangeTo_Directory("CDC", "CDC");
1979
1980 locHistName = string("DeltadEdXVsP_Int_") + locParticleName;
1981 locHistTitle = locParticleROOTName + string(" Candidates;p (GeV/c);CDC #Delta(dE/dX) [Integral-based] (keV/cm)");
1982 dHistMap_DeltadEdXVsP[SYS_CDC][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltadEdxBins, dMinDeltadEdx, dMaxDeltadEdx);
1983
1984 locHistName = string("DeltadEdXVsP_Amp_") + locParticleName;
1985 locHistTitle = locParticleROOTName + string(" Candidates;p (GeV/c);CDC #Delta(dE/dX) [Amplitude-based] (keV/cm)");
1986 dHistMap_DeltadEdXVsP[SYS_CDC_AMP][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltadEdxBins, dMinDeltadEdx, dMaxDeltadEdx);
1987
1988/*
1989 //Uncomment when ready!
1990 locHistName = string("dEdXPullVsP_") + locParticleName;
1991 locHistTitle = locParticleROOTName + string(" Candidates;p (GeV/c);CDC #Delta(dE/dX)/#sigma_{#Delta(dE/dX)}");
1992 dHistMap_dEdXPullVsP[SYS_CDC][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPullBins, dMinPull, dMaxPull);
1993
1994 locHistName = string("dEdXFOMVsP_") + locParticleName;
1995 locHistTitle = locParticleROOTName + string(" Candidates;p (GeV/c);CDC dE/dx PID Confidence Level");
1996 dHistMap_dEdXFOMVsP[SYS_CDC][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
1997*/
1998 gDirectory(TDirectory::CurrentDirectory())->cd("..");
1999
2000 //FDC
2001 CreateAndChangeTo_Directory("FDC", "FDC");
2002
2003 locHistName = string("DeltadEdXVsP_") + locParticleName;
2004 locHistTitle = locParticleROOTName + string(" Candidates;p (GeV/c);FDC #Delta(dE/dX) (keV/cm)");
2005 dHistMap_DeltadEdXVsP[SYS_FDC][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltadEdxBins, dMinDeltadEdx, dMaxDeltadEdx);
2006
2007/*
2008 //Uncomment when ready!
2009 locHistName = string("dEdXPullVsP_") + locParticleName;
2010 locHistTitle = locParticleROOTName + string(" Candidates;p (GeV/c);FDC #Delta(dE/dX)/#sigma_{#Delta(dE/dX)}");
2011 dHistMap_dEdXPullVsP[SYS_FDC][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPullBins, dMinPull, dMaxPull);
2012
2013 locHistName = string("dEdXFOMVsP_") + locParticleName;
2014 locHistTitle = locParticleROOTName + string(" Candidates;p (GeV/c);FDC dE/dx PID Confidence Level");
2015 dHistMap_dEdXFOMVsP[SYS_FDC][locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DFOMBins, 0.0, 1.0);
2016*/
2017 gDirectory(TDirectory::CurrentDirectory())->cd("..");
2018
2019 // DIRC
2020 CreateAndChangeTo_Directory("DIRC", "DIRC");
2021
2022 locHistName = string("NumPhotons_") + locParticleName;
2023 locHistTitle = locParticleROOTName + string("; DIRC NumPhotons");
2024 dHistMap_NumPhotons_DIRC[locPID] = new TH1I(locHistName.c_str(), locHistTitle.c_str(), dDIRCNumPhotonsBins, dDIRCMinNumPhotons, dDIRCMaxNumPhotons);
2025
2026 locHistName = string("ThetaCVsP_") + locParticleName;
2027 locHistTitle = locParticleROOTName + string("; Momentum (GeV); DIRC #theta_{C}");
2028 dHistMap_ThetaCVsP_DIRC[locPID] = new TH2I(locHistName.c_str(), locHistTitle.c_str(), dNum2DPBins, dMinP, dMaxP, dDIRCThetaCBins, dDIRCMinThetaC, dDIRCMaxThetaC);
2029
2030 locHistName = string("Ldiff_kpiVsP_") + locParticleName;
2031 locHistTitle = locParticleROOTName + string("; Momentum (GeV); DIRC L_{K}-L_{#pi}");
2032 dHistMap_Ldiff_kpiVsP_DIRC[locPID] = new TH2I(locHistName.c_str(), locHistTitle.c_str(), dNum2DPBins, dMinP, dMaxP, dDIRCLikelihoodBins, -1*dDIRCMaxLikelihood, dDIRCMaxLikelihood);
2033
2034 locHistName = string("Ldiff_pkVsP_") + locParticleName;
2035 locHistTitle = locParticleROOTName + string("; Momentum (GeV); DIRC L_{p}-L_{K}");
2036 dHistMap_Ldiff_pkVsP_DIRC[locPID] = new TH2I(locHistName.c_str(), locHistTitle.c_str(), dNum2DPBins, dMinP, dMaxP, dDIRCLikelihoodBins, -1*dDIRCMaxLikelihood, dDIRCMaxLikelihood);
2037
2038 gDirectory(TDirectory::CurrentDirectory())->cd("..");
2039 }
2040
2041 //Return to the base directory
2042 ChangeTo_BaseDirectory();
2043 }
2044 japp->RootUnLock(); //RELEASE ROOT LOCK!!
2045}
2046
2047bool DHistogramAction_DetectorPID::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
2048{
2049 //Expect locParticleCombo to be NULL since this is a reaction-independent action.
2050
2051 if(Get_CalledPriorWithComboFlag())
2052 return true; //else double-counting!
2053
2054 vector<const DChargedTrack*> locChargedTracks;
2055 locEventLoop->Get(locChargedTracks, dTrackSelectionTag.c_str());
2056
2057 vector<const DNeutralParticle*> locNeutralParticles;
2058 locEventLoop->Get(locNeutralParticles, dShowerSelectionTag.c_str());
2059
2060 const DDetectorMatches* locDetectorMatches = NULL__null;
2061 locEventLoop->GetSingle(locDetectorMatches);
2062
2063 const DEventRFBunch* locEventRFBunch = NULL__null;
2064 locEventLoop->GetSingle(locEventRFBunch);
2065
2066 const DParticleID* locParticleID = NULL__null;
2067 locEventLoop->GetSingle(locParticleID);
2068
2069 //FILL HISTOGRAMS
2070 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
2071 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
2072 Lock_Action(); //ACQUIRE ROOT LOCK!!
2073 {
2074 if(locEventRFBunch->dTimeSource != SYS_NULL) //only histogram beta for neutrals if the t0 is well known
2075 {
2076 for(size_t loc_i = 0; loc_i < locNeutralParticles.size(); ++loc_i)
2077 {
2078 //doesn't matter which hypothesis you use for beta: t0 is from DEventVertex time
2079 const DNeutralParticleHypothesis* locNeutralParticleHypothesis = locNeutralParticles[loc_i]->Get_BestFOM();
2080 double locBeta_Timing = locNeutralParticleHypothesis->measuredBeta();
2081 const DNeutralShower* locNeutralShower = locNeutralParticles[loc_i]->dNeutralShower;
2082 double locShowerEnergy = locNeutralShower->dEnergy;
2083
2084 double locDeltaT = locNeutralParticleHypothesis->time() - locEventRFBunch->dTime;
2085 if(locNeutralShower->dDetectorSystem == SYS_BCAL)
2086 {
2087 dHistMap_BetaVsP[SYS_BCAL][0]->Fill(locShowerEnergy, locBeta_Timing);
2088 dHistMap_DeltaTVsP[SYS_BCAL][Gamma]->Fill(locShowerEnergy, locDeltaT);
2089 }
2090 else if(locNeutralShower->dDetectorSystem == SYS_FCAL)
2091 {
2092 dHistMap_BetaVsP[SYS_FCAL][0]->Fill(locShowerEnergy, locBeta_Timing);
2093 dHistMap_DeltaTVsP[SYS_FCAL][Gamma]->Fill(locShowerEnergy, locDeltaT);
2094 }
2095 else if(locNeutralShower->dDetectorSystem == SYS_CCAL)
2096 {
2097 dHistMap_BetaVsP[SYS_CCAL][0]->Fill(locShowerEnergy, locBeta_Timing);
2098 dHistMap_DeltaTVsP[SYS_CCAL][Gamma]->Fill(locShowerEnergy, locDeltaT);
2099 }
2100 }
2101 }
2102
2103 for(size_t loc_i = 0; loc_i < locChargedTracks.size(); ++loc_i)
2104 {
2105 const DChargedTrackHypothesis* locChargedTrackHypothesis = locChargedTracks[loc_i]->Get_BestTrackingFOM();
2106 int locCharge = ParticleCharge(locChargedTrackHypothesis->PID());
2107 if(dHistMap_dEdXVsP[SYS_START].find(locCharge) == dHistMap_dEdXVsP[SYS_START].end())
2108 continue;
2109
2110 double locStartTime = locParticleID->Calc_PropagatedRFTime(locChargedTrackHypothesis, locEventRFBunch);
2111 auto locTrackTimeBased = locChargedTrackHypothesis->Get_TrackTimeBased();
2112
2113 Particle_t locPID = locChargedTrackHypothesis->PID();
2114 double locP = locTrackTimeBased->momentum().Mag();
2115 double locTheta = locTrackTimeBased->momentum().Theta()*180.0/TMath::Pi();
2116
2117 //if RF time is indeterminate, start time will be NaN
2118 auto locBCALShowerMatchParams = locChargedTrackHypothesis->Get_BCALShowerMatchParams();
2119 auto locFCALShowerMatchParams = locChargedTrackHypothesis->Get_FCALShowerMatchParams();
2120 auto locTOFHitMatchParams = locChargedTrackHypothesis->Get_TOFHitMatchParams();
2121 auto locSCHitMatchParams = locChargedTrackHypothesis->Get_SCHitMatchParams();
2122 auto locDIRCMatchParams = locChargedTrackHypothesis->Get_DIRCMatchParams();
2123
2124 if(locSCHitMatchParams != NULL__null)
2125 {
2126 dHistMap_dEdXVsP[SYS_START][locCharge]->Fill(locP, locSCHitMatchParams->dEdx*1.0E3);
2127 if((locEventRFBunch->dTimeSource != SYS_START) && (locEventRFBunch->dNumParticleVotes > 1))
2128 {
2129 //If SC was used for RF time, don't compute delta-beta
2130 double locBeta_Timing = locSCHitMatchParams->dPathLength/(29.9792458*(locSCHitMatchParams->dHitTime - locChargedTrackHypothesis->t0()));
2131 dHistMap_BetaVsP[SYS_START][locCharge]->Fill(locP, locBeta_Timing);
2132 if(dHistMap_DeltaBetaVsP[SYS_START].find(locPID) != dHistMap_DeltaBetaVsP[SYS_START].end())
2133 {
2134 double locDeltaBeta = locChargedTrackHypothesis->lorentzMomentum().Beta() - locBeta_Timing;
2135 dHistMap_DeltaBetaVsP[SYS_START][locPID]->Fill(locP, locDeltaBeta);
2136 double locDeltaT = locSCHitMatchParams->dHitTime - locSCHitMatchParams->dFlightTime - locStartTime;
2137 dHistMap_DeltaTVsP[SYS_START][locPID]->Fill(locP, locDeltaT);
2138 }
2139 }
2140 if(dHistMap_DeltadEdXVsP[SYS_START].find(locPID) != dHistMap_DeltadEdXVsP[SYS_START].end())
2141 {
2142 double locdx = locSCHitMatchParams->dHitEnergy/locSCHitMatchParams->dEdx;
2143 double locProbabledEdx = 0.0, locSigmadEdx = 0.0;
2144 locParticleID->GetScintMPdEandSigma(locP, locChargedTrackHypothesis->mass(), locdx, locProbabledEdx, locSigmadEdx);
2145 dHistMap_DeltadEdXVsP[SYS_START][locPID]->Fill(locP, (locSCHitMatchParams->dEdx - locProbabledEdx)*1.0E3);
2146 }
2147 }
2148 if(locTOFHitMatchParams != NULL__null)
2149 {
2150 dHistMap_dEdXVsP[SYS_TOF][locCharge]->Fill(locP, locTOFHitMatchParams->dEdx*1.0E3);
2151 if(locEventRFBunch->dNumParticleVotes > 1)
2152 {
2153 double locBeta_Timing = locTOFHitMatchParams->dPathLength/(29.9792458*(locTOFHitMatchParams->dHitTime - locChargedTrackHypothesis->t0()));
2154 dHistMap_BetaVsP[SYS_TOF][locCharge]->Fill(locP, locBeta_Timing);
2155 if(dHistMap_DeltaBetaVsP[SYS_TOF].find(locPID) != dHistMap_DeltaBetaVsP[SYS_TOF].end())
2156 {
2157 double locDeltaBeta = locChargedTrackHypothesis->lorentzMomentum().Beta() - locBeta_Timing;
2158 dHistMap_DeltaBetaVsP[SYS_TOF][locPID]->Fill(locP, locDeltaBeta);
2159 double locDeltaT = locTOFHitMatchParams->dHitTime - locTOFHitMatchParams->dFlightTime - locStartTime;
2160 dHistMap_DeltaTVsP[SYS_TOF][locPID]->Fill(locP, locDeltaT);
2161 }
2162 }
2163 if(dHistMap_DeltadEdXVsP[SYS_TOF].find(locPID) != dHistMap_DeltadEdXVsP[SYS_TOF].end())
2164 {
2165 double locdx = locTOFHitMatchParams->dHitEnergy/locTOFHitMatchParams->dEdx;
2166 double locProbabledEdx = 0.0, locSigmadEdx = 0.0;
2167 locParticleID->GetScintMPdEandSigma(locP, locChargedTrackHypothesis->mass(), locdx, locProbabledEdx, locSigmadEdx);
2168 dHistMap_DeltadEdXVsP[SYS_TOF][locPID]->Fill(locP, (locTOFHitMatchParams->dEdx - locProbabledEdx)*1.0E3);
2169 }
2170 }
2171 if(locBCALShowerMatchParams != NULL__null)
2172 {
2173 const DBCALShower* locBCALShower = locBCALShowerMatchParams->dBCALShower;
2174 double locEOverP = locBCALShower->E/locP;
2175 dHistMap_BCALEOverPVsP[locCharge]->Fill(locP, locEOverP);
2176 dHistMap_BCALEOverPVsTheta[locCharge]->Fill(locTheta, locEOverP);
2177 if(locEventRFBunch->dNumParticleVotes > 1)
2178 {
2179 double locBeta_Timing = locBCALShowerMatchParams->dPathLength/(29.9792458*(locBCALShower->t - locChargedTrackHypothesis->t0()));
2180 dHistMap_BetaVsP[SYS_BCAL][locCharge]->Fill(locP, locBeta_Timing);
2181 if(dHistMap_DeltaBetaVsP[SYS_BCAL].find(locPID) != dHistMap_DeltaBetaVsP[SYS_BCAL].end())
2182 {
2183 double locDeltaBeta = locChargedTrackHypothesis->lorentzMomentum().Beta() - locBeta_Timing;
2184 dHistMap_DeltaBetaVsP[SYS_BCAL][locPID]->Fill(locP, locDeltaBeta);
2185 double locDeltaT = locBCALShower->t - locBCALShowerMatchParams->dFlightTime - locStartTime;
2186 dHistMap_DeltaTVsP[SYS_BCAL][locPID]->Fill(locP, locDeltaT);
2187 }
2188 }
2189 }
2190 if(locFCALShowerMatchParams != NULL__null)
2191 {
2192 const DFCALShower* locFCALShower = locFCALShowerMatchParams->dFCALShower;
2193 double locEOverP = locFCALShower->getEnergy()/locP;
2194 dHistMap_FCALEOverPVsP[locCharge]->Fill(locP, locEOverP);
2195 dHistMap_FCALEOverPVsTheta[locCharge]->Fill(locTheta, locEOverP);
2196 if(locEventRFBunch->dNumParticleVotes > 1)
2197 {
2198 double locBeta_Timing = locFCALShowerMatchParams->dPathLength/(29.9792458*(locFCALShower->getTime() - locChargedTrackHypothesis->t0()));
2199 dHistMap_BetaVsP[SYS_FCAL][locCharge]->Fill(locP, locBeta_Timing);
2200 if(dHistMap_DeltaBetaVsP[SYS_FCAL].find(locPID) != dHistMap_DeltaBetaVsP[SYS_FCAL].end())
2201 {
2202 double locDeltaBeta = locChargedTrackHypothesis->lorentzMomentum().Beta() - locBeta_Timing;
2203 dHistMap_DeltaBetaVsP[SYS_FCAL][locPID]->Fill(locP, locDeltaBeta);
2204 double locDeltaT = locFCALShower->getTime() - locFCALShowerMatchParams->dFlightTime - locStartTime;
2205 dHistMap_DeltaTVsP[SYS_FCAL][locPID]->Fill(locP, locDeltaT);
2206 }
2207 }
2208 }
2209 if(locDIRCMatchParams != NULL__null && (dHistMap_NumPhotons_DIRC.find(locPID) != dHistMap_NumPhotons_DIRC.end())) {
2210 int locNumPhotons_DIRC = locDIRCMatchParams->dNPhotons;
2211 double locThetaC_DIRC = locDIRCMatchParams->dThetaC;
2212 dHistMap_NumPhotons_DIRC[locPID]->Fill(locNumPhotons_DIRC);
2213 dHistMap_ThetaCVsP_DIRC[locPID]->Fill(locP, locThetaC_DIRC);
2214 double locLpi_DIRC = locDIRCMatchParams->dLikelihoodPion;
2215 double locLk_DIRC = locDIRCMatchParams->dLikelihoodKaon;
2216 double locLp_DIRC = locDIRCMatchParams->dLikelihoodProton;
2217 dHistMap_Ldiff_kpiVsP_DIRC[locPID]->Fill(locP, locLk_DIRC-locLpi_DIRC);
2218 dHistMap_Ldiff_pkVsP_DIRC[locPID]->Fill(locP, locLp_DIRC-locLk_DIRC);
2219 }
2220
2221 if(locTrackTimeBased->dNumHitsUsedFordEdx_CDC > 0)
2222 {
2223 dHistMap_dEdXVsP[SYS_CDC][locCharge]->Fill(locP, locTrackTimeBased->ddEdx_CDC*1.0E6);
2224 dHistMap_dEdXVsP[SYS_CDC_AMP][locCharge]->Fill(locP, locTrackTimeBased->ddEdx_CDC_amp*1.0E6);
2225 if(dHistMap_DeltadEdXVsP[SYS_CDC].find(locPID) != dHistMap_DeltadEdXVsP[SYS_CDC].end())
2226 {
2227 double locProbabledEdx = locParticleID->GetMostProbabledEdx_DC(locP, locChargedTrackHypothesis->mass(), locTrackTimeBased->ddx_CDC, true);
2228 dHistMap_DeltadEdXVsP[SYS_CDC][locPID]->Fill(locP, (locTrackTimeBased->ddEdx_CDC - locProbabledEdx)*1.0E6);
2229 }
2230 if(dHistMap_DeltadEdXVsP[SYS_CDC_AMP].find(locPID) != dHistMap_DeltadEdXVsP[SYS_CDC_AMP].end())
2231 {
2232 double locProbabledEdx = locParticleID->GetMostProbabledEdx_DC(locP, locChargedTrackHypothesis->mass(), locTrackTimeBased->ddx_CDC_amp, true);
2233 dHistMap_DeltadEdXVsP[SYS_CDC_AMP][locPID]->Fill(locP, (locTrackTimeBased->ddEdx_CDC_amp - locProbabledEdx)*1.0E6);
2234 }
2235 }
2236 if(locTrackTimeBased->dNumHitsUsedFordEdx_FDC > 0)
2237 {
2238 dHistMap_dEdXVsP[SYS_FDC][locCharge]->Fill(locP, locTrackTimeBased->ddEdx_FDC*1.0E6);
2239 if(dHistMap_DeltadEdXVsP[SYS_FDC].find(locPID) != dHistMap_DeltadEdXVsP[SYS_FDC].end())
2240 {
2241 double locProbabledEdx = locParticleID->GetMostProbabledEdx_DC(locP, locChargedTrackHypothesis->mass(), locTrackTimeBased->ddx_FDC, false);
2242 dHistMap_DeltadEdXVsP[SYS_FDC][locPID]->Fill(locP, (locTrackTimeBased->ddEdx_FDC - locProbabledEdx)*1.0E6);
2243 }
2244 }
2245 }
2246 }
2247 Unlock_Action(); //RELEASE ROOT LOCK!!
2248
2249 return true; //return false if you want to use this action to apply a cut (and it fails the cut!)
2250}
2251
2252void DHistogramAction_Neutrals::Initialize(JEventLoop* locEventLoop)
2253{
2254 //Create any histograms/trees/etc. within a ROOT lock.
2255 //This is so that when running multithreaded, only one thread is writing to the ROOT file at a time.
2256
2257 //When creating a reaction-independent action, only modify member variables within a ROOT lock.
2258 //Objects created within a plugin (such as reaction-independent actions) can be accessed by many threads simultaneously.
2259
2260 Run_Update(locEventLoop);
2261
2262 string locHistName;
2263
2264 //CREATE THE HISTOGRAMS
2265 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
2266 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
2267 {
2268 //Required: Create a folder in the ROOT output file that will contain all of the output ROOT objects (if any) for this action.
2269 //If another thread has already created the folder, it just changes to it.
2270 CreateAndChangeTo_ActionDirectory();
2271
2272
2273 //BCAL
2274 locHistName = "BCALTrackDOCA";
2275 dHist_BCALTrackDOCA = GetOrCreate_Histogram<TH1I>(locHistName, ";BCAL Shower Distance to Nearest Track (cm)", dNumTrackDOCABins, dMinTrackDOCA, dMaxTrackDOCA);
2276 locHistName = "BCALTrackDeltaPhi";
2277 dHist_BCALTrackDeltaPhi = GetOrCreate_Histogram<TH1I>(locHistName, ";BCAL Shower #Delta#phi#circ to Nearest Track", dNumDeltaPhiBins, dMinDeltaPhi, dMaxDeltaPhi);
2278 locHistName = "BCALTrackDeltaZ";
2279 dHist_BCALTrackDeltaZ = GetOrCreate_Histogram<TH1I>(locHistName, ";BCAL Shower #DeltaZ to Nearest Track (cm)", dNumTrackDOCABins, dMinTrackDOCA, dMaxTrackDOCA);
2280 locHistName = "BCALNeutralShowerEnergy";
2281 dHist_BCALNeutralShowerEnergy = GetOrCreate_Histogram<TH1I>(locHistName, ";BCAL Neutral Shower Energy (GeV)", dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
2282 locHistName = "BCALNeutralShowerDeltaT";
2283 dHist_BCALNeutralShowerDeltaT = GetOrCreate_Histogram<TH1I>(locHistName, ";BCAL Neutral Shower #Deltat (Propagated - RF) (ns)", dNumDeltaTBins, dMinDeltaT, dMaxDeltaT);
2284 locHistName = "BCALNeutralShowerDeltaTVsE";
2285 dHist_BCALNeutralShowerDeltaTVsE = GetOrCreate_Histogram<TH2I>(locHistName, ";BCAL Neutral Shower Energy (GeV);BCAL Neutral Shower #Deltat (ns)", dNum2DShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
2286 locHistName = "BCALNeutralShowerDeltaTVsZ";
2287 dHist_BCALNeutralShowerDeltaTVsZ = GetOrCreate_Histogram<TH2I>(locHistName, ";BCAL Neutral Shower Z (cm);BCAL Neutral Shower #Deltat (ns)", dNum2DBCALZBins, 0.0, 450.0, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
2288
2289 //FCAL
2290 locHistName = "FCALTrackDOCA";
2291 dHist_FCALTrackDOCA = GetOrCreate_Histogram<TH1I>(locHistName, ";FCAL Shower Distance to Nearest Track (cm)", dNumTrackDOCABins, dMinTrackDOCA, dMaxTrackDOCA);
2292 locHistName = "FCALNeutralShowerEnergy";
2293 dHist_FCALNeutralShowerEnergy = GetOrCreate_Histogram<TH1I>(locHistName, ";FCAL Neutral Shower Energy (GeV)", dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
2294 locHistName = "FCALNeutralShowerDeltaT";
2295 dHist_FCALNeutralShowerDeltaT = GetOrCreate_Histogram<TH1I>(locHistName, ";FCAL Neutral Shower #Deltat (Propagated - RF) (ns)", dNumDeltaTBins, dMinDeltaT, dMaxDeltaT);
2296 locHistName = "FCALNeutralShowerDeltaTVsE";
2297 dHist_FCALNeutralShowerDeltaTVsE = GetOrCreate_Histogram<TH2I>(locHistName, ";FCAL Neutral Shower Energy (GeV);FCAL Neutral Shower #Deltat (ns)", dNum2DShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
2298
2299
2300 //CCAL
2301 //locHistName = "CCALTrackDOCA";
2302 //dHist_CCALTrackDOCA = GetOrCreate_Histogram<TH1I>(locHistName, ";CCAL Shower Distance to Nearest Track (cm)", dNumTrackDOCABins, dMinTrackDOCA, dMaxTrackDOCA);
2303 locHistName = "CCALNeutralShowerEnergy";
2304 dHist_CCALNeutralShowerEnergy = GetOrCreate_Histogram<TH1I>(locHistName, ";CCAL Neutral Shower Energy (GeV)", dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
2305 locHistName = "CCALNeutralShowerDeltaT";
2306 dHist_CCALNeutralShowerDeltaT = GetOrCreate_Histogram<TH1I>(locHistName, ";CCAL Neutral Shower #Deltat (Propagated - RF) (ns)", dNumDeltaTBins, dMinDeltaT, dMaxDeltaT);
2307 locHistName = "CCALNeutralShowerDeltaTVsE";
2308 dHist_CCALNeutralShowerDeltaTVsE = GetOrCreate_Histogram<TH2I>(locHistName, ";CCAL Neutral Shower Energy (GeV);CCAL Neutral Shower #Deltat (ns)", dNum2DShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy, dNum2DDeltaTBins, dMinDeltaT, dMaxDeltaT);
2309
2310 //Return to the base directory
2311 ChangeTo_BaseDirectory();
2312 }
2313 japp->RootUnLock(); //RELEASE ROOT LOCK!!
2314}
2315
2316void DHistogramAction_Neutrals::Run_Update(JEventLoop* locEventLoop)
2317{
2318 DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
2319 DGeometry* locGeometry = locApplication->GetDGeometry(locEventLoop->GetJEvent().GetRunNumber());
2320 double locTargetZCenter = 0.0;
2321 locGeometry->GetTargetZ(locTargetZCenter);
2322
2323 if(dTargetCenter.Z() < -9.8E9)
2324 dTargetCenter.SetXYZ(0.0, 0.0, locTargetZCenter);
2325}
2326
2327bool DHistogramAction_Neutrals::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
2328{
2329 //Expect locParticleCombo to be NULL since this is a reaction-independent action.
2330
2331 if(Get_CalledPriorWithComboFlag())
2332 return true; //else double-counting!
2333
2334 vector<const DNeutralShower*> locNeutralShowers;
2335 locEventLoop->Get(locNeutralShowers);
2336
2337 vector<const DTrackTimeBased*> locTrackTimeBasedVector;
2338 locEventLoop->Get(locTrackTimeBasedVector);
2339
2340 const DDetectorMatches* locDetectorMatches = NULL__null;
2341 locEventLoop->GetSingle(locDetectorMatches);
2342
2343 vector<const DEventRFBunch*> locEventRFBunches;
2344 locEventLoop->Get(locEventRFBunches);
2345 double locStartTime = locEventRFBunches.empty() ? 0.0 : locEventRFBunches[0]->dTime;
2346
2347 //FILL HISTOGRAMS
2348 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
2349 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
2350 Lock_Action(); //ACQUIRE ROOT LOCK!!
2351 {
2352 for(size_t loc_i = 0; loc_i < locNeutralShowers.size(); ++loc_i)
2353 {
2354 //assume is photon
2355 double locPathLength = (locNeutralShowers[loc_i]->dSpacetimeVertex.Vect() - dTargetCenter).Mag();
2356 double locDeltaT = locNeutralShowers[loc_i]->dSpacetimeVertex.T() - locPathLength/29.9792458 - locStartTime;
2357
2358 if(locNeutralShowers[loc_i]->dDetectorSystem == SYS_FCAL)
2359 {
2360 const DFCALShower* locFCALShower = NULL__null;
2361 locNeutralShowers[loc_i]->GetSingle(locFCALShower);
2362
2363 double locDistance = 9.9E9;
2364 if(locDetectorMatches->Get_DistanceToNearestTrack(locFCALShower, locDistance))
2365 dHist_FCALTrackDOCA->Fill(locDistance);
2366
2367 dHist_FCALNeutralShowerEnergy->Fill(locNeutralShowers[loc_i]->dEnergy);
2368 dHist_FCALNeutralShowerDeltaT->Fill(locDeltaT);
2369 dHist_FCALNeutralShowerDeltaTVsE->Fill(locNeutralShowers[loc_i]->dEnergy, locDeltaT);
2370 }
2371 else if(locNeutralShowers[loc_i]->dDetectorSystem == SYS_BCAL)
2372 {
2373 const DBCALShower* locBCALShower = NULL__null;
2374 locNeutralShowers[loc_i]->GetSingle(locBCALShower);
2375
2376 double locDistance = 9.9E9, locDeltaPhi = 9.9E9, locDeltaZ = 9.9E9;
2377 if(locDetectorMatches->Get_DistanceToNearestTrack(locBCALShower, locDistance))
2378 dHist_BCALTrackDOCA->Fill(locDistance);
2379 if(locDetectorMatches->Get_DistanceToNearestTrack(locBCALShower, locDeltaPhi, locDeltaZ))
2380 {
2381 dHist_BCALTrackDeltaPhi->Fill(180.0*locDeltaPhi/TMath::Pi());
2382 dHist_BCALTrackDeltaZ->Fill(locDeltaZ);
2383 }
2384
2385 dHist_BCALNeutralShowerEnergy->Fill(locNeutralShowers[loc_i]->dEnergy);
2386 dHist_BCALNeutralShowerDeltaT->Fill(locDeltaT);
2387 dHist_BCALNeutralShowerDeltaTVsE->Fill(locNeutralShowers[loc_i]->dEnergy, locDeltaT);
2388 dHist_BCALNeutralShowerDeltaTVsZ->Fill(locNeutralShowers[loc_i]->dSpacetimeVertex.Z(), locDeltaT);
2389 }
2390 else if(locNeutralShowers[loc_i]->dDetectorSystem == SYS_CCAL)
2391 {
2392 const DCCALShower* locCCALShower = NULL__null;
2393 locNeutralShowers[loc_i]->GetSingle(locCCALShower);
2394
2395 //double locDistance = 9.9E9;
2396 //if(locDetectorMatches->Get_DistanceToNearestTrack(locFCALShower, locDistance))
2397 // dHist_FCALTrackDOCA->Fill(locDistance);
2398
2399 dHist_CCALNeutralShowerEnergy->Fill(locNeutralShowers[loc_i]->dEnergy);
2400 dHist_CCALNeutralShowerDeltaT->Fill(locDeltaT);
2401 dHist_CCALNeutralShowerDeltaTVsE->Fill(locNeutralShowers[loc_i]->dEnergy, locDeltaT);
2402 }
2403 }
2404 }
2405 Unlock_Action(); //RELEASE ROOT LOCK!!
2406
2407 return true; //return false if you want to use this action to apply a cut (and it fails the cut!)
2408}
2409
2410void DHistogramAction_DetectorMatchParams::Initialize(JEventLoop* locEventLoop)
2411{
2412 //Create any histograms/trees/etc. within a ROOT lock.
2413 //This is so that when running multithreaded, only one thread is writing to the ROOT file at a time.
2414
2415 //When creating a reaction-independent action, only modify member variables within a ROOT lock.
2416 //Objects created within a plugin (such as reaction-independent actions) can be accessed by many threads simultaneously.
2417
2418 string locHistName, locHistTitle;
2419
2420 Run_Update(locEventLoop);
2421
2422 vector<const DMCThrown*> locMCThrowns;
2423 locEventLoop->Get(locMCThrowns);
2424
2425 string locTrackSelectionTag = "NotATag";
2426 if(gPARMS->Exists("COMBO:TRACK_SELECT_TAG"))
2427 gPARMS->GetParameter("COMBO:TRACK_SELECT_TAG", locTrackSelectionTag);
2428
2429 //CREATE THE HISTOGRAMS
2430 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
2431 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
2432 {
2433 //So: Default tag is "", User can set it to something else
2434 //In here, if tag is "", get from gparms, if not, leave it alone
2435 //If gparms value does not exist, set it to (and use) "PreSelect"
2436 if(dTrackSelectionTag == "NotATag")
2437 dTrackSelectionTag = (locTrackSelectionTag == "NotATag") ? "PreSelect" : locTrackSelectionTag;
2438
2439 //Required: Create a folder in the ROOT output file that will contain all of the output ROOT objects (if any) for this action.
2440 //If another thread has already created the folder, it just changes to it.
2441 CreateAndChangeTo_ActionDirectory();
2442
2443 //Track Matched to Hit
2444 for(int locTruePIDFlag = 0; locTruePIDFlag < 2; ++locTruePIDFlag)
2445 {
2446 if(locMCThrowns.empty() && (locTruePIDFlag == 1))
2447 continue; //not a simulated event: don't histogram thrown info!
2448
2449 string locDirName = (locTruePIDFlag == 1) ? "TruePID" : "ReconstructedPID";
2450 CreateAndChangeTo_Directory(locDirName.c_str(), locDirName.c_str());
2451
2452 //By PID
2453 for(int loc_i = -2; loc_i < int(dTrackingPIDs.size()); ++loc_i) //-2 = q-, -1 = q+
2454 {
2455 string locParticleName, locParticleROOTName;
2456 int locPID = loc_i;
2457 if(loc_i == -2)
2458 {
2459 locParticleName = "q-";
2460 locParticleROOTName = "#it{q}^{-}";
2461 }
2462 else if(loc_i == -1)
2463 {
2464 locParticleName = "q+";
2465 locParticleROOTName = "#it{q}^{+}";
2466 }
2467 else
2468 {
2469 locParticleName = ParticleType(dTrackingPIDs[loc_i]);
2470 locParticleROOTName = ParticleName_ROOT(dTrackingPIDs[loc_i]);
2471 locPID = int(dTrackingPIDs[loc_i]);
2472 }
2473 CreateAndChangeTo_Directory(locParticleName, locParticleName);
2474 pair<int, bool> locPIDPair(locPID, bool(locTruePIDFlag));
2475
2476 //BCAL
2477 locHistName = "BCALShowerEnergy";
2478 locHistTitle = locParticleROOTName + ";BCAL Shower Energy (GeV)";
2479 dHistMap_BCALShowerEnergy[locPIDPair] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
2480
2481 locHistName = "BCALShowerTrackDepth";
2482 locHistTitle = locParticleROOTName + ";BCAL Shower Track Depth (cm)";
2483 dHistMap_BCALShowerTrackDepth[locPIDPair] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumShowerDepthBins, dMinShowerDepth, dMaxShowerDepth);
2484
2485 locHistName = "BCALShowerTrackDepthVsP";
2486 locHistTitle = locParticleROOTName + ";p (GeV/c);BCAL Shower Track Depth (cm)";
2487 dHistMap_BCALShowerTrackDepthVsP[locPIDPair] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxBCALP, dNumShowerDepthBins, dMinShowerDepth, dMaxShowerDepth);
2488
2489 //FCAL
2490 locHistName = "FCALShowerEnergy";
2491 locHistTitle = locParticleROOTName + ";FCAL Shower Energy (GeV)";
2492 dHistMap_FCALShowerEnergy[locPIDPair] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
2493
2494 locHistName = "FCALShowerTrackDepth";
2495 locHistTitle = locParticleROOTName + ";FCAL Shower Track Depth (cm)";
2496 dHistMap_FCALShowerTrackDepth[locPIDPair] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumShowerDepthBins, dMinShowerDepth, dMaxShowerDepth);
2497
2498 locHistName = "FCALShowerTrackDepthVsP";
2499 locHistTitle = locParticleROOTName + ";p (GeV/c);FCAL Shower Track Depth (cm)";
2500 dHistMap_FCALShowerTrackDepthVsP[locPIDPair] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNumShowerDepthBins, dMinShowerDepth, dMaxShowerDepth);
2501
2502 //CCAL
2503 locHistName = "CCALShowerEnergy";
2504 locHistTitle = locParticleROOTName + ";CCAL Shower Energy (GeV)";
2505 dHistMap_CCALShowerEnergy[locPIDPair] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumShowerEnergyBins, dMinShowerEnergy, dMaxShowerEnergy);
2506
2507 //SC
2508 locHistName = "SCEnergyVsTheta";
2509 locHistTitle = locParticleROOTName + ";#theta#circ;SC Point Energy (MeV)";
2510 dHistMap_SCEnergyVsTheta[locPIDPair] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DHitEnergyBins, dMinHitEnergy, dMaxHitEnergy);
2511
2512 locHistName = "SCPhiVsTheta";
2513 locHistTitle = locParticleROOTName + ";#theta#circ;#phi#circ";
2514 dHistMap_SCPhiVsTheta[locPIDPair] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPhiBins, dMinPhi, dMaxPhi);
2515
2516 gDirectory(TDirectory::CurrentDirectory())->cd(".."); //end of PID
2517 }
2518 gDirectory(TDirectory::CurrentDirectory())->cd(".."); //end of true/recon PID
2519 }
2520
2521 //Return to the base directory
2522 ChangeTo_BaseDirectory();
2523 }
2524 japp->RootUnLock(); //RELEASE ROOT LOCK!!
2525}
2526
2527void DHistogramAction_DetectorMatchParams::Run_Update(JEventLoop* locEventLoop)
2528{
2529 DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
2530 DGeometry* locGeometry = locApplication->GetDGeometry(locEventLoop->GetJEvent().GetRunNumber());
2531 double locTargetZCenter = 0.0;
2532 locGeometry->GetTargetZ(locTargetZCenter);
2533
2534 if(dTargetCenterZ < -9.8E9)
2535 dTargetCenterZ = locTargetZCenter; //only set if not already set
2536}
2537
2538bool DHistogramAction_DetectorMatchParams::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
2539{
2540 //Expect locParticleCombo to be NULL since this is a reaction-independent action.
2541
2542 if(Get_CalledPriorWithComboFlag())
2543 return true; //else double-counting!
2544
2545 vector<const DMCThrown*> locMCThrowns;
2546 locEventLoop->Get(locMCThrowns);
2547
2548 Fill_Hists(locEventLoop, false);
2549 if(!locMCThrowns.empty())
2550 Fill_Hists(locEventLoop, true);
2551
2552 return true; //return false if you want to use this action to apply a cut (and it fails the cut!)
2553}
2554
2555void DHistogramAction_DetectorMatchParams::Fill_Hists(JEventLoop* locEventLoop, bool locUseTruePIDFlag)
2556{
2557 vector<const DChargedTrack*> locChargedTracks;
2558 locEventLoop->Get(locChargedTracks, dTrackSelectionTag.c_str());
2559
2560 vector<const DMCThrownMatching*> locMCThrownMatchingVector;
2561 locEventLoop->Get(locMCThrownMatchingVector);
2562
2563 const DEventRFBunch* locEventRFBunch = NULL__null;
2564 locEventLoop->GetSingle(locEventRFBunch);
2565
2566 //FILL HISTOGRAMS
2567 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
2568 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
2569 Lock_Action(); //ACQUIRE ROOT LOCK!!
2570 {
2571 for(size_t loc_i = 0; loc_i < locChargedTracks.size(); ++loc_i)
2572 {
2573 const DChargedTrackHypothesis* locChargedTrackHypothesis = locChargedTracks[loc_i]->Get_BestFOM();
2574
2575 if(locUseTruePIDFlag && (!locMCThrownMatchingVector.empty()))
2576 {
2577 double locMatchFOM = 0.0;
2578 const DMCThrown* locMCThrown = locMCThrownMatchingVector[0]->Get_MatchingMCThrown(locChargedTrackHypothesis, locMatchFOM);
2579 if(locMCThrown == NULL__null)
2580 continue;
2581 //OK, have the thrown. Now, grab the best charged track hypothesis to get the best matching
2582 locChargedTrackHypothesis = locMCThrownMatchingVector[0]->Get_MatchingChargedHypothesis(locMCThrown, locMatchFOM);
2583 }
2584
2585 pair<int, bool> locPIDPair(int(locChargedTrackHypothesis->PID()), locUseTruePIDFlag);
2586 bool locDisregardPIDFlag = (dHistMap_BCALShowerEnergy.find(locPIDPair) == dHistMap_BCALShowerEnergy.end());
2587 int locQIndex = (locChargedTrackHypothesis->charge() > 0.0) ? -1 : -2;
2588 pair<int, bool> locChargePair(locQIndex, locUseTruePIDFlag);
2589
2590 DVector3 locMomentum = locChargedTrackHypothesis->momentum();
2591 auto locFCALShowerMatchParams = locChargedTrackHypothesis->Get_FCALShowerMatchParams();
2592 auto locSCHitMatchParams = locChargedTrackHypothesis->Get_SCHitMatchParams();
2593 auto locBCALShowerMatchParams = locChargedTrackHypothesis->Get_BCALShowerMatchParams();
2594
2595 //BCAL
2596 if(locBCALShowerMatchParams != NULL__null)
2597 {
2598 const DBCALShower* locBCALShower = locBCALShowerMatchParams->dBCALShower;
2599 dHistMap_BCALShowerEnergy[locChargePair]->Fill(locBCALShower->E);
2600 dHistMap_BCALShowerTrackDepth[locChargePair]->Fill(locBCALShowerMatchParams->dx);
2601 dHistMap_BCALShowerTrackDepthVsP[locChargePair]->Fill(locMomentum.Mag(), locBCALShowerMatchParams->dx);
2602
2603 if(!locDisregardPIDFlag)
2604 {
2605 dHistMap_BCALShowerEnergy[locPIDPair]->Fill(locBCALShower->E);
2606 dHistMap_BCALShowerTrackDepth[locPIDPair]->Fill(locBCALShowerMatchParams->dx);
2607 dHistMap_BCALShowerTrackDepthVsP[locPIDPair]->Fill(locMomentum.Mag(), locBCALShowerMatchParams->dx);
2608 }
2609 }
2610
2611 //FCAL
2612 if(locFCALShowerMatchParams != NULL__null)
2613 {
2614 const DFCALShower* locFCALShower = locFCALShowerMatchParams->dFCALShower;
2615 dHistMap_FCALShowerEnergy[locChargePair]->Fill(locFCALShower->getEnergy());
2616 dHistMap_FCALShowerTrackDepth[locChargePair]->Fill(locFCALShowerMatchParams->dx);
2617 dHistMap_FCALShowerTrackDepthVsP[locChargePair]->Fill(locMomentum.Mag(), locFCALShowerMatchParams->dx);
2618
2619 if(!locDisregardPIDFlag)
2620 {
2621 dHistMap_FCALShowerEnergy[locPIDPair]->Fill(locFCALShower->getEnergy());
2622 dHistMap_FCALShowerTrackDepth[locPIDPair]->Fill(locFCALShowerMatchParams->dx);
2623 dHistMap_FCALShowerTrackDepthVsP[locPIDPair]->Fill(locMomentum.Mag(), locFCALShowerMatchParams->dx);
2624 }
2625 }
2626
2627 //SC
2628 if(locSCHitMatchParams != NULL__null)
2629 {
2630 dHistMap_SCEnergyVsTheta[locChargePair]->Fill(locMomentum.Theta()*180.0/TMath::Pi(), locSCHitMatchParams->dHitEnergy*1.0E3);
2631 dHistMap_SCPhiVsTheta[locChargePair]->Fill(locMomentum.Theta()*180.0/TMath::Pi(), locMomentum.Phi()*180.0/TMath::Pi());
2632
2633 if(!locDisregardPIDFlag)
2634 {
2635 dHistMap_SCEnergyVsTheta[locPIDPair]->Fill(locMomentum.Theta()*180.0/TMath::Pi(), locSCHitMatchParams->dHitEnergy*1.0E3);
2636 dHistMap_SCPhiVsTheta[locPIDPair]->Fill(locMomentum.Theta()*180.0/TMath::Pi(), locMomentum.Phi()*180.0/TMath::Pi());
2637 }
2638 }
2639 }
2640 }
2641 Unlock_Action(); //RELEASE ROOT LOCK!!
2642}
2643
2644void DHistogramAction_EventVertex::Initialize(JEventLoop* locEventLoop)
2645{
2646 string locHistName, locHistTitle;
2647
2648 string locTrackSelectionTag = "NotATag";
2649 if(gPARMS->Exists("COMBO:TRACK_SELECT_TAG"))
2650 gPARMS->GetParameter("COMBO:TRACK_SELECT_TAG", locTrackSelectionTag);
2651
2652 //CREATE THE HISTOGRAMS
2653 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
2654 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
2655 {
2656 //So: Default tag is "", User can set it to something else
2657 //In here, if tag is "", get from gparms, if not, leave it alone
2658 //If gparms value does not exist, set it to (and use) "PreSelect"
2659 if(dTrackSelectionTag == "NotATag")
2660 dTrackSelectionTag = (locTrackSelectionTag == "NotATag") ? "PreSelect" : locTrackSelectionTag;
2661
2662 CreateAndChangeTo_ActionDirectory();
2663
2664 // Event RF Bunch Time
2665 locHistName = "RFTrackDeltaT";
2666 locHistTitle = ";#Deltat_{RF - Track} (ns)";
2667 dRFTrackDeltaT = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumRFTBins, -3.0, 3.0);
2668
2669 // ALL EVENTS
2670 CreateAndChangeTo_Directory("AllEvents", "AllEvents");
2671
2672 // Event Vertex-Z
2673 locHistName = "EventVertexZ";
2674 locHistTitle = ";Event Vertex-Z (cm)";
2675 dEventVertexZ_AllEvents = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumVertexZBins, dMinVertexZ, dMaxVertexZ);
2676
2677 // Event Vertex-Y Vs Vertex-X
2678 locHistName = "EventVertexYVsX";
2679 locHistTitle = ";Event Vertex-X (cm);Event Vertex-Y (cm)";
2680 dEventVertexYVsX_AllEvents = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumVertexXYBins, dMinVertexXY, dMaxVertexXY, dNumVertexXYBins, dMinVertexXY, dMaxVertexXY);
2681
2682 // Event Vertex-T
2683 locHistName = "EventVertexT";
2684 locHistTitle = ";Event Vertex Time (ns)";
2685 dEventVertexT_AllEvents = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTBins, dMinT, dMaxT);
2686
2687 gDirectory(TDirectory::CurrentDirectory())->cd("..");
2688
2689
2690 // 2+ Good Tracks
2691 CreateAndChangeTo_Directory("2+GoodTracks", "2+GoodTracks");
2692
2693 // Event Vertex-Z
2694 locHistName = "EventVertexZ";
2695 locHistTitle = ";Event Vertex-Z (cm)";
2696 dEventVertexZ_2OrMoreGoodTracks = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumVertexZBins, dMinVertexZ, dMaxVertexZ);
2697
2698 // Event Vertex-Y Vs Vertex-X
2699 locHistName = "EventVertexYVsX";
2700 locHistTitle = ";Event Vertex-X (cm);Event Vertex-Y (cm)";
2701 dEventVertexYVsX_2OrMoreGoodTracks = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumVertexXYBins, dMinVertexXY, dMaxVertexXY, dNumVertexXYBins, dMinVertexXY, dMaxVertexXY);
2702
2703 // Event Vertex-T
2704 locHistName = "EventVertexT";
2705 locHistTitle = ";Event Vertex Time (ns)";
2706 dEventVertexT_2OrMoreGoodTracks = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTBins, dMinT, dMaxT);
2707
2708 // Confidence Level
2709 locHistName = "ConfidenceLevel";
2710 dHist_KinFitConfidenceLevel = GetOrCreate_Histogram<TH1I>(locHistName, "Event Vertex Kinematic Fit;Confidence Level;# Events", dNumConfidenceLevelBins, 0.0, 1.0);
2711
2712 //final particle pulls
2713 for(size_t loc_i = 0; loc_i < dFinalStatePIDs.size(); ++loc_i)
2714 {
2715 Particle_t locPID = dFinalStatePIDs[loc_i];
2716 string locParticleDirName = string("Pulls_") + string(ParticleType(locPID));
2717 string locParticleROOTName = ParticleName_ROOT(locPID);
2718 CreateAndChangeTo_Directory(locParticleDirName, locParticleDirName);
2719
2720 //Px Pull
2721 locHistName = "Pull_Px";
2722 locHistTitle = locParticleROOTName + string(", Vertex Fit;p_{x} Pull;# Events");
2723 dHistMap_KinFitPulls[locPID][d_PxPull] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPullBins, dMinPull, dMaxPull);
2724
2725 //Py Pull
2726 locHistName = "Pull_Py";
2727 locHistTitle = locParticleROOTName + string(", Vertex Fit;p_{y} Pull;# Events");
2728 dHistMap_KinFitPulls[locPID][d_PyPull] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPullBins, dMinPull, dMaxPull);
2729
2730 //Pz Pull
2731 locHistName = "Pull_Pz";
2732 locHistTitle = locParticleROOTName + string(", Vertex Fit;p_{z} Pull;# Events");
2733 dHistMap_KinFitPulls[locPID][d_PzPull] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPullBins, dMinPull, dMaxPull);
2734
2735 //Xx Pull
2736 locHistName = "Pull_Xx";
2737 locHistTitle = locParticleROOTName + string(", Vertex Fit;x_{x} Pull;# Events");
2738 dHistMap_KinFitPulls[locPID][d_XxPull] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPullBins, dMinPull, dMaxPull);
2739
2740 //Xy Pull
2741 locHistName = "Pull_Xy";
2742 locHistTitle = locParticleROOTName + string(", Vertex Fit;x_{y} Pull;# Events");
2743 dHistMap_KinFitPulls[locPID][d_XyPull] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPullBins, dMinPull, dMaxPull);
2744
2745 //Xz Pull
2746 locHistName = "Pull_Xz";
2747 locHistTitle = locParticleROOTName + string(", Vertex Fit;x_{z} Pull;# Events");
2748 dHistMap_KinFitPulls[locPID][d_XzPull] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPullBins, dMinPull, dMaxPull);
2749
2750 gDirectory(TDirectory::CurrentDirectory())->cd("..");
2751 }
2752
2753 gDirectory(TDirectory::CurrentDirectory())->cd("..");
2754
2755 //Return to the base directory
2756 ChangeTo_BaseDirectory();
2757 }
2758 japp->RootUnLock(); //RELEASE ROOT LOCK!!
2759}
2760
2761bool DHistogramAction_EventVertex::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
2762{
2763 if(Get_CalledPriorWithComboFlag())
2764 return true; //else double-counting!
2765
2766 const DVertex* locVertex = NULL__null;
2767 locEventLoop->GetSingle(locVertex);
2768
2769 vector<const DChargedTrack*> locChargedTracks;
2770 locEventLoop->Get(locChargedTracks, dTrackSelectionTag.c_str());
2771
2772 const DDetectorMatches* locDetectorMatches = NULL__null;
2773 locEventLoop->GetSingle(locDetectorMatches);
2774
2775 const DParticleID* locParticleID = NULL__null;
2776 locEventLoop->GetSingle(locParticleID);
2777
2778 const DEventRFBunch* locEventRFBunch = NULL__null;
2779 locEventLoop->GetSingle(locEventRFBunch);
2780
2781 //Make sure that brun() is called (to get rf period) before using.
2782 //Cannot call JEventLoop->Get() because object may be in datastream (REST), bypassing factory brun() call.
2783 //Must do here rather than in Initialize() function because this object is shared by all threads (which each have their own factory)
2784 DRFTime_factory* locRFTimeFactory = static_cast<DRFTime_factory*>(locEventLoop->GetFactory("DRFTime"));
2785 if(!locRFTimeFactory->brun_was_called())
2786 {
2787 locRFTimeFactory->brun(locEventLoop, locEventLoop->GetJEvent().GetRunNumber());
2788 locRFTimeFactory->Set_brun_called();
2789 }
2790
2791 //Get time-based tracks: use best PID FOM
2792 //Note that these may not be the PIDs that were used in the fit!!!
2793 //e.g. for a DTrackTimeBased the proton hypothesis has the highest tracking FOM, so it is used in the fit, but the pi+ PID has the highest PID FOM
2794 vector<const DTrackTimeBased*> locTrackTimeBasedVector;
2795 for(size_t loc_i = 0; loc_i < locChargedTracks.size(); ++loc_i)
2796 {
2797 const DChargedTrackHypothesis* locChargedTrackHypothesis = locChargedTracks[loc_i]->Get_BestFOM();
2798 auto locTrackTimeBased = locChargedTrackHypothesis->Get_TrackTimeBased();
2799 if(locTrackTimeBased != NULL__null)
2800 locTrackTimeBasedVector.push_back(locTrackTimeBased);
2801 }
2802
2803 //Event Vertex
2804 //FILL HISTOGRAMS
2805 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
2806 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
2807 Lock_Action();
2808 {
2809 for(size_t loc_i = 0; loc_i < locChargedTracks.size(); ++loc_i)
2810 {
2811 const DChargedTrackHypothesis* locChargedTrackHypothesis = locChargedTracks[loc_i]->Get_BestFOM();
2812 double locPropagatedRFTime = locParticleID->Calc_PropagatedRFTime(locChargedTrackHypothesis, locEventRFBunch);
2813 double locShiftedRFTime = locRFTimeFactory->Step_TimeToNearInputTime(locPropagatedRFTime, locChargedTrackHypothesis->time());
2814 double locDeltaT = locShiftedRFTime - locChargedTrackHypothesis->time();
2815 dRFTrackDeltaT->Fill(locDeltaT);
2816 }
2817 dEventVertexZ_AllEvents->Fill(locVertex->dSpacetimeVertex.Z());
2818 dEventVertexYVsX_AllEvents->Fill(locVertex->dSpacetimeVertex.X(), locVertex->dSpacetimeVertex.Y());
2819 dEventVertexT_AllEvents->Fill(locVertex->dSpacetimeVertex.T());
2820
2821 if(locChargedTracks.size() >= 2)
2822 {
2823 dEventVertexZ_2OrMoreGoodTracks->Fill(locVertex->dSpacetimeVertex.Z());
2824 dEventVertexYVsX_2OrMoreGoodTracks->Fill(locVertex->dSpacetimeVertex.X(), locVertex->dSpacetimeVertex.Y());
2825 dEventVertexT_2OrMoreGoodTracks->Fill(locVertex->dSpacetimeVertex.T());
2826 }
2827 }
2828 Unlock_Action();
2829
2830 if(locVertex->dKinFitNDF == 0)
2831 return true; //kin fit not performed or didn't converge: no results to histogram
2832
2833 double locConfidenceLevel = TMath::Prob(locVertex->dKinFitChiSq, locVertex->dKinFitNDF);
2834
2835 //FILL HISTOGRAMS
2836 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
2837 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
2838 Lock_Action();
2839 {
2840 dHist_KinFitConfidenceLevel->Fill(locConfidenceLevel);
2841
2842 //pulls
2843 if(locConfidenceLevel > dPullHistConfidenceLevelCut)
2844 {
2845 for(size_t loc_i = 0; loc_i < locTrackTimeBasedVector.size(); ++loc_i)
2846 {
2847 const DKinematicData* locKinematicData = static_cast<const DKinematicData*>(locTrackTimeBasedVector[loc_i]);
2848 Particle_t locPID = locKinematicData->PID();
2849 if(dHistMap_KinFitPulls.find(locPID) == dHistMap_KinFitPulls.end())
2850 continue; //PID not histogrammed
2851
2852 map<const JObject*, map<DKinFitPullType, double> >::const_iterator locParticleIterator = locVertex->dKinFitPulls.find(locKinematicData);
2853 if(locParticleIterator == locVertex->dKinFitPulls.end())
2854 continue;
2855
2856 const map<DKinFitPullType, double>& locPullMap = locParticleIterator->second;
2857 map<DKinFitPullType, double>::const_iterator locPullIterator = locPullMap.begin();
2858 for(; locPullIterator != locPullMap.end(); ++locPullIterator)
2859 dHistMap_KinFitPulls[locPID][locPullIterator->first]->Fill(locPullIterator->second);
2860 }
2861 }
2862 }
2863 Unlock_Action();
2864
2865 return true;
2866}
2867
2868void DHistogramAction_DetectedParticleKinematics::Initialize(JEventLoop* locEventLoop)
2869{
2870 string locHistName, locHistTitle, locParticleName, locParticleROOTName;
2871 Particle_t locPID;
2872
2873 string locTrackSelectionTag = "NotATag", locShowerSelectionTag = "NotATag";
2874 if(gPARMS->Exists("COMBO:TRACK_SELECT_TAG"))
2875 gPARMS->GetParameter("COMBO:TRACK_SELECT_TAG", locTrackSelectionTag);
2876 if(gPARMS->Exists("COMBO:SHOWER_SELECT_TAG"))
2877 gPARMS->GetParameter("COMBO:SHOWER_SELECT_TAG", locShowerSelectionTag);
2878
2879 //CREATE THE HISTOGRAMS
2880 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
2881 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
2882 {
2883 //So: Default tag is "", User can set it to something else
2884 //In here, if tag is "", get from gparms, if not, leave it alone
2885 //If gparms value does not exist, set it to (and use) "PreSelect"
2886 if(dTrackSelectionTag == "NotATag")
2887 dTrackSelectionTag = (locTrackSelectionTag == "NotATag") ? "PreSelect" : locTrackSelectionTag;
2888 if(dShowerSelectionTag == "NotATag")
2889 dShowerSelectionTag = (locShowerSelectionTag == "NotATag") ? "PreSelect" : locShowerSelectionTag;
2890
2891 CreateAndChangeTo_ActionDirectory();
2892
2893 // Beam Particle
2894 locPID = Gamma;
2895 locParticleName = string("Beam_") + ParticleType(locPID);
2896 locParticleROOTName = ParticleName_ROOT(locPID);
2897 CreateAndChangeTo_Directory(locParticleName, locParticleName);
2898 locHistName = "Momentum";
2899 locHistTitle = string("Beam ") + locParticleROOTName + string(";p (GeV/c)");
2900 dBeamParticle_P = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumBeamEBins, dMinP, dMaxBeamE);
2901 gDirectory(TDirectory::CurrentDirectory())->cd("..");
2902
2903 //PID
2904 CreateAndChangeTo_Directory("PID", "PID");
2905 {
2906 //beta vs p
2907 locHistName = "BetaVsP_Q+";
2908 locHistTitle = "q^{+};p (GeV/c);#beta";
2909 dHistMap_QBetaVsP[1] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNumBetaBins, dMinBeta, dMaxBeta);
2910
2911 locHistName = "BetaVsP_Q-";
2912 locHistTitle = "q^{-};p (GeV/c);#beta";
2913 dHistMap_QBetaVsP[-1] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNumBetaBins, dMinBeta, dMaxBeta);
2914 }
2915 gDirectory(TDirectory::CurrentDirectory())->cd("..");
2916
2917 for(size_t loc_i = 0; loc_i < dFinalStatePIDs.size(); ++loc_i)
2918 {
2919 locPID = dFinalStatePIDs[loc_i];
2920 locParticleName = ParticleType(locPID);
2921 locParticleROOTName = ParticleName_ROOT(locPID);
2922 CreateAndChangeTo_Directory(locParticleName, locParticleName);
2923
2924 // Momentum
2925 locHistName = "Momentum";
2926 locHistTitle = locParticleROOTName + string(";p (GeV/c)");
2927 dHistMap_P[locPID] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPBins, dMinP, dMaxP);
2928
2929 // Theta
2930 locHistName = "Theta";
2931 locHistTitle = locParticleROOTName + string(";#theta#circ");
2932 dHistMap_Theta[locPID] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumThetaBins, dMinTheta, dMaxTheta);
2933
2934 // Phi
2935 locHistName = "Phi";
2936 locHistTitle = locParticleROOTName + string(";#phi#circ");
2937 dHistMap_Phi[locPID] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPhiBins, dMinPhi, dMaxPhi);
2938
2939 // P Vs Theta
2940 locHistName = "PVsTheta";
2941 locHistTitle = locParticleROOTName + string(";#theta#circ;p (GeV/c)");
2942 dHistMap_PVsTheta[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPBins, dMinP, dMaxP);
2943
2944 // Phi Vs Theta
2945 locHistName = "PhiVsTheta";
2946 locHistTitle = locParticleROOTName + string(";#theta#circ;#phi#circ");
2947 dHistMap_PhiVsTheta[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPhiBins, dMinPhi, dMaxPhi);
2948
2949 //beta vs p
2950 locHistName = "BetaVsP";
2951 locHistTitle = locParticleROOTName + string(";p (GeV/c);#beta");
2952 dHistMap_BetaVsP[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNumBetaBins, dMinBeta, dMaxBeta);
2953
2954 //delta-beta vs p
2955 locHistName = "DeltaBetaVsP";
2956 locHistTitle = locParticleROOTName + string(";p (GeV/c);#Delta#beta");
2957 dHistMap_DeltaBetaVsP[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DDeltaBetaBins, dMinDeltaBeta, dMaxDeltaBeta);
2958
2959 // Vertex-Z
2960 locHistName = "VertexZ";
2961 locHistTitle = locParticleROOTName + string(";Vertex-Z (cm)");
2962 dHistMap_VertexZ[locPID] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumVertexZBins, dMinVertexZ, dMaxVertexZ);
2963
2964 // Vertex-Y Vs Vertex-X
2965 locHistName = "VertexYVsX";
2966 locHistTitle = locParticleROOTName + string(";Vertex-X (cm);Vertex-Y (cm)");
2967 dHistMap_VertexYVsX[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNumVertexXYBins, dMinVertexXY, dMaxVertexXY, dNumVertexXYBins, dMinVertexXY, dMaxVertexXY);
2968
2969 // Vertex-T
2970 locHistName = "VertexT";
2971 locHistTitle = locParticleROOTName + string(";Vertex-T (ns)");
2972 dHistMap_VertexT[locPID] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumTBins, dMinT, dMaxT);
2973
2974 // histogram shower energy for massive neutrals reconstructed in the calorimeter
2975 if(locPID == Neutron) {
2976 locHistName = "ShowerE";
2977 locHistTitle = locParticleROOTName + string(";Shower Energy (GeV)");
2978 dHistMap_ShowerE[locPID] = GetOrCreate_Histogram<TH1I>(locHistName, locHistTitle, dNumPBins, dMinP, dMaxP);
2979 }
2980
2981 gDirectory(TDirectory::CurrentDirectory())->cd("..");
2982 }
2983
2984 //Return to the base directory
2985 ChangeTo_BaseDirectory();
2986 }
2987 japp->RootUnLock(); //RELEASE ROOT LOCK!!
2988}
2989
2990bool DHistogramAction_DetectedParticleKinematics::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
2991{
2992 if(Get_CalledPriorWithComboFlag())
2993 return true; //else double-counting!
2994
2995 vector<const DBeamPhoton*> locBeamPhotons;
2996 locEventLoop->Get(locBeamPhotons);
2997
2998 //FILL HISTOGRAMS
2999 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
3000 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
3001 Lock_Action();
3002 {
3003 for(size_t loc_i = 0; loc_i < locBeamPhotons.size(); ++loc_i)
3004 dBeamParticle_P->Fill(locBeamPhotons[loc_i]->energy());
3005 }
3006 Unlock_Action();
3007
3008 vector<const DChargedTrack*> locPreSelectChargedTracks;
3009 locEventLoop->Get(locPreSelectChargedTracks, dTrackSelectionTag.c_str());
3010
3011 for(size_t loc_i = 0; loc_i < locPreSelectChargedTracks.size(); ++loc_i)
3012 {
3013 const DChargedTrackHypothesis* locChargedTrackHypothesis = locPreSelectChargedTracks[loc_i]->Get_BestTrackingFOM();
3014 int locCharge = ParticleCharge(locChargedTrackHypothesis->PID());
3015
3016 DVector3 locMomentum = locChargedTrackHypothesis->momentum();
3017 double locP = locMomentum.Mag();
3018 double locBeta_Timing = locChargedTrackHypothesis->measuredBeta();
3019
3020 if(dHistMap_QBetaVsP.find(locCharge) == dHistMap_QBetaVsP.end())
3021 continue;
3022
3023 //FILL HISTOGRAMS
3024 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
3025 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
3026 Lock_Action();
3027 {
3028 //Extremely inefficient, I know ...
3029 dHistMap_QBetaVsP[locCharge]->Fill(locP, locBeta_Timing);
3030 }
3031 Unlock_Action();
3032 }
3033
3034 for(size_t loc_i = 0; loc_i < locPreSelectChargedTracks.size(); ++loc_i)
3035 {
3036 const DChargedTrackHypothesis* locChargedTrackHypothesis = locPreSelectChargedTracks[loc_i]->Get_BestFOM();
3037
3038 DVector3 locMomentum = locChargedTrackHypothesis->momentum();
3039 double locPhi = locMomentum.Phi()*180.0/TMath::Pi();
3040 double locTheta = locMomentum.Theta()*180.0/TMath::Pi();
3041 double locP = locMomentum.Mag();
3042 double locBeta_Timing = locChargedTrackHypothesis->measuredBeta();
3043 double locDeltaBeta = locBeta_Timing - locChargedTrackHypothesis->lorentzMomentum().Beta();
3044
3045 Particle_t locPID = (locChargedTrackHypothesis->Get_FOM() < dMinPIDFOM) ? Unknown : locChargedTrackHypothesis->PID();
3046 if(dHistMap_P.find(locPID) == dHistMap_P.end())
3047 continue; //not interested in histogramming
3048
3049 //FILL HISTOGRAMS
3050 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
3051 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
3052 Lock_Action();
3053 {
3054 dHistMap_P[locPID]->Fill(locP);
3055 dHistMap_Phi[locPID]->Fill(locPhi);
3056 dHistMap_Theta[locPID]->Fill(locTheta);
3057 dHistMap_PVsTheta[locPID]->Fill(locTheta, locP);
3058 dHistMap_PhiVsTheta[locPID]->Fill(locTheta, locPhi);
3059 dHistMap_BetaVsP[locPID]->Fill(locP, locBeta_Timing);
3060 dHistMap_DeltaBetaVsP[locPID]->Fill(locP, locDeltaBeta);
3061 dHistMap_VertexZ[locPID]->Fill(locChargedTrackHypothesis->position().Z());
3062 dHistMap_VertexYVsX[locPID]->Fill(locChargedTrackHypothesis->position().X(), locChargedTrackHypothesis->position().Y());
3063 dHistMap_VertexT[locPID]->Fill(locChargedTrackHypothesis->time());
3064 }
3065 Unlock_Action();
3066 }
3067
3068 vector<const DNeutralParticle*> locNeutralParticles;
3069 locEventLoop->Get(locNeutralParticles, dShowerSelectionTag.c_str());
3070
3071 for(size_t loc_i = 0; loc_i < locNeutralParticles.size(); ++loc_i)
3072 {
3073 const DNeutralParticleHypothesis* locNeutralParticleHypothesis = locNeutralParticles[loc_i]->Get_BestFOM();
3074
3075 Particle_t locPID = locNeutralParticleHypothesis->PID();
3076 if(dHistMap_P.find(locPID) == dHistMap_P.end())
3077 continue; //e.g. a decaying particle, or not interested in histogramming
3078
3079 DVector3 locMomentum = locNeutralParticleHypothesis->momentum();
3080 double locPhi = locMomentum.Phi()*180.0/TMath::Pi();
3081 double locTheta = locMomentum.Theta()*180.0/TMath::Pi();
3082 double locP = locMomentum.Mag();
3083
3084 double locBeta_Timing = locNeutralParticleHypothesis->measuredBeta();
3085 double locDeltaBeta = locBeta_Timing - locNeutralParticleHypothesis->lorentzMomentum().Beta();
3086
3087 double locShowerEnergy = locNeutralParticleHypothesis->Get_NeutralShower()->dEnergy;
3088
3089 //FILL HISTOGRAMS
3090 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
3091 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
3092 Lock_Action();
3093 {
3094 dHistMap_P[locPID]->Fill(locP);
3095 dHistMap_Phi[locPID]->Fill(locPhi);
3096 dHistMap_Theta[locPID]->Fill(locTheta);
3097 dHistMap_PVsTheta[locPID]->Fill(locTheta, locP);
3098 dHistMap_PhiVsTheta[locPID]->Fill(locTheta, locPhi);
3099 dHistMap_BetaVsP[locPID]->Fill(locP, locBeta_Timing);
3100 dHistMap_DeltaBetaVsP[locPID]->Fill(locP, locDeltaBeta);
3101 dHistMap_VertexZ[locPID]->Fill(locNeutralParticleHypothesis->position().Z());
3102 dHistMap_VertexYVsX[locPID]->Fill(locNeutralParticleHypothesis->position().X(), locNeutralParticleHypothesis->position().Y());
3103 dHistMap_VertexT[locPID]->Fill(locNeutralParticleHypothesis->time());
3104
3105 if(locPID == Neutron) {
3106 dHistMap_ShowerE[locPID]->Fill(locShowerEnergy);
3107 }
3108 }
3109 Unlock_Action();
3110 }
3111 return true;
3112}
3113
3114void DHistogramAction_TrackShowerErrors::Initialize(JEventLoop* locEventLoop)
3115{
3116 string locHistName, locHistTitle, locParticleName, locParticleROOTName;
3117 Particle_t locPID;
3118
3119 string locTrackSelectionTag = "NotATag", locShowerSelectionTag = "NotATag";
3120 if(gPARMS->Exists("COMBO:TRACK_SELECT_TAG"))
3121 gPARMS->GetParameter("COMBO:TRACK_SELECT_TAG", locTrackSelectionTag);
3122 if(gPARMS->Exists("COMBO:SHOWER_SELECT_TAG"))
3123 gPARMS->GetParameter("COMBO:SHOWER_SELECT_TAG", locShowerSelectionTag);
3124
3125 //CREATE THE HISTOGRAMS
3126 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
3127 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
3128 {
3129 //So: Default tag is "", User can set it to something else
3130 //In here, if tag is "", get from gparms, if not, leave it alone
3131 //If gparms value does not exist, set it to (and use) "PreSelect"
3132 if(dTrackSelectionTag == "NotATag")
3133 dTrackSelectionTag = (locTrackSelectionTag == "NotATag") ? "PreSelect" : locTrackSelectionTag;
3134 if(dShowerSelectionTag == "NotATag")
3135 dShowerSelectionTag = (locShowerSelectionTag == "NotATag") ? "PreSelect" : locShowerSelectionTag;
3136
3137 CreateAndChangeTo_ActionDirectory();
3138
3139 //TRACKS
3140 for(size_t loc_i = 0; loc_i < dFinalStatePIDs.size(); ++loc_i)
3141 {
3142 locPID = dFinalStatePIDs[loc_i];
3143 locParticleName = ParticleType(locPID);
3144 locParticleROOTName = ParticleName_ROOT(locPID);
3145 CreateAndChangeTo_Directory(locParticleName, locParticleName);
3146
3147 // Px
3148 locHistName = "PxErrorVsP";
3149 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{p_{x}} (GeV/c)");
3150 dHistMap_TrackPxErrorVsP[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPxyErrorBins, 0.0, dMaxPxyError);
3151
3152 locHistName = "PxErrorVsTheta";
3153 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{p_{x}} (GeV/c)");
3154 dHistMap_TrackPxErrorVsTheta[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPxyErrorBins, 0.0, dMaxPxyError);
3155
3156 locHistName = "PxErrorVsPhi";
3157 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{p_{x}} (GeV/c)");
3158 dHistMap_TrackPxErrorVsPhi[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DPxyErrorBins, 0.0, dMaxPxyError);
3159
3160 // Py
3161 locHistName = "PyErrorVsP";
3162 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{p_{y}} (GeV/c)");
3163 dHistMap_TrackPyErrorVsP[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPxyErrorBins, 0.0, dMaxPxyError);
3164
3165 locHistName = "PyErrorVsTheta";
3166 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{p_{y}} (GeV/c)");
3167 dHistMap_TrackPyErrorVsTheta[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPxyErrorBins, 0.0, dMaxPxyError);
3168
3169 locHistName = "PyErrorVsPhi";
3170 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{p_{y}} (GeV/c)");
3171 dHistMap_TrackPyErrorVsPhi[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DPxyErrorBins, 0.0, dMaxPxyError);
3172
3173 // Pz
3174 locHistName = "PzErrorVsP";
3175 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{p_{z}} (GeV/c)");
3176 dHistMap_TrackPzErrorVsP[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DPzErrorBins, 0.0, dMaxPzError);
3177
3178 locHistName = "PzErrorVsTheta";
3179 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{p_{z}} (GeV/c)");
3180 dHistMap_TrackPzErrorVsTheta[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DPzErrorBins, 0.0, dMaxPzError);
3181
3182 locHistName = "PzErrorVsPhi";
3183 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{p_{z}} (GeV/c)");
3184 dHistMap_TrackPzErrorVsPhi[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DPzErrorBins, 0.0, dMaxPzError);
3185
3186 // X
3187 locHistName = "XErrorVsP";
3188 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{x} (cm)");
3189 dHistMap_TrackXErrorVsP[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DXYErrorBins, 0.0, dMaxXYError);
3190
3191 locHistName = "XErrorVsTheta";
3192 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{x} (cm)");
3193 dHistMap_TrackXErrorVsTheta[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DXYErrorBins, 0.0, dMaxXYError);
3194
3195 locHistName = "XErrorVsPhi";
3196 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{x} (cm)");
3197 dHistMap_TrackXErrorVsPhi[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DXYErrorBins, 0.0, dMaxXYError);
3198
3199 // Y
3200 locHistName = "YErrorVsP";
3201 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{y} (cm)");
3202 dHistMap_TrackYErrorVsP[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DXYErrorBins, 0.0, dMaxXYError);
3203
3204 locHistName = "YErrorVsTheta";
3205 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{y} (cm)");
3206 dHistMap_TrackYErrorVsTheta[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DXYErrorBins, 0.0, dMaxXYError);
3207
3208 locHistName = "YErrorVsPhi";
3209 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{y} (cm)");
3210 dHistMap_TrackYErrorVsPhi[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DXYErrorBins, 0.0, dMaxXYError);
3211
3212 // Z
3213 locHistName = "ZErrorVsP";
3214 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{z} (cm)");
3215 dHistMap_TrackZErrorVsP[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, dMaxP, dNum2DZErrorBins, 0.0, dMaxZError);
3216
3217 locHistName = "ZErrorVsTheta";
3218 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{z} (cm)");
3219 dHistMap_TrackZErrorVsTheta[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, dMinTheta, dMaxTheta, dNum2DZErrorBins, 0.0, dMaxZError);
3220
3221 locHistName = "ZErrorVsPhi";
3222 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{z} (cm)");
3223 dHistMap_TrackZErrorVsPhi[locPID] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DZErrorBins, 0.0, dMaxZError);
3224
3225 gDirectory(TDirectory::CurrentDirectory())->cd("..");
3226 }
3227
3228 //SHOWERS
3229 for(bool locIsBCALFlag : {false, true})
3230 {
3231 string locDirName = locIsBCALFlag ? "Photon_BCAL" : "Photon_FCAL";
3232 locParticleROOTName = ParticleName_ROOT(Gamma);
3233 CreateAndChangeTo_Directory(locDirName, locDirName);
3234
3235 double locMaxP = locIsBCALFlag ? dMaxPBCAL : dMaxP;
3236 double locMinTheta = locIsBCALFlag ? dMinThetaBCAL : dMinTheta;
3237 double locMaxTheta = locIsBCALFlag ? dMaxTheta : dMaxThetaFCAL;
3238
3239 // E
3240 locHistName = "EErrorVsP";
3241 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{E} (GeV)");
3242 dHistMap_ShowerEErrorVsP[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, locMaxP, dNum2DEErrorBins, 0.0, dMaxEError);
3243
3244 locHistName = "EErrorVsTheta";
3245 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{E} (GeV)");
3246 dHistMap_ShowerEErrorVsTheta[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, locMinTheta, locMaxTheta, dNum2DEErrorBins, 0.0, dMaxEError);
3247
3248 locHistName = "EErrorVsPhi";
3249 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{E} (GeV)");
3250 dHistMap_ShowerEErrorVsPhi[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DEErrorBins, 0.0, dMaxEError);
3251
3252 // X
3253 locHistName = "XErrorVsP";
3254 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{x} (cm)");
3255 dHistMap_ShowerXErrorVsP[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, locMaxP, dNum2DXYErrorBins, 0.0, dMaxXYError);
3256
3257 locHistName = "XErrorVsTheta";
3258 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{x} (cm)");
3259 dHistMap_ShowerXErrorVsTheta[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, locMinTheta, locMaxTheta, dNum2DXYErrorBins, 0.0, dMaxXYError);
3260
3261 locHistName = "XErrorVsPhi";
3262 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{x} (cm)");
3263 dHistMap_ShowerXErrorVsPhi[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DXYErrorBins, 0.0, dMaxXYError);
3264
3265 // Y
3266 locHistName = "YErrorVsP";
3267 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{y} (cm)");
3268 dHistMap_ShowerYErrorVsP[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, locMaxP, dNum2DXYErrorBins, 0.0, dMaxXYError);
3269
3270 locHistName = "YErrorVsTheta";
3271 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{y} (cm)");
3272 dHistMap_ShowerYErrorVsTheta[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, locMinTheta, locMaxTheta, dNum2DXYErrorBins, 0.0, dMaxXYError);
3273
3274 locHistName = "YErrorVsPhi";
3275 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{y} (cm)");
3276 dHistMap_ShowerYErrorVsPhi[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DXYErrorBins, 0.0, dMaxXYError);
3277
3278 // Z
3279 locHistName = "ZErrorVsP";
3280 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{z} (cm)");
3281 dHistMap_ShowerZErrorVsP[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, locMaxP, dNum2DShowerZErrorBins, 0.0, dMaxShowerZError);
3282
3283 locHistName = "ZErrorVsTheta";
3284 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{z} (cm)");
3285 dHistMap_ShowerZErrorVsTheta[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, locMinTheta, locMaxTheta, dNum2DShowerZErrorBins, 0.0, dMaxShowerZError);
3286
3287 locHistName = "ZErrorVsPhi";
3288 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{z} (cm)");
3289 dHistMap_ShowerZErrorVsPhi[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DShowerZErrorBins, 0.0, dMaxShowerZError);
3290
3291 // T
3292 locHistName = "TErrorVsP";
3293 locHistTitle = locParticleROOTName + string(";p (GeV/c);#sigma_{t} (ns)");
3294 dHistMap_ShowerTErrorVsP[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPBins, dMinP, locMaxP, dNum2DTErrorBins, 0.0, dMaxTError);
3295
3296 locHistName = "TErrorVsTheta";
3297 locHistTitle = locParticleROOTName + string(";#theta#circ;#sigma_{t} (ns)");
3298 dHistMap_ShowerTErrorVsTheta[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DThetaBins, locMinTheta, locMaxTheta, dNum2DTErrorBins, 0.0, dMaxTError);
3299
3300 locHistName = "TErrorVsPhi";
3301 locHistTitle = locParticleROOTName + string(";#phi#circ;#sigma_{t} (ns)");
3302 dHistMap_ShowerTErrorVsPhi[locIsBCALFlag] = GetOrCreate_Histogram<TH2I>(locHistName, locHistTitle, dNum2DPhiBins, dMinPhi, dMaxPhi, dNum2DTErrorBins, 0.0, dMaxTError);
3303
3304 gDirectory(TDirectory::CurrentDirectory())->cd("..");
3305 }
3306
3307 //Return to the base directory
3308 ChangeTo_BaseDirectory();
3309 }
3310 japp->RootUnLock(); //RELEASE ROOT LOCK!!
3311}
3312
3313bool DHistogramAction_TrackShowerErrors::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
3314{
3315 if(Get_CalledPriorWithComboFlag())
3316 return true; //else double-counting!
3317
3318 vector<const DChargedTrack*> locPreSelectChargedTracks;
3319 locEventLoop->Get(locPreSelectChargedTracks, dTrackSelectionTag.c_str());
3320
3321 for(size_t loc_i = 0; loc_i < locPreSelectChargedTracks.size(); ++loc_i)
3322 {
3323 const DChargedTrackHypothesis* locChargedTrackHypothesis = locPreSelectChargedTracks[loc_i]->Get_BestFOM();
3324
3325 Particle_t locPID = (locChargedTrackHypothesis->Get_FOM() < dMinPIDFOM) ? Unknown : locChargedTrackHypothesis->PID();
3326 if(dHistMap_TrackPxErrorVsP.find(locPID) == dHistMap_TrackPxErrorVsP.end())
3327 continue; //not interested in histogramming
3328
3329 DVector3 locMomentum = locChargedTrackHypothesis->momentum();
3330 double locPhi = locMomentum.Phi()*180.0/TMath::Pi();
3331 double locTheta = locMomentum.Theta()*180.0/TMath::Pi();
3332 double locP = locMomentum.Mag();
3333
3334 const TMatrixFSym& locCovarianceMatrix = *(locChargedTrackHypothesis->errorMatrix().get());
3335 double locPxError = sqrt(locCovarianceMatrix(0, 0));
3336 double locPyError = sqrt(locCovarianceMatrix(1, 1));
3337 double locPzError = sqrt(locCovarianceMatrix(2, 2));
3338 double locXError = sqrt(locCovarianceMatrix(3, 3));
3339 double locYError = sqrt(locCovarianceMatrix(4, 4));
3340 double locZError = sqrt(locCovarianceMatrix(5, 5));
3341
3342 //FILL HISTOGRAMS
3343 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
3344 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
3345 Lock_Action();
3346 {
3347 dHistMap_TrackPxErrorVsP[locPID]->Fill(locP, locPxError);
3348 dHistMap_TrackPxErrorVsTheta[locPID]->Fill(locTheta, locPxError);
3349 dHistMap_TrackPxErrorVsPhi[locPID]->Fill(locPhi, locPxError);
3350
3351 dHistMap_TrackPyErrorVsP[locPID]->Fill(locP, locPyError);
3352 dHistMap_TrackPyErrorVsTheta[locPID]->Fill(locTheta, locPyError);
3353 dHistMap_TrackPyErrorVsPhi[locPID]->Fill(locPhi, locPyError);
3354
3355 dHistMap_TrackPzErrorVsP[locPID]->Fill(locP, locPzError);
3356 dHistMap_TrackPzErrorVsTheta[locPID]->Fill(locTheta, locPzError);
3357 dHistMap_TrackPzErrorVsPhi[locPID]->Fill(locPhi, locPzError);
3358
3359 dHistMap_TrackXErrorVsP[locPID]->Fill(locP, locXError);
3360 dHistMap_TrackXErrorVsTheta[locPID]->Fill(locTheta, locXError);
3361 dHistMap_TrackXErrorVsPhi[locPID]->Fill(locPhi, locXError);
3362
3363 dHistMap_TrackYErrorVsP[locPID]->Fill(locP, locYError);
3364 dHistMap_TrackYErrorVsTheta[locPID]->Fill(locTheta, locYError);
3365 dHistMap_TrackYErrorVsPhi[locPID]->Fill(locPhi, locYError);
3366
3367 dHistMap_TrackZErrorVsP[locPID]->Fill(locP, locZError);
3368 dHistMap_TrackZErrorVsTheta[locPID]->Fill(locTheta, locZError);
3369 dHistMap_TrackZErrorVsPhi[locPID]->Fill(locPhi, locZError);
3370 }
3371 Unlock_Action();
3372 }
3373
3374 vector<const DNeutralParticle*> locNeutralParticles;
3375 locEventLoop->Get(locNeutralParticles, dShowerSelectionTag.c_str());
3376
3377 for(size_t loc_i = 0; loc_i < locNeutralParticles.size(); ++loc_i)
3378 {
3379 // Only plotting photons for now, maybe we want to include neutrons at some point?
3380 const DNeutralParticleHypothesis* locNeutralParticleHypothesis = locNeutralParticles[loc_i]->Get_Hypothesis(Gamma);
3381 if(locNeutralParticleHypothesis == nullptr) // no photon hypothesis!
3382 continue;
3383 if(locNeutralParticleHypothesis->Get_FOM() < dMinPIDFOM)
3384 continue;
3385
3386 DVector3 locMomentum = locNeutralParticleHypothesis->momentum();
3387 double locPhi = locMomentum.Phi()*180.0/TMath::Pi();
3388 double locTheta = locMomentum.Theta()*180.0/TMath::Pi();
3389 double locP = locMomentum.Mag();
3390
3391 const DNeutralShower* locNeutralShower = locNeutralParticles[loc_i]->dNeutralShower;
3392 const TMatrixFSym& locCovarianceMatrix = *(locNeutralShower->dCovarianceMatrix);
3393 bool locIsBCALFlag = (locNeutralShower->dDetectorSystem == SYS_BCAL);
3394 double locEError = sqrt(locCovarianceMatrix(0, 0));
3395 double locXError = sqrt(locCovarianceMatrix(1, 1));
3396 double locYError = sqrt(locCovarianceMatrix(2, 2));
3397 double locZError = sqrt(locCovarianceMatrix(3, 3));
3398 double locTError = sqrt(locCovarianceMatrix(4, 4));
3399
3400 //FILL HISTOGRAMS
3401 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
3402 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
3403 Lock_Action();
3404 {
3405 dHistMap_ShowerEErrorVsP[locIsBCALFlag]->Fill(locP, locEError);
3406 dHistMap_ShowerEErrorVsTheta[locIsBCALFlag]->Fill(locTheta, locEError);
3407 dHistMap_ShowerEErrorVsPhi[locIsBCALFlag]->Fill(locPhi, locEError);
3408
3409 dHistMap_ShowerXErrorVsP[locIsBCALFlag]->Fill(locP, locXError);
3410 dHistMap_ShowerXErrorVsTheta[locIsBCALFlag]->Fill(locTheta, locXError);
3411 dHistMap_ShowerXErrorVsPhi[locIsBCALFlag]->Fill(locPhi, locXError);
3412
3413 dHistMap_ShowerYErrorVsP[locIsBCALFlag]->Fill(locP, locYError);
3414 dHistMap_ShowerYErrorVsTheta[locIsBCALFlag]->Fill(locTheta, locYError);
3415 dHistMap_ShowerYErrorVsPhi[locIsBCALFlag]->Fill(locPhi, locYError);
3416
3417 dHistMap_ShowerZErrorVsP[locIsBCALFlag]->Fill(locP, locZError);
3418 dHistMap_ShowerZErrorVsTheta[locIsBCALFlag]->Fill(locTheta, locZError);
3419 dHistMap_ShowerZErrorVsPhi[locIsBCALFlag]->Fill(locPhi, locZError);
3420
3421 dHistMap_ShowerTErrorVsP[locIsBCALFlag]->Fill(locP, locTError);
3422 dHistMap_ShowerTErrorVsTheta[locIsBCALFlag]->Fill(locTheta, locTError);
3423 dHistMap_ShowerTErrorVsPhi[locIsBCALFlag]->Fill(locPhi, locTError);
3424 }
3425 Unlock_Action();
3426 }
3427
3428 return true;
3429}
3430
3431void DHistogramAction_NumReconstructedObjects::Initialize(JEventLoop* locEventLoop)
3432{
3433 string locHistName;
3434
3435 bool locIsRESTEvent = locEventLoop->GetJEvent().GetStatusBit(kSTATUS_REST);
3436
3437 //CREATE THE HISTOGRAMS
3438 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
3439 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
3440 {
3441 CreateAndChangeTo_ActionDirectory();
3442
3443 //2D Summary
3444 locHistName = "NumHighLevelObjects";
3445 if(gDirectory(TDirectory::CurrentDirectory())->Get(locHistName.c_str()) != NULL__null) //already created by another thread, or directory name is duplicate (e.g. two identical steps)
3446 dHist_NumHighLevelObjects = static_cast<TH2D*>(gDirectory(TDirectory::CurrentDirectory())->Get(locHistName.c_str()));
3447 else
3448 {
3449 dHist_NumHighLevelObjects = new TH2D(locHistName.c_str(), ";;# Objects / Event", 14, 0.5, 14.5, dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3450 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(1, "DRFTime");
3451 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(2, "DSCHit");
3452 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(3, "DTOFPoint");
3453 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(4, "DBCALShower");
3454 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(5, "DFCALShower");
3455 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(6, "DTimeBasedTrack");
3456 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(7, "TrackSCMatches");
3457 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(8, "TrackTOFMatches");
3458 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(9, "TrackBCALMatches");
3459 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(10, "TrackFCALMatches");
3460 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(11, "DBeamPhoton");
3461 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(12, "DChargedTrack");
3462 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(13, "DNeutralShower");
3463 dHist_NumHighLevelObjects->GetXaxis()->SetBinLabel(14, "DCCALShower");
3464
3465 }
3466
3467 //Charged
3468 locHistName = "NumChargedTracks";
3469 dHist_NumChargedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# DChargedTrack", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3470 locHistName = "NumPosChargedTracks";
3471 dHist_NumPosChargedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{+} DChargedTrack", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3472 locHistName = "NumNegChargedTracks";
3473 dHist_NumNegChargedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{-} DChargedTrack", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3474
3475 //TBT
3476 locHistName = "NumTimeBasedTracks";
3477 dHist_NumTimeBasedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# Time-Based Tracks", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3478 locHistName = "NumPosTimeBasedTracks";
3479 dHist_NumPosTimeBasedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{+} Time-Based Tracks", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3480 locHistName = "NumNegTimeBasedTracks";
3481 dHist_NumNegTimeBasedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{-} Time-Based Tracks", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3482
3483 if(!locIsRESTEvent)
3484 {
3485 //WBT
3486 locHistName = "NumWireBasedTracks";
3487 dHist_NumWireBasedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# Wire-Based Tracks", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3488 locHistName = "NumPosWireBasedTracks";
3489 dHist_NumPosWireBasedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{-} Wire-Based Tracks", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3490 locHistName = "NumNegWireBasedTracks";
3491 dHist_NumNegWireBasedTracks = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{-} Wire-Based Tracks", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3492
3493 //Track Candidates
3494 locHistName = "NumTrackCandidates";
3495 dHist_NumTrackCandidates = GetOrCreate_Histogram<TH1D>(locHistName, ";# Track Candidates", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3496 locHistName = "NumPosTrackCandidates";
3497 dHist_NumPosTrackCandidates = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{+} Track Candidates", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3498 locHistName = "NumNegTrackCandidates";
3499 dHist_NumNegTrackCandidates = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{-} Track Candidates", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3500
3501 //CDC Track Candidates
3502 locHistName = "NumPosTrackCandidates_CDC";
3503 dHist_NumPosTrackCandidates_CDC = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{+} CDC Track Candidates", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3504 locHistName = "NumNegTrackCandidates_CDC";
3505 dHist_NumNegTrackCandidates_CDC = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{-} CDC Track Candidates", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3506
3507 //FDC Track Candidates
3508 locHistName = "NumPosTrackCandidates_FDC";
3509 dHist_NumPosTrackCandidates_FDC = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{+} FDC Track Candidates", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3510 locHistName = "NumNegTrackCandidates_FDC";
3511 dHist_NumNegTrackCandidates_FDC = GetOrCreate_Histogram<TH1D>(locHistName, ";# #it{q}^{-} FDC Track Candidates", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3512 }
3513
3514 //Beam Photons
3515 locHistName = "NumBeamPhotons";
3516 dHist_NumBeamPhotons = GetOrCreate_Histogram<TH1D>(locHistName, ";# DBeamPhoton", dMaxNumBeamPhotons + 1, -0.5, (float)dMaxNumBeamPhotons + 0.5);
3517
3518 //Showers / Neutrals / TOF / SC
3519 locHistName = "NumFCALShowers";
3520 dHist_NumFCALShowers = GetOrCreate_Histogram<TH1D>(locHistName, ";# DFCALShower", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3521 locHistName = "NumCCALShowers";
3522 dHist_NumCCALShowers = GetOrCreate_Histogram<TH1D>(locHistName, ";# DCCALShower", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3523 locHistName = "NumBCALShowers";
3524 dHist_NumBCALShowers = GetOrCreate_Histogram<TH1D>(locHistName, ";# DBCALShower", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3525 locHistName = "NumNeutralShowers";
3526 dHist_NumNeutralShowers = GetOrCreate_Histogram<TH1D>(locHistName, ";# DNeutralShower", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3527 locHistName = "NumTOFPoints";
3528 dHist_NumTOFPoints = GetOrCreate_Histogram<TH1D>(locHistName, ";# DTOFPoint", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3529 locHistName = "NumSCHits";
3530 dHist_NumSCHits = GetOrCreate_Histogram<TH1D>(locHistName, ";# DSCHit", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3531
3532 if(!locIsRESTEvent)
3533 {
3534 locHistName = "NumTAGMHits";
3535 dHist_NumTAGMHits = GetOrCreate_Histogram<TH1D>(locHistName, ";# DTAGMHit", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3536 locHistName = "NumTAGHHits";
3537 dHist_NumTAGHHits = GetOrCreate_Histogram<TH1D>(locHistName, ";# DTAGHHit", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3538 }
3539
3540 //Matches
3541 locHistName = "NumTrackBCALMatches";
3542 dHist_NumTrackBCALMatches = GetOrCreate_Histogram<TH1D>(locHistName, ";# Track-BCAL Matches", dMaxNumMatchObjects + 1, -0.5, (float)dMaxNumMatchObjects + 0.5);
3543 locHistName = "NumTrackFCALMatches";
3544 dHist_NumTrackFCALMatches = GetOrCreate_Histogram<TH1D>(locHistName, ";# Track-FCAL Matches", dMaxNumMatchObjects + 1, -0.5, (float)dMaxNumMatchObjects + 0.5);
3545 locHistName = "NumTrackTOFMatches";
3546 dHist_NumTrackTOFMatches = GetOrCreate_Histogram<TH1D>(locHistName, ";# Track-TOF Matches", dMaxNumMatchObjects + 1, -0.5, (float)dMaxNumMatchObjects + 0.5);
3547 locHistName = "NumTrackSCMatches";
3548 dHist_NumTrackSCMatches = GetOrCreate_Histogram<TH1D>(locHistName, ";# Track-SC Matches", dMaxNumMatchObjects + 1, -0.5, (float)dMaxNumMatchObjects + 0.5);
3549
3550 if(!locIsRESTEvent)
3551 {
3552 //Hits
3553 locHistName = "NumCDCHits";
3554 dHist_NumCDCHits = GetOrCreate_Histogram<TH1I>(locHistName, ";# DCDCHit", dMaxNumCDCHits + 1, -0.5, (float)dMaxNumCDCHits + 0.5);
3555 locHistName = "NumFDCWireHits";
3556 dHist_NumFDCWireHits = GetOrCreate_Histogram<TH1I>(locHistName, ";# Wire DFDCHit", dMaxNumFDCHits/2 + 1, -0.5, (float)dMaxNumFDCHits - 0.5 + 2.0);
3557 locHistName = "NumFDCCathodeHits";
3558 dHist_NumFDCCathodeHits = GetOrCreate_Histogram<TH1I>(locHistName, ";# Cathode DFDCHit", dMaxNumFDCHits/2 + 1, -0.5, (float)dMaxNumFDCHits - 0.5 + 2.0);
3559 locHistName = "NumFDCPseudoHits";
3560 dHist_NumFDCPseudoHits = GetOrCreate_Histogram<TH1I>(locHistName, ";# FDC Pseudo Hits", dMaxNumFDCHits/2 + 1, -0.5, (float)dMaxNumFDCHits - 0.5 + 2.0);
3561
3562 locHistName = "NumTOFHits";
3563 dHist_NumTOFHits = GetOrCreate_Histogram<TH1I>(locHistName, ";# DTOFHit", dMaxNumTOFCalorimeterHits + 1, -0.5, (float)dMaxNumTOFCalorimeterHits + 0.5);
3564 locHistName = "NumBCALHits";
3565 dHist_NumBCALHits = GetOrCreate_Histogram<TH1I>(locHistName, ";# DBCALHit", dMaxNumTOFCalorimeterHits + 1, -0.5, (float)dMaxNumTOFCalorimeterHits + 0.5);
3566 locHistName = "NumFCALHits";
3567 dHist_NumFCALHits = GetOrCreate_Histogram<TH1I>(locHistName, ";# DFCALHit", dMaxNumTOFCalorimeterHits + 1, -0.5, (float)dMaxNumTOFCalorimeterHits + 0.5);
3568 locHistName = "NumCCALHits";
3569 dHist_NumCCALHits = GetOrCreate_Histogram<TH1I>(locHistName, ";# DFCALHit", dMaxNumTOFCalorimeterHits + 1, -0.5, (float)dMaxNumTOFCalorimeterHits + 0.5);
3570
3571 locHistName = "NumRFSignals";
3572 dHist_NumRFSignals = GetOrCreate_Histogram<TH1I>(locHistName, ";# DRFDigiTime + # DRFTDCDigiTime", dMaxNumObjects + 1, -0.5, (float)dMaxNumObjects + 0.5);
3573 }
3574
3575 //Return to the base directory
3576 ChangeTo_BaseDirectory();
3577 }
3578 japp->RootUnLock(); //RELEASE ROOT LOCK!!
3579}
3580
3581bool DHistogramAction_NumReconstructedObjects::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
3582{
3583 if(Get_CalledPriorWithComboFlag())
3584 return true; //else double-counting!
3585
3586 bool locIsRESTEvent = locEventLoop->GetJEvent().GetStatusBit(kSTATUS_REST);
3587
3588 vector<const DTrackTimeBased*> locTrackTimeBasedVector;
3589 locEventLoop->Get(locTrackTimeBasedVector);
3590
3591 vector<const DBeamPhoton*> locBeamPhotons;
3592 locEventLoop->Get(locBeamPhotons);
3593
3594 vector<const DFCALShower*> locFCALShowers;
3595 locEventLoop->Get(locFCALShowers);
3596
3597 vector<const DCCALShower*> locCCALShowers;
3598 locEventLoop->Get(locCCALShowers);
3599
3600 vector<const DChargedTrack*> locChargedTracks;
3601 locEventLoop->Get(locChargedTracks);
3602
3603 vector<const DBCALShower*> locBCALShowers;
3604 locEventLoop->Get(locBCALShowers);
3605
3606 vector<const DNeutralShower*> locNeutralShowers;
3607 locEventLoop->Get(locNeutralShowers);
3608
3609 vector<const DTOFPoint*> locTOFPoints;
3610 locEventLoop->Get(locTOFPoints);
3611
3612 vector<const DSCHit*> locSCHits;
3613 locEventLoop->Get(locSCHits);
3614
3615 vector<const DRFTime*> locRFTimes;
3616 locEventLoop->Get(locRFTimes);
3617
3618 const DDetectorMatches* locDetectorMatches = NULL__null;
3619 locEventLoop->GetSingle(locDetectorMatches);
3620
3621 //if not REST
3622 vector<const DTrackWireBased*> locTrackWireBasedVector;
3623 vector<const DTrackCandidate*> locTrackCandidates;
3624 vector<const DTrackCandidate*> locTrackCandidates_CDC;
3625 vector<const DTrackCandidate*> locTrackCandidates_FDC;
3626 vector<const DCDCHit*> locCDCHits;
3627 vector<const DFDCHit*> locFDCHits;
3628 vector<const DTOFHit*> locTOFHits;
3629 vector<const DBCALHit*> locBCALHits;
3630 vector<const DFCALHit*> locFCALHits;
3631 vector<const DCCALHit*> locCCALHits;
3632 vector<const DTAGMHit*> locTAGMHits;
3633 vector<const DTAGHHit*> locTAGHHits;
3634 vector<const DFDCPseudo*> locFDCPseudoHits;
3635 vector<const DRFDigiTime*> locRFDigiTimes;
3636 vector<const DRFTDCDigiTime*> locRFTDCDigiTimes;
3637
3638 size_t locNumFDCWireHits = 0, locNumFDCCathodeHits = 0;
3639 if(!locIsRESTEvent)
3640 {
3641 locEventLoop->Get(locTrackWireBasedVector);
3642 locEventLoop->Get(locTrackCandidates);
3643 locEventLoop->Get(locTrackCandidates_CDC, "CDC");
3644 locEventLoop->Get(locTrackCandidates_FDC, "FDCCathodes");
3645 locEventLoop->Get(locCDCHits);
3646 locEventLoop->Get(locFDCHits);
3647 locEventLoop->Get(locFDCPseudoHits);
3648 locEventLoop->Get(locTOFHits);
3649 locEventLoop->Get(locBCALHits);
3650 locEventLoop->Get(locFCALHits);
3651 locEventLoop->Get(locCCALHits);
3652 locEventLoop->Get(locTAGHHits);
3653 locEventLoop->Get(locTAGMHits);
3654 locEventLoop->Get(locRFDigiTimes);
3655 locEventLoop->Get(locRFTDCDigiTimes);
3656
3657 for(size_t loc_i = 0; loc_i < locFDCHits.size(); ++loc_i)
3658 {
3659 if(locFDCHits[loc_i]->type == DFDCHit::AnodeWire)
3660 ++locNumFDCWireHits;
3661 else
3662 ++locNumFDCCathodeHits;
3663 }
3664 }
3665
3666 //FILL HISTOGRAMS
3667 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
3668 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
3669 Lock_Action(); //ACQUIRE ROOT LOCK!!
3670 {
3671 //# High-Level Objects
3672 dHist_NumHighLevelObjects->Fill(1, (Double_t)locRFTimes.size());
3673 dHist_NumHighLevelObjects->Fill(2, (Double_t)locSCHits.size());
3674 dHist_NumHighLevelObjects->Fill(3, (Double_t)locTOFPoints.size());
3675 dHist_NumHighLevelObjects->Fill(4, (Double_t)locBCALShowers.size());
3676 dHist_NumHighLevelObjects->Fill(5, (Double_t)locFCALShowers.size());
3677 dHist_NumHighLevelObjects->Fill(6, (Double_t)locTrackTimeBasedVector.size());
3678 dHist_NumHighLevelObjects->Fill(7, (Double_t)locDetectorMatches->Get_NumTrackSCMatches());
3679 dHist_NumHighLevelObjects->Fill(8, (Double_t)locDetectorMatches->Get_NumTrackTOFMatches());
3680 dHist_NumHighLevelObjects->Fill(9, (Double_t)locDetectorMatches->Get_NumTrackBCALMatches());
3681 dHist_NumHighLevelObjects->Fill(10, (Double_t)locDetectorMatches->Get_NumTrackFCALMatches());
3682 dHist_NumHighLevelObjects->Fill(11, (Double_t)locBeamPhotons.size());
3683 dHist_NumHighLevelObjects->Fill(12, (Double_t)locChargedTracks.size());
3684 dHist_NumHighLevelObjects->Fill(13, (Double_t)locNeutralShowers.size());
3685 dHist_NumHighLevelObjects->Fill(14, (Double_t)locCCALShowers.size());
3686 //Charged
3687 unsigned int locNumPos = 0, locNumNeg = 0;
3688 for(size_t loc_i = 0; loc_i < locChargedTracks.size(); ++loc_i)
3689 {
3690 if(ParticleCharge(locChargedTracks[loc_i]->Get_BestFOM()->PID()) > 0)
3691 ++locNumPos;
3692 else
3693 ++locNumNeg;
3694 }
3695 dHist_NumChargedTracks->Fill(locChargedTracks.size());
3696 dHist_NumPosChargedTracks->Fill(locNumPos);
3697 dHist_NumNegChargedTracks->Fill(locNumNeg);
3698
3699 //TBT
3700 locNumPos = 0; locNumNeg = 0;
3701 for(size_t loc_i = 0; loc_i < locTrackTimeBasedVector.size(); ++loc_i)
3702 {
3703 if(ParticleCharge(locTrackTimeBasedVector[loc_i]->PID()) > 0)
3704 ++locNumPos;
3705 else
3706 ++locNumNeg;
3707 }
3708 dHist_NumTimeBasedTracks->Fill(locTrackTimeBasedVector.size());
3709 dHist_NumPosTimeBasedTracks->Fill(locNumPos);
3710 dHist_NumNegTimeBasedTracks->Fill(locNumNeg);
3711
3712 if(!locIsRESTEvent)
3713 {
3714 //WBT
3715 locNumPos = 0; locNumNeg = 0;
3716 for(size_t loc_i = 0; loc_i < locTrackWireBasedVector.size(); ++loc_i)
3717 {
3718 if(ParticleCharge(locTrackWireBasedVector[loc_i]->PID()) > 0)
3719 ++locNumPos;
3720 else
3721 ++locNumNeg;
3722 }
3723 dHist_NumWireBasedTracks->Fill(locTrackWireBasedVector.size());
3724 dHist_NumPosWireBasedTracks->Fill(locNumPos);
3725 dHist_NumNegWireBasedTracks->Fill(locNumNeg);
3726
3727 //Candidates
3728 locNumPos = 0; locNumNeg = 0;
3729 for(size_t loc_i = 0; loc_i < locTrackCandidates.size(); ++loc_i)
3730 {
3731 if(locTrackCandidates[loc_i]->charge() > 0.0)
3732 ++locNumPos;
3733 else
3734 ++locNumNeg;
3735 }
3736 dHist_NumTrackCandidates->Fill(locTrackCandidates.size());
3737 dHist_NumPosTrackCandidates->Fill(locNumPos);
3738 dHist_NumNegTrackCandidates->Fill(locNumNeg);
3739
3740 //CDC Candidates
3741 locNumPos = 0; locNumNeg = 0;
3742 for(size_t loc_i = 0; loc_i < locTrackCandidates_CDC.size(); ++loc_i)
3743 {
3744 if(locTrackCandidates_CDC[loc_i]->charge() > 0.0)
3745 ++locNumPos;
3746 else
3747 ++locNumNeg;
3748 }
3749 dHist_NumPosTrackCandidates_CDC->Fill(locNumPos);
3750 dHist_NumNegTrackCandidates_CDC->Fill(locNumNeg);
3751
3752 //FDC Candidates
3753 locNumPos = 0; locNumNeg = 0;
3754 for(size_t loc_i = 0; loc_i < locTrackCandidates_FDC.size(); ++loc_i)
3755 {
3756 if(locTrackCandidates_FDC[loc_i]->charge() > 0.0)
3757 ++locNumPos;
3758 else
3759 ++locNumNeg;
3760 }
3761 dHist_NumPosTrackCandidates_FDC->Fill(locNumPos);
3762 dHist_NumNegTrackCandidates_FDC->Fill(locNumNeg);
3763 }
3764
3765 //Beam Photons
3766 dHist_NumBeamPhotons->Fill((Double_t)locBeamPhotons.size());
3767
3768 //Showers
3769 dHist_NumFCALShowers->Fill((Double_t)locFCALShowers.size());
3770 dHist_NumCCALShowers->Fill((Double_t)locCCALShowers.size());
3771 dHist_NumBCALShowers->Fill((Double_t)locBCALShowers.size());
3772 dHist_NumNeutralShowers->Fill((Double_t)locNeutralShowers.size());
3773
3774 //TOF & SC
3775 dHist_NumTOFPoints->Fill((Double_t)locTOFPoints.size());
3776 dHist_NumSCHits->Fill((Double_t)locSCHits.size());
3777
3778 //TAGGER
3779 if(!locIsRESTEvent)
3780 {
3781 dHist_NumTAGMHits->Fill((Double_t)locTAGMHits.size());
3782 dHist_NumTAGHHits->Fill((Double_t)locTAGHHits.size());
3783 }
3784
3785 //Matches
3786 dHist_NumTrackBCALMatches->Fill((Double_t)locDetectorMatches->Get_NumTrackBCALMatches());
3787 dHist_NumTrackFCALMatches->Fill((Double_t)locDetectorMatches->Get_NumTrackFCALMatches());
3788 dHist_NumTrackTOFMatches->Fill((Double_t)locDetectorMatches->Get_NumTrackTOFMatches());
3789 dHist_NumTrackSCMatches->Fill((Double_t)locDetectorMatches->Get_NumTrackSCMatches());
3790
3791 //Hits
3792 if(!locIsRESTEvent)
3793 {
3794 dHist_NumCDCHits->Fill((Double_t)locCDCHits.size());
3795 dHist_NumFDCWireHits->Fill((Double_t)locNumFDCWireHits);
3796 dHist_NumFDCCathodeHits->Fill((Double_t)locNumFDCCathodeHits);
3797 dHist_NumFDCPseudoHits->Fill((Double_t)locFDCPseudoHits.size());
3798 dHist_NumTOFHits->Fill((Double_t)locTOFHits.size());
3799 dHist_NumBCALHits->Fill((Double_t)locBCALHits.size());
3800 dHist_NumFCALHits->Fill((Double_t)locFCALHits.size());
3801 dHist_NumCCALHits->Fill((Double_t)locCCALHits.size());
3802 dHist_NumRFSignals->Fill((Double_t)(locRFDigiTimes.size() + locRFTDCDigiTimes.size()));
3803 }
3804 }
3805 Unlock_Action(); //RELEASE ROOT LOCK!!
3806
3807 return true;
3808}
3809
3810void DHistogramAction_TrackMultiplicity::Initialize(JEventLoop* locEventLoop)
3811{
3812 string locTrackSelectionTag = "NotATag", locShowerSelectionTag = "NotATag";
3813 if(gPARMS->Exists("COMBO:TRACK_SELECT_TAG"))
3814 gPARMS->GetParameter("COMBO:TRACK_SELECT_TAG", locTrackSelectionTag);
3815 if(gPARMS->Exists("COMBO:SHOWER_SELECT_TAG"))
3816 gPARMS->GetParameter("COMBO:SHOWER_SELECT_TAG", locShowerSelectionTag);
3817
3818 //CREATE THE HISTOGRAMS
3819 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
3820 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
3821 {
3822 //So: Default tag is "", User can set it to something else
3823 //In here, if tag is "", get from gparms, if not, leave it alone
3824 //If gparms value does not exist, set it to (and use) "PreSelect"
3825 if(dTrackSelectionTag == "NotATag")
3826 dTrackSelectionTag = (locTrackSelectionTag == "NotATag") ? "PreSelect" : locTrackSelectionTag;
3827 if(dShowerSelectionTag == "NotATag")
3828 dShowerSelectionTag = (locShowerSelectionTag == "NotATag") ? "PreSelect" : locShowerSelectionTag;
3829
3830 CreateAndChangeTo_ActionDirectory();
3831
3832 string locHistName("NumReconstructedParticles");
3833 if(gDirectory(TDirectory::CurrentDirectory())->Get(locHistName.c_str()) != NULL__null) //already created by another thread, or directory name is duplicate (e.g. two identical steps)
3834 dHist_NumReconstructedParticles = static_cast<TH2D*>(gDirectory(TDirectory::CurrentDirectory())->Get(locHistName.c_str()));
3835 else
3836 {
3837 dHist_NumReconstructedParticles = new TH2D("NumReconstructedParticles", ";Particle Type;Num Particles / Event", 5 + dFinalStatePIDs.size(), -0.5, 4.5 + dFinalStatePIDs.size(), dMaxNumTracks + 1, -0.5, (float)dMaxNumTracks + 0.5);
3838 dHist_NumReconstructedParticles->GetXaxis()->SetBinLabel(1, "# Total");
3839 dHist_NumReconstructedParticles->GetXaxis()->SetBinLabel(2, "# q != 0");
3840 dHist_NumReconstructedParticles->GetXaxis()->SetBinLabel(3, "# q = 0");
3841 dHist_NumReconstructedParticles->GetXaxis()->SetBinLabel(4, "# q = +");
3842 dHist_NumReconstructedParticles->GetXaxis()->SetBinLabel(5, "# q = -");
3843 for(size_t loc_i = 0; loc_i < dFinalStatePIDs.size(); ++loc_i)
3844 {
3845 string locLabelName = string("# ") + string(ParticleName_ROOT(dFinalStatePIDs[loc_i]));
3846 dHist_NumReconstructedParticles->GetXaxis()->SetBinLabel(6 + loc_i, locLabelName.c_str());
3847 }
3848 }
3849
3850 locHistName = "NumGoodReconstructedParticles";
3851 if(gDirectory(TDirectory::CurrentDirectory())->Get(locHistName.c_str()) != NULL__null) //already created by another thread, or directory name is duplicate (e.g. two identical steps)
3852 dHist_NumGoodReconstructedParticles = static_cast<TH2D*>(gDirectory(TDirectory::CurrentDirectory())->Get(locHistName.c_str()));
3853 else
3854 {
3855 dHist_NumGoodReconstructedParticles = new TH2D("NumGoodReconstructedParticles", ";Particle Type;Num Particles / Event", 5 + dFinalStatePIDs.size(), -0.5, 4.5 + dFinalStatePIDs.size(), dMaxNumTracks + 1, -0.5, (float)dMaxNumTracks + 0.5);
3856 dHist_NumGoodReconstructedParticles->GetXaxis()->SetBinLabel(1, "# Total");
3857 dHist_NumGoodReconstructedParticles->GetXaxis()->SetBinLabel(2, "# q != 0");
3858 dHist_NumGoodReconstructedParticles->GetXaxis()->SetBinLabel(3, "# q = 0");
3859 dHist_NumGoodReconstructedParticles->GetXaxis()->SetBinLabel(4, "# q = +");
3860 dHist_NumGoodReconstructedParticles->GetXaxis()->SetBinLabel(5, "# q = -");
3861 for(size_t loc_i = 0; loc_i < dFinalStatePIDs.size(); ++loc_i)
3862 {
3863 string locLabelName = string("# ") + string(ParticleName_ROOT(dFinalStatePIDs[loc_i]));
3864 dHist_NumGoodReconstructedParticles->GetXaxis()->SetBinLabel(6 + loc_i, locLabelName.c_str());
3865 }
3866 }
3867
3868 //Return to the base directory
3869 ChangeTo_BaseDirectory();
3870 }
3871 japp->RootUnLock(); //RELEASE ROOT LOCK!!
3872}
3873
3874bool DHistogramAction_TrackMultiplicity::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
3875{
3876 if(Get_CalledPriorWithComboFlag())
3877 return true; //else double-counting!
3878
3879 vector<const DChargedTrack*> locChargedTracks;
3880 locEventLoop->Get(locChargedTracks);
3881
3882 vector<const DChargedTrack*> locGoodChargedTracks;
3883 locEventLoop->Get(locGoodChargedTracks, dTrackSelectionTag.c_str());
3884
3885 // get #tracks by PID/q type
3886 size_t locNumPositiveTracks = 0, locNumNegativeTracks = 0;
3887 map<Particle_t, size_t> locNumTracksByPID;
3888 for(size_t loc_i = 0; loc_i < locChargedTracks.size(); ++loc_i)
3889 {
3890 const DChargedTrackHypothesis* locChargedTrackHypothesis = locChargedTracks[loc_i]->Get_BestFOM();
3891 Particle_t locPID = locChargedTrackHypothesis->PID();
3892
3893 if(locChargedTrackHypothesis->charge() > 0.0)
3894 ++locNumPositiveTracks;
3895 else
3896 ++locNumNegativeTracks;
3897
3898 if(locNumTracksByPID.find(locPID) != locNumTracksByPID.end())
3899 ++locNumTracksByPID[locPID];
3900 else
3901 locNumTracksByPID[locPID] = 1;
3902 }
3903
3904 // get # good tracks by PID/q type
3905 size_t locNumGoodPositiveTracks = 0, locNumGoodNegativeTracks = 0;
3906 map<Particle_t, size_t> locNumGoodTracksByPID;
3907 for(size_t loc_i = 0; loc_i < locGoodChargedTracks.size(); ++loc_i)
3908 {
3909 const DChargedTrackHypothesis* locChargedTrackHypothesis = locGoodChargedTracks[loc_i]->Get_BestFOM();
3910 Particle_t locPID = locChargedTrackHypothesis->PID();
3911
3912 double locPIDFOM = locChargedTrackHypothesis->Get_FOM();
3913
3914 if(locChargedTrackHypothesis->charge() > 0.0)
3915 ++locNumGoodPositiveTracks;
3916 else
3917 ++locNumGoodNegativeTracks;
3918
3919 if(locPIDFOM < dMinPIDFOM)
3920 continue;
3921
3922 if(locNumGoodTracksByPID.find(locPID) != locNumGoodTracksByPID.end())
3923 ++locNumGoodTracksByPID[locPID];
3924 else
3925 locNumGoodTracksByPID[locPID] = 1;
3926 }
3927
3928 vector<const DNeutralParticle*> locNeutralParticles;
3929 locEventLoop->Get(locNeutralParticles);
3930
3931 vector<const DNeutralParticle*> locGoodNeutralParticles;
3932 locEventLoop->Get(locGoodNeutralParticles, dShowerSelectionTag.c_str());
3933
3934 // neutrals by pid
3935 for(size_t loc_i = 0; loc_i < locNeutralParticles.size(); ++loc_i)
3936 {
3937 const DNeutralParticleHypothesis* locNeutralParticleHypothesis = locNeutralParticles[loc_i]->Get_BestFOM();
3938 if(locNeutralParticleHypothesis->Get_FOM() < dMinPIDFOM)
3939 continue;
3940
3941 Particle_t locPID = locNeutralParticleHypothesis->PID();
3942 if(locNumTracksByPID.find(locPID) != locNumTracksByPID.end())
3943 ++locNumTracksByPID[locPID];
3944 else
3945 locNumTracksByPID[locPID] = 1;
3946 }
3947
3948 // good neutrals
3949 for(size_t loc_i = 0; loc_i < locGoodNeutralParticles.size(); ++loc_i)
3950 {
3951 const DNeutralParticleHypothesis* locNeutralParticleHypothesis = locGoodNeutralParticles[loc_i]->Get_BestFOM();
3952 if(locNeutralParticleHypothesis->Get_FOM() < dMinPIDFOM)
3953 continue;
3954
3955 Particle_t locPID = locNeutralParticleHypothesis->PID();
3956 if(locNumGoodTracksByPID.find(locPID) != locNumGoodTracksByPID.end())
3957 ++locNumGoodTracksByPID[locPID];
3958 else
3959 locNumGoodTracksByPID[locPID] = 1;
3960 }
3961
3962 size_t locNumGoodTracks = locNumGoodPositiveTracks + locNumGoodNegativeTracks;
3963
3964 //FILL HISTOGRAMS
3965 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
3966 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
3967 Lock_Action();
3968 {
3969 dHist_NumReconstructedParticles->Fill(0.0, (Double_t)(locChargedTracks.size() + locNeutralParticles.size()));
3970 dHist_NumReconstructedParticles->Fill(1.0, (Double_t)locChargedTracks.size());
3971 dHist_NumReconstructedParticles->Fill(2.0, (Double_t)locNeutralParticles.size());
3972 dHist_NumReconstructedParticles->Fill(3.0, (Double_t)locNumPositiveTracks);
3973 dHist_NumReconstructedParticles->Fill(4.0, (Double_t)locNumNegativeTracks);
3974 for(size_t loc_i = 0; loc_i < dFinalStatePIDs.size(); ++loc_i)
3975 dHist_NumReconstructedParticles->Fill(5.0 + (Double_t)loc_i, (Double_t)locNumTracksByPID[dFinalStatePIDs[loc_i]]);
3976
3977 dHist_NumGoodReconstructedParticles->Fill(0.0, (Double_t)(locNumGoodTracks + locGoodNeutralParticles.size()));
3978 dHist_NumGoodReconstructedParticles->Fill(1.0, (Double_t)locNumGoodTracks);
3979 dHist_NumGoodReconstructedParticles->Fill(2.0, (Double_t)locGoodNeutralParticles.size());
3980 dHist_NumGoodReconstructedParticles->Fill(3.0, (Double_t)locNumGoodPositiveTracks);
3981 dHist_NumGoodReconstructedParticles->Fill(4.0, (Double_t)locNumGoodNegativeTracks);
3982 for(size_t loc_i = 0; loc_i < dFinalStatePIDs.size(); ++loc_i)
3983 dHist_NumGoodReconstructedParticles->Fill(5.0 + (Double_t)loc_i, (Double_t)locNumGoodTracksByPID[dFinalStatePIDs[loc_i]]);
3984 }
3985 Unlock_Action();
3986
3987 return true;
3988}
3989
3990// DHistogramAction_TriggerStudies
3991// dHist_Trigger_FCALBCAL_Energy
3992
3993void DHistogramAction_TriggerStudies::Initialize(JEventLoop* locEventLoop)
3994{
3995
3996 //CREATE THE HISTOGRAMS
3997 //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
3998 japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
3999 {
4000 CreateAndChangeTo_ActionDirectory();
4001
4002 string locHistName("Trigger_BCALFCAL_Energy");
4003 if(gDirectory(TDirectory::CurrentDirectory())->Get(locHistName.c_str()) != NULL__null) //already created by another thread, or directory name is duplicate (e.g. two identical steps)
4004 dHist_Trigger_FCALBCAL_Energy = static_cast<TH2D*>(gDirectory(TDirectory::CurrentDirectory())->Get(locHistName.c_str()));
4005 else
4006 {
4007 dHist_Trigger_FCALBCAL_Energy = new TH2D("Trigger_BCALFCAL_Energy", ";GTP FCAL Energy [GeV] / 5 MeV;GTP BCAL Energy [GeV] / 5 MeV", dFCALBins, 0, dMaxFCALEnergy, dBCALBins, 0, dMaxBCALEnergy);
4008 }
4009
4010 //Return to the base directory
4011 ChangeTo_BaseDirectory();
4012 }
4013 japp->RootUnLock(); //RELEASE ROOT LOCK!!
4014}
4015
4016bool DHistogramAction_TriggerStudies::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
4017{
4018 if(Get_CalledPriorWithComboFlag())
4019 return true; //else double-counting!
4020
4021 //CHECK TRIGGER TYPE
4022 const DTrigger* locTrigger = NULL__null;
4023 locEventLoop->GetSingle(locTrigger);
4024 if(locTrigger == nullptr)
4025 return true;
4026
4027
4028 //FILL HISTOGRAMS
4029 //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
4030 //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
4031 Lock_Action();
4032 {
4033 dHist_Trigger_FCALBCAL_Energy->Fill(locTrigger->Get_GTP_FCALEnergy(), locTrigger->Get_GTP_BCALEnergy());
4034 }
4035 Unlock_Action();
4036
4037 return true;
4038}
4039

/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h

1// $Id: JEventLoop.h 1763 2006-05-10 14:29:25Z davidl $
2//
3// File: JEventLoop.h
4// Created: Wed Jun 8 12:30:51 EDT 2005
5// Creator: davidl (on Darwin wire129.jlab.org 7.8.0 powerpc)
6//
7
8#ifndef _JEventLoop_
9#define _JEventLoop_
10
11#include <sys/time.h>
12
13#include <vector>
14#include <list>
15#include <string>
16#include <utility>
17#include <typeinfo>
18#include <string.h>
19#include <map>
20#include <utility>
21using std::vector;
22using std::list;
23using std::string;
24using std::type_info;
25
26#include <JANA/jerror.h>
27#include <JANA/JObject.h>
28#include <JANA/JException.h>
29#include <JANA/JEvent.h>
30#include <JANA/JThread.h>
31#include <JANA/JFactory_base.h>
32#include <JANA/JCalibration.h>
33#include <JANA/JGeometry.h>
34#include <JANA/JResourceManager.h>
35#include <JANA/JStreamLog.h>
36
37// The following is here just so we can use ROOT's THtml class to generate documentation.
38#include "cint.h"
39
40
41// Place everything in JANA namespace
42namespace jana{
43
44
45template<class T> class JFactory;
46class JApplication;
47class JEventProcessor;
48
49
50class JEventLoop{
51 public:
52
53 friend class JApplication;
54
55 enum data_source_t{
56 DATA_NOT_AVAILABLE = 1,
57 DATA_FROM_CACHE,
58 DATA_FROM_SOURCE,
59 DATA_FROM_FACTORY
60 };
61
62 typedef struct{
63 string caller_name;
64 string caller_tag;
65 string callee_name;
66 string callee_tag;
67 double start_time;
68 double end_time;
69 data_source_t data_source;
70 }call_stack_t;
71
72 typedef struct{
73 const char* factory_name;
74 string tag;
75 const char* filename;
76 int line;
77 }error_call_stack_t;
78
79 JEventLoop(JApplication *app); ///< Constructor
80 virtual ~JEventLoop(); ////< Destructor
81 virtual const char* className(void){return static_className();}
82 static const char* static_className(void){return "JEventLoop";}
83
84 JApplication* GetJApplication(void) const {return app;} ///< Get pointer to the JApplication object
85 void RefreshProcessorListFromJApplication(void); ///< Re-copy the list of JEventProcessors from JApplication
86 virtual jerror_t AddFactory(JFactory_base* factory); ///< Add a factory
87 jerror_t RemoveFactory(JFactory_base* factory); ///< Remove a factory
88 JFactory_base* GetFactory(const string data_name, const char *tag="", bool allow_deftag=true); ///< Get a specific factory pointer
89 vector<JFactory_base*> GetFactories(void) const {return factories;} ///< Get all factory pointers
90 void GetFactoryNames(vector<string> &factorynames); ///< Get names of all factories in name:tag format
91 void GetFactoryNames(map<string,string> &factorynames); ///< Get names of all factories in map with key=name, value=tag
92 map<string,string> GetDefaultTags(void) const {return default_tags;}
93 jerror_t ClearFactories(void); ///< Reset all factories in preparation for next event.
94 jerror_t PrintFactories(int sparsify=0); ///< Print a list of all factories.
95 jerror_t Print(const string data_name, const char *tag=""); ///< Print the data of the given type
96
97 JCalibration* GetJCalibration();
98 template<class T> bool GetCalib(string namepath, map<string,T> &vals);
99 template<class T> bool GetCalib(string namepath, vector<T> &vals);
100 template<class T> bool GetCalib(string namepath, T &val);
101
102 JGeometry* GetJGeometry();
103 template<class T> bool GetGeom(string namepath, map<string,T> &vals);
104 template<class T> bool GetGeom(string namepath, T &val);
105
106 JResourceManager* GetJResourceManager(void);
107 string GetResource(string namepath);
108 template<class T> bool GetResource(string namepath, T vals, int event_number=0);
109
110 void Initialize(void); ///< Do initializations just before event processing starts
111 jerror_t Loop(void); ///< Loop over events
112 jerror_t OneEvent(uint64_t event_number); ///< Process a specific single event (if source supports it)
113 jerror_t OneEvent(void); ///< Process a single event
114 inline void Pause(void){pause = 1;} ///< Pause event processing
115 inline void Resume(void){pause = 0;} ///< Resume event processing
116 inline void Quit(void){quit = 1;} ///< Clean up and exit the event loop
117 inline bool GetQuit(void) const {return quit;}
118 void QuitProgram(void);
119
120 // Support for random access of events
121 bool HasRandomAccess(void);
122 void AddToEventQueue(uint64_t event_number){ next_events_to_process.push_back(event_number); }
123 void AddToEventQueue(list<uint64_t> &event_numbers) { next_events_to_process.insert(next_events_to_process.end(), event_numbers.begin(), event_numbers.end()); }
124 list<uint64_t> GetEventQueue(void){ return next_events_to_process; }
125 void ClearEventQueue(void){ next_events_to_process.clear(); }
126
127 template<class T> JFactory<T>* GetSingle(const T* &t, const char *tag="", bool exception_if_not_one=true); ///< Get pointer to first data object from (source or factory).
128 template<class T> JFactory<T>* Get(vector<const T*> &t, const char *tag="", bool allow_deftag=true); ///< Get data object pointers from (source or factory)
129 template<class T> JFactory<T>* GetFromFactory(vector<const T*> &t, const char *tag="", data_source_t &data_source=null_data_source, bool allow_deftag=true); ///< Get data object pointers from factory
130 template<class T> jerror_t GetFromSource(vector<const T*> &t, JFactory_base *factory=NULL__null); ///< Get data object pointers from source.
131 inline JEvent& GetJEvent(void){return event;} ///< Get pointer to the current JEvent object.
132 inline void SetJEvent(JEvent *event){this->event = *event;} ///< Set the JEvent pointer.
133 inline void SetAutoFree(int auto_free){this->auto_free = auto_free;} ///< Set the Auto-Free flag on/off
134 inline pthread_t GetPThreadID(void) const {return pthread_id;} ///< Get the pthread of the thread to which this JEventLoop belongs
135 double GetInstantaneousRate(void) const {return rate_instantaneous;} ///< Get the current event processing rate
136 double GetIntegratedRate(void) const {return rate_integrated;} ///< Get the current event processing rate
137 double GetLastEventProcessingTime(void) const {return delta_time_single;}
138 unsigned int GetNevents(void) const {return Nevents;}
139
140 inline bool CheckEventBoundary(uint64_t event_numberA, uint64_t event_numberB);
141
142 inline bool GetCallStackRecordingStatus(void){ return record_call_stack; }
143 inline void DisableCallStackRecording(void){ record_call_stack = false; }
144 inline void EnableCallStackRecording(void){ record_call_stack = true; }
145 inline void CallStackStart(JEventLoop::call_stack_t &cs, const string &caller_name, const string &caller_tag, const string callee_name, const string callee_tag);
146 inline void CallStackEnd(JEventLoop::call_stack_t &cs);
147 inline vector<call_stack_t> GetCallStack(void){return call_stack;} ///< Get the current factory call stack
148 inline void AddToCallStack(call_stack_t &cs){if(record_call_stack) call_stack.push_back(cs);} ///< Add specified item to call stack record but only if record_call_stack is true
149 inline void AddToErrorCallStack(error_call_stack_t &cs){error_call_stack.push_back(cs);} ///< Add layer to the factory call stack
150 inline vector<error_call_stack_t> GetErrorCallStack(void){return error_call_stack;} ///< Get the current factory error call stack
151 void PrintErrorCallStack(void); ///< Print the current factory call stack
152
153 const JObject* FindByID(JObject::oid_t id); ///< Find a data object by its identifier.
154 template<class T> const T* FindByID(JObject::oid_t id); ///< Find a data object by its type and identifier
155 JFactory_base* FindOwner(const JObject *t); ///< Find the factory that owns a data object by pointer
156 JFactory_base* FindOwner(JObject::oid_t id); ///< Find a factory that owns a data object by identifier
157
158 // User defined references
159 template<class T> void SetRef(T *t); ///< Add a user reference to this JEventLoop (must be a pointer)
160 template<class T> T* GetRef(void); ///< Get a user-defined reference of a specific type
161 template<class T> vector<T*> GetRefsT(void); ///< Get all user-defined refrences of a specicif type
162 vector<pair<const char*, void*> > GetRefs(void){ return user_refs; } ///< Get copy of full list of user-defined references
163 template<class T> void RemoveRef(T *t); ///< Remove user reference from list
164
165 // Convenience methods wrapping JEvent methods of same name
166 uint64_t GetStatus(void){return event.GetStatus();}
167 bool GetStatusBit(uint32_t bit){return event.GetStatusBit(bit);}
168 bool SetStatusBit(uint32_t bit, bool val=true){return event.SetStatusBit(bit, val);}
169 bool ClearStatusBit(uint32_t bit){return event.ClearStatusBit(bit);}
170 void ClearStatus(void){event.ClearStatus();}
171 void SetStatusBitDescription(uint32_t bit, string description){event.SetStatusBitDescription(bit, description);}
172 string GetStatusBitDescription(uint32_t bit){return event.GetStatusBitDescription(bit);}
173 void GetStatusBitDescriptions(map<uint32_t, string> &status_bit_descriptions){return event.GetStatusBitDescriptions(status_bit_descriptions);}
174 string StatusWordToString(void);
175
176 private:
177 JEvent event;
178 vector<JFactory_base*> factories;
179 vector<JEventProcessor*> processors;
180 vector<error_call_stack_t> error_call_stack;
181 vector<call_stack_t> call_stack;
182 JApplication *app;
183 JThread *jthread;
184 bool initialized;
185 bool print_parameters_called;
186 int pause;
187 int quit;
188 int auto_free;
189 pthread_t pthread_id;
190 map<string, string> default_tags;
191 vector<pair<string,string> > auto_activated_factories;
192 bool record_call_stack;
193 string caller_name;
194 string caller_tag;
195 vector<uint64_t> event_boundaries;
196 int32_t event_boundaries_run; ///< Run number boundaries were retrieved from (possbily 0)
197 list<uint64_t> next_events_to_process;
198
199 uint64_t Nevents; ///< Total events processed (this thread)
200 uint64_t Nevents_rate; ///< Num. events accumulated for "instantaneous" rate
201 double delta_time_single; ///< Time spent processing last event
202 double delta_time_rate; ///< Integrated time accumulated "instantaneous" rate (partial number of events)
203 double delta_time; ///< Total time spent processing events (this thread)
204 double rate_instantaneous; ///< Latest instantaneous rate
205 double rate_integrated; ///< Rate integrated over all events
206
207 static data_source_t null_data_source;
208
209 vector<pair<const char*, void*> > user_refs;
210};
211
212
213// The following is here just so we can use ROOT's THtml class to generate documentation.
214#ifdef G__DICTIONARY
215typedef JEventLoop::call_stack_t call_stack_t;
216typedef JEventLoop::error_call_stack_t error_call_stack_t;
217#endif
218
219#if !defined(__CINT__) && !defined(__CLING__)
220
221//-------------
222// GetSingle
223//-------------
224template<class T>
225JFactory<T>* JEventLoop::GetSingle(const T* &t, const char *tag, bool exception_if_not_one)
226{
227 /// This is a convenience method that can be used to get a pointer to the single
228 /// object of type T from the specified factory. It simply calls the Get(vector<...>) method
229 /// and copies the first pointer into "t" (or NULL if something other than 1 object is returned).
230 ///
231 /// This is intended to address the common situation in which there is an interest
232 /// in the event if and only if there is exactly 1 object of type T. If the event
233 /// has no objects of that type or more than 1 object of that type (for the specified
234 /// factory) then an exception of type "unsigned long" is thrown with the value
235 /// being the number of objects of type T. You can supress the exception by setting
236 /// exception_if_not_one to false. In that case, you will have to check if t==NULL to
237 /// know if the call succeeded.
238 vector<const T*> v;
239 JFactory<T> *fac = Get(v, tag);
2
Calling 'JEventLoop::Get'
240
241 if(v.size()!=1){
242 t = NULL__null;
243 if(exception_if_not_one) throw v.size();
244 }
245
246 t = v[0];
247
248 return fac;
249}
250
251//-------------
252// Get
253//-------------
254template<class T>
255JFactory<T>* JEventLoop::Get(vector<const T*> &t, const char *tag, bool allow_deftag)
256{
257 /// Retrieve or generate the array of objects of
258 /// type T for the curent event being processed
259 /// by this thread.
260 ///
261 /// By default, preference is given to reading the
262 /// objects from the data source(e.g. file) before generating
263 /// them in the factory. A flag exists in the factory
264 /// however to change this so that the factory is
265 /// given preference.
266 ///
267 /// Note that regardless of the setting of this flag,
268 /// the data are only either read in or generated once.
269 /// Ownership of the objects will always be with the
270 /// factory so subsequent calls will always return pointers to
271 /// the same data.
272 ///
273 /// If the factory is called on to generate the data,
274 /// it is done by calling the factory's Get() method
275 /// which, in turn, calls the evnt() method.
276 ///
277 /// First, we just call the GetFromFactory() method.
278 /// It will make the initial decision as to whether
279 /// it should look in the source first or not. If
280 /// it returns NULL, then the factory couldn't be
281 /// found so we automatically try the file.
282 ///
283 /// Note that if no factory exists to hold the objects
284 /// from the file, one can be created automatically
285 /// providing the <i>JANA:AUTOFACTORYCREATE</i>
286 /// configuration parameter is set.
287
288 // Check if a tag was specified for this data type to use for the
289 // default.
290 const char *mytag = tag
2.1
'tag' is not equal to NULL
2.1
'tag' is not equal to NULL
2.1
'tag' is not equal to NULL
==NULL__null ? "":tag; // protection against NULL tags
3
'?' condition is false
291 if(strlen(mytag)==0 && allow_deftag
3.1
'allow_deftag' is true
3.1
'allow_deftag' is true
3.1
'allow_deftag' is true
){
4
Taking true branch
292 map<string, string>::const_iterator iter = default_tags.find(T::static_className());
293 if(iter!=default_tags.end())tag = iter->second.c_str();
5
Assuming the condition is true
6
Taking true branch
7
Value assigned to 'tag'
294 }
295
296
297 // If we are trying to keep track of the call stack then we
298 // need to add a new call_stack_t object to the the list
299 // and initialize it with the start time and caller/callee
300 // info.
301 call_stack_t cs;
302
303 // Optionally record starting info of call stack entry
304 if(record_call_stack) CallStackStart(cs, caller_name, caller_tag, T::static_className(), tag);
8
Assuming field 'record_call_stack' is false
9
Taking false branch
305
306 // Get the data (or at least try to)
307 JFactory<T>* factory=NULL__null;
308 try{
309 factory = GetFromFactory(t, tag, cs.data_source, allow_deftag);
10
Passing value via 2nd parameter 'tag'
11
Calling 'JEventLoop::GetFromFactory'
310 if(!factory){
311 // No factory exists for this type and tag. It's possible
312 // that the source may be able to provide the objects
313 // but it will need a place to put them. We can create a
314 // dumb JFactory just to hold the data in case the source
315 // can provide the objects. Before we do though, make sure
316 // the user condones this via the presence of the
317 // "JANA:AUTOFACTORYCREATE" config parameter.
318 string p;
319 try{
320 gPARMS->GetParameter("JANA:AUTOFACTORYCREATE", p);
321 }catch(...){}
322 if(p.size()==0){
323 jout<<std::endl;
324 _DBG__std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<324<<std::endl
;
325 jout<<"No factory of type \""<<T::static_className()<<"\" with tag \""<<tag<<"\" exists."<<std::endl;
326 jout<<"If you are reading objects from a file, I can auto-create a factory"<<std::endl;
327 jout<<"of the appropriate type to hold the objects, but this feature is turned"<<std::endl;
328 jout<<"off by default. To turn it on, set the \"JANA:AUTOFACTORYCREATE\""<<std::endl;
329 jout<<"configuration parameter. This can usually be done by passing the"<<std::endl;
330 jout<<"following argument to the program from the command line:"<<std::endl;
331 jout<<std::endl;
332 jout<<" -PJANA:AUTOFACTORYCREATE=1"<<std::endl;
333 jout<<std::endl;
334 jout<<"Note that since the most commonly expected occurance of this situation."<<std::endl;
335 jout<<"is an error, the program will now throw an exception so that the factory."<<std::endl;
336 jout<<"call stack can be printed."<<std::endl;
337 jout<<std::endl;
338 throw exception();
339 }else{
340 AddFactory(new JFactory<T>(tag));
341 jout<<__FILE__"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"<<":"<<__LINE__341<<" Auto-created "<<T::static_className()<<":"<<tag<<" factory"<<std::endl;
342
343 // Now try once more. The GetFromFactory method will call
344 // GetFromSource since it's empty.
345 factory = GetFromFactory(t, tag, cs.data_source, allow_deftag);
346 }
347 }
348 }catch(exception &e){
349 // Uh-oh, an exception was thrown. Add us to the call stack
350 // and re-throw the exception
351 error_call_stack_t ecs;
352 ecs.factory_name = T::static_className();
353 ecs.tag = tag;
354 ecs.filename = NULL__null;
355 error_call_stack.push_back(ecs);
356 throw e;
357 }
358
359 // If recording the call stack, update the end_time field and add to stack
360 if(record_call_stack) CallStackEnd(cs);
361
362 return factory;
363}
364
365//-------------
366// GetFromFactory
367//-------------
368template<class T>
369JFactory<T>* JEventLoop::GetFromFactory(vector<const T*> &t, const char *tag, data_source_t &data_source, bool allow_deftag)
370{
371 // We need to find the factory providing data type T with
372 // tag given by "tag".
373 vector<JFactory_base*>::iterator iter=factories.begin();
374 JFactory<T> *factory = NULL__null;
375 string className(T::static_className());
376
377 // Check if a tag was specified for this data type to use for the
378 // default.
379 const char *mytag = tag==NULL__null ? "":tag; // protection against NULL tags
12
Assuming 'tag' is equal to NULL
13
Assuming pointer value is null
14
'?' condition is true
380 if(strlen(mytag)==0 && allow_deftag
14.1
'allow_deftag' is true
14.1
'allow_deftag' is true
14.1
'allow_deftag' is true
){
15
Taking true branch
381 map<string, string>::const_iterator iter = default_tags.find(className);
382 if(iter!=default_tags.end())tag = iter->second.c_str();
16
Assuming the condition is false
17
Taking false branch
383 }
384
385 for(; iter!=factories.end(); iter++){
18
Calling 'operator!=<jana::JFactory_base **, std::vector<jana::JFactory_base *>>'
21
Returning from 'operator!=<jana::JFactory_base **, std::vector<jana::JFactory_base *>>'
22
Loop condition is true. Entering loop body
386 // It turns out a long standing bug in g++ makes dynamic_cast return
387 // zero improperly when used on objects created on one side of
388 // a dynamically shared object (DSO) and the cast occurs on the
389 // other side. I saw bug reports ranging from 2001 to 2004. I saw
390 // saw it first-hand on LinuxEL4 using g++ 3.4.5. This is too bad
391 // since it is much more elegant (and safe) to use dynamic_cast.
392 // To avoid this problem which can occur with plugins, we check
393 // the name of the data classes are the same. (sigh)
394 //factory = dynamic_cast<JFactory<T> *>(*iter);
395 if(className == (*iter)->GetDataClassName())factory = (JFactory<T>*)(*iter);
23
Taking true branch
396 if(factory == NULL__null)continue;
24
Assuming 'factory' is not equal to NULL
25
Taking false branch
397 const char *factag = factory->Tag()==NULL__null ? "":factory->Tag();
26
Assuming the condition is true
27
'?' condition is true
398 if(!strcmp(factag, tag)){
28
Null pointer passed to 2nd parameter expecting 'nonnull'
399 break;
400 }else{
401 factory=NULL__null;
402 }
403 }
404
405 // If factory not found, just return now
406 if(!factory){
407 data_source = DATA_NOT_AVAILABLE;
408 return NULL__null;
409 }
410
411 // OK, we found the factory. If the evnt() routine has already
412 // been called, then just call the factory's Get() routine
413 // to return a copy of the existing data
414 if(factory->evnt_was_called()){
415 factory->CopyFrom(t);
416 data_source = DATA_FROM_CACHE;
417 return factory;
418 }
419
420 // Next option is to get the objects from the data source
421 if(factory->GetCheckSourceFirst()){
422 // If the object type/tag is found in the source, it
423 // will return NOERROR, even if there are zero instances
424 // of it. If it is not available in the source then it
425 // will return OBJECT_NOT_AVAILABLE.
426
427 jerror_t err = GetFromSource(t, factory);
428 if(err == NOERROR){
429 // A return value of NOERROR means the source had the objects
430 // even if there were zero of them.(If the source had no
431 // information about the objects OBJECT_NOT_AVAILABLE would
432 // have been returned.)
433 // The GetFromSource() call will eventually lead to a call to
434 // the GetObjects() method of the concrete class derived
435 // from JEventSource. That routine should copy the object
436 // pointers into the factory using the factory's CopyTo()
437 // method which also sets the evnt_called flag for the factory.
438 // Note also that the "t" vector is then filled with a call
439 // to the factory's CopyFrom() method in JEvent::GetObjects().
440 // All we need to do now is just set the factory pointers in
441 // the newly generated JObjects and return the factory pointer.
442
443 factory->SetFactoryPointers();
444 data_source = DATA_FROM_SOURCE;
445
446 return factory;
447 }
448 }
449
450 // OK. It looks like we have to have the factory make this.
451 // Get pointers to data from the factory.
452 factory->Get(t);
453 factory->SetFactoryPointers();
454 data_source = DATA_FROM_FACTORY;
455
456 return factory;
457}
458
459//-------------
460// GetFromSource
461//-------------
462template<class T>
463jerror_t JEventLoop::GetFromSource(vector<const T*> &t, JFactory_base *factory)
464{
465 /// This tries to get objects from the event source.
466 /// "factory" must be a valid pointer to a JFactory
467 /// object since that will take ownership of the objects
468 /// created by the source.
469 /// This should usually be called from JEventLoop::GetFromFactory
470 /// which is called from JEventLoop::Get. The latter will
471 /// create a dummy JFactory of the proper flavor and tag if
472 /// one does not already exist so if objects exist in the
473 /// file without a corresponding factory to create them, they
474 /// can still be used.
475 if(!factory)throw OBJECT_NOT_AVAILABLE;
476
477 return event.GetObjects(t, factory);
478}
479
480//-------------
481// CallStackStart
482//-------------
483inline void JEventLoop::CallStackStart(JEventLoop::call_stack_t &cs, const string &caller_name, const string &caller_tag, const string callee_name, const string callee_tag)
484{
485 /// This is used to fill initial info into a call_stack_t stucture
486 /// for recording the call stack. It should be matched with a call
487 /// to CallStackEnd. It is normally called from the Get() method
488 /// above, but may also be used by external actors to manipulate
489 /// the call stack (presumably for good and not evil).
490
491 struct itimerval tmr;
492 getitimer(ITIMER_PROFITIMER_PROF, &tmr);
493
494 cs.caller_name = this->caller_name;
495 cs.caller_tag = this->caller_tag;
496 this->caller_name = cs.callee_name = callee_name;
497 this->caller_tag = cs.callee_tag = callee_tag;
498 cs.start_time = tmr.it_value.tv_sec + tmr.it_value.tv_usec/1.0E6;
499}
500
501//-------------
502// CallStackEnd
503//-------------
504inline void JEventLoop::CallStackEnd(JEventLoop::call_stack_t &cs)
505{
506 /// Complete a call stack entry. This should be matched
507 /// with a previous call to CallStackStart which was
508 /// used to fill the cs structure.
509
510 struct itimerval tmr;
511 getitimer(ITIMER_PROFITIMER_PROF, &tmr);
512 cs.end_time = tmr.it_value.tv_sec + tmr.it_value.tv_usec/1.0E6;
513 caller_name = cs.caller_name;
514 caller_tag = cs.caller_tag;
515 call_stack.push_back(cs);
516}
517
518//-------------
519// CheckEventBoundary
520//-------------
521inline bool JEventLoop::CheckEventBoundary(uint64_t event_numberA, uint64_t event_numberB)
522{
523 /// Check whether the two event numbers span one or more boundaries
524 /// in the calibration/conditions database for the current run number.
525 /// Return true if they do and false if they don't. The first parameter
526 /// "event_numberA" is also checked if it lands on a boundary in which
527 /// case true is also returned. If event_numberB lands on a boundary,
528 /// but event_numberA does not, then false is returned.
529 ///
530 /// This method is not expected to be called by a user. It is, however called,
531 /// everytime a JFactory's Get() method is called.
532
533 // Make sure our copy of the boundaries is up to date
534 if(event.GetRunNumber()!=event_boundaries_run){
535 event_boundaries.clear(); // in case we can't get the JCalibration pointer
536 JCalibration *jcalib = GetJCalibration();
537 if(jcalib)jcalib->GetEventBoundaries(event_boundaries);
538 event_boundaries_run = event.GetRunNumber();
539 }
540
541 // Loop over boundaries
542 for(unsigned int i=0; i<event_boundaries.size(); i++){
543 uint64_t eb = event_boundaries[i];
544 if((eb - event_numberA)*(eb - event_numberB) < 0.0 || eb==event_numberA){ // think about it ....
545 // events span a boundary or is on a boundary. Return true
546 return true;
547 }
548 }
549
550 return false;
551}
552
553//-------------
554// FindByID
555//-------------
556template<class T>
557const T* JEventLoop::FindByID(JObject::oid_t id)
558{
559 /// This is a templated method that can be used in place
560 /// of the non-templated FindByID(oid_t) method if one knows
561 /// the class of the object with the specified id.
562 /// This method is faster than calling the non-templated
563 /// FindByID and dynamic_cast-ing the JObject since
564 /// this will only search the objects of factories that
565 /// produce the desired data type.
566 /// This method will cast the JObject pointer to one
567 /// of the specified type. To use this method,
568 /// a type is specified in the call as follows:
569 ///
570 /// const DMyType *t = loop->FindByID<DMyType>(id);
571
572 // Loop over factories looking for ones that provide
573 // specified data type.
574 for(unsigned int i=0; i<factories.size(); i++){
575 if(factories[i]->GetDataClassName() != T::static_className())continue;
576
577 // This factory provides data of type T. Search it for
578 // the object with the specified id.
579 const JObject *my_obj = factories[i]->GetByID(id);
580 if(my_obj)return dynamic_cast<const T*>(my_obj);
581 }
582
583 return NULL__null;
584}
585
586//-------------
587// GetCalib (map)
588//-------------
589template<class T>
590bool JEventLoop::GetCalib(string namepath, map<string,T> &vals)
591{
592 /// Get the JCalibration object from JApplication for the run number of
593 /// the current event and call its Get() method to get the constants.
594
595 // Note that we could do this by making "vals" a generic type T thus, combining
596 // this with the vector version below. However, doing this explicitly will make
597 // it easier for the user to understand how to call us.
598
599 vals.clear();
600
601 JCalibration *calib = GetJCalibration();
602 if(!calib){
603 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<603<<" "
<<"Unable to get JCalibration object for run "<<event.GetRunNumber()<<std::endl;
604 return true;
605 }
606
607 return calib->Get(namepath, vals, event.GetEventNumber());
608}
609
610//-------------
611// GetCalib (vector)
612//-------------
613template<class T> bool JEventLoop::GetCalib(string namepath, vector<T> &vals)
614{
615 /// Get the JCalibration object from JApplication for the run number of
616 /// the current event and call its Get() method to get the constants.
617
618 vals.clear();
619
620 JCalibration *calib = GetJCalibration();
621 if(!calib){
622 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<622<<" "
<<"Unable to get JCalibration object for run "<<event.GetRunNumber()<<std::endl;
623 return true;
624 }
625
626 return calib->Get(namepath, vals, event.GetEventNumber());
627}
628
629//-------------
630// GetCalib (single)
631//-------------
632template<class T> bool JEventLoop::GetCalib(string namepath, T &val)
633{
634 /// This is a convenience method for getting a single entry. It
635 /// simply calls the vector version and returns the first entry.
636 /// It returns true if the vector version returns true AND there
637 /// is at least one entry in the vector. No check is made for there
638 /// there being more than one entry in the vector.
639
640 vector<T> vals;
641 bool ret = GetCalib(namepath, vals);
642 if(vals.empty()) return true;
643 val = vals[0];
644
645 return ret;
646}
647
648//-------------
649// GetGeom (map)
650//-------------
651template<class T>
652bool JEventLoop::GetGeom(string namepath, map<string,T> &vals)
653{
654 /// Get the JGeometry object from JApplication for the run number of
655 /// the current event and call its Get() method to get the constants.
656
657 // Note that we could do this by making "vals" a generic type T thus, combining
658 // this with the vector version below. However, doing this explicitly will make
659 // it easier for the user to understand how to call us.
660
661 vals.clear();
662
663 JGeometry *geom = GetJGeometry();
664 if(!geom){
665 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<665<<" "
<<"Unable to get JGeometry object for run "<<event.GetRunNumber()<<std::endl;
666 return true;
667 }
668
669 return geom->Get(namepath, vals);
670}
671
672//-------------
673// GetGeom (atomic)
674//-------------
675template<class T> bool JEventLoop::GetGeom(string namepath, T &val)
676{
677 /// Get the JCalibration object from JApplication for the run number of
678 /// the current event and call its Get() method to get the constants.
679
680 JGeometry *geom = GetJGeometry();
681 if(!geom){
682 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<682<<" "
<<"Unable to get JGeometry object for run "<<event.GetRunNumber()<<std::endl;
683 return true;
684 }
685
686 return geom->Get(namepath, val);
687}
688
689//-------------
690// SetRef
691//-------------
692template<class T>
693void JEventLoop::SetRef(T *t)
694{
695 pair<const char*, void*> p(typeid(T).name(), (void*)t);
696 user_refs.push_back(p);
697}
698
699//-------------
700// GetResource
701//-------------
702template<class T> bool JEventLoop::GetResource(string namepath, T vals, int event_number)
703{
704 JResourceManager *resource_manager = GetJResourceManager();
705 if(!resource_manager){
706 string mess = string("Unable to get the JResourceManager object (namepath=\"")+namepath+"\")";
707 throw JException(mess);
708 }
709
710 return resource_manager->Get(namepath, vals, event_number);
711}
712
713//-------------
714// GetRef
715//-------------
716template<class T>
717T* JEventLoop::GetRef(void)
718{
719 /// Get a user-defined reference (a pointer)
720 for(unsigned int i=0; i<user_refs.size(); i++){
721 if(user_refs[i].first == typeid(T).name()) return (T*)user_refs[i].second;
722 }
723
724 return NULL__null;
725}
726
727//-------------
728// GetRefsT
729//-------------
730template<class T>
731vector<T*> JEventLoop::GetRefsT(void)
732{
733 vector<T*> refs;
734 for(unsigned int i=0; i<user_refs.size(); i++){
735 if(user_refs[i].first == typeid(T).name()){
736 refs.push_back((T*)user_refs[i].second);
737 }
738 }
739
740 return refs;
741}
742
743//-------------
744// RemoveRef
745//-------------
746template<class T>
747void JEventLoop::RemoveRef(T *t)
748{
749 vector<pair<const char*, void*> >::iterator iter;
750 for(iter=user_refs.begin(); iter!= user_refs.end(); iter++){
751 if(iter->second == (void*)t){
752 user_refs.erase(iter);
753 return;
754 }
755 }
756 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<756<<" "
<<" Attempt to remove user reference not in event loop!" << std::endl;
757}
758
759
760#endif //__CINT__ __CLING__
761
762} // Close JANA namespace
763
764
765
766#endif // _JEventLoop_
767

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h

1// Iterators -*- C++ -*-
2
3// Copyright (C) 2001-2013 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1996-1998
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 */
50
51/** @file bits/stl_iterator.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{iterator}
54 *
55 * This file implements reverse_iterator, back_insert_iterator,
56 * front_insert_iterator, insert_iterator, __normal_iterator, and their
57 * supporting functions and overloaded operators.
58 */
59
60#ifndef _STL_ITERATOR_H1
61#define _STL_ITERATOR_H1 1
62
63#include <bits/cpp_type_traits.h>
64#include <ext/type_traits.h>
65#include <bits/move.h>
66
67namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
68{
69_GLIBCXX_BEGIN_NAMESPACE_VERSION
70
71 /**
72 * @addtogroup iterators
73 * @{
74 */
75
76 // 24.4.1 Reverse iterators
77 /**
78 * Bidirectional and random access iterators have corresponding reverse
79 * %iterator adaptors that iterate through the data structure in the
80 * opposite direction. They have the same signatures as the corresponding
81 * iterators. The fundamental relation between a reverse %iterator and its
82 * corresponding %iterator @c i is established by the identity:
83 * @code
84 * &*(reverse_iterator(i)) == &*(i - 1)
85 * @endcode
86 *
87 * <em>This mapping is dictated by the fact that while there is always a
88 * pointer past the end of an array, there might not be a valid pointer
89 * before the beginning of an array.</em> [24.4.1]/1,2
90 *
91 * Reverse iterators can be tricky and surprising at first. Their
92 * semantics make sense, however, and the trickiness is a side effect of
93 * the requirement that the iterators must be safe.
94 */
95 template<typename _Iterator>
96 class reverse_iterator
97 : public iterator<typename iterator_traits<_Iterator>::iterator_category,
98 typename iterator_traits<_Iterator>::value_type,
99 typename iterator_traits<_Iterator>::difference_type,
100 typename iterator_traits<_Iterator>::pointer,
101 typename iterator_traits<_Iterator>::reference>
102 {
103 protected:
104 _Iterator current;
105
106 typedef iterator_traits<_Iterator> __traits_type;
107
108 public:
109 typedef _Iterator iterator_type;
110 typedef typename __traits_type::difference_type difference_type;
111 typedef typename __traits_type::pointer pointer;
112 typedef typename __traits_type::reference reference;
113
114 /**
115 * The default constructor value-initializes member @p current.
116 * If it is a pointer, that means it is zero-initialized.
117 */
118 // _GLIBCXX_RESOLVE_LIB_DEFECTS
119 // 235 No specification of default ctor for reverse_iterator
120 reverse_iterator() : current() { }
121
122 /**
123 * This %iterator will move in the opposite direction that @p x does.
124 */
125 explicit
126 reverse_iterator(iterator_type __x) : current(__x) { }
127
128 /**
129 * The copy constructor is normal.
130 */
131 reverse_iterator(const reverse_iterator& __x)
132 : current(__x.current) { }
133
134 /**
135 * A %reverse_iterator across other types can be copied if the
136 * underlying %iterator can be converted to the type of @c current.
137 */
138 template<typename _Iter>
139 reverse_iterator(const reverse_iterator<_Iter>& __x)
140 : current(__x.base()) { }
141
142 /**
143 * @return @c current, the %iterator used for underlying work.
144 */
145 iterator_type
146 base() const
147 { return current; }
148
149 /**
150 * @return A reference to the value at @c --current
151 *
152 * This requires that @c --current is dereferenceable.
153 *
154 * @warning This implementation requires that for an iterator of the
155 * underlying iterator type, @c x, a reference obtained by
156 * @c *x remains valid after @c x has been modified or
157 * destroyed. This is a bug: http://gcc.gnu.org/PR51823
158 */
159 reference
160 operator*() const
161 {
162 _Iterator __tmp = current;
163 return *--__tmp;
164 }
165
166 /**
167 * @return A pointer to the value at @c --current
168 *
169 * This requires that @c --current is dereferenceable.
170 */
171 pointer
172 operator->() const
173 { return &(operator*()); }
174
175 /**
176 * @return @c *this
177 *
178 * Decrements the underlying iterator.
179 */
180 reverse_iterator&
181 operator++()
182 {
183 --current;
184 return *this;
185 }
186
187 /**
188 * @return The original value of @c *this
189 *
190 * Decrements the underlying iterator.
191 */
192 reverse_iterator
193 operator++(int)
194 {
195 reverse_iterator __tmp = *this;
196 --current;
197 return __tmp;
198 }
199
200 /**
201 * @return @c *this
202 *
203 * Increments the underlying iterator.
204 */
205 reverse_iterator&
206 operator--()
207 {
208 ++current;
209 return *this;
210 }
211
212 /**
213 * @return A reverse_iterator with the previous value of @c *this
214 *
215 * Increments the underlying iterator.
216 */
217 reverse_iterator
218 operator--(int)
219 {
220 reverse_iterator __tmp = *this;
221 ++current;
222 return __tmp;
223 }
224
225 /**
226 * @return A reverse_iterator that refers to @c current - @a __n
227 *
228 * The underlying iterator must be a Random Access Iterator.
229 */
230 reverse_iterator
231 operator+(difference_type __n) const
232 { return reverse_iterator(current - __n); }
233
234 /**
235 * @return *this
236 *
237 * Moves the underlying iterator backwards @a __n steps.
238 * The underlying iterator must be a Random Access Iterator.
239 */
240 reverse_iterator&
241 operator+=(difference_type __n)
242 {
243 current -= __n;
244 return *this;
245 }
246
247 /**
248 * @return A reverse_iterator that refers to @c current - @a __n
249 *
250 * The underlying iterator must be a Random Access Iterator.
251 */
252 reverse_iterator
253 operator-(difference_type __n) const
254 { return reverse_iterator(current + __n); }
255
256 /**
257 * @return *this
258 *
259 * Moves the underlying iterator forwards @a __n steps.
260 * The underlying iterator must be a Random Access Iterator.
261 */
262 reverse_iterator&
263 operator-=(difference_type __n)
264 {
265 current += __n;
266 return *this;
267 }
268
269 /**
270 * @return The value at @c current - @a __n - 1
271 *
272 * The underlying iterator must be a Random Access Iterator.
273 */
274 reference
275 operator[](difference_type __n) const
276 { return *(*this + __n); }
277 };
278
279 //@{
280 /**
281 * @param __x A %reverse_iterator.
282 * @param __y A %reverse_iterator.
283 * @return A simple bool.
284 *
285 * Reverse iterators forward many operations to their underlying base()
286 * iterators. Others are implemented in terms of one another.
287 *
288 */
289 template<typename _Iterator>
290 inline bool
291 operator==(const reverse_iterator<_Iterator>& __x,
292 const reverse_iterator<_Iterator>& __y)
293 { return __x.base() == __y.base(); }
294
295 template<typename _Iterator>
296 inline bool
297 operator<(const reverse_iterator<_Iterator>& __x,
298 const reverse_iterator<_Iterator>& __y)
299 { return __y.base() < __x.base(); }
300
301 template<typename _Iterator>
302 inline bool
303 operator!=(const reverse_iterator<_Iterator>& __x,
304 const reverse_iterator<_Iterator>& __y)
305 { return !(__x == __y); }
306
307 template<typename _Iterator>
308 inline bool
309 operator>(const reverse_iterator<_Iterator>& __x,
310 const reverse_iterator<_Iterator>& __y)
311 { return __y < __x; }
312
313 template<typename _Iterator>
314 inline bool
315 operator<=(const reverse_iterator<_Iterator>& __x,
316 const reverse_iterator<_Iterator>& __y)
317 { return !(__y < __x); }
318
319 template<typename _Iterator>
320 inline bool
321 operator>=(const reverse_iterator<_Iterator>& __x,
322 const reverse_iterator<_Iterator>& __y)
323 { return !(__x < __y); }
324
325 template<typename _Iterator>
326 inline typename reverse_iterator<_Iterator>::difference_type
327 operator-(const reverse_iterator<_Iterator>& __x,
328 const reverse_iterator<_Iterator>& __y)
329 { return __y.base() - __x.base(); }
330
331 template<typename _Iterator>
332 inline reverse_iterator<_Iterator>
333 operator+(typename reverse_iterator<_Iterator>::difference_type __n,
334 const reverse_iterator<_Iterator>& __x)
335 { return reverse_iterator<_Iterator>(__x.base() - __n); }
336
337 // _GLIBCXX_RESOLVE_LIB_DEFECTS
338 // DR 280. Comparison of reverse_iterator to const reverse_iterator.
339 template<typename _IteratorL, typename _IteratorR>
340 inline bool
341 operator==(const reverse_iterator<_IteratorL>& __x,
342 const reverse_iterator<_IteratorR>& __y)
343 { return __x.base() == __y.base(); }
344
345 template<typename _IteratorL, typename _IteratorR>
346 inline bool
347 operator<(const reverse_iterator<_IteratorL>& __x,
348 const reverse_iterator<_IteratorR>& __y)
349 { return __y.base() < __x.base(); }
350
351 template<typename _IteratorL, typename _IteratorR>
352 inline bool
353 operator!=(const reverse_iterator<_IteratorL>& __x,
354 const reverse_iterator<_IteratorR>& __y)
355 { return !(__x == __y); }
356
357 template<typename _IteratorL, typename _IteratorR>
358 inline bool
359 operator>(const reverse_iterator<_IteratorL>& __x,
360 const reverse_iterator<_IteratorR>& __y)
361 { return __y < __x; }
362
363 template<typename _IteratorL, typename _IteratorR>
364 inline bool
365 operator<=(const reverse_iterator<_IteratorL>& __x,
366 const reverse_iterator<_IteratorR>& __y)
367 { return !(__y < __x); }
368
369 template<typename _IteratorL, typename _IteratorR>
370 inline bool
371 operator>=(const reverse_iterator<_IteratorL>& __x,
372 const reverse_iterator<_IteratorR>& __y)
373 { return !(__x < __y); }
374
375 template<typename _IteratorL, typename _IteratorR>
376#if __cplusplus201103L >= 201103L
377 // DR 685.
378 inline auto
379 operator-(const reverse_iterator<_IteratorL>& __x,
380 const reverse_iterator<_IteratorR>& __y)
381 -> decltype(__y.base() - __x.base())
382#else
383 inline typename reverse_iterator<_IteratorL>::difference_type
384 operator-(const reverse_iterator<_IteratorL>& __x,
385 const reverse_iterator<_IteratorR>& __y)
386#endif
387 { return __y.base() - __x.base(); }
388 //@}
389
390 // 24.4.2.2.1 back_insert_iterator
391 /**
392 * @brief Turns assignment into insertion.
393 *
394 * These are output iterators, constructed from a container-of-T.
395 * Assigning a T to the iterator appends it to the container using
396 * push_back.
397 *
398 * Tip: Using the back_inserter function to create these iterators can
399 * save typing.
400 */
401 template<typename _Container>
402 class back_insert_iterator
403 : public iterator<output_iterator_tag, void, void, void, void>
404 {
405 protected:
406 _Container* container;
407
408 public:
409 /// A nested typedef for the type of whatever container you used.
410 typedef _Container container_type;
411
412 /// The only way to create this %iterator is with a container.
413 explicit
414 back_insert_iterator(_Container& __x) : container(&__x) { }
415
416 /**
417 * @param __value An instance of whatever type
418 * container_type::const_reference is; presumably a
419 * reference-to-const T for container<T>.
420 * @return This %iterator, for chained operations.
421 *
422 * This kind of %iterator doesn't really have a @a position in the
423 * container (you can think of the position as being permanently at
424 * the end, if you like). Assigning a value to the %iterator will
425 * always append the value to the end of the container.
426 */
427#if __cplusplus201103L < 201103L
428 back_insert_iterator&
429 operator=(typename _Container::const_reference __value)
430 {
431 container->push_back(__value);
432 return *this;
433 }
434#else
435 back_insert_iterator&
436 operator=(const typename _Container::value_type& __value)
437 {
438 container->push_back(__value);
439 return *this;
440 }
441
442 back_insert_iterator&
443 operator=(typename _Container::value_type&& __value)
444 {
445 container->push_back(std::move(__value));
446 return *this;
447 }
448#endif
449
450 /// Simply returns *this.
451 back_insert_iterator&
452 operator*()
453 { return *this; }
454
455 /// Simply returns *this. (This %iterator does not @a move.)
456 back_insert_iterator&
457 operator++()
458 { return *this; }
459
460 /// Simply returns *this. (This %iterator does not @a move.)
461 back_insert_iterator
462 operator++(int)
463 { return *this; }
464 };
465
466 /**
467 * @param __x A container of arbitrary type.
468 * @return An instance of back_insert_iterator working on @p __x.
469 *
470 * This wrapper function helps in creating back_insert_iterator instances.
471 * Typing the name of the %iterator requires knowing the precise full
472 * type of the container, which can be tedious and impedes generic
473 * programming. Using this function lets you take advantage of automatic
474 * template parameter deduction, making the compiler match the correct
475 * types for you.
476 */
477 template<typename _Container>
478 inline back_insert_iterator<_Container>
479 back_inserter(_Container& __x)
480 { return back_insert_iterator<_Container>(__x); }
481
482 /**
483 * @brief Turns assignment into insertion.
484 *
485 * These are output iterators, constructed from a container-of-T.
486 * Assigning a T to the iterator prepends it to the container using
487 * push_front.
488 *
489 * Tip: Using the front_inserter function to create these iterators can
490 * save typing.
491 */
492 template<typename _Container>
493 class front_insert_iterator
494 : public iterator<output_iterator_tag, void, void, void, void>
495 {
496 protected:
497 _Container* container;
498
499 public:
500 /// A nested typedef for the type of whatever container you used.
501 typedef _Container container_type;
502
503 /// The only way to create this %iterator is with a container.
504 explicit front_insert_iterator(_Container& __x) : container(&__x) { }
505
506 /**
507 * @param __value An instance of whatever type
508 * container_type::const_reference is; presumably a
509 * reference-to-const T for container<T>.
510 * @return This %iterator, for chained operations.
511 *
512 * This kind of %iterator doesn't really have a @a position in the
513 * container (you can think of the position as being permanently at
514 * the front, if you like). Assigning a value to the %iterator will
515 * always prepend the value to the front of the container.
516 */
517#if __cplusplus201103L < 201103L
518 front_insert_iterator&
519 operator=(typename _Container::const_reference __value)
520 {
521 container->push_front(__value);
522 return *this;
523 }
524#else
525 front_insert_iterator&
526 operator=(const typename _Container::value_type& __value)
527 {
528 container->push_front(__value);
529 return *this;
530 }
531
532 front_insert_iterator&
533 operator=(typename _Container::value_type&& __value)
534 {
535 container->push_front(std::move(__value));
536 return *this;
537 }
538#endif
539
540 /// Simply returns *this.
541 front_insert_iterator&
542 operator*()
543 { return *this; }
544
545 /// Simply returns *this. (This %iterator does not @a move.)
546 front_insert_iterator&
547 operator++()
548 { return *this; }
549
550 /// Simply returns *this. (This %iterator does not @a move.)
551 front_insert_iterator
552 operator++(int)
553 { return *this; }
554 };
555
556 /**
557 * @param __x A container of arbitrary type.
558 * @return An instance of front_insert_iterator working on @p x.
559 *
560 * This wrapper function helps in creating front_insert_iterator instances.
561 * Typing the name of the %iterator requires knowing the precise full
562 * type of the container, which can be tedious and impedes generic
563 * programming. Using this function lets you take advantage of automatic
564 * template parameter deduction, making the compiler match the correct
565 * types for you.
566 */
567 template<typename _Container>
568 inline front_insert_iterator<_Container>
569 front_inserter(_Container& __x)
570 { return front_insert_iterator<_Container>(__x); }
571
572 /**
573 * @brief Turns assignment into insertion.
574 *
575 * These are output iterators, constructed from a container-of-T.
576 * Assigning a T to the iterator inserts it in the container at the
577 * %iterator's position, rather than overwriting the value at that
578 * position.
579 *
580 * (Sequences will actually insert a @e copy of the value before the
581 * %iterator's position.)
582 *
583 * Tip: Using the inserter function to create these iterators can
584 * save typing.
585 */
586 template<typename _Container>
587 class insert_iterator
588 : public iterator<output_iterator_tag, void, void, void, void>
589 {
590 protected:
591 _Container* container;
592 typename _Container::iterator iter;
593
594 public:
595 /// A nested typedef for the type of whatever container you used.
596 typedef _Container container_type;
597
598 /**
599 * The only way to create this %iterator is with a container and an
600 * initial position (a normal %iterator into the container).
601 */
602 insert_iterator(_Container& __x, typename _Container::iterator __i)
603 : container(&__x), iter(__i) {}
604
605 /**
606 * @param __value An instance of whatever type
607 * container_type::const_reference is; presumably a
608 * reference-to-const T for container<T>.
609 * @return This %iterator, for chained operations.
610 *
611 * This kind of %iterator maintains its own position in the
612 * container. Assigning a value to the %iterator will insert the
613 * value into the container at the place before the %iterator.
614 *
615 * The position is maintained such that subsequent assignments will
616 * insert values immediately after one another. For example,
617 * @code
618 * // vector v contains A and Z
619 *
620 * insert_iterator i (v, ++v.begin());
621 * i = 1;
622 * i = 2;
623 * i = 3;
624 *
625 * // vector v contains A, 1, 2, 3, and Z
626 * @endcode
627 */
628#if __cplusplus201103L < 201103L
629 insert_iterator&
630 operator=(typename _Container::const_reference __value)
631 {
632 iter = container->insert(iter, __value);
633 ++iter;
634 return *this;
635 }
636#else
637 insert_iterator&
638 operator=(const typename _Container::value_type& __value)
639 {
640 iter = container->insert(iter, __value);
641 ++iter;
642 return *this;
643 }
644
645 insert_iterator&
646 operator=(typename _Container::value_type&& __value)
647 {
648 iter = container->insert(iter, std::move(__value));
649 ++iter;
650 return *this;
651 }
652#endif
653
654 /// Simply returns *this.
655 insert_iterator&
656 operator*()
657 { return *this; }
658
659 /// Simply returns *this. (This %iterator does not @a move.)
660 insert_iterator&
661 operator++()
662 { return *this; }
663
664 /// Simply returns *this. (This %iterator does not @a move.)
665 insert_iterator&
666 operator++(int)
667 { return *this; }
668 };
669
670 /**
671 * @param __x A container of arbitrary type.
672 * @return An instance of insert_iterator working on @p __x.
673 *
674 * This wrapper function helps in creating insert_iterator instances.
675 * Typing the name of the %iterator requires knowing the precise full
676 * type of the container, which can be tedious and impedes generic
677 * programming. Using this function lets you take advantage of automatic
678 * template parameter deduction, making the compiler match the correct
679 * types for you.
680 */
681 template<typename _Container, typename _Iterator>
682 inline insert_iterator<_Container>
683 inserter(_Container& __x, _Iterator __i)
684 {
685 return insert_iterator<_Container>(__x,
686 typename _Container::iterator(__i));
687 }
688
689 // @} group iterators
690
691_GLIBCXX_END_NAMESPACE_VERSION
692} // namespace
693
694namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
695{
696_GLIBCXX_BEGIN_NAMESPACE_VERSION
697
698 // This iterator adapter is @a normal in the sense that it does not
699 // change the semantics of any of the operators of its iterator
700 // parameter. Its primary purpose is to convert an iterator that is
701 // not a class, e.g. a pointer, into an iterator that is a class.
702 // The _Container parameter exists solely so that different containers
703 // using this template can instantiate different types, even if the
704 // _Iterator parameter is the same.
705 using std::iterator_traits;
706 using std::iterator;
707 template<typename _Iterator, typename _Container>
708 class __normal_iterator
709 {
710 protected:
711 _Iterator _M_current;
712
713 typedef iterator_traits<_Iterator> __traits_type;
714
715 public:
716 typedef _Iterator iterator_type;
717 typedef typename __traits_type::iterator_category iterator_category;
718 typedef typename __traits_type::value_type value_type;
719 typedef typename __traits_type::difference_type difference_type;
720 typedef typename __traits_type::reference reference;
721 typedef typename __traits_type::pointer pointer;
722
723 _GLIBCXX_CONSTEXPRconstexpr __normal_iterator() : _M_current(_Iterator()) { }
724
725 explicit
726 __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
727
728 // Allow iterator to const_iterator conversion
729 template<typename _Iter>
730 __normal_iterator(const __normal_iterator<_Iter,
731 typename __enable_if<
732 (std::__are_same<_Iter, typename _Container::pointer>::__value),
733 _Container>::__type>& __i)
734 : _M_current(__i.base()) { }
735
736 // Forward iterator requirements
737 reference
738 operator*() const
739 { return *_M_current; }
740
741 pointer
742 operator->() const
743 { return _M_current; }
744
745 __normal_iterator&
746 operator++()
747 {
748 ++_M_current;
749 return *this;
750 }
751
752 __normal_iterator
753 operator++(int)
754 { return __normal_iterator(_M_current++); }
755
756 // Bidirectional iterator requirements
757 __normal_iterator&
758 operator--()
759 {
760 --_M_current;
761 return *this;
762 }
763
764 __normal_iterator
765 operator--(int)
766 { return __normal_iterator(_M_current--); }
767
768 // Random access iterator requirements
769 reference
770 operator[](const difference_type& __n) const
771 { return _M_current[__n]; }
772
773 __normal_iterator&
774 operator+=(const difference_type& __n)
775 { _M_current += __n; return *this; }
776
777 __normal_iterator
778 operator+(const difference_type& __n) const
779 { return __normal_iterator(_M_current + __n); }
780
781 __normal_iterator&
782 operator-=(const difference_type& __n)
783 { _M_current -= __n; return *this; }
784
785 __normal_iterator
786 operator-(const difference_type& __n) const
787 { return __normal_iterator(_M_current - __n); }
788
789 const _Iterator&
790 base() const
791 { return _M_current; }
792 };
793
794 // Note: In what follows, the left- and right-hand-side iterators are
795 // allowed to vary in types (conceptually in cv-qualification) so that
796 // comparison between cv-qualified and non-cv-qualified iterators be
797 // valid. However, the greedy and unfriendly operators in std::rel_ops
798 // will make overload resolution ambiguous (when in scope) if we don't
799 // provide overloads whose operands are of the same type. Can someone
800 // remind me what generic programming is about? -- Gaby
801
802 // Forward iterator requirements
803 template<typename _IteratorL, typename _IteratorR, typename _Container>
804 inline bool
805 operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
806 const __normal_iterator<_IteratorR, _Container>& __rhs)
807 { return __lhs.base() == __rhs.base(); }
808
809 template<typename _Iterator, typename _Container>
810 inline bool
811 operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
812 const __normal_iterator<_Iterator, _Container>& __rhs)
813 { return __lhs.base() == __rhs.base(); }
814
815 template<typename _IteratorL, typename _IteratorR, typename _Container>
816 inline bool
817 operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
818 const __normal_iterator<_IteratorR, _Container>& __rhs)
819 { return __lhs.base() != __rhs.base(); }
820
821 template<typename _Iterator, typename _Container>
822 inline bool
823 operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
824 const __normal_iterator<_Iterator, _Container>& __rhs)
825 { return __lhs.base() != __rhs.base(); }
19
Assuming the condition is true
20
Returning the value 1, which participates in a condition later
826
827 // Random access iterator requirements
828 template<typename _IteratorL, typename _IteratorR, typename _Container>
829 inline bool
830 operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
831 const __normal_iterator<_IteratorR, _Container>& __rhs)
832 { return __lhs.base() < __rhs.base(); }
833
834 template<typename _Iterator, typename _Container>
835 inline bool
836 operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
837 const __normal_iterator<_Iterator, _Container>& __rhs)
838 { return __lhs.base() < __rhs.base(); }
839
840 template<typename _IteratorL, typename _IteratorR, typename _Container>
841 inline bool
842 operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
843 const __normal_iterator<_IteratorR, _Container>& __rhs)
844 { return __lhs.base() > __rhs.base(); }
845
846 template<typename _Iterator, typename _Container>
847 inline bool
848 operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
849 const __normal_iterator<_Iterator, _Container>& __rhs)
850 { return __lhs.base() > __rhs.base(); }
851
852 template<typename _IteratorL, typename _IteratorR, typename _Container>
853 inline bool
854 operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
855 const __normal_iterator<_IteratorR, _Container>& __rhs)
856 { return __lhs.base() <= __rhs.base(); }
857
858 template<typename _Iterator, typename _Container>
859 inline bool
860 operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
861 const __normal_iterator<_Iterator, _Container>& __rhs)
862 { return __lhs.base() <= __rhs.base(); }
863
864 template<typename _IteratorL, typename _IteratorR, typename _Container>
865 inline bool
866 operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
867 const __normal_iterator<_IteratorR, _Container>& __rhs)
868 { return __lhs.base() >= __rhs.base(); }
869
870 template<typename _Iterator, typename _Container>
871 inline bool
872 operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
873 const __normal_iterator<_Iterator, _Container>& __rhs)
874 { return __lhs.base() >= __rhs.base(); }
875
876 // _GLIBCXX_RESOLVE_LIB_DEFECTS
877 // According to the resolution of DR179 not only the various comparison
878 // operators but also operator- must accept mixed iterator/const_iterator
879 // parameters.
880 template<typename _IteratorL, typename _IteratorR, typename _Container>
881#if __cplusplus201103L >= 201103L
882 // DR 685.
883 inline auto
884 operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
885 const __normal_iterator<_IteratorR, _Container>& __rhs)
886 -> decltype(__lhs.base() - __rhs.base())
887#else
888 inline typename __normal_iterator<_IteratorL, _Container>::difference_type
889 operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
890 const __normal_iterator<_IteratorR, _Container>& __rhs)
891#endif
892 { return __lhs.base() - __rhs.base(); }
893
894 template<typename _Iterator, typename _Container>
895 inline typename __normal_iterator<_Iterator, _Container>::difference_type
896 operator-(const __normal_iterator<_Iterator, _Container>& __lhs,
897 const __normal_iterator<_Iterator, _Container>& __rhs)
898 { return __lhs.base() - __rhs.base(); }
899
900 template<typename _Iterator, typename _Container>
901 inline __normal_iterator<_Iterator, _Container>
902 operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
903 __n, const __normal_iterator<_Iterator, _Container>& __i)
904 { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
905
906_GLIBCXX_END_NAMESPACE_VERSION
907} // namespace
908
909#if __cplusplus201103L >= 201103L
910
911namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
912{
913_GLIBCXX_BEGIN_NAMESPACE_VERSION
914
915 /**
916 * @addtogroup iterators
917 * @{
918 */
919
920 // 24.4.3 Move iterators
921 /**
922 * Class template move_iterator is an iterator adapter with the same
923 * behavior as the underlying iterator except that its dereference
924 * operator implicitly converts the value returned by the underlying
925 * iterator's dereference operator to an rvalue reference. Some
926 * generic algorithms can be called with move iterators to replace
927 * copying with moving.
928 */
929 template<typename _Iterator>
930 class move_iterator
931 {
932 protected:
933 _Iterator _M_current;
934
935 typedef iterator_traits<_Iterator> __traits_type;
936
937 public:
938 typedef _Iterator iterator_type;
939 typedef typename __traits_type::iterator_category iterator_category;
940 typedef typename __traits_type::value_type value_type;
941 typedef typename __traits_type::difference_type difference_type;
942 // NB: DR 680.
943 typedef _Iterator pointer;
944 typedef value_type&& reference;
945
946 move_iterator()
947 : _M_current() { }
948
949 explicit
950 move_iterator(iterator_type __i)
951 : _M_current(__i) { }
952
953 template<typename _Iter>
954 move_iterator(const move_iterator<_Iter>& __i)
955 : _M_current(__i.base()) { }
956
957 iterator_type
958 base() const
959 { return _M_current; }
960
961 reference
962 operator*() const
963 { return std::move(*_M_current); }
964
965 pointer
966 operator->() const
967 { return _M_current; }
968
969 move_iterator&
970 operator++()
971 {
972 ++_M_current;
973 return *this;
974 }
975
976 move_iterator
977 operator++(int)
978 {
979 move_iterator __tmp = *this;
980 ++_M_current;
981 return __tmp;
982 }
983
984 move_iterator&
985 operator--()
986 {
987 --_M_current;
988 return *this;
989 }
990
991 move_iterator
992 operator--(int)
993 {
994 move_iterator __tmp = *this;
995 --_M_current;
996 return __tmp;
997 }
998
999 move_iterator
1000 operator+(difference_type __n) const
1001 { return move_iterator(_M_current + __n); }
1002
1003 move_iterator&
1004 operator+=(difference_type __n)
1005 {
1006 _M_current += __n;
1007 return *this;
1008 }
1009
1010 move_iterator
1011 operator-(difference_type __n) const
1012 { return move_iterator(_M_current - __n); }
1013
1014 move_iterator&
1015 operator-=(difference_type __n)
1016 {
1017 _M_current -= __n;
1018 return *this;
1019 }
1020
1021 reference
1022 operator[](difference_type __n) const
1023 { return std::move(_M_current[__n]); }
1024 };
1025
1026 // Note: See __normal_iterator operators note from Gaby to understand
1027 // why there are always 2 versions for most of the move_iterator
1028 // operators.
1029 template<typename _IteratorL, typename _IteratorR>
1030 inline bool
1031 operator==(const move_iterator<_IteratorL>& __x,
1032 const move_iterator<_IteratorR>& __y)
1033 { return __x.base() == __y.base(); }
1034
1035 template<typename _Iterator>
1036 inline bool
1037 operator==(const move_iterator<_Iterator>& __x,
1038 const move_iterator<_Iterator>& __y)
1039 { return __x.base() == __y.base(); }
1040
1041 template<typename _IteratorL, typename _IteratorR>
1042 inline bool
1043 operator!=(const move_iterator<_IteratorL>& __x,
1044 const move_iterator<_IteratorR>& __y)
1045 { return !(__x == __y); }
1046
1047 template<typename _Iterator>
1048 inline bool
1049 operator!=(const move_iterator<_Iterator>& __x,
1050 const move_iterator<_Iterator>& __y)
1051 { return !(__x == __y); }
1052
1053 template<typename _IteratorL, typename _IteratorR>
1054 inline bool
1055 operator<(const move_iterator<_IteratorL>& __x,
1056 const move_iterator<_IteratorR>& __y)
1057 { return __x.base() < __y.base(); }
1058
1059 template<typename _Iterator>
1060 inline bool
1061 operator<(const move_iterator<_Iterator>& __x,
1062 const move_iterator<_Iterator>& __y)
1063 { return __x.base() < __y.base(); }
1064
1065 template<typename _IteratorL, typename _IteratorR>
1066 inline bool
1067 operator<=(const move_iterator<_IteratorL>& __x,
1068 const move_iterator<_IteratorR>& __y)
1069 { return !(__y < __x); }
1070
1071 template<typename _Iterator>
1072 inline bool
1073 operator<=(const move_iterator<_Iterator>& __x,
1074 const move_iterator<_Iterator>& __y)
1075 { return !(__y < __x); }
1076
1077 template<typename _IteratorL, typename _IteratorR>
1078 inline bool
1079 operator>(const move_iterator<_IteratorL>& __x,
1080 const move_iterator<_IteratorR>& __y)
1081 { return __y < __x; }
1082
1083 template<typename _Iterator>
1084 inline bool
1085 operator>(const move_iterator<_Iterator>& __x,
1086 const move_iterator<_Iterator>& __y)
1087 { return __y < __x; }
1088
1089 template<typename _IteratorL, typename _IteratorR>
1090 inline bool
1091 operator>=(const move_iterator<_IteratorL>& __x,
1092 const move_iterator<_IteratorR>& __y)
1093 { return !(__x < __y); }
1094
1095 template<typename _Iterator>
1096 inline bool
1097 operator>=(const move_iterator<_Iterator>& __x,
1098 const move_iterator<_Iterator>& __y)
1099 { return !(__x < __y); }
1100
1101 // DR 685.
1102 template<typename _IteratorL, typename _IteratorR>
1103 inline auto
1104 operator-(const move_iterator<_IteratorL>& __x,
1105 const move_iterator<_IteratorR>& __y)
1106 -> decltype(__x.base() - __y.base())
1107 { return __x.base() - __y.base(); }
1108
1109 template<typename _Iterator>
1110 inline auto
1111 operator-(const move_iterator<_Iterator>& __x,
1112 const move_iterator<_Iterator>& __y)
1113 -> decltype(__x.base() - __y.base())
1114 { return __x.base() - __y.base(); }
1115
1116 template<typename _Iterator>
1117 inline move_iterator<_Iterator>
1118 operator+(typename move_iterator<_Iterator>::difference_type __n,
1119 const move_iterator<_Iterator>& __x)
1120 { return __x + __n; }
1121
1122 template<typename _Iterator>
1123 inline move_iterator<_Iterator>
1124 make_move_iterator(_Iterator __i)
1125 { return move_iterator<_Iterator>(__i); }
1126
1127 template<typename _Iterator, typename _ReturnType
1128 = typename conditional<__move_if_noexcept_cond
1129 <typename iterator_traits<_Iterator>::value_type>::value,
1130 _Iterator, move_iterator<_Iterator>>::type>
1131 inline _ReturnType
1132 __make_move_if_noexcept_iterator(_Iterator __i)
1133 { return _ReturnType(__i); }
1134
1135 // @} group iterators
1136
1137_GLIBCXX_END_NAMESPACE_VERSION
1138} // namespace
1139
1140#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter)std::make_move_iterator(_Iter) std::make_move_iterator(_Iter)
1141#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter)std::__make_move_if_noexcept_iterator(_Iter) \
1142 std::__make_move_if_noexcept_iterator(_Iter)
1143#else
1144#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter)std::make_move_iterator(_Iter) (_Iter)
1145#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter)std::__make_move_if_noexcept_iterator(_Iter) (_Iter)
1146#endif // C++11
1147
1148#endif