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