Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DSelector_Z2pi_trees.C
Go to the documentation of this file.
1 #include "DSelector_Z2pi_trees.h"
2 
3 void DSelector_Z2pi_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_Z2pi_trees.root"; //"" for none
13  dOutputTreeFileName = "tree_DSelector_Z2pi_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, 0.5, KPlus, 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  dHist_MissingMassSquared = new TH1I("MissingMassSquared", ";Missing Mass Squared (GeV/c^{2})^{2}", 600, -0.24, 0.24);
63  dHist_BeamEnergy = new TH1I("BeamEnergy", ";Beam Energy (GeV)", 600, 0.0, 12.0);
64  // dHist_pMomentumMeasured = new TH1I("pMomentumMeasured", ";p Momentum Measured (GeV)", 100, 0.0, 2);
65  dHist_piplusMomentumMeasured = new TH1I("piplusMomentumMeasured", ";#pi^{+} Momentum Measured (GeV)", 600, 0.0, 12);
66  dHist_piminusMomentumMeasured = new TH1I("piminusMomentumMeasured", ";#pi^{-} Momentum Measured (GeV)", 600, 0.0, 12);
67 
68  // 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.);
69  dHist_KinFitChiSq = new TH1I("KinFitChiSq", ";Kinematic Fit #chi^{2}/NDF", 250, 0., 25.);
70  dHist_KinFitCL = new TH1I("KinFitCL", ";Kinematic Fit Confidence Level", 100, 0., 1.);
71 
72  dHist_M2pigen = new TH1I("M2pigen", ";M_{#pi^{+}#pi^{-}} Gen (GeV/c^{2})", 400, 0.2, 0.6);
73  dHist_M2pikin = new TH1I("M2pikin", ";M_{#pi^{+}#pi^{-}} Kin (GeV/c^{2})", 400, 0.2, 0.6);
74  dHist_M2pidiff = new TH1I("M2pidiff", ";M_{#pi^{+}#pi^{-}} Kin - Gen (GeV/c^{2})", 400, -0.05, 0.05);
75  dHist_tgen = new TH1I("tgen", ";|t| Gen (GeV/c)^{2}", 100, 0.0, 0.01);
76  dHist_tkin = new TH1I("tkin", ";|t| Kin (GeV/c)^{2}", 100, 0.0, 0.01);
77  dHist_tdiff = new TH1I("tdiff", ";|t| Kin - Gen (GeV/c)^{2}", 100, -0.01, 0.01);
78  dHist_tkin_tgen = new TH2I("tkin_tgen", "; |t| Gen ; |t| Kin (GeV/c)^{2}", 50, 0, 0.002, 50, 0, 0.002);
79  dHist_CosTheta_psi = new TH2I("CosTheta_psi", "; #psi; Cos#Theta", 90, -180., 180, 200, -1., 1.);
80  dHist_CosThetakin_CosThetagen = new TH2I("CosThetakin_CosThetagen", "; Cos#Theta Gen; Cos#Theta Kin", 50, -1, 1, 50, -1., 1.);
81  dHist_phigen_Phigen = new TH2I("phigen_Phigen", "; #Phi Gen; #phi Gen", 90, -180., 180, 90,-180,180);
82  dHist_phikin_Phikin = new TH2I("phikin_Phikin", "; #Phi Kin; #phi Kin", 90, -180., 180, 90,-180,180);
83  dHist_phimeas_phigen = new TH2I("phimeas_phigen", "; #phi Gen ; #phi Meas", 90, -180., 180, 90,-180,180);
84  dHist_phikin_phigen = new TH2I("phikin_phigen", "; #phi Gen ; #phi Kin", 90, -180., 180, 90,-180,180);
85  dHist_Phikin_Phigen = new TH2I("Phikin_Phigen", "; #Phi Gen ; #Phi Kin", 90, -180., 180, 90,-180,180);
86  dHist_Phimeas_Phigen = new TH2I("Phimeas_Phigen", "; #Phi Gen ; #Phi Meas", 90, -180., 180, 90,-180,180);
87  dHist_Delta_phi = new TH2I("Delta_phi", "; #phi ; #Delta #phi", 90, -180., 180, 90,-180,180);
88  dHist_Delta_Phi = new TH2I("Delta_Phi", "; #Phi ; #Delta #Phi", 90, -180., 180, 90,-180,180);
89  dHist_Delta_phimeas = new TH2I("Delta_phimeas", "; #phi ; #Delta #phi Meas", 90, -180., 180, 90,-180,180);
90  dHist_Delta_Phimeas = new TH2I("Delta_Phimeas", "; #Phi ; #Delta #Phi Meas", 90, -180., 180, 90,-180,180);
91  dHist_CosTheta = new TH1I("CosTheta", "; Cos#Theta", 100, -1., 1.);
92  dHist_CosThetadiff = new TH1I("CosThetadiff", "; Cos#Theta diff Kin-Gen", 50, -0.5, 0.5);
93  dHist_Phigen = new TH1I("Phigen", ";Phigen (degrees)", 360,-180,180);
94  dHist_phigen = new TH1I("phigen", ";phigen (degrees)", 360,-180,180);
95  dHist_Phikin = new TH1I("Phikin", ";Phikin (degrees)", 360,-180,180);
96  dHist_phikin = new TH1I("phikin", ";phikin (degrees)", 360,-180,180);
97  dHist_Phimeas = new TH1I("Phimeas", ";Phimeas (degrees)", 360,-180,180);
98  dHist_phimeas = new TH1I("phimeas", ";phimeas (degrees)", 360,-180,180);
99  dHist_psikin = new TH1I("psikin", ";psi Kin (degrees)", 360,-180,180);
100  dHist_psigen = new TH1I("psigen", ";psi Gen (degrees)", 360,-180,180);
101  dHist_Phidiff = new TH1I("Phidiff", ";Phi Kin - Gen (degrees)", 100,-50,50);
102  dHist_phidiff = new TH1I("phidiff", ";phi Kin - Gen (degrees)", 100,-50,50);
103  dHist_psidiff = new TH1I("psidiff", ";psi Kin - Gen (degrees)", 100,-50,50);
104 
105  dHist_pipDeltap = new TH1I("pipDeltap","; #pi^{+}: Thrown p - KinFit p/Thrown p",100,-0.2,0.2);
106  dHist_pimDeltap = new TH1I("pimDeltap","; #pi^{-}: Thrown p - KinFit p/ Thrown p",100,-0.2,0.2);
107 
108  dHist_pipDeltap_Measured = new TH1I("pipDeltap_Measured","; #pi^{+}: Thrown p - Measured p/Thrown p",100,-0.2,0.2);
109  dHist_pimDeltap_Measured = new TH1I("pimDeltap_Measured","; #pi^{-}: Thrown p - Measured p/ Thrown p",100,-0.2,0.2);
110 
111 
112  // EXAMPLE CUT PARAMETERS:
113  // fMinProton_dEdx = new TF1("fMinProton_dEdx", "exp(-1.*[0]*x + [1]) + [2]", 0., 10.);
114  // fMinProton_dEdx->SetParameters(4.0, 2.5, 1.25);
115  fMaxPion_dEdx = new TF1("fMaxPion_dEdx", "exp(-1.*[0]*x + [1]) + [2]", 0., 10.);
116  fMaxPion_dEdx->SetParameters(4.0, 2.0, 2.5);
117  dMinKinFitCL = 5.73303e-7; //5.73303e-7;
118  dMaxKinFitChiSq = 5.0;
119  dMinBeamEnergy = 5.5;
120  dMaxBeamEnergy = 6.0;
121  dMin2piMass = 0.2;
122  dMax2piMass = 0.6;
123  dMinMissingMassSquared = -0.1;
125 
126  /************************** EXAMPLE USER INITIALIZATION: CUSTOM OUTPUT BRANCHES - MAIN TREE *************************/
127 
128  //EXAMPLE MAIN TREE CUSTOM BRANCHES (OUTPUT ROOT FILE NAME MUST FIRST BE GIVEN!!!! (ABOVE: TOP)):
129  //The type for the branch must be included in the brackets
130  //1st function argument is the name of the branch
131  //2nd function argument is the name of the branch that contains the size of the array (for fundamentals only)
132  /*
133  dTreeInterface->Create_Branch_Fundamental<Int_t>("my_int"); //fundamental = char, int, float, double, etc.
134  dTreeInterface->Create_Branch_FundamentalArray<Int_t>("my_int_array", "my_int");
135  dTreeInterface->Create_Branch_FundamentalArray<Float_t>("my_combo_array", "NumCombos");
136  dTreeInterface->Create_Branch_NoSplitTObject<TLorentzVector>("my_p4");
137  dTreeInterface->Create_Branch_ClonesArray<TLorentzVector>("my_p4_array");
138  */
139 
140  /************************** EXAMPLE USER INITIALIZATION: CUSTOM OUTPUT BRANCHES - FLAT TREE *************************/
141 
142  //EXAMPLE FLAT TREE CUSTOM BRANCHES (OUTPUT ROOT FILE NAME MUST FIRST BE GIVEN!!!! (ABOVE: TOP)):
143  //The type for the branch must be included in the brackets
144  //1st function argument is the name of the branch
145  //2nd function argument is the name of the branch that contains the size of the array (for fundamentals only)
146  /*
147  dFlatTreeInterface->Create_Branch_Fundamental<Int_t>("flat_my_int"); //fundamental = char, int, float, double, etc.
148  dFlatTreeInterface->Create_Branch_FundamentalArray<Int_t>("flat_my_int_array", "flat_my_int");
149  dFlatTreeInterface->Create_Branch_NoSplitTObject<TLorentzVector>("flat_my_p4");
150  dFlatTreeInterface->Create_Branch_ClonesArray<TLorentzVector>("flat_my_p4_array");
151  */
152 
153  /************************************* ADVANCED EXAMPLE: CHOOSE BRANCHES TO READ ************************************/
154 
155  //TO SAVE PROCESSING TIME
156  //If you know you don't need all of the branches/data, but just a subset of it, you can speed things up
157  //By default, for each event, the data is retrieved for all branches
158  //If you know you only need data for some branches, you can skip grabbing data from the branches you don't need
159  //Do this by doing something similar to the commented code below
160 
161  //dTreeInterface->Clear_GetEntryBranches(); //now get none
162  //dTreeInterface->Register_GetEntryBranch("Proton__P4"); //manually set the branches you want
163 }
164 
165 Bool_t DSelector_Z2pi_trees::Process(Long64_t locEntry)
166 {
167  // The Process() function is called for each entry in the tree. The entry argument
168  // specifies which entry in the currently loaded tree is to be processed.
169  //
170  // This function should contain the "body" of the analysis. It can contain
171  // simple or elaborate selection criteria, run algorithms on the data
172  // of the event and typically fill histograms.
173  //
174  // The processing can be stopped by calling Abort().
175  // Use fStatus to set the return value of TTree::Process().
176  // The return value is currently not used.
177 
178  double PI = 3.14159;
179 
180  //CALL THIS FIRST
181  DSelector::Process(locEntry); //Gets the data from the tree for the entry
182  //cout << "RUN " << Get_RunNumber() << ", EVENT " << Get_EventNumber() << endl;
183  //TLorentzVector locProductionX4 = Get_X4_Production();
184 
185  /******************************************** GET POLARIZATION ORIENTATION ******************************************/
186 
187  //Only if the run number changes
188  //RCDB environment must be setup in order for this to work! (Will return false otherwise)
189  UInt_t locRunNumber = Get_RunNumber();
190  if(locRunNumber != dPreviousRunNumber)
191  {
192  dIsPolarizedFlag = dAnalysisUtilities.Get_IsPolarizedBeam(locRunNumber, dIsPARAFlag);
193  dPreviousRunNumber = locRunNumber;
194  }
195 
196  /********************************************* SETUP UNIQUENESS TRACKING ********************************************/
197 
198  //ANALYSIS ACTIONS: Reset uniqueness tracking for each action
199  //For any actions that you are executing manually, be sure to call Reset_NewEvent() on them here
200  Reset_Actions_NewEvent();
201 
202  //PREVENT-DOUBLE COUNTING WHEN HISTOGRAMMING
203  //Sometimes, some content is the exact same between one combo and the next
204  //e.g. maybe two combos have different beam particles, but the same data for the final-state
205  //When histogramming, you don't want to double-count when this happens: artificially inflates your signal (or background)
206  //So, for each quantity you histogram, keep track of what particles you used (for a given combo)
207  //Then for each combo, just compare to what you used before, and make sure it's unique
208 
209  //EXAMPLE 1: Particle-specific info:
210  set<Int_t> locUsedSoFar_BeamEnergy; //Int_t: Unique ID for beam particles. set: easy to use, fast to search
211  // set<Int_t> locUsedSoFar_Proton, locUsedSoFar_PiPlus, locUsedSoFar_PiMinus;
212  set<Int_t> locUsedSoFar_PiPlus, locUsedSoFar_PiMinus;
213 
214  //EXAMPLE 2: Combo-specific info:
215  //In general: Could have multiple particles with the same PID: Use a set of Int_t's
216  //In general: Multiple PIDs, so multiple sets: Contain within a map
217  //Multiple combos: Contain maps within a set (easier, faster to search)
218  set<map<Particle_t, set<Int_t> > > locUsedSoFar_MissingMass, locUsedSoFar_2pi, locUsedSoFar_Angles;
219 
220  //INSERT USER ANALYSIS UNIQUENESS TRACKING HERE
221 
222  /**************************************** EXAMPLE: FILL CUSTOM OUTPUT BRANCHES **************************************/
223 
224  /*
225  Int_t locMyInt = 7;
226  dTreeInterface->Fill_Fundamental<Int_t>("my_int", locMyInt);
227 
228  TLorentzVector locMyP4(4.0, 3.0, 2.0, 1.0);
229  dTreeInterface->Fill_TObject<TLorentzVector>("my_p4", locMyP4);
230 
231  for(int loc_i = 0; loc_i < locMyInt; ++loc_i)
232  dTreeInterface->Fill_Fundamental<Int_t>("my_int_array", 3*loc_i, loc_i); //2nd argument = value, 3rd = array index
233  */
234 
235 
236  /******************************************* LOOP OVER THROWN DATA (OPTIONAL) ***************************************/
237 
238 
239  //Thrown beam: just use directly
240  double locEbeam_Thrown = 0;
241  if(dThrownBeam != NULL)
242  locEbeam_Thrown = dThrownBeam->Get_P4().E();
243 
244  //Loop over throwns
245  TLorentzVector locPb208P4_Thrown;
246  TLorentzVector locPiPlusP4_Thrown;
247  TLorentzVector locPiMinusP4_Thrown;
248 
249  for(UInt_t loc_i = 0; loc_i < Get_NumThrown(); ++loc_i)
250  {
251  //Set branch array indices corresponding to this particle
252  dThrownWrapper->Set_ArrayIndex(loc_i);
253  Particle_t thrown_pid = dThrownWrapper->Get_PID();
254  // cout << " loc_i=" << loc_i << " thrown_pid=" << thrown_pid << endl;
255  TLorentzVector locP4_Thrown = dThrownWrapper->Get_P4();
256  if (loc_i == 0) locPb208P4_Thrown = locP4_Thrown; // assume order of particles as PID is zero at the moment
257  if (loc_i == 1) locPiPlusP4_Thrown = locP4_Thrown;
258  if (loc_i == 2) locPiMinusP4_Thrown = locP4_Thrown;
259 
260  }
261  cout << endl << "Thrown" << endl;
262  cout << " dThrownBeam="; dThrownBeam->Get_P4().Print();
263  cout << " locPb208P4="; locPb208P4_Thrown.Print();
264  cout << " locPiPlusP4="; locPiPlusP4_Thrown.Print();
265  cout << " locPiMinusP4="; locPiMinusP4_Thrown.Print();
266  TLorentzVector loc2piP4_Thrown = locPiPlusP4_Thrown + locPiMinusP4_Thrown;
267  double tgen = (dThrownBeam->Get_P4() - locPiPlusP4_Thrown - locPiMinusP4_Thrown).M2(); // use beam and 2pi momenta
268 
269 
270 
271 
272  /************************************************* LOOP OVER COMBOS *************************************************/
273 
274  //Loop over combos
275  for(UInt_t loc_i = 0; loc_i < Get_NumCombos(); ++loc_i)
276  {
277  //Set branch array indices for combo and all combo particles
278  dComboWrapper->Set_ComboIndex(loc_i);
279 
280  // Is used to indicate when combos have been cut
281  if(dComboWrapper->Get_IsComboCut()) // Is false when tree originally created
282  continue; // Combo has been cut previously
283 
284  /********************************************** GET PARTICLE INDICES *********************************************/
285 
286  //Used for tracking uniqueness when filling histograms, and for determining unused particles
287 
288  //Step 0
289  Int_t locBeamID = dComboBeamWrapper->Get_BeamID();
290  Int_t locPiPlusTrackID = dPiPlusWrapper->Get_TrackID();
291  Int_t locPiMinusTrackID = dPiMinusWrapper->Get_TrackID();
292 
293  /*********************************************** GET FOUR-MOMENTUM **********************************************/
294 
295  // Get P4's: //is kinfit if kinfit performed, else is measured
296  //dTargetP4 is target p4
297  //Step 0
298  TLorentzVector locBeamP4 = dComboBeamWrapper->Get_P4();
299  TLorentzVector locMissingPb208P4 = dMissingPb208Wrapper->Get_P4();
300  TLorentzVector locPiPlusP4 = dPiPlusWrapper->Get_P4();
301  TLorentzVector locPiMinusP4 = dPiMinusWrapper->Get_P4();
302 
303  TLorentzVector locMissingP4 = locBeamP4; // Ignore target mass/recoil
304  locMissingP4 -= locPiPlusP4 + locPiMinusP4;
305  TLorentzVector loc2piP4 = locPiPlusP4 + locPiMinusP4;
306 
307  cout << "Kin Fit" << endl;
308  cout << " locBeamP4="; locBeamP4.Print();
309  cout << " locMissingPb208P4="; locMissingPb208P4.Print();
310  cout << " locPiPlusP4="; locPiPlusP4.Print();
311  cout << " locPiMinusP4="; locPiMinusP4.Print();
312  cout << " locMissingP4="; locMissingP4.Print();
313  cout << " loc2piP4="; loc2piP4.Print();
314 
315 
316  cout << "KIN: MM2 =" << locMissingP4.M2() << " DeltaE=" << locBeamP4.E()-loc2piP4.E() << " GenDeltaE=" << locEbeam_Thrown-locBeamP4.E() << endl;
317 
318  // Get Measured P4's:
319  //Step 0
320  TLorentzVector locBeamP4_Measured = dComboBeamWrapper->Get_P4_Measured();
321  TLorentzVector locMissingPb208P4_Measured (0,0,0,193.750748);
322  // TLorentzVector locMissingPb208P4_Measured = dMissingPb208Wrapper->Get_P4_Measured();
323  TLorentzVector locPiPlusP4_Measured = dPiPlusWrapper->Get_P4_Measured();
324  TLorentzVector locPiMinusP4_Measured = dPiMinusWrapper->Get_P4_Measured();
325 
326  TLorentzVector locMissingP4_Measured = locBeamP4_Measured; // Ignore target mass/recoil
327  locMissingP4_Measured -= locPiPlusP4_Measured + locPiMinusP4_Measured;
328  locMissingPb208P4_Measured += locMissingP4_Measured;
329  TLorentzVector loc2piP4_Measured = locPiPlusP4_Measured + locPiMinusP4_Measured;
330 
331  cout << "Measured" << endl;
332  cout << " locBeamP4_Measured="; locBeamP4_Measured.Print();
333  cout << " locMissingPb208P4_Measured="; locMissingPb208P4_Measured.Print();
334  cout << " locPiPlusP4_Measured="; locPiPlusP4_Measured.Print();
335  cout << " locPiMinusP4_Measured="; locPiMinusP4_Measured.Print();
336  cout << " locMissingP4_Measured="; locMissingP4_Measured.Print();
337  cout << " loc2piP4_Measured="; loc2piP4_Measured.Print();
338 
339  /********************************************* COMBINE FOUR-MOMENTUM ********************************************/
340 
341  // DO YOUR STUFF HERE
342 
343  // Combine 4-vectors
344 
345  /******************************************** EXECUTE ANALYSIS ACTIONS *******************************************/
346 
347  // Loop through the analysis actions, executing them in order for the active particle combo
348  if(!Execute_Actions()) //if the active combo fails a cut, IsComboCutFlag automatically set
349  continue;
350 
351  //if you manually execute any actions, and it fails a cut, be sure to call:
352  //dComboWrapper->Set_IsComboCut(true);
353 
354  /**************************************** EXAMPLE: FILL CUSTOM OUTPUT BRANCHES **************************************/
355 
356  /*
357  TLorentzVector locMyComboP4(8.0, 7.0, 6.0, 5.0);
358  //for arrays below: 2nd argument is value, 3rd is array index
359  //NOTE: By filling here, AFTER the cuts above, some indices won't be updated (and will be whatever they were from the last event)
360  //So, when you draw the branch, be sure to cut on "IsComboCut" to avoid these.
361  dTreeInterface->Fill_Fundamental<Float_t>("my_combo_array", -2*loc_i, loc_i);
362  dTreeInterface->Fill_TObject<TLorentzVector>("my_p4_array", locMyComboP4, loc_i);
363  */
364 
365  /**************************************** EXAMPLE: PID CUT ACTION ************************************************/
366 
367 
368  // Proton CDC dE/dx histogram and cut
369  /*double locProton_dEdx_CDC = dProtonWrapper->Get_dEdx_CDC()*1e6;
370  if(locProton_dEdx_CDC < fMinProton_dEdx->Eval(locProtonP4.P())) {
371  dComboWrapper->Set_IsComboCut(true);
372  continue;
373  }*/
374 
375  // Pi+/- CDC dE/dx histogram cut (histograms in HistComboPID action)
376  double locPiPlus_dEdx_CDC = dPiPlusWrapper->Get_dEdx_CDC()*1e6;
377  double locPiMinus_dEdx_CDC = dPiMinusWrapper->Get_dEdx_CDC()*1e6;
378  if(locPiPlus_dEdx_CDC > fMaxPion_dEdx->Eval(locPiPlusP4.P()) || locPiMinus_dEdx_CDC > fMaxPion_dEdx->Eval(locPiMinusP4.P())) {
379  dComboWrapper->Set_IsComboCut(true);
380  continue;
381  }
382 
383  cout << " Passed CDC dE/dX cut " << endl;
384 
385 
386 
387  /************************************ EXAMPLE: SELECTION CUTS AND HISTOGRAMS ************************************/
388 
389  //Missing Mass Squared
390  double locMissingMassSquared = locMissingP4_Measured.M2();
391 
392  //Uniqueness tracking: Build the map of particles used for the missing mass
393  //For beam: Don't want to group with final-state photons. Instead use "Unknown" PID (not ideal, but it's easy).
394  map<Particle_t, set<Int_t> > locUsedThisCombo_MissingMass;
395  locUsedThisCombo_MissingMass[Unknown].insert(locBeamID); //beam
396  locUsedThisCombo_MissingMass[PiPlus].insert(locPiPlusTrackID);
397  locUsedThisCombo_MissingMass[PiMinus].insert(locPiMinusTrackID);
398 
399  // beam energy cut for SDME
400  if(locBeamP4.E() < dMinBeamEnergy || locBeamP4.E() > dMaxBeamEnergy) {
401  dComboWrapper->Set_IsComboCut(true);
402  continue;
403  }
404 
405  cout << " Passed beam energy cut " << endl;
406 
407  // Cut on Missing mass
408  if((locMissingMassSquared < dMinMissingMassSquared ) || (locMissingMassSquared > dMaxMissingMassSquared)){ // measured
409  // if((locMissingP4.M2() < dMinMissingMassSquared ) || (locMissingP4.M2() > dMaxMissingMassSquared)){ // kinfit
410  dComboWrapper->Set_IsComboCut(true);
411  continue;
412  }
413 
414  cout << " Passed Missing mass cut " << endl;
415 
416 
417  // kinematic fit CL cut
418  dHist_KinFitChiSq->Fill(dComboWrapper->Get_ChiSq_KinFit()/dComboWrapper->Get_NDF_KinFit());
419  dHist_KinFitCL->Fill(dComboWrapper->Get_ConfidenceLevel_KinFit());
420  if(dComboWrapper->Get_ConfidenceLevel_KinFit() <= dMinKinFitCL) {
421  dComboWrapper->Set_IsComboCut(true);
422  continue;
423  }
424  cout << " Passed kinematic Fit CL cut " << endl;
425 
426  // 2pi mass histogram and cut
427  map<Particle_t, set<Int_t> > locUsedThisCombo_2piMass;
428  locUsedThisCombo_2piMass[PiPlus].insert(locPiPlusTrackID);
429  locUsedThisCombo_2piMass[PiMinus].insert(locPiMinusTrackID);
430  if(loc2piP4.M() < dMin2piMass || loc2piP4.M() > dMax2piMass) {
431  dComboWrapper->Set_IsComboCut(true);
432  continue;
433  }
434  cout << " Passed 2pi mass cut " << endl;
435 
436 
437  if(locUsedSoFar_2pi.find(locUsedThisCombo_2piMass) == locUsedSoFar_2pi.end())
438  {
439  dHist_M2pikin->Fill(loc2piP4.M());
440  dHist_M2pigen->Fill(loc2piP4_Thrown.M());
441  dHist_M2pidiff->Fill(loc2piP4.M()-loc2piP4_Thrown.M());
442  locUsedSoFar_2pi.insert(locUsedThisCombo_2piMass);
443  }
444 
445 
446 
447  /**************************************** EXAMPLE: HISTOGRAM energies and momenta *****************************************/
448 
449  //Histogram beam energy (if haven't already)
450  if(locUsedSoFar_BeamEnergy.find(locBeamID) == locUsedSoFar_BeamEnergy.end())
451  {
452  dHist_BeamEnergy->Fill(locBeamP4.E());
453  locUsedSoFar_BeamEnergy.insert(locBeamID);
454  }
455 
456  //compare to what's been used so far
457  if(locUsedSoFar_MissingMass.find(locUsedThisCombo_MissingMass) == locUsedSoFar_MissingMass.end())
458  {
459  //unique missing mass combo: histogram it, and register this combo of particles
460  dHist_MissingMassSquared->Fill(locMissingMassSquared);
461  locUsedSoFar_MissingMass.insert(locUsedThisCombo_MissingMass);
462  }
463 
464 
465  /*if(locUsedSoFar_Proton.find(locProtonTrackID) == locUsedSoFar_Proton.end())
466  {
467  dHist_pMomentumMeasured->Fill(locProtonP4.Vect().Mag());
468  dHist_Proton_dEdx_P->Fill(locProtonP4.P(), locProton_dEdx_CDC);
469  dHist_pDeltap->Fill(locProtonP4_Thrown.Vect().Mag() > 0? (locProtonP4_Thrown.Vect().Mag()-locProtonP4.Vect().Mag())/locProtonP4_Thrown.Vect().Mag() : 0);
470  dHist_pDeltap_Measured->Fill(locProtonP4_Thrown.Vect().Mag() > 0? (locProtonP4_Thrown.Vect().Mag()-locProtonP4_Measured.Vect().Mag())/locProtonP4_Thrown.Vect().Mag() : 0);
471  locUsedSoFar_Proton.insert(locProtonTrackID);
472  }*/
473 
474 
475  if(locUsedSoFar_PiPlus.find(locPiPlusTrackID) == locUsedSoFar_PiPlus.end())
476  {
477  dHist_piplusMomentumMeasured->Fill(locPiPlusP4.Vect().Mag());
478  dHist_pipDeltap->Fill(locPiPlusP4_Thrown.Vect().Mag() > 0? (locPiPlusP4_Thrown.Vect().Mag()-locPiPlusP4.Vect().Mag())/locPiPlusP4_Thrown.Vect().Mag() : 0);
479  dHist_pipDeltap_Measured->Fill(locPiPlusP4_Thrown.Vect().Mag() > 0? (locPiPlusP4_Thrown.Vect().Mag()-locPiPlusP4_Measured.Vect().Mag())/locPiPlusP4_Thrown.Vect().Mag() : 0);
480  locUsedSoFar_PiPlus.insert(locPiPlusTrackID);
481  }
482 
483  if(locUsedSoFar_PiMinus.find(locPiMinusTrackID) == locUsedSoFar_PiMinus.end())
484  {
485  dHist_piminusMomentumMeasured->Fill(locPiMinusP4.Vect().Mag());
486  dHist_pimDeltap->Fill(locPiMinusP4_Thrown.Vect().Mag() > 0? (locPiMinusP4_Thrown.Vect().Mag()-locPiMinusP4.Vect().Mag())/locPiMinusP4_Thrown.Vect().Mag() : 0);
487  dHist_pimDeltap_Measured->Fill(locPiMinusP4_Thrown.Vect().Mag() > 0? (locPiMinusP4_Thrown.Vect().Mag()-locPiMinusP4_Measured.Vect().Mag())/locPiMinusP4_Thrown.Vect().Mag() : 0);
488  locUsedSoFar_PiMinus.insert(locPiMinusTrackID);
489  }
490 
491  cout << "Ebeam Thrown P4.E=" << dThrownBeam->Get_P4().E() << " Kinfit P4.E=" << locBeamP4.E() << " P4 Measured =" << locBeamP4_Measured.E() << endl;
492  // cout << "Proton Thrown P4.E=" << locPb208P4_Thrown.E() << " Kinfit P4.E=" << locProtonP4.E() << " P4 Measured =" << locProtonP4_Measured.E() << " CL=" << dComboWrapper->Get_ConfidenceLevel_KinFit() << endl;
493  cout << "PiPlus Thrown P4.E=" << locPiPlusP4_Thrown.E() << " Kinfit P4.E=" << locPiPlusP4.E() << " P4 Measured =" << locPiPlusP4_Measured.E() << endl;
494  cout << "PiMinus Thrown P4.E=" << locPiMinusP4_Thrown.E() << " Kinfit P4.E=" << locPiMinusP4.E() << " P4 Measured =" << locPiMinusP4_Measured.E() << endl << endl;
495 
496 
497  if ( locBeamP4_Measured.Z() < 0 || locPiPlusP4_Measured.Z() < 0 || locPiMinusP4_Measured.Z() < 0 ||
498  locPiPlusP4.Z() < 0 || locPiMinusP4.Z() < 0 ) {
499  dComboWrapper->Set_IsComboCut(true);
500  cout << "*** Negative pz ***" << endl;
501  continue;
502  }
503  cout << " Passed Negative pz cut " << endl;
504 
505 
506  // Thrown (generated) variables
507  // calculate kinematic and angular variables
508  double tgen = (dThrownBeam->Get_P4() - loc2piP4_Thrown).M2(); // use beam and 2pi momenta
509  TLorentzRotation resonanceBoost( -loc2piP4_Thrown.BoostVector() ); // boost into 2pi frame
510  TLorentzVector beam_res = resonanceBoost * dThrownBeam->Get_P4();
511  TLorentzVector recoil_res = resonanceBoost * locPb208P4_Thrown;
512  TLorentzVector p1_res = resonanceBoost * locPiPlusP4_Thrown;
513  TLorentzVector p2_res = resonanceBoost * locPiMinusP4_Thrown;
514 
515  double phipol = 0; // *** Note assumes horizontal polarization plane.
516  TVector3 eps(cos(phipol), sin(phipol), 0.0); // beam polarization vector in lab
517 
518  // choose helicity frame: z-axis opposite recoil target in rho rest frame. Note that for Primakoff recoil is never measured.
519  TVector3 y = (dThrownBeam->Get_P4().Vect().Unit().Cross(-locPb208P4_Thrown.Vect().Unit())).Unit();
520 
521  // choose helicity frame: z-axis opposite recoil proton in rho rest frame
522  TVector3 z = -1. * recoil_res.Vect().Unit();
523  TVector3 x = y.Cross(z).Unit();
524  TVector3 anglesgen( (p1_res.Vect()).Dot(x),
525  (p1_res.Vect()).Dot(y),
526  (p1_res.Vect()).Dot(z) );
527 
528  double CosThetagen = anglesgen.CosTheta();
529  double phigen = anglesgen.Phi();
530 
531  double Phigen = atan2(y.Dot(eps), dThrownBeam->Get_P4().Vect().Unit().Dot(eps.Cross(y)));
532 
533  double psigen = Phigen - phigen;
534  if(psigen < -3.14159) psigen += 2*3.14159;
535  if(psigen > 3.14159) psigen -= 2*3.14159;
536 
537 
538  // Repeat for kinematically fit variables.
539  // calculate kinematic and angular variables
540  double tkin = (locBeamP4 - loc2piP4).M2(); // use beam and 2pi momenta
541  TLorentzRotation resonanceBoost2( -loc2piP4.BoostVector() ); // boost into 2pi frame
542  beam_res = resonanceBoost2 * locBeamP4;
543  recoil_res = resonanceBoost2 * locMissingPb208P4;
544  p1_res = resonanceBoost2 * locPiPlusP4;
545  p2_res = resonanceBoost2 * locPiMinusP4;
546 
547  // choose helicity frame: z-axis opposite recoil target in rho rest frame. Note that for Primakoff recoil is missing P4, including target.
548  y = (locBeamP4.Vect().Unit().Cross(-locMissingPb208P4.Vect().Unit())).Unit();
549 
550  // choose helicity frame: z-axis opposite recoil proton in rho rest frame
551  z = -1. * recoil_res.Vect().Unit();
552  x = y.Cross(z).Unit();
553  TVector3 angleskin( (p1_res.Vect()).Dot(x),
554  (p1_res.Vect()).Dot(y),
555  (p1_res.Vect()).Dot(z) );
556 
557  double CosThetakin = angleskin.CosTheta();
558  double phikin = angleskin.Phi();
559 
560  double Phikin = atan2(y.Dot(eps), locBeamP4.Vect().Unit().Dot(eps.Cross(y)));
561 
562  double psikin = Phikin - phikin;
563  if(psikin < -3.14159) psikin += 2*3.14159;
564  if(psikin > 3.14159) psikin -= 2*3.14159;
565 
566  // Repeat for measured variables.
567  // calculate measured and angular variables
568  double tmeas = (locBeamP4_Measured - loc2piP4_Measured).M2(); // use beam and 2pi momenta
569  TLorentzRotation resonanceBoost3( -loc2piP4_Measured.BoostVector() ); // boost into 2pi frame
570  beam_res = resonanceBoost3 * locBeamP4_Measured;
571  recoil_res = resonanceBoost3 * locMissingPb208P4_Measured;
572  p1_res = resonanceBoost3 * locPiPlusP4_Measured;
573  p2_res = resonanceBoost3 * locPiMinusP4_Measured;
574 
575  // choose helicity frame: z-axis opposite recoil target in rho rest frame. Note that for Primakoff recoil is missing P4, including target.
576  y = (locBeamP4_Measured.Vect().Unit().Cross(-locMissingPb208P4_Measured.Vect().Unit())).Unit();
577 
578  // choose helicity frame: z-axis opposite recoil proton in rho rest frame
579  z = -1. * recoil_res.Vect().Unit();
580  x = y.Cross(z).Unit();
581  TVector3 anglesmeas( (p1_res.Vect()).Dot(x),
582  (p1_res.Vect()).Dot(y),
583  (p1_res.Vect()).Dot(z) );
584 
585  double CosThetameas = anglesmeas.CosTheta();
586  double phimeas = anglesmeas.Phi();
587 
588  double Phimeas = atan2(y.Dot(eps), locBeamP4_Measured.Vect().Unit().Dot(eps.Cross(y)));
589 
590  double psimeas = Phimeas - phimeas;
591  if(psimeas < -3.14159) psimeas += 2*3.14159;
592  if(psimeas > 3.14159) psimeas -= 2*3.14159;
593 
594  double Delta_phi = phikin - phigen;
595  double Delta_Phi = Phikin - Phigen;
596  double Delta_phimeas = phimeas - phigen;
597  double Delta_Phimeas = Phimeas - Phigen;
598 
599  map<Particle_t, set<Int_t> > locUsedThisCombo_Angles;
600  locUsedThisCombo_Angles[Unknown].insert(locBeamID); //beam
601  // locUsedThisCombo_Angles[Proton].insert(locProtonTrackID);
602  locUsedThisCombo_Angles[PiPlus].insert(locPiPlusTrackID);
603  locUsedThisCombo_Angles[PiMinus].insert(locPiMinusTrackID);
604  if(locUsedSoFar_Angles.find(locUsedThisCombo_Angles) == locUsedSoFar_Angles.end())
605  {
606  dHist_tgen->Fill(fabs(tgen));
607  dHist_tkin->Fill(fabs(tkin));
608  dHist_tdiff->Fill(fabs(tkin)-fabs(tgen));
609  dHist_tkin_tgen->Fill(fabs(tgen),fabs(tkin));
610  dHist_CosTheta_psi->Fill(psikin*180./3.14159, CosThetakin);
611  dHist_CosTheta->Fill(CosThetakin);
612  dHist_CosThetadiff->Fill(CosThetakin-CosThetagen);
613  // dHist_phi->Fill(phi*180./3.14159);
614  dHist_CosThetakin_CosThetagen->Fill(CosThetagen, CosThetakin);
615  dHist_phikin_Phikin->Fill(Phikin*180./3.14159,phikin*180./3.14159);
616  dHist_phigen_Phigen->Fill(Phigen*180./3.14159,phigen*180./3.14159);
617  dHist_phimeas_phigen->Fill(phigen*180./3.14159,phimeas*180./3.14159);
618  dHist_phikin_phigen->Fill(phigen*180./3.14159,phikin*180./3.14159);
619  dHist_Phimeas_Phigen->Fill(Phigen*180./3.14159,Phimeas*180./3.14159);
620  dHist_Phikin_Phigen->Fill(Phigen*180./3.14159,Phikin*180./3.14159);
621  dHist_Delta_phi->Fill(phigen*180./3.14159,Delta_phi*180./3.14159);
622  dHist_Delta_Phi->Fill(Phigen*180./3.14159,Delta_Phi*180./3.14159);
623  dHist_Delta_phimeas->Fill(phigen*180./3.14159,Delta_phimeas*180./3.14159);
624  dHist_Delta_Phimeas->Fill(Phigen*180./3.14159,Delta_Phimeas*180./3.14159);
625  dHist_phigen->Fill(phigen*180./3.14159);
626  dHist_Phigen->Fill(Phigen*180./3.14159);
627  dHist_phikin->Fill(phikin*180./3.14159);
628  dHist_Phikin->Fill(Phikin*180./3.14159);
629  dHist_Phimeas->Fill(Phimeas*180./3.14159);
630  dHist_phimeas->Fill(phimeas*180./3.14159);
631  dHist_Phidiff->Fill((Phikin-Phigen)*180./3.14159);
632  dHist_phidiff->Fill((phikin-phigen)*180./3.14159);
633  dHist_psigen->Fill(psigen*180./3.14159);
634  dHist_psikin->Fill(psikin*180./3.14159);
635  dHist_psidiff->Fill((psikin-psigen)*180./3.14159);
636  // dHist_psikin->Fill(psikin*180./3.14159);
637  locUsedSoFar_Angles.insert(locUsedThisCombo_Angles);
638  }
639 
640  /****************************************** FILL FLAT TREE (IF DESIRED) ******************************************/
641 
642 
643  /*
644  //FILL ANY CUSTOM BRANCHES FIRST!!
645  Int_t locMyInt_Flat = 7;
646  dFlatTreeInterface->Fill_Fundamental<Int_t>("flat_my_int", locMyInt_Flat);
647 
648  TLorentzVector locMyP4_Flat(4.0, 3.0, 2.0, 1.0);
649  dFlatTreeInterface->Fill_TObject<TLorentzVector>("flat_my_p4", locMyP4_Flat);
650 
651  for(int loc_j = 0; loc_j < locMyInt_Flat; ++loc_j)
652  {
653  dFlatTreeInterface->Fill_Fundamental<Int_t>("flat_my_int_array", 3*loc_j, loc_j); //2nd argument = value, 3rd = array index
654  TLorentzVector locMyComboP4_Flat(8.0, 7.0, 6.0, 5.0);
655  dFlatTreeInterface->Fill_TObject<TLorentzVector>("flat_my_p4_array", locMyComboP4_Flat, loc_j);
656  }
657  */
658 
659  //FILL FLAT TREE
660  //Fill_FlatTree(); //for the active combo
661  } // end of combo loop
662 
663  //FILL HISTOGRAMS: Num combos / events surviving actions
664  Fill_NumCombosSurvivedHists();
665 
666  /******************************************* LOOP OVER THROWN DATA (OPTIONAL) ***************************************/
667 /*
668  //Thrown beam: just use directly
669  if(dThrownBeam != NULL)
670  double locEnergy = dThrownBeam->Get_P4().E();
671 
672  //Loop over throwns
673  for(UInt_t loc_i = 0; loc_i < Get_NumThrown(); ++loc_i)
674  {
675  //Set branch array indices corresponding to this particle
676  dThrownWrapper->Set_ArrayIndex(loc_i);
677 
678  //Do stuff with the wrapper here ...
679  }
680 */
681  /****************************************** LOOP OVER OTHER ARRAYS (OPTIONAL) ***************************************/
682 /*
683  //Loop over beam particles (note, only those appearing in combos are present)
684  for(UInt_t loc_i = 0; loc_i < Get_NumBeam(); ++loc_i)
685  {
686  //Set branch array indices corresponding to this particle
687  dBeamWrapper->Set_ArrayIndex(loc_i);
688 
689  //Do stuff with the wrapper here ...
690  }
691 
692  //Loop over charged track hypotheses
693  for(UInt_t loc_i = 0; loc_i < Get_NumChargedHypos(); ++loc_i)
694  {
695  //Set branch array indices corresponding to this particle
696  dChargedHypoWrapper->Set_ArrayIndex(loc_i);
697 
698  //Do stuff with the wrapper here ...
699  }
700 
701  //Loop over neutral particle hypotheses
702  for(UInt_t loc_i = 0; loc_i < Get_NumNeutralHypos(); ++loc_i)
703  {
704  //Set branch array indices corresponding to this particle
705  dNeutralHypoWrapper->Set_ArrayIndex(loc_i);
706 
707  //Do stuff with the wrapper here ...
708  }
709 */
710 
711  /************************************ EXAMPLE: FILL CLONE OF TTREE HERE WITH CUTS APPLIED ************************************/
712 
713  Bool_t locIsEventCut = true;
714  for(UInt_t loc_i = 0; loc_i < Get_NumCombos(); ++loc_i) {
715  //Set branch array indices for combo and all combo particles
716  dComboWrapper->Set_ComboIndex(loc_i);
717  // Is used to indicate when combos have been cut
718  if(dComboWrapper->Get_IsComboCut())
719  continue;
720  locIsEventCut = false; // At least one combo succeeded
721  break;
722  }
723  if(!locIsEventCut && dOutputTreeFileName != "")
724  Fill_OutputTree();
725 
726 
727  return kTRUE;
728 }
729 
731 {
732  //Save anything to output here that you do not want to be in the default DSelector output ROOT file.
733 
734  //Otherwise, don't do anything else (especially if you are using PROOF).
735  //If you are using PROOF, this function is called on each thread,
736  //so anything you do will not have the combined information from the various threads.
737  //Besides, it is best-practice to do post-processing (e.g. fitting) separately, in case there is a problem.
738 
739  //DO YOUR STUFF HERE
740 
741  //CALL THIS LAST
742  DSelector::Finalize(); //Saves results to the output file
743 }
void Process(unsigned int &NEvents, unsigned int &NEvents_read)
DKinematicData * dMissingPb208Wrapper
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
#define y
DBeamParticle * dComboBeamWrapper
#define PI
Definition: kinematics.h:18
DChargedTrackHypothesis * dPiMinusWrapper
Bool_t Process(Long64_t entry)
void Init(TTree *tree)
DChargedTrackHypothesis * dPiPlusWrapper
double sin(double)
Particle_t
Definition: particleType.h:12