CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoLocalCalo/HcalRecAlgos/src/HBHETimingShapedFlag.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "RecoLocalCalo/HcalRecAlgos/interface/HBHETimingShapedFlag.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 
00005 /*
00006 v1.0 by Jeff Temple
00007 29 August 2009
00008 
00009 This takes the timing envelope algorithms developed by 
00010 Phil Dudero and uses them to apply a RecHit Flag.
00011 */
00012 
00013 HBHETimingShapedFlagSetter::HBHETimingShapedFlagSetter()
00014 {
00015 }
00016 
00017 HBHETimingShapedFlagSetter::HBHETimingShapedFlagSetter(const std::vector<double>& v_userEnvelope)
00018 {
00019   makeTfilterEnvelope(v_userEnvelope);
00020   
00021   ignorelowest_=false;
00022   ignorehighest_=false;
00023   win_offset_=0.;
00024   win_gain_=1.;
00025 }
00026 
00027 HBHETimingShapedFlagSetter::HBHETimingShapedFlagSetter(const std::vector<double>& v_userEnvelope,
00028                                                        bool ignorelowest, bool ignorehighest,
00029                                                        double win_offset, double win_gain)
00030 {
00031   makeTfilterEnvelope(v_userEnvelope);
00032 
00033   ignorelowest_  = ignorelowest;  // can ignore flagging hits below lowest energy threshold
00034   ignorehighest_ = ignorehighest; // can ignore flagging hits above highest energy threshold
00035   win_offset_    = win_offset;    // timing offset
00036   win_gain_      = win_gain;      // time gain
00037 }
00038 
00039 void
00040 HBHETimingShapedFlagSetter::makeTfilterEnvelope(const std::vector<double>& v_userEnvelope)
00041 {
00042   // Transform vector of doubles into a map of <energy,lowtime,hitime> triplets
00043   // Add extra protection in case vector of doubles is not a multiple of 3
00044   if (v_userEnvelope.size()%3)
00045     throw cms::Exception("Invalid tfilterEnvelope definition") <<
00046       "Must be one energy and two times per point";
00047 
00048   for (unsigned int i=0;i<v_userEnvelope.size();i+=3) {
00049     int intGeV = (int)(v_userEnvelope[i]+0.5);
00050     std::pair<double,double> pairOfTimes = std::make_pair(v_userEnvelope[i+1],
00051                                                           v_userEnvelope[i+2]);
00052     if ((pairOfTimes.first  > 0) ||
00053         (pairOfTimes.second < 0) )
00054       throw cms::Exception("Invalid tfilterEnvelope definition") <<
00055         "Min and max time values must straddle t=0; use win_offset to shift";
00056 
00057     tfilterEnvelope_[intGeV] = pairOfTimes;
00058   }
00059 }
00060 
00061 void
00062 HBHETimingShapedFlagSetter::dumpInfo()
00063 {  
00064   std::cout <<"Timing Energy/Time parameters are:"<<std::endl;
00065   TfilterEnvelope_t::const_iterator it;
00066   for (it=tfilterEnvelope_.begin();it!=tfilterEnvelope_.end();++it)
00067     std::cout <<"\t"<<it->first<<" GeV\t"<<it->second.first<<" ns\t"<<it->second.second<<" ns"<<std::endl;
00068 
00069   std::cout <<"ignorelowest  = "<<ignorelowest_<<std::endl;
00070   std::cout <<"ignorehighest = "<<ignorehighest_<<std::endl;
00071   std::cout <<"win_offset    = "<<win_offset_<<std::endl;
00072   std::cout <<"win_gain      = "<<win_gain_<<std::endl;
00073 }
00074 
00075 int
00076 HBHETimingShapedFlagSetter::timingStatus(const HBHERecHit& hbhe)
00077 {
00078   int status=0;  // 3 bits reserved;status can range from 0-7
00079 
00080   // tfilterEnvelope stores triples of energy and high/low time limits; 
00081   // make sure we're checking over an even number of values
00082   // energies are guaranteed by std::map to appear in increasing order
00083 
00084   // need at least two values to make comparison, and must
00085   // always have energy, time pair; otherwise, assume "in time" and don't set bits
00086   if (tfilterEnvelope_.size()==0)
00087     return 0;
00088 
00089   double twinmin, twinmax;  // min, max 'good' time; values outside this range have flag set
00090   double rhtime=hbhe.time();
00091   double energy=hbhe.energy();
00092 
00093   if (energy< (double)tfilterEnvelope_.begin()->first) // less than lowest energy threshold
00094     {
00095       // Can skip timing test on cells below lowest threshold if so desired
00096       if (ignorelowest_) 
00097         return 0;
00098       else {
00099         twinmin=tfilterEnvelope_.begin()->second.first;
00100         twinmax=tfilterEnvelope_.begin()->second.second;
00101       }
00102     }
00103   else
00104     {
00105       // Loop over energies in tfilterEnvelope
00106       TfilterEnvelope_t::const_iterator it;
00107       for (it=tfilterEnvelope_.begin();it!=tfilterEnvelope_.end();++it)
00108         {
00109           // Identify tfilterEnvelope index for this rechit energy
00110           if (energy < (double)it->first)
00111             break;
00112         }
00113 
00114       if (it==tfilterEnvelope_.end())
00115         {
00116           // Skip timing test on cells above highest threshold if so desired
00117           if (ignorehighest_)
00118             return 0;
00119           else {
00120             twinmin=tfilterEnvelope_.rbegin()->second.first;
00121             twinmax=tfilterEnvelope_.rbegin()->second.second;
00122           }
00123         }
00124       else
00125         {
00126           // Perform linear interpolation between energy boundaries
00127 
00128           std::map<int,std::pair<double,double> >::const_iterator prev = it; prev--;
00129 
00130           // twinmax interpolation
00131           double energy1  = prev->first;
00132           double lim1     = prev->second.second;
00133           double energy2  = it->first;
00134           double lim2     = it->second.second;
00135         
00136           twinmax=lim1+((lim2-lim1)*(energy-energy1)/(energy2-energy1));
00137 
00138           // twinmin interpolation
00139           lim1     = prev->second.first;
00140           lim2     = it->second.first;
00141         
00142           twinmin=lim1+((lim2-lim1)*(energy-energy1)/(energy2-energy1));
00143         }
00144     }
00145 
00146   // Apply offset, gain
00147   twinmin=win_offset_+twinmin*win_gain_;
00148   twinmax=win_offset_+twinmax*win_gain_;  
00149 
00150   // Set status high if time outside expected range
00151   if (rhtime<=twinmin || rhtime >= twinmax)
00152     status=1; // set status to 1
00153 
00154   return status;
00155 }
00156 
00157 void HBHETimingShapedFlagSetter::SetTimingShapedFlags(HBHERecHit& hbhe)
00158 {
00159   int status = timingStatus(hbhe);
00160 
00161   // Though we're only using a single bit right now, 3 bits are reserved for these cuts
00162   hbhe.setFlagField(status,HcalCaloFlagLabels::HBHETimingShapedCutsBits,3);
00163 
00164   return;
00165 }