Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions Gate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* \brief To launch GATE:
* - 'Gate' or 'Gate --qt' using the Qt visualization
* - 'Gate your_macro.mac' or 'Gate --qt your_macro.mac' using the Qt visualization
* - 'Gate -d your_macro.mac' using the DigiGate
* - 'Gate your_macro.mac --d hits.root' for Offline Digitizer
* - 'Gate -a [activity,10]' using the parameterized macro creating an alias in your macro
*/

Expand Down Expand Up @@ -36,7 +36,7 @@
#include "GateOutputMgr.hh"
#include "GatePrimaryGeneratorAction.hh"
#include "GateUserActions.hh"
#include "GateDigitizer.hh"
#include "GateDigitizerMgr.hh"
#include "GateClock.hh"
#include "GateUIcontrolMessenger.hh"
#ifdef G4ANALYSIS_USE_ROOT
Expand Down Expand Up @@ -69,7 +69,9 @@ void printHelpAndQuit( G4String msg )
GateMessage( "Core", 0, " -h, --help print the help" << G4endl );
GateMessage( "Core", 0, " -v, --version print the version" << G4endl );
GateMessage( "Core", 0, " -a, --param set alias. format is '[alias1,value1] [alias2,value2] ...'" << G4endl );
GateMessage( "Core", 0, " --d use the DigiMode" << G4endl );
GateMessage( "Core", 0,
" --d FILE use Offline Digi mode with input ROOT file"
<< G4endl );
GateMessage( "Core", 0, " --qt use the Qt visualization mode" << G4endl );
exit( EXIT_FAILURE );
}
Expand Down Expand Up @@ -200,6 +202,7 @@ int main( int argc, char* argv[] )

// analyzing arguments
static G4int isDigiMode = 0; // DigiMode false by default
G4String digiInputFile = "";
static G4int isQt = 0; // Enable Qt or not
G4String listOfParameters = ""; // List of parameters for parameterized macro
DigiMode aDigiMode = kruntimeMode;
Expand All @@ -214,7 +217,7 @@ int main( int argc, char* argv[] )
static struct option longOptions[] = {
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'v' },
{ "d", no_argument, &isDigiMode, 1 },
{ "d", required_argument, 0, 'd' },
{ "qt", no_argument, &isQt, 1 },
{ "param", required_argument, 0, 'a' }
};
Expand Down Expand Up @@ -262,6 +265,10 @@ int main( int argc, char* argv[] )
case 'a':
listOfParameters = optarg;
break;
case 'd':
isDigiMode = 1;
digiInputFile = optarg;
break;
default:
printHelpAndQuit( "Out of switch options" );
break;
Expand All @@ -271,7 +278,19 @@ int main( int argc, char* argv[] )
// Checking if the DigiMode is activated
if( isDigiMode )
aDigiMode = kofflineMode;


if (isDigiMode)
{
if (digiInputFile.empty())
{
G4cerr << "Error: Offline Digi mode requires an input ROOT file.\n"
<< "Usage: Gate main.mac --d input.root\n";
return EXIT_FAILURE;
}

GateHitFileReader::GetInstance()->SetFileName(digiInputFile);
GateDigitizerMgr::GetInstance()->SetOfflineMode(true);
}
// Analyzing parameterized macro
std::queue< G4String > commandQueue = decodeParameters( listOfParameters );

Expand Down
17 changes: 16 additions & 1 deletion source/digits_hits/include/GateDigitizerMgr.hh
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,26 @@ public:
GateCoincidenceDigitizer* FindCoincidenceDigitizer(G4String mName);
/// End of methods for Coincidences


//Methods for OfflineDigi

void SetOfflineMode(bool b) { mOfflineMode = b; }
bool IsOfflineMode() const { return mOfflineMode; }

GateHitsCollection* GetOfflineHitsCollection();

void SetOfflineHitsCollection(GateHitsCollection* hc);
void ClearOfflineHitsCollection();




private:


GateDigitizerMgrMessenger *fMessenger;

GateHitsCollection* mOfflineHitsCollection = nullptr;
bool mOfflineMode = false;
static GateDigitizerMgr* theDigitizerMgr;

protected:
Expand Down
21 changes: 17 additions & 4 deletions source/digits_hits/include/GateHitFileReader.hh
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,21 @@ public:
virtual void Describe(size_t indent=0);


const std::vector<GateHit*>& GetHitVector() const
{
return m_hitVector;
}

std::vector<GateHit*>& GetHitVector()
{
return m_hitVector;
}

bool IsFinished() const
{
return m_finished;
}

protected:

//! Reads a set of hit data from the hit-tree, and stores them into the root-hit buffer
Expand All @@ -111,15 +126,13 @@ protected:
//!< The hit-data are loaded into this buffer by LoadHitData()
//!< They are then transformed into a crystal-hit by PrepareNextEvent()

