34#include "TInterpreter.h"
35#include "TGHtmlBrowser.h"
63 : TRint(appClassName, &fFakeArgc, argv, nullptr, 0, noLogo), fKeepAliveTimer(nullptr),
64 main_thread_id(std::this_thread::get_id()), fIsTabComplete(false), fAllowedToTerminate(true), fRootFilesOpened(0),
70 GetSignalHandler()->Remove();
72 interruptHandler->Add();
84 SetPrompt(
"GRSI [%d] ");
85 std::string grsipath = getenv(
"GRSISYS");
86 gInterpreter->AddIncludePath(Form(
"%s/include", grsipath.c_str()));
119 }
catch(std::runtime_error& e) {
134 for(
const auto& rawFile : opt->
InputFiles()) {
158 int exit_status = missing_raw_file ? 1 : 0;
168 std::this_thread::sleep_for(std::chrono::seconds(1));
174 gSystem->ProcessEvents();
183 std::cout << std::endl;
189 return TRint::HandleTermInput();
197 std::cout <<
"Not allowed to terminate, sorry!" << std::endl;
209 if((clock() % 60) == 0) {
210 std::cout <<
"DING!" << std::flush;
212 std::cout <<
"\r \r" << std::flush;
215 TSeqCollection* canvases = gROOT->GetListOfCanvases();
216 while(canvases->GetEntries() > 0) {
217 static_cast<GCanvas*
>(canvases->At(0))->Close();
233 TRint::Terminate(status);
240 auto result = TRint::TabCompletionHook(buf, pLoc, out);
254 Long_t res = TRint::ProcessLine(inputLine, sync, error);
259 std::string line(inputLine);
261 while((pos = line.find(
"TCanvas", pos)) != std::string::npos) {
269 return TRint::ProcessLine(line.c_str(), sync, error);
276 gROOT->ProcessLine(
".! open http://en.wikipedia.org/wiki/Special:Random > /dev/null 2>&1;");
278 gROOT->ProcessLine(
".! xdg-open http://en.wikipedia.org/wiki/Special:Random > /dev/null 2>&1;");
288 const unsigned int reflength = ref.length() - 78;
290 const std::string& ref =
"Sorting Program for Online and Offline Nuclear Data";
291 const unsigned int reflength = 53;
294 const unsigned int width = reflength + (reflength % 2);
295 printf(
"\t*%s*\n", std::string(width,
'*').c_str());
296 printf(
"\t*%*s%*s*\n", width / 2 + 4,
"GRSI Sort", width / 2 - 4,
"");
297 printf(
"\t*%*s%*s*\n", width / 2 + 12,
"a remake of GRSI SPOON", width / 2 - 12,
"");
298 printf(
"\t*%*s%*s*\n", width / 2 + reflength / 2, ref.c_str(), width / 2 - reflength / 2,
"");
299 printf(
"\t*%*s%*s*\n", width / 2 + 14,
"A lean, mean sorting machine", width / 2 - 14,
"");
300 printf(
"\t*%*s%*s*\n", width / 2 + 9,
"version " GRSI_RELEASE, width / 2 - 9,
"");
301 printf(
"\t*%s*\n", std::string(width,
'*').c_str());
303 std::cout <<
"\tgrsisort version " << GRSI_RELEASE << std::endl;
316 TFile* file =
nullptr;
317 if(sopt.Contains(
"recreate") || sopt.Contains(
"new")) {
319 file =
new TFile(filename.c_str(),
"RECREATE");
320 if(file !=
nullptr && file->IsOpen()) {
322 const char* command = Form(
"TFile* _file%i = (TFile*)%luL;",
fRootFilesOpened,
reinterpret_cast<unsigned long>(file));
323 TRint::ProcessLine(command);
326 std::cout <<
"Could not create " << filename << std::endl;
330 file =
new TFile(filename.c_str(), opt);
331 if(file !=
nullptr && file->IsOpen()) {
333 const char* command = Form(
"TFile* _file%i = (TFile*)%luL;",
fRootFilesOpened,
reinterpret_cast<unsigned long>(file));
334 TRint::ProcessLine(command);
335 std::cout <<
"\tfile " <<
BLUE << file->GetName() <<
RESET_COLOR <<
" opened as " <<
BLUE <<
"_file"
339 if(file->FindObjectAny(
"FragmentTree") !=
nullptr) {
345 std::cout <<
"file " << file->GetName() <<
" added to gFragment." << std::endl;
346 gFragment->AddFile(file->GetName(), TTree::kMaxEntries,
"FragmentTree");
350 if(file->FindObjectAny(
"AnalysisTree") !=
nullptr) {
356 std::cout <<
"file " << file->GetName() <<
" added to gAnalysis." << std::endl;
357 gAnalysis->AddFile(file->GetName(), TTree::kMaxEntries,
"AnalysisTree");
360 if(file->FindObjectAny(
"Channel") !=
nullptr) {
364 if(file->FindObjectAny(
"Values") !=
nullptr) {
369 std::cout <<
"Could not open " << filename << std::endl;
383 std::cerr << R
"(File ")" << filename << R"(" does not exist)" << std::endl;
392 if(file !=
nullptr) {
393 const char* command = Form(
"TRawFile* _raw%i = (TRawFile*)%luL;",
fRawFilesOpened,
reinterpret_cast<unsigned long>(file));
396 std::cout <<
"\tfile " <<
BLUE << filename <<
RESET_COLOR <<
" opened as "
401 }
catch(std::runtime_error& e) {
402 std::cout << e.what();
417 bool missingRawFile =
false;
418 for(
const auto& filename : opt->
InputFiles()) {
420 missingRawFile =
true;
421 std::cerr <<
"File not found: " << filename << std::endl;
427 bool hasInputFragmentTree =
gFragment !=
nullptr;
428 bool hasInputAnalysisTree =
gAnalysis !=
nullptr;
431 bool ableToWriteFragmentHistograms = ((hasRawFile || hasInputFragmentTree) && !opt->
FragmentHistogramLib().empty());
432 bool ableToWriteFragmentTree = (hasRawFile && !missingRawFile);
433 bool ableToWriteAnalysisHistograms = ((hasRawFile || hasInputFragmentTree || hasInputAnalysisTree) &&
435 bool ableToWriteAnalysisTree = (ableToWriteFragmentTree || hasInputFragmentTree);
438 bool writeFragmentHistograms = (ableToWriteFragmentHistograms && opt->
MakeHistos());
440 bool writeAnalysisHistograms = (ableToWriteAnalysisHistograms && opt->
MakeHistos());
441 bool writeAnalysisTree = (ableToWriteAnalysisTree && opt->
MakeAnalysisTree());
446 bool readFromRaw = (hasRawFile && (writeFragmentHistograms || writeFragmentTree ||
447 writeAnalysisHistograms || writeAnalysisTree));
449 bool readFromFragmentTree = (hasInputFragmentTree && (writeFragmentHistograms || writeAnalysisHistograms || writeAnalysisTree));
451 bool generateAnalysisData = ((readFromRaw || readFromFragmentTree) && (writeAnalysisHistograms || writeAnalysisTree));
453 bool readFromAnalysisTree = (hasInputAnalysisTree && (writeAnalysisHistograms || writeAnalysisTree) && !generateAnalysisData);
457 int subRunNumber = 0;
459 runNumber =
fRawFiles[0]->GetRunNumber();
460 subRunNumber =
fRawFiles[0]->GetSubRunNumber();
461 }
else if(readFromFragmentTree) {
462 const auto* run_title =
gFragment->GetListOfFiles()->At(0)->GetTitle();
465 }
else if(readFromAnalysisTree) {
466 const auto* run_title =
gAnalysis->GetListOfFiles()->At(0)->GetTitle();
473 if(outputFragmentTreeFilename.empty()) {
474 if(subRunNumber == -1) {
475 outputFragmentTreeFilename = Form(
"fragment%05i.root", runNumber);
477 outputFragmentTreeFilename = Form(
"fragment%05i_%03i.root", runNumber, subRunNumber);
482 if(outputFragmentHistFilename.empty()) {
483 if(subRunNumber == -1) {
484 outputFragmentHistFilename = Form(
"hist_fragment%05i.root", runNumber);
486 outputFragmentHistFilename = Form(
"hist_fragment%05i_%03i.root", runNumber, subRunNumber);
491 if(outputDiagnosticsFilename.empty()) {
492 if(subRunNumber == -1) {
493 outputDiagnosticsFilename = Form(
"diagnostics%05i.root", runNumber);
495 outputDiagnosticsFilename = Form(
"diagnostics%05i_%03i.root", runNumber, subRunNumber);
500 if(outputAnalysisTreeFilename.empty()) {
501 if(subRunNumber == -1) {
503 outputAnalysisTreeFilename = Form(
"rntuple%05i.root", runNumber);
505 outputAnalysisTreeFilename = Form(
"analysis%05i.root", runNumber);
509 outputAnalysisTreeFilename = Form(
"rntuple%05i_%03i.root", runNumber, subRunNumber);
511 outputAnalysisTreeFilename = Form(
"analysis%05i_%03i.root", runNumber, subRunNumber);
517 if(output_analysis_hist_filename.empty()) {
518 if(subRunNumber == -1) {
519 output_analysis_hist_filename = Form(
"hist_analysis%05i.root", runNumber);
521 output_analysis_hist_filename = Form(
"hist_analysis%05i_%03i.root", runNumber, subRunNumber);
525 if(readFromAnalysisTree) {
526 std::cerr <<
"Reading from analysis tree not currently supported" << std::endl;
533 if(!writeFragmentHistograms && !writeFragmentTree && !writeAnalysisHistograms && !writeAnalysisTree) {
551 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<const TFragment>>>> fragmentQueues;
552 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<TEpicsFrag>>>> scalerQueues;
553 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<TUnpackedEvent>>>> analysisQueues;
565 std::cerr <<
"I'm going to ignore all but first .mid" << std::endl;
576 if(readFromFragmentTree) {
606 std::cout <<
"no detector information, can't set build mode" << std::endl;
610 if(writeFragmentHistograms) {
613 if(unpackLoop !=
nullptr) {
616 if(fragmentChainLoop !=
nullptr) {
623 if(writeFragmentTree) {
626 if(unpackLoop !=
nullptr) {
632 if(fragmentChainLoop !=
nullptr) {
639 if(unpackLoop !=
nullptr) {
642 if(fragmentChainLoop !=
nullptr) {
649 if(generateAnalysisData) {
653 if(unpackLoop !=
nullptr) {
656 if(fragmentChainLoop !=
nullptr) {
659 fragmentQueues.push_back(eventBuildingLoop->
InputQueue());
666 if(writeAnalysisHistograms) {
669 if(detBuildingLoop !=
nullptr) {
672 std::cerr <<
DRED <<
"Error, writing analysis histograms is enabled, but no detector building loop was found!"
681 if(writeAnalysisTree) {
687 analysisQueues.push_back(loop->InputQueue());
697 const char* command = Form(
".x %s", filename.c_str());
701 size_t beginning_pos = filename.find_first_of(
'(');
702 if(beginning_pos != std::string::npos && filename.back() ==
')') {
703 std::string trueFilename = filename.substr(0, beginning_pos);
704 std::string arguments = filename.substr(beginning_pos, std::string::npos);
706 const char* command = Form(
".L %s", trueFilename.c_str());
708 command = Form(
"%s%s", trueFilename.substr(0, filename.find_first_of(
'.')).c_str(), arguments.c_str());
711 std::cerr << R
"(File ")" << trueFilename << R"(" does not exist)" << std::endl;
714 std::cerr << R
"(File ")" << filename << R"(" does not exist)" << std::endl;
722 if(gROOT->IsBatch()) {
726 gROOT->LoadClass(
"TCanvas",
"Gpad");
735 new TGHtmlBrowser(gSystem->ExpandPathName(
"${GRSISYS}/README.html"));
744 std::cout << std::endl
748 static int timesPressed = 0;
750 switch(timesPressed) {
752 std::cout << std::endl
757 std::cout << std::endl
762 std::cout << std::endl
790 std::lock_guard<std::mutex> any_command_lock(g__CommandWaitingMutex);
792 g__LineToProcess = std::move(command);
793 g__CommandFinished =
false;
794 g__ProcessingNeeded =
true;
795 TTimer::SingleShot(0,
"TGRSIint",
this,
"DelayedProcessLine_Action()");
797 std::unique_lock<std::mutex> lock(g__ResultListMutex);
798 while(!g__CommandFinished) {
799 g__NewResult.wait(lock);
802 return g__CommandResult;
809 std::lock_guard<std::mutex> lock(g__CommandListMutex);
810 if(!g__ProcessingNeeded) {
813 message = g__LineToProcess;
817 Getlinem(EGetLineMode::kInit, (
static_cast<TRint*
>(gApplication))->GetPrompt());
820 std::lock_guard<std::mutex> lock(g__ResultListMutex);
821 g__CommandResult = result;
822 g__CommandFinished =
true;
823 g__ProcessingNeeded =
false;
826 g__NewResult.notify_one();
void AddFileToGUI(TFile *file)
const std::string & ProgramName()
int GetRunNumber(const std::string &)
bool FileExists(const char *filename)
bool AllFilesExist(const std::vector< std::string > &filenames)
int GetSubRunNumber(const std::string &)
static int ReadValFile(const char *filename="", Option_t *opt="replace")
static void ClearAllQueues()
static std::string AllThreadStatus()
static size_t StatusWidth()
static std::string AllThreadProgress()
static std::string AllThreadHeader()
static bool AnyThreadRunning()
static size_t ColumnWidth()
void SetOutputFilename(const std::string &name)
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< TUnpackedEvent > > > & InputQueue()
static TAnalysisHistLoop * Get(std::string name="")
void Print(Option_t *opt="") const override
static TAnalysisWriteLoop * Get(std::string name="", std::string outputFilename="")
static void DeleteAllChannels()
static Int_t ReadCalFile(std::ifstream &infile)
static TDataLoop * Get(std::string name="", TRawFile *source=nullptr)
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< TRawEvent > > > & OutputQueue()
void SetSelfStopping(bool self_stopping)
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< TUnpackedEvent > > > & AddOutputQueue(size_t maxSize=50000)
std::shared_ptr< ThreadsafeQueue< std::vector< std::shared_ptr< const TFragment > > > > & InputQueue()
static TDetBuildingLoop * Get(std::string name="")
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > & OutOfOrderQueue()
std::shared_ptr< ThreadsafeQueue< std::vector< std::shared_ptr< const TFragment > > > > & OutputQueue()
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > & InputQueue()
static TEventBuildingLoop * Get(std::string name="", EBuildMode mode=EBuildMode::kTimestamp, uint64_t buildWindow=2000)
void SetSortDepth(unsigned int val)
static TFragDiagnosticsLoop * Get(std::string name="", std::string fOutputFilename="")
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > & InputQueue()
static TFragHistLoop * Get(std::string name="")
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > & InputQueue()
void SetOutputFilename(const std::string &name)
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TBadFragment > > > & BadInputQueue()
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > & InputQueue()
static TFragWriteLoop * Get(std::string name="", std::string fOutputFilename="")
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< TEpicsFrag > > > & ScalerInputQueue()
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > & AddOutputQueue()
void SetSelfStopping(bool self_stopping)
static TFragmentChainLoop * Get(std::string name="", TChain *chain=nullptr)
const std::vector< std::string > & RootInputFiles() const
bool MakeAnalysisTree() const
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!
bool WriteFragmentTree() const
const std::vector< std::string > & InputFiles() const
const std::string & OutputFragmentHistogramFile() const
const std::vector< std::string > & ExternalRunInfo() const
bool CreateFragmentDiagnostics() const
std::string AnalysisHistogramLib() const
const std::string & OutputAnalysisHistogramFile() const
static TAnalysisOptions * AnalysisOptions()
const std::vector< std::string > & ValInputFiles() const
bool CloseAfterSort() const
const std::vector< std::string > & CalInputFiles() const
const std::string & OutputDiagnosticsFile() const
bool ReadingMaterial() const
void ParserLibrary(std::string &library)
const std::vector< std::string > & MacroInputFiles() const
std::string FragmentHistogramLib() const
const std::string & OutputFragmentFile() const
const std::string & OutputAnalysisFile() const
TRawFile * OpenRawFile(const std::string &filename)
int TabCompletionHook(char *, int *, std::ostream &) override
static void PrintHelp(bool)
int fRawFilesOpened
Number of Raw Files opened.
Long_t DelayedProcessLine(std::string command)
std::thread::id main_thread_id
Main sorting thread id.
TGRSIint(int argc, char **argv, void *options=nullptr, int numOptions=0, bool noLogo=false, const char *appClassName="grsisort")
static TGRSIint * fTGRSIint
Static pointer (singleton)
TFile * OpenRootFile(const std::string &filename, Option_t *opt="read")
std::vector< TRawFile * > fRawFiles
List of Raw files opened.
static void LoadGROOTGraphics()
void DelayedProcessLine_Action()
std::string fNewFragmentFile
New fragment file name.
void RunMacroFile(const std::string &filename)
bool fAllowedToTerminate
Flag for shutting down GRSISort.
static TGRSIint * instance(int argc=0, char **argv=nullptr, void *options=nullptr, int numOptions=-1, bool noLogo=false, const char *appClassName="grsisort")
bool fIsTabComplete
Flag for tab completion hook.
int fRootFilesOpened
Number of ROOT files opened.
static TEnv * fGRSIEnv
GRSI environment.
void PrintLogo(bool) override
Long_t ProcessLine(const char *line, Bool_t sync=kFALSE, Int_t *error=nullptr) override
void Terminate(Int_t status=0) override
bool HandleTermInput() override
void Load(bool quiet=false)
if necessary loads shared object library and sets/initializes all other functions
void DestroyRawFile(TRawFile *file)
TRawFile * CreateRawFile(const std::string &file)
static void ClearVersion()
static void SetDate(const char *ver)
static void SetFullVersion(const char *ver)
static Bool_t ReadInfoFile(const char *filename="")
static void ClearFullVersion()
static void SetRunInfo(int runnum=0, int subrunnum=-1)
static void SetVersion(const char *ver)
static Bool_t ReadInfoFromFile(TFile *tempf=nullptr)
static TDetectorInformation * GetDetectorInformation()
static TParserLibrary * Get(bool verbose=false)
void Print(Option_t *opt="") const override
static TUnpackingLoop * Get(std::string name="")
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > & AddGoodOutputQueue(size_t maxSize=50000)
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< TRawEvent > > > & InputQueue()
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< TEpicsFrag > > > & ScalerOutputQueue()
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TBadFragment > > > & BadOutputQueue()
std::condition_variable g__NewResult
std::mutex g__CommandListMutex
std::mutex g__ResultListMutex
std::mutex g__CommandWaitingMutex
std::string g__LineToProcess