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 DEventWriterROOT.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/DEventWriterROOT.cc

libraries/ANALYSIS/DEventWriterROOT.cc

1#include "DEventWriterROOT.h"
2
3static bool BCAL_VERBOSE_OUTPUT = false;
4static bool FCAL_VERBOSE_OUTPUT = false;
5static bool CCAL_VERBOSE_OUTPUT = false;
6static bool DIRC_OUTPUT = true;
7
8static bool STORE_PULL_INFO = false;
9static bool STORE_ERROR_MATRIX_INFO = false;
10
11
12void DEventWriterROOT::Initialize(JEventLoop* locEventLoop)
13{
14 dInitNumThrownArraySize = 20;
15 dInitNumBeamArraySize = 20;
16 dInitNumTrackArraySize = 50;
17 dInitNumNeutralArraySize = 15;
18 dInitNumComboArraySize = 100;
19 dThrownTreeInterface = NULL__null;
20
21 locEventLoop->GetSingle(dAnalysisUtilities);
22
23 auto locReactions = DAnalysis::Get_Reactions(locEventLoop);
24
25 //CREATE & INITIALIZE ANALYSIS ACTIONS
26 for(size_t loc_i = 0; loc_i < locReactions.size(); ++loc_i)
27 {
28 if(!locReactions[loc_i]->Get_EnableTTreeOutputFlag())
29 continue;
30
31 dCutActionMap_ThrownTopology[locReactions[loc_i]] = new DCutAction_ThrownTopology(locReactions[loc_i], true);
32 dCutActionMap_ThrownTopology[locReactions[loc_i]]->Initialize(locEventLoop);
33
34 dCutActionMap_TrueCombo[locReactions[loc_i]] = new DCutAction_TrueCombo(locReactions[loc_i], -1.0, true);
35 dCutActionMap_TrueCombo[locReactions[loc_i]]->Initialize(locEventLoop);
36
37 dCutActionMap_BDTSignalCombo[locReactions[loc_i]] = new DCutAction_BDTSignalCombo(locReactions[loc_i], 5.73303E-7, true, true); //+/- 5sigma
38 dCutActionMap_BDTSignalCombo[locReactions[loc_i]]->Initialize(locEventLoop);
39 }
40
41 //CREATE TREES
42 vector<const DMCThrown*> locMCThrowns;
43 locEventLoop->Get(locMCThrowns);
44
45 vector<const DReactionVertexInfo*> locVertexInfos;
46 locEventLoop->Get(locVertexInfos);
47
48 //Get Target Center Z
49 DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
50 DGeometry* locGeometry = locApplication->GetDGeometry(locEventLoop->GetJEvent().GetRunNumber());
51 dTargetCenterZ = 65.0;
52 locGeometry->GetTargetZ(dTargetCenterZ);
53
54 //CREATE TTREES
55 for(auto& locVertexInfo : locVertexInfos)
56 {
57 auto locVertexReactions = locVertexInfo->Get_Reactions();
58 for(auto& locReaction : locVertexReactions)
59 {
60 dVertexInfoMap.emplace(locReaction, locVertexInfo);
61 if(locReaction->Get_EnableTTreeOutputFlag())
62 Create_DataTree(locReaction, locEventLoop, !locMCThrowns.empty());
63 }
64 }
65}
66
67void DEventWriterROOT::Run_Update(JEventLoop* locEventLoop)
68{
69 locEventLoop->GetSingle(dAnalysisUtilities);
1
Calling 'JEventLoop::GetSingle'
70
71 //Get Target Center Z
72 DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
73 DGeometry* locGeometry = locApplication->GetDGeometry(locEventLoop->GetJEvent().GetRunNumber());
74 dTargetCenterZ = 65.0;
75 locGeometry->GetTargetZ(dTargetCenterZ);
76
77 // update run-dependent info/objects
78 for(auto& locMapPair : dCutActionMap_ThrownTopology)
79 locMapPair.second->Run_Update(locEventLoop);
80 for(auto& locMapPair : dCutActionMap_TrueCombo)
81 locMapPair.second->Run_Update(locEventLoop);
82 for(auto& locMapPair : dCutActionMap_BDTSignalCombo)
83 locMapPair.second->Run_Update(locEventLoop);
84}
85
86DEventWriterROOT::~DEventWriterROOT(void)
87{
88 //Delete tree interface objects
89 for(auto& locMapPair : dTreeInterfaceMap)
90 delete locMapPair.second;
91 if(dThrownTreeInterface != NULL__null)
92 delete dThrownTreeInterface;
93
94 for(auto& locMapPair : dTreeFillDataMap)
95 delete locMapPair.second;
96
97 //Delete actions
98 for(auto& locMapPair : dCutActionMap_ThrownTopology)
99 delete locMapPair.second;
100 for(auto& locMapPair : dCutActionMap_TrueCombo)
101 delete locMapPair.second;
102 for(auto& locMapPair : dCutActionMap_BDTSignalCombo)
103 delete locMapPair.second;
104}
105
106void DEventWriterROOT::Create_ThrownTree(JEventLoop* locEventLoop, string locOutputFileName) const
107{
108 if(dThrownTreeInterface != nullptr)
109 return; //Already setup for this thread!
110 dThrownTreeInterface = DTreeInterface::Create_DTreeInterface("Thrown_Tree", locOutputFileName); //set up this thread
111 if(dThrownTreeInterface->Get_BranchesCreatedFlag())
112 return; //branches already created: return
113
114 //TTREE BRANCHES
115 DTreeBranchRegister locBranchRegister;
116
117 //Get target PID
118 const DMCReaction* locMCReaction = NULL__null;
119 locEventLoop->GetSingle(locMCReaction);
120 Particle_t locTargetPID = locMCReaction->target.PID();
121
122 //setup target info
123 Create_UserTargetInfo(locBranchRegister, locTargetPID);
124
125 //create basic/misc. tree branches (run#, event#, etc.)
126 locBranchRegister.Register_Single<UInt_t>("RunNumber");
127 locBranchRegister.Register_Single<ULong64_t>("EventNumber");
128
129 //Thrown Data
130 Create_Branches_Thrown(locBranchRegister, true);
131
132 //CUSTOM
133 Create_CustomBranches_ThrownTree(locBranchRegister, locEventLoop);
134
135 //CREATE BRANCHES
136 dThrownTreeInterface->Create_Branches(locBranchRegister);
137 dThrownTreeInterface->Set_TreeIndexBranchNames("RunNumber", "EventNumber");
138}
139
140void DEventWriterROOT::Create_DataTree(const DReaction* locReaction, JEventLoop* locEventLoop, bool locIsMCDataFlag)
141{
142 string locReactionName = locReaction->Get_ReactionName();
143 string locOutputFileName = locReaction->Get_TTreeOutputFileName();
144 string locTreeName = locReactionName + string("_Tree");
145
146 //create fill object
147 dTreeFillDataMap[locReaction] = new DTreeFillData();
148
149 //create tree interface
150 DTreeInterface* locTreeInterface = DTreeInterface::Create_DTreeInterface(locTreeName, locOutputFileName);
151 dTreeInterfaceMap[locReaction] = locTreeInterface;
152 if(locTreeInterface->Get_BranchesCreatedFlag())
153 return; //branches already created, then return
154
155 //Branch register
156 DTreeBranchRegister locBranchRegister;
157
158 //fill maps
159 TMap* locPositionToNameMap = Create_UserInfoMaps(locBranchRegister, locEventLoop, locReaction);
160
161/******************************************************************** Create Branches ********************************************************************/
162
163 //create basic/misc. tree branches (run#, event#, etc.)
164 locBranchRegister.Register_Single<UInt_t>("RunNumber");
165 locBranchRegister.Register_Single<ULong64_t>("EventNumber");
166 locBranchRegister.Register_Single<UInt_t>("L1TriggerBits");
167
168 //create X4_Production
169 locBranchRegister.Register_Single<TLorentzVector>("X4_Production");
170
171 //create thrown branches
172 if(locIsMCDataFlag)
173 {
174 Create_Branches_Thrown(locBranchRegister, false);
175 locBranchRegister.Register_Single<Bool_t>("IsThrownTopology");
176 }
177
178 bool locBeamUsedFlag = DAnalysis::Get_IsFirstStepBeam(locReaction);
179
180 //create branches for final-state particle hypotheses
181 if(locBeamUsedFlag)
182 Create_Branches_Beam(locBranchRegister, locIsMCDataFlag);
183 Create_Branches_NeutralHypotheses(locBranchRegister, locIsMCDataFlag);
184 Create_Branches_ChargedHypotheses(locBranchRegister, locIsMCDataFlag);
185
186 //create branches for combos
187 locBranchRegister.Register_Single<UChar_t>("NumUnusedTracks");
188 Create_Branches_Combo(locBranchRegister, locReaction, locIsMCDataFlag, locPositionToNameMap);
189
190 //Kinematic fit data (pulls and covariance matrices)
191 Create_Branches_KinFitData(locBranchRegister, locEventLoop, locReaction, locIsMCDataFlag);
192
193 //Custom branches
194 Create_CustomBranches_DataTree(locBranchRegister, locEventLoop, locReaction, locIsMCDataFlag);
195
196 //Create branches
197 locTreeInterface->Create_Branches(locBranchRegister);
198 locTreeInterface->Set_TreeIndexBranchNames("RunNumber", "EventNumber");
199}
200
201TMap* DEventWriterROOT::Create_UserInfoMaps(DTreeBranchRegister& locBranchRegister, JEventLoop* locEventLoop, const DReaction* locReaction) const
202{
203 auto locReactionVertexInfo = dVertexInfoMap.find(locReaction)->second;
204
205 //kinfit type
206 DKinFitType locKinFitType = locReaction->Get_KinFitType();
207
208 //create & add reaction identification maps
209 TList* locUserInfo = locBranchRegister.Get_UserInfo();
210 TMap* locNameToPIDMap = new TMap();
211 locNameToPIDMap->SetName("NameToPIDMap");
212 locUserInfo->Add(locNameToPIDMap);
213
214 TMap* locNameToPositionMap = new TMap(); //not filled for target or initial particles
215 locNameToPositionMap->SetName("NameToPositionMap");
216 locUserInfo->Add(locNameToPositionMap);
217
218 TMap* locPositionToNameMap = new TMap(); //not filled for target or initial particles
219 locPositionToNameMap->SetName("PositionToNameMap");
220 locUserInfo->Add(locPositionToNameMap);
221
222 TMap* locPositionToPIDMap = new TMap();
223 locPositionToPIDMap->SetName("PositionToPIDMap");
224 locUserInfo->Add(locPositionToPIDMap);
225
226 TMap* locDecayProductMap = new TMap(); //excludes resonances!!! //excludes intermediate decays (e.g. if xi- -> pi-, lambda -> pi-, pi-, p: will be xi- -> pi-, pi-, p and no lambda decay present)
227 locDecayProductMap->SetName("DecayProductMap"); //parent name string -> tlist of decay product name strings
228 locUserInfo->Add(locDecayProductMap);
229
230 TMap* locMiscInfoMap = new TMap();
231 locMiscInfoMap->SetName("MiscInfoMap");
232 locUserInfo->Add(locMiscInfoMap);
233
234 TList* locParticleNameList = new TList();
235 locParticleNameList->SetName("ParticleNameList");
236 locUserInfo->Add(locParticleNameList);
237
238 //Set some misc info
239 ostringstream locKinFitTypeStream;
240 locKinFitTypeStream << locKinFitType;
241 locMiscInfoMap->Add(new TObjString("KinFitType"), new TObjString(locKinFitTypeStream.str().c_str()));
242
243 string ANALYSIS_VERSION_STRING = "";
244 if(gPARMS->Exists("ANALYSIS:DATAVERSIONSTRING"))
245 gPARMS->GetParameter("ANALYSIS:DATAVERSIONSTRING", ANALYSIS_VERSION_STRING);
246 if(ANALYSIS_VERSION_STRING != "")
247 locMiscInfoMap->Add(new TObjString("ANALYSIS:DATAVERSIONSTRING"), new TObjString(ANALYSIS_VERSION_STRING.c_str()));
248
249 string HDDM_DATA_VERSION_STRING = "";
250 if(gPARMS->Exists("REST:DATAVERSIONSTRING"))
251 gPARMS->GetParameter("REST:DATAVERSIONSTRING", HDDM_DATA_VERSION_STRING);
252 if(HDDM_DATA_VERSION_STRING != "")
253 locMiscInfoMap->Add(new TObjString("REST:DATAVERSIONSTRING"), new TObjString(HDDM_DATA_VERSION_STRING.c_str()));
254
255 string REST_JANA_CALIB_CONTEXT = "";
256 if(gPARMS->Exists("REST:JANACALIBCONTEXT"))
257 gPARMS->GetParameter("REST:JANACALIBCONTEXT", REST_JANA_CALIB_CONTEXT);
258 if(REST_JANA_CALIB_CONTEXT == "")
259 gPARMS->GetParameter("JANA_CALIB_CONTEXT", REST_JANA_CALIB_CONTEXT);
260 if(REST_JANA_CALIB_CONTEXT != "")
261 locMiscInfoMap->Add(new TObjString("REST:JANACALIBCONTEXT"), new TObjString(REST_JANA_CALIB_CONTEXT.c_str()));
262
263
264 if(gPARMS->Exists("ANALYSIS:BCAL_VERBOSE_ROOT_OUTPUT"))
265 gPARMS->GetParameter("ANALYSIS:BCAL_VERBOSE_ROOT_OUTPUT", BCAL_VERBOSE_OUTPUT);
266 if(gPARMS->Exists("ANALYSIS:FCAL_VERBOSE_ROOT_OUTPUT"))
267 gPARMS->GetParameter("ANALYSIS:FCAL_VERBOSE_ROOT_OUTPUT", FCAL_VERBOSE_OUTPUT);
268 if(gPARMS->Exists("ANALYSIS:CCAL_VERBOSE_ROOT_OUTPUT"))
269 gPARMS->GetParameter("ANALYSIS:CCAL_VERBOSE_ROOT_OUTPUT", CCAL_VERBOSE_OUTPUT);
270 if(gPARMS->Exists("ANALYSIS:DIRC_ROOT_OUTPUT"))
271 gPARMS->GetParameter("ANALYSIS:DIRC_ROOT_OUTPUT", DIRC_OUTPUT);
272 if(gPARMS->Exists("ANALYSIS:STORE_PULL_INFO"))
273 gPARMS->GetParameter("ANALYSIS:STORE_PULL_INFO",STORE_PULL_INFO);
274 if(gPARMS->Exists("ANALYSIS:STORE_ERROR_MATRIX_INFO"))
275 gPARMS->GetParameter("ANALYSIS:STORE_ERROR_MATRIX_INFO",STORE_ERROR_MATRIX_INFO);
276
277 if(locKinFitType != d_NoFit)
278 {
279 DKinFitUtils_GlueX locKinFitUtils(locEventLoop);
280 size_t locNumConstraints = 0, locNumUnknowns = 0;
281 string locConstraintString = locKinFitUtils.Get_ConstraintInfo(locReactionVertexInfo, locReaction, locNumConstraints, locNumUnknowns);
282 locMiscInfoMap->Add(new TObjString("KinFitConstraints"), new TObjString(locConstraintString.c_str()));
283
284 ostringstream locKinFitInfoStream;
285 locKinFitInfoStream << locNumConstraints;
286 locMiscInfoMap->Add(new TObjString("NumKinFitConstraints"), new TObjString(locKinFitInfoStream.str().c_str()));
287
288 locKinFitInfoStream.str("");
289 locKinFitInfoStream << locNumUnknowns;
290 locMiscInfoMap->Add(new TObjString("NumKinFitUnknowns"), new TObjString(locKinFitInfoStream.str().c_str()));
291 }
292
293 //find the # particles of each pid
294 map<Particle_t, unsigned int> locParticleNumberMap;
295 map<Particle_t, unsigned int> locDecayingParticleNumberMap;
296 map<Particle_t, unsigned int> locTargetParticleNumberMap;
297 for(size_t loc_i = 0; loc_i < locReaction->Get_NumReactionSteps(); ++loc_i)
298 {
299 const DReactionStep* locReactionStep = locReaction->Get_ReactionStep(loc_i);
300 auto locFinalParticleIDs = locReactionStep->Get_FinalPIDs();
301
302 auto locTargetPID = locReactionStep->Get_TargetPID();
303 if(locTargetPID != Unknown)
304 {
305 if(locTargetParticleNumberMap.find(locTargetPID) == locTargetParticleNumberMap.end())
306 locTargetParticleNumberMap[locTargetPID] = 1;
307 else
308 ++locTargetParticleNumberMap[locTargetPID];
309 }
310
311 for(size_t loc_j = 0; loc_j < locFinalParticleIDs.size(); ++loc_j)
312 {
313 if(locReactionStep->Get_MissingParticleIndex() == int(loc_j)) //missing particle
314 continue;
315 Particle_t locPID = locFinalParticleIDs[loc_j];
316
317 //see if decays in a future step
318 int locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, loc_i, loc_j);
319 if(locDecayStepIndex >= 0) //decaying
320 {
321 if(locDecayingParticleNumberMap.find(locPID) == locDecayingParticleNumberMap.end())
322 locDecayingParticleNumberMap[locPID] = 1;
323 else
324 ++locDecayingParticleNumberMap[locPID];
325 }
326 else //detected, not decaying
327 {
328 if(locParticleNumberMap.find(locPID) == locParticleNumberMap.end())
329 locParticleNumberMap[locPID] = 1;
330 else
331 ++locParticleNumberMap[locPID];
332 }
333 }
334 }
335
336 //Create map objects
337 map<Particle_t, unsigned int> locParticleNumberMap_Current, locDecayingParticleNumberMap_Current, locTargetParticleNumberMap_Current;
338 Particle_t locTargetPID = Unknown;
339 TObjString *locObjString_PID, *locObjString_Position, *locObjString_ParticleName;
340 map<int, string> locDecayingParticleNames; //key is step index where they decay
341 for(size_t loc_i = 0; loc_i < locReaction->Get_NumReactionSteps(); ++loc_i)
342 {
343 const DReactionStep* locReactionStep = locReaction->Get_ReactionStep(loc_i);
344
345 //initial particle
346 {
347 ostringstream locPIDStream, locPositionStream, locParticleNameStream;
348 Particle_t locPID = locReactionStep->Get_InitialPID();
349 locPIDStream << PDGtype(locPID);
350 locObjString_PID = new TObjString(locPIDStream.str().c_str());
351
352 locPositionStream << loc_i << "_" << -1;
353 locObjString_Position = new TObjString(locPositionStream.str().c_str());
354
355 locPositionToPIDMap->Add(locObjString_Position, locObjString_PID);
356 if((loc_i == 0) && ((locPID == Gamma) || (locPID == Electron) || (locPID == Positron)))
357 {
358 locParticleNameStream << "ComboBeam";
359 locObjString_ParticleName = new TObjString(locParticleNameStream.str().c_str());
360 locNameToPIDMap->Add(locObjString_ParticleName, locObjString_PID);
361 locParticleNameList->AddLast(locObjString_ParticleName);
362 }
363 else //decaying particle
364 {
365 if(loc_i == 0)
366 locParticleNameStream << "Decaying" << Convert_ToBranchName(ParticleType(locPID));
367 else //name already created for final particle: use it
368 locParticleNameStream << locDecayingParticleNames[loc_i];
369 locObjString_ParticleName = new TObjString(locParticleNameStream.str().c_str());
370 if(loc_i == 0) //in first step
371 {
372 locNameToPIDMap->Add(locObjString_ParticleName, locObjString_PID);
373 locParticleNameList->AddLast(locObjString_ParticleName);
374 }
375 }
376 locPositionToNameMap->Add(locObjString_Position, locObjString_ParticleName);
377 locNameToPositionMap->Add(locObjString_ParticleName, locObjString_Position);
378 }
379
380 //target particle
381 Particle_t locTempTargetPID = locReactionStep->Get_TargetPID();
382 if(locTempTargetPID != Unknown)
383 {
384 locTargetPID = locTempTargetPID;
385
386 if(locTargetParticleNumberMap_Current.find(locTargetPID) == locTargetParticleNumberMap_Current.end())
387 locTargetParticleNumberMap_Current[locTargetPID] = 1;
388 else
389 ++locTargetParticleNumberMap_Current[locTargetPID];
390
391 ostringstream locPIDStream, locPositionStream, locParticleNameStream;
392 locPIDStream << PDGtype(locTargetPID);
393 locObjString_PID = new TObjString(locPIDStream.str().c_str());
394
395 locPositionStream << loc_i << "_" << -2;
396 locObjString_Position = new TObjString(locPositionStream.str().c_str());
397
398 locPositionToPIDMap->Add(locObjString_Position, locObjString_PID);
399
400 locParticleNameStream << "Target";
401 if(locTargetParticleNumberMap[locTargetPID] > 1)
402 locParticleNameStream << locTargetParticleNumberMap_Current[locTargetPID];
403 locObjString_ParticleName = new TObjString(locParticleNameStream.str().c_str());
404
405 locNameToPositionMap->Add(locObjString_ParticleName, locObjString_Position);
406 locNameToPIDMap->Add(locObjString_ParticleName, locObjString_PID);
407 locPositionToNameMap->Add(locObjString_Position, locObjString_ParticleName);
408
409 locParticleNameList->AddLast(locObjString_ParticleName);
410 }
411
412 //final particles
413 auto locFinalParticleIDs = locReactionStep->Get_FinalPIDs();
414 for(size_t loc_j = 0; loc_j < locFinalParticleIDs.size(); ++loc_j)
415 {
416 ostringstream locPIDStream, locPositionStream;
417 Particle_t locPID = locFinalParticleIDs[loc_j];
418 locPIDStream << PDGtype(locPID);
419 locObjString_PID = new TObjString(locPIDStream.str().c_str());
420
421 locPositionStream << loc_i << "_" << loc_j;
422 locObjString_Position = new TObjString(locPositionStream.str().c_str());
423
424 if(locReactionStep->Get_MissingParticleIndex() == int(loc_j)) //missing particle
425 {
426 ostringstream locParticleNameStream;
427 locParticleNameStream << "Missing" << Convert_ToBranchName(ParticleType(locPID));
428 locObjString_ParticleName = new TObjString(locParticleNameStream.str().c_str());
429 locNameToPositionMap->Add(locObjString_ParticleName, locObjString_Position);
430 locPositionToNameMap->Add(locObjString_Position, locObjString_ParticleName);
431 locNameToPIDMap->Add(locObjString_ParticleName, locObjString_PID);
432 string locPIDName = locParticleNameStream.str() + string("__PID");
433 locMiscInfoMap->Add(new TObjString(locPIDName.c_str()), locObjString_PID);
434 ostringstream locMassStream;
435 locMassStream << ParticleMass(locPID);
436 string locMassName = locParticleNameStream.str() + string("__Mass");
437 locMiscInfoMap->Add(new TObjString(locMassName.c_str()), new TObjString(locMassStream.str().c_str()));
438 locParticleNameList->AddLast(locObjString_ParticleName);
439 continue;
440 }
441
442 //build name
443 ostringstream locParticleNameStream;
444 //see if decays in a future step
445 int locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, loc_i, loc_j);
446 if(locDecayStepIndex >= 0) //decays
447 {
448 if(locDecayingParticleNumberMap_Current.find(locPID) == locDecayingParticleNumberMap_Current.end())
449 locDecayingParticleNumberMap_Current[locPID] = 1;
450 else
451 ++locDecayingParticleNumberMap_Current[locPID];
452
453 locParticleNameStream << "Decaying" << Convert_ToBranchName(ParticleType(locPID));
454 if(locDecayingParticleNumberMap[locPID] > 1)
455 locParticleNameStream << locDecayingParticleNumberMap_Current[locPID];
456 locDecayingParticleNames[locDecayStepIndex] = locParticleNameStream.str();
457 }
458 else
459 {
460 if(locParticleNumberMap_Current.find(locPID) == locParticleNumberMap_Current.end())
461 locParticleNumberMap_Current[locPID] = 1;
462 else
463 ++locParticleNumberMap_Current[locPID];
464
465 locParticleNameStream << Convert_ToBranchName(ParticleType(locPID));
466 if(locParticleNumberMap[locPID] > 1)
467 locParticleNameStream << locParticleNumberMap_Current[locPID];
468 }
469
470 locObjString_ParticleName = new TObjString(locParticleNameStream.str().c_str());
471 locParticleNameList->AddLast(locObjString_ParticleName);
472
473 locPositionToPIDMap->Add(locObjString_Position, locObjString_PID);
474 locNameToPositionMap->Add(locObjString_ParticleName, locObjString_Position);
475 locPositionToNameMap->Add(locObjString_Position, locObjString_ParticleName);
476 locNameToPIDMap->Add(locObjString_ParticleName, locObjString_PID);
477 if(locDecayStepIndex >= 0)
478 {
479 ostringstream locMassStream;
480 locMassStream << ParticleMass(locPID);
481 string locMassName = locParticleNameStream.str() + string("__Mass");
482 locMiscInfoMap->Add(new TObjString(locMassName.c_str()), new TObjString(locMassStream.str().c_str()));
483 }
484 }
485 }
486
487 //setup target info
488 Create_UserTargetInfo(locBranchRegister, locTargetPID);
489
490 //fill decay product map
491 deque<size_t> locSavedSteps;
492 for(size_t loc_i = 0; loc_i < locReaction->Get_NumReactionSteps(); ++loc_i)
493 {
494 const DReactionStep* locReactionStep = locReaction->Get_ReactionStep(loc_i);
495
496 //initial particle
497 Particle_t locPID = locReactionStep->Get_InitialPID();
498 if(loc_i == 0)
499 continue;
500 if(!IsFixedMass(locPID))
501 continue; //don't save resonance decays to the map
502
503 //check to see if this decay has already been saved
504 bool locStepAlreadySavedFlag = false;
505 for(size_t loc_j = 0; loc_j < locSavedSteps.size(); ++loc_j)
506 {
507 if(locSavedSteps[loc_j] != loc_i)
508 continue;
509 locStepAlreadySavedFlag = true;
510 break;
511 }
512 if(locStepAlreadySavedFlag)
513 continue;
514
515 //construct the name
516 ostringstream locParticleNameStream;
517 locParticleNameStream << locDecayingParticleNames[loc_i];
518 locObjString_ParticleName = new TObjString(locParticleNameStream.str().c_str());
519
520 TList* locDecayProductNames = NULL__null;
521 Get_DecayProductNames(locReaction, loc_i, locPositionToNameMap, locDecayProductNames, locSavedSteps);
522 locDecayProductMap->Add(locObjString_ParticleName, locDecayProductNames); //parent name string -> tobjarray of decay product name strings
523 }
524
525 return locPositionToNameMap;
526}
527
528void DEventWriterROOT::Get_DecayProductNames(const DReaction* locReaction, size_t locReactionStepIndex, TMap* locPositionToNameMap, TList*& locDecayProductNames, deque<size_t>& locSavedSteps) const
529{
530 const DReactionStep* locReactionStep = locReaction->Get_ReactionStep(locReactionStepIndex);
531
532 if(locDecayProductNames == NULL__null)
533 locDecayProductNames = new TList();
534
535 auto locFinalParticleIDs = locReactionStep->Get_FinalPIDs();
536 for(size_t loc_j = 0; loc_j < locFinalParticleIDs.size(); ++loc_j)
537 {
538 //see if decays in a future step //save and continue if doesn't decay
539 int locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, locReactionStepIndex, loc_j);
540 if(locDecayStepIndex < 0)
541 {
542 ostringstream locPositionStream;
543 locPositionStream << locReactionStepIndex << "_" << loc_j;
544 locDecayProductNames->AddLast(locPositionToNameMap->GetValue(locPositionStream.str().c_str()));
545 continue;
546 }
547
548 //add decay products
549 Get_DecayProductNames(locReaction, locDecayStepIndex, locPositionToNameMap, locDecayProductNames, locSavedSteps);
550 }
551
552 locSavedSteps.push_back(locReactionStepIndex);
553}
554
555void DEventWriterROOT::Create_UserTargetInfo(DTreeBranchRegister& locBranchRegister, Particle_t locTargetPID) const
556{
557 TList* locUserInfo = locBranchRegister.Get_UserInfo();
558 TMap* locMiscInfoMap = (TMap*)locUserInfo->FindObject("MiscInfoMap");
559 if(locMiscInfoMap == NULL__null)
560 {
561 locMiscInfoMap = new TMap();
562 locMiscInfoMap->SetName("MiscInfoMap");
563 locUserInfo->Add(locMiscInfoMap);
564 }
565
566 //PID
567 ostringstream locPIDStream;
568 locPIDStream << PDGtype(locTargetPID);
569 locMiscInfoMap->Add(new TObjString("Target__PID"), new TObjString(locPIDStream.str().c_str()));
570
571 //Mass
572 ostringstream locMassStream;
573 locMassStream << ParticleMass(locTargetPID);
574 locMiscInfoMap->Add(new TObjString("Target__Mass"), new TObjString(locMassStream.str().c_str()));
575
576 //X, Y
577 ostringstream locZeroStream;
578 locZeroStream << 0.0;
579 TObjString* locObjString_Zero = new TObjString(locZeroStream.str().c_str());
580 locMiscInfoMap->Add(new TObjString("Target__CenterX"), locObjString_Zero);
581 locMiscInfoMap->Add(new TObjString("Target__CenterY"), locObjString_Zero);
582
583 //Z
584 ostringstream locPositionStream;
585 locPositionStream << dTargetCenterZ;
586 TObjString* locObjString_Position = new TObjString(locPositionStream.str().c_str());
587 locMiscInfoMap->Add(new TObjString("Target__CenterZ"), locObjString_Position);
588}
589
590void DEventWriterROOT::Create_Branches_Thrown(DTreeBranchRegister& locBranchRegister, bool locIsOnlyThrownFlag) const
591{
592 //BEAM
593 locBranchRegister.Register_Single<Int_t>(Build_BranchName("ThrownBeam", "PID"));
594 locBranchRegister.Register_Single<TLorentzVector>(Build_BranchName("ThrownBeam", "X4")); //reported at target center
595 locBranchRegister.Register_Single<TLorentzVector>(Build_BranchName("ThrownBeam", "P4"));
596 locBranchRegister.Register_Single<Float_t>(Build_BranchName("ThrownBeam", "GeneratedEnergy"));
597
598 //EVENT-WIDE INFO
599 locBranchRegister.Register_Single<ULong64_t>("NumPIDThrown_FinalState"); //19 digits
600 locBranchRegister.Register_Single<ULong64_t>("PIDThrown_Decaying"); //19 digits
601 locBranchRegister.Register_Single<Float_t>("MCWeight");
602
603 //PRODUCTS
604 Create_Branches_ThrownParticles(locBranchRegister, locIsOnlyThrownFlag);
605}
606
607void DEventWriterROOT::Create_Branches_ThrownParticles(DTreeBranchRegister& locBranchRegister, bool locIsOnlyThrownFlag) const
608{
609 string locParticleBranchName = "Thrown";
610
611 string locArraySizeString = "NumThrown";
612 locBranchRegister.Register_Single<UInt_t>(locArraySizeString);
613
614 //IDENTIFIERS
615 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "ParentIndex"), locArraySizeString, dInitNumThrownArraySize);
616 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "PID"), locArraySizeString, dInitNumThrownArraySize);
617 if(!locIsOnlyThrownFlag)
618 {
619 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "MatchID"), locArraySizeString, dInitNumThrownArraySize);
620 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "MatchFOM"), locArraySizeString, dInitNumThrownArraySize);
621 }
622
623 //KINEMATICS: THROWN //at the production vertex
624 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4"), dInitNumThrownArraySize);
625 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4"), dInitNumThrownArraySize);
626}
627
628void DEventWriterROOT::Create_Branches_Beam(DTreeBranchRegister& locBranchRegister, bool locIsMCDataFlag) const
629{
630 string locArraySizeString = "NumBeam";
631 locBranchRegister.Register_Single<UInt_t>(locArraySizeString);
632
633 string locParticleBranchName = "Beam";
634
635 //IDENTIFIER
636 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "PID"), locArraySizeString, dInitNumBeamArraySize);
637 if(locIsMCDataFlag)
638 locBranchRegister.Register_FundamentalArray<Bool_t>(Build_BranchName(locParticleBranchName, "IsGenerator"), locArraySizeString, dInitNumBeamArraySize);
639
640 //KINEMATICS: MEASURED //at the production vertex
641 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Measured"), dInitNumThrownArraySize);
642 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_Measured"), dInitNumThrownArraySize);
643}
644
645void DEventWriterROOT::Create_Branches_ChargedHypotheses(DTreeBranchRegister& locBranchRegister, bool locIsMCDataFlag) const
646{
647 string locArraySizeString = "NumChargedHypos";
648 locBranchRegister.Register_Single<UInt_t>(locArraySizeString);
649
650 string locParticleBranchName = "ChargedHypo";
651
652 //IDENTIFIERS / MATCHING
653 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "TrackID"), locArraySizeString, dInitNumTrackArraySize);
654 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "PID"), locArraySizeString, dInitNumTrackArraySize);
655 if(locIsMCDataFlag)
656 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "ThrownIndex"), locArraySizeString, dInitNumTrackArraySize);
657
658 //KINEMATICS //at the production vertex
659 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Measured"), dInitNumTrackArraySize);
660 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_Measured"), dInitNumTrackArraySize);
661
662 // Global PID
663 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "PIDFOM"), locArraySizeString, dInitNumTrackArraySize);
664
665 //TRACKING INFO
666 locBranchRegister.Register_FundamentalArray<UInt_t>(Build_BranchName(locParticleBranchName, "NDF_Tracking"), locArraySizeString, dInitNumTrackArraySize);
667 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Tracking"), locArraySizeString, dInitNumTrackArraySize);
668 locBranchRegister.Register_FundamentalArray<UInt_t>(Build_BranchName(locParticleBranchName, "NDF_DCdEdx"), locArraySizeString, dInitNumTrackArraySize);
669 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_DCdEdx"), locArraySizeString, dInitNumTrackArraySize);
670 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_CDC"), locArraySizeString, dInitNumTrackArraySize);
671 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_CDC_integral"), locArraySizeString, dInitNumTrackArraySize);
672 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_FDC"), locArraySizeString, dInitNumTrackArraySize);
673
674 //TIMING INFO
675 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "HitTime"), locArraySizeString, dInitNumTrackArraySize);
676 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "RFDeltaTVar"), locArraySizeString, dInitNumTrackArraySize);
677
678 //PID QUALITY
679 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing"), locArraySizeString, dInitNumTrackArraySize);
680 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing"), locArraySizeString, dInitNumTrackArraySize);
681 locBranchRegister.Register_FundamentalArray<UInt_t>(Build_BranchName(locParticleBranchName, "NDF_Timing"), locArraySizeString, dInitNumTrackArraySize);
682
683 //HIT ENERGY
684 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_TOF"), locArraySizeString, dInitNumTrackArraySize);
685 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_ST"), locArraySizeString, dInitNumTrackArraySize);
686 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
687 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALPreshower"), locArraySizeString, dInitNumNeutralArraySize);
688 if(BCAL_VERBOSE_OUTPUT) {
689 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer2"), locArraySizeString, dInitNumNeutralArraySize);
690 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer3"), locArraySizeString, dInitNumNeutralArraySize);
691 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer4"), locArraySizeString, dInitNumNeutralArraySize);
692 }
693 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SigLong_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
694 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SigTheta_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
695 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SigTrans_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
696 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "RMSTime_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
697 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
698 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "E1E9_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
699 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "E9E25_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
700 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SumU_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
701 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SumV_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
702
703 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_CCAL"), locArraySizeString, dInitNumNeutralArraySize);
704
705
706 //SHOWER MATCHING:
707 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "TrackBCAL_DeltaPhi"), locArraySizeString, dInitNumTrackArraySize);
708 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "TrackBCAL_DeltaZ"), locArraySizeString, dInitNumTrackArraySize);
709 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "TrackFCAL_DOCA"), locArraySizeString, dInitNumTrackArraySize);
710
711 //DIRC:
712 if(DIRC_OUTPUT) {
713 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "NumPhotons_DIRC"), locArraySizeString, dInitNumTrackArraySize);
714 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ExtrapolatedX_DIRC"), locArraySizeString, dInitNumTrackArraySize);
715 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ExtrapolatedY_DIRC"), locArraySizeString, dInitNumTrackArraySize);
716 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ThetaC_DIRC"), locArraySizeString, dInitNumTrackArraySize);
717 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Lele_DIRC"), locArraySizeString, dInitNumTrackArraySize);
718 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Lpi_DIRC"), locArraySizeString, dInitNumTrackArraySize);
719 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Lk_DIRC"), locArraySizeString, dInitNumTrackArraySize);
720 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Lp_DIRC"), locArraySizeString, dInitNumTrackArraySize);
721 }
722}
723
724void DEventWriterROOT::Create_Branches_NeutralHypotheses(DTreeBranchRegister& locBranchRegister, bool locIsMCDataFlag) const
725{
726 string locArraySizeString = "NumNeutralHypos";
727 string locParticleBranchName = "NeutralHypo";
728 locBranchRegister.Register_Single<UInt_t>(locArraySizeString);
729
730 //IDENTIFIERS / MATCHING
731 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "NeutralID"), locArraySizeString, dInitNumNeutralArraySize);
732 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "PID"), locArraySizeString, dInitNumNeutralArraySize);
733 if(locIsMCDataFlag)
734 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "ThrownIndex"), locArraySizeString, dInitNumNeutralArraySize);
735
736 //KINEMATICS //is combo-dependent: P4 defined by X4, X4 defined by other tracks
737 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Measured"), dInitNumNeutralArraySize);
738 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_Measured"), dInitNumNeutralArraySize);
739
740 //PID QUALITY
741 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing"), locArraySizeString, dInitNumNeutralArraySize);
742 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing"), locArraySizeString, dInitNumNeutralArraySize);
743 locBranchRegister.Register_FundamentalArray<UInt_t>(Build_BranchName(locParticleBranchName, "NDF_Timing"), locArraySizeString, dInitNumNeutralArraySize);
744
745 //SHOWER INFO
746 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Shower"), dInitNumNeutralArraySize);
747 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ShowerQuality"), locArraySizeString, dInitNumNeutralArraySize);
748 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
749 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALPreshower"), locArraySizeString, dInitNumNeutralArraySize);
750 if(BCAL_VERBOSE_OUTPUT) {
751 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer2"), locArraySizeString, dInitNumNeutralArraySize);
752 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer3"), locArraySizeString, dInitNumNeutralArraySize);
753 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer4"), locArraySizeString, dInitNumNeutralArraySize);
754 }
755 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SigLong_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
756 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SigTheta_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
757 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SigTrans_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
758 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "RMSTime_BCAL"), locArraySizeString, dInitNumNeutralArraySize);
759 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
760 if(FCAL_VERBOSE_OUTPUT) {
761 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "E1E9_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
762 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "E9E25_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
763 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SumU_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
764 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "SumV_FCAL"), locArraySizeString, dInitNumNeutralArraySize);
765 }
766 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Energy_CCAL"), locArraySizeString, dInitNumNeutralArraySize);
767 //NEARBY TRACKS
768 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "TrackBCAL_DeltaPhi"), locArraySizeString, dInitNumNeutralArraySize);
769 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "TrackBCAL_DeltaZ"), locArraySizeString, dInitNumNeutralArraySize);
770 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "TrackFCAL_DOCA"), locArraySizeString, dInitNumNeutralArraySize);
771
772 //PHOTON PID INFO
773 //Computed using DVertex (best estimate of reaction vertex using all "good" tracks)
774 //Can be used to compute timing chisq //is invalid for non-photons, so computed assuming photon PID
775 //Variance of X4_Measured.T() - RFTime, regardless of which RF bunch is chosen. //RF bunch is combo-depende
776 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "PhotonRFDeltaTVar"), locArraySizeString, dInitNumNeutralArraySize);
777}
778
779void DEventWriterROOT::Create_Branches_Combo(DTreeBranchRegister& locBranchRegister, const DReaction* locReaction, bool locIsMCDataFlag, TMap* locPositionToNameMap) const
780{
781 auto locReactionVertexInfo = dVertexInfoMap.find(locReaction)->second;
782 string locNumComboString = "NumCombos";
783 locBranchRegister.Register_Single<UInt_t>(locNumComboString);
784
785 //kinfit type
786 DKinFitType locKinFitType = locReaction->Get_KinFitType();
787 bool locKinFitFlag = (locKinFitType != d_NoFit);
788 bool locVertexKinFitFlag = locKinFitFlag && (locKinFitType != d_P4Fit);
789
790 //Is-cut
791 locBranchRegister.Register_FundamentalArray<Bool_t>("IsComboCut", locNumComboString, dInitNumComboArraySize);
792
793 //create combo-dependent, particle-independent branches
794 if(locIsMCDataFlag)
795 {
796 locBranchRegister.Register_FundamentalArray<Bool_t>("IsTrueCombo", locNumComboString, dInitNumComboArraySize);
797 locBranchRegister.Register_FundamentalArray<Bool_t>("IsBDTSignalCombo", locNumComboString, dInitNumComboArraySize);
798 }
799
800 locBranchRegister.Register_FundamentalArray<Float_t>("RFTime_Measured", locNumComboString, dInitNumComboArraySize);
801 if(locKinFitFlag)
802 {
803 locBranchRegister.Register_FundamentalArray<Float_t>("ChiSq_KinFit", locNumComboString, dInitNumComboArraySize);
804 locBranchRegister.Register_FundamentalArray<UInt_t>("NDF_KinFit", locNumComboString, dInitNumComboArraySize);
805 if((locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndSpacetimeFit))
806 locBranchRegister.Register_FundamentalArray<Float_t>("RFTime_KinFit", locNumComboString, dInitNumComboArraySize);
807 }
808 locBranchRegister.Register_FundamentalArray<UChar_t>("NumUnusedShowers", locNumComboString, dInitNumComboArraySize);
809 locBranchRegister.Register_FundamentalArray<Float_t>("Energy_UnusedShowers", locNumComboString, dInitNumComboArraySize);
810 locBranchRegister.Register_FundamentalArray<UChar_t>("NumUnusedShowers_Quality", locNumComboString, dInitNumComboArraySize);
811 locBranchRegister.Register_FundamentalArray<Float_t>("Energy_UnusedShowers_Quality", locNumComboString, dInitNumComboArraySize);
812 locBranchRegister.Register_FundamentalArray<Float_t>("SumPMag_UnusedTracks", locNumComboString, dInitNumComboArraySize);
813 locBranchRegister.Register_ClonesArray<TVector3>("SumP3_UnusedTracks", dInitNumComboArraySize);
814
815 map<Particle_t, unsigned int> locParticleNumberMap_Current;
816 for(size_t loc_i = 0; loc_i < locReaction->Get_NumReactionSteps(); ++loc_i)
817 {
818 const DReactionStep* locReactionStep = locReaction->Get_ReactionStep(loc_i);
819
820 //initial particle
821 Particle_t locInitialPID = locReactionStep->Get_InitialPID();
822 //should check to make sure the beam particle isn't missing...
823 if((loc_i == 0) && (locReactionStep->Get_InitialPID() != Unknown))
824 Create_Branches_BeamComboParticle(locBranchRegister, locInitialPID, locKinFitType);
825 else //decaying
826 {
827 //get the branch name
828 ostringstream locPositionStream;
829 locPositionStream << loc_i << "_-1";
830 TObjString* locObjString = (TObjString*)locPositionToNameMap->GetValue(locPositionStream.str().c_str());
831 string locParticleBranchName = (const char*)(locObjString->GetString());
832
833 if(IsFixedMass(locInitialPID) && locReactionStep->Get_KinFitConstrainInitMassFlag() && ((locKinFitType == d_P4Fit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit)))
834 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), dInitNumComboArraySize);
835 if((loc_i == 0) || IsDetachedVertex(locInitialPID))
836 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4"), dInitNumComboArraySize);
837
838 auto locStepVertexInfo = locReactionVertexInfo->Get_StepVertexInfo(loc_i);
839 auto locParentVertexInfo = locStepVertexInfo->Get_ParentVertexInfo();
840 if(IsDetachedVertex(locInitialPID) && locVertexKinFitFlag && (locParentVertexInfo != nullptr) && locStepVertexInfo->Get_FittableVertexFlag() && locParentVertexInfo->Get_FittableVertexFlag())
841 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "PathLengthSigma"), locNumComboString, dInitNumComboArraySize);
842 }
843
844 //final particles
845 auto locFinalParticleIDs = locReactionStep->Get_FinalPIDs();
846 for(size_t loc_j = 0; loc_j < locFinalParticleIDs.size(); ++loc_j)
847 {
848 int locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, loc_i, loc_j);
849 if(locDecayStepIndex >= 0)
850 continue; //decaying particle
851
852 //get the branch name
853 ostringstream locPositionStream;
854 locPositionStream << loc_i << "_" << loc_j;
855 TObjString* locObjString = (TObjString*)locPositionToNameMap->GetValue(locPositionStream.str().c_str());
856 string locParticleBranchName = (const char*)(locObjString->GetString());
857
858 //missing particle
859 if(locReactionStep->Get_MissingParticleIndex() == int(loc_j))
860 {
861 // missing particle
862 if((locKinFitType == d_P4Fit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit))
863 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), dInitNumComboArraySize);
864 continue;
865 }
866
867 Particle_t locPID = locFinalParticleIDs[loc_j];
868 if(ParticleCharge(locPID) == 0)
869 Create_Branches_ComboNeutral(locBranchRegister, locParticleBranchName, locKinFitType);
870 else
871 Create_Branches_ComboTrack(locBranchRegister, locParticleBranchName, locKinFitType);
872 }
873 }
874}
875
876void DEventWriterROOT::Create_Branches_BeamComboParticle(DTreeBranchRegister& locBranchRegister, Particle_t locBeamPID, DKinFitType locKinFitType) const
877{
878 string locParticleBranchName = "ComboBeam";
879 string locArraySizeString = "NumCombos";
880
881 //IDENTIFIER
882 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "BeamIndex"), locArraySizeString, dInitNumComboArraySize);
883
884 //KINEMATICS: KINFIT //at the interaction vertex
885 if(locKinFitType != d_NoFit)
886 {
887 if(((locKinFitType != d_VertexFit) && (locKinFitType != d_SpacetimeFit)) || (ParticleCharge(locBeamPID) != 0))
888 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), dInitNumComboArraySize);
889 if(locKinFitType != d_P4Fit)
890 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_KinFit"), dInitNumComboArraySize);
891 }
892}
893
894void DEventWriterROOT::Create_Branches_ComboTrack(DTreeBranchRegister& locBranchRegister, string locParticleBranchName, DKinFitType locKinFitType) const
895{
896 string locArraySizeString = "NumCombos";
897
898 //IDENTIFIER
899 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "ChargedIndex"), locArraySizeString, dInitNumComboArraySize);
900
901 //MEASURED PID
902 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing_Measured"), locArraySizeString, dInitNumComboArraySize);
903 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing_Measured"), locArraySizeString, dInitNumComboArraySize);
904
905 //KINFIT PID
906 if((locKinFitType != d_NoFit) && (locKinFitType != d_SpacetimeFit) && (locKinFitType != d_P4AndSpacetimeFit))
907 {
908 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing_KinFit"), locArraySizeString, dInitNumComboArraySize);
909 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing_KinFit"), locArraySizeString, dInitNumComboArraySize);
910 }
911
912 //KINFIT INFO //at the production vertex
913 if(locKinFitType != d_NoFit)
914 {
915 //update p4 even if vertex-only fit, because charged momentum propagated through b-field
916 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), dInitNumComboArraySize);
917 if(locKinFitType != d_P4Fit)
918 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_KinFit"), dInitNumComboArraySize);
919 }
920}
921
922void DEventWriterROOT::Create_Branches_ComboNeutral(DTreeBranchRegister& locBranchRegister, string locParticleBranchName, DKinFitType locKinFitType) const
923{
924 string locArraySizeString = "NumCombos";
925
926 //IDENTIFIER
927 locBranchRegister.Register_FundamentalArray<Int_t>(Build_BranchName(locParticleBranchName, "NeutralIndex"), locArraySizeString, dInitNumComboArraySize);
928
929 //KINEMATICS //is combo-dependent: P4 defined by X4, X4 defined by other tracks
930 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Measured"), dInitNumComboArraySize);
931 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_Measured"), dInitNumComboArraySize);
932
933 //MEASURED PID
934 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing_Measured"), locArraySizeString, dInitNumComboArraySize);
935 if(locParticleBranchName.substr(0, 6) == "Photon")
936 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing_Measured"), locArraySizeString, dInitNumComboArraySize);
937
938 //KINFIT PID
939 if((locKinFitType != d_NoFit) && (locKinFitType != d_SpacetimeFit) && (locKinFitType != d_P4AndSpacetimeFit))
940 {
941 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing_KinFit"), locArraySizeString, dInitNumComboArraySize);
942 if(locParticleBranchName.substr(0, 6) == "Photon")
943 locBranchRegister.Register_FundamentalArray<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing_KinFit"), locArraySizeString, dInitNumComboArraySize);
944 }
945
946 //KINFIT INFO //at the production vertex
947 if(locKinFitType != d_NoFit)
948 {
949 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), dInitNumComboArraySize);
950 if(locKinFitType != d_P4Fit)
951 locBranchRegister.Register_ClonesArray<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_KinFit"), dInitNumComboArraySize);
952 }
953}
954
955void DEventWriterROOT::Create_Branches_KinFitData(DTreeBranchRegister& locBranchRegister, JEventLoop* locEventLoop, const DReaction* locReaction, bool locIsMCDataFlag) const
956{
957
958 if(!STORE_PULL_INFO && !STORE_ERROR_MATRIX_INFO)
959 return;
960
961 //Get the fit-type (P4, P4 + Vertex, and Vertex-only)
962 DKinFitType kfitType = locReaction->Get_KinFitType();
963
964 vector<Particle_t> finalchargedPIDs,finalneutralPIDs;
965 size_t nReactionSteps = locReaction->Get_NumReactionSteps();
966 int nFinalChargedParticles,nFinalNeutralParticles;
967
968 vector<string> pidVector = getPIDinReaction(locReaction);
969 map<Particle_t,int> assignMap = getNameForParticle(locReaction,pidVector);
970
971 //Check, if at least two charged particles are present in the final state: (important for vertex-fit)
972 int sumAllChargedParticles = 0;
973 int sumAllNeutralParticles = 0;
974 //First, check how many neutral/charged particles are in the final stage
975 //The pull-information is avaiablable for certain particle combinations (charged + neutral) only:
976 //----------------------------------------------------------------------------------------------
977 for(size_t loc_i=0;loc_i<nReactionSteps;loc_i++){
978
979 //Charged Particles:
980 finalchargedPIDs = locReaction->Get_ReactionStep(loc_i)->Get_FinalPIDs(true,d_Charged,true);
981 nFinalChargedParticles = finalchargedPIDs.size();
982 sumAllChargedParticles += nFinalChargedParticles;
983
984 //Neutral Particles:
985 finalneutralPIDs = locReaction->Get_ReactionStep(loc_i)->Get_FinalPIDs(true,d_Neutral,true);
986 nFinalNeutralParticles = finalneutralPIDs.size();
987 sumAllNeutralParticles += nFinalNeutralParticles;
988 }
989 //----------------------------------------------------------------------------------------------
990
991 if(sumAllChargedParticles == 1 && (kfitType == d_VertexFit || kfitType == d_P4AndVertexFit)){
992 STORE_PULL_INFO = false;
993 jout <<" "<< endl;
994 jout <<">>> WARNING: Only one charged track in the final state! No vertex fit possible! No pulls will be stored... <<<"<< endl;
995 jout <<" "<< endl;
996 }
997
998 if(sumAllNeutralParticles > 0 && kfitType == d_VertexFit){
999 STORE_PULL_INFO = false;
1000 jout <<" "<< endl;
1001 jout <<">>> WARNING: Neutral particles involved in pure vertex fit! No pulls will be stored... <<<"<< endl;
1002 jout <<" "<< endl;
1003 }
1004
1005 if(kfitType == d_NoFit){
1006 STORE_PULL_INFO = false;
1007 jout <<" "<< endl;
1008 jout <<">>> WARNING: No fit specified! No pulls will be stored... <<<"<< endl;
1009 jout <<" "<< endl;
1010 }
1011
1012 setPullFlag(locReaction,STORE_PULL_INFO);
1013
1014 //Get Pulls for the beam:
1015 //Particle_t beamPID = locReaction->Get_ReactionStep(0)->Get_InitialPID();
1016
1017 string particleCovM = "numEntries_ParticleErrM";
1018 string showerCovM = "numEntries_ShowerErrM";
1019 string decayCovM = "numEntries_DecayErrM";
1020 if(STORE_ERROR_MATRIX_INFO){
1021 locBranchRegister.Register_Single<Int_t>(particleCovM);
1022 locBranchRegister.Register_Single<Int_t>(showerCovM);
1023 }
1024
1025 //Set the branches for the beam photon:
1026 if(STORE_PULL_INFO)
1027 setTreePullBranches(locBranchRegister,"ComboBeam",kfitType,dInitNumComboArraySize,true);
1028 if(STORE_ERROR_MATRIX_INFO)
1029 locBranchRegister.Register_FundamentalArray< Float_t >(Build_BranchName("ComboBeam","ErrMatrix"),particleCovM,nEntriesParticleCov);
1030
1031 //----------------------------------------------------------------------------------------------
1032 for(size_t loc_i=0;loc_i<nReactionSteps;loc_i++){
1033
1034 //Charged Particles:
1035 finalchargedPIDs = locReaction->Get_ReactionStep(loc_i)->Get_FinalPIDs(true,d_Charged,true);
1036 nFinalChargedParticles = finalchargedPIDs.size();
1037 //----------------------------------------------------------------------------------------------
1038 for(int loc_j=0;loc_j<nFinalChargedParticles;loc_j++){
1039 //Define branches for final charged particles:
1040 string branchName = assignName(finalchargedPIDs.at(loc_j),assignMap);
1041 assignMap[finalchargedPIDs.at(loc_j)]--;
1042 if(branchName != "nada"){
1043 if(STORE_PULL_INFO) setTreePullBranches(locBranchRegister,branchName,kfitType,dInitNumComboArraySize,false);
1044 if(STORE_ERROR_MATRIX_INFO) locBranchRegister.Register_FundamentalArray< Float_t >(Build_BranchName(branchName,"ErrMatrix"),particleCovM,nEntriesParticleCov);
1045 }
1046 }
1047 //----------------------------------------------------------------------------------------------
1048
1049 //Neutral Particles:
1050 finalneutralPIDs = locReaction->Get_ReactionStep(loc_i)->Get_FinalPIDs(true,d_Neutral,true);
1051 nFinalNeutralParticles = finalneutralPIDs.size();
1052 //----------------------------------------------------------------------------------------------
1053 for(int loc_j=0;loc_j<nFinalNeutralParticles;loc_j++){
1054 //Define branches for final neutral particles:
1055 string branchName = assignName(finalneutralPIDs.at(loc_j),assignMap);
1056 assignMap[finalneutralPIDs.at(loc_j)]--;
1057 if(branchName != "nada"){
1058 if(STORE_PULL_INFO) setTreePullBranches(locBranchRegister,branchName,kfitType,dInitNumComboArraySize,true);
1059 if(finalneutralPIDs.at(loc_j) == Gamma && STORE_ERROR_MATRIX_INFO) locBranchRegister.Register_FundamentalArray< Float_t >(Build_BranchName(branchName,"ErrMatrix"),showerCovM,nEntriesShowerCov);
1060 }
1061 }
1062 //----------------------------------------------------------------------------------------------
1063 }
1064 //----------------------------------------------------------------------------------------------
1065
1066 assignMap.clear();
1067 abundanceMap.clear();
1068}
1069
1070void DEventWriterROOT::Fill_ThrownTree(JEventLoop* locEventLoop) const
1071{
1072 vector<const DMCThrown*> locMCThrowns_FinalState;
1073 locEventLoop->Get(locMCThrowns_FinalState, "FinalState");
1074
1075 vector<const DMCThrown*> locMCThrowns_Decaying;
1076 locEventLoop->Get(locMCThrowns_Decaying, "Decaying");
1077
1078 const DMCReaction* locMCReaction = NULL__null;
1079 locEventLoop->GetSingle(locMCReaction);
1080
1081 ULong64_t locNumPIDThrown_FinalState = 0, locPIDThrown_Decaying = 0;
1082 Compute_ThrownPIDInfo(locMCThrowns_FinalState, locMCThrowns_Decaying, locNumPIDThrown_FinalState, locPIDThrown_Decaying);
1083
1084 vector<const DMCThrown*> locMCThrownsToSave;
1085 map<const DMCThrown*, unsigned int> locThrownIndexMap;
1086 Group_ThrownParticles(locMCThrowns_FinalState, locMCThrowns_Decaying, locMCThrownsToSave, locThrownIndexMap);
1087
1088 vector<const DBeamPhoton*> locTaggedMCGenBeams;
1089 locEventLoop->Get(locTaggedMCGenBeams, "TAGGEDMCGEN");
1090
1091 vector<const DBeamPhoton*> locMCGenBeams;
1092 locEventLoop->Get(locMCGenBeams, "MCGEN");
1093
1094 const DBeamPhoton* locTaggedMCGenBeam = locTaggedMCGenBeams.empty() ? locMCGenBeams[0] : locTaggedMCGenBeams[0]; //if empty: will have to do.
1095
1096 japp->RootWriteLock();
1097
1098 //primary event info
1099 dThrownTreeFillData.Fill_Single<UInt_t>("RunNumber", locEventLoop->GetJEvent().GetRunNumber());
1100 dThrownTreeFillData.Fill_Single<ULong64_t>("EventNumber", locEventLoop->GetJEvent().GetEventNumber());
1101
1102 //throwns
1103 Fill_ThrownInfo(&dThrownTreeFillData, locMCReaction, locTaggedMCGenBeam, locMCThrownsToSave, locThrownIndexMap, locNumPIDThrown_FinalState, locPIDThrown_Decaying);
1104
1105 //Custom Branches
1106 Fill_CustomBranches_ThrownTree(&dThrownTreeFillData, locEventLoop, locMCReaction, locMCThrownsToSave);
1107
1108 //FILL TTREE
1109 dThrownTreeInterface->Fill(dThrownTreeFillData);
1110
1111
1112 japp->RootUnLock();
1113
1114}
1115
1116void DEventWriterROOT::Fill_DataTrees(JEventLoop* locEventLoop, string locDReactionTag) const
1117{
1118 if(locDReactionTag == "Thrown")
1119 {
1120 cout << "WARNING: CANNOT FILL THROWN TREE WITH THIS FUNCTION." << endl;
1121 return;
1122 }
1123
1124 vector<const DAnalysisResults*> locAnalysisResultsVector;
1125 locEventLoop->Get(locAnalysisResultsVector);
1126
1127 vector<const DReaction*> locReactionsWithTag;
1128 locEventLoop->Get(locReactionsWithTag, locDReactionTag.c_str());
1129
1130 for(size_t loc_i = 0; loc_i < locAnalysisResultsVector.size(); ++loc_i)
1131 {
1132 deque<const DParticleCombo*> locPassedParticleCombos;
1133 locAnalysisResultsVector[loc_i]->Get_PassedParticleCombos(locPassedParticleCombos);
1134 if(locPassedParticleCombos.empty())
1135 continue;
1136
1137 const DReaction* locReaction = locAnalysisResultsVector[loc_i]->Get_Reaction();
1138 if(!locReaction->Get_EnableTTreeOutputFlag())
1139 continue;
1140
1141 bool locReactionFoundFlag = false;
1142 for(size_t loc_j = 0; loc_j < locReactionsWithTag.size(); ++loc_j)
1143 {
1144 if(locReactionsWithTag[loc_j] != locReaction)
1145 continue;
1146 locReactionFoundFlag = true;
1147 break;
1148 }
1149 if(!locReactionFoundFlag)
1150 continue; //reaction not from this factory, continue
1151
1152 Fill_DataTree(locEventLoop, locReaction, locPassedParticleCombos);
1153 }
1154}
1155
1156void DEventWriterROOT::Fill_DataTree(JEventLoop* locEventLoop, const DReaction* locReaction, deque<const DParticleCombo*>& locParticleCombos) const
1157{
1158 if(locReaction->Get_ReactionName() == "Thrown")
1159 {
1160 cout << "WARNING: CANNOT FILL THROWN TREE WITH THIS FUNCTION." << endl;
1161 return;
1162 }
1163
1164 if(!locReaction->Get_EnableTTreeOutputFlag())
1165 {
1166 cout << "WARNING: ROOT TTREE OUTPUT NOT ENABLED FOR THIS DREACTION (" << locReaction->Get_ReactionName() << ")" << endl;
1167 return;
1168 }
1169
1170 /***************************************************** GET THROWN INFO *****************************************************/
1171
1172 vector<const DMCThrown*> locMCThrowns_FinalState;
1173 locEventLoop->Get(locMCThrowns_FinalState, "FinalState");
1174
1175 vector<const DMCThrown*> locMCThrowns_Decaying;
1176 locEventLoop->Get(locMCThrowns_Decaying, "Decaying");
1177
1178 vector<const DMCThrownMatching*> locMCThrownMatchingVector;
1179 locEventLoop->Get(locMCThrownMatchingVector);
1180 const DMCThrownMatching* locMCThrownMatching = locMCThrownMatchingVector.empty() ? NULL__null : locMCThrownMatchingVector[0];
1181
1182 vector<const DMCReaction*> locMCReactions;
1183 locEventLoop->Get(locMCReactions);
1184 const DMCReaction* locMCReaction = locMCReactions.empty() ? NULL__null : locMCReactions[0];
1185
1186 vector<const DBeamPhoton*> locTaggedMCGenBeams;
1187 locEventLoop->Get(locTaggedMCGenBeams, "TAGGEDMCGEN");
1188
1189 vector<const DBeamPhoton*> locMCGenBeams;
1190 locEventLoop->Get(locMCGenBeams, "MCGEN");
1191
1192 const DBeamPhoton* locTaggedMCGenBeam = nullptr;
1193
1194 if (locTaggedMCGenBeams.empty()){
1195 if ( !locMCGenBeams.empty() ) locTaggedMCGenBeam = locMCGenBeams[0];
1196 }
1197 else locTaggedMCGenBeam = locTaggedMCGenBeams[0];
1198
1199 //Pre-compute thrown info
1200 ULong64_t locNumPIDThrown_FinalState = 0, locPIDThrown_Decaying = 0;
1201 Compute_ThrownPIDInfo(locMCThrowns_FinalState, locMCThrowns_Decaying, locNumPIDThrown_FinalState, locPIDThrown_Decaying);
1202
1203 //Pre-compute thrown info
1204 vector<const DMCThrown*> locMCThrownsToSave;
1205 map<const DMCThrown*, unsigned int> locThrownIndexMap;
1206 Group_ThrownParticles(locMCThrowns_FinalState, locMCThrowns_Decaying, locMCThrownsToSave, locThrownIndexMap);
1207
1208 /****************************************************** GET PARTICLES ******************************************************/
1209
1210 bool locSaveUnusedFlag = locReaction->Get_SaveUnusedFlag();
1211
1212 //Get PIDs need for reaction
1213 auto locDetectedPIDs = locReaction->Get_FinalPIDs(-1, false, false, d_AllCharges, false);
1214 set<Particle_t> locReactionPIDs;
1215 for(size_t loc_j = 0; loc_j < locDetectedPIDs.size(); ++loc_j)
1216 locReactionPIDs.insert(locDetectedPIDs[loc_j]);
1217
1218 //GET HYPOTHESES
1219 vector<const DChargedTrackHypothesis*> locChargedTrackHypotheses;
1220 vector<const DNeutralParticleHypothesis*> locNeutralParticleHypotheses;
1221 if(locSaveUnusedFlag)
1222 {
1223 locChargedTrackHypotheses = Get_ChargedHypotheses(locEventLoop);
1224 locNeutralParticleHypotheses = Get_NeutralHypotheses(locEventLoop, locReactionPIDs);
1225 }
1226 else
1227 {
1228 locChargedTrackHypotheses = Get_ChargedHypotheses_Used(locEventLoop, locReaction, locParticleCombos);
1229 locNeutralParticleHypotheses = Get_NeutralHypotheses_Used(locEventLoop, locReaction, locReactionPIDs, locParticleCombos);
1230 }
1231
1232 //GET BEAM PHOTONS
1233 bool locBeamUsedFlag = DAnalysis::Get_IsFirstStepBeam(locReaction);
1234 vector<const DBeamPhoton*> locBeamPhotons = Get_BeamPhotons(locParticleCombos);
1235
1236 //create map of particles to array index:
1237 //used for pointing combo particles to the appropriate measured-particle array index
1238 //for hypos, they are the preselect versions if they exist, else the combo versions (e.g. PID not in REST)
1239
1240 //indices: beam
1241 map<pair<oid_t, Particle_t>, size_t> locObjectToArrayIndexMap; //particle_t necessary for neutral showers!
1242 for(size_t loc_i = 0; loc_i < locBeamPhotons.size(); ++loc_i)
1243 {
1244 pair<oid_t, Particle_t> locBeamPair(locBeamPhotons[loc_i]->id, locBeamPhotons[loc_i]->PID());
1245 locObjectToArrayIndexMap[locBeamPair] = loc_i;
1246 }
1247
1248 //indices: charged
1249 for(size_t loc_i = 0; loc_i < locChargedTrackHypotheses.size(); ++loc_i)
1250 {
1251 const DTrackTimeBased* locTrackTimeBased = locChargedTrackHypotheses[loc_i]->Get_TrackTimeBased();
1252 pair<oid_t, Particle_t> locTrackPair(locTrackTimeBased->id, locTrackTimeBased->PID());
1253 locObjectToArrayIndexMap[locTrackPair] = loc_i;
1254 }
1255
1256 //indices: neutral
1257 for(size_t loc_i = 0; loc_i < locNeutralParticleHypotheses.size(); ++loc_i)
1258 {
1259 const DNeutralShower* locNeutralShower = locNeutralParticleHypotheses[loc_i]->Get_NeutralShower();
1260 pair<oid_t, Particle_t> locShowerPair(locNeutralShower->id, locNeutralParticleHypotheses[loc_i]->PID());
1261 locObjectToArrayIndexMap[locShowerPair] = loc_i;
1262 }
1263
1264 /**************************************************** GET MISCELLANEOUS ****************************************************/
1265
1266 //GET DETECTOR MATCHES
1267 const DDetectorMatches* locDetectorMatches = NULL__null;
1268 locEventLoop->GetSingle(locDetectorMatches);
1269
1270 //GET DVERTEX
1271 const DVertex* locVertex = NULL__null;
1272 locEventLoop->GetSingle(locVertex);
1273
1274 //GET TRIGGER
1275 const DTrigger* locTrigger = NULL__null;
1276 locEventLoop->GetSingle(locTrigger);
1277
1278 /************************************************* EXECUTE ANALYSIS ACTIONS ************************************************/
1279
1280 japp->RootWriteLock();
1281
1282 Bool_t locIsThrownTopologyFlag = kFALSE;
1283 vector<Bool_t> locIsTrueComboFlags;
1284 vector<Bool_t> locIsBDTSignalComboFlags;
1285 if(locMCReaction != NULL__null)
1286 {
1287 DCutAction_ThrownTopology* locThrownTopologyAction = dCutActionMap_ThrownTopology.find(locReaction)->second;
1288 locIsThrownTopologyFlag = (*locThrownTopologyAction)(locEventLoop, NULL__null); //combo not used/needed
1289 for(size_t loc_i = 0; loc_i < locParticleCombos.size(); ++loc_i)
1290 {
1291 DCutAction_TrueCombo* locTrueComboAction = dCutActionMap_TrueCombo.find(locReaction)->second;
1292 locIsTrueComboFlags.push_back((*locTrueComboAction)(locEventLoop, locParticleCombos[loc_i]));
1293
1294 DCutAction_BDTSignalCombo* locBDTSignalComboAction = dCutActionMap_BDTSignalCombo.find(locReaction)->second;
1295 locIsBDTSignalComboFlags.push_back((*locBDTSignalComboAction)(locEventLoop, locParticleCombos[loc_i]));
1296 }
1297 }
1298
1299 /***************************************************** FILL TTREE DATA *****************************************************/
1300
1301 //Get tree fill data
1302 DTreeFillData* locTreeFillData = dTreeFillDataMap.find(locReaction)->second;
1303
1304 //PRIMARY EVENT INFO
1305 locTreeFillData->Fill_Single<UInt_t>("RunNumber", locEventLoop->GetJEvent().GetRunNumber());
1306 locTreeFillData->Fill_Single<ULong64_t>("EventNumber", locEventLoop->GetJEvent().GetEventNumber());
1307 locTreeFillData->Fill_Single<UInt_t>("L1TriggerBits", locTrigger->Get_L1TriggerBits());
1308
1309 //PRODUCTION X4
1310 DLorentzVector locProductionX4 = locVertex->dSpacetimeVertex;
1311 TLorentzVector locProductionTX4(locProductionX4.X(), locProductionX4.Y(), locProductionX4.Z(), locProductionX4.T());
1312 locTreeFillData->Fill_Single<TLorentzVector>("X4_Production", locProductionTX4);
1313
1314 //THROWN INFORMATION
1315 if(locMCReaction != NULL__null)
1316 {
1317 Fill_ThrownInfo(locTreeFillData, locMCReaction, locTaggedMCGenBeam, locMCThrownsToSave, locThrownIndexMap, locNumPIDThrown_FinalState, locPIDThrown_Decaying, locMCThrownMatching);
1318 locTreeFillData->Fill_Single<Bool_t>("IsThrownTopology", locIsThrownTopologyFlag);
1319 }
1320
1321 //INDEPENDENT BEAM PARTICLES
1322 if(locBeamUsedFlag)
1323 {
1324 //however, only fill with beam particles that are in the combos
1325 locTreeFillData->Fill_Single<UInt_t>("NumBeam", UInt_t(locBeamPhotons.size()));
1326 for(size_t loc_i = 0; loc_i < locBeamPhotons.size(); ++loc_i)
1327 Fill_BeamData(locTreeFillData, loc_i, locBeamPhotons[loc_i], locVertex, locMCThrownMatching);
1328 }
1329
1330 //INDEPENDENT CHARGED TRACKS
1331 locTreeFillData->Fill_Single<UInt_t>("NumChargedHypos", UInt_t(locChargedTrackHypotheses.size()));
1332 for(size_t loc_i = 0; loc_i < locChargedTrackHypotheses.size(); ++loc_i)
1333 Fill_ChargedHypo(locTreeFillData, loc_i, locChargedTrackHypotheses[loc_i], locMCThrownMatching, locThrownIndexMap, locDetectorMatches);
1334
1335 //INDEPENDENT NEUTRAL PARTICLES
1336 locTreeFillData->Fill_Single<UInt_t>("NumNeutralHypos", UInt_t(locNeutralParticleHypotheses.size()));
1337 for(size_t loc_i = 0; loc_i < locNeutralParticleHypotheses.size(); ++loc_i)
1338 Fill_NeutralHypo(locTreeFillData, loc_i, locNeutralParticleHypotheses[loc_i], locMCThrownMatching, locThrownIndexMap, locDetectorMatches);
1339
1340 //UNUSED TRACKS
1341 double locSumPMag_UnusedTracks = 0.0;
1342 TVector3 locSumP3_UnusedTracks;
1343 int locNumUnusedTracks = dAnalysisUtilities->Calc_Momentum_UnusedTracks(locEventLoop, locParticleCombos[0], locSumPMag_UnusedTracks, locSumP3_UnusedTracks);
1344 locTreeFillData->Fill_Single<UChar_t>("NumUnusedTracks", locNumUnusedTracks);
1345
1346 //COMBOS
1347 locTreeFillData->Fill_Single<UInt_t>("NumCombos", UInt_t(locParticleCombos.size()));
1348 for(size_t loc_i = 0; loc_i < locParticleCombos.size(); ++loc_i)
1349 {
1350 Fill_ComboData(locTreeFillData, locReaction, locParticleCombos[loc_i], loc_i, locObjectToArrayIndexMap);
1351
1352 //ENERGY OF UNUSED SHOWERS (access to event loop required)
1353 double locEnergy_UnusedShowers = 0.;
1354 double locEnergy_UnusedShowers_Quality = 0.;
1355 int locNumber_UnusedShowers_Quality = 0;
1356 int locNumber_UnusedShowers = dAnalysisUtilities->Calc_Energy_UnusedShowers(locEventLoop, locParticleCombos[loc_i], locEnergy_UnusedShowers, locNumber_UnusedShowers_Quality, locEnergy_UnusedShowers_Quality);
1357 locTreeFillData->Fill_Array<UChar_t>("NumUnusedShowers", locNumber_UnusedShowers, loc_i);
1358 locTreeFillData->Fill_Array<Float_t>("Energy_UnusedShowers", locEnergy_UnusedShowers, loc_i);
1359 locTreeFillData->Fill_Array<UChar_t>("NumUnusedShowers_Quality", locNumber_UnusedShowers_Quality, loc_i);
1360 locTreeFillData->Fill_Array<Float_t>("Energy_UnusedShowers_Quality", locEnergy_UnusedShowers_Quality, loc_i);
1361
1362 //MOMENTUM OF UNUSED TRACKS (access to event loop required)
1363 double locSumPMag_UnusedTracks = 0;
1364 TVector3 locSumP3_UnusedTracks;
1365 dAnalysisUtilities->Calc_Momentum_UnusedTracks(locEventLoop, locParticleCombos[loc_i], locSumPMag_UnusedTracks, locSumP3_UnusedTracks);
1366 locTreeFillData->Fill_Array<Float_t>("SumPMag_UnusedTracks", locSumPMag_UnusedTracks, loc_i);
1367 locTreeFillData->Fill_Array<TVector3>("SumP3_UnusedTracks", locSumP3_UnusedTracks, loc_i);
1368
1369 if(locMCReaction != NULL__null)
1370 {
1371 locTreeFillData->Fill_Array<Bool_t>("IsTrueCombo", locIsTrueComboFlags[loc_i], loc_i);
1372 locTreeFillData->Fill_Array<Bool_t>("IsBDTSignalCombo", locIsTrueComboFlags[loc_i], loc_i);
1373 }
1374 }
1375
1376 //Kinematic fit data (pulls and covariance matrices)
1377 Fill_KinFitData(locTreeFillData, locEventLoop, locReaction, locMCReaction, locMCThrownsToSave, locMCThrownMatching, locDetectorMatches, locBeamPhotons, locChargedTrackHypotheses, locNeutralParticleHypotheses, locParticleCombos);
1378
1379 //CUSTOM
1380 Fill_CustomBranches_DataTree(locTreeFillData, locEventLoop, locReaction, locMCReaction, locMCThrownsToSave, locMCThrownMatching, locDetectorMatches, locBeamPhotons, locChargedTrackHypotheses, locNeutralParticleHypotheses, locParticleCombos);
1381
1382 //FILL
1383 DTreeInterface* locTreeInterface = dTreeInterfaceMap.find(locReaction)->second;
1384 locTreeInterface->Fill(*locTreeFillData);
1385
1386 japp->RootUnLock();
1387
1388}
1389
1390vector<const DBeamPhoton*> DEventWriterROOT::Get_BeamPhotons(const deque<const DParticleCombo*>& locParticleCombos) const
1391{
1392 //however, only fill with beam particles that are in the combos
1393 set<const DBeamPhoton*> locBeamPhotonSet;
1394 vector<const DBeamPhoton*> locBeamPhotons;
1395 for(size_t loc_j = 0; loc_j < locParticleCombos.size(); ++loc_j)
1396 {
1397 const DParticleComboStep* locParticleComboStep = locParticleCombos[loc_j]->Get_ParticleComboStep(0);
1398 const DKinematicData* locKinematicData = locParticleComboStep->Get_InitialParticle_Measured();
1399 if(locKinematicData == NULL__null)
1400 continue;
1401 const DBeamPhoton* locBeamPhoton = dynamic_cast<const DBeamPhoton*>(locKinematicData);
1402 if(locBeamPhoton == NULL__null)
1403 continue;
1404 if(locBeamPhotonSet.find(locBeamPhoton) != locBeamPhotonSet.end())
1405 continue; //already included
1406 locBeamPhotonSet.insert(locBeamPhoton);
1407 locBeamPhotons.push_back(locBeamPhoton);
1408 }
1409
1410 return locBeamPhotons;
1411}
1412
1413vector<const DChargedTrackHypothesis*> DEventWriterROOT::Get_ChargedHypotheses(JEventLoop* locEventLoop) const
1414{
1415 //For default/preselect, save all
1416 //For combo, of new PIDs ONLY, save one of each for each track
1417 //save the one with the same RF bunch as the common bunch
1418
1419 vector<const DChargedTrack*> locChargedTracks;
1420 locEventLoop->Get(locChargedTracks, "Combo");
1421
1422 vector<const DChargedTrackHypothesis*> locChargedHyposToSave;
1423 for(auto& locChargedTrack : locChargedTracks)
1424 locChargedHyposToSave.insert(locChargedHyposToSave.end(), locChargedTrack->dChargedTrackHypotheses.begin(), locChargedTrack->dChargedTrackHypotheses.end());
1425
1426 return locChargedHyposToSave;
1427}
1428
1429vector<const DChargedTrackHypothesis*> DEventWriterROOT::Get_ChargedHypotheses_Used(JEventLoop* locEventLoop, const DReaction* locReaction, const deque<const DParticleCombo*>& locParticleCombos) const
1430{
1431 //get all hypos
1432 vector<const DChargedTrackHypothesis*> locAllHypos = Get_ChargedHypotheses(locEventLoop);
1433
1434 //get used time-based tracks
1435 set<const DTrackTimeBased*> locUsedTimeBasedTracks;
1436 for(auto& locCombo : locParticleCombos)
1437 {
1438 auto locChargedParticles = locCombo->Get_FinalParticles_Measured(locReaction, d_Charged);
1439 for(auto& locParticle : locChargedParticles)
1440 locUsedTimeBasedTracks.insert(static_cast<const DChargedTrackHypothesis*>(locParticle)->Get_TrackTimeBased());
1441 }
1442
1443 //loop through "all" hypos, removing those that weren't used
1444 for(auto locIterator = locAllHypos.begin(); locIterator != locAllHypos.end();)
1445 {
1446 const DTrackTimeBased* locTrackTimeBased = (*locIterator)->Get_TrackTimeBased();
1447 if(locUsedTimeBasedTracks.find(locTrackTimeBased) != locUsedTimeBasedTracks.end())
1448 ++locIterator;
1449 else
1450 locIterator = locAllHypos.erase(locIterator);
1451 }
1452
1453 return locAllHypos;
1454}
1455
1456vector<const DNeutralParticleHypothesis*> DEventWriterROOT::Get_NeutralHypotheses(JEventLoop* locEventLoop, const set<Particle_t>& locReactionPIDs) const
1457{
1458 //For default/preselect, save all
1459 //For combo, of new PIDs ONLY, save one of each for each shower
1460 //save the one with the same RF bunch as the common bunch
1461
1462 vector<const DNeutralParticle*> locNeutralParticles;
1463 locEventLoop->Get(locNeutralParticles, "Combo");
1464
1465 vector<const DNeutralParticleHypothesis*> locNeutralHyposToSave;
1466 for(auto& locNeutralParticle : locNeutralParticles)
1467 locNeutralHyposToSave.insert(locNeutralHyposToSave.end(), locNeutralParticle->dNeutralParticleHypotheses.begin(), locNeutralParticle->dNeutralParticleHypotheses.end());
1468
1469 return locNeutralHyposToSave;
1470}
1471
1472vector<const DNeutralParticleHypothesis*> DEventWriterROOT::Get_NeutralHypotheses_Used(JEventLoop* locEventLoop, const DReaction* locReaction, const set<Particle_t>& locReactionPIDs, const deque<const DParticleCombo*>& locParticleCombos) const
1473{
1474 //get all hypos
1475 vector<const DNeutralParticleHypothesis*> locAllHypos = Get_NeutralHypotheses(locEventLoop, locReactionPIDs);
1476
1477 //get used showers
1478 set<pair<const DNeutralShower*, Particle_t> > locUsedNeutralShowers;
1479 for(auto& locCombo : locParticleCombos)
1480 {
1481 auto locNeutralParticles = locCombo->Get_FinalParticles_Measured(locReaction, d_Neutral);
1482 for(auto& locParticle : locNeutralParticles)
1483 {
1484 const DNeutralShower* locNeutralShower = static_cast<const DNeutralParticleHypothesis*>(locParticle)->Get_NeutralShower();
1485 pair<const DNeutralShower*, Particle_t> locShowerPair(locNeutralShower, locParticle->PID());
1486 locUsedNeutralShowers.insert(locShowerPair);
1487 }
1488 }
1489
1490 //loop through "all" hypos, removing those that weren't used
1491 for(auto locIterator = locAllHypos.begin(); locIterator != locAllHypos.end();)
1492 {
1493 const DNeutralShower* locNeutralShower = (*locIterator)->Get_NeutralShower();
1494 pair<const DNeutralShower*, Particle_t> locShowerPair(locNeutralShower, (*locIterator)->PID());
1495 if(locUsedNeutralShowers.find(locShowerPair) == locUsedNeutralShowers.end())
1496 locIterator = locAllHypos.erase(locIterator);
1497 else
1498 ++locIterator;
1499 }
1500
1501 return locAllHypos;
1502}
1503
1504ULong64_t DEventWriterROOT::Calc_ParticleMultiplexID(Particle_t locPID) const
1505{
1506 int locPower = ParticleMultiplexPower(locPID);
1507 if(locPower == -1)
1508 return 0;
1509
1510 int locIsFinalStateInt = Is_FinalStateParticle(locPID);
1511 if(locPID == Pi0)
1512 locIsFinalStateInt = 1;
1513
1514 if(locIsFinalStateInt == 1) //decimal
1515 {
1516 ULong64_t locParticleMultiplexID = 1;
1517 for(int loc_i = 0; loc_i < locPower; ++loc_i)
1518 locParticleMultiplexID *= ULong64_t(10);
1519 return locParticleMultiplexID;
1520 }
1521 //decaying: binary
1522 return (ULong64_t(1) << ULong64_t(locPower)); //bit-shift
1523}
1524
1525void DEventWriterROOT::Compute_ThrownPIDInfo(const vector<const DMCThrown*>& locMCThrowns_FinalState, const vector<const DMCThrown*>& locMCThrowns_Decaying, ULong64_t& locNumPIDThrown_FinalState, ULong64_t& locPIDThrown_Decaying) const
1526{
1527 //THROWN PARTICLES BY PID
1528 locNumPIDThrown_FinalState = 0;
1529 for(size_t loc_i = 0; loc_i < locMCThrowns_FinalState.size(); ++loc_i) //final state
1530 {
1531 Particle_t locPID = locMCThrowns_FinalState[loc_i]->PID();
1532 ULong64_t locPIDMultiplexID = Calc_ParticleMultiplexID(locPID);
1533 if(locPIDMultiplexID == 0)
1534 continue; //unrecognized PID!!!
1535 unsigned int locCurrentNumParticles = (locNumPIDThrown_FinalState / locPIDMultiplexID) % ULong64_t(10);
1536 if(locCurrentNumParticles != 9)
1537 locNumPIDThrown_FinalState += locPIDMultiplexID;
1538 }
1539
1540 locPIDThrown_Decaying = 0;
1541 for(size_t loc_i = 0; loc_i < locMCThrowns_Decaying.size(); ++loc_i) //decaying
1542 {
1543 Particle_t locPID = locMCThrowns_Decaying[loc_i]->PID();
1544 ULong64_t locPIDMultiplexID = Calc_ParticleMultiplexID(locPID);
1545 if(locPIDMultiplexID == 0)
1546 continue; //unrecognized PID!!!
1547 if(locPID != Pi0)
1548 locPIDThrown_Decaying |= locPIDMultiplexID; //bit-wise or
1549 else //save pi0's as final state instead of decaying
1550 {
1551 unsigned int locCurrentNumParticles = (locNumPIDThrown_FinalState / locPIDMultiplexID) % ULong64_t(10);
1552 if(locCurrentNumParticles != 9)
1553 locNumPIDThrown_FinalState += locPIDMultiplexID;
1554 }
1555 }
1556}
1557
1558void DEventWriterROOT::Group_ThrownParticles(const vector<const DMCThrown*>& locMCThrowns_FinalState, const vector<const DMCThrown*>& locMCThrowns_Decaying, vector<const DMCThrown*>& locMCThrownsToSave, map<const DMCThrown*, unsigned int>& locThrownIndexMap) const
1559{
1560 locMCThrownsToSave.clear();
1561 locMCThrownsToSave.insert(locMCThrownsToSave.end(), locMCThrowns_FinalState.begin(), locMCThrowns_FinalState.end());
1562 locMCThrownsToSave.insert(locMCThrownsToSave.end(), locMCThrowns_Decaying.begin(), locMCThrowns_Decaying.end());
1563
1564 //create map of mcthrown to array index
1565 locThrownIndexMap.clear();
1566 for(size_t loc_i = 0; loc_i < locMCThrownsToSave.size(); ++loc_i)
1567 locThrownIndexMap[locMCThrownsToSave[loc_i]] = loc_i;
1568}
1569
1570void DEventWriterROOT::Fill_ThrownInfo(DTreeFillData* locTreeFillData, const DMCReaction* locMCReaction, const DBeamPhoton* locTaggedMCGenBeam, const vector<const DMCThrown*>& locMCThrowns, const map<const DMCThrown*, unsigned int>& locThrownIndexMap, ULong64_t locNumPIDThrown_FinalState, ULong64_t locPIDThrown_Decaying, const DMCThrownMatching* locMCThrownMatching) const
1571{
1572 //THIS MUST BE CALLED FROM WITHIN A LOCK, SO DO NOT PASS IN JEVENTLOOP! //TOO TEMPTING TO DO SOMETHING BAD
1573
1574 //WEIGHT
1575 locTreeFillData->Fill_Single<Float_t>("MCWeight", locMCReaction->weight);
1576
1577 //THROWN BEAM
1578 locTreeFillData->Fill_Single<Int_t>(Build_BranchName("ThrownBeam", "PID"), PDGtype(locMCReaction->beam.PID()));
1579 locTreeFillData->Fill_Single<Float_t>(Build_BranchName("ThrownBeam", "GeneratedEnergy"), locMCReaction->beam.energy());
1580
1581 DVector3 locThrownBeamX3 = locMCReaction->beam.position();
1582 TLorentzVector locThrownBeamTX4(locThrownBeamX3.X(), locThrownBeamX3.Y(), locThrownBeamX3.Z(), locMCReaction->beam.time());
1583 locTreeFillData->Fill_Single<TLorentzVector>(Build_BranchName("ThrownBeam", "X4"), locThrownBeamTX4);
1584
1585 DLorentzVector locThrownBeamP4 = locTaggedMCGenBeam->lorentzMomentum();
1586 TLorentzVector locThrownBeamTP4(locThrownBeamP4.Px(), locThrownBeamP4.Py(), locThrownBeamP4.Pz(), locThrownBeamP4.E());
1587 locTreeFillData->Fill_Single<TLorentzVector>(Build_BranchName("ThrownBeam", "P4"), locThrownBeamTP4);
1588
1589 //THROWN PRODUCTS
1590 locTreeFillData->Fill_Single<UInt_t>("NumThrown", locMCThrowns.size());
1591 for(size_t loc_i = 0; loc_i < locMCThrowns.size(); ++loc_i)
1592 Fill_ThrownParticleData(locTreeFillData, loc_i, locMCThrowns[loc_i], locThrownIndexMap, locMCThrownMatching);
1593
1594 //PID INFO
1595 locTreeFillData->Fill_Single<ULong64_t>("NumPIDThrown_FinalState", locNumPIDThrown_FinalState);
1596 locTreeFillData->Fill_Single<ULong64_t>("PIDThrown_Decaying", locPIDThrown_Decaying);
1597}
1598
1599void DEventWriterROOT::Fill_ThrownParticleData(DTreeFillData* locTreeFillData, unsigned int locArrayIndex, const DMCThrown* locMCThrown, const map<const DMCThrown*, unsigned int>& locThrownIndexMap, const DMCThrownMatching* locMCThrownMatching) const
1600{
1601 string locParticleBranchName = "Thrown";
1602
1603 //IDENTIFIERS
1604 int locParentIndex = -1; //e.g. photoproduced
1605 map<const DMCThrown*, unsigned int>::const_iterator locIterator;
1606 for(locIterator = locThrownIndexMap.begin(); locIterator != locThrownIndexMap.end(); ++locIterator)
1607 {
1608 if(locIterator->first->myid != locMCThrown->parentid)
1609 continue;
1610 locParentIndex = locIterator->second;
1611 break;
1612 }
1613 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "ParentIndex"), locParentIndex, locArrayIndex);
1614 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "PID"), locMCThrown->pdgtype, locArrayIndex);
1615
1616 //MATCHING
1617 if(locMCThrownMatching != NULL__null)
1618 {
1619 Int_t locMatchID = -1;
1620 double locMatchFOM = -1.0;
1621 if(ParticleCharge(locMCThrown->PID()) != 0)
1622 {
1623 const DChargedTrack* locChargedTrack = locMCThrownMatching->Get_MatchingChargedTrack(locMCThrown, locMatchFOM);
1624 if(locChargedTrack != NULL__null)
1625 locMatchID = locChargedTrack->candidateid;
1626 }
1627 else
1628 {
1629 //Can't use DNeutralShower JObject::id (must use dShowerID):
1630 //Matching done with default-tag showers, but pre-select showers are saved to tree: JObject::id's don't match
1631 const DNeutralShower* locNeutralShower = locMCThrownMatching->Get_MatchingNeutralShower(locMCThrown, locMatchFOM);
1632 if(locNeutralShower != NULL__null)
1633 locMatchID = locNeutralShower->dShowerID;
1634 }
1635 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "MatchID"), locMatchID, locArrayIndex);
1636 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "MatchFOM"), locMatchFOM, locArrayIndex);
1637 }
1638
1639 //KINEMATICS: THROWN //at the production vertex
1640 TLorentzVector locX4_Thrown(locMCThrown->position().X(), locMCThrown->position().Y(), locMCThrown->position().Z(), locMCThrown->time());
1641 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4"), locX4_Thrown, locArrayIndex);
1642 TLorentzVector locP4_Thrown(locMCThrown->momentum().X(), locMCThrown->momentum().Y(), locMCThrown->momentum().Z(), locMCThrown->energy());
1643 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4"), locP4_Thrown, locArrayIndex);
1644}
1645
1646void DEventWriterROOT::Fill_BeamData(DTreeFillData* locTreeFillData, unsigned int locArrayIndex, const DBeamPhoton* locBeamPhoton, const DVertex* locVertex, const DMCThrownMatching* locMCThrownMatching) const
1647{
1648 string locParticleBranchName = "Beam";
1649
1650 //IDENTIFIER
1651 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "PID"), PDGtype(locBeamPhoton->PID()), locArrayIndex);
1652
1653 //MATCHING
1654 if(locMCThrownMatching != NULL__null)
1655 {
1656 // Tag the thrown beam photon by comparing energy, time and counter
1657 const DBeamPhoton* locBeamPhotonTaggedMCGEN = locMCThrownMatching->Get_TaggedMCGENBeamPhoton();
1658 Bool_t locIsGeneratorFlag = kFALSE;
1659 if (locBeamPhotonTaggedMCGEN != NULL__null)
1660 locIsGeneratorFlag = (locBeamPhotonTaggedMCGEN->energy() == locBeamPhoton->energy() && locBeamPhotonTaggedMCGEN->dCounter == locBeamPhoton->dCounter && locBeamPhotonTaggedMCGEN->time() == locBeamPhoton->time()) ? kTRUE : kFALSE;
1661 locTreeFillData->Fill_Array<Bool_t>(Build_BranchName(locParticleBranchName, "IsGenerator"), locIsGeneratorFlag, locArrayIndex);
1662 }
1663
1664 //KINEMATICS: MEASURED
1665
1666 //use production vertex, propagate photon time
1667 DVector3 locTargetCenter = locBeamPhoton->position();
1668 DVector3 locProductionVertex = locVertex->dSpacetimeVertex.Vect();
1669 double locDeltaPath = (locProductionVertex - locTargetCenter).Mag();
1670 bool locDownstreamFlag = ((locProductionVertex.Z() - locTargetCenter.Z()) > 0.0);
1671 double locDeltaT = locDownstreamFlag ? locDeltaPath/29.9792458 : -1.0*locDeltaPath/29.9792458;
1672 double locTime = locBeamPhoton->time() + locDeltaT;
1673
1674 TLorentzVector locX4_Measured(locProductionVertex.X(), locProductionVertex.Y(), locProductionVertex.Z(), locTime);
1675 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Measured"), locX4_Measured, locArrayIndex);
1676
1677 DLorentzVector locDP4 = locBeamPhoton->lorentzMomentum();
1678 TLorentzVector locP4_Measured(locDP4.Px(), locDP4.Py(), locDP4.Pz(), locDP4.E());
1679 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_Measured"), locP4_Measured, locArrayIndex);
1680}
1681
1682void DEventWriterROOT::Fill_ChargedHypo(DTreeFillData* locTreeFillData, unsigned int locArrayIndex, const DChargedTrackHypothesis* locChargedTrackHypothesis, const DMCThrownMatching* locMCThrownMatching, const map<const DMCThrown*, unsigned int>& locThrownIndexMap, const DDetectorMatches* locDetectorMatches) const
1683{
1684 string locParticleBranchName = "ChargedHypo";
1685
1686 //ASSOCIATED OBJECTS
1687 auto locTrackTimeBased = locChargedTrackHypothesis->Get_TrackTimeBased();
1688
1689 const DBCALShower* locBCALShower = NULL__null;
1690 if(locChargedTrackHypothesis->Get_BCALShowerMatchParams() != NULL__null)
1691 locBCALShower = locChargedTrackHypothesis->Get_BCALShowerMatchParams()->dBCALShower;
1692
1693 const DFCALShower* locFCALShower = NULL__null;
1694 if(locChargedTrackHypothesis->Get_FCALShowerMatchParams() != NULL__null)
1695 locFCALShower = locChargedTrackHypothesis->Get_FCALShowerMatchParams()->dFCALShower;
1696
1697 //IDENTIFIERS
1698 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "TrackID"), locTrackTimeBased->candidateid, locArrayIndex);
1699 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "PID"), PDGtype(locChargedTrackHypothesis->PID()), locArrayIndex);
1700
1701 //MATCHING
1702 if(locMCThrownMatching != NULL__null)
1703 {
1704 Int_t locThrownIndex = -1;
1705 double locMatchFOM = 0.0;
1706 const DMCThrown* locMCThrown = locMCThrownMatching->Get_MatchingMCThrown(locChargedTrackHypothesis, locMatchFOM);
1707 if(locMCThrown != NULL__null)
1708 locThrownIndex = locThrownIndexMap.find(locMCThrown)->second;
1709 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "ThrownIndex"), locThrownIndex, locArrayIndex);
1710 }
1711
1712 //KINEMATICS: MEASURED
1713 DVector3 locPosition = locChargedTrackHypothesis->position();
1714 TLorentzVector locTX4_Measured(locPosition.X(), locPosition.Y(), locPosition.Z(), locChargedTrackHypothesis->time());
1715 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Measured"), locTX4_Measured, locArrayIndex);
1716
1717 DLorentzVector locDP4 = locChargedTrackHypothesis->lorentzMomentum();
1718 TLorentzVector locP4_Measured(locDP4.Px(), locDP4.Py(), locDP4.Pz(), locDP4.E());
1719 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_Measured"), locP4_Measured, locArrayIndex);
1720
1721 // Global PID
1722 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "PIDFOM"), locChargedTrackHypothesis->Get_FOM(), locArrayIndex);
1723
1724 //TRACKING INFO
1725 locTreeFillData->Fill_Array<UInt_t>(Build_BranchName(locParticleBranchName, "NDF_Tracking"), locTrackTimeBased->Ndof, locArrayIndex);
1726 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Tracking"), locTrackTimeBased->chisq, locArrayIndex);
1727 locTreeFillData->Fill_Array<UInt_t>(Build_BranchName(locParticleBranchName, "NDF_DCdEdx"), locChargedTrackHypothesis->Get_NDF_DCdEdx(), locArrayIndex);
1728 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_DCdEdx"), locChargedTrackHypothesis->Get_ChiSq_DCdEdx(), locArrayIndex);
1729 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_CDC"), locTrackTimeBased->ddEdx_CDC_amp, locArrayIndex);
1730 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_CDC_integral"), locTrackTimeBased->ddEdx_CDC, locArrayIndex);
1731 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_FDC"), locTrackTimeBased->ddEdx_FDC, locArrayIndex);
1732
1733 //HIT ENERGY
1734 double locTOFdEdx = (locChargedTrackHypothesis->Get_TOFHitMatchParams() != NULL__null) ? locChargedTrackHypothesis->Get_TOFHitMatchParams()->dEdx : 0.0;
1735 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_TOF"), locTOFdEdx, locArrayIndex);
1736 double locSCdEdx = (locChargedTrackHypothesis->Get_SCHitMatchParams() != NULL__null) ? locChargedTrackHypothesis->Get_SCHitMatchParams()->dEdx : 0.0;
1737 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "dEdx_ST"), locSCdEdx, locArrayIndex);
1738 double locBCALEnergy = (locBCALShower != NULL__null) ? locBCALShower->E : 0.0;
1739 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCAL"), locBCALEnergy, locArrayIndex);
1740 double locBCALPreshowerEnergy = (locBCALShower != NULL__null) ? locBCALShower->E_preshower : 0.0;
1741 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALPreshower"), locBCALPreshowerEnergy, locArrayIndex);
1742 if(BCAL_VERBOSE_OUTPUT) {
1743 double locBCALLayer2Energy = (locBCALShower != NULL__null) ? locBCALShower->E_L2 : 0.0;
1744 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer2"), locBCALLayer2Energy, locArrayIndex);
1745 double locBCALLayer3Energy = (locBCALShower != NULL__null) ? locBCALShower->E_L3 : 0.0;
1746 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer3"), locBCALLayer3Energy, locArrayIndex);
1747 double locBCALLayer4Energy = (locBCALShower != NULL__null) ? locBCALShower->E_L4 : 0.0;
1748 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer4"), locBCALLayer4Energy, locArrayIndex);
1749 }
1750
1751 double locFCALEnergy = (locFCALShower != NULL__null) ? locFCALShower->getEnergy() : 0.0;
1752 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_FCAL"), locFCALEnergy, locArrayIndex);
1753
1754 //double locCCALEnergy = (locCCALShower != NULL) ? locCCALShower->getEnergy() : 0.0;
1755 //locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_CCAL"), locCCALEnergy, locArrayIndex);
1756
1757 //SHOWER PROPERTIES
1758 double locSigLongBCAL = (locBCALShower != NULL__null) ? locBCALShower->sigLong : 0.0;
1759 double locSigThetaBCAL = (locBCALShower != NULL__null) ? locBCALShower->sigTheta : 0.0;
1760 double locSigTransBCAL = (locBCALShower != NULL__null) ? locBCALShower->sigTrans : 0.0;
1761 double locRMSTimeBCAL = (locBCALShower != NULL__null) ? locBCALShower->rmsTime : 0.0;
1762 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SigLong_BCAL"), locSigLongBCAL, locArrayIndex);
1763 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SigTheta_BCAL"), locSigThetaBCAL, locArrayIndex);
1764 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SigTrans_BCAL"), locSigTransBCAL, locArrayIndex);
1765 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "RMSTime_BCAL"), locRMSTimeBCAL, locArrayIndex);
1766
1767 double locE1E9FCAL = (locFCALShower != NULL__null) ? locFCALShower->getE1E9() : 0.0;
1768 double locE9E25FCAL = (locFCALShower != NULL__null) ? locFCALShower->getE9E25() : 0.0;
1769 double locSumUFCAL = (locFCALShower != NULL__null) ? locFCALShower->getSumU() : 0.0;
1770 double locSumVFCAL = (locFCALShower != NULL__null) ? locFCALShower->getSumV() : 0.0;
1771 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "E1E9_FCAL"), locE1E9FCAL, locArrayIndex);
1772 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "E9E25_FCAL"), locE9E25FCAL, locArrayIndex);
1773 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SumU_FCAL"), locSumUFCAL, locArrayIndex);
1774 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SumV_FCAL"), locSumVFCAL, locArrayIndex);
1775
1776 //TIMING INFO
1777 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "HitTime"), locChargedTrackHypothesis->t1(), locArrayIndex);
1778 double locStartTimeError = locChargedTrackHypothesis->t0_err();
1779 double locRFDeltaTVariance = (*locChargedTrackHypothesis->errorMatrix())(6, 6) + locStartTimeError*locStartTimeError;
1780 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "RFDeltaTVar"), locRFDeltaTVariance, locArrayIndex);
1781
1782 //MEASURED PID INFO
1783 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing"), locChargedTrackHypothesis->measuredBeta(), locArrayIndex);
1784 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing"), locChargedTrackHypothesis->Get_ChiSq_Timing(), locArrayIndex);
1785 locTreeFillData->Fill_Array<UInt_t>(Build_BranchName(locParticleBranchName, "NDF_Timing"), locChargedTrackHypothesis->Get_NDF_Timing(), locArrayIndex);
1786
1787 //SHOWER MATCHING: BCAL
1788 double locTrackBCAL_DeltaPhi = 999.0, locTrackBCAL_DeltaZ = 999.0;
1789 if(locChargedTrackHypothesis->Get_BCALShowerMatchParams() != NULL__null)
1790 {
1791 locTrackBCAL_DeltaPhi = locChargedTrackHypothesis->Get_BCALShowerMatchParams()->dDeltaPhiToShower;
1792 locTrackBCAL_DeltaZ = locChargedTrackHypothesis->Get_BCALShowerMatchParams()->dDeltaZToShower;
1793 }
1794 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "TrackBCAL_DeltaPhi"), locTrackBCAL_DeltaPhi, locArrayIndex);
1795 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "TrackBCAL_DeltaZ"), locTrackBCAL_DeltaZ, locArrayIndex);
1796
1797 //SHOWER MATCHING: FCAL
1798 double locDOCAToShower_FCAL = 999.0;
1799 if(locChargedTrackHypothesis->Get_FCALShowerMatchParams() != NULL__null)
1800 locDOCAToShower_FCAL = locChargedTrackHypothesis->Get_FCALShowerMatchParams()->dDOCAToShower;
1801 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "TrackFCAL_DOCA"), locDOCAToShower_FCAL, locArrayIndex);
1802
1803 // DIRC
1804 if(DIRC_OUTPUT) {
1805 int locDIRCNumPhotons = 0;
1806 double locDIRCExtrapolatedX = 999;
1807 double locDIRCExtrapolatedY = 999;
1808 double locDIRCThetaC = 999.;
1809 double locDIRCLele = 999.;
1810 double locDIRCLpi = 999.;
1811 double locDIRCLk = 999.;
1812 double locDIRCLp = 999.;
1813 auto locDIRCMatchParams = locChargedTrackHypothesis->Get_DIRCMatchParams();
1814 if(locDIRCMatchParams != NULL__null) {
1815 locDIRCExtrapolatedX = locDIRCMatchParams->dExtrapolatedPos.X();
1816 locDIRCExtrapolatedY = locDIRCMatchParams->dExtrapolatedPos.Y();
1817 locDIRCNumPhotons = locDIRCMatchParams->dNPhotons;
1818 locDIRCThetaC = locDIRCMatchParams->dThetaC;
1819 locDIRCLele = locDIRCMatchParams->dLikelihoodElectron;
1820 locDIRCLpi = locDIRCMatchParams->dLikelihoodPion;
1821 locDIRCLk = locDIRCMatchParams->dLikelihoodKaon;
1822 locDIRCLp = locDIRCMatchParams->dLikelihoodProton;
1823 }
1824 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "NumPhotons_DIRC"), locDIRCNumPhotons, locArrayIndex);
1825 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ExtrapolatedX_DIRC"), locDIRCExtrapolatedX, locArrayIndex);
1826 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ExtrapolatedY_DIRC"), locDIRCExtrapolatedY, locArrayIndex);
1827 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ThetaC_DIRC"), locDIRCThetaC, locArrayIndex);
1828 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Lele_DIRC"), locDIRCLele, locArrayIndex);
1829 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Lpi_DIRC"), locDIRCLpi, locArrayIndex);
1830 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Lk_DIRC"), locDIRCLk, locArrayIndex);
1831 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Lp_DIRC"), locDIRCLp, locArrayIndex);
1832 }
1833}
1834
1835void DEventWriterROOT::Fill_NeutralHypo(DTreeFillData* locTreeFillData, unsigned int locArrayIndex, const DNeutralParticleHypothesis* locNeutralParticleHypothesis, const DMCThrownMatching* locMCThrownMatching, const map<const DMCThrown*, unsigned int>& locThrownIndexMap, const DDetectorMatches* locDetectorMatches) const
1836{
1837 string locParticleBranchName = "NeutralHypo";
1838 const DNeutralShower* locNeutralShower = locNeutralParticleHypothesis->Get_NeutralShower();
1839
1840 //ASSOCIATED OBJECTS
1841 const DBCALShower* locBCALShower = NULL__null;
1842 locNeutralShower->GetSingle(locBCALShower);
1843 const DFCALShower* locFCALShower = NULL__null;
1844 locNeutralShower->GetSingle(locFCALShower);
1845 const DCCALShower* locCCALShower = NULL__null;
1846 locNeutralShower->GetSingle(locCCALShower);
1847
1848 //IDENTIFIERS
1849 Particle_t locPID = locNeutralParticleHypothesis->PID();
1850 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "NeutralID"), locNeutralShower->dShowerID, locArrayIndex);
1851 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "PID"), PDGtype(locPID), locArrayIndex);
1852
1853 //MATCHING
1854 if(locMCThrownMatching != NULL__null)
1855 {
1856 Int_t locThrownIndex = -1;
1857 double locMatchFOM = 0.0;
1858 const DMCThrown* locMCThrown = locMCThrownMatching->Get_MatchingMCThrown(locNeutralParticleHypothesis, locMatchFOM);
1859 if(locMCThrown != NULL__null)
1860 locThrownIndex = locThrownIndexMap.find(locMCThrown)->second;
1861 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "ThrownIndex"), locThrownIndex, locArrayIndex);
1862 }
1863
1864 //KINEMATICS: MEASURED
1865 DVector3 locPosition = locNeutralParticleHypothesis->position();
1866 TLorentzVector locX4_Measured(locPosition.X(), locPosition.Y(), locPosition.Z(), locNeutralParticleHypothesis->time());
1867 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Measured"), locX4_Measured, locArrayIndex);
1868
1869 DLorentzVector locDP4 = locNeutralParticleHypothesis->lorentzMomentum();
1870 TLorentzVector locP4_Measured(locDP4.Px(), locDP4.Py(), locDP4.Pz(), locDP4.E());
1871 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_Measured"), locP4_Measured, locArrayIndex);
1872
1873 //MEASURED PID INFO
1874 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing"), locNeutralParticleHypothesis->measuredBeta(), locArrayIndex);
1875 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing"), locNeutralParticleHypothesis->Get_ChiSq(), locArrayIndex);
1876 locTreeFillData->Fill_Array<UInt_t>(Build_BranchName(locParticleBranchName, "NDF_Timing"), locNeutralParticleHypothesis->Get_NDF(), locArrayIndex);
1877 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ShowerQuality"), locNeutralShower->dQuality, locArrayIndex);
1878
1879 //SHOWER ENERGY
1880 DetectorSystem_t locDetector = locNeutralShower->dDetectorSystem;
1881 double locBCALEnergy = (locDetector == SYS_BCAL) ? locNeutralShower->dEnergy : 0.0;
1882 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCAL"), locBCALEnergy, locArrayIndex);
1883 double locBCALPreshowerEnergy = (locDetector == SYS_BCAL) ? static_cast<const DBCALShower*>(locNeutralShower->dBCALFCALShower)->E_preshower : 0.0;
1884 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALPreshower"), locBCALPreshowerEnergy, locArrayIndex);
1885 if(BCAL_VERBOSE_OUTPUT) {
1886 double locBCALLayer2Energy = (locBCALShower != NULL__null) ? locBCALShower->E_L2 : 0.0;
1887 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer2"), locBCALLayer2Energy, locArrayIndex);
1888 double locBCALLayer3Energy = (locBCALShower != NULL__null) ? locBCALShower->E_L3 : 0.0;
1889 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer3"), locBCALLayer3Energy, locArrayIndex);
1890 double locBCALLayer4Energy = (locBCALShower != NULL__null) ? locBCALShower->E_L4 : 0.0;
1891 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_BCALLayer4"), locBCALLayer4Energy, locArrayIndex);
1892 }
1893
1894 double locFCALEnergy = (locDetector == SYS_FCAL) ? locNeutralShower->dEnergy : 0.0;
1895 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_FCAL"), locFCALEnergy, locArrayIndex);
1896
1897 double locCCALEnergy = (locDetector == SYS_CCAL) ? locNeutralShower->dEnergy : 0.0;
1898 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Energy_CCAL"), locCCALEnergy, locArrayIndex);
1899
1900 //SHOWER POSITION
1901 DLorentzVector locHitDX4 = locNeutralShower->dSpacetimeVertex;
1902 TLorentzVector locTX4_Shower(locHitDX4.X(), locHitDX4.Y(), locHitDX4.Z(), locHitDX4.T());
1903 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Shower"), locTX4_Shower, locArrayIndex);
1904
1905 //SHOWER PROPERTIES
1906 double locSigLongBCAL = (locBCALShower != NULL__null) ? locBCALShower->sigLong : 0.0;
1907 double locSigThetaBCAL = (locBCALShower != NULL__null) ? locBCALShower->sigTheta : 0.0;
1908 double locSigTransBCAL = (locBCALShower != NULL__null) ? locBCALShower->sigTrans : 0.0;
1909 double locRMSTimeBCAL = (locBCALShower != NULL__null) ? locBCALShower->rmsTime : 0.0;
1910 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SigLong_BCAL"), locSigLongBCAL, locArrayIndex);
1911 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SigTheta_BCAL"), locSigThetaBCAL, locArrayIndex);
1912 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SigTrans_BCAL"), locSigTransBCAL, locArrayIndex);
1913 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "RMSTime_BCAL"), locRMSTimeBCAL, locArrayIndex);
1914
1915 if(FCAL_VERBOSE_OUTPUT) {
1916 double locE1E9FCAL = (locFCALShower != NULL__null) ? locFCALShower->getE1E9() : 0.0;
1917 double locE9E25FCAL = (locFCALShower != NULL__null) ? locFCALShower->getE9E25() : 0.0;
1918 double locSumUFCAL = (locFCALShower != NULL__null) ? locFCALShower->getSumU() : 0.0;
1919 double locSumVFCAL = (locFCALShower != NULL__null) ? locFCALShower->getSumV() : 0.0;
1920 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "E1E9_FCAL"), locE1E9FCAL, locArrayIndex);
1921 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "E9E25_FCAL"), locE9E25FCAL, locArrayIndex);
1922 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SumU_FCAL"), locSumUFCAL, locArrayIndex);
1923 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "SumV_FCAL"), locSumVFCAL, locArrayIndex);
1924 }
1925
1926 //Track DOCA to Shower - BCAL
1927 double locNearestTrackBCALDeltaPhi = 999.0, locNearestTrackBCALDeltaZ = 999.0;
1928 if(locBCALShower != NULL__null)
1929 {
1930 if(!locDetectorMatches->Get_DistanceToNearestTrack(locBCALShower, locNearestTrackBCALDeltaPhi, locNearestTrackBCALDeltaZ))
1931 {
1932 locNearestTrackBCALDeltaPhi = 999.0;
1933 locNearestTrackBCALDeltaZ = 999.0;
1934 }
1935 else if((locNearestTrackBCALDeltaPhi > 999.0) || (locNearestTrackBCALDeltaZ > 999.0))
1936 {
1937 locNearestTrackBCALDeltaPhi = 999.0;
1938 locNearestTrackBCALDeltaZ = 999.0;
1939 }
1940 }
1941 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "TrackBCAL_DeltaPhi"), locNearestTrackBCALDeltaPhi, locArrayIndex);
1942 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "TrackBCAL_DeltaZ"), locNearestTrackBCALDeltaZ, locArrayIndex);
1943
1944 //Track DOCA to Shower - FCAL
1945 double locDistanceToNearestTrack_FCAL = 999.0;
1946 if(locFCALShower != NULL__null)
1947 {
1948 if(!locDetectorMatches->Get_DistanceToNearestTrack(locFCALShower, locDistanceToNearestTrack_FCAL))
1949 locDistanceToNearestTrack_FCAL = 999.0;
1950 if(locDistanceToNearestTrack_FCAL > 999.0)
1951 locDistanceToNearestTrack_FCAL = 999.0;
1952 }
1953 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "TrackFCAL_DOCA"), locDistanceToNearestTrack_FCAL, locArrayIndex);
1954
1955 //PHOTON PID INFO
1956 double locStartTimeError = locNeutralParticleHypothesis->t0_err();
1957 double locPhotonRFDeltaTVar = (*locNeutralParticleHypothesis->errorMatrix())(6, 6) + locStartTimeError*locStartTimeError;
1958 if(locPID != Gamma)
1959 locPhotonRFDeltaTVar = 0.0;
1960 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "PhotonRFDeltaTVar"), locPhotonRFDeltaTVar, locArrayIndex);
1961}
1962
1963void DEventWriterROOT::Fill_ComboData(DTreeFillData* locTreeFillData, const DReaction* locReaction, const DParticleCombo* locParticleCombo, unsigned int locComboIndex, const map<pair<oid_t, Particle_t>, size_t>& locObjectToArrayIndexMap) const
1964{
1965 //MAIN CLASSES
1966 const DKinFitResults* locKinFitResults = locParticleCombo->Get_KinFitResults();
1967 const DEventRFBunch* locEventRFBunch = locParticleCombo->Get_EventRFBunch();
1968
1969 //IS COMBO CUT
1970 locTreeFillData->Fill_Array<Bool_t>("IsComboCut", kFALSE, locComboIndex);
1971
1972 //RF INFO
1973 double locRFTime = (locEventRFBunch != NULL__null) ? locEventRFBunch->dTime : numeric_limits<double>::quiet_NaN();
1974 locTreeFillData->Fill_Array<Float_t>("RFTime_Measured", locRFTime, locComboIndex);
1975
1976 //KINFIT INFO
1977 DKinFitType locKinFitType = locReaction->Get_KinFitType();
1978 bool locKinFitFlag = (locKinFitType != d_NoFit);
1979 if(locKinFitFlag)
1980 {
1981 if(locKinFitResults != NULL__null)
1982 {
1983 locTreeFillData->Fill_Array<Float_t>("ChiSq_KinFit", locKinFitResults->Get_ChiSq(), locComboIndex);
1984 locTreeFillData->Fill_Array<UInt_t>("NDF_KinFit", locKinFitResults->Get_NDF(), locComboIndex);
1985 if((locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndSpacetimeFit))
1986 {
1987 double locRFTime_KinFit = -9.9E9; //NOT IMPLEMENTED YET
1988 locTreeFillData->Fill_Array<Float_t>("RFTime_KinFit", locRFTime_KinFit, locComboIndex);
1989 }
1990 }
1991 else
1992 {
1993 locTreeFillData->Fill_Array<Float_t>("ChiSq_KinFit", 0.0, locComboIndex);
1994 locTreeFillData->Fill_Array<UInt_t>("NDF_KinFit", 0, locComboIndex);
1995 if((locKinFitType == d_SpacetimeFit) || (locKinFitType == d_P4AndSpacetimeFit))
1996 locTreeFillData->Fill_Array<Float_t>("RFTime_KinFit", -9.9E9, locComboIndex);
1997 }
1998 }
1999
2000 //STEP DATA
2001 for(size_t loc_i = 0; loc_i < locParticleCombo->Get_NumParticleComboSteps(); ++loc_i)
2002 Fill_ComboStepData(locTreeFillData, locReaction, locParticleCombo, loc_i, locComboIndex, locKinFitType, locObjectToArrayIndexMap);
2003}
2004
2005void DEventWriterROOT::Fill_ComboStepData(DTreeFillData* locTreeFillData, const DReaction* locReaction, const DParticleCombo* locParticleCombo, unsigned int locStepIndex, unsigned int locComboIndex, DKinFitType locKinFitType, const map<pair<oid_t, Particle_t>, size_t>& locObjectToArrayIndexMap) const
2006{
2007 auto locReactionVertexInfo = dVertexInfoMap.find(locReaction)->second;
2008 auto locReactionStep = locReaction->Get_ReactionStep(locStepIndex);
2009 const TList* locUserInfo = dTreeInterfaceMap.find(locReaction)->second->Get_UserInfo(); //No Lock! But this should be unchanging at this point anyway
2010 const TMap* locPositionToNameMap = (TMap*)locUserInfo->FindObject("PositionToNameMap");
2011
2012 auto locParticleComboStep = locParticleCombo->Get_ParticleComboStep(locStepIndex);
2013 DLorentzVector locStepX4 = locParticleComboStep->Get_SpacetimeVertex();
2014 TLorentzVector locStepTX4(locStepX4.X(), locStepX4.Y(), locStepX4.Z(), locStepX4.T());
2015
2016 //beam & production vertex
2017 Particle_t locInitialPID = locReactionStep->Get_InitialPID();
2018 const DKinematicData* locInitialParticle = locParticleComboStep->Get_InitialParticle();
2019 const DBeamPhoton* locBeamPhoton = dynamic_cast<const DBeamPhoton*>(locInitialParticle);
2020 if(locBeamPhoton != NULL__null)
2021 {
2022 const DKinematicData* locInitParticleMeasured = locParticleComboStep->Get_InitialParticle_Measured();
2023 const DBeamPhoton* locMeasuredBeamPhoton = dynamic_cast<const DBeamPhoton*>(locInitParticleMeasured);
2024
2025 //get array index
2026 pair<oid_t, Particle_t> locBeamPair(locMeasuredBeamPhoton->id, locMeasuredBeamPhoton->PID());
2027 size_t locBeamIndex = locObjectToArrayIndexMap.find(locBeamPair)->second;
2028
2029 Fill_ComboBeamData(locTreeFillData, locComboIndex, locBeamPhoton, locBeamIndex, locKinFitType);
2030 }
2031 else //decaying
2032 {
2033 //get the branch name
2034 ostringstream locPositionStream;
2035 locPositionStream << locStepIndex << "_-1";
2036 TObjString* locObjString = (TObjString*)locPositionToNameMap->GetValue(locPositionStream.str().c_str());
2037 string locParticleBranchName = (const char*)(locObjString->GetString());
2038
2039 auto locP4FitFlag = ((locKinFitType == d_P4Fit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit));
2040 if(IsFixedMass(locInitialPID) && locReactionStep->Get_KinFitConstrainInitMassFlag() && locP4FitFlag)
2041 {
2042 TLorentzVector locDecayP4;
2043 if(locInitialParticle == NULL__null)
2044 {
2045 //fit failed to converge, calc from other particles
2046 DLorentzVector locDecayDP4 = dAnalysisUtilities->Calc_FinalStateP4(locReaction, locParticleCombo, locStepIndex, false);
2047 locDecayDP4.SetE(sqrt(locDecayDP4.Vect().Mag2() + ParticleMass(locInitialPID)*ParticleMass(locInitialPID)));
2048 locDecayP4.SetPxPyPzE(locDecayDP4.Px(), locDecayDP4.Py(), locDecayDP4.Pz(), locDecayDP4.E());
2049 }
2050 else
2051 locDecayP4.SetPxPyPzE(locInitialParticle->momentum().X(), locInitialParticle->momentum().Y(), locInitialParticle->momentum().Z(), locInitialParticle->energy());
2052 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), locDecayP4, locComboIndex);
2053 }
2054
2055 if((locStepIndex == 0) || IsDetachedVertex(locInitialPID))
2056 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4"), locStepTX4, locComboIndex);
2057
2058 auto locStepVertexInfo = locReactionVertexInfo->Get_StepVertexInfo(locStepIndex);
2059 auto locParentVertexInfo = locStepVertexInfo->Get_ParentVertexInfo();
2060 auto locVertexKinFitFlag = ((locKinFitType != d_P4Fit) && (locKinFitType != d_NoFit));
2061 if(IsDetachedVertex(locInitialPID) && locVertexKinFitFlag && (locParentVertexInfo != nullptr) && locStepVertexInfo->Get_FittableVertexFlag() && locParentVertexInfo->Get_FittableVertexFlag())
2062 {
2063 auto locKinFitParticle = locParticleComboStep->Get_InitialKinFitParticle();
2064 auto locPathLengthSigma = locKinFitParticle->Get_PathLengthUncertainty();
2065 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "PathLengthSigma"), locPathLengthSigma, locComboIndex);
2066 }
2067 }
2068
2069 //final state particles
2070 for(size_t loc_i = 0; loc_i < locParticleComboStep->Get_NumFinalParticles(); ++loc_i)
2071 {
2072 Particle_t locPID = locReactionStep->Get_FinalPID(loc_i);
2073 const DKinematicData* locKinematicData = locParticleComboStep->Get_FinalParticle(loc_i);
2074 const DKinematicData* locKinematicData_Measured = locParticleComboStep->Get_FinalParticle_Measured(loc_i);
2075
2076 //decaying particle
2077 if(DAnalysis::Get_DecayStepIndex(locReaction, locStepIndex, loc_i) >= 0)
2078 continue;
2079
2080 //get the branch name
2081 ostringstream locPositionStream;
2082 locPositionStream << locStepIndex << "_" << loc_i;
2083 TObjString* locObjString = (TObjString*)locPositionToNameMap->GetValue(locPositionStream.str().c_str());
2084 string locParticleBranchName = (const char*)(locObjString->GetString());
2085
2086 //missing particle
2087 if(locReactionStep->Get_MissingParticleIndex() == int(loc_i))
2088 {
2089 if((locKinFitType == d_P4Fit) || (locKinFitType == d_P4AndVertexFit) || (locKinFitType == d_P4AndSpacetimeFit))
2090 {
2091 TLorentzVector locMissingP4;
2092 if(locKinematicData == NULL__null)
2093 {
2094 //fit failed to converge, calc from other particles
2095 DLorentzVector locMissingDP4 = dAnalysisUtilities->Calc_MissingP4(locReaction, locParticleCombo, false);
2096 locMissingDP4.SetE(sqrt(locMissingDP4.Vect().Mag2() + ParticleMass(locPID)*ParticleMass(locPID)));
2097 locMissingP4.SetPxPyPzE(locMissingDP4.Px(), locMissingDP4.Py(), locMissingDP4.Pz(), locMissingDP4.E());
2098 }
2099 else
2100 locMissingP4.SetPxPyPzE(locKinematicData->momentum().X(), locKinematicData->momentum().Y(), locKinematicData->momentum().Z(), locKinematicData->energy());
2101
2102 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), locMissingP4, locComboIndex);
2103 }
2104 continue;
2105 }
2106
2107 //fill the data
2108 if(ParticleCharge(locPID) == 0)
2109 {
2110 const DNeutralParticleHypothesis* locNeutralHypo = dynamic_cast<const DNeutralParticleHypothesis*>(locKinematicData);
2111 const DNeutralParticleHypothesis* locMeasuredNeutralHypo = dynamic_cast<const DNeutralParticleHypothesis*>(locKinematicData_Measured);
2112
2113 //get array index
2114 const DNeutralShower* locNeutralShower = locNeutralHypo->Get_NeutralShower();
2115 pair<oid_t, Particle_t> locNeutralPair(locNeutralShower->id, locNeutralHypo->PID());
2116 size_t locNeutralIndex = locObjectToArrayIndexMap.find(locNeutralPair)->second;
2117
2118 Fill_ComboNeutralData(locTreeFillData, locComboIndex, locParticleBranchName, locMeasuredNeutralHypo, locNeutralHypo, locNeutralIndex, locKinFitType);
2119 }
2120 else
2121 {
2122 const DChargedTrackHypothesis* locChargedHypo = dynamic_cast<const DChargedTrackHypothesis*>(locKinematicData);
2123 const DChargedTrackHypothesis* locMeasuredChargedHypo = dynamic_cast<const DChargedTrackHypothesis*>(locKinematicData_Measured);
2124
2125 //get array index
2126 const DTrackTimeBased* locTrackTimeBased = locChargedHypo->Get_TrackTimeBased();
2127 pair<oid_t, Particle_t> locTrackPair(locTrackTimeBased->id, locChargedHypo->PID());
2128 size_t locChargedIndex = locObjectToArrayIndexMap.find(locTrackPair)->second;
2129
2130 Fill_ComboChargedData(locTreeFillData, locComboIndex, locParticleBranchName, locMeasuredChargedHypo, locChargedHypo, locChargedIndex, locKinFitType);
2131 }
2132 }
2133}
2134
2135void DEventWriterROOT::Fill_ComboBeamData(DTreeFillData* locTreeFillData, unsigned int locComboIndex, const DBeamPhoton* locBeamPhoton, size_t locBeamIndex, DKinFitType locKinFitType) const
2136{
2137 string locParticleBranchName = "ComboBeam";
2138
2139 //IDENTIFIER
2140 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "BeamIndex"), locBeamIndex, locComboIndex);
2141
2142 //KINEMATICS: KINFIT
2143 if(locKinFitType != d_NoFit)
2144 {
2145 if(locKinFitType != d_P4Fit)
2146 {
2147 DVector3 locPosition = locBeamPhoton->position();
2148 TLorentzVector locX4_KinFit(locPosition.X(), locPosition.Y(), locPosition.Z(), locBeamPhoton->time());
2149 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_KinFit"), locX4_KinFit, locComboIndex);
2150 }
2151
2152 //if charged, bends in b-field, update p4 when vertex changes
2153 if(((locKinFitType != d_VertexFit) && (locKinFitType != d_SpacetimeFit)) || (ParticleCharge(locBeamPhoton->PID()) != 0))
2154 {
2155 DLorentzVector locDP4 = locBeamPhoton->lorentzMomentum();
2156 TLorentzVector locP4_KinFit(locDP4.Px(), locDP4.Py(), locDP4.Pz(), locDP4.E());
2157 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), locP4_KinFit, locComboIndex);
2158 }
2159 }
2160}
2161
2162void DEventWriterROOT::Fill_ComboChargedData(DTreeFillData* locTreeFillData, unsigned int locComboIndex, string locParticleBranchName, const DChargedTrackHypothesis* locMeasuredChargedHypo, const DChargedTrackHypothesis* locChargedHypo, size_t locChargedIndex, DKinFitType locKinFitType) const
2163{
2164 //IDENTIFIER
2165 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "ChargedIndex"), locChargedIndex, locComboIndex);
2166
2167 //MEASURED PID
2168 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing_Measured"), locMeasuredChargedHypo->measuredBeta(), locComboIndex);
2169 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing_Measured"), locMeasuredChargedHypo->Get_ChiSq_Timing(), locComboIndex);
2170
2171 //KINFIT PID
2172 if((locKinFitType != d_NoFit) && (locKinFitType != d_SpacetimeFit) && (locKinFitType != d_P4AndSpacetimeFit))
2173 {
2174 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing_KinFit"), locChargedHypo->measuredBeta(), locComboIndex);
2175 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing_KinFit"), locChargedHypo->Get_ChiSq_Timing(), locComboIndex);
2176 }
2177
2178 //KINFIT
2179 if(locKinFitType != d_NoFit)
2180 {
2181 //KINEMATICS
2182 if(locKinFitType != d_P4Fit)
2183 {
2184 DVector3 locPosition = locChargedHypo->position();
2185 TLorentzVector locX4_KinFit(locPosition.X(), locPosition.Y(), locPosition.Z(), locChargedHypo->time());
2186 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_KinFit"), locX4_KinFit, locComboIndex);
2187 }
2188
2189 //update even if vertex-only fit, because charged momentum propagated through b-field
2190 DLorentzVector locDP4 = locChargedHypo->lorentzMomentum();
2191 TLorentzVector locP4_KinFit(locDP4.Px(), locDP4.Py(), locDP4.Pz(), locDP4.E());
2192 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), locP4_KinFit, locComboIndex);
2193 }
2194}
2195
2196void DEventWriterROOT::Fill_ComboNeutralData(DTreeFillData* locTreeFillData, unsigned int locComboIndex, string locParticleBranchName, const DNeutralParticleHypothesis* locMeasuredNeutralHypo, const DNeutralParticleHypothesis* locNeutralHypo, size_t locNeutralIndex, DKinFitType locKinFitType) const
2197{
2198 //IDENTIFIER
2199 locTreeFillData->Fill_Array<Int_t>(Build_BranchName(locParticleBranchName, "NeutralIndex"), locNeutralIndex, locComboIndex);
2200
2201 //KINEMATICS: MEASURED
2202 DVector3 locPosition = locMeasuredNeutralHypo->position();
2203 TLorentzVector locX4_Measured(locPosition.X(), locPosition.Y(), locPosition.Z(), locMeasuredNeutralHypo->time());
2204 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_Measured"), locX4_Measured, locComboIndex);
2205
2206 DLorentzVector locDP4 = locMeasuredNeutralHypo->lorentzMomentum();
2207 TLorentzVector locP4_Measured(locDP4.Px(), locDP4.Py(), locDP4.Pz(), locDP4.E());
2208 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_Measured"), locP4_Measured, locComboIndex);
2209
2210 //MEASURED PID INFO
2211 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing_Measured"), locMeasuredNeutralHypo->measuredBeta(), locComboIndex);
2212 if(locParticleBranchName.substr(0, 6) == "Photon")
2213 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing_Measured"), locMeasuredNeutralHypo->Get_ChiSq(), locComboIndex);
2214
2215 //KINFIT PID INFO
2216 if((locKinFitType != d_NoFit) && (locKinFitType != d_SpacetimeFit) && (locKinFitType != d_P4AndSpacetimeFit))
2217 {
2218 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "Beta_Timing_KinFit"), locNeutralHypo->measuredBeta(), locComboIndex);
2219 if(locParticleBranchName.substr(0, 6) == "Photon")
2220 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(locParticleBranchName, "ChiSq_Timing_KinFit"), locNeutralHypo->Get_ChiSq(), locComboIndex);
2221 }
2222
2223 //KINFIT
2224 if(locKinFitType != d_NoFit)
2225 {
2226 //KINEMATICS
2227 if(locKinFitType != d_P4Fit)
2228 {
2229 DVector3 locPosition = locNeutralHypo->position();
2230 TLorentzVector locX4_KinFit(locPosition.X(), locPosition.Y(), locPosition.Z(), locNeutralHypo->time());
2231 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "X4_KinFit"), locX4_KinFit, locComboIndex);
2232 }
2233
2234 //update even if vertex-only fit, because neutral momentum defined by vertex
2235 DLorentzVector locDP4 = locNeutralHypo->lorentzMomentum();
2236 TLorentzVector locP4_KinFit(locDP4.Px(), locDP4.Py(), locDP4.Pz(), locDP4.E());
2237 locTreeFillData->Fill_Array<TLorentzVector>(Build_BranchName(locParticleBranchName, "P4_KinFit"), locP4_KinFit, locComboIndex);
2238 }
2239}
2240
2241void DEventWriterROOT::Fill_KinFitData(DTreeFillData* locTreeFillData, JEventLoop* locEventLoop, const DReaction* locReaction, const DMCReaction* locMCReaction, const vector<const DMCThrown*>& locMCThrowns,
2242 const DMCThrownMatching* locMCThrownMatching, const DDetectorMatches* locDetectorMatches,
2243 const vector<const DBeamPhoton*>& locBeamPhotons, const vector<const DChargedTrackHypothesis*>& locChargedHypos,
2244 const vector<const DNeutralParticleHypothesis*>& locNeutralHypos, const deque<const DParticleCombo*>& locParticleCombos) const
2245{
2246 if(!STORE_PULL_INFO && !STORE_ERROR_MATRIX_INFO)
2247 return;
2248
2249 if(STORE_ERROR_MATRIX_INFO){
2250 locTreeFillData->Fill_Single<Int_t>("numEntries_ParticleErrM", nEntriesParticleCov);
2251 locTreeFillData->Fill_Single<Int_t>("numEntries_ShowerErrM", nEntriesShowerCov);
2252 }
2253 bool writeOutPulls = getPullFlag( locReaction );
2254
2255 //Retreive and fill pull-information:
2256 //######################################################################################################################
2257 DKinFitType kfitType = locReaction->Get_KinFitType();
2258
2259 //Now fill the pulls for all particles:
2260 int nParticleCombos = locParticleCombos.size();
2261 int nMeasuredFinalParticles;
2262 double currentCharge;
2263 Particle_t currentPID;
2264
2265 //----------------------------------------------------------------------------
2266 for(int iPC=0;iPC<nParticleCombos;iPC++){
2267 Get_PullsFromFit(locParticleCombos.at(iPC));
2268
2269 vector<string> pidVector = getPIDinReaction(locReaction);
2270 map<Particle_t,int> assignMap = getNameForParticle(locReaction,pidVector);
2271
2272
2273 //Look at beam photons:
2274 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2275 const DParticleComboStep* locParticleComboStep = locParticleCombos[iPC]->Get_ParticleComboStep(0);
2276 const DKinematicData* beamPhoton = locParticleComboStep->Get_InitialParticle_Measured();
2277
2278 if(kfitType == d_P4Fit || kfitType == d_P4AndVertexFit){
2279 if(writeOutPulls){
2280 map<DKinFitPullType, double> someBeamMap = getPulls(beamPhoton,NULL__null,kfitType);
2281 fillTreePullBranches(locTreeFillData,"ComboBeam",kfitType,someBeamMap,iPC,true);
2282 someBeamMap.clear();
2283 }
2284 }
2285 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2286
2287 //Look at the decay products:
2288 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2289 vector<const DKinematicData*> finalParticlesMeasured = locParticleCombos.at(iPC)->Get_FinalParticles_Measured(locReaction, d_AllCharges);
2290 vector<const DKinematicData*> finalParticles = locParticleCombos.at(iPC)->Get_FinalParticles(locReaction, d_AllCharges);
2291
2292 vector<const JObject*> finalParticleObjects = locParticleCombos.at(iPC)->Get_FinalParticle_SourceObjects(d_AllCharges);
2293 nMeasuredFinalParticles = finalParticlesMeasured.size();
2294
2295 //----------------------------------------------------------------------------
2296 for(int iFP=0;iFP<nMeasuredFinalParticles;iFP++){
2297 const DKinematicData* part = finalParticlesMeasured.at(iFP);
2298 const DKinematicData* partFit = finalParticles.at(iFP);
2299 const DNeutralShower* sh = dynamic_cast<const DNeutralShower*>(finalParticleObjects.at(iFP));
2300 bool isNeutral = false;
2301
2302 map<DKinFitPullType, double> someMap;
2303 if(writeOutPulls) someMap = getPulls(part,sh,kfitType);
2304 //-----------------------------------------------------
2305 if(sh == NULL__null){
2306 currentCharge = part->charge();
2307 currentPID = part->PID();
2308 }else{
2309 currentCharge = 0.0;
2310 currentPID = Gamma;
2311 }
2312
2313 if(currentCharge == 0) isNeutral = true;
2314 //-----------------------------------------------------
2315
2316 string branchName = assignName(currentPID,assignMap);
2317 assignMap[currentPID]--;
2318 //-----------------------------------------------------
2319 if(branchName != "nada"){
2320 if(STORE_PULL_INFO){
2321 fillTreePullBranches(locTreeFillData,branchName,kfitType,someMap,iPC,isNeutral);
2322 fillTreeTrackPullBranches(locTreeFillData,branchName,kfitType,someMap,iPC,isNeutral,part,partFit);
2323 }
2324 if(STORE_ERROR_MATRIX_INFO)
2325 fillTreeErrMBranches(locTreeFillData,branchName,kfitType,part,sh,isNeutral);
2326 }
2327 //-----------------------------------------------------
2328 if(STORE_PULL_INFO) someMap.clear();
2329 }
2330 //----------------------------------------------------------------------------
2331 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2332
2333 myPullsMap.clear();
2334 assignMap.clear();
2335 abundanceMap.clear();
2336
2337 }
2338
2339}
2340
2341
2342//I guess this is the most clumsiest way of assigning a few names to a tree-branch, but it is doing what it is supposed to do...
2343//*************************************************************************************************************************************
2344vector<string> DEventWriterROOT::getPIDinReaction(const DReaction* locReaction)const
2345{
2346 vector <string> myVector;
2347 vector<Particle_t> particle = locReaction->Get_FinalPIDs(-1,false,false,d_AllCharges,true);
2348 int nParticleIDs = particle.size();
2349 //----------------------------------------------------
2350 for(int k=0;k<nParticleIDs;k++){
2351 myVector.push_back(EnumString(particle.at(k)));
2352 }
2353 //----------------------------------------------------
2354 return myVector;
2355}
2356
2357map<Particle_t, int> DEventWriterROOT::getNameForParticle(const DReaction* someReaction, vector<string> someVector)const
2358{
2359 map <Particle_t,int> myMap;
2360 vector<Particle_t> particle = someReaction->Get_FinalPIDs(-1,false,false,d_AllCharges,true);
2361 int nParticleIDs = particle.size();
2362 int currentCounter = 0;
2363 int nEl = someVector.size();
2364 //----------------------------------------------------
2365 for(int k=0;k<nParticleIDs;k++){
2366 currentCounter = 0;
2367
2368 //----------------------------------------------------
2369 for(int j=0;j<nEl;j++){
2370 if(EnumString(particle.at(k)) == someVector.at(j)){
2371 currentCounter++;
2372 someVector.at(j) = "";
2373 }
2374 }
2375 //----------------------------------------------------
2376 if(currentCounter > 0){
2377 abundanceMap[particle.at(k)] = currentCounter;
2378 myMap[particle.at(k)] = currentCounter;
2379 }
2380 }
2381 //----------------------------------------------------
2382 return myMap;
2383}
2384
2385string DEventWriterROOT::assignName(Particle_t someParticle, map<Particle_t,int> someMap)const
2386{
2387 string myName = "nada";
2388 int abundance = abundanceMap.find(someParticle)->second;
2389 if(abundance == 1) {
2390 myName = EnumString(someParticle);
2391 } else if(abundance > 1) {
2392 int index = abundance - someMap.find(someParticle)->second +1;
2393 string addName;
2394 ostringstream convert;
2395 convert << index;
2396 addName = convert.str();
2397 if(strcmp(EnumString(someParticle),"Gamma")==0) {
2398 myName = "Photon" + addName;
2399 } else {
2400 myName = EnumString(someParticle) + addName;
2401 }
2402 }
2403
2404 return myName;
2405}
2406
2407void DEventWriterROOT::Get_PullsFromFit(const DParticleCombo* particleCombos) const
2408{
2409 const DKinFitResults* fitResults = particleCombos->Get_KinFitResults();
2410 if(fitResults != NULL__null){
2411 fitResults->Get_Pulls(myPullsMap);
2412 }
2413}
2414
2415map<DKinFitPullType, double> DEventWriterROOT::getPulls(const JObject* particle, const JObject* shower, DKinFitType yourFitType) const{
2416 map<DKinFitPullType, double> myMap;
2417
2418 if(particle != NULL__null || shower != NULL__null) {
2419
2420 if(yourFitType == d_P4Fit || yourFitType == d_VertexFit) {
2421 myMap = myPullsMap.find(particle)->second;
2422 }else if(yourFitType == d_P4AndVertexFit ){ //Option noFit is not considered
2423 if(shower == NULL__null) {
2424 myMap = myPullsMap.find(particle)->second;
2425 } else myMap = myPullsMap.find(shower)->second;
2426 }
2427 }
2428
2429 return myMap;
2430}
2431
2432
2433//Get the pull-features:
2434void DEventWriterROOT::setTreePullBranches(DTreeBranchRegister& locBranchRegister,string yourBranchName,DKinFitType yourFitType, int yourNCombos, bool isNeutral) const
2435{
2436 string locArraySizeString = "NumCombos";
2437
2438 if(yourFitType == d_P4Fit){
2439 //Regular Pulls:
2440 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Px_Pull"),locArraySizeString, yourNCombos);
2441 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Py_Pull"),locArraySizeString, yourNCombos);
2442 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Pz_Pull"),locArraySizeString, yourNCombos);
2443
2444 //Pulls used for tracking:
2445 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"QPt_Pull"),locArraySizeString, yourNCombos);
2446 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Phi_Pull"),locArraySizeString, yourNCombos);
2447 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"tanLambda_Pull"),locArraySizeString, yourNCombos);
2448 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"D_Pull"),locArraySizeString, yourNCombos);
2449
2450 }else if(yourFitType == d_P4AndVertexFit){
2451 //------------------------------------------------------------
2452 if(isNeutral){
2453 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"E_Pull"),locArraySizeString, yourNCombos);
2454 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xx_Pull"),locArraySizeString, yourNCombos);
2455 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xy_Pull"),locArraySizeString, yourNCombos);
2456 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xz_Pull"),locArraySizeString, yourNCombos);
2457 }else{
2458 //Regular Pulls:
2459 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Px_Pull"),locArraySizeString, yourNCombos);
2460 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Py_Pull"),locArraySizeString, yourNCombos);
2461 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Pz_Pull"),locArraySizeString, yourNCombos);
2462 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xx_Pull"),locArraySizeString, yourNCombos);
2463 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xy_Pull"),locArraySizeString, yourNCombos);
2464 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xz_Pull"),locArraySizeString, yourNCombos);
2465
2466 //Pulls used for tracking:
2467 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"QPt_Pull"),locArraySizeString, yourNCombos);
2468 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Phi_Pull"),locArraySizeString, yourNCombos);
2469 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"tanLambda_Pull"),locArraySizeString, yourNCombos);
2470 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"D_Pull"),locArraySizeString, yourNCombos);
2471 }
2472 //------------------------------------------------------------
2473 }else if(yourFitType == d_VertexFit && !isNeutral){
2474 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xx_Pull"),locArraySizeString, yourNCombos);
2475 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xy_Pull"),locArraySizeString, yourNCombos);
2476 locBranchRegister.Register_FundamentalArray<Double_t>(Build_BranchName(yourBranchName,"Xz_Pull"),locArraySizeString, yourNCombos);
2477 }
2478}
2479
2480//Fill the tree branches:
2481void DEventWriterROOT::fillTreePullBranches(DTreeFillData* locTreeFillData,string yourBranchName,DKinFitType yourFitType,map<DKinFitPullType, double> yourPullsMap, int yourIndex, bool isNeutral) const
2482{
2483
2484 if(yourFitType == d_P4Fit){
2485 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Px_Pull"), yourPullsMap.find(d_PxPull)->second,yourIndex);
2486 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Py_Pull"), yourPullsMap.find(d_PyPull)->second,yourIndex);
2487 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Pz_Pull"), yourPullsMap.find(d_PzPull)->second,yourIndex);
2488
2489 }else if(yourFitType == d_P4AndVertexFit){
2490 //------------------------------------------------------------
2491 if(isNeutral){
2492 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "E_Pull"), yourPullsMap.find(d_EPull)->second,yourIndex);
2493 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xx_Pull"), yourPullsMap.find(d_XxPull)->second,yourIndex);
2494 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xy_Pull"), yourPullsMap.find(d_XyPull)->second,yourIndex);
2495 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xz_Pull"), yourPullsMap.find(d_XzPull)->second,yourIndex);
2496 }else{
2497 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Px_Pull"), yourPullsMap.find(d_PxPull)->second,yourIndex);
2498 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Py_Pull"), yourPullsMap.find(d_PyPull)->second,yourIndex);
2499 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Pz_Pull"), yourPullsMap.find(d_PzPull)->second,yourIndex);
2500 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xx_Pull"), yourPullsMap.find(d_XxPull)->second,yourIndex);
2501 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xy_Pull"), yourPullsMap.find(d_XyPull)->second,yourIndex);
2502 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xz_Pull"), yourPullsMap.find(d_XzPull)->second,yourIndex);
2503 }
2504 //------------------------------------------------------------
2505 }else if(yourFitType == d_VertexFit && !isNeutral){
2506 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xx_Pull"), yourPullsMap.find(d_XxPull)->second,yourIndex);
2507 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xy_Pull"), yourPullsMap.find(d_XyPull)->second,yourIndex);
2508 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Xz_Pull"), yourPullsMap.find(d_XzPull)->second,yourIndex);
2509 }
2510}
2511
2512//Make sure, the pull information is written out, when available
2513void DEventWriterROOT::setPullFlag(const DReaction* currentReaction, bool myFlag) const
2514{
2515 writePulls[currentReaction] = myFlag;
2516}
2517
2518bool DEventWriterROOT::getPullFlag(const DReaction* currentReaction) const
2519{
2520 bool outFlag = writePulls.find(currentReaction)->second;
2521 return outFlag;
2522}
2523
2524//Now fill the individual elements of the error matrix to the tree:
2525void DEventWriterROOT::fillTreeErrMBranches(DTreeFillData* locTreeFillData,string yourBranchName,DKinFitType yourFitType, const DKinematicData* particle, const DNeutralShower* shower, bool isNeutral) const
2526{
2527 if(yourFitType == d_P4Fit) {
2528 fillTreeParticleErrMBranches(locTreeFillData,yourBranchName,particle);
2529 } else if(yourFitType == d_P4AndVertexFit) {
2530 if(isNeutral) {
2531 fillTreeShowerErrMBranches(locTreeFillData,yourBranchName,shower);
2532 } else {
2533 fillTreeParticleErrMBranches(locTreeFillData,yourBranchName,particle);
2534 }
2535 } else if(yourFitType == d_VertexFit && !isNeutral) {
2536 fillTreeParticleErrMBranches(locTreeFillData,yourBranchName,particle);
2537 }
2538}
2539
2540//Fill the 7x7 error matrix elements:
2541void DEventWriterROOT::fillTreeParticleErrMBranches(DTreeFillData* locTreeFillData,string yourBranchName, const DKinematicData* particle) const
2542{
2543 if(particle != NULL__null){
2544 const TMatrixTSym<float> errMatrix = *( particle->errorMatrix() );
2545
2546 int mIndex = 0;
2547 float matrixEl = 0.0;
2548 for(int row=0;row<7;row++){
2549 for(int col=0;col<7;col++){
2550 if(col >= row){
2551 matrixEl = errMatrix[row][col];
2552 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(yourBranchName, "ErrMatrix"),matrixEl,mIndex);
2553 mIndex++;
2554 }
2555 }
2556 }
2557
2558 }
2559}
2560
2561//Fill the 5x5 error matrix elements:
2562void DEventWriterROOT::fillTreeShowerErrMBranches(DTreeFillData* locTreeFillData,string yourBranchName, const DNeutralShower* shower) const
2563{
2564 if(shower != NULL__null){
2565 const TMatrixTSym <float> errMatrix = *( shower->dCovarianceMatrix );
2566 float matrixEl = 0.0;
2567
2568 int mIndex = 0;
2569 for(int row=0;row<5;row++){
2570 for(int col=0;col<5;col++){
2571 if(col >= row){
2572 matrixEl = errMatrix[row][col];
2573 locTreeFillData->Fill_Array<Float_t>(Build_BranchName(yourBranchName, "ErrMatrix"),matrixEl,mIndex);
2574 mIndex++;
2575 }
2576 }
2577 }
2578
2579 }
2580}
2581
2582//GET THE TRACKING PULLS:
2583
2584//Get the difference in pull errors for one momentum component:
2585double DEventWriterROOT::getDiffSquaredErrP_Component(double yourRecComponent,double yourFitComponent,double yourPull) const
2586{
2587 double diff = yourRecComponent - yourFitComponent;
2588 double error_component = 0.0;
2589
2590 if(diff != 0.0 && yourPull != 0.0){
2591 error_component = diff*diff / (yourPull*yourPull);
2592 }
2593
2594 return error_component;
2595}
2596
2597// Get the difference in pull errors for the position
2598vector< vector<double> > DEventWriterROOT::getSquaredErrX(const DKinematicData* particle, const DKinematicData* particleFit, map<DKinFitPullType, double> yourPullsMap) const{
2599
2600 double x_pull = yourPullsMap.find(d_XxPull)->second;
2601 double y_pull = yourPullsMap.find(d_XyPull)->second;
2602
2603 double x_rec = particle->x();
2604 double x_fit = particleFit->x();
2605
2606 double y_rec = particle->y();
2607 double y_fit = particleFit->y();
2608
2609 double error_x = getDiffSquaredErrP_Component(x_rec,x_fit,x_pull);
2610 double error_y = getDiffSquaredErrP_Component(y_rec,y_fit,y_pull);
2611
2612 const TMatrixTSym<float> errMatrix = *( particle->errorMatrix() ); //--> Reconstructed errors!
2613 double error_x_rec = errMatrix[3][3];
2614 double error_y_rec = errMatrix[4][4];
2615
2616 double error_x_fit = error_x_rec - error_x;
2617 double error_y_fit = error_y_rec - error_y;
2618
2619 vector <double> xComponent;
2620 vector <double> yComponent;
2621
2622 xComponent.push_back(error_x_rec);
2623 xComponent.push_back(error_x_fit);
2624
2625 yComponent.push_back(error_y_rec);
2626 yComponent.push_back(error_y_fit);
2627
2628 vector < vector<double> > myErrors;
2629 myErrors.push_back(xComponent);
2630 myErrors.push_back(yComponent);
2631
2632 return myErrors;
2633
2634}
2635
2636//Get the difference in pull errors for the momentum
2637vector< vector<double> > DEventWriterROOT::getSquaredErrP(const DKinematicData* particle, const DKinematicData* particleFit, map<DKinFitPullType, double> yourPullsMap) const
2638{
2639
2640 double px_pull = yourPullsMap.find(d_PxPull)->second;
2641 double py_pull = yourPullsMap.find(d_PyPull)->second;
2642 double pz_pull = yourPullsMap.find(d_PzPull)->second;
2643
2644 double px_rec = particle->px();
2645 double px_fit = particleFit->px();
2646
2647 double py_rec = particle->py();
2648 double py_fit = particleFit->py();
2649
2650 double pz_rec = particle->pz();
2651 double pz_fit = particleFit->pz();
2652
2653 double error_x = getDiffSquaredErrP_Component(px_rec,px_fit,px_pull);
2654 double error_y = getDiffSquaredErrP_Component(py_rec,py_fit,py_pull);
2655 double error_z = getDiffSquaredErrP_Component(pz_rec,pz_fit,pz_pull);
2656
2657 const TMatrixTSym<float> errMatrix = *( particle->errorMatrix() ); //--> Reconstructed errors!
2658 double error_x_rec = errMatrix[0][0];
2659 double error_y_rec = errMatrix[1][1];
2660 double error_z_rec = errMatrix[2][2];
2661
2662 double error_x_fit = error_x_rec - error_x;
2663 double error_y_fit = error_y_rec - error_y;
2664 double error_z_fit = error_z_rec - error_z;
2665
2666 vector <double> xComponent;
2667 vector <double> yComponent;
2668 vector <double> zComponent;
2669
2670 xComponent.push_back(error_x_rec);
2671 xComponent.push_back(error_x_fit);
2672
2673 yComponent.push_back(error_y_rec);
2674 yComponent.push_back(error_y_fit);
2675
2676 zComponent.push_back(error_z_rec);
2677 zComponent.push_back(error_z_fit);
2678
2679 vector < vector<double> > myErrors;
2680 myErrors.push_back(xComponent);
2681 myErrors.push_back(yComponent);
2682 myErrors.push_back(zComponent);
2683
2684 return myErrors;
2685}
2686
2687//1.) Start with phi:
2688//Calculate the error for one state (fitted,reconstructed):
2689double DEventWriterROOT::getPhiError(const DKinematicData* particle, vector< vector<double> > yourErrorMatrix, int isFitted) const
2690{
2691 double myPhiError = 0.0;
2692 double myPx = particle->px();
2693 double myPy = particle->py();
2694
2695 //Phi = artan(Px/Py) --> caclulate derivatives from this...
2696 if(myPy != 0.0){
2697
2698 double myDPx = yourErrorMatrix[0][isFitted];
2699 double myDPy = yourErrorMatrix[1][isFitted];
2700
2701 double arg = myPx / myPy;
2702 double factor1 = 1.0 / pow( myPy*(1.0 + arg*arg), 2);
2703 double factor2 = (myDPx + arg*arg*myDPy);
2704
2705 myPhiError = factor1*factor2;
2706 }
2707
2708 return myPhiError;
2709}
2710
2711
2712//Now calculate the pull:
2713double DEventWriterROOT::getPhiPull(const DKinematicData* particle, const DKinematicData* particleFit, vector< vector<double> > yourErrorMatrix) const
2714{
2715 double myPhiPull = -100.0;
2716
2717 double phi_rec = ( particle->momentum() ).Phi();
2718 double phi_fit = ( particleFit->momentum() ).Phi();
2719
2720 double dPhi_rec = getPhiError(particle,yourErrorMatrix,0);
2721 double dPhi_fit = getPhiError(particleFit,yourErrorMatrix,1);
2722
2723 double pull_norm = dPhi_rec - dPhi_fit;
2724
2725 if(pull_norm > 0.0){
2726 myPhiPull = (phi_rec - phi_fit) / sqrt(pull_norm);
2727 }
2728
2729 return myPhiPull;
2730}
2731
2732//2.) Tan(lambda):
2733//Get the error of lambda:
2734double DEventWriterROOT::getLambdaError(const DKinematicData* particle, vector< vector<double> > yourErrorMatrix, int isFitted) const
2735{
2736 double myTanLambdaError = 0.0;
2737 //lambda = pi/2 - theta --> dlambda = dtheta...
2738
2739 double myPx = particle->px();
2740 double myPy = particle->py();
2741 double myPz = particle->pz();
2742
2743 double myDPx = yourErrorMatrix[0][isFitted];
2744 double myDPy = yourErrorMatrix[1][isFitted];
2745 double myDPz = yourErrorMatrix[2][isFitted];
2746
2747 double r2 = myPx*myPx + myPy*myPy + myPz*myPz;
2748 double lambda = 0.5*M_PI3.14159265358979323846 - ( particle->momentum() ).Theta();
2749 //---------------------------
2750 if(r2 > 0.0 && cos(lambda) != 0.0){
2751 double r = sqrt(r2);
2752 double factor1 = 1.0 / ( pow(r,6) * pow(cos(lambda),4) );
2753 double sum1 = myPx*myPz;
2754 double sum2 = myPy*myPz;
2755 double sum3 = (r - myPz*myPz);
2756 double factor2 = sum1*sum1*myDPx + sum2*sum2*myDPy + sum3*sum3*myDPz;
2757
2758 myTanLambdaError = factor1*factor2;
2759 }
2760 //---------------------------
2761
2762
2763 return myTanLambdaError;
2764}
2765
2766
2767//Go for the pull itself:
2768double DEventWriterROOT::getTanLambdaPull(const DKinematicData* particle, const DKinematicData* particleFit, vector< vector<double> > yourErrorMatrix) const
2769{
2770 double myTanLambdaPull = -100.0;
2771
2772 //Reconstructed values:
2773 double lambda_rec = 0.5*M_PI3.14159265358979323846 - ( particle->momentum() ).Theta();
2774 double tanLambda_rec = tan(lambda_rec);
2775 double dtanLambda_rec = getLambdaError(particle,yourErrorMatrix,0);
2776
2777 //Fitted values:
2778 double lambda_fit = 0.5*M_PI3.14159265358979323846 - ( particleFit->momentum() ).Theta();
2779 double tanLambda_fit = tan(lambda_fit);
2780 double dtanLambda_fit = getLambdaError(particleFit,yourErrorMatrix,1);
2781
2782 double pull_norm = dtanLambda_rec-dtanLambda_fit;
2783 //---------------------------
2784 if(pull_norm > 0.0){
2785 myTanLambdaPull = (tanLambda_rec-tanLambda_fit) / sqrt(pull_norm);
2786 }
2787 //---------------------------
2788
2789 return myTanLambdaPull;
2790}
2791
2792//3.) q/pt:
2793//Calculate error for 1/pt:
2794double DEventWriterROOT::getQPTError(const DKinematicData* particle, vector< vector<double> > yourErrorMatrix, int isFitted) const
2795{
2796 double myQPTError = 0.0;
2797 double myPx = particle->px();
2798 double myPy = particle->py();
2799 double r2 = myPx*myPx + myPy*myPy;
2800
2801 double myDPx = yourErrorMatrix[0][isFitted];
2802 double myDPy = yourErrorMatrix[1][isFitted];
2803 //---------------------------
2804 if(r2 > 0.0){
2805 double q = particle->charge();
2806 double factor1 = q*q / pow(r2,3);
2807 double factor2 = (myPx*myPx*myDPx + myPy*myPy*myDPy);
2808
2809 myQPTError = factor1*factor2;
2810 }
2811 //---------------------------
2812
2813 return myQPTError;
2814}
2815
2816
2817//Get the pull:
2818double DEventWriterROOT::getQPTPull(const DKinematicData* particle, const DKinematicData* particleFit, vector< vector<double> > yourErrorMatrix) const
2819{
2820 double myPTPull = -100.0;
2821
2822 double particle_charge = particle->charge();
2823
2824 double myPx_rec = particle->px();
2825 double myPy_rec = particle->py();
2826 double r_rec = myPx_rec*myPx_rec + myPy_rec*myPy_rec;
2827
2828 double myPx_fit = particleFit->px();
2829 double myPy_fit = particleFit->py();
2830 double r_fit = myPx_fit*myPx_fit + myPy_fit*myPy_fit;
2831
2832 //---------------------------
2833 if(r_rec > 0.0 && r_fit > 0.0){
2834 double qpt_rec = particle_charge/sqrt(r_rec);
2835 double dqpt_rec = getQPTError(particle,yourErrorMatrix,0);
2836
2837 double qpt_fit = particle_charge/sqrt(r_fit);
2838 double dqpt_fit = getQPTError(particleFit,yourErrorMatrix,1);
2839
2840 double pull_norm = dqpt_rec-dqpt_fit;
2841 //---------------------------
2842 if(pull_norm > 0.0){
2843 myPTPull = (qpt_rec-qpt_fit)/sqrt(pull_norm);
2844 }
2845 //---------------------------
2846 }
2847 //---------------------------
2848
2849
2850 return myPTPull;
2851}
2852
2853//4.) D:
2854//Get the error of D:
2855double DEventWriterROOT::getDError(const DKinematicData* particle, vector< vector<double> > yourErrorMatrix, int isFitted) const
2856{
2857
2858 double myDsq=particle->position().Perp2()+1e-8;
2859 double myx=particle->x();
2860 double myy=particle->y();
2861
2862 double myVarX=yourErrorMatrix[0][isFitted];
2863 double myVarY=yourErrorMatrix[1][isFitted];
2864 double myDError=(myx*myx*myVarX+myy*myy*myVarY)/myDsq;
2865
2866 return myDError;
2867}
2868
2869//Go for the pull itself:
2870double DEventWriterROOT::getDPull(const DKinematicData* particle, const DKinematicData* particleFit, vector< vector<double> > yourErrorMatrix) const
2871{
2872 double myDPull=-100.0;
2873
2874 //Reconstructed values:
2875 double D_rec=particle->position().Perp();
2876 double dx_rec=particle->x();
2877 double dy_rec=particle->y();
2878 double phi_rec=particle->momentum().Phi();
2879 double cosphi_rec=cos(phi_rec);
2880 double sinphi_rec=sin(phi_rec);
2881 if ((dx_rec>0.0 && sinphi_rec>0.0) || (dy_rec<0.0 && cosphi_rec>0.0)
2882 || (dy_rec>0.0 && cosphi_rec<0.0) || (dx_rec<0.0 && sinphi_rec<0.0))
2883 D_rec*=-1.;
2884 double dD_rec=getDError(particle,yourErrorMatrix,0);
2885
2886 //Fitted values:
2887 double D_fit=particleFit->position().Perp();
2888 double dx_fit=particleFit->x();
2889 double dy_fit=particleFit->y();
2890 double phi_fit=particleFit->momentum().Phi();
2891 double cosphi_fit=cos(phi_fit);
2892 double sinphi_fit=sin(phi_fit);
2893 if ((dx_fit>0.0 && sinphi_fit>0.0) || (dy_fit<0.0 && cosphi_fit>0.0)
2894 || (dy_fit>0.0 && cosphi_fit<0.0) || (dx_fit<0.0 && sinphi_fit<0.0))
2895 D_fit*=-1.;
2896 double dD_fit=getDError(particle,yourErrorMatrix,1);
2897
2898 double pull_norm = dD_rec-dD_fit;
2899 //---------------------------
2900 if(pull_norm > 0.0){
2901 myDPull = (D_rec-D_fit) / sqrt(pull_norm);
2902 }
2903 //---------------------------
2904
2905 return myDPull;
2906}
2907
2908//Create a vector containing all pulls:
2909vector<double> DEventWriterROOT::collectTrackingPulls(const DKinematicData* particle, const DKinematicData* particleFit, map<DKinFitPullType, double> yourPullsMap) const
2910{
2911 //1.) Get the pre-and post-fit errors:
2912 vector< vector<double> > myErrors = getSquaredErrP(particle,particleFit,yourPullsMap);
2913 vector< vector<double> > myXErrors = getSquaredErrX(particle,particleFit,yourPullsMap);
2914
2915 //2.) Calculate the pulls:
2916 //2.1.) q/pt:
2917 double qpt_pull = getQPTPull(particle,particleFit,myErrors);
2918 //2.2.) phi:
2919 double phi_pull = getPhiPull(particle,particleFit,myErrors);
2920 //2.3.) tan(lambda):
2921 double tanLambda_pull = getTanLambdaPull(particle,particleFit,myErrors);
2922 //2.4.) D
2923 double D_pull = getDPull(particle,particleFit,myXErrors);
2924
2925 //3.) Store everything into a vector:
2926 vector<double> myTrackingPulls;
2927 myTrackingPulls.push_back(qpt_pull);
2928 myTrackingPulls.push_back(phi_pull);
2929 myTrackingPulls.push_back(tanLambda_pull);
2930 myTrackingPulls.push_back(D_pull);
2931
2932 return myTrackingPulls;
2933}
2934
2935//Fill the tracking pulls:
2936void DEventWriterROOT::fillTreeTrackPullBranches(DTreeFillData* locTreeFillData,string yourBranchName,DKinFitType yourFitType,map<DKinFitPullType, double> yourPullsMap, int yourIndex, bool isNeutral, const DKinematicData* particle, const DKinematicData* particleFit) const
2937{
2938 if( !isNeutral && (yourFitType == d_P4Fit || yourFitType == d_P4AndVertexFit) ){//Get the tracking pulls for charged tracks only...
2939 //1.) Get the vector containing the tracking pulls:
2940 vector<double> myTrackingPulls = collectTrackingPulls(particle,particleFit,yourPullsMap);
2941
2942 //2.) Fill the pulls to the tree:
2943 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "QPt_Pull"),myTrackingPulls[0],yourIndex);
2944 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "Phi_Pull"),myTrackingPulls[1],yourIndex);
2945 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "tanLambda_Pull"),myTrackingPulls[2],yourIndex);
2946 locTreeFillData->Fill_Array<Double_t>(Build_BranchName(yourBranchName, "D_Pull"),myTrackingPulls[3],yourIndex);
2947 }
2948}
2949

/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