#include #include #include #include #include #include #include #include #include #include #include #include #include "EoaCore.hxx" #include "ICOMETEvent.hxx" #include "IMidasFile.hxx" #include "ICOMETInput.hxx" #include "ICOMETOutput.hxx" #include "IOADatabase.hxx" #include "IHandleHack.hxx" #include "ICOMETLog.hxx" #include "IMemoryUsage.hxx" #include "IProfileData.hxx" #include "IEventLoopStride.hxx" #include "IInputFileList.hxx" #include "cometEventLoop.hxx" #include "IFieldManager.hxx" #include "IUniformField.hxx" namespace { void cometEventLoopUsage(std::string programName, COMET::ICOMETEventLoopFunction& userCode, int readCount) { std::cout << "usage: " << programName << " [options] [input-file] ..." << std::endl << std::endl; std::cout << "Options:" << std::endl; std::cout << " -o Set the name of an output file." << std::endl << " Multiple output files can" << " be provided." << std::endl; std::cout << " -a Read all events"; if (readCount<1) std::cout << " [Default]"; std::cout << std::endl; std::cout << " -b [,c,u,n] Set the field maps load from specified file, current input file, uniforme field with 1 Testla at Z direction, or no field"; std::cout << " NOTICE: if this option is not given and field manager is not set elsewhere, then any access to fieldmap will lead to exception throw."; std::cout << std::endl; std::cout << " -c Set the logging config file name" << std::endl; std::cout << " -d Increase the debug level" << std::endl; std::cout << " -D =[error,severe,warn,debug,trace]" << std::endl << " Change the named debug level" << std::endl; std::cout << " -f Look for an event number" << std::endl; std::cout << " -f , Look for a run and event number" << std::endl; std::cout << " -F Change the order of the input files, one of: " < Force a geometry file" << std::endl; std::cout << " -g Don't save geometry in output" << std::endl; std::cout << " -H Debug IHandle (slow)" << std::endl; std::cout << " -I Text file containing a list of input files. Each line be of one of the forms: \n" " filename [file-type] \n" " filename [file-type] [list-name]\n" " filename [file-type] [list-index]\n" " where file-type is optional, but must be either 'midas' or 'root' depending on \n" " whether the data is directly from MIDAS or is an oaEvent file, respectively. \n" " If not given, the value 'root' is assumed and list-name/index cannot be used.\n" " If given, list-name/index can also be provided, which denotes which IEntryList will \n" " be used when looping over this file." << std::endl; std::cout << " -B Abort (throw error) if file cannot be read" << std::endl; std::cout << " -R Number of times attempts to open a file before skipping it or aborting.\n" " Useful for accessing xrootd files, which can fail on first attempt." << std::endl; std::cout << " -m MIDAS input file" << std::endl; std::cout << " -n Only read events"; if (readCount>0) std::cout << " [Default: " << readCount << "]"; std::cout << std::endl; std::cout << " -q Decrease the verbosity" << std::endl; std::cout << " -r COMET ROOT file" << std::endl; std::cout << " -s Skip events" << std::endl; std::cout << " -S Stride through events (loop over events out of order). Options:\n" " primes = use the smallest prime number guaranteed to stride through all events in the input file.\n" " random = Step through the events in a random order.\n" " [0-9]+ = An integer which fixes the number of events to skip over.\n" << std::endl; std::cout << " -t [bpTPEFecC] Only accept these triggers" " [WARNING: THIS OPTION IS NOT YET VALID FOR COMET AND WILL BE IGNORED] " // << std::endl // << " b Beam triggers" // << std::endl // << " p Pedestal/noise triggers" // << std::endl // << " T TPC laser triggers" // << std::endl // << " P P0D light injection triggers" // << std::endl // << " E ECal LED triggers" // << std::endl // << " F FGD LED triggers" // << std::endl // << " e Electronics calib triggers" // << std::endl // << " c TFB cosmic ray triggers" // << std::endl // << " C FGD cosmic ray triggers" << std::endl; std::cout << " -u Log the memory and CPU usage" << std::endl; std::cout << " -U Print the memory and CPU usage" << std::endl; std::cout << " -v Increase the verbosity" << std::endl; std::cout << " -V =[quiet,log,info,verbose]" << std::endl << " Change the named log level" << std::endl; std::cout << " -O [=] Set an option for the user code" << std::endl; std::cout << std::endl; userCode.Usage(); std::exit(1); } }; int COMET::cometEventLoop(int argc, char** argv, COMET::ICOMETEventLoopFunction& userCode, int defaultReadCount) { if (defaultReadCount<0) defaultReadCount = 0; int readCount = defaultReadCount; int debugLevel = 0; std::map namedDebugLevel; int logLevel = -1; // Will choose default logging level... std::map namedLogLevel; std::string programName = argv[0]; char *configName = NULL; std::vector outputNames; std::vector outputFiles; std::string file_order; bool preventSavedGeometry = false; std::string geometryFile = ""; std::string fieldMapOption = ""; int targetRun = -1; int targetEvent = -1; int exitStatus = 0; std::string strideOption=""; // No stride IMemoryUsage memoryUsage; bool printMemoryUsage = false; COMET::IInputFileList input_files; // If this is not zero, then only accept triggers matched in this mask. unsigned int validTriggersMask = 0; signal(SIGSEGV, SIG_DFL); enum FileType_t{ kRootFile, kMIDASFile } fileType = kRootFile; // Process the options. for (;;) { int c = getopt(argc, argv, "ab:c:dD:f:F:G:gHI:BR:mn:o:O:qrs:S:t:uvV:"); if (c<0) break; switch (c) { case 'a': { // readcount of zero means read the entire file. readCount = 0; break; } case 'b': { // Specify the way to initialize magnetic field fieldMapOption = optarg; break; } case 'c': { configName = strdup(optarg); break; } case 'd': { // increase the debugging level. ++debugLevel; break; } case 'D': { // Set the debug level for a named trace. std::string arg(optarg); std::size_t sep = arg.find("="); if (sep != std::string::npos) { std::string name = arg.substr(0,sep); std::string levelName = arg.substr(sep+1); switch (levelName[0]) { case 'e': case 'E': namedDebugLevel[name.c_str()] = COMET::ICOMETLog::ErrorLevel; break; case 's': case 'S': namedDebugLevel[name.c_str()] = COMET::ICOMETLog::SevereLevel; break; case 'w': case 'W': namedDebugLevel[name.c_str()] = COMET::ICOMETLog::WarnLevel; break; case 'd': case 'D': namedDebugLevel[name.c_str()] = COMET::ICOMETLog::DebugLevel; break; case 't': case 'T': namedDebugLevel[name.c_str()] = COMET::ICOMETLog::TraceLevel; break; default: cometEventLoopUsage(programName,userCode,defaultReadCount); } } break; } case 'f': { // Look for a particular run and event number in the file. std::string arg(optarg); if (arg.find(',')!=std::string::npos) { std::istringstream input(arg); char c; input >> targetRun; input >> c; input >> targetEvent; } else { std::istringstream input(arg); input >> targetEvent; } break; } case 'F': { // Set the file ordering file_order = optarg; break; } case 'G': { // Force a particular geometry file. geometryFile = optarg; break; } case 'g': { // prevent the geometry from being saved. preventSavedGeometry = true; break; } case 'H': { // Debug the handles. EnableHandleRegistry(true); break; } case 'I': { if(!input_files.ReadListFromFile(optarg)){ COMETError("Problem obtaining input list from file."); return 1; } break; } case 'B': { // Change from the default behaviour to fail on bad files input_files.SetSkipBadFiles(false); break; } case 'R': { // Set the number of times a file will be opened std::istringstream tmp(optarg); int nRetries = 0; tmp >> nRetries; input_files.SetOpenRetries(nRetries); break; } case 'm': { fileType = kMIDASFile; break; } case 'n': { std::istringstream tmp(optarg); tmp >> readCount; break; } case 'o': { outputNames.push_back(optarg); break; } case 'O': { std::string option = optarg; std::string value = ""; // If the option is "