6#include "FairRootManager.h"
8#include "FairRuntimeDb.h"
13#include "TVirtualMC.h"
23 LOG(debug4) <<
"BmnNdet default constructor called";
32 LOG(debug4) <<
"BmnNdet constructor called with name: " << name <<
" and active: " << active;
37 LOG(debug4) <<
"BmnNdet destructor called";
51 LOG(debug4) <<
"BmnNdet Initialize method called";
52 FairDetector::Initialize();
59 LOG(debug4) <<
"BmnNdet BeginEvent method called";
64 LOG(debug4) <<
"BmnNdet FindHitIndex method called for (trackID, address): (" << trackID <<
", " << address <<
")";
68 if (ThisPoint->GetTrackID() == trackID && ThisPoint->GetAddress() == address) {
87 LOG(debug4) <<
"GetBirkQCF function called";
88 const double BirkConst = 12.6;
89 double QCF = 1.0 + (BirkConst / gMC->TrackStep()) * gMC->Edep();
95 LOG(debug4) <<
"BmnNdet ProcessHits method called for event " << gMC->CurrentEvent();
96 Int_t trackID = gMC->GetStack()->GetCurrentTrackNumber();
99 if (gMC->IsTrackEntering()) {
100 LOG(debug4) <<
"BmnNdet::ProcessHits: vacuum" << gMC->CurrentVolName() <<
" " << gMC->CurrentVolPath();
102 gMC->TrackPosition(tPos);
103 gMC->TrackMomentum(tMom);
106 auto [planeId, direction] =
fGeoHandler->GetEnteredFace(pos, mom);
107 uint8_t armID =
fGeoHandler->GetArmFromPath(gMC->CurrentVolPath());
110 BmnNdetSurfacePoint(gMC->GetStack()->GetCurrentTrackNumber(), pos, mom, gMC->TrackTime() * 1.0e09,
111 gMC->TrackLength(), gMC->TrackPid(), gMC->CurrentEvent(), armID,
112 static_cast<uint8_t
>(planeId),
static_cast<uint8_t
>(direction));
123 uint32_t address =
fGeoHandler->GetAddressFromPath(gMC->CurrentVolPath());
126 if (
GetHit(trackID, address) ==
nullptr) {
128 <<
". Edep = " << gMC->Edep() <<
" Time = " << gMC->TrackTime() * 1.0e09;
129 if (!gMC->IsTrackEntering())
130 LOG(warning) <<
"trackID = " << trackID <<
" is not marked as gMC->IsTrackEntering() ";
134 newPoint->ResetLinks();
135 newPoint->SetEventID(gMC->CurrentEvent());
136 newPoint->SetTrackID(trackID);
139 gMC->TrackPosition(tPos);
140 gMC->TrackMomentum(tMom);
141 newPoint->SetPosition(
TVector3(tPos.
X(), tPos.
Y(), tPos.
Z()));
142 newPoint->SetMomentum(
TVector3(tMom.
X(), tMom.
Y(), tMom.
Z()));
144 double dEdep = (gMC->TrackCharge() != 0 && gMC->TrackStep() > 0) ? gMC->Edep() /
GetBirkQCF()
146 newPoint->SetEnergyLoss(dEdep);
147 newPoint->SetTime(gMC->TrackTime() * 1.0e09);
148 newPoint->SetLength(gMC->TrackLength());
153 double dEdep = (gMC->TrackCharge() != 0 && gMC->TrackStep() > 0) ? gMC->Edep() /
GetBirkQCF()
155 if (dEdep > std::numeric_limits<double>::epsilon()) {
156 LOG(debug4) <<
"BmnNdet::ProcessHits. trackID = " << trackID <<
" inside or exiting. "
158 <<
" Time = " << gMC->TrackTime() * 1.0e09;
161 double weighted_time = point->GetEnergyLoss() * point->GetTime() + dEdep * gMC->TrackTime() * 1.0e09;
162 point->SetEnergyLoss(point->GetEnergyLoss() + dEdep);
163 point->SetTime(weighted_time / point->GetEnergyLoss());
170 if (gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()) {
187 if (point->GetEnergyLoss() < std::numeric_limits<double>::epsilon()) {
188 LOG(debug4) <<
"BmnNdet ProcessHits: remove hit. trackID = " << point->GetTrackID() <<
" "
199 LOG(debug4) <<
"BmnNdet EndOfEvent method called";
206 LOG(debug4) <<
"BmnNdet Register method called";
207 if (!FairRootManager::Instance()->GetObject(
"NdetPoint")) {
208 FairRootManager::Instance()->Register(
"NdetPoint",
"Ndet",
fCollection,
kTRUE);
211 LOG(debug4) <<
"NdetPoint Already registered";
216 LOG(debug4) <<
"BmnNdet GetCollection iColl=" << iColl;
226 LOG(debug4) <<
"BmnNdet Print method called";
228 std::cout <<
"-I- BmnNdet: " << nHits <<
" points registered in event " << gMC->CurrentEvent() << std::endl;
230 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug4)) {
232 (*fCollection)[
i]->Print();
239 LOG(debug4) <<
"BmnNdet Reset method called";
246 LOG(debug4) <<
"BmnNdet ConstructGeometry method called";
247 TString fileName = GetGeometryFileName();
249 LOG(info) <<
Form(
"Constructing NDET geometry from ROOT file %s", fileName.
Data());
250 ConstructRootGeometry();
253 FairGeoLoader* geoLoad = FairGeoLoader::Instance();
254 FairGeoInterface* geoFace = geoLoad->getGeoInterface();
264 FairRun* fRun = FairRun::Instance();
265 FairRuntimeDb* rtdb = fRun->GetRuntimeDb();
271 FairGeoNode* node =
nullptr;
273 while ((node = (FairGeoNode*)iter.
Next())) {
274 FairGeoVolume* aVol =
dynamic_cast<FairGeoVolume*
>(node);
275 if (node->isSensitive()) {
277 LOG(debug4) <<
"BmnNdet ConstructGeometry add sensitive node " << aVol->GetName();
280 LOG(debug4) <<
"BmnNdet ConstructGeometry add passive node " << aVol->GetName();
284 par->setInputVersion(fRun->GetRunId(), 1);
286 ProcessNodes(volList);
291 LOG(debug4) <<
"BmnNdet CheckIfSensitive method called with name: " << name;
299 return gMC->CurrentMedium() ==
gGeoManager->GetMedium(
"vacuum")->GetId();
311 if (index < 0 || index >=
fCollection->GetEntriesFast()) {
312 LOG(debug4) <<
"BmnNdet RemoveHit method index: " << index <<
" out of range.";
321 const auto* stack =
static_cast<CbmStack*
>(gMC->GetStack());
322 int current_id = start_track_id;
324 std::unordered_map<int, int> vacuum_map;
328 vacuum_map[
i] = pt->GetTrackID();
332 const TParticle* particle = stack->GetParticle(current_id);
334 LOG(error) <<
"BmnNdet::GetSurfacePoint. No particle with ID: " << current_id;
338 for (
const auto& [ipt, vac_track] : vacuum_map) {
339 if (vac_track == current_id) {
340 LOG(debug4) <<
"BmnNdet::GetSurfacePoint. Linked to " << vac_track;
346 LOG(debug4) <<
Form(
"BmnNdet::GetSurfacePoint. Reached primary particle %d, no vacuum point found",
352 if (mother_id == current_id || mother_id < 0) {
353 LOG(error) <<
Form(
"BmnNdet::GetSurfacePoint. Invalid or circular mother link for track %d", current_id);
357 current_id = mother_id;
R__EXTERN TGeoManager * gGeoManager
char * Form(const char *fmt,...)
static std::string GetInfoString(uint32_t address)
Return a formatted string with all address components.
TObjArray * GetGeoSensitiveNodes()
TObjArray * GetGeoPassiveNodes()
static const TString SensitiveVolume_name_VETO
static const TString fEnvelopeVolumeName
static const TString SensitiveVolume_name_NICA
uint32_t GetAddress() const
void SetAddress(uint32_t address)
virtual Bool_t ProcessHits(FairVolume *vol=nullptr)
Processes hits and creates BmnNdetPoints.
virtual ~BmnNdet()
Destructor.
Int_t FindHitIndex(int trackID, uint32_t address)
Retrieves the hit index corresponding to a specific address and trackID.
virtual void EndOfEvent()
Called at the end of each event.
BmnNdet()
Default constructor.
BmnNdetPoint * AddHit(BmnNdetPoint *point)
Adds the hit to hits collection.
virtual TClonesArray * GetCollection(Int_t iColl) const
Accessor to the hit collection.
virtual Bool_t CheckIfVacuum()
Checks whether current volume is vacuum.
virtual Bool_t CheckIfSensitive(std::string name)
Checks whether a volume is sensitive based on its name.
bool FinaliseTrackProcessing(BmnNdetPoint *point)
Removes zero-energy hits.
virtual void ConstructGeometry()
Constructs geometry from files.
virtual void Reset()
Clears the hit collection.
virtual void Register()
Registers the hit collection in the ROOT manager.
int GetSurfacePoint(int start_track_id)
Returns index of surface point.
void RemoveHit(Int_t index)
Remove hit from hits collection by index.
BmnNdetPoint * GetHit(int trackID, uint32_t address)
Retrieves the hit corresponding to a specific address and trackID.
virtual void Initialize()
Initialises detector and FairRun.
TClonesArray * fSurfaceCollection
TClonesArray * fCollection
virtual void BeginEvent()
Called at the beginning of each event.
virtual void Print(Option_t *) const
Screen output of hit collection.
TObject * Next() override
Int_t GetEntriesFast() const
void AddLast(TObject *obj) override
Int_t GetFirstMother() const
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
const char * Data() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const