ImgAlgos/include/GlobalMethods.h

Go to the documentation of this file.
00001 #ifndef IMGALGOS_GLOBALMETHODS_H
00002 #define IMGALGOS_GLOBALMETHODS_H
00003 
00004 //--------------------------------------------------------------------------
00005 // File and Version Information:
00006 //      $Id: GlobalMethods.h 12801 2016-10-29 00:20:40Z dubrovin@SLAC.STANFORD.EDU $
00007 //
00008 // Description:
00009 //      Class GlobalMethods.
00010 //
00011 //------------------------------------------------------------------------
00012 
00013 //-----------------
00014 // C/C++ Headers --
00015 //-----------------
00016 
00017 #include <string>
00018 #include <fstream>   // ofstream
00019 #include <iomanip>   // for setw, setfill
00020 #include <sstream>   // for stringstream
00021 #include <iostream>
00022 #include <math.h>
00023 //#include <stdio.h>
00024 
00025 //----------------------
00026 // Base Class Headers --
00027 //----------------------
00028 
00029 //-------------------------------
00030 // Collaborating Class Headers --
00031 //-------------------------------
00032 
00033 #include "PSEvt/Event.h"
00034 #include "PSEnv/Env.h"
00035 #include "PSEvt/Source.h"
00036 #include "MsgLogger/MsgLogger.h"
00037 #include "CSPadPixCoords/Image2D.h"
00038 
00039 #include "pdscalibdata/NDArrIOV1.h"
00040 
00041 //For save in PNG and TIFF formats
00042 //#define png_infopp_NULL (png_infopp)NULL
00043 //#define int_p_NULL (int*)NULL
00044 
00045 // see: https://github.com/ignf/gilviewer/issues/8
00046 // and: http://libpng.sourceforge.net/ANNOUNCE-1.4.1.txt
00047 #ifndef int_p_NULL
00048 #define png_infopp_NULL (png_infopp)NULL
00049 #define int_p_NULL (int*)NULL
00050 #endif
00051 //#include <boost/mpl/vector.hpp>
00052 #include <boost/gil/gil_all.hpp>
00053 
00054 //#include <boost/mpl/vector.hpp>
00055 //#include <boost/gil/typedefs.hpp>
00056 //#include <boost/gil/extension/dynamic_image/any_image.hpp>
00057 //#include <boost/gil/planar_pixel_reference.hpp>
00058 //#include <boost/gil/color_convert.hpp>
00059 //#include <boost/gil/typedefs.hpp>
00060 //#include <boost/gil/image.hpp>
00061 //#include <boost/gil/image_view.hpp>
00062 //#include <boost/gil/image_view_factory.hpp>
00063 
00064 #ifndef BOOST_GIL_NO_IO
00065 //#include <boost/gil/extension/io/jpeg_io.hpp>
00066 
00067 #include <boost/gil/extension/io/png_dynamic_io.hpp>
00068 //#include <boost/gil/extension/io/jpeg_dynamic_io.hpp> 
00069 #endif
00070 
00071 //------------------------------------
00072 // Collaborating Class Declarations --
00073 //------------------------------------
00074 #include "pdsdata/xtc/Src.hh"     // for srcToString( const Pds::Src& src )
00075 
00076 //              ---------------------
00077 //              -- Class Interface --
00078 //              ---------------------
00079 
00080 namespace ImgAlgos {
00081 
00082 /**
00083  *  @defgroup ImgAlgos ImgAlgos package 
00084  *  @brief Package ImgAlgos contains a collection of psana modules and algorithms for LCLS data processing
00085  *
00086  *  Modules in this package can be destinguished be their names as follows. 
00087  *  @li Psana modules:
00088  *  \n  Acqiris* - work with acqiris data
00089  *  \n  CSPad* - work with CSPAD data
00090  *  \n  *detector-name* - work with specific detector data
00091  *  \n  *ImageProducer - produces 2-d ndarray from raw data and save it in the event store
00092  *  \n  NDArr* - modules for ndarray processing
00093  *  \n  Img* - modules for image (2-d ndarray) processing
00094  *  
00095  *  @li Algorithms:
00096  *  \n  CorAna* - modules (psana and standalone) developed for time-correlation analysis 
00097  *  \n  Geometry* - unified heirarchial detector geometry description
00098  *  \n  Global* - global methods
00099  *
00100  */
00101 
00102 
00103 /// @addtogroup ImgAlgos
00104 
00105 /**
00106  *  @ingroup ImgAlgos
00107  *
00108  *  @brief Global methods for ImgAlgos package
00109  *
00110  *  This software was developed for the LCLS project.  If you use all or 
00111  *  part of it, please give an appropriate acknowledgment.
00112  *
00113  *  @version $Id: GlobalMethods.h 12801 2016-10-29 00:20:40Z dubrovin@SLAC.STANFORD.EDU $
00114  *
00115  *  @author Mikhail S. Dubrovin
00116  */
00117 
00118 using namespace boost::gil;
00119 using namespace std;
00120 
00121 //typedef boost::mpl::vector<gray8_image_t, gray16_image_t, gray32_image_t> my_images_t;
00122 
00123 //typedef pixel<float,gray_layout_t>      gray_float_pixel_t;
00124 //typedef image<gray_float_pixel_t,false> gray_float_image_t;
00125 //typedef gray_float_image_t::view_t      gray_float_view_t; 
00126 
00127 //typedef pixel<double,gray_layout_t>      gray_double_pixel_t;
00128 //typedef image<gray_double_pixel_t,false> gray_double_image_t;
00129 //typedef gray_double_image_t::view_t      gray_double_view_t; 
00130 
00131  enum DATA_TYPE {NONDEFDT, ASDATA, ASINP, FLOAT, DOUBLE, SHORT, UNSIGNED, INT, INT16, INT32, UINT, UINT8, UINT16, UINT32};
00132 
00133  enum FILE_MODE {BINARY, TEXT, TIFF, PNG, METADTEXT};
00134 
00135  enum DETECTOR_TYPE {OTHER, CSPAD, CSPAD2X2, PNCCD, PRINCETON, ACQIRIS, TM6740, 
00136                      OPAL1000, OPAL2000, OPAL4000, OPAL8000,
00137                      ANDOR, ORCAFL40, FCCD960, EPIX, EPIX100A, EPIX10K, 
00138                      QUARTZ4A150, RAYONIX, IMP, EVR, FCCD, TIMEPIX, FLI, PIMAX};
00139 
00140  // const static int UnknownCM = -10000; 
00141 
00142 //--------------------
00143 
00144 struct TwoIndexes {
00145   int i;
00146   int j;
00147 
00148   TwoIndexes(const int& ii=0, const int& jj=0) : i(ii), j(jj) {}
00149 
00150   TwoIndexes& operator=(const TwoIndexes& rhs) {
00151     i = rhs.i;
00152     j = rhs.j;
00153     return *this;
00154   }
00155 };
00156 
00157 //--------------------
00158 
00159 struct TwoIndValue {
00160   int i;
00161   int j;
00162   double v;
00163 
00164   TwoIndValue(const int& ii=0, const int& jj=0, const double& vv=0) : i(ii), j(jj), v(vv) {}
00165 
00166   TwoIndValue& operator=(const TwoIndValue& rhs) {
00167     i = rhs.i;
00168     j = rhs.j;
00169     v = rhs.v;
00170     return *this;
00171   }
00172 };
00173 
00174 //--------------------
00175 
00176 class NDArrPars {
00177 public:
00178   NDArrPars();
00179   NDArrPars(const unsigned ndim, const unsigned size, const unsigned* shape, const DATA_TYPE dtype, const Pds::Src& src);
00180   virtual ~NDArrPars(){}
00181 
00182   void setPars(const unsigned ndim, const unsigned size, const unsigned* shape, const DATA_TYPE dtype, const Pds::Src& src);
00183   void print();
00184   bool      is_set()    {return m_is_set;}
00185   unsigned  ndim()      {return m_ndim;}
00186   unsigned  size()      {return m_size;}
00187   unsigned* shape()     {return &m_shape[0];}
00188   DATA_TYPE dtype()     {return m_dtype;}
00189   const Pds::Src& src() {return m_src;}
00190 
00191 private:
00192   unsigned  m_ndim;
00193   unsigned  m_size;
00194   unsigned  m_shape[5];
00195   DATA_TYPE m_dtype;
00196   Pds::Src  m_src;
00197   bool      m_is_set;
00198 
00199   // Copy constructor and assignment are disabled by default
00200   NDArrPars ( const NDArrPars& ) ;
00201   NDArrPars& operator = ( const NDArrPars& ) ;
00202 };
00203 
00204 //--------------------
00205 
00206 class GlobalMethods  {
00207 public:
00208   GlobalMethods() {}
00209   virtual ~GlobalMethods() {}
00210 
00211 private:
00212   // Copy constructor and assignment are disabled by default
00213   GlobalMethods ( const GlobalMethods& ) ;
00214   GlobalMethods& operator = ( const GlobalMethods& ) ;
00215 };
00216 
00217 //--------------------
00218 
00219   std::string stringFromUint(unsigned number, unsigned width=6, char fillchar='0');
00220   std::string stringTimeStamp(PSEvt::Event& evt, std::string fmt="%Y%m%d-%H%M%S%f"); //("%Y-%m-%d %H:%M:%S%f%z");
00221   std::string stringRunNumber(PSEvt::Event& evt, unsigned width=4);
00222   int getRunNumber(PSEvt::Event& evt);
00223   double doubleTime(PSEvt::Event& evt);
00224   unsigned fiducials(PSEvt::Event& evt);                  // returns 17-bits (131071) integer value: fiducials clock runs at 360Hz.
00225   unsigned eventCounterSinceConfigure(PSEvt::Event& evt); // returns 15-bits (32767)  integer value: event counter since Configure.
00226   void printSizeOfTypes();
00227   /// Define the shape or throw message that can not do that.
00228   bool defineImageShape(PSEvt::Event& evt, const PSEvt::Source& src, const std::string& key, unsigned* shape);
00229   bool defineNDArrPars(PSEvt::Event& evt, const PSEvt::Source& src, const std::string& key, NDArrPars* ndarr_pars, bool print_wng=false);
00230   void saveTextInFile(const std::string& fname, const std::string& text, bool print_msg);
00231   std::string stringInstrument(PSEnv::Env& env);
00232   std::string stringExperiment(PSEnv::Env& env);
00233   unsigned expNum(PSEnv::Env& env);
00234   std::string stringExpNum(PSEnv::Env& env, unsigned width=4);
00235   bool file_exists(std::string& fname);
00236   std::string srcToString( const Pds::Src& src ); // convert source address to string
00237   DETECTOR_TYPE detectorTypeForStringSource(const std::string& str_src);
00238   DETECTOR_TYPE detectorTypeForSource(const PSEvt::Source& src);
00239   std::string calibGroupForDetType(const DETECTOR_TYPE det_type);
00240   std::string stringForDetType(const DETECTOR_TYPE det_type);
00241   std::string calibGroupForSource(PSEvt::Source& src);
00242   std::string split_string_left(const std::string& s, size_t& pos, const char& sep=':');
00243   std::string strDataType(const DATA_TYPE& dtype);
00244 
00245 //--------------------
00246 //--------------------
00247 //--------------------
00248 //--------------------
00249 
00250 //--------------------
00251 /// For type=T returns the string with symbolic data type and its size, i.e. "d of size 8"
00252   template <typename T>
00253   std::string strOfDataTypeAndSize()
00254   {
00255     std::stringstream ss; ss << typeid(T).name() << " of size " << sizeof(T);
00256     return ss.str();
00257   }
00258 
00259 //--------------------
00260 
00261   template <typename T>
00262     bool isSupportedDataType()
00263     {
00264         std::cout <<  "Input data type: " << strOfDataTypeAndSize<T>() << std::endl;
00265         if ( *typeid(T).name() != 't') {
00266           cout <<  "Sorry, but saving images in PNG works for uint16_t data only..." << endl;
00267           return false;
00268         }
00269         return true;
00270     }
00271 
00272 //--------------------
00273 
00274   template <typename T>
00275     DATA_TYPE dataType()
00276     {
00277       if      ( typeid(T) == typeid(double  )) return DOUBLE;
00278       else if ( typeid(T) == typeid(float   )) return FLOAT;
00279       else if ( typeid(T) == typeid(int     )) return INT;
00280       else if ( typeid(T) == typeid(int32_t )) return INT32;
00281       else if ( typeid(T) == typeid(uint32_t)) return UINT32;
00282       else if ( typeid(T) == typeid(uint16_t)) return UINT16;
00283       else if ( typeid(T) == typeid(uint8_t )) return UINT8;
00284       else if ( typeid(T) == typeid(int16_t )) return INT16;
00285       else if ( typeid(T) == typeid(short   )) return SHORT;
00286       else if ( typeid(T) == typeid(unsigned)) return UNSIGNED;
00287       else                                     return NONDEFDT;
00288     }
00289 
00290 //--------------------
00291 
00292   template <typename T>
00293     std::string strDataType()
00294     {
00295       return strDataType(dataType<T>());
00296     }
00297 
00298 //--------------------
00299 /// Define inage shape in the event for specified type, src, and key 
00300   template <typename T>
00301   bool defineImageShapeForType(PSEvt::Event& evt, const PSEvt::Source& src, const std::string& key, unsigned* shape)
00302   {
00303     boost::shared_ptr< ndarray<const T,2> > img_const = evt.get(src, key);
00304     if (img_const.get()) {
00305       for(int i=0;i<2;i++) shape[i]=img_const->shape()[i];
00306       //shape=img->shape();
00307       return true;
00308     } 
00309 
00310     boost::shared_ptr< ndarray<T,2> > img = evt.get(src, key);
00311     if (img.get()) {
00312       for(int i=0;i<2;i++) shape[i]=img->shape()[i];
00313       //shape=img->shape();
00314       return true;
00315     } 
00316     return false;
00317   }
00318 
00319 //--------------------
00320 /// Define ndarray parameters in the event for specified type, src, and key 
00321   template <typename T, unsigned NDim>
00322   bool defineNDArrParsForTypeNDim(PSEvt::Event& evt, const PSEvt::Source& src, const std::string& key, DATA_TYPE dtype, NDArrPars* ndarr_pars)
00323   {
00324     Pds::Src pds_src;    
00325 
00326     boost::shared_ptr< ndarray<T,NDim> >  shp = evt.get(src, key, &pds_src);
00327     if (shp.get()) { ndarr_pars->setPars(NDim, shp->size(), shp->shape(), dtype, pds_src); return true; } 
00328 
00329     return false;
00330   }
00331 
00332 //--------------------
00333 /// Define ndarray parameters in the event for specified type, src, and key 
00334   template <typename T>
00335   bool defineNDArrParsForType(PSEvt::Event& evt, const PSEvt::Source& src, const std::string& key, DATA_TYPE dtype, NDArrPars* ndarr_pars)
00336   {
00337     // CONST
00338     if (defineNDArrParsForTypeNDim<const T,2>(evt, src, key, dtype, ndarr_pars)) return true;
00339     if (defineNDArrParsForTypeNDim<const T,3>(evt, src, key, dtype, ndarr_pars)) return true;
00340     if (defineNDArrParsForTypeNDim<const T,4>(evt, src, key, dtype, ndarr_pars)) return true;
00341     if (defineNDArrParsForTypeNDim<const T,5>(evt, src, key, dtype, ndarr_pars)) return true;
00342     if (defineNDArrParsForTypeNDim<const T,1>(evt, src, key, dtype, ndarr_pars)) return true;
00343 
00344     // NON-CONST
00345     if (defineNDArrParsForTypeNDim<T,2>(evt, src, key, dtype, ndarr_pars)) return true;
00346     if (defineNDArrParsForTypeNDim<T,3>(evt, src, key, dtype, ndarr_pars)) return true;
00347     if (defineNDArrParsForTypeNDim<T,4>(evt, src, key, dtype, ndarr_pars)) return true;
00348     if (defineNDArrParsForTypeNDim<T,5>(evt, src, key, dtype, ndarr_pars)) return true;
00349     if (defineNDArrParsForTypeNDim<T,1>(evt, src, key, dtype, ndarr_pars)) return true;
00350 
00351     return false;
00352   }
00353 
00354 //--------------------
00355 /// Save 2-D array in file
00356   template <typename T>
00357     bool save2DArrayInPNGForType(const std::string& fname, const T* arr, const unsigned& rows, const unsigned& cols)
00358     {
00359         using namespace boost::gil;
00360 
00361         //unsigned size = cols*rows;
00362 
00363         if ( *typeid(T).name() == *typeid(uint16_t).name() ) {
00364           uint16_t* p_arr = (uint16_t*)&arr[0];
00365           gray16c_view_t image = interleaved_view(cols, rows, (const gray16_pixel_t*)p_arr, cols*sizeof(T));
00366           png_write_view(fname, image);
00367           return true;
00368         }
00369 
00370         else if ( *typeid(T).name() == *typeid(uint8_t).name() ) {
00371           uint8_t* p_arr = (uint8_t*)&arr[0];
00372           gray8c_view_t image = interleaved_view(cols, rows, (const gray8_pixel_t*)p_arr, cols*sizeof(T));
00373           png_write_view(fname, image);
00374           return true;
00375         }
00376 
00377         return false;
00378     }
00379 
00380 //--------------------
00381 /// Save 2-D array in file
00382   template <typename T>
00383   void save2DArrayInFile(const std::string& fname, const T* arr, const unsigned& rows, const unsigned& cols, bool print_msg, FILE_MODE file_type=TEXT)
00384   {  
00385     if (fname.empty()) {
00386       MsgLog("GlobalMethods", warning, "The output file name is empty. 2-d array is not saved.");
00387       return;
00388     }
00389 
00390     if( print_msg ) MsgLog("GlobalMethods", info, "Save 2-d array in file " << fname.c_str() << " file type:" << strOfDataTypeAndSize<T>());
00391 
00392     //======================
00393     if (file_type == TEXT) {
00394         std::ofstream out(fname.c_str()); 
00395         out << std::setprecision(9); // << std::setw(8) << std::setprecision(0) << std::fixed 
00396               for (unsigned r = 0; r != rows; ++r) {
00397                 for (unsigned c = 0; c != cols; ++c) {
00398                   out << arr[r*cols + c] << ' ';
00399                 }
00400                 out << '\n';
00401               }
00402         out.close();
00403         return; 
00404     }
00405 
00406     //======================
00407     if (file_type == BINARY) {
00408         std::ios_base::openmode mode = std::ios_base::out | std::ios_base::binary;
00409         std::ofstream out(fname.c_str(), mode);
00410         //out.write(reinterpret_cast<const char*>(arr), rows*cols*sizeof(T));
00411         for (unsigned r = 0; r != rows; ++r) {
00412           const T* data = &arr[r*cols];
00413           out.write(reinterpret_cast<const char*>(data), cols*sizeof(T));
00414         }
00415         out.close();
00416         return; 
00417     }
00418 
00419     //======================
00420     if (file_type == PNG) {
00421 
00422         using namespace boost::gil;
00423 
00424         if (save2DArrayInPNGForType<T>(fname, arr, rows, cols)) return;
00425         MsgLog("GlobalMethods", warning, "Input data type " << strOfDataTypeAndSize<T>() << " is not implemented for saving in PNG. File IS NOT saved!");
00426         return; 
00427     }
00428 
00429     //======================
00430     if (file_type == TIFF) {
00431         MsgLog("GlobalMethods", warning, "Saving of images in TIFF format is not implemented yet.");
00432         return; 
00433     }
00434 
00435     //======================
00436   }
00437 
00438 
00439 //--------------------
00440 /// Save ndarray<T,2> in TEXT file NON-CONST T
00441 //  template <typename T>
00442 //  void save2DArrayInFile(const std::string& fname, const ndarray<T,2>& p_ndarr, bool print_msg, FILE_MODE file_type=TEXT)
00443 //  {  
00444 //    save2DArrayInFile<T> (fname, p_ndarr.data(), p_ndarr.shape()[0], p_ndarr.shape()[1], print_msg, file_type);
00445 //  }
00446 
00447 //--------------------
00448 /// Save ndarray<const T,2> in TEXT file
00449   template <typename T>
00450   void save2DArrayInFile(const std::string& fname, const ndarray<const T,2>& p_ndarr, bool print_msg, FILE_MODE file_type=TEXT)
00451   {  
00452     save2DArrayInFile<T> (fname, p_ndarr.data(), p_ndarr.shape()[0], p_ndarr.shape()[1], print_msg, file_type);
00453   }
00454 
00455 //--------------------
00456 /// Save shared_ptr< ndarray<const T,2> > in TEXT file WITH NON-CONST
00457   template <typename T>
00458   void save2DArrayInFile(const std::string& fname, const boost::shared_ptr< ndarray<T,2> >& p_ndarr, bool print_msg, FILE_MODE file_type=TEXT)
00459   {  
00460     save2DArrayInFile<T> (fname, p_ndarr->data(), p_ndarr->shape()[0], p_ndarr->shape()[1], print_msg, file_type);
00461   }
00462 
00463 //--------------------
00464 /// Save shared_ptr< ndarray<T,2> > in TEXT file WITH CONST
00465   template <typename T>
00466   void save2DArrayInFile(const std::string& fname, const boost::shared_ptr< ndarray<const T,2> >& p_ndarr, bool print_msg, FILE_MODE file_type=TEXT)
00467   {  
00468     save2DArrayInFile<T> (fname, p_ndarr->data(), p_ndarr->shape()[0], p_ndarr->shape()[1], print_msg, file_type);
00469   }
00470 
00471 //--------------------
00472 /// Save 2-D array in file
00473   template <typename T>
00474   bool save2DArrayInFileForType(PSEvt::Event& evt, const PSEvt::Source& src, const std::string& key, const std::string& fname, bool print_msg, FILE_MODE file_type=TEXT)
00475   {
00476     boost::shared_ptr< ndarray<const T,2> > shp_const = evt.get(src, key);
00477     if ( shp_const.get() ) {
00478         save2DArrayInFile<T> (fname, shp_const, print_msg, file_type);
00479         return true;
00480     }
00481 
00482     boost::shared_ptr< ndarray<T,2> > shp = evt.get(src, key);
00483     if ( shp.get() ) {
00484         save2DArrayInFile<T> (fname, shp, print_msg, file_type);
00485         return true;
00486     }
00487 
00488     return false; 
00489   }
00490 
00491 //--------------------
00492 /// Save 2-D array in event for type in case if key == "Image2D" 
00493   template <typename T>
00494   bool saveImage2DInFileForType(PSEvt::Event& evt, const PSEvt::Source& src, const std::string& key, const std::string& fname, bool print_msg)
00495   {
00496     boost::shared_ptr< CSPadPixCoords::Image2D<T> > shp = evt.get(src, key);
00497     if ( ! shp.get() ) return false; 
00498     if( print_msg ) MsgLog("GlobalMethods::saveImage2DInFileForType", info, "Get image as Image2D<T> from event and save it in file");
00499     shp -> saveImageInFile(fname,0);
00500     return true;
00501   }
00502 
00503 //--------------------
00504 /// Save 1-D array in the calibStore for const T
00505   template <typename T>
00506   void save1DArrayInCalibStore(PSEnv::Env& env, const Pds::Src& src, const std::string& key, const ndarray<const T,1>& data)
00507   {
00508     boost::shared_ptr< ndarray<const T,1> > shp( new ndarray<const T,1>(data) );
00509     env.calibStore().put(shp, src, key);
00510   }
00511 
00512 //--------------------
00513 //--------------------
00514 //--------------------
00515 //--------------------
00516 //--------------------
00517 /// Save N-D array in event for const T
00518   template <typename T, unsigned NDim>
00519   void saveNDArrayInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, const ndarray<const T,NDim>& nda)
00520   {
00521     boost::shared_ptr< ndarray<const T,NDim> > shp( new ndarray<const T,NDim>(nda) );
00522     evt.put(shp, src, key);
00523   }
00524 
00525 
00526 /// Save 1-D array in event for const T
00527   template <typename T>
00528   void save1DArrayInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, const ndarray<const T,1>& data)
00529   {
00530     boost::shared_ptr< ndarray<const T,1> > shp( new ndarray<const T,1>(data) );
00531     evt.put(shp, src, key);
00532   }
00533 
00534 //--------------------
00535 /// Save 2-D array in event for const T
00536   template <typename T>
00537   void save2DArrayInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, const ndarray<const T,2>& data)
00538   {
00539     boost::shared_ptr< ndarray<const T,2> > shp( new ndarray<const T,2>(data) );
00540     evt.put(shp, src, key);
00541   }
00542 
00543 
00544 //--------------------
00545 /// Save 3-D array in event for const T
00546   template <typename T>
00547   void save3DArrayInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, const ndarray<const T,3>& data)
00548   {
00549     boost::shared_ptr< ndarray<const T,3> > shp( new ndarray<const T,3>(data) );
00550     evt.put(shp, src, key);
00551   }
00552 
00553 //--------------------
00554 /// Save 4-D array in event for const T
00555   template <typename T>
00556   void save4DArrayInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, const ndarray<const T,4>& data)
00557   {
00558     boost::shared_ptr< ndarray<const T,4> > shp( new ndarray<const T,4>(data) );
00559     evt.put(shp, src, key);
00560   }
00561 
00562 //--------------------
00563 /// Save 5-D array in event for const T
00564   template <typename T>
00565   void save5DArrayInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, const ndarray<const T,5>& data)
00566   {
00567     boost::shared_ptr< ndarray<const T,5> > shp( new ndarray<const T,5>(data) );
00568     evt.put(shp, src, key);
00569   }
00570 
00571 //--------------------
00572 /// Save 2-D non-const T array in event
00573   template <typename T>
00574   void saveNonConst2DArrayInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, const ndarray<T,2>& data)
00575   {
00576     boost::shared_ptr< ndarray<T,2> > shp( new ndarray<T,2>(data) );
00577     evt.put(shp, src, key);
00578   }
00579 
00580 //-------------------
00581   /**
00582    * @brief Save 3-D array in event, for src and key.
00583    * 
00584    * @param[in]  evt
00585    * @param[in]  src
00586    * @param[in]  key
00587    * @param[in] ndarr
00588    */
00589 
00590   template <typename T>
00591   void save3DArrInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, const ndarray<const T,3>& ndarr)
00592   {
00593       boost::shared_ptr< ndarray<const T,3> > shp( new ndarray<const T,3>(ndarr) );
00594       evt.put(shp, src, key);
00595   }
00596 
00597 //-------------------
00598   /**
00599    * @brief Save N-D array in event, for src and key.
00600    * 
00601    * @param[in]  evt
00602    * @param[in]  src
00603    * @param[in]  key
00604    * @param[in]  arr
00605    * @param[in]  ndarr_pars
00606    * @param[in]  print_bits = 1-warnings
00607    */
00608 
00609   template <typename T, unsigned NDim>
00610   void saveNDArrInEventForTypeNDim(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, T* arr, NDArrPars* ndarr_pars, unsigned print_bits=1)
00611   {
00612       boost::shared_ptr< ndarray<T,NDim> > shp( new ndarray<T,NDim>(arr, ndarr_pars->shape()) );
00613       evt.put(shp, src, key);    
00614   }
00615 
00616 //-------------------
00617 
00618   template <typename T>
00619   void saveNDArrInEvent(PSEvt::Event& evt, const Pds::Src& src, const std::string& key, T* arr, NDArrPars* ndarr_pars, unsigned print_bits=1)
00620   {
00621       if ( print_bits & 1 && ! ndarr_pars->is_set() ) 
00622         MsgLog("saveNDArrInEvent", warning, "NDArrPars are not set for src: " << boost::lexical_cast<std::string>(src) << " key: " << key);
00623 
00624       unsigned ndim = ndarr_pars->ndim();
00625       if ( print_bits & 1 && ndim > 5 ) MsgLog("saveNDArrInEvent", warning, "ndim=" << ndim << " out of the range of implemented ndims [1,5]");
00626       if ( print_bits & 1 && ndim < 1 ) MsgLog("saveNDArrInEvent", warning, "ndim=" << ndim << " out of the range of implemented ndims [1,5]");
00627 
00628       if      (ndim == 2) saveNDArrInEventForTypeNDim<const T,2>(evt, src, key, arr, ndarr_pars, print_bits);
00629       else if (ndim == 3) saveNDArrInEventForTypeNDim<const T,3>(evt, src, key, arr, ndarr_pars, print_bits);
00630       else if (ndim == 4) saveNDArrInEventForTypeNDim<const T,4>(evt, src, key, arr, ndarr_pars, print_bits);
00631       else if (ndim == 5) saveNDArrInEventForTypeNDim<const T,5>(evt, src, key, arr, ndarr_pars, print_bits);
00632       else if (ndim == 1) saveNDArrInEventForTypeNDim<const T,1>(evt, src, key, arr, ndarr_pars, print_bits);
00633   }
00634 
00635 //--------------------
00636 /// Get string of the 2-D array partial data for test print purpose with "const T"
00637   template <typename T>
00638     std::string stringOf2DArrayData(const ndarray<const T,2>& data, std::string comment="",
00639                                   unsigned row_min=0, unsigned row_max=1, 
00640                                   unsigned col_min=0, unsigned col_max=10 )
00641   {
00642       std::stringstream ss;
00643       ss << comment << std::setprecision(3); 
00644           for (unsigned r = row_min; r < row_max; ++ r) {
00645             for (unsigned c = col_min; c < col_max; ++ c ) ss << " " << std::setw(7) << data[r][c]; 
00646             if(row_max > 1) ss << " ...\n";
00647           }
00648       return ss.str();
00649   }
00650 
00651 //--------------------
00652 /// Get string of the 2-D array partial data for test print purpose
00653   template <typename T>
00654     std::string stringOf2DArrayData(const ndarray<T,2>& data, std::string comment="",
00655                                   unsigned row_min=0, unsigned row_max=1, 
00656                                   unsigned col_min=0, unsigned col_max=10 )
00657   {
00658       std::stringstream ss;
00659       ss << comment << std::setprecision(3); 
00660           for (unsigned r = row_min; r < row_max; ++ r) {
00661             for (unsigned c = col_min; c < col_max; ++ c ) ss << " " << std::setw(7) << data[r][c]; 
00662             if(row_max > 1) ss << " ...\n";
00663           }
00664       return ss.str();
00665   }
00666 
00667 //--------------------
00668 /// String parameter s, consisting of values separated by space, is used as a stringstream to fill the output vector v. 
00669   template <typename T>
00670     void parse_string(std::string& s, std::vector<T>& v)
00671   {  
00672     std::stringstream ss(s);
00673     //cout << "parsing string: " << s << endl;
00674     T val;
00675     do { 
00676         ss >> val;
00677         v.push_back(val);
00678         //cout << val << endl;
00679     } while( ss.good() ); 
00680   }
00681 
00682 //--------------------
00683 
00684 // Load ndarray<T,2> from file TEXT fname
00685   template <typename T>
00686   void load2DArrayFromFile(const std::string& fname, const ndarray<T,2>& ndarr, bool print_msg=false, FILE_MODE file_type=TEXT)
00687   {  
00688     // std::ios_base::openmode mode = std::ios_base::out | std::ios_base::binary;
00689     // open file
00690 
00691     std::ifstream in(fname.c_str());   // or: (fname.c_str(), mode), where mode = std::ios::binary; 
00692       if (not in.good()) {
00693         const std::string msg = "Failed to open file: "+fname;
00694         MsgLogRoot(error, msg);
00695         throw std::runtime_error(msg);
00696       }
00697 
00698       if (print_msg) MsgLog("GlobalMethods", info, " load2DArrayFromFile: " << fname);
00699       
00700       // read all numbers
00701       T* it = ndarr.data();
00702       size_t count = 0;
00703       size_t size = ndarr.size();
00704       while(in and count != size) {
00705         in >> *it++;
00706         ++ count;
00707       }
00708       
00709       // check that we read whole array
00710       if (count != size) {
00711         const std::string msg = "File "+fname+" does not have enough data: ";
00712         MsgLogRoot(error, msg);
00713         throw std::runtime_error(msg);
00714       }
00715       
00716       // and no data left after we finished reading
00717       T tmp ;
00718       if ( in >> tmp ) {
00719         const std::string msg = "File "+fname
00720                               + " has extra data; read:" + stringFromUint(count,10,' ') 
00721                               + " expecting:"           + stringFromUint(size,10,' ');
00722         MsgLogRoot(error, msg);
00723         throw std::runtime_error(msg);
00724       }
00725       
00726       in.close();
00727   }
00728 
00729 //--------------------
00730 /// Re-call to pdscalibdata::NDArrIOV1,
00731 /// Save N-D array in file with metadata
00732 
00733   template <typename T, unsigned NDim>
00734     void saveNDArrayInFile(const ndarray<const T,NDim>& nda, const std::string& fname, const std::vector<std::string>& comments = std::vector<std::string>(), const unsigned& print_bits=1)
00735   {
00736     pdscalibdata::NDArrIOV1<T,NDim>::save_ndarray(nda, fname, comments, print_bits);
00737   }
00738 
00739 
00740 //--------------------
00741 /// Save ndarray in file
00742   template <typename T>
00743     void saveNDArrayInFile(const std::string& fname, const T* arr, NDArrPars* ndarr_pars, bool print_msg, FILE_MODE file_type=TEXT,
00744                            const std::vector<std::string>& comments = std::vector<std::string>())
00745   {  
00746     if (fname.empty()) {
00747       MsgLog("GlobalMethods", warning, "The output file name is empty. 2-d array is not saved.");
00748       return;
00749     }
00750 
00751     if( print_msg ) MsgLog("GlobalMethods", info, "Save 2-d array in file " << fname.c_str() << " file type:" << strOfDataTypeAndSize<T>());
00752 
00753     unsigned* shape = ndarr_pars->shape();
00754     unsigned  ndim  = ndarr_pars->ndim();
00755 
00756     unsigned cols = shape[ndim-1];
00757     unsigned rows = (ndim>1) ? ndarr_pars->size()/cols : 1; 
00758 
00759     //======================
00760 
00761     if (file_type == METADTEXT) {
00762 
00763       //std::vector<std::string> comments;
00764       //comments.push_back("PRODUCER   pdscalibdata/GlobalMethods/saveNDArrayInFile");
00765 
00766       if (ndim == 2) {
00767         ndarray<const T,2> nda(arr, shape);
00768         pdscalibdata::NDArrIOV1<T,2>::save_ndarray(nda, fname, comments);
00769       }
00770 
00771       else if (ndim == 3) {
00772         ndarray<const T,3> nda(arr, shape);
00773         pdscalibdata::NDArrIOV1<T,3>::save_ndarray(nda, fname, comments);
00774       }
00775 
00776       else if (ndim == 4) {
00777         ndarray<const T,4> nda(arr, shape);
00778         pdscalibdata::NDArrIOV1<T,4>::save_ndarray(nda, fname, comments);
00779       }
00780 
00781       else if (ndim == 5) {
00782         ndarray<const T,5> nda(arr, shape);
00783         pdscalibdata::NDArrIOV1<T,5>::save_ndarray(nda, fname, comments);
00784       }
00785 
00786       else if (ndim == 1) {
00787         ndarray<const T,1> nda(arr, shape);
00788         pdscalibdata::NDArrIOV1<T,1>::save_ndarray(nda, fname, comments);
00789       }
00790 
00791       else {
00792         if( print_msg ) MsgLog("pdscalibdata/GlobalMethods/saveNDArrayInFile", error, 
00793                                "ndarray of type " << strOfDataTypeAndSize<T>()
00794                                << " Ndim=" << ndim << " can not be saved in file: " << fname.c_str() );         
00795       }
00796 
00797       return;
00798     }
00799 
00800     //======================
00801     if (file_type == TEXT) {
00802         std::ofstream out(fname.c_str()); 
00803         out << std::setprecision(9); // << std::setw(8) << std::setprecision(0) << std::fixed 
00804               for (unsigned r = 0; r != rows; ++r) {
00805                 for (unsigned c = 0; c != cols; ++c) {
00806                   out << arr[r*cols + c] << ' ';
00807                 }
00808                 out << '\n';
00809               }
00810         out.close();
00811         return; 
00812     }
00813 
00814     //======================
00815     if (file_type == BINARY) {
00816         std::ios_base::openmode mode = std::ios_base::out | std::ios_base::binary;
00817         std::ofstream out(fname.c_str(), mode);
00818         //out.write(reinterpret_cast<const char*>(arr), rows*cols*sizeof(T));
00819         for (unsigned r = 0; r != rows; ++r) {
00820           const T* data = &arr[r*cols];
00821           out.write(reinterpret_cast<const char*>(data), cols*sizeof(T));
00822         }
00823         out.close();
00824         return; 
00825     }
00826   }
00827 
00828 
00829 
00830 //--------------------
00831 //--------------------
00832 //--------------------
00833 //--------------------
00834 
00835 } // namespace ImgAlgos
00836 
00837 #endif // IMGALGOS_GLOBALMETHODS_H

Generated on 19 Dec 2016 for PSDMSoftware by  doxygen 1.4.7