19#ifndef __MINIBALLGUI_HH
29#ifndef __CALIBRATION_HH
39#ifndef __MIDASCONVERTER_HH
42#ifndef __MBSCONVERTER_HH
45#ifndef __MEDCONVERTER_HH
50#ifndef __EVENTBUILDER_HH
55#ifndef __HISTOGRAMMER_HH
65#ifndef __MINIBALLGUI_HH
70#ifndef __MINIBALLANGLEFITTER_HH
75#ifndef __CDCALIBRATOR_HH
81#ifndef __COMMAND_LINE_INTERFACE_HH
137std::shared_ptr<MiniballSettings>
myset;
140std::shared_ptr<MiniballCalibration>
mycal;
147std::unique_ptr<THttpServer>
serv;
156 std::shared_ptr<MiniballCalibration>
mycal;
157 std::shared_ptr<MiniballSettings>
myset;
170std::shared_ptr<MiniballEventBuilder>
eb_mon;
194 std::cout <<
"Caught signal " << signum << endl;
208 std::string rootline =
".L " + std::string(CUR_DIR) +
"include/MonitorMacros.hh";
209 gROOT->ProcessLine( rootline.data() );
220 eb_mon = std::make_shared<MiniballEventBuilder>( inputptr->
myset );
227 std::cerr <<
"Currently only supporting 64 kB block size" << std::endl;
234 long long buffer[8*1024];
244 int start_block = 0, start_subevt = 0;
245 int nblocks = 0, nsubevts = 0;
246 unsigned long nbuild = 0;
249 std::string spyname_singles =
datadir_name +
"/singles.root";
250 std::string spyname_events =
datadir_name +
"/events.root";
251 std::string spyname_hists =
datadir_name +
"/hists.root";
258 conv_mon->SetOutput( spyname_singles );
267 std::string toptitle;
270 else toptitle =
"DataSpy ";
271 toptitle +=
" (" + std::to_string(
mon_time ) +
" s)";
272 serv->SetItemField(
"/",
"_toptitle", toptitle.data() );
285 start_block = nblocks;
293 start_subevt = nsubevts;
308 std::cout <<
"Looking for data from DataSpy" << std::endl;
309 spy_length = myspy.
Read( file_id, (
char*)buffer, inputptr->
myset->GetBlockSize() );
311 std::cout <<
"No data yet on first pass" << std::endl;
312 gSystem->Sleep( 2e3 );
322 while( block_ctr < 1024 && poll_ctr < 1000 *
mon_time / wait_time ){
325 if( spy_length > 0 ) {
327 block_ctr += nblocks;
331 gSystem->Sleep( wait_time );
336 spy_length = myspy.
Read( file_id, (
char*)buffer, inputptr->
myset->GetBlockSize() );
337 byte_ctr += spy_length;
344 if( spy_length > 0 ) {
346 block_ctr += nblocks;
349 std::cout <<
"Got " << byte_ctr <<
" bytes of data in " << block_ctr <<
" blocks from DataSpy" << std::endl;
364 std::cout <<
"Looking for data from MBSEventServer" << std::endl;
378 eb_mon->SetOutput( spyname_events,
true );
383 TTree *sorted_tree =
conv_mon->GetSortedTree()->CloneTree();
384 TTree *mbsinfo_tree =
conv_mon->GetMbsInfo()->CloneTree();
385 eb_mon->SetInputTree( sorted_tree );
386 eb_mon->SetMBSInfoTree( mbsinfo_tree );
387 eb_mon->GetTree()->Reset();
388 nbuild =
eb_mon->BuildEvents();
395 hist_mon->SetOutput( spyname_hists,
true );
399 TTree *evt_tree =
eb_mon->GetTree()->CloneTree();
442 std::string server_name =
"http:" + std::to_string(
port_num) +
"?top=MiniballDAQMonitoring";
443 serv = std::make_unique<THttpServer>( server_name.data() );
444 serv->SetReadOnly(kFALSE);
448 serv->SetItemField(
"/",
"_monitoring",
"5000");
451 serv->SetItemField(
"/",
"drawopt",
"[colz,hist]");
454 serv->RegisterCommand(
"/Start",
"StartMonitor()");
455 serv->RegisterCommand(
"/Stop",
"StopMonitor()");
456 serv->RegisterCommand(
"/ResetAll",
"ResetAll()");
457 serv->RegisterCommand(
"/ResetSingles",
"ResetConv()");
458 serv->RegisterCommand(
"/ResetEvents",
"ResetEvnt()");
459 serv->RegisterCommand(
"/ResetHists",
"ResetHist()");
476 std::cout <<
"Default spy hists" << std::endl;
481 physhists.push_back( {
"ParticleSpectra/pE_theta_coinc",
"TH2",
"colz"} );
482 physhists.push_back( {
"ParticleSpectra/pE_dE0",
"TH2",
"colz"} );
483 physhists.push_back( {
"GammaRaySingles/gE_singles_ebis",
"TH1",
"hist"} );
484 physhists.push_back( {
"GammaRaySingles/gE_singles_dc_ebis",
"TH1",
"hist"} );
485 physhists.push_back( {
"GammaRayParticleCoincidences/gE_recoil_dc_ejectile",
"TH1",
"hist"} );
486 physhists.push_back( {
"GammaRayParticleCoincidences/gE_recoil_dc_recoil",
"TH1",
"hist"} );
496 if( !infile.is_open() ) {
498 std::cerr <<
"Error: Could not open file " <<
spy_hists_file << std::endl;
504 std::getline( infile, line );
505 while( line.at(0) ==
'#' )
506 std::getline( infile, line );
509 std::istringstream iss(line);
513 std::getline( infile, line );
514 iss = std::istringstream(line);
518 while( std::getline( infile, line ) ) {
521 if( line.length() == 0 )
continue;
524 std::string name, classType =
"TH1", drawOption =
"hist";
525 iss = std::istringstream(line);
526 iss >> name >> classType >> drawOption;
529 if( name.length() > 0 )
530 physhists.push_back({name, classType, drawOption});
548 std::cout <<
"\n +++ Miniball Analysis:: processing MiniballConverter +++" << std::endl;
552 std::string name_input_file;
553 std::string name_output_file;
556 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
560 name_input_file = name_input_file.substr( 0, name_input_file.find_last_of(
".") );
562 if(
flag_source ) name_output_file = name_input_file +
"_source.root";
563 else name_output_file = name_input_file +
".root";
565 name_output_file =
datadir_name +
"/" + name_output_file;
571 ftest.open( name_input_file.data() );
572 if( !ftest.is_open() ) {
574 std::cerr << name_input_file <<
" does not exist" << std::endl;
582 ftest.open( name_output_file.data() );
587 rtest =
new TFile( name_output_file.data() );
589 if( rtest->TestBit(TFile::kRecovered) ){
590 std::cout << name_output_file <<
" possibly corrupted, reconverting" << std::endl;
594 std::cout << name_output_file <<
" already converted" << std::endl;
601 std::cout << name_input_file <<
" --> ";
602 std::cout << name_output_file << std::endl;
617 if(
myset->GetMbsEventMode() )
629 conv_midas.
SetOutput( name_output_file );
654 if(
myset->GetMbsEventMode() )
676 std::cout <<
"\n +++ Miniball Analysis:: processing MiniballEventBuilder +++" << std::endl;
680 std::string name_input_file;
681 std::string name_output_file;
682 bool return_flag =
false;
688 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
692 name_input_file = name_input_file.substr( 0, name_input_file.find_last_of(
".") );
694 name_output_file =
datadir_name +
"/" + name_input_file +
"_events.root";
695 name_input_file =
datadir_name +
"/" + name_input_file +
".root";
698 ftest.open( name_input_file.data() );
699 if( !ftest.is_open() ) {
701 std::cerr << name_input_file <<
" does not exist" << std::endl;
721 ftest.open( name_output_file.data() );
726 rtest =
new TFile( name_output_file.data() );
728 if( rtest->TestBit(TFile::kRecovered) ){
729 std::cout << name_output_file <<
" possibly corrupted, rebuilding" << std::endl;
733 std::cout << name_output_file <<
" already built" << std::endl;
742 std::cout << name_input_file <<
" --> ";
743 std::cout << name_output_file << std::endl;
766 std::cout <<
"\n +++ Miniball Analysis:: processing MiniballHistogrammer +++" << std::endl;
769 std::string name_input_file;
771 std::vector<std::string> name_hist_files;
774 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
778 name_input_file = name_input_file.substr( 0,
779 name_input_file.find_last_of(
".") );
780 name_input_file =
datadir_name +
"/" + name_input_file +
"_events.root";
782 ftest.open( name_input_file.data() );
783 if( !ftest.is_open() ) {
785 std::cerr << name_input_file <<
" does not exist" << std::endl;
791 name_hist_files.push_back( name_input_file );
796 if( name_hist_files.size() ) {
815 std::cout <<
"\n +++ Miniball Analysis:: processing MiniballAngleFitter +++" << std::endl;
819 std::string name_input_file;
820 std::string name_output_file =
"22Ne_angle_fit.root";
821 std::string hadd_file_list =
"";
822 std::string name_results_file =
"22Ne_angle_fit.cal";
825 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
829 name_input_file = name_input_file.substr( 0,
830 name_input_file.find_last_of(
".") );
831 name_input_file =
datadir_name +
"/" + name_input_file +
"_events.root";
834 ftest.open( name_input_file.data() );
835 if( ftest.is_open() ) {
838 rtest =
new TFile( name_input_file.data() );
839 if( !rtest->IsZombie() ) {
840 hadd_file_list +=
" " + name_input_file;
843 std::cout <<
"Skipping " << name_input_file;
844 std::cout <<
", it's broken" << std::endl;
852 std::cout <<
"Skipping " << name_input_file;
853 std::cout <<
", file does not exist" << std::endl;
863 gErrorIgnoreLevel = kError;
864 std::string cmd =
"hadd -k -T -v 0 -f ";
865 cmd += name_output_file;
866 cmd += hadd_file_list;
867 gSystem->Exec( cmd.data() );
868 gErrorIgnoreLevel = kInfo;
898 std::cout <<
"\n +++ Miniball Analysis:: processing CD Calibrator +++" << std::endl;
901 std::string name_input_file;
902 std::vector<std::string> name_hist_files;
910 std::cout <<
"Please provide a calibration file to run cdcal... Exiting;" << std::endl;
916 for(
unsigned int i = 0; i <
input_names.size(); i++ ){
920 name_input_file = name_input_file.substr( 0,
921 name_input_file.find_last_of(
".") );
922 name_input_file =
datadir_name +
"/" + name_input_file +
".root";
924 ftest.open( name_input_file.data() );
925 if( !ftest.is_open() ) {
927 std::cerr << name_input_file <<
" does not exist" << std::endl;
933 name_hist_files.push_back( name_input_file );
938 if( name_hist_files.size() ) {
953int main(
int argc,
char *argv[] ){
959 interface->Add(
"-o",
"Output file for histogram file", &
output_name );
963 interface->Add(
"-f",
"Flag to force new ROOT conversion", &
flag_convert );
964 interface->Add(
"-e",
"Flag to force new event builder (new calibration)", &
flag_events );
965 interface->Add(
"-source",
"Flag to define an source only run", &
flag_source );
966 interface->Add(
"-ebis",
"Flag to define an EBIS only run, discarding data >4ms after an EBIS event", &
flag_ebis );
967 interface->Add(
"-midas",
"Flag to define input as MIDAS data type (FEBEX with Daresbury firmware - default)", &
flag_midas );
968 interface->Add(
"-mbs",
"Flag to define input as MBS data type (FEBEX with GSI firmware)", &
flag_mbs );
969 interface->Add(
"-med",
"Flag to define input as MED data type (DGF and MADC)", &
flag_med );
970 interface->Add(
"-anglefit",
"Flag to run the angle fit", &
flag_angle_fit );
971 interface->Add(
"-angledata",
"File containing 22Ne segment energies", &
name_angle_file );
972 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 );
973 interface->Add(
"-spy",
"Flag to run the DataSpy", &
flag_spy );
974 interface->Add(
"-spyhists",
"File containing histograms for monitoring in the spy", &
spy_hists_file );
975 interface->Add(
"-m",
"Monitor input file every X seconds", &
mon_time );
976 interface->Add(
"-p",
"Port number for web server (default 8030)", &
port_num );
977 interface->Add(
"-d",
"Directory to put the sorted data default is /path/to/data/sorted", &
datadir_name );
978 interface->Add(
"-g",
"Launch the GUI", &
gui_flag );
979 interface->Add(
"-h",
"Print this help", &
help_flag );
981 interface->CheckFlags( argc, argv );
984 interface->CheckFlags( 1, argv );
992 TApplication theApp(
"App", &argc, argv );
1004 std::cout <<
"Angle fitting using energies from a file" << std::endl;
1007 std::cout <<
"Angle fitting using 22Ne data files, with automatic peak fitting" << std::endl;
1011 std::cout <<
"When fitting the 22Ne angle data, you must give segments energy file as input" << std::endl;
1012 std::cout <<
"using the -angledata flag. Alternatively, you can give the raw data files using" << std::endl;
1013 std::cout <<
"the -i flag and the peaks will be automatically fitted from the events file." << std::endl;
1023 std::cout <<
"You have to provide at least one input file unless you are in DataSpy mode!" << std::endl;
1033 unsigned char str1, str2;
1034 unsigned int id1, id2;
1035 ss >> str1 >> id1 >> str2 >> id2;
1051 if( extension ==
"lmd" ) {
1054 std::cout <<
"Assuming we have MBS data because of the .lmd extension" << std::endl;
1055 std::cout <<
"Forcing the data block size to 32 kB" << std::endl;
1059 else if( extension ==
"med" ) {
1062 std::cout <<
"Assuming we have MED data because of the .med extension" << std::endl;
1063 std::cout <<
"Forcing the data block size to 32 kB" << std::endl;
1079 std::cout <<
"Getting data from shared memory every " <<
mon_time;
1080 std::cout <<
" seconds using DataSpy" << std::endl;
1087 std::cout <<
"Running sort in a loop every " <<
mon_time;
1088 std::cout <<
" seconds\nMonitoring " <<
input_names.at(0) << std::endl;
1095 std::cout <<
"Cannot monitor multiple input files, switching to normal mode" << std::endl;
1102 std::cout <<
"Assuming MIDAS data for spy" << std::endl;
1113 if(
input_names.at(0).find(
"/") == std::string::npos )
1135 gSystem->Exec( cmd.data() );
1136 std::cout <<
"Sorted data files being saved to " <<
datadir_name << std::endl;
1145 name_input_file = name_input_file.substr( 0,
1146 name_input_file.find_last_of(
".") );
1180 std::ifstream ftest;
1182 if( !ftest.is_open() ) {
1185 std::cout <<
" Using defaults" << std::endl;
1193 std::cout <<
"Settings file: " <<
name_set_file << std::endl;
1200 std::cout <<
"No settings file provided. Using defaults." << std::endl;
1209 std::ifstream ftest;
1211 if( !ftest.is_open() ) {
1214 std::cout <<
" Using defaults" << std::endl;
1222 std::cout <<
"Calibration file: " <<
name_cal_file << std::endl;
1230 std::cout <<
"No calibration file provided. Using defaults." << std::endl;
1239 std::ifstream ftest;
1241 if( !ftest.is_open() ) {
1244 std::cout <<
" Using defaults" << std::endl;
1259 std::cout <<
"No reaction file provided. Using defaults." << std::endl;
1267 mycal->ReadCalibration();
1286 std::cout <<
"MBS data spy not yet supported" << std::endl;
1294 std::cout <<
"MED data spy not supported because data is historical" << std::endl;
1314 gSystem->ProcessEvents();
1317 TThread *th0 =
new TThread(
"monitor",
monitor_run, (
void*)&data );
1324 gSystem->ProcessEvents();
1350 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