emcOMCalibrationDataT.h

Go to the documentation of this file.
00001 #ifndef __EMCOMCALIBRATIONDATAT_H__
00002 #define __EMCOMCALIBRATIONDATAT_H__
00003 
00004 #ifndef __EMCOBJECTMANAGER_H__
00005 #include "emcObjectManager.h"
00006 #endif
00007 #include <map>
00008 #include <vector>
00009 
00010 class emcCalibrationData;
00011 class PdbBankID;
00012 
00018 template <class BM>
00019 class emcOMCalibrationDataT : public emcObjectManager
00020 {
00021 public:
00022 
00023   emcOMCalibrationDataT(const char* name = "", const char* title = "");
00024   virtual ~emcOMCalibrationDataT();
00025 
00026   virtual bool CanCollect(const emcManageable& object) const;
00027 
00028   virtual bool CanRead(const emcManageable& object) const;
00029 
00030   virtual bool CanWrite(const emcManageable& object) const;
00031 
00032   virtual emcManageable* Collect(const emcManageable& object,
00033                                  const PHTimeStamp& when);
00034 
00035   bool GetBankID(size_t type, size_t number, PdbBankID& bankID) const;
00036   bool GetTypeAndNumber(const PdbBankID& bankID, size_t& type,
00037                         size_t& number) const;
00038 
00039   using emcObjectManager::Read;
00040 
00041   virtual bool Read(emcManageable& object,
00042                     const PHTimeStamp& time_stamp,
00043                     int id);
00044 
00045   virtual void Reset(void);
00046 
00047   virtual bool Write(const emcManageable& object,
00048                      const PHTimeStamp& tdummy,
00049                      int dummy = -1);
00050 
00051 private:
00052   emcCalibrationData* GetCalibrationData(const emcCalibrationData& cal);
00053   emcCalibrationData* AllocateCalibrationData(const emcCalibrationData& cal);
00054   void FreeCalibrationData(const emcCalibrationData& cal);
00055   bool ReadFromFile(const PdbBankID& bankID, emcCalibrationData& cal);
00056 
00057 private:
00058 
00059   std::map<int, std::vector<emcCalibrationData*> * > fCalibrationMap;
00060 
00061 private:
00062   class changeName
00063   {
00064   public:
00065     changeName(const char* name)
00066     {
00067       name_ = emcManageable::GetStorageName(BM::storage());
00068       name_ += ":";
00069       name_ += name;
00070     }
00071 
00072     const char* c_str() const
00073     {
00074       return name_.c_str();
00075     }
00076 
00077   private:
00078     std::string name_;
00079   };
00080 
00081   BM* fBM;
00082 };
00083 
00084 
00085 //_____________________________________________________________________________
00086 //_____________________________________________________________________________
00087 //_____________________________________________________________________________
00088 
00089 #include "emcDataManager.h"
00090 #include "emcCalibrationData.h"
00091 #include "PdbEmcLCTof.hh"
00092 #include "PdbEmcTofSectorOffset.hh"
00093 #include "PdbCoordinate.hh"
00094 #include "PdbBankList.hh"
00095 #include "PdbBankID.hh"
00096 #include "PdbBankListIterator.hh"
00097 #include "PdbApplication.hh"
00098 #include "PdbBankManager.hh"
00099 #include "Pdb.hh"
00100 #include <sstream>
00101 #include <fstream>
00102 #include "EmcIndexer.h"
00103 #include <cstdlib>
00104 #include <vector>
00105 #include <cmath>
00106 
00107 //_____________________________________________________________________________
00108 template <class BM>
00109 emcOMCalibrationDataT<BM>::emcOMCalibrationDataT(const char* name,
00110                                                  const char* title)
00111   : emcObjectManager(changeName(name).c_str(), title),
00112     fBM(new BM)
00113 {}
00114 
00115 //_____________________________________________________________________________
00116 template <class BM>
00117 emcOMCalibrationDataT<BM>::~emcOMCalibrationDataT()
00118 {
00119   Reset();
00120 }
00121 
00122 //_____________________________________________________________________________
00123 template <class BM>
00124 emcCalibrationData*
00125 emcOMCalibrationDataT<BM>::AllocateCalibrationData(const emcCalibrationData& cal)
00126 {
00127   emcCalibrationData::EType type = cal.GetType();
00128   size_t number = cal.GetNumber();
00129 
00130   if (fCalibrationMap.find(type) == fCalibrationMap.end())
00131     {
00132       // gee, we don't know this type yet !
00133       fCalibrationMap[type] =
00134         new std::vector<emcCalibrationData*>(cal.GetRange());
00135       std::vector<emcCalibrationData*> * vec = fCalibrationMap[type];
00136       size_t i;
00137       for (i = 0;i < vec->size();i++)
00138         {
00139           (*vec)[i] = 0;
00140         }
00141     }
00142 
00143   std::vector<emcCalibrationData*> * vec = fCalibrationMap[type];
00144   assert(number < vec->size());
00145   delete (*vec)[number];
00146   (*vec)[number] = new emcCalibrationData(type, number);
00147   return (*vec)[number];
00148 }
00149 
00150 //_____________________________________________________________________________
00151 template <class BM>
00152 void
00153 emcOMCalibrationDataT<BM>::FreeCalibrationData(const emcCalibrationData& cal)
00154 {
00155   emcCalibrationData::EType type = cal.GetType();
00156   size_t number = cal.GetNumber();
00157 
00158   if (fCalibrationMap.find(type) != fCalibrationMap.end())
00159     {
00160       std::vector<emcCalibrationData*> * vec = fCalibrationMap[type];
00161       delete (*vec)[number];
00162       (*vec)[number] = 0;
00163     }
00164 }
00165 
00166 
00167 //_____________________________________________________________________________
00168 template <class BM>
00169 bool
00170 emcOMCalibrationDataT<BM>::CanCollect(const emcManageable& object) const
00171   {
00172     return CanRead(object);
00173   }
00174 
00175 //_____________________________________________________________________________
00176 template <class BM>
00177 bool
00178 emcOMCalibrationDataT<BM>::CanRead(const emcManageable& object) const
00179 {
00180   if ( object.GetSource() != fBM->storage() )
00181     {
00182       return false;
00183     }
00184   
00185   const emcManageable* object_ptr = &object;
00186   const emcCalibrationData* test =
00187     dynamic_cast<const emcCalibrationData*>(object_ptr);
00188   
00189   if (test)
00190     {
00191       return true;
00192     }
00193   
00194   return false;
00195 }
00196 
00197 //_____________________________________________________________________________
00198 template <class BM>
00199 bool
00200 emcOMCalibrationDataT<BM>::CanWrite(const emcManageable& object) const
00201 {
00202   if ( object.GetDestination() != fBM->storage() )
00203     {
00204       return false;
00205     }
00206   
00207   const emcManageable* object_ptr = &object;
00208   const emcCalibrationData* test =
00209     dynamic_cast<const emcCalibrationData*>(object_ptr);
00210   
00211   if (test)
00212     {
00213       return true;
00214     }
00215   return false;
00216 }
00217 
00218 //_____________________________________________________________________________
00219 template <class BM>
00220 emcManageable*
00221 emcOMCalibrationDataT<BM>::Collect(const emcManageable& object,
00222                                    const PHTimeStamp& when)
00223 {
00224   const emcCalibrationData& cal =
00225     static_cast<const emcCalibrationData&>(object);
00226 
00227   emcCalibrationData* calibdata;
00228 
00229   calibdata = GetCalibrationData(cal);
00230 
00231   if (calibdata)
00232     {
00233       // we already have this one in memory.
00234       if (calibdata->IsValid(when))
00235         {
00236           // it's still valid, so we return it.
00237           return calibdata;
00238         }
00239     }
00240   else
00241     {
00242       calibdata = AllocateCalibrationData(cal);
00243     }
00244 
00245   emcManageable::EStorage data_source = object.GetSource();
00246 
00247   if ( DM()->GetVerboseLevel() )
00248     {
00249       std::cout << "<I-EMCAL> Fetching " << object.GetCategory() << " from "
00250                 << emcManageable::GetStorageName(data_source) << std::endl;
00251     }
00252 
00253   calibdata->SetSource(cal.GetSource());
00254 
00255   PdbBankID id;
00256   GetBankID(cal.GetType(), cal.GetNumber(), id);
00257 
00258   bool ok = Read(*calibdata, when, id.getInternalValue());
00259 
00260   if (ok)
00261     {
00262       return calibdata;
00263     }
00264   else
00265     {
00266       if ( DM()->GetVerboseLevel() )
00267         {
00268           std::cerr << "<E-EMCAL> emcOMCalibrationT<"
00269                     << fBM->name()
00270                     << ">::Collect failed for "
00271                     << object.GetCategory() << std::endl;
00272         }
00273       FreeCalibrationData(cal);
00274       return 0;
00275     }
00276 }
00277 
00278 //_____________________________________________________________________________
00279 template <class BM>
00280 emcCalibrationData*
00281 emcOMCalibrationDataT<BM>::GetCalibrationData(const emcCalibrationData& cal)
00282 {
00283   emcCalibrationData::EType type = cal.GetType();
00284   size_t number = cal.GetNumber();
00285   emcCalibrationData* rv = 0;
00286 
00287   if (fCalibrationMap.find(type) != fCalibrationMap.end())
00288     {
00289       // we already know about this type
00290       std::vector<emcCalibrationData*> *vec = fCalibrationMap[type];
00291       assert(vec != 0);
00292       assert(number < vec->size());
00293       return (*vec)[number];
00294     }
00295 
00296   return rv;
00297 }
00298 
00299 //_____________________________________________________________________________
00300 template <class BM>
00301 bool
00302 emcOMCalibrationDataT<BM>::GetBankID(size_t type, size_t number,
00303                                      PdbBankID& bankID) const
00304 {
00305   // Get the bankID from the type and the number
00306   // return false if type and/or number are not valid
00307   // FIXME: no test is done for the moment.
00308 
00309   if ( type == emcCalibrationData::kTofSectorOffset )
00310     {
00311       bankID.setInternalValue(number);
00312     }
00313   else
00314     {
00315       int id; // assumes int = 4 bytes !
00316 
00317       id = ( ( type << 24 ) & ( 0xFF000000 ) ) + ( number & 0xFFFFFF );
00318       bankID.setInternalValue(id);
00319     }
00320 
00321   return true;
00322 }
00323 
00324 //_____________________________________________________________________________
00325 template <class BM>
00326 bool
00327 emcOMCalibrationDataT<BM>::GetTypeAndNumber(const PdbBankID& bankID,
00328                                             size_t& type, size_t& number) const
00329 {
00330   // Get the type and the numbe from the bankID
00331   // return false if the bankID is not valid.
00332   // FIXME: no test is done for the moment.
00333 
00334   int id = bankID.getInternalValue();
00335   type = ( id & 0xFF000000 ) >> 24;
00336   number = ( id & 0xFFFFFF );
00337 
00338   return true;
00339 }
00340 
00341 //_____________________________________________________________________________
00342 template <class BM>
00343 bool
00344 emcOMCalibrationDataT<BM>::Read(emcManageable& object,
00345                                 const PHTimeStamp& time_stamp,
00346                                 int id)
00347 {
00348   bool kIsRead = false;
00349   emcCalibrationData& cal = static_cast<emcCalibrationData&>(object);
00350 
00351   size_t type;
00352   size_t number;
00353 
00354   PdbBankID bankID;
00355 
00356   if ( id >= 0 )
00357     {
00358       bankID.setInternalValue(id);
00359       GetTypeAndNumber(bankID, type, number);
00360       if (type != static_cast<size_t>(cal.GetType()) ||
00361           number != cal.GetNumber())
00362         {
00363           std::cerr << "<W> emcOMCalibrationDataT<" << BM::name()
00364                     << ">::Read : the 3rd parameter is not"
00365                     << " consistent with the object you give. "
00366                     << "Might well be what "
00367                     << " you want, but hum, are you really sure you know what "
00368                     << " you are doing here ?! "
00369                     << std::endl;
00370         }
00371     }
00372   else
00373     {
00374       type = cal.GetType();
00375       number = cal.GetNumber();
00376       GetBankID(type, number, bankID);
00377     }
00378   
00379   // Try to open a read transaction
00380   PdbStatus status = fBM->DBApplication()->startRead();
00381 
00382   if (status)
00383     {
00384       if (DM()->GetVerboseLevel())
00385         {
00386           std::cout << "<I> emcOMCalibrationDataT<" << BM::name()
00387                     << ">::Read : I'm going to read the following"
00388                     << " emcCalibrationData : ";
00389           cal.Print();
00390         }
00391 
00392       // Convert here from calBank to emcCalibration (cal) object
00393 
00394       std::string pdb_classname = "PdbEmcLCTofBank";
00395       if (type == emcCalibrationData::kIniCal)
00396         {
00397           pdb_classname = "PdbCoordinateBank";
00398         }
00399       else if (type == emcCalibrationData::kTofSectorOffset)
00400         {
00401           pdb_classname = "PdbEmcTofSectorOffsetBank";
00402         }
00403       std::string basename = "calib.emc.";
00404       basename += cal.GetCategory();
00405 
00406       PdbCalBank* emcBank =
00407         fBM->BankManager()->fetchBank(pdb_classname.c_str(),
00408                                       bankID,
00409                                       basename.c_str(),
00410                                       const_cast<PHTimeStamp&>(time_stamp));
00411 
00412       if (!emcBank)
00413         {        
00414           if ( cal.GetType() == emcCalibrationData::kTofSectorOffset )
00415             {
00416               // we're allowed to fail.
00417               // In that case, return a default empty object,
00418               // where offsets are 0 simply.
00419               
00420               std::cout << "<W-EMCAL> emcOMCalibrationDataT<" << BM::name()
00421                         << ">::Read : "
00422                         << "cannot fetch bank (flavour = "
00423                         << cal.GetCategory() << ",type=0x"
00424                         << std::hex << static_cast<int>(type)
00425                         << std::dec
00426                         << ",number=" << number
00427                         << ") at time " << time_stamp
00428                         << " in DB(s) " << basename << " : " 
00429                         << "Returning default object instead"
00430                         << std::endl;
00431 
00432               cal.SetTypeAndSize(static_cast<emcCalibrationData::EType>(type),
00433                                  1);
00434               cal.Set(0,0.0,0.0,0);
00435               cal.Set(0,0.0,0.0,1);
00436               cal.Set(0,0.0,0.0,2);
00437               cal.Set(0,0.0,0.0,3);
00438               cal.Set(0,0.0,0.0,4);
00439               kIsRead = true;
00440             }
00441           else
00442             {
00443               std::cerr << "<E-EMCAL> emcOMCalibrationDataT<" << BM::name()
00444                         << ">::Read : "
00445                         << "cannot fetch bank (flavour = "
00446                         << cal.GetCategory() << ",type= "
00447                         << std::hex << static_cast<int>(type)
00448                         << ",number=" << number
00449                         << ") at time " << time_stamp
00450                         << " in DB(s) " << basename << "*" << std::endl;
00451             }
00452         }
00453       else
00454         {
00455           kIsRead = true;
00456 
00457           size_t i;
00458 
00459           // warning : the type MUST be set before the size,
00460           // as it decides on the number of dimensions for the internals
00461           // of cal.
00462 
00463           switch (cal.GetType())
00464             {
00465             case emcCalibrationData::kIniCal:
00466               {
00467                 cal.SetTypeAndSize(static_cast<emcCalibrationData::EType>(type),
00468                                    emcBank->getLength());
00469                 PdbCoordinate* pdb;
00470                 for ( i = 0; i < cal.GetSize(); i++ )
00471                   {
00472                     pdb = dynamic_cast<PdbCoordinate*>(&(emcBank->getEntry(i)));
00473                     size_t j;
00474                     for ( j = 0; j < cal.GetDimension(); j++ )
00475                       {
00476                         cal.Set(i, pdb->getParameter(j), pdb->getParError(j), j);
00477                       }
00478                   }
00479               }
00480             break;
00481             case emcCalibrationData::kTofSectorOffset:
00482               {
00483                 assert(emcBank->getLength() == 1);
00484                 cal.SetTypeAndSize(static_cast<emcCalibrationData::EType>(type),
00485                                    emcBank->getLength());
00486                 PdbEmcTofSectorOffset* pdb = 
00487                   dynamic_cast<PdbEmcTofSectorOffset*>(&(emcBank->getEntry(0)));
00488 
00489                 assert(cal.GetSize() == 1);
00490 
00491                 cal.Set(0,pdb->runnumber()*1.0,pdb->numberOfEvents()*1.0,0);
00492                 cal.Set(0,pdb->peak(),pdb->width(),1);
00493                 cal.Set(0,pdb->gausPeak(),pdb->gausWidth(),2);
00494                 cal.Set(0,pdb->BBCT0(),pdb->BBCT0rms(),3);
00495                 cal.Set(0,pdb->TOFT0(),pdb->TOFT0rms(),4);
00496               }
00497             break;
00498             default:
00499               {
00500                 cal.SetTypeAndSize(static_cast<emcCalibrationData::EType>(type),
00501                                    emcBank->getLength());
00502                 PdbEmcLCTof* pdb;
00503                 for ( i = 0; i < cal.GetSize(); i++ )
00504                   {
00505                     pdb = dynamic_cast<PdbEmcLCTof*>(&(emcBank->getEntry(i)));
00506                     float value;
00507                     float error;
00508                     pdb->GetLCTofs(value, error);
00509                     cal.Set(i, value, error);
00510                   }
00511               }
00512             }
00513 
00514 
00515           cal.SetNumber(number);
00516           cal.SetValidityPeriod(emcBank->getStartValTime(),
00517                                 emcBank->getEndValTime());
00518 
00519         }
00520       bool commit = fBM->DBApplication()->commit();
00521       kIsRead = commit && kIsRead;
00522       delete emcBank;
00523     } // if (status)
00524 
00525   if (!kIsRead)
00526     {
00527       cal.Reset();
00528     }
00529   else
00530     {
00531       if (DM()->GetVerboseLevel())
00532         {
00533           std::cout << "<I> emcOMCalibrationDataT<" << BM::name()
00534                     << ">::Read : I've read the following "
00535                     << "emcCalibrationData from "
00536                     << emcManageable::GetStorageName(cal.GetSource());
00537           cal.Print();
00538         }
00539     }
00540 
00541   return kIsRead;
00542 }
00543 
00544 //_____________________________________________________________________________
00545 template <class BM>
00546 void
00547 emcOMCalibrationDataT<BM>::Reset(void)
00548 {
00549   std::map<int, std::vector<emcCalibrationData*> * >::iterator p;
00550 
00551   for (p = fCalibrationMap.begin();p != fCalibrationMap.end();p++)
00552     {
00553       std::vector<emcCalibrationData*> *vec = p->second;
00554       size_t i;
00555       for (i = 0;i < vec->size();i++)
00556         {
00557           delete (*vec)[i];
00558         }
00559       delete vec;
00560     }
00561   fCalibrationMap.erase(fCalibrationMap.begin(), fCalibrationMap.end());
00562 }
00563 
00564 //_____________________________________________________________________________
00565 template <class BM>
00566 bool
00567 emcOMCalibrationDataT<BM>::Write(const emcManageable& object,
00568                                  const PHTimeStamp&, int)
00569 {
00570   bool kWritten = false;
00571 
00572   const emcCalibrationData& ccal =
00573     static_cast<const emcCalibrationData&>(object);
00574   emcCalibrationData& cal =
00575     const_cast<emcCalibrationData&>(ccal);
00576 
00577   // Start a write transaction
00578   PdbStatus status = fBM->DBApplication()->startUpdate();
00579 
00580   if (!status)
00581     {
00582       if ( DM()->GetVerboseLevel() )
00583         {
00584           std::cerr << "<E-EMCAL> emcOMCalibrationDataT<" << BM::name()
00585                     << ">::Write : "
00586                     << "Cannot open a write transaction" << std::endl;
00587         }
00588       fBM->DBApplication()->abort();
00589       return false;
00590     }
00591 
00592   PdbCalBank* emcBank = 0;
00593   PHTimeStamp begin, end;
00594   PdbBankID bankID;
00595   GetBankID(cal.GetType(), cal.GetNumber(), bankID);
00596 
00597   std::string pdb_classname = "PdbEmcLCTofBank";
00598   if (cal.GetType() == emcCalibrationData::kIniCal)
00599     {
00600       pdb_classname = "PdbCoordinateBank";
00601     }
00602   else if (cal.GetType() == emcCalibrationData::kTofSectorOffset)
00603     {
00604       pdb_classname = "PdbEmcTofSectorOffsetBank";
00605     }
00606   else
00607     {
00608       std::cerr << __FILE__ << ":" << __LINE__
00609                 << " Do not know how to handle this type"
00610                 << std::endl;
00611       return false;
00612     }
00613 
00614   std::string description = "Written by emcOMCalibrationData (flavour ";
00615   description += cal.GetCategory();
00616   description += ").";
00617   std::string basename = "calib.emc.";
00618   basename += cal.GetCategory();
00619 
00620   begin = cal.GetStartValTime();
00621   end = cal.GetEndValTime();
00622 
00623 
00624   emcBank = fBM->BankManager()->createBank(pdb_classname.c_str(),
00625                                            bankID,
00626                                            description.c_str(),
00627                                            begin, end,
00628                                            basename.c_str());
00629 
00630   assert(emcBank != 0);
00631 
00632   // We then fill the PdbCalBank from the values in cal.
00633   size_t i;
00634 
00635   emcBank->setLength(cal.GetSize());
00636 
00637   switch (cal.GetType())
00638     {
00639     case emcCalibrationData::kIniCal:
00640       {
00641         PdbCoordinate* pdb;
00642 
00643         for ( i = 0; i < emcBank->getLength(); i++ )
00644           {
00645             pdb = (PdbCoordinate*) & (emcBank->getEntry(i));
00646             size_t j;
00647             for ( j = 0; j < cal.GetDimension(); j++ )
00648               {
00649                 pdb->setParameter(j, cal.GetValue(i, j));
00650                 pdb->setParError(j, cal.GetError(i, j));
00651               }
00652           }
00653       }
00654       break;
00655     case emcCalibrationData::kTofSectorOffset:
00656       {
00657         assert(emcBank->getLength() == 1);
00658         PdbEmcTofSectorOffset* pdb = 
00659           (PdbEmcTofSectorOffset*) & (emcBank->getEntry(0));
00660         int runnumber = static_cast<int>(floor(cal.GetValue(0,0)));
00661         int nevents = static_cast<int>(floor(cal.GetError(0,0)));
00662         pdb->setProcessInfo(runnumber,nevents);
00663         pdb->setPeak(cal.GetValue(0,1),cal.GetError(0,1));
00664         pdb->setGausPeak(cal.GetValue(0,2),cal.GetError(0,2));
00665         pdb->setBBC(cal.GetValue(0,3),cal.GetError(0,3));
00666         pdb->setTOF(cal.GetValue(0,4),cal.GetError(0,4));
00667         pdb->print();
00668         break;
00669       }
00670     default:
00671       {
00672         PdbEmcLCTof* pdb;
00673 
00674         for ( i = 0; i < emcBank->getLength(); i++ )
00675           {
00676             pdb = (PdbEmcLCTof*) & (emcBank->getEntry(i));
00677             assert(pdb != 0);
00678             pdb->SetLCTofs(cal.GetValue(i), cal.GetError(i));
00679           }
00680       }
00681     }
00682 
00683   status = fBM->DBApplication()->commit();
00684   if (status)
00685     {
00686       kWritten = true;
00687     }
00688   else
00689     {
00690       std::cerr << "<E> emcOMCalibrationDataT<" << BM::name()
00691                 << ">::Write : commit failed ?!" << std::endl;
00692       kWritten = false;
00693     }
00694 
00695   delete emcBank;
00696 
00697   return kWritten;
00698 }
00699 
00700 
00701 #endif