00001 00002 #ifndef PDSCALIBDATA_NDARRIOV1_H 00003 #define PDSCALIBDATA_NDARRIOV1_H 00004 00005 //-------------------------------------------------------------------------- 00006 // File and Version Information: 00007 // $Id: NDArrIOV1.h 12297 2016-07-20 00:10:06Z dubrovin@SLAC.STANFORD.EDU $ 00008 // $Revision: 12297 $ 00009 // $HeadURL: file://localhost/reg/g/psdm/svnrepo/psdmrepo/pdscalibdata/tags/V00-05-43/include/NDArrIOV1.h $ 00010 // $Header$ 00011 // $LastChangedDate: 2016-07-19 17:10:06 -0700 (Tue, 19 Jul 2016) $ 00012 // $Date: 2016-07-19 17:10:06 -0700 (Tue, 19 Jul 2016) $ 00013 // 00014 // Author: Mikhail Dubrovin 00015 //------------------------------------------------------------------------ 00016 00017 //----------------- 00018 // C/C++ Headers -- 00019 //----------------- 00020 #include <string> 00021 #include <vector> 00022 #include <iostream> // for cout, puts etc. 00023 00024 //---------------------- 00025 // Base Class Headers -- 00026 //---------------------- 00027 00028 //------------------------------- 00029 // Collaborating Class Headers -- 00030 //------------------------------- 00031 #include "ndarray/ndarray.h" 00032 00033 //------------------------------------ 00034 // Collaborating Class Declarations -- 00035 //------------------------------------ 00036 #include "pdscalibdata/GlobalMethods.h" 00037 00038 // --------------------- 00039 // -- Class Interface -- 00040 // --------------------- 00041 00042 using namespace std; 00043 00044 namespace pdscalibdata { 00045 00046 /** 00047 * @defgroup pdscalibdata pdscalibdata package 00048 * @brief Package pdscalibdata contains modules which retrieves the calibration parameters of all detectors 00049 */ 00050 00051 /** 00052 * @ingroup pdscalibdata 00053 * 00054 * This software was developed for the LCLS project. If you use all or 00055 * part of it, please give an appropriate acknowledgment. 00056 * 00057 * @see 00058 * 00059 * @version $Id: NDArrIOV1.h 12297 2016-07-20 00:10:06Z dubrovin@SLAC.STANFORD.EDU $ 00060 * 00061 * @author Mikhail Dubrovin 00062 * 00063 * 00064 * @anchor interface 00065 * @par<interface> Interface 00066 * 00067 * @li Expected format of the data file with metadata 00068 * @code 00069 * # line of comment always begins with # 00070 * # Mandatory fields to define the ndarray<TYPE,NDIM> and its shape as unsigned shape[NDIM] = {DIM:1,DIM:2,DIM:3} 00071 * # TYPE float 00072 * # NDIM 3 00073 * # DIM:1 3 00074 * # DIM:2 4 00075 * # DIM:3 8 00076 * 00077 * 21757 21769 33464 10769 68489 68561 77637 54810 00078 * ... other data lines 00079 * 21757 21773 33430 10628 68349 68345 77454 54729 00080 * @endcode 00081 * 00082 * @li Includes and typedefs 00083 * @code 00084 * #include "pdscalibdata/NDArrIOV1.h" 00085 * typedef pdscalibdata::NDArrIOV1<float,3> NDAIO; 00086 * @endcode 00087 * 00088 * @li Instatiation 00089 * \n Constractor 0: 00090 * \n Uses file name as input parameter w/o default initialization: 00091 * @code 00092 * std::string fname("path/pedestals/0-end.data"); // mandatory parameter 00093 * unsigned print_bits(0377); // optional parameter 00094 * 00095 * ARRIO* arrio = new ARRIO(fname, print_bits); 00096 * @endcode 00097 * \n 00098 * \n 00099 * \n Constractor 1: 00100 * \n Uses file name, array shape, and single value for default initialization: 00101 * @code 00102 * std::string fname("path/pedestals/0-end.data"); // mandatory parameter 00103 * unsigned shape[] = {2,3,4}; // mandatory parameter 00104 * TYPE val_def = 123; // optional parameter 00105 * unsigned print_bits(0377); // optional parameter 00106 * 00107 * ARRIO* arrio = new ARRIO(fname, shape, data_def, print_bits); 00108 * @endcode 00109 * shape is used for 00110 * \n 1) cross-check of metadata shape from file, 00111 * \n 2) creation of ndarray<TYPE,NDIM> with default parameters if file is missing. 00112 * \n 00113 * \n 00114 * \n Constractor 2: 00115 * \n Uses file name and default ndarray: 00116 * @code 00117 * CalibPars::common_mode_t data_def[] = {1, 50, 10, Size}; 00118 * ndarray<CalibPars::common_mode_t,1> nda = make_ndarray(&data_def[0], 4); 00119 * ARRIO* arrio = new ARRIO(fname, nda, print_bits); 00120 * @endcode 00121 * 00122 * @li Access methods 00123 * @code 00124 * const ndarray<const float,3>& nda = arrio -> get_ndarray(); // returns ndarray 00125 * // or 00126 * const ndarray<const float,3>& nda = arrio -> get_ndarray(fname); // returns ndarray 00127 * std::string& str_status = arrio -> status(); // returns status comment 00128 * @endcode 00129 * 00130 * @li Print methods 00131 * \n File name needs to be provided either in constructor or in the get_ndarray(fname) method. 00132 * @code 00133 * arrio -> print(); // prints recognized templated parameters 00134 * arrio -> print_file(); // prints input file line-by-line 00135 * arrio -> print_ndarray(); // prints ndarray 00136 * @endcode 00137 * 00138 * @li Save ndarray in file 00139 * @code 00140 * NDAIO::save_ndarray(nda, fname); 00141 * @endcode 00142 * or save ndarray in file with additional comments 00143 * @code 00144 * std::vector<std::string> comments; 00145 * comments.push_back("TITLE File to load ndarray of calibration parameters"); 00146 * comments.push_back("EXPERIMENT amo12345"); 00147 * comments.push_back("DETECTOR Camp.0:pnCCD.1"); 00148 * comments.push_back("CALIB_TYPE pedestals"); 00149 * 00150 * unsigned print_bits=1; 00151 * NDAIO::save_ndarray(nda, fname, comments, print_bits); 00152 * @endcode 00153 * where each record in the vector is added to the file header as a commented string. 00154 * The last command saves the file with content 00155 * @code 00156 * # TITLE File to load ndarray of calibration parameters 00157 * # 00158 * # EXPERIMENT amo12345 00159 * # DETECTOR Camp.0:pnCCD.1 00160 * # CALIB_TYPE pedestals 00161 * 00162 * # DATE_TIME 2014-05-06 15:24:10 00163 * # AUTHOR <user-login-name> 00164 * 00165 * # Metadata for ndarray<float,3> 00166 * # TYPE float 00167 * # NDIM 3 00168 * # DIM:0 3 00169 * # DIM:1 4 00170 * # DIM:2 8 00171 * 00172 * 21757 21769 33464 10769 68489 68561 77637 54810 00173 * ... 00174 * 102 40 272 270 194 246 60 118 00175 * @endcode 00176 */ 00177 00178 template <typename TDATA, unsigned NDIM> // stands for something like ndarray<TDATA, NDIM> 00179 class NDArrIOV1 { 00180 00181 static const unsigned c_ndim = NDIM; 00182 00183 public: 00184 00185 typedef TDATA data_t; 00186 typedef unsigned shape_t; 00187 00188 enum STATUS { LOADED=1, DEFAULT, UNREADABLE, UNDEFINED }; 00189 00190 /** 00191 * @brief Three constructors provide different default initialization. 00192 * Each of them create an object which holds the file name and pointer (0 before load) to ndarray. 00193 * File name can be specified later in the get_ndarray(fname) method, but print_file() and print_ndarray() 00194 * methods will complain about missing file name until it is specified. 00195 */ 00196 00197 00198 /** 00199 * @brief Constructor with missing default initialization. Empty ndarray will be returned if constants from file can not be loaded. 00200 * @param[in] fname - std::string file name 00201 * @param[in] print_bits - unsigned bit-word to control verbosity 00202 */ 00203 NDArrIOV1 ( const std::string& fname 00204 , const unsigned print_bits=0377 ); 00205 00206 /** 00207 * @brief Constructor with default ndarray of specified shape filled by a single value. 00208 * @param[in] fname - std::string file name 00209 * @param[in] shape_def - default shape of the ndarray (is used for shape crosscheck at readout and in case of missing file or metadata) 00210 * @param[in] val_def - value to fill all data elements by default(in case of missing file or metadata) 00211 * @param[in] print_bits - unsigned bit-word to control verbosity 00212 */ 00213 NDArrIOV1 ( const std::string& fname 00214 , const shape_t* shape_def 00215 , const TDATA& val_def=TDATA(0) 00216 , const unsigned print_bits=0377 ); 00217 00218 /** 00219 * @brief Constructor with externally defined default ndarray. 00220 * @param[in] fname - std::string file name 00221 * @param[in] nda_def - default ndarray, which will be returned if file is missing 00222 * @param[in] print_bits - unsigned bit-word to control verbosity 00223 */ 00224 NDArrIOV1 ( const std::string& fname 00225 , const ndarray<const TDATA, NDIM>& nda_def 00226 , const unsigned print_bits=0377 ); 00227 00228 /// Destructor 00229 ~NDArrIOV1 (); 00230 00231 /// Returns number of dimensions of ndarray. 00232 unsigned int ndim() const { return NDIM; } 00233 00234 /// Access methods 00235 /// prints recognized templated parameters. 00236 void print(); 00237 00238 /// Prints input file line-by-line. 00239 void print_file(); 00240 00241 /// Loads (if necessary) ndarray from file and print it. 00242 void print_ndarray(); 00243 00244 /// Loads (if necessary) ndarray from file and returns it. 00245 /** 00246 * @param[in] fname std::string file name 00247 */ 00248 ndarray<TDATA, NDIM>& get_ndarray(const std::string& fname = std::string()); 00249 //ndarray<const TDATA, NDIM>& get_ndarray(const std::string& fname = std::string()); 00250 00251 /// Returns string with status of calibration constants. 00252 std::string str_status(); 00253 00254 /// Returns enumerated status of calibration constants. 00255 STATUS status() { return m_status; } 00256 00257 /// Returns string with info about ndarray. 00258 std::string str_ndarray_info(); 00259 00260 /// Returns string of shape. 00261 std::string str_shape(); 00262 00263 /// Static method to save ndarray in file with internal metadata and external comments 00264 /** 00265 * @param[in] nda ndarray to save in file 00266 * @param[in] fname std::string file name to save ndarray 00267 * @param[in] vcoms std::vector<std::string> vector of strings with comments; one-string comment per vector entry 00268 * @param[in] print_bits for output control; 0-print nothing, +1-info about saved files 00269 */ 00270 static void save_ndarray(const ndarray<const TDATA, NDIM>& nda, 00271 const std::string& fname, 00272 const std::vector<std::string>& vcoms = std::vector<std::string>(), 00273 const unsigned& print_bits=0377); 00274 00275 protected: 00276 00277 private: 00278 00279 /// Data members 00280 00281 ndarray<TDATA, NDIM>* p_nda; 00282 00283 std::string m_fname; 00284 TDATA m_val_def; 00285 const ndarray<const TDATA, NDIM> m_nda_def; 00286 ndarray<TDATA, NDIM> m_nda_empty; 00287 unsigned m_print_bits; 00288 unsigned m_count_str_data; 00289 unsigned m_count_str_comt; 00290 unsigned m_count_data; 00291 00292 unsigned m_ctor; 00293 unsigned m_ndim; 00294 size_t m_size; 00295 shape_t m_shape[NDIM]; 00296 std::string m_str_type; 00297 DATA_TYPE m_enum_type; 00298 STATUS m_status; 00299 00300 TDATA* p_data; 00301 00302 /// static method returns class name for MsgLog 00303 static std::string __name__(){ return std::string("NDArrIOV1"); } 00304 00305 /// member data common initialization in constructors 00306 void init(); 00307 00308 /// loads metadata and ndarray<TYPE,NDIM> from file 00309 void load_ndarray(); 00310 00311 /// true if the file name non empty anf file is readable 00312 bool file_is_available(); 00313 00314 /// parser for comment lines and metadata from file with ndarray 00315 /** 00316 * @param[in] str one string of comments from file 00317 */ 00318 void parse_str_of_comment(const std::string& str); 00319 00320 /// creates ndarray, begins to fill data from the 1st string and reads data by the end 00321 /** 00322 * @param[in] in input file stream 00323 * @param[in] str 1st string of the data 00324 */ 00325 void load_data(std::ifstream& in, const std::string& str); 00326 00327 /// creates ndarray<TYPE,NDIM> with shape from constructor parameter or metadata. 00328 /** 00329 * @param[in] fill_def if true - fills ndarray with default values 00330 */ 00331 void create_ndarray(const bool& fill_def=false); 00332 00333 /// Copy constructor and assignment are disabled by default 00334 NDArrIOV1 ( const NDArrIOV1& ) ; 00335 NDArrIOV1& operator = ( const NDArrIOV1& ) ; 00336 }; 00337 00338 } // namespace pdscalibdata 00339 00340 #endif // PDSCALIBDATA_NDARRIOV1_H