CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/EventFilter/ESDigiToRaw/src/ESDataFormatterV4.cc

Go to the documentation of this file.
00001 #include <vector>
00002 #include <map>
00003 #include <set>
00004 #include <algorithm>
00005 
00006 #include "FWCore/ParameterSet/interface/FileInPath.h"
00007 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00008 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
00009 #include "EventFilter/FEDInterface/interface/FEDHeader.h"
00010 #include "EventFilter/FEDInterface/interface/FEDTrailer.h"
00011 #include "FWCore/Utilities/interface/CRC16.h"
00012 
00013 #include "EventFilter/ESDigiToRaw/src/ESDataFormatterV4.h"
00014 
00015 using namespace std;
00016 using namespace edm;
00017 
00018 const int ESDataFormatterV4::bDHEAD    = 2;
00019 const int ESDataFormatterV4::bDH       = 6;
00020 const int ESDataFormatterV4::bDEL      = 24;
00021 const int ESDataFormatterV4::bDERR     = 8;
00022 const int ESDataFormatterV4::bDRUN     = 24;
00023 const int ESDataFormatterV4::bDRUNTYPE = 32;
00024 const int ESDataFormatterV4::bDTRGTYPE = 16;
00025 const int ESDataFormatterV4::bDCOMFLAG = 8;
00026 const int ESDataFormatterV4::bDORBIT   = 32;
00027 const int ESDataFormatterV4::bDVMAJOR  = 8;
00028 const int ESDataFormatterV4::bDVMINOR  = 8;
00029 const int ESDataFormatterV4::bDCH      = 4; 
00030 const int ESDataFormatterV4::bDOPTO    = 8;
00031 
00032 const int ESDataFormatterV4::sDHEAD    = 28;
00033 const int ESDataFormatterV4::sDH       = 24;
00034 const int ESDataFormatterV4::sDEL      = 0;
00035 const int ESDataFormatterV4::sDERR     = bDEL + sDEL;
00036 const int ESDataFormatterV4::sDRUN     = 0;
00037 const int ESDataFormatterV4::sDRUNTYPE = 0;
00038 const int ESDataFormatterV4::sDTRGTYPE = 0;
00039 const int ESDataFormatterV4::sDCOMFLAG = bDTRGTYPE + sDTRGTYPE;
00040 const int ESDataFormatterV4::sDORBIT   = 0;
00041 const int ESDataFormatterV4::sDVMINOR  = 8;
00042 const int ESDataFormatterV4::sDVMAJOR  = bDVMINOR + sDVMINOR;
00043 const int ESDataFormatterV4::sDCH      = 0;
00044 const int ESDataFormatterV4::sDOPTO    = 16;
00045 
00046 const int ESDataFormatterV4::bKEC    = 8;   // KCHIP packet event counter
00047 const int ESDataFormatterV4::bKFLAG2 = 8;
00048 const int ESDataFormatterV4::bKBC    = 12;  // KCHIP packet bunch counter
00049 const int ESDataFormatterV4::bKFLAG1 = 4;
00050 const int ESDataFormatterV4::bKET    = 1;
00051 const int ESDataFormatterV4::bKCRC   = 1;
00052 const int ESDataFormatterV4::bKCE    = 1;
00053 const int ESDataFormatterV4::bKID    = 16;
00054 const int ESDataFormatterV4::bFIBER  = 6;   // Fiber number
00055 const int ESDataFormatterV4::bKHEAD1 = 2;
00056 const int ESDataFormatterV4::bKHEAD2 = 2;
00057 const int ESDataFormatterV4::bKHEAD  = 4;
00058 
00059 const int ESDataFormatterV4::sKEC    = 16;  
00060 const int ESDataFormatterV4::sKFLAG2 = 16; 
00061 const int ESDataFormatterV4::sKBC    = 0;  
00062 const int ESDataFormatterV4::sKFLAG1 = 24; 
00063 const int ESDataFormatterV4::sKET    = 0;
00064 const int ESDataFormatterV4::sKCRC   = bKET + sKET;
00065 const int ESDataFormatterV4::sKCE    = bKCRC + sKCRC;
00066 const int ESDataFormatterV4::sKID    = 0;
00067 const int ESDataFormatterV4::sFIBER  = bKID + sKID + 1;  
00068 const int ESDataFormatterV4::sKHEAD1 = bFIBER + sFIBER + 2;
00069 const int ESDataFormatterV4::sKHEAD2 = bKHEAD1 + sKHEAD1;
00070 const int ESDataFormatterV4::sKHEAD  = 28; 
00071 
00072 const int ESDataFormatterV4::bADC0  = 16;
00073 const int ESDataFormatterV4::bADC1  = 16;
00074 const int ESDataFormatterV4::bADC2  = 16;
00075 const int ESDataFormatterV4::bPACE  = 2;
00076 const int ESDataFormatterV4::bSTRIP = 5;
00077 const int ESDataFormatterV4::bE0    = 1;
00078 const int ESDataFormatterV4::bE1    = 1;
00079 const int ESDataFormatterV4::bHEAD  = 4;
00080 
00081 const int ESDataFormatterV4::sADC0  = 0;
00082 const int ESDataFormatterV4::sADC1  = bADC0 + sADC0;
00083 const int ESDataFormatterV4::sADC2  = 0;
00084 const int ESDataFormatterV4::sSTRIP = bADC2 + sADC2;
00085 const int ESDataFormatterV4::sPACE  = bSTRIP + sSTRIP; 
00086 const int ESDataFormatterV4::sE0    = bSTRIP + sSTRIP + 1;
00087 const int ESDataFormatterV4::sE1    = bE0 + sE0;
00088 const int ESDataFormatterV4::sHEAD  = 28;
00089 
00090 const int ESDataFormatterV4::bOEMUTTCEC = 32; 
00091 const int ESDataFormatterV4::bOEMUTTCBC = 16;
00092 const int ESDataFormatterV4::bOEMUKEC   = 8;
00093 const int ESDataFormatterV4::bOHEAD     = 4;
00094 
00095 const int ESDataFormatterV4::sOEMUTTCEC = 0; 
00096 const int ESDataFormatterV4::sOEMUTTCBC = 0;
00097 const int ESDataFormatterV4::sOEMUKEC   = 16;
00098 const int ESDataFormatterV4::sOHEAD     = 28;
00099 
00100 ESDataFormatterV4::ESDataFormatterV4(const ParameterSet& ps) 
00101   : ESDataFormatter(ps) {
00102 
00103   lookup_ = ps.getUntrackedParameter<FileInPath>("LookupTable");
00104 
00105   // initialize look-up table
00106   for (int i=0; i<2; ++i)
00107     for (int j=0; j<2; ++j)
00108       for (int k=0 ;k<40; ++k)
00109         for (int m=0; m<40; m++) {
00110           fedId_[i][j][k][m] = -1;
00111           kchipId_[i][j][k][m] = -1;
00112           paceId_[i][j][k][m] = -1;
00113           bundleId_[i][j][k][m] = -1;
00114           fiberId_[i][j][k][m] = -1;
00115           optoId_[i][j][k][m] = -1;
00116         }
00117 
00118   for(int i=0;i<56;++i) { 
00119     for(int j=0;j<3;++j) fedIdOptoRx_[i][j] = false ; 
00120   } 
00121 
00122   for(int i=0;i<56;++i) { 
00123     for(int j=0;j<3;++j) 
00124       for(int k=0;k<12;k++)
00125         fedIdOptoRxFiber_[i][j][k] = false ; 
00126   }   
00127 
00128   // read in look-up table
00129   int nLines, iz, ip, ix, iy, fed, kchip, pace, bundle, fiber, optorx;
00130   ifstream file;
00131   file.open(lookup_.fullPath().c_str());
00132   if( file.is_open() ) {
00133 
00134     file >> nLines;
00135     
00136     for (int i=0; i<nLines; ++i) {
00137       int fedId = -1; 
00138       file >> iz >> ip >> ix >> iy >> fed >> kchip >> pace >> bundle >> fiber >> optorx;
00139       
00140       fedId = fedId_[(3-iz)/2-1][ip-1][ix-1][iy-1] = fed;
00141       kchipId_[(3-iz)/2-1][ip-1][ix-1][iy-1] = kchip;
00142       paceId_[(3-iz)/2-1][ip-1][ix-1][iy-1] = pace - 1;
00143       bundleId_[(3-iz)/2-1][ip-1][ix-1][iy-1] = bundle;
00144       fiberId_[(3-iz)/2-1][ip-1][ix-1][iy-1] = fiber;
00145       optoId_[(3-iz)/2-1][ip-1][ix-1][iy-1] = optorx; 
00146       
00147       if (fedId<FEDNumbering::MINPreShowerFEDID|| fedId>FEDNumbering::MAXPreShowerFEDID) { 
00148         if (debug_) cout << "ESDataFormatterV4::ESDataFormatterV4 : fedId value : " << fedId 
00149                          << " out of ES range, at lookup table line : " << i << endl; 
00150       } else if (optorx < 1 || optorx > 3) { 
00151         if (debug_) cout << "ESDataFormatterV4::ESDataFormatterV4 : optorx value : " << optorx 
00152                          << " out of ES range, at lookup table line : " << i << endl;   
00153       } else { // all good ..
00154         int fedidx = fed - FEDNumbering::MINPreShowerFEDID; 
00155         fedIdOptoRx_[fedidx][optorx-1] = true;
00156         if (fiber>0 && fiber<13) { 
00157           fedIdOptoRxFiber_[fedidx][optorx-1][fiber-1] = true;
00158         } else { 
00159           if (debug_) cout << "ESDataFormatterV4::ESDataFormatterV4 : fiber value : " << fiber
00160                            << " out of ES range, at lookup table line : " << i << endl;   
00161         } 
00162       } 
00163       
00164     }
00165     
00166   } else {
00167     if (debug_) cout<<"ESDataFormatterV4::ESDataFormatterV4 : Look up table file can not be found in "<<lookup_.fullPath().c_str()<<endl;
00168   }
00169 
00170   file.close();
00171 
00172 }
00173 
00174 ESDataFormatterV4::~ESDataFormatterV4() {
00175 }
00176 
00177 struct ltfiber
00178 {
00179   bool operator()(const pair<int,int> s1, const pair<int,int> s2) const
00180   {
00181     return (s1.second < s2.second);  
00182   }
00183 };
00184 
00185 
00186 struct ltstrip : public binary_function<ESDataFormatterV4::Word64&, ESDataFormatterV4::Word64&,bool> {   
00187   bool operator()(const ESDataFormatterV4::Word64& s1, const ESDataFormatterV4::Word64& s2) 
00188   {
00189     ESDataFormatterV4::Word64 PACESTRIP_MASK = 0x00ff000000000000ull; 
00190     ESDataFormatterV4::Word64 PACESTRIP_OFFSET = 48ull; 
00191 
00192     ESDataFormatterV4::Word64 val1 = (s1 & PACESTRIP_MASK) >> PACESTRIP_OFFSET ; 
00193     ESDataFormatterV4::Word64 val2 = (s2 & PACESTRIP_MASK) >> PACESTRIP_OFFSET ;
00194 
00195     return (val1 < val2);  
00196   } 
00197 }; 
00198 
00199 
00200 
00201 void ESDataFormatterV4::DigiToRaw(int fedId, Digis & digis, FEDRawData& fedRawData) {
00202   
00203   int ts[3] = {0, 0, 0};
00204   Word32 word1, word2;
00205   Word64 word;
00206   int numberOfStrips = 0 ;
00207   
00208   int optorx_ch_counts[3][12]; 
00209   
00210   int kchip, pace, optorx, fiber ;
00211   map<int, vector<Word64> > map_data;
00212   vector<Word64> words;
00213   
00214   vector<Word32> testVector ; 
00215   
00216   set<pair<int,int>, ltfiber> set_of_kchip_fiber_in_optorx[3]; 
00217   
00218   map_data.clear();
00219   
00220   // clean optorx channel status fields:  
00221   for(int i=0;i<3;++i)
00222     for(int j=0;j<12;++j)  
00223       optorx_ch_counts[i][j] = 0 ; 
00224   
00225   const DetDigis & detDigis = digis[fedId] ;
00226   
00227   if (debug_) { 
00228     cout << "ESDataFormatterV4::DigiToRaw : FEDID : " << fedId << " size of detDigis : " 
00229          << detDigis.size() << endl ;         
00230   }
00231   
00232   for (DetDigis::const_iterator it = detDigis.begin(); it != detDigis.end(); ++it) {
00233     
00234     const ESDataFrame& dataframe = (*it);
00235     const ESDetId& detId = dataframe.id();
00236     
00237     for (int is=0; is<dataframe.size(); ++is) ts[is] = dataframe.sample(is).adc();
00238     
00239     kchip = kchipId_[(3-detId.zside())/2-1][detId.plane()-1][detId.six()-1][detId.siy()-1];
00240     pace  = paceId_[(3-detId.zside())/2-1][detId.plane()-1][detId.six()-1][detId.siy()-1];
00241     
00242     if (debug_) cout <<"Si : "<<detId.zside()<<" "<<detId.plane()<<" "<<detId.six()<<" "<<detId.siy()
00243                      <<" "<<detId.strip()<<" ("<<kchip<<","<<pace<<") "<<ts[0]<<" "<<ts[1]<<" "<<ts[2]<<endl;
00244     
00245     // convert strip number from detector id to electronics id
00246     int siz = detId.zside();
00247     int sip = detId.plane();
00248     int six = detId.six();
00249     int siy = detId.siy();
00250     int sistrip = detId.strip();
00251     if (siz == 1 && sip == 1 && siy <= 20) sistrip = 33 - sistrip;
00252     if (siz == 1 && sip == 2 && six > 20) sistrip = 33 - sistrip;
00253     if (siz == -1 && sip == 1 && siy > 20) sistrip = 33 - sistrip;
00254     if (siz == -1 && sip == 2 && six <= 20) sistrip = 33 - sistrip;
00255 
00256     word1 = (ts[1] << sADC1) | (ts[0] << sADC0);
00257     word2 = (0xc << sHEAD) | (pace << sPACE) | ((sistrip-1) << sSTRIP)  | (ts[2] << sADC2);
00258     word  = (Word64(word2) << 32 ) | Word64(word1);
00259     
00260     map_data[kchip].push_back(word);
00261     
00262     optorx = optoId_[(3-detId.zside())/2-1][detId.plane()-1][detId.six()-1][detId.siy()-1];
00263     fiber = fiberId_[(3-detId.zside())/2-1][detId.plane()-1][detId.six()-1][detId.siy()-1];
00264     
00265     optorx_ch_counts[optorx-1][fiber-1]++; // increment number of strip hits on fiber status field ; 
00266     
00267     set<pair<int,int>, ltfiber> & theSet = set_of_kchip_fiber_in_optorx[optorx-1]; 
00268     theSet.insert(pair<int,int>(kchip,fiber)); 
00269     
00270     // mark global strip number in this FED
00271     ++numberOfStrips; 
00272   }
00273   
00274   for(int iopto=0; iopto<3; ++iopto) { 
00275     
00276     if (fedIdOptoRx_[fedId-FEDNumbering::MINPreShowerFEDID][iopto]) { 
00277       
00278       word2 = (0x6 << sOHEAD) | (kchip_ec_ << sOEMUKEC) | (kchip_bc_ << sOEMUTTCBC) ; 
00279       word1 = (kchip_ec_ << sOEMUTTCEC) ;
00280       word  = (Word64(word2) << 32 ) | Word64(word1);
00281       if (debug_) cout<<"OPTORX: "<<print(word)<<endl; 
00282       words.push_back(word); 
00283       
00284       set<pair<int,int>, ltfiber> & theSet = set_of_kchip_fiber_in_optorx[iopto]; 
00285       
00286       if (debug_) { 
00287         cout << "ESDataFormatterV4::DigiToRaw : FEDID : " << fedId << " size of  set_of_kchip_fiber_in_optorx[" 
00288              << iopto << "] : "  
00289              << theSet.size() << endl ;         
00290       }
00291       
00292       set<pair<int,int>, ltfiber>::const_iterator kit = theSet.begin();
00293       
00294       int ikchip = 0; 
00295       
00296       while (kit != theSet.end()) { 
00297         
00298         const pair<int,int>& kchip_fiber = (*kit); 
00299         
00300         if (debug_) cout<<"KCHIP : "<<kchip_fiber.first << " FIBER: " << kchip_fiber.second << endl;
00301         
00302         if (fedIdOptoRxFiber_[fedId-FEDNumbering::MINPreShowerFEDID][iopto][kchip_fiber.second-1]) { 
00303           
00304           // Set all PACEs enabled for MC 
00305           word1 = (0 << sKFLAG1) | (0xf << sKFLAG2) | (((kchip_fiber.first<<2) | 0x02) << sKID);
00306           word2 = (0x9 << sKHEAD) | (kchip_ec_ << sKEC) | (kchip_bc_ << sKBC); 
00307           
00308           word  = (Word64(word2) << 32 ) | Word64(word1);       
00309           if (debug_) cout<<"KCHIP : "<<print(word)<<endl; 
00310           
00311           words.push_back(word);
00312           
00313           vector<Word64> & data = map_data[kchip_fiber.first];
00314           
00315           // sort against stripid field, as hardware gives this order to strip data : 
00316           sort(data.begin(), data.end(), ltstrip());
00317           
00318           for (unsigned int id=0; id<data.size(); ++id) {
00319             if (debug_) cout<<"Data  : "<<print(data[id])<<endl;
00320             words.push_back(data[id]);
00321           }      
00322         }
00323         ++kit ; ++ikchip;      
00324         
00325       }
00326     }
00327     
00328   } 
00329   
00330   int dataSize = (words.size() + 8) * sizeof(Word64);
00331   
00332   vector<Word64> DCCwords;
00333   
00334   word2 = (3 << sDHEAD) | (1 <<sDH) | (run_number_ << sDRUN);
00335   word1 = (numberOfStrips << sDEL) | (0xff << sDERR) ;
00336   word  = (Word64(word2) << 32 ) | Word64(word1);
00337   DCCwords.push_back(word);
00338   
00339   word2 = (3 << sDHEAD) | (2 <<sDH);
00340   word1 = 0;
00341   word  = (Word64(word2) << 32 ) | Word64(word1);
00342   DCCwords.push_back(word);
00343   
00344   word2 = (3 << sDHEAD) | (3 <<sDH) | (4 << sDVMAJOR) | (3 << sDVMINOR); 
00345   word1 = (orbit_number_ << sDORBIT);
00346   word  = (Word64(word2) << 32 ) | Word64(word1);
00347   DCCwords.push_back(word);
00348   
00349   for(int iopto=0; iopto < 3; ++iopto ) { 
00350     // N optorx module header word: 
00351     word1 = 0;
00352     if (fedIdOptoRx_[fedId-FEDNumbering::MINPreShowerFEDID][iopto]) {
00353       word2 = (3 << sDHEAD) | ((iopto+4) <<sDH) | (0x80 << sDOPTO) ; 
00354       int ich = 0; 
00355       for(ich=0;ich<4;++ich) { 
00356         int chStatus = (optorx_ch_counts[iopto][ich+8]>0) ? 0xe : 0xd ;
00357         chStatus = (fedIdOptoRxFiber_[fedId-FEDNumbering::MINPreShowerFEDID][iopto][ich+8]) ? chStatus : 0x00 ; 
00358         word2 |= (chStatus  << (ich*4)); // 
00359       }
00360       
00361       for(ich=0;ich<8;++ich) {
00362         int chStatus = (optorx_ch_counts[iopto][ich]>0) ? 0xe : 0xd ;
00363       chStatus = (fedIdOptoRxFiber_[fedId-FEDNumbering::MINPreShowerFEDID][iopto][ich]) ? chStatus : 0x00 ;
00364       word1 |= (chStatus  << (ich*4));     
00365       }
00366     } else
00367       word2 = (3 << sDHEAD) | ((iopto+4) <<sDH) | (0x00 << sDOPTO) ;
00368     
00369     word  = (Word64(word2) << 32 ) | Word64(word1);
00370     DCCwords.push_back(word);
00371     
00372   } 
00373   
00374   // Output (data size in Bytes)
00375   // FEDRawData * rawData = new FEDRawData(dataSize);
00376   fedRawData.resize(dataSize);
00377   
00378   Word64 * w = reinterpret_cast<Word64* >(fedRawData.data());
00379   
00380   // header
00381   FEDHeader::set( reinterpret_cast<unsigned char*>(w), trgtype_, lv1_, bx_, fedId); 
00382   w++;
00383   
00384   // ES-DCC 
00385   for (unsigned int i=0; i<DCCwords.size(); ++i) {
00386     if (debug_) cout<<"DCC  : "<<print(DCCwords[i])<<endl;
00387     *w = DCCwords[i];
00388     w++;
00389   }
00390   
00391   // event data
00392   for (unsigned int i=0; i<words.size(); ++i) {
00393     *w = words[i];
00394     w++;  
00395   }
00396   
00397   // trailer
00398   FEDTrailer::set( reinterpret_cast<unsigned char*>(w), dataSize/sizeof(Word64), 
00399                    evf::compute_crc(fedRawData.data(), dataSize),
00400                    0, 0);
00401 
00402 }
00403