S1S2Evaluation.cc

00001 #include "S1S2Evaluation.hh"
00002 #include "SumChannels.hh"
00003 #include "PulseFinder.hh"
00004 #include "Integrator.hh"
00005 #include "RootWriter.hh"
00006 #include "EventHandler.hh"
00007 #include <string>
00008 #include <stdexcept>
00009 
00010 S1S2Evaluation::S1S2Evaluation() :
00011   BaseModule(GetDefaultName(), "Evaluate S1/S2, fprompt, etc for all channels")
00012 {
00013   AddDependency<PulseFinder>();
00014   AddDependency<SumChannels>();
00015   AddDependency<Integrator>();
00016 
00017 }
00018 
00019 
00020 int S1S2Evaluation::Initialize()
00021 {
00022   _pulse_finder = EventHandler::GetInstance()->GetModule<PulseFinder>();
00023   if(!_pulse_finder){
00024     Message(ERROR)<<"S1S2Evaluator::Initialize(): No PulseFinder module!\n";
00025     return 1;
00026   }
00027   return 0;
00028 }
00029 
00030 int S1S2Evaluation::Finalize()
00031 {
00032   return 0;
00033 }
00034 
00035 int S1S2Evaluation::Process(EventPtr evt)
00036 {
00037   EventDataPtr data = evt->GetEventData();
00038   //find the region of interest based on the sumchannel pulses
00039   ChannelData* sumch = data->GetChannelByID(ChannelData::CH_SUM);
00040   if(!sumch)
00041     return 0;
00042   //need at least 1 pulse
00043   if(sumch->npulses < 1)
00044     return 0;
00045   //check that the two pulses are good s1 and s2 pulses
00046   Pulse& sum_s1 = sumch->pulses[0];
00047   
00048   //Check if pulse is S1
00049   double* integral = sumch->GetIntegralWaveform();
00050   int ratio_samps = (int)(0.02*sumch->sample_rate);
00051   if (sum_s1.peak_index >= ratio_samps && 
00052       sum_s1.peak_index < sumch->nsamps-ratio_samps)
00053   {
00054       sum_s1.ratio1 = (integral[sum_s1.peak_index+ratio_samps] - 
00055                       integral[sum_s1.peak_index-ratio_samps]) / 
00056           sum_s1.integral;
00057       sum_s1.ratio2 = (integral[sum_s1.peak_index-ratio_samps] - 
00058                       integral[sum_s1.start_index]) / 
00059           sum_s1.integral;
00060       //sum_s1.ratio3 = - sum_s1.peak_amplitude / 
00061       //(integral[sum_s1.peak_index] - integral[sum_s1.peak_index-50]);
00062   }
00063   if (sum_s1.ratio1 > 0.05 && sum_s1.ratio2 < 0.02)
00064   {
00065       //this is a valid s1 event
00066       sum_s1.is_s1 = true;
00067   }
00068 
00069   data->s1_valid = ( sum_s1.is_clean && sum_s1.is_s1 );
00070   data->s1_fixed_valid = sum_s1.is_s1 && sum_s1.fixed_int1_valid;
00071   data->s1_start_time = sum_s1.start_time;
00072   data->s1_end_time = sum_s1.end_time;
00073   if(sumch->npulses >1){
00074     Pulse& sum_s2 = sumch->pulses[1];
00075     data->s2_valid = (sum_s2.is_clean && !sum_s2.is_s1);
00076     data->s2_fixed_valid = !sum_s2.is_s1 && sum_s2.fixed_int2_valid;
00077     data->s2_start_time = sum_s2.start_time;
00078     data->s2_end_time = sum_s2.end_time;
00079     data->drift_time = sum_s2.start_time - sum_s1.start_time;
00080   }
00081   else{
00082     data->s2_valid = false;
00083     data->s2_fixed_valid = false;
00084     data->s2_start_time = 0;
00085     data->s2_end_time = 0;
00086     data->drift_time = 0;
00087   }
00088   data->s1s2_valid = ( data->s1_valid && data->s2_valid && sumch->npulses == 2);
00089   data->s1s2_fixed_valid = data->s1_fixed_valid && data->s2_fixed_valid 
00090     && sumch->npulses ==2;
00091   
00092   //make sure s1/s2 for the pulse is initialized to 0
00093   data->s1_full = 0;
00094   data->s2_full = 0;
00095   data->s1_fixed = 0;
00096   data->s2_fixed = 0;
00097   data->max_s1 = 0;
00098   data->max_s2 = 0;
00099   data->max_s1_chan = -1;
00100   data->max_s2_chan = -1;
00101   double fast = 0;
00102   
00103   //Evaluate S1/S2 for each channel
00104   for(size_t ch = 0; ch < data->channels.size(); ch++)
00105   {
00106     ChannelData& chdata = data->channels[ch];
00107     //only look at real channels
00108     if(chdata.channel_id < 0) continue;
00109     //skip channels we've been told to explicitly skip
00110     if(_skip_channels.find(chdata.channel_id) != _skip_channels.end())
00111       continue;
00112     //skip if there is no baseline
00113     if(!chdata.baseline.found_baseline) 
00114     {
00115       //needs baseline to do the integral
00116       data->s1_valid = false;
00117       data->s1_fixed_valid = false;
00118       data->s2_valid = false;
00119       data->s2_fixed_valid = false;
00120       data->s1s2_valid = false;
00121       data->s1s2_fixed_valid = false;
00122       continue;
00123     }
00124 
00125     for(size_t pulsenum = 0; pulsenum < chdata.pulses.size(); pulsenum++)
00126     {
00127         Pulse pulse = chdata.pulses[pulsenum]; //note: this is a copy!
00128         if(pulsenum == 0)
00129         {
00130             double* integral = chdata.GetIntegralWaveform();
00131             int ratio_samps = (int)(0.02*chdata.sample_rate);
00132             if (pulse.peak_index >= ratio_samps && 
00133                 pulse.peak_index < chdata.nsamps-ratio_samps)
00134             {
00135                 pulse.ratio1 = (integral[pulse.peak_index+ratio_samps] - 
00136                                 integral[pulse.peak_index-ratio_samps]) / 
00137                     pulse.integral;
00138                 pulse.ratio2 = (integral[pulse.peak_index-ratio_samps] - 
00139                                 integral[pulse.start_index]) / 
00140                     pulse.integral;
00141                 //pulse.ratio3 = - pulse.peak_amplitude / 
00142                 //(integral[pulse.peak_index] - integral[pulse.peak_index-50]);
00143             }
00144             
00145             if (pulse.ratio1 > 0.05 && pulse.ratio2 < 0.02)
00146             {
00147                 //this is a valid s1 event
00148                 pulse.is_s1 = true;
00149             }
00150             // this is s1
00151             //chdata.s1_full = -pulse.integral/chdata.spe_mean;
00152             chdata.s1_full = pulse.npe;
00153             chdata.s1_fixed = -pulse.fixed_int1/chdata.spe_mean;
00154             if (data->pulses_aligned == true || data->channels.size() == 1)
00155             {
00156                 data->s1_full += chdata.s1_full;
00157                 data->s1_fixed += chdata.s1_fixed;
00158                 if(chdata.s1_full > data->max_s1)
00159                 {
00160                     data->max_s1 = chdata.s1_full;
00161                     data->max_s1_chan = chdata.channel_id;
00162                 }
00163                 int s1_90 = chdata.TimeToSample(pulse.start_time+0.09, true);
00164                 fast += -(chdata.integral[s1_90] - chdata.integral[pulse.start_index]) /
00165                     chdata.spe_mean;
00166             }
00167         }
00168         else if (pulsenum == 1)
00169         {
00170             //this is s2
00171             chdata.s2_full = -pulse.integral/chdata.spe_mean;
00172             chdata.s2_fixed = - pulse.fixed_int2/chdata.spe_mean;
00173             if (data->pulses_aligned == true || data->channels.size() == 1)
00174             {
00175                 data->s2_full += chdata.s2_full;
00176                 data->s2_fixed += chdata.s2_fixed;
00177                 if(chdata.s2_full > data->max_s2)
00178                 {
00179                     data->max_s2 = chdata.s2_full;
00180                     data->max_s2_chan = chdata.channel_id;
00181                 }
00182             }
00183         }
00184     }//end loop over pulses
00185   }//end loop over channels
00186   //evaluate the total f90
00187   data->f90_full = fast/data->s1_full;
00188   data->f90_fixed = fast/data->s1_fixed;
00189   return 0;
00190 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1