00001 #include "SetupNavigator.h"
00002 #include "ModulesParser.h"
00003 #include "TSetupData.h"
00004 #include "definitions.h"
00005 #include "debug_tools.h"
00006
00007 #include <TSQLiteServer.h>
00008 #include <TSQLiteResult.h>
00009 #include <TSQLiteRow.h>
00010
00011 #include <cstdlib>
00012 #include <iostream>
00013 #include <sstream>
00014 #include <fstream>
00015 #include <string>
00016
00017 #include <TSQLiteResult.h>
00018 #include <TSQLiteRow.h>
00019
00020 SetupNavigator* SetupNavigator::fThis=NULL;
00021
00022 static std::string StripTimeShiftConfigFromString(std::string con) {
00023 const char *start = "{no_time_shift=", *end = "}";
00024 std::size_t pos;
00025 while ( (pos=con.find(start)) != std::string::npos)
00026 con.replace(pos, con.find(end, pos)-pos+1, "");
00027 return con;
00028 }
00029
00030
00031
00032 std::map<IDs::channel, double> SetupNavigator::fPedestalValues;
00033 std::map<IDs::channel, double> SetupNavigator::fNoiseValues;
00034 std::map<IDs::source, double> SetupNavigator::fCoarseTimeOffset;
00035 std::map< IDs::channel, SetupNavigator::EnergyCalibRow_t > SetupNavigator::fEnergyCalibrationConstants;
00036
00037 SetupNavigator::SetupNavigator() :
00038 fCommandLineArgs(),
00039 fSQLiteFilename("sqlite://calibration.db"), fServer(new TSQLiteServer(fSQLiteFilename.c_str())),
00040 fPedestalNoiseTableName("PedestalAndNoise"), fCoarseTimeOffsetTableName("CoarseTimeOffset"),
00041 fEnergyCalibrationConstantsTableName("Energy") {
00042 if (fServer->IsZombie()) {
00043 std::cout << "SetupNavigator: ERROR: Couldn't connect to SQLite database." << std::endl;
00044 throw Except::NoCalibDB();
00045 }
00046 }
00047
00048
00049 SetupNavigator::~SetupNavigator() {
00050 }
00051
00052
00053 void SetupNavigator::Close() {
00054 if(IsCalibRun())
00055 OutputCalibCSV();
00056 fServer->Close();
00057 if (fThis)
00058 delete fThis;
00059 fThis = NULL;
00060 }
00061
00062
00063 std::string SetupNavigator::GetBank(const IDs::channel& src)const{
00064 std::map<std::string, std::string>* bankDetNameMap=&TSetupData::Instance()->fBankToDetectorMap;
00065 for(std::map<std::string, std::string>::iterator it = bankDetNameMap->begin();
00066 it != bankDetNameMap->end(); ++it){
00067 if(modules::parser::iequals(it->second , src.str())) return it->first;
00068 }
00069 std::cout << "Invalid detector name: " << src.str() << std::endl;
00070 throw Except::InvalidDetector();
00071 }
00072
00073 void SetupNavigator::CacheCalibDB() {
00074
00075
00076 if (!fServer->HasTable(fPedestalNoiseTableName.c_str())) {
00077 std::cout << "SetupNavigator: ERROR: Table " << fPedestalNoiseTableName << " does not exist." << std::endl;
00078 if (!IsCalibRun()) throw Except::MissingTable(fPedestalNoiseTableName.c_str());
00079 } else {
00080 if (!ReadPedestalAndNoiseValues()) {
00081 std::cout << "SetupNavigator: ERROR: Table " << fPedestalNoiseTableName
00082 << " contains no calib data for this run ("<<GetRunNumber()<<")" << std::endl;
00083 if (!IsCalibRun()) throw Except::UncalibratedRun();
00084 }
00085 }
00086 if (!fServer->HasTable(fCoarseTimeOffsetTableName.c_str())) {
00087 std::cout << "SetupNavigator: ERROR: Table " << fCoarseTimeOffsetTableName << " does not exist." << std::endl;
00088 if(!IsCalibRun()) throw Except::MissingTable(fPedestalNoiseTableName.c_str());
00089 } else {
00090 if (!ReadCoarseTimeOffsetValues()) {
00091 std::cout << "SetupNavigator: ERROR: Table " << fCoarseTimeOffsetTableName
00092 << " contains no calib data for this run ("<<GetRunNumber()<<")" << std::endl;
00093 if (!IsCalibRun()) throw Except::UncalibratedRun();
00094 }
00095 }
00096 if (!fServer->HasTable(fEnergyCalibrationConstantsTableName.c_str())) {
00097 std::cout << "SetupNavigator: Error: Table " << fEnergyCalibrationConstantsTableName << " does not exist." << std::endl;
00098 if (!IsCalibRun()) throw Except::MissingTable(fEnergyCalibrationConstantsTableName.c_str());
00099 } else {
00100 if (!ReadEnergyCalibrationConstants()) {
00101 std::cout << "SetupNavigator: ERROR: Table " << fEnergyCalibrationConstantsTableName
00102 << " contains no calib data for this run ("<<GetRunNumber()<<")" << std::endl;
00103 if (!IsCalibRun()) throw Except::UncalibratedRun();
00104 }
00105 }
00106 }
00107
00108 bool SetupNavigator::ReadPedestalAndNoiseValues() {
00109
00110 double pedestal=definitions::DefaultValue;
00111 double noise=definitions::DefaultValue;
00112 std::string channelname;
00113
00114 std::stringstream query;
00115 int run_number = GetRunNumber();
00116
00117 query << "SELECT * FROM " << fPedestalNoiseTableName << " WHERE run=" << run_number << ";";
00118 TSQLiteResult* result = (TSQLiteResult*) fServer->Query(query.str().c_str());
00119 query.str("");
00120
00121 TSQLiteRow* row = (TSQLiteRow*) result->Next();
00122 while (row != NULL) {
00123 channelname = row->GetField(1);
00124 pedestal = atof(row->GetField(2));
00125 noise = atof(row->GetField(3));
00126
00127 fPedestalValues[channelname] = pedestal;
00128 fNoiseValues[channelname] = noise;
00129 delete row;
00130 row = (TSQLiteRow*) result->Next();
00131 }
00132 delete result;
00133
00134 return !fPedestalValues.empty();
00135 }
00136
00137
00138 bool SetupNavigator::ReadCoarseTimeOffsetValues() {
00139
00140 const std::vector<std::string> table = GetCoarseTimeOffsetColumns();
00141 for(unsigned i=0;i<table.size();++i) DEBUG_VALUE(i, table[i]);
00142
00143 std::stringstream query;
00144 query << "SELECT channel";
00145 for (unsigned int i = 0; i < table.size(); ++i)
00146 query << ",\"" << table[i] << '"';
00147 query << " FROM " << fCoarseTimeOffsetTableName << " WHERE run==" << GetRunNumber();
00148 TSQLResult* res = fServer->Query(query.str().c_str());
00149
00150 TSQLRow* row;
00151 while ((row = res->Next())) {
00152 for (unsigned int i = 0; i < table.size(); ++i) {
00153 std::stringstream srcstr;
00154 srcstr << row->GetField(0) << IDs::field_separator << table[i];
00155 if(row->GetField(1+i))
00156 fCoarseTimeOffset[IDs::source(srcstr.str())] = atof(row->GetField(1 + i));
00157 }
00158 delete row;
00159 }
00160 delete res;
00161 return !fCoarseTimeOffset.empty();
00162 }
00163
00164 std::vector<std::string> SetupNavigator::GetCoarseTimeOffsetColumns() {
00165 std::vector<std::string> cols;
00166 std::stringstream cmd;
00167 cmd << "PRAGMA table_info(" << fCoarseTimeOffsetTableName << ")";
00168 TSQLResult* res = fServer->Query(cmd.str().c_str());
00169 TSQLRow* row;
00170 while ((row = res->Next())) {
00171 if (row->GetField(1) != std::string("run") && row->GetField(1) != std::string("channel"))
00172 cols.push_back(std::string(row->GetField(1)));
00173 delete row;
00174 }
00175 delete res;
00176 return cols;
00177 }
00178
00179
00180 bool SetupNavigator::ReadEnergyCalibrationConstants() {
00181 std::stringstream cmd;
00182
00183
00184
00185 cmd << "SELECT channel,gain,offset FROM " << fEnergyCalibrationConstantsTableName
00186 << " WHERE run==" << GetRunNumber();
00187 TSQLResult* res = fServer->Query(cmd.str().c_str());
00188 TSQLRow* row;
00189 while ((row = res->Next())) {
00190 fEnergyCalibrationConstants[IDs::channel(row->GetField(0))] =
00191 EnergyCalibRow_t(atof(row->GetField(1)), atof(row->GetField(2)));
00192 delete row;
00193 }
00194 delete res;
00195
00196 return true;
00197 }
00198
00199
00200 void SetupNavigator::OutputCalibCSV() {
00201 char r[6];
00202 sprintf(r, "%05d", GetRunNumber());
00203
00204 std::ofstream fPN((std::string("calib.run") + r + "." + fPedestalNoiseTableName + ".csv").c_str());
00205 fPN << "run,channel,pedestal,noise" << std::endl;
00206 for (std::map<IDs::channel, double>::const_iterator i = fPedestalValues.begin(); i != fPedestalValues.end(); ++i)
00207 fPN << GetRunNumber() << "," << i->first.str() << ","
00208 << i->second << "," << fNoiseValues.at(i->first) << std::endl;
00209
00210 std::ofstream fTO((std::string("calib.run") + r + "." + fCoarseTimeOffsetTableName + ".csv").c_str());
00211 std::set<IDs::generator> gens;
00212 std::set<IDs::channel> chns;
00213 for (std::map<IDs::source, double>::const_iterator i = fCoarseTimeOffset.begin(); i != fCoarseTimeOffset.end(); ++i) {
00214 gens.insert(i->first.Generator());
00215 chns.insert(i->first.Channel());
00216 }
00217 fTO << "run,channel";
00218 for (std::set<IDs::generator>::const_iterator i = gens.begin(); i != gens.end(); ++i)
00219 fTO << "," << i->str();
00220 fTO << std::endl;
00221 for (std::set<IDs::channel>::const_iterator i = chns.begin(); i != chns.end(); ++i) {
00222 fTO << GetRunNumber() << "," << i->str();
00223 for (std::set<IDs::generator>::const_iterator j = gens.begin(); j != gens.end(); ++j) {
00224 fTO << ",";
00225 if (fCoarseTimeOffset.count(IDs::source(*i, *j)))
00226 fTO << fCoarseTimeOffset.at(IDs::source(*i, *j));
00227 }
00228 fTO << std::endl;
00229 }
00230 }
00231
00232 void SetupNavigator::SetPedestalAndNoise(const IDs::channel& chn, double ped, double nse) {
00233 if(!IsCalibRun()) {
00234 std::cout << "SetupNavigator: Warning: Request to edit pedestals and "
00235 "noises when not flagged as calibration. Not setting." << std::endl;
00236 return;
00237 }
00238 fPedestalValues[chn] = ped;
00239 fNoiseValues[chn] = nse;
00240 }
00241
00242 void SetupNavigator::SetCoarseTimeOffset(const IDs::source& src, double dt) {
00243 if(!IsCalibRun()) {
00244 std::cout << "SetupNavigator: Warning: Request to edit coarse time offsets "
00245 "when not flagged as calibration. Not setting." << std::endl;
00246 return;
00247 }
00248
00249 fCoarseTimeOffset[IDs::source(src.Channel(), IDs::generator(StripTimeShiftConfigFromString(src.Generator().str())))] = dt;
00250 }
00251
00252 double SetupNavigator::GetNoise(const IDs::channel& channel) const {
00253 return alcap::at<Except::InvalidDetector>(fNoiseValues,channel,channel.str().c_str());
00254 }
00255 double SetupNavigator::GetPedestal(const IDs::channel& channel) const {
00256 return alcap::at<Except::InvalidDetector>(fPedestalValues,channel,channel.str().c_str());
00257 }
00258
00259 SetupNavigator::EnergyCalibRow_t SetupNavigator::GetEnergyCalibrationConstants(const IDs::channel& ch) const {
00260 return alcap::at<Except::InvalidDetector>(fEnergyCalibrationConstants, ch, ch.str().c_str());
00261 }
00262 double SetupNavigator::GetCoarseTimeOffset( IDs::source source) const {
00263
00264
00265 std::string conf=source.Generator().Config();
00266 unsigned curly_br=conf.find('}');
00267 if(curly_br!=std::string::npos){ source.Generator().Config(conf.substr(0,curly_br+1));}
00268
00269 return source.matches(IDs::channel("muSc")) ? 0. : alcap::at<Except::InvalidDetector>(fCoarseTimeOffset,source,source.str().c_str());
00270 }