CSPadPixCoords/include/CSPadImageProducer.h

Go to the documentation of this file.
00001 #ifndef CSPADPIXCOORDS_CSPADIMAGEPRODUCER_H
00002 #define CSPADPIXCOORDS_CSPADIMAGEPRODUCER_H
00003 
00004 //--------------------------------------------------------------------------
00005 // File and Version Information:
00006 //      $Id: CSPadImageProducer.h 8778 2014-08-07 00:17:27Z dubrovin@SLAC.STANFORD.EDU $
00007 //
00008 // Description:
00009 //      Class CSPadImageProducer.
00010 //
00011 //------------------------------------------------------------------------
00012 
00013 //-----------------
00014 // C/C++ Headers --
00015 //-----------------
00016 
00017 //----------------------
00018 // Base Class Headers --
00019 //----------------------
00020 #include "psana/Module.h"
00021 #include "MsgLogger/MsgLogger.h"
00022 
00023 //-------------------------------
00024 // Collaborating Class Headers --
00025 //-------------------------------
00026 #include "PSCalib/CSPadCalibPars.h"
00027 
00028 #include "CSPadPixCoords/QuadParameters.h"
00029 #include "CSPadPixCoords/PixCoords2x1.h"
00030 #include "CSPadPixCoords/PixCoordsQuad.h"
00031 #include "CSPadPixCoords/PixCoordsCSPad.h"
00032 
00033 #include "CSPadPixCoords/Image2D.h"
00034 #include "CSPadPixCoords/GlobalMethods.h"
00035 
00036 //------------------------------------
00037 // Collaborating Class Declarations --
00038 //------------------------------------
00039 
00040 #include "PSEvt/Source.h"
00041 //#include "psddl_psana/cspad.ddl.h"
00042 
00043 //              ---------------------
00044 //              -- Class Interface --
00045 //              ---------------------
00046 
00047 using namespace std;
00048 
00049 namespace CSPadPixCoords {
00050 
00051 /// @addtogroup CSPadPixCoords
00052 
00053 /**
00054  *  @ingroup CSPadPixCoords
00055  *
00056  *  @brief CSPadImageProducer produces the CSPad image for each event and add it to the event in psana framework.
00057  *
00058  *  CSPadImageProducer works in psana framework. It does a few operation as follows:
00059  *  \n 1) get the pixel coordinates from PixCoords2x1, PixCoordsQuad, and PixCoordsCSPad classes,
00060  *  \n 2) get data from the event,
00061  *  \n 3) produce the Image2D object with CSPad image for each event,
00062  *  \n 4) add the Image2D object in the event for further modules.
00063  *
00064  *  Time consumed to fill the CSPad image array (currently [1750][1750]) 
00065  *  is measured to be about 40 msec/event on psana0105. 
00066  *
00067  *  This class should not be used directly in the code of users modules. 
00068  *  Instead, it should be added as a module in the psana.cfg file with appropriate parameters.
00069  *  Then, the produced Image2D object can be extracted from event and used in other modules.
00070  *
00071  *  This software was developed for the LCLS project.  If you use all or 
00072  *  part of it, please give an appropriate acknowledgment.
00073  *
00074  *  @see PixCoords2x1, PixCoordsQuad, PixCoordsCSPad, CSPadImageGetTest
00075  *
00076  *  @version \$Id: CSPadImageProducer.h 8778 2014-08-07 00:17:27Z dubrovin@SLAC.STANFORD.EDU $
00077  *
00078  *  @author Mikhail S. Dubrovin
00079  */
00080     
00081 typedef int16_t pixmap_cspad_t;
00082 typedef int32_t pixnum_cspad_t;
00083 
00084 
00085 class CSPadImageProducer : public Module {
00086 public:
00087 
00088   enum { NQuadsMax    = Psana::CsPad::MaxQuadsPerSensor  };  // 4
00089   enum { N2x1         = Psana::CsPad::SectorsPerQuad     };  // 8
00090   enum { NCols2x1     = Psana::CsPad::ColumnsPerASIC     };  // 185
00091   enum { NRows2x1     = Psana::CsPad::MaxRowsPerASIC * 2 };  // 388
00092   enum { SizeOf2x1Arr = NRows2x1 * NCols2x1              };  // 185*388;
00093   const static uint32_t ARR_SIZE=32*SizeOf2x1Arr;
00094 
00095   /// Default constructor
00096   CSPadImageProducer (const std::string& name) ;
00097 
00098   /// Destructor
00099   virtual ~CSPadImageProducer () ;
00100 
00101   /// Method which is called once at the beginning of the job
00102   virtual void beginJob(Event& evt, Env& env);
00103   
00104   /// Method which is called at the beginning of the run
00105   virtual void beginRun(Event& evt, Env& env);
00106   
00107   /// Method which is called at the beginning of the calibration cycle
00108   virtual void beginCalibCycle(Event& evt, Env& env);
00109   
00110   /// Method which is called with event data, this is the only required 
00111   /// method, all other methods are optional
00112   virtual void event(Event& evt, Env& env);
00113   
00114   /// Method which is called at the end of the calibration cycle
00115   virtual void endCalibCycle(Event& evt, Env& env);
00116 
00117   /// Method which is called at the end of the run
00118   virtual void endRun(Event& evt, Env& env);
00119 
00120   /// Method which is called once at the end of the job
00121   virtual void endJob(Event& evt, Env& env);
00122 
00123 
00124 protected:
00125 
00126   void printInputParameters();
00127   void getConfigPars(Env& env);
00128   bool getGeometryPars(const std::string& calib_dir, const int runnum, const unsigned prbits);
00129   void getCalibPars(Event& evt, Env& env);
00130   void procEvent(Event& evt, Env& env);
00131   void getCSPadConfigFromData(Event& evt);
00132   void checkTypeImplementation();
00133   void cspadImgActivePixelMask(Env& env);
00134 
00135   //void cspad_image_init();
00136   //void cspad_image_fill(const int16_t* data, CSPadPixCoords::QuadParameters* quadpars, PSCalib::CSPadCalibPars *cspad_calibpar);
00137   //void cspad_image_save_in_file(const std::string &filename = "cspad_image.txt");
00138   //void cspad_image_add_in_event(Event& evt);
00139 
00140 private:
00141 
00142   // Data members, this is for example purposes only
00143 
00144   std::string m_calibDir;       // i.e. ./calib
00145   std::string m_typeGroupName;  // i.e. CsPad::CalibV1
00146   std::string m_str_src;        // i.e. CxiDs1.0:Cspad.0
00147    
00148   Source      m_source;         // Data source set from config file
00149   Pds::Src    m_src;
00150   std::string m_inkey; 
00151   std::string m_imgkey;         
00152   std::string m_fname_pixmap;
00153   std::string m_fname_pixnum;
00154   std::string m_outtype;
00155   bool     m_tiltIsApplied;
00156   unsigned m_print_bits;
00157   long     m_count;
00158   long     m_count_cfg;
00159   long     m_count_msg;
00160   DATA_TYPE   m_dtype;
00161 
00162   // Parameters form Psana::CsPad::ConfigV# object
00163   uint32_t m_numQuadsInConfig;
00164   uint32_t m_roiMask        [4];
00165   uint32_t m_numAsicsStored [4];
00166 
00167   // Parameters form Psana::CsPad::DataV# and Psana::CsPad::ElementV# object
00168   uint32_t m_numQuads;
00169   uint32_t m_quadNumber     [4];
00170   uint32_t m_num2x1Stored   [4];
00171 
00172   PSCalib::CSPadCalibPars        *m_cspad_calibpar;
00173   CSPadPixCoords::PixCoords2x1   *m_pix_coords_2x1;
00174   CSPadPixCoords::PixCoordsQuad  *m_pix_coords_quad;
00175   CSPadPixCoords::PixCoordsCSPad *m_pix_coords_cspad;
00176 
00177   //uint32_t   m_cspad_ind;
00178   double    *m_coor_x_pix;
00179   double    *m_coor_y_pix;
00180   uint32_t  *m_coor_x_int;
00181   uint32_t  *m_coor_y_int;
00182 
00183   const static int NX_QUAD=850;
00184   const static int NY_QUAD=850;
00185 
00186   const static int NX_CSPAD=1750;
00187   const static int NY_CSPAD=1750;
00188   const static uint32_t IMG_SIZE=NX_CSPAD*NY_CSPAD;
00189 
00190   //enum{ NX_QUAD=850, 
00191   //      NY_QUAD=850 };
00192 
00193   //enum{ NX_CSPAD=1750, 
00194   //      NY_CSPAD=1750,
00195   //      IMG_SIZE=NX_CSPAD*NY_CSPAD };
00196 
00197   //double m_arr_cspad_image[NX_CSPAD][NY_CSPAD];
00198 
00199 //-------------------
00200   /**
00201    * @brief Gets m_src, m_numQuadsInConfig, m_roiMask[q] and m_num2x1Stored[q] from the Psana::CsPad::ConfigV# object.
00202    * 
00203    */
00204 
00205   template <typename T>
00206   bool getQuadConfigParsForType(Env& env) {
00207 
00208     //cout  << " Check configuration for source: " << m_source << endl;      
00209 
00210         shared_ptr<T> config = env.configStore().get(m_source, &m_src);
00211         if (config.get()) {
00212             for (uint32_t q = 0; q < NQuadsMax; ++ q) {
00213               m_roiMask[q]         = config->roiMask(q);
00214               m_numAsicsStored[q]  = config->numAsicsStored(q);
00215             }
00216             m_count_cfg ++;
00217             return true;
00218         }
00219         return false;
00220   }
00221 
00222 //-------------------
00223   /**
00224    * @brief Gets m_numQuads and m_quadNumber[q] from the Psana::CsPad::DataV# and ElementV# objects.
00225    * 
00226    */
00227 
00228   template <typename TDATA, typename TELEMENT>
00229   bool getCSPadConfigFromDataForType(Event& evt) {
00230 
00231     //typedef int16_t data_cspad_t;
00232 
00233     std::string key=""; // FOR RAW CSPAD DATA
00234 
00235     shared_ptr<TDATA> data = evt.get(m_source, key, &m_src);
00236     if (data.get()) {
00237       m_numQuads = data->quads_shape()[0];
00238 
00239       for (uint32_t q = 0; q < m_numQuads; ++ q) {
00240         const TELEMENT& el = data->quads(q);
00241         m_quadNumber[q]    = el.quad();
00242         m_num2x1Stored[q]  = el.data().shape()[0];
00243       }
00244       return true;
00245     }
00246     return false;
00247   }
00248 
00249 //--------------------
00250   /**
00251    * @brief Fills a part of the image (img_nda) for one quad per call.
00252    * 
00253    * @param[in]  data            pointer to the beginning of the data array for quad.
00254    * @param[in]  quadpars        pointer to the object with configuration parameters for quad.
00255    * @param[out] img_nda         reference to the ndarray<T,2> with CSPAD image.
00256    */
00257   
00258   template <typename TIN, typename TOUT>
00259   void cspadImageFillForType(const TIN* data, CSPadPixCoords::QuadParameters* quadpars, ndarray<TOUT,2>& img_nda) 
00260   {
00261         int       quad    = quadpars -> getQuadNumber();
00262         uint32_t  roiMask = quadpars -> getRoiMask();
00263 
00264         int ind_in_arr = 0;
00265 
00266         for(uint32_t sect=0; sect < N2x1; sect++)
00267         {
00268              bool bitIsOn = roiMask & (1<<sect);
00269              if( !bitIsOn ) continue; 
00270 
00271              int pix_in_cspad = (quad*N2x1 + sect) * SizeOf2x1Arr;
00272  
00273              const TIN *data2x1 = &data[ind_in_arr * SizeOf2x1Arr];
00274              //cout  << "  add section " << sect << endl;            
00275  
00276              for (uint32_t c=0; c<NCols2x1; c++) {
00277              for (uint32_t r=0; r<NRows2x1; r++) {
00278 
00279                // This access takes 72ms/cspad
00280                //int ix = (int) m_pix_coords_cspad -> getPixCoor_pix (XCOOR, quad, sect, r, c);
00281                //int iy = (int) m_pix_coords_cspad -> getPixCoor_pix (YCOOR, quad, sect, r, c);
00282 
00283                // This access takes 40ms/cspad
00284                int ix = m_coor_x_int [pix_in_cspad];
00285                int iy = m_coor_y_int [pix_in_cspad];
00286                pix_in_cspad++;
00287 
00288                if(ix <  0)        continue;
00289                if(iy <  0)        continue;
00290                if(ix >= NX_CSPAD) continue;
00291                if(iy >= NY_CSPAD) continue;
00292 
00293                //if (data2x1[c*NRows2x1+r] != 1 ) cout << " data=" << data2x1[c*NRows2x1+r]  
00294                //    << " q:" << quad << " s:" << sect << " r:"  << r << " c:"  <<  c << endl;      
00295                //m_arr_cspad_image[ix][iy] += (double)data2x1[c*NRows2x1+r];
00296                img_nda[ix][iy] += (TOUT)data2x1[c*NRows2x1+r];
00297              }
00298              }
00299              ++ind_in_arr;
00300         }
00301   }
00302 
00303 //-------------------
00304   /**
00305    * @brief For requested m_source and m_inkey process Psana::CsPad::DataV1, or V2
00306    * Returns false if data is missing.
00307    * Output image data type TOUT is equal to input data type TOUT=int16_t.
00308    */
00309 
00310   template <typename TDATA, typename TELEMENT>
00311   bool procCSPadDataForType (Event& evt) {
00312 
00313       typedef int16_t data_cspad_t;
00314       typedef int16_t TOUT; // ok 
00315       //typedef double  TOUT; // ok
00316       //typedef float   TOUT; // ok
00317 
00318       shared_ptr<TDATA> data_shp = evt.get(m_source, m_inkey, &m_src); // get m_src here
00319       
00320       if (data_shp.get()) {
00321       
00322         const unsigned shape[] = {NY_CSPAD,NX_CSPAD};
00323         ndarray<TOUT,2> img_nda(shape);
00324         std::fill(img_nda.begin(), img_nda.end(), TOUT(0));    
00325         //std::fill_n(img_nda.data(), int(IMG_SIZE), TOUT(0));    
00326         //std::fill_n(&m_arr_cspad_image[0][0], int(IMG_SIZE), double(0));
00327       
00328         int nQuads = data_shp->quads_shape()[0];
00329         for (int q = 0; q < nQuads; ++ q) {
00330             const TELEMENT& el = data_shp->quads(q);      
00331             const ndarray<const data_cspad_t,3>& data_nda = el.data();
00332             uint32_t qNum = el.quad() ;
00333             CSPadPixCoords::QuadParameters *quadpars = new CSPadPixCoords::QuadParameters(qNum, NX_QUAD, NY_QUAD, m_numAsicsStored[qNum], m_roiMask[qNum]);      
00334 
00335             cspadImageFillForType<data_cspad_t, TOUT>(data_nda.data(), quadpars, img_nda);
00336         }
00337       
00338         //addImageInEventForType<double>(evt, &m_arr_cspad_image[0][0]);
00339         //addImageInEventForType<TOUT>(evt, img_nda);
00340         save2DArrayInEvent<TOUT>(evt, m_src, m_imgkey, img_nda);
00341 
00342         return true;
00343       } // if (data_shp.get())
00344       return false;
00345   }
00346 
00347 //-------------------
00348   /**
00349    * @brief For requested m_source and m_inkey process CSPAD data ndarray<T,3>
00350    * Returns false if data is missing.
00351    * Output image data type T is equal to input data type T.
00352    */
00353 
00354   template <typename T>
00355     void procCSPadNDArrForTypeAndNDArr (Event& evt, const ndarray<const T,3> inp_ndarr) {
00356  
00357           const unsigned shape[] = {NY_CSPAD,NX_CSPAD};
00358           ndarray<T,2> img_nda(shape);
00359           //std::fill_n(img_nda.data(), int(IMG_SIZE), T(0));    
00360           std::fill(img_nda.begin(), img_nda.end(), T(0));    
00361 
00362           //const ndarray<const T,3> inp_ndarr = *shp.get(); //const T* p_data = shp->data();
00363           //cout << "inp_ndarr.shape():" << str_shape<const T,3>(inp_ndarr) << '\n';
00364         
00365           int ind2x1_in_arr = 0;        
00366 
00367           if (inp_ndarr.shape()[0] == 32) { // full size array [32, 185, 388]
00368 
00369               for (uint32_t q = 0; q < 4; ++ q) {
00370                   const T* data_quad = &inp_ndarr[ind2x1_in_arr][0][0]; 
00371                   CSPadPixCoords::QuadParameters *quadpars = new CSPadPixCoords::QuadParameters(q, NX_QUAD, NY_QUAD, 8, 255);                 
00372                   cspadImageFillForType<T,T>(data_quad, quadpars, img_nda);        
00373                   ind2x1_in_arr += 8;
00374               }
00375           }
00376           else { // array shaped as data [N<32, 185, 388]
00377 
00378               for (uint32_t q = 0; q < m_numQuads; ++ q) {
00379                       const T* data_quad = &inp_ndarr[ind2x1_in_arr][0][0]; 
00380                   uint32_t qNum = m_quadNumber[q]; 
00381                   CSPadPixCoords::QuadParameters *quadpars = new CSPadPixCoords::QuadParameters(qNum, NX_QUAD, NY_QUAD, m_numAsicsStored[qNum], m_roiMask[qNum]);         
00382               
00383                   cspadImageFillForType<T,T>(data_quad, quadpars, img_nda);        
00384                   ind2x1_in_arr += m_num2x1Stored[q];
00385               }
00386           }
00387         
00388           //addImageInEventForType<T>(evt, img_nda);
00389           save2DArrayInEvent<T>(evt, m_src, m_imgkey, img_nda);
00390   }
00391 
00392 //-------------------
00393   /**
00394    * @brief For requested m_source and m_inkey process CSPAD data ndarray<T,3>
00395    * Returns false if data is missing.
00396    * Output image data type T is equal to input data type T.
00397    */
00398 
00399   template <typename T>
00400   bool procCSPadNDArrForType (Event& evt) {
00401  
00402         if( m_print_bits & 8 ) MsgLog(name(), info, "Produce image from CSPAD ndarray, source:" << m_source 
00403                                                    << " key:" << m_inkey << " data type:" << typeid(T).name() );
00404         
00405         shared_ptr< ndarray<const T,3> > shp_const = evt.get(m_source, m_inkey, &m_src); // get m_src here
00406         if (shp_const.get()) { procCSPadNDArrForTypeAndNDArr<T>(evt, *shp_const.get()); return true; }
00407 
00408         shared_ptr< ndarray<T,3> > shp = evt.get(m_source, m_inkey, &m_src); // get m_src here
00409         if (shp.get()) { procCSPadNDArrForTypeAndNDArr<T>(evt, *shp.get()); return true; }
00410 
00411         return false;
00412   }
00413 
00414 //-------------------
00415 
00416 };
00417 
00418 } // namespace CSPadPixCoords
00419 
00420 #endif // CSPADPIXCOORDS_CSPADIMAGEPRODUCER_H

Generated on 19 Dec 2016 for PSANAmodules by  doxygen 1.4.7