My Project
|
00001 /* 00002 $Id: ReadNeXusFile.hh 2247 2011-04-27 05:20:41Z jisuzuki $ 00003 */ 00004 00005 #ifndef READNEXUSFILE 00006 #define READNEXUSFILE 00007 00008 #include <map> 00009 #include "Header.hh" 00010 #include "HeaderBase.hh" 00011 #include "SplitString.hh" 00012 #include "ElementContainer.hh" 00013 #include "NeutronVector.hh" 00014 #include "UInt4Container.hh" 00015 #include "napi.h" 00016 #include "ElementContainerArray.hh" 00017 #include "ElementContainerMatrix.hh" 00018 #include "UInt4ContainerArray.hh" 00019 #include "UInt4ContainerMatrix.hh" 00020 #include "TwoDimElementContainer.hh" 00021 00023 00032 class ReadNeXusFile 00033 { 00034 private: 00035 SplitString *ss; 00036 UInt4 w_handleFlag; 00037 protected: 00038 NXhandle handle; 00039 void OpenNeXusFile( const string &FileName ); 00040 void CloseNeXusFile(); 00041 Int4 CurrentNumber; 00042 00043 public: 00044 ReadNeXusFile( const string &FileName ); 00045 ReadNeXusFile( NXhandle w_handle ); 00046 ~ReadNeXusFile(); 00047 00048 NXhandle PutHandle(){ return handle; } 00049 00050 vector<string> GetGroupInfo(); 00059 vector<string> GetNextEntry(); 00069 vector<Int4> GetInfo(); 00070 Int4 PutCurrentNumber(){ return CurrentNumber; }; 00083 void OpenGroup( const string &GroupName, const string &GroupClass ); 00091 void CloseGroup(){ NXclosegroup( handle ); } 00093 void OpenData( const string &DataSetName ); 00099 void CloseData(){ NXclosedata( handle ); } 00104 void ReadData(const string &Name, UInt4 &i); 00105 void ReadData(const string &Name, Int4 &i); 00106 void ReadData(const string &Name, Double &d); 00107 void ReadData(const string &Name, string &s); 00108 void ReadData(const string &Name, vector<UInt4> &vi); 00109 void ReadData(const string &Name, vector<Int4> &vi); 00110 void ReadData(const string &Name, vector<Double> &vd); 00111 void ReadData(const string &Name, vector<string> &vs); 00112 00113 UInt4 ReadDataUInt4( const string &Name ) { 00114 UInt4 i; 00115 ReadData(Name, i); 00116 return i; 00117 } 00121 Int4 ReadDataInt4( const string &Name ) { 00122 Int4 i; 00123 ReadData(Name, i); 00124 return i; 00125 } 00128 Double ReadDataDouble( const string &Name ) { 00129 Double d; 00130 ReadData(Name, d); 00131 return d; 00132 } 00135 string ReadDataString( const string &Name ) { 00136 string s; 00137 ReadData(Name, s); 00138 return s; 00139 } 00143 vector<Double> ReadDoubleVector( const string &Name ) { 00144 vector<Double> vd; 00145 ReadData(Name, vd); 00146 return vd; 00147 } 00150 vector<Int4> ReadInt4Vector( const string &Name ) { 00151 vector<Int4> vi; 00152 ReadData(Name, vi); 00153 return vi; 00154 } 00157 vector<UInt4> ReadUInt4Vector( const string &Name ) { 00158 vector<UInt4> vi; 00159 ReadData(Name, vi); 00160 return vi; 00161 } 00164 vector<string> ReadStringVector( const string &Name ) { 00165 vector<string> vs; 00166 ReadData(Name, vs); 00167 return vs; 00168 } 00174 HeaderBase ReadHeaderBase( const string &Name ) { 00175 HeaderBase header; 00176 ReadData(Name, header); 00177 return header; 00178 } 00179 ElementContainer ReadElementContainer( const string &Name ) { 00180 ElementContainer EC; 00181 ReadData(Name, EC); 00182 return EC; 00183 } 00184 ElementContainerArray ReadElementContainerArray( const string &Name ) { 00185 ElementContainerArray ECA; 00186 ReadData(Name, ECA); 00187 return ECA; 00188 } 00189 ElementContainerMatrix ReadElementContainerMatrix( const string &Name ) { 00190 ElementContainerMatrix ECM; 00191 ReadData(Name, ECM); 00192 return ECM; 00193 } 00194 UInt4Container ReadUInt4Container( const string &Name ) { 00195 UInt4Container UC; 00196 ReadData(Name, UC); 00197 return UC; 00198 } 00199 UInt4ContainerArray ReadUInt4ContainerArray( const string &Name ) { 00200 UInt4ContainerArray UCA; 00201 ReadData(Name, UCA); 00202 return UCA; 00203 } 00204 UInt4ContainerMatrix ReadUInt4ContainerMatrix( const string &Name ) { 00205 UInt4ContainerMatrix UCM; 00206 ReadData(Name, UCM); 00207 return UCM; 00208 } 00210 00211 00220 template <class T> 00221 void ReadData( const string &Name, T &t ) { 00222 OpenGroup( Name, "NXdata" ); 00223 00224 try { 00225 UInt4 v = GetAttribute2<UInt4>("version"); 00226 00227 if (v==2) { 00228 ReadData2(t); 00229 } else { 00230 std::cerr << "ReadNeXusFile::ReadData(): unsupported version: " 00231 << v << std::endl; 00232 } 00233 } 00234 catch (NXstatus s) { 00235 // no "version" means version1 (old code) 00236 ReadData1(t); 00237 } 00238 00239 CloseGroup(); 00240 } 00241 00242 00251 template <class T> 00252 void ReadData( const string &Name, std::map<string, T> &t ); 00253 00254 00262 template <class T> 00263 void ReadData( const string &Name, std::vector<T *> &t ); 00264 00265 00266 private: 00276 template <class T> 00277 void ReadData2(T &t ) { 00278 t.NXread(*this); 00279 } 00280 00285 template <class T> 00286 void ReadData1( Map<T> &H ) { 00287 std::cout << "CAUTION: ReadNeXusFile::ReadData1(const string &Name, Map<T> &H) shouldn't be called" << std::endl; 00288 } 00289 00294 void ReadData1( StlMapDouble &H ) { 00295 std::cout << "CAUTION: ReadNeXusFile::ReadData1(const string &Name, StlMapDouble &H) shouldn't be called" << std::endl; 00296 } 00297 00298 void ReadData1( HeaderBase &H ); 00299 void ReadData1( ElementContainer &EC ); 00300 void ReadData1( ElementContainerArray &ECA ); 00301 void ReadData1( ElementContainerMatrix &ECM ); 00302 void ReadData1( UInt4Container &UC ); 00303 void ReadData1( UInt4ContainerArray &UCA ); 00304 void ReadData1( UInt4ContainerMatrix &UCM ); 00306 00307 00308 public: 00309 TwoDimElementContainer ReadTwoDimElementContainer( const string &Name ); 00310 00311 private: 00312 ElementContainer ReadElementContainer1( const string &Name ) { 00313 ElementContainer EC; 00314 OpenGroup( Name, "NXdata" ); 00315 ReadData1(EC); 00316 CloseGroup(); 00317 return EC; 00318 } 00322 HeaderBase ReadHeaderBase1( const string &Name ) { 00323 HeaderBase HB; 00324 OpenGroup( Name, "NXdata" ); 00325 ReadData1(HB); 00326 CloseGroup(); 00327 return HB; 00328 } 00332 ElementContainerArray ReadElementContainerArray1( const string &Name ) { 00333 ElementContainerArray ECA; 00334 OpenGroup( Name, "NXdata" ); 00335 ReadData1(ECA); 00336 CloseGroup(); 00337 return ECA; 00338 } 00342 ElementContainerMatrix ReadElementContainerMatrix1( const string &Name ) { 00343 ElementContainerMatrix ECM; 00344 OpenGroup( Name, "NXdata" ); 00345 ReadData1(ECM); 00346 CloseGroup(); 00347 return ECM; 00348 } 00353 UInt4ContainerMatrix ReadUInt4ContainerMatrix1( const string &Name ) { 00354 UInt4ContainerMatrix UCM; 00355 OpenGroup( Name, "NXdata" ); 00356 ReadData1(UCM); 00357 CloseGroup(); 00358 return UCM; 00359 } 00363 UInt4ContainerArray ReadUInt4ContainerArray1( const string &Name ) { 00364 UInt4ContainerArray UCA; 00365 OpenGroup( Name, "NXdata" ); 00366 ReadData1(UCA); 00367 CloseGroup(); 00368 return UCA; 00369 } 00373 UInt4Container ReadUInt4Container1( const string &Name ) { 00374 UInt4Container UC; 00375 OpenGroup( Name, "NXdata" ); 00376 ReadData1(UC); 00377 CloseGroup(); 00378 return UC; 00379 } 00398 template <class T> 00399 T GetAttribute2(const string &Name); 00400 00401 00405 template <class T> 00406 UInt4 GetAttribute3( NXhandle handle, string Name, T *value, 00407 Int4 DataLength, Int4 DataType ) { 00408 return NXgetattr( handle, const_cast<char *>(Name.c_str()), static_cast<void *>(value), 00409 &DataLength, &DataType ); 00410 } 00411 00412 public: 00420 NXstatus GetNextEntry2( char *Name, char *nxclass, int *type) { 00421 return NXgetnextentry(handle, Name, nxclass, type); 00422 } 00423 }; 00424 00426 template <class T> 00427 void ReadNeXusFile:: 00428 ReadData( const string &Name, std::map<string, T> &t ) 00429 { 00430 OpenGroup( Name, "NXdata" ); 00431 00432 NXname _name, _class; 00433 int _id, _status; 00434 00435 std::vector<std::string> keys; 00436 while ((_status=GetNextEntry2(_name, _class, &_id))==1) { 00437 // std::cerr << "NEXTENTRY: " << _name << "," << _class << ", " 00438 // << _id << "," << _status << std::endl; 00439 std::string _s(_name); 00440 ReadData(_s, t[_s]); 00441 keys.push_back(_s); 00442 } 00443 00444 for (typename std::map<std::string, T>::iterator p=t.begin(), 00445 end=t.end();p!=end;++p) { 00446 // if p->first (key) does not exist in keys vector 00447 // then p (keys, val) should be removed 00448 if ((std::find(keys.begin(), keys.end(), p->first))==keys.end()) 00449 t.erase(p); 00450 // is this code really safe? 00451 } 00452 00453 CloseGroup(); 00454 } 00455 00457 template <class T> 00458 void ReadNeXusFile:: 00459 ReadData( const string &Name, std::vector<T *> &t ) 00460 { 00461 OpenGroup( Name, "NXdata" ); 00462 Int4 newsize = ReadDataInt4("size"); 00463 Int4 cursize = t.size(); 00464 00465 for (signed int i=newsize;i<cursize;++i) 00466 delete t[i]; 00467 t.resize(newsize); 00468 for (signed int i=cursize;i<newsize;++i) 00469 t[i] = new T; 00470 00471 UInt4 i=0; 00472 static char index[128]; 00473 for (typename std::vector<T *>::iterator p=t.begin(), 00474 end=t.end();p!=end;++p, ++i) { 00475 sprintf(index, "%s%d", Name.c_str(), i); 00476 ReadData(index, **p); 00477 } 00478 00479 CloseGroup(); 00480 } 00481 00483 template <class T> 00484 T ReadNeXusFile:: 00485 GetAttribute2(const string &Name){ 00486 NXstatus status = 0; 00487 00488 while( status != -1 ){ 00489 NXname AttrName; 00490 Int4 Length; 00491 Int4 Type; 00492 status = NXgetnextattr( handle, AttrName, &Length, &Type ); 00493 //cout << "AttrName = " << AttrName << endl; 00494 string StAttrName = string( AttrName ); 00495 //cout << "StAttrName = " << StAttrName << " " << Name << endl; 00496 if( StAttrName == Name ){ 00497 T val; 00498 00499 GetAttribute3<T>(handle, Name, &val, Length, Type); 00500 // following doesn't work 00501 //NXgetattr( handle, const_cast<char *>(Name.c_str()), (void*)(val), &Length, &Type ); 00502 00503 return val; 00504 } 00505 } 00506 00507 // if attribute is not exist 00508 throw (-1); // NXstatus 00509 } 00510 #endif 00511 00512 00513 /* Test code on Python environment. 00514 r = Neutron.ReadNeXusFile( "nx.nx" ) 00515 00516 vs = r.GetNextEntry() 00517 r.OpenGroup( vs[0], vs[1] ) 00518 00519 vs = r.GetNextEntry() 00520 r.OpenGroup( vs[0], vs[1] ) 00521 00522 vs = r.GetNextEntry() 00523 E = r.ReadElementContainer( vs[0] ) 00524 00525 r.CloseGroup() 00526 r.CloseGroup() 00527 del r 00528 00529 00530 */