82 LOG(debug4) <<
"BmnFHCal ProcessHits method called for event " << gMC->CurrentEvent();
89 LOG(debug4) <<
"BmnFHCal::ProcessHits. trackID = " << gMC->GetStack()->GetCurrentTrackNumber() <<
" "
91 <<
". Edep = " << gMC->Edep() <<
" Time = " << gMC->TrackTime() * 1.0e09;
93 if (gMC->IsTrackEntering() || !fPoint) {
95 fPoint->SetEventID(gMC->CurrentEvent());
96 fPoint->SetAddress(fGeoHandler->GetAddressFromPath(gMC->CurrentVolPath()));
97 TLorentzVector tPos, tMom;
98 gMC->TrackPosition(tPos);
99 gMC->TrackMomentum(tMom);
100 fPoint->SetPosition(tPos.Vect());
101 fPoint->SetMomentum(tMom.Vect());
102 fPoint->SetEnergyLoss(CalculateEnergyLoss(gMC->TrackStep(), gMC->Edep()));
103 fPoint->SetTime(gMC->TrackTime() * 1.0e09);
104 fPoint->SetLength(gMC->TrackLength());
108 assert(fPoint->GetAddress() == fGeoHandler->GetAddressFromPath(gMC->CurrentVolPath()));
109 double dEdep = CalculateEnergyLoss(gMC->TrackStep(), gMC->Edep());
110 double weighted_time = fPoint->GetEnergyLoss() * fPoint->GetTime() + dEdep * gMC->TrackTime() * 1.0e09;
111 fPoint->SetEnergyLoss(fPoint->GetEnergyLoss() + dEdep);
112 if (fPoint->GetEnergyLoss() > 0.)
113 fPoint->SetTime(weighted_time / fPoint->GetEnergyLoss());
115 if (gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()) {
116 if (fPoint->GetEnergyLoss() > std::numeric_limits<double>::epsilon()) {
118 if (surface_track >= 0) {
119 fPoint->SetTrackID(surface_track);
120 fMultiLinkMap[fPoint->GetAddress()].AddLink(
121 FairLink(
"MCTrack", surface_track, fPoint->GetEnergyLoss()));
124 auto* existing =
GetHit(fPoint->GetAddress());
151 LOG(debug3) <<
"BmnFHCal GetCollection method called with iColl: " << iColl;
152 for (Int_t
i = 0;
i < fCollection->GetEntriesFast();
i++) {
154 hit->SetEntryNr(FairLink(
"FHCalPoint",
i, hit->GetEnergyLoss()));
156 if (fMultiLinkMap.find(address) != fMultiLinkMap.end()) {
157 hit->SetLinks(fMultiLinkMap.at(address));
158 LOG(debug3) <<
"BmnFHCal::GetCollection Links: " << hit->GetNLinks();
159 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug3) && hit->GetNLinks()) {
160 hit->PrintLinkInfo();
165 return (iColl == 0) ? fCollection :
nullptr;
190 TString fileName = GetGeometryFileName();
191 if (fileName.EndsWith(
".root")) {
192 LOG(info) <<
"Constructing FHCal geometry from ROOT file %s" << fileName.Data();
193 ConstructRootGeometry();
196 FairGeoLoader* geoLoad = FairGeoLoader::Instance();
197 FairGeoInterface* geoFace = geoLoad->getGeoInterface();
198 fGeoHandler->setGeomFile(GetGeometryFileName());
199 geoFace->addGeoModule(fGeoHandler.get());
201 Bool_t rc = geoFace->readSet(fGeoHandler.get());
203 fGeoHandler->create(geoLoad->getGeoBuilder());
204 TList* volList = fGeoHandler->getListOfVolumes();
207 FairRun* fRun = FairRun::Instance();
208 FairRuntimeDb* rtdb = FairRun::Instance()->GetRuntimeDb();
213 TListIter iter(volList);
214 FairGeoNode* node = NULL;
215 FairGeoVolume* aVol = NULL;
216 while ((node = (FairGeoNode*)iter.Next())) {
217 aVol =
dynamic_cast<FairGeoVolume*
>(node);
218 if (node->isSensitive()) {
219 fSensNodes->AddLast(aVol);
221 fPassNodes->AddLast(aVol);
225 par->setInputVersion(fRun->GetRunId(), 1);
227 ProcessNodes(volList);
246 LOG(debug4) <<
"UpdateHit: Updating hit at address " << existing.
GetAddress()
247 <<
" with current E_loss = " << existing.GetEnergyLoss()
248 <<
" update E_loss += " << update.GetEnergyLoss();
250 const double eloss_existing = existing.GetEnergyLoss();
251 const double eloss_update = update.GetEnergyLoss();
252 const double eloss_total = eloss_existing + eloss_update;
254 if (eloss_total == 0)
257 const double weight_existing = eloss_existing / eloss_total;
258 const double weight_update = eloss_update / eloss_total;
260 TVector3 pos_existing, mom_existing;
261 existing.Position(pos_existing);
262 existing.Momentum(mom_existing);
264 TVector3 pos_update, mom_update;
265 update.Position(pos_update);
266 update.Momentum(mom_update);
268 existing.SetPosition(weight_existing * pos_existing + weight_update * pos_update);
269 existing.SetMomentum(weight_existing * mom_existing + weight_update * mom_update);
270 existing.SetTime(weight_existing * existing.GetTime() + weight_update * update.GetTime());
271 existing.SetLength(weight_existing * existing.GetLength() + weight_update * update.GetLength());
272 if (weight_update > weight_existing)
273 existing.SetTrackID(update.GetTrackID());
274 existing.SetEnergyLoss(eloss_total);
279 int current_id = start_track_id;
280 TParticle* current = ((
CbmStack*)gMC->GetStack())->GetParticle(current_id);
282 if (current->IsPrimary()) {
283 LOG(debug4) << Form(
"BmnFHCal::GetSurfaceMCTrack. Current particle %d is primary", current_id);
286 int mother_id = current->GetFirstMother();
287 TParticle* mother = ((
CbmStack*)gMC->GetStack())->GetParticle(mother_id);
289 LOG(error) << Form(
"BmnFHCal::GetSurfaceMCTrack. Current track with id %d has mother but it is "
290 "not stored in MC stack",
294 if (mother_id == current_id) {
295 LOG(error) <<
"BmnFHCal::GetSurfaceMCTrack. Infinite loop detected for track ID: " << current_id;
299 TVector3 current_vtx(current->Vx(), current->Vy(), current->Vz());
300 TVector3 mother_vtx(mother->Vx(), mother->Vy(), mother->Vz());
301 if (fGeoHandler->IsPointInside(current_vtx) && !fGeoHandler->IsPointInside(mother_vtx))
303 LOG(debug4) << Form(
"BmnFHCal::GetSurfaceMCTrack. Current track with id %d has vtx (%.2f %.2f "
304 "%.2f) inside detector. Its mother %d vtx (%.2f %.2f %.2f) is outside",
305 current_id, current_vtx.X(), current_vtx.Y(), current_vtx.Z(), mother_id,
306 mother_vtx.X(), mother_vtx.Y(), mother_vtx.Z());
310 current_id = mother_id;