CommandCoder.cxx

Go to the documentation of this file.
00001 // -*- mode: C++ -*- 
00002 //
00003 // Copyright (C) 2006 Christian Holm Christensen <cholm@nbi.dk>
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public License
00007 // as published by the Free Software Foundation; either version 2.1
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free
00017 // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018 // 02111-1307 USA
00019 //
00020 // Note, some of this code is based on the ROOT CommandCoder interface 
00021 //
00027 #ifdef HAVE_CONFIG_H
00028 # include "config.h"
00029 #endif
00030 #include <rcuxx/Rcu.h>
00031 #include <rcuxx/Bc.h>
00032 #include <rcuxx/Fmd.h>
00033 #include <rcuxx/Altro.h>
00034 #include "CommandCoder.h"
00035 #include "Rcu.h"
00036 #include "Bc.h"
00037 #include "Fmd.h"
00038 #include "Altro.h"
00039 #include "Configurator.h"
00040 #include <rcudb/Server.h>
00041 #include <stdexcept>
00042 #include <iostream>
00043 #include <iomanip>
00044 #include <fstream>
00045 #include <algorithm>
00046 #include <sstream>
00047 #ifndef DB_URL
00048 # error Database URL not defined 
00049 #endif
00050 #ifndef RCUXX_URL
00051 
00052 # define RCUXX_URL "coder:"
00053 #endif
00054 
00055 struct to_lower
00056 {
00057   char operator()(char c) const
00058   {
00059     return std::tolower(c);
00060   }
00061 };
00062 
00063 namespace 
00064 {
00066   std::string fConfigFile(CONFIG_FILE);
00067   int len;
00068 }
00069 
00070 //____________________________________________________________________
00071 void RcuConf::setConfigFile(const std::string& file)
00072 {
00073   fConfigFile = file;
00074 }
00075 
00076 //____________________________________________________________________
00077 CommandCoderBase* CommandCoderBase::instance = new RcuConf::CommandCoder;
00078 
00079 //____________________________________________________________________
00080 RcuConf::CommandCoder::CommandCoder()
00081   : fServer(0), 
00082     fRcuxx(0), 
00083     fBcxx(0), 
00084     fAltroxx(0), 
00085     fRcu(0), 
00086     fBc(0), 
00087     fAltro(0),
00088     fConfigurator(0), 
00089     fRet(0),
00090     fVerbose(false), 
00091     fDebug(false),
00092     fInit(false),
00093     fDetector("tpc")
00094 {
00095   // Note, that this method throws on error 
00096   std::cout << "Constructing CommandCoder" << std::endl;
00097   fDbUrl      = DB_URL;
00098   fRcuUrl     = RCUXX_URL;
00099   fVerbose    = false;  
00100 }
00101 
00102 //____________________________________________________________________
00103 void
00104 RcuConf::CommandCoder::init() 
00105 {
00106   if (fInit) return;
00107   
00108   // Read the configuration file 
00109   readConfig();
00110 
00111   // Connect to DB
00112   std::cout << "Opening connection to DB on " << fDbUrl << std::endl;
00113   fServer = RcuDb::Server::Connect(fDbUrl);
00114   if (!fServer) throw std::runtime_error("Failed to open connection to db!");
00115       
00116   // Connect to FEE
00117   std::cout << "Opening connection to RCU on " << fRcuUrl << std::endl;
00118   fRcuxx = Rcuxx::Rcu::Open(fRcuUrl.c_str(), false, fDebug);
00119   if (!fRcuxx) throw std::runtime_error("Failed to open connection to RCU");
00120       
00121   std::transform(fDetector.begin(), fDetector.end(), 
00122                  fDetector.begin(), to_lower());
00123   if      (fDetector == "fmd") fBcxx = new Rcuxx::Fmd(*fRcuxx);
00124   else                         fBcxx = new Rcuxx::Bc(*fRcuxx);
00125   fAltroxx = new Rcuxx::Altro(*fRcuxx);
00126       
00127   // Make components 
00128   fRcu    = new RcuConf::Rcu(*fRcuxx);
00129   fBc     = new RcuConf::Bc(*fBcxx);
00130   fAltro  = new RcuConf::Altro(*fAltroxx);
00131       
00132   // Make command coder
00133   fConfigurator = new Configurator(*fServer, *fRcu, *fBc, *fAltro);
00134   fConfigurator->SetDebug(fDebug);
00135   fInit = true;
00136 }
00137 
00138 //____________________________________________________________________
00139 bool
00140 RcuConf::CommandCoder::readConfig()
00141 {
00142   std::cout << "Reading configuration file " << fConfigFile << std::endl;
00143   std::ifstream config(fConfigFile.c_str());
00144   if (!config) return false;
00145   
00146   unsigned int line = 0;
00147   std::string  tmp;
00148   while (true) {
00149     char c = config.peek();
00150     while (true) {
00151       if (c == ' ' || c == '\t') { // || c == '\n') {
00152         config.get();
00153         if (c == '\n') line++;
00154         continue;
00155       }
00156       c = config.peek();
00157       break;
00158     }
00159     if (c == '#') {
00160       std::getline(config, tmp);
00161       line++;
00162       continue;
00163     }
00164     std::string key, val;
00165     config >> key >> val;
00166     std::transform(key.begin(), key.end(), key.begin(), to_lower());
00167 
00168     if (key[0] != '#') 
00169       std::cout << "Line # " << line << " Read key=" << key 
00170                 << " value=" << val << std::endl;
00171     if      (key == "db:")       fDbUrl    = val;
00172     else if (key == "rcu:")      fRcuUrl   = val;
00173     else if (key == "detector:") fDetector = val;
00174     else if (key == "verbose:") {
00175       std::transform(val.begin(), val.end(), val.begin(), to_lower());
00176       fVerbose = (val == "yes" || val == "true" || val == "on" || val == "1");
00177     }
00178     else if (key == "debug:") {
00179       std::transform(val.begin(), val.end(), val.begin(), to_lower());
00180       fDebug = (val == "yes" || val == "true" || val == "on" || val == "1");
00181     }
00182     std::getline(config, tmp);
00183     line++;
00184     if (config.eof()) break;
00185   }
00186 
00187   config.close();
00188   return true;
00189 }
00190 
00191 
00192 //____________________________________________________________________
00193 int
00194 RcuConf::CommandCoder::createDataBlock(char *target, int tag)
00195 {
00196   // Initialize if not already done
00197   init();
00198   
00199   // Clear all errors. 
00200   fErrors.clear();
00201   if (!fConfigurator) return 0;
00202   
00203   // Try to find the number part 
00204   if (fVerbose) 
00205     std::cout << "Target: " << target << " tag: " << tag << std::endl;
00206   std::string s(target);
00207   std::string::size_type us = s.find('_');
00208   if (us == std::string::npos) {
00209     std::stringstream str;
00210     str << "Didn't find separating '_' in \"" << s << "\"";
00211     fErrors.push_back(str.str());
00212     return -1;
00213   }
00214 
00215   // Extract the coordinates. 
00216   std::string nums = s.substr(us+1, s.size() - us);
00217   std::stringstream str(nums);
00218   int x, y, z;
00219   char us1, us2;
00220   str >> x >> us1 >> y >> us2 >> z;
00221   if (str.bad() || us1 != '_' || us2 != '_') {
00222     std::stringstream str;
00223     str << "Badly formated target \"" << s << "\"";
00224     fErrors.push_back(str.str());
00225     return -1;
00226   }
00227   if (fVerbose)
00228     std::cout << "X=" << x << " Y=" << y << " Z=" << z << std::endl;
00229   
00230   // Let the configurator do it's thing. 
00231   len = fRet = fConfigurator->Write(tag, x, y, z);
00232   if (fRet < 0) fErrors.push_back(fConfigurator->ErrorString());
00233 
00234   // Return number or words, or negative error code 
00235   if (fVerbose) std::cout << "Made block of size: " << fRet << std::endl;
00236   return fRet;
00237 }
00238 
00239 //____________________________________________________________________
00240 long int* 
00241 RcuConf::CommandCoder::getDataBlock()
00242 {
00243   if (!fConfigurator) return 0;
00244   long int* ret = fConfigurator->RCU().GetBlock();
00245   if (fVerbose) std::cout << "Getting the data block: " << ret << std::endl;
00246 
00247   if (fDebug) {
00248     std::cout << std::hex << std::setfill('0');
00249     for (int i = 0; i < len; i++) 
00250       std::cout << "\t0x" << std::setw(8) << ret[i] << std::endl;
00251     std::cout << std::dec << std::setfill(' ');
00252   }
00253   
00254   return ret;
00255 }
00256 
00257 
00258 //____________________________________________________________________
00259 //
00260 // EOF
00261 // 
Top of page Last update Fri Apr 27 01:54:15 2007
Copyright © 2004 Christian Holm Created by DoxyGen 1.3.5