CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/EventFilter/CSCRawToDigi/src/CSCALCTHeader.cc

Go to the documentation of this file.
00001 #include "EventFilter/CSCRawToDigi/interface/CSCALCTHeader.h"
00002 #include "EventFilter/CSCRawToDigi/interface/CSCDMBHeader.h"
00003 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00004 #include "EventFilter/CSCRawToDigi/src/bitset_append.h"
00005 #include "EventFilter/CSCRawToDigi/src/cscPackerCompare.h"
00006 #include <iomanip>
00007 
00008 bool CSCALCTHeader::debug=false;
00009 short unsigned int CSCALCTHeader::firmwareVersion=2007; 
00010 
00011 CSCALCTHeader::CSCALCTHeader(int chamberType)
00012 : header2006(chamberType),
00013   header2007(chamberType)
00014 { //constructor for digi->raw packing based on header2006 
00015   if (firmwareVersion==2006)
00016   {
00017     memcpy(theOriginalBuffer, &header2006, header2006.sizeInWords()*2);
00018   }
00019   else if(firmwareVersion==2007)
00020   {
00021     memcpy(theOriginalBuffer, &header2007, header2007.sizeInWords()*2);
00022     // assume no virtex or masks or registers
00023     sizeInWords2007_ = header2007.sizeInWords() + header2007.lctBins*CSCALCT::sizeInWords()*2;
00024     theALCTs.resize(header2007.lctBins*2);
00025   }
00026   else
00027   {
00028     edm::LogError("CSCALCTHeader|CSCRawToDigi")
00029       <<"Cannot construct ALCT header: ALCT firmware version is bad/not defined!" << firmwareVersion;
00030   }
00031 
00032 }
00033 
00034 CSCALCTHeader::CSCALCTHeader(const unsigned short * buf) {
00039   static unsigned short int collisionMaskWordcount[7]    = { 8, 8,12,16,16,24,28};
00040   static unsigned short int hotChannelMaskWordcount[7]   = {18,18,24,36,36,48,60};
00041 
00043   if (buf[0]==0xDB0A) {
00044     firmwareVersion=2007;
00045   }
00046   else if ( (buf[0]&0xF800)==0x6000 ) {
00047     firmwareVersion=2006;
00048   }
00049   else {
00050     edm::LogError("CSCALCTHeader|CSCRawToDigi") << "failed to determine ALCT firmware version!!";
00051   }
00052 
00053   LogTrace("CSCALCTHeader|CSCRawToDigi") << "firmware version - " << firmwareVersion;
00054 
00056   switch (firmwareVersion) {
00057   case 2006:
00058     memcpy(&header2006, buf, header2006.sizeInWords()*2);
00059     buf +=header2006.sizeInWords();
00060     memcpy(&alcts2006, buf, alcts2006.sizeInWords()*2);
00061     buf +=alcts2006.sizeInWords();
00062     break;
00063 
00064   case 2007:
00065     memcpy(&header2007, buf, header2007.sizeInWords()*2); 
00066     buf +=header2007.sizeInWords();
00067     sizeInWords2007_ = header2007.sizeInWords();
00069     if (header2007.configPresent==1) {
00070       memcpy(&virtexID, buf, virtexID.sizeInWords()*2);
00071       buf +=virtexID.sizeInWords();
00072       sizeInWords2007_ = virtexID.sizeInWords();
00073       memcpy(&configRegister, buf, configRegister.sizeInWords()*2);
00074       buf +=configRegister.sizeInWords();
00075       sizeInWords2007_ += configRegister.sizeInWords();
00076 
00077       collisionMasks.resize(collisionMaskWordcount[header2007.boardType]);
00078       for (unsigned int i=0; i<collisionMaskWordcount[header2007.boardType]; ++i){
00079         memcpy(&collisionMasks[i], buf, collisionMasks[i].sizeInWords()*2);
00080         buf += collisionMasks[i].sizeInWords();
00081         sizeInWords2007_ += collisionMasks[i].sizeInWords();
00082       }
00083 
00084       hotChannelMasks.resize(hotChannelMaskWordcount[header2007.boardType]);
00085       for (unsigned int i=0; i<hotChannelMaskWordcount[header2007.boardType]; ++i) {
00086         memcpy(&hotChannelMasks[i], buf, hotChannelMasks[i].sizeInWords()*2);
00087         buf += hotChannelMasks[i].sizeInWords();
00088         sizeInWords2007_ += hotChannelMasks[i].sizeInWords();
00089       }
00090     }
00091 
00092     theALCTs.resize(header2007.lctBins*2); 
00093     for (int i=0; i<header2007.lctBins*2; ++i) {
00094       memcpy(&theALCTs[i], buf, theALCTs[i].sizeInWords()*2);
00095       buf += theALCTs[i].sizeInWords(); 
00096       sizeInWords2007_ += theALCTs[i].sizeInWords();
00097     }
00098 
00099     ALCTDigis();
00100     break;
00101 
00102   default:
00103     edm::LogError("CSCALCTHeader|CSCRawToDigi")
00104       <<"couldn't construct: ALCT firmware version is bad/not defined!";
00105     break;
00106   }
00107 
00109   if ((firmwareVersion==2006)||(firmwareVersion==2007))
00110     memcpy(theOriginalBuffer, buf-sizeInWords(), sizeInWords()*2);
00111   
00112 }
00113 
00114 
00115 CSCALCTHeader::CSCALCTHeader(const CSCALCTStatusDigi & digi){
00116   CSCALCTHeader(digi.header());
00117 }
00118 
00119 void CSCALCTHeader::setEventInformation(const CSCDMBHeader & dmb) {
00120   header2006.setEventInformation(dmb);
00121 }
00122 
00123 
00124 unsigned short CSCALCTHeader::nLCTChipRead() const {
00125   if(firmwareVersion == 2006) {
00126     return header2006.nLCTChipRead();
00127   }
00128   else {
00129     // nLCTChip obsolete in ALCT2007 format (email Andrey K. & Victor B., 20.10.2008)
00130     // and we don't think anyone makes uses of this call.
00131     //    edm::LogError("CSCALCTHeader|CSCRawToDigi")
00132     //      <<"How is nLCTChipRead() supposed to work for ALCTHeader2007?";
00133   }
00134   return 0;
00135 }
00136 
00137 
00138 std::vector<CSCALCTDigi> CSCALCTHeader::ALCTDigis() const 
00139 { 
00140   std::vector<CSCALCTDigi> result;
00141 
00142   switch (firmwareVersion) {
00143   case 2006:
00144     {
00145       result = alcts2006.ALCTDigis();
00146       break;
00147     }
00148   case 2007:
00149     {
00150       result.reserve(theALCTs.size());
00151       for (unsigned int i=0; i<theALCTs.size(); ++i) {
00152         CSCALCTDigi digi(theALCTs[i].valid, theALCTs[i].quality, theALCTs[i].accel, theALCTs[i].pattern,
00153                          theALCTs[i].keyWire, (int)i/2, i%2+1);
00154         result.push_back(digi);
00155       }
00156       break;
00157     }
00158   default:
00159     edm::LogError("CSCALCTHeader|CSCRawToDigi")
00160       <<"Empty Digis: ALCT firmware version is bad/not defined!" << firmwareVersion; 
00161     break;
00162   }
00163   for(unsigned i = 0; i < result.size(); ++i) {result[i].setFullBX(BXNCount());}
00164   return result;
00165 
00166 }
00167 
00168 
00169 void CSCALCTHeader::add(const std::vector<CSCALCTDigi> & digis)
00170 {
00171   if(firmwareVersion == 2006) {
00172       alcts2006.add(digis);
00173   }
00174   else if(firmwareVersion == 2007) {
00175     if(theALCTs.empty())
00176     {
00177       theALCTs.resize(header2007.lctBins*2);
00178     }
00179     for(std::vector<CSCALCTDigi>::const_iterator digi = digis.begin();
00180         digi != digis.end(); ++digi)
00181     {
00182       int bx = digi->getBX();
00183       if(bx < (int)header2007.lctBins) 
00184       {
00185         // 2 ALCTs per bx
00186         int i = bx*2;
00187         int q1 = theALCTs[i].quality;
00188         int q2 = theALCTs[i+1].quality;
00189         // see if it's non=blank
00190         if(!theALCTs[i].valid)
00191         {
00192           theALCTs[i] = CSCALCT(*digi);
00193         }
00194         // new best LCT
00195         else if(digi->getQuality() > q1)
00196         {
00197           theALCTs[i+1] = theALCTs[i];
00198           theALCTs[i] = CSCALCT(*digi);
00199         }
00200         // new second best
00201         else if(!theALCTs[i+1].valid || (digi->getQuality() > q2))
00202         {
00203           theALCTs[i+1] = CSCALCT(*digi);
00204         }
00205       }
00206     }
00207   }
00208 }
00209 
00210 
00211 boost::dynamic_bitset<> CSCALCTHeader::pack()
00212 {
00213   boost::dynamic_bitset<> result;
00214   if(firmwareVersion == 2006)
00215   {
00216      boost::dynamic_bitset<> header
00217        = bitset_utilities::ushortToBitset(header2006.sizeInWords()*16,
00218                                           (unsigned short *) &header2006);
00219      boost::dynamic_bitset<> alcts 
00220        = bitset_utilities::ushortToBitset(alcts2006.sizeInWords()*16,
00221                                           (unsigned short *) &alcts2006);
00222      result = bitset_utilities::append(header, alcts);
00223   }
00224 
00225   else if(firmwareVersion == 2007)
00226   {
00227     result = bitset_utilities::ushortToBitset(header2007.sizeInWords()*16,
00228                                           (unsigned short *) &header2007);
00229 
00230     for (unsigned i = 0; i < theALCTs.size(); ++i)
00231     {
00232        boost::dynamic_bitset<> alct
00233          = bitset_utilities::ushortToBitset(theALCTs[i].sizeInWords()*16,
00234                                           (unsigned short *) &theALCTs[i]);
00235        result = bitset_utilities::append(result, alct);
00236     }
00237   }
00238   return result;
00239 }
00240     
00241 
00242 
00243 void CSCALCTHeader::selfTest(int firmware)
00244 {
00245   firmwareVersion = firmware;
00246   CSCALCTDigi alct0(true, 1, 1, 1, 10, 6, 1);
00247   CSCALCTDigi alct1(true, 1, 1, 0, 11, 6, 2);
00248 
00249     // tests packing and unpacking
00250     for(int station = 1; station <= 4; ++station)
00251     {
00252       CSCDetId detId(1, station, 1, 1, 0);
00253 
00254       std::vector<CSCALCTDigi> oldAlcts;
00255       oldAlcts.push_back(alct0);
00256       oldAlcts.push_back(alct1);
00257       CSCALCTHeader alctHeader(detId.iChamberType());
00258 
00259       alctHeader.add(oldAlcts);
00260 
00261       std::vector<CSCALCTDigi> alcts = alctHeader.ALCTDigis();
00262       // pick out the valid ones
00263       std::vector<CSCALCTDigi> validALCTs;
00264       for(std::vector<CSCALCTDigi>::const_iterator alctItr = alcts.begin();
00265           alctItr != alcts.end(); ++ alctItr)
00266       {
00267         if(alctItr->isValid())
00268         {
00269           validALCTs.push_back(*alctItr);
00270         }
00271       }
00272       assert(validALCTs[0] == alct0);
00273       assert(validALCTs[1] == alct1);
00274       //cscClassPackerCompare(alctHeader);
00275     }
00276 }
00277 
00278 std::ostream & operator<<(std::ostream & os, const CSCALCTHeader & header) 
00279 {
00280   os << "ALCT HEADER CSCID " << header.CSCID()
00281      << "  L1ACC " << header.L1Acc() << std::endl;
00282   os << " time samples " << header.NTBins() << std::endl;
00283   return os;
00284 }
00285 
00286