#include "hparticlecandfiller.h" #include "hcategorymanager.h" //---------- detector def ---------- #include "hgeantdef.h" #include "hparticledef.h" #include "hmdcdef.h" #include "hmdctrackddef.h" #include "hmdctrackgdef.h" #include "tofdef.h" #include "showerdef.h" #include "richdef.h" #include "rpcdef.h" //---------- hades etc ------------- #include "hades.h" #include "hiterator.h" #include "hcategory.h" #include "hlinearcategory.h" #include "hlocation.h" #include "hruntimedb.h" #include "hspectrometer.h" #include "hdetector.h" #include "hevent.h" //--------- data objects ----------- #include "hmetamatch2.h" #include "hmdcseg.h" #include "hmdcsegsim.h" #include "hmdctrkcand.h" #include "hsplinetrack.h" #include "hrktrackB.h" #include "hshowerhitsim.h" #include "htofhit.h" #include "htofcluster.h" #include "hrichhit.h" #include "hrichhitsim.h" #include "hrpccluster.h" #include "hrpcclustersim.h" #include "hparticlecand.h" #include "hparticlecandsim.h" #include "hparticlecandfillerpar.h" #include "hparticleanglecor.h" #include #include #include #include #include using namespace std; using namespace Particle; //_HADES_CLASS_DESCRIPTION /////////////////////////////////////////////////////////////////////////////// // // HParticleCandFiller // // This tasks loops over HMetaMatch2 objects and fills // the output objects HParticleCand. The taks detects // if it is running in simulation or read data mode automatically // by the existence of the HGeantKine category in the input file. // Different filter options can be applied (see description of // setConditions() ). /////////////////////////////////////////////////////////////////////////////// ClassImp(HParticleCandFiller) HParticleCandFiller::HParticleCandFiller (const Option_t par[]): HReconstructor () { // Constructor calls the constructor of class HReconstructor without the name // and the title as arguments. Optional parameters are explained in setConditions(). initVars (); setConditions(par); } HParticleCandFiller::HParticleCandFiller (const Text_t * name, const Text_t * title, const Option_t par[]): HReconstructor (name, title) { // Constructor calls the constructor of class HReconstructor with the name // and the title as arguments. Optional parameters are explained in setConditions(). initVars (); setConditions(par); } HParticleCandFiller::~HParticleCandFiller (void) { // destructor deletes the iterator if(fMetaMatchIter) delete fMetaMatchIter; } void HParticleCandFiller::setConditions(const Option_t par[]) { // Set parameters by names. Options (may be separated by comma or blank chars), // By default (no option specified) all values will be kFALSE: // GOODSEG0 - skip the track when inner seg chi2 < 0 // GOODSEG1 - skip the track when outer seg chi2 < 0 // GOODMETA - skip the track when no META was fired // GOODRK - skip the track when RK chi2 < 0 // KALMAN - switch from RK to Kalman for mom reco // GOODLEPTON - skip all candidates which have no RICH matching // DEBUG - write out candidate objects for debugging // NORICHALIGN- dont align rich phi and theta TString s = par; s.ToUpper(); fbgoodSeg0 = (strstr(s.Data(), "GOOGSEG0") != NULL); fbgoodSeg1 = (strstr(s.Data(), "GOODSEG1") != NULL); fbgoodMeta = (strstr(s.Data(), "GOODMETA") != NULL); fbgoodRK = (strstr(s.Data(), "GOODRK") != NULL); fbgoodLepton = (strstr(s.Data(), "GOODLEPTON")!= NULL); fmomSwitch = (strstr(s.Data(), "KALMAN") != NULL) ? Particle::kMomKalman : Particle::kMomRK; fbIsDebug = (strstr(s.Data(), "DEBUG") != NULL); fbdoRichAlign= (strstr(s.Data(), "NORICHALIGN")!= NULL)? kFALSE : kTRUE; } void HParticleCandFiller::initVars () { // set internal variables to start values fCatMdcTrkCand = NULL; fCatMetaMatch = NULL; fCatMdcSeg = NULL; fCatTofHit = NULL; fCatTofCluster = NULL; fCatShowerHit = NULL; fCatRichHit = NULL; fCatRpcCluster = NULL; fCatSpline = NULL; fCatRK = NULL; fCatKalman = NULL; fCatParticleCand = NULL; fCatGeantKine = NULL; fMetaMatchIter = NULL; fCatParticleCand = NULL; fCatParticleDebug= NULL; fFillerPar = NULL; fbIsSimulation = kFALSE; fbIsDebug = kFALSE; fbgoodSeg0 = kFALSE; fbgoodSeg1 = kFALSE; fbgoodMeta = kFALSE; fbgoodRK = kFALSE; fbgoodLepton = kFALSE; fmomSwitch = Particle::kMomRK; fbdoRichAlign = kTRUE; fMinWireGoodTrack= 5; fScaleGhostTrack = 0.1; fScaleGoodTrack = 3.0; fAngleCloseTrack = 15.; all_candidates.resize( 2000, 0 ); // increase capacity to avoid later copying of data all_candidates.clear(); // capacity is still large } Bool_t HParticleCandFiller::init (void) { // Get Categories and Parameters etc.... HEvent *ev = gHades->getCurrentEvent (); if (ev) { fCatGeantKine = ev->getCategory (catGeantKine); if (fCatGeantKine) { fbIsSimulation = kTRUE; } else { fbIsSimulation = kFALSE;} if(!(fCatMetaMatch = HCategoryManager::getCategory(catMetaMatch ,kFALSE,"catMetaMatch" ))) return kFALSE; if(!(fCatMdcTrkCand = HCategoryManager::getCategory(catMdcTrkCand,kFALSE,"catMdcTrkCand"))) return kFALSE; if(!(fCatMdcSeg = HCategoryManager::getCategory(catMdcSeg ,kFALSE,"catMdcSeg" ))) return kFALSE; fCatTofHit = HCategoryManager::getCategory(catTofHit ,kTRUE,"catTofHit"); fCatTofCluster = HCategoryManager::getCategory(catTofCluster ,kTRUE,"catTofCluster"); fCatRichHit = HCategoryManager::getCategory(catRichHit ,kTRUE,"catRichHit"); fCatRpcCluster = HCategoryManager::getCategory(catRpcCluster ,kTRUE,"catRpcCluster"); fCatSpline = HCategoryManager::getCategory(catSplineTrack ,kTRUE,"catSplineTrack"); if(fmomSwitch==Particle::kMomRK) fCatRK = HCategoryManager::getCategory(catRKTrackB ,kTRUE,"catRKTrackB"); if(fmomSwitch==Particle::kMomKalman)fCatKalman = HCategoryManager::getCategory(catKalTrack ,kTRUE,"catKalTrack"); fCatShowerHit = HCategoryManager::getCategory(catShowerHit,kTRUE,"catShowerHit"); if (fbIsSimulation) { fCatParticleCand = HCategoryManager::addCategory(catParticleCand,"HParticleCandSim",5000,"Particle"); } else { fCatParticleCand = HCategoryManager::addCategory(catParticleCand,"HParticleCand" ,5000,"Particle"); } if (!fCatParticleCand) { return kFALSE; } if (fbIsDebug) { fCatParticleDebug = HCategoryManager::addCategory(catParticleDebug,"candidate",5000,"Particle",kTRUE); if (!fCatParticleDebug) { return kFALSE; } } fMetaMatchIter = (HIterator*) fCatMetaMatch->MakeIterator("native"); if(!fMetaMatchIter){ Error ("init()", "Retrieve ZERO pointer for MetaMatch iter!"); return kFALSE; } fFillerPar =(HParticleCandFillerPar*) gHades->getRuntimeDb()->getContainer("ParticleCandFillerPar"); if(!fFillerPar) { Error ("init()", "Retrieve ZERO pointer for HParticleCandFillerPar!"); return kFALSE; } } else { Error ("init()", "Retrieve ZERO pointer for fMetaMatchIter!"); return kFALSE; } return kTRUE; } Int_t HParticleCandFiller::execute (void) { // loop on HMetaMatch2 objects and fill an intermediate // working candidate object. Selections are performed on this // objects. All objects which are flagged to be used are // transported to the output HParticleCand category. clearVector(); HMetaMatch2* metaMatch = 0; fMetaMatchIter->Reset(); while( (metaMatch = (HMetaMatch2*)fMetaMatchIter->Next()) != 0){ if (fmomSwitch == Particle::kMomRK) fillCand (metaMatch); else if (fmomSwitch == Particle::kMomKalman) fillCandKalman(metaMatch); } fillSingleProperties(); fillCollectiveProperties(); fillOutput(); clearVector(); return 0; } Bool_t HParticleCandFiller::finalize (void) { // jobs to be done after last event is finished. return kTRUE; } Int_t HParticleCandFiller::findBestRich(HMetaMatch2* meta,HMdcSeg* mdcSeg1 ) { // returns the best rich slot in HMetaMatch2 // corrections for RICH phi+theta are taken into // account if(!meta || !mdcSeg1 || !fCatRichHit || !fFillerPar) return -1; Int_t nrich = meta->getNCandForRich(); Int_t slot = -1; if(nrich > 1){ Float_t zVertex = gHades->getCurrentEvent()->getHeader()->getVertexZ(); Double_t thebest = 0; Double_t phibest = 0; Double_t qabest = 0; HRichHit* richHit = 0; //vector meanChrg ; vector qa ; // cout<<"-------------------------------"<getARichInd(i)); Double_t theta = richHit->getTheta(); Double_t phi = richHit->getPhi(); Double_t richCorr = 0.; if(zVertex > -1000 ) richCorr = fFillerPar->getRichCorr(zVertex,theta); theta += richCorr; // first correct z position emission Double_t thetaCor = theta; Double_t phiCor = phi; if(!fbIsSimulation && fbdoRichAlign){ HParticleAngleCor::alignRichRing(theta,phi,thetaCor,phiCor); // second correct theta/phi } Double_t rphi = fmod(phiCor,60.) + 60; qa.push_back(HParticleTool::calcRichQA(mdcSeg1, (Float_t) thetaCor,(Float_t) phiCor)); //meanChrg.push_back(richHit->getRingAmplitude()/(Float_t)richHit->getRingPadNr()); if(i == 0) { phibest = rphi; thebest = thetaCor; qabest = qa[i] ; slot = 0;} if(qa[i] < qabest) { slot = i; qabest = qa[i]; } /* cout< phi :"<= chrgCut ){ cout<<"found other ring : " << i <<", chrg : "<getSystem() < 0) { // no MetaMatch num = 1; } else { num = meta->getNRpcClusters(); if(meta->getNShrHits() > num) { num = meta->getNShrHits();} if(meta->getNTofHits() > num) { num = meta->getNTofHits();} } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // was rk succesful ? (rk indedx has to taken from another place ....) // also quality parameters ... // caution : meta->getRungeKuttaInd(); // is filled in case a.) no METAHIT b.) rk failed Bool_t rkSuccess = kTRUE; Int_t rkReplaceInd = meta->getRungeKuttaInd(); Float_t rkchi2 = -1; if ( (rk = HCategoryManager::getObject(rk,fCatRK,rkReplaceInd)) != 0 ) {rkchi2 = rk->getChiq();} if ( rk && rkchi2 < 0) { rkSuccess = kFALSE; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // fill the different candiates for 1 metaMatch object for(Int_t n = 0; n < num; n ++) { candidate& cand = *(new candidate); cand.reset(); cand.rkSuccess = rkSuccess; cand.nCand = num; //-------------------------------------------------------------------- // fill common info cand .fillMeta(meta); cand.mdctrk .fillMeta(meta); cand.spline .fillMeta(meta); cand.richhit .fillMeta(meta,0); mdcTrkCand = HCategoryManager::getObject(mdcTrkCand,fCatMdcTrkCand,cand.mdctrk.ind); if(mdcTrkCand){ cand.seg1.ind = mdcTrkCand->getSeg1Ind(); cand.seg2.ind = mdcTrkCand->getSeg2Ind(); } mdcSeg1 = HCategoryManager::getObject(mdcSeg1 ,fCatMdcSeg ,cand.seg1.ind); mdcSeg2 = HCategoryManager::getObject(mdcSeg2 ,fCatMdcSeg ,cand.seg2.ind); spline = HCategoryManager::getObject(spline ,fCatSpline ,cand.spline.ind); richHit = HCategoryManager::getObject(richHit ,fCatRichHit ,cand.richhit.ind); cand.mdctrk .fill(mdcTrkCand); cand.seg1 .fill(mdcSeg1); cand.seg2 .fill(mdcSeg2); cand.spline .fill(spline); cand.richhit .fill(richHit); //-------------------------------------------------------------------- //-------------------------------------------------------------------- // fill META hits and RICH cand.tof[kTofClst].fillMeta(meta,n,kTofClst); cand.tof[kTofHit1].fillMeta(meta,n,kTofHit1); cand.tof[kTofHit2].fillMeta(meta,n,kTofHit2); cand.rpcclst .fillMeta(meta,n); cand.showerhit .fillMeta(meta,n); tofClst = HCategoryManager::getObject(tofClst ,fCatTofCluster,cand.tof[kTofClst].ind); tofHit1 = HCategoryManager::getObject(tofHit1 ,fCatTofHit ,cand.tof[kTofHit1].ind); tofHit2 = HCategoryManager::getObject(tofHit2 ,fCatTofHit ,cand.tof[kTofHit2].ind); showerHit = HCategoryManager::getObject(showerHit ,fCatShowerHit ,cand.showerhit.ind); rpcClst = HCategoryManager::getObject(rpcClst ,fCatRpcCluster,cand.rpcclst.ind); cand.tof[kTofClst].fill(tofClst); cand.tof[kTofHit1].fill(tofHit1); cand.tof[kTofHit2].fill(tofHit2); cand.rpcclst .fill(rpcClst); cand.showerhit .fill(showerHit); cand.richhit .fill(richHit); //-------------------------------------------------------------------- //-------------------------------------------------------------------- // define system for this candidate if ( meta->getSystem() < 0) { cand.system = -1; } else if( !(tofClst||tofHit1||tofHit2) && (showerHit || rpcClst) ) { cand.system = 0; } else if( (tofClst||tofHit1||tofHit2) && !showerHit && !rpcClst) { cand.system = 1; } else if( (tofClst||tofHit1||tofHit2) && (showerHit || rpcClst) ) { cand.system = 2; } else { Error("fillCand()","wrong logic detected for system!"); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // make decision what to fill // for rk. For different cases some preselection // has to be done //-------------------------------------------------------------------- // selection from Meta Float_t tofqua[3] = {-1,-1,-1}; Float_t minTof = 1e37; Int_t minIndMeta = kNoUse; if(tofClst||tofHit1||tofHit2) { // find best match TOF for(Int_t i = 0; i < 3; i ++) { tofqua[i] = cand.tof[i].quality; if (tofqua[i] >= 0 && tofqua[i] < minTof){ minTof = tofqua[i]; minIndMeta = i;} } cand.selectTof = minIndMeta; // best TOF } if(rpcClst) { if(cand.rpcclst.quality >= 0){ // compare to rpc if(cand.rpcclst.quality < minTof ) { minIndMeta = kRpcClst; } // better rpc } } if(minIndMeta < 0 && showerHit) { minIndMeta = kShowerHit; } cand.usedMeta = minIndMeta; //-------------------------------------------------------------------- //-------------------------------------------------------------------- // vars for tof selection with rk HRKTrackB* rkhit [3] = { 0, 0, 0}; Float_t rkqua [3] = {-1,-1,-1}; Float_t min = 1e37; Int_t minInd = kNoUse; //-------------------------------------------------------------------- //-------------------------------------------------------------------- if(cand.system < 0 || !rkSuccess){ // no META || RK failed cand.rk.ind = meta->getRungeKuttaInd(); cand.rk.usedMeta = kNoUse; } else if(cand.system == 0){ // rpc+shr and rpc|shr // inner if (rpcClst) { cand.rk.ind = meta->getRungeKuttaIndRpcClst(n); cand.rk.usedMeta = kRpcClst; } else if (showerHit) { cand.rk.ind = meta->getRungeKuttaIndShowerHit(n); cand.rk.usedMeta = kShowerHit; } else { Error("fillCand()","(system == 0) No valid rk object!"); } } else if (cand.system > 0) { // both cases using outer system //-------------------------------------------------------------------- // select tof hits // Strategy : select by best quality of rk matching rkhit[kTofClst] = tofClst ? HCategoryManager::getObject(rkhit[kTofClst],fCatRK,meta->getRungeKuttaIndTofClst(n)): 0 ; rkhit[kTofHit1] = tofHit1 ? HCategoryManager::getObject(rkhit[kTofHit1],fCatRK,meta->getRungeKuttaIndTofHit1(n)): 0 ; rkhit[kTofHit2] = tofHit2 ? HCategoryManager::getObject(rkhit[kTofHit2],fCatRK,meta->getRungeKuttaIndTofHit2(n)): 0 ; if(tofClst && rkhit[kTofClst]) { rkqua[kTofClst] = rkhit[kTofClst]->getQualityTof();} if(tofHit1 && rkhit[kTofHit1]) { rkqua[kTofHit1] = rkhit[kTofHit1]->getQualityTof();} if(tofHit2 && rkhit[kTofHit2]) { rkqua[kTofHit2] = rkhit[kTofHit2]->getQualityTof();} // find best match for(Int_t i = 0; i < 3; i ++) { if (rkqua[i] > 1e37 ) rkqua[i] = 1e36; if (rkqua[i] >= 0 && rkqua[i] < min){ min = rkqua[i]; minInd = i;} } cand.rk.selectTof = minInd; // best TOF //-------------------------------------------------------------------- if (cand.system == 1) { //-------------------------------------------------------------------- if (minInd == kTofClst) { cand.rk.ind = meta->getRungeKuttaIndTofClst(n); cand.rk.usedMeta = kTofClst;} else if(minInd == kTofHit1) { cand.rk.ind = meta->getRungeKuttaIndTofHit1(n); cand.rk.usedMeta = kTofHit1;} else if(minInd == kTofHit2) { cand.rk.ind = meta->getRungeKuttaIndTofHit2(n); cand.rk.usedMeta = kTofHit2;} else { Error("fillCand()","(system == 1) No valid rk object!"); } //-------------------------------------------------------------------- } else if (cand.system == 2){ //-------------------------------------------------------------------- // inner+outer // Strategy: if rpcClst + best tof exists take better matched // else take existing rpc or best tof // tof dedx + showersums will be copied later no matter if rpc/tof was selected //-------------------------------------------------------------------- // get properties of RPC Float_t rpcQua = -1; Int_t rpcInd = -1; if (rpcClst) { rpcInd = meta->getRungeKuttaIndRpcClst(n); rk = HCategoryManager::getObject(rk,fCatRK,rpcInd); if(rk){ rpcQua = rk ->getQualityRpc(); } } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // case TOF + RPC if( minInd >= 0 && rpcClst ){ if (rpcQua >= 0 && rpcQua < min ) { // better rpc cand.rk.ind = meta->getRungeKuttaIndRpcClst(n); cand.rk.usedMeta = kRpcClst; } else { // better tof if (minInd == kTofClst) { cand.rk.ind = meta->getRungeKuttaIndTofClst(n); cand.rk.usedMeta = kTofClst;} else if (minInd == kTofHit1) { cand.rk.ind = meta->getRungeKuttaIndTofHit1(n); cand.rk.usedMeta = kTofHit1;} else if (minInd == kTofHit2) { cand.rk.ind = meta->getRungeKuttaIndTofHit2(n); cand.rk.usedMeta = kTofHit2;} else { Error("fillCand()","(system == 2,tof+rpc, better tof), No valid rk object!"); } } } //-------------------------------------------------------------------- // case TOF + no RPC if( minInd >= 0 && !rpcClst ){ if (minInd == kTofClst) { cand.rk.ind = meta->getRungeKuttaIndTofClst(n); cand.rk.usedMeta = kTofClst;} else if (minInd == kTofHit1) { cand.rk.ind = meta->getRungeKuttaIndTofHit1(n); cand.rk.usedMeta = kTofHit1;} else if (minInd == kTofHit2) { cand.rk.ind = meta->getRungeKuttaIndTofHit2(n); cand.rk.usedMeta = kTofHit2;} else { Error("fillCand()","(system == 2,tof+norpc) No valid rk object!"); } } //-------------------------------------------------------------------- // case no TOF + RPC if( minInd < 0 && rpcClst ){ if(rpcInd >= 0 ) { cand.rk.ind = rpcInd; cand.rk.usedMeta = kRpcClst; cand.rk.selectTof = kNoUse; } else { Error("fillCand()","(system == 2, notof+rpc) No valid rk object!"); } } //-------------------------------------------------------------------- // case no TOF + no RPC (should not happen) if( minInd < 0 && !rpcClst ){ Error("fillCand()","(system == 2, notof+norpc) should not happen!"); } //-------------------------------------------------------------------- } else { Error("fillCand()","(system > 2) should not happen!"); } } else { Error("fillCand()","else should not happen!"); } if (cand.rk.ind < 0 && cand.spline.ind >= 0){ Error("fillCand()","(after system, system == %i) rkind ==-1 , should not happen!",cand.system); cout<<"seg1 "<getSystem() < 0) { // no MetaMatch num = 1; } else { num = meta->getNRpcClusters(); if(meta->getNShrHits() > num) { num = meta->getNShrHits();} if(meta->getNTofHits() > num) { num = meta->getNTofHits();} } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // was rk succesful ? (rk indedx has to taken from another place ....) // also quality parameters ... // caution : meta->getRungeKuttaInd(); // is filled in case a.) no METAHIT b.) rk failed Bool_t rkSuccess = kTRUE; Int_t rkReplaceInd = meta->getRungeKuttaInd(); Float_t rkchi2 = -1; if ( (rk = HCategoryManager::getObject(rk,fCatRK,rkReplaceInd)) != 0 ) {rkchi2 = rk->getChiq();} if ( rk && rkchi2 < 0) { rkSuccess = kFALSE; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // fill the different candiates for 1 metaMatch object for(Int_t n = 0; n < num; n ++) { candidate& cand = *(new candidate); cand.reset(); cand.rkSuccess = rkSuccess; cand.nCand = num; //-------------------------------------------------------------------- // fill common info cand .fillMeta(meta); cand.mdctrk .fillMeta(meta); cand.spline .fillMeta(meta); mdcTrkCand = HCategoryManager::getObject(mdcTrkCand,fCatMdcTrkCand,cand.mdctrk.ind); if(mdcTrkCand){ cand.seg1.ind = mdcTrkCand->getSeg1Ind(); cand.seg2.ind = mdcTrkCand->getSeg2Ind(); } mdcSeg1 = HCategoryManager::getObject(mdcSeg1 ,fCatMdcSeg ,cand.seg1.ind); mdcSeg2 = HCategoryManager::getObject(mdcSeg2 ,fCatMdcSeg ,cand.seg2.ind); spline = HCategoryManager::getObject(spline ,fCatSpline ,cand.spline.ind); Int_t slot = findBestRich(meta,mdcSeg1); cand.richhit.fillMeta(meta,slot); // only best matched rich ? richHit = HCategoryManager::getObject(richHit ,fCatRichHit ,cand.richhit.ind); cand.mdctrk .fill(mdcTrkCand); cand.seg1 .fill(mdcSeg1); cand.seg2 .fill(mdcSeg2); cand.spline .fill(spline); cand.richhit .fill(richHit); //-------------------------------------------------------------------- //-------------------------------------------------------------------- // fill META hits and RICH cand.tof[kTofClst].fillMeta(meta,n,kTofClst); cand.tof[kTofHit1].fillMeta(meta,n,kTofHit1); cand.tof[kTofHit2].fillMeta(meta,n,kTofHit2); cand.rpcclst .fillMeta(meta,n); // automatic match between best RPC and SHOWER ? cand.showerhit .fillMeta(meta,n); tofClst = HCategoryManager::getObject(tofClst ,fCatTofCluster,cand.tof[kTofClst].ind); tofHit1 = HCategoryManager::getObject(tofHit1 ,fCatTofHit ,cand.tof[kTofHit1].ind); tofHit2 = HCategoryManager::getObject(tofHit2 ,fCatTofHit ,cand.tof[kTofHit2].ind); showerHit = HCategoryManager::getObject(showerHit ,fCatShowerHit ,cand.showerhit.ind); rpcClst = HCategoryManager::getObject(rpcClst ,fCatRpcCluster,cand.rpcclst.ind); cand.tof[kTofClst].fill(tofClst); cand.tof[kTofHit1].fill(tofHit1); cand.tof[kTofHit2].fill(tofHit2); cand.rpcclst .fill(rpcClst); cand.showerhit .fill(showerHit); cand.richhit .fill(richHit); //-------------------------------------------------------------------- //-------------------------------------------------------------------- // define system for this candidate if ( meta->getSystem() < 0) { cand.system = -1; } else if( !(tofClst||tofHit1||tofHit2) && (showerHit || rpcClst) ) { cand.system = 0; } else if( (tofClst||tofHit1||tofHit2) && !showerHit && !rpcClst) { cand.system = 1; } else if( (tofClst||tofHit1||tofHit2) && (showerHit || rpcClst) ) { cand.system = 2; } else { Error("fillCand()","wrong logic detected for system!"); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // make decision what to fill // for rk. For different cases some preselection // has to be done //-------------------------------------------------------------------- // selection from Meta Float_t tofqua[3] = {-1,-1,-1}; Float_t minTof = 1e37; Int_t minIndMeta = kNoUse; if(tofClst||tofHit1||tofHit2) { // find best match TOF for(Int_t i = 0; i < 3; i ++) { tofqua[i] = cand.tof[i].quality; if (tofqua[i] >= 0 && tofqua[i] < minTof){ minTof = tofqua[i]; minIndMeta = i;} } cand.selectTof = minIndMeta; // best TOF } if(rpcClst) { if(cand.rpcclst.quality >= 0){ // compare to rpc if(cand.rpcclst.quality < minTof ) { minIndMeta = kRpcClst; } // better rpc } } if(minIndMeta < 0 && showerHit) { minIndMeta = kShowerHit; } cand.usedMeta = minIndMeta; //-------------------------------------------------------------------- //-------------------------------------------------------------------- // vars for tof selection with rk HRKTrackB* rkhit [3] = { 0, 0, 0}; Float_t rkqua [3] = {-1,-1,-1}; Float_t min = 1e37; Int_t minInd = kNoUse; //-------------------------------------------------------------------- //-------------------------------------------------------------------- if(cand.system < 0 || !rkSuccess){ // no META || RK failed cand.rk.ind = meta->getRungeKuttaInd(); cand.rk.usedMeta = kNoUse; } else if(cand.system == 0){ // rpc+shr and rpc|shr // inner if (rpcClst) { cand.rk.ind = meta->getRungeKuttaIndRpcClst(n); cand.rk.usedMeta = kRpcClst; } else if (showerHit) { cand.rk.ind = meta->getRungeKuttaIndShowerHit(n); cand.rk.usedMeta = kShowerHit; } else { Error("fillCand()","(system == 0) No valid rk object!"); } } else if (cand.system > 0) { // both cases using outer system //-------------------------------------------------------------------- // select tof hits // Strategy : select by best quality of rk matching rkhit[kTofClst] = tofClst ? HCategoryManager::getObject(rkhit[kTofClst],fCatRK,meta->getRungeKuttaIndTofClst(n)): 0 ; rkhit[kTofHit1] = tofHit1 ? HCategoryManager::getObject(rkhit[kTofHit1],fCatRK,meta->getRungeKuttaIndTofHit1(n)): 0 ; rkhit[kTofHit2] = tofHit2 ? HCategoryManager::getObject(rkhit[kTofHit2],fCatRK,meta->getRungeKuttaIndTofHit2(n)): 0 ; if(tofClst && rkhit[kTofClst]) { rkqua[kTofClst] = rkhit[kTofClst]->getQualityTof();} if(tofHit1 && rkhit[kTofHit1]) { rkqua[kTofHit1] = rkhit[kTofHit1]->getQualityTof();} if(tofHit2 && rkhit[kTofHit2]) { rkqua[kTofHit2] = rkhit[kTofHit2]->getQualityTof();} // find best match for(Int_t i = 0; i < 3; i ++) { if (rkqua[i] > 1e37 ) rkqua[i] = 1e36; if (rkqua[i] >= 0 && rkqua[i] < min){ min = rkqua[i]; minInd = i;} } cand.rk.selectTof = minInd; // best TOF //-------------------------------------------------------------------- if (cand.system == 1) { //-------------------------------------------------------------------- if (minInd == kTofClst) { cand.rk.ind = meta->getRungeKuttaIndTofClst(n); cand.rk.usedMeta = kTofClst;} else if(minInd == kTofHit1) { cand.rk.ind = meta->getRungeKuttaIndTofHit1(n); cand.rk.usedMeta = kTofHit1;} else if(minInd == kTofHit2) { cand.rk.ind = meta->getRungeKuttaIndTofHit2(n); cand.rk.usedMeta = kTofHit2;} else { Error("fillCand()","(system == 1) No valid rk object!"); } //-------------------------------------------------------------------- } else if (cand.system == 2){ //-------------------------------------------------------------------- // inner+outer // Strategy: if rpcClst + best tof exists take better matched // else take existing rpc or best tof // tof dedx + showersums will be copied later no matter if rpc/tof was selected //-------------------------------------------------------------------- // get properties of RPC Float_t rpcQua = -1; Int_t rpcInd = -1; if (rpcClst) { rpcInd = meta->getRungeKuttaIndRpcClst(n); rk = HCategoryManager::getObject(rk,fCatRK,rpcInd); if(rk){ rpcQua = rk ->getQualityRpc(); } } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // case TOF + RPC if( minInd >= 0 && rpcClst ){ if (rpcQua >= 0 && rpcQua < min ) { // better rpc cand.rk.ind = meta->getRungeKuttaIndRpcClst(n); cand.rk.usedMeta = kRpcClst; } else { // better tof if (minInd == kTofClst) { cand.rk.ind = meta->getRungeKuttaIndTofClst(n); cand.rk.usedMeta = kTofClst;} else if (minInd == kTofHit1) { cand.rk.ind = meta->getRungeKuttaIndTofHit1(n); cand.rk.usedMeta = kTofHit1;} else if (minInd == kTofHit2) { cand.rk.ind = meta->getRungeKuttaIndTofHit2(n); cand.rk.usedMeta = kTofHit2;} else { Error("fillCand()","(system == 2,tof+rpc, better tof), No valid rk object!"); } } } //-------------------------------------------------------------------- // case TOF + no RPC if( minInd >= 0 && !rpcClst ){ if (minInd == kTofClst) { cand.rk.ind = meta->getRungeKuttaIndTofClst(n); cand.rk.usedMeta = kTofClst;} else if (minInd == kTofHit1) { cand.rk.ind = meta->getRungeKuttaIndTofHit1(n); cand.rk.usedMeta = kTofHit1;} else if (minInd == kTofHit2) { cand.rk.ind = meta->getRungeKuttaIndTofHit2(n); cand.rk.usedMeta = kTofHit2;} else { Error("fillCand()","(system == 2,tof+norpc) No valid rk object!"); } } //-------------------------------------------------------------------- // case no TOF + RPC if( minInd < 0 && rpcClst ){ if(rpcInd >= 0 ) { cand.rk.ind = rpcInd; cand.rk.usedMeta = kRpcClst; cand.rk.selectTof = kNoUse; } else { Error("fillCand()","(system == 2, notof+rpc) No valid rk object!"); } } //-------------------------------------------------------------------- // case no TOF + no RPC (should not happen) if( minInd < 0 && !rpcClst ){ Error("fillCand()","(system == 2, notof+norpc) should not happen!"); } //-------------------------------------------------------------------- } else { Error("fillCand()","(system > 2) should not happen!"); } } else { Error("fillCand()","else should not happen!"); } if (cand.rk.ind < 0 && cand.spline.ind >= 0){ Error("fillCand()","(after system, system == %i) rkind ==-1 , should not happen!",cand.system); cout<<"seg1 "<getSystem() < 0) { // no MetaMatch num = 1; } else { num = meta->getNRpcClusters(); if(meta->getNShrHits() > num) { num = meta->getNShrHits();} if(meta->getNTofHits() > num) { num = meta->getNTofHits();} } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // was trk succesful ? (rk indedx has to taken from another place ....) // also quality parameters ... // caution : meta->getRungeKuttaInd(); // is filled in case a.) no METAHIT b.) rk failed Bool_t rkSuccess = kTRUE; Int_t rkReplaceInd = meta->getKalmanFilterInd(); Float_t rkchi2 = -1; if ( (rk = HCategoryManager::getObject(rk,fCatKalman,rkReplaceInd)) != 0 ) {rkchi2 = rk->getChi2();} if ( rk && rkchi2 < 0) { rkSuccess = kFALSE; } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // fill the different candiates for 1 metaMatch object for(Int_t n = 0; n < num; n ++) { candidate& cand = *(new candidate); cand.reset(); cand.rkSuccess = rkSuccess; cand.nCand = num; //-------------------------------------------------------------------- // fill common info cand .fillMeta(meta); cand.mdctrk .fillMeta(meta); cand.spline .fillMeta(meta); cand.richhit .fillMeta(meta,0); mdcTrkCand = HCategoryManager::getObject(mdcTrkCand,fCatMdcTrkCand,cand.mdctrk.ind); if(mdcTrkCand){ cand.seg1.ind = mdcTrkCand->getSeg1Ind(); cand.seg2.ind = mdcTrkCand->getSeg2Ind(); } mdcSeg1 = HCategoryManager::getObject(mdcSeg1 ,fCatMdcSeg ,cand.seg1.ind); mdcSeg2 = HCategoryManager::getObject(mdcSeg2 ,fCatMdcSeg ,cand.seg2.ind); spline = HCategoryManager::getObject(spline ,fCatSpline ,cand.spline.ind); richHit = HCategoryManager::getObject(richHit ,fCatRichHit ,cand.richhit.ind); cand.mdctrk .fill(mdcTrkCand); cand.seg1 .fill(mdcSeg1); cand.seg2 .fill(mdcSeg2); cand.spline .fill(spline); cand.richhit .fill(richHit); //-------------------------------------------------------------------- //-------------------------------------------------------------------- // fill META hits and RICH cand.tof[kTofClst].fillMeta(meta,n,kTofClst); cand.tof[kTofHit1].fillMeta(meta,n,kTofHit1); cand.tof[kTofHit2].fillMeta(meta,n,kTofHit2); cand.rpcclst .fillMeta(meta,n); cand.showerhit .fillMeta(meta,n); tofClst = HCategoryManager::getObject(tofClst ,fCatTofCluster,cand.tof[kTofClst].ind); tofHit1 = HCategoryManager::getObject(tofHit1 ,fCatTofHit ,cand.tof[kTofHit1].ind); tofHit2 = HCategoryManager::getObject(tofHit2 ,fCatTofHit ,cand.tof[kTofHit2].ind); showerHit = HCategoryManager::getObject(showerHit ,fCatShowerHit ,cand.showerhit.ind); rpcClst = HCategoryManager::getObject(rpcClst ,fCatRpcCluster,cand.rpcclst.ind); cand.tof[kTofClst].fill(tofClst); cand.tof[kTofHit1].fill(tofHit1); cand.tof[kTofHit2].fill(tofHit2); cand.rpcclst .fill(rpcClst); cand.showerhit .fill(showerHit); cand.richhit .fill(richHit); //-------------------------------------------------------------------- //-------------------------------------------------------------------- // define system for this candidate if ( meta->getSystem() < 0) { cand.system = -1; } else if( !(tofClst||tofHit1||tofHit2) && (showerHit || rpcClst) ) { cand.system = 0; } else if( (tofClst||tofHit1||tofHit2) && !showerHit && !rpcClst) { cand.system = 1; } else if( (tofClst||tofHit1||tofHit2) && (showerHit || rpcClst) ) { cand.system = 2; } else { Error("fillCandKalman()","wrong logic detected for system!"); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // make decision what to fill // for rk. For different cases some preselection // has to be done //-------------------------------------------------------------------- // selection from Meta Float_t tofqua[3] = {-1,-1,-1}; Float_t minTof = 1e37; Int_t minIndMeta = kNoUse; if(tofClst||tofHit1||tofHit2) { // find best match TOF for(Int_t i = 0; i < 3; i ++) { tofqua[i] = cand.tof[i].quality; if (tofqua[i] >= 0 && tofqua[i] < minTof){ minTof = tofqua[i]; minIndMeta = i;} } cand.selectTof = minIndMeta; // best TOF } if(rpcClst) { if(cand.rpcclst.quality >= 0){ // compare to rpc if(cand.rpcclst.quality < minTof ) { minIndMeta = kRpcClst; } // better rpc } } if(minIndMeta < 0 && showerHit) { minIndMeta = kShowerHit; } cand.usedMeta = minIndMeta; //-------------------------------------------------------------------- //-------------------------------------------------------------------- // vars for tof selection with rk HKalTrack* rkhit [3] = { 0, 0, 0}; Float_t rkqua [3] = {-1,-1,-1}; Float_t min = 1e37; Int_t minInd = kNoUse; //-------------------------------------------------------------------- //-------------------------------------------------------------------- if(cand.system < 0 || !rkSuccess){ // no META || RK failed cand.kal.ind = meta->getKalmanFilterInd(); cand.kal.usedMeta = kNoUse; } else if(cand.system == 0){ // rpc+shr and rpc|shr // inner if (rpcClst) { cand.kal.ind = meta->getKalmanFilterIndRpcClst(n); cand.kal.usedMeta = kRpcClst; } else if (showerHit) { cand.kal.ind = meta->getKalmanFilterIndShowerHit(n); cand.kal.usedMeta = kShowerHit; } else { Error("fillCandKalman()","(system == 0) No valid trk object!"); meta ->print(); } } else if (cand.system > 0) { // both cases using outer system //-------------------------------------------------------------------- // select tof hits // Strategy : select by best quality of rk matching rkhit[kTofClst] = tofClst ? HCategoryManager::getObject(rkhit[kTofClst],fCatKalman,meta->getKalmanFilterIndTofClst(n)): 0 ; rkhit[kTofHit1] = tofHit1 ? HCategoryManager::getObject(rkhit[kTofHit1],fCatKalman,meta->getKalmanFilterIndTofHit1(n)): 0 ; rkhit[kTofHit2] = tofHit2 ? HCategoryManager::getObject(rkhit[kTofHit2],fCatKalman,meta->getKalmanFilterIndTofHit2(n)): 0 ; if(tofClst && rkhit[kTofClst]) { rkqua[kTofClst] = rkhit[kTofClst]->getQualityTof();} if(tofHit1 && rkhit[kTofHit1]) { rkqua[kTofHit1] = rkhit[kTofHit1]->getQualityTof();} if(tofHit2 && rkhit[kTofHit2]) { rkqua[kTofHit2] = rkhit[kTofHit2]->getQualityTof();} // find best match for(Int_t i = 0; i < 3; i ++) { if (rkqua[i] > 1e37 ) rkqua[i] = 1e36; if (rkqua[i] >= 0 && rkqua[i] < min){ min = rkqua[i]; minInd = i;} } cand.kal.selectTof = minInd; // best TOF //-------------------------------------------------------------------- if (cand.system == 1) { //-------------------------------------------------------------------- if (minInd == kTofClst) { cand.kal.ind = meta->getKalmanFilterIndTofClst(n); cand.kal.usedMeta = kTofClst;} else if(minInd == kTofHit1) { cand.kal.ind = meta->getKalmanFilterIndTofHit1(n); cand.kal.usedMeta = kTofHit1;} else if(minInd == kTofHit2) { cand.kal.ind = meta->getKalmanFilterIndTofHit2(n); cand.kal.usedMeta = kTofHit2;} else { Error("fillCandKalman()","(system == 1) No valid trk object!"); meta ->print(); } //-------------------------------------------------------------------- } else if (cand.system == 2){ //-------------------------------------------------------------------- // inner+outer // Strategy: if rpcClst + best tof exists take better matched // else take existing rpc or best tof // tof dedx + showersums will be copied later no matter if rpc/tof was selected //-------------------------------------------------------------------- // get properties of RPC Float_t rpcQua = -1; Int_t rpcInd = -1; if (rpcClst) { rpcInd = meta->getKalmanFilterIndRpcClst(n); rk = HCategoryManager::getObject(rk,fCatKalman,rpcInd); if(rk){ rpcQua = rk ->getQualityRpc(); } } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // case TOF + RPC if( minInd >= 0 && rpcClst ){ if (rpcQua >= 0 && rpcQua < min ) { // better rpc cand.kal.ind = meta->getKalmanFilterIndRpcClst(n); cand.kal.usedMeta = kRpcClst; } else { // better tof if (minInd == kTofClst) { cand.kal.ind = meta->getKalmanFilterIndTofClst(n); cand.kal.usedMeta = kTofClst;} else if (minInd == kTofHit1) { cand.kal.ind = meta->getKalmanFilterIndTofHit1(n); cand.kal.usedMeta = kTofHit1;} else if (minInd == kTofHit2) { cand.kal.ind = meta->getKalmanFilterIndTofHit2(n); cand.kal.usedMeta = kTofHit2;} else { Error("fillCandKalman()","(system == 2,tof+rpc, better tof), No valid trk object!"); meta ->print(); } } } //-------------------------------------------------------------------- // case TOF + no RPC if( minInd >= 0 && !rpcClst ){ if (minInd == kTofClst) { cand.kal.ind = meta->getKalmanFilterIndTofClst(n); cand.kal.usedMeta = kTofClst;} else if (minInd == kTofHit1) { cand.kal.ind = meta->getKalmanFilterIndTofHit1(n); cand.kal.usedMeta = kTofHit1;} else if (minInd == kTofHit2) { cand.kal.ind = meta->getKalmanFilterIndTofHit2(n); cand.kal.usedMeta = kTofHit2;} else { Error("fillCandKalman()","(system == 2,tof+norpc) No valid trk object!"); meta ->print(); } } //-------------------------------------------------------------------- // case no TOF + RPC if( minInd < 0 && rpcClst ){ if(rpcInd >= 0 ) { cand.kal.ind = rpcInd; cand.kal.usedMeta = kRpcClst; cand.kal.selectTof = kNoUse; } else { Error("fillCandKalman()","(system == 2, notof+rpc) No valid trk object!"); meta ->print(); } } //-------------------------------------------------------------------- // case no TOF + no RPC (should not happen) if( minInd < 0 && !rpcClst ){ Error("fillCandKalman()","(system == 2, notof+norpc) should not happen!"); meta ->print(); } //-------------------------------------------------------------------- } else { Error("fillCandKalman()","(system > 2) should not happen!"); meta ->print(); } } else { Error("fillCandKalman()","else should not happen!"); meta ->print(); } if (cand.kal.ind < 0 && cand.spline.ind >= 0){ Error("fillCandKalman()","(after system, system == %i) trkind ==-1 , should not happen!",cand.system); cout<<"seg1 "<print(); } rk = HCategoryManager::getObject(rk,fCatKalman,cand.kal.ind); cand.kal.fill(rk); //-------------------------------------------------------------------- //-------------------------------------------------------------------- // simulation part if(fbIsSimulation){ objects.reset(); objects.pMdcTrk = mdcTrkCand; objects.pSeg1 = (HMdcSegSim* ) mdcSeg1; objects.pSeg2 = (HMdcSegSim* ) mdcSeg2; objects.pRichHit = (HRichHitSim*) richHit; objects.pTofClst = (HTofClusterSim*) tofClst; objects.pTofHit1 = (HTofHitSim*) tofHit1; objects.pTofHit2 = (HTofHitSim*) tofHit2; objects.pRpcClst = (HRpcClusterSim*) rpcClst; objects.pShowerHit = (HShowerHitSim*) showerHit; objects.pSpline = spline; objects.pKalman = rk; fillCandSim(cand); } //-------------------------------------------------------------------- all_candidates.push_back(&cand); } } void HParticleCandFiller::fillCandSim(candidate& cand) { //-------------------------------------------------------------------- // for simulation we have to fill HGEANT infos // in addition. The GEANT track infos are collected // in trackVec objects for each detector and for // all detectors together. The tracks in the common // vector are sorted by 3 criteria: // 1. number of detectors which have seen this track // 2. sum of weights of the track // 3. correlation flag // The best track number will be transported // to HParticleCandSim output object. Int_t tr = -1; //-------------------------------------------------------------------- // MDC //-------------------------------------------------------------------- // search for "good tracks" (ghosts identified by MDC tracking) vector goodTracks; // good inner+outer or inner (if no outer segment) Int_t nGoodInnerTracks = objects.pSeg1->getNNotFakeTracks(); for(Int_t i = 0; i < nGoodInnerTracks; i ++) { tr = objects.pSeg1->getTrack(i); if(objects.pSeg2) tr = objects.pSeg1->getGoodTrack(i,objects.pSeg2,fMinWireGoodTrack); // if out seg, check if it matches if(tr > 0 ) { // good track! goodTracks.push_back(tr); } } //-------------------------------------------------------------------- Int_t ghost = 0; if(objects.pSeg1) { //we found an inner mdc segment for(Int_t i = 0; i < objects.pSeg1->getNTracks(); i++) { //loop over all contributing tracks ... ghost = kIsInnerGhost; if(i < nGoodInnerTracks && objects.pSeg1->getNTimes(i) >= fMinWireGoodTrack) ghost = 0; // good track tr = objects.pSeg1->getTrack(i); if(tr < 1 && tr != gHades->getEmbeddingRealTrackId() ) continue; // skip cells which contain no valid hit if(tr > 0 && find(goodTracks.begin(),goodTracks.end(),tr) == goodTracks.end()) { // ghost cand.mdc1Tracks.addTrack(tr,objects.pSeg1->getNTimes(i),kIsInInnerMDC|kIsGhost|ghost,fScaleGhostTrack); } else { // good or real track if(tr > 0 ) cand.mdc1Tracks.addTrack(tr,objects.pSeg1->getNTimes(i),kIsInInnerMDC,fScaleGoodTrack); // GEANT else cand.mdc1Tracks.addTrack(tr,objects.pSeg1->getNTimes(i),kIsInInnerMDC); // REAL } } cand.mdc1Tracks.calcWeights(); } if(objects.pSeg2) { //we found an outer mdc segment Int_t nGoodOuterTracks = objects.pSeg2->getNNotFakeTracks(); for(Int_t i = 0; i < objects.pSeg2->getNTracks(); i++) { //loop over all contributing tracks ... ghost = kIsOuterGhost; if(i < nGoodOuterTracks && objects.pSeg2->getNTimes(i) >= fMinWireGoodTrack) ghost = 0; // good track tr = objects.pSeg2->getTrack(i); if(tr < 1 && tr != gHades->getEmbeddingRealTrackId() ) continue; // skip cells which contain no valid hit if(tr > 0 && find(goodTracks.begin(),goodTracks.end(),tr) == goodTracks.end()) { // ghost cand.mdc2Tracks.addTrack(tr,objects.pSeg2->getNTimes(i),kIsInOuterMDC|kIsGhost|ghost,fScaleGhostTrack); } else { // good or real track if(tr > 0 ) cand.mdc2Tracks.addTrack(tr,objects.pSeg2->getNTimes(i),kIsInOuterMDC,fScaleGoodTrack); // GEANT else cand.mdc2Tracks.addTrack(tr,objects.pSeg2->getNTimes(i),kIsInOuterMDC); // REAL } } cand.mdc2Tracks.calcWeights(); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // RICH //Check for up to three possibly contributing leptons in this ring if(objects.pRichHit){ if(objects.pRichHit->weigTrack1 > 0.0 && (objects.pRichHit->track1 > 0 || objects.pRichHit->track1 == gHades->getEmbeddingRealTrackId())) { cand.richTracks.addTrack(objects.pRichHit->track1,objects.pRichHit->weigTrack1,kIsInRICH); } if(objects.pRichHit->weigTrack2 > 0.0 && (objects.pRichHit->track2 > 0 || objects.pRichHit->track2 == gHades->getEmbeddingRealTrackId())) { cand.richTracks.addTrack(objects.pRichHit->track2,objects.pRichHit->weigTrack2,kIsInRICH); } if(objects.pRichHit->weigTrack3 > 0.0 && (objects.pRichHit->track3 > 0 || objects.pRichHit->track3 == gHades->getEmbeddingRealTrackId())) { cand.richTracks.addTrack(objects.pRichHit->track3,objects.pRichHit->weigTrack3,kIsInRICH); } cand.richTracks.calcWeights(); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- // META // // we have to copy the GEANT infos of the selected objects! //-------------------------------------------------------------------- // RK success or failed ? Int_t selMetaHit = kNoUse; if(cand.rkSuccess) { selMetaHit = cand.rk.usedMeta; } // from RK matching else { selMetaHit = cand.usedMeta; } // from segment matching //-------------------------------------------------------------------- //-------------------------------------------------------------------- if (selMetaHit == kTofClst) { if(objects.pTofClst) { Int_t nTr = objects.pTofClst ->getNParticipants(); for(Int_t i = 0; i < nTr && i < 3; i ++) { //Get track numbers tr = objects.pTofClst->getNTrack1(i); tr = HParticleTool::findFirstHitInTof(tr,2); Bool_t good = kFALSE; if( tr > 0 || tr == gHades->getEmbeddingRealTrackId() ) { cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); good = kTRUE; } if(objects.pTofClst->getNTrack1(i) != objects.pTofClst->getNTrack2(i) ){ // skip same track tr = objects.pTofClst ->getNTrack2(); tr = HParticleTool::findFirstHitInTof(tr,2); if( tr > 0 || tr == gHades->getEmbeddingRealTrackId() ) { cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); } } else { if (good) cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); } // same track accepeted cand.tofTracks.calcWeights(); } } //-------------------------------------------------------------------- } else if(selMetaHit == kTofHit1) { if(objects.pTofHit1){ tr = objects.pTofHit1 ->getNTrack1(); tr = HParticleTool::findFirstHitInTof(tr,2); Bool_t good = kFALSE; if( tr > 0 || tr == gHades->getEmbeddingRealTrackId() ) { cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); good = kTRUE; } if(objects.pTofHit1 ->getNTrack1() != objects.pTofHit1 ->getNTrack2() ){ // skip same track tr = objects.pTofHit1 ->getNTrack2(); tr = HParticleTool::findFirstHitInTof(tr,2); if( tr > 0 || tr == gHades->getEmbeddingRealTrackId() ) { cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); } } else { if (good) cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); } // same track accepeted cand.tofTracks.calcWeights(); } //-------------------------------------------------------------------- } else if(selMetaHit == kTofHit2) { if(objects.pTofHit2){ tr = objects.pTofHit2 ->getNTrack1(); tr = HParticleTool::findFirstHitInTof(tr,2); Bool_t good = kFALSE; if( tr > 0 || tr == gHades->getEmbeddingRealTrackId() ) { cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); good = kTRUE; } if(objects.pTofHit2 ->getNTrack1() != objects.pTofHit2 ->getNTrack2() ){ // skip same track tr = objects.pTofHit2 ->getNTrack2(); tr = HParticleTool::findFirstHitInTof(tr,2); if( tr > 0 || tr == gHades->getEmbeddingRealTrackId() ) { cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); } } else { if (good) cand.tofTracks.addTrack(tr,1,kIsInTOF|kIsInMETA); } // same track accepeted cand.tofTracks.calcWeights(); } //-------------------------------------------------------------------- } else if(selMetaHit == kRpcClst) { if(objects.pRpcClst){ Int_t tracks[4]; Bool_t atbox[4]; objects.pRpcClst->getTrackList (tracks); objects.pRpcClst->getIsAtBoxList(atbox); Int_t nTr = objects.pRpcClst->howManyTracks(); if(nTr > 4) { Warning("fillCandSim()","RPC number of tracks > 4! Should not happen."); nTr = 4; } for(Int_t i = 0; i < nTr; i ++) { tr = tracks[i]; if( tr >= 0 || tr == gHades->getEmbeddingRealTrackId()){ if(tr >= 0 ) { // sim tracks if(atbox[i]) { cand.rpcTracks.addTrack(tr,1,kIsInRPC|kIsInMETA);} else { Warning("fillCandSim()","RPC track not at box! Should not happen."); } } else { // embedded tracks cand.rpcTracks.addTrack(tr,1,kIsInRPC|kIsInMETA); } } } cand.rpcTracks.calcWeights(); } //-------------------------------------------------------------------- // if there is Shower fill it if((cand.system == 0 || cand.system == 2) && objects.pShowerHit) { Int_t nTr = objects.pShowerHit->getNTracks(); for(Int_t i = 0; i < nTr; i ++) { tr = objects.pShowerHit->getTrack(i); if( tr >= 0 || tr == gHades->getEmbeddingRealTrackId()){ cand.showerTracks.addTrack(tr,1,kIsInSHOWER|kIsInMETA); } } cand.showerTracks.calcWeights(); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- } else if(selMetaHit == kShowerHit){ if(objects.pShowerHit) { Int_t nTr = objects.pShowerHit->getNTracks(); for(Int_t i = 0; i < nTr; i ++) { tr = objects.pShowerHit->getTrack(i); if( tr >= 0 || tr == gHades->getEmbeddingRealTrackId()){ cand.showerTracks.addTrack(tr,1,kIsInSHOWER|kIsInMETA); } } cand.showerTracks.calcWeights(); } //-------------------------------------------------------------------- } else { ; } // NO META //-------------------------------------------------------------------- //-------------------------------------------------------------------- // now add all detector tracks to commonTracks // and sort them by 1. flag and 2. weight cand.commonTracks.addTrackWeight(cand.mdc1Tracks); cand.commonTracks.addTrackWeight(cand.mdc2Tracks); cand.commonTracks.addTrackWeight(cand.richTracks); cand.commonTracks.addTrackWeight(cand.tofTracks); cand.commonTracks.addTrackWeight(cand.rpcTracks); cand.commonTracks.addTrackWeight(cand.showerTracks); cand.commonTracks.sortWeightNdet(); //-------------------------------------------------------------------- } void HParticleCandFiller::fillSingleProperties() { // selection for single tracks done in this loop // 1. RICH-MDC matching flags are set // 2. all cuts (GOODSEG0 .... ) are performed here. // Rejected candidate objects will will have use == 0. Float_t zVertex = gHades->getCurrentEvent()->getHeader()->getVertexZ(); for(UInt_t i = 0; i < all_candidates.size(); i ++){ candidate& cand = *(all_candidates[i]); //----------------------------------------------------- // RICH - MDC matching // 1. correct rings for vertex position // 2. check matching for RK if(cand.richhit.ind >= 0){ Float_t richCorr = fFillerPar->getRichCorr(zVertex,cand.richhit.theta); cand.corrThetaRich = richCorr; cand.richhit.theta += richCorr; if(!fbIsSimulation && fbdoRichAlign){ // for real data do alignment of rich Double_t thetaCor = cand.richhit.theta; Double_t phiCor = cand.richhit.phi; HParticleAngleCor::alignRichRing(cand.richhit.theta,cand.richhit.phi,thetaCor,phiCor); // second correct theta/phi cand.alignThetaRich = thetaCor - cand.richhit.theta; cand.alignPhiRich = phiCor - cand.richhit.phi; cand.richhit.theta = (Float_t)thetaCor; cand.richhit.phi = (Float_t)phiCor; } Float_t dTheta = cand.deltaThetaSeg1(); // delta theta Float_t dPhi = cand.deltaPhiSeg1(); // delta phi Float_t mom = cand.spline.p; // if(cand.rk.chi2 > 0) mom = cand.rk.p; // cand.richMdcQuality = sqrt( dTheta * dTheta + dPhi * dPhi); cand.richRkQuality = -1; cand.hasRingCorrelation = 0; if(fFillerPar->acceptPhiTheta(cand.sector,mom,dPhi,dTheta)){ cand.hasRingCorrelation = kIsRICHMDC; } if(cand.rk.chi2 > 0){ dTheta = cand.deltaThetaRk(); // delta theta dPhi = cand.deltaPhiRk(); // delta phi cand.richRkQuality = sqrt( dTheta * dTheta + dPhi * dPhi); if(fFillerPar->acceptPhiTheta(cand.sector,mom,dPhi,dTheta)){ cand.hasRingCorrelation = cand.hasRingCorrelation | kIsRICHRK; // add flag } } } //----------------------------------------------------- //----------------------------------------------------- // filter candidates by options. cand.used=0 will be skipped // when createing output objects if(fbgoodSeg0 && cand.seg1.chi2 < 0) { cand.used = 0; } if(fbgoodSeg1 && cand.seg2.chi2 < 0) { cand.used = 0; } if(fbgoodMeta && cand.system < 0) { cand.used = 0; } if(fbgoodRK && cand.rk.chi2 < 0) { cand.used = 0; } if(fbgoodLepton && cand.hasRingCorrelation == 0){ cand.used = 0; } //----------------------------------------------------- } } void HParticleCandFiller::fillCollectiveProperties() { // collect information of the environment of a // candidate // 1. calculation openening angles etc. to fitted // and not fitted other candidates (in inner MDC) UInt_t size = all_candidates.size(); if(size < 2) return; Float_t phi1,phi2,theta1,theta2; Float_t oAngle = -1; Int_t ind = 0; //---------------------------------------------------------- for(UInt_t i = 0; i < size - 1; i ++){ // outer loop candidate& cand = *(all_candidates[i]); if(cand.rkSuccess){ phi1 = cand.rk.phi; theta1 = cand.rk.theta; } else { phi1 = cand.seg1.phi; theta1 = cand.seg1.theta; } //---------------------------------------------------------- for(UInt_t j = i + 1; j < size; j ++){ // inner loop candidate& cand2 = *(all_candidates[j]); if(cand.ind == cand2.ind) continue; // skip candidate from same MetaMatch if(cand.sector != cand2.sector) continue; // only in same sector if(cand2.rkSuccess){ phi2 = cand2.rk.phi; theta2 = cand2.rk.theta; } else { phi2 = cand2.seg1.phi; theta2 = cand2.seg1.theta; } oAngle = HParticleTool::getOpeningAngle(phi1,theta1,phi2,theta2); if(oAngle < fAngleCloseTrack){ // only for small angle cand.closeTracks.addTrack(j,oAngle); } } // end inner //---------------------------------------------------------- // find closest fitted/nonfitted tracks UInt_t ntr = (cand.closeTracks).tracks.size(); for(UInt_t l = 0; l < ntr; l ++){ ind = (cand.closeTracks).tracks[l].ind; oAngle = (cand.closeTracks).tracks[l].oAngle; candidate& c = *(all_candidates[ind]); if(c.seg1.chi2 > 0){ if(oAngle < fabs(cand.oAFitted)){ cand.oAFitted = oAngle; if( c.hasRingCorrelation == 0) { cand.oAFitted *= -1; } // hadron case } } else { if(oAngle < fabs(cand.oANoFitted)){ cand.oANoFitted = oAngle; if( c.hasRingCorrelation == 0) { cand.oANoFitted *= -1; } // hadron case } } } //---------------------------------------------------------- } // end outer //---------------------------------------------------------- } void HParticleCandFiller::fillOutput() { // From the candidate objects the output HParticleCand // will be filled if the candidate flage useed == 1 // All additional categories objects will be filled // in the same order so that the objects later can be // easily matched. HParticleCand* part = 0; HParticleCandSim* partS = 0; Int_t index = -1; for(UInt_t i = 0; i < all_candidates.size(); i ++){ candidate* cand = all_candidates[i]; if(!cand->used) continue; if(fbIsSimulation) { if((partS = HCategoryManager::newObject(partS,fCatParticleCand,index)) != 0 ) { cand->fillParticleCand (partS,index); cand->fillParticleCandSim(partS,fCatGeantKine); } } else { if((part = HCategoryManager::newObject(part,fCatParticleCand,index)) != 0 ) { cand->fillParticleCand (part,index); } } if(fbIsDebug){ candidate* c; c = HCategoryManager::newSlot(c,fCatParticleDebug,index); if(c){ c = new (c) candidate(*cand); } } } } void HParticleCandFiller::clearVector(void) { // clear the working objects at the end of each event. UInt_t nt = all_candidates.size(); for(UInt_t i = 0; i < nt; i ++){ candidate* cand = all_candidates[i]; delete cand; } all_candidates.clear(); }