//----------------------------------------------------------- // File and Version Information: // $Id$ // // Description: // Implementation of class TpcSpaceChargeTask // // Environment: // Software developed for the PANDA Detector at FAIR. // // Author List: // Cristoforo Simonetto TUM (original author) // Felix Boehmer TUM // //----------------------------------------------------------- // This Class' Header ------------------ #include "TpcSpaceChargeTask.h" // Collaborating Class Headers -------- #include "TpcGas.h" #include "TClonesArray.h" #include "FairRootManager.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" #include "TpcPoint.h" #include "TpcPrimaryCluster.h" #include "TVector3.h" #include "TpcDigiPar.h" #include "TpcDigiMapper.h" #include #include #include #include #include // Class Member definitions ----------- TpcSpaceChargeTask::TpcSpaceChargeTask() //default constructor : FairTask("TPC Space Charge"), //ftpcMinR(15.5), //ftpcMaxR(41.5), //these are all default values //ftpcMinZ(-39.5), //change with set-functions individually //ftpcMaxZ(109.5), frBinCount(26), fzBinCount(75), fangle(0.17453), //TODO: parameter management! fionDriftVelocity(1.766e-6), // [cm/ns] ftime(0), ferrorCount(0), fprimChargeOnly(false), fALICEmode(false), fpointBranchName("TpcPoint"), fPrimClBranchName("TpcPrimaryCluster"), fPrimClArray(NULL), fEpsilon(4), fEvtCounter(0) {} TpcSpaceChargeTask::~TpcSpaceChargeTask() {} InitStatus TpcSpaceChargeTask::Init() { //Get ROOT Manager FairRootManager* ioman= FairRootManager::Instance(); if(ioman==0) { Error("TpcSpaceChargeTask::Init","RootManager not instantiated!"); return kERROR; } // Get input collection fpointArray=(TClonesArray*) ioman->GetObject(fpointBranchName); if(fpointArray==NULL && (!fALICEmode)) { Error("TpcSpaceChargeTask::Init","MC-Point-array not found!"); return kERROR; } fPrimClArray = (TClonesArray*) ioman->GetObject(fPrimClBranchName); if(fPrimClArray==NULL && fALICEmode) { Error("TpcSpaceChargeTask::Init","PrimaryCluster-array not found!"); return kERROR; } fsupression=fpar->getSupression(); ftpcMaxR=fpar->getRMax(); //make sure these are the values for the ACTIVE detector region ftpcMinR=fpar->getRMin(); //see geometry/tpc.geo ftpcMaxZ=fpar->windowMax(); ftpcMinZ=fpar->windowMin(); //fgemGain=fpar->getGain(); frate=fpar->getRate(); fgas=fpar->getGas(); fWGas = fgas->W(); //fgemCharge = fsupression * fgemGain; //this should be epsilon fdistPerTime = fionDriftVelocity / frate; //Ion travel distance per event frBinWidth = ((ftpcMaxR - ftpcMinR) / frBinCount); fzBinWidth = ((ftpcMaxZ - ftpcMinZ) / fzBinCount); std::cout<<"\n\n--------- TpcSpaceChargeTask working parameters ----------"<(fzBinCount, 0)); return kSUCCESS; } void TpcSpaceChargeTask::SetParContainers() { std::cout<<"TpcSpaceChargeTask::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 TpcSpaceChargeTask::Exec(Option_t* opt) { std::cout<<"TpcSpaceChargeTask::Exec() on Event Number "<GetEntriesFast(); std::cout<<"TpcSpaceChargeTask::Exec() : Converting " <pos(); double posZ = pos.Z(); double r = pos.Perp(); bool outside = false; if( r ftpcMaxR ) outside=true; if( posZftpcMaxZ) outside = true; if(outside) { TString warn("Hit occured outside the Tpc-Volume! ("); char posbuf[10]; sprintf(posbuf,"%.4f",pos.X()); warn.Append(posbuf); warn+=","; sprintf(posbuf,"%.4f",pos.Y()); warn.Append(posbuf); warn+=","; sprintf(posbuf,"%.4f",pos.Z()); warn.Append(posbuf); warn+=")"; Warning("TpcSpaceChargeTask::Exec", warn.Data()); ferrorCount++; continue; } int rBin = (int)(std::fabs(r - ftpcMinR) / frBinWidth); int zBin = (int)(std::fabs(posZ - ftpcMinZ) / fzBinWidth); //Now fill in the point-charge into the charge-map (fchargeMap[rBin])[zBin] += icl->q(); //At the same x-y-coordinates Ions are created on the gem-plane by the //impact of the drifted electrons (assuming instant electron drift) in //the gems if(!fprimChargeOnly) (fchargeMap[rBin])[0] += icl->q()*fEpsilon; } return; } else { TpcPoint* currentPoint; int np = fpointArray->GetEntriesFast(); //number of MC points for(int n=0; nAt(n); int qPoint=0; qPoint = (int)(currentPoint->GetEnergyLoss()*1e9 / fWGas); // [eV] double posX = currentPoint->GetX(); double posY = currentPoint->GetY(); double posZ = currentPoint->GetZ(); double r = sqrt(posX*posX + posY*posY); //check for boundaries: bool outside = false; if( r ftpcMaxR ) outside=true; if( posZftpcMaxZ) outside = true; if(outside) { TString warn("Hit occured outside the Tpc-Volume! ("); char pos[10]; sprintf(pos,"%.4f",posX); warn.Append(pos); warn+=","; sprintf(pos,"%.4f",posY); warn.Append(pos); warn+=","; sprintf(pos,"%.4f",posZ); warn.Append(pos); warn+=")"; Warning("TpcSpaceChargeTask::Exec", warn.Data()); ferrorCount++; continue; } int rBin = (int)(std::fabs(r - ftpcMinR) / frBinWidth); int zBin = (int)(std::fabs(posZ - ftpcMinZ) / fzBinWidth); //Now fill in the point-charge into the charge-map fchargeMap.at(rBin).at(zBin) += qPoint; //At the same x-y-coordinates Ions are created on the gem-plane by the //impact of the drifted electrons (assuming instant electron drift) in //the gems if(!fprimChargeOnly) fchargeMap.at(rBin).at(0) += (int)(qPoint*fEpsilon); } //end Loop over all Points of this track/event ftime++; //Drift charge one bin in z-direction when enough "time" has passed //This takes a lot of time. Normally not used, instead done by a macro if( fmod((double)ftime * fdistPerTime, fzBinWidth) < fdistPerTime) { std::cout<<"\n**** Drifting all the charge after " <0; nz--) fchargeMap.at(nr).at(nz) = fchargeMap.at(nr).at(nz-1); for(int nr=0; nr > fchargeDens; for (int nr=0; nr(fzBinCount, 0.)); for (int nr=0; nr