My Project
|
00001 /* 00002 $Id: ElementContainer.hh 2295 2011-08-10 02:57:13Z jisuzuki $ 00003 */ 00004 00005 00006 #ifndef ELEMENTCONTAINER 00007 #define ELEMENTCONTAINER 00008 00009 #include <algorithm> 00010 #include <boost/serialization/serialization.hpp> 00011 #include <boost/serialization/string.hpp> 00012 #include <napi.h> 00013 00014 #include "Header.hh" 00015 #include "HeaderBase.hh" 00016 #include "CppToPython.hh" 00017 #include "StlMapDouble.hh" 00018 #include "NeutronWriteBinaryData.hh" 00019 #include "NeutronReadBinaryData.hh" 00020 #include "SimpleIOVectorToTextFile.hh" 00021 00023 00058 class ElementContainer 00059 { 00060 private: 00061 00062 // If the vector named "Error-key" in the argument contains 00063 // a negative value element, this method returns "true". 00064 bool IsMaskData( vector<Double> &v, const vector<Double> *vp ); 00065 00066 00067 00068 //vector< vector< Double >* > v; 00069 //vector< string > s; 00070 StlMapDouble M; 00076 HeaderBase *header; 00077 HeaderBase *UnitHeader; 00078 00079 string Xkey, Ykey, Ekey; 00080 00081 void _Add( const string &Key, vector< Double > &value, string Unit="None" ) 00082 { M.Add( Key, value ); UnitHeader -> Add( Key, Unit ); } 00083 00084 00092 void Formatter2( 00093 const std::vector<Double> *rx, const std::vector<Double> *&ry, 00094 const std::vector<Double> *&re); 00095 00096 friend class boost::serialization::access; 00100 template <class Archive> 00101 void serialize(Archive &ar, const unsigned int ver); 00102 00103 friend class WriteNeXusFile; 00107 template <class Write> 00108 void NXwrite(Write &W) const ; 00109 00110 friend class ReadNeXusFile; 00114 template <class Read> 00115 void NXread(Read &R) ; 00116 00117 protected: 00118 00119 public: 00120 ElementContainer(); 00125 ElementContainer( const HeaderBase &Header ); 00131 ElementContainer( const ElementContainer &ob ); 00134 ~ElementContainer(); 00137 ElementContainer &operator=( const ElementContainer &ob ); 00140 ElementContainer &operator+=(const ElementContainer &r ); 00143 ElementContainer &MaskedPlus(const ElementContainer &r ); 00144 ElementContainer &MaskedSub( const ElementContainer &r ); 00145 ElementContainer &MaskedMul( const ElementContainer &r ); 00146 ElementContainer &MaskedDiv( const ElementContainer &r ); 00147 00148 00149 ElementContainer &operator+=( const std::pair<Double, Double> &r ); 00152 ElementContainer &operator+=( const Double r ) { 00153 return *this += std::make_pair(r, 0.0); 00154 } 00157 ElementContainer operator+(const ElementContainer &r ) const { 00158 ElementContainer result(*this); 00159 return result += r; 00160 } 00166 ElementContainer operator+(const std::pair<Double, Double> &r ) const { 00167 ElementContainer result(*this); 00168 return result += r; 00169 } 00172 ElementContainer operator+(const Double r ) const { 00173 ElementContainer result(*this); 00174 return result += r; 00175 } 00179 ElementContainer &operator-=(const ElementContainer &r ); 00182 ElementContainer &operator-=( const std::pair<Double, Double> &r ); 00185 ElementContainer &operator-=( const Double r ) { 00186 return *this -= std::make_pair(r, 0.0); 00187 } 00190 ElementContainer operator-( ElementContainer &r ) const { 00191 ElementContainer result(*this); 00192 return result -= r; 00193 } 00196 ElementContainer operator-(const std::pair<Double, Double> &r ) const { 00197 ElementContainer result(*this); 00198 return result -= r; 00199 } 00202 ElementContainer operator-(const Double r ) const { 00203 ElementContainer result(*this); 00204 return result -= r; 00205 } 00209 ElementContainer &operator*=(const ElementContainer &r ); 00212 ElementContainer &operator*=( const std::pair<Double, Double> &r ); 00215 ElementContainer &operator*=( const Double r ) { 00216 return *this *= std::make_pair(r, 0.0); 00217 } 00220 ElementContainer operator*( ElementContainer &r ) const { 00221 ElementContainer result(*this); 00222 return result *= r; 00223 } 00226 ElementContainer operator*(const std::pair<Double, Double> &r ) const { 00227 ElementContainer result(*this); 00228 return result *= r; 00229 } 00232 ElementContainer operator*(const Double r ) const { 00233 ElementContainer result(*this); 00234 return result *= r; 00235 } 00239 ElementContainer &operator/=(const ElementContainer &r ); 00242 ElementContainer &operator/=( const std::pair<Double, Double> &r ); 00245 ElementContainer &operator/=( const Double r ) { 00246 return *this /= std::make_pair(r, 0.0); 00247 } 00250 ElementContainer operator/( ElementContainer &r ) const { 00251 ElementContainer result(*this); 00252 return result /= r; 00253 } 00260 ElementContainer operator/(const std::pair<Double, Double> &r ) const { 00261 ElementContainer result(*this); 00262 return result /= r; 00263 } 00266 ElementContainer operator/(const Double r ) const { 00267 ElementContainer result(*this); 00268 return result /= r; 00269 } 00274 ElementContainer ReBin( ElementContainer &E, string &Key ){return ReBin( E.Put( Key ) );} 00283 ElementContainer ReBin( const vector<Double> &v ); 00293 ElementContainer Binning( const vector<Double> &v ); 00300 ElementContainer Binning( ElementContainer &E, string &Key ) 00301 {return Binning( E.Put( Key ) );} 00302 00303 ElementContainer Averaging( const vector<Double> &v ); 00310 ElementContainer Averaging( ElementContainer &E, string &Key ) 00311 {return Averaging( E.Put( Key ) );} 00312 00313 00314 void SetKeys( const string &X, const string &Y, const string &E ); 00325 const string &PutXKey() const { return Xkey; } 00328 const string &PutYKey() const { return Ykey; } 00331 const string &PutEKey() const { return Ekey; } 00334 vector<Double> PutX(); 00337 vector<Double> PutY(); 00340 vector<Double> PutE(); 00343 PyObject *PutXList(){ return PutList( PutXKey() ); } 00346 PyObject *PutYList(){ return PutList( PutYKey() ); } 00349 PyObject *PutEList(){ return PutList( PutEKey() ); } 00352 UInt4 PutTableSize() const { return M.Size(); } 00354 UInt4 PutSize() const { return PutTableSize(); } 00356 UInt4 PutSize( UInt4 IndexNumber ) const { return M(IndexNumber) -> size(); } 00358 UInt4 PutSize( const string &Key ) const { return M.Size(Key); } 00364 Int8 PutIndexNumber( const string &Key ){return M.PutIndexNumber( Key );} 00371 string PutName( UInt4 IndexNumber ); 00372 //{ return (M.PutKeyList())[IndexNumber]; } 00375 vector<string> PutKeys(); 00376 PyObject *PutKeysList(); 00377 00378 HeaderBase PutUnitHeader(){return *UnitHeader;} 00379 HeaderBase PutHeader(){return *header;} 00390 HeaderBase *PutHeaderPointer(){ return header; } 00391 void InputUnitHeader( const HeaderBase &uHeader ); 00392 void InputHeader( const HeaderBase &Header ); 00400 void ReSetUnit( string key, string unit ){ UnitHeader->OverWrite( key,unit); } 00401 00402 void DumpKey(); 00406 void Add( const string &Key, vector< Double > value, const string &Unit="None" ); 00413 void Add( const string &Key, vector< Float > value, const string &Unit="None" ); 00420 void Add( const string &Key, vector< UInt4 > value, const string &Unit="None" ); 00427 void Add( const string &Key, vector< UInt2 > value, const string &Unit="None" ); 00434 void Add( const string &Key, PyObject *value, const string &Unit="None" ); 00441 void Add( const string &Key, Double *&Array, UInt4 ArraySize, const string &Unit="None" ); 00447 void Add( const string &Key, Float *&Array, UInt4 ArraySize, const string &Unit="None" ); 00453 void Add( const string &Key, UInt4 *&Array, UInt4 ArraySize, const string &Unit="None" ); 00459 void Add( const string &Key, UInt2 *&Array, UInt4 ArraySize, const string &Unit="None" ); 00466 void AddBlankVector( const string &Key, UInt4 Size=0, const string &Unit="None" ); 00476 vector<Double> Find( const string &Key ){ return Put(Key); } 00479 vector<Double> Find( UInt4 IndexNumber ){ return Put(IndexNumber); } 00482 Double Find( const string &Key, UInt4 Index ){return ( Put(Key) )[Index]; } 00485 vector<Double> Put( UInt4 IndexNumber ){return M.Put( IndexNumber );} 00487 vector<Double> Put( const string &Key ){return M.Put( Key );} 00489 Double Put( const string &Key, UInt4 Index ){ return Find(Key,Index); } 00492 string PutUnit( const string &Key ) const; 00493 void SetUnit( const string &Key, const string &NewUnit ); 00494 00495 PyObject *PutList( const string &Key ){return __gCppToPython.VectorDoubleToList( Put( Key ) );} 00506 vector<Double> ReduceColumn( const string &Key ); 00507 PyObject *ReduceColumnList( const string &Key ){return __gCppToPython. 00508 VectorDoubleToList( ReduceColumn( Key ) ); 00509 } 00510 00511 UInt4 CheckKey( const string &Key ){return M.CheckKey( Key );} 00523 void Copy( const string &Old, const string &New ); 00527 void Remove( const string &Key ); 00530 void Replace( const string &Key, const vector<Double> &value ); 00531 void Replace( const string &Key, PyObject *value ); 00534 void AppendValue( const string &Key, Double value ){M( Key ) -> push_back( value );} 00541 void AppendValue( const string &Key, const vector<Double> &value ); 00550 void SetValue( const string &Key, UInt4 Number, Double value ); 00566 template <class T> 00567 void Transform(const std::string &Key, T F, const std::string &newunit="None"); 00568 00570 void Reverse(void) { M.Reverse(); } 00571 00572 void Dump(); 00581 PyObject* PyDump(); 00582 00583 void dump() {DumpValue();} 00584 00585 void DumpValue(); 00586 void DumpFromVectorContainer(); 00587 void DumpFromVectorContainer( UInt4 size ); 00588 00589 void Dump( UInt4 size ); 00598 void DumpValue( UInt4 size ); 00599 00600 string PutXYEKeys(); 00601 string PutMergedKey(); 00602 vector<UInt4> PutSizeVector(); 00603 vector<Double> PutMergedDataVector(); 00604 00605 void BuildElementContainer( string XYEKeys, 00606 string MergedKey, 00607 vector<UInt4> SizeVector, 00608 vector<Double> MergedDataVector, 00609 HeaderBase h, 00610 HeaderBase uh ); 00619 vector<Double>* operator()( const string &Key ){return M( Key );} 00628 vector<Double>* operator()( UInt4 index ){return M( index );} 00638 void AddToHeader( const string &Key, Int4 value ){ header->Add( Key, value ); } 00646 void AddToHeader( const string &Key, Double value ){ header->Add( Key, value ); } 00654 void AddToHeader( const string &Key, string value ){ header->Add( Key, value ); } 00662 void AddToHeader( const string &Key, vector<Int4> value ){ header->Add( Key, value ); } 00670 void AddToHeader( const string &Key, vector<Double> value ){ header->Add( Key, value ); } 00678 void AddToHeader( const string &Key, vector<string> value ){ header->Add( Key, value ); } 00688 Double Sum( const string &key, const UInt4 i0, const UInt4 i1 ) const; 00694 Double Sum( const string &key ) const; 00700 Double Sum( void ) const; 00706 std::pair<Double, Double> Sum( const string &key, const string &err_key, UInt4 i0, UInt4 i1 ) const; 00711 std::pair<Double, Double> Sum( const string &key, const string &err_key ) const; 00724 std::pair<Double, Double> Sum2( void ) const ; 00729 std::pair<Double, Double> Sum( Double ini, Double fin ) const; 00740 Double Ave( const string &key ); 00746 Double Ave( const string &key, const string &err ); 00752 Double Min( const string &key ); 00755 Double Max( const string &key ); 00759 std::pair<Double, Double> Integrate(); 00771 // vector<Double> Integrate( UInt4 ini, UInt4 fin ); 00785 std::pair<Double, Double> Integrate( Double ini, Double fin ); 00786 void SaveToBinFile( string key, string FileName ); 00791 void ReadBinFile( string FileName, string key ); 00801 void SaveTextFile( string FileName ); 00802 void SaveTextFile( string FileName, Int4 prec ); 00803 void SaveTextFile( string FileName, Char deli ); 00804 void SaveTextFile( string FileName, Int4 prec, Char deli ); 00811 void LoadTextFile( string FileName ); 00819 bool safesum; 00820 // http://en.wikipedia.org/wiki/Kahan_summation_algorithm 00821 // warning, Ave(string, string) doesn't performs this safe summation yet 00822 00823 00824 // developing methods 00825 ElementContainer Mul( Double d ); 00826 ElementContainer &MulMySelf( Double d ); 00827 ElementContainer Mul( Double d, Double e ); 00828 ElementContainer &MulMySelf( Double d, Double e ); 00829 ElementContainer Mul( pair<Double,Double> &d ){ return Mul(d.first,d.second); } 00830 ElementContainer &MulMySelf( pair<Double,Double> &d ){ return MulMySelf(d.first,d.second); } 00831 00832 ElementContainer Plus( Double d ); 00833 ElementContainer &PlusMySelf( Double d ); 00834 ElementContainer Plus( Double d, Double e ); 00835 ElementContainer &PlusMySelf( Double d, Double e ); 00836 ElementContainer Plus( pair<Double,Double> &d ){ return Plus(d.first,d.second); } 00837 ElementContainer &PlusMySelf( pair<Double,Double> &d ){ return PlusMySelf(d.first,d.second); } 00838 }; 00839 00841 template <class Archive> 00842 void ElementContainer:: 00843 serialize(Archive &ar, const unsigned int ver) { 00844 ar & boost::serialization::make_nvp("XKey", Xkey); 00845 ar & boost::serialization::make_nvp("YKey", Ykey); 00846 ar & boost::serialization::make_nvp("EKey", Ekey); 00847 00848 ar & boost::serialization::make_nvp("Header", *header); 00849 ar & boost::serialization::make_nvp("UnitHeader", *UnitHeader); 00850 00851 ar & boost::serialization::make_nvp("ElementContainerData", M); 00852 } 00853 00855 template <class T> 00856 void ElementContainer:: 00857 Transform(const std::string &Key, T F, const std::string &newunit) { 00858 if( CheckKey( Key ) != 1 ){ 00859 cout << "ElementContainer::Transform(string)" 00860 << endl; 00861 cout << Key << " is not found in this container." << endl; 00862 return; 00863 } 00864 vector< Double > &vec = *M( Key ); 00865 00866 std::transform(vec.begin(), vec.end(), vec.begin(), F); 00867 ReSetUnit(Key, newunit); 00868 } 00869 00871 template <class Write> 00872 void ElementContainer:: 00873 NXwrite(Write &W) const { 00874 W.WriteData("XKey", Xkey); 00875 W.WriteData("YKey", Ykey); 00876 W.WriteData("EKey", Ekey); 00877 00878 if (!header->Empty()) 00879 W.WriteData("Header", *header); 00880 if (!UnitHeader->Empty()) 00881 W.WriteData("UnitHeader", *UnitHeader); 00882 00883 W.WriteData("ElementContainerData", M.M); 00884 } 00885 00887 template <class Read> 00888 void ElementContainer:: 00889 NXread(Read &R) { 00890 R.ReadData("XKey", Xkey); 00891 R.ReadData("YKey", Ykey); 00892 R.ReadData("EKey", Ekey); 00893 00894 R.ReadData("ElementContainerData", M.M); 00895 00896 NXname _name, _class; 00897 int _id, _status; 00898 while ((_status=R.GetNextEntry2(_name, _class, &_id))==1) { 00899 // std::cerr << "NEXTENTRY: " << _name << "," << _class << ", " 00900 // << _id << "," << _status << std::endl; 00901 if (strcmp(_name, "Header")==0) 00902 R.ReadData("Header", *header); 00903 else if (strcmp(_name, "UnitHeader")==0) 00904 R.ReadData("UnitHeader", *UnitHeader); 00905 } 00906 00907 } 00908 00909 #endif