Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DReaction_factory_ReactionFilter.cc
Go to the documentation of this file.
2 
3 /*
4  * COMMAND LINE INPUT:
5  *
6  * Any particles whose decays are not explicitly listed: default decay mode will be used if any. If none available, it will be assumed that the particle is to be detected.
7  * This means that no default decay should be listed for the pi+, k+, etc.
8  *
9  * Reaction Form 1: BeamPID_TargetPID__FS1PID_FS2PID_FS3PID
10  * Reaction Form 2: DecayPID_TargetPID__FS1PID_FS2PID_FS3PID
11  * Reaction Form 3: DecayPID__FS1PID_FS2PID_FS3PID
12  * To distinguish between forms 1 & 2: If first step, form 1 is assumed
13  *
14  * PID: Geant PID
15  * parentheses around any means missing, Unknown means inclusive
16  *
17  * CONTROL MODE EXAMPLES:
18  * -PReaction1=1_14__14_8_9 #g, p -> p, pi+, pi-
19  * -PReaction2=1_14__14_8_9_7 #g, p -> p, pi+, pi-, pi0
20  *
21  * -PReaction3=1_14__14_8_9_7 #g, p -> p, pi+, pi-, pi0
22  * -PReaction3:Decay1=7__2_3_1 # pi0 -> e+, e-, g
23  * -PReaction3:Flags=F1_B2_T4_M7_U1 #Fit enum 1 (p4-only (includes mass)), +/- 2 RF bunches, 4 extra tracks, don't constrain mass on pi0 (can have any number), save unused tracks # Can list these in any order
24  * Fit enums are defined in DReaction.h (d_P4AndVertexFit is 4 and is the default)
25  * -PReaction3:Name=my_pi0_channel
26  *
27  * -PReaction4=1_14__14_8_9_m7 #g, p -> p, pi+, pi-, missing pi0
28  * -PReaction4=1_14__14_8_9_m0 #g, p -> p, pi+, pi-, inclusive
29  *
30  */
31 
32 /******************************************************************************** CUSTOMIZATION FUNCTIONS ********************************************************************************/
33 
35 {
36  //DO NOT SPECIFY DEFAULT DECAYS FOR PARTICLES THAT CAN BE DETECTED!!!!!! (e.g. pion, neutron, klong)
37 
38  //MESONS
39  if(locPID == Pi0)
40  return (new DReactionStep(Pi0, {Gamma, Gamma}));
41  else if(locPID == KShort)
42  return (new DReactionStep(KShort, {PiMinus, PiPlus}));
43  else if(locPID == Eta)
44  return (new DReactionStep(Eta, {Gamma, Gamma}));
45  else if(locPID == omega)
46  return (new DReactionStep(omega, {PiMinus, PiPlus, Pi0}));
47  else if(locPID == EtaPrime)
48  return (new DReactionStep(EtaPrime, {PiMinus, PiPlus, Eta}));
49  else if(locPID == phiMeson)
50  return (new DReactionStep(phiMeson, {KMinus, KPlus}));
51  else if(locPID == D0)
52  return (new DReactionStep(D0, {KMinus, PiPlus}));
53  else if(locPID == AntiD0)
54  return (new DReactionStep(AntiD0, {KPlus, PiMinus}));
55  else if(locPID == Jpsi)
56  return (new DReactionStep(Jpsi, {Electron, Positron}));
57 
58  //BARYONS
59  else if(locPID == Lambda)
60  return (new DReactionStep(Lambda, {PiMinus, Proton}));
61  else if(locPID == AntiLambda)
62  return (new DReactionStep(AntiLambda, {PiPlus, AntiProton}));
63  else if(locPID == SigmaMinus)
64  return (new DReactionStep(SigmaMinus, {PiMinus, Neutron}));
65  else if(locPID == Sigma0)
66  return (new DReactionStep(Sigma0, {Gamma, Lambda}));
67  else if(locPID == SigmaPlus)
68  return (new DReactionStep(SigmaPlus, {Pi0, Proton}));
69  else if(locPID == Xi0)
70  return (new DReactionStep(Xi0, {Pi0, Lambda}));
71  else if(locPID == AntiXi0)
72  return (new DReactionStep(AntiXi0, {Pi0, AntiLambda}));
73  else if(locPID == XiMinus)
74  return (new DReactionStep(XiMinus, {PiMinus, Lambda}));
75  else if(locPID == AntiXiPlus)
76  return (new DReactionStep(AntiXiPlus, {PiPlus, AntiLambda}));
77  else if(locPID == OmegaMinus)
78  return (new DReactionStep(OmegaMinus, {KMinus, Lambda}));
79  else if(locPID == Lambda_c)
80  return (new DReactionStep(Lambda_c, {PiPlus, KMinus, Proton}));
81 
82  return nullptr;
83 }
84 
85 void DReaction_factory_ReactionFilter::Set_Flags(DReaction* locReaction, string locRemainingFlagString)
86 {
87  //Example: -PReaction3:Flags=F1_B2_T4_M7 #Fit enum 1 (p4-only (includes mass)), +/- 2 RF bunches, 4 extra tracks, don't constrain mass on pi0 (can have any number) # Can list these in any order
88 
89  //First set defaults, then let user override them
90  locReaction->Set_KinFitType(d_P4AndVertexFit);
91  locReaction->Set_NumPlusMinusRFBunches(1); // +/- 1 bunch for sideband subtraction
92  locReaction->Set_MaxExtraShowers(999);
93  locReaction->Set_MaxExtraGoodTracks(3);
94 
95  bool locSaveUnusedHypotheses = false;
96  string locTreeFileName = string("tree_") + locReaction->Get_ReactionName() + string(".root");
97 
98  //Parse user input
99  while(locRemainingFlagString != "")
100  {
101  auto locUnderscoreIndex = locRemainingFlagString.find("_");
102  auto locThisFlagString = (locUnderscoreIndex != string::npos) ? locRemainingFlagString.substr(0, locUnderscoreIndex) : locRemainingFlagString;
103 
104  //Get the type char
105  auto locFlagTypeChar = locThisFlagString[0];
106 
107  //Get the value
108  istringstream locIStream(locThisFlagString.substr(1));
109  int locFlagArg;
110  locIStream >> locFlagArg;
111  if(locIStream.fail())
112  {
113  cout << "BUILDING DREACTION, FLAG " << locThisFlagString << " NOT RECOGNIZED." << endl;
114  if(locUnderscoreIndex == string::npos)
115  break;
116  continue;
117  }
118 
119  switch(locFlagTypeChar)
120  {
121  case 'B': //# +/- rf bunches
122  locReaction->Set_NumPlusMinusRFBunches(locFlagArg);
123  break;
124  case 'F': //kinfit enum value
125  locReaction->Set_KinFitType(DKinFitType(locFlagArg));
126  break;
127  case 'S': //# extra showers
128  locReaction->Set_MaxExtraShowers(locFlagArg);
129  break;
130  case 'T': //# extra tracks
131  locReaction->Set_MaxExtraGoodTracks(locFlagArg);
132  break;
133  case 'U': //# save unused hypotheses
134  locSaveUnusedHypotheses = (locFlagArg == 0) ? false : true;
135  break;
136  case 'M': //pid to not constrain mass of during kinfit
137  for(auto& locStep : locReaction->Get_ReactionSteps())
138  {
139  if(locStep->Get_InitialPID() != Particle_t(locFlagArg))
140  continue;
141  (const_cast<DReactionStep*>(locStep))->Set_KinFitConstrainInitMassFlag(false);
142  }
143  break;
144  default:
145  cout << "BUILDING DREACTION, FLAG " << locThisFlagString << " NOT RECOGNIZED." << endl;
146  continue;
147  }
148 
149  if(locUnderscoreIndex == string::npos)
150  break;
151  locRemainingFlagString = locRemainingFlagString.substr(locUnderscoreIndex + 1);
152  }
153 
154  locReaction->Enable_TTreeOutput(locTreeFileName, locSaveUnusedHypotheses); //true/false: do/don't save unused hypotheses
155 }
156 
157 //------------------
158 // evnt
159 //------------------
160 jerror_t DReaction_factory_ReactionFilter::evnt(JEventLoop* locEventLoop, uint64_t locEventNumber)
161 {
162  // DOCUMENTATION:
163  // ANALYSIS library: https://halldweb1.jlab.org/wiki/index.php/GlueX_Analysis_Software
164  // DReaction factory: https://halldweb1.jlab.org/wiki/index.php/Analysis_DReaction
165 
166  //INIT
167  dSourceComboP4Handler = new DSourceComboP4Handler(nullptr, false);
168  dSourceComboTimeHandler = new DSourceComboTimeHandler(nullptr, nullptr, nullptr);
169 
170  auto locInputTuple = Parse_Input();
171  auto locReactions = Create_Reactions(locInputTuple);
172 
173  // Loop over reactions
174  for(auto locReaction : locReactions)
175  {
176  auto locKinFitType = locReaction->Get_KinFitType();
177  auto locKinFitPerformedFlag = (locKinFitType != d_NoFit);
178  auto locP4Fit = ((locKinFitType != d_NoFit) && (locKinFitType != d_VertexFit) && (locKinFitType != d_SpacetimeFit));
179 
180  /**************************************************** Analysis Actions ****************************************************/
181 
182  // HISTOGRAM MASSES
183  Add_MassHistograms(locReaction, false, "PreKinFit"); //false: measured
184 
185  // IF NO KINFIT
186  if(!locKinFitPerformedFlag)
187  {
188  locReaction->Add_AnalysisAction(new DHistogramAction_PID(locReaction, false));
189  locReaction->Add_AnalysisAction(new DHistogramAction_ParticleComboKinematics(locReaction, false));
190  _data.push_back(locReaction); //Register the DReaction with the factory
191  continue;
192  }
193 
194  // KINEMATIC FIT
195  locReaction->Add_AnalysisAction(new DHistogramAction_KinFitResults(locReaction, 0.05)); //5% confidence level cut on pull histograms only
196 
197  //POST-KINFIT PID CUTS
198  Add_PostKinfitTimingCuts(locReaction);
199 
200  // HISTOGRAM MASSES, POST-KINFIT
201  if(locP4Fit)
202  {
203  Add_MassHistograms(locReaction, false, "PostKinFit"); //false: measured
204  if(locKinFitPerformedFlag)
205  Add_MassHistograms(locReaction, true, "PostKinFit_KinFit"); //true: kinfit
206  }
207 
208  // KINEMATICS
209  locReaction->Add_AnalysisAction(new DHistogramAction_ParticleComboKinematics(locReaction, true));
210 
211  _data.push_back(locReaction); //Register the DReaction with the factory
212  }
213 
214  return NOERROR;
215 }
216 
217 /********************************************************************************** CREATION FUNCTIONS ***********************************************************************************/
218 
220 {
221  auto locInclusiveFlag = (std::get<4>(locStepTuple) == DReactionStep::Get_ParticleIndex_Inclusive());
222  auto locBeamMissingFlag = (std::get<4>(locStepTuple) == DReactionStep::Get_ParticleIndex_Initial());
223 // auto locSecondBeamMissingFlag = (std::get<4>(locStepTuple) == DReactionStep::Get_ParticleIndex_SecondBeam());
224 
225  if(std::get<1>(locStepTuple) == Unknown) //no target or 2nd beam: pure decay
226  return (new DReactionStep(std::get<0>(locStepTuple), std::get<2>(locStepTuple), std::get<3>(locStepTuple), locInclusiveFlag));
227  else //rescattering decay //2nd beam is not allowed for now (and in fact, is undistinguishable in input scheme)
228  return (new DReactionStep(std::get<0>(locStepTuple), std::get<1>(locStepTuple), std::get<2>(locStepTuple), std::get<3>(locStepTuple), locInclusiveFlag, locBeamMissingFlag));
229 }
230 
231 void DReaction_factory_ReactionFilter::Create_Steps(DReaction* locReaction, DReactionStep* locCurrentStep, vector<DReactionStepTuple>& locDecayStepTuples)
232 {
233  //loop over final state particles of the current step. if the user has specified a decay for any of them, use that one. else generate decays as needed
234  for(auto& locFinalPID : locCurrentStep->Get_FinalPIDs(false)) //false: exclude missing
235  {
236  auto Find_DecayStep = [&locFinalPID](const DReactionStepTuple& locDecayStepTuple) -> bool{return (std::get<0>(locDecayStepTuple) == locFinalPID);};
237  auto locStepTupleIterator = std::find_if(locDecayStepTuples.begin(), locDecayStepTuples.end(), Find_DecayStep);
238 
239  //If not found, create default decay chain (if it's a detected particle (e.g. pion), this won't do anything)
240  DReactionStep* locDecayStep = nullptr;
241  if(locStepTupleIterator == locDecayStepTuples.end())
242  locDecayStep = Create_DefaultDecayStep(locFinalPID);
243  else //use user-specified decay, and erase it from the vector
244  {
245  locDecayStep = Create_ReactionStep(*locStepTupleIterator);
246  locDecayStepTuples.erase(locStepTupleIterator);
247  }
248  if(locDecayStep == nullptr)
249  continue; //must be a final-state particle
250 
251  //and, call this function again to see if we need to create decays for THOSE particles
252  locReaction->Add_ReactionStep(locDecayStep);
253  Create_Steps(locReaction, locDecayStep, locDecayStepTuples);
254  }
255 }
256 
257 vector<DReaction*> DReaction_factory_ReactionFilter::Create_Reactions(const map<size_t, tuple<string, string, string, vector<string>>>& locInputStrings)
258 {
259  //loop through channels, setting up the reactions
260  vector<DReaction*> locReactions;
261  for(auto& locReactionPair : locInputStrings)
262  {
263  auto& locNameString = std::get<0>(locReactionPair.second);
264  auto& locFirstStepString = std::get<1>(locReactionPair.second);
265  auto& locFlagString = std::get<2>(locReactionPair.second);
266  if(dDebugFlag)
267  cout << "name string, first step string, flag string, #decay strings: " << locNameString << ", " << locFirstStepString << ", " << locFlagString << ", " << std::get<3>(locReactionPair.second).size() << endl;
268 
269  DReactionStepTuple locFirstStepTuple;
270  if(!Parse_StepPIDString(locFirstStepString, locFirstStepTuple))
271  {
272  cout << "BUILDING DREACTIONS, INVALID PID STRING: " << locFirstStepString << endl;
273  continue;
274  }
275 
276  //see if we need to make our tree/reaction name
277  //automatic reaction naming scheme (if not manually specified):
278  //FirstStep__SpecifiedDecayStep1__SpecifiedDecayStep2_..._FlagString
279  //within a step: InitName1InitName2_FinalName1FinalName2... //name is from ShortName()
280  //also put "miss" in front of missing particles
281  auto locReactionName = (locNameString != "") ? locNameString : Create_StepNameString(locFirstStepTuple, true); //will continue below if needed
282 
283  //loop over steps
284  vector<DReactionStepTuple> locDecayStepTuples;
285  for(auto& locDecayStepString : std::get<3>(locReactionPair.second))
286  {
287  DReactionStepTuple locDecayStepTuple;
288  if(!Parse_StepPIDString(locDecayStepString, locDecayStepTuple))
289  {
290  cout << "BUILDING DREACTIONS, INVALID DECAY PID STRING: " << locDecayStepString << endl;
291  continue;
292  }
293  locDecayStepTuples.push_back(locDecayStepTuple);
294 
295  //expand name if needed
296  if(locNameString == "")
297  locReactionName += string("__") + Create_StepNameString(locDecayStepTuple, false);
298  }
299 
300  if((locNameString == "") && (locFlagString != "")) //add flags to name
301  locReactionName += string("__") + locFlagString;
302 
303  if(dDebugFlag)
304  cout << "ReactionFilter: reaction name: " << locReactionName << endl;
305 
306  //create dreaction & first step
307  auto locReaction = new DReaction(locReactionName);
308  auto locPrimaryStep = Create_ReactionStep(locFirstStepTuple);
309  locReaction->Add_ReactionStep(locPrimaryStep);
310 
311  //create following steps
312  Create_Steps(locReaction, locPrimaryStep, locDecayStepTuples);
313 
314  //Set flags
315  Set_Flags(locReaction, locFlagString);
316 
317  //save reaction
318  cout << "ReactionFilter: Reaction: " << locReactionName << endl;
319  DAnalysis::Print_Reaction(locReaction);
320 
321  locReactions.push_back(locReaction);
322  }
323 
324  return locReactions;
325 }
326 
327 /************************************************************** ACTIONS AND CUTS **************************************************************/
328 
329 void DReaction_factory_ReactionFilter::Add_MassHistograms(DReaction* locReaction, bool locUseKinFitResultsFlag, string locBaseUniqueName)
330 {
331  auto locKinFitType = locReaction->Get_KinFitType();
332  auto locP4Fit = ((locKinFitType != d_NoFit) && (locKinFitType != d_VertexFit) && (locKinFitType != d_SpacetimeFit));
333  auto locNumMissingParticles = locReaction->Get_MissingPIDs().size();
334 
335  size_t locNumInclusiveSteps = 0;
336  for(auto locReactionStep : locReaction->Get_ReactionSteps())
337  {
338  if(locReactionStep->Get_IsInclusiveFlag())
339  ++locNumInclusiveSteps;
340  }
341 
342  //invariant mass
343  set<Particle_t> locDecayPIDsUsed;
344  for(size_t loc_i = 1; loc_i < locReaction->Get_NumReactionSteps(); ++loc_i)
345  {
346  //do missing mass squared hists for every decaying and missing particle
347  auto locReactionStep = locReaction->Get_ReactionStep(loc_i);
348 
349  if(locP4Fit && locUseKinFitResultsFlag && locReactionStep->Get_KinFitConstrainInitMassFlag())
350  continue;
351 
352  auto locDecayPID = locReactionStep->Get_InitialPID();
353  if(locDecayPIDsUsed.find(locDecayPID) != locDecayPIDsUsed.end())
354  continue; //already done!
355  if(DAnalysis::Check_IfMissingDecayProduct(locReaction, loc_i))
356  continue;
357 
358  Create_InvariantMassHistogram(locReaction, locDecayPID, locUseKinFitResultsFlag, locBaseUniqueName);
359  locDecayPIDsUsed.insert(locDecayPID);
360  }
361 
362  //missing mass
363  for(size_t loc_i = 0; loc_i < locReaction->Get_NumReactionSteps(); ++loc_i)
364  {
365  auto locReactionStep = locReaction->Get_ReactionStep(loc_i);
366  set<Particle_t> locMissingDecayPIDsUsed;
367  for(size_t loc_j = 0; loc_j < locReactionStep->Get_NumFinalPIDs(); ++loc_j)
368  {
369  auto locPID = locReactionStep->Get_FinalPID(loc_j);
370 //cout << "i, j, pid, missing index: " << loc_i << ", " << loc_j << ", " << locPID << ", " << locReactionStep->Get_MissingParticleIndex() << endl;
371  if(locMissingDecayPIDsUsed.find(locPID) != locMissingDecayPIDsUsed.end())
372  continue;
373 
374  //check if missing particle
375  if(int(loc_j) == locReactionStep->Get_MissingParticleIndex())
376  {
377  if((locNumMissingParticles > 1) || (locNumInclusiveSteps > 0))
378  continue;
379  if(locUseKinFitResultsFlag && locP4Fit)
380  continue; //mass is constrained, will be a spike
381  Create_MissingMassSquaredHistogram(locReaction, locPID, locUseKinFitResultsFlag, locBaseUniqueName, 0, {});
382  }
383 
384  //check if decaying particle
385  auto locDecayStepIndex = DAnalysis::Get_DecayStepIndex(locReaction, loc_i, loc_j);
386 //cout << "decay step index: " << locDecayStepIndex << endl;
387  if(locDecayStepIndex <= 0)
388  continue; //nope
389 
390  //nothing can be missing anywhere, except in it's decay products
391  auto locMissingDecayProducts = DAnalysis::Get_MissingDecayProductIndices(locReaction, locDecayStepIndex);
392 //cout << "num missing total/decay: " << locNumMissingParticles << ", " << locMissingDecayProducts.size() << endl;
393  if((locNumMissingParticles - locMissingDecayProducts.size()) > 0)
394  continue; //nope
395 
396  //check inclusives, same thing
397  size_t locNumInclusiveDecayProductSteps = 0;
398  for(auto& locParticlePair : locMissingDecayProducts)
399  {
400  if(locParticlePair.second == DReactionStep::Get_ParticleIndex_Inclusive())
401  ++locNumInclusiveDecayProductSteps;
402  }
403 //cout << "num inclusives total/decay: " << locNumInclusiveSteps << ", " << locNumInclusiveDecayProductSteps << endl;
404  if((locNumInclusiveSteps - locNumInclusiveDecayProductSteps) > 0)
405  continue; //nope
406 
407 //cout << "p4 fit, use kinfit, constrain flag: " << locP4Fit << ", " << locUseKinFitResultsFlag << ", " << locReaction->Get_ReactionStep(locDecayStepIndex)->Get_KinFitConstrainInitMassFlag() << endl;
408  if(locP4Fit && locUseKinFitResultsFlag && locReaction->Get_ReactionStep(locDecayStepIndex)->Get_KinFitConstrainInitMassFlag())
409  continue; //constrained, will be a spike
410 
411  auto locFinalPIDs = locReactionStep->Get_FinalPIDs();
412  locFinalPIDs.erase(locFinalPIDs.begin() + loc_j);
413  deque<Particle_t> locMissingMassOffOfPIDs(locFinalPIDs.begin(), locFinalPIDs.end());
414  Create_MissingMassSquaredHistogram(locReaction, locPID, locUseKinFitResultsFlag, locBaseUniqueName, loc_i, locMissingMassOffOfPIDs);
415 
416  locMissingDecayPIDsUsed.insert(locPID);
417  }
418  }
419 
420  //if nothing missing, overall missing mass squared
421  if((locNumMissingParticles == 0) && (locNumInclusiveSteps == 0) && (!locUseKinFitResultsFlag || !locP4Fit))
422  Create_MissingMassSquaredHistogram(locReaction, Unknown, locUseKinFitResultsFlag, locBaseUniqueName, 0, {});
423 }
424 
426 {
427  locReaction->Add_AnalysisAction(new DHistogramAction_PID(locReaction, true));
428 
429  //Get, loop over detected PIDs in reaction
430  //Will have little effect except for on particles at detached vertices
431  auto locFinalPIDs = locReaction->Get_FinalPIDs(-1, false, false, d_AllCharges, false);
432  for(auto locPID : locFinalPIDs)
433  {
434  //Add timing cuts //false: measured data
435  auto locTimeCuts = dSourceComboTimeHandler->Get_TimeCuts(locPID);
436  for(auto& locSystemPair : locTimeCuts)
437  locReaction->Add_AnalysisAction(new DCutAction_PIDDeltaT(locReaction, true, locSystemPair.second->Eval(12.0), locPID, locSystemPair.first)); //true: kinfit results
438  }
439 }
440 
441 void DReaction_factory_ReactionFilter::Create_InvariantMassHistogram(DReaction* locReaction, Particle_t locPID, bool locUseKinFitResultsFlag, string locBaseUniqueName)
442 {
443  pair<float, float> locCutPair;
444  if(!dSourceComboP4Handler->Get_InvariantMassCuts(locPID, locCutPair))
445  return;
446 
447  //determine #bins
448  int locNumBins = int((locCutPair.second - locCutPair.first)*1000.0 + 0.001);
449  if(locNumBins < 200)
450  locNumBins *= 5; //get close to 1000 bins
451  if(locNumBins < 500)
452  locNumBins *= 2; //get close to 1000 bins
453 
454  //build name string
455  string locActionUniqueName = string(ParticleType(locPID)) + string("_") + locBaseUniqueName;
456 
457  //add histogram action
458  locReaction->Add_AnalysisAction(new DHistogramAction_InvariantMass(locReaction, locPID, locUseKinFitResultsFlag, locNumBins, locCutPair.first, locCutPair.second, locActionUniqueName));
459 }
460 
461 void DReaction_factory_ReactionFilter::Create_MissingMassSquaredHistogram(DReaction* locReaction, Particle_t locPID, bool locUseKinFitResultsFlag, string locBaseUniqueName, int locMissingMassOffOfStepIndex, const deque<Particle_t>& locMissingMassOffOfPIDs)
462 {
463  pair<TF1*, TF1*> locFuncPair;
464  if(!dSourceComboP4Handler->Get_MissingMassSquaredCuts(locPID, locFuncPair))
465  return;
466  auto locCutPair = std::make_pair(locFuncPair.first->Eval(12.0), locFuncPair.second->Eval(12.0)); //where it's likely widest
467 
468  //determine #bins
469  int locNumBins = int((locCutPair.second - locCutPair.first)*1000.0 + 0.001);
470  if(locNumBins < 200)
471  locNumBins *= 5; //get close to 1000 bins
472  if(locNumBins < 500)
473  locNumBins *= 2; //get close to 1000 bins
474 
475  //build name string
476  ostringstream locActionUniqueNameStream;
477  if((locPID == Unknown) && (locMissingMassOffOfStepIndex == 0))
478  locActionUniqueNameStream << locBaseUniqueName;
479  else if(locMissingMassOffOfStepIndex == 0)
480  locActionUniqueNameStream << ParticleType(locPID) << "_" << locBaseUniqueName;
481  else if(locPID == Unknown)
482  locActionUniqueNameStream << "Step" << locMissingMassOffOfStepIndex << "_" << locBaseUniqueName;
483  else
484  locActionUniqueNameStream << ParticleType(locPID) << "_Step" << locMissingMassOffOfStepIndex << "_" << locBaseUniqueName;
485 
486  if(dDebugFlag)
487  {
488  cout << "create miss mass squared action: off step index, kinfit flag, off pids: " << locMissingMassOffOfStepIndex << ", " << locUseKinFitResultsFlag;
489  for(auto& locPID : locMissingMassOffOfPIDs)
490  cout << ", " << locPID;
491  cout << endl;
492  }
493  //add histogram action
494  locReaction->Add_AnalysisAction(new DHistogramAction_MissingMassSquared(locReaction, locMissingMassOffOfStepIndex, locMissingMassOffOfPIDs, locUseKinFitResultsFlag, locNumBins, locCutPair.first, locCutPair.second, locActionUniqueNameStream.str()));
495 }
496 
497 /*********************************************************************************** UTILITY FUNCTIONS ***********************************************************************************/
498 
499 bool DReaction_factory_ReactionFilter::Convert_StringToPID(string locString, Particle_t& locPID, bool& locIsMissingFlag)
500 {
501  if(locString[0] == 'm')
502  {
503  locIsMissingFlag = true;
504  locString = locString.substr(1);
505  }
506  else
507  locIsMissingFlag = false;
508 
509  istringstream locIStream(locString);
510  int locPIDInt;
511  locIStream >> locPIDInt;
512  if(locIStream.fail())
513  return false;
514 
515  locPID = (Particle_t)locPIDInt;
516  return true;
517 }
518 
519 string DReaction_factory_ReactionFilter::Create_StepNameString(const DReactionStepTuple& locStepTuple, bool locFirstStepFlag)
520 {
521  string locNameString = "";
522  auto locFirstStepTargetPID = locFirstStepFlag ? std::get<1>(locStepTuple) : Unknown;
523  if(!locFirstStepFlag)
524  {
525  locNameString = ShortName(std::get<0>(locStepTuple));
526  auto locSecondPID = std::get<1>(locStepTuple);
527  if(locSecondPID != Unknown)
528  locNameString += ShortName(locSecondPID);
529  locNameString += "_";
530  }
531  for(auto& locFinalPID : std::get<2>(locStepTuple))
532  {
533  if(locFinalPID == locFirstStepTargetPID)
534  continue; //target PID is understood
535  locNameString += ShortName(locFinalPID);
536  }
537  auto locMissFinalPID = std::get<3>(locStepTuple);
538  if(locMissFinalPID != Unknown)
539  locNameString += string("miss") + ShortName(locMissFinalPID);
540 
541  if(std::get<4>(locStepTuple) == DReactionStep::Get_ParticleIndex_Inclusive())
542  locNameString += "inc";
543  return locNameString;
544 }
545 
546 map<size_t, tuple<string, string, string, vector<string>>> DReaction_factory_ReactionFilter::Parse_Input(void)
547 {
548  //Get input channel info
549  //key is reaction#, 1st string: name (if any) //2nd string: value for 1st decay step //3rd string: value for flags //string vector: value for decays
550  map<size_t, tuple<string, string, string, vector<string>>> locInputStrings;
551  map<string, string> locParameterMap; //parameter key - filter, value
552  gPARMS->GetParameters(locParameterMap, "Reaction"); //gets all parameters with this filter at the beginning of the key
553  for(auto locParamPair : locParameterMap)
554  {
555  if(dDebugFlag)
556  cout << "param pair: " << locParamPair.first << ", " << locParamPair.second << endl;
557 
558  //make sure that what follows "Reaction," up to the colon (if any) is a number
559  auto locColonIndex = locParamPair.first.find(':');
560  auto locPreColonName = locParamPair.first.substr(0, locColonIndex);
561  if(dDebugFlag)
562  cout << "colon index, pre-colon name: " << locColonIndex << ", " << locPreColonName << endl;
563 
564  istringstream locIStream(locPreColonName);
565  size_t locReactionNumber;
566  locIStream >> locReactionNumber;
567  if(locIStream.fail())
568  continue; //must be for a different use
569  if(dDebugFlag)
570  cout << "reaction #: " << locReactionNumber << endl;
571 
572  //hack so that don't get warning message about no default
573  string locKeyValue;
574  string locFullParamName = string("Reaction") + locParamPair.first; //have to add back on the filter
575  gPARMS->SetDefaultParameter(locFullParamName, locKeyValue);
576 
577  //save it in the input map
578  if(locColonIndex == string::npos)
579  std::get<1>(locInputStrings[locReactionNumber]) = locKeyValue;
580  else
581  {
582  auto locPostColonName = locParamPair.first.substr(locColonIndex + 1);
583  if(locPostColonName.substr(0, 4) == "Name")
584  std::get<0>(locInputStrings[locReactionNumber]) = locKeyValue;
585  else if(locPostColonName.substr(0, 5) == "Flags")
586  std::get<2>(locInputStrings[locReactionNumber]) = locKeyValue;
587  else
588  std::get<3>(locInputStrings[locReactionNumber]).push_back(locKeyValue);
589  }
590 
591  if(dDebugFlag)
592  {
593  cout << "reaction #, tuple strings: " << locReactionNumber << ", " << std::get<0>(locInputStrings[locReactionNumber]) << ", " << std::get<1>(locInputStrings[locReactionNumber]) << ", " << std::get<2>(locInputStrings[locReactionNumber]);
594  for(auto& locTempString : std::get<3>(locInputStrings[locReactionNumber]))
595  cout << ", " << locTempString;
596  cout << endl;
597  }
598 
599  }
600  return locInputStrings;
601 }
602 
604 {
605  //return tuple: initial pid, target/2nd-beam pid, detected final pids, missing final pid (if any), missing particle index
606  locStepTuple = std::make_tuple(Unknown, Unknown, vector<Particle_t>{}, Unknown, DReactionStep::Get_ParticleIndex_None());
607 
608  //find separator
609  auto locStateSeparationIndex = locStepString.find("__");
610  if(locStateSeparationIndex == string::npos)
611  return false;
612 
613  //start with initial state
614  {
615  auto locInitStateString = locStepString.substr(0, locStateSeparationIndex);
616  auto locUnderscoreIndex = locInitStateString.find("_");
617  auto locInitParticleString = (locUnderscoreIndex != string::npos) ? locInitStateString.substr(0, locUnderscoreIndex) : locInitStateString;
618 
619  Particle_t locPID;
620  bool locIsMissingFlag;
621  if(!Convert_StringToPID(locInitParticleString, locPID, locIsMissingFlag))
622  return false;
623  std::get<0>(locStepTuple) = locPID;
624  if(locIsMissingFlag)
625  std::get<4>(locStepTuple) = DReactionStep::Get_ParticleIndex_Initial();
626 
627  if(locUnderscoreIndex != string::npos)
628  {
629  locInitStateString = locInitStateString.substr(locUnderscoreIndex + 1);
630  if(!Convert_StringToPID(locInitStateString, locPID, locIsMissingFlag))
631  return false;
632  std::get<1>(locStepTuple) = locPID;
633  if(locIsMissingFlag)
634  std::get<4>(locStepTuple) = DReactionStep::Get_ParticleIndex_SecondBeam();
635  }
636  }
637 
638  string locRemainingStepString = locStepString.substr(locStateSeparationIndex + 2);
639  while(true)
640  {
641  auto locUnderscoreIndex = locRemainingStepString.find("_");
642  auto locParticleString = (locUnderscoreIndex != string::npos) ? locRemainingStepString.substr(0, locUnderscoreIndex) : locRemainingStepString;
643  if(dDebugFlag)
644  cout << "remaining string, underscore index, particle string: " << locRemainingStepString << ", " << locUnderscoreIndex << ", " << locParticleString << endl;
645 
646  Particle_t locPID = Unknown;
647  bool locIsMissingFlag = false;
648  if(!Convert_StringToPID(locParticleString, locPID, locIsMissingFlag))
649  {
650  cout << "BUILDING DREACTION, STEP PID STRING " << locStepString << " NOT RECOGNIZED." << endl;
651  return false;
652  }
653  if(locIsMissingFlag)
654  {
655  if(locPID != Unknown)
656  std::get<3>(locStepTuple) = locPID;
657  else
658  std::get<4>(locStepTuple) = DReactionStep::Get_ParticleIndex_Inclusive();
659  }
660  else
661  std::get<2>(locStepTuple).push_back(locPID);
662 
663  if(locUnderscoreIndex == string::npos)
664  break;
665  locRemainingStepString = locRemainingStepString.substr(locUnderscoreIndex + 1);
666  }
667 
668  if(std::get<3>(locStepTuple) != Unknown)
669  std::get<4>(locStepTuple) = std::get<2>(locStepTuple).size();
670 
671  if(dDebugFlag)
672  {
673  cout << "step tuple: init pid, 2nd init pid, #final pids, missing pid, missing index: " << std::get<0>(locStepTuple) << ", " << std::get<1>(locStepTuple);
674  cout << ", " << std::get<2>(locStepTuple).size() << ", " << std::get<3>(locStepTuple) << ", " << std::get<4>(locStepTuple) << endl;
675  }
676  return true;
677 }
void Add_ReactionStep(const DReactionStep *locReactionStep)
Definition: DReaction.h:48
bool Get_InvariantMassCuts(Particle_t locPID, pair< float, float > &locMinMaxCuts_GeV) const
void Set_MaxExtraGoodTracks(size_t locMaxExtraGoodTracks)
Definition: DReaction.h:59
void Enable_TTreeOutput(string locTTreeOutputFileName, bool locSaveUnusedFlag=false)
Definition: DReaction.h:163
DKinFitType Get_KinFitType(void) const
Definition: DReaction.h:79
bool Get_MissingMassSquaredCuts(Particle_t locPID, pair< TF1 *, TF1 * > &locMinMaxCuts_GeVSq) const
void Set_MaxExtraShowers(size_t locMaxExtraShowers)
Definition: DReaction.h:58
bool Get_KinFitConstrainInitMassFlag(void) const
Definition: DReactionStep.h:97
char string[256]
void Create_MissingMassSquaredHistogram(DReaction *locReaction, Particle_t locPID, bool locUseKinFitResultsFlag, string locBaseUniqueName, int locMissingMassOffOfStepIndex, const deque< Particle_t > &locMissingMassOffOfPIDs)
void Set_NumPlusMinusRFBunches(size_t locNumPlusMinusRFBunches)
Definition: DReaction.h:57
static char * ParticleType(Particle_t p)
Definition: particleType.h:142
void Add_PostKinfitTimingCuts(DReaction *locReaction)
map< size_t, tuple< string, string, string, vector< string > > > Parse_Input(void)
bool Check_IfMissingDecayProduct(const DReaction *locReaction, size_t locStepIndex)
Definition: DReaction.h:259
vector< Particle_t > Get_FinalPIDs(int locStepIndex=-1, bool locIncludeMissingFlag=true, bool locIncludeDecayingFlag=true, Charge_t locCharge=d_AllCharges, bool locIncludeDuplicatesFlag=true) const
Definition: DReaction.cc:17
void Set_KinFitType(DKinFitType locKinFitType)
Definition: DReaction.h:53
vector< pair< int, int > > Get_MissingDecayProductIndices(const DReaction *locReaction, size_t locStepIndex)
Definition: DReaction.h:239
void Create_InvariantMassHistogram(DReaction *locReaction, Particle_t locPID, bool locUseKinFitResultsFlag, string locBaseUniqueName)
void Set_Flags(DReaction *locReaction, string locRemainingFlagString)
Particle_t Get_InitialPID(void) const
Definition: DReactionStep.h:81
DReactionStep * Create_ReactionStep(const DReactionStepTuple &locStepTuple)
string Create_StepNameString(const DReactionStepTuple &locStepTuple, bool locFirstStepFlag)
map< DetectorSystem_t, TF1 * > Get_TimeCuts(Particle_t locPID) const
void Add_MassHistograms(DReaction *locReaction, bool locUseKinFitResultsFlag, string locBaseUniqueName="")
string Get_ReactionName(void) const
Definition: DReaction.h:75
Particle_t Get_FinalPID(size_t locIndex) const
Definition: DReactionStep.h:87
bool Convert_StringToPID(string locString, Particle_t &locPID, bool &locIsMissingFlag)
vector< DReaction * > Create_Reactions(const map< size_t, tuple< string, string, string, vector< string >>> &locInputStrings)
bool Parse_StepPIDString(string locStepString, DReactionStepTuple &locStepTuple)
vector< Particle_t > Get_MissingPIDs(int locStepIndex=-1, Charge_t locCharge=d_AllCharges, bool locIncludeDuplicatesFlag=true) const
Definition: DReaction.cc:46
jerror_t evnt(JEventLoop *locEventLoop, uint64_t locEventNumber)
static char * ShortName(Particle_t locPID)
Definition: particleType.h:443
vector< Particle_t > Get_FinalPIDs(bool locIncludeMissingFlag=true, Charge_t locCharge=d_AllCharges, bool locIncludeDuplicatesFlag=true) const
void Create_Steps(DReaction *locReaction, DReactionStep *locCurrentStep, vector< DReactionStepTuple > &locDecayStepTuples)
const DReactionStep * Get_ReactionStep(size_t locStepIndex) const
Definition: DReaction.h:84
int Get_DecayStepIndex(const DReaction *locReaction, size_t locStepIndex, size_t locParticleIndex)
Definition: DReaction.cc:135
void Add_AnalysisAction(DAnalysisAction *locAnalysisAction)
Definition: DReaction.h:50
vector< const DReactionStep * > Get_ReactionSteps(void) const
Definition: DReaction.h:85
tuple< Particle_t, Particle_t, vector< Particle_t >, Particle_t, int > DReactionStepTuple
size_t Get_NumReactionSteps(void) const
Definition: DReaction.h:83
DReactionStep * Create_DefaultDecayStep(Particle_t locPID)
void Print_Reaction(const DReaction *locReaction)
Definition: DReaction.h:172
Particle_t
Definition: particleType.h:12