00001 #include "SumOfIntegralEval.hh" 00002 #include "intarray.hh" 00003 #include "BaselineFinder.hh" 00004 #include "SumChannels.hh" 00005 #include "PulseFinder.hh" 00006 #include "EvalRois.hh" 00007 #include "SumOfIntegral.hh" 00008 #include "Roi.hh" 00009 #include "RootWriter.hh" 00010 #include <algorithm> 00011 #include <cmath> 00012 #include "TFile.h" 00013 #include "TH1F.h" 00014 00015 SumOfIntegralEval::SumOfIntegralEval() : 00016 BaseModule(GetDefaultName(), 00017 "Calculate sum of pulse shape parameters calculated on each channel") 00018 { 00019 AddDependency<BaselineFinder>(); 00020 AddDependency<PulseFinder>(); 00021 AddDependency<EvalRois>(); 00022 } 00023 00024 SumOfIntegralEval::~SumOfIntegralEval() 00025 { 00026 Finalize(); 00027 } 00028 00029 int SumOfIntegralEval::Initialize() 00030 { 00031 return 0; 00032 } 00033 00034 int SumOfIntegralEval::Finalize() 00035 { 00036 return 0; 00037 } 00038 00039 int SumOfIntegralEval::Process(EventPtr evt) 00040 { 00041 EventDataPtr data = evt->GetEventData(); 00042 00043 if (data->channels.size() < 2) //redundant if there is only one channel 00044 return 0; 00045 00046 //Calculate per-region variables 00047 size_t n_regions = data->channels[0].regions.size(); 00048 for (size_t region_num = 0; region_num < n_regions; region_num++) 00049 { 00050 Roi roi; 00051 roi.integral = 0; 00052 roi.npe = 0; 00053 00054 for (size_t ch = 0; ch < data->channels.size(); ch++) 00055 { 00056 ChannelData& chdata = data->channels[ch]; 00057 00058 //skip channels we've been told to explicitly skip 00059 if(_skip_channels.find(chdata.channel_id) != _skip_channels.end()) 00060 continue; 00061 00062 //only loop over real channels 00063 if (chdata.channel_id < 0) 00064 continue; 00065 00066 //if any remaining channels don't have valid baselines - do not save any information 00067 if(! (chdata.baseline.found_baseline) 00068 || chdata.baseline.saturated) 00069 { 00070 roi.Init(); 00071 break; 00072 } 00073 00074 if (roi.end_index == 0) 00075 { 00076 //Initialize common values 00077 roi.start_time = chdata.regions[region_num].start_time; 00078 roi.end_time = chdata.regions[region_num].end_time; 00079 roi.start_index = chdata.regions[region_num].start_index; 00080 roi.end_index = chdata.regions[region_num].end_index; 00081 roi.max = -1; 00082 roi.min = -1; 00083 roi.min_index = -1; 00084 } 00085 roi.integral += chdata.regions[region_num].integral; 00086 roi.npe += chdata.regions[region_num].npe; 00087 }//end loop over channels 00088 data->roi_sum_of_int.push_back(roi); 00089 } 00090 00091 //Calculate per-pulse variables 00092 if (! data->pulses_aligned) //makes no sense if pulses are different on each channel 00093 return 0; 00094 00095 size_t n_pulses = data->channels[0].pulses.size(); 00096 00097 for (size_t pulse_num = 0; pulse_num < n_pulses; pulse_num++) 00098 { 00099 SumOfIntegral sum_of_int; 00100 double total_pulse_shape_int = 0; 00101 00102 for (size_t ch = 0; ch < data->channels.size(); ch++) 00103 { 00104 ChannelData& chdata = data->channels[ch]; 00105 00106 //skip channels we've been told to explicitly skip 00107 if(_skip_channels.find(chdata.channel_id) != _skip_channels.end()) 00108 continue; 00109 00110 //only loop over real channels 00111 if (chdata.channel_id < 0) 00112 continue; 00113 00114 //if any remaining channels don't have valid pulse - do not save any information 00115 if(! (chdata.baseline.found_baseline) 00116 || chdata.baseline.saturated 00117 || chdata.pulses.size() != n_pulses) 00118 { 00119 sum_of_int.Clear(); 00120 total_pulse_shape_int = 0; 00121 break; 00122 } 00123 00124 Pulse pulse = chdata.pulses[pulse_num]; 00125 00126 if (sum_of_int.start_index < 0) 00127 { 00128 //Initialize common values 00129 sum_of_int.start_index = pulse.start_index; 00130 sum_of_int.start_time = pulse.start_time; 00131 sum_of_int.end_index = pulse.end_index; 00132 sum_of_int.end_time = pulse.end_time; 00133 sum_of_int.start_clean = pulse.start_clean; 00134 sum_of_int.end_clean = pulse.end_clean; 00135 sum_of_int.dt = pulse.dt; 00136 sum_of_int.f_param.assign(pulse.f_param.size(), 0); 00137 sum_of_int.fixed_npe1_valid = pulse.fixed_int1_valid; 00138 sum_of_int.fixed_npe2_valid = pulse.fixed_int2_valid; 00139 } 00140 00141 sum_of_int.saturated = (sum_of_int.saturated || pulse.peak_saturated); 00142 sum_of_int.npe += pulse.npe; 00143 for (int fp = 0; fp < (int)pulse.f_param.size(); fp++) 00144 { 00145 sum_of_int.f_param.at(fp) += pulse.f_param.at(fp)*pulse.npe; 00146 } 00147 sum_of_int.f90 += pulse.f90*pulse.npe; 00148 sum_of_int.fixed_npe1 += -pulse.fixed_int1/chdata.spe_mean; 00149 sum_of_int.fixed_npe2 += -pulse.fixed_int2/chdata.spe_mean; 00150 if (sum_of_int.max_chan_npe < pulse.npe) 00151 { 00152 sum_of_int.max_chan = chdata.channel_id; 00153 sum_of_int.max_chan_npe = pulse.npe; 00154 } 00155 00156 sum_of_int.gatti += pulse.gatti*pulse.pulse_shape_int; 00157 sum_of_int.ll_ele += pulse.ll_ele*pulse.pulse_shape_int; 00158 sum_of_int.ll_nuc += pulse.ll_nuc*pulse.pulse_shape_int; 00159 sum_of_int.ll_r += pulse.ll_r*pulse.pulse_shape_int; 00160 total_pulse_shape_int += pulse.pulse_shape_int; 00161 00162 } // end loop over channels 00163 00164 //Correctly normalize all weighted sums 00165 if (sum_of_int.npe != 0) 00166 { 00167 for (int fp = 0; fp < (int)sum_of_int.f_param.size(); fp++) 00168 { 00169 sum_of_int.f_param.at(fp) = sum_of_int.f_param.at(fp)/sum_of_int.npe; 00170 } 00171 sum_of_int.f90_fixed = sum_of_int.f90/sum_of_int.fixed_npe1; 00172 sum_of_int.f90 = sum_of_int.f90/sum_of_int.npe; 00173 } 00174 if (total_pulse_shape_int != 0) 00175 { 00176 sum_of_int.gatti = sum_of_int.gatti/total_pulse_shape_int; 00177 sum_of_int.ll_ele = sum_of_int.ll_ele/total_pulse_shape_int; 00178 sum_of_int.ll_nuc = sum_of_int.ll_nuc/total_pulse_shape_int; 00179 sum_of_int.ll_r = sum_of_int.ll_r/total_pulse_shape_int; 00180 } 00181 //Store information in event class 00182 data->sum_of_int.push_back(sum_of_int); 00183 } // end loop over pulses 00184 return 0; 00185 }