ChannelData.cc

00001 #include "ChannelData.hh"
00002 #include "Message.hh"
00003 #include "TGraph.h"
00004 #include "TMultiGraph.h"
00005 #include "TAxis.h"
00006 #include "TLine.h"
00007 #include "TBox.h"
00008 #include "TPad.h"
00009 #include "TList.h"
00010 #include "TGaxis.h"
00011 #include "TMarker.h"
00012 #include <algorithm>
00013 #include <cmath>
00014 
00015 #include "intarray.hh"
00016 #include "EvalTGraphPoint.C"
00017 
00018 class Scale{
00019   double _offset;
00020   double _stretch;
00021 public:
00022   Scale(double offset, double stretch) : _offset(offset), _stretch(stretch) {}
00023   double operator()(double x){ return _stretch*x + _offset; }
00024 };
00025 
00026 TGraph* ChannelData::GetTGraph(bool baseline_subtracted, int downsample) const
00027 {
00028   if( nsamps < 2 || waveform.empty())
00029     return 0;
00030   if( baseline_subtracted && subtracted_waveform.empty())
00031     return 0;
00032   if(downsample < 1) downsample = 1;
00033   std::vector<double> x(nsamps/downsample);
00034   std::vector<double> ycpy( downsample>1 ? nsamps/downsample : 0);
00035   //double y[(const int)nsamps];
00036   const double* y = (baseline_subtracted ? GetBaselineSubtractedWaveform() :
00037                      GetWaveform() );
00038   for(int i=0; i<nsamps/downsample; i++){
00039     x[i] = (i*downsample - trigger_index) / sample_rate;
00040     if(downsample > 1)
00041       ycpy[i] = y[i*downsample];
00042   }
00043   TGraph* graph = new TGraph(nsamps/downsample,&x[0],
00044                              (downsample > 1 ? &(ycpy[0]) : y) );
00045   char name[30];
00046   if(label != "")
00047     sprintf(name,"%i-%s",channel_id, label.c_str());
00048   else 
00049     sprintf(name,"%i",channel_id);
00050   graph->SetName(name);
00051   graph->SetTitle(name);
00052   graph->SetEditable(false);
00053   //graph->GetXaxis()->SetTitle("sample time [#mu s]");
00054   //graph->SetMarkerStyle(7);
00055   return graph;
00056 }
00057 
00058 void ChannelData::Draw(bool baseline_subtracted, int downsample,
00059                        bool autoscalex, bool autoscaley, 
00060                        double xmin, double xmax, double ymin, double ymax)
00061 {
00062   if(downsample < 1) downsample = 1;
00063   TGraph* chgraph = GetTGraph(baseline_subtracted,downsample);
00064   if(!chgraph)
00065     return;
00066   int ns = chgraph->GetN();
00067   TMultiGraph* graphs = new TMultiGraph;
00068   graphs->SetBit(TObject::kCanDelete, true);
00069   Double_t* x = chgraph->GetX();
00070   graphs->Add(chgraph);
00071   graphs->SetName(chgraph->GetName());
00072   graphs->SetTitle(chgraph->GetTitle());
00073     
00074   //see if the derivative is there
00075   if((int)derivative.size() == nsamps){
00076     std::vector<double> scaled_derivative(ns);
00077     for(int i=0; i<ns; i++){
00078       scaled_derivative[i] = derivative[i*downsample]*3;
00079     }
00080    
00081     TGraph* dergraph = new TGraph(ns, x, &scaled_derivative[0]);
00082     
00083     //dergraph->SetMarkerStyle(7);
00084     dergraph->SetLineColor(kRed);
00085     dergraph->SetMarkerColor(kRed);
00086     graphs->Add(dergraph);
00087   }
00088   
00089     
00090   if((int)smoothed_data.size() == nsamps){
00091     
00092     TGraph* smoothgraph = 0;
00093     if(downsample > 1 ){
00094       std::vector<double> smoothcp(ns);
00095       for(int i=0; i<ns; i++)
00096         smoothcp[i] = smoothed_data[i*downsample];
00097       smoothgraph = new TGraph(ns,x,&(smoothcp[0]));
00098     }
00099     else
00100       smoothgraph = new TGraph(ns, x, &(smoothed_data[0]));
00101     smoothgraph->SetLineColor(kTeal);
00102     smoothgraph->SetMarkerColor(kTeal);
00103     graphs->Add(smoothgraph);
00104   }
00105   
00106   //add other graphs here
00107   //draw the baseline if present
00108   if (baseline.found_baseline &&!baseline_subtracted){                          
00109     std::vector<double> base(ns);                                  
00110     for (int i=0; i<ns; i++){                       
00111       base[i] = waveform[i*downsample] - subtracted_waveform[i*downsample]; 
00112     }                                                                        
00113     TGraph* basegraph = new TGraph(ns, x, &(base[0]));                 
00114     basegraph->SetLineColor(kRed);                                    
00115     basegraph->SetMarkerColor(kRed);                                    
00116     graphs->Add(basegraph);   
00117   } 
00118   
00119   
00120   graphs->Draw("alp");
00121   if( !autoscalex )
00122     graphs->GetXaxis()->SetRangeUser(xmin, xmax);
00123   if( !autoscaley )
00124     graphs->GetYaxis()->SetRangeUser(ymin, ymax);
00125   if(!autoscalex || !autoscaley)
00126     graphs->Draw("alp");
00127   
00128   //now look for the integral
00129   bool draw_integral = false;
00130   int integral_color = kBlue;
00131   double integral_scale=1, integral_offset=0;
00132   TGraph* integral_graph = 0;
00133   if((int)integral.size() == nsamps){
00134     
00135     draw_integral = true;
00136     //draw the integral along the baseline
00137     std::vector<double> shifted_integral(ns);
00138     double x1,x2,y1,y2;
00139     gPad->Update();
00140     gPad->GetRangeAxis(x1,y1,x2,y2);
00141     integral_offset = (baseline_subtracted ? 0 : baseline.mean);
00142     double raw_ratio = (y2 - integral_offset) / (integral_offset - y1);
00143     double integral_ratio = std::abs(integral_max) / std::abs(integral_min);
00144     if (raw_ratio < integral_ratio) {
00145       integral_scale = (y2 - integral_offset) / std::abs(integral_max) * 0.9;
00146     }else{
00147       integral_scale = (integral_offset - y1) / std::abs(integral_min) * 0.9;
00148     }
00149     for(int i=0;i<ns;i++){
00150       shifted_integral[i] = integral_scale*integral[i*downsample]+
00151         integral_offset;
00152     }
00153     integral_graph = new TGraph(ns, x, &shifted_integral[0]);
00154     integral_graph->SetLineColor(integral_color);
00155     integral_graph->SetMarkerColor(integral_color);
00156     graphs->Add(integral_graph);
00157   }
00158   
00159   //Draw the pulse start, end, and amplitude if there
00160   for(size_t i=0; i<pulses.size(); i++){
00161     Pulse& pulse = pulses[i];
00162     double base = (baseline_subtracted ? 0 : baseline.mean);
00163     if(pulse.found_start){
00164       double peaky = 0;
00165       if(pulse.found_peak)
00166         peaky = base - pulse.peak_amplitude;
00167       TBox* pbox = new TBox( x[pulse.start_index], base,
00168                              x[pulse.end_index], peaky);
00169       pbox->SetBit(TObject::kCanDelete,true);
00170       pbox->SetLineColor(kGreen);
00171       pbox->Draw();
00172       
00173       TLine* pline = new TLine( x[pulse.peak_index], base,
00174                                 x[pulse.peak_index], peaky);
00175       pline->SetBit(TObject::kCanDelete,true);
00176       pline->SetLineColor(kMagenta);
00177       pline->Draw();
00178     }
00179     if(pulse.fit.fit_done){
00180       bool time_based_fit = false;
00181       if(time_based_fit){
00182         TF1* fitfunc = pulse.fit.GetTF1();
00183         if (pulse.fit.fit_result == 0)
00184           fitfunc->SetLineColor(kGreen);
00185         else
00186           fitfunc->SetLineColor(kRed);
00187         fitfunc->SetBit(TObject::kCanDelete,true);
00188         fitfunc->Draw("same");
00189       }
00190       else{
00191         TF1* fitfunc = pulse.fit.GetTF1();
00192         const int nfitpts = pulse.fit.end_index - pulse.fit.start_index;
00193         if(nfitpts > 2){
00194           double fitx[nfitpts];
00195           double fity[nfitpts];
00196           for(int j=0; j<nfitpts; j++){
00197             fitx[j] = x[pulse.fit.start_index+j];
00198             fity[j] = fitfunc->Eval(pulse.fit.start_index + j);
00199           }
00200           TGraph* fitgraph = new TGraph(nfitpts, fitx, fity);
00201           fitgraph->SetBit(TObject::kCanDelete,true);
00202           if (pulse.fit.fit_result == 0)
00203             fitgraph->SetLineColor(kGreen);
00204           else
00205             fitgraph->SetLineColor(kRed);
00206           fitgraph->Draw("same");
00207         }
00208         delete fitfunc;
00209       }
00210     }
00211   }//end loop over pulses
00212     //Draw the region start, end, and amplitude if there
00213   for(size_t i=0; i<regions.size(); i++){
00214     Roi& region = regions[i];
00215     double base = (baseline_subtracted ? 0 : baseline.mean);
00216     
00217       double peaky = 0;
00218      
00219         peaky = base + region.min;
00220       TBox* pbox = new TBox( x[region.start_index], base,
00221                              x[region.end_index], peaky);
00222       pbox->SetBit(TObject::kCanDelete,true);
00223       pbox->SetLineColor(kGreen);
00224       pbox->Draw();
00225       if(draw_integral){
00226       TLine* iline = new TLine( x[region.min_index], base,
00227                                 x[region.min_index], base+region.integral*integral_scale);
00228       iline->SetBit(TObject::kCanDelete,true);
00229       iline->SetLineColor(kBlue);
00230       iline->SetLineWidth(4);
00231       iline->Draw();
00232       }
00233       TLine* pline = new TLine( x[region.min_index], base,
00234                                 x[region.min_index], peaky);
00235       pline->SetBit(TObject::kCanDelete,true);
00236       pline->SetLineColor(kMagenta);
00237       pline->Draw();
00238       
00239     
00240 
00241   }//end loop over regions
00242   //Draw boxes around the single photoelectrons
00243   for(size_t i = 0; i<single_pe.size(); i++){
00244     const Spe& spe = single_pe[i];
00245     TBox* spebox = 
00246       new TBox(spe.start_time, baseline.mean,
00247                spe.start_time + spe.length, 
00248                baseline.mean - spe.amplitude);
00249     spebox->SetBit(TObject::kCanDelete, true);
00250     spebox->SetLineColor(kRed);
00251     spebox->Draw();
00252   }
00253   
00254  //Draw boxes for each ROI
00255   /*
00256     TAxis* yax = graphs->GetYaxis();
00257     for(size_t i=0; i<regions.size(); i++){
00258     const Roi& roi = regions[i];
00259     TBox* roibox = new TBox(roi.start_time, yax->GetBinLowEdge(1), 
00260     roi.end_time, yax->GetBinUpEdge(yax->GetNbins()));
00261     roibox->SetBit(TObject::kCanDelete, true);
00262     //roibox->SetFillColor(kGreen);
00263     //roibox->SetFillStyle(3003);
00264     roibox->SetLineColor(kGreen);
00265     roibox->Draw("l");
00266     }
00267   */
00268   
00269   //mark the integral max and min;
00270   if(draw_integral){
00271     /*TMarker* max_integral = 
00272       new TMarker(integral_max_time, integral_graph->Eval(integral_max_time),
00273       3);*/
00274     TMarker* max_integral = 
00275       new TMarker(integral_max_time, 
00276                   EvalTGraphPoint(*integral_graph,integral_max_time),3);
00277     max_integral->SetMarkerColor(integral_color);
00278     max_integral->SetBit(TObject::kCanDelete, true);
00279     max_integral->Draw();
00280     /*TMarker* min_integral = 
00281       new TMarker(integral_min_time, integral_graph->Eval(integral_min_time),
00282       3);*/
00283     TMarker* min_integral = 
00284       new TMarker(integral_min_time, 
00285                   EvalTGraphPoint(*integral_graph,integral_min_time),3);
00286     min_integral->SetMarkerColor(integral_color);
00287     min_integral->SetBit(TObject::kCanDelete, true);
00288     min_integral->Draw();
00289     //draw a separate axis if the integral was drawn
00290     if(gPad){
00291       //gPad->Update();
00292       double x1,x2,y1,y2;
00293       gPad->GetRangeAxis(x1,y1,x2,y2);
00294       gPad->SetBit(TObject::kCanDelete, true);
00295       TGaxis* gaxis = new TGaxis(x2,y1,x2,y2,
00296                                  (y1-integral_offset)/integral_scale,
00297                                  (y2-integral_offset)/integral_scale,
00298                                  510,"L+");
00299       gaxis->SetName("integral_axis");
00300       if(channel_id == CH_SUM)
00301         gaxis->SetTitle("Integral [photoelectrons]"); 
00302       else
00303         gaxis->SetTitle("Integral [counts*samples]");
00304       gaxis->SetLineColor(integral_color);
00305       gaxis->SetTextColor(integral_color);
00306       gaxis->SetTitleColor(integral_color);
00307       gaxis->SetLabelColor(integral_color);
00308       gaxis->SetTitleOffset(1.2);
00309       gaxis->Draw();
00310     }
00311   
00312   }
00313   //label the xaxis
00314   graphs->GetXaxis()->SetTitle("sample time [#mus]");
00315   if(channel_id == CH_SUM)
00316     graphs->GetYaxis()->SetTitle("Amplitude [arb]");
00317   else
00318     graphs->GetYaxis()->SetTitle("Amplitude [counts]");
00319   
00320   //gPad->Update();
00321   
00322 }
00323 
00324 void ChannelData::Print(int verbosity)
00325 {
00326     {
00327         Message m(INFO);
00328         m<<"CHANNEL "<<channel_id<<std::endl;
00329         m<<"Timestamp: "<<timestamp<<std::endl; 
00330         m<<"Trigger Index: "<<trigger_index<<std::endl;
00331         m<<"Smoothed Min: "<<smoothed_min<<std::endl; 
00332         m<<"Smoothed Max: "<<smoothed_max<<std::endl;
00333         m<<"Saturated: "<<saturated<<std::endl;
00334         m<<"Maximum: "<<maximum<<std::endl;
00335         m<<"Minimum: "<<minimum<<std::endl;
00336         m<<"Max Time: "<<max_time<<std::endl;
00337         m<<"Min Time: "<<min_time<<std::endl;
00338         m<<"SPE Mean: "<<spe_mean<<std::endl;
00339         m<<"SPE Sigma: "<<spe_sigma<<std::endl;
00340         m<<"Baseline Found: "<<baseline.found_baseline<<std::endl;
00341         m<<"Baseline Mean: "<<baseline.mean<<std::endl;
00342         m<<"Baseline Variance: "<<baseline.variance<<std::endl;
00343         m<<"Baseline Search Start Index: "<<baseline.search_start_index<<std::endl;
00344         m<<"Baseline Length: "<<baseline.length<<std::endl;
00345         m<<"Baseline Saturated: "<<baseline.saturated<<std::endl;
00346         m<<"Baseline Laser Skip: "<<baseline.laserskip<<std::endl;
00347         m<<"No. of Pulses: "<<npulses<<std::endl;
00348         m<<"Integral Max: "<<integral_max<<std::endl;
00349         m<<"Integral Min: "<<integral_min<<std::endl;
00350         m<<"Integral Max Time: "<<integral_max_time<<std::endl;
00351         m<<"Integral Min Time: "<<integral_min_time<<std::endl;
00352         m<<"Integral Max Index: "<<integral_max_index<<std::endl;
00353         m<<"Integral Min Index: "<<integral_min_index<<std::endl;
00354         m<<"Integral Max Time: "<<integral_max_time<<std::endl;
00355         m<<"S1 Full: "<<s1_full<<std::endl;
00356         m<<"S1 Fixed: "<<s1_fixed<<std::endl;
00357         m<<"S2 Full: "<<s2_full<<std::endl;
00358         m<<"S2 Fixed: "<<s2_fixed<<std::endl;
00359     }
00360     if (verbosity > 1)
00361     {
00362         for (int i = 0; i < npulses; i++)
00363         {
00364             pulses[i].Print(channel_id, i);
00365         }
00366     }
00367 }
00368         
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1