00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "PSCalib/CalibFileFinder.h"
00017
00018
00019
00020
00021 #include <algorithm>
00022 #include <limits>
00023 #include <iostream>
00024 #include <stdexcept>
00025 #include <boost/filesystem.hpp>
00026 #include <boost/lexical_cast.hpp>
00027
00028
00029
00030
00031 #include "MsgLogger/MsgLogger.h"
00032 #include "pdsdata/xtc/DetInfo.hh"
00033 #include "PSCalib/Exceptions.h"
00034
00035
00036
00037
00038
00039 namespace fs = boost::filesystem;
00040
00041 namespace {
00042
00043 const char logger[] = "CalibFileFinder";
00044
00045
00046 class CalibFile {
00047 public:
00048 CalibFile(const fs::path& path)
00049 : m_path(path)
00050 {
00051 std::string basename = path.stem().string();
00052 std::string::size_type p = basename.find('-');
00053 if (p == std::string::npos) {
00054 throw std::runtime_error("missing dash in filename: " + path.string());
00055 }
00056
00057 std::string beginstr(basename, 0, p);
00058 std::string endstr(basename, p+1);
00059
00060 m_begin = boost::lexical_cast<unsigned>(beginstr);
00061 if (endstr == "end") {
00062 m_end = std::numeric_limits<unsigned>::max();
00063 } else {
00064 m_end = boost::lexical_cast<unsigned>(endstr);
00065 }
00066 }
00067
00068 const fs::path path() const { return m_path; }
00069 unsigned begin() const { return m_begin; }
00070 unsigned end() const { return m_end; }
00071
00072
00073 bool operator<(const CalibFile& other) const {
00074 if (m_begin != other.m_begin) return m_begin < other.m_begin;
00075 return m_end > other.m_end;
00076 }
00077
00078 private:
00079 fs::path m_path;
00080 unsigned m_begin;
00081 unsigned m_end;
00082 };
00083
00084 std::ostream& operator<<(std::ostream& out, const CalibFile& cf) {
00085 return out << "CalibFile(\"" << cf.path() << "\", " << cf.begin() << ", " << cf.end() << ")" ;
00086 }
00087
00088
00089
00090 std::string toString( const Pds::Src& src )
00091 {
00092 if ( src.level() != Pds::Level::Source ) {
00093 throw PSCalib::NotDetInfoError(ERR_LOC);
00094 }
00095
00096 const Pds::DetInfo& info = static_cast<const Pds::DetInfo&>( src ) ;
00097 std::ostringstream str ;
00098 str << Pds::DetInfo::name(info.detector()) << '.' << info.detId()
00099 << ':' << Pds::DetInfo::name(info.device()) << '.' << info.devId() ;
00100 return str.str() ;
00101 }
00102
00103 }
00104
00105
00106
00107
00108
00109
00110 namespace PSCalib {
00111
00112
00113
00114
00115
00116 CalibFileFinder::CalibFileFinder (const std::string& calibDir,
00117 const std::string& typeGroupName,
00118 const unsigned& print_bits)
00119 : m_calibDir(calibDir)
00120 , m_typeGroupName(typeGroupName)
00121 , m_print_bits(print_bits)
00122 {
00123 }
00124
00125
00126
00127
00128 CalibFileFinder::~CalibFileFinder ()
00129 {
00130 }
00131
00132
00133 std::string
00134 CalibFileFinder::trancateSourceName(const std::string& str)
00135 {
00136 size_t pL = str.find('(');
00137 size_t pR = str.find(')', pL+1);
00138 return (pL != std::string::npos) ? std::string(str, pL+1, pR-pL-1) : str;
00139 }
00140
00141
00142
00143 std::string
00144 CalibFileFinder::findCalibFile(const std::string& src, const std::string& dataType, unsigned long runNumber) const
00145 try {
00146
00147 if ( m_calibDir == "" ) return std::string();
00148
00149
00150 fs::path dir = m_calibDir;
00151 dir /= m_typeGroupName;
00152 dir /= trancateSourceName(src);
00153 dir /= dataType;
00154
00155
00156 std::vector<std::string> files;
00157 typedef fs::directory_iterator dir_iter;
00158 for (dir_iter diriter = dir_iter(dir); diriter != dir_iter(); ++ diriter ) {
00159 const fs::path& path = diriter->path();
00160 files.push_back(path.string());
00161 }
00162
00163 return selectCalibFile(files, runNumber, m_print_bits);
00164
00165 } catch (const fs::filesystem_error& ex) {
00166
00167 return std::string();
00168 }
00169
00170
00171 std::string
00172 CalibFileFinder::findCalibFile(const Pds::Src& src, const std::string& dataType, unsigned long runNumber) const
00173 {
00174 return findCalibFile(::toString(src), dataType, runNumber);
00175 }
00176
00177
00178 std::string
00179 CalibFileFinder::selectCalibFile(const std::vector<std::string>& files, unsigned long runNumber, unsigned print_bits)
00180 {
00181
00182 std::vector<CalibFile> calfiles;
00183 for (std::vector<std::string>::const_iterator iter = files.begin(); iter != files.end(); ++ iter) {
00184
00185 const fs::path path(*iter);
00186
00187
00188 if (path.stem().string() == "HISTORY") continue;
00189
00190
00191 if (path.extension() != ".data") {
00192 if( print_bits & 1 ) MsgLog(logger, info, "skipping file with wrong extension: " + path.string());
00193 continue;
00194 }
00195
00196 try {
00197 calfiles.push_back(CalibFile(path));
00198 } catch (const std::exception& ex) {
00199 if( print_bits & 2 ) MsgLog(logger, warning, "skipping file: " + path.string() + ": " + ex.what());
00200 }
00201
00202 }
00203
00204
00205
00206 std::sort(calfiles.begin(), calfiles.end());
00207 typedef std::vector<CalibFile>::const_reverse_iterator FileIter;
00208 for (FileIter it = calfiles.rbegin() ; it != calfiles.rend() ; ++ it ) {
00209 MsgLog(logger, debug, "trying: " << *it << " for run " << runNumber);
00210 if (it->begin() <= runNumber and runNumber <= it->end()) return it->path().string();
00211 }
00212 return std::string();
00213 }
00214
00215 }