cspad_mod/src/DataProxy2x2.cpp

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: DataProxy2x2.cpp 6840 2013-09-24 22:07:32Z salnikov@SLAC.STANFORD.EDU $
00004 //
00005 // Description:
00006 //      Class DataProxy2x2...
00007 //
00008 // Author List:
00009 //      Andy Salnikov
00010 //
00011 //------------------------------------------------------------------------
00012 
00013 //-----------------------
00014 // This Class's Header --
00015 //-----------------------
00016 #include "cspad_mod/DataProxy2x2.h"
00017 
00018 //-----------------
00019 // C/C++ Headers --
00020 //-----------------
00021 
00022 //-------------------------------
00023 // Collaborating Class Headers --
00024 //-------------------------------
00025 #include "cspad_mod/CsPad2x2ElementV1.h"
00026 #include "MsgLogger/MsgLogger.h"
00027 #include "pdscalibdata/CsPadCommonModeSubV1.h"
00028 #include "pdscalibdata/CsPad2x2PedestalsV1.h"
00029 #include "pdscalibdata/CsPad2x2PixelGainV1.h"
00030 #include "pdscalibdata/CsPad2x2PixelStatusV1.h"
00031 
00032 //-----------------------------------------------------------------------
00033 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00034 //-----------------------------------------------------------------------
00035 
00036 namespace {
00037 
00038   const char logger[] = "DataProxy2x2";
00039 
00040 }
00041 
00042 
00043 //              ----------------------------------------
00044 //              -- Public Function Member Definitions --
00045 //              ----------------------------------------
00046 
00047 namespace cspad_mod {
00048 
00049 //----------------
00050 // Constructors --
00051 //----------------
00052 DataProxy2x2::DataProxy2x2 (const PSEvt::EventKey& key, PSEnv::EnvObjectStore& calibStore)
00053   : PSEvt::Proxy<Psana::CsPad2x2::ElementV1>()
00054   , m_key(key)
00055   , m_calibStore(calibStore)
00056   , m_data()
00057 {
00058 }
00059 
00060 //--------------
00061 // Destructor --
00062 //--------------
00063 DataProxy2x2::~DataProxy2x2 ()
00064 {
00065 }
00066 
00067 boost::shared_ptr<Psana::CsPad2x2::ElementV1>
00068 DataProxy2x2::getTypedImpl(PSEvt::ProxyDictI* dict, const Pds::Src& source, const std::string& key)
00069 {
00070   if (m_data.get()) return m_data;
00071 
00072   // get the original object
00073   boost::shared_ptr<void> vptr = dict->get(m_key.typeinfo(), PSEvt::Source(m_key.src()), m_key.key(), 0);
00074   if (not vptr.get()) return m_data;
00075   boost::shared_ptr<Psana::CsPad2x2::ElementV1> obj = boost::static_pointer_cast<Psana::CsPad2x2::ElementV1>(vptr);
00076 
00077   // get calibration data
00078   boost::shared_ptr<pdscalibdata::CsPad2x2PedestalsV1> pedestals = m_calibStore.get(m_key.src());
00079   boost::shared_ptr<pdscalibdata::CsPad2x2PixelGainV1> pixelGain = m_calibStore.get(m_key.src());
00080   boost::shared_ptr<pdscalibdata::CsPad2x2PixelStatusV1> pixStatusCalib = m_calibStore.get(m_key.src());
00081   boost::shared_ptr<pdscalibdata::CsPadCommonModeSubV1> cModeCalib = m_calibStore.get(m_key.src());
00082 
00083   // get few constants
00084   const unsigned nSect = 2;
00085   const unsigned ssize = Psana::CsPad2x2::ColumnsPerASIC*Psana::CsPad2x2::MaxRowsPerASIC*2;
00086 
00087   // make data arrays
00088   int16_t* pixelData = new int16_t[ssize*nSect];
00089   float commonMode[nSect];
00090 
00091   // loop over sections
00092   for ( unsigned sect = 0; sect < nSect ; ++ sect ) {
00093 
00094     const ndarray<const int16_t, 3>& data = obj->data();
00095 
00096     // start of pixel data
00097     const int16_t* sdata = data.data() + sect;
00098 
00099     // output pixel data
00100     int16_t* output = pixelData + sect;
00101 
00102     // default common mode value for this section,
00103     // large negative number means unknown
00104     commonMode[sect] = pdscalibdata::CsPadCommonModeSubV1::UnknownCM;
00105 
00106     // status codes for pixels
00107     const uint16_t* pixStatus = 0;
00108     if (pixStatusCalib.get()) {
00109       pixStatus = &pixStatusCalib->status()[0][0][sect];
00110     }
00111 
00112     // this sector's pedestal data
00113     const float* peddata = 0;
00114     if (pedestals.get()) {
00115       peddata = &pedestals->pedestals()[0][0][sect];
00116     }
00117 
00118     // this sector's pixel gain data
00119     const float* gaindata = 0;
00120     if (pixelGain) {
00121       gaindata = &pixelGain->pixelGains()[0][0][sect];
00122     }
00123 
00124     // calculate common mode if requested
00125     float cmode = 0;
00126     if (cModeCalib.get()) {
00127       MsgLog(logger, debug, "calculating common mode for s=" << sect);
00128       cmode = cModeCalib->findCommonMode(sdata, peddata, pixStatus, ssize, nSect);
00129       if (cmode == pdscalibdata::CsPadCommonModeSubV1::UnknownCM) {
00130         // reset subtracted value
00131         cmode = 0;
00132       } else {
00133         // remember it
00134         commonMode[sect] = cmode;
00135       }
00136     }
00137 
00138     // subtract pedestals and common mode, apply pixel gain, and round to
00139     // nearest int; pixel gain is _inverse_ gain so we multiply it
00140     if (peddata and gaindata) {
00141       unsigned last = ssize*nSect;
00142       for (unsigned i = 0; i != last; i += nSect) {
00143         double val = (sdata[i] - peddata[i] - cmode) * gaindata[i];
00144         output[i] = val < 0 ? int(val - 0.5) : int(val + 0.5);
00145       }
00146     } else if (peddata) {
00147       unsigned last = ssize*nSect;
00148       for (unsigned i = 0; i != last; i += nSect) {
00149         double val = sdata[i] - peddata[i] - cmode;
00150         output[i] = val < 0 ? int(val - 0.5) : int(val + 0.5);
00151       }
00152     } else if (gaindata) {
00153       unsigned last = ssize*nSect;
00154       for (unsigned i = 0; i != last; i += nSect) {
00155         double val = (sdata[i] - cmode) * gaindata[i];
00156         output[i] = val < 0 ? int(val - 0.5) : int(val + 0.5);
00157       }
00158     } else {
00159       unsigned last = ssize*nSect;
00160       for (unsigned i = 0; i != last; i += nSect) {
00161         double val = sdata[i] - cmode;
00162         output[i] = val < 0 ? int(val - 0.5) : int(val + 0.5);
00163       }
00164     }
00165 
00166   }
00167 
00168   // make new object
00169   m_data.reset(new CsPad2x2ElementV1(*obj, pixelData, commonMode));
00170 
00171   return m_data;
00172 }
00173 
00174 } // namespace cspad_mod

Generated on 19 Dec 2016 for PSANAmodules by  doxygen 1.4.7