00001 #include "emcDCProcessorv3.h"
00002
00003 #include "emcDataError.h"
00004 #include "EmcIndexer.h"
00005 #include "emcTowerContainer.h"
00006 #include "emcTowerContent.h"
00007 #include "emcCalFEM.h"
00008 #include "emcTofT0FEM.h"
00009 #include "emcCalibrationDataHelper.h"
00010 #include "emcCalibrationData.h"
00011 #include <cmath>
00012 #include <cassert>
00013 #include <iostream>
00014 #include <iterator>
00015
00016 using std::string;
00017 using std::cout;
00018 using std::endl;
00019 using std::vector;
00020
00021 static const string ksGains = "Gains";
00022 static const string ksLCTofs = "LCTofs";
00023 static const string ksWalkTofs = "WalkTofs";
00024 static const string ksTacPeds = "TacPeds";
00025 static const string ksT0Sector = "T0Sector";
00026 static const string ksTofT0s = "TofT0Bs";
00027
00028
00029 ClassImp(emcDCProcessorv3)
00030
00031 namespace {
00032 static const int fgTDCThreshold = 0;
00033 }
00034
00035
00036 emcDCProcessorv3::emcDCProcessorv3(emcCalibrationDataHelper* ch)
00037 : fCH(ch), fZeroSuppression(false)
00038 {
00039 if (!fCH) throw;
00040 fksGainsBLR = "Gains:BLR:0:xmax:-3:-9:-15:92446";
00041 fgNormtLimitPbSc = 47.84;
00042
00043
00044
00045 if (fCH->runNumber()>=164777)
00046 {
00047 fksGainsBLR = "Gains:BLR:0:x:ZS:AVOFRATIO:164777";
00048 fgNormtLimitPbSc = 0.01;
00049 }
00050 }
00051
00052
00053 emcDCProcessorv3::~emcDCProcessorv3()
00054 {
00055 std::cout << "emcDCProcessv3::~emcDCProcessorv3 : "
00056 << fNormProblems.size()
00057 << " PbSc towers for which we changed "
00058 << " the warnmap due to normt value "
00059 << " below the cut of "
00060 << fgNormtLimitPbSc
00061 << std::endl;
00062 std::copy(fNormProblems.begin(),fNormProblems.end(),
00063 std::ostream_iterator<int>(std::cout,"\n"));
00064 }
00065
00066
00067 bool
00068 emcDCProcessorv3::calibrate(emcTowerContainer* pbsc,
00069 emcTowerContainer* pbgl,
00070 time_t incrementalTime)
00071 {
00072 vector<emcTowerContainer*> towers;
00073 FPTR calE[2];
00074 FPTR calT[2];
00075
00076 calE[0] = &emcDCProcessorv3::calibrateEnergyPbSc;
00077 calE[1] = &emcDCProcessorv3::calibrateEnergyPbGl;
00078
00079 calT[0] = &emcDCProcessorv3::calibrateTimePbSc;
00080 calT[1] = &emcDCProcessorv3::calibrateTimePbGl;
00081
00082 if ( pbsc )
00083 {
00084 towers.push_back(pbsc);
00085 }
00086 if ( pbgl )
00087 {
00088 towers.push_back(pbgl);
00089 }
00090
00091 for ( size_t i = 0; i < towers.size(); ++i )
00092 {
00093 for ( unsigned int itower = 0; itower < towers[i]->size(); ++itower )
00094 {
00095 emcTowerContent* t = towers[i]->getTower(itower);
00096
00097 int towerID = t->TowerID();
00098
00099
00100 if ( EmcIndexer::isReference(towerID) ) continue;
00101
00102 float tof = -9999.9;
00103 float energy = 0.0;
00104
00105 if ( t->ADC() > fgADCThreshold &&
00106 !( t->DataError() & emcDataError::CHANNEL_DISABLED()) )
00107 {
00108 if ( t->TDC() > fgTDCThreshold &&
00109 !(t->DataError() & emcDataError::TAC_OUT()) )
00110 {
00111 tof = (this->*calT[i])(t,incrementalTime);
00112 }
00113 energy = (this->*calE[i])(t,incrementalTime);
00114 t->SetCalibrated(energy,tof);
00115 }
00116 else
00117 {
00118 if ( fZeroSuppression )
00119 {
00120 cout << __FILE__ << ":" << __LINE__
00121 << " suppressing tower " << towerID
00122 << endl;
00123 towers[i]->removeTower(itower);
00124 --itower;
00125 }
00126 else
00127 {
00128 t->SetCalibrated(energy,tof);
00129 }
00130 }
00131 }
00132 }
00133 return true;
00134 }
00135
00136
00137 float
00138 emcDCProcessorv3::calibrateEnergyPbGl(emcTowerContent* t, time_t)
00139 {
00140 const emcCalFEM* calfem = fCH->getCalibration(t->FEM(),ksGains);
00141 assert(calfem!=0);
00142
00143 time_t ti = 0;
00144
00145 float normt = calfem->getValue(t->Channel(),ti);
00146 if ( t->hasGain() )
00147 {
00148 t->SetGain(normt);
00149 }
00150
00151 if ( normt > 0 )
00152 {
00153 return t->ADC()*fCH->getEnergyCalibration(t->TowerID())/normt;
00154 }
00155 else
00156 {
00157 return 0.0;
00158 }
00159 }
00160
00161
00162 float
00163 emcDCProcessorv3::calibrateEnergyPbSc(emcTowerContent* t,
00164 time_t incrementalTime)
00165 {
00166 const emcCalFEM* calfem = fCH->getCalibration(t->FEM(),fksGainsBLR);
00167
00168 float normt = calfem->getValue(t->Channel(),incrementalTime);
00169
00170 if ( t->hasGain() )
00171 {
00172 t->SetGain(normt);
00173 }
00174 if ( normt > fgNormtLimitPbSc )
00175 {
00176 return t->ADC()*fCH->getEnergyCalibration(t->TowerID())/normt;
00177 }
00178 else
00179 {
00180
00181
00182
00183
00184
00185 unsigned int oldwarn = t->WarnNeighbours();
00186 unsigned int ampl_mask = 0x40000;
00187 unsigned int normt_mask = 0x1000000;
00188 unsigned int newwarn = oldwarn | ampl_mask | normt_mask;
00189
00190 if ( (oldwarn & ampl_mask) != ampl_mask &&
00191 (newwarn & ampl_mask) == ampl_mask )
00192 {
00193 fNormProblems.insert(t->TowerID());
00194 }
00195
00196 return 0.0;
00197
00198
00199
00200
00201
00202
00203
00204
00205 }
00206 }
00207
00208
00209 float
00210 emcDCProcessorv3::calibrateTimePbGl(emcTowerContent* t,
00211 time_t )
00212 {
00213 int ifem = t->FEM();
00214 int channel = t->Channel();
00215
00216 const emcCalFEM* LC = fCH->getCalibration(ifem,ksLCTofs);
00217 const emcCalFEM* WT = fCH->getCalibration(ifem,ksWalkTofs);
00218 const emcCalFEM* T0 = fCH->getCalibration(ifem,ksTofT0s);
00219
00220 assert(LC!=0);
00221 assert(WT!=0);
00222 assert(T0!=0);
00223
00224 float t0 = T0->getValueFast(channel,0);
00225
00226 float lc = LC->getValueFast(channel,0);
00227
00228 lc = ((lc>20. && lc<55.)? lc : 38.9)/1000.;
00229
00230 float wk = WT->getValueFast(channel,1);
00231
00232 float dt = wk*emcDCProcessorv3::Log(t->ADC());
00233
00234 return - (t->TDC()-dt)*lc - t0;
00235 }
00236
00237
00238 float
00239 emcDCProcessorv3::calibrateTimePbSc(emcTowerContent* t,
00240 time_t )
00241 {
00242 int ifem = t->FEM();
00243 int channel = t->Channel();
00244
00245 const emcCalFEM* LC = fCH->getCalibration(ifem,ksLCTofs);
00246 const emcCalFEM* WT = fCH->getCalibration(ifem,ksWalkTofs);
00247 const emcCalFEM* T0 = fCH->getCalibration(ifem,ksTofT0s);
00248
00249 assert(LC!=0);
00250 assert(WT!=0);
00251
00252 float lc = LC->getValueFast(channel,0);
00253 float wk = WT->getValueFast(channel,1);
00254 float t0 = T0->getValueFast(channel,0);
00255
00256 lc = ((lc>25.&&lc<65.)? lc : 40.0)/1000.;
00257
00258 float adc = t->LG();
00259
00260 float walk = (adc>0.&&wk<0.)? wk*4000./adc : 0.;
00261
00262 return - lc*(t->TDC()-walk) - t0;
00263 }
00264
00265
00266 int
00267 emcDCProcessorv3::isValid() const
00268 {
00269 return 1;
00270 }
00271
00272
00273 void
00274 emcDCProcessorv3::identify(std::ostream& out) const
00275 {
00276 out << "emcDCProcessorv3::identify" << endl;
00277 }
00278
00279
00280 float
00281 emcDCProcessorv3::Log(int adc)
00282 {
00283 static vector<float> preComputedLogs = emcDCProcessorv3::LogInit();
00284
00285 assert(adc>=0 && static_cast<unsigned int>(adc)<preComputedLogs.size());
00286
00287 return preComputedLogs[adc];
00288 }
00289
00290
00291 vector<float>
00292 emcDCProcessorv3::LogInit(void)
00293 {
00294 vector<float> logs;
00295
00296 logs.push_back(0);
00297
00298 for (size_t i = 1 ; i <= 4095*22 ; i++) {
00299 logs.push_back(log(i));
00300 }
00301 return logs;
00302 }
00303
00304
00305 void
00306 emcDCProcessorv3::Reset()
00307 {
00308 }