1 #include "numuCC4piMultiPiSelection.hxx" 2 #include "baseSelection.hxx" 3 #include "SystematicTuning.hxx" 4 #include "CutUtils.hxx" 5 #include "EventBoxUtils.hxx" 6 #include "Parameters.hxx" 7 #include "SubDetId.hxx" 9 #include "SystematicUtils.hxx" 12 numuCC4piMultiPiSelection::numuCC4piMultiPiSelection(
bool forceBreak):
SelectionBase(forceBreak,
EventBoxId::kEventBoxTracker) {
16 systTuning::Initialize();
39 AddStep(0, StepBase::kCut,
"Fwd 4piMultiPi Cut",
new numuCC4pi::Fwd());
53 AddStep(1, StepBase::kCut,
"Bwd 4piMultiPi Cut",
new numuCC4pi::Bwd());
92 SetBranchAlias(0,
"Fwd CC0pi", 0, 0);
93 SetBranchAlias(1,
"Fwd CC1pi", 0, 1);
94 SetBranchAlias(2,
"Fwd CCOther", 0, 2);
96 SetBranchAlias(3,
"Bwd CC0pi", 1,0);
97 SetBranchAlias(4,
"Bwd CC1pi", 1,1);
98 SetBranchAlias(5,
"Bwd CCOther", 1,2);
100 SetBranchAlias(6,
"HAFwd CC0pi", 2,0);
101 SetBranchAlias(7,
"HAFwd CC1pi", 2,1);
102 SetBranchAlias(8,
"HAFwd CCOther", 2,2);
104 SetBranchAlias(9,
"HABwd CC0pi", 3,0);
105 SetBranchAlias(10,
"HABwd CC1pi", 3,1);
106 SetBranchAlias(11,
"HABwd CCOther",3,2);
108 SetPreSelectionAccumLevel(2);
118 FVDef::FVdefminFGD1[2] = 0;
119 FVDef::FVdefmaxFGD1[2] = 0;
122 SetDetectorFV(SubDetId::kFGD1);
134 if (!event.EventBoxes[EventBoxId::kEventBoxTracker])
event.EventBoxes[EventBoxId::kEventBoxTracker] =
new EventBoxTracker();
136 boxUtils::FillTracksWithTPC(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
137 boxUtils::FillTracksWithFGD(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
138 boxUtils::FillTracksWithECal(event);
140 boxUtils::FillTrajsChargedInTPC(event);
141 boxUtils::FillTrajsChargedInFGDAndNoTPC(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
142 boxUtils::FillTrajsChargedHATracker(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
143 boxUtils::FillTrajsInECal(event);
148 bool numuCC4piMultiPiSelection::FillEventSummary(
AnaEventC& event, Int_t allCutsPassed[]){
151 if(allCutsPassed[0])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
152 if(allCutsPassed[1])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
153 if(allCutsPassed[2])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
155 if(allCutsPassed[3])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
156 if(allCutsPassed[4])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
157 if(allCutsPassed[5])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
159 if(allCutsPassed[6])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
160 if(allCutsPassed[7])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
161 if(allCutsPassed[8])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
163 if(allCutsPassed[9])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
164 if(allCutsPassed[10])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
165 if(allCutsPassed[11])
static_cast<AnaEventSummaryB*
>(
event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
167 return (static_cast<AnaEventSummaryB*>(event.
Summary)->EventSample != SampleId::kUnassigned);
177 if(!cc4piMultiPibox->
MainTrack)
return 1;
180 static_cast<AnaEventSummaryB*>(event.
Summary)->LeptonCandidate[SampleId::kFGD1NuMuCC1Pi] = cc4piMultiPibox->
MainTrack;
183 anaUtils::CopyArray( cc4piMultiPibox->
MainTrack->
PositionStart, static_cast<AnaEventSummaryB*>(event.
Summary)->VertexPosition[SampleId::kFGD1NuMuCC0Pi], 4);
184 anaUtils::CopyArray( cc4piMultiPibox->
MainTrack->
PositionStart, static_cast<AnaEventSummaryB*>(event.
Summary)->VertexPosition[SampleId::kFGD1NuMuCC1Pi], 4);
185 anaUtils::CopyArray( cc4piMultiPibox->
MainTrack->
PositionStart, static_cast<AnaEventSummaryB*>(event.
Summary)->VertexPosition[SampleId::kFGD1NuMuCCOther], 4);
203 if (useTPCPions) numuCC4piMultiPiUtils::FindTPCPions(event, box, det, useOldSecondaryPID);
204 if (useME) numuCC4piMultiPiUtils::FindMEPions(event,det, prod5Cut);
205 if (useFGDPions) numuCC4piMultiPiUtils::FindIsoFGDPions(event, box, det);
207 int nnegpions = cc4piMultiPibox->nNegativePionTPCtracks;
208 int npospions = cc4piMultiPibox->nPositivePionTPCtracks;
209 int nisofgdpions = cc4piMultiPibox->nIsoFGDPiontracks;
210 int nmichelelectrons = EventBox->nFGDMichelElectrons[det];
211 int npi0 = cc4piMultiPibox->nPosPi0TPCtracks+ cc4piMultiPibox->nElPi0TPCtracks;
213 int pionFGD = nmichelelectrons;
214 if (!nmichelelectrons && nisofgdpions>0) pionFGD = 1;
216 cc4piMultiPibox->nPosPions = npospions+pionFGD;
217 cc4piMultiPibox->nOtherPions = nnegpions+npi0;
230 EventBoxTracker::RecObjectGroupEnum groupID;
231 groupID = EventBoxTracker::kTracksWithECal;
232 EventBoxB* EventBox =
event.EventBoxes[EventBoxId::kEventBoxTracker];
235 double higherEnergyObject = 0;
239 AnaTrackB *allECALObjects =
static_cast<AnaTrackB*
>(EventBox->RecObjectsInGroup[groupID][i]);
251 cc4piMultiPibox->ISOEcal.push_back(
object);
254 if(ecalBase->
EMEnergy > higherEnergyObject){
255 higherEnergyObject = ecalBase->
EMEnergy;
256 highestObject = object;
262 cc4piMultiPibox->HObject = highestObject;
264 if( numuCC4piMultiPiUtils::ECALPi0Selection(event, box, highestObject, MostUpstreamLayerHitCut, det) ) {
265 cc4piMultiPibox->Pi0Ecaltrack = highestObject;
266 cc4piMultiPibox->nPi0Ecaltracks = cc4piMultiPibox->nPi0Ecaltracks+1;
281 if( cc4piMultiPibox->nPosPions + cc4piMultiPibox->nOtherPions == 0 ) {
297 if( cc4piMultiPibox->nOtherPions != 0 )
return false;
298 if( cc4piMultiPibox->nPosPions == 1 ){
314 if( cc4piMultiPibox->nOtherPions != 0 ){
317 if( cc4piMultiPibox->nPosPions > 1 ){
320 if( cc4piMultiPibox->nPi0Ecaltracks > 0){
332 cc4piMultiPibox->nPositivePionTPCtracks = 0;
333 cc4piMultiPibox->nPosPi0TPCtracks = 0;
334 cc4piMultiPibox->nNegativePionTPCtracks = 0;
335 cc4piMultiPibox->nElPi0TPCtracks = 0;
337 EventBoxTracker::RecObjectGroupEnum groupID;
338 if (det==SubDetId::kFGD1) groupID = EventBoxTracker::kTracksWithGoodQualityTPCInFGD1FV;
339 else if (det==SubDetId::kFGD2) groupID = EventBoxTracker::kTracksWithGoodQualityTPCInFGD2FV;
342 EventBoxB* EventBox =
event.EventBoxes[EventBoxId::kEventBoxTracker];
349 if(useOldSecondaryPID){
350 if ( numuCC4piMultiPiUtils::TPCpionSelection(ptrack) ) {
351 cc4piMultiPibox->PositivePionTPCtracks[cc4piMultiPibox->nPositivePionTPCtracks] = ptrack;
352 cc4piMultiPibox->nPositivePionTPCtracks++;
354 else if ( numuCC4piMultiPiUtils::TPCElPi0Selection(ptrack) ) {
355 cc4piMultiPibox->PosPi0TPCtracks[cc4piMultiPibox->nPosPi0TPCtracks] = ptrack;
356 cc4piMultiPibox->nPosPi0TPCtracks++;
360 Float_t PIDLikelihood[4];
364 double ElLklh = PIDLikelihood[1];
365 double ProtonLklh = PIDLikelihood[2];
366 double PionLklh = PIDLikelihood[3];
367 double norm = ElLklh+ProtonLklh+PionLklh;
372 if( ProtonLklh > ElLklh && ProtonLklh > PionLklh )
continue;
375 if( PionLklh > ElLklh ){
376 cc4piMultiPibox->PositivePionTPCtracks[cc4piMultiPibox->nPositivePionTPCtracks] = ptrack;
377 cc4piMultiPibox->nPositivePionTPCtracks++;
380 if( ptrack->
Momentum > 900. )
continue;
381 cc4piMultiPibox->PosPi0TPCtracks[cc4piMultiPibox->nPosPi0TPCtracks] = ptrack;
382 cc4piMultiPibox->nPosPi0TPCtracks++;
387 if( cc4piMultiPibox->
MainTrack == ptrack )
continue;
389 if(useOldSecondaryPID) {
390 if ( numuCC4piMultiPiUtils::TPCpionSelection(ptrack) ) {
391 cc4piMultiPibox->NegativePionTPCtracks[cc4piMultiPibox->nNegativePionTPCtracks] = ptrack;
392 cc4piMultiPibox->nNegativePionTPCtracks++;
394 else if ( numuCC4piMultiPiUtils::TPCElPi0Selection(ptrack) ) {
395 cc4piMultiPibox->ElPi0TPCtracks[cc4piMultiPibox->nElPi0TPCtracks] = ptrack;
396 cc4piMultiPibox->nElPi0TPCtracks++;
401 Float_t PIDLikelihood[4];
405 double ElLklh = PIDLikelihood[1];
406 double PionLklh = PIDLikelihood[3];
407 double norm = ElLklh+PionLklh;
411 if( PionLklh > 0.8 ){
412 cc4piMultiPibox->NegativePionTPCtracks[cc4piMultiPibox->nNegativePionTPCtracks] = ptrack;
413 cc4piMultiPibox->nNegativePionTPCtracks++;
416 cc4piMultiPibox->ElPi0TPCtracks[cc4piMultiPibox->nElPi0TPCtracks] = ptrack;
417 cc4piMultiPibox->nElPi0TPCtracks++;
429 cc4piMultiPibox->nIsoFGDPiontracks = 0;
430 cc4piMultiPibox->nIsoFGDElPi0tracks = 0;
432 EventBoxTracker::RecObjectGroupEnum groupID;
433 if (det==SubDetId::kFGD1) groupID = EventBoxTracker::kTracksWithFGD1AndNoTPC;
434 else if (det==SubDetId::kFGD2) groupID = EventBoxTracker::kTracksWithFGD2AndNoTPC;
437 EventBoxB* EventBox =
event.EventBoxes[EventBoxId::kEventBoxTracker];
443 if( numuCC4piMultiPiUtils::FGDpionSelection(track,det) ){
444 cc4piMultiPibox->IsoFGDPiontracks[cc4piMultiPibox->nIsoFGDPiontracks] = track;
445 cc4piMultiPibox->nIsoFGDPiontracks++;
447 else if( numuCC4piMultiPiUtils::FGDElPi0Selection(event,box,track,det) ){
448 cc4piMultiPibox->IsoFGDElPi0tracks[cc4piMultiPibox->nIsoFGDElPi0tracks] = track;
449 cc4piMultiPibox->nIsoFGDElPi0tracks++;
467 anaUtils::ResizeArray(EventBox->
FGDMichelElectrons[det], EventBox->nFGDMichelElectrons[det]);
472 bool numuCC4piMultiPiUtils::TPCpionSelection(
AnaTrackB *track){
475 Float_t PIDLikelihood[4];
478 if ( PIDLikelihood[3] < 0.3 )
return false;
480 double cut1 = (PIDLikelihood[0]+PIDLikelihood[3])/(1.-PIDLikelihood[2]);
482 if( track->
Momentum < 500. && cut1 < 0.8 )
return false;
490 bool numuCC4piMultiPiUtils::TPCElPi0Selection(
AnaTrackB *track){
495 bool seltrack =
false;
499 if( track->
Momentum < 50. )
return seltrack;
509 if( !tpcTrack )
continue;
514 if (TMath::Abs(pulls[0]) > 1.e+6
515 || TMath::Abs(pulls[1]) > 1.e+6
516 || TMath::Abs(pulls[2]) > 1.e+6
517 || TMath::Abs(pulls[3]) > 1.e+6)
continue;
519 if( pulls[1] < -2.0 || pulls[1] > 2.0 )
break;
521 if( track->
Charge > 0. && ( pulls[2] > -4.0 && pulls[2] < 8.0 ) )
break;
536 if( !fgdTrack )
return false;
538 if( TMath::Abs(fgdTrack->
Pullp) > 1.e+6 || TMath::Abs(fgdTrack->
Pullmu) > 1.e+6 || TMath::Abs(fgdTrack->
Pullpi) > 1.e+6 )
return false;
543 if( fgdTrack->
Pullno == 1 )
return false;
549 if ( det == SubDetId::kFGD1 && fgdTrack->
Containment != 1 )
return false;
550 else if( det == SubDetId::kFGD2 && fgdTrack->
Containment != 2 )
return false;
555 if(cosFGDpion > -0.3 && cosFGDpion < 0.3)
return false;
557 if( fgdTrack->
Pullpi < 2.5 && fgdTrack->
Pullpi > -2.0 )
return true;
576 if( !fgdTrack )
return false;
578 if( TMath::Abs(fgdTrack->
Pullp) > 1.e+6 || TMath::Abs(fgdTrack->
Pullmu) > 1.e+6 || TMath::Abs(fgdTrack->
Pullpi) > 1.e+6 )
return false;
583 if( fgdTrack->
Pullno == 1 )
return false;
589 if ( det == SubDetId::kFGD1 && fgdTrack->
Containment != 1 )
return false;
590 else if( det == SubDetId::kFGD2 && fgdTrack->
Containment != 2 )
return false;
595 if(EventBox->nFGDMichelElectrons[det] > 0 && fgdTrack->
Pullpi < -3.0 )
return true;
596 if(EventBox->nFGDMichelElectrons[det] == 0 && fgdTrack->
Pullpi < -1.5 )
return true;
610 if(cc4piMultiPibox->nPi0Ecaltracks > 0)
return false;
626 bool Ecalpi0 =
false;
628 double EMENERGY = -9999.;
629 double MIPEM = -9999.;
630 double EM_UPSTREAM = -9999;
632 if( !EcalSegment )
return false;
638 if (EMENERGY > 30. && MIPEM > 0.) Ecalpi0 =
true;
644 if(EM_UPSTREAM > MostUpstreamLayerHitCut ) Ecalpi0 =
false;
672 if (!track)
return false;
689 if (!trueTrack)
return false;
706 if(systId == SystId::kTpcClusterEff){
710 if (tpcTrack->
NNodes > 16 && tpcTrack->
NNodes < 19)
return true;
715 if(systId == SystId::kChargeIDEff){
716 if (track == cc4piMultiPibox.
MainTrack)
return true;
719 if(systId == SystId::kTpcFgdMatchEff){
720 if (track == cc4piMultiPibox.
MainTrack)
return true;
723 if(systId == SystId::kECalPID){
724 if (track == cc4piMultiPibox.
MainTrack) {
725 if (branch==2 || branch==3)
return true;
726 else if (branch==0 || branch==4 || branch==5) {
751 if(systId == SystId::kTpcTrackEff){
756 if(systId == SystId::kECalTrackEff){
761 if(systId == SystId::kTpcP0dMatchEff){
765 if(systId == SystId::kTpcECalMatchEff){
769 if(systId == SystId::kFgdECalMatchEff){
773 if(systId == SystId::kFgdECalSmrdMatchEff){
777 if(systId == SystId::kSIPion){
792 if(systId == SystId::kSIProton){
814 (void)PreviousToyBoxB;
AnaTrueVertexB * TrueVertex
Pointer to the AnaTrueVertexB of the interaction that created this AnaTrueParticleB.
bool Apply(AnaEventC &event, ToyBoxB &box) const
Float_t PositionStart[4]
The reconstructed start position of the particle.
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) ...
bool Apply(AnaEventC &event, ToyBoxB &box) const
void InitializeEvent(AnaEventC &event)
Fill the EventBox with the objects needed by this selection.
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.
Float_t Pullp
Proton pull, according to FGD information.
void DefineDetectorFV()
Define the detector Fiducial Volume in which this selection is applied.
Float_t Pullno
Dummy pull. If the FGD pulls weren't set, this is set to 1.
Int_t NNodes
The number of nodes in the reconstructed object.
SubDetId_h DetectorFV
Indicate the FV we are interested in.
Int_t GParentPDG
The PDG code of this particle's grandparent, or 0 if there is no grandparent.
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
bool IsRelevantSystematic(const AnaEventC &event, const ToyBoxB &box, SystId_h systId, Int_t branch) const
Is this systematic relevant for this selection.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool CheckRedoSelection(const AnaEventC &event, const ToyBoxB &PreviousToyBox, Int_t &redoFromStep)
AnaTrueObjectC * TrueObject
The link to the true oject that most likely generated this reconstructed object.
Float_t Momentum
The initial momentum of the true particle.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool TrackUsesDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
Float_t Pullmu
Muon pull, according to FGD information.
Float_t Charge
The reconstructed charge of the particle.
Int_t ID
The ID of the trueObj, which corresponds to the ID of the TTruthParticle that created it...
void DefineSteps()
Define all steps in the selection.
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.
int nTPCSegments
How many TPC tracks are associated with this track.
Representation of a true Monte Carlo trajectory/particle.
SubDetEnum
Enumeration of all detector systems and subdetectors.
Int_t PDG
The PDG code of this particle.
Int_t ParentPDG
The PDG code of this particle's immediate parent, or 0 if there is no parent.
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 Apply(AnaEventC &event, ToyBoxB &box) const
Representation of a TPC segment of a global track.
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...
AnaTrackB * MainTrack
For storing tracks information in the bunch.
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...
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.
int nFGDSegments
How many FGD tracks are associated with this track.
Int_t Containment
Containment flag required for proper PID analysis.
Int_t MostUpStreamLayerHit
Innermost layer hit of the ecal object (used in ecal pi0 veto)
AnaParticleB * GetSegmentWithMostNodesInClosestTpc(const AnaTrackB &track)
Combined function to address NuMu selection needs as efficiently as possible - gets the TPC segment w...
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
bool InFiducialVolume(SubDetId::SubDetEnum det, const Float_t *pos, const Float_t *FVdefmin, const Float_t *FVdefmax)
bool TrackUsesOnlyDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
AnaFGDParticleB * FGDSegments[NMAXFGDS]
The FGD segments that contributed to this global track.
A cut on event quality. Requires good beam and ND280 data quality flags.
Float_t PositionEnd[4]
The reconstructed end position of the particle.
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) ...