psana_examples/src/DumpDamage.cpp

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id$
00004 //
00005 // Description:
00006 //      Class DumpDamage
00007 //
00008 // Author List:
00009 //
00010 //------------------------------------------------------------------------
00011 
00012 //-----------------------
00013 // This Class's Header --
00014 //-----------------------
00015 #include "psana_examples/DumpDamage.h"
00016 
00017 //-----------------
00018 // C/C++ Headers --
00019 //-----------------
00020 #include <list>
00021 #include <sstream>
00022 #include <iostream>
00023 #include <iomanip>
00024 #include <algorithm>
00025 //-------------------------------
00026 // Collaborating Class Headers --
00027 //-------------------------------
00028 #include "boost/io/ios_state.hpp"
00029 #include "MsgLogger/MsgLogger.h"
00030 
00031 //-----------------------------------------------------------------------
00032 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00033 //-----------------------------------------------------------------------
00034 
00035 using namespace psana_examples;
00036 PSANA_MODULE_FACTORY(DumpDamage)
00037 
00038 namespace {
00039   
00040   struct LocationAndDamage {
00041     bool inCfg;
00042     bool inCalib;
00043     bool inEvent;
00044     bool inDamageMap;
00045     Pds::Damage damage;
00046     std::string eventKeyString;
00047 
00048     LocationAndDamage() : inCfg(false), inCalib(false), inEvent(false), inDamageMap(false), damage(0) {};
00049 
00050     LocationAndDamage(bool _inCfg, bool _inCalib, bool _inEvent, bool _inDamageMap, 
00051                       Pds::Damage _damage, std::string _eventKeyString) 
00052       : inCfg(_inCfg), inCalib(_inCalib), inEvent(_inEvent), 
00053         inDamageMap(_inDamageMap), damage(_damage), eventKeyString(_eventKeyString) {}
00054 
00055     LocationAndDamage(const LocationAndDamage &other) 
00056       : inCfg(other.inCfg), inCalib(other.inCalib), inEvent(other.inEvent), 
00057         inDamageMap(other.inDamageMap), damage(other.damage), eventKeyString(other.eventKeyString) {}
00058 
00059     LocationAndDamage & operator=(const LocationAndDamage &other) {
00060       inCfg = other.inCfg;
00061       inCalib = other.inCalib;
00062       inEvent = other.inEvent;
00063       inDamageMap = other.inDamageMap;
00064       damage = other.damage;
00065       eventKeyString = other.eventKeyString;
00066       return *this;
00067     }
00068 
00069     bool operator <(const struct LocationAndDamage &other) const {
00070       if (inCfg < other.inCfg) return true;
00071       if (inCfg > other.inCfg) return false;
00072       if (inCalib < other.inCalib) return true;
00073       if (inCalib > other.inCalib) return false;
00074       if (inEvent < other.inEvent) return true;
00075       if (inEvent > other.inEvent) return false;
00076       if (inDamageMap < other.inDamageMap) return true;
00077       if (inDamageMap > other.inDamageMap) return false;
00078       if (damage.value() < other.damage.value()) return true;
00079       if (damage.value() > other.damage.value()) return false;
00080       return (eventKeyString < other.eventKeyString);
00081     }
00082   };
00083 
00084   void
00085   setDamage(const boost::shared_ptr<PSEvt::DamageMap> damageMap, const PSEvt::EventKey & key, 
00086             bool &inDamageMap, Pds::Damage & damage) 
00087   {
00088     inDamageMap = false;
00089     damage = Pds::Damage(0);
00090     if (damageMap) {
00091       PSEvt::DamageMap::const_iterator damagePos = damageMap->find(key);
00092       if (damagePos != damageMap->end()) {
00093         inDamageMap = true;
00094         damage = damagePos->second;
00095       }
00096     }
00097   }
00098   
00099 
00100 } // local namespace
00101 
00102 //              ----------------------------------------
00103 //              -- Public Function Member Definitions --
00104 //              ----------------------------------------
00105 
00106 namespace psana_examples {
00107 
00108 //----------------
00109 // Constructors --
00110 //----------------
00111 DumpDamage::DumpDamage (const std::string& name)
00112   : Module(name)
00113 {
00114   m_totalEvents = -1;
00115 }
00116 
00117 //--------------
00118 // Destructor --
00119 //--------------
00120 DumpDamage::~DumpDamage ()
00121 {
00122 }
00123 
00124 void 
00125 DumpDamage::printKeysAndDamage(std::ostream& out, Event &evt, Env &env) {
00126 
00127   boost::io::ios_flags_saver ifs(out);
00128 
00129   m_damageMap = evt.get();
00130   bool inDamageMap;
00131   Pds::Damage damage;
00132 
00133   std::map<PSEvt::EventKey, LocationAndDamage> allKeys;
00134   std::list<EventKey>::const_iterator iter;
00135 
00136   const PSEvt::HistI * configHist  = env.configStore().proxyDict()->hist();
00137   if (not configHist) MsgLog(name(),fatal,"Internal error - no HistI object in configStore");
00138   
00139   const std::list<EventKey> configKeys = env.configStore().keys();
00140 
00141   // gather list of event keys and their damage for printing
00142 
00143   // find config keys that we have not seen or that have changed since we last saw them
00144   for (iter = configKeys.begin(); iter != configKeys.end(); ++iter) {
00145     const EventKey &configKey = *iter;
00146     if ( (m_configUpdates.find(configKey) == m_configUpdates.end()) or
00147          (m_configUpdates[configKey] < configHist->updates(configKey)) ) {
00148       setDamage(m_damageMap, configKey, inDamageMap, damage);
00149       std::ostringstream configKeyString;
00150       configKeyString << configKey;
00151       allKeys[configKey] = LocationAndDamage(true,false,false,inDamageMap,damage,configKeyString.str());
00152       m_configUpdates[configKey] = configHist->updates(configKey);
00153     }
00154   }
00155 
00156   const PSEvt::HistI * calibHist  = env.calibStore().proxyDict()->hist();
00157   if (not calibHist) MsgLog(name(),fatal,"Internal error - no HistI object in calibStore");
00158 
00159   const std::list<EventKey> calibKeys = env.calibStore().keys();
00160 
00161   // find calib keys that we have not seen or that have changed since we last saw them
00162   for (iter = calibKeys.begin(); iter != calibKeys.end(); ++iter) {
00163     const EventKey &calibKey = *iter;
00164     if ( (m_calibUpdates.find(calibKey) == m_calibUpdates.end()) or
00165          (m_calibUpdates[calibKey] < calibHist->updates(calibKey)) ) {
00166       setDamage(m_damageMap, calibKey, inDamageMap, damage);
00167       std::ostringstream calibKeyString;
00168       calibKeyString << calibKey;
00169       std::map<PSEvt::EventKey, LocationAndDamage>::iterator keyPos = allKeys.find(calibKey);
00170       if (keyPos != allKeys.end()) {
00171         // a key in both the calib and config store seems odd, print warning
00172         MsgLog(name(),warning," calib key: " << calibKey << " was also in configStore");
00173         keyPos->second.inCalib = true;
00174         if ((keyPos->second.inDamageMap != inDamageMap) or
00175             (keyPos->second.damage.value() != damage.value())) {
00176           // Getting different damage values for the same key suggests a bug
00177           MsgLog(name(),error,"  calib key " << calibKey << " was also in configStore " 
00178                  << " with different damage.  Discarding new calib damage values which are: "
00179                  << "found in damageMap=" << inDamageMap
00180                  << " damage= 0x" << std::hex << damage.value());
00181         }
00182       } else {
00183         allKeys[calibKey] = LocationAndDamage(false,true,false,inDamageMap,damage,calibKeyString.str());
00184       }
00185       m_calibUpdates[calibKey] = calibHist->updates(calibKey);
00186     }
00187   }
00188 
00189   const std::list<EventKey> eventKeys = evt.keys();
00190 
00191   // now go through all even keys
00192   for (iter = eventKeys.begin(); iter != eventKeys.end(); ++iter) {
00193     const EventKey &eventKey = *iter;
00194     setDamage(m_damageMap, eventKey, inDamageMap, damage);
00195     std::ostringstream eventKeyString;
00196     eventKeyString << eventKey;
00197     std::map<PSEvt::EventKey, LocationAndDamage>::iterator keyPos = allKeys.find(eventKey);
00198     if (keyPos == allKeys.end()) {
00199       allKeys[eventKey] = LocationAndDamage(false,false,true,inDamageMap,damage, eventKeyString.str());
00200     } else {
00201       LocationAndDamage &locAndDamage = keyPos->second;
00202       locAndDamage.inEvent = true;
00203       if ((locAndDamage.inDamageMap != inDamageMap) or (locAndDamage.damage.value() != damage.value())) {
00204         // Getting different damage values for the same key suggests a bug
00205         MsgLog(name(), error, "event key " << eventKey 
00206                << " was also a config or calib keys but with different damage. old values: "
00207                << "inDamageMap= " 
00208                << locAndDamage.inDamageMap  << " damage= 0x" 
00209                << std::hex << locAndDamage.damage.value()
00210                << " discarding old values");
00211         locAndDamage.inDamageMap = inDamageMap;
00212         locAndDamage.damage = damage;
00213       }
00214     }
00215   }
00216 
00217   // find all keys that are damaged, but were not in the event
00218   if (m_damageMap) {
00219     PSEvt::DamageMap::const_iterator damageIter;
00220     for (damageIter = m_damageMap->begin(); damageIter != m_damageMap->end(); ++damageIter) {
00221       const PSEvt::EventKey &eventKey = damageIter->first;
00222       Pds::Damage damage = damageIter->second;
00223       std::ostringstream eventKeyString;
00224       eventKeyString << eventKey;
00225       std::map<PSEvt::EventKey, LocationAndDamage>::iterator keyPos = allKeys.find(eventKey);
00226       if (keyPos == allKeys.end()) {
00227         allKeys[eventKey] = LocationAndDamage(false,false,false,true,damage, eventKeyString.str());
00228       }
00229     }
00230   }
00231       
00232   std::vector<LocationAndDamage> allKeysList;
00233   std::map<PSEvt::EventKey, LocationAndDamage>::iterator pos;
00234   for (pos = allKeys.begin(); pos != allKeys.end(); ++pos) {
00235     allKeysList.push_back(pos->second);
00236   }
00237   sort(allKeysList.begin(), allKeysList.end());
00238 
00239   // finally, print all the keys
00240   std::vector<LocationAndDamage>::iterator printPos;
00241   for (printPos = allKeysList.begin(); printPos != allKeysList.end(); ++printPos) {
00242     LocationAndDamage &locAndDamage = *printPos;
00243     out << "    ";
00244     out << ((locAndDamage.inCfg) ? "cfg" : "---");
00245     out << ((locAndDamage.inCalib) ? " clb" : " ---");
00246     out << ((locAndDamage.inEvent) ? " evt" : " ---");
00247     out << ((locAndDamage.inDamageMap) ? " dmg" : " ---");
00248     out << " ";
00249     std::ostringstream damageBits;
00250     if (locAndDamage.inDamageMap) {
00251       out << "0x" << std::setw(8) << std::setfill('0') << std::hex << locAndDamage.damage.value();
00252       uint32_t value = locAndDamage.damage.value();
00253       if (value) {
00254         bool DroppedContribution    = value & (1<<Pds::Damage::DroppedContribution);
00255         bool Uninitialized          = value & (1<<Pds::Damage::Uninitialized);
00256         bool OutOfOrder             = value & (1<<Pds::Damage::OutOfOrder);
00257         bool OutOfSynch             = value & (1<<Pds::Damage::OutOfSynch);
00258         bool UserDefined            = value & (1<<Pds::Damage::UserDefined);
00259         bool IncompleteContribution = value & (1<<Pds::Damage::IncompleteContribution);
00260         bool ContainsIncomplete     = value & (1<<Pds::Damage::ContainsIncomplete);
00261         damageBits << "dropped=" << DroppedContribution;
00262         damageBits << " uninitialized="<<Uninitialized;
00263         damageBits << " OutOfOrder="<<OutOfOrder;
00264         damageBits << " OutOfSynch="<<OutOfSynch;
00265         damageBits << " UserDefined="<<UserDefined;
00266         damageBits << " IncompleteContribution="<<IncompleteContribution;
00267         damageBits << " ContainsIncomplete="<<ContainsIncomplete;
00268         damageBits << " userBits=0x"<< locAndDamage.damage.userBits();
00269       }
00270     } else {
00271       out << "          ";
00272     }
00273     out << " " << locAndDamage.eventKeyString << '\n';
00274     std::string damageBitsStr = damageBits.str();
00275     if (damageBitsStr.size()) {
00276       out << "                    " << damageBitsStr << '\n';
00277     }
00278   }
00279   // report on any src only damage:
00280   if (m_damageMap) {
00281     const std::vector<std::pair<Pds::Src,Pds::Damage> > & srcDmgList = 
00282       m_damageMap->getSrcDroppedContributions();
00283     if (srcDmgList.size()>0) {
00284       out << " -------- src damage with dropped contribs --------- \n";
00285       for (unsigned idx=0; idx < srcDmgList.size(); ++idx) {
00286         const std::pair<Pds::Src,Pds::Damage> &srcDmgPair = srcDmgList.at(idx);
00287         const Pds::Src &src = srcDmgPair.first;
00288         const Pds::Damage &dmg = srcDmgPair.second;
00289         out << "   0x" << std::setw(8) << std::setfill('0') << std::hex << dmg.value();
00290         out << "  " << src << '\n';
00291       }
00292     }
00293   }
00294 }
00295 
00296 
00297 void 
00298 DumpDamage::beginJob(Event& evt, Env& env)
00299 {
00300   m_runNumber = -1;
00301   MsgLog(name(), info, " beginJob()");
00302   printKeysAndDamage(std::cout, evt, env);
00303 }
00304 
00305 void 
00306 DumpDamage::beginRun(Event& evt, Env& env)
00307 {
00308   m_calibCycleNumber = -1;
00309   MsgLog(name(),info," beginRun(): run=" << ++m_runNumber);
00310   printKeysAndDamage(std::cout, evt, env);
00311 }
00312 
00313 void 
00314 DumpDamage::beginCalibCycle(Event& evt, Env& env)
00315 {
00316   m_eventNumber = -1;
00317   MsgLog(name(),info," beginCalibCycle() run=" << m_runNumber << " calib=" << ++m_calibCycleNumber);
00318   printKeysAndDamage(std::cout, evt, env);
00319 }
00320 
00321 void 
00322 DumpDamage::event(Event& evt, Env& env)
00323 {
00324   MsgLog(name(),info," event() run=" << m_runNumber 
00325          << " calib=" << m_calibCycleNumber << " eventNumber=" 
00326          << ++m_eventNumber << " totalEvents= " << ++m_totalEvents );
00327   printKeysAndDamage(std::cout, evt, env);
00328 }
00329 
00330 /// Method which is called at the end of the calibration cycle
00331 void
00332 DumpDamage::endCalibCycle(Event& evt, Env& env)
00333 {
00334   MsgLog(name(), info, " endCalibCycle() run=" << m_runNumber << " calib=" << m_calibCycleNumber);
00335   printKeysAndDamage(std::cout, evt, env);
00336 }
00337 
00338 /// Method which is called at the end of the run
00339 void
00340 DumpDamage::endRun(Event& evt, Env& env)
00341 {
00342   MsgLog(name(), info, " endRun() run=" << m_runNumber);
00343   printKeysAndDamage(std::cout, evt, env);
00344 }
00345 
00346 /// Method which is called once at the end of the job
00347 void
00348 DumpDamage::endJob(Event& evt, Env& env)
00349 {
00350   MsgLog(name(), info, " endJob()");
00351   printKeysAndDamage(std::cout, evt, env);
00352 }
00353 
00354 
00355 } // namespace psana_examples

Generated on 19 Dec 2016 for PSANAmodules by  doxygen 1.4.7