00001 #include "RecoTBCalo/HcalTBObjectUnpacker/interface/HcalTBTDCUnpacker.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include <math.h>
00004
00005
00006 static const int lcTriggerTime = 1;
00007 static const int lcTTCL1ATime = 2;
00008 static const int lcBeamCoincidence = 3;
00009 static const int lcLaserFlash = 4;
00010 static const int lcQIEPhase = 5;
00011
00012 static const int lcMuon1 = 90;
00013 static const int lcMuon2 = 91;
00014 static const int lcMuon3 = 92;
00015 static const int lcScint1 = 93;
00016 static const int lcScint2 = 94;
00017 static const int lcScint3 = 95;
00018 static const int lcScint4 = 96;
00019 static const int lcBeamHalo1 = 50;
00020 static const int lcBeamHalo2 = 51;
00021 static const int lcBeamHalo3 = 55;
00022 static const int lcBeamHalo4 = 63;
00023 static const int lcTOF1S = 129;
00024 static const int lcTOF1J = 130;
00025 static const int lcTOF2S = 131;
00026 static const int lcTOF2J = 132;
00027
00028 namespace hcaltb {
00029
00030 static FILE* dumpObs=0;
00031
00032 HcalTBTDCUnpacker::HcalTBTDCUnpacker(bool include_unmatched_hits) :
00033 includeUnmatchedHits_(include_unmatched_hits) {
00034
00035
00036 }
00037 void HcalTBTDCUnpacker::setCalib(const std::vector<std::vector<std::string> >& calibLines_) {
00038 for(int i=0;i<161;i++)
00039 {
00040 tdc_ped[i]=0.;tdc_convers[i]=1.;
00041 }
00042 for(unsigned int ii=0;ii<calibLines_.size();ii++)
00043 {
00044
00045 if(calibLines_[ii][0]=="TDC")
00046 {
00047 if(calibLines_[ii].size()==4)
00048 {
00049 int channel=atoi(calibLines_[ii][1].c_str());
00050 tdc_ped[channel]=atof(calibLines_[ii][2].c_str());
00051 tdc_convers[channel]=atof(calibLines_[ii][3].c_str());
00052
00053 }
00054 else
00055 {
00056 throw cms::Exception("Incomplete configuration") <<
00057 "Wrong TDC configuration format : expected 3 parameters, got "<<calibLines_[ii].size()-1;
00058 }
00059 }
00060
00061
00062 if(calibLines_[ii][0]=="WC")
00063 {
00064 if(calibLines_[ii].size()==6)
00065 {
00066 int plane=atoi(calibLines_[ii][1].c_str());
00067 wc_[plane].b0=atof(calibLines_[ii][2].c_str());
00068 wc_[plane].b1=atof(calibLines_[ii][3].c_str());
00069 wc_[plane].mean=atof(calibLines_[ii][4].c_str());
00070 wc_[plane].sigma=atof(calibLines_[ii][5].c_str());
00071
00072
00073 }
00074 else
00075 {
00076 throw cms::Exception("Incomplete configuration") <<
00077 "Wrong Wire Chamber configuration format : expected 5 parameters, got "<<calibLines_[ii].size()-1;
00078 }
00079 }
00080
00081 }
00082 }
00083
00084 void HcalTBTDCUnpacker::unpack(const FEDRawData& raw,
00085 HcalTBEventPosition& pos,
00086 HcalTBTiming& timing) const {
00087 std::vector<Hit> hits;
00088
00089 unpackHits(raw, hits, timing);
00090
00091 reconstructWC(hits, pos);
00092 reconstructTiming(hits, timing);
00093
00094 }
00095
00096 struct ClassicTDCDataFormat {
00097 unsigned int cdfHeader0,cdfHeader1,cdfHeader2,cdfHeader3;
00098 unsigned int n_max_hits;
00099 unsigned int n_hits;
00100 unsigned int hits[2];
00101 };
00102
00103 struct CombinedTDCQDCDataFormat {
00104 unsigned int cdfHeader0,cdfHeader1,cdfHeader2,cdfHeader3;
00105 unsigned int n_qdc_hits;
00106 unsigned int n_tdc_hits;
00107 unsigned short qdc_values[4];
00108 };
00109
00110
00111
00112 void HcalTBTDCUnpacker::unpackHits(const FEDRawData& raw,
00113 std::vector<Hit>& hits,HcalTBTiming& timing) const {
00114 const ClassicTDCDataFormat* tdc=(const ClassicTDCDataFormat*)raw.data();
00115
00116 if (raw.size()<3*8) {
00117 throw cms::Exception("Missing Data") << "No data in the TDC block";
00118 }
00119
00120 const unsigned int* hitbase=0;
00121 unsigned int totalhits=0;
00122
00123
00124 if (tdc->n_max_hits!=192) {
00125 const CombinedTDCQDCDataFormat* qdctdc=(const CombinedTDCQDCDataFormat*)raw.data();
00126 hitbase=(unsigned int*)(qdctdc);
00127 hitbase+=6;
00128 hitbase+=qdctdc->n_qdc_hits/2;
00129 totalhits=qdctdc->n_tdc_hits&0xFFFF;
00130
00131
00132
00133
00134 } else {
00135 hitbase=&(tdc->hits[0]);
00136 totalhits=tdc->n_hits;
00137 }
00138
00139 for (unsigned int i=0; i<totalhits; i++) {
00140 Hit h;
00141 h.channel=(hitbase[i]&0x7FC00000)>>22;
00142 h.time=(hitbase[i]&0xFFFFF)*tdc_convers[h.channel];
00143 hits.push_back(h);
00144
00145 }
00146
00147
00148 int v775[32];
00149 for (int i=0;i<32;i++) v775[i]=-1;
00150 if (tdc->n_max_hits!=192) {
00151 const CombinedTDCQDCDataFormat* qdctdc=(const CombinedTDCQDCDataFormat*)raw.data();
00152 hitbase=(unsigned int*)(qdctdc);
00153 hitbase+=6;
00154 hitbase+=qdctdc->n_qdc_hits/2;
00155 hitbase+=(qdctdc->n_tdc_hits&0xFFFF);
00156 totalhits=(qdctdc->n_tdc_hits&0xFFFF0000)>>16;
00157 for (unsigned int i=0; i<totalhits; i++) {
00158 Hit h;
00159
00160 h.channel=129+((hitbase[i]&0x3F0000)>>16);
00161 h.time=(hitbase[i]&0xFFF)*tdc_convers[h.channel] ;
00162 hits.push_back(h);
00163 if ( (h.channel-129)<32 )
00164 v775[(h.channel-129)] = (hitbase[i]&0xFFF);
00165
00166 }
00167 }
00168 timing.setV775(v775);
00169 }
00170
00171 void HcalTBTDCUnpacker::reconstructTiming(const std::vector<Hit>& hits,
00172 HcalTBTiming& timing) const {
00173 std::vector<Hit>::const_iterator j;
00174 double trigger_time=0;
00175 double ttc_l1a_time=0;
00176 double laser_flash=0;
00177 double qie_phase=0;
00178 double TOF1S_time=0;
00179 double TOF1J_time=0;
00180 double TOF2S_time=0;
00181 double TOF2J_time=0;
00182
00183 std::vector<double> m1hits, m2hits, m3hits, s1hits, s2hits, s3hits, s4hits,
00184 bh1hits, bh2hits, bh3hits, bh4hits,beam_coinc;
00185
00186 for (j=hits.begin(); j!=hits.end(); j++) {
00187 switch (j->channel) {
00188 case lcTriggerTime: trigger_time = j->time-tdc_ped[lcTriggerTime]; break;
00189 case lcTTCL1ATime: ttc_l1a_time = j->time-tdc_ped[lcTTCL1ATime]; break;
00190 case lcBeamCoincidence: beam_coinc.push_back(j->time-tdc_ped[lcBeamCoincidence]); break;
00191 case lcLaserFlash: laser_flash = j->time-tdc_ped[lcLaserFlash]; break;
00192 case lcQIEPhase: qie_phase = j->time-tdc_ped[lcQIEPhase]; break;
00193 case lcMuon1: m1hits.push_back(j->time-tdc_ped[lcMuon1]); break;
00194 case lcMuon2: m2hits.push_back(j->time-tdc_ped[lcMuon2]); break;
00195 case lcMuon3: m3hits.push_back(j->time-tdc_ped[lcMuon3]); break;
00196 case lcScint1: s1hits.push_back(j->time-tdc_ped[lcScint1]); break;
00197 case lcScint2: s2hits.push_back(j->time-tdc_ped[lcScint2]); break;
00198 case lcScint3: s3hits.push_back(j->time-tdc_ped[lcScint3]); break;
00199 case lcScint4: s4hits.push_back(j->time-tdc_ped[lcScint4]); break;
00200 case lcTOF1S: TOF1S_time = j->time-tdc_ped[lcTOF1S]; break;
00201 case lcTOF1J: TOF1J_time = j->time-tdc_ped[lcTOF1J]; break;
00202 case lcTOF2S: TOF2S_time = j->time-tdc_ped[lcTOF2S]; break;
00203 case lcTOF2J: TOF2J_time = j->time-tdc_ped[lcTOF2J]; break;
00204 case lcBeamHalo1: bh1hits.push_back(j->time-tdc_ped[lcBeamHalo1]); break;
00205 case lcBeamHalo2: bh2hits.push_back(j->time-tdc_ped[lcBeamHalo2]); break;
00206 case lcBeamHalo3: bh3hits.push_back(j->time-tdc_ped[lcBeamHalo3]); break;
00207 case lcBeamHalo4: bh4hits.push_back(j->time-tdc_ped[lcBeamHalo4]); break;
00208 default: break;
00209 }
00210 }
00211
00212 timing.setTimes(trigger_time,ttc_l1a_time,laser_flash,qie_phase,TOF1S_time,TOF1J_time,TOF2S_time,TOF2J_time);
00213 timing.setHits (m1hits,m2hits,m3hits,s1hits,s2hits,s3hits,s4hits,bh1hits,bh2hits,bh3hits,bh4hits,beam_coinc);
00214
00215 }
00216
00217 const int HcalTBTDCUnpacker::WC_CHANNELIDS[PLANECOUNT*3] = {
00218 12, 13, 14,
00219 10, 11, 14,
00220 22, 23, 24,
00221 20, 21, 24,
00222 32, 33, 34,
00223 30, 31, 34,
00224 101, 102, 104,
00225 107, 108, 110,
00226 113, 114, 116,
00227 97, 98, 99,
00228 42, 43, -1,
00229 44, 60, -1,
00230 40, 41, -1,
00231 45, 61, -1,
00232 52, 53, -1,
00233 54, 62, -1
00234 };
00235
00236 static const double TDC_OFFSET_CONSTANT = 12000;
00237 static const double N_SIGMA = 2.5;
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 void HcalTBTDCUnpacker::reconstructWC(const std::vector<Hit>& hits, HcalTBEventPosition& ep) const {
00272
00273 const int MAX_HITS=100;
00274 float hits1[MAX_HITS], hits2[MAX_HITS], hitsA[MAX_HITS];
00275 int n1,n2,nA,chan1,chan2,chanA;
00276
00277 std::vector<double> x;
00278
00279 for (int plane=0; plane<PLANECOUNT; plane++) {
00280 n1=0; n2=0; nA=0;
00281
00282 std::vector<double> plane_hits;
00283 double hit_time;
00284 hits1[0]=-1000;
00285 hits2[0]=-1000;
00286 hitsA[0]=-1000;
00287 hitsA[1]=-1000;
00288
00289 chan1=WC_CHANNELIDS[plane*3];
00290 chan2=WC_CHANNELIDS[plane*3+1];
00291 chanA=WC_CHANNELIDS[plane*3+2];
00292
00293 for (std::vector<Hit>::const_iterator j=hits.begin(); j!=hits.end(); j++) {
00294 if (j->channel==chan1 && n1<MAX_HITS) {
00295 hits1[n1]=j->time-TDC_OFFSET_CONSTANT; n1++;
00296 }
00297 if (j->channel==chan2 && n2<MAX_HITS) {
00298 hits2[n2]=j->time-TDC_OFFSET_CONSTANT; n2++;
00299 }
00300 if (j->channel==chanA && nA<MAX_HITS) {
00301 hitsA[nA]=j->time-TDC_OFFSET_CONSTANT; nA++;
00302 }
00303 }
00304
00305 if (n1!=0 && n2!=0 && dumpObs!=0) {
00306 fprintf(dumpObs,"%d,%f,%f,%f,%f\n",plane,hits1[0],hits2[0],hitsA[0],hitsA[1]);
00307 fflush(dumpObs);
00308 }
00309
00310
00311 for (int ii=0; ii<n1; ii++) {
00312 int jmin=-1, lmin=-1;
00313 float dsumMin=99999;
00314 for (int jj=0; jj<n2; jj++) {
00315 for (int ll=0; ll<nA; ll++) {
00316 float dsum=fabs(wc_[plane].mean - hits1[ii] - hits2[jj] + 2.0*hitsA[ll]);
00317 if(dsum<(N_SIGMA*wc_[plane].sigma) && dsum<dsumMin){
00318 jmin=jj;
00319 lmin=ll;
00320 dsumMin=dsum;
00321 }
00322 }
00323 }
00324 if (jmin>=0) {
00325 hit_time = wc_[plane].b0 +
00326 wc_[plane].b1 * (hits1[ii]-hits2[jmin]);
00327 if((plane%2)==0)
00328 {
00329 plane_hits.push_back(-hit_time);
00330 }else{
00331 plane_hits.push_back(hit_time);
00332 }
00333 hits1[ii]=-99999;
00334 hits2[jmin]=-99999;
00335 hitsA[lmin]=99999;
00336 }
00337 }
00338
00339 if (includeUnmatchedHits_||plane>9)
00340 for (int ii=0; ii<n1; ii++) {
00341 if (hits1[ii]<-99990) continue;
00342 for (int jj=0; jj<n2; jj++) {
00343 if (hits2[jj]<-99990) continue;
00344 hit_time = wc_[plane].b0 +
00345 wc_[plane].b1 * (hits1[ii]-hits2[jj]);
00346 if((plane%2)==0)
00347 {
00348 plane_hits.push_back(-hit_time);
00349 }else{
00350 plane_hits.push_back(hit_time);
00351 }
00352 }
00353 }
00354
00355 if ((plane%2)==0) x=plane_hits;
00356 else {
00357 char chamber='A'+plane/2;
00358 ep.setChamberHits(chamber,x,plane_hits);
00359 }
00360 }
00361
00362 }
00363
00364 }