// ------------------------------------------------------------------------- // ----- PndSdsStripHitProducer source file ----- // ------------------------------------------------------------------------- // This Class #include "PndSdsStripHitProducer.h" // SDS #include "PndSdsMCPoint.h" #include "PndSdsCalcStrip.h" #include "PndSdsDigiStrip.h" //PANDA #include "PndStringSeparator.h" #include "PndDetectorList.h" //FAIR #include "FairRootManager.h" #include "FairRun.h" #include "FairRuntimeDb.h" #include "FairContFact.h" #include "FairGeoNode.h" #include "FairGeoVector.h" //ROOT #include "TClonesArray.h" #include "TArrayD.h" #include "TVector2.h" #include "TString.h" #include "TObjString.h" #include "TGeoManager.h" #include "TList.h" #include "TRandom.h" // ----- Default constructor ------------------------------------------- PndSdsStripHitProducer::PndSdsStripHitProducer() : PndSdsTask("SDS Strip Digi Producer(PndSdsStripHitProducer)"), fDataBuffer(0) { fOverrideParams = false; fDigiParameterList = new TList(); fChargeDigiParameterList = new TList(); fPersistance = kTRUE; fGeoH = PndGeoHandling::Instance(); fTimeOrderedDigi = kFALSE; } // ------------------------------------------------------------------------- // ----- Default constructor ------------------------------------------- PndSdsStripHitProducer::PndSdsStripHitProducer(const char* name) : PndSdsTask(name), fDataBuffer(0) { fOverrideParams = false; fDigiParameterList = new TList(); fChargeDigiParameterList = new TList(); fPersistance = kTRUE; fGeoH = PndGeoHandling::Instance(); fTimeOrderedDigi = kFALSE; } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- PndSdsStripHitProducer::~PndSdsStripHitProducer() { if (0!=fDigiParameterList) delete fDigiParameterList; if (0!=fChargeDigiParameterList) delete fChargeDigiParameterList; if (0!=fDataBuffer) delete fDataBuffer; // TODO: needs check: now cleared correctly? for( std::map::iterator it = fStripCalcTop.begin(); it != fStripCalcTop.end(); it++){ if(0 != it->second) delete it->second; it->second = 0; } for( std::map::iterator it = fStripCalcBot.begin(); it != fStripCalcBot.end(); it++){ if(0 != it->second) delete it->second; it->second = 0; } for(std::map::iterator it = fChargeConverter.begin(); it != fChargeConverter.end(); it++){ if(0 != it->second) delete it->second; it->second = 0; } } // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- InitStatus PndSdsStripHitProducer::ReInit() { SetParContainers(); SetCalculators(); return kSUCCESS; } // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- void PndSdsStripHitProducer::SetCalculators() { // After the first start if the Init() tis can be set properly. TIter params(fDigiParameterList); while(PndSdsStripDigiPar* digipar=(PndSdsStripDigiPar*)params()){ if(0==digipar) { Error("SetCalculators()","A Digi Parameter Set does not exist properly."); continue; } const char* senstype = digipar->GetSensType(); if(fVerbose>1){ Info("SetCalculators()","Create a Parameter Set for %s sensors",senstype); std::cout<2)digipar->Print(); //TODO switch also with PndSdsCalcStripDif fStripCalcTop[senstype]=new PndSdsCalcStrip(digipar,kTOP); fStripCalcTop[senstype]->SetVerboseLevel(fVerbose); fStripCalcBot[senstype]=new PndSdsCalcStrip(digipar,kBOTTOM); fStripCalcBot[senstype]->SetVerboseLevel(fVerbose); } } // ------------------------------------------------------------------------- void PndSdsStripHitProducer::SetParContainers() { if(fVerbose>1) Info("SetParContainers","done."); return; } // ----- Public method Init -------------------------------------------- InitStatus PndSdsStripHitProducer::Init() { FairRootManager* ioman = FairRootManager::Instance(); SetBranchNames(); if ( ! ioman ) { std::cout << "-E- PndSdsStripHitProducer::Init: " << "RootManager not instantiated!" << std::endl; return kFATAL; } fPointArray = (TClonesArray*) ioman->GetObject(fInBranchName); if ( ! fPointArray ) { std::cout << "-E- PndSdsStripHitProducer::Init: " << "No "<GetObject("MCEventHeader."); if(!fMcEventHeader) { std::cout << "-E- PndSdsStripHitProducer::Init: " << "No MCEventHeader. array!" << std::endl; return kERROR; } // Create and register output array // fStripArray = new TClonesArray("PndSdsDigiStrip"); fStripArray = ioman->Register(fOutBranchName, "PndSdsDigiStrip", fFolderName, fPersistance); if (fTimeOrderedDigi) fDataBuffer = new PndWriteoutBufferT(fOutBranchName, "PndSdsDigiStrip"); SetCalculators(); if(fVerbose>0){ std::cout << "-I- PndSdsStripHitProducer: Initialisation successfull with these parameters:" << std::endl; TIter params(fDigiParameterList); while(PndSdsStripDigiPar* digipar=(PndSdsStripDigiPar*)params()){ if(0!=digipar) { digipar->Print(); } } } return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Public method Exec -------------------------------------------- void PndSdsStripHitProducer::Exec(Option_t* opt) { // Reset output array fGeoH->SetVerbose(fVerbose); for (std::map::iterator it = fChargeConverter.begin(); it != fChargeConverter.end(); it++){ it->second->StartExecute(); } // Declare some variables PndSdsMCPoint *point = NULL; // Int_t detID = 0; // Detector ID // Int_t trackID = 0; // Track index fStripArray = FairRootManager::Instance()->GetTClonesArray(fOutBranchName); if (fTimeOrderedDigi) { std::vector data = fDataBuffer->WriteOutData(FairRootManager::Instance()->GetEventTime()); int nStrip = 0; for (int i = 0; i < data.size(); i++) new ((*fStripArray)[nStrip++]) PndSdsDigiStrip(data[i]); data.clear(); } // Loop over PndSdsMCPoints Int_t nPoints = fPointArray->GetEntriesFast(); if (fVerbose > 0){ std::cout<<" Nr of Points: "<At(iPoint); selected = SelectSensorParams(point->GetSensorID()); if( !selected ) { continue; } if (fVerbose > 2){ std::cout<<"***** Strip Digi for "<GetSensType()<<" ******"<GetPath(point->GetSensorID())< 2){ std::cout << "****Global Point: " << std::endl; point->Print(""); } // transform to local sensor system... (mc point has the ID not the path to the volume) TVector3 posInL = fGeoH->MasterToLocalShortId(point->GetPosition(),point->GetSensorID()); TVector3 posOutL = fGeoH->MasterToLocalShortId(point->GetPositionOut(),point->GetSensorID()); if (fVerbose > 2){ posInL.Print();posOutL.Print(); std::cout << "Energy: " << point->GetEnergyLoss() << std::endl; } // detID = point->GetDetectorID(); // Top Side if (fVerbose > 2) std::cout << "Top Side: " << std::endl; // Calculate a cluster of Strips fired std::vector topStrips = fCurrentStripCalcTop->GetStrips(posInL.X(), posInL.Y(), posInL.Z(), posOutL.X(), posOutL.Y(), posOutL.Z(), point->GetEnergyLoss()); if (topStrips.size() != 0) { if (fVerbose > 1) std::cout << "SensorStrips: " << std::endl; for(std::vector::const_iterator kit=topStrips.begin(); kit!= topStrips.end(); ++kit) { if (fTimeOrderedDigi == kFALSE){ AddDigi(iStrip,iPoint,FairRootManager::Instance()->GetBranchId(fInBranchName),point->GetSensorID(), fCurrentStripCalcTop->CalcFEfromStrip(kit->GetIndex()), fCurrentStripCalcTop->CalcChannelfromStrip(kit->GetIndex()),kit->GetCharge()); } else{ std::vectorindices; indices.push_back(iPoint); PndSdsDigiStrip tempStrip(indices, FairRootManager::Instance()->GetBranchId(fInBranchName), point->GetSensorID(), fCurrentStripCalcTop->CalcFEfromStrip(kit->GetIndex()), fCurrentStripCalcTop->CalcChannelfromStrip(kit->GetIndex()), kit->GetCharge(), FairRootManager::Instance()->GetEventTime()); fDataBuffer->FillNewData(tempStrip, FairRootManager::Instance()->GetEventTime() + 100); } if (fVerbose > 1) std::cout << *kit << std::endl; } }else if(fVerbose>2) std::cout<<"Top side empty"< 2) std::cout << "Bottom Side: " << std::endl; std::vector botStrips = fCurrentStripCalcBot->GetStrips(posInL.X(), posInL.Y(), posInL.Z(), posOutL.X(), posOutL.Y(), posOutL.Z(), point->GetEnergyLoss()); if (botStrips.size() != 0) { if (fVerbose > 2) std::cout << " SensorStrips: " << std::endl; for(std::vector::const_iterator kit=botStrips.begin(); kit!= botStrips.end(); ++kit) { if (fTimeOrderedDigi == kFALSE) { AddDigi(iStrip, iPoint, FairRootManager::Instance()->GetBranchId(fInBranchName), point->GetSensorID(), fCurrentStripCalcBot->CalcFEfromStrip(kit->GetIndex())+ fCurrentDigiPar->GetNrTopFE(), fCurrentStripCalcBot->CalcChannelfromStrip(kit->GetIndex()), kit->GetCharge()); } else{ std::vectorindices; indices.push_back(iPoint); PndSdsDigiStrip tempStrip(indices, FairRootManager::Instance()->GetBranchId(fInBranchName), point->GetSensorID(), fCurrentStripCalcBot->CalcFEfromStrip(kit->GetIndex())+ fCurrentDigiPar->GetNrTopFE(), fCurrentStripCalcBot->CalcChannelfromStrip(kit->GetIndex()), kit->GetCharge(), FairRootManager::Instance()->GetEventTime()); fDataBuffer->FillNewData(tempStrip, FairRootManager::Instance()->GetEventTime() + 100); } if (fVerbose > 2) std::cout << *kit << std::endl; } } else if(fVerbose>2) std::cout<<"Bottom side empty"<At(i); SelectSensorParams(finDigi->GetSensorID()); smearedCharge = SmearCharge(finDigi->GetCharge()); //FIXME: This is not elegant and error prone, for Tasks afterwards will not know how we digitized! finDigi->SetCharge(fCurrentChargeConverter->ChargeToDigiValue(smearedCharge)); indexnum = finDigi->GetNIndices(); for(Int_t ind=0;indAt(ind); tempstamp = DigitizeTime(point->GetTime(),smearedCharge); if(tempstamp < timestamp) timestamp = tempstamp; } finDigi->SetTimeStamp(timestamp); } for (std::map::iterator it = fChargeConverter.begin(); it != fChargeConverter.end(); it++){ it->second->EndExecute(); } // Event summary if(fVerbose > 1) std::cout << "-I- PndSdsStripHitProducer: " << nPoints << " PndSdsMCPoints, " << iStrip << " Digis created."<< std::endl; } // ------------------------------------------------------------------------- void PndSdsStripHitProducer::AddDigi(Int_t &iStrip, Int_t iPoint, Int_t detID, Int_t sensorID, Int_t fe, Int_t chan, Double_t charge) { PndSdsDigiStrip* aDigi = 0; for(Int_t kstr = 0; kstr < iStrip ; kstr++) { // search if that channel fired already aDigi = (PndSdsDigiStrip*)fStripArray->At(kstr); if ( aDigi->GetDetID() == detID && aDigi->GetSensorID() == sensorID && aDigi->GetFE() == fe && aDigi->GetChannel() == chan ) { aDigi->AddCharge(charge); aDigi->AddIndex(iPoint); return; } } // we're here when this channel didn't fire std::vectorindices; indices.push_back(iPoint); new ((*fStripArray)[iStrip]) PndSdsDigiStrip(indices,detID,sensorID,fe,chan,charge, 0); iStrip++; return; } // ------------------------------------------------------------------------- Bool_t PndSdsStripHitProducer::SelectSensorParams(Int_t sensorID) { fCurrentDigiPar = NULL; fCurrentStripCalcTop = NULL; fCurrentStripCalcBot = NULL; fCurrentChargeConverter = NULL; TString detpath = fGeoH->GetPath(sensorID); if( !(detpath.Contains("Strip")) ) { // filter from pixel points return kFALSE; } TIter parsetiter(fDigiParameterList); while ( PndSdsStripDigiPar* digipar = (PndSdsStripDigiPar*)parsetiter() ) { const char* sensortype = digipar->GetSensType(); if(detpath.Contains(sensortype)) { fCurrentStripCalcTop = fStripCalcTop[sensortype]; fCurrentStripCalcBot = fStripCalcBot[sensortype]; fCurrentChargeConverter = fChargeConverter[sensortype]; fCurrentDigiPar = digipar; return kTRUE; } } // no suiting object found //if (fVerbose > 1) if(fVerbose>1) Info("SelectSensorParams()","No valid sensor parameters selected, skipping this point."); std::cout<<"detector name does not contain a valid parameter name."< 2) std::cout<<" DetName : "<GetT(); return fCurrentChargeConverter->GetTimeStamp(time,charge,eventTime); } //______________________________________________________________________________ Double_t PndSdsStripHitProducer::SmearCharge(Double_t charge) { Double_t smeared = gRandom->Gaus(charge,fCurrentDigiPar->GetNoise()); if (fVerbose > 3) std::cout<<" charge = "<ForceFill(); } } ClassImp(PndSdsStripHitProducer);