emcBadModulesv1.C

Go to the documentation of this file.
00001 #include "emcBadModulesv1.h"
00002 
00003 #include "emcDefines.h"
00004 #include "emcFEMList.h"
00005 #include "EmcIndexer.h"
00006 #include "PbScIndexer.h"
00007 #include "PbGlIndexer.h"
00008 #include "emcDataManager.h"
00009 #include "emcManageable.h"
00010 #include "emcQAFEM.h"
00011 #include "emcRejectList.h"
00012 
00013 #include <fstream>
00014 #include <cstdio>
00015 #include <cassert>
00016 #include <sstream>
00017 
00018 ClassImp(emcBadModulesv1)
00019 
00020 using namespace std;
00021 
00022 static size_t NFEMS = 172;
00023 static size_t NCHANNELS = NFEMS*144;
00024 
00025 static string INFO_NO_REJECT_FILE = "<INFO> No Q&A information from physics.";
00026 static string ERROR_CANNOT_READ_REJECT_FILE = "<ERROR> Cannot open reject file ";
00027 
00028 //_____________________________________________________________________________
00029 emcBadModulesv1::emcBadModulesv1()
00030   : fDataSource(emcDataStorageMap(emcManageable::kNone)),
00031     fOrigin(emcBadModules::kNone),
00032     fDirectory(""),
00033     fTimeStamp(0),
00034     fIsRejectListAlreadyRead(false)
00035 {
00036   Allocate();
00037   ComputeMaps();
00038 }
00039 
00040 //_____________________________________________________________________________
00041 emcBadModulesv1::emcBadModulesv1(const char* directory, 
00042                                  emcBadModules::EInformationOrigin origin,
00043                                  bool init,
00044                                  const char* sectors)
00045   : fDataSource(emcDataStorageMap(emcManageable::kFile_ASCII)),
00046     fOrigin(origin),
00047     fDirectory(directory), 
00048     fTimeStamp(0),
00049     fIsRejectListAlreadyRead(false)
00050 {
00051   Allocate();
00052   if (init) 
00053     {
00054       ComputeMaps(sectors);
00055     }
00056 }
00057 
00058 //_____________________________________________________________________________
00059 emcBadModulesv1::emcBadModulesv1(const PHTimeStamp& ts,
00060                                  emcBadModules::EInformationOrigin origin,
00061                                  const emcDataStorageMap& source,
00062                                  bool init,
00063                                  const char* sectors)
00064   : fDataSource(source),
00065     fOrigin(origin),
00066     fDirectory(""), 
00067     fTimeStamp(ts),
00068     fIsRejectListAlreadyRead(false)
00069 {
00070   Allocate();
00071   if (init) 
00072     {
00073       ComputeMaps(sectors);
00074     }
00075 }
00076 
00077 //_____________________________________________________________________________
00078 emcBadModulesv1::emcBadModulesv1(const emcBadModulesv1& bm) 
00079   : emcBadModules()
00080 {
00081   bm.copyTo(*this);
00082 }
00083 
00084 //_____________________________________________________________________________
00085 emcBadModulesv1&
00086 emcBadModulesv1::operator=(const emcBadModulesv1& bm)
00087 {
00088   if ( this != &bm )
00089     {
00090       bm.copyTo(*this);
00091     }
00092   return *this;
00093 }
00094 
00095 //_____________________________________________________________________________
00096 void
00097 emcBadModulesv1::copyTo(emcBadModulesv1& to) const
00098 {
00099   to.fDataSource = fDataSource;
00100   to.fOrigin = fOrigin;
00101   to.fDirectory = fDirectory;
00102   to.fTimeStamp = fTimeStamp;
00103   to.fErrorMap = fErrorMap;
00104   to.fWarnMap = fWarnMap;
00105   to.fCollectedFEMs = fCollectedFEMs;
00106   to.fComputedFEMs = fComputedFEMs;
00107   to.fErrorRaw = fErrorRaw;
00108   to.fWarnRaw = fWarnRaw;
00109 }
00110 
00111 //_____________________________________________________________________________
00112 emcBadModulesv1::~emcBadModulesv1()
00113 {
00114   
00115 }
00116 
00117 //_____________________________________________________________________________
00118 void
00119 emcBadModulesv1::Allocate(void)
00120 {
00121   fErrorRaw[emcBadModules::kOnline].resize(NCHANNELS,0);
00122   fWarnRaw[emcBadModules::kOnline].resize(NCHANNELS,0);
00123 
00124   fErrorRaw[emcBadModules::kPhysics].resize(NCHANNELS,0);
00125   fWarnRaw[emcBadModules::kPhysics].resize(NCHANNELS,0);
00126 
00127   fErrorMap.resize( fErrorRaw[emcBadModules::kOnline].size() , 0 );
00128   fWarnMap.resize( fErrorRaw[emcBadModules::kOnline].size() , 0 ); 
00129 
00130   fCollectedFEMs.resize(NFEMS,false);
00131   fComputedFEMs.resize(NFEMS,false);
00132 }
00133 
00134 //_____________________________________________________________________________
00135 void
00136 emcBadModulesv1::Collect(size_t ifem)
00137 {
00138   if ( fOrigin == emcBadModules::kPhysics || fOrigin == emcBadModules::kAll ) 
00139     {
00140       CollectPhysicsQA();
00141     }
00142 
00143   if ( fOrigin == emcBadModules::kOnline || fOrigin == emcBadModules::kAll ) 
00144     {
00145       CollectOnlineQA(ifem);
00146     }
00147 
00148   fCollectedFEMs[ifem] = true;
00149 }
00150 
00151 //_____________________________________________________________________________
00152 string 
00153 emcBadModulesv1::CollectPhysicsQA(void)
00154 {
00155   if ( fIsRejectListAlreadyRead ) 
00156     {
00157       return "";
00158     }
00159 
00160   if ( fDataSource.storage("RejectList") == emcManageable::kNone ) 
00161     {
00162       return "";
00163     }
00164 
00165   emcRejectList rl;
00166 
00167   rl.SetSource(fDataSource.storage("RejectList"));
00168 
00169   emcDataManager* dm = emcDataManager::GetInstance();
00170 
00171   string sourcedir = dm->GetSourceDir();
00172   
00173   dm->SetSourceDir(fDirectory.c_str());
00174 
00175   bool ok = dm->Read(rl,fTimeStamp);
00176 
00177   if ( ok )
00178     {
00179       for ( size_t towerid = 0; towerid < rl.maxsize(); ++towerid ) 
00180         {
00181           fErrorRaw[emcBadModules::kPhysics][towerid] = rl.Error(towerid);
00182           fWarnRaw[emcBadModules::kPhysics][towerid] = rl.Warning(towerid);
00183         }
00184       fIsRejectListAlreadyRead=true;
00185       return "";
00186     }
00187   else
00188     {
00189       string msg = "Could not read Physics QA information from ";
00190       msg += emcManageable::GetStorageName(fDataSource.storage("QAs"));
00191       return msg;
00192     }
00193 }
00194 
00195 //_____________________________________________________________________________
00196 string 
00197 emcBadModulesv1::CollectOnlineQA(void)
00198 {
00199   for ( size_t i = 0; i < NFEMS; i++ ) 
00200     {
00201       string msg = CollectOnlineQA(i);
00202       if ( msg != "" ) 
00203         {
00204           cerr << msg << endl;
00205         }
00206     }  
00207   return "";
00208 }
00209 
00210 //_____________________________________________________________________________
00211 string
00212 emcBadModulesv1::CollectOnlineQA(size_t ifem)
00213 {
00214   string msg = "";
00215 
00216   if ( fDataSource.storage("QAs") == emcManageable::kNone )
00217     {
00218       return "";
00219     }
00220 
00221   emcQAFEM qaFEM(ifem);
00222   qaFEM.SetSource(fDataSource.storage("QAs"));
00223   emcDataManager* dm = emcDataManager::GetInstance();
00224   bool ok = dm->Read(qaFEM, fTimeStamp);
00225   if ( !ok )
00226     {
00227       ostringstream message;
00228       message << "Cannot collect FEM " << ifem
00229               << " from "
00230               << emcManageable::GetStorageName(fDataSource.storage("QAs"))
00231               << " : using defaults instead";
00232       emcQAFEM* def = emcQAFEM::Default(ifem);
00233       qaFEM = *def;
00234       delete def;
00235       msg = message.str();
00236     }
00237 
00238   // Copy information from QAFEM object to our guts.
00239 
00240   for ( size_t i = 0; i < qaFEM.size(); i++) 
00241     {
00242       int towerID = EmcIndexer::PXSM144iCH_iPX(ifem,i);
00243       fErrorRaw[emcBadModules::kOnline][towerID] = 
00244         static_cast<unsigned int>(qaFEM.getValue(i,0));
00245       fWarnRaw[emcBadModules::kOnline][towerID] = 
00246         static_cast<unsigned int>(qaFEM.getValue(i,1));
00247     }
00248 
00249   return msg;
00250 }
00251 
00252 //_____________________________________________________________________________
00253 void
00254 emcBadModulesv1::ComputeMaps(const char* sectors)
00255 {
00256   if ( fDirectory.empty() && 
00257        ( fDataSource.storage("QAs") != emcManageable::kNone ||
00258          fDataSource.storage("RejectList") != emcManageable::kNone) 
00259        )
00260     {
00261       std::cout << "emcBadModulesv1::ComputeMaps : using timestamp="
00262                 << fTimeStamp << std::endl;
00263     }
00264 
00265   emcFEMList fems(sectors);
00266 
00267   for (size_t i = 0; i < NFEMS; i++ ) 
00268     {
00269       if ( fems.hasFEM(i) )
00270         {
00271           ComputeMaps(i);
00272         }
00273     }
00274 }
00275 
00276 //_____________________________________________________________________________
00277 void 
00278 emcBadModulesv1::ComputeMaps(size_t ifem)
00279 {
00280   // Compute the neighbour error and warning flags for each tower
00281   // in the fem ifem.
00282   //
00283   // For amplitude bits are:
00284   // ---------------------
00285   // |   | 18| 19| 20|   |
00286   // ---------------------
00287   // | 13| 14| 15| 16| 17|
00288   // ---------------------  ^ y
00289   // | 8 | 9 | 10| 11| 12|  |
00290   // ---------------------  |
00291   // | 3 | 4 | 5 | 6 | 7 |  |
00292   // ---------------------  ------> z(x)
00293   // |   | 0 | 1 | 2 |   |
00294   // ---------------------
00295   // as viewed from the back of the central tower (which has bit 10 set
00296   // to 1 if it's itself a bad module); corner towers are excluded
00297   //
00298   // For ToF bits are :
00299   // -------------
00300   // | 27| 28| 29|  ^ y
00301   // -------------  |
00302   // | 24| 25| 26|  |
00303   // -------------  |
00304   // | 21| 22| 23|  ------> z(x)
00305   // -------------
00306   // as viewed from the back of the central tower (which has bit 25 set
00307   // to 1 if it's itself a bad module)
00308   //
00309   // So, a channel has a problem with amplitude measurements if its neighbor
00310   // error bit map  satisfies this mask:
00311   //            0x400
00312   // Actually, this mask is returned by the IamDeadMask() method
00313   // so that the amplitude for bad modules can be set to 0 at the calibration
00314   // stage.
00315   //
00316   // Some other useful masks.
00317   // The mask to look for amplitude errors or warnings in the 3x3 region
00318   // around a tower is:
00319   //          0x1ce70
00320   // In the 5x5 region:
00321   //         0x1fffff
00322   // To see if there are ToF problems for this tower:
00323   //        0x2000000
00324 
00325   if ( fComputedFEMs[ifem] ) return;
00326 
00327   // Be sure all the information we need is there.
00328   if ( ! fCollectedFEMs[ifem] ) 
00329     {
00330       vector<size_t> fems;
00331       GetListOfNeighbourFEMs(ifem,fems);
00332       for ( size_t i = 0; i < fems.size(); i++) 
00333         {
00334           if ( ! fCollectedFEMs[ fems[i] ] ) 
00335             {
00336               Collect(fems[i]);
00337             }
00338         }
00339     }
00340 
00341   // Mind your steps. In the loop below, only *Fast methods are allowed
00342   // as the non-Fast method use update() which in turn use this ComputeMaps
00343   // method (i.e. you would end up in infinite recursion trying to use
00344   // non-Fast methods here).
00345 
00346   for ( size_t i = 0; i < 144; i++ ) 
00347     {
00348       int towerID = EmcIndexer::PXSM144iCH_iPX(ifem,i);
00349       int sector,x,y;
00350       EmcIndexer::decodeTowerId(towerID,sector,x,y);
00351       
00352       unsigned int neighbourError = 0;
00353       unsigned int neighbourWarn = 0;
00354       unsigned int bitOffset = 0;
00355       
00356       //
00357       // Amplitude tests first (in a 5x5 area).
00358       //
00359       
00360       for ( int yoff = -2; yoff <= 2; yoff++ ) {       
00361         for ( int xoff = -2; xoff <= 2; xoff++ ) {
00362           //=====> check if this is a corner tower
00363           bool corner=
00364             (xoff==-2 && yoff==-2) ||
00365             (xoff==-2 && yoff== 2) ||
00366             (xoff== 2 && yoff==-2) ||
00367             (xoff== 2 && yoff== 2);
00368           
00369           if (corner) continue;
00370           
00371           if (!EmcIndexer::IsValid(sector, x+xoff, y+yoff)) 
00372             {
00373               // physical boundaries (edges)
00374               neighbourError |= (1<<bitOffset);
00375               neighbourWarn |= (1<<bitOffset);          
00376             }
00377           else 
00378             {
00379               int neighbourTower = 
00380                 EmcIndexer::getTowerId(sector,x+xoff,y+yoff);
00381               
00382               // Errors
00383               if ( ( ErrorFast(kPhysics,neighbourTower) & 
00384                      fMASK_Ampl_Physics ) ||
00385                    ( ErrorFast(kOnline,neighbourTower ) & 
00386                      fMASK_Ampl_Online ) ) 
00387                 {
00388                   neighbourError |= ( 1 << bitOffset );
00389                 }
00390               
00391               // Warnings
00392               if ( ( WarningFast(kPhysics,neighbourTower) & 
00393                      fMASK_Ampl_Physics ) ||
00394                    ( WarningFast(kOnline,neighbourTower ) & 
00395                      fMASK_Ampl_OnlineWarn ) ) 
00396                 {
00397                   neighbourWarn |= ( 1 << bitOffset );
00398                 }
00399             }     
00400           bitOffset++;
00401         }
00402       } // end of ampl tests.
00403       
00404       //
00405       // timing tests then. (in a 3x3 area).
00406       //
00407       
00408       for ( int yoff = -1; yoff <= 1; yoff++ ) {
00409         for ( int xoff = -1; xoff <= 1; xoff++ ) {
00410           
00411           if (!EmcIndexer::IsValid(sector, x+xoff, y+yoff)) {
00412             // physical boundaries (edges)
00413             neighbourError |= (1<<bitOffset);
00414             neighbourWarn |= (1<<bitOffset);        
00415           }
00416           else {
00417             
00418             int neighbourTower = EmcIndexer::getTowerId(sector,x+xoff,y+yoff);
00419             
00420             // Errors
00421             if ( ( ErrorFast(kPhysics,neighbourTower) & fMASK_TOF_Physics ) ||
00422                  ( ErrorFast(kOnline,neighbourTower ) & fMASK_TOF_Online ) ) 
00423               {
00424                 neighbourError |= ( 1 << bitOffset );
00425               }
00426             
00427             // Warnings
00428             if ( ( WarningFast(kPhysics,neighbourTower) & fMASK_TOF_Physics ) 
00429                  ||
00430                  ( WarningFast(kOnline,neighbourTower ) & fMASK_TOF_OnlineWarn 
00431                    ) ) 
00432               {
00433                 neighbourWarn |= ( 1 << bitOffset );
00434               }
00435           }       
00436           bitOffset++;
00437         }
00438       } // end of timing tests.
00439       
00440       fErrorMap[towerID] = neighbourError;
00441       fWarnMap[towerID] = neighbourWarn;
00442       
00443     } // end of loop over towers.
00444   
00445   fComputedFEMs[ifem] = true;
00446 }
00447 
00448 //_____________________________________________________________________________
00449 unsigned int 
00450 emcBadModulesv1::Error(emcBadModules::EInformationOrigin source, 
00451                      int towerID)
00452 {
00453   if ( !IsValid(towerID) ) return 0;
00454   update(towerID);
00455 
00456   return ErrorFast(source,towerID);
00457 }
00458 
00459 //_____________________________________________________________________________
00460 unsigned int
00461 emcBadModulesv1::ErrorFast(emcBadModules::EInformationOrigin source, 
00462                          int towerID) const
00463 {
00464   RawMapIterator it;
00465   it = fErrorRaw.find(source);
00466   if ( it != fErrorRaw.end() ) 
00467     {
00468       return (it->second)[towerID];
00469     }
00470   else 
00471     {
00472       return 0;
00473     }
00474 }
00475 
00476 //_____________________________________________________________________________
00477 unsigned int
00478 emcBadModulesv1::Deadmap(int towerID)
00479 {
00480   if ( !IsValid(towerID) ) return 0;
00481   update(towerID);
00482   return DeadmapFast(towerID);
00483 }
00484 
00485 //_____________________________________________________________________________
00486 unsigned int
00487 emcBadModulesv1::DeadmapFast(int towerID) const
00488 {
00489   return fErrorMap[towerID];
00490 }
00491 
00492 //_____________________________________________________________________________
00493 void
00494 emcBadModulesv1::GetListOfNeighbourFEMs(size_t ifem, vector<size_t>& fems)
00495 {
00496   int iS;
00497   int iSM;
00498 
00499   fems.clear();
00500 
00501   EmcIndexer::PXSM144_iSiSM144(ifem, iS, iSM);
00502   
00503   EmcIndexer* indexer;
00504   
00505   assert(iS>=0 && iS<8);
00506   
00507   if (iS<6) 
00508     {
00509       indexer = PbScIndexer::buildPbScIndexer();
00510     }
00511   else 
00512     {
00513       indexer = PbGlIndexer::buildPbGlIndexer();
00514     }
00515   
00516   int xref,yref;
00517   
00518   indexer->SMxySM(iSM,xref,yref);
00519   
00520   int x,y;
00521   
00522   for (x=xref-1;x<=xref+1;x++) {
00523     for (y=yref-1;y<=yref+1;y++) {
00524       iSM = indexer->xySMiSM(x,y);
00525       if (iSM>-1) {
00526         int sm_phenix_scope = EmcIndexer::iSiSM144_PXSM144(iS, iSM);    
00527         assert(sm_phenix_scope>=0);
00528         fems.push_back(static_cast<size_t>(sm_phenix_scope));
00529       }
00530     }
00531   }
00532 }
00533 
00534 //_____________________________________________________________________________
00535 void
00536 emcBadModulesv1::identify(std::ostream& os) const
00537 {
00538   os << "emcBadModulesv1" << endl;
00539 }
00540 
00541 //_____________________________________________________________________________
00542 int
00543 emcBadModulesv1::isValid() const
00544 {
00545   return 1;
00546 }
00547 
00548 //_____________________________________________________________________________
00549 bool 
00550 emcBadModulesv1::IsValid(int towerID) const
00551 {
00552   return ( towerID >=0 && towerID < static_cast<int>(fErrorMap.size()) );
00553 }
00554 
00555 //_____________________________________________________________________________
00556 ostream& 
00557 emcBadModulesv1::Print(int towerid, ostream& out)
00558 {
00559   string head = " TOWID FEM  CH SEC  Z  Y   ERRonl  WARNonl  ERRphys  WARNphys  ERRMAP  WARNMAP";
00560 
00561   size_t rc = 20;
00562   size_t count = rc;
00563 
00564   if ( towerid == -1 ) 
00565     {
00566       for ( size_t i = 0; i < fErrorMap.size(); i++ ) 
00567         {
00568           if ( count == rc )
00569             {
00570               out << head << endl;
00571               count = 0;
00572             }
00573           PrintOne(i,out);
00574           ++count;
00575         }
00576     }
00577   else
00578     {
00579       out << head << endl;
00580       PrintOne(towerid,out);
00581     }
00582   return out;
00583 }
00584 
00585 //_____________________________________________________________________________
00586 ostream& 
00587 emcBadModulesv1::PrintOne(int towerID, ostream& out)
00588 {
00589   ostream::fmtflags oldflags = out.flags();
00590 
00591   int femAbsolutePosition, femChannel;
00592   int sector, z, y;
00593   
00594   EmcIndexer::PXPXSM144CH(towerID, femAbsolutePosition, femChannel);
00595   
00596   EmcIndexer::decodeTowerId(towerID, sector, z, y );
00597 
00598   // We put those into local variables, just in case
00599   // some data collection occurs in the methods in the r.h.s. of
00600   // the expressions below (because in collection some messages can
00601   // be output on the screen and would screw up this PrintOne method output).
00602   int errOnl = Error(emcBadModules::kOnline,towerID);
00603   int warnOnl = Warning(emcBadModules::kOnline,towerID);
00604   int errPhy = Error(emcBadModules::kPhysics,towerID);
00605   int warnPhy = Warning(emcBadModules::kPhysics,towerID);
00606   unsigned int dead = Deadmap(towerID);
00607   unsigned int warn = Warnmap(towerID);
00608   
00609   out << setw(6) << towerID << " " 
00610       << setw(3) << femAbsolutePosition << " "
00611       << setw(3) << femChannel << " "
00612       << setw(3) << sector << " "
00613       << setw(2) << z << " "
00614       << setw(2) << y << " ";
00615   
00616   out.setf(ostream::showbase);
00617   out.setf(ostream::hex,ostream::basefield);
00618   
00619   out << setw(8) << errOnl << " "
00620       << setw(8) << warnOnl  << " "
00621       << setw(8) << errPhy << " "
00622       << setw(8) << warnPhy << " "
00623       << setw(8) << dead << " "
00624       << setw(8) << warn << endl;
00625   
00626   out.setf(oldflags);
00627 
00628   return out;
00629 }
00630 
00631 //_____________________________________________________________________________
00632 void
00633 emcBadModulesv1::Reset()
00634 {
00635   Allocate();
00636   fDataSource.clear();
00637   fOrigin = emcBadModules::kNone;
00638   fDirectory = "";
00639   fTimeStamp.setTics(0);
00640   fIsRejectListAlreadyRead=false;
00641 }
00642 
00643 // //_____________________________________________________________________________
00644 // int 
00645 // emcBadModules::TowerID(int femAbsolutePosition, int femChannel) const
00646 // {
00647 //   return EmcIndexer::PXSM144iCH_iPX(femAbsolutePosition,femChannel);
00648 // }
00649 
00650 //_____________________________________________________________________________
00651 void
00652 emcBadModulesv1::update(int towerID)
00653 {
00654   int ifem, ichannel;
00655   EmcIndexer::PXPXSM144CH(towerID,ifem,ichannel);
00656   if ( ifem >= 0 ) 
00657     {
00658       if ( !fCollectedFEMs[ifem] || !fComputedFEMs[ifem] )
00659         {
00660           ComputeMaps(ifem);
00661         }
00662     }
00663 }
00664 
00665 //_____________________________________________________________________________
00666 unsigned int 
00667 emcBadModulesv1::Warning(emcBadModules::EInformationOrigin source, 
00668                        int towerID)
00669 {
00670   if ( !IsValid(towerID) ) return 0;
00671   update(towerID);
00672   return WarningFast(source,towerID);
00673 }
00674 
00675 //_____________________________________________________________________________
00676 unsigned int
00677 emcBadModulesv1::WarningFast(emcBadModules::EInformationOrigin source, 
00678                            int towerID) const
00679 {
00680   RawMapIterator it;
00681   it = fWarnRaw.find(source);
00682   if ( it != fWarnRaw.end() ) 
00683     {
00684       return (it->second)[towerID];
00685     }
00686   else 
00687     {
00688       return 0;
00689     }
00690 }
00691 
00692 //_____________________________________________________________________________
00693 unsigned int
00694 emcBadModulesv1::Warnmap(int towerID)
00695 {
00696   if ( !IsValid(towerID) ) return 0;
00697   update(towerID);
00698   return WarnmapFast(towerID);
00699 }
00700 
00701 //_____________________________________________________________________________
00702 unsigned int
00703 emcBadModulesv1::WarnmapFast(int towerID) const
00704 {
00705   return fWarnMap[towerID];
00706 }