CMS 3D CMS Logo

CastorPacker.cc

Go to the documentation of this file.
00001 #include "EventFilter/CastorRawToDigi/interface/CastorPacker.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 "EventFilter/Utilities/interface/Crc.h"
00008 
00009 CastorPacker::Collections::Collections() {
00010   castorCont=0;
00011   tpCont=0;
00012   calibCont=0;
00013 }
00014 
00015 template <class Coll, class DetIdClass> 
00016 int process(const Coll* pt, const DetId& did, unsigned short* buffer, int& presamples) {
00017   if (pt==0) return 0;
00018   int size=0;
00019   typename Coll::const_iterator i=pt->find(DetIdClass(did));
00020   if (i!=pt->end()) {
00021     presamples=i->presamples();
00022     size=i->size();
00023     for (int j=0; j<size; j++) 
00024       buffer[j]=(*i)[j].raw();
00025   }
00026   return size;
00027 }
00028 
00029 int CastorPacker::findSamples(const DetId& did, const Collections& inputs,
00030                             unsigned short* buffer, int &presamples) {
00031 
00032   if (did.det()!=DetId::Calo) return 0;
00033   int size=0;
00034   HcalCastorDetId genId(did);
00035 
00036   size=process<CastorDigiCollection,HcalCastorDetId>(inputs.castorCont,did,buffer,presamples);
00037 
00038   return size;
00039 }
00040 
00041 void CastorPacker::pack(int fedid, int dccnumber,
00042                       int nl1a, int orbitn, int bcn,
00043                       const Collections& inputs, 
00044                       const CastorElectronicsMap& emap,
00045                       FEDRawData& output) {
00046   std::vector<unsigned short> precdata(HcalHTRData::CHANNELS_PER_SPIGOT*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
00047   std::vector<unsigned short> trigdata(HcalHTRData::CHANNELS_PER_SPIGOT*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
00048   std::vector<unsigned char> preclen(HcalHTRData::CHANNELS_PER_SPIGOT);
00049   std::vector<unsigned char> triglen(HcalHTRData::CHANNELS_PER_SPIGOT);
00050   static const int HTRFormatVersion=3;
00051 
00052   HcalHTRData spigots[15];
00053   // loop over all valid channels in the given dcc, spigot by spigot.
00054   for (int spigot=0; spigot<15; spigot++) {
00055     spigots[spigot].allocate(HTRFormatVersion);
00056     CastorElectronicsId exampleEId;
00057     int npresent=0;
00058     int presamples=-1, samples=-1;
00059     for (int fiber=1; fiber<=8; fiber++) 
00060       for (int fiberchan=0; fiberchan<3; fiberchan++) {
00061         int linear=(fiber-1)*3+fiberchan;
00062         HcalQIESample chanSample(0,0,fiber,fiberchan,false,false);
00063         unsigned short chanid=chanSample.raw()&0xF800;
00064         preclen[linear]=0;
00065 
00066         CastorElectronicsId partialEid(fiberchan,fiber,spigot,dccnumber);
00067         // does this partial id exist?
00068         CastorElectronicsId fullEid;
00069         HcalGenericDetId genId;
00070         if (!emap.lookup(partialEid,fullEid,genId)) continue;
00071 
00072         // next, see if there is a digi with this id
00073         unsigned short* database=&(precdata[linear*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL]);
00074         int mypresamples;
00075         int mysamples=findSamples(genId,inputs,database,mypresamples);
00076 
00077         if (mysamples>0) {
00078           if (samples<0) samples=mysamples;
00079           else if (samples!=mysamples) {
00080             edm::LogError("CASTOR") << "Mismatch of samples in a single HTR (unsupported) " << mysamples << " != " << samples;
00081             continue;
00082           }
00083           if (presamples<0) {
00084             presamples=mypresamples;
00085             exampleEId=fullEid;
00086           } else if (mypresamples!=presamples) {
00087             edm::LogError("CASTOR") << "Mismatch of presamples in a single HTR (unsupported) " << mypresamples << " != " << presamples;
00088             continue;       
00089           }
00090           for (int ii=0; ii<samples; ii++)
00091             database[ii]=(database[ii]&0x7FF)|chanid;
00092           preclen[linear]=(unsigned char)(samples);
00093           npresent++;
00094         }       
00095       }
00097     if (npresent>0) {
00098       spigots[spigot].pack(&(preclen[0]),&(precdata[0]),
00099                            &(triglen[0]),&(trigdata[0]),
00100                            false);
00101       static const int pipeline=0x22;
00102       static const int firmwareRev=0;
00103       int submodule=exampleEId.htrTopBottom()&0x1;
00104       submodule|=(exampleEId.htrSlot()&0x1F)<<1;
00105       submodule|=(exampleEId.readoutVMECrateId()&0x1f)<<6;
00106       spigots[spigot].packHeaderTrailer(nl1a,
00107                                         bcn,
00108                                         submodule,
00109                                         orbitn,
00110                                         pipeline,
00111                                         samples,
00112                                         presamples,
00113                                         firmwareRev);
00114       
00115     }
00116   }
00117   // calculate the total length, and resize the FEDRawData
00118   int theSize=0;
00119   for (int spigot=0; spigot<15; spigot++) {
00120     theSize+=spigots[spigot].getRawLength()*sizeof(unsigned short);
00121   }
00122   theSize+=sizeof(HcalDCCHeader)+8; // 8 for trailer
00123   theSize+=(8-(theSize%8))%8; // even number of 64-bit words.
00124   output.resize(theSize);
00125   
00126   // construct the bare DCC Header
00127   HcalDCCHeader* dcc=(HcalDCCHeader*)(output.data());
00128   dcc->clear();
00129   dcc->setHeader(fedid,bcn,nl1a,orbitn);
00130 
00131   // pack the HTR data into the FEDRawData block using HcalDCCHeader
00132   for (int spigot=0; spigot<15; spigot++) {
00133     if (spigots[spigot].getRawLength()>0)
00134       dcc->copySpigotData(spigot,spigots[spigot],true,0);
00135   }
00136   // trailer
00137   FEDTrailer fedTrailer(output.data()+(output.size()-8));
00138   fedTrailer.set(output.data()+(output.size()-8),
00139     output.size()/8,
00140     evf::compute_crc(output.data(),output.size()), 0, 0);
00141 
00142 }

Generated on Tue Jun 9 17:34:20 2009 for CMSSW by  doxygen 1.5.4