//=============================================================== // This is the Level-3 farm process program. It's job is to // read events from a ET system or file, apply the L3 algorithm // to determine which ones to keep, and then write those out to // a different ET system or file. Here is an overview of how this // system is set up: // // 1.) Events are read in using the standard EVIO event source. // This supports both file and ET system input types. // // 2.) The L3 algorithm is applied by simply getting the DL3Trigger // objects through the standard JANA framework mechanism. The L3 // algorithm should supply only a single object which has a flag // named "L3_decision" which can be set to one of a few values, but // mainly we check if it is set to kDISCARD_EVENT or not. If the // decision is NOT to discard the event, then the event is written // to the output. // // 3.) Events are also saved if they they are: // - non-Physics events such as EPICS, CODA Control, or SYNC // events // - evenly divisible by the value of the config parameter // "L3:AUTO_KEEP_PERIOD" (this records the unbiased sample. // set the config. param. to 0 to not record an unbiased // sample) // // 4.) Output is done by completely reforming the event based on // data objects like Df250PulseIntegral amd Df125CDCPulse. This is // needed because the original format from CODA is likely to be // "entangled" having many events interspersed within the EVIO // buffer. The reconstituted EVIO event has its pointer copied to // a queue in the L3farm_out object. (There is only one L3farm_out // object). This means the creation of the EVIO buffers can be done // in parallel by multiple threads while only the pointer copy needs // to be done serially. // // 5.) A separate "event writer" thread grabs buffers from the // output queue and writes them to the output, and deletes them // from memory when done. //=============================================================== #include using namespace std; #include using namespace jana; #include "L3farm_out.h" #include "JEventProcessor_L3proc.h" void Usage(string end_message=""); void ParseCommandLineArguments(int narg, char *argv[]); uint64_t AUTO_KEEP_PERIOD = 10; string OUTPUT_SINK_NAME = "hdl3out.evio"; bool ROOT_FILENAME = ""; //----------- // main //----------- int main(int narg, char *argv[]) { if(narg<=1)Usage(); // Parse command line arguments ParseCommandLineArguments(narg, argv); // Instantiate an event loop object DApplication app(narg, argv); // Get JANA configuration parameters gPARMS->SetDefaultParameter("L3:AUTO_KEEP_PERIOD", AUTO_KEEP_PERIOD, "Keep one event regardless of L3 decision for every L3:AUTO_KEEP_PERIOD events read in."); gPARMS->SetDefaultParameter("L3:OUTPUT", OUTPUT_SINK_NAME, "Where to write saved event. If it starts with \"ET:\" then it's an ET system, otherwise it's an EVIO file. Set to 'none' for no output."); gPARMS->SetDefaultParameter("L3:ROOT_FILENAME", ROOT_FILENAME, "If set to non-empty string, open a ROOT file with this name. Useful for debugging."); // Create L3farm_out object which will write // the accepted events to the output ET system // or file. Launch thread for it to run in. L3farm_out *l3out = new L3farm_out(OUTPUT_SINK_NAME); pthread_t l3out_thr; pthread_create(&l3out_thr, NULL, L3OutputThread, l3out); // Always set timeout to infinite since we are usually be reading from ET uint32_t THREAD_TIMEOUT = 1<<31; uint32_t THREAD_TIMEOUT_FIRST_EVENT = 1<<31; bool ET_STATION_CREATE_BLOCKING = true; gPARMS->SetParameter("THREAD_TIMEOUT", THREAD_TIMEOUT); gPARMS->SetParameter("THREAD_TIMEOUT_FIRST_EVENT", THREAD_TIMEOUT_FIRST_EVENT); gPARMS->SetParameter("EVIO:ET_STATION_CREATE_BLOCKING", ET_STATION_CREATE_BLOCKING); // Run though all events, calling our event processor's methods app.Run(new JEventProcessor_L3proc(l3out)); // Clean up l3out->Quit(); void *retval=NULL; pthread_join(l3out_thr, &retval); delete l3out; return 0; } //--------------------------------- // ParseCommandLineArguments //--------------------------------- void ParseCommandLineArguments(int narg, char *argv[]) { for(int i=1; iUsage(); cout< 0) cout << end_message << endl; exit(0); }