CMS 3D CMS Logo

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