std::queue<GateHit*> m_hitQueue; //!< Queue of waiting hits for the current event
//!< For each event, the queue is filled (from data read out of the hit-file) at
//!< the beginning of each event by PrepareNextEvent(). It is emptied into
//!< a crystal-hit collection at the end of each event by PrepareEndOfEvent()
std::vector<GateHit*> m_hitVector;

GateHitFileReaderMessenger *m_messenger; //!< Messenger;

private:
static GateHitFileReader* instance; //!< Instance of the GateHitFielReader singleton
bool m_finished;
};

#endif
Expand Down
2 changes: 2 additions & 0 deletions source/digits_hits/include/GateToRoot.hh
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public:
void RecordOpticalData(const G4Event *event);
// v. cuplov - optical photons

void SetOfflineOutputFileName();

void RecordVoxels(const G4Step *);

void BookBeginOfAquisition();
Expand Down
19 changes: 18 additions & 1 deletion source/digits_hits/src/GateDigitizerInitializationModule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "G4SDManager.hh"
#include "G4DigiManager.hh"
#include "G4ios.hh"
#include "GateDigitizerMgr.hh"

GateDigitizerInitializationModule::GateDigitizerInitializationModule(GateSinglesDigitizer *digitizer)
:GateVDigitizerModule("DigiInit","digitizerMgr/"+digitizer->GetSD()->GetName()+"/SinglesDigitizer/"+digitizer->m_digitizerName+"/digiInit",digitizer, digitizer->GetSD()),
Expand Down Expand Up @@ -65,7 +66,23 @@ void GateDigitizerInitializationModule::Digitize()
}


GateHitsCollection* inHC = (GateHitsCollection*) (DigiMan->GetHitsCollection(m_HCID));// DigiMan->GetHitsCollectionID(HCname)));
GateHitsCollection* inHC;
GateDigitizerMgr* digitizerMgr=GateDigitizerMgr::GetInstance();


if (GateDigitizerMgr::GetInstance()->IsOfflineMode() &&
digitizerMgr->GetOfflineHitsCollection() == nullptr)
{
GateMessage("OfflineDigi", 1,
"No offline hits, skipping digitization.");
return;
}


if (GateDigitizerMgr::GetInstance()->IsOfflineMode())
inHC = digitizerMgr->GetOfflineHitsCollection();
else
inHC = (GateHitsCollection*)DigiMan->GetHitsCollection(m_HCID);


if (inHC)
Expand Down
29 changes: 29 additions & 0 deletions source/digits_hits/src/GateDigitizerMgr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,35 @@ void GateDigitizerMgr::RunCoincidenceDigitizers()
//m_alreadyRun=true;
}


GateHitsCollection* GateDigitizerMgr::GetOfflineHitsCollection()
{

if (mOfflineHitsCollection)
return mOfflineHitsCollection;

}


void GateDigitizerMgr::SetOfflineHitsCollection(GateHitsCollection* hc)
{
if (mOfflineHitsCollection)
delete mOfflineHitsCollection;

mOfflineHitsCollection = hc;
}


void GateDigitizerMgr::ClearOfflineHitsCollection()
{
delete mOfflineHitsCollection;
mOfflineHitsCollection = nullptr;
}





