emcPedestalFEM.C

Go to the documentation of this file.
00001 #include "emcPedestalFEM.h"
00002 #include "emcCalFEMFactory.h"
00003 #include <cstdlib>
00004 #include <cstdio>
00005 #include <iterator>
00006 #include <map>
00007 #include <iomanip>
00008 #include <cassert>
00009 #include <algorithm>
00010 #include <string>
00011 #include <vector>
00012 #include "emcDefines.h"
00013 #include <cmath>
00014 
00015 using namespace std;
00016 
00017 namespace 
00018 {
00019   static string name = "emcPedestalFEM" ;
00020   static string title = "Pedestal calibration data";
00021   string Title(const string& title, int version)
00022   {
00023     string rv = title;
00024     if ( version==0 ) 
00025       {
00026         rv += "(3 per AMU)";
00027       }
00028     else
00029       {
00030         rv += "(5 per AMU)";
00031       }
00032     return rv;
00033   }
00034 
00035   static string classname = "emcPedestalFEM" ;
00036   static float ERROR_VALUE = -9999.99 ;
00037 
00038   emcCalFEM* creator3(int absPosition,
00039                      const PHTimeStamp& start,
00040                      const PHTimeStamp& end,
00041                      bool isDefault)
00042   {
00043     if ( isDefault )
00044       {
00045         return emcPedestalFEM::Default(absPosition,start,end,0);
00046       }
00047     else
00048       {
00049         return new emcPedestalFEM(absPosition,start,end,0);
00050       }
00051   }
00052  
00053   emcCalFEM* creator5(int absPosition,
00054                       const PHTimeStamp& start,
00055                       const PHTimeStamp& end,
00056                       bool isDefault)
00057   {
00058     if ( isDefault )
00059       {
00060         return emcPedestalFEM::Default(absPosition,start,end,1);
00061       }
00062     else
00063       {
00064         return new emcPedestalFEM(absPosition,start,end,1);
00065       }
00066   }
00067 
00068   static bool r3 = emcCalFEMFactory::registerCreator("Pedestals",
00069                                                      creator3);
00070   static bool r5 = emcCalFEMFactory::registerCreator("Pedestals5",
00071                                                      creator5);
00072 }
00073 
00074 //_____________________________________________________________________________
00075 emcPedestalFEM::emcPedestalFEM(int absPosition,
00076                                const PHTimeStamp& t1, const PHTimeStamp& t2,
00077                                int version)
00078   : emcCalFEM(absPosition,t1,t2)
00079 {
00080   NameIt(name,Title(title,version),classname) ;
00081   SetVersion(version) ;
00082   fValidTypes = emcPedestalFEM::ValidTypes(version) ;
00083 }
00084 
00085 //_____________________________________________________________________________
00086 emcPedestalFEM::emcPedestalFEM(int absPosition,                        
00087                                int version)
00088   : emcCalFEM(absPosition)
00089 {
00090   NameIt(name,Title(title,version),classname) ;
00091   SetVersion(version) ;
00092   fValidTypes = emcPedestalFEM::ValidTypes(version) ;
00093 }
00094 
00095 //_____________________________________________________________________________
00096 emcPedestalFEM::emcPedestalFEM(const emcPedestalFEM& o)
00097   : emcCalFEM(o.AbsolutePosition())
00098 {
00099   o.Copy(*this) ;
00100 }
00101 
00102 //_____________________________________________________________________________
00103 emcPedestalFEM&
00104 emcPedestalFEM::operator=(const emcPedestalFEM& o)
00105 {
00106   if ( this == &o ) return *this ;
00107   Reset() ;
00108   o.Copy(*this) ;
00109   return *this ;
00110 }
00111 
00112 //_____________________________________________________________________________
00113 void
00114 emcPedestalFEM::Copy(emcPedestalFEM& o) const
00115 {
00116   emcCalFEM::Copy(o) ;
00117   o.SetVersion(Version()) ;
00118   o.Reset() ;
00119   o.fValidTypes = emcPedestalFEM::ValidTypes(Version()) ;
00120   size_t i ;
00121 
00122   for ( i = 0 ; i < fValidTypes.size() ; i++) {
00123     string type = fValidTypes[i] ;
00124     o.fPed[type] = new ChannelVector ;
00125     ChannelVector* vec = fPed[type] ;
00126     assert(vec!=0) ;
00127     size_t j ;
00128     for ( j = 0 ; j < vec->size() ; j++) {
00129       o.fPed[type]->push_back((*vec)[j]) ;
00130     }
00131   }  
00132 }
00133 
00134 //_____________________________________________________________________________
00135 emcPedestalFEM::~emcPedestalFEM()
00136 {
00137   Reset() ;
00138 }
00139 
00140 //_____________________________________________________________________________
00141 void emcPedestalFEM::AppendOneChannel(const char* sped_type, AmuVector& vec)
00142 {
00143   assert (IsValidType(sped_type)) ;
00144   assert (vec.size()==64) ;
00145 
00146   string ped_type = sped_type ;
00147 
00148   if (fPed[ped_type]==0) {
00149     fPed[ped_type] = new ChannelVector ;
00150   }
00151 
00152   int thesize = fPed[ped_type]->size() ;
00153 
00154   if (thesize<144) {
00155     float average = 0 ;
00156     float rms = 0 ;
00157     for ( size_t i = 0 ; i < vec.size() ; i++) {
00158       average += vec[i] ;
00159     }
00160     average /= vec.size() ;
00161     if ( vec.size() > 1 ) {
00162       for ( size_t i = 0 ; i < vec.size() ; i++) {
00163         rms += (vec[i]-average)*(vec[i]-average) ;
00164       }
00165       rms /= vec.size()-1 ;
00166     }
00167     rms = sqrt(rms) ;
00168     fPed[ped_type]->push_back(vec) ;
00169     int iaverage = static_cast<int>(floor(average+0.5));
00170     fPedAverage[ped_type].push_back(iaverage) ;
00171     fPedRMS[ped_type].push_back(rms) ;
00172     if ( ped_type == "TAC" ) 
00173       {
00174         const std::string ksTACDEV = "TACDEV";
00175 
00176         AmuVector vecdev = vec;
00177         float devmean = 0.0;
00178 
00179         for ( size_t i = 0; i < vecdev.size(); ++i )
00180           {
00181             vecdev[i] -= iaverage;
00182             devmean += vecdev[i];
00183           }
00184         devmean /= vecdev.size();
00185         float devrms = 0.0;
00186         for ( size_t i = 0; i < vecdev.size(); ++i )
00187           {
00188             devrms += (vecdev[i]-devmean)*(vecdev[i]-devmean);
00189           }
00190         devrms /= vecdev.size() - 1;
00191 
00192         if (!fPed[ksTACDEV])
00193           {
00194             fPed[ksTACDEV] = new ChannelVector;
00195           }
00196         fPed[ksTACDEV]->push_back(vecdev);
00197         fPedAverage[ksTACDEV].push_back(static_cast<int>(floor(devmean+0.5)));
00198         fPedRMS[ksTACDEV].push_back(devrms);
00199       }
00200   }
00201   else {
00202     cerr << EMC_ERROR_MSG 
00203          << " emcPedestalFEM::AppendOneChannel : FEM is already full" << endl ;
00204   }
00205 }
00206 
00207 //_____________________________________________________________________________
00208 emcPedestalFEM*
00209 emcPedestalFEM::Default(const int& absPosition, 
00210                         const PHTimeStamp& t1, 
00211                         const PHTimeStamp& t2,
00212                         int version) 
00213 {
00214   emcPedestalFEM* fem = new emcPedestalFEM(absPosition,t1,t2,version) ;
00215 
00216   AmuVector vec(64,0) ;
00217 
00218   size_t ch, i ;
00219 
00220   vector<string> ped_types = emcPedestalFEM::ValidTypes(fem->Version()) ;
00221 
00222   for ( ch = 0 ; ch < 144 ; ch++ ) {
00223     for ( i = 0 ; i < ped_types.size() ; i++ ) {
00224       fem->AppendOneChannel(ped_types[i].c_str(),vec) ;
00225     }
00226   }
00227 
00228   return fem ;
00229 }
00230 
00231 //_____________________________________________________________________________
00232 const char* 
00233 emcPedestalFEM::GetCategory(void) const
00234 {
00235   if (Version()==0) return "Pedestals" ;
00236   if (Version()==1) return "Pedestals5" ;
00237   std::cerr << "<E> " << __FILE__ << ":" << __LINE__ << " Version unknown!!!"
00238             << std::endl;
00239   return "Unknown";
00240 }
00241 
00242 //_____________________________________________________________________________
00243 size_t emcPedestalFEM::GetNumberOfChannels(void) const
00244 { 
00245   /* FIXME: The logic of this function might be a little too complicated
00246      for what it really does... But it's better to warn the user in case
00247      the object has not been filled completely (i.e. not all ped types
00248      have the same size, which we call here not 'consistent' state).
00249    */
00250 
00251   size_t i ;
00252   size_t thesize = 0 ;
00253   ChannelVector* cv = 0 ;
00254 
00255   // we first search for the first ped array which is not void
00256   for ( i = 0 ; i < fValidTypes.size() && cv == 0; i++ ) {
00257     cv = fPed[fValidTypes[i]] ;
00258     if (cv) {
00259       thesize = cv->size() ;
00260     }
00261   }
00262 
00263   if (thesize==0) return 0 ; // everything is void
00264 
00265   // we then check that all ped arrays have the same size
00266   
00267   bool consistent = true ;
00268 
00269   for ( i = 0 ; i < fValidTypes.size() ; i++ ) {
00270     cv = fPed[fValidTypes[i]] ;
00271     if (cv) {
00272       if ( cv->size() != thesize ) consistent = false ;
00273     } else {
00274       consistent = false ;
00275     }
00276   }
00277 
00278   if (!consistent) {
00279     cerr << EMC_ERROR_MSG 
00280          << " Pedestal object not in consistent state: " << endl ;
00281     for ( i = 0 ; i<fValidTypes.size() ; i++ ) {
00282       cv = fPed[fValidTypes[i]] ;
00283       if (cv) {
00284         cerr << fValidTypes[i] << " has a size of " <<  cv->size() << endl ;
00285       } else {
00286         cerr << fValidTypes[i] << " has a size of " <<  0 << endl ;
00287       }
00288     }
00289   }
00290 
00291   // warning: if not in consistent state, thesize is the size
00292   // of the first ped type which is filled ! FIXME ? to return the max value?
00293   return thesize ;
00294 }
00295 
00296 //_____________________________________________________________________________
00297 float
00298 emcPedestalFEM::getValue(int ich, const string& ped_type, float& rms) const
00299 {
00300   rms = 0.0 ;
00301   if ( !IsValidType(ped_type) ) return ERROR_VALUE ;
00302   vector<int>& vec = fPedAverage[ped_type] ;
00303   if ( ich < 0 || ich >= static_cast<int>(vec.size()) ) {
00304     return ERROR_VALUE ;
00305   }
00306   return getValueFast(ich,ped_type,rms) ;
00307 }
00308 
00309 //_____________________________________________________________________________
00310 float
00311 emcPedestalFEM::getValueFast(int ich, const string& ped_type, float& rms) const
00312 {
00313   rms = fPedRMS[ped_type][ich] ;
00314   return fPedAverage[ped_type][ich] ;
00315 }
00316 
00317 //_____________________________________________________________________________
00318 float
00319 emcPedestalFEM::getValue(int ch_index, int amu_number, 
00320                          const string& ped_type) const
00321 {
00322   float err_value = ERROR_VALUE ;
00323 
00324   if (!IsValidType(ped_type)) return err_value ;
00325   ChannelVector* cv = fPed[ped_type] ;
00326 
00327   if (cv==0) {
00328     static bool first = true ;
00329     if (first) {
00330       cerr << EMC_ERROR_MSG << "emcPedestalFEM::getValue : cv is NULL. "
00331            << endl << "Please check that. "
00332            << "This message will _not_ be repeated even if " << endl
00333            << "the same error occurs again." << endl ;
00334     }
00335     first=false ;
00336     return err_value ;
00337   }
00338 
00339   if ( ch_index < 0 || ch_index >= static_cast<int>(cv->size()) ) {
00340     return err_value ;
00341   }
00342   if ( amu_number < 0 || amu_number >= static_cast<int>((*cv)[ch_index].size()) ) {
00343     return err_value ;
00344   }
00345   return (*cv)[ch_index][amu_number] ;
00346 }
00347 
00348 //_____________________________________________________________________________
00349 float 
00350 emcPedestalFEM::getValueFast(int ch_index, int amu_number, 
00351                              const string& ped_type) const
00352 {
00353   return (*(fPed[ped_type]))[ch_index][amu_number] ;
00354 }
00355 
00356 //_____________________________________________________________________________
00357 void emcPedestalFEM::GetValues(int ch_index, int amu_number, 
00358                                int& low, int& high, int& tac)
00359 {
00360   // This method assumes that LG_Pre-Post, HG_Pre-Post and TAC are
00361   // valid ped types.  WARNING: No check on ch_index and amu_number !
00362 
00363   low  = (*fPed["LG_Pre-Post"])[ch_index][amu_number] ;
00364   high = (*fPed["HG_Pre-Post"])[ch_index][amu_number] ;
00365   tac  = (*fPed["TAC"])[ch_index][amu_number] ;
00366 }
00367 
00368 //_____________________________________________________________________________
00369 bool
00370 emcPedestalFEM::IsEqual(const emcCalFEM& obj) const
00371 {
00372   if ( !dynamic_cast<const emcPedestalFEM*>(&obj) ) return false ;
00373 
00374   if ( obj.size() != size() ) return false ;
00375 
00376   if ( Version() != obj.Version() ) return false ;
00377 
00378   vector<string> obj_types = ValidTypes(obj.Version()) ;
00379 
00380   if ( obj_types.size() != fValidTypes.size() ) return false ;
00381 
00382   for ( size_t t = 0 ; t < fValidTypes.size() ; t++ ) {
00383 
00384     string type = fValidTypes[t] ;
00385 
00386     for ( size_t ichannel = 0 ; ichannel < size() ; ichannel++) {
00387       for ( size_t amu = 0 ; amu < 64 ; amu++) {       
00388         if ( getValue(ichannel,amu,type) != obj.getValue(ichannel,amu,type) ) {
00389           return false ;
00390         }
00391       }
00392     }
00393 
00394   }
00395 
00396   return true ;
00397 }
00398 
00399 //_____________________________________________________________________________
00400 bool emcPedestalFEM::IsValidType(const string& sped) const
00401 {
00402   vector<string>::const_iterator result ;
00403 
00404   result = find(fValidTypes.begin(),fValidTypes.end(),sped) ;
00405 
00406   if (result!=fValidTypes.end()) return true ;
00407 
00408   cout << "<E> Invalid ped type : " << sped << endl ;
00409   return false ;
00410 }
00411 
00412 //_____________________________________________________________________________
00413 void emcPedestalFEM::Reset(void)
00414 {
00415   size_t i ;
00416 
00417   for ( i = 0 ; i < fValidTypes.size() ; i++ ) {
00418     delete fPed[fValidTypes[i]] ;
00419   }
00420   fPed.clear() ;
00421   fPedAverage.clear() ;
00422   fPedRMS.clear() ;
00423 }
00424 
00425 //_____________________________________________________________________________
00426 ostream&
00427 emcPedestalFEM::Print(ostream& out, int level) const
00428 {
00429   emcCalFEM::Print(out,level);
00430 
00431   if (level) {
00432 
00433     map<string,emcPedestalFEM::ChannelVector*>::const_iterator it ;
00434     emcPedestalFEM::ChannelVector* cv ;
00435     size_t ch,amu ;
00436     size_t rc ;
00437     
00438     for (it=fPed.begin();it!=fPed.end();it++) {
00439       out << string(50,'-')  << endl ;
00440       out << "-- Pedestals for " << it->first << endl ;
00441       out << string(50,'-') << endl ;
00442       cv = it->second ;
00443       assert (cv!=0) ;
00444       for (ch=0;ch<cv->size();ch++) {
00445         out << "CH# " << ch << "\t : " ;
00446         rc = 0 ;
00447         for (amu=0;amu<(*cv)[ch].size();amu++) {
00448           rc++ ;
00449           out << static_cast<int>((*cv)[ch][amu]) << " " ;
00450           if (rc==10) {
00451             out << endl ;
00452             out << "\t : " ;
00453             rc = 0 ;
00454           }
00455         }
00456         out << "Average=" << fPedAverage[it->first][ch]
00457             << " RMS=" << fPedRMS[it->first][ch] << endl ;
00458         out << endl ;
00459       }
00460     }
00461   }
00462   return out ;
00463 }
00464 
00465 //_____________________________________________________________________________
00466 vector<string>
00467 emcPedestalFEM::ValidTypes(int version) 
00468 {
00469   vector<string> validtypes ;
00470 
00471   if (version==1) {
00472     validtypes.push_back("LG_Pre") ;
00473     validtypes.push_back("HG_Pre") ;
00474     validtypes.push_back("LG_Post") ;
00475     validtypes.push_back("HG_Post") ;
00476     validtypes.push_back("TAC") ;
00477     validtypes.push_back("TACDEV") ;
00478   }
00479   else if (version==0) {
00480     validtypes.push_back("LG_Pre-Post") ;
00481     validtypes.push_back("HG_Pre-Post") ;
00482     validtypes.push_back("TAC") ;
00483   }
00484   else {
00485     assert(0==1) ;
00486   }
00487 
00488   return validtypes ;
00489 }