34#include "TInterpreter.h"
35#include "TGHtmlBrowser.h"
66 : TRint(appClassName, &fFakeArgc, argv, nullptr, 0, noLogo), fKeepAliveTimer(nullptr),
67 main_thread_id(std::this_thread::get_id()), fIsTabComplete(false), fAllowedToTerminate(true), fRootFilesOpened(0),
73 GetSignalHandler()->Remove();
75 interruptHandler->Add();
87 SetPrompt(
"GRSI [%d] ");
88 std::string grsipath = getenv(
"GRSISYS");
89 gInterpreter->AddIncludePath(Form(
"%s/include", grsipath.c_str()));
122 }
catch(std::runtime_error& e) {
137 for(
const auto& rawFile : opt->
InputFiles()) {
161 int exit_status = missing_raw_file ? 1 : 0;
171 std::this_thread::sleep_for(std::chrono::seconds(1));
177 gSystem->ProcessEvents();
186 std::cout << std::endl;
192 return TRint::HandleTermInput();
200 std::cout <<
"Not allowed to terminate, sorry!" << std::endl;
212 if((clock() % 60) == 0) {
213 std::cout <<
"DING!" << std::flush;
215 std::cout <<
"\r \r" << std::flush;
218 TSeqCollection* canvases = gROOT->GetListOfCanvases();
219 while(canvases->GetEntries() > 0) {
220 static_cast<GCanvas*
>(canvases->At(0))->Close();
236 TRint::Terminate(status);
243 auto result = TRint::TabCompletionHook(buf, pLoc, out);
257 Long_t res = TRint::ProcessLine(inputLine, sync, error);
262 std::string line(inputLine);
264 while((pos = line.find(
"TCanvas", pos)) != std::string::npos) {
272 return TRint::ProcessLine(line.c_str(), sync, error);
279 gROOT->ProcessLine(
".! open http://en.wikipedia.org/wiki/Special:Random > /dev/null 2>&1;");
281 gROOT->ProcessLine(
".! xdg-open http://en.wikipedia.org/wiki/Special:Random > /dev/null 2>&1;");
291 const unsigned int reflength = ref.length() - 78;
293 const std::string& ref =
"Sorting Program for Online and Offline Nuclear Data";
294 const unsigned int reflength = 53;
297 const unsigned int width = reflength + (reflength % 2);
298 printf(
"\t*%s*\n", std::string(width,
'*').c_str());
299 printf(
"\t*%*s%*s*\n", width / 2 + 4,
"GRSI Sort", width / 2 - 4,
"");
300 printf(
"\t*%*s%*s*\n", width / 2 + 12,
"a remake of GRSI SPOON", width / 2 - 12,
"");
301 printf(
"\t*%*s%*s*\n", width / 2 + reflength / 2, ref.c_str(), width / 2 - reflength / 2,
"");
302 printf(
"\t*%*s%*s*\n", width / 2 + 14,
"A lean, mean sorting machine", width / 2 - 14,
"");
303 printf(
"\t*%*s%*s*\n", width / 2 + 9,
"version " GRSI_RELEASE, width / 2 - 9,
"");
304 printf(
"\t*%s*\n", std::string(width,
'*').c_str());
309 std::cout <<
"\tgrsisort version " << GRSI_RELEASE << std::endl;
322 TFile* file =
nullptr;
323 if(sopt.Contains(
"recreate") || sopt.Contains(
"new")) {
325 file =
new TFile(filename.c_str(),
"RECREATE");
326 if(file !=
nullptr && file->IsOpen()) {
328 const char* command = Form(
"TFile* _file%i = (TFile*)%luL;",
fRootFilesOpened,
reinterpret_cast<unsigned long>(file));
329 TRint::ProcessLine(command);
332 std::cout <<
"Could not create " << filename << std::endl;
336 file =
new TFile(filename.c_str(), opt);
337 if(file !=
nullptr && file->IsOpen()) {
339 const char* command = Form(
"TFile* _file%i = (TFile*)%luL;",
fRootFilesOpened,
reinterpret_cast<unsigned long>(file));
340 TRint::ProcessLine(command);
341 std::cout <<
"\tfile " <<
BLUE << file->GetName() <<
RESET_COLOR <<
" opened as " <<
BLUE <<
"_file"
345 if(file->FindObjectAny(
"FragmentTree") !=
nullptr) {
351 std::cout <<
"file " << file->GetName() <<
" added to gFragment." << std::endl;
352 gFragment->AddFile(file->GetName(), TTree::kMaxEntries,
"FragmentTree");
356 if(file->FindObjectAny(
"AnalysisTree") !=
nullptr) {
362 std::cout <<
"file " << file->GetName() <<
" added to gAnalysis." << std::endl;
363 gAnalysis->AddFile(file->GetName(), TTree::kMaxEntries,
"AnalysisTree");
366 if(file->FindObjectAny(
"Channel") !=
nullptr) {
370 if(file->FindObjectAny(
"Values") !=
nullptr) {
375 std::cout <<
"Could not open " << filename << std::endl;
389 std::cerr << R
"(File ")" << filename << R"(" does not exist)" << std::endl;
398 if(file !=
nullptr) {
399 const char* command = Form(
"TRawFile* _raw%i = (TRawFile*)%luL;",
fRawFilesOpened,
reinterpret_cast<unsigned long>(file));
402 std::cout <<
"\tfile " <<
BLUE << filename <<
RESET_COLOR <<
" opened as "
407 }
catch(std::runtime_error& e) {
408 std::cout << e.what();
423 bool missingRawFile =
false;
424 for(
const auto& filename : opt->
InputFiles()) {
426 missingRawFile =
true;
427 std::cerr <<
"File not found: " << filename << std::endl;
433 bool hasInputFragmentTree =
gFragment !=
nullptr;
434 bool hasInputAnalysisTree =
gAnalysis !=
nullptr;
437 bool ableToWriteFragmentHistograms = ((hasRawFile || hasInputFragmentTree) && !opt->
FragmentHistogramLib().empty());
438 bool ableToWriteFragmentTree = (hasRawFile && !missingRawFile);
439 bool ableToWriteAnalysisHistograms = ((hasRawFile || hasInputFragmentTree || hasInputAnalysisTree) &&
441 bool ableToWriteAnalysisTree = (ableToWriteFragmentTree || hasInputFragmentTree);
444 bool writeFragmentHistograms = (ableToWriteFragmentHistograms && opt->
MakeHistos());
446 bool writeAnalysisHistograms = (ableToWriteAnalysisHistograms && opt->
MakeHistos());
447 bool writeAnalysisTree = (ableToWriteAnalysisTree && opt->
MakeAnalysisTree());
452 bool readFromRaw = (hasRawFile && (writeFragmentHistograms || writeFragmentTree ||
453 writeAnalysisHistograms || writeAnalysisTree));
455 bool readFromFragmentTree = (hasInputFragmentTree && (writeFragmentHistograms || writeAnalysisHistograms || writeAnalysisTree));
457 bool generateAnalysisData = ((readFromRaw || readFromFragmentTree) && (writeAnalysisHistograms || writeAnalysisTree));
459 bool readFromAnalysisTree = (hasInputAnalysisTree && (writeAnalysisHistograms || writeAnalysisTree) && !generateAnalysisData);
463 int subRunNumber = 0;
465 runNumber =
fRawFiles[0]->GetRunNumber();
466 subRunNumber =
fRawFiles[0]->GetSubRunNumber();
467 }
else if(readFromFragmentTree) {
468 const auto* run_title =
gFragment->GetListOfFiles()->At(0)->GetTitle();
471 }
else if(readFromAnalysisTree) {
472 const auto* run_title =
gAnalysis->GetListOfFiles()->At(0)->GetTitle();
479 if(outputFragmentTreeFilename.empty()) {
480 if(subRunNumber == -1) {
481 outputFragmentTreeFilename = Form(
"fragment%05i.root", runNumber);
483 outputFragmentTreeFilename = Form(
"fragment%05i_%03i.root", runNumber, subRunNumber);
488 if(outputFragmentHistFilename.empty()) {
489 if(subRunNumber == -1) {
490 outputFragmentHistFilename = Form(
"hist_fragment%05i.root", runNumber);
492 outputFragmentHistFilename = Form(
"hist_fragment%05i_%03i.root", runNumber, subRunNumber);
497 if(outputDiagnosticsFilename.empty()) {
498 if(subRunNumber == -1) {
499 outputDiagnosticsFilename = Form(
"diagnostics%05i.root", runNumber);
501 outputDiagnosticsFilename = Form(
"diagnostics%05i_%03i.root", runNumber, subRunNumber);
506 if(outputAnalysisTreeFilename.empty()) {
507 if(subRunNumber == -1) {
509 outputAnalysisTreeFilename = Form(
"rntuple%05i.root", runNumber);
511 outputAnalysisTreeFilename = Form(
"analysis%05i.root", runNumber);
515 outputAnalysisTreeFilename = Form(
"rntuple%05i_%03i.root", runNumber, subRunNumber);
517 outputAnalysisTreeFilename = Form(
"analysis%05i_%03i.root", runNumber, subRunNumber);
523 if(output_analysis_hist_filename.empty()) {
524 if(subRunNumber == -1) {
525 output_analysis_hist_filename = Form(
"hist_analysis%05i.root", runNumber);
527 output_analysis_hist_filename = Form(
"hist_analysis%05i_%03i.root", runNumber, subRunNumber);
531 if(readFromAnalysisTree) {
532 std::cerr <<
"Reading from analysis tree not currently supported" << std::endl;
539 if(!writeFragmentHistograms && !writeFragmentTree && !writeAnalysisHistograms && !writeAnalysisTree) {
557 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<const TFragment>>>> fragmentQueues;
558 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<TEpicsFrag>>>> scalerQueues;
559 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<TUnpackedEvent>>>> analysisQueues;
571 std::cerr <<
"I'm going to ignore all but first .mid" << std::endl;
582 if(readFromFragmentTree) {
612 std::cout <<
"no detector information, can't set build mode" << std::endl;
616 if(writeFragmentHistograms) {
619 if(unpackLoop !=
nullptr) {
622 if(fragmentChainLoop !=
nullptr) {
629 if(writeFragmentTree) {
632 if(unpackLoop !=
nullptr) {
638 if(fragmentChainLoop !=
nullptr) {
645 if(unpackLoop !=
nullptr) {
648 if(fragmentChainLoop !=
nullptr) {
655 if(generateAnalysisData) {
659 if(unpackLoop !=
nullptr) {
662 if(fragmentChainLoop !=
nullptr) {
665 fragmentQueues.push_back(eventBuildingLoop->
InputQueue());
672 if(writeAnalysisHistograms) {
675 if(detBuildingLoop !=
nullptr) {
678 std::cerr <<
DRED <<
"Error, writing analysis histograms is enabled, but no detector building loop was found!"
687 if(writeAnalysisTree) {
693 analysisQueues.push_back(loop->InputQueue());
703 const char* command = Form(
".x %s", filename.c_str());
707 size_t beginning_pos = filename.find_first_of(
'(');
708 if(beginning_pos != std::string::npos && filename.back() ==
')') {
709 std::string trueFilename = filename.substr(0, beginning_pos);
710 std::string arguments = filename.substr(beginning_pos, std::string::npos);
712 const char* command = Form(
".L %s", trueFilename.c_str());
714 command = Form(
"%s%s", trueFilename.substr(0, filename.find_first_of(
'.')).c_str(), arguments.c_str());
717 std::cerr << R
"(File ")" << trueFilename << R"(" does not exist)" << std::endl;
720 std::cerr << R
"(File ")" << filename << R"(" does not exist)" << std::endl;
735 if(gROOT->IsBatch()) {
739 gROOT->LoadClass(
"TCanvas",
"Gpad");
748 new TGHtmlBrowser(gSystem->ExpandPathName(
"${GRSISYS}/README.html"));
757 std::cout << std::endl
761 static int timesPressed = 0;
763 switch(timesPressed) {
765 std::cout << std::endl
770 std::cout << std::endl
775 std::cout << std::endl
803 std::lock_guard<std::mutex> any_command_lock(g__CommandWaitingMutex);
805 g__LineToProcess = std::move(command);
806 g__CommandFinished =
false;
807 g__ProcessingNeeded =
true;
808 TTimer::SingleShot(0,
"TGRSIint",
this,
"DelayedProcessLine_Action()");
810 std::unique_lock<std::mutex> lock(g__ResultListMutex);
811 while(!g__CommandFinished) {
812 g__NewResult.wait(lock);
815 return g__CommandResult;
822 std::lock_guard<std::mutex> lock(g__CommandListMutex);
823 if(!g__ProcessingNeeded) {
826 message = g__LineToProcess;
830 Getlinem(EGetLineMode::kInit, (
static_cast<TRint*
>(gApplication))->GetPrompt());
833 std::lock_guard<std::mutex> lock(g__ResultListMutex);
834 g__CommandResult = result;
835 g__CommandFinished =
true;
836 g__ProcessingNeeded =
false;
839 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()
void PopupLogo(bool about)
std::condition_variable g__NewResult
std::mutex g__CommandListMutex
std::mutex g__ResultListMutex
std::mutex g__CommandWaitingMutex
std::string g__LineToProcess