ImgAlgos/include/NDArrImageProducer.h

Go to the documentation of this file.
00001 #ifndef IMGALGOS_NDARRIMAGEPRODUCER_H
00002 #define IMGALGOS_NDARRIMAGEPRODUCER_H
00003 
00004 //--------------------------------------------------------------------------
00005 // File and Version Information:
00006 //      $Id: NDArrImageProducer.h 9474 2015-01-10 01:02:37Z dubrovin@SLAC.STANFORD.EDU $
00007 //
00008 // Description:
00009 //      Class NDArrImageProducer.
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/GeometryAccess.h"
00027 
00028 //#include "PSCalib/CSPad2x2CalibPars.h"
00029 //#include "CSPadPixCoords/PixCoordsCSPad2x2V2.h"
00030 #include "ImgAlgos/GlobalMethods.h"
00031 
00032 //------------------------------------
00033 // Collaborating Class Declarations --
00034 //------------------------------------
00035 
00036 #include "PSEvt/Source.h"
00037 
00038 
00039 //              ---------------------
00040 //              -- Class Interface --
00041 //              ---------------------
00042 
00043 namespace ImgAlgos {
00044 
00045 /// @addtogroup ImgAlgos
00046 
00047 /**
00048  *  @ingroup ImgAlgos
00049  *
00050  *  @brief NDArrImageProducer produces the CSPad2x2 image for each event and add it to the event in psana framework.
00051  *
00052  *  NDArrImageProducer works in psana framework. It does a few operation as follows:
00053  *  1) get the pixel coordinates from PixCoords2x1 and PixCoordsCSPad2x2 classes,
00054  *  2) get data from the event,
00055  *  3) produce the Image2D object with CSPad image for each event,
00056  *  4) add the Image2D object in the event for further modules.
00057  *
00058  *  The CSPad2x2 image array currently is shaped as [400][400] pixels.
00059  *
00060  *  This class should not be used directly in the code of users modules. 
00061  *  Instead, it should be added as a module in the psana.cfg file with appropriate parameters.
00062  *  Then, the produced Image2D object can be extracted from event and used in other modules.
00063  *
00064  *  This software was developed for the LCLS project.  If you use all or 
00065  *  part of it, please give an appropriate acknowledgment.
00066  *
00067  *  @see PixCoords2x1, PixCoordsQuad, PixCoordsCSPad, CSPadImageGetTest
00068  *
00069  *  @version \$Id: NDArrImageProducer.h 9474 2015-01-10 01:02:37Z dubrovin@SLAC.STANFORD.EDU $
00070  *
00071  *  @author Mikhail S. Dubrovin
00072  */
00073 
00074 class NDArrImageProducer : public Module {
00075 public:
00076 
00077   // Default constructor
00078   NDArrImageProducer (const std::string& name) ;
00079 
00080   // Destructor
00081   virtual ~NDArrImageProducer () ;
00082 
00083   /// Method which is called once at the beginning of the job
00084   virtual void beginJob(Event& evt, Env& env);
00085   
00086   /// Method which is called at the beginning of the run
00087   virtual void beginRun(Event& evt, Env& env);
00088   
00089   /// Method which is called at the beginning of the calibration cycle
00090   virtual void beginCalibCycle(Event& evt, Env& env);
00091   
00092   /// Method which is called with event data, this is the only required 
00093   /// method, all other methods are optional
00094   virtual void event(Event& evt, Env& env);
00095   
00096   /// Method which is called at the end of the calibration cycle
00097   virtual void endCalibCycle(Event& evt, Env& env);
00098 
00099   /// Method which is called at the end of the run
00100   virtual void endRun(Event& evt, Env& env);
00101 
00102   /// Method which is called once at the end of the job
00103   virtual void endJob(Event& evt, Env& env);
00104 
00105 
00106 protected:
00107 
00108   void printInputParameters();
00109   bool getCalibPars(Event& evt, Env& env);
00110   void cspad_image_init();
00111   void procEvent(Event& evt, Env& env);
00112   void checkTypeImplementation();
00113 
00114 private:
00115 
00116   // Data members, this is for example purposes only
00117 
00118   std::string m_calibdir;       // i.e. ./calib
00119   std::string m_calibgroup;     // i.e. CsPad2x2::CalibV1
00120   std::string m_str_src;        // i.e. MecTargetChamber.0:Cspad2x2.1
00121   Source      m_source;         // i.e. Detinfo(MecTargetChamber.0:Cspad2x2.1)
00122   Pds::Src    m_src;
00123   std::string m_inkey; 
00124   std::string m_outimgkey;      // i.e. "CSPad:Image"
00125   std::string m_outtype;
00126   std::string m_oname;
00127   unsigned    m_oindex;
00128   double      m_pix_scale_size_um;
00129   int         m_x0_off_pix;
00130   int         m_y0_off_pix;
00131   int        *m_xy0_off_pix;
00132   int         m_mode;           // mode of mapping pixels from ndarray to 2-d image
00133   bool        m_do_tilt;        // on/off tilt angles
00134   unsigned    m_print_bits;
00135   unsigned    m_count_evt;
00136   unsigned    m_count_clb;
00137   unsigned    m_count_msg;      // number of messages counter
00138   DATA_TYPE   m_dtype;
00139 
00140   unsigned    m_size;
00141   const unsigned  *m_coor_x_ind;
00142   const unsigned  *m_coor_y_ind;
00143   unsigned    m_x_ind_max;
00144   unsigned    m_y_ind_max;
00145 
00146   PSCalib::GeometryAccess* m_geometry;
00147 
00148 public:
00149 
00150 //--------------------
00151 
00152   template <typename TINP, typename TOUT>
00153     void save2DArrayInEventForType (Event& evt, ndarray<TINP,2>& img_inp ) {
00154 
00155       //If types are equal - just save array in event 
00156       if (typeid(TOUT) == typeid(TINP)) { // typeid(double).name()
00157         save2DArrayInEvent<TINP>(evt, m_src, m_outimgkey, img_inp);
00158         return;
00159       }
00160       
00161       //Copy array with type changing
00162       ndarray<TOUT,2> img_out (img_inp.shape());
00163 
00164       typename ndarray<TOUT,2>::iterator it_out = img_out.begin(); 
00165       for (typename ndarray<TINP,2>::iterator it=img_inp.begin(); it!=img_inp.end(); ++it, ++it_out ) {
00166           *it_out = (TOUT)*it;
00167       }
00168 
00169       save2DArrayInEvent<TOUT>(evt, m_src, m_outimgkey, img_out);
00170   }
00171 
00172 //--------------------
00173 
00174   template <typename T, unsigned ND>
00175   void image_fill_and_add_in_event(Event& evt, const ndarray<const T,ND>& data)
00176   {
00177     if (data.size() != m_size) { 
00178       stringstream ss; ss << "ndarray for source:" << m_source 
00179                           << " and key:" << m_inkey
00180                           << " has size: " << data.size()
00181                           << " different from number of pixels in geometry:" << m_size; 
00182       MsgLog(name(), warning, ss.str());
00183       throw std::runtime_error(ss.str());
00184     }
00185 
00186     unsigned shape[2] = {m_x_ind_max+1, m_y_ind_max+1};
00187     ndarray<T,2> img_nda(shape);
00188 
00189     std::fill_n(img_nda.data(), int(img_nda.size()), T(0));
00190   
00191     const T* p_data = data.data();
00192 
00193 
00194     if (m_mode == 0) {
00195       // Pixel intensity is replaced by the latest mapped pixel
00196       for (unsigned i=0; i<m_size; ++i)
00197         img_nda[m_coor_x_ind[i]][m_coor_y_ind[i]] = p_data[i];
00198     }
00199 
00200     else if (m_mode == 1) {
00201       // Select maximal intensity of two overlapping pixels
00202       for (unsigned i=0; i<m_size; ++i) {  
00203          T* p_tmp = &img_nda[m_coor_x_ind[i]][m_coor_y_ind[i]];
00204          if ( *p_tmp==0 || p_data[i] > *p_tmp) *p_tmp = p_data[i];
00205       }
00206     }
00207 
00208     else if (m_mode == 2) {
00209       // Accumulate pixel intensity in the 2-d image
00210       for (unsigned i=0; i<m_size; ++i) {  
00211         //unsigned ix = m_coor_x_ind[i];
00212         //unsigned iy = m_coor_y_ind[i];  
00213         img_nda[m_coor_x_ind[i]][m_coor_y_ind[i]] += p_data[i]; 
00214       }
00215     }
00216 
00217     //else if (m_mode == 3) 
00218       // Interpolation TBA
00219 
00220     else {
00221       // The same as mode 0
00222       for (unsigned i=0; i<m_size; ++i)
00223         img_nda[m_coor_x_ind[i]][m_coor_y_ind[i]] = p_data[i];
00224     }
00225 
00226     if      ( m_dtype == ASINP  ) save2DArrayInEvent<T>(evt, m_src, m_outimgkey, img_nda);
00227     else if ( m_dtype == INT16  ) save2DArrayInEventForType<T, int16_t> (evt, img_nda); 
00228     else if ( m_dtype == FLOAT  ) save2DArrayInEventForType<T, float>   (evt, img_nda); 
00229     else if ( m_dtype == DOUBLE ) save2DArrayInEventForType<T, double>  (evt, img_nda); 
00230     else if ( m_dtype == INT    ) save2DArrayInEventForType<T, int>     (evt, img_nda); 
00231   }
00232 
00233 //--------------------
00234 
00235   template <typename T, unsigned ND>
00236   bool procNDArrForTypeAndND(Event& evt, Env& env) {
00237 
00238        // CONST ndarray 
00239        shared_ptr< ndarray<const T,ND> > shp_const = evt.get(m_source, m_inkey, &m_src); // get m_src here
00240        if (shp_const.get()) {
00241          if ( ! getCalibPars(evt, env) ) return false;
00242          const ndarray<const T,ND>& nda = *shp_const.get();
00243          image_fill_and_add_in_event <T,ND> (evt, nda);
00244          return true;
00245        }
00246 
00247        // NON-CONST ndarray 
00248        shared_ptr< ndarray<T,ND> > shp = evt.get(m_source, m_inkey, &m_src); // get m_src here
00249        if (shp.get()) {
00250          if ( ! getCalibPars(evt, env) ) return false;
00251          ndarray<T,ND>& nda = *shp.get();
00252          image_fill_and_add_in_event <T,ND> (evt, nda);
00253          return true;
00254        }
00255 
00256        return false;
00257   }
00258   
00259 //--------------------
00260 
00261   template <typename T>
00262   bool procNDArrForType (Event& evt, Env& env) {
00263  
00264     if( m_print_bits & 8 ) MsgLog(name(), warning, "Produce image from ndarray, source:" << m_source 
00265                                   << " key:" << m_inkey << " data type:" << typeid(T).name() );
00266     
00267     if ( procNDArrForTypeAndND<T,2>(evt, env) ) return true;
00268     if ( procNDArrForTypeAndND<T,3>(evt, env) ) return true;
00269     if ( procNDArrForTypeAndND<T,4>(evt, env) ) return true;
00270     if ( procNDArrForTypeAndND<T,1>(evt, env) ) return true;
00271     
00272     return false;
00273   }
00274   
00275 //--------------------
00276 
00277 
00278 }; // class NDArrImageProducer
00279 
00280 } // namespace ImgAlgos
00281 
00282 #endif // IMGALGOS_NDARRIMAGEPRODUCER_H

Generated on 19 Dec 2016 for PSDMSoftware by  doxygen 1.4.7