FileRun.hpp 3.12 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
#ifndef __HEPNOS_FILE_RUN_H
#define __HEPNOS_FILE_RUN_H

#include <string>
#include <limits>
#include <boost/filesystem.hpp>
#include <hepnos/FileProductAccessorBackend.hpp>
#include <hepnos/ProductAccessor.hpp>
#include <hepnos/FileSubRun.hpp>
#include <hepnos/FileObjectIterator.hpp>

namespace hepnos {

namespace fs = boost::filesystem;

class FileNamespace;
template<typename T> class FileObjectIterator;

class FileRun : public ProductAccessor<FileProductAccessorBackend> {

    private:

        friend class FileNamespace;
        friend class FileObjectIterator<FileRun>;

        FileRun(std::uint64_t runNumber, const std::string& dir) 
        : ProductAccessor<FileProductAccessorBackend>(dir)
        , _runNumber(runNumber)
        , _path(dir) {}

        FileRun(const std::string& dir)
        : ProductAccessor<FileProductAccessorBackend>(dir)
        , _runNumber(0)
        , _path(dir) {
            std::size_t i,j;
            j = dir.size()-1;
            if(dir[j] == '/') j--;
            i = j;
            while(dir[i] != '/') i--;
            i += 1;
            while(dir[i] == '0') i++;
            j += 1;
            std::string runDir(&dir[i], j-i);
            if(runDir.size() > 0)
                _runNumber = std::stoi(runDir);
        }

        FileRun() 
        : ProductAccessor<FileProductAccessorBackend>("")
        , _runNumber(std::numeric_limits<std::uint64_t>::max())
        , _path("") {}

        std::uint64_t _runNumber;
        std::string _path;

    public:

        typedef FileObjectIterator<FileSubRun> iterator;

        std::uint64_t getRunNumber() const {
            return _runNumber;
        }

        bool isValid() const {
            return _runNumber != std::numeric_limits<std::uint64_t>::max();
        }

        FileSubRun createSubRun() {
            fs::directory_iterator begin(_path), end;
            size_t subRunNumber = std::count_if(begin, end,
                    [](const fs::directory_entry& d) {
                    return fs::is_directory(d.path());
                    });
            std::stringstream ss;
            ss << _path << std::setfill('0') << std::setw(12) << subRunNumber << "/";
            std::string dir = ss.str();
            fs::create_directory(dir);
            return FileSubRun(subRunNumber, dir);
        }

        FileSubRun openSubRun(std::uint64_t subRunNumber) {
            std::stringstream ss;
            ss << _path << std::setfill('0') << std::setw(12) << subRunNumber << "/";
            std::string dir = ss.str();
            if(fs::is_directory(dir))
                return FileSubRun(subRunNumber, dir);
            else
                return FileSubRun();
        }

        std::size_t numSubRuns() const {
            fs::directory_iterator begin(_path), end;
            return std::count_if(begin, end,
                    [](const fs::directory_entry& d) {
                    return fs::is_directory(d.path());
                    });
        }

        iterator begin() {
            return iterator(_path,0,numSubRuns());
        }

        iterator end() {
            auto n = numSubRuns();
            return iterator(_path,n,n);
        }
};

}
#endif