/** CbmMuchFindHits.cxx *@author Mikhail Ryzhinskiy *@since 22.03.07 *@version 1.0 ** ** CBM task class for finding hits in the MUCH ** Task level RECO ** Produces objects of type CbmMuchHit out of CbmMuchDigi. **/ #include #include #include using std::setw; using std::left; using std::right; using std::fixed; using std::setprecision; using std::cerr; using std::set; #include "TClonesArray.h" #include "CbmRootManager.h" #include "CbmRunAna.h" #include "CbmRuntimeDb.h" #include "CbmGeoMuchPar.h" #include "CbmMuchDigi.h" #include "CbmMuchDigiPar.h" #include "CbmMuchDigiScheme.h" #include "CbmMuchFindHits.h" #include "CbmMuchHit.h" #include "CbmMuchSector.h" #include "CbmMuchStation.h" // ----- Default constructor ------------------------------------------ CbmMuchFindHits::CbmMuchFindHits() : CbmTask("MuchFindHits", 1) { fGeoPar = NULL; fDigiPar = NULL; fDigis = NULL; fHits = NULL; fDigiScheme = new CbmMuchDigiScheme(); } // ------------------------------------------------------------------------- // ----- Standard constructor ------------------------------------------ CbmMuchFindHits::CbmMuchFindHits(Int_t iVerbose) : CbmTask("MuchFindHits", iVerbose) { fGeoPar = NULL; fDigiPar = NULL; fDigis = NULL; fHits = NULL; fDigiScheme = new CbmMuchDigiScheme(); } // ------------------------------------------------------------------------- // ----- Constructor with name ----------------------------------------- CbmMuchFindHits::CbmMuchFindHits(const char* name, Int_t iVerbose) : CbmTask(name, iVerbose) { fGeoPar = NULL; fDigiPar = NULL; fDigis = NULL; fHits = NULL; fDigiScheme = new CbmMuchDigiScheme(); } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- CbmMuchFindHits::~CbmMuchFindHits() { if ( fHits ) { fHits->Delete(); delete fHits; } } // ------------------------------------------------------------------------- // ----- Public method Exec -------------------------------------------- void CbmMuchFindHits::Exec(Option_t* opt) { fTimer.Start(); Bool_t warn = kFALSE; // Check for digi scheme if ( ! fDigiScheme ) { cerr << "-E- " << fName << "::Exec: No digi scheme!" << endl; return; } // Clear output array fHits->Clear(); // Sort MUCH digis with respect to sectors (fills fDigiMap) SortDigis(); // Find hits in sectors Int_t nDigis = 0; Int_t nHits = 0; Int_t nStations = fDigiScheme->GetNStations(); CbmMuchStation* station = NULL; for (Int_t iStation=0; iStationGetStation(iStation); Int_t nDigisInStation = 0; Int_t nHitsInStation = 0; Int_t nSectors = station->GetNSectors(); for (Int_t iSector=0; iSectorGetSector(iSector); set digiSet; if ( fDigiMap.find(sector) == fDigiMap.end() ) { cout << "-E- " << fName << "::Exec: sector " << sector->GetSectorNr() << " of station " << station->GetStationNr() << "not found in front map!" << endl; warn = kTRUE; continue; } digiSet = fDigiMap[sector]; Int_t nDigisInSector = digiSet.size(); Int_t nHitsInSector = FindHits(station, sector, digiSet); if ( fVerbose > 2 ) cout << "Sector " << sector->GetSectorNr() << ", Digis " << nDigisInSector << ", Hits " << nHitsInSector << endl; nHitsInStation += nHitsInSector; nDigisInStation += nDigisInSector; } // Sector loop if ( fVerbose > 1 ) cout << "Total for station " << station->GetStationNr() << ": Digis " << nDigisInStation << ", hits " << nHitsInStation << endl; nDigis += nDigisInStation; nHits += nHitsInStation; } // Station loop fTimer.Stop(); if ( fVerbose ) { cout << endl; cout << "-I- " << fName << ":Event summary" << endl; cout << " Active channels : " << nDigis << endl; cout << " Hits created : " << nHits << endl; cout << " Real time : " << fTimer.RealTime() << endl; } else { if ( warn ) cout << "- "; else cout << "+ "; cout << setw(15) << left << fName << ": " << setprecision(4) << setw(8) << fixed << right << fTimer.RealTime() << " s, digis " << nDigis << ", hits: " << nHits << endl; } } // ------------------------------------------------------------------------- // ----- Private method SetParContainers ------------------------------- void CbmMuchFindHits::SetParContainers() { // Get run and runtime database CbmRunAna* run = CbmRunAna::Instance(); if ( ! run ) Fatal("SetParContainers", "No analysis run"); CbmRuntimeDb* db = run->GetRuntimeDb(); if ( ! db ) Fatal("SetParContainers", "No runtime database"); // Get MUCH geometry parameter container fGeoPar = (CbmGeoMuchPar*) db->getContainer("CbmGeoMuchPar"); // Get MUCH digitisation parameter container fDigiPar = (CbmMuchDigiPar*) db->getContainer("CbmMuchDigiPar"); } // ------------------------------------------------------------------------- // ----- Private method Init ------------------------------------------- InitStatus CbmMuchFindHits::Init() { // Get input array CbmRootManager* ioman = CbmRootManager::Instance(); if ( ! ioman ) Fatal("Init", "No CbmRootManager"); fDigis = (TClonesArray*) ioman->GetObject("MuchDigi"); // Register output array fHits = new TClonesArray("CbmMuchHit", 1000); ioman->Register("MuchHit", "Hit in MUCH", fHits, kTRUE); // Build digitisation scheme Bool_t success = fDigiScheme->Init(fGeoPar, fDigiPar); if ( ! success ) return kERROR; // Create sectorwise digi sets MakeSets(); // Control output if (fVerbose >= 1) fDigiScheme->Print(); cout << "-I- " << fName << "::Init: " << "MUCH digitization scheme succesfully initialised" << endl; cout << " Stations: " << fDigiScheme->GetNStations() << ", Sectors: " << fDigiScheme->GetNSectors() << ", Channels: " << fDigiScheme->GetNChannels() << endl; return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Private method ReInit ----------------------------------------- InitStatus CbmMuchFindHits::ReInit() { // Clear digitisation scheme fDigiScheme->Clear(); // Build new digitisation scheme Bool_t success = fDigiScheme->Init(fGeoPar, fDigiPar); if ( ! success ) return kERROR; // Create sectorwise digi sets MakeSets(); // Control output if (fVerbose >= 1) fDigiScheme->Print(); cout << "-I- " << fName << "::Init: " << "MUCH digitization scheme succesfully reinitialised" << endl; cout << " Stations: " << fDigiScheme->GetNStations() << ", Sectors: " << fDigiScheme->GetNSectors() << ", Channels: " << fDigiScheme->GetNChannels() << endl; return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Private method MakeSets --------------------------------------- void CbmMuchFindHits::MakeSets() { fDigiMap.clear(); Int_t nStations = fDigiScheme->GetNStations(); for (Int_t iStation=0; iStationGetStation(iStation); Int_t nSectors = station->GetNSectors(); for (Int_t iSector=0; iSectorGetSector(iSector); set a; fDigiMap[sector] = a; } } } // ------------------------------------------------------------------------- // ----- Private method SortDigis -------------------------------------- void CbmMuchFindHits::SortDigis() { // Check input array if ( ! fDigis ) { cout << "-E- " << fName << "::SortDigis: No input array!" << endl; return; } // Clear sector digi sets map >::iterator mapIt; for (mapIt=fDigiMap.begin(); mapIt!=fDigiMap.end(); mapIt++) ((*mapIt).second).clear(); // Fill digis into sets CbmMuchDigi* digi = NULL; CbmMuchSector* sector = NULL; Int_t stationNr = -1; Int_t sectorNr = -1; Int_t nDigis = fDigis->GetEntriesFast(); for (Int_t iDigi=0; iDigiAt(iDigi); stationNr = digi->GetStationNr(); sectorNr = digi->GetSectorNr(); sector = fDigiScheme->GetSector(stationNr, sectorNr); if ( fDigiMap.find(sector) == fDigiMap.end() ) { cerr << "-E- " << fName << "::SortDigis:: sector " << sectorNr << " of station " << stationNr << " not found in digi scheme (F)!" << endl; continue; } fDigiMap[sector].insert(iDigi); } } // ------------------------------------------------------------------------- // ----- Private method FindHits --------------------------------------- Int_t CbmMuchFindHits::FindHits(CbmMuchStation* station, CbmMuchSector* sector, set& digiSet) { // Counter Int_t nNew = 0; // Get sector parameters Int_t detId = sector->GetDetectorId(); Int_t iType = sector->GetType(); Double_t xc = sector->GetX0(); Double_t yc = sector->GetY0(); Double_t rot = sector->GetRotation(); Double_t lx = sector->GetLx(); Double_t ly = sector->GetLy(); Double_t dx = sector->GetDx(); Double_t dy = sector->GetDy(); Double_t z = station->GetZ(); Int_t stationNr = station->GetStationNr(); Int_t sectorNr = sector->GetSectorNr(); // Some auxiliary values Double_t sinrot = TMath::Sin(rot); Double_t cosrot = TMath::Cos(rot); // Calculate error matrix in sector system Double_t vX, vY, vXY; if ( iType == 1 || iType == 2) { vX = dx / TMath::Sqrt(12.); vY = dy / TMath::Sqrt(12.); vXY = 0.; } else { cerr << "-E- " << fName << "::FindHits: Illegal sector type " << iType << endl; return 0; } // Transform variances into global c.s. Double_t wX = vX * vX * cosrot * cosrot - 2. * vXY * cosrot * sinrot + vY * vY * sinrot * sinrot; Double_t wY = vX * vX * sinrot * sinrot + 2. * vXY * cosrot * sinrot + vY * vY * cosrot * cosrot; Double_t wXY = (vX*vX - vY*vY) * cosrot * sinrot + vXY * ( cosrot*cosrot - sinrot*sinrot ); Double_t sigmaX = TMath::Sqrt(wX); Double_t sigmaY = TMath::Sqrt(wY); // Now perform the loop over active channels set::iterator iter; // ----- Types 1,2 : Pad-type sector --------------------------------------- Int_t nColumns = Int_t( (lx+1e-7) / dx ); Int_t iDigi = -1; Int_t iChan = -1; Int_t iCol = -1; Int_t iRow = -1; Int_t nHits = fHits->GetEntriesFast(); Double_t xint, yint; Double_t x, y; TVector3 pos, dpos; CbmMuchDigi* digi = NULL; for (iter=digiSet.begin(); iter!=digiSet.end(); iter++) { iDigi = (*iter); digi = (CbmMuchDigi*) fDigis->At(iDigi); if ( ! digi ) { cout << "-W- " << GetName() << "::FindHits: Invalid digi index " << iDigi << " in the sector " << sector->GetSectorNr() << ", station " << station->GetStationNr() << endl; continue; } iChan = digi->GetChannelNr(); iRow = Int_t( iChan / nColumns ); iCol = iChan - iRow * nColumns; xint = ( Double_t(iCol) + 0.5 ) * dx; yint = ( Double_t(iRow) + 0.5 ) * dy; // Translation to centre of sector xint = xint - lx/2.; yint = yint - ly/2.; // Rotation around sector centre x = xint * cosrot - yint * sinrot; y = xint * sinrot + yint * cosrot; // Translation into global c.s. x = x + xc; y = y + yc; // Make new hit pos.SetXYZ(x, y, z); dpos.SetXYZ(sigmaX, sigmaY, 0.); new ((*fHits)[nHits++]) CbmMuchHit(detId, pos, dpos, wXY, iDigi, digi->GetTimes(), digi->GetDTimes()); nNew++; if ( fVerbose > 3 ) cout << "New MuchHit at (" << x << ", " << y << ", " << z << "), station " << stationNr << ", sector " << sectorNr << ", channel " << iChan << endl; } // Loop over digi set // --------------------------------------------------------------------- return nNew; } // ------------------------------------------------------------------------- ClassImp(CbmMuchFindHits)