CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoTBCalo/HcalTBObjectUnpacker/src/HcalTBTDCUnpacker.cc

Go to the documentation of this file.
00001 #include "RecoTBCalo/HcalTBObjectUnpacker/interface/HcalTBTDCUnpacker.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include <math.h>
00004 
00005 // Timing channels
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 //  setupWC(); reads it from configuration file
00034 //  dumpObs_=fopen("dump_obs.csv","w");
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 //   TDC configuration
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         //        printf("Got TDC %i ped %f , conversion %f\n",channel, tdc_ped[channel],tdc_convers[channel]);
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                 } // End of the TDCs
00059 
00060 //   Wire chambers calibration
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        //         printf("Got WC plane %i b0 %f, b1 %f, mean %f, sigma %f\n",plane, 
00071        //                wc_[plane].b0,wc_[plane].b1,wc_[plane].mean,wc_[plane].sigma);
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                 } // End of the Wire Chambers
00079 
00080          } // End of the CalibLines
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; // maximum number of hits possible in the block
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; // Count of QDC channels
00105     unsigned int n_tdc_hits; // upper/lower TDC counts    
00106     unsigned short qdc_values[4];
00107   };
00108 
00109 //static const double CONVERSION_FACTOR=25.0/32.0;
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   // old TDC (767)
00123   if (tdc->n_max_hits!=192) {
00124     const CombinedTDCQDCDataFormat* qdctdc=(const CombinedTDCQDCDataFormat*)raw.data();
00125     hitbase=(const unsigned int*)(qdctdc);
00126     hitbase+=6; // header
00127     hitbase+=qdctdc->n_qdc_hits/2; // two unsigned short per unsigned long
00128     totalhits=qdctdc->n_tdc_hits&0xFFFF; // mask off high bits
00129 
00130     //    for (unsigned int i=0; i<qdctdc->n_qdc_hits; i++)
00131     //      printf("QADC: %02d %d\n",i,qdctdc->qdc_values[i]&0xFFF);
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; // hardcode channel assignment
00141     h.time=(hitbase[i]&0xFFFFF)*tdc_convers[h.channel]; 
00142     hits.push_back(h);
00143     //        printf("V767: %d %f\n",h.channel,h.time);
00144   }
00145 
00146   // new TDC (V775)
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; // header
00153     hitbase+=qdctdc->n_qdc_hits/2; // two unsigned short per unsigned long
00154     hitbase+=(qdctdc->n_tdc_hits&0xFFFF); // same length
00155     totalhits=(qdctdc->n_tdc_hits&0xFFFF0000)>>16; // mask off high bits    
00156     for (unsigned int i=0; i<totalhits; i++) {
00157       Hit h;    
00158 //      h.channel=129+i;
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       //      printf("V775: %d %f\n",h.channel,h.time);
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, // WCA LR plane 
00218                                                      10, 11, 14, // WCA UD plane
00219                                                      22, 23, 24, // WCB LR plane
00220                                                      20, 21, 24, // WCB UD plane
00221                                                      32, 33, 34, // WCC LR plane
00222                                                      30, 31, 34, // WCC UD plane
00223                                                      101, 102, 104, // WCD LR plane
00224                                                      107, 108, 110, // WCD UD plane
00225                                                      113, 114, 116, // WCE LR plane
00226                                                      97, 98, 99, // WCE UD plane 
00227                                                     42, 43, -1, // WCF LR plane (was WC1)
00228                                                     44, 60, -1, // WCF UD plane (was WC1)
00229                                                     40, 41, -1, // WCG LR plane (was WC2)
00230                                                     45, 61, -1, // WCG UD plane (was WC2)
00231                                                     52, 53, -1, // WCH LR plane (was WC3)
00232                                                     54, 62, -1  // WCH UD plane (was WC3)
00233 };
00234 
00235 static const double TDC_OFFSET_CONSTANT = 12000;
00236 static const double N_SIGMA = 2.5;
00237 
00238 /* Obsolated - reads it from the configuration file
00239 void HcalTBTDCUnpacker::setupWC() {
00240 
00241   wc_[0].b0 = -0.0870056; wc_[0].b1 = -0.193263;  // WCA planes
00242   wc_[1].b0 = -0.0288171; wc_[1].b1 = -0.191231;
00243 
00244   wc_[2].b0 = -0.2214840; wc_[2].b1 = -0.191683;  // WCB planes
00245   wc_[3].b0 = -1.0847300; wc_[3].b1 = -0.187691;
00246 
00247   wc_[4].b0 = -0.1981440; wc_[4].b1 = -0.192760;  // WCC planes
00248   wc_[5].b0 =  0.4230690; wc_[5].b1 = -0.192278;
00249 
00250   wc_[6].b0 = -0.6039130; wc_[6].b1 = -0.185674;  // WCD planes
00251   wc_[7].b0 = -0.4366590; wc_[7].b1 = -0.184992;
00252 
00253   wc_[8].b0 =  1.7016400; wc_[8].b1 = -0.185575;  // WCE planes
00254   wc_[9].b0 = -0.2324480; wc_[9].b1 = -0.185367;
00255 
00256   wc_[0].mean=225.2; wc_[0].sigma=5.704; 
00257   wc_[1].mean=223.5; wc_[1].sigma=5.862; 
00258   wc_[2].mean=227.2; wc_[2].sigma=5.070; 
00259   wc_[3].mean=235.7; wc_[3].sigma=6.090; 
00260   wc_[4].mean=243.3; wc_[4].sigma=7.804; 
00261   wc_[5].mean=230.3; wc_[5].sigma=28.91; 
00262 
00263   wc_[6].mean=225.0; wc_[6].sigma=6.000; 
00264   wc_[7].mean=225.0; wc_[7].sigma=6.000; 
00265   wc_[8].mean=225.0; wc_[8].sigma=6.000; 
00266   wc_[9].mean=225.0; wc_[9].sigma=6.000; 
00267 }
00268 */
00269 
00270 void HcalTBTDCUnpacker::reconstructWC(const std::vector<Hit>& hits, HcalTBEventPosition& ep) const {
00271   // process all planes, looping over all hits...
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     // anode-matched hits
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)   // unmatched hits (all pairs get in here)
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 }