void GateDigitizerMgr::ShowSummary()
{
G4cout<<"-----------------------"<<G4endl;
Expand Down
72 changes: 31 additions & 41 deletions source/digits_hits/src/GateHitFileReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ GateHitFileReader* GateHitFileReader::instance = 0;
// Private constructor: this function should only be called from GetInstance()
GateHitFileReader::GateHitFileReader()
: GateClockDependent("hitreader",false)
, m_fileName("gate")
, m_fileName("gate.root")
, m_hitFile(0)
, m_hitTree(0)
, m_entries(0)
, m_currentEntry(0)
, m_finished(false)
{
// Clear the root-hit structure
m_hitBuffer.Clear();
Expand Down Expand Up @@ -71,26 +72,24 @@ GateHitFileReader* GateHitFileReader::GetInstance()


// This method must be called (normally by the application manager) before starting a new DigiGate acquisition
// It opens the ROOT input file, sets up the hit tree, and loads the first series of hits
void GateHitFileReader::PrepareAcquisition()
{
m_finished = false;
// Open the input file
m_hitFile = new TFile((m_fileName+".root").c_str(),"READ");
if (!m_hitFile)
{
G4String msg = "Could not open the requested hit file '" + m_fileName + ".root'!";
G4Exception( "GateHitFileReader::PrepareBeforeAcquisition", "PrepareBeforeAcquisition", FatalException, msg );
}
if (!(m_hitFile->IsOpen()))
{
G4String msg = "Could not open the requested hit file '" + m_fileName + ".root'!";
G4Exception( "GateHitFileReader::PrepareBeforeAcquisition", "PrepareBeforeAcquisition", FatalException, msg );
}

m_hitFile = TFile::Open(m_fileName.c_str(), "READ");

if (!m_hitFile || m_hitFile->IsZombie())
{
G4String msg =
"Could not open hit file '" + m_fileName + "'";
G4Exception("GateHitFileReader::PrepareBeforeAcquisition", "PrepareBeforeAcquisition", FatalException, msg);
}
// Get the hit tree
m_hitTree = (TTree*)( m_hitFile->Get(GateHitConvertor::GetOutputAlias()) );
if (!m_hitTree)
{
G4String msg = "Could not find a tree of hits in the ROOT file '" + m_fileName + ".root'!";
G4String msg = "Could not find a tree of hits in the ROOT file '" + m_fileName + "'!";
G4Exception( "GateHitFileReader::PrepareBeforeAcquisition", "PrepareBeforeAcquisition", FatalException, msg);
}
// Reset the entry counters
Expand All @@ -103,6 +102,7 @@ void GateHitFileReader::PrepareAcquisition()

// Load the first hit into the root-hit structure
LoadHitData();

}


Expand All @@ -119,50 +119,41 @@ void GateHitFileReader::PrepareAcquisition()
*/
G4int GateHitFileReader::PrepareNextEvent(G4Event* )
{
G4cout << " GateHitFileReader::PrepareNextEvent\n";

for (auto hit : m_hitVector)
delete hit;

m_hitVector.clear();

// Store the current runID and eventID
G4int currentEventID = m_hitBuffer.eventID;
G4int currentRunID = m_hitBuffer.runID;

// We've reached the end-of-file
if ( (currentEventID==-1) && (currentRunID==-1) )
return 0;
{
m_finished = true;
return 0;
}

// Load the hits for the current event
// We loop until the data that have been read are found to be for a different event or run
while ( (currentEventID == m_hitBuffer.eventID) && (currentRunID == m_hitBuffer.runID) ) {

// Create a new hit and store it into the hit-queue
GateHit* aHit = m_hitBuffer.CreateHit();
m_hitQueue.push(aHit);
m_hitVector.push_back(aHit);

// Load the next set of hit-data into the root-hit structure
LoadHitData();
}

if (currentRunID==m_hitBuffer.runID){
// We got a set of hits for the current run -> return 1
return 1;
}
else
{
// We got a set of hits for a later run -> return 0
if (!m_hitVector.empty())
return 1;
return 0;
}
}


// This method is meant to be called by output manager before calling the methods RecordEndOfEvent() of the output modules.
// It creates a new hit-collection, based on the queue of hits previously filled by PrepareNextEvent()
void GateHitFileReader::PrepareEndOfEvent()
{
// We loop until the hit-queue is empty
// Each hit is inserted into the crystalSD hit-collection, then removed from the queue
while (m_hitQueue.size()) {
GateOutputMgr::GetInstance()->GetHitCollection()->insert(m_hitQueue.front());
m_hitQueue.pop();
}
}



Expand All @@ -176,11 +167,10 @@ void GateHitFileReader::TerminateAfterAcquisition()
m_hitFile=0;
}

// If the hit queue was not empty (it should be), clear it up
while (m_hitQueue.size()) {
delete m_hitQueue.front();
m_hitQueue.pop();
}
for (auto hit : m_hitVector)
delete hit;

m_hitVector.clear();

// Note that we don't delete the tree: it was based on the file so
// I assume it was destroyed at the same time as the file was closed (true?)
Expand Down
8 changes: 2 additions & 6 deletions source/digits_hits/src/GateOutputMgr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,11 @@ GateOutputMgr::GateOutputMgr(const G4String name)
}
#endif

if (m_digiMode==kruntimeMode) {

GateAnalysis* gateAnalysis = new GateAnalysis("analysis", this,m_digiMode);
AddOutputModule((GateVOutputModule*)gateAnalysis);

if (m_digiMode==kruntimeMode) {
GateMultiPhotonAnalysis* gateMultiPhotonAnalysis = new GateMultiPhotonAnalysis("multianalysis", this, m_digiMode);
AddOutputModule((GateVOutputModule*)gateMultiPhotonAnalysis);

Expand Down Expand Up @@ -195,11 +196,6 @@ void GateOutputMgr::RecordEndOfEvent(const G4Event* event)
{
GateMessage("Output", 5, "GateOutputMgr::RecordEndOfEvent\n";);

#ifdef G4ANALYSIS_USE_ROOT
if (m_digiMode==kofflineMode)
GateHitFileReader::GetInstance()->PrepareEndOfEvent();
#endif

for (size_t iMod=0; iMod<m_outputModules.size(); iMod++) {
if ( m_outputModules[iMod]->IsEnabled() )
{
Expand Down
Loading
Loading