Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "EventFilter/CSCRawToDigi/interface/CSCGEMData.h"
0002 #include "DataFormats/GEMDigi/interface/GEMPadDigiCluster.h"
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0005 
0006 #include <string>
0007 #include <cstdio>
0008 #include <strings.h>  // for bzero
0009 #include <cstring>
0010 #include <iostream>
0011 
0012 #ifdef LOCAL_UNPACK
0013 bool CSCGEMData::debug = false;
0014 #else
0015 std::atomic<bool> CSCGEMData::debug{false};
0016 #endif
0017 
0018 CSCGEMData::CSCGEMData(int ntbins, int gems_fibers) : ntbins_(ntbins), size_(0) {
0019   theData[0] = 0x6C04;
0020   ntbins_ = ntbins;
0021   gems_enabled_ = gems_fibers;
0022   ngems_ = 0;
0023   /* Not implemented in the firmware yet */
0024   /*
0025   for (int i=0; i<4; i++)
0026     ngems_ += (gems_fibers>>i) & 0x1;
0027   */
0028   ngems_ = 4;
0029   size_ = 2 + ntbins_ * ngems_ * 4;
0030 
0031   /// initialize GEM data
0032   for (int i = 0; i < (size_ - 2); i++) {
0033     int gem_chamber = (i % 16) / 8;
0034     theData[i + 1] = 0x3FFF | (gem_chamber << 14);
0035   }
0036 
0037   theData[size_ - 1] = 0x6D04;
0038 }
0039 
0040 CSCGEMData::CSCGEMData(const unsigned short* buf, int length, int gems_fibers) : size_(length) {
0041   size_ = length;
0042   ngems_ = 0;
0043   /* Not implemented in the firmware yet */
0044   /*
0045   for (int i=0; i<4; i++)
0046     ngems_ += (gems_fibers>>i) & 0x1;
0047   */
0048   ngems_ = 4;
0049   ntbins_ = (size_ - 2) / (4 * ngems_);
0050   gems_enabled_ = gems_fibers;
0051   memcpy(theData, buf, size_ * 2);
0052 }
0053 
0054 void CSCGEMData::print() const {
0055   LogTrace("CSCGEMData|CSCRawToDigi") << "CSCGEMData.Print";
0056   for (int line = 0; line < ((size_)); ++line) {
0057     LogTrace("CSCGEMData|CSCRawToDigi") << std::hex << theData[line];
0058   }
0059 }
0060 
0061 int CSCGEMData::getPartitionNumber(int addr, int npads) const { return addr / (npads - 1); }
0062 
0063 int CSCGEMData::getPartitionStripNumber(int address, int nPads, int etaPart) const {
0064   return address - (nPads * etaPart);
0065 }
0066 
0067 std::vector<GEMPadDigiCluster> CSCGEMData::digis(int gem_chamber) const {
0068   /// GEM data format v2
0069   std::vector<GEMPadDigiCluster> result;
0070   result.clear();
0071   int nPads = 192;  // From geometry
0072   int maxClusters = 4;
0073   int nGEMs = 4;
0074   // nGEMs = ngems_; // based on enabled fibers. not implemented in the firmware yet
0075   for (int i = 0; i < ntbins_; i++) {
0076     for (int fiber = 0; fiber < nGEMs; fiber++) {
0077       for (int cluster = 0; cluster < maxClusters; cluster++) {
0078         int dataAddr = 1 + (i * nGEMs + fiber) * maxClusters + cluster;
0079         int gem_layer = (theData[dataAddr] >> 14) & 0x1;  // gemA=0 or gemB=1
0080         if (gem_layer == gem_chamber) {
0081           int cl_word = theData[dataAddr] & 0x3fff;
0082           int pad = theData[dataAddr] & 0xff;
0083           int eta = (theData[dataAddr] >> 8) & 0x7;
0084           int cluster_size = (theData[dataAddr] >> 11) & 0x7;
0085           if (pad < nPads) {
0086             int padInPart = eta * nPads + pad;
0087             if (debug)
0088               LogTrace("CSCGEMData|CSCRawToDigi")
0089                   << "GEMlayer" << gem_layer << " cl_word" << dataAddr << ": 0x" << std::hex << cl_word << std::dec
0090                   << " tbin: " << i << " fiber#: " << (fiber + 1) << " cluster#: " << (cluster + 1)
0091                   << " padInPart: " << padInPart << " pad: " << pad << " eta: " << eta
0092                   << " cluster_size: " << cluster_size << std::endl;
0093             std::vector<short unsigned int> pads;
0094             for (int iP = 0; iP <= cluster_size; ++iP)
0095               pads.push_back(padInPart + iP);
0096             GEMPadDigiCluster pad_cluster(pads, i);
0097             result.push_back(pad_cluster);
0098           }
0099         }
0100       }
0101     }
0102   }
0103 
0104   /// GEM data format v1
0105   /// It is not used in the production
0106   /// Keeping this commented code just for v1 unpacking algo reference
0107   /*
0108   std::vector<GEMPadDigiCluster> result;
0109   result.clear();
0110   int nPads = 192; // From geometry
0111   int maxAddr = 1536;
0112   int nGEMs = 2;
0113   int maxClusters = 8;
0114   // std::cout << std::hex << "markers " << theData[0] << ": " << theData[size_-1] << std::dec << " size: " << size_ << std::endl;
0115   for (int i=0; i<ntbins_; i++)
0116     {
0117       for (int gem=0; gem<nGEMs; gem++)
0118         {
0119           if (gem==gem_chamber) // Return only digis for specified GEM chamber
0120             {
0121               for (int TMBCluster=0; TMBCluster<maxClusters; TMBCluster++)
0122                 {
0123                   int dataAddr = 1 + (i*nGEMs+gem)*maxClusters + TMBCluster;
0124                   int address = theData[dataAddr] & 0x7ff;
0125                   // std::cout << dataAddr << ": " << address <<std::endl;
0126                   int nExtraPads = (theData[dataAddr] >>11)&0x7;
0127                   if (address<maxAddr)
0128                     {
0129                       int  etaPart   = getPartitionNumber(address,nPads);
0130                       int  padInPart = getPartitionStripNumber(address,nPads,etaPart);
0131                       vector<short unsigned int> pads;
0132                       for(int iP = 0; iP <= nExtraPads; ++iP)
0133                         pads.push_back(padInPart + iP );
0134                       GEMPadDigiCluster cluster ( pads, i);
0135                       result.push_back(cluster);
0136                     }
0137                 }
0138             }
0139         }
0140     }
0141   */
0142   return result;
0143 }
0144 
0145 /// Unpack GEMPadDigiCluster digi trigger objects per eta/roll
0146 /// gem_chamber - GEM GE11 layer gemA/B [0,1]
0147 /// eta_roll - GEM eta/roll 8 rolls per GEM layer [0-7]
0148 std::vector<GEMPadDigiCluster> CSCGEMData::etaDigis(int gem_chamber, int eta_roll, int alctMatchTime) const {
0149   /// GEM data format v2
0150   std::vector<GEMPadDigiCluster> result;
0151   result.clear();
0152   int nPads = 192;  // From geometry
0153   int maxClusters = 4;
0154   int nGEMs = 4;
0155   // nGEMs = ngems_; // based on enabled fibers. currently not implemented in the firmware
0156   for (int i = 0; i < ntbins_; i++) {
0157     for (int fiber = 0; fiber < nGEMs; fiber++) {
0158       for (int cluster = 0; cluster < maxClusters; cluster++) {
0159         int dataAddr = 1 + (i * nGEMs + fiber) * maxClusters + cluster;
0160         int gem_layer = (theData[dataAddr] >> 14) & 0x1;  // gemA=0 or gemB=1
0161         if (gem_layer == gem_chamber) {
0162           int cl_word = theData[dataAddr] & 0x3fff;
0163           int pad = theData[dataAddr] & 0xff;
0164           int eta = (theData[dataAddr] >> 8) & 0x7;
0165           int cluster_size = (theData[dataAddr] >> 11) & 0x7;
0166           if ((pad < nPads) && (eta == eta_roll)) {
0167             int padInPart = pad;
0168             if (debug)
0169               LogTrace("CSCGEMData|CSCRawToDigi")
0170                   << "GEMlayer" << gem_layer << " cl_word" << dataAddr << ": 0x" << std::hex << cl_word << std::dec
0171                   << " tbin: " << i << " fiber#: " << (fiber + 1) << " cluster#: " << (cluster + 1)
0172                   << " padInPart: " << padInPart << " pad: " << pad << " eta: " << eta
0173                   << " cluster_size: " << cluster_size << " alctMatchTime: " << alctMatchTime << std::endl;
0174             std::vector<short unsigned int> pads;
0175             for (int iP = 0; iP <= cluster_size; ++iP)
0176               pads.push_back(padInPart + iP);
0177             GEMPadDigiCluster pad_cluster(pads, i);
0178             pad_cluster.setAlctMatchTime(alctMatchTime);
0179             result.push_back(pad_cluster);
0180           }
0181         }
0182       }
0183     }
0184   }
0185   return result;
0186 }
0187 
0188 /// Add/pack GEMPadDigiCluster digi trigger objects per eta/roll
0189 /// gem_chamber - GEM GE11 layer gemA/B [0,1]
0190 /// eta_roll - GEM eta/roll 8 rolls per GEM layer [0-7]
0191 void CSCGEMData::addEtaPadCluster(const GEMPadDigiCluster& digi, int gem_chamber, int eta_roll) {
0192   int bx = digi.bx();
0193   /// Check that bx < GEM data max allocated tbins and that gem_chamber/layer is in 0,1 range
0194   if ((gem_chamber < 2) && (bx < ntbins_)) {
0195     int gem_layer = gem_chamber & 0x1;
0196     int cluster_size = digi.pads().size() - 1;
0197     int pad = digi.pads()[0];
0198     int eta = eta_roll;
0199     int cl_word = (gem_layer << 14) + (pad & 0xff) + ((eta & 0x7) << 8) + ((cluster_size & 0x7) << 11);
0200     int dataAddr = 1 + bx * 16 + 8 * gem_layer;
0201     int cluster_num = 0;
0202     /// search for first free/empty cluster word
0203     while (((theData[dataAddr + cluster_num] & 0x3fff) != 0x3fff) && (cluster_num < 8)) {
0204       cluster_num++;
0205     }
0206     /// fill free cluster word if it was found
0207     if (((theData[dataAddr + cluster_num] & 0x3fff) == 0x3fff) && (cluster_num < 8)) {
0208       theData[dataAddr + cluster_num] = cl_word;
0209     }
0210   }
0211 }