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

Morgue.cxx

Go to the documentation of this file.
00001 
00003 // Morgue
00005 //
00006 // This is a long-awaited attempt to build a fully-featured CandMorgue
00007 // class.  It's function is to remain in Candidate files and inform other
00008 // reconstructed data about things that might comprimise data quality in this
00009 // event.
00010 //
00011 // In particular it records:
00012 //  - A history of when individual strips go dead (and when they come alive again)
00013 //    due to readout deadtime
00014 //  - A list of strips that may have associated hardware problems (and the severity of the problems)
00015 //  - A record of when the nearest LI injection event occoured
00016 //
00017 //  This object is just for storage and retrieval of this data. The actual compilation
00018 // is done in the Coroner (which declares things dead).
00019 //
00020 // n.tagg1@physics.ox.ac.uk
00022 //
00023 // Some docs:
00024 // Phil A's notes on the topic:
00025 // http://www.slac.stanford.edu/~gmieg/proposals/CandMorgue.txt
00026 //
00028 
00029 
00030 #include "Morgue.h"
00031 #include "MinosObjectMap/MomNavigator.h"
00032 #include "CandData/CandRecord.h"
00033 
00034 ClassImp(Morgue)
00035 
00036 
00037 // Functions used to construct and build Morgue data.
00039 
00040 Morgue::Morgue()
00041 {
00042   Reset();
00043 }
00044 
00045 Morgue::~Morgue()
00046 {
00047   Reset();
00048 }
00049 
00050 void Morgue::Reset()
00051 {
00055   fTriggerTime = 0;
00056   fNearestLiTime = -1e9;
00057   fGraveyard.clear();
00058   fPrison.clear();
00059 }
00060 
00061 
00062 void Morgue::AddDeadStrip(const PlexStripEndId& seid, 
00063                           Double_t fired, 
00064                           Double_t probableRecover, 
00065                           Double_t definateRecover)
00066 {
00070   StripGrave grave;
00071   //grave.fSeid = seid;
00072   grave.fFired = fired;
00073   grave.fProbableRecover = probableRecover;
00074   grave.fDefinateRecover = definateRecover;
00075   
00076   fGraveyard.insert(std::pair<PlexStripEndId,StripGrave>(seid,grave));
00077 }
00078 
00079 
00080 void Morgue::AddBadStrip(const PlexStripEndId& seid, 
00081                          HardwareComponent component,
00082                          Badness_t badness,
00083                          const char* reason )
00084 {
00088   StripPrisonCell cell;
00089   cell.fComponent = component,
00090   cell.fBadness = badness;
00091   cell.fReason  = reason;
00092   Prison_t::iterator it = fPrison.find(seid);
00093   if(it!=fPrison.end()) {
00094     // This strip already has an entry. Take the worst entry.
00095     if(badness > it->second.fBadness) {
00096       it->second = cell;
00097     }
00098     return;
00099   }
00100 
00101   // insert a new entry.
00102   fPrison[seid] = cell;
00103 }
00104 
00105 
00107 // Retrieval: Get ahold of an existing Morgue
00109 
00110 const Morgue& Morgue::GetMorgue(const MomNavigator* mom)
00111 {
00115 
00116    // Find PrimaryCandidateRecord fragment in MOM.
00117   CandRecord *candrec = dynamic_cast<CandRecord *>
00118     (mom->GetFragment("CandRecord", "PrimaryCandidateRecord"));
00119  
00120   return GetMorgue(candrec);
00121 }
00122 
00123 const Morgue& Morgue::GetMorgue(const CandRecord* candrec)
00124 {
00128   static Morgue nullMorgue;
00129   const Morgue* m;
00130 
00131   if (candrec == 0) return nullMorgue;
00132   
00133   m = dynamic_cast<const Morgue*>(candrec->FindComponent("Morgue","Morgue"));
00134   if(m) return *m;
00135 
00136   m = dynamic_cast<const Morgue*>(candrec->FindTemporary("Morgue","Morgue"));
00137   if(m) return *m;
00138 
00139   return nullMorgue;
00140 }
00141 
00143 // Retrieval: Print
00145 void Morgue::Print(Option_t* option) const
00146 {
00150   using namespace std;
00151   cout << "----Morgue-----" << endl;
00152   cout << " Total dead stripends " << GetNumDeadStripEnds() << endl;
00153   cout << "  at trigger time " << fTriggerTime*1e9 << endl;
00154 
00155   if(option[0]=='a') {
00156     Graveyard_t::const_iterator it = fGraveyard.begin();
00157     for(; it!=fGraveyard.end(); it++) {    
00158       Deadness_t deadness = it->second.Deadness(fTriggerTime);
00159       cout << it->first.AsString() 
00160            << "\t" << deadness 
00161            << "\t" << 1e9*(it->second.fFired-fTriggerTime)
00162            << "\t" << 1e9*(it->second.fProbableRecover-fTriggerTime)
00163            << "\t" << 1e9*(it->second.fDefinateRecover-fTriggerTime)
00164            << endl;
00165     }
00166   }
00167 }
00168 
00169 
00171 // Retrieval: Dead chip functions
00173 
00174 Morgue::Deadness_t Morgue::StripGrave::Deadness(Double_t time) const
00175 {
00179   // If the channel fired before now, it could be dead:
00180   if(time <= fFired) return kNotDead;
00181 
00182   // If we're under 5us, the chip hasn't recovered yet for sure:
00183   if(time <= fProbableRecover) return kDead;
00184 
00185   // If we're under 30us the chip may have recovered:
00186   if(time <= fDefinateRecover) return kMaybeDead;
00187 
00188   // Oh, it's recovered.
00189   return kNotDead;
00190 }
00191 
00192 
00193 // These functions return how many strip ends are dead (or possibly dead)
00194 
00195 Int_t 
00196 Morgue::GetNumDeadStripEndsInVeto( Double_t time,
00197                                    Deadness_t deadness) const
00198 {
00205   
00206     if (time == -1.0) time = GetTriggerTime();
00207 
00208   int num = 0;
00209   Graveyard_t::const_iterator it = fGraveyard.begin();
00210   for(; it!=fGraveyard.end(); it++) {
00211 
00212     // Is this strip up for consideration?
00213     if(it->first.IsVetoShield()) {
00214       if(it->second.Deadness(time) >= deadness) {
00215         num++; // It's at least as dead as the requested deadness.
00216       }
00217     }
00218   }
00219   
00220   return num;
00221 
00222 }
00223 
00224 
00225 Int_t 
00226 Morgue::GetNumDeadStripEnds(Int_t plane_start, 
00227                             Int_t plane_end, 
00228                             Double_t time,                          
00229                             Deadness_t deadness) const
00230 {
00237   
00238   if (time == -1.0) time = GetTriggerTime();
00239 
00240   int num = 0;
00241   Graveyard_t::const_iterator it = fGraveyard.begin();
00242   for(; it!=fGraveyard.end(); it++) {
00243 
00244     // Is this strip up for consideration?
00245     if(it->first.GetPlane() <= plane_start) continue;
00246     if(it->first.GetPlane() >= plane_end) continue;    
00247 
00248     
00249     if(it->second.Deadness(time) >= deadness) {
00250       num++; // It's at least as dead as the requested deadness.
00251     }
00252   }
00253   
00254   return num;
00255 }
00256 
00257 Int_t 
00258 Morgue::GetNumDeadStripEnds(Int_t plane, 
00259                             Double_t time, 
00260                             Deadness_t deadness) const
00261 
00262 {
00269 
00270   if(time==-1.0) time = GetTriggerTime();
00271 
00272   int num = 0;
00273   Graveyard_t::const_iterator it = fGraveyard.begin();
00274   for(; it!=fGraveyard.end(); it++) {
00275 
00276     // Is this strip up for consideration?
00277     if(it->first.GetPlane() != plane) continue;
00278     
00279     if(it->second.Deadness(time) >= deadness) {
00280       num++; // It's at least as dead as the requested deadness.
00281     }
00282   }
00283   return num;
00284 }
00285 
00286 // These return the state of a specific strip
00287 Morgue::Deadness_t 
00288 Morgue::StripEndIsDead(PlexStripEndId seid,
00289                        Double_t time) const
00290                        
00291 {
00297 
00298   if(time==-1.0) time = GetTriggerTime();
00299 
00300   // Default: alive.
00301   Deadness_t result = kNotDead;
00302 
00303   // Find all graves for this strip.
00304   std::pair<Graveyard_t::const_iterator,Graveyard_t::const_iterator> range = 
00305     fGraveyard.equal_range(seid);
00306 
00307   // Go through all these possible dead times and return the worst one.
00308   Graveyard_t::const_iterator it;
00309   for(it = range.first; it!= range.second; it++) {
00310     Deadness_t thisres = it->second.Deadness(time);
00311     if(thisres>result) result = thisres;
00312   }
00313   
00314   return result;
00315 }
00316 
00317 const std::vector<PlexStripEndId>& 
00318 Morgue::GetDeadStripEnds(Double_t time, 
00319                          Deadness_t deadness) const
00320 {
00329   if(time == -1.0) time = GetTriggerTime();
00330 
00331   static std::vector<PlexStripEndId> retval;
00332   retval.clear();
00333   retval.reserve(1024);
00334 
00335   Graveyard_t::const_iterator it = fGraveyard.begin();
00336   for(; it!=fGraveyard.end(); it++) {
00337     if(it->second.Deadness(time) >= deadness) retval.push_back(it->first);
00338   }
00339   
00340   return retval;
00341 }
00342 
00343 
00345 // Retrieval: Bad strip functions
00347 
00348 Int_t Morgue::GetNumBadStripEnds(Int_t plane_start, 
00349                                  Int_t plane_end,
00350                                  Badness_t badness ) const
00351 {
00355   int bad_strips = 0;
00356   for(Prison_t::const_iterator it = fPrison.begin(); 
00357       it!= fPrison.end(); ++it) {
00358     int plane = it->first.GetPlane();
00359     if((plane >= plane_start) && (plane <= plane_end)) {
00360       if(it->second.fBadness >= badness) bad_strips++;
00361     }
00362   }
00363   return bad_strips;
00364 }
00365 
00366 Int_t Morgue::GetNumBadStripEnds(Int_t plane,
00367                                  Badness_t badness) const
00368 {
00372   int bad_strips = 0;
00373   for(Prison_t::const_iterator it = fPrison.begin(); 
00374       it!= fPrison.end(); it++) {
00375     if( plane == it->first.GetPlane() ) {
00376       if(it->second.fBadness >= badness) bad_strips++;
00377     }
00378   }
00379   return bad_strips;
00380 }
00381 
00382 Morgue::Badness_t Morgue::StripEndIsBad(const PlexStripEndId& seid) const
00383 {
00387   Prison_t::const_iterator it = fPrison.find(seid);
00388   if(it==fPrison.end()) return kGood;
00389   
00390   return it->second.fBadness;
00391 }
00392 
00393 const char* Morgue::HowIsStripEndBad(const PlexStripEndId& seid) const
00394 {
00401   Prison_t::const_iterator it = fPrison.find(seid);
00402   if(it==fPrison.end()) return "Good";
00403   
00404   if(it->second.fReason) return it->second.fReason;
00405   return "Unknown";
00406 }

Generated on Mon Feb 15 11:07:01 2010 for loon by  doxygen 1.3.9.1