//----------------------------------------------------------- // File and Version Information: // $Id$ // // Description: // Implementation of class TpcdEdxTask // see TpcdEdxTask.hh for details // // Environment: // Software developed for the PANDA Detector at FAIR. // // Author List: // Felix Boehmer, Christian Hoeppner TUM // // //----------------------------------------------------------- // Panda Headers ---------------------- // This Class' Header ------------------ #include "TpcdEdxTask.h" // C/C++ Headers ---------------------- #include #include #include #include #include // Collaborating Class Headers -------- #include "FairRootManager.h" #include "TClonesArray.h" #include "GFTrack.h" #include "GFTrackCand.h" #include "TpcCluster.h" #include "TpcDigiMapper.h" #include "TpcFrontend.h" #include "TpcSPHit.h" #include "PndMCTrack.h" #include "TpcPoint.h" #include "TpcAlignmentManager.h" #include "TpcPadShapePool.h" #include "TpcPadPlane.h" #include "TpcAbsPadShape.h" #include "TpcPad.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" #include "TpcDigiPar.h" #include "GFAbsTrackRep.h" #include "GFRecoHitFactory.h" #include "GFKalman.h" #include "GFException.h" #include "TH1D.h" #include "TFile.h" #include "TGeoTrack.h" #include "GFDetPlane.h" #include "TpcdEdx.h" #include "RecoHits/GFAbsRecoHit.h" #include "TVector3.h" //#include //#include #include "PndDetectorList.h" // Class Member definitions ----------- TpcdEdxTask::TpcdEdxTask() : FairTask("dE/dx Task"), _persistence(kFALSE), _DX(1.), _idealdEdx(kFALSE), fUseFirstDigiPos(kFALSE), fIgnoreEdgeDigis(kFALSE) { _trackBranchName = "TpcTrackPostFit"; _clusterBranchName = "TpcCluster"; _digiBranchName = "TpcDigi"; _outBranchName = "TpcdEdx"; //_spHitBranchName = "TpcSPHit"; fVerbose = 0; //fPadPlaneFile = "tpc/FOPI/par/padplane_FOPI.dat"; //fShapeFile = "tpc/parfiles/PadShapePrototype.dat"; } TpcdEdxTask::~TpcdEdxTask() { } InitStatus TpcdEdxTask::Init() { //Get ROOT Manager FairRootManager* ioman= FairRootManager::Instance(); if(ioman==0) { Error("TpcdEdxTask::Init","RootManager not instantiated!"); return kERROR; } // Get input collection _trackArray=(TClonesArray*) ioman->GetObject(_trackBranchName); if(_trackArray==0) { Error("TpcdEdxTask::Init","track-array not found!"); return kERROR; } if(_idealdEdx) { _mcTrackArray=(TClonesArray*) ioman->GetObject("MCTrack"); if(_mcTrackArray==0) Fatal("TpcdEdxTask::Init","MCTrack-array not found! Cannot calculate MC dEdx"); _pointArray=(TClonesArray*) ioman->GetObject("TpcPoint"); if(_pointArray==0) Fatal("TpcdEdxTask::Init","Point-array not found! Cannot calculate MC dEdx"); } _clusterArray=(TClonesArray*) ioman->GetObject(_clusterBranchName); if(_clusterArray==0) { Error("TpcdEdxTask::Init","Cluster/Hit - array not found!"); return kERROR; } _digiArray=(TClonesArray*) ioman->GetObject(_digiBranchName); if(_digiArray==0) { Error("TpcdEdxTask::Init","Digi-array not found!"); return kERROR; } _dEdxOutArray = new TClonesArray(_outBranchName); ioman->Register("dEdx","Tpc",_dEdxOutArray,_persistence); _dEdxMCOutArray = new TClonesArray("TpcdEdx"); ioman->Register("dEdx_MC","Tpc",_dEdxMCOutArray,_persistence); // setup histograms _distHist=new TH1D("distHist","Stepping lentghs",500,-3.,3.); _dirHist=new TH1D("dirHist","direction abundances",10,-2.,2.); _hitBranchID = FairRootManager::Instance()->GetBranchId(_clusterBranchName); std::cout<<"Initializing PadPlane ... "<getPadShapes(); fPlane = fPar->getPadPlane(); fRMin = fPar->getRMin(); fRMax = fPar->getRMax(); if(fIgnoreEdgeDigis) { fRMin = fRCutoff1; fRMax = fRCutoff2; } return kSUCCESS; } void TpcdEdxTask::SetParContainers() { std::cout<<"TpcClusterFinderTask::SetParContainers"<GetRuntimeDb(); if ( ! db ) Fatal("SetParContainers", "No runtime database"); // Get Tpc digitisation parameter container fPar= (TpcDigiPar*) db->getContainer("TpcDigiPar"); if (! fPar ) Fatal("SetParContainers", "TpcDigiPar not found"); } void TpcdEdxTask::Exec(Option_t* opt) { std::cout<<"TpcdEdxTask::Exec()"<Delete(); _dEdxMCOutArray->Delete(); Int_t ntracks=_trackArray->GetEntriesFast(); if(ntracks>20000){ std::cout<<"ntracks="<At(itr); if (fVerbose) std::cout<<"*** Number of hits in track: "<getNumHits()<<" ***"<getCardinalRep(); if (theRep->getStatusFlag() != 0) { // write empty dEdx and continue with next trk new((*_dEdxOutArray)[itr]) TpcdEdx(dedx); if(_idealdEdx) { new((*_dEdxMCOutArray)[itr]) TpcdEdx(dedx_MC); } continue; } GFTrackCand cand = trk->getCand(); bool useSPHits = false; if(TString(_clusterArray->GetClass()->GetName()) == "TpcSPHit") useSPHits = true; //these are SORTED, first entry corresponds to track's start-hit std::vector hitIDs = cand.getHitIDs(_hitBranchID); //GET MC INFORMATION FOR CROSS-CHECK //only works with IdealTracking and pure trackIDs std::vector pointlist; if(_idealdEdx) { if (fVerbose) std::cerr<<"collect MC points"<GetEntriesFast(); ++p) { int id = ((TpcPoint*)_pointArray->At(p))->GetTrackID(); if(id==0) //only primary tracks pointlist.push_back((TpcPoint*)_pointArray->At(p)); } } TVector3 pos,mom; TVectorD protState = theRep->getState(); if (fVerbose) std::cerr<<"get pos and mom"<getPos(); mom = theRep->getMom(); } catch(GFException& e){ e.what(); // write empty dEdx and continue with next trk new((*_dEdxOutArray)[itr]) TpcdEdx(dedx); if(_idealdEdx) { new((*_dEdxMCOutArray)[itr]) TpcdEdx(dedx_MC); } continue; //TODO: exception handling } TVector3 startDir = mom; startDir.SetMag(1.); TVector3 altFirstPos; //reference plane: GFDetPlane pl; pl.setO(pos); pl.setNormal(startDir); if (fVerbose) std::cerr<<"collect digis"< digis; // unsigned int count = 0; TClonesArray* actClArr; int foundDigi = -1; //first digi in (opposite) track direction for(int i=0; iAt(hitIDs[i]); int clBrID = theHit->getClusterBranchID(); int clID = theHit->getClusterID(); if(count==0) { TString clBrName = ioman->GetBranchName(clBrID); actClArr = (TClonesArray*) ioman->GetObject(clBrName); } cl = (TpcCluster*)(actClArr->At(clID)); count++; } else cl = (TpcCluster*) _clusterArray->At(hitIDs[i]); const std::map* digiMap = cl->getDigiMap(); double maxDist = 0.; //(cm) for(std::map::const_iterator it=digiMap->begin();it!=digiMap->end();++it){ //avoid double-counting if(!digis.count(it->first)) digis[it->first] = (TpcDigi*) _digiArray->At(it->first); else continue; TpcDigi* aDigi = digis[it->first]; //only for first hit (cluster): find first Digi if(i==0 && fUseFirstDigiPos) { //get Digi coordinates: TVector3 dPos; try { TpcDigiMapper::getInstance()->map(aDigi,dPos); } catch (...) { std::cerr<<"TpcdEdxTask::Could not get Position of digi! Skipping ..."<localToMaster("tpc",dPos); TVector3 pc, dpc; try{ theRep->extrapolateToPoint(dPos,pc,dpc); }catch(GFException exp){ std::cerr<<"TpcdEdxTask::Exec() error during first digi extrapolation:"< maxDist && (dDist*pl.getNormal()) < 0.) { //we want negative extrap! if(fIgnoreEdgeDigis) if(dPos.Perp() < fRCutoff1 || dPos.Perp() > fRCutoff2) continue; foundDigi = (*it).first; altFirstPos = dPos; maxDist = dDist.Mag(); } } } //end loop over this cluster's digis } //end loop over hits (clusters) //startDir *= -1.; dedx.setMom(mom); if (fVerbose) { TVector3 pos0(((TpcCluster*)(_clusterArray->At(hitIDs[0])))->pos()); std::cout<<"pos - pos0 mag"<< (pos-pos0).Mag() << std::endl; } GFDetPlane here,next; here.setO(pos); here.setNormal(mom); if(fVerbose) {std::cout<<"Original extrap direction:"<= 0 && fUseFirstDigiPos) { if(fVerbose) { std::cout<<"Moved plane from cluster position (r="< 2*fRMin) //first digi outside, track supposedly goes inwards pull = 1.01; here.setO(altFirstPos*pull); //pull it inward a little } int counter(0); bool exc = false; std::set usedDigis; //bookkeeping for speedup while(true){ //stepalong until no digi is found between the planes bool abort = true; bool forceabort = false; double dir = 1.; if (fVerbose) std::cerr<<"at counter "<0) here=next;//not the first time else if(here.getNormal() * startDir < 0) { //_DX*=-1; dir=-1.; } TVector3 destination = here.getO()+(here.getNormal()*_DX*dir); TVector3 poca,dirInPoca; double dist; try{ theRep->extrapolateToPoint(destination,poca,dirInPoca); next.setO(poca); next.setNormal(dirInPoca); } catch(GFException& e){ e.what(); exc=true; break; //TODO: exception handling } //check if next lies out of the TPC volume if(next.getO().Perp() > fRMax || next.getO().Perp() < fRMin) { if(fVerbose) std::cout<<"OUT OF CHAMBER next.Perp(): <<"<extrapolate(next,protState); } catch(GFException& e) { e.what(); exc=true; break; } double thisDist = dist-totDist; totDist = dist; if (fVerbose) { std::cout<<"Extrapolation results :\n";poca.Print(); std::cout<::const_iterator cit; for(cit=digis.begin(); cit!=digis.end();cit++){ if(usedDigis.count(cit->first)) continue; TVector3 digiPos; try { TpcDigiMapper::getInstance()->map(cit->second,digiPos); } catch(const std::exception& ex) { std::cout< fRCutoff2) continue; digiPos=TpcAlignmentManager::getInstance()->localToMaster("tpc",digiPos); behindHere = normHere * (here.dist(digiPos)); behindNext = normNext * (next.dist(digiPos)); behindHere *= 1./fabs(behindHere); behindNext *= 1./fabs(behindNext); double ok = behindHere + behindNext; // 0 if digi between planes if (fVerbose) std::cout<<"JDIOSFSDF OK: "<second)->amp(); usedDigis.insert(cit->first); } } } if (fVerbose) std::cout<<"dE: "<= 0.) dedx.add(dE,thisDist); //MC PART --------------------------------------------------- dE = 0.; if(_idealdEdx) { for(unsigned int m=0;mPosition(pointPos); if((here.getO()-pointPos).Mag() > (_DX+2.)) continue; behindHere = normHere * (here.dist(pointPos)); behindNext = normNext * (next.dist(pointPos)); if(behindHere<0.){//in front of if(behindNext>=0.){ dE+=pointlist.at(m)->GetEnergyLoss(); } } else{ if(behindNext<0.){//in front of dE+=pointlist.at(m)->GetEnergyLoss(); } } } if(dE>0. && (!exc)){ dedx_MC.add(dE*1E9,dist); } } // end if _idealdEdx } if(exc==false) new((*_dEdxOutArray)[itr]) TpcdEdx(dedx); else new((*_dEdxOutArray)[itr]) TpcdEdx(); if(_idealdEdx) { new((*_dEdxMCOutArray)[itr]) TpcdEdx(dedx_MC); } //for(unsigned int i=0;imkdir("DEDX"); file->cd("DEDX"); _distHist->Write(); delete _distHist; _dirHist->Write(); delete _dirHist; file->Close(); delete file; } void TpcdEdxTask::SetIgnoreEdgeDigis(double r1, double r2, Bool_t opt) { fRCutoff1 = r1; fRCutoff2 = r2; fIgnoreEdgeDigis = opt; } ClassImp(TpcdEdxTask)