ImgAlgos/include/CommonModeCorrection.h

Go to the documentation of this file.
00001 #ifndef IMGALGOS_COMMONMODECORRECTION_H
00002 #define IMGALGOS_COMMONMODECORRECTION_H
00003 
00004 //--------------------------------------------------------------------------
00005 // File and Version Information:
00006 //      $Id: CommonModeCorrection.h 12157 2016-06-25 00:03:15Z dubrovin@SLAC.STANFORD.EDU $
00007 //
00008 // Description: see documentation below
00009 //
00010 //------------------------------------------------------------------------
00011 
00012 //-----------------
00013 // C/C++ Headers --
00014 //-----------------
00015 
00016 #include <string>
00017 //#include <iostream> // for cout
00018 //#include <cstddef>  // for size_t
00019 //#include <cstring>  // for memcpy
00020 
00021 using namespace std;
00022 
00023 //----------------------
00024 // Base Class Headers --
00025 //----------------------
00026 
00027 //-------------------------------
00028 // Collaborating Class Headers --
00029 //-------------------------------
00030 
00031 #include "PSEvt/Source.h"
00032 #include "MsgLogger/MsgLogger.h"
00033 #include "ndarray/ndarray.h"
00034 
00035 #include "PSCalib/CalibPars.h"
00036 #include "ImgAlgos/CommonMode.h"
00037 #include "ImgAlgos/GlobalMethods.h"
00038 #include "ImgAlgos/TimeInterval.h"
00039 #include "psalg/psalg.h"
00040 
00041 //------------------------------------
00042 // Collaborating Class Declarations --
00043 //------------------------------------
00044 
00045 //              ---------------------
00046 //              -- Class Interface --
00047 //              ---------------------
00048 
00049 namespace ImgAlgos {
00050 
00051 /// @addtogroup ImgAlgos
00052 
00053 /**
00054  *  @ingroup ImgAlgos
00055  *
00056  *  @brief CommonModeCorrection - apply common mode correction algorithms.
00057  *
00058  *  This software was developed for the LCLS project.  If you use all or 
00059  *  part of it, please give an appropriate acknowledgment.
00060  *
00061  *  @version $Id: CommonModeCorrection.h 12157 2016-06-25 00:03:15Z dubrovin@SLAC.STANFORD.EDU $
00062  *
00063  *  @author Mikhail S. Dubrovin
00064  *
00065  *  @see CommonMode
00066  *
00067  *
00068  *  @anchor interface
00069  *  @par<interface> Interface Description
00070  *
00071  * 
00072  *  @li Includes
00073  *  @code
00074  *  #include "ImgAlgos/CommonModeCorrection.h"
00075  *  #include "ndarray/ndarray.h"     // need it for I/O arrays
00076  *  @endcode
00077  *
00078  *
00079  *  @li Initialization
00080  *  \n
00081  *  @code
00082  *  const PSEvt::Source source("DetInfo(CxiDs2.0:Cspad.0)"); 
00083  *  const common_mode_t cmod_pars[] = {1, 50, 25, 100};
00084  *  const unsigned size = 32*185*388;
00085  *  const pixel_status_t* status = 0; // or get it from calibration store
00086  *  const unsigned pbits = 0377;
00087  * 
00088  *  CommonModeCorrection* p_cmog = new CommonModeCorrection(source, cmod_pars, size status, pbits);
00089  *  @endcode
00090  *
00091  *
00092  *  @li Do common mode correction
00093  *  @code
00094  *  T* data = ...; // get it from data (assumes that pedestals are subtracted).
00095  *  p_cmog -> do_common_mode<T>(data);
00096  *  @endcode
00097  */
00098 
00099 //template <typename T>
00100 class CommonModeCorrection  {
00101 public:
00102 
00103   typedef PSCalib::CalibPars::pixel_status_t pixel_status_t;
00104   typedef PSCalib::CalibPars::common_mode_t common_mode_t;
00105 
00106   //static const size_t RSMMAX = 10;
00107 
00108   /**
00109    * @brief Evaluate and apply common mode correction. 
00110    * 
00111    * @param[in] source    - data source
00112    * @param[in] cmod_pars - common mode parameters from calibration file
00113    * @param[in] size      - ndarray full saze for data and pixel-status array
00114    * @param[in] status    - pixel status array, 0-good/ >0-bad pixel
00115    * @param[in] pbits     - print control bit-word; =0-print nothing, +1-input parameters, ....
00116    */
00117 
00118   CommonModeCorrection (const PSEvt::Source& source, 
00119                         const common_mode_t* cmod_pars, 
00120                         const unsigned size, 
00121                         const pixel_status_t* status=0, 
00122                         const unsigned pbits=0);
00123 
00124   /// Destructor
00125   //virtual ~CommonModeCorrection () { delete m_cmod_pars; }
00126   virtual ~CommonModeCorrection () {}
00127 
00128   /**
00129    * @brief Sets pointer to array of common mode parameters.
00130    * @param[in] cmod_pars - common mode parameters from calibration file
00131    */
00132   void setCModPars(const common_mode_t* cmod_pars); //  {m_cmod_pars = cmod_pars;}
00133 
00134   void printInputPars();
00135 
00136   // Copy constructor and assignment are disabled by default
00137   CommonModeCorrection ( const CommonModeCorrection& ) ;
00138   CommonModeCorrection& operator = ( const CommonModeCorrection& ) ;
00139 
00140 
00141 private:
00142 
00143   PSEvt::Source          m_source;      // string with source name
00144   const common_mode_t*   m_cmod_pars;   // common mode parameters
00145   unsigned               m_size;        // number of elements in the input data ndarray 
00146   const pixel_status_t*  m_status;      // pointer to pixel status array
00147   unsigned               m_pbits;       // bit mask for print options
00148   DETECTOR_TYPE          m_dettype;     // numerated detector type source
00149 
00150   /// Returns name of the class
00151   inline const char* _name_() {return "ImgAlgos::CommonModeCorrection";}
00152 
00153 public:
00154 //-------------------
00155 
00156   template <typename T>
00157     void do_common_mode(T* data)
00158     {
00159       unsigned mode = (unsigned) m_cmod_pars[0];
00160       const common_mode_t* pars = &m_cmod_pars[1]; // [0] element=mode is excluded from parameters
00161       float cmod_corr = 0;
00162 
00163       const pixel_status_t* status = 0;
00164 
00165       if (m_pbits & 128) MsgLog(_name_(), info,   "mode:" << mode 
00166                                           << "  dettype:" << m_dettype
00167                                           <<  "  source:" << m_source);
00168 
00169       if (mode == 0) return;
00170 
00171       // Algorithm 1 for CSPAD
00172       if (mode == 1 && m_dettype == CSPAD) {
00173           unsigned ssize = 185*388;
00174           for (unsigned ind = 0; ind<32*ssize; ind+=ssize) {
00175             if(m_status) status = &m_status[ind];
00176             cmod_corr = findCommonMode<T>(pars, &data[ind], status, ssize); 
00177           }
00178           return;
00179       }
00180 
00181       // Algorithm 1 for CSPAD2X2
00182       else if (mode == 1 && m_dettype == CSPAD2X2) {
00183           unsigned ssize = 185*388;
00184           int stride = 2;
00185           for (unsigned seg = 0; seg<2; ++seg) {
00186             if(m_status) status = &m_status[seg];
00187             cmod_corr = findCommonMode<T>(pars, &data[seg], status, ssize, stride); 
00188           }
00189           return;
00190       }
00191 
00192       // Algorithm 1 for any detector 
00193       else if (mode == 1) {  
00194         //unsigned mode     = m_cmod_pars[0]; // mode - algorithm number for common mode
00195         //unsigned mean_max = m_cmod_pars[1]; // maximal value for the common mode correctiom
00196         //unsigned rms_max  = m_cmod_pars[2]; // maximal value for the found peak rms
00197         //unsigned thresh   = m_cmod_pars[3]; // threshold on number of pixels in the peak finding algorithm
00198           unsigned nsegs    = (unsigned)m_cmod_pars[4]; // number of segments in the detector
00199           unsigned ssize    = (unsigned)m_cmod_pars[5]; // segment size
00200           unsigned stride   = (unsigned)m_cmod_pars[6]; // stride (step to jump)
00201 
00202           nsegs  = (nsegs<1)   ?   1 : nsegs;
00203           ssize  = (ssize<100) ? 128 : ssize;
00204           stride = (nsegs<1)   ?   1 : stride;
00205 
00206           for (unsigned ind = 0; ind<nsegs*ssize; ind+=ssize) {
00207             if(m_status) status = &m_status[ind];
00208             cmod_corr = findCommonMode<T>(pars, &data[ind], status, ssize, stride); 
00209           }
00210           return;
00211       }
00212 
00213       // Algorithm 2 - MEAN for any detector 
00214       else if (mode == 2) {
00215           T threshold     = (T)        m_cmod_pars[1];
00216           T maxCorrection = (T)        m_cmod_pars[2];
00217           unsigned length = (unsigned) m_cmod_pars[3];
00218           T cm            = 0;          
00219           length = (length<100) ? 128 : length;
00220           
00221           for (unsigned i0=0; i0<m_size; i0+=length) {
00222               if(m_status) status = &m_status[i0];
00223               psalg::commonMode<T>(&data[i0], status, length, threshold, maxCorrection, cm);
00224               //     commonMode<T>(&data[i0], status, length, threshold, maxCorrection, cm); // from GlobalMethods.h
00225           }
00226           return; 
00227       }
00228 
00229       // Algorithm 3 - MEDIAN for any detector 
00230       else if (mode == 3) {
00231           T threshold     = (T)        m_cmod_pars[1];
00232           T maxCorrection = (T)        m_cmod_pars[2];
00233           unsigned length = (unsigned) m_cmod_pars[3];
00234           T cm            = 0;          
00235           length = (length<100) ? 128 : length;
00236           
00237           for (unsigned i0=0; i0<m_size; i0+=length) {
00238               if(m_status) status = &m_status[i0];
00239               //psalg::commonModeMedian<T>(&data[i0], status, length, threshold, maxCorrection, cm);
00240                        commonModeMedian<T>(&data[i0], status, length, threshold, maxCorrection, cm);
00241           }
00242 
00243           return; 
00244       }
00245 
00246       // Algorithm 4 - MEDIAN algorithm, detector-dependent
00247       else if (mode == 4) { 
00248 
00249         TimeInterval dt;
00250         if (do_common_mode_median<T>(data)) {
00251           if (m_pbits & 128) MsgLog("medianInRegion", info, " common mode dt(sec) = " << dt.getCurrentTimeInterval() );
00252           return; 
00253         }
00254 
00255       }
00256 
00257       //---------
00258       // Algorithm 5 for CSPAD uses unbond pixels
00259       else if (mode == 5 && m_dettype == CSPAD) {
00260           unsigned ssize = 185*388;
00261           for (unsigned ind = 0; ind<32*ssize; ind+=ssize) {
00262             cmod_corr = applyCModeUnbond<T>(pars, &data[ind], ssize); 
00263             if (m_pbits & 128) MsgLog("do_common_mode", info, "alg#5  segment = " << ind/ssize << " common mode = " << cmod_corr);
00264           }
00265           return;
00266       }
00267 
00268       // Algorithm 5 for CSPAD2X2 uses unbond pixels
00269       else if (mode == 5 && m_dettype == CSPAD2X2) {
00270           unsigned ssize = 185*388;
00271           int stride = 2;
00272           for (unsigned seg = 0; seg<2; ++seg) {
00273             cmod_corr = applyCModeUnbond<T>(pars, &data[seg], ssize, stride); 
00274             if (m_pbits & 128) MsgLog("do_common_mode", info, "alg#5  segment = " << seg << " common mode = " << cmod_corr);
00275           }
00276           return;
00277       }
00278       //---------
00279 
00280       // Other algorithms which are not implemented yet
00281       else {
00282           static long counter = 0; counter ++;
00283           if (counter<21) {  MsgLog(_name_(), warning, "Algorithm " << mode << " requested in common_mode parameters is not implemented.");
00284             if (counter==20) MsgLog(_name_(), warning, "STOP PRINTING ABOVE WARNING MESSAGE.");
00285           }
00286       }
00287     }
00288 
00289 //-------------------
00290 
00291   template <typename T>
00292     bool do_common_mode_fccd960(T* data)
00293     {
00294       const common_mode_t* pars = &m_cmod_pars[1]; 
00295       // [0] element=mode is excluded from parameters
00296       unsigned cmtype = (unsigned) m_cmod_pars[1];
00297       unsigned pbits = (m_pbits & 256) ? 0xffff : 0;
00298 
00299       if (m_pbits & 128) MsgLog(_name_(), info, "FCCD960 cmtype:" << cmtype);
00300 
00301       //T maxCorrection = (T) m_cmod_pars[2];
00302 
00303       unsigned shape[2] = {960, 960};
00304 
00305       ndarray<T,2> d(data, shape);
00306       ndarray<const pixel_status_t,2> stat(m_status, shape);
00307       
00308       if (cmtype & 1) {
00309         //common mode correction for 1x160-pixel rows with stride 2
00310         size_t nregs  = 6;      
00311         size_t ncols  = shape[1]/nregs; // 160-pixel
00312         size_t nrows  = 1;
00313         size_t colmin = 0;
00314 
00315         for(size_t row=0; row<shape[1]; row++) {
00316           for(size_t s=0; s<nregs; s++) {
00317             colmin = s * ncols;
00318             for(size_t k=0; k<2; k++)
00319               medianInRegion<T>(pars, d, stat, row, colmin+k, nrows, ncols, 1, 2, pbits); 
00320           }
00321         }
00322       }
00323 
00324       if (cmtype & 2) {
00325         //common mode correction for 480x10-pixel 96*2 supercolumns
00326         size_t nregs  = 96*2;   
00327         size_t nrows  = shape[0]/2;
00328         size_t ncols  = shape[1]/96;
00329       
00330         for(size_t s=0; s<nregs; s++) {
00331           //meanInRegion  <T>(pars, d, stat, rowmin[s], colmin[s], nrows, ncols, 1, 1); 
00332           size_t rowmin = (s/96)*nrows;
00333           size_t colmin = (s%96)*ncols;
00334           medianInRegion<T>(pars, d, stat, rowmin, colmin, nrows, ncols, 1, 1, pbits); 
00335         }
00336       }
00337       return true; 
00338     }
00339 
00340 //-------------------
00341 // Common mode correction algorithm for Epix100
00342 
00343   template <typename T>
00344     bool do_common_mode_epix100_v1(T* data)
00345     {
00346       const common_mode_t* pars = &m_cmod_pars[1]; 
00347       // [0] element=mode is excluded from parameters
00348       unsigned cmtype = (unsigned) m_cmod_pars[1];
00349       unsigned pbits = (m_pbits & 256) ? 0xffff : 0;
00350 
00351       // EPIX100A, common_mode file example: 4 6 30 10
00352       if (m_pbits & 128) MsgLog(_name_(), info, "EPIX100A cmtype:" << cmtype);
00353 
00354       //T maxCorrection = (T) m_cmod_pars[2];
00355 
00356       unsigned shape[2] = {704, 768};
00357 
00358       size_t nregs  = 16;       
00359       size_t nrows  = shape[0]/2; // 352
00360       size_t ncols  = shape[1]/8; // 96
00361       size_t rowmin = 0;
00362       size_t colmin = 0;
00363       
00364       ndarray<T,2> d(data, shape);
00365       ndarray<const pixel_status_t,2> stat(m_status, shape);
00366 
00367       for(size_t s=0; s<nregs; s++) {
00368         //meanInRegion  <T>(pars, d, stat, rowmin[s], colmin[s], nrows, ncols, 1, 1, pbits); 
00369         rowmin = (s/8)*nrows;
00370         colmin = (s%8)*ncols;
00371 
00372         if (cmtype & 1) {
00373           //common mode for 352x96-pixel 16 banks
00374           medianInRegionV3<T>(pars, d, stat, rowmin, colmin, nrows, ncols, 1, 1, pbits); 
00375           //medianInRegionV2<T>(pars, d, stat, rowmin, colmin, nrows, ncols, 1, 1, pbits); 
00376           //medianInRegion<T>(pars, d, stat, rowmin, colmin, nrows, ncols, 1, 1, pbits); 
00377           //meanInRegion<T>(pars, d, stat, rowmin, colmin, nrows, ncols, 1, 1, pbits); 
00378         }
00379 
00380         if (cmtype & 2) {
00381           //common mode for 96-pixel rows in 16 banks
00382           for(size_t r=0; r<nrows; r++) {
00383             medianInRegionV3<T>(pars, d, stat, rowmin+r, colmin, 1, ncols, 1, 1, pbits); 
00384             //medianInRegionV2<T>(pars, d, stat, rowmin+r, colmin, 1, ncols, 1, 1, pbits); 
00385             //medianInRegion<T>(pars, d, stat, rowmin+r, colmin, 1, ncols, 1, 1, pbits); 
00386             //meanInRegion<T>(pars, d, stat, rowmin+r, colmin, 1, ncols, 1, 1, pbits); 
00387           }
00388         }
00389 
00390         if (cmtype & 4) {
00391           //common mode for 352-pixel columns in 16 banks
00392           for(size_t c=0; c<ncols; c++) {
00393             medianInRegionV3<T>(pars, d, stat, rowmin, colmin+c, nrows, 1, 1, 1, pbits); 
00394             //medianInRegionV2<T>(pars, d, stat, rowmin, colmin+c, nrows, 1, 1, 1, pbits); 
00395             //medianInRegion<T>(pars, d, stat, rowmin, colmin+c, nrows, 1, 1, 1, pbits); 
00396             //meanInRegion<T>(pars, d, stat, rowmin, colmin+c, nrows, 1, 1, 1, pbits); 
00397           }
00398         }
00399       }
00400       return true; 
00401     }
00402 
00403 //-------------------
00404 // Optimized common mode correction algorithm for Epix100
00405 
00406   template <typename T>
00407     bool do_common_mode_epix100_v2(T* data)
00408     {
00409       const common_mode_t* pars = &m_cmod_pars[1]; 
00410       // [0] element=mode is excluded from parameters
00411       unsigned cmtype = (unsigned) m_cmod_pars[1];
00412       unsigned pbits = (m_pbits & 256) ? 0xffff : 0;
00413 
00414       // EPIX100A, common_mode file example: 4 6 30 10
00415       if (m_pbits & 128) MsgLog(_name_(), info, "EPIX100A cmtype:" << cmtype);
00416 
00417       //T maxCorrection = (T) m_cmod_pars[2];
00418 
00419       unsigned shape[2] = {704, 768};
00420 
00421       ndarray<T,2> d(data, shape);
00422       ndarray<const pixel_status_t,2> stat(m_status, shape);
00423 
00424       medianEpix100V1<T>(pars, d, stat, pbits);
00425 
00426       return true;
00427     }
00428 
00429 //-------------------
00430 
00431   template <typename T>
00432     bool do_common_mode_median(T* data)
00433     {
00434       if      (m_dettype == EPIX100A) return do_common_mode_epix100_v1<T>(data);
00435       //if      (m_dettype == EPIX100A) return do_common_mode_epix100_v2<T>(data);
00436       else if (m_dettype == FCCD960)  return do_common_mode_fccd960<T>(data);
00437       return false; 
00438     }
00439 
00440 //-------------------
00441 };
00442 
00443 } // namespace ImgAlgos
00444 
00445 #endif // IMGALGOS_COMMONMODECORRECTION_H

Generated on 19 Dec 2016 for PSDMSoftware by  doxygen 1.4.7