PulseShapeEval.cc

00001 #include "PulseShapeEval.hh"
00002 #include "intarray.hh"
00003 #include "BaselineFinder.hh"
00004 #include "SumChannels.hh"
00005 #include "PulseFinder.hh"
00006 #include "RootWriter.hh"
00007 #include <algorithm>
00008 #include <cmath>
00009 #include "TFile.h"
00010 #include "TH1F.h"
00011 
00012 PulseShapeEval::PulseShapeEval() : 
00013   BaseModule(GetDefaultName(), 
00014                 "Calculate pulse shape parameters for event discrimination")
00015 {
00016   AddDependency<BaselineFinder>();
00017   AddDependency<PulseFinder>();
00018 
00019   RegisterParameter("pulse_shape_file", pulse_shape_file="auxiliary_files/shapes.root",
00020                    "File containing reference pulse shapes");
00021   RegisterParameter("gatti_weights_hist", 
00022                     gatti_weights_hist="gatti_weights",
00023                     "Name of Gatti wieghts histogram");
00024   RegisterParameter("ll_ele_weights_hist", 
00025                     ll_ele_weights_hist="ll_ele_weights",
00026                     "Name of electron log-likelihood weights histogram");
00027   RegisterParameter("ll_nuc_weights_hist", 
00028                     ll_nuc_weights_hist="ll_nuc_weights",
00029                     "Name of nuclear recoil log-likelihood weights histogram");
00030   RegisterParameter("ll_r_weights_hist", 
00031                     ll_r_weights_hist="ll_r_weights",
00032                     "Name of log-likelihood ratio weights histogram");
00033 }
00034 
00035 PulseShapeEval::~PulseShapeEval()
00036 {
00037   Finalize();
00038 }
00039 
00040 int PulseShapeEval::Initialize() 
00041 { 
00042     int status =  PulseShapeEval::LoadWeights(); 
00043     
00044     return status;
00045 }
00046 
00047 int PulseShapeEval::Finalize() 
00048 { 
00049     std::map<int, TH1F*>::iterator mapit_gatti = gatti_weights.begin();
00050     std::map<int, TH1F*>::iterator mapit_ll_ele = ll_ele_weights.begin();
00051     std::map<int, TH1F*>::iterator mapit_ll_nuc = ll_nuc_weights.begin();
00052     std::map<int, TH1F*>::iterator mapit_ll_r = ll_r_weights.begin();
00053 
00054     for(; mapit_gatti != gatti_weights.end(); mapit_gatti++)
00055         delete mapit_gatti->second;
00056     for(; mapit_ll_ele != ll_ele_weights.end(); mapit_ll_ele++)
00057         delete mapit_ll_ele->second;
00058     for(; mapit_ll_nuc != ll_nuc_weights.end(); mapit_ll_nuc++)
00059         delete mapit_ll_nuc->second;
00060     for(; mapit_ll_r != ll_r_weights.end(); mapit_ll_r++)
00061         delete mapit_ll_r->second;
00062     
00063     gatti_weights.clear();
00064     ll_ele_weights.clear();
00065     ll_nuc_weights.clear();
00066     ll_r_weights.clear();
00067 
00068     return 0; 
00069 }
00070 
00071 int PulseShapeEval::LoadWeights()
00072 {
00073     //Basic checks
00074     TFile* f = new TFile(pulse_shape_file.c_str());
00075     if (f->IsZombie())
00076     {
00077         Message(ERROR)<<"Unable to open pulse shape file: "
00078                       <<pulse_shape_file<<std::endl;
00079         return 1;
00080     }
00081 
00082     //Loop over and find weights for all real channels
00083     for (int i = 0; i < 50; i++)
00084     {
00085         std::ostringstream gatti_name, ll_ele_name, ll_nuc_name, ll_r_name;
00086         gatti_name<<gatti_weights_hist<<"_"<<i;
00087         ll_ele_name<<ll_ele_weights_hist<<"_"<<i;
00088         ll_nuc_name<<ll_nuc_weights_hist<<"_"<<i;
00089         ll_r_name<<ll_r_weights_hist<<"_"<<i;
00090 
00091         if (! f->Get(gatti_name.str().c_str()) || 
00092             ! f->Get(ll_ele_name.str().c_str()) || 
00093             ! f->Get(ll_nuc_name.str().c_str()) || 
00094             ! f->Get(ll_r_name.str().c_str()))
00095         {
00096             break;
00097         }
00098 
00099         //ASSUMPTIONS
00100         // All weight histograms have the same binning
00101         
00102         //Load histograms of weights
00103         TH1F* gatti_weights_temp = (TH1F*) f->Get(gatti_name.str().c_str())->Clone();
00104         TH1F* ll_ele_weights_temp = (TH1F*) f->Get(ll_ele_name.str().c_str())->Clone();
00105         TH1F* ll_nuc_weights_temp = (TH1F*) f->Get(ll_nuc_name.str().c_str())->Clone();
00106         TH1F* ll_r_weights_temp = (TH1F*) f->Get(ll_r_name.str().c_str())->Clone();
00107         
00108         //Disassociate histograms from ROOT file - stupid ROOT !
00109         gatti_weights_temp->SetDirectory(0);
00110         ll_ele_weights_temp->SetDirectory(0);
00111         ll_nuc_weights_temp->SetDirectory(0);
00112         ll_r_weights_temp->SetDirectory(0);
00113 
00114         gatti_weights.insert(std::make_pair(i, gatti_weights_temp));
00115         ll_ele_weights.insert(std::make_pair(i, ll_ele_weights_temp));
00116         ll_nuc_weights.insert(std::make_pair(i, ll_nuc_weights_temp));
00117         ll_r_weights.insert(std::make_pair(i, ll_r_weights_temp));
00118     }
00119 
00120     //Load weights for SUM channel
00121     std::ostringstream gatti_name, ll_ele_name, ll_nuc_name, ll_r_name;
00122     gatti_name<<gatti_weights_hist<<"_-2";
00123     ll_ele_name<<ll_ele_weights_hist<<"_-2";
00124     ll_nuc_name<<ll_nuc_weights_hist<<"_-2";
00125     ll_r_name<<ll_r_weights_hist<<"_-2";
00126 
00127     if (f->Get(gatti_name.str().c_str()) && 
00128         f->Get(ll_ele_name.str().c_str()) && 
00129         f->Get(ll_nuc_name.str().c_str()) && 
00130         f->Get(ll_r_name.str().c_str()))
00131     {
00132         //Load histograms of weights
00133         TH1F* gatti_weights_temp = (TH1F*) f->Get(gatti_name.str().c_str())->Clone();
00134         TH1F* ll_ele_weights_temp = (TH1F*) f->Get(ll_ele_name.str().c_str())->Clone();
00135         TH1F* ll_nuc_weights_temp = (TH1F*) f->Get(ll_nuc_name.str().c_str())->Clone();
00136         TH1F* ll_r_weights_temp = (TH1F*) f->Get(ll_r_name.str().c_str())->Clone();
00137         
00138         //Disassociate histograms from ROOT file - stupid ROOT !
00139         gatti_weights_temp->SetDirectory(0);
00140         ll_ele_weights_temp->SetDirectory(0);
00141         ll_nuc_weights_temp->SetDirectory(0);
00142         ll_r_weights_temp->SetDirectory(0);
00143 
00144         gatti_weights.insert(std::make_pair(-2, gatti_weights_temp));
00145         ll_ele_weights.insert(std::make_pair(-2, ll_ele_weights_temp));
00146         ll_nuc_weights.insert(std::make_pair(-2, ll_nuc_weights_temp));
00147         ll_r_weights.insert(std::make_pair(-2, ll_r_weights_temp));
00148 
00149 
00150         //Create histogram for binning data
00151         event_shape = (TH1F*)(gatti_weights_temp->Clone());
00152         event_shape->SetDirectory(0);
00153         event_shape->Reset();
00154 
00155     }    
00156 
00157     f->Close();
00158 
00159     return 0;
00160 }
00161 
00162 int PulseShapeEval::Process(EventPtr evt)
00163 {
00164     EventDataPtr data = evt->GetEventData();
00165     ChannelData* sumch = data->GetChannelByID(ChannelData::CH_SUM);
00166     
00167     double total_first_pulse_integral = 0;
00168     data->gatti = 0;
00169     data->ll_r = 0;
00170     
00171     if (gatti_weights.size() < data->channels.size())
00172     {
00173         Message(ERROR)<<"PulseShapeEval.cc: Size of weights file less than number of channels"
00174                       <<std::endl;
00175         return -1;
00176     }
00177 
00178     for (size_t ch = 0; ch < data->channels.size(); ch++)
00179     {
00180         ChannelData& chdata = data->channels[ch];
00181         //skip channels we've been told to explicitly skip
00182         if(_skip_channels.find(chdata.channel_id) != _skip_channels.end())
00183             continue;
00184 
00185         if (gatti_weights.find(chdata.channel_id) == gatti_weights.end())
00186         {
00187             Message(ERROR)<<"PulseShapeEval.cc: Weights file for channel "
00188                           <<chdata.channel_id<<" not loaded"
00189                           <<std::endl;
00190             return -1; 
00191         }
00192 
00193         if(!(chdata.baseline.found_baseline) || chdata.baseline.saturated)
00194             continue;
00195         
00196         const double* wave = chdata.GetBaselineSubtractedWaveform();
00197         int n_bins = gatti_weights[chdata.channel_id]->GetNbinsX();
00198 
00199         for (size_t pulse_num = 0; pulse_num < chdata.pulses.size(); pulse_num++)
00200         {
00201             chdata.pulses[pulse_num].gatti = 0;
00202             chdata.pulses[pulse_num].ll_ele = 0;
00203             chdata.pulses[pulse_num].ll_nuc = 0;
00204             chdata.pulses[pulse_num].ll_r = 0;
00205             
00206             Pulse pulse;
00207                     
00208             if (data->pulses_aligned == true)
00209             {
00210                 if (! sumch)
00211                 {
00212                     Message(ERROR)<<"PulseShapeEval.cc: Request to align pulses across channels, but sum channels disabled"<<std::endl;
00213                     return -1;
00214                 }
00215                 //Align everything by the corresponding pulse on the sum channel
00216                 pulse = sumch->pulses[pulse_num];
00217             }
00218             else
00219             {
00220                 pulse = chdata.pulses[pulse_num];
00221             }
00222 
00223             int pulse_index = pulse.start_index;
00224             event_shape->Reset();
00225             
00226             for(int i = 1; i <= n_bins; i++)
00227             {
00228                 //Get event pulse shape
00229                 double t0 = event_shape->GetBinLowEdge(i);
00230                 double t1 = event_shape->GetBinLowEdge(i+1);
00231                 double z = 0;
00232                 
00233                 if (chdata.TimeToSample(pulse.peak_time + t1) < 0 ||
00234                     chdata.TimeToSample(pulse.peak_time + t0) >= chdata.nsamps)
00235                 {
00236                     event_shape->SetBinContent(i, 0);
00237                 }
00238                 else
00239                 {
00240                     while (chdata.SampleToTime(pulse_index) < pulse.peak_time + t0)
00241                         pulse_index++;
00242                     
00243                     /*
00244                       if (pulse_num == 0)
00245                       Message(INFO)<<"Bin: "<<i<<" "
00246                       <<chdata.SampleToTime(pulse_index)<<" "
00247                       <<pulse.peak_time + t0<<" "
00248                       <<pulse.peak_time + t1<<" "
00249                       <<std::endl;
00250                     */    
00251                     while (chdata.SampleToTime(pulse_index) > pulse.peak_time + t0 &&
00252                            chdata.SampleToTime(pulse_index) < pulse.peak_time + t1 &&
00253                            pulse_index < chdata.nsamps)
00254                     {
00255                         z = z - wave[pulse_index];
00256                         pulse_index++;
00257                     }
00258                     event_shape->SetBinContent(i, z);
00259                 }
00260                 
00261             //Calculate pulse shape parameters
00262                 chdata.pulses[pulse_num].gatti += gatti_weights[chdata.channel_id]->GetBinContent(i) * event_shape->GetBinContent(i);
00263                 chdata.pulses[pulse_num].ll_ele += ll_ele_weights[chdata.channel_id]->GetBinContent(i) * event_shape->GetBinContent(i);
00264                 chdata.pulses[pulse_num].ll_nuc += ll_nuc_weights[chdata.channel_id]->GetBinContent(i) * event_shape->GetBinContent(i);
00265                 chdata.pulses[pulse_num].ll_r += ll_r_weights[chdata.channel_id]->GetBinContent(i) * event_shape->GetBinContent(i);
00266             }// end loop over time bins
00267         
00268             //Scale by integral of pulse
00269             double pulse_integral = event_shape->Integral();
00270             chdata.pulses[pulse_num].pulse_shape_int = pulse_integral;
00271             if (pulse_integral != 0)
00272             {
00273                 chdata.pulses[pulse_num].gatti = chdata.pulses[pulse_num].gatti / pulse_integral;
00274                 chdata.pulses[pulse_num].ll_ele = chdata.pulses[pulse_num].ll_ele / pulse_integral;
00275                 chdata.pulses[pulse_num].ll_nuc = chdata.pulses[pulse_num].ll_nuc / pulse_integral;
00276                 chdata.pulses[pulse_num].ll_r = chdata.pulses[pulse_num].ll_r / pulse_integral;
00277             }
00278             
00279             if (data->pulses_aligned == true || data->channels.size() == 1)
00280             {
00281                 if (pulse_num == 0 && chdata.channel_id >= 0)
00282                 {
00283                     total_first_pulse_integral += pulse_integral;
00284                     data->gatti += chdata.pulses[pulse_num].gatti * pulse_integral;
00285                     data->ll_r += chdata.pulses[pulse_num].ll_r * pulse_integral;
00286                 }
00287             }   
00288             
00289         } // end loop over pulses
00290     } // end loop over channels
00291 
00292     //Normalized pulse shape variables
00293     if (total_first_pulse_integral != 0)
00294     {
00295         data->gatti = data->gatti / total_first_pulse_integral;
00296         data->ll_r = data->ll_r / total_first_pulse_integral;
00297     }
00298     return 0;
00299 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1