Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

LIPatternFinderSimple.cxx

Go to the documentation of this file.
00001 
00034 #include <cmath>
00035 #include <numeric>
00036 #include <cassert>
00037 #include <algorithm>
00038 #include <functional>
00039 
00040 #include "MessageService/MsgService.h"
00041 
00042 #include "LIPatternFinderSimple.h"
00043 
00044 ClassImp(LIPatternFinderSimple)
00045 
00046 //_____________________________________________________________________
00047 CVSID(
00048 "$Id: LIPatternFinderSimple.cxx,v 1.5 2006/05/27 08:58:13 rhatcher Exp $"
00049 );
00050 //_____________________________________________________________________
00051 
00052 // STL Functors
00053 
00054 struct is_east_side: public unary_function<CandDigitHandle *, bool>
00055 {
00056    bool operator()(CandDigitHandle * digit) {
00057      
00058          const PlexSEIdAltL & seid = digit->GetPlexSEIdAltL();
00059          return (seid.GetEnd() == StripEnd::kEast);
00060    }
00061 };
00062 //.....................................................................
00063 struct sum_q :
00064               public binary_function<double, CandDigitHandle *, double>
00065 {
00066    double operator()(double sum, CandDigitHandle * current_digit) {
00067      
00068           return (sum + current_digit->GetCharge());
00069    }
00070 };
00071 //.....................................................................
00072 struct is_in_plane_and_above_thr:
00073                        public unary_function<CandDigitHandle *, bool>
00074 {
00075    int    _plane;
00076    double _threshold;
00077 
00078    is_in_plane_and_above_thr(int plane, double threshold) :
00079                               _plane(plane), _threshold(threshold) { }
00080                               
00081    bool operator()(CandDigitHandle * digit) {
00082 
00083       const PlexSEIdAltL & seid = digit->GetPlexSEIdAltL();
00084       
00085       return ( (digit->GetCharge() > _threshold) &&
00086                                         (seid.GetPlane() == _plane) );
00087    }
00088 };
00089 //.....................................................................
00090 struct is_in_plane_range_and_above_thr:
00091                         public unary_function<CandDigitHandle *, bool>
00092 {
00093    int    _pl_min, _pl_max;
00094    double _threshold;
00095 
00096    is_in_plane_range_and_above_thr(
00097         int pl_min, int pl_max, double threshold) :
00098            _pl_min(pl_min), _pl_max(pl_max), _threshold(threshold) { }
00099 
00100    bool operator()(CandDigitHandle * digit) {
00101 
00102       const PlexSEIdAltL & seid = digit->GetPlexSEIdAltL();
00103 
00104       return ( (digit->GetCharge() >  _threshold) &&
00105                              (seid.GetPlane() >= _pl_min) &&
00106                                         (seid.GetPlane() <= _pl_max) );
00107    }
00108 };
00109 //.....................................................................
00110 struct min_plane:
00111    public binary_function<CandDigitHandle *, CandDigitHandle *, bool> {
00112    bool operator()(CandDigitHandle * a, CandDigitHandle * b) {
00113           return a->GetPlexSEIdAltL().GetPlane() <
00114                                        b->GetPlexSEIdAltL().GetPlane();
00115    }
00116 };
00117 //_____________________________________________________________________
00118 LIPatternFinderSimple::LIPatternFinderSimple()
00119 {
00120   MSG("LIPatternFinder", Msg::kVerbose)
00121                                      << "LIPatternFinderSimple ctor\n";
00122   DefaultConfig();
00123 }
00124 //_____________________________________________________________________
00125 LIPatternFinderSimple::~LIPatternFinderSimple()
00126 {
00127   MSG("LIPatternFinder", Msg::kVerbose)
00128                                      << "LIPatternFinderSimple dtor\n";
00129 }
00130 //_____________________________________________________________________
00131 void LIPatternFinderSimple::DefaultConfig(void)
00132 {
00133   // see header file for comments on variables
00134   
00135   fMaxEWAsymmetry               = 5.e+5; 
00136   fPulseHeightThreshold         = 200; 
00137   fMaxNDigits                   = 1000;
00138   fMaxCharge                    = 1.e+6;
00139   fHighActivityThreshold        = 0.90;
00140   fLowActivityThreshold         = 0.20;
00141 }
00142 //_____________________________________________________________________
00143 void LIPatternFinderSimple::Configure(const Registry & registry)
00144 {
00145   double tmpd;
00146   
00147   if (registry.Get("MaxEWAsymmetry", tmpd))    fMaxEWAsymmetry = tmpd;
00148   if (registry.Get("MaxNDigits", tmpd))            fMaxNDigits = tmpd;
00149   if (registry.Get("MaxCharge", tmpd))              fMaxCharge = tmpd;
00150   if (registry.Get("PulseHeightThreshold", tmpd))
00151                                          fPulseHeightThreshold = tmpd;
00152   if (registry.Get("HighActivityThreshold", tmpd))
00153                                         fHighActivityThreshold = tmpd;
00154   if (registry.Get("LowActivityThreshold", tmpd))
00155                                          fLowActivityThreshold = tmpd;
00156 }
00157 //_____________________________________________________________________
00158 bool LIPatternFinderSimple::IsLightInjectionTrash(
00159                                             CandDigitListHandle * cdlh)
00160 {
00161   MSG("LIPatternFinder", Msg::kVerbose)
00162                             << "LIPatternFinderSimple running" << endl;
00163 
00164   CandDigitHandleItr cdh_iter ( cdlh->GetDaughterIterator() );
00165 
00166   vector<CandDigitHandle *> digits;
00167   
00168   while ( CandDigitHandle * digit = cdh_iter.Ptr() ) {
00169 
00170     digits.push_back(digit);
00171         
00172     cdh_iter.Next();
00173   }
00174 
00175   sort(digits.begin(), digits.end(), min_plane()); // sort in pl.-nu.
00176   
00177   //PrintSnarl(digits);
00178 
00179   double asymmetry  = GetEWAsymmetry(digits);
00180   double tot_charge = GetTotalCharge(digits);
00181 
00182   vector<double> segment_activity =
00183                                 ActivityBetweenCrateBoundaries(digits);
00184 
00185   sort(segment_activity.begin(), segment_activity.end());
00186 
00187   double first_max  = segment_activity[ segment_activity.size()-1 ];
00188   double second_max = segment_activity[ segment_activity.size()-2 ];
00189   
00190   MSG("LIPatternFinder", Msg::kVerbose)
00191           << "------------------------- LIPatternFinderSimple summary:"
00192           << endl;             
00193   MSG("LIPatternFinder", Msg::kVerbose)
00194                            << "E-W Asymmetry  = " << asymmetry << endl;
00195   MSG("LIPatternFinder", Msg::kVerbose)
00196                             << "N-Digits  = " << digits.size() << endl;
00197   MSG("LIPatternFinder", Msg::kVerbose)
00198                            << "Total charge  = " << tot_charge << endl;
00199   MSG("LIPatternFinder", Msg::kVerbose)
00200        << "Fraction of active planes between crate boundaries" << endl;
00201   MSG("LIPatternFinder", Msg::kVerbose)
00202                             << "    - 1st max = " << first_max << endl;
00203   MSG("LIPatternFinder", Msg::kVerbose)
00204                            << "    - 2nd max = " << second_max << endl;
00205 
00206   //-- check for large EAST-WEST asymmetry
00207   bool exceeds_max_EW_asymmetry = (asymmetry     > fMaxEWAsymmetry);
00208 
00209   //-- check if event exceeds a maximum number of digits
00210   bool exceeds_max_n_digits     = (digits.size() > fMaxNDigits);
00211 
00212   //-- check if event exceeds a maximum charge
00213   bool exceeds_max_charge       = (tot_charge    > fMaxCharge);
00214 
00215   //-- check if event activity is confined to a single segment (=
00216   //   area between two crate boundaries). To do this I have
00217   //   calculated the fraction of active planes in each segment
00218   //   and check whether the 1st maximum is very high while the
00219   //   2nd maximum is low.
00220   bool shows_segment_asymmetry  =
00221                (first_max  > fHighActivityThreshold) && 
00222                                  (second_max < fLowActivityThreshold);
00223 
00224   bool is_LI = exceeds_max_EW_asymmetry &&
00225                           exceeds_max_n_digits &&
00226                                     exceeds_max_charge &&
00227                                               shows_segment_asymmetry;  
00228   return is_LI;
00229 }
00230 //_____________________________________________________________________
00231 double LIPatternFinderSimple::GetEWAsymmetry(
00232                         const vector<CandDigitHandle *> & digits) const
00233 {
00234 // returns the net |WEST side - EAST side| charge
00235   
00236   //-- copy input vector
00237 
00238   vector<CandDigitHandle *> digits_cp( digits.size() );
00239   
00240   copy( digits.begin(), digits.end(), digits_cp.begin() );
00241 
00242   //-- East-West partition
00243   
00244   vector<CandDigitHandle *>::iterator part_iter = partition(
00245                  digits_cp.begin(), digits_cp.end(), is_east_side() );
00246 
00247   //-- accumulate charge
00248   
00249   double q_east = accumulate(
00250                           digits_cp.begin(), part_iter, 0.0, sum_q());
00251   double q_west = accumulate(
00252                           part_iter, digits_cp.end(), 0.0, sum_q());
00253 
00254   MSG("LIPatternFinder", Msg::kVerbose) << "Q_W = " << q_west << endl;
00255   MSG("LIPatternFinder", Msg::kVerbose) << "Q_E = " << q_east << endl;
00256                           
00257   //-- calculate asymmetry
00258 
00259   double asymmetry = fabs(q_west-q_east);
00260 
00261   return asymmetry; 
00262 }
00263 //_____________________________________________________________________
00264 double LIPatternFinderSimple::GetTotalCharge(
00265                         const vector<CandDigitHandle *> & digits) const
00266 {
00267 // returns the total charge
00268 
00269   double q = accumulate(digits.begin(), digits.end(), 0.0, sum_q());
00270 
00271   return q;
00272 }
00273 //_____________________________________________________________________
00274 double LIPatternFinderSimple::FractionOfActivePlanesInRange(
00275                int plane_min, int plane_max, 
00276                         const vector<CandDigitHandle *> & digits) const
00277 {
00278 // returns the fraction of active planes in the range [pl_min, pl_max]
00279 
00280   int n_total_planes  = 1 + plane_max - plane_min;
00281   int n_active_planes = 0;
00282   
00283   assert(n_total_planes > 0);
00284 
00285   for(int plane = plane_min; plane < plane_max; plane++) {
00286 
00287     int n_digits = count_if(digits.begin(), digits.end(),
00288               is_in_plane_and_above_thr(plane, fPulseHeightThreshold));
00289 
00290     if(n_digits > 0) n_active_planes++;  
00291   }
00292 
00293   double fraction = (double) n_active_planes / (double) n_total_planes;
00294 
00295   return fraction;
00296 }
00297 //_____________________________________________________________________
00298 vector<double>
00299      LIPatternFinderSimple::ActivityBetweenCrateBoundaries(
00300                         const vector<CandDigitHandle *> & digits) const
00301 {
00302   vector<double> active_fraction;
00303 
00304   const int kNDetectorSegments = 8;
00305   
00306   const int kMinPlane[kNDetectorSegments] = {
00307                                1,  65, 129, 193, 250, 314, 378, 442 };
00308   const int kMaxPlane[kNDetectorSegments] = {
00309                               64, 128, 192, 248, 313, 377, 441, 485 };
00310 
00311   for(int isegment = 0; isegment < kNDetectorSegments; isegment++)
00312          active_fraction.push_back(
00313               FractionOfActivePlanesInRange(
00314                    kMinPlane[isegment], kMaxPlane[isegment], digits) );
00315                 
00316   return active_fraction;
00317 }
00318 //_____________________________________________________________________
00319 void LIPatternFinderSimple::PrintSnarl(
00320                         const vector<CandDigitHandle *> & digits) const
00321 {
00322   vector<CandDigitHandle *>::const_iterator digit_iter;
00323 
00324   for(digit_iter = digits.begin();
00325                             digit_iter != digits.end(); ++digit_iter) {
00326 
00327     const PlexSEIdAltL & seid = (*digit_iter)->GetPlexSEIdAltL();
00328     RawChannelId rawchid = (*digit_iter)->GetChannelId();
00329     
00330     MSG("LIPatternFinder", Msg::kVerbose)
00331          << " PL = "    << seid.GetPlane()
00332          << " END = "   << seid.GetEnd()
00333          << " CRATE = " << rawchid.GetCrate()
00334          << " VARC = "  << rawchid.GetVarcId()
00335          << " VMM = "   << rawchid.GetVmm()    
00336          << " Q = "     << (*digit_iter)->GetCharge() << endl;
00337   }
00338 }
00339 //_____________________________________________________________________

Generated on Mon Feb 15 11:06:52 2010 for loon by  doxygen 1.3.9.1