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