00001 #include "emcDCProcessorv2.h"
00002
00003 #include "emcDataError.h"
00004 #include "EmcIndexer.h"
00005 #include "emcTowerContainer.h"
00006 #include "emcTowerContent.h"
00007 #include "emcCalFEM.h"
00008 #include "emcCalibrationDataHelper.h"
00009 #include "emcCalibrationData.h"
00010 #include <cmath>
00011 #include <iostream>
00012 #include <cassert>
00013
00014 using namespace std;
00015
00016 static const string ksGains = "Gains";
00017 static const string ksLCTofs = "LCTofs";
00018 static const string ksWalkTofs = "WalkTofs";
00019 static const string ksTacPeds = "TacPeds";
00020 static const string ksT0Sector = "T0Sector";
00021
00022 ClassImp(emcDCProcessorv2)
00023
00024
00025 namespace {
00026
00027 float walkCorrection(float amp)
00028 {
00029 static const float walkCorrections[] = {
00030
00031 0.0277778, 0.107143, 0.173529, 0.0543478, 0.116667, 0.10, 0.0744804, 0.0957627, 0.164296, 0.077351, 0.153276, 0.205479, 0.164593, 0.165495, 0.21152, 0.24188, 0.26691, 0.264707, 0.260216, 0.235105, 0.170128, 0.101093, 0.0506275, 0.0129709, -0.0310411, -0.0710098, -0.107253, -0.155408, -0.190727, -0.217815, -0.236577, -0.241337, -0.241553, -0.242847, -0.232342, -0.215285, -0.206976, -0.191099, -0.172913, -0.152418, -0.126642, -0.102625, -0.083642, -0.0752175, -0.0562135, -0.0406164, -0.0194486, -0.00347076, 0.0184414, 0.0312518, 0.0502009, 0.0678629, 0.0832042, 0.0936487, 0.103101, 0.114466, 0.137864, 0.156677, 0.169112, 0.174417, 0.173401, 0.17573, 0.185781, 0.201714, 0.215833, 0.22749, 0.240455, 0.246843, 0.252532, 0.256536, 0.262321, 0.26874, 0.278161, 0.285608, 0.289092, 0.290117, 0.301697, 0.308295, 0.316562, 0.331756, 0.334545, 0.34805, 0.362435, 0.36986, 0.373365, 0.382179, 0.405925, 0.396395, 0.406755, 0.421493, 0.430347, 0.440847, 0.457075, 0.463535, 0.458969, 0.466124, 0.479996, 0.487251, 0.489726, 0.494271
00032 };
00033
00034 int bin=int(amp/10);
00035 if(bin>=100) bin=99;
00036 return walkCorrections[bin];
00037 }
00038 }
00039
00040
00041 emcDCProcessorv2::emcDCProcessorv2(emcCalibrationDataHelper* ch)
00042 : fCH(ch), fZeroSuppression(false)
00043 {
00044 }
00045
00046
00047 emcDCProcessorv2::~emcDCProcessorv2()
00048 {
00049 }
00050
00051
00052 bool
00053 emcDCProcessorv2::calibrate(emcTowerContainer* pbsc,
00054 emcTowerContainer* pbgl,
00055 time_t incrementalTime)
00056 {
00057 vector<emcTowerContainer*> towers;
00058 FPTR calE[2];
00059 FPTR calT[2];
00060
00061 calE[0] = &emcDCProcessorv2::calibrateEnergyPbSc;
00062 calE[1] = &emcDCProcessorv2::calibrateEnergyPbGl;
00063
00064 calT[0] = &emcDCProcessorv2::calibrateTimePbSc;
00065 calT[1] = &emcDCProcessorv2::calibrateTimePbGl;
00066
00067 if ( pbsc )
00068 {
00069 towers.push_back(pbsc);
00070 }
00071 if ( pbgl )
00072 {
00073 towers.push_back(pbgl);
00074 }
00075
00076 for ( size_t i = 0; i < towers.size(); ++i )
00077 {
00078 for ( unsigned int itower = 0; itower < towers[i]->size(); ++itower )
00079 {
00080 emcTowerContent* t = towers[i]->getTower(itower);
00081
00082 int towerID = t->TowerID();
00083
00084
00085 if ( EmcIndexer::isReference(towerID) ) continue;
00086
00087 if ( t->ADC() > fgADCThreshold &&
00088 !( t->DataError() & emcDataError::CHANNEL_DISABLED()) )
00089 {
00090 float tof = -9999;
00091 float energy = 0.0;
00092 if ( !(t->DataError() & 0x2400) )
00093 {
00094 tof = (this->*calT[i])(t,incrementalTime);
00095 }
00096 energy = (this->*calE[i])(t,incrementalTime);
00097 t->SetCalibrated(energy,tof);
00098 }
00099 else
00100 {
00101 if ( fZeroSuppression )
00102 {
00103 cout << __FILE__ << ":" << __LINE__
00104 << " suppressing tower " << towerID
00105 << endl;
00106 towers[i]->removeTower(itower);
00107 --itower;
00108 }
00109 else
00110 {
00111 t->SetCalibrated(0,0);
00112 }
00113 }
00114 }
00115 }
00116 return true;
00117 }
00118
00119
00120 float
00121 emcDCProcessorv2::calibrateEnergyPbGl(emcTowerContent* t, time_t)
00122 {
00123 const emcCalFEM* calfem = fCH->getCalibrationFast(t->FEM(),ksGains);
00124 assert(calfem!=0);
00125
00126 time_t ti = 0;
00127
00128 float normt = calfem->getValue(t->Channel(),ti);
00129 if ( t->hasGain() )
00130 {
00131 t->SetGain(normt);
00132 }
00133
00134 if ( normt > 0.0 )
00135 {
00136 return t->ADC()*fCH->getEnergyCalibrationFast(t->TowerID())/normt;
00137 }
00138 else
00139 {
00140 return 0.0;
00141 }
00142 }
00143
00144
00145 float
00146 emcDCProcessorv2::calibrateEnergyPbSc(emcTowerContent* t,
00147 time_t incrementalTime)
00148 {
00149 const emcCalFEM* calfem = fCH->getCalibrationFast(t->FEM(),ksGains);
00150 assert(calfem!=0);
00151
00152 float normt = calfem->getValue(t->Channel(),incrementalTime);
00153 if ( t->hasGain() )
00154 {
00155 t->SetGain(normt);
00156 }
00157
00158 if ( normt > 0.01 )
00159 {
00160 return t->ADC()*fCH->getEnergyCalibrationFast(t->TowerID())/normt;
00161 }
00162 else
00163 {
00164 return 0.0;
00165 }
00166 }
00167
00168
00169 float
00170 emcDCProcessorv2::calibrateTimePbGl(emcTowerContent* t,
00171 time_t )
00172 {
00173 int ifem = t->FEM();
00174 int channel = t->Channel();
00175
00176 const emcCalFEM* LC = fCH->getCalibration(ifem,ksLCTofs);
00177 const emcCalFEM* WT = fCH->getCalibration(ifem,ksWalkTofs);
00178
00179 assert(LC!=0);
00180 assert(WT!=0);
00181
00182 float tof = t->TDC();
00183
00184 float t0 = WT->getValueFast(channel,0);
00185
00186 float lc = LC->getValueFast(channel,0);
00187
00188 lc = ((lc>20. && lc<55.)? lc : 38.9)/1000.;
00189
00190 float wk = WT->getValueFast(channel,1);
00191
00192 float dt = wk*emcDCProcessorv2::Log(t->ADC());
00193
00194 tof = - (tof-t0-dt)*lc;
00195
00196 return tof;
00197 }
00198
00199
00200 float
00201 emcDCProcessorv2::calibrateTimePbSc(emcTowerContent* t,
00202 time_t )
00203 {
00204 int ifem = t->FEM();
00205 int channel = t->Channel();
00206
00207 const emcCalFEM* LC = fCH->getCalibration(ifem,ksLCTofs);
00208 const emcCalFEM* WT = fCH->getCalibration(ifem,ksWalkTofs);
00209
00210 assert(LC!=0);
00211 assert(WT!=0);
00212
00213 float lc = LC->getValueFast(channel,0);
00214 float t0 = WT->getValueFast(channel,0);
00215 float wk = WT->getValueFast(channel,1);
00216
00217 lc = ((lc>32.&&lc<48.)? lc : 40.0)/1000.;
00218
00219 int adc = t->ADC();
00220
00221 float walk = (adc>0.)? wk*Log(adc)*1000. : 0.;
00222 float walkCorr = (lc>0)? walkCorrection(adc/15.7) : 0.;
00223 float walkStretch = (lc>0)? (wk-0.0469)*6.26 : 0.;
00224
00225 float tof = - ( (t->TDC()-t0-walk)*lc - walkCorr - walkStretch);
00226
00227 return tof;
00228 }
00229
00230
00231 int
00232 emcDCProcessorv2::isValid() const
00233 {
00234 return 1;
00235 }
00236
00237
00238 void
00239 emcDCProcessorv2::identify(std::ostream& out) const
00240 {
00241 out << "emcDCProcessorv2::identify" << endl;
00242 }
00243
00244
00245 float
00246 emcDCProcessorv2::Log(int adc)
00247 {
00248 static vector<float> preComputedLogs = emcDCProcessorv2::LogInit();
00249
00250 assert(adc>=0 && static_cast<unsigned int>(adc)<preComputedLogs.size());
00251
00252 return preComputedLogs[adc];
00253 }
00254
00255
00256 vector<float>
00257 emcDCProcessorv2::LogInit(void)
00258 {
00259 vector<float> logs;
00260
00261 logs.push_back(0);
00262
00263 for (size_t i = 1 ; i <= 4095*16 ; i++) {
00264 logs.push_back(log((float)i));
00265 }
00266 return logs;
00267 }
00268
00269
00270 void
00271 emcDCProcessorv2::Reset()
00272 {
00273 }