ProcessedPlotter.cc

00001 #include "ProcessedPlotter.hh"
00002 #include "RootGraphix.hh"
00003 #include "PulseFinder.hh"
00004 #include "Differentiator.hh"
00005 #include "SumChannels.hh"
00006 #include "BaselineFinder.hh"
00007 #include "Fitter.hh"
00008 #include "SpeFinder.hh"
00009 #include "ConvertData.hh"
00010 #include "EventHandler.hh"
00011 #include "ConfigHandler.hh"
00012 #include "CommandSwitchFunctions.hh"
00013 #include "V172X_Params.hh"
00014 #include "EvalRois.hh"
00015 #include "Integrator.hh"
00016 #include "S1S2Evaluation.hh"
00017 #include "PadZoomer.hh"
00018 
00019 #include <algorithm>
00020 #include <sstream>
00021 
00022 #include "TCanvas.h"
00023 #include "TColor.h"
00024 #include "TGraph.h"
00025 #include "TMultiGraph.h"
00026 #include "TH2F.h"
00027 #include "TAxis.h"
00028 #include "TLegend.h"
00029 #include "TList.h"
00030 #include "TMath.h"
00031 #include "TDirectory.h"
00032 #include "TMarker.h"
00033 #include "TEllipse.h"
00034 #include "TPaveLabel.h"
00035 
00036 const int colors[] = {kBlack, kRed, kGreen, kCyan, kBlue, kMagenta, kYellow, 
00037                       kGray+2, kOrange-3, kGreen+3, kCyan+3, kMagenta-5, 
00038                       kRed-2};
00039 const int ncolors = sizeof(colors)/sizeof(int); 
00040 
00041 
00042 ProcessedPlotter::ProcessedPlotter() : 
00043   BaseModule(GetDefaultName(), 
00044              "Plot each channel's waveform and selected analysis results"),
00045   _graphix(0), _paused(false)
00046 {
00047   
00048   AddDependency<ConvertData>();
00049   AddDependency<RootGraphix>();
00050   //Register all the config handler parameters
00051   //RegisterParameter("multi_canvas",multi_canvas = true);
00052   RegisterParameter("chans_per_pad", chans_per_pad = 8,
00053                     "Maximum number of channels to stack on a single plot");
00054   RegisterParameter("overlay_analysis", overlay_analysis = true,
00055                     "Overlay the raw data with analysis module output (if only 1 channel in the pad)?");
00056   RegisterParameter("multi_color", multi_color = true,
00057                     "Draw with multiple colors?");
00058   RegisterParameter("draw_legend", draw_legend = true,
00059                     "Include a legend with the plot?");
00060   RegisterParameter("draw_title", draw_title = false,
00061                     "Draw a separate title on the pulses plot?");
00062   RegisterParameter("autoscalex", autoscalex = true,
00063                     "Set the scale of the x axis automatically?");
00064   RegisterParameter("autoscaley",autoscaley = true,
00065                     "Set the scale of the y axis automatically?");
00066   RegisterParameter("xmin", xmin = -10, "Minimum range of the x axis");
00067   RegisterParameter("xmax", xmax = 10, "Maximum range of the x axis");
00068   RegisterParameter("ymin", ymin = 0, "Minimum range of the y axis");
00069   RegisterParameter("ymax", ymax = 16383, "Maximum range of the y axis");
00070   RegisterParameter("subtract_baseline", subtract_baseline = false,
00071                     "Subtract the baseline before plotting?");
00072   RegisterParameter("downsample",downsample=1,
00073                     "Factor by which to downsample graphed waveforms");
00074   
00075   RegisterParameter("drawpulses",drawpulses = true,
00076                     "Enable drawing of raw pulses?");
00077   RegisterParameter("drawpmtweights",drawpmtweights = false,
00078                     "Enable drawing of PMT weights graph?");
00079   RegisterParameter("scale_pmts_sum",scale_pmts_sum = false,
00080                     "Scale PMT weights to sum (true) or max (false)");
00081   
00082   
00083   for(int i=0; i<NCANVASES; ++i)
00084     _canvas[i] = 0;
00085 }
00086 
00087 ProcessedPlotter::~ProcessedPlotter()
00088 {
00089   Finalize();
00090 }
00091 
00092 int ProcessedPlotter::Initialize()
00093 {
00094   EventHandler* evhandler = EventHandler::GetInstance();
00095   _graphix = evhandler->GetModule<RootGraphix>();
00096   if(!_graphix){
00097     //shouldn't happen...
00098     Message(ERROR)<<"ProcessedPlotter called Initialize, but no RootGraphix!\n";
00099     return 1;
00100   }
00101   
00102   //only draw pmt weights if there is pmt info from the database
00103 
00104     drawpmtweights = false;
00105   //also disable pmtweights if not S1S2Evaluation
00106   S1S2Evaluation* eval = evhandler->GetModule<S1S2Evaluation>();
00107   if(!eval || !eval->enabled)
00108     drawpmtweights = false;
00109   
00110   if(!drawpulses && !drawpmtweights){
00111     Message(ERROR)<<"Processed plotter is enabled, but all draw functions "
00112                   <<"are disabled. Aborting\n";
00113     return 2;
00114   }
00115   
00116   if(drawpulses){
00117     _canvas[PULSES] = _graphix->GetCanvas();
00118     if(draw_title){
00119       //add a pad to hold the title
00120       RootGraphix::Lock glock = _graphix->AcquireLock();
00121       _canvas[PULSES]->Divide(1,2);
00122       _canvas[PULSES]->cd(1);
00123       double y=0.95;
00124       gPad->SetPad(0,y,1,1);
00125       TPaveLabel* subtitle = new TPaveLabel(0.08,0,0.92,1,"","NDC");
00126       subtitle->SetBorderSize(0);
00127       subtitle->SetBit(TObject::kCanDelete,true);
00128       subtitle->SetTextColor(kYellow);
00129       subtitle->SetFillColor(kBlue);
00130       subtitle->SetFillStyle(1001);
00131       subtitle->SetTextFont(62);
00132       subtitle->SetTextSize(1.1);
00133       subtitle->Draw();
00134       _canvas[PULSES]->cd(2);
00135       gPad->SetPad(0,0,1,y);
00136     }
00137   }
00138     
00139   if(drawpmtweights)
00140     _canvas[PMTWEIGHTS] = _graphix->GetCanvas();
00141   
00142   if(downsample < 1) downsample = 1;
00143   return 0;
00144 }
00145 
00146 int ProcessedPlotter::Finalize()
00147 {
00148   for(int i=0; i<NCANVASES; ++i)
00149     _canvas[i] = 0;
00150   return 0;
00151 }
00152 
00153 int ProcessedPlotter::Process(EventPtr event)
00154 {
00155   if(_paused) return 0;
00156   EventDataPtr data = event->GetEventData();
00157   Message(DEBUG3)<<"ProcessedPlotter: Acquiring graphics lock.\n";
00158   RootGraphix::Lock glock = _graphix->AcquireLock();
00159   Message(DEBUG3)<<"ProcessedPlotter: Successfully acquired graphics lock.\n";
00160   char title[30];
00161   sprintf(title, "Run %d - Event %d", data->run_id, data->event_id);
00162   if(drawpulses && _canvas[PULSES]){
00163     _canvas[PULSES]->SetTitle(title);
00164     TPad* pulsepad = _canvas[PULSES];
00165     if(draw_title){
00166       //draw the run+event label
00167       _canvas[PULSES]->cd(1);
00168       if(gPad->GetListOfPrimitives() && 
00169          gPad->GetListOfPrimitives()->GetEntries() == 1){
00170         TPaveLabel* label = (TPaveLabel*)(gPad->GetListOfPrimitives()->At(0));
00171         if(label){
00172           label->SetLabel(title);
00173           gPad->Modified();
00174         }
00175       }
00176       pulsepad = (TPad*)(_canvas[PULSES]->cd(2));
00177       if(!pulsepad){
00178         Message(ERROR)<<"ProcessedPlotter: Unable to find pulse pad!\n";
00179         return 1;
00180       }
00181     }
00182     pulsepad->Clear();
00183     //Organize pads by number of channels
00184     // get only the channels not excluded
00185     int nchans = 0;
00186     std::vector<ChannelData*> chans_to_draw;
00187     for( size_t ch = 0; ch < data->channels.size(); ch++){
00188       if( _skip_channels.find(data->channels[ch].channel_id) == 
00189           _skip_channels.end() ){
00190         nchans++;
00191         chans_to_draw.push_back(&(data->channels[ch]));
00192       }
00193       
00194     }
00195     
00196     int cpp = chans_per_pad;
00197     if(cpp < 1)
00198       cpp = (nchans > 0 ? nchans : 1);
00199     int total_pads = (nchans+cpp-1)/cpp;
00200     
00201     if(total_pads == 0)
00202       return 0;
00203     else if(total_pads == 1) {}
00204     else if(total_pads == 2)
00205       pulsepad->Divide(2,1);
00206     else if(total_pads < 5)
00207       pulsepad->Divide(2,2);
00208     else if(total_pads < 7)
00209       pulsepad->Divide(3,2);
00210     else if(total_pads < 10)
00211       pulsepad->Divide(3,3);
00212     else if(total_pads < 13)
00213       pulsepad->Divide(4,3);
00214     else if(total_pads < 17)
00215       pulsepad->Divide(4,4);
00216     else if(total_pads < 21)
00217       pulsepad->Divide(5,4);
00218     else if(total_pads < 26)
00219       pulsepad->Divide(5,5);
00220     else if(total_pads < 31)
00221       pulsepad->Divide(6,5);
00222     else if(total_pads < 37)
00223       pulsepad->Divide(6,6);
00224     else if(total_pads < 43)
00225       pulsepad->Divide(7,6);
00226     else{
00227       int rootpads = (int)(ceil(sqrt(total_pads)));
00228       pulsepad->Divide(rootpads,rootpads);
00229     }
00230     for(int pad=0; pad<total_pads; pad++){
00231       pulsepad->cd( (total_pads == 1 ? 0 : pad+1 ) );
00232       
00233       if( overlay_analysis && (cpp == 1 || nchans == 1) ){
00234         chans_to_draw[pad]->Draw(subtract_baseline, downsample,
00235                                  autoscalex, autoscaley, 
00236                                  xmin, xmax, ymin, ymax);
00237       }
00238       else{
00239         int chans_this_pad = std::min(cpp, nchans-pad*cpp);
00240         TMultiGraph* graphs = new TMultiGraph;
00241         graphs->SetBit(TObject::kCanDelete, true);
00242         TLegend* legend = 0;
00243         if(draw_legend && chans_this_pad > 1){
00244           legend = new TLegend(0,.9,1,1);
00245           legend->SetBit(TObject::kCanDelete, true);
00246           legend->SetNColumns(4);
00247           legend->SetColumnSeparation(-.3);
00248           legend->SetMargin(0.25);
00249         }
00250         
00251         for(int i = pad*cpp; 
00252             i < (pad+1)*cpp && i < nchans; i++){
00253           TGraph* g = chans_to_draw[i]->GetTGraph(subtract_baseline,downsample);
00254           if(!g) continue;
00255           if(multi_color && chans_this_pad>1){
00256             g->SetLineColor(colors[abs(chans_to_draw[i]->channel_id)%ncolors]);
00257             //int id = data->channels[i].channel_id;
00258             //g->SetLineColor(TColor::GetColor(85 * ((id&1)+(id&8)/8), 
00259             //85 * ((id&2)/2 + (id&16)/16), 
00260             //                             85 * ((id&4)/4 + (id&32)/32) ));
00261             g->SetMarkerColor(g->GetLineColor());
00262             g->SetFillColor(g->GetLineColor());
00263           }
00264           if(legend)
00265             legend->AddEntry(g, g->GetTitle(), "lpf");
00266           graphs->Add(g);
00267           if(chans_this_pad == 1)
00268             graphs->SetTitle(g->GetTitle());
00269           
00270         }
00271         
00272         graphs->Draw("alp");
00273         if(!autoscalex)
00274           graphs->GetXaxis()->SetRangeUser(xmin, xmax);
00275         if(!autoscaley)
00276           graphs->GetYaxis()->SetRangeUser(ymin, ymax);
00277         
00278         /*TAxis* yax = graphs->GetYaxis();
00279           if(yax)
00280           yax->SetLabelOffset(0);
00281           TAxis* xax = graphs->GetXaxis();
00282           if(xax)
00283           xax->SetTitle("sample time [#mu s]");
00284         */
00285         if(legend)
00286           legend->Draw();
00287         
00288       }
00289     }
00290     // update the last pad
00291     if(!autoscalex || !autoscaley )
00292       gPad->Modified();
00293     _canvas[PULSES]->cd(0);
00294     _canvas[PULSES]->SetSelected(0);
00295     //_canvas[PULSES]->Update();
00296     new PadZoomer(pulsepad);
00297   }
00298   
00299 
00300   return 0;
00301 }
00302 
00303 
00304 const TCanvas* ProcessedPlotter::GetCanvas(int i) const
00305 { 
00306   if (i == 0 || i == 1) 
00307     return _canvas[i]; 
00308   else
00309     {
00310       Message(ERROR)<<"ProcessedPlotter::GetCanvas()"<<std::endl
00311                     <<"Attempt to access non-existent canvas"
00312                     <<std::endl;
00313       return NULL;
00314     }
00315 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1