00001 #include "AverageWaveforms.hh"
00002 #include "ConvertData.hh"
00003 #include "BaselineFinder.hh"
00004 #include "SumChannels.hh"
00005 #include "intarray.hh"
00006 #include "TGraphErrors.h"
00007 #include "TFile.h"
00008 #include "PulseFinder.hh"
00009 #include "RootWriter.hh"
00010 #include "EventData.hh"
00011
00012 #include <algorithm>
00013 #include <functional>
00014 #include <iostream>
00015 #include <fstream>
00016 #include <string>
00017 #include <sstream>
00018 using namespace std;
00019
00020 AverageWaveforms::AverageWaveforms() :
00021 BaseModule(GetDefaultName(), "Average the waveform for each channel over the entire run and save to the output root file")
00022 {
00023 AddDependency<ConvertData>();
00024 AddDependency<SumChannels>();
00025 AddDependency<BaselineFinder>();
00026 AddDependency<PulseFinder>();
00027
00028
00029
00030 RegisterParameter("use_event_list", use_event_list = false,
00031 "True if no cuts should be performed and the average should be constructed from a set of events specified in a text file.");
00032 RegisterParameter("event_list_location", event_list_location = "auxiliary_files/average_event_list.txt",
00033 "Location of text file to be used if use_event_list is true. Each line of the file must have the run number and then the event number (separated by a space) sorted in ascending order.");
00034
00035
00036 RegisterParameter("with_s2", with_s2 = false, "True if run contains s2");
00037 RegisterParameter("min_pulse_height", min_pulse_height = 100,
00038 "Minimum pulse height for one waveform to be counted in average waveform");
00039 RegisterParameter("max_pulse_height", max_pulse_height = 3000,
00040 "Maximum pulse height for one waveform to be counted in average waveform");
00041 RegisterParameter("min_fprompt", min_fprompt = 0,
00042 "Minimum fprompt for one waveform to be counted in average waveform");
00043 RegisterParameter("max_fprompt", max_fprompt = 1,
00044 "Maximum fprompt for one waveform to be counted in average waveform");
00045 RegisterParameter("align_by_peak", align_by_peak = true,
00046 "Align waveforms by the peak of the first pulse on the sum channel. Otherwise align by the trigger.");
00047 RegisterParameter("sum_start_time", sum_start_time = -20,
00048 "");
00049 RegisterParameter("sum_end_time", sum_end_time = 400,
00050 "");
00051 RegisterParameter("min_s1_start_time", min_s1_start_time = -0.08,
00052 "");
00053 RegisterParameter("max_s1_start_time", max_s1_start_time = 0.05,
00054 "");
00055 RegisterParameter("bin_size", bin_size = 50, "Use multiple of baseline group #");
00056 RegisterParameter("min_s2_start_time", min_s2_start_time = 40, "");
00057 RegisterParameter("max_s2_start_time", max_s2_start_time = 300, "");
00058 RegisterParameter("number_of_base_groups", number_of_base_groups = 2, "");
00059 }
00060
00061 AverageWaveforms::~AverageWaveforms()
00062 {
00063 Cleanup();
00064 }
00065
00066 void AverageWaveforms::Cleanup()
00067 {
00068 std::map<int,TGraphErrors*>::iterator mapit = _plots.begin();
00069 for( ; mapit != _plots.end() ; mapit++){
00070 delete mapit->second;
00071 }
00072 _plots.clear();
00073 _num_event.clear();
00074 }
00075
00076
00077 int AverageWaveforms::Initialize()
00078 {
00079
00080 if (use_event_list)
00081 {
00082 string line;
00083 current_event = -1;
00084 current_run = -1;
00085 txt.open(event_list_location.c_str());
00086 if (txt.is_open() && txt.good())
00087 {
00088 getline(txt,line);
00089 istringstream ss1(line);
00090 string temp;
00091 getline(ss1, temp, ' ');
00092 istringstream ss2(temp);
00093 ss2 >> current_run;
00094 getline(ss1, temp, ' ');
00095 istringstream ss3(temp);
00096 ss3 >> current_event;
00097 }
00098 }
00099 return 0;
00100 }
00101
00102 int AverageWaveforms::Finalize()
00103 {
00104 if(gFile && gFile->IsOpen()){
00105 std::map<int,TGraphErrors*>::iterator mapit = _plots.begin();
00106 for( ; mapit != _plots.end(); mapit++){
00107 TGraphErrors* graph = mapit->second;
00108
00109 double* ey = graph->GetEY();
00110
00111 for(int i=0; i < graph->GetN(); i++){
00112
00113 ey[i] = sqrt(ey[i]);
00114 }
00115 graph->SetFillStyle(3002);
00116 graph->SetFillColor(kRed);
00117 graph->Write();
00118 }
00119 }
00120 std::map<int, int>::iterator numOfEvents = _num_event.begin();
00121 for ( ; numOfEvents != _num_event.end(); numOfEvents++){
00122 Message(INFO)<<"<Module> AverageWaveforms: Channel "<< numOfEvents->first
00123 <<" includes "<< numOfEvents->second <<" events"<<std::endl;
00124 }
00125 if (txt.is_open())
00126 txt.close();
00127 Cleanup();
00128 return 0;
00129 }
00130
00131 int AverageWaveforms::Process(EventPtr evt)
00132 {
00133 EventDataPtr event = evt->GetEventData();
00134 ChannelData* sum_ch = event->GetChannelByID(ChannelData::CH_SUM);
00135
00136
00137 if (align_by_peak && !sum_ch)
00138 return 0;
00139
00140 if (!use_event_list)
00141 {
00142 if (!sum_ch)
00143 return 0;
00144
00145 if(! with_s2)
00146 {
00147
00148 if (sum_ch->pulses.size() != 1)
00149 return 0;
00150 }
00151 else
00152 {
00153
00154 if (sum_ch->pulses.size()!=2)
00155 return 0;
00156
00157 if (sum_ch->pulses[1].start_time < min_s2_start_time)
00158 return 0;
00159 if (sum_ch->pulses[1].start_time > max_s2_start_time)
00160 return 0;
00161 }
00162
00163
00164 if (sum_ch->pulses[0].start_time < min_s1_start_time) return 0;
00165 if (sum_ch->pulses[0].start_time > max_s1_start_time) return 0;
00166 if (sum_ch->pulses[0].f90 < min_fprompt) return 0;
00167 if (sum_ch->pulses[0].f90 > max_fprompt) return 0;
00168 }
00169
00170 else
00171 {
00172
00173
00174 while (event->run_id != current_run && txt.is_open() && txt.good())
00175 {
00176 string line;
00177 getline(txt,line);
00178 istringstream ss1(line);
00179 string temp;
00180 getline(ss1, temp, ' ');
00181 istringstream ss2(temp);
00182 ss2 >> current_run;
00183 getline(ss1, temp, ' ');
00184 istringstream ss3(temp);
00185 ss3 >> current_event;
00186 }
00187
00188
00189 if (event->event_id != current_event)
00190 return 0;
00191 }
00192
00193
00194
00195 for (size_t ch = 0; ch < event->channels.size(); ch++)
00196 {
00197 ChannelData& chdata = event->channels[ch];
00198
00199 if(_skip_channels.find(chdata.channel_id) != _skip_channels.end())
00200 continue;
00201
00202
00203 if (!use_event_list)
00204 {
00205
00206 if(!(chdata.baseline.found_baseline) || chdata.baseline.saturated)
00207 continue;
00208
00209 if (chdata.saturated)
00210 continue;
00211 }
00212
00213
00214
00215
00216
00217 _num_event[chdata.channel_id]++;
00218 const double* wave = chdata.GetBaselineSubtractedWaveform();
00219 int start_samp;
00220 int end_samp;
00221 if (align_by_peak == true)
00222 {
00223 double sum_peak_time = sum_ch->pulses[0].peak_time;
00224 start_samp = chdata.TimeToSample(sum_start_time - sum_peak_time, true);
00225 end_samp = chdata.TimeToSample(sum_end_time - sum_peak_time, true);
00226 }
00227 else
00228 {
00229 start_samp = chdata.TimeToSample(sum_start_time, true);
00230 end_samp = chdata.TimeToSample(sum_end_time, true);
00231 }
00232 const int nsamps = (end_samp - start_samp + 1) / bin_size;
00233
00234 std::map<int,TGraphErrors*>::iterator prev = _plots.find(chdata.channel_id);
00235 if(prev == _plots.end())
00236 {
00237 double* x_ray = new double[nsamps];
00238 double* y_ray = new double[nsamps];
00239 double* ey_ray = new double[nsamps];
00240 TGraphErrors* avg = new TGraphErrors(nsamps, x_ray, y_ray, 0, ey_ray);
00241 char name[25];
00242 sprintf(name,"average_channel%d",chdata.channel_id);
00243 avg->SetName(name);
00244 avg->SetTitle(name);
00245
00246 double* x = avg->GetX();
00247 double* y = avg->GetY();
00248 double* ey = avg->GetEY();
00249 int index;
00250 double yj;
00251 int j;
00252
00253 for(int i=0; i < nsamps; i++)
00254 {
00255 index = start_samp+i*bin_size;
00256 yj = 0;
00257 x[i]=chdata.SampleToTime(index);
00258 y[i]=0;
00259 ey[i]=0;
00260
00261 for (j=0; j<bin_size; j++)
00262 {
00263 if (chdata.channel_id >= 0)
00264 yj = yj - wave[index+j]/(chdata.spe_mean);
00265 else
00266 yj = yj - wave[index+j];
00267 }
00268 y[i] += yj;
00269
00270
00271 ey[i] = fabs(y[i]);
00272 }
00273 _plots.insert(std::make_pair(chdata.channel_id,avg));
00274 }
00275 else
00276 {
00277 TGraphErrors* avg = prev->second;
00278 if(avg->GetN() != nsamps)
00279 {
00280 Message(ERROR)<<"Uneven number of samples between two events "
00281 <<"for channel "<<chdata.channel_id<<std::endl;
00282 return 1;
00283 }
00284
00285 double* y = avg->GetY();
00286 double* ey = avg->GetEY();
00287 int index;
00288 double yj;
00289 int j;
00290
00291 for(int i=0; i < nsamps; i++)
00292 {
00293 index = start_samp+i*bin_size;
00294 yj=0;
00295
00296 for (j=0; j<bin_size; j++)
00297 {
00298 if (chdata.channel_id >= 0)
00299 yj = yj - wave[index+j]/(chdata.spe_mean);
00300 else
00301 yj = yj - wave[index+j];
00302 }
00303 y[i] += yj;
00304
00305
00306 ey[i] += fabs(yj);
00307 }
00308 }
00309 }
00310
00311
00312 if (use_event_list && txt.is_open() && txt.good())
00313 {
00314 string line;
00315 getline(txt,line);
00316 istringstream ss1(line);
00317 string temp;
00318 getline(ss1, temp, ' ');
00319 istringstream ss2(temp);
00320 ss2 >> current_run;
00321 getline(ss1, temp, ' ');
00322 istringstream ss3(temp);
00323 ss3 >> current_event;
00324 }
00325
00326
00327 return 0;
00328 }
00329
00330
00331