From d27612d9dc4154bebd7e195fa55259fe6b717d7c Mon Sep 17 00:00:00 2001 From: Amir MOHAMMADI <amir.mohammadi@idiap.ch> Date: Tue, 5 Oct 2021 22:34:03 +0200 Subject: [PATCH] remove csv and torch IO functions --- bob/io/base/cpp/CSVFile.cpp | 314 -------------------------- bob/io/base/cpp/T3File.cpp | 318 --------------------------- bob/io/base/cpp/TensorArrayFile.cpp | 144 ------------ bob/io/base/cpp/TensorFile.cpp | 163 -------------- bob/io/base/cpp/TensorFile.h | 246 --------------------- bob/io/base/cpp/TensorFileHeader.cpp | 173 --------------- bob/io/base/cpp/TensorFileHeader.h | 95 -------- bob/io/base/data/torch.tensor | Bin 20508 -> 0 bytes bob/io/base/data/torch3.bindata | Bin 40968 -> 0 bytes bob/io/base/test.cpp | 4 +- bob/io/base/test_file.py | 89 -------- setup.py | 5 - 12 files changed, 2 insertions(+), 1549 deletions(-) delete mode 100644 bob/io/base/cpp/CSVFile.cpp delete mode 100644 bob/io/base/cpp/T3File.cpp delete mode 100644 bob/io/base/cpp/TensorArrayFile.cpp delete mode 100644 bob/io/base/cpp/TensorFile.cpp delete mode 100644 bob/io/base/cpp/TensorFile.h delete mode 100644 bob/io/base/cpp/TensorFileHeader.cpp delete mode 100644 bob/io/base/cpp/TensorFileHeader.h delete mode 100644 bob/io/base/data/torch.tensor delete mode 100644 bob/io/base/data/torch3.bindata diff --git a/bob/io/base/cpp/CSVFile.cpp b/bob/io/base/cpp/CSVFile.cpp deleted file mode 100644 index 1200523..0000000 --- a/bob/io/base/cpp/CSVFile.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/** - * @date Thu 10 May 2012 15:19:24 CEST - * @author Andre Anjos <andre.anjos@idiap.ch> - * - * @brief Code to read and write CSV files to/from arrays. CSV files are always - * treated as containing sequences of double precision numbers. - * - * Copyright (C) Idiap Research Institute, Martigny, Switzerland - */ - -#include <sstream> -#include <fstream> -#include <string> -#include <boost/filesystem.hpp> -#include <boost/format.hpp> -#include <boost/filesystem.hpp> -#include <boost/make_shared.hpp> -#include <boost/tokenizer.hpp> - -#include <boost/shared_array.hpp> -#include <boost/algorithm/string.hpp> - -#include <bob.io.base/CodecRegistry.h> - -typedef boost::tokenizer<boost::escaped_list_separator<char> > Tokenizer; - -class CSVFile: public bob::io::base::File { - - public: //api - - /** - * Peeks the file contents for a type. We assume the element type to be - * always doubles. This method, effectively, only peaks for the total - * number of lines and the number of columns in the file. - */ - void peek() { - - std::string line; - size_t line_number = 0; - size_t entries = 0; - std::streampos cur_pos = 0; - - m_file.seekg(0); //< returns to the begin of file and start reading... - - while (std::getline(m_file,line)) { - ++line_number; - m_pos.push_back(cur_pos); - cur_pos = m_file.tellg(); - Tokenizer tok(line); - size_t size = std::distance(tok.begin(), tok.end()); - if (!entries) entries = size; - else if (entries != size) { - boost::format m("line %d at file '%s' contains %d entries instead of %d (expected)"); - m % line_number % m_filename % size % entries; - throw std::runtime_error(m.str()); - } - } - - if (!line_number) { - m_newfile = true; - m_pos.clear(); - return; - } - - m_arrayset_type.dtype = bob::io::base::array::t_float64; - m_arrayset_type.nd = 1; - m_arrayset_type.shape[0] = entries; - m_arrayset_type.update_strides(); - - m_array_type = m_arrayset_type; - m_array_type.nd = 2; - m_array_type.shape[0] = m_pos.size(); - m_array_type.shape[1] = entries; - m_array_type.update_strides(); - } - - CSVFile(const char* path, char mode): - m_filename(path), - m_newfile(false) { - - if (mode == 'r' || (mode == 'a' && boost::filesystem::exists(path))) { //try peeking - - if (mode == 'r') - m_file.open(m_filename.c_str(), std::ios::in); - else if (mode == 'a') - m_file.open(m_filename.c_str(), std::ios::app|std::ios::in|std::ios::out); - if (!m_file.is_open()) { - boost::format m("cannot open file '%s' for reading or appending"); - m % path; - throw std::runtime_error(m.str()); - } - - peek(); ///< peek file properties - } - else { - m_file.open(m_filename.c_str(), std::ios::trunc|std::ios::in|std::ios::out); - - if (!m_file.is_open()) { - boost::format m("cannot open file '%s' for writing"); - m % path; - throw std::runtime_error(m.str()); - } - - m_newfile = true; - } - - //general precision settings, in case output is needed... - m_file.precision(10); - m_file.setf(std::ios_base::scientific, std::ios_base::floatfield); - - } - - virtual ~CSVFile() { } - - virtual const char* filename() const { - return m_filename.c_str(); - } - - virtual const bob::io::base::array::typeinfo& type() const { - return m_arrayset_type; - } - - virtual const bob::io::base::array::typeinfo& type_all() const { - return m_array_type; - } - - virtual size_t size() const { - return m_pos.size(); - } - - virtual const char* name() const { - return s_codecname.c_str(); - } - - virtual void read_all(bob::io::base::array::interface& buffer) { - if (m_newfile) - throw std::runtime_error("uninitialized CSV file cannot be read"); - - if (!buffer.type().is_compatible(m_array_type)) buffer.set(m_array_type); - - //read contents - std::string line; - if (m_file.eof()) m_file.clear(); ///< clear current "end" state. - m_file.seekg(0); - double* p = static_cast<double*>(buffer.ptr()); - while (std::getline(m_file, line)) { - Tokenizer tok(line); - for(Tokenizer::iterator k=tok.begin(); k!=tok.end(); ++k) { - std::istringstream(*k) >> *(p++); - } - } - } - - virtual void read(bob::io::base::array::interface& buffer, size_t index) { - - if (m_newfile) - throw std::runtime_error("uninitialized CSV file cannot be read"); - - if (!buffer.type().is_compatible(m_arrayset_type)) - buffer.set(m_arrayset_type); - - if (index >= m_pos.size()) { - boost::format m("cannot array at position %d -- there is only %d entries at file '%s'"); - m % index % m_pos.size() % m_filename; - throw std::runtime_error(m.str()); - } - - //reads a specific line from the file. - std::string line; - if (m_file.eof()) m_file.clear(); ///< clear current "end" state. - m_file.seekg(m_pos[index]); - if (!std::getline(m_file, line)) { - boost::format m("could not seek to line %u (offset %u) while reading file '%s'"); - m % index % m_pos[index] % m_filename; - throw std::runtime_error(m.str()); - } - Tokenizer tok(line); - double* p = static_cast<double*>(buffer.ptr()); - for(Tokenizer::iterator k=tok.begin(); k!=tok.end(); ++k) { - std::istringstream(*k) >> *(p++); - } - - } - - virtual size_t append (const bob::io::base::array::interface& buffer) { - - const bob::io::base::array::typeinfo& type = buffer.type(); - - if (m_newfile) { - if (type.nd != 1 || type.dtype != bob::io::base::array::t_float64) { - boost::format m("cannot append %s to file '%s' - CSV files only accept 1D double precision float arrays"); - m % type.str() % m_filename; - throw std::runtime_error(m.str()); - } - m_pos.clear(); - m_arrayset_type = m_array_type = type; - m_array_type.shape[1] = m_arrayset_type.shape[0]; - m_newfile = false; - } - - else { - - //check compatibility - if (!m_arrayset_type.is_compatible(buffer.type())) { - boost::format m("CSV file '%s' only accepts arrays of type %s"); - m % m_filename % m_arrayset_type.str(); - throw std::runtime_error(m.str()); - } - - } - - const double* p = static_cast<const double*>(buffer.ptr()); - if (m_pos.size()) m_file << std::endl; ///< adds a new line - m_pos.push_back(m_file.tellp()); ///< register start of line - for (size_t k=1; k<type.shape[0]; ++k) m_file << *(p++) << ","; - m_file << *(p++); - m_array_type.shape[0] = m_pos.size(); - m_array_type.update_strides(); - return (m_pos.size()-1); - - } - - virtual void write (const bob::io::base::array::interface& buffer) { - - const bob::io::base::array::typeinfo& type = buffer.type(); - - if (m_newfile) { - if (type.nd != 2 || type.dtype != bob::io::base::array::t_float64) { - boost::format m("cannot write %s to file '%s' - CSV files only accept a single 2D double precision float array as input"); - m % type.str() % m_filename; - throw std::runtime_error(m.str()); - } - const double* p = static_cast<const double*>(buffer.ptr()); - for (size_t l=1; l<type.shape[0]; ++l) { - m_pos.push_back(m_file.tellp()); - for (size_t k=1; k<type.shape[1]; ++k) m_file << *(p++) << ","; - m_file << *(p++) << std::endl; - } - for (size_t k=1; k<type.shape[1]; ++k) m_file << *(p++) << ","; - m_file << *(p++); - m_arrayset_type = type; - m_arrayset_type.nd = 1; - m_arrayset_type.shape[0] = type.shape[1]; - m_arrayset_type.update_strides(); - m_array_type = type; - m_newfile = false; - return; - } - - //TODO - throw std::runtime_error("Writing a 2D array to a CSV file that already contains entries is not implemented at the moment"); - - } - - private: //representation - std::fstream m_file; - std::string m_filename; - bool m_newfile; - bob::io::base::array::typeinfo m_array_type; - bob::io::base::array::typeinfo m_arrayset_type; - std::vector<std::streampos> m_pos; ///< dictionary of line starts - - static std::string s_codecname; - -}; - -std::string CSVFile::s_codecname = "bob.csv"; - -/** - * From this point onwards we have the registration procedure. If you are - * looking at this file for a coding example, just follow the procedure bellow, - * minus local modifications you may need to apply. - */ - -/** - * This defines the factory method F that can create codecs of this type. - * - * Here are the meanings of the mode flag that should be respected by your - * factory implementation: - * - * 'r': opens for reading only - no modifications can occur; it is an - * error to open a file that does not exist for read-only operations. - * 'w': opens for reading and writing, but truncates the file if it - * exists; it is not an error to open files that do not exist with - * this flag. - * 'a': opens for reading and writing - any type of modification can - * occur. If the file does not exist, this flag is effectively like - * 'w'. - * - * Returns a newly allocated File object that can read and write data to the - * file using a specific backend. - * - * @note: This method can be static. - */ -static boost::shared_ptr<bob::io::base::File> make_file (const char* path, char mode) { - return boost::make_shared<CSVFile>(path, mode); -} - -/** - * Takes care of codec registration per se. - */ -static bool register_codec() { - - boost::shared_ptr<bob::io::base::CodecRegistry> instance = - bob::io::base::CodecRegistry::instance(); - - instance->registerExtension(".csv", "Comma-Separated Values", &make_file); - instance->registerExtension(".txt", "Comma-Separated Values", &make_file); - - return true; - -} - -static bool codec_registered = register_codec(); diff --git a/bob/io/base/cpp/T3File.cpp b/bob/io/base/cpp/T3File.cpp deleted file mode 100644 index 8380a62..0000000 --- a/bob/io/base/cpp/T3File.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/** - * @date Wed Oct 26 17:11:16 2011 +0200 - * @author Andre Anjos <andre.anjos@idiap.ch> - * - * @brief Implements a torch3vision bindata reader/writer - * The format, as described in the old source code goes like this. - * 1) data is always recorded in little endian format - * 2) the first 4 bytes describe an integer that indicates the number of arrays - * to follow - * 3) the second 4 bytes describe an integer that specifies the frame width. - * 4) all arrays inserted there are single dimensional arrays. - * 5) all elements from all arrays are "normally" float (4-bytes), but could be - * double if set in the header of T3 during compilation. The file size will - * indicate the right type to use. - * Because of this restriction, this codec will only be able to work with - * single-dimension input. - * - * Copyright (C) Idiap Research Institute, Martigny, Switzerland - */ - -#include <fstream> -#include <boost/filesystem.hpp> -#include <boost/make_shared.hpp> -#include <boost/format.hpp> - -//some infrastructure to check the file size -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <bob.core/check.h> - -#include <bob.io.base/CodecRegistry.h> -#include <bob.io.base/blitz_array.h> - -static inline size_t get_filesize(const char* filename) { - struct stat filestatus; - stat(filename, &filestatus); - return filestatus.st_size; -} - -class T3File: public bob::io::base::File { - - public: //api - - T3File(const char* path, char mode): - m_filename(path), - m_newfile(true), - m_length(0) { - if ( mode == 'r' || (mode == 'a' && boost::filesystem::exists(path) ) ) { // try peek - size_t fsize = get_filesize(path); - fsize -= 8; // remove the first two entries - // read the first two 4-byte integers in the file, convert to unsigned - - std::fstream s(path, std::ios::binary|std::ios::in); - - if (!s) { - boost::format m("cannot open file `%s'"); - m % path; - throw std::runtime_error(m.str()); - } - - uint32_t nsamples, framesize; - nsamples = framesize = 0; - s.read((char*)&nsamples, sizeof(uint32_t)); - s.read((char*)&framesize, sizeof(uint32_t)); - - m_length = nsamples; - - // are those floats or doubles? - if (fsize == (nsamples*framesize*sizeof(float))) { - m_type_array.dtype = bob::io::base::array::t_float32; - m_type_arrayset.dtype = bob::io::base::array::t_float32; - } - else if (fsize == (nsamples*framesize*sizeof(double))) { - m_type_array.dtype = bob::io::base::array::t_float64; - m_type_arrayset.dtype = bob::io::base::array::t_float64; - } - else { - boost::format s("Cannot read file '%s', mode = '%c': fsize (%d) != %d*%d*sizeof(float32) nor *sizeof(float64)"); - s % path % mode % fsize % nsamples % framesize; - throw std::runtime_error(s.str()); - } - - size_t shape[2] = {nsamples, framesize}; - m_type_array.set_shape<size_t>(2, &shape[0]); - m_type_arrayset.set_shape<size_t>(1, &shape[1]); - m_newfile = false; - - } - } - - virtual ~T3File() { } - - virtual const char* filename() const { - return m_filename.c_str(); - } - - virtual const bob::io::base::array::typeinfo& type_all () const { - return m_type_array; - } - - virtual const bob::io::base::array::typeinfo& type () const { - return m_type_arrayset; - } - - virtual size_t size() const { - return m_length; - } - - virtual const char* name() const { - return s_codecname.c_str(); - } - - virtual void read_all(bob::io::base::array::interface& buffer) { - - if (m_newfile) { - boost::format f("cannot read uninitialized t3 binary file at '%s'"); - f % m_filename; - throw std::runtime_error(f.str()); - } - - if (!buffer.type().is_compatible(m_type_array)) buffer.set(m_type_array); - - //open the file, now for reading the contents... - std::ifstream ifile(m_filename.c_str(), std::ios::binary|std::ios::in); - - //skip the first 8 bytes, that contain the header that we already read - ifile.seekg(8, std::ios::beg); - ifile.read(static_cast<char*>(buffer.ptr()), buffer.type().buffer_size()); - - } - - virtual void read(bob::io::base::array::interface& buffer, size_t index) { - - if (m_newfile) { - boost::format f("cannot read uninitialized t3 binary file at '%s'"); - f % m_filename; - throw std::runtime_error(f.str()); - } - - const bob::io::base::array::typeinfo& type = buffer.type(); - - if (!buffer.type().is_compatible(m_type_arrayset)) buffer.set(m_type_arrayset); - - //open the file, now for reading the contents... - std::ifstream ifile(m_filename.c_str(), std::ios::binary|std::ios::in); - - //skip the first 8 bytes, that contain the header that we already read - ifile.seekg(8 + (index*type.buffer_size()), std::ios::beg); - ifile.read(static_cast<char*>(buffer.ptr()), type.buffer_size()); - - } - - virtual size_t append (const bob::io::base::array::interface& buffer) { - - const bob::io::base::array::typeinfo& info = buffer.type(); - - if (!m_newfile && !info.is_compatible(m_type_arrayset)) { - boost::format f("input buffer of type %s cannot be appended to already initialized torch3vision binary file of type %s"); - f % info.str() % m_type_arrayset.str(); - throw std::runtime_error(f.str()); - } - - std::ofstream ofile; - if (m_newfile) { - - //can only save uni-dimensional data, so throw if that is not the case - if (info.nd != 1) { - boost::format m("codec for torch3vision binary files can only save uni-dimensional data, but you passed: %s"); - m % info.str(); - throw std::runtime_error(m.str()); - } - - //can only save float32 or float64, otherwise, throw. - if ((info.dtype != bob::io::base::array::t_float32) && - (info.dtype != bob::io::base::array::t_float64)) { - boost::format f("cannot have T3 bindata files with type %s - only float32 or float64"); - f % bob::io::base::array::stringize(info.dtype); - throw std::runtime_error(f.str()); - } - - ofile.open(m_filename.c_str(), std::ios::binary|std::ios::out|std::ios::trunc); - - //header writing... - const uint32_t nsamples = 0; - const uint32_t framesize = info.shape[0]; - ofile.write((const char*)&nsamples, sizeof(uint32_t)); - ofile.write((const char*)&framesize, sizeof(uint32_t)); - - m_type_arrayset = info; - m_type_array.dtype = info.dtype; - m_newfile = false; ///< block re-initialization - m_length = 0; - - } - else { - //only open the file, the rest is setup already - ofile.open(m_filename.c_str(), std::ios::binary|std::ios::out|std::ios::app); - } - - if (!ofile) { - boost::format f("cannot open output file '%s' for writing"); - f % m_filename; - throw std::runtime_error(f.str()); - } - - ofile.write(static_cast<const char*>(buffer.ptr()), info.buffer_size()); - ofile.close(); - - //setup new type information - ++m_length; - size_t shape[2] = {m_length, info.shape[0]}; - m_type_array.set_shape<size_t>(2, &shape[0]); - - //update the header information on the file - ofile.open(m_filename.c_str(), std::ios::binary|std::ios::in|std::ios::out); - const uint32_t nsamples = m_length; - ofile.write((const char*)&nsamples, sizeof(uint32_t)); - ofile.flush(); - return m_length-1; - - } - - /** - * Supports writing a single vector or a set of vectors represented as a - * matrix. In this last case, vectors are formed from the rows of the given - * matrix. - */ - virtual void write (const bob::io::base::array::interface& buffer) { - - m_newfile = true; //force file re-setting - const bob::io::base::array::typeinfo& info = buffer.type(); - - if (info.nd == 1) {//just do a normal append - append(buffer); - } - - else if (info.nd == 2) { //append every array individually - - const uint8_t* ptr = static_cast<const uint8_t*>(buffer.ptr()); - bob::io::base::array::typeinfo slice_info(info.dtype, static_cast<size_t>(1), - &info.shape[1]); - for (size_t k=0; k<info.shape[0]; ++k) { - const void* slice_ptr=static_cast<const void*>(ptr+k*slice_info.buffer_size()); - bob::io::base::array::blitz_array slice(const_cast<void*>(slice_ptr), slice_info); - append(slice); - } - - } - - else { - boost::format f("cannot do single write of torch3vision .bindata file with array with type '%s' - only supports 1D or 2D arrays of types float32 or float64"); - f % info.str(); - throw std::runtime_error(f.str()); - } - - } - - private: //representation - - std::string m_filename; - bool m_newfile; - bob::io::base::array::typeinfo m_type_array; - bob::io::base::array::typeinfo m_type_arrayset; - size_t m_length; - - static std::string s_codecname; - -}; - -std::string T3File::s_codecname = "torch3.binary"; - -/** - * From this point onwards we have the registration procedure. If you are - * looking at this file for a coding example, just follow the procedure bellow, - * minus local modifications you may need to apply. - */ - -/** - * This defines the factory method F that can create codecs of this type. - * - * Here are the meanings of the mode flag that should be respected by your - * factory implementation: - * - * 'r': opens for reading only - no modifications can occur; it is an - * error to open a file that does not exist for read-only operations. - * 'w': opens for reading and writing, but truncates the file if it - * exists; it is not an error to open files that do not exist with - * this flag. - * 'a': opens for reading and writing - any type of modification can - * occur. If the file does not exist, this flag is effectively like - * 'w'. - * - * Returns a newly allocated File object that can read and write data to the - * file using a specific backend. - * - * @note: This method can be static. - */ -static boost::shared_ptr<bob::io::base::File> make_file (const char* path, char mode) { - return boost::make_shared<T3File>(path, mode); -} - -/** - * Takes care of codec registration per se. - */ -static bool register_codec() { - - boost::shared_ptr<bob::io::base::CodecRegistry> instance = - bob::io::base::CodecRegistry::instance(); - - instance->registerExtension(".bindata", "torch3 binary data format", &make_file); - - return true; - -} - -static bool codec_registered = register_codec(); diff --git a/bob/io/base/cpp/TensorArrayFile.cpp b/bob/io/base/cpp/TensorArrayFile.cpp deleted file mode 100644 index d0cb72d..0000000 --- a/bob/io/base/cpp/TensorArrayFile.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/** - * @date Wed Oct 26 17:11:16 2011 +0200 - * @author Andre Anjos <andre.anjos@idiap.ch> - * - * @brief Implements the TensorArrayCodec type - * - * Copyright (C) Idiap Research Institute, Martigny, Switzerland - */ - -#include "TensorFile.h" -#include <bob.io.base/CodecRegistry.h> - -class TensorArrayFile: public bob::io::base::File { - - public: //api - - TensorArrayFile(const char* path, bob::io::base::TensorFile::openmode mode): - m_file(path, mode), - m_filename(path) { - if (m_file.size()) m_file.peek(m_type); - } - - virtual ~TensorArrayFile() { } - - virtual const char* filename() const { - return m_filename.c_str(); - } - - virtual const bob::io::base::array::typeinfo& type_all () const { - return m_type; - } - - virtual const bob::io::base::array::typeinfo& type () const { - return m_type; - } - - virtual size_t size() const { - return m_file.size(); - } - - virtual const char* name() const { - return s_codecname.c_str(); - } - - virtual void read_all(bob::io::base::array::interface& buffer) { - - if(!m_file) - throw std::runtime_error("uninitialized binary file cannot be read"); - - m_file.read(0, buffer); - - } - - virtual void read(bob::io::base::array::interface& buffer, size_t index) { - - if(!m_file) - throw std::runtime_error("uninitialized binary file cannot be read"); - - m_file.read(index, buffer); - - } - - virtual size_t append (const bob::io::base::array::interface& buffer) { - - m_file.write(buffer); - - if (size() == 1) m_file.peek(m_type); - - return size() - 1; - - } - - virtual void write (const bob::io::base::array::interface& buffer) { - - //we don't have a special way to treat write()'s like in HDF5. - append(buffer); - - } - - private: //representation - - bob::io::base::TensorFile m_file; - bob::io::base::array::typeinfo m_type; - std::string m_filename; - - static std::string s_codecname; - -}; - -std::string TensorArrayFile::s_codecname = "bob.tensor"; - -/** - * From this point onwards we have the registration procedure. If you are - * looking at this file for a coding example, just follow the procedure bellow, - * minus local modifications you may need to apply. - */ - -/** - * This defines the factory method F that can create codecs of this type. - * - * Here are the meanings of the mode flag that should be respected by your - * factory implementation: - * - * 'r': opens for reading only - no modifications can occur; it is an - * error to open a file that does not exist for read-only operations. - * 'w': opens for reading and writing, but truncates the file if it - * exists; it is not an error to open files that do not exist with - * this flag. - * 'a': opens for reading and writing - any type of modification can - * occur. If the file does not exist, this flag is effectively like - * 'w'. - * - * Returns a newly allocated File object that can read and write data to the - * file using a specific backend. - * - * @note: This method can be static. - */ -static boost::shared_ptr<bob::io::base::File> make_file (const char* path, char mode) { - - bob::io::base::TensorFile::openmode _mode; - if (mode == 'r') _mode = bob::io::base::TensorFile::in; - else if (mode == 'w') _mode = bob::io::base::TensorFile::out; - else if (mode == 'a') _mode = bob::io::base::TensorFile::append; - else throw std::runtime_error("unsupported tensor file opening mode"); - - return boost::make_shared<TensorArrayFile>(path, _mode); - -} - -/** - * Takes care of codec registration per se. - */ -static bool register_codec() { - - boost::shared_ptr<bob::io::base::CodecRegistry> instance = - bob::io::base::CodecRegistry::instance(); - - instance->registerExtension(".tensor", "torch3vision v2.1 tensor files", &make_file); - - return true; - -} - -static bool codec_registered = register_codec(); diff --git a/bob/io/base/cpp/TensorFile.cpp b/bob/io/base/cpp/TensorFile.cpp deleted file mode 100644 index 8f9ff34..0000000 --- a/bob/io/base/cpp/TensorFile.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @date Wed Jun 22 17:50:08 2011 +0200 - * @author Andre Anjos <andre.anjos@idiap.ch> - * - * @brief This class can be used to store and load multiarrays into/from files. - * - * Copyright (C) Idiap Research Institute, Martigny, Switzerland - */ - -#include "TensorFile.h" - -#include <bob.io.base/reorder.h> -#include <bob.io.base/array_type.h> - -// see: http://stackoverflow.com/questions/13061979/shared-ptr-to-an-array-should-it-be-used -template< typename T > -struct array_deleter -{ - void operator ()( T const * p) - { - delete[] p; - } -}; - -bob::io::base::TensorFile::TensorFile(const std::string& filename, - bob::io::base::TensorFile::openmode flag): - m_header_init(false), - m_current_array(0), - m_n_arrays_written(0), - m_openmode(flag) -{ - if((flag & bob::io::base::TensorFile::out) && (flag & bob::io::base::TensorFile::in)) { - m_stream.open(filename.c_str(), std::ios::in | std::ios::out | - std::ios::binary); - if(m_stream) - { - m_header.read(m_stream); - m_buffer.reset(new char[m_header.m_type.buffer_size()], array_deleter<char>()); - m_header_init = true; - m_n_arrays_written = m_header.m_n_samples; - - if (flag & bob::io::base::TensorFile::append) { - m_stream.seekp(0, std::ios::end); - m_current_array = m_header.m_n_samples; - } - } - } - else if(flag & bob::io::base::TensorFile::out) { - if(m_stream && (flag & bob::io::base::TensorFile::append)) { - m_stream.open(filename.c_str(), std::ios::out | std::ios::in | - std::ios::binary); - m_header.read(m_stream); - m_buffer.reset(new char[m_header.m_type.buffer_size()], array_deleter<char>()); - m_header_init = true; - m_n_arrays_written = m_header.m_n_samples; - m_stream.seekp(0, std::ios::end); - m_current_array = m_header.m_n_samples; - } - else - m_stream.open(filename.c_str(), std::ios::out | std::ios::binary); - } - else if(flag & bob::io::base::TensorFile::in) { - m_stream.open(filename.c_str(), std::ios::in | std::ios::binary); - if(m_stream) { - m_header.read(m_stream); - m_buffer.reset(new char[m_header.m_type.buffer_size()], array_deleter<char>()); - m_header_init = true; - m_n_arrays_written = m_header.m_n_samples; - - if (flag & bob::io::base::TensorFile::append) { - throw std::runtime_error("cannot append data in read only mode"); - } - } - } - else { - throw std::runtime_error("invalid combination of flags"); - } -} - -bob::io::base::TensorFile::~TensorFile() { - close(); -} - -void bob::io::base::TensorFile::peek(bob::io::base::array::typeinfo& info) const { - info = m_header.m_type; -} - -void bob::io::base::TensorFile::close() { - // Rewrite the header and update the number of samples - m_header.m_n_samples = m_n_arrays_written; - if(m_openmode & bob::io::base::TensorFile::out) m_header.write(m_stream); - - m_stream.close(); -} - -void bob::io::base::TensorFile::initHeader(const bob::io::base::array::typeinfo& info) { - // Check that data have not already been written - if (m_n_arrays_written > 0 ) { - throw std::runtime_error("cannot init the header of an output stream in which data have already been written"); - } - - // Initialize header - m_header.m_type = info; - m_header.m_tensor_type = bob::io::base::arrayTypeToTensorType(info.dtype); - m_header.write(m_stream); - - // Temporary buffer to help with data transposition... - m_buffer.reset(new char[m_header.m_type.buffer_size()], array_deleter<char>()); - - m_header_init = true; -} - -void bob::io::base::TensorFile::write(const bob::io::base::array::interface& data) { - - const bob::io::base::array::typeinfo& info = data.type(); - - if (!m_header_init) initHeader(info); - else { - //checks compatibility with previously written stuff - if (!m_header.m_type.is_compatible(info)) - throw std::runtime_error("buffer does not conform to expected type"); - } - - bob::io::base::row_to_col_order(data.ptr(), m_buffer.get(), info); - - m_stream.write(static_cast<const char*>(m_buffer.get()), info.buffer_size()); - - // increment m_n_arrays_written and m_current_array - ++m_current_array; - if (m_current_array>m_n_arrays_written) ++m_n_arrays_written; -} - -void bob::io::base::TensorFile::read (bob::io::base::array::interface& buf) { - - if(!m_header_init) { - throw std::runtime_error("TensorFile: header is not initialized"); - } - if(!buf.type().is_compatible(m_header.m_type)) buf.set(m_header.m_type); - - m_stream.read(reinterpret_cast<char*>(m_buffer.get()), - m_header.m_type.buffer_size()); - - bob::io::base::col_to_row_order(m_buffer.get(), buf.ptr(), m_header.m_type); - - ++m_current_array; -} - -void bob::io::base::TensorFile::read (size_t index, bob::io::base::array::interface& buf) { - - // Check that we are reaching an existing array - if( index > m_header.m_n_samples ) { - boost::format m("request to read list item at position %d which is outside the bounds of declared object with size %d"); - m % index % m_header.m_n_samples; - throw std::runtime_error(m.str()); - } - - // Set the stream pointer at the correct position - m_stream.seekg( m_header.getArrayIndex(index) ); - m_current_array = index; - - // Put the content of the stream in the blitz array. - read(buf); -} diff --git a/bob/io/base/cpp/TensorFile.h b/bob/io/base/cpp/TensorFile.h deleted file mode 100644 index 35d42bf..0000000 --- a/bob/io/base/cpp/TensorFile.h +++ /dev/null @@ -1,246 +0,0 @@ -/** - * @date Wed Jun 22 17:50:08 2011 +0200 - * @author Andre Anjos <andre.anjos@idiap.ch> - * - * @brief This class can be used to load and store arrays from/to .tensor files - * - * Copyright (C) Idiap Research Institute, Martigny, Switzerland - */ - -#ifndef BOB_IO_TENSORFILE_H -#define BOB_IO_TENSORFILE_H - -#include <boost/format.hpp> -#include <stdexcept> - -#include <bob.io.base/blitz_array.h> - -#include "TensorFileHeader.h" - -namespace bob { namespace io { namespace base { - - /** - * Defines the flags that might be used when loading/storing a file - * containing blitz arrays. - */ - enum _TensorFileFlag { - _unset = 0, - _append = 1L << 0, - _in = 1L << 3, - _out = 1L << 4 - }; - - /** - * This class can be used for loading and storing multiarrays from/to - * tensor files - */ - class TensorFile - { - public: - /** - * Defines the bitmask type for providing information about the type of - * the stream. - */ - typedef _TensorFileFlag openmode; - static const openmode append = _append; - static const openmode in = _in; - static const openmode out = _out; - - /** - * Constructor - */ - TensorFile(const std::string& filename, openmode f); - - /** - * Destructor - */ - ~TensorFile(); - - /** - * Tests if next operation will succeed. - */ - inline bool operator!() const { return !m_stream; } - - /** - * Closes the TensorFile - */ - void close(); - - /** - * Puts an Array of a given type into the output stream/file. If the - * type/shape have not yet been set, it is set according to the type - * and shape given in the blitz array, otherwise the type/shape should - * match or an exception is thrown. - * - * Please note that blitz::Array<> will be implicitly constructed as - * required and respecting those norms. - * - * @warning: Please convert your files to HDF5, this format is - * deprecated starting on 16.04.2011 - AA - */ - void write(const bob::io::base::array::interface& data); - - /** - * Reads the file data into a bob::io::base::array::interface - this variant reads the next - * variable. The bob::io::base::array::interface size will be reset if required. - */ - void read(bob::io::base::array::interface& data); - - /** - * Reads the file data into a bob::io::base::array::interface - this variant allows the - * specification of a position to read data from. The bob::io::base::array::interface size will be - * reset if required. - */ - void read (size_t index, bob::io::base::array::interface& data); - - /** - * Peeks the file and returns the currently set typeinfo - */ - void peek(bob::io::base::array::typeinfo& info) const; - - /** - * Gets the number of samples/arrays written so far - * - * @warning An exception is thrown if nothing was written so far - */ - inline size_t size() const { - return (m_header_init)? m_n_arrays_written : 0; - } - - /** - * Gets the number of elements per array - * - * @warning An exception is thrown if nothing was written so far - */ - inline size_t getNElements() const { - headerInitialized(); - return m_header.getNElements(); - } - - /** - * Gets the size along a particular dimension - * - * @warning An exception is thrown if nothing was written so far - */ - inline size_t getSize(size_t dim_index) const { - headerInitialized(); - return m_header.m_type.shape[dim_index]; - } - - /** - * Initializes the tensor file with the given type and shape. - */ - inline void initTensorFile(const bob::io::base::array::typeinfo& info) { - initHeader(info); - } - - private: //Some stuff I need privately - - /** - * Checks if the end of the tensor file is reached - */ - inline void endOfFile() { - if(m_current_array >= m_header.m_n_samples ) { - boost::format m("TensorFile::endOfFile(): current array index == %d is outside the bounds of declared object with size %d"); - m % m_current_array % m_header.m_n_samples; - throw std::runtime_error(m.str()); - } - } - - /** - * Checks that the header has been initialized, and raise an - * exception if not - */ - inline void headerInitialized() const { - if (!m_header_init) { - throw std::runtime_error("TensorFile: header is not initialized"); - } - } - - /** - * Initializes the header of the (output) stream with the given type - * and shape - */ - void initHeader(const bob::io::base::array::typeinfo& info); - - public: - - /******************************************************************** - * Specific blitz::Array<> operations - ********************************************************************/ - - - /** - * A shortcut to write a blitz::Array<T,D> - * - * @warning: Please convert your files to HDF5, this format is - * deprecated starting on 16.04.2011 - AA - */ - template <typename T, int D> - inline void write(blitz::Array<T,D>& bz) { - write(bob::io::base::array::blitz_array(bz)); - } - - /** - * Load one blitz++ multiarray from the input stream/file All the - * multiarrays saved have the same dimensions. - */ - template <typename T, int D> inline blitz::Array<T,D> read() { - bob::io::base::array::typeinfo info; - peek(info); - bob::io::base::array::blitz_array buf(info); - read(buf); - return bob::io::base::array::cast<T,D>(buf); - } - - template <typename T, int D> inline blitz::Array<T,D> read(size_t - index) { - bob::io::base::array::typeinfo info; - peek(info); - bob::io::base::array::blitz_array buf(info); - read(index, buf); - return bob::io::base::array::cast<T,D>(buf); - } - - private: //representation - - bool m_header_init; - size_t m_current_array; - size_t m_n_arrays_written; - std::fstream m_stream; - detail::TensorFileHeader m_header; - openmode m_openmode; - boost::shared_ptr<void> m_buffer; - }; - - inline _TensorFileFlag operator&(_TensorFileFlag a, _TensorFileFlag b) { - return _TensorFileFlag(static_cast<int>(a) & static_cast<int>(b)); - } - - inline _TensorFileFlag operator|(_TensorFileFlag a, _TensorFileFlag b) { - return _TensorFileFlag(static_cast<int>(a) | static_cast<int>(b)); - } - - inline _TensorFileFlag operator^(_TensorFileFlag a, _TensorFileFlag b) { - return _TensorFileFlag(static_cast<int>(a) ^ static_cast<int>(b)); - } - - inline _TensorFileFlag& operator|=(_TensorFileFlag& a, _TensorFileFlag b) { - return a = a | b; - } - - inline _TensorFileFlag& operator&=(_TensorFileFlag& a, _TensorFileFlag b) { - return a = a & b; - } - - inline _TensorFileFlag& operator^=(_TensorFileFlag& a, _TensorFileFlag b) { - return a = a ^ b; - } - - inline _TensorFileFlag operator~(_TensorFileFlag a) { - return _TensorFileFlag(~static_cast<int>(a)); - } - -}}} - -#endif /* BOB_IO_BINFILE_H */ diff --git a/bob/io/base/cpp/TensorFileHeader.cpp b/bob/io/base/cpp/TensorFileHeader.cpp deleted file mode 100644 index fb96a13..0000000 --- a/bob/io/base/cpp/TensorFileHeader.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @date Wed Jun 22 17:50:08 2011 +0200 - * @author Andre Anjos <andre.anjos@idiap.ch> - * - * This class defines an header for storing multiarrays into .tensor files. - * - * Copyright (C) Idiap Research Institute, Martigny, Switzerland - */ - -#include <boost/format.hpp> - -#include "TensorFileHeader.h" - -bob::io::base::detail::TensorFileHeader::TensorFileHeader() - : m_tensor_type(bob::io::base::Char), - m_type(), - m_n_samples(0), - m_tensor_size(0) -{ -} - -bob::io::base::detail::TensorFileHeader::~TensorFileHeader() { } - -size_t bob::io::base::detail::TensorFileHeader::getArrayIndex (size_t index) const { - size_t header_size = 7 * sizeof(int); - return header_size + index * m_tensor_size; -} - -void bob::io::base::detail::TensorFileHeader::read(std::istream& str) { - // Start reading at the beginning of the stream - str.seekg(std::ios_base::beg); - - int val; - str.read( reinterpret_cast<char*>(&val), sizeof(int)); - m_tensor_type = (bob::io::base::TensorType)val; - m_type.dtype = bob::io::base::tensorTypeToArrayType(m_tensor_type); - - str.read( reinterpret_cast<char*>(&val), sizeof(int)); - m_n_samples = (size_t)val; - - int nd; - str.read(reinterpret_cast<char*>(&nd), sizeof(int)); - - int shape[BOB_MAX_DIM]; - - str.read( reinterpret_cast<char*>(&val), sizeof(int)); - shape[0] = (size_t)val; - str.read( reinterpret_cast<char*>(&val), sizeof(int)); - shape[1] = (size_t)val; - str.read( reinterpret_cast<char*>(&val), sizeof(int)); - shape[2] = (size_t)val; - str.read( reinterpret_cast<char*>(&val), sizeof(int)); - shape[3] = (size_t)val; - - m_type.set_shape(nd, shape); - - header_ok(); -} - -void bob::io::base::detail::TensorFileHeader::write(std::ostream& str) const -{ - // Start writing at the beginning of the stream - str.seekp(std::ios_base::beg); - - int val; - val = (int)m_tensor_type; - str.write( reinterpret_cast<char*>(&val), sizeof(int)); - val = (int)m_n_samples; - str.write( reinterpret_cast<char*>(&val), sizeof(int)); - val = (int)m_type.nd; - str.write( reinterpret_cast<char*>(&val), sizeof(int)); - val = (int)m_type.shape[0]; - str.write( reinterpret_cast<char*>(&val), sizeof(int)); - val = (int)m_type.shape[1]; - str.write( reinterpret_cast<char*>(&val), sizeof(int)); - val = (int)m_type.shape[2]; - str.write( reinterpret_cast<char*>(&val), sizeof(int)); - val = (int)m_type.shape[3]; - str.write( reinterpret_cast<char*>(&val), sizeof(int)); -} - -void bob::io::base::detail::TensorFileHeader::header_ok() -{ - // Check the type - switch (m_tensor_type) - { - // supported tensor types - case bob::io::base::Char: - case bob::io::base::Short: - case bob::io::base::Int: - case bob::io::base::Long: - case bob::io::base::Float: - case bob::io::base::Double: - break; - // error - default: - throw std::runtime_error("unsupported data type found while scanning header of tensor file"); - } - - // Check the number of samples and dimensions - if( m_type.nd < 1 || m_type.nd > 4) { - boost::format m("header for tensor file indicates an unsupported type: %s"); - m % m_type.str(); - throw std::runtime_error(m.str()); - } - - // OK - update(); -} - -void bob::io::base::detail::TensorFileHeader::update() -{ - size_t base_size = 0; - switch (m_tensor_type) - { - case bob::io::base::Char: base_size = sizeof(char); break; - case bob::io::base::Short: base_size = sizeof(short); break; - case bob::io::base::Int: base_size = sizeof(int); break; - case bob::io::base::Long: base_size = sizeof(long); break; - case bob::io::base::Float: base_size = sizeof(float); break; - case bob::io::base::Double: base_size = sizeof(double); break; - default: - throw std::runtime_error("unsupported data type found while updating tensor file"); - } - - size_t tsize = 1; - for(size_t i = 0; i < m_type.nd; ++i) tsize *= m_type.shape[i]; - - m_tensor_size = tsize * base_size; -} - - -bob::io::base::TensorType bob::io::base::arrayTypeToTensorType(bob::io::base::array::ElementType eltype) -{ - switch(eltype) - { - case bob::io::base::array::t_int8: - return bob::io::base::Char; - case bob::io::base::array::t_int16: - return bob::io::base::Short; - case bob::io::base::array::t_int32: - return bob::io::base::Int; - case bob::io::base::array::t_int64: - return bob::io::base::Long; - case bob::io::base::array::t_float32: - return bob::io::base::Float; - case bob::io::base::array::t_float64: - return bob::io::base::Double; - default: - throw std::runtime_error("unsupported data type found while converting array type to tensor type"); - } -} - -bob::io::base::array::ElementType bob::io::base::tensorTypeToArrayType(bob::io::base::TensorType tensortype) -{ - switch(tensortype) - { - case bob::io::base::Char: - return bob::io::base::array::t_int8; - case bob::io::base::Short: - return bob::io::base::array::t_int16; - case bob::io::base::Int: - return bob::io::base::array::t_int32; - case bob::io::base::Long: - return bob::io::base::array::t_int64; - case bob::io::base::Float: - return bob::io::base::array::t_float32; - case bob::io::base::Double: - return bob::io::base::array::t_float64; - default: - throw std::runtime_error("unsupported data type found while converting tensor type to array type"); - } -} diff --git a/bob/io/base/cpp/TensorFileHeader.h b/bob/io/base/cpp/TensorFileHeader.h deleted file mode 100644 index 7e852b8..0000000 --- a/bob/io/base/cpp/TensorFileHeader.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @date Wed Jun 22 17:50:08 2011 +0200 - * @author Andre Anjos <andre.anjos@idiap.ch> - * - * @brief This class defines an header for storing multiarrays into - * .tensor files. - * - * Copyright (C) Idiap Research Institute, Martigny, Switzerland - */ - -#ifndef BOB_IO_BASE_TENSORFILEHEADER_H -#define BOB_IO_BASE_TENSORFILEHEADER_H - -#include <fstream> -#include <blitz/array.h> - -#include <bob.io.base/array.h> - -namespace bob { namespace io { namespace base { - - // TensorType - enum TensorType - { - Char, - Short, - Int, - Long, - Float, - Double - }; - - TensorType arrayTypeToTensorType(bob::io::base::array::ElementType eltype); - bob::io::base::array::ElementType tensorTypeToArrayType(bob::io::base::TensorType tensortype); - - namespace detail { - /** - * The Header for storing arrays into binary files. Please note that this - * class is for private use of the TensorFile type. - */ - struct TensorFileHeader { - - /** - * Constructor - */ - TensorFileHeader(); - - /** - * Destructor - */ - virtual ~TensorFileHeader(); - - /** - * Gets the offset of some array in the file - */ - size_t getArrayIndex(size_t index) const; - - /** - * Writes the header into an output stream - */ - void write(std::ostream& str) const; - - /** - * Reads the header from an input stream - */ - void read(std::istream& str); - - /** - * Gets number of elements in binary file - */ - inline size_t getNElements() const { - size_t tmp = 1; - for(size_t i=0; i<m_type.nd; ++i) tmp *= m_type.shape[i]; - return tmp; - } - - /** - * Checks if the header is valid - */ - void header_ok(); - - /** - * Update the TensorSize value - */ - void update(); - - //representation - TensorType m_tensor_type; ///< array element type - bob::io::base::array::typeinfo m_type; ///< the type information - size_t m_n_samples; ///< total number of arrays in the file - size_t m_tensor_size; ///< the number of dimensions in each array - }; - -}}}} - -#endif /* BOB_IO_BASE_TENSORFILEHEADER_H */ diff --git a/bob/io/base/data/torch.tensor b/bob/io/base/data/torch.tensor deleted file mode 100644 index 8c02f00dfbfc96d26e9678dc9f41ee38e98c1f16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20508 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	BQ*Zl8jpVF0V-*q6-esxB? z{hAwT_R@P2?GqTC>`$jC+ovCYXxFPPZJ+(_m0f_rExTg51$GnXW!lYh5V8|F&ti9Z z(SO@}CW?0F`K;|8J)K~;Fld$CkFOi-rrfw-_i_n~eOW1k{eiWd_Dgp>wA)~M%WnJS z3wB<G4EAgPirH^Bk+!#v*0FDYX=%S!%+vnOGfR6ODNlRp&wlnZdL!*4(&FuRbEMjD zo*81lUDDIO@42P@$~04Z-2@$b)^o1*2UWxEU#7&{AKH^>KW$=+{kcQl_A-ge_AggI zw43v%$L{V~Q#+9iS-W6<1G`_(C)nM6yxY$2^aZ<XR=4c>e~a1YH_F@ZJmqSCp(ELT z?}0>n)4B}%pc`rS=6#X&%F{yZ-#)gqXWq+cFS0?y-quLkK98Hv{=EKAyOVN<?8>uR z?QRMi*u6V%YIj1f(Jtct20O(K5A7!DNZa4=wX^pOv9s4W=4!tr+0=e}y0ZQIYI*yt zUt;!dTRH8&{ui^~vR(r`#^LqY(tg%oNBhdhmiCvTbnK<hc-w2qc-p(}Nwi<FFVTK# zZ>0UY?nwKnv_N~O^RD*kpZ)CTB*xoc?M}9zek#}gUU;Fs<&AuM>8n}x&dg5sEzzd- z1?wN$y;+%QCsHbFH$`5<ZsU%bcAH{8+HHCM%8oPRqusU=2K&?c()J=1LiXF9S=#TI z8Djrof1>>jo>Y6&o@D#8J(2bvGeYdQOL*FQ9(T333b(V5OE$F+OjovlRVQ!Xze2<Q z@vet<-|ug*%Lwqao4Yd8ZtKGhb|Q~o+1)afwr7g4v#<Q<Xa6@P&|dGfxBZU@JNs{$ z%J$M5S?m?pY1mtA)Ubb*p=`gwT-yF>l#YE#u${e*B%ggsgS@?nxTk&5Syy{OwQ&0n z(_`#ozx&y%^+eh)pB`hswKvjUygS*R_g0#{?u~r=%aMil>r_kZn<5JB6KgW;`F=av zGnF#fZ{Ii5?)%bAyMuC(c4dby*iBi&VsBC@Z$FWT&t8Uy&z`+V$bPbcw7rKQpZ$eU zJNx!oA@+*bv+PrErP=S_pJ=ZzE5zRUjJN&C)2{Z)r(Nx{o?F_VNHeupOEI-~-Kt@4 znqq42AEaa7<b2C+#`E2F+1qE@9o$i2=k;c{-F0q0`(q(?_R{T<_RD95*k`DR+p{Fc z+dEGQv40k;V}E?JfxX3c4f{vIcJ^DhY1p^N=-B^GHMP&(Xkb5Si-x^ftd6~SmZ^RG zv=I9YwQ&0bQ)BEuc1PM<Ylhp4U(2$8awE%r%9&jIYyXSv`Hjl#!&OV{FNx>a-{_3A zUze(EuaUCU?oZoPJ3i$Fc6}Ev*j+1Uu;*Q;VIPyCY@bysWdHDwnEmf!A^YWpLiRG1 z4EFan8`w7`#oNyaE3{wmx5)k!PpbX(v_ShiFD>m4Z#S^t5MgJ3?3tzglnhh*+fOa+ zJ+>LxUkJCeHxTx;->}xeKDAKD{^8SCc3v6_?C!kZU>EiFmECc3Y5SW0j`sS~W9%90 zGVBkC=hzGKq}nrgMcPZ8_O`$O64J)&KILlvK*ZDjL#C<yir<d*49_g>-)=In-}}_k zzFyMPKJt^Fz05^d`}!|__S0s>*c;wRv(LYkW^a5m-+qE&nSByNvHiW%x%S^?#n?YN z<!wKWQQUr=;|aTZ`xAECHgekgt}(Ee4YsrY5^QHLWFc*TL|@we)G8MH1HZ-WrM7U| zfBf~zjv-pd{z-SFy$gS;{o;Q`_Wh@F?Juf^+kgD$Xm9$|(w;lQ&fY)5&VJGfSNlV! zT<t%eaJ6^JHnsPTva_H1)Dm1Kv!p27+id2vU-Iddou$i9JE?FT`whDc?44D^?JaL) z*-tu~YabF(Xx~+zVShm*++MFE(q8eLt9`kor@i?(SNnyLcJ|p>ruIb<cJ_{2HNat< zaLU!b{*<@9>L)+@;4gmmCOwh%n`Xz@|Lje+_rIBMZ*x1}{<J}veSBkv{qvbI_Clw; z?Q1Ng?M42I*?ZT?+uvDlU~m1~(f&uco&B72Q~M(uH0%qCgzVp#|FrAa%xN!HBxJvU zN!<SHUq^eUYgzVZ{uSA`8kX6=IGt;MWoC%I{SE_rrR^H_ewz*KjiYt!WutZMmp-<% z-yC6Q|Ldf;eVU}FeRi~+{pORd_RoGh+HVcDvv&!xvp*1KXRmVF+umh*h<&AIxP8#+ zT>I<S%k5iLs_oM{s_YrAXW7g3M%tfXak9Uc9BALH6mCCF%F}-PDOdaQNIU!Wn+@!x z!|d#DXPVm2+ht&H^~ulvKw6;v8uf7d)z{PPRT?ww)Am-_CmEI5ACD@uKNVhR@4}sG zzxJHBeb8nD`)*5V`=lT{`>w49_O;s#>_fI0*iQ+uv;UT?Y`?sS!QR65mYwc$7W+9R zLiWb%4eUEuob2O&7ui3)UT&`uU1%SrQevN$8gG9g%Ff;;)zp5=W&?ZmEgJUIn8fYN z7{u-4Q<d%0q66){J0k5xFSyzlGdkHj?lQ1{``;0qW`Csy+OM4vW52jN+5W+eH2ZGJ z9Q!2I68q=>i|m`4GVFy8CfetACfon{>}S9Df~&pX7eD)N(?Y=JEXpvouiR>2|KgdY zeV~}9{RIh6`{#-A_UW@i?74d)?Mv%2?DtFN*zYtbvp?ihYVYDxYX2yr(4M;?!~R=) zvOO!Kll|AN2KFh>E$!z-+S$vVa<xD4+|s@;(bV2#1E>AP?;GqGOm5jN%oVb)D;2WW z*{Wf`P$}GAFTBv6Q?11Qq)(~+9_1?g4cD^ltyrAwW49aF=RL8s-*Dg3elstheZTE3 zyQwF(+Ns<Aw2O-fv=3=Zwm&sB#(v``Kl|68{p{1y1MMe(=H{=b*?+Fju-_q(W54Bg zntkKhT>A<Ci|n<o=i7gn9b^A{MvT2rcclG~86ox$l*8@$x+3joNqX9Ed2R`w=j6&V z1^2(|Se@)|OpCEs%m}o9Deq~2zdPCf`}HjQ=SLFl1^yS=pZQp3Z*Vr({!x8~eMnlo z{n9Uf_S;W++kZIiYCliH(_a3QpFP)6Z~ObY()RbFm)d#CFR;5ScgXI{5*GXaf5q(O zn&s`&Cx_U-zma7>^K7oYrcbH;Tc1+<FK2S?XC%ejPh@biKbB@{|9g{$J^M-)`~T}7 z+8J!#YIok%+RpFR1-n0w{p@e21=_Fgj<i3!C(-`Wj2L^{nKAZ!J<0ZrH?!=cZ{*u6 zoz1oHi!8MNXHaH;?najV*3@`=&a6Ot^%)`d6M94Jxfz}8C#4438+`J!pBQatUy*KV z&k$i}pU&)L?>;rgeqCz3{g#w?`=hDx_GvfL><@$1JV@l&U-(~S|HZ4+-v4%%z240% z`>cbB_6L&V?U_;o?N#IK?ETKT+Sg7Fu~%PXV6U-ftKHnMrgm=LtL%bh4%zK~`O2=8 zo6r6@KcBtR9u50dm-FrKOXt|H^eMG}ky>dVlw4`QBQ4(korI@-XPT+~yigtcq>Y^R z77i!u0+&Cui(%}wJI29kXKr=NF7be?y@yh`J@3pI`^P<z_Kul>_G>i4?XBuF?9WQ& z*!%r2vY!FMH}dW4=f>D8%#5-BkQi@&@~5Ny&-+{L82*ac+b0CtHz|eNPm%Dnw~W@Y zmw#btul~u;{@e5z`=FUI_FMZR?H#YD*{|wJwx602Z=Zf6%l?&Tsr{`xS@tmzh4z|} zh4zf6a_!q^$JobT^tNA{7-+vY)6`z}kgL7v>sNMfze(6-$ZObTYuvKqyl}zp^RriW zBAk5o%xhWfw?4PDPj9QTx4&6#|7CxL{fAH0_F5{{_7l_N?dP0zwZ9v!W3OQ>ZU4aG zr`_~@5AB*WKH8Ow9kQF{zsGh{x2)aqZ4d1V*BjVNwMW`3%!sl7&>d+%wJ*|s-i<8# z;QvMTPM^x`Qy7ZvU!Bdh530?uFUk(IPwR-ZkKAZr&)(8%w|VwdJ3oIr`#Gmw?d_ji z+OOZLVSn$hqkXb+xcyYMaQnjUNPElPNc)}L$@X*7;_bKZOSG?<6JxJ?E6e_wXQ@5& z?R@)0gEITachc+=ujSic=1jF;^3KoRu~FXsmX5T&rOzt6OAk-ldKI_YDKhcdC+>P^ zcfjhFUG_2-`>dUu_J7{{+22&Gvp@Q&+Fm8S(%zw{-rnJKt$o6cEPI19-u4|SruOZu z;`X;gb?g^L=-6w9>DXV>khWhDrD(@6ZHaBk%1k@?SFh~8J+QP-n-*gKc~*$MMq0eR z<IODlwT5N(i8ssbbN5%+PuW{xKks&$z2V+O`-vHW_TDf2>>p?!va2i#w9~JZw_o?z z(*Evd4f~&4H0({XOzk~V0_{uF0_}5TJ?&@C3IUJN{ZkLOpFcguUTId0{nHy+_WI{? z?Y;gN*|*%vw+}s=YyTs>(7xwtn!W251N$j1x9lb!zF^1LAZw@UQE$6{HjDi!eQEn2 z8#(QJ-@USP<KnYF%P4N2F)hU2K&j6DWl^=gw_26`gBkVqb57UWZ&oU?|IOlLKX<c% zeO!yYy~in6d$&n3_WhEc_J;m;_JX@-+DU8*w>=#A-1aDIuU*nI7JG@Gj`laEh1mbv zn`r;@W}1CqRH1#r=Q8_e`z!31q*U6w+{m}zH9N+>WM+u{#I{I#+0`2MAK5GIZm%@3 zzxB}4ew_%Pz20U6d#+Qi_JN=L>@Q3Yu`f;wwExu=X)oIyY44pLXzzE?)!uJTi2d@@ zx%TH&OYDCbmD%5BD7G*2F143ClWSkdmTEsIM8`ft{*YbLq5``(xhuBowtlm%TC8E; zx<Lcn_jp~#U?0AT(|+qZ7JDyIPkWohO8b*WW%fmk#rFS~)Y#9sQE%V9r^5bCYM{N# zRs(y{TxI(k34!)&b|u>LO^&fY@YK(qQ~Q?P_JaAgyM_8}pE(QJ`6w)~`wKGjk)^%+ z^bq?u2NLa<Z>Y5QSXyI$Y=4El%AI`swSSB3Ik{8qH^_O~zeo+V-+j#6esY+Oy>hsn zed!ZRd#(&+`?5@B`|dxE_KIg+?S;>J+lzemv!9$2Xs>_K)&5^cr2RKJPkZnEiS`=| z%IuHbEVmc=RBgY!yUO0;W10Qw?qvH2F;Dxg<qY<=QVZ+~Z%Wu*a+`0<cKD9%yFz*U zFY7ey6V_;e`<~sKIqjLYa@u#d%iFIJ%(3T}%CT3tnQtF*C*OWbZJqsGuTp!xnIZN9 znWpx09$DJwJ+!os_qDS>7o=k!@>|SaDQK15n!x9_2j}|PdU0N{-DeqSXa8n{oy=BF z`?zP8_JT8G>|Z5U+W$7HvH!1HZ7*}9-2S;#j=kQEH2ct5A@(sTf%ZB~PWE1>T<tkd zyV{>jH?_Z&VroC%MB4t|CIkDz2s`^2F;DvgXT0ronVjs4&$-&4>yEUy-<N2gdNa#@ zvs#ILf@-yWi&~Yv*5@+&fUrXQq!}Uhj}uMpZ)|>OcWPmQ-G06|w*2$!Y$vVewmYwV z%dRqy!G4e4PrDdKK6}Yx2K(jQeD(&+;`V|c{OqH<lI@#sWZB<RF0ntex58fPTE4wQ zYM}kqR8#wHD>Ur8%}&@&dBknEG2YScZqO>bMS)B0N_jQxy7;Eq#_;voGGAq}JH4X7 z?)H|4cJ<*p_UfwP_BjS+_Pe-i?M2k8?Qef7v%hyH*M1jIs=ankq<#B2SNo-)Hp&@S zduB0D`<+`2?4PHY+RxzQ1J472=D}y~)Uel^6k@+B*3Q0N($l`QJJP<CC)K_;qR^iG zX1V>zo+^9IPu2ED-lg_OX2saoJ-4)<Tr6aNHh7g?0-uK6-^C|w-<B`2{aPSv*T~Ro zXIGYJ7x9k8ZpyiDw%Kd8+C{D8v_G_x#s2<!1N(|o-u6st;r6*{@%C%4rrBGmhTGqc zu(Ll>E^q%La+Tdrsn51E=ZD+wQTl9q@%?T)hcqGk89Qg%6)W$t-5(cj`-=UFZKI{9 z-G?1p?LrvD?fu^S*{k2ovX@Y;vRBw#Y0vq&%zpiieETCjsrK)a;_cTlIN7Hq=-3PW zb+rE(W@jH8qhr5ulZO5G5(fLvB|`Rd*BaQb&sMgN6!)~>BIXIs51_W<zwTuFgAs-H z;rlD>->FvHFWyvXpZT}Qo*^+FT<%3|;<Oi+SztFcU)HYs&OY0T61QwGOs%jp6I)>S zxK-BfvFtS4SzmZ<JxZ_JhOqY9@g2Wl$7S`?&SZmz{qo<A_5mln?M0*P>~)`7+8eFV zuwNUy%8q+Mrd_&|klnu~5xYGbw%Qpk*Ra13Z)(45A&b3ngpi%CP@ipK*%I4)HVwPW zK1=OhY~Zy2pKfa3b}h~R{PlACKbtD;zok^#``*g3pPC+T?>aNYzA)O(J~!0P{!OZ> z{q9_4`%e!n?LSot*$2IOWhb(Q(_XJp-hR&(4f|FRPkYY{Q+wy<miBJvUG3G<;_a`U z$+h45smy+cYL$JtVVQkfYP|i{C_8)QP#ydHb)5D*ZzkA%z9M0_Limd9-A593Ra>^& zoz7ygm%G2)PP0+O?&AKFwyg8n>|{6%>|T{5+7&<EU}y5=m0j{CPW!cb()P6_LiSM_ z()Q7DtL&z@1ln!5X=)d3*l2fs#a6qvO%LrP)@j(Q3wzo>k1@6PS6^WFCH%T=aoH@} z>z7#UrY|qBOSZUWw|$d_Jx_AHeZtLr`{dM0`<W?~_D61I*&AF>vu{ib1h+dhwrkj5 zi_)=ANinq-KkjP(BwgA5SlUNB*Ug;v)7NR(cW>9Q*Zl2h@82eGZ@bmN{{Lxjd+F|E z`x`g%?cIG!?E^oS*?$Zzv_E&&+up}Y+WzJ$7W<Ez9@=T=wAz{7kg%(-;j}Y<H^J^Z z8=w96zhd@l3mEK;pKh=#UNzHhKU1WgC9{TITkAJlo`({4jdLsPJ~U6YOHx~4*Q0U5 z&Ux=lyA#Q+b}P6H?B)m<*v+n-YWL~M20M1SLw28+v)CUx>}r2l$kRSmQ`-KBj)9$g zz<gT+$LF^1vJ>qTO-|Uk8cW;vDTUh~kjSw=`?1WvhoRX1$LU;q$DU;S8>xZzN)dMU zEm1o5{82jgceZQTU;X81|219Np2z%_U83nvyZ6S@_FH~9+B=8Z*;_Qp+wV#T^$EP~ zg;L|~Wv}Pk`$ZJmFXBtJPu-VjANk(Te)a|f`>(uw_NTW$w0pc|rk#YSwVj1cqn%{d zN4vFmE$vT%*695fv!8JBg5A^m8|;qXpJ2Djz|qcb`G4D8w?5f+Yre7F$){mATes0} z#W8NXBZ3BY+isiMS#lWIO`lj`XKvPL=j6H6?xV~CyXw?cc2)ny>~{y-+2_TW+S{MG zV7JrtjcvEs6<bBqK)Z*5tLzqT<+T4H>S^CqlVKnJugE@LrNq8SGRIzHf1>@hGv4+Y z+YIclZqcwWNQR6n1wFR3U(GCTpLOnn-E+%ZcEWso_B+=Z*hgh3+xu)`vCrf8w9k2M zY5)I|pZ)!PiT3}*a_ocB;_Xd9;{)3b>{+68><=`^+ds||vRB!$)lRUt({78|Ej!Iv zQ+xdruJ$z%I`;g0eD-&4y|OdjUSStIwZP7|Sk^A;oP^!fKk9Z`zx3_I_%!T_$~*1W z^jFxi{_L^)^`pnm!OqjJQm4_*WJ#vo+x0W;1iPl%^#^^lOEdjxr%@+wKe=AsUanZ) zzNEX;PUFu5+aOkJyDs?!cA6VG?GJ1*u(wYQw4cJ2YR`8o&0hRQmi^JaiS`_4z3o-f zP3>=HDBIuJs9`UYp=`e>-qb$5RLEZ7)CIfyS1#Dy<KVMjWFl>^w%)+LYNLj|#WPF$ zLy>m&M`G;knZNqkE2hTV*G!MGpA~0ke`%M7{iSqMd*7#)_UA)%?8976*vVhLV7Hxz z&wfd$oqhFjS9>FKY5T<-eD-rb?zW3=?6lj+9%)x@>S)KvU|@Ief~g(jMN>P?9}#x1 z(-Q3--#4{$G-|XvTRqioK1ZaTwxg%rmpPes=bufm^O9I#rxmu;?u7mVy9ic3`va?3 z>>ue$+gqyrwA<7tYiBE<VQ1jC$}W64i~ZaU2KIYiS=t+X@w1PZ83S(nOq~;A|LB9C zy-v8D{nB)0`?U<>_TGYg_7DDx*_W?iv6p+Z!S1@jEjxkSk9KAJeD+$QI`&7K<?Sz~ zn%XCT#>g3*>>s8C+W%D#x8E`=#@;D8-hR4rxczaJaQm{3Nc%NHp7t}=u-M<$m$v_y zrfk3Wr=z{ZBTIWuBWe2;B@FgkRzI{0eLca>Z*GO%^9dDp`^63H7EY+J`(o{Bmt*Z| zcVk+noeoE&UCg`+J5%>nb{Dc*?RJ|s+U;CZVfSSFOgr(QrFMlUFW8+lI$@V%am&up z=%-yS51;+U5_$Usr3H54iUxK(Pj=fe@$lI{Pd2sZ7xA>`IPY!WHYWt!hY?JUw|~gw zWG|gzYQHB{+5YqnPWw`QY5VdbA^U$8KkdHyuCfa^xMg>@kiq`&Z!vp^dU^Y}26_7* zQ9AY(qMr8UuPyCQo$<C`wl~rKmS~Q><c&1@+SxJoo?XfIR=tt-L1Lcv;#ETSEpevy zZ#HSz$EGOTXO;@t-`m7#zbNaY-G&Vh?T)ukwc}v!wNvWowA->}rrqMerFLO`opwU2 zD(sHfHri=6PPG%ikZD(b;ewsypAB|%zV5c;yMDoL%F9=FuU${rr7UEzXT5sCZi3Yb zyL{7IcDhzS?aC|U?c1^$>=$$=+9~hYYS;W*%zoPj1N%q&H0-&j#MnF5WZ2)T$*?z{ z5o5pooU47-aaVi8bY**)Vj=sbf5q(ci-hbeiW%(fEF0~*B@Wpgd;H37ruk31Yeho# z%#7mTIiKc#j`p`tdfN-LI@uS^h_PRh9&f+yK%%|cjWqkl-eh}C&Q$wUF;9CAHgS8M zG-dn03Ci{fB_HkPnEteTVffSTUlD`-&H@H|zONhX4Bqdy%iQ$PZe89-yYv6V><i+R z?e`yhXy>c_(@wsW!M^yvnEk8ge)g}W!|fH{_}TA1?rpFB+Rxr=lYxD8nzH?^RV?<? z(mvYlb~<7Aq?o}zVk@WpmjVWRDS=+Q*6myEj&bwZU)^Y6?=mUG{`u?>`;9YW?AOf+ zvG<u7Vs9<!X+IaV&dpTX{?uv~d&zPJ`@28H?7LsRvNIO2wwt$RtDWPS3wEz9Z`qy7 z6|xsE6|&DZmA3yFZfD>0(a%2Pi=VyKzC`;k`xEW&9!RuTt<SI*xs_%=r6bv1<hiB& z+hk??S%%W~Keut(=Nx=!XPffTPSNXx-P#SD_Ad>j?JfBD?28Sh?O&uR+b;;Wv+qub zw|{s(-@aQq-2QaEkiF(ZOM9PF-u5Yb6YZJAa_kH0GVD7~<l6Iz<=8*olW6~LT8Mq? zZ%6xPCUN`Bl`Qr#)$;cBb@KL{zr^g>ZBN)KC#<r|+r(+F)+%p*?VX>!KytkO$-Rm8 zzo*C8^UMsf7dho^pSDxOzA#nUes{dGeG@4C6fxM>DIKzN-1Fad?uMCmMPi5SK3Sfy zTblFHPFi2uKD1oO-sGvJ{gsb?_WEk!_Qu?)_Ah#p?Y((Z?IjyC>?eWN;j4s$`>N^d zSnTC@a@tQ#P`3Z6D{Wr{8uR`oX1{PBr~U0mmiAiDE$t&jJ?)=MdfKO4O0%z*FR?dO zF0q%pmSx}Z$<JQ$yth4fV!ZwC?TPjq8B^`+&!pKOWk|K(RGeY|-m}m?jW@@>qb1os z<B_Gkq_MR9*(7Cq&JZ2@<>f;5TYrk#f3^H+_sT%pUSgAh{mC3t`~0*(`+KuP>{(}p z*lT_Evv(Btw3q(vXn)U4+P*+v+P*sPquu-YEcSZxhwOIj+iE-K-UPdc&o|ipT=UTG z@B3GFD=OseLw0f6pM7j;-*m>?{*`LDJp*^DeM@h$eU(Ix{qh_6_AjpG+i!gDXP;>% zZSR|?Y_GIV!+x`gw0+4xG5dS}#q3u_>DV8M3$%AljJLOsi?<J$6k=b~6Jo#rh_}7& z30Hfaz8L#6B^mZT7qaX>Zb`JyJM3yNQ^jC^_3v&w2g3z+9@D4V#p^Awi~hU8uB`Z@ z-Q}IG_BWH1?fExy+Ap;EX=i6BZEu{cY=5y%-rlHK$X?1!+P><ztNpb1e)g@?V(cq8 zQ|+zP!|nOSJncQ>b?j&SaI{xp61QKonbY3-)hjz^(_40IFLv84k?FJLichp#DYd{Z z%J7z5+hP`bIbJ^duL6AbCm&ndv!3?0clzpQubCEaA9yg)Uh`&_z5R`R`@YNh_QKl@ z?0;1=*ca{Ov|nB?Zy%^9ZU4*lr=4`Eko~eCJNwNt;r55c!|hkDGO*VyX0SIiUSOxD zvB2)hluo-vGp5?DbiQS`ZiR;Zk}aI};ny$NS?-x>ccN;loyyEiyCqjm?N~0G+SOk+ zwR;{ZWXEzO)6Qi5R=Z_^OYItE4%u0(=d@P?%_$}++q0Jn*_WA0+aC_M1Gia3WjyV@ zI8*H{+mh|u_G;MwZ<4oP9;Ra-!_Q~mx`M^tTKA_N(}fFmZ$nnuJ!-DAZC=V|SNvpx zorm!WyVr#b_Fh{!?Kd-s+lMBb+Rr=bYOkFZXn&R~)&5^yhW(3%40{LuRQulQ4Er-% z4eSLfh3wNpbnJ5jb?g^8{Io0AkhYKI<g=fcCuASEh{b-|l&N;fS&DXDVg`0yW{!4; z^aAZRuo&2#<1nx*&QG-a%+YK2v!l~4FSXT9)+Er5zd+V5YsG(CX`AP^SFN7gI%a>f z-IKs+=d$>}ZR|omJI4nsc53qq>^=)0vP-wPWw)N4&)$fK&wjg^wEb66PkWOy-u4qO zxZ2O{iL^gFBgVe<ji0?>i@g1wT6ud%K0f=i-^J{!?QYrCK6qu<bLN7b3R9o$<N71E zDf*3e`?hVhtIB7vZ{y^%zx+?kzTQaM{%?!CeY%9FePma%J@4%_`{l|d_E|Ub?d@wa z>{n--+81szuzwn=V_&#|(_ZWSZo3c1F4zgnF0i|t)oSM~YHcUo`ps5{?TYQr(j&ID zTvu%6AMdlBRCL7lA;%Tl<Yy0Tmsu&=J=6%ayS$9gZoBJq+y87=Y-cXrYU|Fm$#z%C z8r#DqYiv&xtg%&054Yv46t+F%Z(tjxbj6m(*U|3py9suDA9mY`e0*h>o2G2PZ)%9W zUShm`#EcO8s_8NItEb1<%ZPc}2RF*wGw$HD|Fn$7{*>`gy91`T?7SYnvh&oxWv5+G zXWL#i%XY1Wqn-Pjt#%wHx9lAEKeQ9%;Ip4t_R(&mAfNrdzmE1oGh*xw#B=OTBMR+L z+{m|oU6WzINW#<p>`_<y;u?8-A?*cr7K;n)<}gRvT{XC6`*Xr9+eLEIY}a_qx1C)- z%Qi}AkL~OBBeoVzM{LU)*VxXN*kt=c;EJv0lK-~9b2;tWFSFRadiTKA<JL*r+=X{+ zJtu#&{ZqhcxAOvvUDwqAwrZx&ZF45vv5mdWV#n(tWGDQ1f?e^m4R-sCPuOuRWwGC~ zRm0w?J<|Tp1#kNpRww(U&wloATO+~qJ10z~?Va?b?dLCLu|H*b%g)C7gx#c57wrBA zEw$_U(`&22+h<#t&uJIYFx5^(|CXI&K7;+GVg~z#8#wJh{TH*BeQIfM_}R~XQEI&X zZ{AdUWr-a7tm!fKg4w3_Y*9M)VR=IKSDhQ}bOIFZ3fA-4v8rCN-7I*;wtNPg-N~Qo zcE=bD?9N*T+Ic;lVE4YR({2H0q+Oh;r`=yiN4vwK8g{iJ8g_Bqk#?6_r`qW*d1$A8 z`<0!_p$m2lj!W$x#wXg{z9wO(`O4HTMD>K-OSKbr`dw4)){7sq`>J=#uKVi-yZuEB z_S(UA_My{b?4>)C?bj%W+jE|EwZH$|(tdBVy#1kCdHdyCIPIOye%dX6@yhO++D|)$ z6Bq29*n91+-N>*F|2x&THgLObbW*EbpWX>O_eZbn;<rDv>(2aW7rU9$zIwfZ{i4&Z z_Chm5>@~Pk?PX8q+NXc_vtRby(*DmT4g1z*EcW-`Y_PNQSY;RPzRGUR-yXZaR)Ka~ z*bVH=^aAZ3>NncSJ>FnvvYgX?<BL~zTTWfDdmFaYF7o;-yEv^|b~_~x+1)fdVOP3_ z)Bat)kiBb(ynU|1PrEa@t#<OZfp(f<j&=u)PuS&V3fa%e`)GIB_@~{poR4-tR&m<z zJafTLQ1_6X$VLr&zNs<x(>s&xIa31dzdpCL|MAGup0`=v{(7~%eQ+6reP}U*eXqe! zJF`m{?6z&*YPTn&)ow~koh@U2ovqsJI@_n`P3;n;7TB#meZfx7^p@S(%@6Hd?_aQc z&Ch4QDB0A$lgSCZHsG6Bjy*$lhW$nfPy5(JQ~QJp2K#$Px9pzUp0LY%^2%=i=?iuz z)@-%gy{5p9P1L~d6-T7qQuzgT%8OX+ExdK?C;k$%XMX$2ZZ;dAy>>B!{esn;_WFw< z^W?kNbK1vkd}t?lG}A61(9=$$venM^@&&tNG0OG|Oyc$?b@KLq?^xQW*2vpWE%<0x z@L{*z6^j#gTlx9yttN!nUsnvbH_kG(x8I>*e=$<W{`EQy`>8y9_BB>N?PhM|v_G_% z#opKWmR-==t#&Lffp!aX>uh}zX4$@E>$6pT`@mMUYO0;ai3@hz4`12+P5o#G+9!FB zm(TuZle~S^Z%2DpSx@`Gy@~d@9m)1@8J+AuY|*e+`YmQ3`{|XP;!iPqj};pB>zA<D zcbnd_+j#Yr-CC|*yDcJ-cAVl1>`v|8YL}n+(QbE^ko|4Y{>#NI_B{qa?WAs9u$z7T zf}L%;kiC`T2|J#MRd(w>O|XkoIb^qHsfNAeS_AvchnDt1P4f0~E%Nrag6!<U>*#-p z*;`xOva>QjVHce7(e87Kvi-IvmiBwL7}%SAceH2RtYJU@pP2o}Ll5l?m$KNm<O<pE zFJQ30uXD>zb<0e<rPhviIsbcYng36<{m0yATU))xc9mVAo%;RVcKgp=u+w?^%I-@E z19<(4rLnaA`Ry9^!5{qWw|w@qcm3pNe_g=SzH*I*{mbPn_9Dd$_TF1K?I#oq*`F(B zu>Ws;%Z_ysi~Wvl278t76YMOd7ub2JEU+`&wbgEZ!cx0)CokBY`mx*Y*}GSE-gyl6 ztK<&ZMIGI0H+|bfJGGRLcE2(|+C8q6w>Q~jVDG!x!2aGtOZ!J#H0&cb7}&qrqG5lc zNXY(Ko{;_1q>pyb-t4wJ`)PyS?02v1cCXQ}FG*Fl&jqcuGL*IlwRfhzePt)KgvI`R z#z(tKg+q4peOB2$Fl@9FbWpV0#L#EE_}^69p#M{C-6f{ke$WlH<9s#2&cfh?-4csi zc6RGI?Kc++*=Lsu*;hpB*e`F6v={sDXm6KnYJYV#i+#u6-F9#6PS~w8_-R+XiPK(0 zSK2;yDT{sl^H+8&&3@W_`z~gGRpX~!yYeBslkp$z&ZT~|W4Lg^F8lCSyNEmn`_FDV z_RrUF+W&jI+ivOFhj!Y9^7d6f#OxRS5wo8gs$<_2U<V$v$Z3|h?~Bl}x7=)CKPAT0 zzR&!S-LDs~>?Uk`Xm{$|1-rl(yY0*r4%yvY!eYN;E2lj#s6V`k)4p;Ai~Z4J27BhE zEcWdwAMK2v@3!-5?zBs^b+qF<Z)(TH&}S>l&}aMk?^N5};(fMDbv^B#nl{><6***Q zxbdOg<E)Q%(Hl7JgST+n=bK8~?+mfCpVTUEFKj4n@ACGQ-72G7c0G??*+o5lW%t0~ zr`@upEcORqys~?5am$Y7#Vfmr#Vq!{FJ9TLPWouKJ6p(JHd@(!7Bio{LgYugVuKTQ zSKn^1ll5O}H}ClbJBGHYcGF*PunUh{Wj8tHqg@;qpZ%FFoc8BdvDnXK5VyY^u47-c z(ZJq&orZn+`&V{x1q}AB1q}B4vl;B0We(Y0j#_FLZE?%)0~??HHtU~u<)2^Ksr(SL zf4rX4zGx|n{XgxWc05ma+sUQ1+I4ap*uD4_VYlyJuPt|8oh>LIM2Yp;{!;a{TgMY= z#}u&CZuy#rc3KG^?Rd67v`aDkX_r+fWZwsxmrPW)58J|NU%B(4o!rF>cK>5O+F2_f zvJ+4~WcOYBr`;mkTXuerU)j}eerQ)|a?5VP$qRPjh9~T@KJ2zrTJ_NG!Iuekd`~CX z6^K~d%@okEJ9)*_uKt>-o$r(ayLR(NyMB+QcH3X>wktEZWjEvc1-rZEKkb-HgzQx} zYJm4?nh5aOUo2p-U;XfvUGTbxcKekM+1Z(%u=}TZ%kG-xEj#W~2K$t3A$yM{EcW(B zKkc|&PuP`e{Iq*%c*{=SZ>e4NoJ>1KXGJ^riJ5kle|v44vg>U3{_C~1;_I`$WTa>} zD?ib$({+{I0f|F)(k3VD!uM>oi`lc)j&<upyZM}a_9x01?6a4$*em8S*q<~%Vb`I5 z%kIC<Eju0gLv~uvUfJcW;k3V$@zGAj;+Eakm%Hs=znfsE%GztUuWqWHKx3!fMP6&W z3N{Tpi?#o4C(q)uW1Por=e_2?t*xb^-87>>JKF^nc5mF4+7)Omu#+~wWoO69XMgyg znEi`XW&5*hHS7;@^4T9Zyk+<7`vf~H<pp*jMknmD^lsU49o=eIl*?fMZWX8fO3Pbz zkxyUQ>6+iN%e?W*&g0!~yE$Tq?6z;5Y4^t>(2j}O+D<w-(e8Ujo$Z61I@^lBy|$X2 zb+%{b^V!+opI~RRs=`jtXO&%$<RQC9%OBc(ezn2wQ{+;+xes31RX=@YXQ}(suFd$C zU1`WFyRSj3?9?R=*%?V4vRh|-%TCScr(Nb^7W<j2IPK%kU9i*T?6rGo+Gv+OBhyZl z!`kjKqk-L|`FwWMSNylVVIpMrBURS!cn+tXZyu*zg|(txfTgEh@a_V;Qx{*^O<2HU z-^|Hp|79De{kuwe`#YOC?JKuDw6h6aWvA`8%C2eiRy$SwTXsvIys}e?`e+wxbjwcQ z!v?#x-zV6~E_-Nq!svwEoZwY<Qv#RTeObNL&ON==?iH7T-F+r&yT|_`?CkUEY<K>e zY6~g{Z?pE<DjxrD+jM2Oovn1FUBBo8yWcN2*iF>BWw-44Zad$n8|*GT*=_g!#csR4 zlNan>=%295-n7;3t<NgE_m4N&wLjlr_rd6d-HG)N?Y?Y!Xt(j&1v@77pLU5acH6}_ zPPG%1H?VW)k+r*M6liC_p<&l?($ww+yMdjruBTmruBY9nOQv=jwvKjl$`kE)?`*IW zI5yL6`Pbccr{2G^`_08?UsT3mzw7xcyR)x$+ew8iwVR=T!me=VR=fKbF4*0T{AlO- zX186(^WAoQ8@Jj$mtJ7EBxsdg?}n{*Dl!Y~bRTT6vu>PfH+5QpT{)MA-77;+JDv1I zyV$=|Z4(*$Z2A86+P+&5XZyt6+V0+rhjwOL3+#3`cG?v@+F&<%+g3X!kwbQ`w$HSi zk>6^U-!#=OSZ0CUvK=$+u07gdXSHpn-G$apJD;Yhb`DQA*j;$B+b-1Pgk7Y~3A<dq zpLTEVzp|Ti@`7E>^WAoZ;y>*cdM~vLT9j#*!5V4zDz??`oTH~*0av7*Kzgg)2Z;rC zFJ5l2`(k^-?)j@%cBbn&?KumD?61Wt+n-y`V(;|ym7VLG4R*RuciW}JeYEqqe!(s) z@}u41*SqaLcTBZoe7wPK-O~+rmA<R&c-CySEB0P$SIX9FCnvtZZem)i-3)6-yICv- zcHX9ecB;v(cA&Zs<o^plr`m2mUvGPTZm#`0<3o0PJXhIy)g{_Jb6;v__-uon^yA%j zsoqQNrq@rk+x={UU5w}gJ9V~RyI=P=*hTp)wfo)NX;+omYA617f}QY-4R)EvC+v!~ zf7(4LV6g8ryJdH2{X@H_rnl@4#C)`~d9%T8q0j=mlBE@PW%ZqQS`R1KtrS{d=ev2U zoydlVc3akQ+J9c9VZSHZ)P7Tmko`w)KKmalSnPMK<+Qg_|7ph<ved5o#7sNo)tvTD z=|c7l=P%ej-LTb8vT3TF<Mx?$ZC<PF^xRk3eQxixvtaJEtKBfuPEKTj-ByD}J04bR zJ5xq$yCRlIJDw*K>>B^|+JdkcZ>DYe=|sE3j3xHLPcGP5sok>E-<E0T($Hz=;I+!m z;>iZPBRgi=O{|-0cYA4to$iwfb_!1?*xhfQYIoz#Zo3KM3+xJ7JMDgZtg_oEc*w5q z!v;G}{hxL+MGW@IDu?VuO>fy5X#TXjef5G}{D}*8ioCsc_7V&17PI%-xo#}5o4u>T zZsV~Fc8PjF?VKwZ>~$OE?R__C*k=pz*|RKTu@`&t%Fa#YkX_Nft#)ydOYJ;wzp~5N z{?N|S_=KIxrwMjDH_o&xYw5Jx=(^NSZSzdKu9i-__L`}7u}>!0DKhlhWu~^;shNA) z9c9t5GrVMKXSpELZh_ZQyZGA~whzBgwLSI4$u>c;)ZUd@-2U&C3wCc-KeS`=S!!1o z;%OHkvcPVN?<za7JG<?yw#>BCGi|h6JHNtC#JJHeC8O2ut;bTkq-`_pgj%NBF-tG7 z^HyA7r?`Eq-LnNO_L1Mk?0?_6V7F@fLp!y%uk3QtKH3%LGuU7Jw%cyA(Ji}W_g~p* zoxK3=-|WA3!S1T{PdoMhV)jZ8E$v0pOzmgiv9!N#`O~iF({4Mnvlr~jRDRl7Y<XyR zb`gtxO7urN(TSaQ=U30P%T8~#`;*dYSCH9iSMa~b?w?ts-Hp0VyUPnJ?BY{e?OskQ zu=6XFwNuZNwOeHAX?K>X*RJO11v~4%y|z(|(`+}mZL_WKskdLf)X{FA&>_3T4G-;j zj$E)?kl$)&($r~J@3GYG-L{!_?jj59bQ?PD{0$oIVzU$NuH+@!9boFUJO5~d9RvR% zJKZN6>=XnK*=-74Ww*lqgq{5+PWy^qV)oUALiR1c#q5h$vDo+i6|>(Er)+<mkI()~ zk&yjfZa#ah<t+Ajg+lfbYc%YuEu`(`g6-_*r<&R;C7Rl&TmH1`wmo6ze))pk&YKtP z_}{&<i(kuWA9((P-I`4^?Iep6?YL|M?PPNj?Y#6G?Oy!pv0M0Xf}KNZtDT=wqg~6S z3cDw!j&>)rW$mJk9qp7%8tvxzud-Wm`;{H2?)MY#v%R=8(N4Fd-kz0hhi!?+QoDqx zk9Ml(FWBuBJY-k7J=1Pk)l|En=M(InXSCY=N@=x|<B7C8#Sm$CF)h)~`hSnzpL-kZ z)Z3@p{VZs;>-Sw{x8=wMyL*pc*;Q`jv@icB1|CoQWGrp}+(6oX0kgP$<$42q)d(H? zf<#k$olqV7?Tq5~AM51ptG8*`gU(&C%Tl)AmZ5B)6s}_*TghNAxRKM|CR@n9B1g#n zOrgB}{2~VX*%F8Btm~%Q733z`eV&nN*E}K9E>K9rZfa_xUG0nlJ3j76yKNII>|U5T z+O5r$wTsFZu~W781gFv9!x!w9o1d_|oLFbe?h<bs;ICspGrZdVgORiC9fL-@%ry_~ zf=zDOS*&_!*CM;XE=eNN?#A+&c2S@*tG3gwDXG<NvPGbs>J3vnp6L~Kep_bR&3~}L z&O~B?o!Hiy;Poo;>mS<XS^l&WEfTU<s*|^u4A-$YGnclvOjEWO+hkxb7p-IeV3UEp zN0u^pFG5(Wy#3q05c`1R-u7>zb?l{bl)>$PUPf_y&!1xU|L$C{+n{*JPTOdK-M1wV z?f6@#+Ig+WwELQwXm?kq(T>l;)2^RG!|t51ryVy_q@CNO0z03HnRY(rigq5?S?t2E znc69{_1bBx-Lf;3J7m{+@`Bx~6B)L7frhr~`^)WD3zgX4s{3LSUL#`1as8Fu)=dxX z{%(F~_wnj0yCa>6c8QLGcKJVh>=?}&?MiDp?KaNLw5#MXuyb~Bv|Cp_)sE}Y2D@Y8 z3+%iZdhPbuG}<Yhy<j(eJ*U0%7Eb$9r9$?5{q5`*tv9ew-=JZyo@i=+Jk1om_Lw`= z&c1T9hP}@w4f`{H9PO|EceLO1#M0jIm!p09HVym05+VDVRV?;d&tBPCoV#Eb^LV%2 zalch|dsh^I-Q$v*Xs4Z?Xs2ZCX}4bA)9#tEr=7Q9pxt7lKs%GaR(2-WSnST;lCU#s z?zG#v_#wDob5Z_~-94#8c9tn|ww!Gdw%RM}?Oz<rx8Jb-mJR#)t+u-_zOs95ddqIc zwug3?w13)t*muEBMbFx9A1Hq%x7tlHZnT?R)oC|tT7lhiD^I)P1qF7lj;rjxF!b69 z&8e_kS(#|}?&t+O77jl9n=4rCx0Ny2Py8olANEJg-lF)U-Tm#H_7Z`1_GZGK;JsCa z4f6I`LVWhxnacK{eYokl%Jvt7?d;bkncA0^3EBUSR<;M#rA>EU*{yoM!S1B<Dmz}` zNV`{6op#qISJ>IbC)zz>H?XTQakSIW_q2P=Vr?g{?Pzy%A-CP;rQCMvOEc|WiX5^# zXnM=8G3le-q(`sp<|rJpo3_!>c8TW#+pr7u_Ipoc*}vm{W3zDcD;sZx6LtY6x9s$F zf7+c%|7dr`<d)qwwG(y*dXaW-XJpzr<R;o#%qy@fs_3-4&KhYaVdH6M&lzc_HNC)Y z_moV#ZYNJWqt2;zo~t?SbH9t(YnuPG<9PAPZqe3<c5BQ}*hy`BXjj0;XRn;1Y_Cuw zZ~vW_&%T12&t9iS-oBtg-kxQxhW&PPY5Szr2KI3)S?sSG{Iu)*xWVq(>aBJMtsCv~ z7Zlh@&d9V|KQq&g(ah6s0=tG?Eu(?mT#Z0GeRc!8RcfAgH$mg&OW5ox103yAg%8;Y zYyPxrOZjLQoBh$wXfca@)6-XWY3>VbHMe=&hrg}2FFBrXKlv(~ZGq`a>nmA_cFH=p z?0B+1+8tcX0`AWoc>c=HD3!rJ%OuiHbZUj2|Fi<T?A$~<UEM~zh0`<b@+}<gHko+Z z@pD?+MWiI!X)i6XbJ)JsF2MYjU9IX*JGot3?OeqV*-0rZu#<ha!ESZjM>}n;pLR#p z4%t=5eY9I(b<57An8ALA$xpj~RzK~eHgehv6$sgzzj|f2(%^($P~B9!t^iNFD`lN_ zT8@EsKavvdp2sEH@%^{5yO1es_voLx-D?&NyZyiQ?P||U*ljA|v@?^pwtGGAq1~#) zk9OY-f7(5K|H>|Y1E>A-^_=!%FJIYBRVcG($*Z>y{$Fo@aCL?K`A?a)3w~-^zqY(( z%dd6I&SO2N{h>{q_8&KJ+V3c0u)k^i(~djnqn)2sqn)x<pq+<lpj`=Dq@9><qaDXJ zQ@gtco^}crj&^nZ6?T`L0_{X47ud~vw%cyOv)y)%j*WJ6)@-%oc{{=Gh}SB+)d5TG zuG=@-b#5%M6MeqH4s;gZtk{os^`Ccx`w*AyPT0+P{>sj5?L)gWot<`zoILH?i~{W* zvPar==rr18S~}XDVb!p!z93<@#Z<`dYr3qR(jR?0!E{+Wm9776`=(~v-QYcBx9ZU= eJMHw3c5%fF_U)W}_V2j(>~qb2+A(c=Xa@i@1TP!_ diff --git a/bob/io/base/data/torch3.bindata b/bob/io/base/data/torch3.bindata deleted file mode 100644 index bbf2b2d8507213774b60619f6d5469d2e0feb423..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40968 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 P9D>d|1f6*ZI{Od+&i7s! diff --git a/bob/io/base/test.cpp b/bob/io/base/test.cpp index 5b4acd5..559535a 100644 --- a/bob/io/base/test.cpp +++ b/bob/io/base/test.cpp @@ -48,10 +48,10 @@ BOB_TRY input.reset(); if (blitz::any(test_data - read_data)) - throw std::runtime_error("The CSV IO test did not succeed"); + throw std::runtime_error("The HDF5 IO test did not succeed"); if (blitz::any(test_data - read_data_2)) - throw std::runtime_error("The CSV IO test did not succeed"); + throw std::runtime_error("The HDF5 IO test did not succeed"); Py_RETURN_NONE; BOB_CATCH_FUNCTION("_test_api", 0) diff --git a/bob/io/base/test_file.py b/bob/io/base/test_file.py index f58ca5d..12b2485 100644 --- a/bob/io/base/test_file.py +++ b/bob/io/base/test_file.py @@ -230,92 +230,3 @@ def test_hdf5(): transcode(test_utils.datafile('test1.hdf5', __name__)) transcode(test_utils.datafile('matlab_1d.hdf5', __name__)) transcode(test_utils.datafile('matlab_2d.hdf5', __name__)) - -@test_utils.extension_available('.bindata') -def test_torch3_binary(): - - # array writing tests - a1 = numpy.random.normal(size=(3,4)).astype('float32') #good, supported - a2 = numpy.random.normal(size=(3,4)).astype('float64') #good, supported - a3 = numpy.random.normal(size=(3,4)).astype('complex128') #not supported - - array_readwrite('.bindata', a1) - array_readwrite(".bindata", a2) - nose.tools.assert_raises(RuntimeError, array_readwrite, ".bindata", a3) - - # arrayset writing tests - a1 = [] - a2 = [] - a3 = [] - a4 = [] - for k in range(10): - a1.append(numpy.random.normal(size=(24,)).astype('float32')) #supported - a2.append(numpy.random.normal(size=(24,)).astype('float64')) #supported - a3.append(numpy.random.normal(size=(24,)).astype('complex128')) #unsupp. - a4.append(numpy.random.normal(size=(3,3))) #not supported - - arrayset_readwrite('.bindata', a1) - arrayset_readwrite(".bindata", a2) - - # checks we raise if we don't suppport a type - nose.tools.assert_raises(RuntimeError, arrayset_readwrite, ".bindata", a3) - nose.tools.assert_raises(RuntimeError, arrayset_readwrite, ".bindata", a4) - - # complete transcoding test - transcode(test_utils.datafile('torch3.bindata', __name__)) - -@test_utils.extension_available('.tensor') -def test_tensorfile(): - - # array writing tests - a1 = numpy.random.normal(size=(3,4)).astype('float32') - a2 = numpy.random.normal(size=(3,4,5)).astype('float64') - a3 = (100*numpy.random.normal(size=(2,3,4,5))).astype('int32') - - array_readwrite('.tensor', a1) - array_readwrite(".tensor", a2) - array_readwrite(".tensor", a3) - array_readwrite('.tensor', a3[::2,::2]) #test non-contiguous - - # arrayset writing tests - a1 = [] - a2 = [] - a3 = [] - for k in range(10): - a1.append(numpy.random.normal(size=(3,4)).astype('float32')) - a2.append(numpy.random.normal(size=(3,4,5)).astype('float64')) - a3.append((100*numpy.random.normal(size=(2,3,4,5))).astype('int32')) - - arrayset_readwrite('.tensor', a1) - arrayset_readwrite(".tensor", a2) - arrayset_readwrite(".tensor", a3) - - # complete transcoding test - transcode(test_utils.datafile('torch.tensor', __name__)) - -@test_utils.extension_available('.csv') -def test_csv(): - - # array writing tests - a1 = numpy.random.normal(size=(5,5)).astype('float64') - a2 = numpy.random.normal(size=(5,10)).astype('float64') - a3 = numpy.random.normal(size=(5,100)).astype('float64') - - array_readwrite('.csv', a1, close=True) - array_readwrite(".csv", a2, close=True) - array_readwrite('.csv', a3, close=True) - array_readwrite('.csv', a3[::2,::2], close=True) #test non-contiguous - - # arrayset writing tests - a1 = [] - a2 = [] - a3 = [] - for k in range(10): - a1.append(numpy.random.normal(size=(5,)).astype('float64')) - a2.append(numpy.random.normal(size=(50,)).astype('float64')) - a3.append(numpy.random.normal(size=(500,)).astype('float64')) - - arrayset_readwrite('.csv', a1, close=True) - arrayset_readwrite(".csv", a2, close=True) - arrayset_readwrite('.csv', a3, close=True) - diff --git a/setup.py b/setup.py index 5dbcd6d..04ed2f1 100644 --- a/setup.py +++ b/setup.py @@ -141,7 +141,6 @@ setup( Library("bob.io.base.bob_io_base", [ "bob/io/base/cpp/CodecRegistry.cpp", - "bob/io/base/cpp/CSVFile.cpp", "bob/io/base/cpp/File.cpp", "bob/io/base/cpp/HDF5ArrayFile.cpp", "bob/io/base/cpp/HDF5Attribute.cpp", @@ -151,11 +150,7 @@ setup( "bob/io/base/cpp/HDF5Types.cpp", "bob/io/base/cpp/HDF5Utils.cpp", "bob/io/base/cpp/reorder.cpp", - "bob/io/base/cpp/T3File.cpp", - "bob/io/base/cpp/TensorArrayFile.cpp", - "bob/io/base/cpp/TensorFileHeader.cpp", "bob/io/base/cpp/utils.cpp", - "bob/io/base/cpp/TensorFile.cpp", "bob/io/base/cpp/array.cpp", "bob/io/base/cpp/array_type.cpp", "bob/io/base/cpp/blitz_array.cpp", -- GitLab