5#ifndef __MINIBALLGUI_HH
15#ifndef __CALIBRATION_HH
25#ifndef __MIDASCONVERTER_HH
28#ifndef __MBSCONVERTER_HH
31#ifndef __MEDCONVERTER_HH
36#ifndef __EVENTBUILDER_HH
41#ifndef __HISTOGRAMMER_HH
51#ifndef __MINIBALLGUI_HH
56#ifndef __MINIBALLANGLEFITTER_HH
61#ifndef __CDCALIBRATOR_HH
67#ifndef __COMMAND_LINE_INTERFACE_HH
123std::shared_ptr<MiniballSettings>
myset;
126std::shared_ptr<MiniballCalibration>
mycal;
133std::unique_ptr<THttpServer>
serv;
142 std::shared_ptr<MiniballCalibration>
mycal;
143 std::shared_ptr<MiniballSettings>
myset;
156std::shared_ptr<MiniballEventBuilder>
eb_mon;
180 std::cout <<
"Caught signal " << signum << endl;
194 std::string rootline =
".L " + std::string(CUR_DIR) +
"include/MonitorMacros.hh";
195 gROOT->ProcessLine( rootline.data() );
206 eb_mon = std::make_shared<MiniballEventBuilder>( inputptr->
myset );
213 std::cerr <<
"Currently only supporting 64 kB block size" << std::endl;
220 long long buffer[8*1024];
230 int start_block = 0, start_subevt = 0;
231 int nblocks = 0, nsubevts = 0;
232 unsigned long nbuild = 0;
235 std::string spyname_singles =
datadir_name +
"/singles.root";
236 std::string spyname_events =
datadir_name +
"/events.root";
237 std::string spyname_hists =
datadir_name +
"/hists.root";
244 conv_mon->SetOutput( spyname_singles );
253 std::string toptitle;
256 else toptitle =
"DataSpy ";
257 toptitle +=
" (" + std::to_string(
mon_time ) +
" s)";
258 serv->SetItemField(
"/",
"_toptitle", toptitle.data() );
271 start_block = nblocks;
279 start_subevt = nsubevts;
294 std::cout <<
"Looking for data from DataSpy" << std::endl;
295 spy_length = myspy.
Read( file_id, (
char*)buffer, inputptr->
myset->GetBlockSize() );
297 std::cout <<
"No data yet on first pass" << std::endl;
298 gSystem->Sleep( 2e3 );
308 while( block_ctr < 1024 && poll_ctr < 1000 *
mon_time / wait_time ){
311 if( spy_length > 0 ) {
313 block_ctr += nblocks;
317 gSystem->Sleep( wait_time );
322 spy_length = myspy.
Read( file_id, (
char*)buffer, inputptr->
myset->GetBlockSize() );
323 byte_ctr += spy_length;
330 if( spy_length > 0 ) {
332 block_ctr += nblocks;
335 std::cout <<
"Got " << byte_ctr <<
" bytes of data in " << block_ctr <<
" blocks from DataSpy" << std::endl;
350 std::cout <<
"Looking for data from MBSEventServer" << std::endl;
364 eb_mon->SetOutput( spyname_events,
true );
369 TTree *sorted_tree =
conv_mon->GetSortedTree()->CloneTree();
370 TTree *mbsinfo_tree =
conv_mon->GetMbsInfo()->CloneTree();
371 eb_mon->SetInputTree( sorted_tree );
372 eb_mon->SetMBSInfoTree( mbsinfo_tree );
373 eb_mon->GetTree()->Reset();
374 nbuild =
eb_mon->BuildEvents();
381 hist_mon->SetOutput( spyname_hists,
true );
385 TTree *evt_tree =
eb_mon->GetTree()->CloneTree();
428 std::string server_name =
"http:" + std::to_string(
port_num) +
"?top=MiniballDAQMonitoring";
429 serv = std::make_unique<THttpServer>( server_name.data() );
430 serv->SetReadOnly(kFALSE);
434 serv->SetItemField(
"/",
"_monitoring",
"5000");
437 serv->SetItemField(
"/",
"drawopt",
"[colz,hist]");
440 serv->RegisterCommand(
"/Start",
"StartMonitor()");
441 serv->RegisterCommand(
"/Stop",
"StopMonitor()");
442 serv->RegisterCommand(
"/ResetAll",
"ResetAll()");
443 serv->RegisterCommand(
"/ResetSingles",
"ResetConv()");
444 serv->RegisterCommand(
"/ResetEvents",
"ResetEvnt()");
445 serv->RegisterCommand(
"/ResetHists",
"ResetHist()");
462 std::cout <<
"Default spy hists" << std::endl;
467 physhists.push_back( {
"ParticleSpectra/pE_theta_coinc",
"TH2",
"colz"} );
468 physhists.push_back( {
"ParticleSpectra/pE_dE0",
"TH2",
"colz"} );
469 physhists.push_back( {
"GammaRaySingles/gE_singles_ebis",
"TH1",
"hist"} );
470 physhists.push_back( {
"GammaRaySingles/gE_singles_dc_ebis",
"TH1",
"hist"} );
471 physhists.push_back( {
"GammaRayParticleCoincidences/gE_recoil_dc_ejectile",
"TH1",
"hist"} );
472 physhists.push_back( {
"GammaRayParticleCoincidences/gE_recoil_dc_recoil",
"TH1",
"hist"} );
482 if( !infile.is_open() ) {
484 std::cerr <<
"Error: Could not open file " <<
spy_hists_file << std::endl;
490 std::getline( infile, line );
491 while( line.at(0) ==
'#' )
492 std::getline( infile, line );
495 std::istringstream iss(line);
499 std::getline( infile, line );
500 iss = std::istringstream(line);
504 while( std::getline( infile, line ) ) {
507 if( line.length() == 0 )
continue;
510 std::string name, classType =
"TH1", drawOption =
"hist";
511 iss = std::istringstream(line);
512 iss >> name >> classType >> drawOption;
515 if( name.length() > 0 )
516 physhists.push_back({name, classType, drawOption});
534 std::cout <<
"\n +++ Miniball Analysis:: processing MiniballConverter +++" << std::endl;
538 std::string name_input_file;
539 std::string name_output_file;
542 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
546 name_input_file = name_input_file.substr( 0, name_input_file.find_last_of(
".") );
548 if(
flag_source ) name_output_file = name_input_file +
"_source.root";
549 else name_output_file = name_input_file +
".root";
551 name_output_file =
datadir_name +
"/" + name_output_file;
557 ftest.open( name_input_file.data() );
558 if( !ftest.is_open() ) {
560 std::cerr << name_input_file <<
" does not exist" << std::endl;
568 ftest.open( name_output_file.data() );
573 rtest =
new TFile( name_output_file.data() );
575 if( rtest->TestBit(TFile::kRecovered) ){
576 std::cout << name_output_file <<
" possibly corrupted, reconverting" << std::endl;
580 std::cout << name_output_file <<
" already converted" << std::endl;
587 std::cout << name_input_file <<
" --> ";
588 std::cout << name_output_file << std::endl;
603 if(
myset->GetMbsEventMode() )
615 conv_midas.
SetOutput( name_output_file );
640 if(
myset->GetMbsEventMode() )
662 std::cout <<
"\n +++ Miniball Analysis:: processing MiniballEventBuilder +++" << std::endl;
666 std::string name_input_file;
667 std::string name_output_file;
668 bool return_flag =
false;
674 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
678 name_input_file = name_input_file.substr( 0, name_input_file.find_last_of(
".") );
680 name_output_file =
datadir_name +
"/" + name_input_file +
"_events.root";
681 name_input_file =
datadir_name +
"/" + name_input_file +
".root";
684 ftest.open( name_input_file.data() );
685 if( !ftest.is_open() ) {
687 std::cerr << name_input_file <<
" does not exist" << std::endl;
707 ftest.open( name_output_file.data() );
712 rtest =
new TFile( name_output_file.data() );
714 if( rtest->TestBit(TFile::kRecovered) ){
715 std::cout << name_output_file <<
" possibly corrupted, rebuilding" << std::endl;
719 std::cout << name_output_file <<
" already built" << std::endl;
728 std::cout << name_input_file <<
" --> ";
729 std::cout << name_output_file << std::endl;
752 std::cout <<
"\n +++ Miniball Analysis:: processing MiniballHistogrammer +++" << std::endl;
755 std::string name_input_file;
757 std::vector<std::string> name_hist_files;
760 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
764 name_input_file = name_input_file.substr( 0,
765 name_input_file.find_last_of(
".") );
766 name_input_file =
datadir_name +
"/" + name_input_file +
"_events.root";
768 ftest.open( name_input_file.data() );
769 if( !ftest.is_open() ) {
771 std::cerr << name_input_file <<
" does not exist" << std::endl;
777 name_hist_files.push_back( name_input_file );
782 if( name_hist_files.size() ) {
801 std::cout <<
"\n +++ Miniball Analysis:: processing MiniballAngleFitter +++" << std::endl;
805 std::string name_input_file;
806 std::string name_output_file =
"22Ne_angle_fit.root";
807 std::string hadd_file_list =
"";
808 std::string name_results_file =
"22Ne_angle_fit.cal";
811 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
815 name_input_file = name_input_file.substr( 0,
816 name_input_file.find_last_of(
".") );
817 name_input_file =
datadir_name +
"/" + name_input_file +
"_events.root";
820 ftest.open( name_input_file.data() );
821 if( ftest.is_open() ) {
824 rtest =
new TFile( name_input_file.data() );
825 if( !rtest->IsZombie() ) {
826 hadd_file_list +=
" " + name_input_file;
829 std::cout <<
"Skipping " << name_input_file;
830 std::cout <<
", it's broken" << std::endl;
838 std::cout <<
"Skipping " << name_input_file;
839 std::cout <<
", file does not exist" << std::endl;
849 gErrorIgnoreLevel = kError;
850 std::string cmd =
"hadd -k -T -v 0 -f ";
851 cmd += name_output_file;
852 cmd += hadd_file_list;
853 gSystem->Exec( cmd.data() );
854 gErrorIgnoreLevel = kInfo;
884 std::cout <<
"\n +++ Miniball Analysis:: processing CD Calibrator +++" << std::endl;
887 std::string name_input_file;
888 std::vector<std::string> name_hist_files;
896 std::cout <<
"Please provide a calibration file to run cdcal... Exiting;" << std::endl;
902 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
906 name_input_file = name_input_file.substr( 0,
907 name_input_file.find_last_of(
".") );
908 name_input_file =
datadir_name +
"/" + name_input_file +
".root";
910 ftest.open( name_input_file.data() );
911 if( !ftest.is_open() ) {
913 std::cerr << name_input_file <<
" does not exist" << std::endl;
919 name_hist_files.push_back( name_input_file );
924 if( name_hist_files.size() ) {
939int main(
int argc,
char *argv[] ){
945 interface->Add(
"-o",
"Output file for histogram file", &
output_name );
949 interface->Add(
"-f",
"Flag to force new ROOT conversion", &
flag_convert );
950 interface->Add(
"-e",
"Flag to force new event builder (new calibration)", &
flag_events );
951 interface->Add(
"-source",
"Flag to define an source only run", &
flag_source );
952 interface->Add(
"-ebis",
"Flag to define an EBIS only run, discarding data >4ms after an EBIS event", &
flag_ebis );
953 interface->Add(
"-midas",
"Flag to define input as MIDAS data type (FEBEX with Daresbury firmware - default)", &
flag_midas );
954 interface->Add(
"-mbs",
"Flag to define input as MBS data type (FEBEX with GSI firmware)", &
flag_mbs );
955 interface->Add(
"-med",
"Flag to define input as MED data type (DGF and MADC)", &
flag_med );
956 interface->Add(
"-anglefit",
"Flag to run the angle fit", &
flag_angle_fit );
957 interface->Add(
"-angledata",
"File containing 22Ne segment energies", &
name_angle_file );
958 interface->Add(
"-cdcal",
"Make the CD calibration plots with pid and nid as the reference strips, given in the string format p<pid>n<nid>", &
cdcal_strips );
959 interface->Add(
"-spy",
"Flag to run the DataSpy", &
flag_spy );
960 interface->Add(
"-spyhists",
"File containing histograms for monitoring in the spy", &
spy_hists_file );
961 interface->Add(
"-m",
"Monitor input file every X seconds", &
mon_time );
962 interface->Add(
"-p",
"Port number for web server (default 8030)", &
port_num );
963 interface->Add(
"-d",
"Directory to put the sorted data default is /path/to/data/sorted", &
datadir_name );
964 interface->Add(
"-g",
"Launch the GUI", &
gui_flag );
965 interface->Add(
"-h",
"Print this help", &
help_flag );
967 interface->CheckFlags( argc, argv );
970 interface->CheckFlags( 1, argv );
978 TApplication theApp(
"App", &argc, argv );
990 std::cout <<
"Angle fitting using energies from a file" << std::endl;
993 std::cout <<
"Angle fitting using 22Ne data files, with automatic peak fitting" << std::endl;
997 std::cout <<
"When fitting the 22Ne angle data, you must give segments energy file as input" << std::endl;
998 std::cout <<
"using the -angledata flag. Alternatively, you can give the raw data files using" << std::endl;
999 std::cout <<
"the -i flag and the peaks will be automatically fitted from the events file." << std::endl;
1009 std::cout <<
"You have to provide at least one input file unless you are in DataSpy mode!" << std::endl;
1019 unsigned char str1, str2;
1020 unsigned int id1, id2;
1021 ss >> str1 >> id1 >> str2 >> id2;
1037 if( extension ==
"lmd" ) {
1040 std::cout <<
"Assuming we have MBS data because of the .lmd extension" << std::endl;
1041 std::cout <<
"Forcing the data block size to 32 kB" << std::endl;
1045 else if( extension ==
"med" ) {
1048 std::cout <<
"Assuming we have MED data because of the .med extension" << std::endl;
1049 std::cout <<
"Forcing the data block size to 32 kB" << std::endl;
1065 std::cout <<
"Getting data from shared memory every " <<
mon_time;
1066 std::cout <<
" seconds using DataSpy" << std::endl;
1073 std::cout <<
"Running sort in a loop every " <<
mon_time;
1074 std::cout <<
" seconds\nMonitoring " <<
input_names.at(0) << std::endl;
1081 std::cout <<
"Cannot monitor multiple input files, switching to normal mode" << std::endl;
1088 std::cout <<
"Assuming MIDAS data for spy" << std::endl;
1099 if(
input_names.at(0).find(
"/") == std::string::npos )
1121 gSystem->Exec( cmd.data() );
1122 std::cout <<
"Sorted data files being saved to " <<
datadir_name << std::endl;
1131 name_input_file = name_input_file.substr( 0,
1132 name_input_file.find_last_of(
".") );
1166 std::ifstream ftest;
1168 if( !ftest.is_open() ) {
1171 std::cout <<
" Using defaults" << std::endl;
1179 std::cout <<
"Settings file: " <<
name_set_file << std::endl;
1186 std::cout <<
"No settings file provided. Using defaults." << std::endl;
1195 std::ifstream ftest;
1197 if( !ftest.is_open() ) {
1200 std::cout <<
" Using defaults" << std::endl;
1208 std::cout <<
"Calibration file: " <<
name_cal_file << std::endl;
1216 std::cout <<
"No calibration file provided. Using defaults." << std::endl;
1225 std::ifstream ftest;
1227 if( !ftest.is_open() ) {
1230 std::cout <<
" Using defaults" << std::endl;
1245 std::cout <<
"No reaction file provided. Using defaults." << std::endl;
1253 mycal->ReadCalibration();
1272 std::cout <<
"MBS data spy not yet supported" << std::endl;
1280 std::cout <<
"MED data spy not supported because data is historical" << std::endl;
1300 gSystem->ProcessEvents();
1303 TThread *th0 =
new TThread(
"monitor",
monitor_run, (
void*)&data );
1310 gSystem->ProcessEvents();
1336 std::cout <<
"\n\nFinished!\n";
int Read(int id, char *data, unsigned int length)
int OpenEventServer(std::string _server, unsigned short _port)
const MBSEvent * GetNextEventFromStream()
void SaveExpEnergies(std::string energy_file)
bool SetInputEnergiesFile(std::string fname)
bool SetInputROOTFile(std::string fname)
void SaveReactionFile(std::string fname)
void SetOutput(std::string output_file_name, bool cWrite=false)
void SetNsideTagId(unsigned char id)
unsigned long FillHists()
void SetInputFile(std::vector< std::string > input_file_names)
void SetPsideTagId(unsigned char id)
void AddCalibration(std::shared_ptr< MiniballCalibration > mycal)
void AddCalibration(std::shared_ptr< MiniballCalibration > mycal)
unsigned long long int SortTree(bool do_sort=true)
void SetOutput(std::string output_file_name)
void AddCalibration(std::shared_ptr< MiniballCalibration > mycal)
void SetInputFile(std::string input_file_name)
unsigned long BuildEvents()
void SetOutput(std::string output_file_name, bool cWrite=false)
void SetOutput(std::string output_file_name, bool cWrite=false)
unsigned long FillHists()
void SetInputFile(std::vector< std::string > input_file_names)
int ConvertFile(std::string input_file_name, unsigned long start_block=0, long end_block=-1)
int ConvertFile(std::string input_file_name, unsigned long start_block=0, long end_block=-1)
int ConvertFile(std::string input_file_name, unsigned long start_block=0, long end_block=-1)
std::string name_set_file
int main(int argc, char *argv[])
std::shared_ptr< MiniballSettings > myset
std::shared_ptr< MiniballConverter > conv_mon
std::shared_ptr< MiniballReaction > myreact
void ReadSpyHistogramList()
std::unique_ptr< THttpServer > serv
std::shared_ptr< MiniballHistogrammer > hist_mon
void * monitor_run(void *ptr)
std::shared_ptr< MiniballMbsConverter > conv_mbs_mon
std::shared_ptr< MiniballEventBuilder > eb_mon
std::vector< bool > force_convert
std::string name_cal_file
std::shared_ptr< MiniballMidasConverter > conv_midas_mon
std::string name_react_file
void signal_callback_handler(int signum)
std::string spy_hists_file
std::string name_angle_file
std::vector< std::string > input_names
std::shared_ptr< MiniballCalibration > mycal
std::vector< std::vector< std::string > > physhists
std::vector< std::vector< std::string > > physhists
std::shared_ptr< MiniballReaction > myreact
std::shared_ptr< MiniballCalibration > mycal
std::shared_ptr< MiniballSettings > myset