CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/HcalRawToDigi/src/HcalPacker.cc

Go to the documentation of this file.
00001 #include "EventFilter/HcalRawToDigi/interface/HcalPacker.h"
00002 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00003 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
00004 #include "DataFormats/HcalDetId/interface/HcalGenericDetId.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00007 #include "FWCore/Utilities/interface/CRC16.h"
00008 
00009 HcalPacker::Collections::Collections() {
00010   hbhe=0;
00011   hoCont=0;
00012   hfCont=0;
00013   tpCont=0;
00014   zdcCont=0;
00015   calibCont=0;
00016 }
00017 
00018 template <class Coll, class DetIdClass> 
00019 int process(const Coll* pt, const DetId& did, unsigned short* buffer, int& presamples,bool& isUS, bool& isMP) {
00020   isUS=false; isMP=false;
00021   if (pt==0) return 0;
00022   int size=0;
00023   typename Coll::const_iterator i=pt->find(DetIdClass(did));
00024   if (i!=pt->end()) {
00025     isUS=i->zsUnsuppressed();
00026     isMP=i->zsMarkAndPass();
00027     presamples=i->presamples();
00028     size=i->size();
00029     for (int j=0; j<size; j++) 
00030       buffer[j]=(*i)[j].raw();
00031   }
00032   return size;
00033 }
00034 
00035 static unsigned char processTrig(const HcalTrigPrimDigiCollection* pt, const HcalTrigTowerDetId& tid, unsigned short* buffer) {
00036   if (pt==0) return 0;
00037   int size=0;
00038   HcalTrigPrimDigiCollection::const_iterator i=pt->find(tid);
00039   if (i!=pt->end()) {
00040     int presamples=i->presamples();
00041     int samples=i->size();
00042 
00043     for (int j=0; j<samples; j++) {
00044        buffer[j]=(*i)[j].raw();
00045        if (j==presamples) buffer[j]|=0x0200;
00046     }
00047   }
00048   return size;
00049 }
00050 
00051 int HcalPacker::findSamples(const DetId& did, const Collections& inputs,
00052                             unsigned short* buffer, int &presamples, bool& isUS, bool& isMP) {
00053   if (!(did.det()==DetId::Hcal || (did.det()== DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId)) ) return 0;
00054   int size=0;
00055   HcalGenericDetId genId(did);
00056   
00057   switch (genId.genericSubdet()) {
00058   case(HcalGenericDetId::HcalGenBarrel):
00059   case(HcalGenericDetId::HcalGenEndcap):
00060     size=process<HBHEDigiCollection,HcalDetId>(inputs.hbhe,did,buffer,presamples,isUS,isMP);
00061     break;
00062   case(HcalGenericDetId::HcalGenOuter):
00063     size=process<HODigiCollection,HcalDetId>(inputs.hoCont,did,buffer,presamples,isUS,isMP);
00064     break;
00065   case(HcalGenericDetId::HcalGenForward):
00066     size=process<HFDigiCollection,HcalDetId>(inputs.hfCont,did,buffer,presamples,isUS,isMP);
00067     break;
00068   case(HcalGenericDetId::HcalGenZDC):
00069     size=process<ZDCDigiCollection,HcalZDCDetId>(inputs.zdcCont,did,buffer,presamples,isUS,isMP);
00070     break;
00071   case(HcalGenericDetId::HcalGenCalibration):
00072     size=process<HcalCalibDigiCollection,HcalCalibDetId>(inputs.calibCont,did,buffer,presamples,isUS,isMP);
00073     break;
00074   default: size=0;
00075   }
00076   return size;
00077 }
00078 
00079 void HcalPacker::pack(int fedid, int dccnumber,
00080                       int nl1a, int orbitn, int bcn,
00081                       const Collections& inputs, 
00082                       const HcalElectronicsMap& emap,
00083                       FEDRawData& output) {
00084   std::vector<unsigned short> precdata(HcalHTRData::CHANNELS_PER_SPIGOT*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
00085   std::vector<unsigned short> trigdata(HcalHTRData::CHANNELS_PER_SPIGOT*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
00086   std::vector<unsigned char> preclen(HcalHTRData::CHANNELS_PER_SPIGOT);
00087   std::vector<unsigned char> triglen(HcalHTRData::CHANNELS_PER_SPIGOT);
00088   static const int HTRFormatVersion=5;
00089   bool channelIsMP[HcalHTRData::CHANNELS_PER_SPIGOT];
00090 
00091   HcalHTRData spigots[15];
00092   // loop over all valid channels in the given dcc, spigot by spigot.
00093   for (int spigot=0; spigot<15; spigot++) {
00094     spigots[spigot].allocate(HTRFormatVersion);
00095     HcalElectronicsId exampleEId;
00096     int npresent=0;
00097     int presamples=-1, samples=-1;
00098     bool haveUnsuppressed=false;
00099     for (int fiber=1; fiber<=8; fiber++) 
00100       for (int fiberchan=0; fiberchan<3; fiberchan++) {
00101         int linear=(fiber-1)*3+fiberchan;
00102         HcalQIESample chanSample(0,0,fiber,fiberchan,false,false);
00103         unsigned short chanid=chanSample.raw()&0xF800;
00104         preclen[linear]=0;
00105         channelIsMP[linear]=false;
00106 
00107         HcalElectronicsId partialEid(fiberchan,fiber,spigot,dccnumber);
00108         // does this partial id exist?
00109         HcalElectronicsId fullEid;
00110         HcalGenericDetId genId;
00111         if (!emap.lookup(partialEid,fullEid,genId)) continue;
00112 
00113 
00114         // next, see if there is a digi with this id
00115         unsigned short* database=&(precdata[linear*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL]);
00116         int mypresamples=-1;
00117         bool isUS=false, isMP=false;
00118         int mysamples=findSamples(genId,inputs,database,mypresamples,isUS,isMP);
00119         haveUnsuppressed=haveUnsuppressed || isUS;
00120         channelIsMP[linear]=isMP;
00121 
00122         if (mysamples>0) {
00123           if (samples<0) samples=mysamples;
00124           else if (samples!=mysamples) {
00125             edm::LogError("HCAL") << "Mismatch of samples in a single HTR (unsupported) " << mysamples << " != " << samples;
00126             continue;
00127           }
00128           if (presamples<0) {
00129             presamples=mypresamples;
00130             exampleEId=fullEid;
00131           } else if (mypresamples!=presamples) {
00132             edm::LogError("HCAL") << "Mismatch of presamples in a single HTR (unsupported) " << mypresamples << " != " << presamples;
00133             continue;       
00134           }
00135           for (int ii=0; ii<samples; ii++)
00136             database[ii]=(database[ii]&0x7FF)|chanid;
00137           preclen[linear]=(unsigned char)(samples);
00138           npresent++;
00139         }       
00140       }
00141     for (int slb=1; slb<=6; slb++) 
00142       for (int slbchan=0; slbchan<=3; slbchan++) {
00143         int linear=(slb-1)*4+slbchan;
00144         HcalTriggerPrimitiveSample idCvt(0,0,slb,slbchan);
00145         unsigned short chanid=idCvt.raw()&0xF800;
00146         triglen[linear]=0;
00147 
00148         HcalElectronicsId partialEid(slbchan,slb,spigot,dccnumber,0,0,0);
00149         // does this partial id exist?
00150         HcalElectronicsId fullEid;
00151         HcalTrigTowerDetId tid;
00152         if (!emap.lookup(partialEid,fullEid,tid)) {
00153 //        std::cout << "TPGPACK : no match for " << partialEid << std::endl;
00154           continue;
00155         }  //else std::cout << "TPGPACK : converted " << partialEid << " to " << fullEid << "/" << tid << std::endl;
00156           
00157         // finally, what about a trigger channel?
00158         if (!tid.null()) {
00159           unsigned short* trigbase=&(trigdata[linear*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL]);
00160           triglen[linear]=processTrig(inputs.tpCont,tid,trigbase);
00161           
00162           for (unsigned char q=0; q<triglen[linear]; q++)
00163             trigbase[q]=(trigbase[q]&0x7FF)|chanid;
00164         }
00165       }
00167     if (npresent>0) {
00168       spigots[spigot].pack(&(preclen[0]),&(precdata[0]),
00169                            &(triglen[0]),&(trigdata[0]),
00170                            false);
00171       static const int pipeline=0x22;
00172       static const int firmwareRev=0;
00173       int submodule=exampleEId.htrTopBottom()&0x1;
00174       submodule|=(exampleEId.htrSlot()&0x1F)<<1;
00175       submodule|=(exampleEId.readoutVMECrateId()&0x1f)<<6;
00176       spigots[spigot].packHeaderTrailer(nl1a,
00177                                         bcn,
00178                                         submodule,
00179                                         orbitn,
00180                                         pipeline,
00181                                         samples,
00182                                         presamples,
00183                                         firmwareRev);
00184       if (haveUnsuppressed) {
00185         spigots[spigot].packUnsuppressed(channelIsMP);
00186       }
00187       
00188     }
00189   }
00190   // calculate the total length, and resize the FEDRawData
00191   int theSize=0;
00192   for (int spigot=0; spigot<15; spigot++) {
00193     theSize+=spigots[spigot].getRawLength()*sizeof(unsigned short);
00194   }
00195   theSize+=sizeof(HcalDCCHeader)+8; // 8 for trailer
00196   theSize+=(8-(theSize%8))%8; // even number of 64-bit words.
00197   output.resize(theSize);
00198   
00199   // construct the bare DCC Header
00200   HcalDCCHeader* dcc=(HcalDCCHeader*)(output.data());
00201   dcc->clear();
00202   dcc->setHeader(fedid,bcn,nl1a,orbitn);
00203 
00204   // pack the HTR data into the FEDRawData block using HcalDCCHeader
00205   for (int spigot=0; spigot<15; spigot++) {
00206     if (spigots[spigot].getRawLength()>0)
00207       dcc->copySpigotData(spigot,spigots[spigot],true,0);
00208   }
00209   // trailer
00210   FEDTrailer fedTrailer(output.data()+(output.size()-8));
00211   fedTrailer.set(output.data()+(output.size()-8),
00212     output.size()/8,
00213     evf::compute_crc(output.data(),output.size()), 0, 0);
00214 }