// ------------------------------------------------------------------------- // ----- PndMvdStripClusterTask source file ----- // ----- Created 10/01/06 by V. Friese ----- // ------------------------------------------------------------------------- #include #include "TClonesArray.h" #include "TArrayD.h" #include "TGeoManager.h" #include "TGeoMatrix.h" #include "CbmRootManager.h" #include "CbmRunAna.h" #include "CbmRuntimeDb.h" #include "CbmGeoNode.h" #include "CbmGeoVector.h" #include "PndStringVector.h" #include "PndMvdGeoPar.h" #include "PndMvdStripDigiPar.h" #include "PndMvdStripClusterTask.h" #include "PndMvdMCPoint.h" #include "PndMvdCalcStrip.h" #include "PndMvdDigiStrip.h" // #include "PndMvdStripCluster.h" #include "PndMvdCluster.h" #include "PndMvdGeoHandling.h" #include "PndMvdStripClusterBuilder.h" #include // enum SensorSide { kTOP, kBOTTOM }; // ----- Default constructor ------------------------------------------- PndMvdStripClusterTask::PndMvdStripClusterTask() : CbmTask("MVD Strip Clustertisation Task") { fChargeCut = 1.e6; // this ist really large and shall have no effect fGeoFile = ""; } // ------------------------------------------------------------------------- // ----- constructor ------------------------------------------- PndMvdStripClusterTask::PndMvdStripClusterTask(Double_t chargecut, TString geoFile) : CbmTask("MVD Strip Clustertisation Task") { fChargeCut = chargecut; fGeoFile = geoFile; } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- PndMvdStripClusterTask::~PndMvdStripClusterTask() { if(0!=fGeoH) delete fGeoH; } // ------------------------------------------------------------------------- // ----- Initialization of Parameter Containers ------------------------- void PndMvdStripClusterTask::SetParContainers() { // Get Base Container CbmRunAna* ana = CbmRunAna::Instance(); CbmRuntimeDb* rtdb=ana->GetRuntimeDb(); fGeoPar = (PndMvdGeoPar*)(rtdb->getContainer("PndMvdGeoPar")); fDigiParRect = (PndMvdStripDigiPar*)(rtdb->getContainer("MVDStripDigiParRect")); fDigiParTrap = (PndMvdStripDigiPar*)(rtdb->getContainer("MVDStripDigiParTrap")); } InitStatus PndMvdStripClusterTask::ReInit() { InitStatus stat=kERROR; return stat; /* CbmRunAna* ana = CbmRunAna::Instance(); CbmRuntimeDb* rtdb=ana->GetRuntimeDb(); fGeoPar=(PndMvdGeoPar*)(rtdb->getContainer("PndMvdGeoPar")); return kSUCCESS; */ } // ----- Public method Init -------------------------------------------- InitStatus PndMvdStripClusterTask::Init() { CbmRootManager* ioman = CbmRootManager::Instance(); if ( ! ioman ) { std::cout << "-E- PndMvdStripClusterTask::Init: " << "RootManager not instantiated!" << std::endl; return kFATAL; } // Get input array fDigiArray = (TClonesArray*) ioman->GetObject("MVDStripDigis"); if ( ! fDigiArray ) { std::cout << "-W- PndMvdStripClusterTask::Init: " << "No MVDDigi array!" << std::endl; return kERROR; } // set output arrays fHitArray = new TClonesArray("PndMvdHit"); ioman->Register("MVDHitsStrip", "MVD", fHitArray, kTRUE); fClusterArray = new TClonesArray("PndMvdCluster"); ioman->Register("MVDStripClusterCand","MVD",fClusterArray,kTRUE); // geo name handling // This requires a connection to a simulation file! if (fGeoFile=="") fGeoFile = ioman->GetInFile()->GetName(); fGeoH = new PndMvdGeoHandling(fGeoFile.Data()); // else *infile = new TFile(fGeoFile); // TGeoManager *geoMan = (TGeoManager*) infile->Get("CBMGeom"); // std::cout << "-I- geoMan in StripClusterTask is = "< 2) std::cout<<"Sarting PndMvdStripClusterTask::Exec()"< digiStripArray; // Reset output array if ( ! fClusterArray ) Fatal("Exec", "No ClusterArray"); fClusterArray->Clear(); if ( ! fHitArray ) Fatal("Exec", "No HitArray"); fHitArray->Clear(); // a std::map is a SORTED container, it is sorted by the identifier TString detName; std::map firedSensors; Int_t nPoints = fDigiArray->GetEntriesFast(); Int_t strip; SensorSide side; PndMvdDigiStrip* myDigi=0; PndMvdCluster* myCandTop=0; PndMvdCluster* myCandBot=0; // load the Clusterfinder PndMvdStripClusterBuilder clusterbuilder; // Sort Digi indice into the clusterbuilder for (Int_t iPoint = 0; iPoint < fDigiArray->GetEntriesFast(); iPoint++) { // sort digis by sensor name and stripnumber myDigi = (PndMvdDigiStrip*)(fDigiArray->At(iPoint)); detName = myDigi->GetDetName().Data(); SelectSensorParams(detName); fStripCalcTop->CalcFeChToStrip(myDigi->GetFE(), myDigi->GetChannel(), strip, side); clusterbuilder.AddDigi(detName.Data(),side,strip,iPoint); // sortedDigis[detName][side][strip] = iPoint; // if(firedSensors[detName.Data()]) firedSensors[detName.Data()]=myDigi->GetDetID(); if(firedSensors[detName.Data()]) firedSensors[detName.Data()]++; else firedSensors[detName.Data()] = 1; //first hit } //TODO // maybe I shall convert the vectors into PndMvdClustCand objects and fill // the fClusterArray std::vector< PndMvdCluster > clusters; std::vector< Int_t > topclusters;// contains index to fClusterArray std::vector< Int_t > botclusters;// contains index to fClusterArray std::vector< Int_t > oneclustertop; std::vector< Int_t > oneclusterbot; TVector2 topDirection, botDirection; TGeoVolume* actVolume; TGeoBBox* actBox; TVector3 sensorDim, localpos, locDpos; Int_t detID, iDigi, clindex, topIndex, botIndex; Double_t mycharge; TVector2 meantopPoint, meanbotPoint, onsensorPoint; TVector3 hitPos,hitErr; Double_t t, b; // ------- SEARCH ------ clusters = clusterbuilder.SearchClusters(); // fetch ids in 'clusters' to the top and bot side topclusters = clusterbuilder.GetTopClusterIDs(); botclusters = clusterbuilder.GetBotClusterIDs(); // Fill the ClonesArray for output TODO: do this better, don't copy objects around for(std::vector< PndMvdCluster >::iterator clit= clusters.begin(); clit!=clusters.end(); ++clit) { clindex = fClusterArray->GetEntriesFast(); new((*fClusterArray)[clindex]) PndMvdCluster(*clit); } // begin the hit reconstruction // loop structure: // //top clusters // |-sensors // |-calculate chargeweighted mean // |-bot clusters // |-|-calc chargew. mean // |-|-calc the crossing strip points // |-|-fill hit array // ----- search for clusters ----- //printout for checking if(fVerbose > 2) { std::cout<<"Top Clusters: "; for (std::vector< Int_t>::iterator itTop = topclusters.begin(); itTop!=topclusters.end(); ++itTop) { std::cout<<*itTop<<" | ";} std::cout<::iterator itBot = botclusters.begin(); itBot!=botclusters.end(); ++itBot) { std::cout<<*itBot<<" | "; } std::cout<::iterator itTop = topclusters.begin(); itTop!=topclusters.end(); ++itTop) { Double_t topcharge = 0., meantopstrip=0.; oneclustertop = (clusters[*itTop]).GetClusterList(); TString detnametop = ((PndMvdDigiStrip*)fDigiArray->At(oneclustertop[0]))->GetDetName(); SelectSensorParams(detnametop); // for (std::map::iterator itSensors=firedSensors.begin(); // itSensors!=firedSensors.end(); ++itSensors) // { // detName = itSensors->first; // if(detnametop == detName) // { topDirection = fStripCalcTop->GetStripDirection(); botDirection = fStripCalcBot->GetStripDirection(); // detID = itSensors->second; // gGeoManager->cd(fGeoH->GetPath(detName.Data())); // detID = 2; // Strip part detID = ((PndMvdDigiStrip*)fDigiArray->At(oneclustertop[0]))->GetDetID(); gGeoManager->cd(fGeoH->GetPath(detnametop.Data())); actVolume = gGeoManager->GetCurrentVolume(); actBox = (TGeoBBox*)(actVolume->GetShape()); sensorDim.SetX(actBox->GetDX()); sensorDim.SetY(actBox->GetDY()); sensorDim.SetZ(actBox->GetDZ()); if(fVerbose>1) { std::cout <<" -I- current Box Volume:"<::iterator itTopDigi = oneclustertop.begin(); itTopDigi != oneclustertop.end(); ++itTopDigi) {// I use the temp. variables from the top of this method again // calculate the mean charge and stripnumber myDigi = (PndMvdDigiStrip*)fDigiArray->At(*itTopDigi); fStripCalcTop->CalcFeChToStrip(myDigi->GetFE(), myDigi->GetChannel(), strip, side); topcharge += myDigi->GetCharge(); meantopstrip += myDigi->GetCharge() * strip; if(fVerbose > 2)std::cout<<"FE no: "<GetFE()<<" | channel no: " <GetChannel()<<" | topstrip no: "<0) { meantopstrip = meantopstrip/topcharge; fStripCalcTop->CalcStripPointOnLine(meantopstrip, meantopPoint); meantopPoint -= fCurrentDigiPar->GetTopAnchor(); // loop on bottom side for (std::vector< Int_t>::iterator itBot = botclusters.begin(); itBot!=botclusters.end(); ++itBot) { botIndex = *itBot; Double_t botcharge = 0., meanbotstrip=0.; oneclusterbot = (clusters[*itBot]).GetClusterList(); TString detnamebot = ((PndMvdDigiStrip*)fDigiArray->At(oneclusterbot[0]))->GetDetName(); if(detnamebot != detnametop) continue; for (std::vector::iterator itBotDigi = oneclusterbot.begin(); itBotDigi != oneclusterbot.end(); ++itBotDigi) {// I use the temp. variables from the top of this method again // calculate the mean charge and stripnumber // here we must use the top calculator to get the correct numbers myDigi = (PndMvdDigiStrip*)fDigiArray->At(*itBotDigi); fStripCalcTop->CalcFeChToStrip(myDigi->GetFE(), myDigi->GetChannel(), strip, side); botcharge += myDigi->GetCharge(); meanbotstrip += myDigi->GetCharge() * strip; if(fVerbose > 2)std::cout<<"FE no: "<GetFE()<<" | channel no: " <GetChannel()<<" | botstrip no: "<0) { meanbotstrip = meanbotstrip/botcharge; if(fVerbose > 2) { std::cout<<"Charges: Ctop = "<LocalToMasterId(localpos,detName.Data()); // calculate the errors corresponding to a skewed system! // TODO: how tot treat the errors correctly? // if(clustersize == 1) { "1/sqrt(12)" } t = fCurrentDigiPar->GetTopPitch()*cos(fCurrentDigiPar->GetOrient()); b = fCurrentDigiPar->GetBotPitch()*cos(fCurrentDigiPar->GetOrient()+fCurrentDigiPar->GetSkew()); locDpos.SetX( sqrt((t*t+b*b)/12.) ); t = fCurrentDigiPar->GetTopPitch()*sin(fCurrentDigiPar->GetOrient()); b = fCurrentDigiPar->GetBotPitch()*sin(fCurrentDigiPar->GetOrient()+fCurrentDigiPar->GetSkew()); locDpos.SetY( sqrt((t*t+b*b)/12.) ); locDpos.SetZ( 0. ); hitErr = fGeoH->LocalToMasterErrorsId(locDpos,detName.Data()); // --- add hit to list --- Int_t i = fHitArray->GetEntriesFast(); new((*fHitArray)[i]) PndMvdHit(detID,detName.Data(),hitPos,hitErr, *itTop,mycharge,oneclusterbot.size()+oneclustertop.size()); ((PndMvdHit*)((*fHitArray)[i]))->SetBotIndex(*itBot); } } }// loop bot clusters } }// loop top clusters // if (fVerbose > 0) std::cout << "-I- PndMvdStripClusterTask: " << fClusterArray->GetEntriesFast() << " Mvd Clusters and " << fHitArray->GetEntriesFast()<<" Hits calculated." << " out of " <GetEntriesFast()<< " Digis"<< std::endl; if (fVerbose > 1) std::cout<<"PndMvdStripClusterTask::Exec() is done."<GetPath(detname.Data()); if (path.Contains("Rect")) { fStripCalcTop = fStripCalcTopRect; fStripCalcBot = fStripCalcBotRect; fCurrentDigiPar = fDigiParRect; } else if (path.Contains("Trap")) { fStripCalcTop = fStripCalcTopTrap; fStripCalcBot = fStripCalcBotTrap; fCurrentDigiPar = fDigiParTrap; } else { std::cout<<"-E- PndMvdStripClusterTask::SelectSensorParams on\n" <<"\t"<GetThreshold(); ?? // fChargeCut = factor * fCurrentDigiPar->GetNoise(); ?? } ClassImp(PndMvdStripClusterTask);