// $Id$ // // File: JEventProcessor_fmwpcview.cc // Created: Fri Oct 3 08:14:14 EDT 2014 // Creator: davidl (on Darwin harriet.jlab.org 13.4.0 i386) // #include #include #include using namespace std; #include "JEventProcessor_fmwpcview.h" using namespace jana; #include #include #include #include jv_mainframe *JVMF = NULL; JEventProcessor_fmwpcview *JEP=NULL; bool QUIT = false; // Routine used to create our JEventProcessor #include #include #include #include #include void fmwpcviewJANAThread(JApplication *japp); //------------------- // main //------------------- int main(int narg, char *argv[]) { // Create JANA JApplication JApplication *japp = new DApplication(narg, argv); // Create a ROOT TApplication object TApplication app("FMWPC Viewer", &narg, argv); app.SetReturnFromRun(true); JVMF = new jv_mainframe(gClient->GetRoot(), 1500, 1000, true); // Run JANA in separate thread thread t(fmwpcviewJANAThread, japp); try{ // app.Run(); while( !QUIT ){ if( JVMF->CanvasNeedsUpdate ) { // Update f125 canvas JVMF->CanvasNeedsUpdate = false; TCanvas *c = JVMF->canvasf125->GetCanvas(); for( int ipad=1; ipad<100; ipad++){ auto p = c->GetPad( ipad ); if(p == NULL) break; p->Modified(); } c->Update(); // Update f250 canvas c = JVMF->canvasf250->GetCanvas(); for( int ipad=1; ipad<100; ipad++){ auto p = c->GetPad( ipad ); if(p == NULL) break; p->Modified(); } c->Update(); } gSystem->ProcessEvents(); if(JVMF->continuous) JEP->NextEvent(); usleep(1000); } }catch(std::exception &e){ _DBG_ << "Exception: " << e.what() << endl; } japp->Quit(); return 0; } //------------------- // fmwpcviewJANAThread // // C-callable routine that can be used with pthread_create to launch // a thread that creates the ROOT GUI and handles all ROOT GUI interactions //------------------- void fmwpcviewJANAThread(JApplication *japp) { try{ japp->Run(new JEventProcessor_fmwpcview()); }catch(std::exception &e){ _DBG_ << "Exception: " << e.what() << endl; } } //============================================================================== //------------------ // JEventProcessor_fmwpcview (Constructor) //------------------ JEventProcessor_fmwpcview::JEventProcessor_fmwpcview() { Nrows = 3; Ncols = 4; id_start = 0; loop = NULL; eventnumber = 0; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); JEP = this; } //------------------ // ~JEventProcessor_fmwpcview (Destructor) //------------------ JEventProcessor_fmwpcview::~JEventProcessor_fmwpcview() { } //------------------ // init //------------------ jerror_t JEventProcessor_fmwpcview::init(void) { return NOERROR; } //------------------ // brun //------------------ jerror_t JEventProcessor_fmwpcview::brun(JEventLoop *loop, int32_t runnumber) { this->loop = loop; loop->EnableCallStackRecording(); return NOERROR; } //------------------ // evnt //------------------ jerror_t JEventProcessor_fmwpcview::evnt(JEventLoop *loop, uint64_t eventnumber) { // We need to wait here in order to allow the GUI to control when to // go to the next event. Lock the mutex and wait for the GUI to wake us japp->monitor_heartbeat = false; japp->SetShowTicker(false); pthread_mutex_lock(&mutex); // static bool processed_first_event = false; this->loop = loop; this->eventnumber = eventnumber; JEvent &jevent = loop->GetJEvent(); JEventSource *source = jevent.GetJEventSource(); JVMF->UpdateInfo(source->GetSourceName(), jevent.GetRunNumber(), jevent.GetEventNumber()); DrawHistos(); pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); return NOERROR; } //------------------ // NextEvent //------------------ void JEventProcessor_fmwpcview::NextEvent(void) { // This just unblocks the pthread_cond_wait() call in evnt(). pthread_cond_signal(&cond); } //------------------ // DrawHistos //------------------ void JEventProcessor_fmwpcview::DrawHistos(void) { // f125 vector wrds125; loop->Get(wrds125); TCanvas *c = JVMF->canvasf125->GetCanvas(); if( JVMF->hfmwpc.empty() && !wrds125.empty() ){ JVMF->Make125Histos( wrds125[0]->samples.size() ); c->Divide(Ncols, Nrows); } // Draw histograms only when starting id value has changed. // Otherwise, let ROOT update them without completing redrawing. static int last_id_start = -1; if( (id_start!=last_id_start) && (!JVMF->hfmwpc.empty()) ){ cout << "Redrawing histos starting with wireid=" << id_start << endl; for(int i=0; icd( ipad ); JVMF->hfmwpc[i + id_start]->Draw(); JVMF->hfmwpc_subtracted[i + id_start]->Draw("same"); } last_id_start = id_start; } for(auto h : JVMF->hfmwpc) h->Reset(); for(auto h : JVMF->hfmwpc_subtracted) h->Reset(); // These will hold info on the histogram used to subtract // noise from the other histograms int peak125 = 1E4; TH1I *hnorm = NULL; // Loop over all wires with data for this event set hit_wire_ids; for(auto wrd : wrds125){ uint32_t iwire = (71-wrd->channel) + (wrd->slot==3 ? 0:72); if( iwire >= JVMF->hfmwpc.size() ) continue; if( (int)iwire < id_start ) continue; if( (int)iwire >= id_start+Ncols*Nrows ) continue; hit_wire_ids.insert( iwire ); auto h = JVMF->hfmwpc[iwire]; auto Nbins = h->GetNbinsX(); int mypeak = 0; for(uint32_t i=0; isamples.size(); i++){ if( (int)i>=Nbins ) break; h->SetBinContent(i+1, wrd->samples[i]); if( wrd->samples[i] > mypeak ) mypeak=wrd->samples[i]; } if( mypeak < peak125 ){ peak125 = mypeak; hnorm = h; } } // Loop over hit wires and update subtracted histograms if( hnorm != NULL ){ for(auto iwire : hit_wire_ids){ auto h = JVMF->hfmwpc[iwire]; auto hs = JVMF->hfmwpc_subtracted[iwire]; if( (int)iwire < id_start ) continue; if( (int)iwire >= id_start+Ncols*Nrows ) continue; for(int ibin=1; ibin<=h->GetNbinsX(); ibin++){ int val = 100 + h->GetBinContent(ibin) - hnorm->GetBinContent(ibin); hs->SetBinContent(ibin, val); } } } // f250 vector wrds250; loop->Get(wrds250); c = JVMF->canvasf250->GetCanvas(); if( JVMF->hpaddles.empty() && !wrds250.empty() ){ JVMF->Make250Histos( wrds250[0]->samples.size() ); c->Divide(2, 2); c->cd(1); JVMF->hpaddles[3]->Draw(); c->cd(2); JVMF->hpaddles[2]->Draw(); c->cd(3); JVMF->hpaddles[1]->Draw(); c->cd(4); JVMF->hpaddles[0]->Draw(); } for(auto h : JVMF->hpaddles) h->Reset(); for(auto wrd : wrds250){ uint32_t ichan = wrd->channel; if( ichan >= JVMF->hpaddles.size() ) continue; auto h = JVMF->hpaddles[ichan]; auto Nbins = h->GetNbinsX(); double max = 0; double xmax = 0; for(uint32_t i=0; isamples.size(); i++){ if( (int)isamples[i]; h->SetBinContent(i+1, val); if((double)val > max) { max = (double)val; xmax = (double)i; } } } if( max > 250.0 ){ auto f = JVMF->fpaddles[ichan]; f->SetParameter(0, max); f->SetParameter(1, xmax); f->SetParameter(2, 2.0); f->SetParameter(3, 100.0); c->cd(ichan+1); h->Fit(f); } } if(!JVMF->hpaddles.empty()){ c->cd(1); JVMF->hpaddles[3]->Draw(); c->cd(2); JVMF->hpaddles[2]->Draw(); c->cd(3); JVMF->hpaddles[1]->Draw(); c->cd(4); JVMF->hpaddles[0]->Draw(); } JVMF->CanvasNeedsUpdate = !(wrds125.empty() && wrds250.empty()); } //------------------ // erun //------------------ jerror_t JEventProcessor_fmwpcview::erun(void) { // This is called whenever the run number changes, before it is // changed to give you a chance to clean up before processing // events from the next run number. return NOERROR; } //------------------ // fini //------------------ jerror_t JEventProcessor_fmwpcview::fini(void) { // Called before program exit after event processing is finished. return NOERROR; }