#include "hparticlecand.h" #include "henergylosscorrpar.h" #include "hparticleanglecor.h" #include "hphysicsconstants.h" #include "TMath.h" #include #include using namespace std; // ROOT's IO and RTTI stuff is added here ClassImp(HParticleCand) //_HADES_CLASS_DESCRIPTION //////////////////////////////////////////////////////////////////////////////// // // // HParticleCand // // In this container matched hits from all detectors are stored. // The class does not define the algorithm how the matching is done. // This is defined in HMetaMatchF2 (coarse matching) and HParticleCandFiller. // // ------------------------------------------------------------------------- // Track Cleaner flags // To clean the ParticleCand objects from unwanted fakes // the object carries a bitfield (32 bit Int_t). The different // qualitiy criteria can be used to select the best reconstructed // candidate in the case of multiple use of single detector hits. // The single bit numbers are defined by enum eFlagBits (see hparticledef.h) // // The selection of tracks and setting of the corresponding flags is performed // by HParticleCandCleaner and HParticleCandSorter classes (see the documentation). // // For example void setFlagBit(HParticle::kIsDoubleRICH) sets the bit flag that // the RICH hit has been used in more than one HParticleCand object. // Correspondingly one can ask for the flag with Bool_t isFlagBit(HParticle::kIsDoubleRICH) // void setFlagBit(Int_t bit) and Bool_t isFlagBit(Int_t bit) works for the bitnumber (0-31) specified // manually (if one knows what one is doing....) // void setFlagBit (eFlagBits bit) // void unsetFlagBit (eFlagBits bit) // Bool_t isFlagBit (eFlagBits bit) // void setFlagBit (Int_t bit); // void unsetFlagBit (Int_t bit); // Bool_t isFlagBit (Int_t bit); // void setFlagBitByValue(eFlagBits bit, Bool_t val) sets/unsets bit depending on val // void setFlagBitByValue(Int_t bit, Bool_t val) sets/unsets bit depending on val // Bool_t isFlagDoubleHit () check all Double_t hits flags simultanously (false if none set) // Bool_t isFlagAllBestHit() check all best hit flags simultanously (true if all are set) // Int_t getDoubleHitsLeptons() returns the 4 bit Double_t hit word as Int_t // Int_t getDoubleHitsHadrons() returns the 3 bit Double_t hit word (excluding RICH) as Int_t // Bool_t isFlagNoBestHit () check all best hit flags simultanously (true if none set) // Int_t getFlagField() do what you want with flags field // Bool_t isFlagAND(Int_t num,Int_t fl, ...) check all flags in argument simultanously (false if none set) // Bool_t isFlagOR(Int_t num,Int_t fl, ...) check all flags in argument simultanously (true if any set) // void printFlags(TString comment="") prints all flags in binary representation. // void printInfo() prints indices of detector hits + quality criteria + flags // // The function // Bool_t select(Bool_t (*function)(HParticleCand* )) { return (*function)(this); } // taking a pointer to function with argument HParticleCand* returning a Bool_t allows // todo complex selection on the HParticleCand object as one has // full access to all members of HParticleCand inside the test function. // The function pointer can be a pointer to a global function or member function // of an Object for example: // // Bool_t test(HParticleCand* cand){ // global function // if ( put all selection criteria here ) return kTRUE; // else return kFALSE; // } or // // static Bool_t dummy::test(HParticleCand* cand){ // member function of object dummy // // needs to be declared static ! // if ( put all selection criteria here ) return kTRUE; // else return kFALSE; // } // would be called in the code like // // dummy d; // HParticleCand* p= new HParticleCand() // just to get an object // p->select(test)) // global function // p->select(dummy::test)) // member function of object dummy (static call without object creation) // p->select(d.test)) // member function of real object dummy // // //////////////////////////////////////////////////////////////////////////////// void HParticleCand::setFlagBit (Int_t bit) { // set given bit in flag (0-32) if(bit >= 0 && bit < 32 ) fFlags |= ( 0x01 << bit ); else { Error("HParticleCand::setFlagBit(Int_t)","Bit number out of range : %i!",bit); } } void HParticleCand::unsetFlagBit (Int_t bit) { // unset given bit in flag (0-32) if(bit >= 0 && bit < 32 ) fFlags &= ~( 0x01 << bit ); else { Error("HParticleCand::unsetFlagBit(Int_t)","Bit number out of range : %i!",bit); } } Bool_t HParticleCand::isFlagBit (Int_t bit) { // check given bit in flag (0-32) // return kTRUE if bit is set if (bit >= 0 && bit < 32 ) return (fFlags >> bit ) & 0x01; else { Error("HParticleCand::isFlagBit(Int_t)","Bit number out of range : %i!",bit); return kFALSE; } } Bool_t HParticleCand::isFlagOR(Int_t num,...) { // check given number of bits in argument in flag (0-32) // return kTRUE if any bit is set va_list ap; va_start(ap,num); for(Int_t i=0;i 31) { Error("HParticleCand::isFlagOR()","Bit number out of range : i=%i ,%i!",i,bit); va_end(ap); return kFALSE; } if(isFlagBit(bit)) { va_end(ap); return kTRUE; } } va_end(ap); return kFALSE; } Bool_t HParticleCand::isFlagAND(Int_t num, ...) { // check given number of bits in argument in flag (0-32) // return kTRUE if all bits are set va_list ap; va_start(ap,num); for(Int_t i=0;i 31) { Error("HParticleCand::isFlagAND()","Bit number out of range : i=%i ,%i!",i,bit); va_end(ap); return kFALSE; } if(!isFlagBit(bit)) { va_end(ap); return kFALSE; } } va_end(ap); return kTRUE; } void HParticleCand::printFlags(TString comment) { // print the flag field in binary representation // Comment will be printed at the end of line TString out=""; for(Int_t i=32;i>0;i--){ if(i%4==0) out+=" "; out+= ( (fFlags>>(i-1)) & 0x1 ); } cout<<"bin "<>0) & 0x01){ cout<<" " <<"sec: " <>1) & 0x01){ cout<<" " <<", ichi2: " <= 0 && fChi2 > 0 ) ? fMetaMatchQuality*fChi2 : -1.f) <<", RKRKMR: " <<((fMetaMatchRadius >= 0 && fChi2 > 0 ) ? fMetaMatchRadius*fChi2 : -1.f) <<", RKR: " <<((fRichInd >= 0) ? getRichMatchingQuality() : -1.f) <<", RK: " <>2) & 0x01){ cout<<"PID : pid : " <>3) & 0x01) printFlags(); } Float_t HParticleCand::getZprime(Float_t xBeam,Float_t yBeam,Float_t& rPrime) { // xBeam, yBeam - position of beam(target) line in lab.system // returns zPrime coordinate value, rPrime as function argument Float_t phi = fPhi * TMath::DegToRad(); Float_t cosPhi = TMath::Cos(phi); Float_t sinPhi = TMath::Sin(phi); Float_t tanTh = TMath::Tan(fTheta * TMath::DegToRad()); rPrime = fR + xBeam * sinPhi - yBeam * cosPhi; if(TMath::Abs(tanTh) > 1.e-10) { return fZ + (xBeam * cosPhi + yBeam * sinPhi) / tanTh; } else { return fZ; } } Float_t HParticleCand::getZprime(Float_t xBeam,Float_t yBeam) { // xBeam, yBeam - position of beam(target) line in lab.system // returns zPrime coordinate value. if rPrime is needed too // use Float_t HParticleCand::getZprime(Float_t xBeam,Float_t yBeam,Float_t& rPrime) // to save some calculations Float_t tanTh = TMath::Tan(fTheta * TMath::DegToRad()); if(TMath::Abs(tanTh) < 1.e-10) return fZ; Float_t phi = fPhi * TMath::DegToRad(); return fZ + (xBeam * TMath::Cos(phi) + yBeam * TMath::Sin(phi)) / tanTh; } Float_t HParticleCand::getRprime(Float_t xBeam,Float_t yBeam) { // xBeam, yBeam - position of beam(target) line in lab.system // returns zPrime coordinate value. if zPrime is needed too // use Float_t HParticleCand::getZprime(Float_t xBeam,Float_t yBeam,Float_t& rPrime) // to save some calculations Float_t phi = fPhi * TMath::DegToRad(); return fR + xBeam * TMath::Sin(phi) - yBeam * TMath::Cos(phi); } Float_t HParticleCand::getMomentumPID(Int_t pid) { // returns the momentum of the candidate taking // into account the charge of the provided PID ( mom*charge) // In the track reconstruction by default all // momenta are recontructed using charge = 1 if(fMomentum == -1) return fMomentum; Float_t mom = fMomentum; Int_t chrg = TMath::Abs(HPhysicsConstants::charge(pid)); if(chrg > 0) mom = mom*chrg; return mom; } Float_t HParticleCand::getMomentumCorrectionPID(Int_t pid) { // return the momentum correction for the candidate // due to material budget in target + rich + absorbers. // requires HEnergyLossCorrPar. The correction takes // into acount the charge of the particle ( > 1). Units // are MeV/c if(fMomentum == -1) return 0; static Bool_t doError = kTRUE; HEnergyLossCorrPar* corrpar = HEnergyLossCorrPar::getObject(); Float_t corr = 0.; if(corrpar){ Double_t mom = fMomentum; Int_t chrg = TMath::Abs(HPhysicsConstants::charge(pid)); if(chrg > 0) mom = mom*chrg; corr = (Float_t) corrpar->getDeltaMom(pid,mom,fTheta); } else { if(doError) Error("getMomCorr()","HEnergyLossCorrPar not initialized!"); doError = kFALSE; } return corr; } Float_t HParticleCand::getCorrectedMomentumPID(Int_t pid) { // return the corrected momentum for the candidate // due to material budget in target + rich + absorbers. // requires HEnergyLossCorrPar. The correction takes // into acount the charge of the particle ( > 1). Units // are MeV/c if(fMomentum == -1) return fMomentum; Float_t mom = fMomentum; Int_t chrg = TMath::Abs(HPhysicsConstants::charge(pid)); if(chrg > 0) mom = mom*chrg; Float_t corr = getMomentumCorrectionPID(pid); return mom + corr; } Float_t HParticleCand::getMass2PID(Int_t pid) { // returns the mass2 of the candidate taking // into account the charge of the provided PID ( mom*charge) // In the track reconstruction by default all // momenta are recontructed using charge = 1 if(fMass2 == -1) return fMass2; Float_t mom = fMomentum; Int_t chrg = TMath::Abs(HPhysicsConstants::charge(pid)); if(chrg > 0) mom = mom*chrg; return (mom*mom)/(1-fBeta*fBeta)/(fBeta*fBeta); } Float_t HParticleCand::getMass2CorrectionPID(Int_t pid) { // return the mass2 correction (mass2_corr-mass2) for the candidate // due to material budget in target + rich + absorbers. // requires HEnergyLossCorrPar. The correction takes // into acount the charge of the particle ( > 1). Units // are MeV/c if(fMass2 == -1) return 0; Float_t mass2 = getMass2PID(pid); Float_t mass2corr = getCorrectedMass2PID(pid); return mass2corr-mass2; } Float_t HParticleCand::getCorrectedMass2PID(Int_t pid) { // return the corrected mass2 for the candidate // due to material budget in target + rich + absorbers. // requires HEnergyLossCorrPar. The correction takes // into acount the charge of the particle ( > 1). Units // are MeV/c if(fMass2 == -1) return fMass2; Float_t mom = getCorrectedMomentumPID(pid); return (mom*mom)/(1-fBeta*fBeta)/(fBeta*fBeta); } Float_t HParticleCand::getRichMatchingQualityNorm() { // norm delta theta phi by width of distributions, // do some correction for theta,phi and momentum // (W. Koenig, see HParticleAngleCor::matchRingTrack() ) return HParticleAngleCor::matchRingTrack(this); } Int_t HParticleCand::getNLayer(UInt_t io) { Int_t sum=0; for(UInt_t i=0;i<12;i++){ sum+= getLayer(io,i); } return sum; } Int_t HParticleCand::getNLayerMod(UInt_t mod) { Int_t sum=0; UInt_t io =0; if(mod>1) io =1; UInt_t first = 0; UInt_t last = 12; if(mod==1||mod==3)first=6; if(mod==0||mod==2)last =6; for(UInt_t i=first;i0;i--){ if(i<25&&i%6==0) out+=" "; out+= ( (fLayers>>(i-1)) & 0x1 ); } cout<<" layers "<> fFlags; R__b >> fPID; R__b >> fSector; R__b >> fSystem; R__b >> fCharge; R__b >> fTofRec; R__b >> fRingCorr; R__b >> fIndex; R__b >> fBeta; R__b >> fMomentum; R__b >> fMass2; R__b >> fPhi; R__b >> fTheta; R__b >> fR; R__b >> fZ; R__b >> fChi2; R__b >> fDistanceToMetaHit; R__b >> fMdcdEdx; R__b >> fTofdEdx; R__b >> fInnerSegmentChi2; R__b >> fOuterSegmentChi2; R__b >> fAngleToNearbyFittedInner; R__b >> fAngleToNearbyUnfittedInner; R__b >> fRingNumPads; R__b >> fRingAmplitude; R__b >> fRingHouTra; R__b >> fRingPatternMatrix; R__b >> fRingCentroid; R__b >> fRichPhi; R__b >> fRichTheta; R__b >> fMetaMatchQuality; if(R__v > 1) R__b >> fMetaMatchQualityShower; if(R__v > 3){ R__b >> fMetaMatchRadius; R__b >> fMetaMatchRadiusShower; } else { fMetaMatchRadius=-1; fMetaMatchRadiusShower=-1; } R__b >> fShowerSum0; R__b >> fShowerSum1; R__b >> fShowerSum2; if(R__v > 1) R__b >> fSelectedMeta; R__b >> fMetaInd; R__b >> fRichInd; R__b >> fInnerSegInd; R__b >> fOuterSegInd; R__b >> fRpcInd; R__b >> fShowerInd; R__b >> fTofHitInd; R__b >> fTofClstInd; if(R__v > 2) R__b >> fLayers; else fLayers = 0; R__b.CheckByteCount(R__s, R__c, HParticleCand::IsA()); } else { R__c = R__b.WriteVersion(HParticleCand::IsA(), kTRUE); TLorentzVector::Streamer(R__b); R__b << fFlags; R__b << fPID; R__b << fSector; R__b << fSystem; R__b << fCharge; R__b << fTofRec; R__b << fRingCorr; R__b << fIndex; R__b << fBeta; R__b << fMomentum; R__b << fMass2; R__b << fPhi; R__b << fTheta; R__b << fR; R__b << fZ; R__b << fChi2; R__b << fDistanceToMetaHit; R__b << fMdcdEdx; R__b << fTofdEdx; R__b << fInnerSegmentChi2; R__b << fOuterSegmentChi2; R__b << fAngleToNearbyFittedInner; R__b << fAngleToNearbyUnfittedInner; R__b << fRingNumPads; R__b << fRingAmplitude; R__b << fRingHouTra; R__b << fRingPatternMatrix; R__b << fRingCentroid; R__b << fRichPhi; R__b << fRichTheta; R__b << fMetaMatchQuality; R__b << fMetaMatchQualityShower; R__b << fMetaMatchRadius; R__b << fMetaMatchRadiusShower; R__b << fShowerSum0; R__b << fShowerSum1; R__b << fShowerSum2; R__b << fSelectedMeta; R__b << fMetaInd; R__b << fRichInd; R__b << fInnerSegInd; R__b << fOuterSegInd; R__b << fRpcInd; R__b << fShowerInd; R__b << fTofHitInd; R__b << fTofClstInd; R__b << fLayers; R__b.SetByteCount(R__c, kTRUE); } }