/* Copyright (C) 2004-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Volker Friese [committer], Florian Uhlig, Philipp Sitzmann */ // ------------------------------------------------------------------------- // ----- CbmMvd source file ----- // ----- Created 26/07/04 by V. Friese ----- // ------------------------------------------------------------------------- #include "CbmMvd.h" #include "CbmMvdPoint.h" #include "CbmStack.h" #include "tools/CbmMvdGeoHandler.h" #include "FairRootManager.h" #include "FairRun.h" #include "FairRuntimeDb.h" #include "FairVolume.h" #include "TClonesArray.h" #include "TGeoManager.h" #include "TList.h" #include "TObjArray.h" #include "TParticle.h" #include "TString.h" #include "TVirtualMC.h" #include "TVirtualMCStack.h" #include <iostream> using std::cout; using std::endl; // ----- Default constructor ------------------------------------------- CbmMvd::CbmMvd() // : CbmMvd("MVD", kTRUE, kMvd) : FairDetector("MVD", kTRUE, ToIntegralType(ECbmModuleId::kMvd)) , fTrackID(0) , fPdg(0) , fVolumeID(0) , fPosIn(0.0, 0.0, 0.0, 0.0) , fPosOut(0.0, 0.0, 0.0, 0.0) , fMomIn(0.0, 0.0, 0.0, 0.0) , fMomOut(0.0, 0.0, 0.0, 0.0) , fTime(0.) , fLength(0.) , fELoss(0.) , fPosIndex(0) , fCollection(new TClonesArray("CbmMvdPoint")) , kGeoSaved(kFALSE) , fGeoPar(new TList()) , fStationMap() , fmvdHandler(nullptr) { ResetParameters(); fGeoPar->SetName(GetName()); fVerboseLevel = 1; fmvdHandler = new CbmMvdGeoHandler(); } // ------------------------------------------------------------------------- // ----- Standard constructor ------------------------------------------ CbmMvd::CbmMvd(const char* name, Bool_t active) : FairDetector(name, active, ToIntegralType(ECbmModuleId::kMvd)) , fTrackID(0) , fPdg(0) , fVolumeID(0) , fPosIn(0.0, 0.0, 0.0, 0.0) , fPosOut(0.0, 0.0, 0.0, 0.0) , fMomIn(0.0, 0.0, 0.0, 0.0) , fMomOut(0.0, 0.0, 0.0, 0.0) , fTime(0.) , fLength(0.) , fELoss(0.) , fPosIndex(0) , fCollection(new TClonesArray("CbmMvdPoint")) , kGeoSaved(kFALSE) , fGeoPar(new TList()) , fStationMap() , fmvdHandler(nullptr) { fGeoPar->SetName(GetName()); fVerboseLevel = 1; fmvdHandler = new CbmMvdGeoHandler(); } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- CbmMvd::~CbmMvd() { if (fGeoPar) { fGeoPar->Delete(); delete fGeoPar; } if (fCollection) { fCollection->Delete(); delete fCollection; } } // ------------------------------------------------------------------------- // ----- Virtual public method ProcessHits ------------------------------ Bool_t CbmMvd::ProcessHits(FairVolume* vol) { // Store track parameters at entrance of sensitive volume if (gMC->IsTrackEntering()) { fPdg = gMC->TrackPid(); fELoss = 0.; fTime = gMC->TrackTime() * 1.0e09; fLength = gMC->TrackLength(); gMC->TrackPosition(fPosIn); gMC->TrackMomentum(fMomIn); } // Sum energy loss for all steps in the active volume fELoss += gMC->Edep(); // Set additional parameters at exit of active volume. Create CbmMvdPoint. if (gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()) { fTrackID = gMC->GetStack()->GetCurrentTrackNumber(); gMC->TrackPosition(fPosOut); gMC->TrackMomentum(fMomOut); const char* address = gMC->CurrentVolPath(); TString stAdd(address); if (stAdd.Contains("/MVDscripted_0")) { fVolumeID = fmvdHandler->GetIDfromPath(stAdd); } else { fVolumeID = vol->getMCid(); } if (fELoss == 0.) return kFALSE; AddHit(fTrackID, fPdg, fStationMap[fVolumeID], TVector3(fPosIn.X(), fPosIn.Y(), fPosIn.Z()), TVector3(fPosOut.X(), fPosOut.Y(), fPosOut.Z()), TVector3(fMomIn.Px(), fMomIn.Py(), fMomIn.Pz()), TVector3(fMomOut.Px(), fMomOut.Py(), fMomOut.Pz()), fTime, fLength, fELoss); // Increment number of MvdPoints for this track CbmStack* stack = (CbmStack*) gMC->GetStack(); stack->AddPoint(ECbmModuleId::kMvd); ResetParameters(); } return kTRUE; } // ------------------------------------------------------------------------- // ----- Public method BeginEvent -------------------------------------- void CbmMvd::BeginEvent() {} // ------------------------------------------------------------------------- // ----- Virtual public method EndOfEvent ------------------------------ void CbmMvd::EndOfEvent() { if (fVerboseLevel) Print(); // fCollection->Clear(); fCollection->Delete(); ResetParameters(); } // ------------------------------------------------------------------------- // ----- Virtual public method Register -------------------------------- void CbmMvd::Register() { FairRootManager::Instance()->Register("MvdPoint", GetName(), fCollection, kTRUE); } // ------------------------------------------------------------------------- // ----- Virtual public method GetCollection --------------------------- TClonesArray* CbmMvd::GetCollection(Int_t iColl) const { if (iColl == 0) return fCollection; else return NULL; } // ------------------------------------------------------------------------- // ----- Virtual public method Print ----------------------------------- void CbmMvd::Print(Option_t*) const { Int_t nHits = fCollection->GetEntriesFast(); LOG(info) << fName << ": " << nHits << " points registered in this event."; } // ------------------------------------------------------------------------- // ----- Virtual public method Reset ----------------------------------- void CbmMvd::Reset() { // fCollection->Clear(); fCollection->Delete(); ResetParameters(); } // ------------------------------------------------------------------------- // ----- Virtual public method CopyClones ------------------------------ void CbmMvd::CopyClones(TClonesArray* cl1, TClonesArray* cl2, Int_t offset) { Int_t nEntries = cl1->GetEntriesFast(); LOG(info) << "CbmMvd: " << nEntries << " entries to add."; TClonesArray& clref = *cl2; CbmMvdPoint* oldpoint = NULL; for (Int_t i = 0; i < nEntries; i++) { oldpoint = (CbmMvdPoint*) cl1->At(i); Int_t index = oldpoint->GetTrackID() + offset; oldpoint->SetTrackID(index); new (clref[fPosIndex]) CbmMvdPoint(*oldpoint); fPosIndex++; } LOG(info) << "CbmMvd: " << cl2->GetEntriesFast() << " merged entries."; } // ------------------------------------------------------------------------- // --------Pulic method ConstructGeometry()----------------------------------------------------------------- void CbmMvd::ConstructGeometry() { TString fileName = GetGeometryFileName(); if (fileName.EndsWith(".root")) { LOG(info) << "Constructing MVD geometry from ROOT file " << fileName.Data(); ConstructRootGeometry(); } else if (fileName.EndsWith(".geo")) { LOG(fatal) << "Don't use old .geo style geometrys for the MVD. Please use " "a .root geometry"; } else LOG(fatal) << "Geometry format of MVD file " << fileName.Data() << " not supported."; } // ----- Virtual public method ConstructAsciiGeometry ----------------------- void CbmMvd::ConstructAsciiGeometry() {} // ------------------------------------------------------------------------- // -------- Public method ConstructRootGeometry --------------------- void CbmMvd::ConstructRootGeometry(TGeoMatrix*) // added 05.05.14 by P. Sitzmann { FairDetector::ConstructRootGeometry(); fmvdHandler->Init(kTRUE); fmvdHandler->Fill(); fStationMap = fmvdHandler->GetMap(); if (fStationMap.size() == 0) LOG(fatal) << "Tried to load MVD Geometry, but didn't succeed to load Sensors"; LOG(debug) << "filled mvd StationMap with: " << fStationMap.size() << " new Sensors"; } // ------------------------------------------------------------------------- // ----- Private method AddHit -------------------------------------------- CbmMvdPoint* CbmMvd::AddHit(Int_t trackID, Int_t pdg, Int_t sensorNr, TVector3 posIn, TVector3 posOut, TVector3 momIn, TVector3 momOut, Double_t time, Double_t length, Double_t eLoss) { TClonesArray& clref = *fCollection; Int_t size = clref.GetEntriesFast(); LOG(debug2) << "CbmMvd: Adding Point at (" << posIn.X() << ", " << posIn.Y() << ", " << posIn.Z() << ") cm, sensor " << sensorNr << ", track " << trackID << ", energy loss " << eLoss * 1e06 << " keV"; return new (clref[size]) CbmMvdPoint(trackID, pdg, sensorNr, posIn, posOut, momIn, momOut, time, length, eLoss); } // ---------------------------------------------------------------------------- Bool_t CbmMvd::IsSensitive(const std::string& name) { TString tsname = name; if (tsname.Contains("sensorActive") || tsname.Contains("MimosaActive") || (tsname.Contains("mvdstation") && !(tsname.Contains("PartAss")))) { LOG(debug) << "*** Register " << tsname << " as active volume."; return kTRUE; } else if (tsname.EndsWith("-P0")) { // if(fVerboseLevel>1) LOG(debug) << "*** Register " << tsname << " as active volume."; return kTRUE; } return kFALSE; } Bool_t CbmMvd::CheckIfSensitive(std::string name) { return IsSensitive(name); } // ---------------------------------------------------------------------------- ClassImp(CbmMvd)