My Project
ReadNeXusFile.hh
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  */
 All Classes Functions Variables Friends