cspad_mod/src/CsPad2x2Pedestals.cpp

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: CsPad2x2Pedestals.cpp 5542 2013-02-28 20:51:26Z salnikov@SLAC.STANFORD.EDU $
00004 //
00005 // Description:
00006 //      Class CsPad2x2Pedestals...
00007 //
00008 // Author List:
00009 //      Andy Salnikov
00010 //
00011 //------------------------------------------------------------------------
00012 
00013 //-----------------------
00014 // This Class's Header --
00015 //-----------------------
00016 #include "cspad_mod/CsPad2x2Pedestals.h"
00017 
00018 //-----------------
00019 // C/C++ Headers --
00020 //-----------------
00021 #include <fstream>
00022 #include <cmath>
00023 
00024 //-------------------------------
00025 // Collaborating Class Headers --
00026 //-------------------------------
00027 #include "MsgLogger/MsgLogger.h"
00028 #include "psddl_psana/cspad.ddl.h"
00029 
00030 //-----------------------------------------------------------------------
00031 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00032 //-----------------------------------------------------------------------
00033 
00034 using namespace Psana;
00035 
00036 // This declares this class as psana module
00037 using namespace cspad_mod;
00038 PSANA_MODULE_FACTORY(CsPad2x2Pedestals)
00039 
00040 //              ----------------------------------------
00041 //              -- Public Function Member Definitions --
00042 //              ----------------------------------------
00043 
00044 namespace cspad_mod {
00045 
00046 //----------------
00047 // Constructors --
00048 //----------------
00049 CsPad2x2Pedestals::CsPad2x2Pedestals (const std::string& name)
00050   : Module(name)
00051   , m_pedFile()
00052   , m_noiseFile()
00053   , m_src()
00054   , m_count(0)
00055   , m_sum()
00056   , m_sum2()
00057 {
00058   m_pedFile = configStr("output", "cspad2x2-pedestals.dat");
00059   m_noiseFile = configStr("noise", "cspad2x2-noise.dat");
00060   
00061   // initialize arrays
00062   std::fill_n(&m_sum[0][0][0], MaxSectors*NumColumns*NumRows, 0.);
00063   std::fill_n(&m_sum2[0][0][0], MaxSectors*NumColumns*NumRows, 0.);
00064 }
00065 
00066 //--------------
00067 // Destructor --
00068 //--------------
00069 CsPad2x2Pedestals::~CsPad2x2Pedestals ()
00070 {
00071 }
00072 
00073 /// Method which is called at the beginning of the run
00074 void 
00075 CsPad2x2Pedestals::beginRun(Event& evt, Env& env)
00076 {
00077   // Find all configuration objects matching the source address
00078   // provided in configuration. If there is more than one configuration 
00079   // object is found then complain and stop.
00080   
00081   Source src(configStr("source", "DetInfo(:Cspad2x2)"));
00082   int count = 0;
00083   
00084   // cspad2x2 data could come with either CsPad2x2::ConfigV* or CsPad::ConfigV3
00085   // configuration (latter happened for brief period)
00086   shared_ptr<Psana::CsPad2x2::ConfigV1> config1 = env.configStore().get(src, &m_src);
00087   if (config1.get()) {
00088     ++ count;
00089   }
00090   
00091   shared_ptr<Psana::CsPad2x2::ConfigV2> config2 = env.configStore().get(src, &m_src);
00092   if (config2.get()) {
00093     ++ count;
00094   }
00095 
00096   shared_ptr<Psana::CsPad::ConfigV3> config3 = env.configStore().get(src, &m_src);
00097   if (config3.get()) {
00098     ++ count;
00099   }
00100 
00101   if (not count) {
00102     MsgLog(name(), error, "No CsPad2x2 configuration objects found, terminating.");
00103     terminate();
00104     return;
00105   }
00106   
00107   if (count > 1) {
00108     MsgLog(name(), error, "Multiple CsPad2x2 configuration objects found, use more specific source address. Terminating.");
00109     terminate();
00110     return;
00111   }
00112 
00113   MsgLog(name(), info, "Found CsPad2x2 object with address " << m_src);
00114   if (m_src.level() != Pds::Level::Source) {
00115     MsgLog(name(), error, "Found Cspad2x2 configuration object with address not at Source level. Terminating.");
00116     terminate();
00117     return;
00118   }
00119 
00120   const Pds::DetInfo& dinfo = static_cast<const Pds::DetInfo&>(m_src);
00121   // validate that this is indeed cspad2x2, should always be true, but
00122   // additional protection here should not hurt
00123   if (dinfo.device() != Pds::DetInfo::Cspad2x2) {
00124     MsgLog(name(), error, "Found Cspad2x2 configuration object with invalid address. Terminating.");
00125     terminate();
00126     return;
00127   }
00128 }
00129 
00130 /// Method which is called with event data, this is the only required 
00131 /// method, all other methods are optional
00132 void 
00133 CsPad2x2Pedestals::event(Event& evt, Env& env)
00134 {
00135 
00136   // we should expect 2x2 data
00137   shared_ptr<Psana::CsPad2x2::ElementV1> data1 = evt.get(m_src);
00138   if (data1.get()) {
00139 
00140     ++ m_count;
00141     
00142     // process statistics for 2x2
00143     const ndarray<const int16_t, 3>& data = data1->data();
00144     collectStat(data.data());
00145     
00146   }
00147     
00148 }
00149 
00150 
00151 
00152 /// Method which is called once at the end of the job
00153 void 
00154 CsPad2x2Pedestals::endJob(Event& evt, Env& env)
00155 {
00156 
00157   MsgLog(name(), info, "collected total " << m_count << " events");
00158   
00159   const double* sum = &m_sum[0][0][0];
00160   const double* sum2 = &m_sum2[0][0][0];
00161   const int size = NumColumns*NumRows*2;
00162 
00163   if (not m_pedFile.empty()) {
00164 
00165     // save pedestals as average
00166     std::ofstream out(m_pedFile.c_str());
00167     for (int i = 0; i < size; ++ i) {
00168       double avg = m_count ? sum[i] / m_count : 0;
00169       out << avg << '\n';
00170     }
00171 
00172     out.close();
00173 
00174   }
00175 
00176   if (not m_noiseFile.empty()) {
00177     
00178     // save pedestals as average
00179     std::ofstream out(m_noiseFile.c_str());
00180     for (int i = 0; i < size; ++ i) {
00181       double stdev = 0;
00182       if (m_count > 1) {
00183         double avg = sum[i] / m_count;
00184         stdev = std::sqrt(sum2[i] / m_count - avg*avg);
00185       }
00186       out << stdev << '\n';
00187     }
00188 
00189     out.close();
00190 
00191   }
00192 
00193 }
00194 
00195 
00196 /// collect statistics for 2x2
00197 void 
00198 CsPad2x2Pedestals::collectStat(const int16_t* data)
00199 {
00200   double* sum = &m_sum[0][0][0];
00201   double* sum2 = &m_sum2[0][0][0];
00202   const int size = NumColumns*NumRows*2;
00203   
00204   for (int i = 0; i < size; ++ i) {
00205     double val = data[i];
00206     sum[i] += val;
00207     sum2[i] += val*val;
00208   }          
00209 
00210 }
00211 
00212 } // namespace cspad_mod

Generated on 19 Dec 2016 for PSANAmodules by  doxygen 1.4.7