Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DSelector_p2pi_trees.C
Go to the documentation of this file.
1 #include "DSelector_p2pi_trees.h"
2 
3 void DSelector_p2pi_trees::Init(TTree *locTree)
4 {
5  // USERS: IN THIS FUNCTION, ONLY MODIFY SECTIONS WITH A "USER" OR "EXAMPLE" LABEL. LEAVE THE REST ALONE.
6 
7  // The Init() function is called when the selector needs to initialize a new tree or chain.
8  // Typically here the branch addresses and branch pointers of the tree will be set.
9  // Init() will be called many times when running on PROOF (once per file to be processed).
10 
11  //USERS: SET OUTPUT FILE NAME //can be overriden by user in PROOF
12  dOutputFileName = "DSelector_p2pi_trees.root"; //"" for none
13  dOutputTreeFileName = "tree_DSelector_p2pi_trees.root"; //"" for none
14  //dFlatTreeFileName = ""; //output flat tree (one combo per tree entry), "" for none
15  //dFlatTreeName = ""; //if blank, default name will be chosen
16 
17  //Because this function gets called for each TTree in the TChain, we must be careful:
18  //We need to re-initialize the tree interface & branch wrappers, but don't want to recreate histograms
19  bool locInitializedPriorFlag = dInitializedFlag; //save whether have been initialized previously
20  DSelector::Init(locTree); //This must be called to initialize wrappers for each new TTree
21  //gDirectory now points to the output file with name dOutputFileName (if any)
22  if(locInitializedPriorFlag)
23  return; //have already created histograms, etc. below: exit
24 
27 
28  /*********************************** EXAMPLE USER INITIALIZATION: ANALYSIS ACTIONS **********************************/
29 
30  //ANALYSIS ACTIONS: //Executed in order if added to dAnalysisActions
31  //false/true below: use measured/kinfit data
32 
33  //PID
34  dAnalysisActions.push_back(new DHistogramAction_ParticleID(dComboWrapper, false));//false: use measured data
35  dAnalysisActions.push_back(new DHistogramAction_ParticleID(dComboWrapper, true, "KinFit")); //true: use kinfit data;
36  //below: value: +/- N ns, Unknown: All PIDs, SYS_NULL: all timing systems
37  dAnalysisActions.push_back(new DCutAction_PIDDeltaT(dComboWrapper, false, 2.0, Unknown, SYS_BCAL));
38 
39  //MASSES
40  //dAnalysisActions.push_back(new DHistogramAction_InvariantMass(dComboWrapper, false, Lambda, 1000, 1.0, 1.2, "Lambda"));
41  //dAnalysisActions.push_back(new DHistogramAction_MissingMassSquared(dComboWrapper, false, 1000, -0.1, 0.1));
42 
43  //KINFIT RESULTS
44  dAnalysisActions.push_back(new DHistogramAction_KinFitResults(dComboWrapper));
45 
46  //CUT MISSING MASS
47  //dAnalysisActions.push_back(new DCutAction_MissingMassSquared(dComboWrapper, false, -0.03, 0.02));
48 
49  //BEAM ENERGY
50  dAnalysisActions.push_back(new DHistogramAction_BeamEnergy(dComboWrapper, false));
51  //dAnalysisActions.push_back(new DCutAction_BeamEnergy(dComboWrapper, false, 8.4, 9.05));
52 
53  //KINEMATICS
54  dAnalysisActions.push_back(new DHistogramAction_ParticleComboKinematics(dComboWrapper, false));
55 
56  //INITIALIZE ACTIONS
57  //If you create any actions that you want to run manually (i.e. don't add to dAnalysisActions), be sure to initialize them here as well
58  Initialize_Actions();
59 
60  /******************************** EXAMPLE USER INITIALIZATION: STAND-ALONE HISTOGRAMS *******************************/
61 
62  //EXAMPLE MANUAL HISTOGRAMS:
63  dHist_MissingMassSquared = new TH1I("MissingMassSquared", ";Missing Mass Squared (GeV/c^{2})^{2}", 600, -0.24, 0.24);
64  dHist_BeamEnergy = new TH1I("BeamEnergy", ";Beam Energy (GeV)", 600, 0.0, 12.0);
65  dHist_pMomentumMeasured = new TH1I("pMomentumMeasured", ";p Momentum Measured (GeV)", 100, 0.0, 2);
66  dHist_piplusMomentumMeasured = new TH1I("piplusMomentumMeasured", ";#pi^{+} Momentum Measured (GeV)", 600, 0.0, 12);
67  dHist_piminusMomentumMeasured = new TH1I("piminusMomentumMeasured", ";#pi^{-} Momentum Measured (GeV)", 600, 0.0, 12);
68 
69  dHist_Proton_dEdx_P = new TH2I("Proton_dEdx_P", " ;p_{proton} GeV/c; dE/dx (keV/cm)", 250, 0.0, 5.0, 250, 0.0, 25.);
70  dHist_KinFitChiSq = new TH1I("KinFitChiSq", ";Kinematic Fit #chi^{2}/NDF", 250, 0., 25.);
71  dHist_KinFitCL = new TH1I("KinFitCL", ";Kinematic Fit Confidence Level", 100, 0., 1.);
72 
73  dHist_M2pi = new TH1I("M2pi", ";M_{#pi^{+}#pi^{-}} (GeV/c^{2})", 600, 0, 1.2);
74  dHist_t = new TH1I("t", ";|t| (GeV/c)^{2}", 100, 0.0, 2.0);
75  dHist_CosTheta_Psi = new TH2I("CosTheta_Psi", "; #psi; cos#theta", 360, -180., 180, 200, -1., 1.);
76  dHist_phi = new TH1I("phi", ";phi (degrees)", 360,-180,180);
77  dHist_Phi = new TH1I("Phi", ";Phi (degrees)", 360,-180,180);
78  dHist_psi = new TH1I("psi", ";psi (degrees)", 360,-180,180);
79 
80  dHist_pDeltap = new TH1I("pDeltap","; proton: Thrown p - KinFit p/Thrown p",100,-0.2,0.2);
81  dHist_pipDeltap = new TH1I("pipDeltap","; #pi^{+}: Thrown p - KinFit p/Thrown p",100,-0.2,0.2);
82  dHist_pimDeltap = new TH1I("pimDeltap","; #pi^{-}: Thrown p - KinFit p/ Thrown p",100,-0.2,0.2);
83 
84  dHist_pDeltap_Measured = new TH1I("pDeltap_Measured","; proton: Thrown p - Measured p/Thrown p",100,-0.2,0.2);
85  dHist_pipDeltap_Measured = new TH1I("pipDeltap_Measured","; #pi^{+}: Thrown p - Measured p/Thrown p",100,-0.2,0.2);
86  dHist_pimDeltap_Measured = new TH1I("pimDeltap_Measured","; #pi^{-}: Thrown p - Measured p/ Thrown p",100,-0.2,0.2);
87 
88  // EXAMPLE CUT PARAMETERS:
89  fMinProton_dEdx = new TF1("fMinProton_dEdx", "exp(-1.*[0]*x + [1]) + [2]", 0., 10.);
90  fMinProton_dEdx->SetParameters(4.0, 2.5, 1.25);
91  fMaxPion_dEdx = new TF1("fMaxPion_dEdx", "exp(-1.*[0]*x + [1]) + [2]", 0., 10.);
92  fMaxPion_dEdx->SetParameters(4.0, 2.0, 2.5);
93  dMinKinFitCL = 5.73303e-7; //5.73303e-7;
94  dMaxKinFitChiSq = 5.0;
95  dMinBeamEnergy = 8.4;
96  dMaxBeamEnergy = 9.0;
97  dMin2piMass = 0.5;
98  dMax2piMass = 1.1;
99  // dMinMissingMassSquared = -0.04;
100  // dMaxMissingMassSquared = 0.04;
103 
104 
105 
106  /************************** EXAMPLE USER INITIALIZATION: CUSTOM OUTPUT BRANCHES - MAIN TREE *************************/
107 
108  //EXAMPLE MAIN TREE CUSTOM BRANCHES (OUTPUT ROOT FILE NAME MUST FIRST BE GIVEN!!!! (ABOVE: TOP)):
109  //The type for the branch must be included in the brackets
110  //1st function argument is the name of the branch
111  //2nd function argument is the name of the branch that contains the size of the array (for fundamentals only)
112  /*
113  dTreeInterface->Create_Branch_Fundamental<Int_t>("my_int"); //fundamental = char, int, float, double, etc.
114  dTreeInterface->Create_Branch_FundamentalArray<Int_t>("my_int_array", "my_int");
115  dTreeInterface->Create_Branch_FundamentalArray<Float_t>("my_combo_array", "NumCombos");
116  dTreeInterface->Create_Branch_NoSplitTObject<TLorentzVector>("my_p4");
117  dTreeInterface->Create_Branch_ClonesArray<TLorentzVector>("my_p4_array");
118  */
119 
120  /************************** EXAMPLE USER INITIALIZATION: CUSTOM OUTPUT BRANCHES - FLAT TREE *************************/
121 
122  //EXAMPLE FLAT TREE CUSTOM BRANCHES (OUTPUT ROOT FILE NAME MUST FIRST BE GIVEN!!!! (ABOVE: TOP)):
123  //The type for the branch must be included in the brackets
124  //1st function argument is the name of the branch
125  //2nd function argument is the name of the branch that contains the size of the array (for fundamentals only)
126  /*
127  dFlatTreeInterface->Create_Branch_Fundamental<Int_t>("flat_my_int"); //fundamental = char, int, float, double, etc.
128  dFlatTreeInterface->Create_Branch_FundamentalArray<Int_t>("flat_my_int_array", "flat_my_int");
129  dFlatTreeInterface->Create_Branch_NoSplitTObject<TLorentzVector>("flat_my_p4");
130  dFlatTreeInterface->Create_Branch_ClonesArray<TLorentzVector>("flat_my_p4_array");
131  */
132 
133  /************************************* ADVANCED EXAMPLE: CHOOSE BRANCHES TO READ ************************************/
134 
135  //TO SAVE PROCESSING TIME
136  //If you know you don't need all of the branches/data, but just a subset of it, you can speed things up
137  //By default, for each event, the data is retrieved for all branches
138  //If you know you only need data for some branches, you can skip grabbing data from the branches you don't need
139  //Do this by doing something similar to the commented code below
140 
141  //dTreeInterface->Clear_GetEntryBranches(); //now get none
142  //dTreeInterface->Register_GetEntryBranch("Proton__P4"); //manually set the branches you want
143 }
144 
145 Bool_t DSelector_p2pi_trees::Process(Long64_t locEntry)
146 {
147  // The Process() function is called for each entry in the tree. The entry argument
148  // specifies which entry in the currently loaded tree is to be processed.
149  //
150  // This function should contain the "body" of the analysis. It can contain
151  // simple or elaborate selection criteria, run algorithms on the data
152  // of the event and typically fill histograms.
153  //
154  // The processing can be stopped by calling Abort().
155  // Use fStatus to set the return value of TTree::Process().
156  // The return value is currently not used.
157 
158  //CALL THIS FIRST
159  DSelector::Process(locEntry); //Gets the data from the tree for the entry
160  //cout << "RUN " << Get_RunNumber() << ", EVENT " << Get_EventNumber() << endl;
161  //TLorentzVector locProductionX4 = Get_X4_Production();
162 
163  /******************************************** GET POLARIZATION ORIENTATION ******************************************/
164 
165  //Only if the run number changes
166  //RCDB environment must be setup in order for this to work! (Will return false otherwise)
167  UInt_t locRunNumber = Get_RunNumber();
168  if(locRunNumber != dPreviousRunNumber)
169  {
170  dIsPolarizedFlag = dAnalysisUtilities.Get_IsPolarizedBeam(locRunNumber, dIsPARAFlag);
171  dPreviousRunNumber = locRunNumber;
172  }
173 
174  /********************************************* SETUP UNIQUENESS TRACKING ********************************************/
175 
176  //ANALYSIS ACTIONS: Reset uniqueness tracking for each action
177  //For any actions that you are executing manually, be sure to call Reset_NewEvent() on them here
178  Reset_Actions_NewEvent();
179 
180  //PREVENT-DOUBLE COUNTING WHEN HISTOGRAMMING
181  //Sometimes, some content is the exact same between one combo and the next
182  //e.g. maybe two combos have different beam particles, but the same data for the final-state
183  //When histogramming, you don't want to double-count when this happens: artificially inflates your signal (or background)
184  //So, for each quantity you histogram, keep track of what particles you used (for a given combo)
185  //Then for each combo, just compare to what you used before, and make sure it's unique
186 
187  //EXAMPLE 1: Particle-specific info:
188  set<Int_t> locUsedSoFar_BeamEnergy; //Int_t: Unique ID for beam particles. set: easy to use, fast to search
189  set<Int_t> locUsedSoFar_Proton, locUsedSoFar_PiPlus, locUsedSoFar_PiMinus;
190 
191  //EXAMPLE 2: Combo-specific info:
192  //In general: Could have multiple particles with the same PID: Use a set of Int_t's
193  //In general: Multiple PIDs, so multiple sets: Contain within a map
194  //Multiple combos: Contain maps within a set (easier, faster to search)
195  set<map<Particle_t, set<Int_t> > > locUsedSoFar_MissingMass, locUsedSoFar_2pi, locUsedSoFar_Angles;
196 
197  //INSERT USER ANALYSIS UNIQUENESS TRACKING HERE
198 
199  /**************************************** EXAMPLE: FILL CUSTOM OUTPUT BRANCHES **************************************/
200 
201  /*
202  Int_t locMyInt = 7;
203  dTreeInterface->Fill_Fundamental<Int_t>("my_int", locMyInt);
204 
205  TLorentzVector locMyP4(4.0, 3.0, 2.0, 1.0);
206  dTreeInterface->Fill_TObject<TLorentzVector>("my_p4", locMyP4);
207 
208  for(int loc_i = 0; loc_i < locMyInt; ++loc_i)
209  dTreeInterface->Fill_Fundamental<Int_t>("my_int_array", 3*loc_i, loc_i); //2nd argument = value, 3rd = array index
210  */
211 
212  /******************************************* LOOP OVER THROWN DATA (OPTIONAL) ***************************************/
213 
214 
215  //Thrown beam: just use directly
216  if(dThrownBeam != NULL)
217  double locEbeam_Thrown = dThrownBeam->Get_P4().E();
218 
219  //Loop over throwns
220  TLorentzVector locProtonP4_Thrown;
221  TLorentzVector locPiPlusP4_Thrown;
222  TLorentzVector locPiMinusP4_Thrown;
223 
224  for(UInt_t loc_i = 0; loc_i < Get_NumThrown(); ++loc_i)
225  {
226  //Set branch array indices corresponding to this particle
227  dThrownWrapper->Set_ArrayIndex(loc_i);
228  Particle_t thrown_pid = dThrownWrapper->Get_PID();
229  // cout << " loc_i=" << loc_i << " thrown_pid=" << thrown_pid << endl;
230  TLorentzVector locP4_Thrown = dThrownWrapper->Get_P4();
231  if (loc_i == 0) locProtonP4_Thrown = locP4_Thrown; // assume order of particles as PID is zero at the moment
232  if (loc_i == 1) locPiPlusP4_Thrown = locP4_Thrown;
233  if (loc_i == 2) locPiMinusP4_Thrown = locP4_Thrown;
234 
235  }
236  /*locProtonP4_Thrown.Print();
237  locPiPlusP4_Thrown.Print();
238  locPiMinusP4_Thrown.Print();
239  cout << endl;
240  */
241 
242 
243 
244  /************************************************* LOOP OVER COMBOS *************************************************/
245 
246  //Loop over combos
247  for(UInt_t loc_i = 0; loc_i < Get_NumCombos(); ++loc_i)
248  {
249  //Set branch array indices for combo and all combo particles
250  dComboWrapper->Set_ComboIndex(loc_i);
251 
252  // Is used to indicate when combos have been cut
253  if(dComboWrapper->Get_IsComboCut()) // Is false when tree originally created
254  continue; // Combo has been cut previously
255 
256  /********************************************** GET PARTICLE INDICES *********************************************/
257 
258  //Used for tracking uniqueness when filling histograms, and for determining unused particles
259 
260  //Step 0
261  Int_t locBeamID = dComboBeamWrapper->Get_BeamID();
262  Int_t locProtonTrackID = dProtonWrapper->Get_TrackID();
263  Int_t locPiPlusTrackID = dPiPlusWrapper->Get_TrackID();
264  Int_t locPiMinusTrackID = dPiMinusWrapper->Get_TrackID();
265 
266  /*********************************************** GET FOUR-MOMENTUM **********************************************/
267 
268  // Get P4's: //is kinfit if kinfit performed, else is measured
269  //dTargetP4 is target p4
270  //Step 0
271  TLorentzVector locBeamP4 = dComboBeamWrapper->Get_P4();
272  TLorentzVector locProtonP4 = dProtonWrapper->Get_P4();
273  TLorentzVector locPiPlusP4 = dPiPlusWrapper->Get_P4();
274  TLorentzVector locPiMinusP4 = dPiMinusWrapper->Get_P4();
275 
276  // Get Measured P4's:
277  //Step 0
278  TLorentzVector locBeamP4_Measured = dComboBeamWrapper->Get_P4_Measured();
279  TLorentzVector locProtonP4_Measured = dProtonWrapper->Get_P4_Measured();
280  TLorentzVector locPiPlusP4_Measured = dPiPlusWrapper->Get_P4_Measured();
281  TLorentzVector locPiMinusP4_Measured = dPiMinusWrapper->Get_P4_Measured();
282 
283  /********************************************* COMBINE FOUR-MOMENTUM ********************************************/
284 
285  // DO YOUR STUFF HERE
286 
287  // Combine 4-vectors
288  TLorentzVector locMissingP4_Measured = locBeamP4_Measured + dTargetP4;
289  locMissingP4_Measured -= locProtonP4_Measured + locPiPlusP4_Measured + locPiMinusP4_Measured;
290  TLorentzVector loc2piP4 = locPiPlusP4 + locPiMinusP4;
291 
292 
293  cout << "MM2 =" << locMissingP4_Measured.M2() << endl;
294 
295 
296 
297  /******************************************** EXECUTE ANALYSIS ACTIONS *******************************************/
298 
299  // Loop through the analysis actions, executing them in order for the active particle combo
300  if(!Execute_Actions()) //if the active combo fails a cut, IsComboCutFlag automatically set
301  continue;
302 
303  //if you manually execute any actions, and it fails a cut, be sure to call:
304  //dComboWrapper->Set_IsComboCut(true);
305 
306  /**************************************** EXAMPLE: FILL CUSTOM OUTPUT BRANCHES **************************************/
307 
308  /*
309  TLorentzVector locMyComboP4(8.0, 7.0, 6.0, 5.0);
310  //for arrays below: 2nd argument is value, 3rd is array index
311  //NOTE: By filling here, AFTER the cuts above, some indices won't be updated (and will be whatever they were from the last event)
312  //So, when you draw the branch, be sure to cut on "IsComboCut" to avoid these.
313  dTreeInterface->Fill_Fundamental<Float_t>("my_combo_array", -2*loc_i, loc_i);
314  dTreeInterface->Fill_TObject<TLorentzVector>("my_p4_array", locMyComboP4, loc_i);
315  */
316 
317 
318  /**************************************** EXAMPLE: PID CUT ACTION ************************************************/
319 
320 
321  // Proton CDC dE/dx histogram and cut
322  double locProton_dEdx_CDC = dProtonWrapper->Get_dEdx_CDC()*1e6;
323  if(locProton_dEdx_CDC < fMinProton_dEdx->Eval(locProtonP4.P())) {
324  dComboWrapper->Set_IsComboCut(true);
325  continue;
326  }
327 
328  // Pi+/- CDC dE/dx histogram cut (histograms in HistComboPID action)
329  double locPiPlus_dEdx_CDC = dPiPlusWrapper->Get_dEdx_CDC()*1e6;
330  double locPiMinus_dEdx_CDC = dPiMinusWrapper->Get_dEdx_CDC()*1e6;
331  if(locPiPlus_dEdx_CDC > fMaxPion_dEdx->Eval(locPiPlusP4.P()) || locPiMinus_dEdx_CDC > fMaxPion_dEdx->Eval(locPiMinusP4.P())) {
332  dComboWrapper->Set_IsComboCut(true);
333  continue;
334  }
335 
336 
337  /************************************ EXAMPLE: SELECTION CUTS AND HISTOGRAMS ************************************/
338 
339  //Missing Mass Squared
340  double locMissingMassSquared = locMissingP4_Measured.M2();
341 
342  //Uniqueness tracking: Build the map of particles used for the missing mass
343  //For beam: Don't want to group with final-state photons. Instead use "Unknown" PID (not ideal, but it's easy).
344  map<Particle_t, set<Int_t> > locUsedThisCombo_MissingMass;
345  locUsedThisCombo_MissingMass[Unknown].insert(locBeamID); //beam
346  locUsedThisCombo_MissingMass[Proton].insert(locProtonTrackID);
347  locUsedThisCombo_MissingMass[PiPlus].insert(locPiPlusTrackID);
348  locUsedThisCombo_MissingMass[PiMinus].insert(locPiMinusTrackID);
349 
350  // beam energy cut for SDME
351  if(locBeamP4.E() < dMinBeamEnergy || locBeamP4.E() > dMaxBeamEnergy) {
352  dComboWrapper->Set_IsComboCut(true);
353  continue;
354  }
355 
356  // Cut on Missing mass
357  if((locMissingMassSquared < dMinMissingMassSquared ) || (locMissingMassSquared > dMaxMissingMassSquared)){
358  dComboWrapper->Set_IsComboCut(true);
359  continue;
360  }
361 
362  // kinematic fit CL cut
363  dHist_KinFitChiSq->Fill(dComboWrapper->Get_ChiSq_KinFit()/dComboWrapper->Get_NDF_KinFit());
364  dHist_KinFitCL->Fill(dComboWrapper->Get_ConfidenceLevel_KinFit());
365  if(dComboWrapper->Get_ConfidenceLevel_KinFit() <= dMinKinFitCL) {
366  dComboWrapper->Set_IsComboCut(true);
367  continue;
368  }
369 
370  // rho mass histogram and cut
371  map<Particle_t, set<Int_t> > locUsedThisCombo_2piMass;
372  locUsedThisCombo_2piMass[PiPlus].insert(locPiPlusTrackID);
373  locUsedThisCombo_2piMass[PiMinus].insert(locPiMinusTrackID);
374  if(loc2piP4.M() < dMin2piMass || loc2piP4.M() > dMax2piMass) {
375  dComboWrapper->Set_IsComboCut(true);
376  continue;
377  }
378  if(locUsedSoFar_2pi.find(locUsedThisCombo_2piMass) == locUsedSoFar_2pi.end())
379  {
380  dHist_M2pi->Fill(loc2piP4.M());
381  locUsedSoFar_2pi.insert(locUsedThisCombo_2piMass);
382  }
383 
384 
385  /**************************************** EXAMPLE: HISTOGRAM energies and momenta *****************************************/
386 
387  //Histogram beam energy (if haven't already)
388  if(locUsedSoFar_BeamEnergy.find(locBeamID) == locUsedSoFar_BeamEnergy.end())
389  {
390  dHist_BeamEnergy->Fill(locBeamP4.E());
391  locUsedSoFar_BeamEnergy.insert(locBeamID);
392  }
393 
394  //compare to what's been used so far
395  if(locUsedSoFar_MissingMass.find(locUsedThisCombo_MissingMass) == locUsedSoFar_MissingMass.end())
396  {
397  //unique missing mass combo: histogram it, and register this combo of particles
398  dHist_MissingMassSquared->Fill(locMissingMassSquared);
399  locUsedSoFar_MissingMass.insert(locUsedThisCombo_MissingMass);
400  }
401 
402 
403  if(locUsedSoFar_Proton.find(locProtonTrackID) == locUsedSoFar_Proton.end())
404  {
405  dHist_pMomentumMeasured->Fill(locProtonP4.Vect().Mag());
406  dHist_Proton_dEdx_P->Fill(locProtonP4.P(), locProton_dEdx_CDC);
407  dHist_pDeltap->Fill(locProtonP4_Thrown.Vect().Mag() > 0? (locProtonP4_Thrown.Vect().Mag()-locProtonP4.Vect().Mag())/locProtonP4_Thrown.Vect().Mag() : 0);
408  dHist_pDeltap_Measured->Fill(locProtonP4_Thrown.Vect().Mag() > 0? (locProtonP4_Thrown.Vect().Mag()-locProtonP4_Measured.Vect().Mag())/locProtonP4_Thrown.Vect().Mag() : 0);
409  locUsedSoFar_Proton.insert(locProtonTrackID);
410  }
411 
412  if(locUsedSoFar_PiPlus.find(locPiPlusTrackID) == locUsedSoFar_PiPlus.end())
413  {
414  dHist_piplusMomentumMeasured->Fill(locPiPlusP4.Vect().Mag());
415  dHist_pipDeltap->Fill(locPiPlusP4_Thrown.Vect().Mag() > 0? (locPiPlusP4_Thrown.Vect().Mag()-locPiPlusP4.Vect().Mag())/locPiPlusP4_Thrown.Vect().Mag() : 0);
416  dHist_pipDeltap_Measured->Fill(locPiPlusP4_Thrown.Vect().Mag() > 0? (locPiPlusP4_Thrown.Vect().Mag()-locPiPlusP4_Measured.Vect().Mag())/locPiPlusP4_Thrown.Vect().Mag() : 0);
417  locUsedSoFar_PiPlus.insert(locPiPlusTrackID);
418  }
419 
420  if(locUsedSoFar_PiMinus.find(locPiMinusTrackID) == locUsedSoFar_PiMinus.end())
421  {
422  dHist_piminusMomentumMeasured->Fill(locPiMinusP4.Vect().Mag());
423  dHist_pimDeltap->Fill(locPiMinusP4_Thrown.Vect().Mag() > 0? (locPiMinusP4_Thrown.Vect().Mag()-locPiMinusP4.Vect().Mag())/locPiMinusP4_Thrown.Vect().Mag() : 0);
424  dHist_pimDeltap_Measured->Fill(locPiMinusP4_Thrown.Vect().Mag() > 0? (locPiMinusP4_Thrown.Vect().Mag()-locPiMinusP4_Measured.Vect().Mag())/locPiMinusP4_Thrown.Vect().Mag() : 0);
425  locUsedSoFar_PiMinus.insert(locPiMinusTrackID);
426  }
427 
428  cout << "Ebeam Thrown P4.E=" << dThrownBeam->Get_P4().E() << " Kinfit P4.E=" << locBeamP4.E() << " P4 Measured =" << locBeamP4_Measured.E() << endl;
429  cout << "Proton Thrown P4.E=" << locProtonP4_Thrown.E() << " Kinfit P4.E=" << locProtonP4.E() << " P4 Measured =" << locProtonP4_Measured.E() << " CL=" << dComboWrapper->Get_ConfidenceLevel_KinFit() << endl;
430  cout << "PiPlus Thrown P4.E=" << locPiPlusP4_Thrown.E() << " Kinfit P4.E=" << locPiPlusP4.E() << " P4 Measured =" << locPiPlusP4_Measured.E() << endl;
431  cout << "PiMinus Thrown P4.E=" << locPiMinusP4_Thrown.E() << " Kinfit P4.E=" << locPiMinusP4.E() << " P4 Measured =" << locPiMinusP4_Measured.E() << endl << endl;
432 
433  // calculate kinematic and angular variables
434  double t = (locProtonP4 - dTargetP4).M2();
435  TLorentzRotation resonanceBoost( -loc2piP4.BoostVector() ); // boost into 2pi frame
436  TLorentzVector beam_res = resonanceBoost * locBeamP4;
437  TLorentzVector recoil_res = resonanceBoost * locProtonP4;
438  TLorentzVector p1_res = resonanceBoost * locPiPlusP4;
439  TLorentzVector p2_res = resonanceBoost * locPiMinusP4;
440 
441 
442  // normal to the production plane
443  TVector3 y = (locBeamP4.Vect().Unit().Cross(-locProtonP4.Vect().Unit())).Unit();
444 
445  // choose helicity frame: z-axis opposite recoil proton in rho rest frame
446  TVector3 z = -1. * recoil_res.Vect().Unit();
447  TVector3 x = y.Cross(z).Unit();
448  TVector3 angles( (p1_res.Vect()).Dot(x),
449  (p1_res.Vect()).Dot(y),
450  (p1_res.Vect()).Dot(z) );
451 
452  double CosTheta = angles.CosTheta();
453 
454  double phi = angles.Phi();
455 
456  TVector3 eps(1.0, 0.0, 0.0); // beam polarization vector
457  double Phi = atan2(y.Dot(eps), locBeamP4.Vect().Unit().Dot(eps.Cross(y)));
458 
459  double psi = phi - Phi;
460  if(psi < -3.14159) psi += 2*3.14159;
461  if(psi > 3.14159) psi -= 2*3.14159;
462 
463  // cout << " phi=" << phi << " Phi=" << Phi << " psi=" << psi << endl;
464 
465  map<Particle_t, set<Int_t> > locUsedThisCombo_Angles;
466  locUsedThisCombo_Angles[Unknown].insert(locBeamID); //beam
467  locUsedThisCombo_Angles[Proton].insert(locProtonTrackID);
468  locUsedThisCombo_Angles[PiPlus].insert(locPiPlusTrackID);
469  locUsedThisCombo_Angles[PiMinus].insert(locPiMinusTrackID);
470  if(locUsedSoFar_Angles.find(locUsedThisCombo_Angles) == locUsedSoFar_Angles.end())
471  {
472  dHist_t->Fill(fabs(t));
473  dHist_CosTheta_Psi->Fill(psi*180./3.14159, CosTheta);
474  dHist_phi->Fill(phi*180./3.14159);
475  dHist_Phi->Fill(Phi*180./3.14159);
476  dHist_psi->Fill(psi*180./3.14159);
477  locUsedSoFar_Angles.insert(locUsedThisCombo_Angles);
478  }
479  }
480 
481  /****************************************** FILL FLAT TREE (IF DESIRED) ******************************************/
482 
483  /*
484  //FILL ANY CUSTOM BRANCHES FIRST!!
485  Int_t locMyInt_Flat = 7;
486  dFlatTreeInterface->Fill_Fundamental<Int_t>("flat_my_int", locMyInt_Flat);
487 
488  TLorentzVector locMyP4_Flat(4.0, 3.0, 2.0, 1.0);
489  dFlatTreeInterface->Fill_TObject<TLorentzVector>("flat_my_p4", locMyP4_Flat);
490 
491  for(int loc_j = 0; loc_j < locMyInt_Flat; ++loc_j)
492  {
493  dFlatTreeInterface->Fill_Fundamental<Int_t>("flat_my_int_array", 3*loc_j, loc_j); //2nd argument = value, 3rd = array index
494  TLorentzVector locMyComboP4_Flat(8.0, 7.0, 6.0, 5.0);
495  dFlatTreeInterface->Fill_TObject<TLorentzVector>("flat_my_p4_array", locMyComboP4_Flat, loc_j);
496  }
497 
498 
499  //FILL FLAT TREE
500  //Fill_FlatTree(); //for the active combo
501  } // end of combo loop
502  */
503 
504  //FILL HISTOGRAMS: Num combos / events surviving actions
505  Fill_NumCombosSurvivedHists();
506 
507  /****************************************** LOOP OVER OTHER ARRAYS (OPTIONAL) ***************************************/
508 /*
509  //Loop over beam particles (note, only those appearing in combos are present)
510  for(UInt_t loc_i = 0; loc_i < Get_NumBeam(); ++loc_i)
511  {
512  //Set branch array indices corresponding to this particle
513  dBeamWrapper->Set_ArrayIndex(loc_i);
514 
515  //Do stuff with the wrapper here ...
516  }
517 
518  //Loop over charged track hypotheses
519  for(UInt_t loc_i = 0; loc_i < Get_NumChargedHypos(); ++loc_i)
520  {
521  //Set branch array indices corresponding to this particle
522  dChargedHypoWrapper->Set_ArrayIndex(loc_i);
523 
524  //Do stuff with the wrapper here ...
525  }
526 
527  //Loop over neutral particle hypotheses
528  for(UInt_t loc_i = 0; loc_i < Get_NumNeutralHypos(); ++loc_i)
529  {
530  //Set branch array indices corresponding to this particle
531  dNeutralHypoWrapper->Set_ArrayIndex(loc_i);
532 
533  //Do stuff with the wrapper here ...
534  }
535 */
536 
537  /************************************ EXAMPLE: FILL CLONE OF TTREE HERE WITH CUTS APPLIED ************************************/
538 
539  Bool_t locIsEventCut = true;
540  for(UInt_t loc_i = 0; loc_i < Get_NumCombos(); ++loc_i) {
541  //Set branch array indices for combo and all combo particles
542  dComboWrapper->Set_ComboIndex(loc_i);
543  // Is used to indicate when combos have been cut
544  if(dComboWrapper->Get_IsComboCut())
545  continue;
546  locIsEventCut = false; // At least one combo succeeded
547  break;
548  }
549  if(!locIsEventCut && dOutputTreeFileName != "")
550  Fill_OutputTree();
551 
552 
553  return kTRUE;
554 }
555 
557 {
558  //Save anything to output here that you do not want to be in the default DSelector output ROOT file.
559 
560  //Otherwise, don't do anything else (especially if you are using PROOF).
561  //If you are using PROOF, this function is called on each thread,
562  //so anything you do will not have the combined information from the various threads.
563  //Besides, it is best-practice to do post-processing (e.g. fitting) separately, in case there is a problem.
564 
565  //DO YOUR STUFF HERE
566 
567  //CALL THIS LAST
568  DSelector::Finalize(); //Saves results to the output file
569 }
DChargedTrackHypothesis * dPiMinusWrapper
void Process(unsigned int &NEvents, unsigned int &NEvents_read)
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
Bool_t Process(Long64_t entry)
#define y
DChargedTrackHypothesis * dPiPlusWrapper
Definition: GlueX.h:19
DBeamParticle * dComboBeamWrapper
DChargedTrackHypothesis * dProtonWrapper
void Init(TTree *tree)
Particle_t
Definition: particleType.h:12