CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/EventFilter/CastorRawToDigi/src/CastorCtdcPacker.cc

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