emcQAs.C

Go to the documentation of this file.
00001 // $Id: emcQAs.C,v 1.10 2003/10/02 11:54:15 aphecete Exp $
00002 
00003 #include "emcQAs.h"
00004 #include <fstream>
00005 #include "emcDataManager.h"
00006 #include <string.h>
00007 #include "EmcIndexer.h"
00008 #include "emcCalFEM.h"
00009 #include "emcRawDataAccessor.h"
00010 #include "emcRawDataObject.h"
00011 #include <fstream>
00012 #include <cstdio>
00013 
00014 using namespace std;
00015 
00016 //_____________________________________________________________________________
00017 // MV 2001/12/04 initialize static bad masks and warning masks
00018 // for problems found from monitoring data, masks can, in principle,
00019 // be different for warnings and errors
00020 INT32 const emcQAs::fMoniAmplMask=0x40000;
00021 INT32 const emcQAs::fMoniTofMask=0x0; // should be set to a sensible value!
00022 INT32 const emcQAs::fMoniAmplWarnMask=0x0; // should be set to a sensible value!
00023 INT32 const emcQAs::fMoniTofWarnMask=0x0; // should be set to a sensible value!
00024 
00025 // for problems found from physics data, let's assume the masks are the same
00026 unsigned char const emcQAs::fPhysAmplMask=0x0f;
00027 unsigned char const emcQAs::fPhysTofMask=0xf0;
00028 
00029 //_____________________________________________________________________________
00030 bool emcQAs::ApplyExtraRejectList(void)
00031 {
00032 
00033   // MV 2001/12/04 function completely re-written
00034   
00035   char s[256] ;
00036   
00037   int sector=-999;
00038   int z=-999;
00039   int y=-999;
00040   int amplError=0;
00041   int tofError=0;
00042   unsigned char physErrorBits=0;
00043   int amplWarning=0;
00044   int tofWarning=0;
00045   unsigned char physWarningBits=0;
00046   int itemId=-999;
00047 
00048   map<int, unsigned char>::iterator physRejectIterator, physWarningIterator;
00049 
00050   if(fExtraRejectListFilename=="") return true;
00051   
00052   ifstream in(fExtraRejectListFilename.c_str()) ;
00053   if(!in.is_open()){
00054     
00055     cerr <<"<E> emcQAs::ApplyExtraRejectList: Cannot open " 
00056          <<fExtraRejectListFilename<<endl;
00057     return false ;
00058     
00059   }
00060   
00061   while(in.getline(s, 255, '\n')){
00062     
00063     if(s[0]=='#') continue; // skip comment lines
00064     if(7!=sscanf(s, "%d %d %d %d %d %d %d", &sector, &z, &y, &amplError, &tofError, &amplWarning, &tofWarning))
00065       continue; // skip incomplete lines
00066 
00067     if(EmcIndexer::IsValid(sector, z, y)){
00068 
00069       itemId = EmcIndexer::getTowerId(sector, z, y);
00070       
00071       physErrorBits=tofError<<4 | amplError;
00072 
00073       //=====> check if this channel is already in the map.
00074       //=====> if this is the case, do a bit-or on the error bits
00075       physRejectIterator=fPhysRejectMap.find(itemId);
00076       if(physRejectIterator!=fPhysRejectMap.end()){
00077             
00078         physErrorBits|=fPhysRejectMap[itemId];
00079         
00080       }     
00081 
00082       //=====> fill the bad map
00083       fPhysRejectMap[itemId]=physErrorBits;
00084 
00085       //=====> now deal with warnings
00086       physWarningBits=tofWarning<<4 | amplWarning;
00087 
00088       //=====> check if this channel is already in the map.
00089       //=====> if this is the case, do a bit-or on the warning bits
00090       physWarningIterator=fPhysWarningMap.find(itemId);
00091       if(physWarningIterator!=fPhysWarningMap.end()){
00092             
00093         physWarningBits|=fPhysWarningMap[itemId];
00094         
00095       }     
00096 
00097       //=====> fill the warning map
00098       fPhysWarningMap[itemId]=physWarningBits;
00099 
00100     } else{
00101       
00102       cerr <<"<E> emcQAs::ApplyExtraRejectList: no such tower:"<<endl
00103            <<"sector="<<sector<<" z="<<z<<" y="<<y<<endl;
00104       
00105     }
00106     
00107   }
00108   
00109   in.close();
00110   return true;
00111   
00112 }
00113 
00114 //_____________________________________________________________________________
00115 bool emcQAs::BuildDeadMap(void)
00116 {
00117   
00118   // MV 2001/12/04 function (almost) completely re-written
00119 
00120   map<int, unsigned char>::iterator physRejectIterator, physWarningIterator;
00121   bool badAmpl=false;
00122   bool badTof=false;
00123   bool warnAmpl=false;
00124   bool warnTof=false;
00125   bool badMonitorAmpl=false;
00126   bool badMonitorTof=false;
00127   bool warnMonitorAmpl=false;
00128   bool warnMonitorTof=false;
00129 
00130   //=====> apply physics reject list first so that it gets fair treatment
00131   ApplyExtraRejectList();
00132   
00133   emcDataManager* dm = emcDataManager::GetInstance() ;
00134 
00135   delete[] fDeadMap ;
00136   fDeadMap = 0 ;
00137 
00138   delete [] fWarnMap;
00139   fWarnMap=0;
00140 
00141   emcRawDataAccessor* rda = emcRawDataAccessor::GetInstance() ;
00142   if (!rda) {
00143     if (dm->GetVerboseLevel()>=1) {
00144       cerr << "<E> emcQAs::BuildDeadMap() : Cannot access RDA" << endl ;
00145     }
00146     return false ;
00147   }
00148 
00149   emcRawDataObject* rdo = rda->GetRawDataObject() ;
00150  
00151   fDeadMap = new Int_t[rdo->GetMaxSize()] ;
00152   fWarnMap = new Int_t[rdo->GetMaxSize()] ;
00153 
00154   int i ;
00155   int sector ;
00156   int tower ;
00157   int x,y ;
00158   int neighborBad, neighborWarn;
00159 
00160   // Compute the neighbour error and warning flags for each tower
00161   //
00162   // For amplitude bits are:
00163   // ---------------------
00164   // |   | 18| 19| 20|   |
00165   // ---------------------
00166   // | 13| 14| 15| 16| 17|
00167   // ---------------------  ^ y
00168   // | 8 | 9 | 10| 11| 12|  |
00169   // ---------------------  |
00170   // | 3 | 4 | 5 | 6 | 7 |  |
00171   // ---------------------  ------> z(x)
00172   // |   | 0 | 1 | 2 |   |
00173   // ---------------------
00174   // as viewed from the back of the central tower (which has bit 10 set
00175   // to 1 if it's itself a bad module); corner towers are excluded
00176   //
00177   // For ToF bits are :
00178   // -------------
00179   // | 27| 28| 29|  ^ y
00180   // -------------  |
00181   // | 24| 25| 26|  |
00182   // -------------  |
00183   // | 21| 22| 23|  ------> z(x)
00184   // -------------
00185   // as viewed from the back of the central tower (which has bit 25 set
00186   // to 1 if it's itself a bad module)
00187   //
00188   // So, a channel has a problem with amlitude measurements if its neighbor
00189   // error bit map  satisfies this mask:
00190   //            0x400
00191   // Actually, this mask should be returned by the IamDeadMask() method
00192   // so that the amlitude for bad modules can be set to 0 at the calibration
00193   // stage.
00194   //
00195   // Some other useful masks.
00196   // The mask to look for amplitude errors or warnings in the 3x3 region
00197   // around a tower is:
00198   //          0x1ce70
00199   // In the 5x5 region:
00200   //         0x1fffff
00201   // To see if there are ToF problems for this tower:
00202   //        0x2000000
00203   
00204   int xoff, yoff;
00205 
00206   for (i=0; i<rdo->GetMaxSize(); i++){
00207     
00208     tower=rdo->GetItemId(i);
00209 
00210     EmcIndexer::decodeTowerId(tower, sector, x, y) ;
00211     
00212     neighborBad=0;
00213     neighborWarn=0;
00214 
00215     int neib ;
00216     int index ;
00217 
00218     int bitOffset=0;
00219 
00220     //=====> set amplitude flags first
00221     for(yoff=-2; yoff<=2; yoff++){
00222       for(xoff=-2; xoff<=2; xoff++){
00223         
00224 
00225         //=====> check if this is a corner tower
00226         bool corner=
00227           (xoff==-2 && yoff==-2) ||
00228           (xoff==-2 && yoff== 2) ||
00229           (xoff== 2 && yoff==-2) ||
00230           (xoff== 2 && yoff== 2);
00231 
00232         if(corner) continue;
00233 
00234         if(EmcIndexer::IsValid(sector, x+xoff, y+yoff)){
00235 
00236           neib = EmcIndexer::getTowerId(sector, x+xoff, y+yoff) ;
00237           index = rdo->GetIndexByTowerId(neib) ;
00238 
00239           //=====> deal with bad channels first
00240           //=====> give each channel benefit of a doubt
00241           badAmpl=false;
00242           badMonitorAmpl=false;
00243           
00244           //=====> see if this channel have errors found from physics
00245           physRejectIterator=fPhysRejectMap.find(neib);
00246           if(physRejectIterator!=fPhysRejectMap.end()){
00247             
00248             fPhysRejectMap[neib] & fPhysAmplMask ? badAmpl=true: badAmpl=false;
00249             
00250           }         
00251           
00252           //=====> see if this channel have errors found from monitoring
00253           GetError(index) & fMoniAmplMask ? badMonitorAmpl=true: badMonitorAmpl=false;
00254           
00255           if(badMonitorAmpl || badAmpl){
00256 
00257             // module has bad amplitude
00258             neighborBad |= (1<<bitOffset) ;
00259 
00260           }
00261 
00262           //=====> deal with warnings
00263           //=====> give each channel benefit of a doubt
00264           warnAmpl=false;
00265           warnMonitorAmpl=false;
00266           
00267           //=====> see if this channel have warnings found from physics
00268           physWarningIterator=fPhysWarningMap.find(neib);
00269           if(physWarningIterator!=fPhysWarningMap.end()){
00270             
00271             fPhysWarningMap[neib] & fPhysAmplMask ? warnAmpl=true: warnAmpl=false;
00272             
00273           }         
00274           
00275           //=====> see if this channel have errors found from monitoring
00276           GetWarning(index) & fMoniAmplWarnMask ? warnMonitorAmpl=true: warnMonitorAmpl=false;
00277           
00278           if(warnMonitorAmpl || warnAmpl){
00279 
00280             // module has amplitude warning
00281             neighborWarn |= (1<<bitOffset) ;
00282 
00283           }
00284         } else{
00285 
00286           // physical boundaries (edges)
00287           neighborBad |= (1<<bitOffset) ;
00288           neighborWarn |= (1<<bitOffset) ;
00289 
00290         }
00291 
00292         bitOffset++;
00293 
00294       } // end z(x) loop on neighbor channels
00295     } // end y loop on neighbor channels
00296 
00297     //=====> set ToF flags
00298     for(yoff=-1; yoff<=1; yoff++){
00299       for(xoff=-1; xoff<=1; xoff++){
00300         
00301         if(EmcIndexer::IsValid(sector, x+xoff, y+yoff)){
00302 
00303           neib = EmcIndexer::getTowerId(sector, x+xoff, y+yoff) ;
00304           index = rdo->GetIndexByTowerId(neib) ;
00305 
00306           //=====> first, look for bad ToF
00307           //=====> give each channel benefit of a doubt
00308           badTof=false;
00309           badMonitorTof=false;
00310           
00311           //=====> see if this channel have errors found from physics
00312           physRejectIterator=fPhysRejectMap.find(neib);
00313           if(physRejectIterator!=fPhysRejectMap.end()){
00314             
00315             fPhysRejectMap[neib] & fPhysTofMask ? badTof=true: badTof=false;
00316             
00317           }         
00318           
00319           //=====> see if this channel have errors found from monitoring
00320           GetError(index) & fMoniTofMask ? badMonitorTof=true: badMonitorTof=false;
00321           
00322           if(badMonitorTof || badTof){
00323 
00324             // module has bad ToF
00325             neighborBad |= (1<<bitOffset) ;
00326 
00327           }
00328 
00329 
00330           //=====> now look for ToF warnings
00331           //=====> give each channel benefit of a doubt
00332           warnTof=false;
00333           warnMonitorTof=false;
00334           
00335           //=====> see if this channel have warnings found from physics
00336           physWarningIterator=fPhysWarningMap.find(neib);
00337           if(physWarningIterator!=fPhysWarningMap.end()){
00338             
00339             fPhysWarningMap[neib] & fPhysTofMask ? warnTof=true: warnTof=false;
00340             
00341           }         
00342           
00343           //=====> see if this channel have warnings found from monitoring
00344           GetWarning(index) & fMoniTofWarnMask ? warnMonitorTof=true: warnMonitorTof=false;
00345           
00346           if(warnMonitorTof || warnTof){
00347 
00348             // module has a ToF warning
00349             neighborWarn |= (1<<bitOffset) ;
00350 
00351           }
00352         } else{
00353 
00354           // physical boundaries (edges)
00355           neighborBad |= (1<<bitOffset) ;
00356           neighborWarn |= (1<<bitOffset) ;
00357 
00358         }
00359 
00360         bitOffset++;
00361 
00362       } // end z(x) loop on neighbor channels
00363     } // end y loop on neighbor channels
00364 
00365     //printf("index %d tower %d bits %x\n",i,tower,neighbours) ;
00366     fDeadMap[i] = neighborBad;
00367     fWarnMap[i] = neighborWarn;
00368 
00369   } // end loop on rdo channels
00370 
00371   return true;
00372 
00373 }
00374 
00375 //_____________________________________________________________________________
00376 Int_t* emcQAs::GetDeadMap(void)
00377 {
00378   if (!fDeadMap) BuildDeadMap() ;
00379   return fDeadMap ;
00380 }
00381 
00382 //_____________________________________________________________________________
00383 Int_t emcQAs::GetDead(int ichannel)
00384 {
00385   return (GetDeadMap())[ichannel] ;
00386 }
00387 
00388 //_____________________________________________________________________________
00389 Int_t* emcQAs::GetWarnMap(void)
00390 {
00391   // MV 2001/12/08
00392 
00393   if (!fWarnMap) BuildDeadMap() ;
00394   return fWarnMap ;
00395 }
00396 
00397 //_____________________________________________________________________________
00398 Int_t emcQAs::GetWarn(int ichannel)
00399 {
00400   // MV 2001/12/08
00401 
00402   return (GetWarnMap())[ichannel] ;
00403 }
00404 
00405 //_____________________________________________________________________________
00406 INT32 emcQAs::GetError(int ichannel) const
00407 {
00408   emcQAFEM* qafem = dynamic_cast<emcQAFEM*>(fFEMs[ichannel/144]) ;
00409   if (qafem) {
00410     return static_cast<INT32>(qafem->getValue(ichannel%144,0)) ;
00411   }
00412   else {
00413     return 0 ;
00414   }
00415 }
00416 
00417 //_____________________________________________________________________________
00418 INT32 emcQAs::GetWarning(int ichannel) const
00419 {
00420   emcQAFEM* qafem = dynamic_cast<emcQAFEM*>(fFEMs[ichannel/144]) ;
00421   if (qafem) {
00422     return static_cast<INT32>(qafem->getValue(ichannel%144,1)) ;
00423   }
00424   else {
00425     return 0 ;
00426   }
00427 }
00428 
00429 //_____________________________________________________________________________
00430 bool emcQAs::WriteDataToFile(const char* producerName, int femCode,
00431                              const PHTimeStamp& tStart, 
00432                              const PHTimeStamp& tEnd,
00433                              INT8* errors, INT8* warnings) 
00434 {
00435   // femCode is absolute (i.e. SM) position of FEM
00436   // errors and warnings arrays _MUST_ be of size 144
00437 
00438   char filename[256] ;
00439 
00440   int SN,SM ;
00441   EmcIndexer::PXSM144_iSiSM144(femCode , SN, SM);
00442 
00443   emcDataManager* dm = emcDataManager::GetInstance() ;
00444 
00445   snprintf(filename,255,"%s/QA/%sSM%02d.%s.QA",
00446            dm->GetDestinationDir(),
00447            EmcIndexer::EmcSectorId(SN),SM,
00448            producerName) ;
00449 
00450   ofstream out(filename) ;
00451   if (!out) {
00452     cerr << "<E> emcQAs::WriteDataToFile - Can not create file " 
00453          << filename << endl ;
00454     return false ;
00455   }
00456 
00457   out << tStart << endl ;
00458   out << tEnd << endl ;
00459   int i ;
00460   for ( i = 0 ; i < 144 ; i++ ) {
00461     out << i << " " << (int)errors[i] << " " << (int)warnings[i] << endl ;
00462   }
00463   out.close() ;
00464   return true ;
00465 }