TimeTool/src/Analyze.cpp

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id$
00004 //
00005 // Description:
00006 //      Class TimeTool::Analyze...
00007 //
00008 // Author List:
00009 //      Matthew J. Weaver
00010 //
00011 //------------------------------------------------------------------------
00012 
00013 #define __STDC_LIMIT_MACROS
00014 
00015 //-----------------------
00016 // This Class's Header --
00017 //-----------------------
00018 #include "TimeTool/Analyze.h"
00019 
00020 //-----------------
00021 // C/C++ Headers --
00022 //-----------------
00023 #include <cfloat>
00024 #include <limits.h>
00025 #include <fstream>
00026 #include <iterator>
00027 #include <algorithm>
00028 #include "psalg/psalg.h"
00029 
00030 //-------------------------------
00031 // Collaborating Class Headers --
00032 //-------------------------------
00033 // to work with detector data include corresponding 
00034 // header from psddl_psana package
00035 #include "MsgLogger/MsgLogger.h"
00036 #include "PSEvt/EventId.h"
00037 #include "psddl_psana/evr.ddl.h"
00038 #include "psddl_psana/lusi.ddl.h"
00039 #include "psddl_psana/camera.ddl.h"
00040 #include "psddl_psana/opal1k.ddl.h"
00041 #include "psddl_psana/timetool.ddl.h"
00042 #include "ndarray/ndarray.h"
00043 #include "PSCalib/CalibParsStore.h"
00044 
00045 #include <iomanip>
00046 #include <fstream>
00047 #include <sstream>
00048 
00049 //-----------------------------------------------------------------------
00050 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00051 //-----------------------------------------------------------------------
00052 
00053 // This declares this class as psana module
00054 using namespace TimeTool;
00055 PSANA_MODULE_FACTORY(Analyze)
00056 
00057 namespace {
00058   
00059   static bool 
00060   calculate_logic(const ndarray<const Psana::TimeTool::EventLogic,1>& cfg,
00061                   const ndarray<const Psana::EvrData::FIFOEvent,1>& event)
00062   {
00063     bool v = (cfg.size()==0) ||
00064       (cfg[0].logic_op() == Psana::TimeTool::EventLogic::L_AND ||
00065        cfg[0].logic_op() == Psana::TimeTool::EventLogic::L_AND_NOT);
00066     for(unsigned i=0; i<cfg.size(); i++) {
00067 
00068       bool p=false;
00069       for(unsigned j=0; j<event.size(); j++)
00070         if (event[j].eventCode()==cfg[i].event_code()) {
00071           p=true;
00072           break;
00073         }
00074       switch(cfg[i].logic_op()) {
00075       case Psana::TimeTool::EventLogic::L_OR:
00076         v = v||p; break;
00077       case Psana::TimeTool::EventLogic::L_AND:
00078         v = v&&p; break;
00079       case Psana::TimeTool::EventLogic::L_OR_NOT:
00080         v = v||!p; break;
00081       case Psana::TimeTool::EventLogic::L_AND_NOT:
00082         v = v&&!p; break;
00083       default: break;
00084       }
00085     }
00086     return v;
00087   }
00088 
00089   class TimeToolData : public Psana::TimeTool::DataV2 {
00090   public:
00091     // class to provide high level TimeTool::DataV2 type to users in the
00092     // event store. Presently we do not save the three arrays
00093     // projected_signal, projected_sideband, and projected_reference in this
00094     // event store data. If all of these are needed, note that the make_shared 
00095     // pattern used to create an instance of this object has a limit of 9 
00096     // parameters for the constructor, and those 3 would bring us to 10 parameters.
00097     TimeToolData(Psana::TimeTool::DataV2::EventType event_type_arg,
00098                  double amplitude_arg,
00099                  double position_pixel_arg,
00100                  double position_time_arg,
00101                  double position_fwhm_arg,
00102                  double ref_amplitude_arg,
00103                  double nxt_amplitude_arg)
00104       : m_event_type(event_type_arg),
00105         m_amplitude(amplitude_arg),
00106         m_position_pixel(position_pixel_arg),
00107         m_position_time(position_time_arg),
00108         m_position_fwhm(position_fwhm_arg),
00109         m_ref_amplitude(ref_amplitude_arg),
00110         m_nxt_amplitude(nxt_amplitude_arg)
00111     {}
00112 
00113     virtual enum Psana::TimeTool::DataV2::EventType event_type() const { return m_event_type; }
00114     virtual double amplitude() const { return m_amplitude; }
00115     virtual double position_pixel() const { return m_position_pixel; }
00116     virtual double position_time() const { return m_position_time; };
00117     virtual double position_fwhm() const { return m_position_fwhm; };
00118     virtual double ref_amplitude() const { return m_ref_amplitude; };
00119     virtual double nxt_amplitude() const { return m_nxt_amplitude; };
00120     virtual ndarray<const int32_t, 1> projected_signal() const { return m_projected_signal; };
00121     virtual ndarray<const int32_t, 1> projected_sideband() const { return m_projected_sideband; };
00122     virtual ndarray<const int32_t, 1> projected_reference() const { return m_projected_reference; };
00123 
00124   private:
00125     Psana::TimeTool::DataV2::EventType m_event_type;
00126     double m_amplitude;
00127     double m_position_pixel;
00128     double m_position_time;
00129     double m_position_fwhm;
00130     double m_ref_amplitude;
00131     double m_nxt_amplitude;
00132     ndarray<const int32_t, 1> m_projected_signal;
00133     ndarray<const int32_t, 1> m_projected_sideband;
00134     ndarray<const int32_t, 1> m_projected_reference;
00135   };
00136 
00137   // TODO: move to psalg
00138   void local_rolling_average(const ndarray<const uint16_t,2> &newArray, 
00139                              ndarray<double,2> &accumulatedArray, 
00140                              double newFraction,
00141                              const std::string &loggerName) {
00142     if (accumulatedArray.empty()) {
00143       accumulatedArray = ndarray<double,2>(newArray.shape());
00144       for (unsigned row = 0; row < newArray.shape()[0]; ++row) {
00145         for (unsigned col = 0; col < newArray.shape()[1]; ++col) {
00146           accumulatedArray[row][col] = double(newArray[row][col]);
00147         }
00148       }
00149     } else {
00150       if ((newArray.shape()[0] != accumulatedArray.shape()[0]) or 
00151           (newArray.shape()[1] != accumulatedArray.shape()[1])) {
00152         MsgLog(loggerName, error, "newArray shape != accumArray shape");
00153       }
00154       for (unsigned row = 0; row < newArray.shape()[0]; ++row) {
00155         for (unsigned col = 0; col < newArray.shape()[1]; ++col) {
00156           double oldVal = accumulatedArray[row][col];
00157           accumulatedArray[row][col] = (1.0-newFraction)*oldVal + newFraction * newArray[row][col];
00158         }
00159       }
00160       
00161     }
00162   }
00163 
00164 }
00165 
00166 
00167 //              ----------------------------------------
00168 //              -- Public Function Member Definitions --
00169 //              ----------------------------------------
00170 
00171 namespace TimeTool {
00172 
00173 //----------------
00174 // Constructors --
00175 //----------------
00176 Analyze::Analyze (const std::string& name)
00177   : Module(name)
00178 {
00179   std::string emptys;
00180 
00181   // get the values from configuration or use defaults
00182   m_get_key = configSrc("get_key","DetInfo(:Opal1000)");
00183   m_beam_on_off_key = configStr("beam_on_off_key","");
00184   m_laser_on_off_key = configStr("laser_on_off_key","");
00185   m_put_key = configStr("put_key","TTSPEC");
00186 
00187   // update a list of valid configuration keys so that we can warn user of mispecfied configuration
00188   m_validConfigKeys.insert("get_key");
00189   m_validConfigKeys.insert("beam_on_off_key");
00190   m_validConfigKeys.insert("laser_on_off_key");
00191   m_validConfigKeys.insert("put_key");
00192   m_validConfigKeys.insert("eventcode_nobeam");
00193 
00194   int eventcode_nobeam = config("eventcode_nobeam",0);
00195   if (eventcode_nobeam>0) {
00196     ndarray<Psana::TimeTool::EventLogic,1> e = 
00197       make_ndarray<Psana::TimeTool::EventLogic>(1);
00198     e[0] = Psana::TimeTool::EventLogic(eventcode_nobeam,
00199                                        Psana::TimeTool::EventLogic::L_AND_NOT);
00200     m_beam_logic = e;
00201   }
00202   else if (eventcode_nobeam<0) {
00203     ndarray<Psana::TimeTool::EventLogic,1> e = 
00204       make_ndarray<Psana::TimeTool::EventLogic>(1);
00205     e[0] = Psana::TimeTool::EventLogic(-eventcode_nobeam,
00206                                        Psana::TimeTool::EventLogic::L_AND);
00207     m_beam_logic = e;
00208   }
00209 
00210   int eventcode_skip   = config("eventcode_skip",0);
00211   m_validConfigKeys.insert("eventcode_skip");
00212 
00213   if (eventcode_skip>0) {
00214     ndarray<Psana::TimeTool::EventLogic,1> e = 
00215       make_ndarray<Psana::TimeTool::EventLogic>(1);
00216     e[0] = Psana::TimeTool::EventLogic(eventcode_skip,
00217                                        Psana::TimeTool::EventLogic::L_AND_NOT);
00218     m_laser_logic = e;
00219   }
00220   else if (eventcode_skip<0) {
00221     ndarray<Psana::TimeTool::EventLogic,1> e = 
00222       make_ndarray<Psana::TimeTool::EventLogic>(1);
00223     e[0] = Psana::TimeTool::EventLogic(-eventcode_skip,
00224                                        Psana::TimeTool::EventLogic::L_AND);
00225     m_laser_logic = e;
00226   }
00227 
00228   m_validConfigKeys.insert("ipm_get_key");
00229   m_validConfigKeys.insert("ipm_beam_threshold");
00230   m_validConfigKeys.insert("calib_poly");
00231 
00232   m_ipm_get_key        = configStr("ipm_get_key",emptys);
00233   m_ipm_beam_threshold = config("ipm_beam_threshold",DBL_MIN);
00234 
00235   { std::vector<double> v = configList("calib_poly");
00236     if (v.size()) {
00237       ndarray<double,1> e = make_ndarray<double>(v.size());
00238       std::copy(v.begin(),v.end(),e.begin());
00239       m_calib_poly = e;
00240     } }
00241 
00242   m_projectX_set = !config("projectX",true).isDefault();
00243   m_projectX     = config("projectX",true);
00244   m_proj_cut     = config("proj_cut" ,INT_MIN);
00245 
00246   m_validConfigKeys.insert("proj_cut");
00247   m_validConfigKeys.insert("projectX");
00248 
00249   std::vector<unsigned> uempty;
00250   std::vector<unsigned> sig_roi_x = configList("sig_roi_x", uempty);
00251   std::vector<unsigned> sig_roi_y = configList("sig_roi_y", uempty);
00252   std::vector<unsigned> sb_roi_x = configList("sb_roi_x", uempty);
00253   std::vector<unsigned> sb_roi_y = configList("sb_roi_y", uempty);
00254 
00255   m_validConfigKeys.insert("sb_roi_x");
00256   m_validConfigKeys.insert("sb_roi_y");
00257   m_validConfigKeys.insert("sig_roi_x");
00258   m_validConfigKeys.insert("sig_roi_y");
00259 
00260   m_frame_roi[0] = m_frame_roi[1] = 0;
00261 
00262   if (sb_roi_x.size() && sb_roi_y.size()) {
00263     m_sb_roi_set = true;
00264     if (m_projectX) {
00265       if (sb_roi_x[0]!=sig_roi_x[0] ||
00266           sb_roi_x[1]!=sig_roi_x[1]) {
00267         sb_roi_x[0] = sig_roi_x[0];
00268         sb_roi_x[1] = sig_roi_x[1];
00269         MsgLog(name, warning, 
00270                name << ": Signal and sideband roi x ranges differ.  Setting sideband roi to signal.");
00271       }
00272       if ((sb_roi_y[1]-sb_roi_y[0]) != (sig_roi_y[1]-sig_roi_y[0])) {
00273         MsgLog(name, fatal, 
00274                name << ": Signal and sideband roi y range sizes differ.");
00275       }
00276     }
00277     else {
00278       if (sb_roi_y[0]!=sig_roi_y[0] ||
00279           sb_roi_y[1]!=sig_roi_y[1]) {
00280         sb_roi_y[0] = sig_roi_y[0];
00281         sb_roi_y[1] = sig_roi_y[1];
00282         MsgLog(name, warning, 
00283                name << ": Signal and sideband roi y ranges differ.  Setting sideband roi to signal.");
00284       }
00285       if ((sb_roi_x[1]-sb_roi_x[0]) != (sig_roi_x[1]-sig_roi_x[0])) {
00286         MsgLog(name, fatal, 
00287                name << ": Signal and sideband roi x range sizes differ.");
00288       }
00289     }
00290     m_sb_roi_lo[0] = sb_roi_y[0];
00291     m_sb_roi_hi[0] = sb_roi_y[1];
00292     m_sb_roi_lo[1] = sb_roi_x[0];
00293     m_sb_roi_hi[1] = sb_roi_x[1];
00294   }
00295   else {
00296     m_sb_roi_set = false;
00297     m_sb_roi_lo[0] = m_sb_roi_hi[0] = 0;
00298     m_sb_roi_lo[1] = m_sb_roi_hi[1] = 0;
00299   }
00300 
00301   if (sig_roi_x.size() && sig_roi_y.size()) {
00302     m_sig_roi_set   = true;
00303     m_sig_roi_lo[0] = sig_roi_y[0];
00304     m_sig_roi_hi[0] = sig_roi_y[1];
00305     m_sig_roi_lo[1] = sig_roi_x[0];
00306     m_sig_roi_hi[1] = sig_roi_x[1];
00307   }
00308   else {
00309     m_sig_roi_set   = false;
00310     m_sig_roi_lo[0] = 0;
00311     m_sig_roi_hi[0] = 0;
00312     m_sig_roi_lo[1] = 0;
00313     m_sig_roi_hi[1] = 0;
00314   }
00315 
00316   m_ref_roi_set = false;
00317   m_ref_roi_lo[0] = 0;
00318   m_ref_roi_hi[0] = 0;
00319   m_ref_roi_lo[1] = 0;
00320   m_ref_roi_hi[1] = 0;
00321 
00322   m_sb_avg_fraction  = config("sb_avg_fraction",DBL_MIN);
00323   m_ref_avg_fraction = config("ref_avg_fraction",DBL_MIN);
00324 
00325   m_validConfigKeys.insert("sb_avg_fraction");
00326   m_validConfigKeys.insert("ref_avg_fraction");
00327   m_validConfigKeys.insert("weights");
00328   m_validConfigKeys.insert("weights_file");
00329   m_validConfigKeys.insert("ref_load");
00330 
00331   { std::vector<double> w = configList("weights");
00332     if (w.size()==0) {
00333       std::string weights_file = configStr("weights_file");
00334       if (!weights_file.empty()) {
00335         std::ifstream s(weights_file.c_str());
00336         while(s.good()) {
00337           double v;
00338           s >> v;
00339           w.push_back(v);
00340         }
00341       }
00342     }
00343     if (w.size()==0) {
00344       //      MsgLog(name, fatal, name << ": No weights defined for timetool");
00345     }
00346     else {
00347       //  Reverse the ordering of the weights for the
00348       //  psalg::finite_impulse_response implementation
00349       ndarray<double,1> a = make_ndarray<double>(w.size());
00350       for(unsigned i=0; i<w.size(); i++)
00351         a[i] = w[w.size()-i-1];
00352       m_weights = a;
00353     }
00354   }
00355 
00356   m_use_calib_db_ref = config("use_calib_db_ref",false);
00357   m_validConfigKeys.insert("use_calib_db_ref");
00358 
00359   std::string ref_load  = configStr("ref_load", "");
00360   if (!ref_load.empty()) {
00361     if (m_use_calib_db_ref) {
00362       MsgLog(name, fatal, name << ": ref_load and use_calib_db_ref confict, both are set.");
00363     }
00364     std::ifstream s(ref_load.c_str());
00365     if (not s) {
00366       MsgLog(name, fatal, "Could not open reference file: " << ref_load);
00367     }
00368     std::vector<double> ref;
00369     while(s.good()) {
00370       double v;
00371       s >> v;
00372       ref.push_back(v);
00373     }
00374     ref.resize(ref.size()-1);
00375 
00376     m_ref_avg = make_ndarray<double>(ref.size());
00377     for(unsigned i=0; i<ref.size(); i++)
00378       m_ref_avg[i] = ref[i];
00379 
00380     MsgLog(name, info, name <<": loaded reference of size " << m_ref_avg.size());
00381     for(unsigned i=0; i<5; i++) 
00382       MsgLog(name, info, name <<": ref[" << i << "=" << m_ref_avg[i]);
00383     MsgLog(name, info, name << ": ..");
00384     for(unsigned i=m_ref_avg.size()-5; i<m_ref_avg.size(); i++) 
00385       MsgLog(name, info, name <<": ref[" << i << "=" << m_ref_avg[i]);
00386 
00387   }
00388 
00389   m_ref_store = configStr("ref_store");
00390 
00391   m_pedestal  = 0;
00392 
00393   m_analyze_event = config("analyze_event",-1);
00394 
00395   if (config("eventdump",false)) {
00396     m_eventDump.init(m_put_key);
00397   }
00398 
00399   unsigned ndump = config("dump",0);
00400   for(unsigned i=0; i<ndump; i++)
00401     m_hdump.push_back(DumpH());
00402 
00403   m_validConfigKeys.insert("dump");
00404   m_validConfigKeys.insert("eventdump");
00405   m_validConfigKeys.insert("analyze_event");
00406   m_validConfigKeys.insert("ref_store");
00407 
00408   checkForInvalidConfigKeys(m_validConfigKeys);
00409 }
00410 
00411 void Analyze::checkForInvalidConfigKeys(const std::set<std::string> &validConfigKeys) const {
00412   ConfigSvc::ConfigSvc cfgSvc = configSvc();
00413   std::list<std::string> configKeys = cfgSvc.getKeys(name());
00414   std::list<std::string>::iterator iter;
00415   bool invalidKeyFound = false;
00416   for (iter = configKeys.begin(); iter != configKeys.end(); ++iter) {
00417     if (validConfigKeys.end()==validConfigKeys.find(*iter)) {
00418       MsgLog(name(), error, name() << ": invalid configuration key: " << *iter);
00419       invalidKeyFound = true;
00420     }
00421   }
00422   if (invalidKeyFound) {
00423     WithMsgLog(name(), info, str) {
00424       str << ": invalid keys found. The valid keys are: ";
00425       std::ostream_iterator<std::string> str_it(str, "\n   ");
00426       std::copy(validConfigKeys.begin(), validConfigKeys.end(), str_it);
00427     }
00428   }
00429 }
00430 
00431 //--------------
00432 // Destructor --
00433 //--------------
00434 Analyze::~Analyze ()
00435 {
00436 }
00437 
00438 /// Method which is called once at the beginning of the job
00439 void 
00440 Analyze::beginJob(Event& evt, Env& env)
00441 {
00442   m_analyze_projections = false;
00443 
00444   if (m_hdump.size()>0) {
00445     m_hmgr = env.hmgr();
00446     if (not m_hmgr) {
00447       MsgLog(name(), error, 
00448              "env does not have a histogram manager, but histogramming has been requested "
00449              "(config dump parmameter > 0). No histograms will be made");
00450     }
00451   }
00452     
00453   shared_ptr<Psana::TimeTool::ConfigV2> c = 
00454     env.configStore().get(m_get_key);
00455   if (c.get()) {
00456     const Psana::TimeTool::ConfigV2& config = *c.get();
00457     if (m_beam_logic.size()==0)
00458       m_beam_logic  = config.beam_logic();
00459     if (m_laser_logic.size()==0)
00460       m_laser_logic = config.laser_logic();
00461     if (m_calib_poly.size()==0)
00462       m_calib_poly  = config.calib_poly();
00463     if (!m_projectX_set)
00464       m_projectX    = unsigned(config.project_axis())==unsigned(Psana::TimeTool::ConfigV1::X);
00465     if (m_proj_cut != INT_MIN)
00466       m_proj_cut    = config.signal_cut();
00467     if (!m_sig_roi_set) {
00468       m_sig_roi_lo[0] = config.sig_roi_lo().row();
00469       m_sig_roi_lo[1] = config.sig_roi_lo().column();
00470       m_sig_roi_hi[0] = config.sig_roi_hi().row();
00471       m_sig_roi_hi[1] = config.sig_roi_hi().column();
00472     }
00473     if (!m_sb_roi_set && config.subtract_sideband()) {
00474       m_sb_roi_lo[0] = config.sb_roi_lo().row();
00475       m_sb_roi_lo[1] = config.sb_roi_lo().column();
00476       m_sb_roi_hi[0] = config.sb_roi_hi().row();
00477       m_sb_roi_hi[1] = config.sb_roi_hi().column();
00478     }
00479     if (m_sb_avg_fraction != DBL_MIN)
00480       m_sb_avg_fraction = config.sb_convergence();
00481     if (m_ref_avg_fraction != DBL_MIN)
00482       m_ref_avg_fraction = config.ref_convergence();
00483     if (m_weights.size()==0)
00484       m_weights          = config.weights();
00485 
00486     m_analyze_projections = config.write_projections();
00487 
00488     m_analyze_projections &= 
00489       m_projectX == (unsigned(config.project_axis())==unsigned(Psana::TimeTool::ConfigV1::X)) &&
00490       m_sig_roi_lo[0] == config.sig_roi_lo().row() &&
00491       m_sig_roi_lo[1] == config.sig_roi_lo().column() &&
00492       m_sig_roi_hi[0] == config.sig_roi_hi().row() &&
00493       m_sig_roi_hi[1] == config.sig_roi_hi().column();
00494       
00495     if (m_sb_roi_set) {
00496       m_analyze_projections &= 
00497         config.subtract_sideband() &&
00498         m_sb_roi_lo[0] == config.sb_roi_lo().row() &&
00499         m_sb_roi_lo[1] == config.sb_roi_lo().column() &&
00500         m_sb_roi_hi[0] == config.sb_roi_hi().row() &&
00501         m_sb_roi_hi[1] == config.sb_roi_hi().column();
00502     }
00503   }
00504   else {
00505     shared_ptr<Psana::TimeTool::ConfigV1> c = 
00506       env.configStore().get(m_get_key);
00507     if (c.get()) {
00508       const Psana::TimeTool::ConfigV1& config = *c.get();
00509       if (m_beam_logic.size()==0)
00510         m_beam_logic  = config.beam_logic();
00511       if (m_laser_logic.size()==0)
00512         m_laser_logic = config.laser_logic();
00513       if (m_calib_poly.size()==0)
00514         m_calib_poly  = config.calib_poly();
00515       if (!m_projectX_set)
00516         m_projectX    = config.project_axis()==Psana::TimeTool::ConfigV1::X;
00517       if (m_proj_cut != INT_MIN)
00518         m_proj_cut    = config.signal_cut();
00519       if (!m_sig_roi_set) {
00520         m_sig_roi_lo[0] = config.sig_roi_lo().row();
00521         m_sig_roi_lo[1] = config.sig_roi_lo().column();
00522         m_sig_roi_hi[0] = config.sig_roi_hi().row();
00523         m_sig_roi_hi[1] = config.sig_roi_hi().column();
00524       }
00525       if (!m_sb_roi_set && config.subtract_sideband()) {
00526         m_sb_roi_lo[0] = config.sb_roi_lo().row();
00527         m_sb_roi_lo[1] = config.sb_roi_lo().column();
00528         m_sb_roi_hi[0] = config.sb_roi_hi().row();
00529         m_sb_roi_hi[1] = config.sb_roi_hi().column();
00530       }
00531       if (m_sb_avg_fraction != DBL_MIN)
00532         m_sb_avg_fraction = config.sb_convergence();
00533       if (m_ref_avg_fraction != DBL_MIN)
00534         m_ref_avg_fraction = config.ref_convergence();
00535       if (m_weights.size()==0)
00536         m_weights          = config.weights();
00537 
00538       m_analyze_projections = config.write_projections();
00539 
00540       m_analyze_projections &= 
00541         m_projectX == (config.project_axis()==Psana::TimeTool::ConfigV1::X) &&
00542         m_sig_roi_lo[0] == config.sig_roi_lo().row() &&
00543         m_sig_roi_lo[1] == config.sig_roi_lo().column() &&
00544         m_sig_roi_hi[0] == config.sig_roi_hi().row() &&
00545         m_sig_roi_hi[1] == config.sig_roi_hi().column();
00546       
00547       if (m_sb_roi_set) {
00548         m_analyze_projections &= 
00549           config.subtract_sideband() &&
00550           m_sb_roi_lo[0] == config.sb_roi_lo().row() &&
00551           m_sb_roi_lo[1] == config.sb_roi_lo().column() &&
00552           m_sb_roi_hi[0] == config.sb_roi_hi().row() &&
00553           m_sb_roi_hi[1] == config.sb_roi_hi().column();
00554       }
00555     }
00556   }
00557 
00558   if (m_beam_logic.size()==0)
00559     MsgLog(name(), info, 
00560            name() << ": no beam_logic configuration given.  Assume beam is always T");
00561   if (m_laser_logic.size()==0)
00562     MsgLog(name(), info, 
00563            name() << ": no laser_logic configuration given.  Assume laser is always T");
00564 
00565   {
00566     shared_ptr<Psana::Camera::FrameFexConfigV1> config = 
00567       env.configStore().get(m_get_key);
00568     if (config.get() && 
00569         config->forwarding()==Psana::Camera::FrameFexConfigV1::RegionOfInterest) {
00570       MsgLog(name(), info, 
00571              name() << ": found configured roi of [" 
00572              << config->roiBegin().column() << ','
00573              << config->roiEnd  ().column() << "] ["
00574              << config->roiBegin().row() << ','
00575              << config->roiEnd  ().row() << "]");
00576 
00577       //  current software does not correct for ROI
00578 #if 0
00579       unsigned roi_y = config->roiBegin().row();
00580       m_frame_roi [0] = roi_y;
00581       m_sig_roi_lo[0] -= roi_y;
00582       m_sig_roi_hi[0] -= roi_y;
00583       m_sb_roi_lo [0] -= roi_y;
00584       m_sb_roi_hi [0] -= roi_y;
00585 
00586       unsigned roi_x = config->roiBegin().column();
00587       m_frame_roi [1] = roi_x;
00588       m_sig_roi_lo[1] -= roi_x;
00589       m_sig_roi_hi[1] -= roi_x;
00590       m_sb_roi_lo [1] -= roi_x;
00591       m_sb_roi_hi [1] -= roi_x;
00592 #endif
00593     }
00594   }
00595 
00596   unsigned pdim = m_projectX ? 1:0;
00597   Axis a(m_sig_roi_hi[pdim]-m_sig_roi_lo[pdim]+1,
00598          double(m_sig_roi_lo[pdim])-0.5,double(m_sig_roi_hi[pdim]+0.5));
00599   unsigned i=0;
00600   if (m_hmgr) {
00601     for(std::list<DumpH>::iterator it=m_hdump.begin();
00602         it!=m_hdump.end(); it++,i++) {
00603       { std::stringstream s;
00604         s << "Raw projection: event " << i;
00605         it->hraw = m_hmgr->hist1d(s.str().c_str(),"projection",a); }
00606       { std::stringstream s;
00607         s << "Ref projection: event " << i;
00608         it->href = m_hmgr->hist1d(s.str().c_str(),"projection",a); }
00609       { std::stringstream s;
00610         s << "Ratio: event " << i;
00611         it->hrat = m_hmgr->hist1d(s.str().c_str(),"ratio",a); }
00612       { std::stringstream s;
00613         s << "Filtered: event " << i;
00614         it->hflt = m_hmgr->hist1d(s.str().c_str(),"filtered",a); }
00615     }
00616   }
00617     
00618   m_count=0;
00619 }
00620 
00621 /// Method which is called at the beginning of the run
00622 void 
00623 Analyze::beginRun(Event& evt, Env& env)
00624 {
00625   if (m_use_calib_db_ref) {
00626 
00627     // get run number
00628     shared_ptr<EventId> eventId = evt.get();
00629     int run = 0;
00630     if (eventId.get()) {
00631       run = eventId->run();
00632     } else {
00633       MsgLog(name(), warning, name() << ": Looking up refernce in calibration database. Cannot determine run number, will use 0.");
00634     }
00635 
00636     // get Pds::Src from configuration Source
00637     boost::shared_ptr<PSEvt::AliasMap> amap = env.aliasMap();
00638     if (not amap) {
00639       MsgLog(name(), fatal, name() << ": could not get alias map from env");
00640     }
00641     Source::SrcMatch srcMatch = m_get_key.srcMatch(*amap);
00642     Pds::Src src(srcMatch.src());
00643 
00644     // get calibration parameters
00645     std::string calib_dir = env.calibDir();
00646     MsgLog(name(), trace, name() << ": Using " << calib_dir << " for calibration database");
00647     std::string group = "Camera::CalibV1";
00648     const int maxPrintBits = 0xFF;
00649     PSCalib::CalibPars* calibpars = PSCalib::CalibParsStore::Create(calib_dir, group, src, 
00650                                                                     run, maxPrintBits);
00651     if (not calibpars) {
00652       MsgLog(name(), fatal, name() << ": failed to create CalibPars object");
00653     }
00654 
00655     const PSCalib::CalibPars::pedestals_t* ped_data = calibpars->pedestals();
00656     if (not ped_data) {
00657       MsgLog(name(), fatal, name() << ": use_calib_db_ref has been specified,"
00658              << " but no pedestals were obtained from the calibration database "
00659              << "for this run: " << run << ". Look in: " << calib_dir << "/"
00660              << group  << "/" << src);
00661     }
00662 
00663     size_t rank = calibpars->ndim(PSCalib::PEDESTALS);
00664     const PSCalib::CalibPars::shape_t * shape = calibpars->shape(PSCalib::PEDESTALS);
00665 
00666     if (rank != 2) {
00667       MsgLog(name(), fatal, name() << ": unexpected, size of pedestals is not two. It is" << rank);
00668     }
00669     if ((shape[0] != 1024) and (shape[1] != 1024)) {
00670       MsgLog(name(), warning, name() << 
00671              ": unexpected, shape of calibration pedestals for ref avg is " <<
00672              "not 1024 x 1024, it is " << shape[0] << " x " << shape[1]);
00673     }
00674     double avg = 0.0;
00675     m_ref_frame_avg = make_ndarray<double>(shape[0], shape[1]);
00676     for (unsigned row = 0; row < shape[0]; ++row) {
00677       for (unsigned col = 0; col < shape[1]; ++col) {
00678         avg += *ped_data;
00679         m_ref_frame_avg[row][col] = *ped_data++;
00680       }
00681     }
00682     MsgLog(name(), info, "** Successfully loaded pedestal file for initial Reference. Average pedestal value: " << avg/double(shape[0]*shape[1]));
00683     delete calibpars;
00684   }
00685 }
00686 
00687 /// Method which is called at the beginning of the calibration cycle
00688 void 
00689 Analyze::beginCalibCycle(Event& evt, Env& env)
00690 {
00691 }
00692 
00693 bool Analyze::getIsOffFromOnOffKey(const std::string & moduleParameter, const std::string & key, Event & evt) 
00694 {
00695   boost::shared_ptr<std::string> onOff = evt.get(m_get_key, key);
00696   if (not onOff) {
00697     onOff = evt.get(key);
00698     if (not onOff) MsgLog(name(), fatal, moduleParameter << "=" << key
00699                           << " specified but not present for either the source specified with the get_key="
00700                           << m_get_key << " nor no source. It must be present in all events ");
00701   }
00702   bool isOn = *onOff == "on";
00703   bool isOff = *onOff == "off";
00704   if ((not isOn) and (not isOff)) MsgLog(name(), fatal, key
00705                                          << " found but value must be on of 'on' or 'off', "
00706                                          << "all lowercase. However it is: " << *onOff);
00707   return isOff;
00708 }
00709 
00710 bool 
00711 Analyze::setBeamAndLaserStatusForEvent(bool &nobeam, bool &nolaser, Event &evt) 
00712 {
00713   shared_ptr<Psana::EvrData::DataV4> evr4 = evt.get(Source("DetInfo(:Evr)"));
00714   shared_ptr<Psana::EvrData::DataV3> evr3;
00715   if (not evr4) evr3 = evt.get(Source("DetInfo(:Evr)"));
00716   if (not(evr3 or evr4)) {
00717     MsgLog(name(), warning, name() << ": Could not fetch evr data - tried DataV3 and DataV4.");
00718     m_eventDump.returnReason(evt,"no_evr_data");
00719     return false;
00720   }
00721 
00722   ndarray<const Psana::EvrData::FIFOEvent,1> fifoEvents =  \
00723     evr4 ? evr4->fifoEvents() : evr3->fifoEvents();
00724 
00725   if (m_beam_on_off_key.length()>0) {
00726     nobeam = getIsOffFromOnOffKey("beam_on_off_key", 
00727                                   m_beam_on_off_key, evt);
00728   } else {
00729     nobeam  = !calculate_logic(m_beam_logic,
00730                                fifoEvents);
00731   }
00732   
00733 
00734   if (m_laser_on_off_key.length()>0) {
00735     nolaser = getIsOffFromOnOffKey("laser_on_off_key",
00736                                    m_laser_on_off_key, evt);
00737   } else {
00738     nolaser = !calculate_logic(m_laser_logic, 
00739                                fifoEvents);
00740   }
00741 
00742   MsgLog(name(), trace, name() << ": evr_codes " << fifoEvents.size()
00743          << ": nobeam " << (nobeam ? 'T':'F')
00744          << ": nolaser " << (nolaser ? 'T':'F')
00745          << (nolaser ? "  -- not processing event as no laser" : ""));
00746 
00747   m_eventDump.laserBeamStatus(nobeam, nolaser, evt);
00748 
00749   if (nolaser) {
00750     m_eventDump.returnReason(evt,"no_laser");
00751     return false;
00752   }
00753   return true;
00754 }
00755 
00756 
00757 void 
00758 Analyze::updateBeamStatusBasedOnIpm(bool &nobeam, Event &evt) {
00759   //
00760   //  Beam is absent if not enough signal on the IPM detector
00761   //
00762   if (!m_ipm_get_key.empty()) {
00763     shared_ptr<Psana::Lusi::IpmFexV1> ipm = evt.get(Source(m_ipm_get_key));
00764     if (ipm.get()) {
00765       MsgLog(name(), info, name() << ": ipm sum = " << ipm.get()->sum());
00766       nobeam |= ipm.get()->sum() < m_ipm_beam_threshold;
00767     }
00768     else {
00769       MsgLog(name(), info, name() << ": failed to get ipm " << m_ipm_get_key);
00770 
00771       MsgLog(name(), info, name() << ":\t  src   \tkey\talias");
00772       std::list<EventKey> keys = evt.keys();
00773       for(std::list<EventKey>::iterator it=keys.begin(); it!=keys.end(); it++) {
00774         MsgLog(name(), info, name() << ": "
00775                << '\t' << std::setw(8) << std::hex << it->src().phy() 
00776                << '\t' << it->key()
00777                << '\t' << it->alias());
00778       }
00779     }
00780   }
00781 }
00782 
00783 bool
00784 Analyze::isRefShot(Event &evt) {
00785   bool nobeam, nolaser;
00786   if (not setBeamAndLaserStatusForEvent(nobeam, nolaser, evt)) return false;
00787   updateBeamStatusBasedOnIpm(nobeam, evt);
00788   if ((not nolaser) and (nobeam)) return true;
00789   return false;
00790 }
00791 
00792 
00793 /// Method which is called with event data, this is the only required 
00794 /// method, all other methods are optional
00795 void 
00796 Analyze::event(Event& evt, Env& env)
00797 {
00798   bool nobeam, nolaser;
00799   if (not setBeamAndLaserStatusForEvent(nobeam, nolaser, evt)) return;
00800   updateBeamStatusBasedOnIpm(nobeam, evt);
00801 
00802   ndarray<const int32_t,1> sig;
00803   ndarray<const int32_t,1> sb;
00804   ndarray<const int32_t,1> ref;
00805   unsigned pdim = m_projectX ? 1:0;
00806 
00807   ndarray<const uint16_t,2> frameData;
00808 
00809   if (m_analyze_projections) {
00810     shared_ptr<Psana::TimeTool::DataV2> tt = evt.get(m_get_key);
00811     if (tt.get()) {
00812       sig  = tt.get()->projected_signal();
00813       sb   = tt.get()->projected_sideband();
00814       ref  = tt.get()->projected_reference();
00815     }
00816     else {
00817       shared_ptr<Psana::TimeTool::DataV1> tt = evt.get(m_get_key);
00818       if (tt.get()) {
00819         sig  = tt.get()->projected_signal();
00820         sb   = tt.get()->projected_sideband();
00821       }
00822       else {
00823         MsgLog(name(), warning, name() << ": analyze_projections is true, but could not fetch timetool data");
00824         m_eventDump.returnReason(evt, "no_timetool_data");
00825         return;
00826       }
00827     }
00828   }
00829   else {
00830     shared_ptr<Psana::Camera::FrameV1> frame = evt.get(m_get_key);
00831     if (!frame.get()) {
00832       MsgLog(name(), warning, name() << ": Could not fetch frame data");
00833       m_eventDump.returnReason(evt,"no_frame_data");
00834       return;
00835     }
00836 
00837     if (frame->depth() <= 8) {
00838       MsgLog(name(), warning, name() << ": frame data is 8 bit, not analyzing data");
00839       m_eventDump.returnReason(evt,"8bit_frame_data");
00840       return;
00841     }
00842 
00843     m_pedestal = frame->offset();
00844     
00845     frameData = frame->data16();
00846 
00847     bool lfatal=false;
00848     for(unsigned i=0; i<2; i++) {
00849       if (m_sig_roi_hi[i] >= frameData.shape()[i]) {
00850         lfatal |= (m_projectX == (i==0));
00851         MsgLog(name(), warning, 
00852                name() << ": signal " << (i==0 ? 'Y':'X') << " upper bound ["
00853                << m_sig_roi_hi[i] << "] exceeds frame bounds ["
00854                << frameData.shape()[i] << "].");
00855         m_sig_roi_hi[i] = frameData.shape()[i]-1;
00856       }
00857       if (m_sb_roi_hi[i] >= frameData.shape()[i]) {
00858         lfatal |= (m_projectX == (i==0));
00859         MsgLog(name(), warning, 
00860                name() << ": sideband " << (i==0 ? 'Y':'X') << " upper bound ["
00861                << m_sb_roi_hi[i] << "] exceeds frame bounds ["
00862                << frameData.shape()[i] << "].");
00863         m_sb_roi_hi[i] = frameData.shape()[i]-1;
00864       }
00865       if (m_ref_roi_hi[i] >= frameData.shape()[i]) {
00866         lfatal |= (m_projectX == (i==0));
00867         MsgLog(name(), warning, 
00868                name() << ": reference " << (i==0 ? 'Y':'X') << " upper bound ["
00869                << m_ref_roi_hi[i] << "] exceeds frame bounds ["
00870                << frameData.shape()[i] << "].");
00871         m_ref_roi_hi[i] = frameData.shape()[i]-1;
00872       }
00873     }
00874     if (lfatal)
00875       MsgLog(name(), fatal, 
00876              name() << ": Fix bounds before proceeding.");
00877     
00878     //
00879     //  Project signal ROI
00880     //
00881     if ((m_sig_roi_hi[0] == m_sig_roi_lo[0]) or (m_sig_roi_hi[1] == m_sig_roi_lo[1])) {
00882       MsgLog(name(), fatal, name() << ": signal ROI has a 0-length width or height. Set sig_roi_x and sig_roi_y config parameters.");
00883     }
00884     m_eventDump.arrayROI(m_sig_roi_lo, m_sig_roi_hi, pdim, "_sig", evt);
00885     sig = psalg::project(frameData, 
00886                          m_sig_roi_lo, 
00887                          m_sig_roi_hi,
00888                          m_pedestal, pdim);
00889     m_eventDump.array(sig, evt, "_sig");
00890     
00891     //
00892     //  Calculate sideband correction
00893     //
00894     if (use_sb_roi()) {
00895       m_eventDump.arrayROI(m_sb_roi_lo, m_sb_roi_hi, pdim, "_sb", evt);
00896       sb = psalg::project(frameData, 
00897                           m_sb_roi_lo , 
00898                           m_sb_roi_hi,
00899                           m_pedestal, pdim);
00900       m_eventDump.array(sb, evt, "_sb");
00901     }
00902 
00903     //
00904     //  Calculate reference correction
00905     //
00906     if (use_ref_roi()) {
00907       m_eventDump.arrayROI(m_ref_roi_lo, m_ref_roi_hi, pdim, "_ref", evt);
00908       ref = psalg::project(frameData, 
00909                            m_ref_roi_lo , 
00910                            m_ref_roi_hi,
00911                            m_pedestal, pdim);
00912     }
00913   }
00914   
00915   ndarray<double,1> sigd = make_ndarray<double>(sig.shape()[0]);
00916   ndarray<double,1> refd = make_ndarray<double>(sig.shape()[0]);
00917 
00918   //
00919   //  Correct projection for common mode found in sideband
00920   //
00921   if (sb.size()) {
00922     psalg::rolling_average(sb, m_sb_avg, m_sb_avg_fraction);
00923     m_eventDump.array(m_sb_avg, evt, "_sb_avg");
00924 
00925     ndarray<const double,1> sbc = psalg::commonModeLROE(sb, m_sb_avg);
00926     m_eventDump.array(sbc, evt, "_sb_commonMode");
00927 
00928     if (use_ref_roi())
00929       for(unsigned i=0; i<sig.shape()[0]; i++) {
00930         sigd[i] = double(sig[i])-sbc[i];
00931         refd[i] = double(ref[i])-sbc[i];
00932       }
00933     else
00934       for(unsigned i=0; i<sig.shape()[0]; i++)
00935         sigd[i] = double(sig[i])-sbc[i];
00936   }
00937   else {
00938     if (use_ref_roi())
00939       for(unsigned i=0; i<sig.shape()[0]; i++) {
00940         sigd[i] = double(sig[i]);
00941         refd[i] = double(ref[i]);
00942       }
00943     else
00944       for(unsigned i=0; i<sig.shape()[0]; i++)
00945         sigd[i] = double(sig[i]);
00946   }
00947   
00948   //
00949   //  Require projection has a minimum amplitude (else no laser)
00950   //
00951   bool lcut=true;
00952   for(unsigned i=0; i<sig.shape()[0]; i++)
00953     if (sigd[i]>m_proj_cut)
00954       lcut=false;
00955   
00956   if (lcut) {
00957     MsgLog(name(), trace, name() << ": signal projection does not have minimum amplitude for laser presence based on proj_cut:" << m_proj_cut << ", returning from Event");
00958     m_eventDump.returnReason(evt,"fails_proj_cut");
00959     return;
00960   }
00961 
00962   bool setInitial = setInitialReferenceIfUsingCalibirationDatabase(pdim);
00963   if (setInitial and !nobeam) {
00964     // Below we dump the ref_frame_avg when there is nobeam. 
00965     // Here we dump if beam and it was just set.
00966     m_eventDump.frameRef(m_ref_frame_avg, evt);
00967   }
00968 
00969   if (nobeam) {
00970     MsgLog(name(), trace, name() << ": Updating reference.");
00971     psalg::rolling_average(ndarray<const double,1>(use_ref_roi()? refd:sigd),
00972                            m_ref_avg, m_ref_avg_fraction);
00973 
00974     if (m_eventDump.doDump()) {
00975       local_rolling_average(frameData, m_ref_frame_avg, m_ref_avg_fraction, name());
00976       m_eventDump.frameRef(m_ref_frame_avg, evt);
00977       m_eventDump.array(use_ref_roi()?refd:sigd, evt, "_ref");
00978     }
00979     //
00980     //  If we are analyzing one event against all references,
00981     //  copy the cached signal and apply this reference;
00982     //  else we are done with this event.
00983     //
00984     if (!(m_analyze_event<0 || m_count<=m_analyze_event))
00985       std::copy(m_analyze_signal.begin(),
00986                 m_analyze_signal.end(),
00987                 sigd.begin());
00988     else {
00989       MsgLog(name(), trace, name() << " exiting early do to nobeam");      
00990       m_eventDump.returnReason(evt, "nobeam");
00991       return;
00992     }
00993   }
00994   else if (use_ref_roi()) {
00995     psalg::rolling_average(ndarray<const double,1>(refd),
00996                            m_ref_avg, m_ref_avg_fraction);
00997   }
00998 
00999   if (m_ref_avg.size()==0) {
01000     MsgLog(name(), warning, name() << ": No reference.");
01001     m_eventDump.returnReason(evt, "no_reference");
01002     return;
01003   }
01004   
01005   if (!(m_analyze_event<0)) {
01006     //
01007     //  If this is the selected event to analyze against all 
01008     //  references, cache it for use from this point on.
01009     //
01010     if (m_count==m_analyze_event) {
01011       if (!nobeam) {
01012         m_analyze_signal = make_ndarray<double>(sigd.size());
01013         std::copy(sigd.begin(), sigd.end(), m_analyze_signal.begin());
01014       } else {
01015         MsgLog(name(), error, name() << " analyze_event set, and this is the event count=" << m_count << " but there is no beam.");
01016         m_eventDump.returnReason(evt, "analyze_event_but_nobeam_for_event");
01017       }
01018     } else if (!nobeam)  {
01019       MsgLog(name(), trace, name() << " analyze_event is set, but no beam");
01020       m_eventDump.returnReason(evt,"analyze_event_nobeam");
01021       return;
01022     }
01023   }
01024   
01025   m_count++;
01026   m_eventDump.array(m_ref_avg, evt, "_ref_avg");
01027 
01028   //
01029   //  Divide by the reference
01030   //
01031   for(unsigned i=0; i<sig.shape()[0]; i++)
01032     sigd[i] = sigd[i]/m_ref_avg[i] - 1;
01033 
01034   m_eventDump.array(sigd, evt, "_sigd");
01035   //
01036   //  Apply the digital filter
01037   //
01038   ndarray<double,1> qwf = psalg::finite_impulse_response(m_weights,sigd);
01039   m_eventDump.array(qwf, evt, "_qwf");
01040 
01041   if (!m_hdump.empty() and m_hmgr) {
01042     DumpH& h = m_hdump.front();
01043     for(unsigned i=0; i<sig.shape()[0]; i++)
01044       h.hraw->fill(double(i)+m_sig_roi_lo[pdim],double(sig[i]));
01045     for(unsigned i=0; i<sig.shape()[0]; i++)
01046       h.href->fill(double(i)+m_sig_roi_lo[pdim],m_ref_avg[i]);
01047     for(unsigned i=0; i<sigd.shape()[0]; i++)
01048       h.hrat->fill(double(i)+m_sig_roi_lo[pdim],sigd[i]);
01049     for(unsigned i=0; i<qwf.shape()[0]; i++)
01050       h.hflt->fill(double(i)+m_sig_roi_lo[pdim],qwf[i]);
01051     m_hdump.pop_front();
01052   }
01053     
01054   //
01055   //  Find the two highest peaks that are well-separated
01056   //
01057   const double afrac = 0.50;
01058   std::list<unsigned> peaks = 
01059     psalg::find_peaks(qwf, afrac, 2);
01060   
01061   unsigned nfits = peaks.size();
01062   if (nfits>0) {
01063     unsigned ix = *peaks.begin();
01064     ndarray<double,1> pFit0 = psalg::parab_fit(qwf,ix,0.8);
01065     if (pFit0[2]>0) {
01066       double   xflt = pFit0[1]+m_sig_roi_lo[pdim]+m_frame_roi[pdim];
01067         
01068       double  xfltc = 0;
01069       for(unsigned i=m_calib_poly.size(); i!=0; )
01070         xfltc = xfltc*xflt + m_calib_poly[--i];
01071         
01072       double nxtAmpl=0;
01073       if (nfits>1) {
01074         ndarray<double,1> pFit1 = 
01075           psalg::parab_fit(qwf,*(++peaks.begin()),0.8);
01076         if (pFit1[2]>0)
01077           nxtAmpl = pFit1[0];
01078       }
01079 
01080       // put 
01081       boost::shared_ptr<Psana::TimeTool::DataV2> timeToolEvtData = 
01082         boost::make_shared<TimeToolData>(Psana::TimeTool::DataV2::Signal,
01083                                          pFit0[0],
01084                                          xflt,
01085                                          xfltc,
01086                                          pFit0[2],
01087                                          m_ref_avg[ix],
01088                                          nxtAmpl);
01089       evt.put(timeToolEvtData,m_put_key);
01090       MsgLog(name(), trace, name() << " added TimeToolData");
01091       m_eventDump.returnReason(evt, "success");
01092     } else {
01093       MsgLog(name(), trace, name() << " pfits <=0 , nodata");
01094       m_eventDump.returnReason(evt, "no_parab_fit");
01095     }
01096   } else {
01097     MsgLog(name(), trace, name() << " no peaks, no data");
01098     m_eventDump.returnReason(evt, "no_peaks");
01099   }
01100 }
01101 
01102 bool 
01103 Analyze::setInitialReferenceIfUsingCalibirationDatabase(unsigned pdim) {
01104   if (not m_use_calib_db_ref) return false;
01105   if (0 != m_ref_avg.size()) return false;
01106   if (use_ref_roi()) {
01107     MsgLog(name(), warning, name() << ": use_ref_roi is set, and use_calib_db_ref is true. not implemented");
01108     return false;
01109   }
01110 
01111   ndarray<uint16_t,2> ref_frame_avg_uint16(m_ref_frame_avg.shape());
01112   for (unsigned row = 0; row < m_ref_frame_avg.shape()[0]; row++) {
01113     for (unsigned col = 0; col < m_ref_frame_avg.shape()[1]; col++) {
01114       double origVal = m_ref_frame_avg[row][col];
01115       uint16_t uintVal = uint16_t(origVal);
01116       if ((origVal > UINT16_MAX) or (origVal < 0)) {
01117         MsgLog(name(), warning, name() << ": ref_frame_avg[" << row << "][" << col << "] has value outside 16 bit unsigned integer bounds. Clamping");
01118         if (origVal > UINT16_MAX) {
01119           uintVal = UINT16_MAX;
01120         } else if (origVal < 0) {
01121           uintVal = 0;
01122         }
01123       }
01124       ref_frame_avg_uint16[row][col] = uintVal;
01125     }
01126   }
01127 
01128   ndarray<const uint16_t,2> ref_frame_avg_const_uint16(ref_frame_avg_uint16);
01129 
01130   ndarray<const int,1> ref_avg = psalg::project(ref_frame_avg_const_uint16, 
01131                               m_sig_roi_lo, 
01132                               m_sig_roi_hi,
01133                               m_pedestal, pdim);
01134   
01135   m_ref_avg  = ndarray<double,1>(ref_avg.shape());
01136   for (unsigned i = 0; i < ref_avg.shape()[0]; ++i) {
01137     m_ref_avg[i]=double(ref_avg[i]);
01138   }
01139 
01140   return true;
01141 }
01142  
01143 /// Method which is called at the end of the calibration cycle
01144 void 
01145 Analyze::endCalibCycle(Event& evt, Env& env)
01146 {
01147 }
01148 
01149 /// Method which is called at the end of the run
01150 void 
01151 Analyze::endRun(Event& evt, Env& env)
01152 {
01153 }
01154 
01155 /// Method which is called once at the end of the job
01156 void 
01157 Analyze::endJob(Event& evt, Env& env)
01158 {
01159   if (!m_ref_store.empty()) {
01160     std:: ofstream f(m_ref_store.c_str());
01161     for(unsigned i=0; i<m_ref_avg.size(); i++)
01162       f << m_ref_avg[i] << ' ';
01163     f << std::endl;
01164   }
01165 }
01166 
01167 } // namespace TimeTool
01168 

Generated on 19 Dec 2016 for PSDMSoftware by  doxygen 1.4.7