00001 #ifndef IMGALGOS_GLOBALMETHODS_H
00002 #define IMGALGOS_GLOBALMETHODS_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <string>
00018 #include <fstream>
00019 #include <iomanip>
00020 #include <sstream>
00021 #include <iostream>
00022 #include <math.h>
00023
00024
00025
00026
00027
00028
00029
00030
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
00042
00043
00044
00045
00046
00047 #ifndef int_p_NULL
00048 #define png_infopp_NULL (png_infopp)NULL
00049 #define int_p_NULL (int*)NULL
00050 #endif
00051
00052 #include <boost/gil/gil_all.hpp>
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #ifndef BOOST_GIL_NO_IO
00065
00066
00067 #include <boost/gil/extension/io/png_dynamic_io.hpp>
00068
00069 #endif
00070
00071
00072
00073
00074 #include "pdsdata/xtc/Src.hh"
00075
00076
00077
00078
00079
00080 namespace ImgAlgos {
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 using namespace boost::gil;
00119 using namespace std;
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
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
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
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
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");
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);
00225 unsigned eventCounterSinceConfigure(PSEvt::Event& evt);
00226 void printSizeOfTypes();
00227
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 );
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
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
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
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
00314 return true;
00315 }
00316 return false;
00317 }
00318
00319
00320
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
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
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
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
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
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
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);
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
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
00441
00442
00443
00444
00445
00446
00447
00448
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
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
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
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
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
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
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
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
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
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
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
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
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
00583
00584
00585
00586
00587
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
00600
00601
00602
00603
00604
00605
00606
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
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
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
00669 template <typename T>
00670 void parse_string(std::string& s, std::vector<T>& v)
00671 {
00672 std::stringstream ss(s);
00673
00674 T val;
00675 do {
00676 ss >> val;
00677 v.push_back(val);
00678
00679 } while( ss.good() );
00680 }
00681
00682
00683
00684
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
00689
00690
00691 std::ifstream in(fname.c_str());
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
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
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
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
00731
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
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
00764
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);
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
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 }
00836
00837 #endif // IMGALGOS_GLOBALMETHODS_H