// $Id$ // // File: JEventProcessor_evio_rate_scan.cc // Created: Sun Feb 26 19:30:39 EST 2017 // Creator: davidl (on Linux gluon48.jlab.org 2.6.32-431.20.3.el6.x86_64 x86_64) // #include "JEventProcessor_evio_rate_scan.h" using namespace jana; #include #include // Routine used to create our JEventProcessor #include #include #include #include #include extern "C"{ void InitPlugin(JApplication *app){ InitJANAPlugin(app); app->AddProcessor(new JEventProcessor_evio_rate_scan()); } } // "C" // This does a CAS (=Compare And Exchange) loop to atomically // add to a double inline void CAS_loop_add(atomic &var, double val) { auto current = var.load(); while(!var.compare_exchange_weak(current, current+val)); } //------------------ // JEventProcessor_evio_rate_scan (Constructor) //------------------ JEventProcessor_evio_rate_scan::JEventProcessor_evio_rate_scan() { for(auto &v : event_cnt) v=0; for(auto &v : Ibeam_cnt) v=0; for(auto &v : Ibeam_Isfiducial_cnt) v=0; } //------------------ // ~JEventProcessor_evio_rate_scan (Destructor) //------------------ JEventProcessor_evio_rate_scan::~JEventProcessor_evio_rate_scan() { } //------------------ // init //------------------ jerror_t JEventProcessor_evio_rate_scan::init(void) { gPARMS->SetParameter("EVIO:LINK", false); gPARMS->SetParameter("EVIO:LINK_BORCONFIG", false); gPARMS->SetParameter("EVIO:PARSE_F250", false); gPARMS->SetParameter("EVIO:PARSE_F125", false); gPARMS->SetParameter("EVIO:PARSE_F1TDC", false); gPARMS->SetParameter("EVIO:PARSE_CAEN1290TDC", false); gPARMS->SetParameter("EVIO:PARSE_CONFIG", false); gPARMS->SetParameter("EVIO:PARSE_BOR", false); gPARMS->SetParameter("EVIO:PARSE_EPICS", false); gPARMS->SetParameter("EVIO:PARSE_EVENTTAG", false); gPARMS->SetParameter("EVIO:APPLY_TRANSLATION_TABLE", false); gPARMS->SetParameter("EVIO:F250_EMULATION_MODE", 0); gPARMS->SetParameter("EVIO:F125_EMULATION_MODE", 0); return NOERROR; } //------------------ // brun //------------------ jerror_t JEventProcessor_evio_rate_scan::brun(JEventLoop *loop, int32_t runnumber) { // Create temporary factory object to read in trip map DBeamCurrent_factory *fac = new DBeamCurrent_factory(); fac->init(); fac->brun(loop, runnumber); // Copy conversion factors to local members ticks_per_sec = fac->ticks_per_sec; rcdb_250MHz_offset_tics = (double)fac->rcdb_250MHz_offset_tics; jout << " ticks_per_sec = " << ticks_per_sec << endl; jout << "rcdb_250MHz_offset_tics = " << rcdb_250MHz_offset_tics << endl; // Copy trip, recover, and boundaries maps into ROOT trees jout << "Creating trip and recover trees..." << endl; double t; TTree *tree = new TTree("trip", ""); tree->Branch("t", &t, "t/D"); for(auto tt : fac->trip){ t = tt; tree->Fill(); } tree = new TTree("recover", ""); tree->Branch("t", &t, "t/D"); for(auto tt : fac->recover){ t = tt; tree->Fill(); } //DBeamCurrent_factory::Boundary b; tree = new TTree("boundaries", ""); TBranch *branch = tree->Branch("boundaries", 0, "t/D:Ibeam:t_trip_prev:t_trip_next"); for(auto bb : fac->recover){ branch->SetAddress(&bb); //tree->Fill(); } delete fac; jout << "Done" << endl; return NOERROR; } //------------------ // evnt //------------------ jerror_t JEventProcessor_evio_rate_scan::evnt(JEventLoop *loop, uint64_t eventnumber) { // Get CODA Event Info vector codainfos; loop->Get(codainfos); if(codainfos.empty()) return NOERROR; const DCODAEventInfo *codainfo = codainfos[0]; // Get DBeamCurrent const DBeamCurrent *curr=NULL; try{ loop->GetSingle(curr); }catch(...){} // Get time relative to RCDB recorded start time of event double t = (codainfo->avg_timestamp - rcdb_250MHz_offset_tics)/ticks_per_sec; // Increment bin for this second if(t>=0.0){ uint32_t it = (uint32_t)t; if( it < event_cnt.size() ){ event_cnt[it]++; if(curr) { CAS_loop_add(Ibeam_cnt[it], curr->Ibeam); if(curr->is_fiducial) CAS_loop_add(Ibeam_Isfiducial_cnt[it], curr->Ibeam); } } } return NOERROR; } //------------------ // erun //------------------ jerror_t JEventProcessor_evio_rate_scan::erun(void) { return NOERROR; } //------------------ // fini //------------------ jerror_t JEventProcessor_evio_rate_scan::fini(void) { // Create and fill histograms with values from atomic arrays TH1I *h = new TH1I("event_cnt", "Events per second vs. t;seconds since start of run (s)", event_cnt.size(), 0.0, (double)event_cnt.size()); for(uint32_t ibin=1; ibin<=event_cnt.size(); ibin++) h->SetBinContent(ibin, event_cnt[ibin-1]); TH1D *hI = new TH1D("Ibeam", "Beam current vs. t;seconds since start of run (s)", event_cnt.size(), 0.0, (double)event_cnt.size()); TH1D *hf = new TH1D("Ibeam_fiducial", "Beam current vs. t fiducial;seconds since start of run (s)", event_cnt.size(), 0.0, (double)event_cnt.size()); for(uint32_t ibin=1; ibin<=event_cnt.size(); ibin++){ if(event_cnt[ibin-1] == 0.0) continue; hI->SetBinContent(ibin, Ibeam_cnt[ibin-1]/event_cnt[ibin-1]); hf->SetBinContent(ibin, Ibeam_Isfiducial_cnt[ibin-1]/event_cnt[ibin-1]); } return NOERROR; }