Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-04 02:53:15

0001 /*
0002  */
0003 
0004 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/EventSetup.h"
0007 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0008 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0009 #include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h"
0010 #include "SimCalorimetry/EcalSelectiveReadoutAlgos/interface/EcalSelectiveReadout.h"
0011 #include <fstream>
0012 #include <string>
0013 
0014 /** The EcalSimRawData CMSSW module produces raw data from digis. The raw data
0015  * are written into files which can be loaded into the TCC DCC and SRP boards
0016  * in order to emulate the front-end. Only barrel is fully supported.
0017  * The produced files for TCC assumes a special LUT in the TCC forged for
0018  * FE emulation mode.
0019  * <P>Module Parameters:
0020  * <UL><LI>string digiProducer: digi label</LI>
0021  *    <LI>string EBDigiCollection: EB crystal digi product instance name</LI>
0022  *    <LI>string EEDigiCollection: EE crystal digi product instance name</LI>
0023  *    <LI>string srProducer: sr flags digi label"</LI>
0024  *    <LI>string EBSrFlagCollection: EB SR flags product instance name</LI>
0025  *    <LI>string EESrFlagCollection: EE SR flags product instance name</LI>
0026  *    <LI>string trigPrimProducer: trigger primitive digi label"</LI>
0027  *    <LI>string trigPrimDigiCollection: trigger primitive digi product instance
0028  * name</LI> <LI>string tcpPrimDigiCollection: TCP FENIX output trigger
0029  * primitive digi product instance name</LI> <LI>string writeMode: output
0030  * format. "write", "littleEndian", "bigEndian" <LI>untracked bool tpVerbose:
0031  * make verbose the trigger primitive processing</LI> <LI>untracked bool
0032  * xtalVerbose: make verbose the crystal digi processing</LI> <LI>untracked
0033  * int32 dccNum: Id of the dcc raw data must be produced for. -1 means every
0034  * DCC</LI> <LI>untracked int32 tccNum: Id of the tcc raw data must be produced
0035  * for. -1 means every TCC</LI> <LI>untracked bool tcc2dccData: switch for
0036  * TCC->DCC data stream production</LI> <LI>untracked bool srp2dccData: switch
0037  * for SRP->DCC data stream production</LI> <LI>untracked int32 tccInDefaultVal:
0038  * default TriggerPrimitive values if the trigger tower is abscent</LI>
0039  *    <LI>untracked string outputBaseName: basename for output files</LI>
0040  *    </UL>
0041  */
0042 class EcalSimRawData : public edm::one::EDAnalyzer<> {
0043 public:
0044   /** Constructor
0045    * @param pset CMSSW configuration
0046    */
0047   explicit EcalSimRawData(const edm::ParameterSet &pset);
0048 
0049   /** Destructor
0050    */
0051   ~EcalSimRawData() override = default;
0052 
0053   /** Main method. Called back for each event. This method produced the
0054    * raw data and write them to disk.
0055    */
0056   void analyze(const edm::Event &, const edm::EventSetup &) override;
0057 
0058 private:
0059   enum tokenType { tcp = 0, tp = 1 };
0060 
0061   int iEvent;
0062 
0063   /** Number of crystals in ECAL barrel along eta
0064    */
0065   static const int nEbEta = 170;
0066 
0067   /** Number of crystals in ECAL barrel along phi
0068    */
0069   static const int nEbPhi = 360;
0070 
0071   /** X-edge of endcap (x,y)- crystal grid
0072    */
0073   static const int nEeX = 100;
0074 
0075   /** Y-edge of endcap (x,y)- crystal grid
0076    */
0077   static const int nEeY = 100;
0078 
0079   /** Number of endcaps
0080    */
0081   static const int nEndcaps = 2;
0082 
0083   /** Supercrystal edge in number of crystals
0084    */
0085   static const int scEdge = 5;
0086 
0087   /** Maximum number of supercrystal along x axis
0088    */
0089   static const int nScX = 20;
0090 
0091   /** Maximum number of supercrystal along y axis
0092    */
0093   static const int nScY = 20;
0094 
0095   /* Edge size of a barrel TT in num. of crystals
0096    */
0097   static const int ttEdge = 5;
0098 
0099   /** Number of TTs along SM phi
0100    */
0101   static const int nTtSmPhi = 4;
0102 
0103   /** Number of TTs along SM eta
0104    */
0105   static const int nTtSmEta = 17;
0106 
0107   /** Number of TTs along Ecal Phi
0108    */
0109   static const int nTtPhi = nEbPhi / ttEdge;  // 72
0110 
0111   /** Number of TTs along Ecal barrel eta
0112    */
0113   static const int nEbTtEta = nEbEta / ttEdge;  // 34
0114 
0115   /** Number of TTs along eta for one endcap.
0116    */
0117   static const int nEeTtEta = 11;
0118 
0119   /** Number of TTs along ECAL eta
0120    */
0121   static const int nTtEta = nEbTtEta + 2 * nEeTtEta;  // 56
0122 
0123   /** Number of barrel DCCs along Phi
0124    */
0125   static const int nDccInPhi = 18;
0126 
0127   /** Number of DCCs for a single endcap
0128    */
0129   static const int nDccEndcap = 9;
0130 
0131   /** number of TTs along phi of a TCC sector
0132    */
0133   static const int ebTccPhiEdge = 20;
0134 
0135   /** Number of Barrel TTCs along phi
0136    */
0137   static const int nTccInPhi = 18;
0138 
0139   /** Number of TCCs for a single endcap
0140    */
0141   static const int nTccEndcap = 36;
0142 
0143   /** Number of barrel crystals along phi covered by a DCC
0144    */
0145   static const int ebDccPhiEdge = 20;
0146 
0147   /** Number of trigger towers alng phi covered by a DCC
0148    */
0149   static const int nTtPhisPerEbDcc = 4;
0150 
0151   /** Number of trigger towers alng phi covered by a TCC
0152    */
0153   static const int nTtPhisPerEbTcc = 4;
0154 
0155   /** Number of barrel trigger tower types (in term of VFE card orientation)
0156    */
0157   static const int nTtTypes = 2;
0158 
0159   /** Map of trigger tower types (in term of VFE card orientation).
0160    * ttType[iTtEta0]: trigger tower type of TTs with eta 'c-arrary' index
0161    * iTtEta0
0162    */
0163   static const int ttType[nEbTtEta];
0164 
0165   /** Maps (strip_id, channel_id) to phi index within a TT.
0166    * stripCh2Phi[iTtType][strip_id-1][ch_id-1] will be the phi index of the
0167    * TT of type iTtType with strip ID 'strip_id' and channel VFE id 'ch_id'.
0168    * The phi runs from 0 to 4 and increases with the phi of std CMS
0169    * coordinates.
0170    */
0171   static const int stripCh2Phi[nTtTypes][ttEdge][ttEdge];
0172 
0173   /** Maps strip_id to eta index within a TT.
0174    * strip2Eta[iTtType][strip_id-1] will be the eta index of channels
0175    * with strip_id 'strip_id'. The eta index runs from 0 to 4 and increasing
0176    * with the eta of the std CMS coordinates.
0177    */
0178   static const int strip2Eta[nTtTypes][ttEdge];
0179 
0180   /** Output format mode
0181    * <UL><I>littleEndian: little endian binary</I>
0182    *     <I>bigEndian: big endian binary</I>
0183    *     <I>ascii: ascii mode. The one accepted by the TCC, DCC and SRP board
0184    * control software.</I>
0185    * </UL>
0186    */
0187   enum writeMode_t { littleEndian, bigEndian, ascii };
0188 
0189 private:
0190   /*
0191   const EBDigiCollection*
0192   getEBDigis(const edm::Event& event) const;
0193 
0194   const EEDigiCollection*
0195   getEEDigis(const edm::Event& event) const;
0196 
0197   const EcalTrigPrimDigiCollection*
0198   getTrigPrims(const edm::Event& event) const;
0199   */
0200 
0201   /// call these once an event, to make sure everything
0202   /// is up-to-date
0203   void checkGeometry(const edm::EventSetup &eventSetup);
0204   void checkTriggerMap(const edm::EventSetup &eventSetup);
0205 
0206   /** Converts std CMSSW crystal eta index into a c-index (contiguous integer
0207    * starting from 0 and increasing with pseudo-rapidity).
0208    * @param iEta std CMSSW crystal eta index
0209    * @return the c-array index
0210    */
0211   int iEta2cIndex(int iEta) const { return (iEta < 0) ? iEta + 85 : iEta + 84; }
0212 
0213   /** Converts std CMSSW crystal phi index into a c-index (contiguous integer
0214    * starting from 0 at phi=0deg and increasing with phi).
0215    * @param iPhi std CMSSW crystal phi index
0216    * @return the c-array index
0217    */
0218   int iPhi2cIndex(int iPhi) const {
0219     int iPhi0 = iPhi - 11;
0220     if (iPhi0 < 0)
0221       iPhi0 += nEbPhi;
0222     return iPhi0;
0223   }
0224 
0225   /** Converts std CMSSW ECAL trigger tower eta index into
0226    * a c-index (contiguous integer starting from 0 and increasing with
0227    * pseudo-rapidity).
0228    * @param iEta std CMSSW trigger tower eta index
0229    * @return the c-array index
0230    */
0231   int iTtEta2cIndex(int iTtEta) const { return (iTtEta < 0) ? (iTtEta + 28) : (iTtEta + 27); }
0232 
0233   /** Converse of iTtEta2cIndex
0234    * @param iTtEta0 c eta index of TT
0235    * @param std CMSSW TT eta index
0236    */
0237   int cIndex2iTtEta(int iTtEta0) const { return (iTtEta0 < 28) ? (iTtEta0 - 28) : (iTtEta0 - 27); }
0238 
0239   /** Converse of iTtPhi2cIndex
0240    * @param iTtPhi0 phi index of TT
0241    * @return std CMSS TT index
0242    */
0243   int cIndex2TtPhi(int iTtPhi0) const { return iTtPhi0 + 1; }
0244 
0245   /** Converts std CMSSW ECAL trigger tower phi index into a c-index
0246    * (contiguous integer starting from 0 at phi=0deg and increasing with phi).
0247    * @param iPhi std CMSSW ECAL trigger tower phi index
0248    * @return the c-array index
0249    */
0250   int iTtPhi2cIndex(int iTtPhi) const { return iTtPhi - 1; }
0251 
0252   /*
0253     int iXY2cIndex(int iX) const{
0254     return iX-1;
0255   }
0256   */
0257 
0258   /** Converts electronic number of an ECAL barrel channel to geometrical
0259    * indices
0260    * @param ittEta0 trigger tower c index
0261    * @param ittPhi0 trigger tower c index
0262    * @param strip1 strip index within the TT. Runs from 1 to 5.
0263    * @param ch1 channel electronics number within the VFE. Runs from 1 to 5.
0264    * @param [out] iEta0 eta c index of the channel
0265    * @param [out] iPhi0 eta c index of the channel
0266    */
0267   void elec2GeomNum(int ittEta0, int ittPhi0, int strip1, int ch1, int &iEta0, int &iPhi0) const;
0268 
0269   /* Set horizontal parity of a 16-bit word of FE data
0270    * @param a the word whose parity must be set.
0271    */
0272   void setHParity(uint16_t &a) const;
0273 
0274   /** Generates FE crystal data
0275    * @param basename base for the output file name. DCC number is appended to
0276    * the name
0277    * @param iEvent event index
0278    * @param adcCount the payload, the ADC count of the channels.
0279    */
0280   void genFeData(std::string &basename, int iEvent, const std::vector<uint16_t> adcCount[nEbEta][nEbPhi]) const;
0281 
0282   /** Generates FE trigger primitives data
0283    * @param basename base for the output file name. DCC number is appended to
0284    * the name
0285    * @param iEvent event index
0286    * @param tps the payload, the trigger primitives
0287    */
0288   void genTccIn(std::string &basename, int iEvent, const int tps[nTtEta][nTtPhi]) const;
0289 
0290   /** Generates TCC->DCC data
0291    * @param basename base for the output file name. DCC number is appended to
0292    * the name
0293    * @param iEvent event index
0294    * @param tps the payload, the trigger primitives
0295    */
0296   void genTccOut(std::string &basename, int iEvent, const int tps[nTtEta][nTtPhi]) const;
0297 
0298   /** Retrieves barrel digis (APD ADC count).
0299    * @param event CMS event
0300    * @param adc [out] the adc counts: adc[iEta0][iPhi0][iTimeSample0]
0301    */
0302   void getEbDigi(const edm::Event &event, std::vector<uint16_t> adc[nEbEta][nEbPhi]) const;
0303 
0304   /** Extracts the trigger primitive (TP). The collection name
0305    * parameter permits to select either the TCP Fenix output
0306    * or the TCC output.
0307    * Note: TCP output is only valid for the barrel.
0308    * @param event CMS event
0309    * @param collName label of the EDM collection containing the TP.
0310    * @param tp [out] the trigger primitives
0311    */
0312   void getTp(const edm::Event &event, tokenType type, int tp[nTtEta][nTtPhi]) const;
0313 
0314   /** Help function to get the file extension which depends on the output
0315    * formats.
0316    */
0317   std::string getExt() const;
0318 
0319   /** Write a data 16-bit word into file according to selected format.
0320    * @param f the file stream to write to
0321    * @param data the peace of data to write
0322    * @param [in,out] iword pass zero when writing for the first time in a file,
0323    * then the value returned by the previous call. Counts the number of words
0324    * written into the file.
0325    * @param hpar if true the horizontal odd word parity is set before writing
0326    * the word into the file.
0327    */
0328   void fwrite(std::ofstream &f, uint16_t data, int &iword, bool hpar = true) const;
0329 
0330   /** Computes the selective readout flags.
0331    * @param [in] event CMS event
0332    * @param [out] ebSrf the computed SR flags for barrel
0333    * @param [out] eeSrf the computed SR flags for endcaps
0334    */
0335   void getSrfs(const edm::Event &event, int ebSrf[nTtEta][nTtPhi], int eeSrf[nEndcaps][nScX][nScY]) const;
0336 
0337   /** Generates SR flags
0338    * @param basename base for the output file name. DCC number is appended to
0339    * the name
0340    * @param iEvent event index
0341    * @param the trigger tower flags
0342    */
0343   void genSrData(std::string &basename, int iEvent, int ttf[nEbTtEta][nTtPhi]) const;
0344 
0345 private:
0346   /** Name of module/plugin/producer making digis
0347    */
0348   std::string digiProducer_;
0349 
0350   /** EB digi product instance name
0351    */
0352   std::string ebDigiCollection_;
0353 
0354   /** EE digi product instance name
0355    */
0356   std::string eeDigiCollection_;
0357 
0358   /** Label of SR flags and suppressed digis
0359    */
0360   std::string srDigiProducer_;
0361 
0362   /** EB SRP flag digi product instance name
0363    */
0364   std::string ebSrFlagCollection_;
0365 
0366   /** EE SRP flag digi product instancename
0367    */
0368   std::string eeSrFlagCollection_;
0369 
0370   /** Trigger primitive digi product instance name
0371    */
0372   std::string tpDigiCollection_;
0373 
0374   /** TCP Fenix output digi product instance name
0375    */
0376   std::string tcpDigiCollection_;
0377 
0378   /** Calorimeter geometry
0379    */
0380   const CaloGeometry *theGeometry;
0381 
0382   /** Name of the trigger primitive label
0383    */
0384   std::string tpProducer_;
0385 
0386   /** output format
0387    */
0388   writeMode_t writeMode_;
0389 
0390   /** Verbosity switch for crystal data
0391    */
0392   bool xtalVerbose_;
0393 
0394   /** Verbosity switch for crystal data
0395    */
0396   bool tpVerbose_;
0397 
0398   /** Switch for data of SRP->DCC link
0399    */
0400   bool srp2dcc_;
0401 
0402   /** Switch for data of TCC->DCC link
0403    */
0404   bool tcc2dcc_;
0405 
0406   /** Switch for data of FE->DCC link
0407    */
0408   bool fe2dcc_;
0409 
0410   /** Switch for data of FE->TCC link
0411    */
0412   bool fe2tcc_;
0413 
0414   /** ECAL endcap trigger tower map
0415    */
0416   const EcalTrigTowerConstituentsMap *theTriggerTowerMap;
0417 
0418   /** Selective readout simulator
0419    */
0420   std::unique_ptr<EcalSelectiveReadout> esr_;
0421 
0422   /** Output file for trigger tower flags
0423    */
0424   std::ofstream ttfFile;
0425 
0426   /** Output file for selective readout flags
0427    */
0428   std::ofstream srfFile;
0429 
0430   /** Index of the TCC, FE data must be produced for. -1 for all TTCs
0431    */
0432   int tccNum_;
0433 
0434   /** Index of the DCC, FE data must be produced for. -1 for all TTCs
0435    */
0436   int dccNum_;
0437 
0438   /** default TriggerPrimitive values if the trigger tower is abscent
0439    */
0440   int tccInDefaultVal_;
0441 
0442   /** basename for output files
0443    */
0444   std::string basename_;
0445 
0446   edm::EDGetTokenT<EESrFlagCollection> eeSrFlagToken_;
0447   edm::EDGetTokenT<EBSrFlagCollection> ebSrFlagToken_;
0448   edm::EDGetTokenT<EBDigiCollection> ebDigisToken_;
0449   edm::EDGetTokenT<EcalTrigPrimDigiCollection> trigPrimDigisToken_[2];
0450 };