Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:21

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*/
0068     return timeSample(95)->controllerData;
0069   }
0070   unsigned sizeInWords() const { return 100; }
0071 
0072   /// unpacked from the controller words for each channel in the layer
0073   CSCCFEBSCAControllerWord scaControllerWord(int layer) const;
0074 
0075   void setControllerWord(const CSCCFEBSCAControllerWord &controllerWord);
0076 
0077   /// Old CFEB format: dummy word 100 should be 0x7FFF
0078   /// New CFEB format: the sum of word 97 and 100 should be 0x7FFF (word 100 is inverted word 97)
0079   bool check() const { return ((dummy == 0x7FFF) || ((dummy + crc) == 0x7FFF)); }
0080 
0081   bool checkCRC() const { return crc == calcCRC(); }
0082 
0083   unsigned calcCRC() const;
0084 
0085   /// =VB= Set calculated CRC value for simulated CFEB Time Slice data
0086   void setCRC() {
0087     crc = calcCRC();
0088     dummy = 0x7FFF - crc;
0089   }
0090 
0091   friend std::ostream &operator<<(std::ostream &os, const CSCCFEBTimeSlice &);
0092 
0093   ///accessors for words 97, 98 and 99
0094   unsigned get_crc() const { return crc; }
0095   unsigned get_n_free_sca_blocks() const { return n_free_sca_blocks; }
0096   unsigned get_lctpipe_count() const { return lctpipe_count; }
0097   unsigned get_lctpipe_full() const { return lctpipe_full; }
0098   unsigned get_l1pipe_full() const { return l1pipe_full; }
0099   unsigned get_lctpipe_empty() const { return lctpipe_empty; }
0100   unsigned get_l1pipe_empty() const { return l1pipe_empty; }
0101   unsigned get_buffer_warning() const { return buffer_warning; }
0102   unsigned get_buffer_count() const { return buffer_count; }
0103   unsigned get_L1A_number() const { return L1A_number; }
0104 
0105   void set_L1Anumber(unsigned l1a) { L1A_number = l1a & 0x3F; }
0106 
0107 private:
0108   unsigned short theSamples[96];
0109 
0110   /// WORD 97
0111   unsigned crc : 16;
0112 
0113   /// WORD 98
0114   unsigned n_free_sca_blocks : 4;
0115   unsigned lctpipe_count : 4;
0116   unsigned lctpipe_full : 1;
0117   unsigned l1pipe_full : 1;
0118   unsigned lctpipe_empty : 1;
0119   unsigned l1pipe_empty : 1;
0120   unsigned blank_space_1 : 4;
0121 
0122   /// WORD 99
0123   unsigned buffer_warning : 1;
0124   unsigned buffer_count : 5;
0125   unsigned L1A_number : 6;
0126   unsigned blank_space_3 : 4;
0127 
0128   /// WORD 100
0129   unsigned dummy : 16;
0130 };
0131 
0132 #endif