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
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
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
00100
00101
00102
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
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
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
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
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
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
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
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
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
00245
00246
00247
00248
00249
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
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 }
00267
00268
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 }
00290 }
00291
00292
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 }