/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . * */ #include #include #include #include #include #include "TCanvas.h" #include "TH1D.h" #include "TMinuit.h" #include "TFitResult.h" #include "TF1.h" #include "TLatex.h" #include "TPaveText.h" #include "TPaveStats.h" #include "src/common_cpp/DataStructure/Data.hh" #include "src/common_cpp/DataStructure/Spill.hh" #include "src/common_cpp/DataStructure/ReconEvent.hh" #include "src/common_cpp/DataStructure/SciFiEvent.hh" #include "src/common_cpp/DataStructure/SciFiSpacePoint.hh" #include "src/common_cpp/DataStructure/ImageData/ImageData.hh" #include "src/common_cpp/DataStructure/ImageData/Image.hh" #include "src/common_cpp/DataStructure/ImageData/CanvasWrapper.hh" #include "src/legacy/Interface/STLUtils.hh" #include "Utils/Squeak.hh" #include "src/reduce/ReduceCppSciFiPlot/ReduceCppSciFiPlot.hh" namespace MAUS { PyMODINIT_FUNC init_ReduceCppSciFiPlot(void) { PyWrapReduceBase::PyWrapReduceBaseModInit( "ReduceCppSciFiPlot", "", "", "", ""); } ReduceCppSciFiPlot::ReduceCppSciFiPlot() : ReduceBase("ReduceCppSciFiPlot") {} ReduceCppSciFiPlot::~ReduceCppSciFiPlot() { // Everything will be deleted by the ImageData destructor. } void ReduceCppSciFiPlot::_birth(const std::string& argJsonConfigDocument) { if (!_output) { throw MAUS::Exceptions::Exception(Exceptions::nonRecoverable, "The output is disconnected.", "ReduceCppSciFiPlot::_birth"); } if (!_output->GetImage()) _output->SetImage(new MAUS::Image()); // JsonCpp setup Json::Value configJSON; configJSON = JsonWrapper::StringToJson(argJsonConfigDocument); _refresh_rate = configJSON["reduce_plot_refresh_rate"].asInt(); // Set ROOT to batch mode by default unless specified otherwise int root_batch_mode = 1; if ( configJSON["root_batch_mode"].isInt() ) root_batch_mode = configJSON["root_batch_mode"].asInt(); if ( root_batch_mode ) gROOT->SetBatch(); // setup vectors to hold histogram objects std::vector sp_types; std::vector tku_sptrips, tkd_sptrips; std::vector tku_spdoubs, tkd_spdoubs; std::vector dig_st_vec, sp_st_vec; std::vector kuno_vec; // reusable histogram name and title strings std::string h_name, h_title; // setup histograms _eff_plot = new TH1F("SP_Type", "Spacepoint Type Across All Stations; Station;", 5, -0.5, 4.5); _track1_2Clus = new TH1F("Tr1pStSp", "Spacepoint Doublets TKU; Station;", 5, 0.5, 5.5); _track2_2Clus = new TH1F("Tr2pStSp", "Spacepoint Doublets TKD; Station", 5, 0.5, 5.5); _track1_3Clus = new TH1F("Tr1pStSp", "Spacepoint Triplets TKU; Station;", 5, 0.5, 5.5); _track2_3Clus = new TH1F("Tr2pStSp", "Spacepoint Triplets TKD; Station;", 5, 0.5, 5.5); // push into a vector all histograms belonging to same canvas sp_types.push_back(_eff_plot); sp_types.push_back(_track1_3Clus); sp_types.push_back(_track2_3Clus); sp_types.push_back(_track1_2Clus); sp_types.push_back(_track2_2Clus); // setup histograms per tracker/station/plane for (int tr = 0; tr < 2; ++tr) { std::string trs; if (tr == 0) trs = "U"; if (tr == 1) trs = "D"; // digits per station, one for each tracker h_name = "Digits_TK" + trs; h_title = "Digits per Station TK" + trs; _dig_st_hist[tr] = new TH1F(h_name.c_str(), h_title.c_str(), 5, 0.5, 5.5); _dig_st_hist[tr]->GetXaxis()->SetTitle("Station"); _histos.push_back(_dig_st_hist[tr]); dig_st_vec.push_back(_dig_st_hist[tr]); // spacepoints per station, one for each tracker h_name = "SP_TK" + trs; h_title = "Spacepoints per Station TK" + trs; _sp_st_hist[tr] = new TH1F(h_name.c_str(), h_title.c_str(), 5, 0.5, 5.5); _sp_st_hist[tr]->GetXaxis()->SetTitle("Station"); _histos.push_back(_sp_st_hist[tr]); sp_st_vec.push_back(_sp_st_hist[tr]); // kuno sum, one for each tracker h_name = "Kuno_Sum_TK" + trs; h_title = "Kuno Sum TK" + trs; _kuno_hist[tr] = new TH1F(h_name.c_str(), h_title.c_str(), 670, -5, 642); _kuno_hist[tr]->GetXaxis()->SetTitle("Channel sum"); _histos.push_back(_kuno_hist[tr]); kuno_vec.push_back(_kuno_hist[tr]); // go through all stations, /* NOTE station numbers run from 1->5 */ for (int st = 1; st < 6; ++st) { // XY 2d of triplets h_name = "SP_Triplet TK" + trs + " Station " + std::to_string(st); h_title = "Space Point Triplets TK" + trs + " Station " + std::to_string(st); _spt_hist[tr][st] = new TH2F(h_name.c_str(), h_title.c_str(), 200, -200, 200, 200, -200, 200); _spt_hist[tr][st]->GetXaxis()->SetTitle("X [mm]"); _spt_hist[tr][st]->GetYaxis()->SetTitle("Y [mm]"); // XY 2d of doublets h_name = "SP_Doublet TK" + trs + " Station " + std::to_string(st); h_title = "Space Point Doublets TK" + trs + " Station " + std::to_string(st); _spd_hist[tr][st] = new TH2F(h_name.c_str(), h_title.c_str(), 200, -200, 200, 200, -200, 200); _spd_hist[tr][st]->GetXaxis()->SetTitle("X [mm]"); _spd_hist[tr][st]->GetYaxis()->SetTitle("Y [mm]"); if (tr == 0) { tku_sptrips.push_back(_spt_hist[tr][st]); tku_spdoubs.push_back(_spd_hist[tr][st]); } if (tr == 1) { tkd_sptrips.push_back(_spt_hist[tr][st]); tkd_spdoubs.push_back(_spd_hist[tr][st]); } for (int pl = 0; pl < 3; ++pl) { // digits per channel, for each station, each tracker h_name = "DC_Tk" + trs + std::to_string(st) + std::to_string(pl); h_title = "Digits per Channel TK" + trs + std::to_string(st) + std::to_string(pl); if (tr == 0) { _dig_ch_hist_up[st][pl] = new TH1F(h_name.c_str(), h_title.c_str(), 215, 0, 215); _dig_ch_hist_up[st][pl]->GetXaxis()->SetTitle("Channel"); tku_digs.push_back(_dig_ch_hist_up[st][pl]); _histos.push_back(_dig_ch_hist_up[st][pl]); } if (tr == 1) { _dig_ch_hist_dn[st][pl] = new TH1F(h_name.c_str(), h_title.c_str(), 215, 0, 215); _dig_ch_hist_dn[st][pl]->GetXaxis()->SetTitle("Channel"); _histos.push_back(_dig_ch_hist_dn[st][pl]); tkd_digs.push_back(_dig_ch_hist_dn[st][pl]); } } } } // now, setup the canvases to draw histograms on TCanvas* _canvas_SciFiSpacepoints = new TCanvas("SciFiReduce_SPtypes", "Spacepoint_Types_in_Stations", 1200, 800); TCanvas* _canvas_SciFiDigitUS = new TCanvas("SciFiReduce_TKU_DigsPerChannel", "Digit_in_Channel_US", 1200, 800); TCanvas* _canvas_SciFiDigitDS = new TCanvas("SciFiReduce_TKD_DigsPerChannel", "Digit_in_Channel_DS", 1200, 800); TCanvas* _canvas_US_trip = new TCanvas("SciFiReduce_TKU_triplet_xy", "Spacepoint_Triplets_Up", 1200, 800); TCanvas* _canvas_DS_trip = new TCanvas("SciFiReduce_TKD_triplet_xy", "Spacepoint_Triplets_Down", 1200, 800); TCanvas* _canvas_US_doub = new TCanvas("SciFiReduce_TKU_doublet_xy", "Spacepoint_Doublets_Up", 1200, 800); TCanvas* _canvas_DS_doub = new TCanvas("SciFiReduce_TKD_doublet_xy", "Spacepoint_Doublets_Down", 1200, 800); TCanvas* _canvas_dig_st = new TCanvas("SciFiReduce_Digits", "Digits Per Station", 1200, 800); TCanvas* _canvas_sp_st = new TCanvas("SciFiReduce_Spacepoints", "Spacepoints Per Station", 1200, 800); TCanvas* _canvas_Kuno = new TCanvas("SciFiReduce_Kuno", "Kuno Sum", 1200, 800); // push canvas objects into a vector _canvs.push_back(_canvas_SciFiSpacepoints); _canvs.push_back(_canvas_SciFiDigitUS); _canvs.push_back(_canvas_SciFiDigitDS); _canvs.push_back(_canvas_US_trip); _canvs.push_back(_canvas_DS_trip); _canvs.push_back(_canvas_US_doub); _canvs.push_back(_canvas_DS_doub); _canvs.push_back(_canvas_dig_st); _canvs.push_back(_canvas_sp_st); _canvs.push_back(_canvas_Kuno); // push histos into vector // the histograms in this vec will get reset in the reset() method _histos.push_back(_eff_plot); _histos.push_back(_track1_2Clus); _histos.push_back(_track2_2Clus); _histos.push_back(_track1_3Clus); _histos.push_back(_track2_3Clus); _histos.insert(_histos.begin(), tku_digs.begin(), tku_digs.end()); _histos.insert(_histos.begin(), tkd_digs.begin(), tkd_digs.end()); _histos.insert(_histos.begin(), sp_types.begin(), sp_types.end()); _histos.insert(_histos.begin(), tku_sptrips.begin(), tku_sptrips.end()); _histos.insert(_histos.begin(), tkd_sptrips.begin(), tkd_sptrips.end()); _histos.insert(_histos.begin(), tku_spdoubs.begin(), tku_spdoubs.end()); _histos.insert(_histos.begin(), tkd_spdoubs.begin(), tkd_spdoubs.end()); _histos.insert(_histos.begin(), dig_st_vec.begin(), dig_st_vec.end()); _histos.insert(_histos.begin(), sp_st_vec.begin(), sp_st_vec.end()); _histos.insert(_histos.begin(), kuno_vec.begin(), kuno_vec.end()); // setup canvas wrappers to hold histograms+canvases CanvasWrapper *cwrap_eff = ReduceCppTools::get_canvas_divide_wrapper(_canvas_SciFiSpacepoints, 3, 2, false, sp_types, "TKSpacePointTypes"); CanvasWrapper *cwrap_digUS = ReduceCppTools::get_canvas_divide_wrapper(_canvas_SciFiDigitUS, 3, 5, false, tku_digs, "TKUdigitsPerChannel"); CanvasWrapper *cwrap_digDS = ReduceCppTools::get_canvas_divide_wrapper(_canvas_SciFiDigitDS, 3, 5, false, tkd_digs, "TKDdigitsPerChannel"); CanvasWrapper *cwrap_US_tripxy = ReduceCppTools::get_canvas_divide_wrapper(_canvas_US_trip, 3, 2, false, tku_sptrips, "TKUtripletsXY", "TKUtripletsXY", "COLZ"); CanvasWrapper *cwrap_DS_tripxy = ReduceCppTools::get_canvas_divide_wrapper(_canvas_DS_trip, 3, 2, false, tkd_sptrips, "TKDtripletsXY", "TKDtripletsXY", "COLZ"); CanvasWrapper *cwrap_US_doubxy = ReduceCppTools::get_canvas_divide_wrapper(_canvas_US_doub, 3, 2, false, tku_spdoubs, "TKUdoubletsXY", "TKUdoubletsXY", "COLZ"); CanvasWrapper *cwrap_DS_doubxy = ReduceCppTools::get_canvas_divide_wrapper(_canvas_DS_doub, 3, 2, false, tkd_spdoubs, "TKDdoubletsXY", "TKDdoubletsXY", "COLZ"); CanvasWrapper *cwrap_dig_st = ReduceCppTools::get_canvas_divide_wrapper(_canvas_dig_st, 2, 1, false, dig_st_vec, "DigitsPerStation", "DigitsPerStation"); CanvasWrapper *cwrap_sp_st = ReduceCppTools::get_canvas_divide_wrapper(_canvas_sp_st, 2, 1, false, sp_st_vec, "SpacepointsPerStation", "SpacepointsPerStation"); CanvasWrapper *cwrap_Kuno = ReduceCppTools::get_canvas_divide_wrapper(_canvas_Kuno, 2, 1, false, kuno_vec, "TKKuno", "TKKuno"); // this->reset(); // get images from canvaswrappers _output->GetImage()->CanvasWrappersPushBack(cwrap_eff); _output->GetImage()->CanvasWrappersPushBack(cwrap_digUS); _output->GetImage()->CanvasWrappersPushBack(cwrap_digDS); _output->GetImage()->CanvasWrappersPushBack(cwrap_US_tripxy); _output->GetImage()->CanvasWrappersPushBack(cwrap_DS_tripxy); _output->GetImage()->CanvasWrappersPushBack(cwrap_US_doubxy); _output->GetImage()->CanvasWrappersPushBack(cwrap_DS_doubxy); _output->GetImage()->CanvasWrappersPushBack(cwrap_dig_st); _output->GetImage()->CanvasWrappersPushBack(cwrap_sp_st); _output->GetImage()->CanvasWrappersPushBack(cwrap_Kuno); } void ReduceCppSciFiPlot::_death() {} void ReduceCppSciFiPlot::_process(MAUS::Data* data) { if (data == NULL) throw Exceptions::Exception(Exceptions::recoverable, "Data was NULL", "ReduceCppSciFiPlot::_process"); if (data->GetSpill() == NULL) throw Exceptions::Exception(Exceptions::recoverable, "Spill was NULL", "ReduceCppSciFiPlot::_process"); std::string ev_type = data->GetSpill()->GetDaqEventType(); if (ev_type != "physics_event") return; if (data->GetSpill()->GetReconEvents() == NULL) throw Exceptions::Exception(Exceptions::recoverable, "ReconEvents were NULL", "ReduceCppSciFiPlot::_process"); int xRun = data->GetSpill()->GetRunNumber(); int xSpill = data->GetSpill()->GetSpillNumber(); _output->SetEventType(ev_type); _output->GetImage()->SetRunNumber(xRun); _output->GetImage()->SetSpillNumber(xSpill); ReconEventPArray* recon_events = data->GetSpill()->GetReconEvents(); for (size_t i = 0; i < recon_events->size(); ++i) { MAUS::SciFiEvent* scifi_event = recon_events->at(i)->GetSciFiEvent(); if (scifi_event == NULL) continue; this->update_scifi_plots(scifi_event, xRun); } _process_count++; if ( !(_process_count % _refresh_rate) ) this->update(); } void ReduceCppSciFiPlot::reset() { for (unsigned int i = 0; i < _histos.size(); i++) _histos[i]->Reset(); _process_count = 0; } void ReduceCppSciFiPlot::update() { for (unsigned int i = 0; i < _canvs.size(); i++) { _canvs[i]->cd()->Modified(); _canvs[i]->Update(); } } void ReduceCppSciFiPlot::update_scifi_plots(SciFiEvent* scifi_event, int runNum) { // get scifi digits MAUS::SciFiDigitPArray trk_digits = scifi_event->digits(); // clusters MAUS::SciFiClusterPArray trk_clusters = scifi_event->clusters(); // spacepoints MAUS::SciFiSpacePointPArray trk_spoints = scifi_event->spacepoints(); std::string htitle; // go through digits if (trk_digits.size()) { for (size_t d = 0; d < trk_digits.size(); ++d) { MAUS::SciFiDigit* dig = trk_digits[d]; int tr = dig->get_tracker(); int st = dig->get_station(); int pl = dig->get_plane(); int ch = dig->get_channel(); if (st < 0 || st > 5) continue; if (pl < 0 || pl > 2) continue; std::string trs; if (tr == 0) trs = "U"; if (tr == 1) trs = "D"; // Fill # digits per station _dig_st_hist[tr]->Fill(st); htitle = "Digits per Station TK" + trs + ", Run " + std::to_string(runNum); _dig_st_hist[tr]->SetTitle(htitle.c_str()); htitle = "Digits per Channel TK" + trs + " Station" + std::to_string(st) + " Plane" + std::to_string(pl) + ", Run " + std::to_string(runNum); if (tr == 0) { // Fill digits per channel _dig_ch_hist_up[st][pl]->Fill(ch); _dig_ch_hist_up[st][pl]->SetTitle(htitle.c_str()); } else if (tr == 1) { // Fill digits per channel _dig_ch_hist_dn[st][pl]->Fill(ch); _dig_ch_hist_dn[st][pl]->SetTitle(htitle.c_str()); } } // end loop over digits } // end check on if digits exist // now, go through spacepoints if (trk_spoints.size()) { int tkcnt[2], tkcnd[2]; std::vector chanlist[6]; for (unsigned int s = 0; s < trk_spoints.size(); ++s) { MAUS::SciFiSpacePoint* sp = trk_spoints[s]; int n_type = 0; double chansum = 0; int tr = sp->get_tracker(); int st = sp->get_station(); double x = sp->get_position().x(); double y = sp->get_position().y(); std::string trs; if (tr == 0) trs = "U"; if (tr == 1) trs = "D"; // Fill # spacepoints per station _sp_st_hist[tr]->Fill(st); htitle = "Spacepoints per Station TK" + trs + ", Run " + std::to_string(runNum); _sp_st_hist[tr]->SetTitle(htitle.c_str()); std::string sptype = sp->get_type(); // if triplet if (sptype == "triplet") { n_type = 3; tkcnt[tr] += 1; // Fill xy 2d for triplets for each station _spt_hist[tr][st]->Fill(x, y); htitle = "Spacepoint Triplets TK" + trs + " Station" + std::to_string(st) + ", Run " + std::to_string(runNum); _spt_hist[tr][st]->SetTitle(htitle.c_str()); MAUS::SciFiClusterPArray tripclus = sp->get_channels_pointers(); for (unsigned int cl = 0; cl < tripclus.size(); ++cl) { MAUS::SciFiCluster *clust = tripclus[cl]; // compute Kuno sum for triplets chansum += clust->get_channel(); } // Fill kuno histogram _kuno_hist[tr]->Fill(chansum); htitle = "Kuno Sum TK" + trs + ", Run " + std::to_string(runNum); _kuno_hist[tr]->SetTitle(htitle.c_str()); // fill # triplet spacepoints per station htitle = "Spacepoint Triplets TK" + trs + ", Run " + std::to_string(runNum); if (tr == 0) { _track1_3Clus->Fill(st); _track1_3Clus->SetTitle(htitle.c_str()); } else if (tr == 1) { _track2_3Clus->Fill(st); _track2_3Clus->SetTitle(htitle.c_str()); } } else { // doublet n_type = 2; tkcnd[tr] += 1; // Fill xy 2d for doublets for each station _spd_hist[tr][st]->Fill(x, y); htitle = "Spacepoint Doublets TK" + trs + " Station" + std::to_string(st) + ", Run " + std::to_string(runNum); _spd_hist[tr][st]->SetTitle(htitle.c_str()); // fill # doublet spacepoints per station if (tr == 0) _track1_2Clus->Fill(st); if (tr == 1) _track2_2Clus->Fill(st); } // histogram the spscepoint type across all stations in both trackers _eff_plot->Fill(n_type); } // end loop over spacepoints } // end check on spacepoint exists } } // MAUS