32#include "TInterpreter.h"
33#include "TGHtmlBrowser.h"
64 : TRint(appClassName, new int(0), argv, nullptr, 0, noLogo), fKeepAliveTimer(nullptr),
65 main_thread_id(std::this_thread::get_id()), fIsTabComplete(false), fAllowedToTerminate(true), fRootFilesOpened(0),
71 GetSignalHandler()->Remove();
73 interruptHandler->Add();
85 SetPrompt(
"GRSI [%d] ");
86 std::string grsipath = getenv(
"GRSISYS");
87 gInterpreter->AddIncludePath(Form(
"%s/include", grsipath.c_str()));
120 }
catch(std::runtime_error& e) {
135 for(
const auto& rawFile : opt->
InputFiles()) {
159 int exit_status = missing_raw_file ? 1 : 0;
169 std::this_thread::sleep_for(std::chrono::seconds(1));
175 gSystem->ProcessEvents();
184 std::cout << std::endl;
190 return TRint::HandleTermInput();
198 std::cout <<
"Not allowed to terminate, sorry!" << std::endl;
210 if((clock() % 60) == 0) {
211 std::cout <<
"DING!" << std::flush;
213 std::cout <<
"\r \r" << std::flush;
216 TSeqCollection* canvases = gROOT->GetListOfCanvases();
217 while(canvases->GetEntries() > 0) {
218 static_cast<GCanvas*
>(canvases->At(0))->Close();
222 TRint::Terminate(status);
229 auto result = TRint::TabCompletionHook(buf, pLoc, out);
243 Long_t res = TRint::ProcessLine(inputLine, sync, error);
248 std::string line(inputLine);
250 while((pos = line.find(
"TCanvas", pos)) != std::string::npos) {
258 return TRint::ProcessLine(line.c_str(), sync, error);
265 gROOT->ProcessLine(
".! open http://en.wikipedia.org/wiki/Special:Random > /dev/null 2>&1;");
267 gROOT->ProcessLine(
".! xdg-open http://en.wikipedia.org/wiki/Special:Random > /dev/null 2>&1;");
277 const unsigned int reflength = ref.length() - 78;
279 const std::string& ref =
"Sorting Program for Online and Offline Nuclear Data";
280 const unsigned int reflength = 53;
283 const unsigned int width = reflength + (reflength % 2);
284 printf(
"\t*%s*\n", std::string(width,
'*').c_str());
285 printf(
"\t*%*s%*s*\n", width / 2 + 4,
"GRSI Sort", width / 2 - 4,
"");
286 printf(
"\t*%*s%*s*\n", width / 2 + 12,
"a remake of GRSI SPOON", width / 2 - 12,
"");
287 printf(
"\t*%*s%*s*\n", width / 2 + reflength / 2, ref.c_str(), width / 2 - reflength / 2,
"");
288 printf(
"\t*%*s%*s*\n", width / 2 + 14,
"A lean, mean sorting machine", width / 2 - 14,
"");
289 printf(
"\t*%*s%*s*\n", width / 2 + 9,
"version " GRSI_RELEASE, width / 2 - 9,
"");
290 printf(
"\t*%s*\n", std::string(width,
'*').c_str());
295 std::cout <<
"\tgrsisort version " << GRSI_RELEASE << std::endl;
308 TFile* file =
nullptr;
309 if(sopt.Contains(
"recreate") || sopt.Contains(
"new")) {
311 file =
new TFile(filename.c_str(),
"RECREATE");
312 if(file !=
nullptr && file->IsOpen()) {
314 const char* command = Form(
"TFile* _file%i = (TFile*)%luL;",
fRootFilesOpened,
reinterpret_cast<unsigned long>(file));
315 TRint::ProcessLine(command);
318 std::cout <<
"Could not create " << filename << std::endl;
322 file =
new TFile(filename.c_str(), opt);
323 if(file !=
nullptr && file->IsOpen()) {
325 const char* command = Form(
"TFile* _file%i = (TFile*)%luL;",
fRootFilesOpened,
reinterpret_cast<unsigned long>(file));
326 TRint::ProcessLine(command);
327 std::cout <<
"\tfile " <<
BLUE << file->GetName() <<
RESET_COLOR <<
" opened as " <<
BLUE <<
"_file"
331 if(file->FindObjectAny(
"FragmentTree") !=
nullptr) {
337 std::cout <<
"file " << file->GetName() <<
" added to gFragment." << std::endl;
338 gFragment->AddFile(file->GetName(), TTree::kMaxEntries,
"FragmentTree");
342 if(file->FindObjectAny(
"AnalysisTree") !=
nullptr) {
348 std::cout <<
"file " << file->GetName() <<
" added to gAnalysis." << std::endl;
349 gAnalysis->AddFile(file->GetName(), TTree::kMaxEntries,
"AnalysisTree");
352 if(file->FindObjectAny(
"Channel") !=
nullptr) {
356 if(file->FindObjectAny(
"Values") !=
nullptr) {
361 std::cout <<
"Could not open " << filename << std::endl;
375 std::cerr << R
"(File ")" << filename << R"(" does not exist)" << std::endl;
384 if(file !=
nullptr) {
385 const char* command = Form(
"TRawFile* _raw%i = (TRawFile*)%luL;",
fRawFilesOpened,
reinterpret_cast<unsigned long>(file));
388 std::cout <<
"\tfile " <<
BLUE << filename <<
RESET_COLOR <<
" opened as "
393 }
catch(std::runtime_error& e) {
394 std::cout << e.what();
409 bool missing_raw_file =
false;
410 for(
const auto& filename : opt->
InputFiles()) {
412 missing_raw_file =
true;
413 std::cerr <<
"File not found: " << filename << std::endl;
419 bool has_input_fragment_tree =
gFragment !=
nullptr;
420 bool has_input_analysis_tree =
gAnalysis !=
nullptr;
423 bool able_to_write_fragment_histograms =
425 bool able_to_write_fragment_tree = (has_raw_file && !missing_raw_file);
426 bool able_to_write_analysis_histograms = ((has_raw_file || has_input_fragment_tree || has_input_analysis_tree) &&
428 bool able_to_write_analysis_tree = (able_to_write_fragment_tree || has_input_fragment_tree);
431 bool write_fragment_histograms = (able_to_write_fragment_histograms && opt->
MakeHistos());
432 bool write_fragment_tree = able_to_write_fragment_tree && opt->
WriteFragmentTree();
433 bool write_analysis_histograms =
434 (able_to_write_analysis_histograms && opt->
MakeHistos());
435 bool write_analysis_tree = (able_to_write_analysis_tree && opt->
MakeAnalysisTree());
440 bool read_from_raw = (has_raw_file && (write_fragment_histograms || write_fragment_tree ||
441 write_analysis_histograms || write_analysis_tree));
443 bool read_from_fragment_tree =
444 (has_input_fragment_tree && (write_fragment_histograms || write_analysis_histograms || write_analysis_tree));
446 bool generate_analysis_data =
447 ((read_from_raw || read_from_fragment_tree) && (write_analysis_histograms || write_analysis_tree));
449 bool read_from_analysis_tree =
450 (has_input_analysis_tree && (write_analysis_histograms || write_analysis_tree) && !generate_analysis_data);
454 int sub_run_number = 0;
456 run_number =
fRawFiles[0]->GetRunNumber();
457 sub_run_number =
fRawFiles[0]->GetSubRunNumber();
458 }
else if(read_from_fragment_tree) {
459 const auto* run_title =
gFragment->GetListOfFiles()->At(0)->GetTitle();
462 }
else if(read_from_analysis_tree) {
463 const auto* run_title =
gAnalysis->GetListOfFiles()->At(0)->GetTitle();
470 if(output_fragment_tree_filename.length() == 0) {
471 if(sub_run_number == -1) {
472 output_fragment_tree_filename = Form(
"fragment%05i.root", run_number);
474 output_fragment_tree_filename = Form(
"fragment%05i_%03i.root", run_number, sub_run_number);
479 if(output_fragment_hist_filename.length() == 0) {
480 if(sub_run_number == -1) {
481 output_fragment_hist_filename = Form(
"hist_fragment%05i.root", run_number);
483 output_fragment_hist_filename = Form(
"hist_fragment%05i_%03i.root", run_number, sub_run_number);
488 if(output_analysis_tree_filename.length() == 0) {
489 if(sub_run_number == -1) {
491 output_analysis_tree_filename = Form(
"rntuple%05i.root", run_number);
493 output_analysis_tree_filename = Form(
"analysis%05i.root", run_number);
497 output_analysis_tree_filename = Form(
"rntuple%05i_%03i.root", run_number, sub_run_number);
499 output_analysis_tree_filename = Form(
"analysis%05i_%03i.root", run_number, sub_run_number);
505 if(output_analysis_hist_filename.length() == 0) {
506 if(sub_run_number == -1) {
507 output_analysis_hist_filename = Form(
"hist_analysis%05i.root", run_number);
509 output_analysis_hist_filename = Form(
"hist_analysis%05i_%03i.root", run_number, sub_run_number);
513 if(read_from_analysis_tree) {
514 std::cerr <<
"Reading from analysis tree not currently supported" << std::endl;
521 if(!write_fragment_histograms && !write_fragment_tree && !write_analysis_histograms && !write_analysis_tree) {
539 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<const TFragment>>>> fragmentQueues;
540 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<TEpicsFrag>>>> scalerQueues;
541 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<TUnpackedEvent>>>> analysisQueues;
553 std::cerr <<
"I'm going to ignore all but first .mid" << std::endl;
564 if(read_from_fragment_tree) {
594 std::cout <<
"no detector information, can't set build mode" << std::endl;
598 if(write_fragment_histograms) {
601 if(unpackLoop !=
nullptr) {
604 if(fragmentChainLoop !=
nullptr) {
611 if(write_fragment_tree) {
614 if(unpackLoop !=
nullptr) {
620 if(fragmentChainLoop !=
nullptr) {
627 if(generate_analysis_data) {
631 if(unpackLoop !=
nullptr) {
634 if(fragmentChainLoop !=
nullptr) {
637 fragmentQueues.push_back(eventBuildingLoop->
InputQueue());
644 if(write_analysis_histograms) {
647 if(detBuildingLoop !=
nullptr) {
650 std::cerr <<
DRED <<
"Error, writing analysis histograms is enabled, but no detector building loop was found!"
659 if(write_analysis_tree) {
665 analysisQueues.push_back(loop->InputQueue());
675 const char* command = Form(
".x %s", filename.c_str());
679 size_t beginning_pos = filename.find_first_of(
'(');
680 if(beginning_pos != std::string::npos && filename.back() ==
')') {
681 std::string trueFilename = filename.substr(0, beginning_pos);
682 std::string arguments = filename.substr(beginning_pos, std::string::npos);
684 const char* command = Form(
".L %s", trueFilename.c_str());
686 command = Form(
"%s%s", trueFilename.substr(0, filename.find_first_of(
'.')).c_str(), arguments.c_str());
689 std::cerr << R
"(File ")" << trueFilename << R"(" does not exist)" << std::endl;
692 std::cerr << R
"(File ")" << filename << R"(" does not exist)" << std::endl;
707 if(gROOT->IsBatch()) {
711 gROOT->LoadClass(
"TCanvas",
"Gpad");
720 new TGHtmlBrowser(gSystem->ExpandPathName(
"${GRSISYS}/README.html"));
729 std::cout << std::endl
733 static int timesPressed = 0;
735 switch(timesPressed) {
737 std::cout << std::endl
742 std::cout << std::endl
747 std::cout << std::endl
775 std::lock_guard<std::mutex> any_command_lock(g__CommandWaitingMutex);
777 g__LineToProcess = std::move(command);
778 g__CommandFinished =
false;
779 g__ProcessingNeeded =
true;
780 TTimer::SingleShot(0,
"TGRSIint",
this,
"DelayedProcessLine_Action()");
782 std::unique_lock<std::mutex> lock(g__ResultListMutex);
783 while(!g__CommandFinished) {
784 g__NewResult.wait(lock);
787 return g__CommandResult;
794 std::lock_guard<std::mutex> lock(g__CommandListMutex);
795 if(!g__ProcessingNeeded) {
798 message = g__LineToProcess;
802 Getlinem(EGetLineMode::kInit, (
static_cast<TRint*
>(gApplication))->GetPrompt());
805 std::lock_guard<std::mutex> lock(g__ResultListMutex);
806 g__CommandResult = result;
807 g__CommandFinished =
true;
808 g__ProcessingNeeded =
false;
811 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 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 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
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
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()
if necessary loads shared object library and sets/initializes all other functions
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