Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for TVirtualMCSensitiveDetector. #889

Draft
wants to merge 9 commits into
base: dev
Choose a base branch
from
46 changes: 22 additions & 24 deletions base/sim/FairDetector.cxx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
Expand Down Expand Up @@ -45,7 +45,10 @@ FairDetector::FairDetector(const FairDetector& rhs)
, fLogger(rhs.fLogger)
{}

FairDetector::~FairDetector() { delete flGeoPar; }
FairDetector::~FairDetector()
{
delete flGeoPar;
}

FairDetector& FairDetector::operator=(const FairDetector& rhs)
{
Expand All @@ -70,34 +73,12 @@ FairDetector::FairDetector()

// -------------------------------------------------------------------------

void FairDetector::DefineSensitiveVolumes()
{
LOG(info) << "FairDetector::DefineSensitiveVolumes";
TObjArray* volumes = gGeoManager->GetListOfVolumes();
TIter next(volumes);
TGeoVolume* volume;
while ((volume = static_cast<TGeoVolume*>(next()))) {
if (IsSensitive(volume->GetName())) {
LOG(debug) << "Sensitive Volume " << volume->GetName();
AddSensitiveVolume(volume);
}
}
}

// -------------------------------------------------------------------------

void FairDetector::Initialize()
{
// Registers hits collection in Root manager;
// sets sensitive volumes.
// ---

// Define sensitive volumes if in MT
if (gMC->IsMT()) {
std::cout << "Define sensitive volume " << std::endl;
DefineSensitiveVolumes();
}

Int_t NoOfEntries = svList->GetEntries();
Int_t fMCid;
FairGeoNode* fN;
Expand All @@ -124,6 +105,23 @@ void FairDetector::Initialize()
fMC = TVirtualMC::GetMC();
}

// -------------------------------------------------------------------------

void FairDetector::ProcessHits()
{
static const auto printOnce = [this] {
LOG(warning) << "Calling depracated Bool_t FairDetector::ProcessHits(FairVolume* vol = 0) for \"" << GetName()
<< "\".";
LOG(warning) << " Replace with void FairDetector::ProcessHits(). ";
Comment on lines +113 to +115
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused…

The message says not to call the method with (FairVolume* vol) and recommends to call the () one.
But this warning message is shown inside the () one?

What am I missing? I guess, I must have misunderstood something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, having looked at it again… Now I understand more!

Maybe rephrase to somethig like "Please override / implement ProcessHits on " << GetName() << " instead of the old ProcessHits(FairVolume*)".

return true;
}();
(void)printOnce;
ProcessHits(NULL);
return;
}

// -------------------------------------------------------------------------

void FairDetector::SaveGeoParams()
{
if (!fGeoSaved) {
Expand Down
12 changes: 7 additions & 5 deletions base/sim/FairDetector.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
Expand Down Expand Up @@ -45,9 +45,13 @@ class FairDetector : public FairModule
*/
virtual void Initialize();
/**
this method is called for each step during simulation (see FairMCApplication::Stepping())
this method is called for each step during simulation by the VMC
*/
virtual Bool_t ProcessHits(FairVolume* v = 0) = 0;
virtual void ProcessHits();
/**
DEPRACTED method, currently called by void FairDetector::ProcessHits()
*/
virtual Bool_t ProcessHits(FairVolume* v = 0) { return false; }
Comment on lines +51 to +54
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider Doxygen and C++ deprecation annotations?

Suggested change
/**
DEPRACTED method, currently called by void FairDetector::ProcessHits()
*/
virtual Bool_t ProcessHits(FairVolume* v = 0) { return false; }
/**
* \deprecated method, currently called by void FairDetector::ProcessHits()
*/
[[deprecated]] virtual Bool_t ProcessHits(FairVolume* v = 0) { return false; }

/**
this is called at the end of an event after the call to tree fill in the FairRootManager
*/
Expand Down Expand Up @@ -105,8 +109,6 @@ class FairDetector : public FairModule
/** Assignment operator */
FairDetector& operator=(const FairDetector&);

void DefineSensitiveVolumes();

Int_t fDetId; // Detector Id has to be set from ctr.
FairLogger* fLogger; //! /// FairLogger

Expand Down
114 changes: 45 additions & 69 deletions base/sim/FairMCApplication.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ FairMCApplication::FairMCApplication(const FairMCApplication& rhs, std::unique_p
auto& clone = fOwnedModules.emplace_back(module->CloneModule());
fListModules.emplace_back(clone.get());
fModules->Add(clone.get());
for (auto sens : rhs.fMapSensitiveDetectors) {
if (sens.second == module) {
fMapSensitiveDetectors[sens.first] = clone.get();
}
}
}

// Create and fill a list of active detectors
Expand Down Expand Up @@ -526,62 +531,6 @@ void FairMCApplication::Stepping()
TrackId = fMC->GetStack()->GetCurrentTrackNumber();
}

// Check if the volume with id is in the volume multimap.
// If it is not in the map the volume is not a sensitive volume
// and we do not call nay of our ProcessHits functions.

// If the volume is in the multimap, check in second step if the current
// copy is alredy inside the multimap.
// If the volume is not in the multimap add the copy of the volume to the
// multimap.
// In any case call the ProcessHits function for this specific detector.
Int_t copyNo;
Int_t id = fMC->CurrentVolID(copyNo);
auto voliter = fVolMap.find(id);

if (voliter != fVolMap.end()) {
Bool_t InMap = kFALSE;
FairVolume* disvol = nullptr;
FairDetector* disdet = nullptr;

// Call Process hits for FairVolume with this id, copyNo
do {
disvol = voliter->second;
if (copyNo == disvol->getCopyNo()) {
disdet = disvol->GetDetector();
if (disdet) {
disdet->ProcessHits(disvol);
}
InMap = kTRUE;
break;
}
++voliter;
} while (voliter != fVolMap.upper_bound(id));

// if (disvol && !InMap) { // fDisVolume is set previously, no check needed

// Create new FairVolume with this id, copyNo.
// Use the FairVolume with the same id found in the map to get
// the link to the detector.
// Seems that this never happens (?)
if (!InMap) {
// cout << "Volume not in map; disvol ? " << disvol << endl
FairVolume* fNewV = new FairVolume(fMC->CurrentVolName(), id);
fNewV->setMCid(id);
fNewV->setModId(disvol->getModId());
fNewV->SetModule(disvol->GetModule());
fNewV->setCopyNo(copyNo);
fVolMap.insert(pair<Int_t, FairVolume*>(id, fNewV));
disdet = disvol->GetDetector();

// LOG(info) << "FairMCApplication::Stepping: new fair volume"
// << id << " " << copyNo << " " << disdet;
if (disdet) {
disdet->ProcessHits(fNewV);
}
}
}

// If information about the tracks should be stored the information as to be
// stored for any step.
// Information about each single step has also to be stored for the other
Expand All @@ -599,7 +548,8 @@ void FairMCApplication::Stepping()
}
}
if (fRadLenMan || fRadMapMan) {
id = fMC->CurrentVolID(copyNo);
Int_t copyNo;
Int_t id = fMC->CurrentVolID(copyNo);
auto modvoliter = (fParent ? fParent : this)->fModVolMap.find(id);
if (fRadLenMan) {
fRadLenMan->AddPoint(fMC, modvoliter->second);
Expand Down Expand Up @@ -656,13 +606,10 @@ void FairMCApplication::StopMCRun()
}

//_____________________________________________________________________________
void FairMCApplication::FinishEvent()
void FairMCApplication::EndOfEvent()
{
// User actions after finishing of an event
// User actions just before finishing of an event
// ---
LOG(debug) << "[" << fRootManager->GetInstanceId()
<< " FairMCMCApplication::FinishEvent: " << fMCEventHeader->GetEventID() << " (MC "
<< gMC->CurrentEvent() << ")";
if (gMC->IsMT()
&& fRun->GetSink()->GetSinkType() == kONLINESINK) { // fix the rare case when running G4 multithreaded on MQ
fMCEventHeader->SetEventID(gMC->CurrentEvent() + 1);
Expand All @@ -680,18 +627,24 @@ void FairMCApplication::FinishEvent()
fFairTaskList->FinishEvent();
}

for (auto detectorPtr : listActiveDetectors) {
detectorPtr->FinishEvent();
}

if (fRootManager && fSaveCurrentEvent) {
fRootManager->Fill();
} else {
fSaveCurrentEvent = kTRUE;
}
}

//_____________________________________________________________________________
void FairMCApplication::FinishEvent()
{
// User actions after finishing of an event
// ---
LOG(debug) << "[" << fRootManager->GetInstanceId()
<< " FairMCMCApplication::FinishEvent: " << fMCEventHeader->GetEventID() << " (MC "
<< gMC->CurrentEvent() << ")";

for (auto detectorPtr : listActiveDetectors) {
detectorPtr->EndOfEvent();
detectorPtr->FinishEvent();
}

fStack->Reset();
Expand Down Expand Up @@ -983,7 +936,6 @@ void FairMCApplication::RegisterOutput()
if (detector) {
// check whether detector is active
if (detector->IsActive()) {
detector->Initialize();
detector->Register();
}
}
Expand Down Expand Up @@ -1338,4 +1290,28 @@ void FairMCApplication::UndoGeometryModifications()
gGeoManager->ClearPhysicalNodes(kFALSE);
}

ClassImp(FairMCApplication);
void FairMCApplication::ConstructSensitiveDetectors()
{
std::map<std::string, FairModule*> cloneVolumeMap;

for (auto const& x : fMapSensitiveDetectors) {
std::string volName = x.first; //.substr(0, x.first.find("#", 0));
ChristianTackeGSI marked this conversation as resolved.
Show resolved Hide resolved
if (volName.find('#') != std::string::npos) {
volName = volName.substr(0, volName.find("#", 0));
auto it = cloneVolumeMap.find(volName);
LOG(debug) << "FairMCApplication::ConstructSensitiveDetectors got clone " << x.first << " " << x.second;
if (it != cloneVolumeMap.end())
continue;
cloneVolumeMap[volName] = x.second;
LOG(debug) << "FairMCApplication::ConstructSensitiveDetectors really do " << volName;
}
LOG(debug) << "FairMCApplication::ConstructSensitiveDetectors really do " << volName;
TVirtualMC::GetMC()->SetSensitiveDetector(volName, x.second);
}
}

void FairMCApplication::AddSensitiveModule(std::string volName, FairModule* module)
ChristianTackeGSI marked this conversation as resolved.
Show resolved Hide resolved
{
fMapSensitiveDetectors[volName] = module;
}
ClassImp(FairMCApplication)
23 changes: 23 additions & 0 deletions base/sim/FairMCApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class FairRootManager;
class FairTask;
class FairTrajFilter;
class FairVolume;
class FairModule;
class FairRunSim;
class TChain;
class TIterator;
Expand Down Expand Up @@ -105,6 +106,12 @@ class FairMCApplication : public TVirtualMCApplication
Bool_t MisalignGeometry() override;
/** Define parameters for optical processes (optional) */
void ConstructOpGeometry() override; // MC Application

/** set sensitive detectors following TVirtualMCSensitiveDetector logic */
void ConstructSensitiveDetectors() override; // MC Application

/** Define actions just before sensitive->EndOfEvent */
void EndOfEvent() override; // MC Application
/** Define actions at the end of event */
void FinishEvent() override; // MC Application
/** Define actions at the end of primary track */
Expand Down Expand Up @@ -222,6 +229,11 @@ class FairMCApplication : public TVirtualMCApplication
*/
FairMCApplicationState GetState() const { return fState; }

/**
* Add module to the list of sensitive detectors.
*/
void AddSensitiveModule(std::string volName, FairModule* module);

/**
* Return non-owning pointer to FairRadGridManager
*/
Expand All @@ -232,6 +244,11 @@ class FairMCApplication : public TVirtualMCApplication
*/
auto GetIsMT() { return fMC ? fMC->IsMT() : false; }

/**
* Method introduced temporarily. It should go awway with DEPRACATED Bool_t FairDetector::ProcessHits()
*/
FairVolume* GetFairVolume();
Comment on lines +247 to +250
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using C++ deprecations?

Suggested change
/**
* Method introduced temporarily. It should go awway with DEPRACATED Bool_t FairDetector::ProcessHits()
*/
FairVolume* GetFairVolume();
/**
* \deprecate Method introduced temporarily. It should go awway with DEPRACATED Bool_t FairDetector::ProcessHits()
*/
[[deprecated]] FairVolume* GetFairVolume();

(And doxygen deprecations in addition?)


private:
// methods
Int_t GetIonPdg(Int_t z, Int_t a) const;
Expand Down Expand Up @@ -333,6 +350,12 @@ class FairMCApplication : public TVirtualMCApplication
*/
std::vector<FairModule*> fListModules{}; //!

/**
* List of sensitive detectors.
* To be used with TVirtualMCSensitiveDetector.
*/
std::map<std::string, FairModule*> fMapSensitiveDetectors;

/**
* Owned Modules (inside the worker)
*/
Expand Down
Loading