/******************************************************************************* * * TRIQS: a Toolbox for Research in Interacting Quantum Systems * * Copyright (C) 2011 by O. Parcollet * * TRIQS is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * TRIQS. If not, see . * ******************************************************************************/ #ifndef TRIQS_ARRAYS_HDF5_ARRAY_PROXY_H #define TRIQS_ARRAYS_HDF5_ARRAY_PROXY_H #include "./array_proxy_impl.hpp" namespace triqs { namespace arrays { namespace h5 { /// The array proxy template class array_proxy : TRIQS_CONCEPT_TAG_NAME(ImmutableArray), // WRONG ! IT does not yet implement [ ] public sliceable_object < ValueType, h5::index_system, array_proxy_option, Tag::h5_array_proxy, ViewFactory, indexmaps::slicer, array_proxy > { public : typedef ValueType value_type; typedef std::pair< boost::shared_ptr ,std::string> storage_type; static const bool T_is_complex = boost::is_complex::value; typedef index_system< Rank, Rank_f> indexmap_type; static const unsigned int rank = Rank; /// Opens a proxy on an existing array. The dataset must exists template< class FileGroupType > array_proxy ( FileGroupType file_group, std::string const & name) : indexmap_ ( indexmap_type(file_group.openDataSet( name.c_str() ).getSpace(),T_is_complex) ) { if (!h5::exists(file_group, name)) TRIQS_RUNTIME_ERROR<< " h5 : no dataset"<< name << " in file "; storage_ = std::make_pair( boost::make_shared(file_group),name); DataSet dataset = file_group.openDataSet( name.c_str() ); try { if (T_is_complex) write_string_attribute(&dataset,"__complex__","1"); } catch (...) {} // catch if the attribute already exists... } /// Constructs a proxy on a new data set of the dimension of the domain D. The data must not exist. template< class FileGroupType, class LengthType > array_proxy ( FileGroupType file_group, std::string const & name_, LengthType L, bool overwrite = false) : indexmap_ ( indexmap_type (L) ) { if (h5::exists(file_group, name_)) { if (overwrite) file_group.unlink(name_.c_str()); else TRIQS_RUNTIME_ERROR<< " h5 : dataset"<< name_ << " already exists in the file "; } storage_ = std::make_pair( boost::make_shared(file_group),name_); DataSpace ds = indexmap_.template dataspace(); //(indexmap_type::rank_full, &indexmap_.lengths()[0], &indexmap_.strides()[0] ); DataSet dataset = file_group.createDataSet( name_.c_str(), data_type_file(ValueType()), ds); if (T_is_complex) write_string_attribute(&dataset,"__complex__","1"); } /// Shallow copy array_proxy(const array_proxy & X):indexmap_(X.indexmap()),storage_(X.storage_){} /// for slice construction array_proxy (const indexmap_type & IM, const storage_type & ST): indexmap_(IM),storage_(ST){ } public: indexmap_type const & indexmap() const {return indexmap_;} storage_type const & storage() const {return storage_;} storage_type & storage() {return storage_;} const H5::CommonFG * file_group() const { return storage_.first.get();} std::string const & name() const { return storage_.second;} typedef typename indexmap_type::domain_type domain_type; domain_type const & domain() const { return indexmap_.domain();} typedef typename domain_type::index_value_type shape_type; shape_type const & shape() const { return domain().lengths();} size_t num_elements() const { return domain().number_of_elements();} bool is_empty() const { return this->num_elements()==0;} template< typename ISP>// put in the file... void operator=(ISP const & X) { try { BOOST_AUTO(C, make_const_cache(X, Option::C())); //typename result_of::cache::type C(X); DataSet dataset = file_group()->openDataSet( name().c_str() ); dataset.write( h5::data(C.view()), h5::data_type_mem(C.view()),h5::data_space(C.view()),indexmap().template dataspace()); } TRIQS_ARRAYS_H5_CATCH_EXCEPTION; } template // from the file to the array or the array_view... friend void triqs_arrays_assign_delegation (LHS & lhs, array_proxy const & rhs) { static_assert((is_amv_value_or_view_class::value), "LHS is not a value or a view class "); h5::resize_or_check(lhs, rhs.indexmap().domain().lengths()); try { DataSet dataset = rhs.file_group()->openDataSet( rhs.name().c_str() ); BOOST_AUTO(C, make_cache(lhs, Option::C() )); //typename result_of::cache::type C(lhs); dataset.read( h5::data(C.view()), h5::data_type_mem(C.view()), h5::data_space(C.view()), rhs.indexmap().template dataspace() ); } TRIQS_ARRAYS_H5_CATCH_EXCEPTION; } protected: indexmap_type indexmap_; storage_type storage_; }; }// namesapce h5 template < class V, int R, int Rf > struct ViewFactory< V, R, h5::array_proxy_option, Tag::h5_array_proxy > { typedef h5::array_proxy type; }; }} #endif