1 #include "numuCCMultiPiSelection.hxx" 2 #include "numuCCSelection.hxx" 3 #include "baseSelection.hxx" 4 #include "SystematicTuning.hxx" 5 #include "CutUtils.hxx" 6 #include "EventBoxUtils.hxx" 7 #include "Parameters.hxx" 8 #include "SubDetId.hxx" 10 #include "SystematicUtils.hxx" 11 #include <DetectorDefinition.hxx> 49 systTuning::Initialize();
103 bool numuCCMultiPiSelection::FillEventSummary(
AnaEventC& event, Int_t allCutsPassed[]){
107 if(allCutsPassed[0]){
108 static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
111 else if (allCutsPassed[1]){
112 static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
115 else if (allCutsPassed[2]){
116 static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
120 return (static_cast<AnaEventSummaryB*>(event.
Summary)->EventSample != SampleId::kUnassigned);
135 static_cast<AnaEventSummaryB*>(event.
Summary)->LeptonCandidate[SampleId::kFGD1NuMuCC1Pi] = box.
HMNtrack;
138 for(
int i = 0; i < 4; ++i){
160 if (useTPCPions) numuCCMultiPiUtils::FindTPCPions(event, box, det, useOldSecondaryPID);
161 if (useME) numuCCMultiPiUtils::FindMEPions(event,det, prod5Cut);
162 if (useFGDPions) numuCCMultiPiUtils::FindIsoFGDPions(event, box, det);
164 int nnegpions = ccmultipibox->nNegativePionTPCtracks;
165 int npospions = ccmultipibox->nPositivePionTPCtracks;
166 int nisofgdpions = ccmultipibox->nIsoFGDPiontracks;
167 int nmichelelectrons = EventBox->nFGDMichelElectrons[det];
168 int npi0 = ccmultipibox->nPosPi0TPCtracks+ ccmultipibox->nElPi0TPCtracks;
170 int pionFGD = nmichelelectrons;
171 if (!nmichelelectrons && nisofgdpions>0) pionFGD = 1;
173 ccmultipibox->nPosPions = npospions+pionFGD;
174 ccmultipibox->nOtherPions = nnegpions+npi0;
188 if( ccmultipibox->nPosPions + ccmultipibox->nOtherPions == 0 )
return true;
202 if( ccmultipibox->nOtherPions != 0 )
return false;
203 if( ccmultipibox->nPosPions == 1 )
return true;
217 if( ccmultipibox->nOtherPions != 0 )
return true;
218 if( ccmultipibox->nPosPions > 1 )
return true;
219 if( ccmultipibox->nPi0Ecaltracks > 0)
return true;
230 ccmultipibox->nPositivePionTPCtracks = 0;
231 ccmultipibox->nPosPi0TPCtracks = 0;
232 ccmultipibox->nNegativePionTPCtracks = 0;
233 ccmultipibox->nElPi0TPCtracks = 0;
235 EventBoxTracker::RecObjectGroupEnum groupID;
236 if (det==SubDetId::kFGD1) groupID = EventBoxTracker::kTracksWithGoodQualityTPCInFGD1FV;
237 else if (det==SubDetId::kFGD2) groupID = EventBoxTracker::kTracksWithGoodQualityTPCInFGD2FV;
240 EventBoxB* EventBox =
event.EventBoxes[EventBoxId::kEventBoxTracker];
247 if(useOldSecondaryPID){
248 if ( numuCCMultiPiUtils::TPCpionSelection(ptrack) ) {
249 ccmultipibox->PositivePionTPCtracks[ccmultipibox->nPositivePionTPCtracks] = ptrack;
250 ccmultipibox->nPositivePionTPCtracks++;
252 else if ( numuCCMultiPiUtils::TPCElPi0Selection(ptrack) ) {
253 ccmultipibox->PosPi0TPCtracks[ccmultipibox->nPosPi0TPCtracks] = ptrack;
254 ccmultipibox->nPosPi0TPCtracks++;
258 Float_t PIDLikelihood[4];
262 double ElLklh = PIDLikelihood[1];
263 double ProtonLklh = PIDLikelihood[2];
264 double PionLklh = PIDLikelihood[3];
265 double norm = ElLklh+ProtonLklh+PionLklh;
270 if( ProtonLklh > ElLklh && ProtonLklh > PionLklh )
continue;
273 if( PionLklh > ElLklh ){
274 ccmultipibox->PositivePionTPCtracks[ccmultipibox->nPositivePionTPCtracks] = ptrack;
275 ccmultipibox->nPositivePionTPCtracks++;
278 if( ptrack->
Momentum > 900. )
continue;
279 ccmultipibox->PosPi0TPCtracks[ccmultipibox->nPosPi0TPCtracks] = ptrack;
280 ccmultipibox->nPosPi0TPCtracks++;
285 if( ccmultipibox->
HMNtrack == ptrack )
continue;
287 if(useOldSecondaryPID) {
288 if ( numuCCMultiPiUtils::TPCpionSelection(ptrack) ) {
289 ccmultipibox->NegativePionTPCtracks[ccmultipibox->nNegativePionTPCtracks] = ptrack;
290 ccmultipibox->nNegativePionTPCtracks++;
292 else if ( numuCCMultiPiUtils::TPCElPi0Selection(ptrack) ) {
293 ccmultipibox->ElPi0TPCtracks[ccmultipibox->nElPi0TPCtracks] = ptrack;
294 ccmultipibox->nElPi0TPCtracks++;
299 Float_t PIDLikelihood[4];
303 double ElLklh = PIDLikelihood[1];
304 double PionLklh = PIDLikelihood[3];
305 double norm = ElLklh+PionLklh;
309 if( PionLklh > 0.8 ){
310 ccmultipibox->NegativePionTPCtracks[ccmultipibox->nNegativePionTPCtracks] = ptrack;
311 ccmultipibox->nNegativePionTPCtracks++;
314 ccmultipibox->ElPi0TPCtracks[ccmultipibox->nElPi0TPCtracks] = ptrack;
315 ccmultipibox->nElPi0TPCtracks++;
328 ccmultipibox->nIsoFGDPiontracks = 0;
329 ccmultipibox->nIsoFGDElPi0tracks = 0;
331 EventBoxTracker::RecObjectGroupEnum groupID;
332 if (det==SubDetId::kFGD1) groupID = EventBoxTracker::kTracksWithFGD1AndNoTPC;
333 else if (det==SubDetId::kFGD2) groupID = EventBoxTracker::kTracksWithFGD2AndNoTPC;
336 EventBoxB* EventBox =
event.EventBoxes[EventBoxId::kEventBoxTracker];
342 if( numuCCMultiPiUtils::FGDpionSelection(track,det) ){
343 ccmultipibox->IsoFGDPiontracks[ccmultipibox->nIsoFGDPiontracks] = track;
344 ccmultipibox->nIsoFGDPiontracks++;
346 else if( numuCCMultiPiUtils::FGDElPi0Selection(event,box,track,det) ){
347 ccmultipibox->IsoFGDElPi0tracks[ccmultipibox->nIsoFGDElPi0tracks] = track;
348 ccmultipibox->nIsoFGDElPi0tracks++;
366 anaUtils::ResizeArray(EventBox->
FGDMichelElectrons[det], EventBox->nFGDMichelElectrons[det]);
371 bool numuCCMultiPiUtils::TPCpionSelection(
AnaTrackB *track){
374 Float_t PIDLikelihood[4];
377 if ( PIDLikelihood[3] < 0.3 )
return false;
379 double cut1 = (PIDLikelihood[0]+PIDLikelihood[3])/(1.-PIDLikelihood[2]);
381 if( track->
Momentum < 500. && cut1 < 0.8 )
return false;
388 bool numuCCMultiPiUtils::TPCElPi0Selection(
AnaTrackB *track){
393 bool seltrack =
false;
397 if( track->
Momentum < 50. )
return seltrack;
407 if( !tpcTrack )
continue;
412 if (TMath::Abs(pulls[0]) > 1.e+6
413 || TMath::Abs(pulls[1]) > 1.e+6
414 || TMath::Abs(pulls[2]) > 1.e+6
415 || TMath::Abs(pulls[3]) > 1.e+6)
continue;
417 if( pulls[1] < -2.0 || pulls[1] > 2.0 )
break;
419 if( track->
Charge > 0. && ( pulls[2] > -4.0 && pulls[2] < 8.0 ) )
break;
434 if( !fgdTrack )
return false;
436 if( TMath::Abs(fgdTrack->
Pullp) > 1.e+6 || TMath::Abs(fgdTrack->
Pullmu) > 1.e+6 || TMath::Abs(fgdTrack->
Pullpi) > 1.e+6 )
return false;
441 if( fgdTrack->
Pullno == 1 )
return false;
447 if ( det == SubDetId::kFGD1 && fgdTrack->
Containment != 1 )
return false;
448 else if( det == SubDetId::kFGD2 && fgdTrack->
Containment != 2 )
return false;
453 if(cosFGDpion > -0.3 && cosFGDpion < 0.3)
return false;
455 if( fgdTrack->
Pullpi < 2.5 && fgdTrack->
Pullpi > -2.0 )
return true;
474 if( !fgdTrack )
return false;
476 if( TMath::Abs(fgdTrack->
Pullp) > 1.e+6 || TMath::Abs(fgdTrack->
Pullmu) > 1.e+6 || TMath::Abs(fgdTrack->
Pullpi) > 1.e+6 )
return false;
481 if( fgdTrack->
Pullno == 1 )
return false;
487 if ( det == SubDetId::kFGD1 && fgdTrack->
Containment != 1 )
return false;
488 else if( det == SubDetId::kFGD2 && fgdTrack->
Containment != 2 )
return false;
493 if(EventBox->nFGDMichelElectrons[det] > 0 && fgdTrack->
Pullpi < -3.0 )
return true;
494 if(EventBox->nFGDMichelElectrons[det] == 0 && fgdTrack->
Pullpi < -1.5 )
return true;
530 case SystId::kChargeIDEff:
532 case SystId::kTpcFgdMatchEff:
537 if (ccmultipibox->nPositivePionTPCtracks==1 && track==ccmultipibox->PositivePionTPCtracks[0])
return true;
539 else if (branch == 2){
541 if (ccmultipibox->nNegativePionTPCtracks==1 && track==ccmultipibox->NegativePionTPCtracks[0] &&
542 ccmultipibox->nOtherPions==1 && ccmultipibox->nPosPions == 0)
return true;
551 case SystId::kTpcClusterEff:
579 if(systId == SystId::kTpcTrackEff){
582 if (branch==0 || branch==1){
584 if (abs(trueTrack->
PDG)==211 || abs(trueTrack->
PDG)==13)
return true;
590 if (ccmultipibox->nNegativePionTPCtracks+ccmultipibox->nPositivePionTPCtracks>2 || ccmultipibox->nNegativePionTPCtracks>1)
return false;
593 if (abs(trueTrack->
PDG)==211 || abs(trueTrack->
PDG)==13)
return true;
630 if (systId==SystId::kSIPion){
634 if (box2->nOtherPions >1 || box2->nPosPions > 2 )
return false;
648 boxUtils::FillTracksWithECal(event);
656 if( _numuCCSelection.
CheckRedoSelection(event,PreviousToyBox,redoFromStep))
return true;
660 redoFromStep=_FindPionsStepIndex;
675 EventBoxTracker::RecObjectGroupEnum groupID;
676 groupID = EventBoxTracker::kTracksWithECal;
677 EventBoxB* EventBox =
event.EventBoxes[EventBoxId::kEventBoxTracker];
680 double higherEnergyObject = 0;
684 AnaTrackB *allECALObjects =
static_cast<AnaTrackB*
>(EventBox->RecObjectsInGroup[groupID][i]);
696 ccmultipibox->ISOEcal.push_back(
object);
699 if(ecalBase->
EMEnergy > higherEnergyObject){
700 higherEnergyObject = ecalBase->
EMEnergy;
701 highestObject = object;
707 ccmultipibox->HObject = highestObject;
709 if( numuCCMultiPiUtils::ECALPi0Selection(event, box, highestObject, MostUpstreamLayerHitCut, det) ) {
710 ccmultipibox->Pi0Ecaltrack = highestObject;
711 ccmultipibox->nPi0Ecaltracks = ccmultipibox->nPi0Ecaltracks+1;
730 bool Ecalpi0 =
false;
732 double EMENERGY = -9999.;
733 double MIPEM = -9999.;
734 double EM_UPSTREAM = -9999;
736 if( !EcalSegment )
return false;
742 if (EMENERGY > 30. && MIPEM > 0.) Ecalpi0 =
true;
748 if(EM_UPSTREAM > MostUpstreamLayerHitCut ) Ecalpi0 =
false;
761 if(ccmultipibox->nPi0Ecaltracks > 0)
return false;
bool IsRelevantRecObjectForSystematic(const AnaEventC &event, AnaRecObjectC *recObj, SystId_h systId, Int_t branch) const
Is this track relevant for a given systematic (prior to selection, call when initializing the event...
AnaTrueVertexB * TrueVertex
Pointer to the AnaTrueVertexB of the interaction that created this AnaTrueParticleB.
Float_t PositionStart[4]
The reconstructed start position of the particle.
void DefineDetectorFV()
Define the detector Fiducial Volume in which this selection is applied.
Int_t GetStepNumber(const std::string &title, Int_t ID=0) const
Return the step number (starting at 0) corresponding to an step with a given title.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool IsRelevantRecObjectForSystematicInToy(const AnaEventC &event, const ToyBoxB &box, AnaRecObjectC *recObj, SystId_h systId, Int_t branch) const
Is this track relevant for a given systematic (after selection, called for each toy) ...
void CopySteps(SelectionBase &sel1, UInt_t branchID1, UInt_t first, UInt_t last, Int_t b0=-1, Int_t b1=-1, Int_t b2=-1, Int_t b3=-1, Int_t b4=-1, Int_t b5=-1, Int_t b6=-1, Int_t b7=-1)
Copy a clone of the steps in range first-last from branch sbranch1 in selection ssel1 to sbranch2 in ...
void SetPreSelectionAccumLevel(Int_t presel)
Set the pre-selection accum level.
int GetFGDMichelElectrons(const AnaEventB &event, const SubDetId::SubDetEnum det, AnaFgdTimeBinB **arr, bool prod5Cut=0)
Get all delayed time bins as Michel Electron candidates.
AnaECALParticleB * ECALSegments[NMAXECALS]
The ECAL segments that contributed to this global track.
int nECALSegments
How many ECAL tracks are associated with this track.
bool Apply(AnaEventC &event, ToyBoxB &box) const
Float_t Pullp
Proton pull, according to FGD information.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool Apply(AnaEventC &event, ToyBoxB &box) const
Float_t Pullno
Dummy pull. If the FGD pulls weren't set, this is set to 1.
SubDetId_h DetectorFV
Indicate the FV we are interested in.
Representation of an ECAL segment of a global track.
Float_t Pullpi
Pion pull, according to FGD information.
AnaTPCParticleB * TPCSegments[NMAXTPCS]
The TPC segments that contributed to this global track.
bool Apply(AnaEventC &event, ToyBoxB &box) const
void AddSplit(UInt_t nbranches, Int_t b0=-1, Int_t b1=-1, Int_t b2=-1, Int_t b3=-1, Int_t b4=-1, Int_t b5=-1, Int_t b6=-1, Int_t b7=-1)
Add a split in the step sequence. The user should specify the number of branches in this split and th...
Float_t Pullmu
Muon pull, according to FGD information.
Float_t Charge
The reconstructed charge of the particle.
bool CheckRedoSelection(const AnaEventC &event, const ToyBoxB &PreviousToyBox, Int_t &redoFromStep)
Float_t GetPIDLikelihood(const AnaTrackB &track, Int_t hypo, bool prod5Cut=0)
Int_t nRecObjectsInGroup[NMAXRECOBJECTGROUPS]
----—— RecObjects and TrueRecObjects used in the selection and systematics ------------—— ...
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
bool IsRelevantRecObjectForSystematic(const AnaEventC &event, AnaRecObjectC *recObj, SystId_h systId, Int_t branch) const
Is this track relevant for a given systematic (prior to selection, call when initializing the event...
int nTPCSegments
How many TPC tracks are associated with this track.
Representation of a true Monte Carlo trajectory/particle.
void InitializeEvent(AnaEventC &event)
Fill the EventBox with the objects needed by this selection.
bool IsRelevantTrueObjectForSystematic(const AnaEventC &event, AnaTrueObjectC *trueObj, SystId_h systId, Int_t branch) const
Is this true track relevant for a given systematic (prior to selection, call when initializing the ev...
bool IsRelevantTrueObjectForSystematicInToy(const AnaEventC &event, const ToyBoxB &box, AnaTrueObjectC *trueTrack, SystId_h systId, Int_t branch) const
Is this true track relevant for a given systematic (after selection, called for each toy) ...
SubDetEnum
Enumeration of all detector systems and subdetectors.
Int_t PDG
The PDG code of this particle.
AnaTrackB * HMNtrack
For storing the highest momentum negative track.
AnaFgdTimeBinB ** FGDMichelElectrons[2]
----------— Michel Electron candidates -------------------------------—
Representation of a global track.
Float_t ComputeTPCPull(const AnaTPCParticleB &track, const std::string &particle)
Function to recompute the pull for a TPC track segment.
bool IsRelevantRecObjectForSystematicInToy(const AnaEventC &, const ToyBoxB &, AnaRecObjectC *, SystId_h systId, Int_t branch=0) const
Is this track relevant for a given systematic (after selection, called for each toy) ...
Representation of a TPC segment of a global track.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool APPLY_SYST_FINE_TUNING
General tuning, the concept of apply the systematic for only the "relevant" objects.
bool IsRelevantTrueObjectForSystematic(const AnaEventC &event, AnaTrueObjectC *trueObj, SystId_h systId, Int_t branch) const
Is this true track relevant for a given systematic (prior to selection, call when initializing the ev...
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
AnaEventSummaryC * Summary
A summary of the event with high level quantities.
Representation of a FGD segment of a global track.
bool IsRelevantSystematic(const AnaEventC &event, const ToyBoxB &box, SystId_h systId, Int_t branch) const
Is this systematic relevant for this selection.
void SetBranchAlias(Int_t ID, const std::string &name, Int_t b0=-1, Int_t b1=-1, Int_t b2=-1, Int_t b3=-1, Int_t b4=-1, Int_t b5=-1, Int_t b6=-1, Int_t b7=-1)
Set the branch alias and unique ID provided the branch sequence.
int nFGDSegments
How many FGD tracks are associated with this track.
Int_t Containment
Containment flag required for proper PID analysis.
void SetDetectorFV(SubDetId_h det, Int_t ibranch=-1)
Set the detector in which the Fiducial Volume is defined.
Int_t MostUpStreamLayerHit
Innermost layer hit of the ecal object (used in ecal pi0 veto)
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
ToyBoxB ** PreviousToyBox
Array of pointers to the PreviousToyBox (for each event)
bool TrackUsesOnlyDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
AnaFGDParticleB * FGDSegments[NMAXFGDS]
The FGD segments that contributed to this global track.
bool IsRelevantTrueObjectForSystematicInToy(const AnaEventC &, const ToyBoxB &, AnaTrueObjectC *, SystId_h systId, Int_t branch=0) const
Is this true track relevant for a given systematic (after selection, called for each toy) ...
numuCCMultiPiSelection(bool forceBreak=true)
void InitializeEvent(AnaEventC &event)
Fill the EventBox with the objects needed by this selection.
void AddStep(StepBase::TypeEnum type, const std::string &title, StepBase *step, bool cut_break=false)
Int_t GetCutNumber(const std::string &title, Int_t ID=0) const
Return the cut number (starting at 0) corresponding to an step with a given title.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool CheckRedoSelection(const AnaEventC &event, const ToyBoxB &PreviousToyBox, Int_t &redoFromStep)