Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:06

0001 #ifndef EventFilter_CSCRawToDigi_CSCCFEBTimeSlice_h
0002 #define EventFilter_CSCRawToDigi_CSCCFEBTimeSlice_h
0003 
0004 /**
0005  CFEB Data Stream 
0006 The ordering of the words in the data stream from a single CFEB is described by the following nested loops: 
0007 
0008 do (N_ts  time samples){ 
0009   do (Gray code loop over 16 CSC Strips; S=0,1,3,2,6,7,5,4,12,13,15,14,10,11,9,8){ 
0010     do (loop over 6 CSC Layers; L=3,1,5,6,4,2){ 
0011     }
0012   } 
0013   CRC word 
0014   CFEB Info word 98 
0015   CFEB Info word 99 
0016   Dummy word (0x7FFF)
0017 }
0018 */
0019 
0020 struct CSCCFEBDataWord {
0021   unsigned short adcCounts : 12;
0022   unsigned short adcOverflow : 1;
0023   /// combined from all 16 strips to make a word
0024   unsigned short controllerData : 1;
0025   /// Overlapped sample flag (normally HIGH;
0026   /// set LOW when two separate LCTs share a time sample).
0027   unsigned short overlappedSampleFlag : 1;
0028   /// Always LOW for data words.  HIGH for DDU Code word
0029   /// (maybe End of Event or Error)
0030   unsigned short errorstat : 1;
0031 };
0032 
0033 #include <iostream>
0034 #include <cstring>  //for bzero
0035 
0036 struct CSCCFEBSCAControllerWord {
0037   /**
0038 TRIG_TIME indicates which of the eight time samples in the 400ns SCA block (lowest bit is the first sample, highest bit the eighth sample) corresponds to the arrival of the LCT; it should be at some fixed phase relative to the peak of the CSC pulse.  SCA_BLK is the SCA Capacitor block used for this time sample. L1A_PHASE and LCT_PHASE show the phase of the 50ns CFEB digitization clock at the time the trigger was received (1=clock high, 0=clock low).  SCA_FULL indicates lost SCA data due to SCA full condition.  The TS_FLAG bit indicates the number of time samples to digitize per event; high=16 time samples, low=8 time samples. 
0039 
0040   */
0041   explicit CSCCFEBSCAControllerWord(unsigned short frame);
0042   CSCCFEBSCAControllerWord() { bzero(this, 2); }
0043 
0044   unsigned short trig_time : 8;
0045   unsigned short sca_blk : 4;
0046   unsigned short l1a_phase : 1;
0047   unsigned short lct_phase : 1;
0048   unsigned short sca_full : 1;
0049   unsigned short ts_flag : 1;
0050 };
0051 
0052 class CSCCFEBTimeSlice {
0053 public:
0054   CSCCFEBTimeSlice();
0055 
0056   /// input from 0 to 95
0057   CSCCFEBDataWord *timeSample(int index) const { return (CSCCFEBDataWord *)(theSamples + index); }
0058 
0059   /// layer and element count from one
0060   // CSCCFEBDataWord * timeSample(int layer, int channel) const;
0061 
0062   /// !!! Important change. Use isDCFEB flag in user code to distinguish between CFEB and DCFEB
0063   /// !!! Use CSCCFEBData::isDCFEB() function to get this flag from CSCCFEBData object
0064   CSCCFEBDataWord *timeSample(int layer, int channel, bool isDCFEB = false) const;
0065 
0066   /// whether we keep 8 or 16 time samples
0067   bool sixteenSamples() const { /*return scaControllerWord(1).ts_flag;i*/ return timeSample(95)->controllerData; }
0068   unsigned sizeInWords() const { return 100; }
0069 
0070   /// unpacked from the controller words for each channel in the layer
0071   CSCCFEBSCAControllerWord scaControllerWord(int layer) const;
0072 
0073   void setControllerWord(const CSCCFEBSCAControllerWord &controllerWord);
0074 
0075   /// Old CFEB format: dummy word 100 should be 0x7FFF
0076   /// New CFEB format: the sum of word 97 and 100 should be 0x7FFF (word 100 is inverted word 97)
0077   bool check() const { return ((dummy == 0x7FFF) || ((dummy + crc) == 0x7FFF)); }
0078 
0079   bool checkCRC() const { return crc == calcCRC(); }
0080 
0081   unsigned calcCRC() const;
0082 
0083   /// =VB= Set calculated CRC value for simulated CFEB Time Slice data
0084   void setCRC() {
0085     crc = calcCRC();
0086     dummy = 0x7FFF - crc;
0087   }
0088 
0089   friend std::ostream &operator<<(std::ostream &os, const CSCCFEBTimeSlice &);
0090 
0091   ///accessors for words 97, 98 and 99
0092   unsigned get_crc() const { return crc; }
0093   unsigned get_n_free_sca_blocks() const { return n_free_sca_blocks; }
0094   unsigned get_lctpipe_count() const { return lctpipe_count; }
0095   unsigned get_lctpipe_full() const { return lctpipe_full; }
0096   unsigned get_l1pipe_full() const { return l1pipe_full; }
0097   unsigned get_lctpipe_empty() const { return lctpipe_empty; }
0098   unsigned get_l1pipe_empty() const { return l1pipe_empty; }
0099   unsigned get_buffer_warning() const { return buffer_warning; }
0100   unsigned get_buffer_count() const { return buffer_count; }
0101   unsigned get_L1A_number() const { return L1A_number; }
0102 
0103   void set_L1Anumber(unsigned l1a) { L1A_number = l1a & 0x3F; }
0104 
0105 private:
0106   unsigned short theSamples[96];
0107 
0108   /// WORD 97
0109   unsigned crc : 16;
0110 
0111   /// WORD 98
0112   unsigned n_free_sca_blocks : 4;
0113   unsigned lctpipe_count : 4;
0114   unsigned lctpipe_full : 1;
0115   unsigned l1pipe_full : 1;
0116   unsigned lctpipe_empty : 1;
0117   unsigned l1pipe_empty : 1;
0118   unsigned blank_space_1 : 4;
0119 
0120   /// WORD 99
0121   unsigned buffer_warning : 1;
0122   unsigned buffer_count : 5;
0123   unsigned L1A_number : 6;
0124   unsigned blank_space_3 : 4;
0125 
0126   /// WORD 100
0127   unsigned dummy : 16;
0128 };
0129 
0130 #endif