00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "pdscalibdata/NDArrIOV1.h"
00013
00014
00015
00016
00017 #include <algorithm>
00018 #include <stdexcept>
00019 #include <fstream>
00020 #include <sstream>
00021 #include <stdlib.h>
00022 #include <cstring>
00023 #include <stdint.h>
00024
00025
00026
00027
00028 #include "MsgLogger/MsgLogger.h"
00029
00030 namespace pdscalibdata {
00031
00032
00033
00034 template <typename TDATA, unsigned NDIM>
00035 NDArrIOV1<TDATA, NDIM>::NDArrIOV1 ( const std::string& fname
00036 , const unsigned print_bits )
00037 : p_nda(0)
00038 , m_fname(fname)
00039 , m_val_def(0)
00040 , m_nda_def(ndarray<const TDATA, NDIM>())
00041 , m_print_bits(print_bits)
00042 , m_ctor(0)
00043 {
00044 init();
00045 m_size = 0;
00046 }
00047
00048
00049
00050 template <typename TDATA, unsigned NDIM>
00051 NDArrIOV1<TDATA, NDIM>::NDArrIOV1 ( const std::string& fname
00052 , const shape_t* shape_def
00053 , const TDATA& val_def
00054 , const unsigned print_bits )
00055 : p_nda(0)
00056 , m_fname(fname)
00057 , m_val_def(val_def)
00058 , m_nda_def(ndarray<const TDATA, NDIM>())
00059 , m_print_bits(print_bits)
00060 , m_ctor(1)
00061 {
00062 init();
00063 std::memcpy (&m_shape[0], shape_def, c_ndim*sizeof(shape_t));
00064
00065
00066
00067 }
00068
00069
00070
00071 template <typename TDATA, unsigned NDIM>
00072 NDArrIOV1<TDATA, NDIM>::NDArrIOV1 ( const std::string& fname
00073 , const ndarray<const TDATA, NDIM>& nda_def
00074 , const unsigned print_bits )
00075 : p_nda(0)
00076 , m_fname(fname)
00077 , m_val_def(0)
00078 , m_nda_def(nda_def)
00079 , m_print_bits(print_bits)
00080 , m_ctor(2)
00081 {
00082 init();
00083 m_size = nda_def.size();
00084 std::memcpy (&m_shape[0], nda_def.shape(), c_ndim*sizeof(shape_t));
00085
00086 }
00087
00088
00089
00090 template <typename TDATA, unsigned NDIM>
00091 NDArrIOV1<TDATA, NDIM>::~NDArrIOV1()
00092 {
00093 if(m_print_bits & 2) MsgLog(__name__(), info, "DESTRUCTOR is called for ctor:" << m_ctor << ", fname=" << m_fname);
00094 delete p_nda;
00095 }
00096
00097
00098
00099 template <typename TDATA, unsigned NDIM>
00100 void NDArrIOV1<TDATA, NDIM>::init()
00101 {
00102 if( m_print_bits & 2 ) {
00103 MsgLog(__name__(), info, "ctor:" << m_ctor << ", fname=" << m_fname);
00104 print();
00105 }
00106 m_status = NDArrIOV1<TDATA, NDIM>::UNDEFINED;
00107 }
00108
00109
00110
00111 template <typename TDATA, unsigned NDIM>
00112 void NDArrIOV1<TDATA, NDIM>::load_ndarray()
00113 {
00114
00115 if ((!file_is_available()) && m_ctor>0) {
00116 if( m_print_bits & 4 ) MsgLog(__name__(), warning, "Use default calibration parameters.");
00117 create_ndarray(true);
00118 m_status = NDArrIOV1<TDATA, NDIM>::DEFAULT;
00119 return;
00120 }
00121
00122 if( m_print_bits & 1 ) MsgLog(__name__(), info, "Load file \"" << m_fname << "\"");
00123
00124 m_count_str_data = 0;
00125 m_count_str_comt = 0;
00126 m_count_data = 0;
00127
00128
00129 std::ifstream in(m_fname.c_str());
00130 if (not in.good()) {
00131 if(m_print_bits) MsgLog(__name__(), error, "Failed to open file: \"" + m_fname + "\"");
00132 m_status = NDArrIOV1<TDATA, NDIM>::UNREADABLE;
00133 return;
00134 }
00135
00136
00137 std::string str;
00138 while(getline(in,str)) {
00139
00140
00141
00142 if(str[0] == '#') parse_str_of_comment(str.substr(1));
00143
00144
00145 else if (str.find_first_not_of(" ")==string::npos) continue;
00146
00147
00148 else load_data(in,str);
00149 }
00150
00151
00152 in.close();
00153 m_status = NDArrIOV1<TDATA, NDIM>::LOADED;
00154 }
00155
00156
00157
00158 template <typename TDATA, unsigned NDIM>
00159 std::string NDArrIOV1<TDATA, NDIM>::str_status()
00160 {
00161 if (m_status == NDArrIOV1<TDATA, NDIM>::LOADED) return std::string("loaded from file");
00162 else if (m_status == NDArrIOV1<TDATA, NDIM>::DEFAULT) return std::string("used default");
00163 else if (m_status == NDArrIOV1<TDATA, NDIM>::UNREADABLE) return std::string("file is unreadable");
00164 else if (m_status == NDArrIOV1<TDATA, NDIM>::UNDEFINED) return std::string("undefined...");
00165 else return std::string("unknown...");
00166 }
00167
00168
00169
00170 template <typename TDATA, unsigned NDIM>
00171 bool NDArrIOV1<TDATA, NDIM>::file_is_available()
00172 {
00173 if(m_fname.empty()) {
00174 if( m_print_bits & 4 ) MsgLog(__name__(), warning, "File name IS EMPTY!");
00175 return false;
00176 }
00177
00178 std::ifstream file(m_fname.c_str());
00179 if(!file.good()) {
00180 if( m_print_bits & 8 ) MsgLog(__name__(), warning, "File: " << m_fname << " DOES NOT EXIST!");
00181 return false;
00182 }
00183 file.close();
00184 return true;
00185 }
00186
00187
00188
00189 template <typename TDATA, unsigned NDIM>
00190 void NDArrIOV1<TDATA, NDIM>::parse_str_of_comment(const std::string& str)
00191 {
00192 m_count_str_comt ++;
00193
00194
00195 std::string field;
00196 std::stringstream ss(str);
00197
00198 ss >> field;
00199
00200 if (field=="DTYPE") {
00201 ss >> m_str_type;
00202 m_enum_type = enumDataTypeForString(m_str_type);
00203
00204 if( m_print_bits & 32 )
00205 if (m_enum_type != enumDataType<TDATA>()) {
00206 std::stringstream smsg;
00207 smsg << "(enum) DTYPE in file metadata (" << strDataTypeForEnum(m_enum_type)
00208 << ") is different from expected (" << strDataTypeForEnum(enumDataType<TDATA>()) << ")";
00209 MsgLog(__name__(), warning, smsg.str());
00210 }
00211 }
00212
00213 else if (field=="NDIM") {
00214 ss >> m_ndim;
00215 if (m_ndim != ndim()) {
00216 std::stringstream smsg;
00217 smsg << "NDIM in file metadata: " << m_ndim
00218 << " is different from declaration: " << ndim();
00219 MsgLog(__name__(), warning, smsg.str());
00220
00221 }
00222 }
00223
00224 else if (field.substr(0,4)=="DIM:") {
00225
00226 int dim = atoi(&field[4]);
00227 shape_t val;
00228 ss >> val;
00229
00230 if (m_ctor == 0) {
00231 m_shape[dim] = val;
00232 m_size *= val;
00233
00234 }
00235 else if (m_shape[dim] !=val) {
00236 std::stringstream smsg;
00237 smsg << "NDArray metadata shape field " << field
00238 << " = " << val
00239 << " is different from expected " << m_shape[dim]
00240 << " in file " << m_fname
00241 << "\nCheck that calibration file has expected shape and data...";
00242 MsgLog(__name__(), warning, smsg.str());
00243
00244 }
00245 }
00246
00247 else
00248
00249 return;
00250 }
00251
00252
00253
00254 template <typename TDATA, unsigned NDIM>
00255 void NDArrIOV1<TDATA, NDIM>::create_ndarray(const bool& fill_def)
00256 {
00257 if (p_nda) delete p_nda;
00258
00259
00260
00261 p_nda = new ndarray<TDATA, NDIM>(m_shape);
00262 p_data = p_nda->data();
00263 m_size = p_nda->size();
00264
00265 if (m_ctor>0 && fill_def) {
00266 if (m_ctor==2) std::memcpy (p_data, m_nda_def.data(), m_size*sizeof(TDATA));
00267 else if (m_ctor==1) std::fill_n (p_data, m_size, m_val_def);
00268 else return;
00269 }
00270 if( m_print_bits & 16 ) MsgLog(__name__(), info, "Created ndarray of the shape=(" << str_shape() << ")");
00271 if( m_print_bits & 32 ) MsgLog(__name__(), info, "Created ndarray: " << *p_nda);
00272 }
00273
00274
00275
00276 template <typename TDATA, unsigned NDIM>
00277 void NDArrIOV1<TDATA, NDIM>::load_data(std::ifstream& in, const std::string& str)
00278 {
00279 if (! m_count_str_data++) create_ndarray();
00280
00281
00282 TDATA val;
00283 TDATA* it=p_data;
00284
00285 std::stringstream ss(str);
00286 while (ss >> val and m_count_data != m_size) {
00287 *it++ = val;
00288 ++m_count_data;
00289
00290 }
00291
00292
00293 while(in >> val and m_count_data != m_size) {
00294 *it++ = val;
00295 ++m_count_data;
00296
00297 }
00298
00299
00300 if (m_count_data != m_size) {
00301 std::stringstream ss;
00302 ss << "NDArray file:\n " << m_fname << "\n does not have enough data: "
00303 << "read " << m_count_data << " numbers, expecting " << m_size;
00304
00305 if( ndim()>1 ) throw std::runtime_error(ss.str());
00306 }
00307
00308
00309 if ( in >> val ) {
00310 ++ m_count_data;
00311 std::stringstream ss;
00312 ss << "NDArray file:\n " << m_fname << "\n has extra data: "
00313 << "read " << m_count_data << " numbers, expecting " << m_size;
00314 MsgLog(__name__(), warning, ss.str());
00315 if( ndim()>1 ) throw std::runtime_error(ss.str());
00316 }
00317 }
00318
00319
00320
00321 template <typename TDATA, unsigned NDIM>
00322
00323 ndarray<TDATA, NDIM>&
00324 NDArrIOV1<TDATA, NDIM>::get_ndarray(const std::string& fname)
00325 {
00326 if ( (!fname.empty()) && fname != m_fname) {
00327 m_fname = fname;
00328 load_ndarray();
00329 }
00330
00331 if (!p_nda) load_ndarray();
00332 if (!p_nda) {
00333 if(m_print_bits) MsgLog(__name__(), error, "ndarray IS NOT LOADED! Check file: \"" << m_fname <<"\"");
00334 return m_nda_empty;
00335 }
00336
00337
00338
00339 return *p_nda;
00340 }
00341
00342
00343
00344 template <typename TDATA, unsigned NDIM>
00345 void NDArrIOV1<TDATA, NDIM>::print()
00346 {
00347 std::stringstream ss;
00348 ss << "print()"
00349 << "\n Constructor # " << m_ctor
00350 << "\n Number of dimensions : " << ndim()
00351 << "\n Data type and size : " << strOfDataTypeAndSize<TDATA>()
00352 << "\n Enumerated data type : " << enumDataType<TDATA>()
00353 << "\n String data type : " << strDataType<TDATA>()
00354 << '\n';
00355 MsgLog(__name__(), info, ss.str());
00356 }
00357
00358
00359
00360 template <typename TDATA, unsigned NDIM>
00361 void NDArrIOV1<TDATA, NDIM>::print_file()
00362 {
00363 if (! file_is_available() ) {
00364 MsgLog(__name__(), warning, "print_file() : file " << m_fname << " is not available!");
00365 return;
00366 }
00367
00368 MsgLog(__name__(), info, "print_file()\nContent of the file: " << m_fname);
00369
00370
00371 std::ifstream in(m_fname.c_str());
00372 if (not in.good()) { MsgLog(__name__(), error, "Failed to open file: "+m_fname); return; }
00373
00374
00375
00376
00377
00378 std::string str;
00379 while(getline(in,str)) cout << str << '\n';
00380 cout << '\n';
00381
00382 in.close();
00383 }
00384
00385
00386
00387 template <typename TDATA, unsigned NDIM>
00388 void NDArrIOV1<TDATA, NDIM>::print_ndarray()
00389 {
00390
00391 if (! p_nda) load_ndarray();
00392 if (! p_nda) return;
00393
00394 std::stringstream smsg;
00395 smsg << "Print ndarray<" << strDataType<TDATA>()
00396 << "," << ndim()
00397 << "> of size=" << p_nda->size()
00398 << ":\n" << *p_nda;
00399 MsgLog(__name__(), info, smsg.str());
00400 }
00401
00402
00403
00404 template <typename TDATA, unsigned NDIM>
00405 std::string NDArrIOV1<TDATA, NDIM>::str_ndarray_info()
00406 {
00407
00408 if (! p_nda) load_ndarray();
00409 if (! p_nda) return std::string("ndarray is non-accessible...");
00410
00411 std::stringstream smsg;
00412 smsg << "ndarray<" << std::setw(8) << std::left << strDataType<TDATA>()
00413 << "," << ndim()
00414 << "> of size=" << p_nda->size()
00415 << ":";
00416 TDATA* it = p_nda->data();
00417 for( unsigned i=0; i<min(size_t(10),p_nda->size()); i++ ) smsg << " " << *it++; smsg << " ...";
00418
00419 return smsg.str();
00420 }
00421
00422
00423
00424 template <typename TDATA, unsigned NDIM>
00425 std::string NDArrIOV1<TDATA, NDIM>::str_shape()
00426 {
00427 std::stringstream smsg;
00428 for( unsigned i=0; i<ndim(); i++ ) {
00429 smsg << m_shape[i]; if (i<ndim()-1) smsg << ", ";
00430 }
00431 return smsg.str();
00432 }
00433
00434
00435
00436 template <typename TDATA, unsigned NDIM>
00437 void NDArrIOV1<TDATA, NDIM>::save_ndarray(const ndarray<const TDATA, NDIM>& nda,
00438 const std::string& fname,
00439 const std::vector<std::string>& vcoms,
00440 const unsigned& print_bits)
00441 {
00442 const unsigned ndim = NDIM;
00443 std::string str_dtype = strDataType<TDATA>();
00444 std::stringstream sstype; sstype << "ndarray<" << str_dtype
00445 << "," << ndim << ">";
00446
00447 if (print_bits & 1) {
00448 std::stringstream smsg;
00449 smsg << "Save " << sstype.str()
00450 << " of size=" << nda.size()
00451 << " in file: " << fname;
00452 MsgLog(__name__(), info, smsg.str());
00453 }
00454
00455
00456 std::ofstream out(fname.c_str());
00457 if (not out.good()) {
00458 if(print_bits) MsgLog(__name__(), error, "Failed to open output file: " + fname);
00459 return;
00460 }
00461
00462
00463 if (!vcoms.empty()) {
00464 for(vector<string>::const_iterator it = vcoms.begin(); it != vcoms.end(); it++)
00465 out << "# " << *it << '\n';
00466 out << '\n';
00467 }
00468
00469
00470 out << "# DATE_TIME " << strTimeStamp() << '\n';
00471 out << "# AUTHOR " << strEnvVar("LOGNAME") << '\n';
00472 out << '\n';
00473
00474
00475 out << "# Metadata for " << sstype.str() << '\n';
00476 out << "# DTYPE " << str_dtype << '\n';
00477 out << "# NDIM " << ndim << '\n';
00478
00479 for(unsigned i=0; i<ndim; i++) out << "# DIM:" << i << " " << nda.shape()[i] << '\n';
00480 out << '\n';
00481
00482
00483 unsigned nmax_in_line = (ndim>1) ? nda.shape()[ndim-1] : 10;
00484 unsigned count_in_line=0;
00485
00486 typename ndarray<const TDATA, NDIM>::iterator it = nda.begin();
00487 for (; it!=nda.end(); ++it) {
00488 out << std::setw(10) << *it << " ";
00489 if( ++count_in_line < nmax_in_line) continue;
00490 count_in_line = 0;
00491 out << '\n';
00492 }
00493
00494
00495 out.close();
00496 }
00497
00498
00499
00500 }
00501
00502
00503
00504
00505
00506 template class pdscalibdata::NDArrIOV1<int,1>;
00507 template class pdscalibdata::NDArrIOV1<unsigned,1>;
00508 template class pdscalibdata::NDArrIOV1<unsigned short,1>;
00509 template class pdscalibdata::NDArrIOV1<float,1>;
00510 template class pdscalibdata::NDArrIOV1<double,1>;
00511 template class pdscalibdata::NDArrIOV1<int16_t,1>;
00512 template class pdscalibdata::NDArrIOV1<uint8_t,1>;
00513
00514 template class pdscalibdata::NDArrIOV1<int,2>;
00515 template class pdscalibdata::NDArrIOV1<unsigned,2>;
00516 template class pdscalibdata::NDArrIOV1<unsigned short,2>;
00517 template class pdscalibdata::NDArrIOV1<float,2>;
00518 template class pdscalibdata::NDArrIOV1<double,2>;
00519 template class pdscalibdata::NDArrIOV1<int16_t,2>;
00520 template class pdscalibdata::NDArrIOV1<uint8_t,2>;
00521
00522 template class pdscalibdata::NDArrIOV1<int,3>;
00523 template class pdscalibdata::NDArrIOV1<unsigned,3>;
00524 template class pdscalibdata::NDArrIOV1<unsigned short,3>;
00525 template class pdscalibdata::NDArrIOV1<float,3>;
00526 template class pdscalibdata::NDArrIOV1<double,3>;
00527 template class pdscalibdata::NDArrIOV1<int16_t,3>;
00528 template class pdscalibdata::NDArrIOV1<uint8_t,3>;
00529
00530 template class pdscalibdata::NDArrIOV1<int,4>;
00531 template class pdscalibdata::NDArrIOV1<unsigned,4>;
00532 template class pdscalibdata::NDArrIOV1<unsigned short,4>;
00533 template class pdscalibdata::NDArrIOV1<float,4>;
00534 template class pdscalibdata::NDArrIOV1<double,4>;
00535 template class pdscalibdata::NDArrIOV1<int16_t,4>;
00536 template class pdscalibdata::NDArrIOV1<uint8_t,4>;
00537
00538 template class pdscalibdata::NDArrIOV1<int,5>;
00539 template class pdscalibdata::NDArrIOV1<unsigned,5>;
00540 template class pdscalibdata::NDArrIOV1<unsigned short,5>;
00541 template class pdscalibdata::NDArrIOV1<float,5>;
00542 template class pdscalibdata::NDArrIOV1<double,5>;
00543 template class pdscalibdata::NDArrIOV1<int16_t,5>;
00544 template class pdscalibdata::NDArrIOV1<uint8_t,5>;
00545
00546
00547
00548