Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:15

0001 // -*- C++ -*-
0002 //
0003 // Package:    SiPixelInputSources
0004 // Class:      PixelSLinkDataInputSource
0005 //
0006 /**\class PixelSLinkDataInputSource PixelSLinkDataInputSource.cc
0007 IORawData/SiPixelInputSources/src/PixelSLinkDataInputSource.cc
0008 
0009 Description: <one line class summary>
0010 
0011 Implementation:
0012 <Notes on implementation>
0013 */
0014 //
0015 // Original Author:  Freya Blekman
0016 //         Created:  Fri Sep  7 15:46:34 CEST 2007
0017 //
0018 //
0019 
0020 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0021 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0022 #include "FWCore/Framework/interface/Frameworkfwd.h"
0023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0024 #include "IORawData/SiPixelInputSources/interface/PixelSLinkDataInputSource.h"
0025 #include "Utilities/StorageFactory/interface/IOTypes.h"
0026 #include "Utilities/StorageFactory/interface/StorageAccount.h"
0027 #include "Utilities/StorageFactory/interface/StorageFactory.h"
0028 #include <iostream>
0029 #include <memory>
0030 
0031 using namespace edm;
0032 
0033 // function to get the trigger number from fill words
0034 int PixelSLinkDataInputSource::getEventNumberFromFillWords(const std::vector<uint64_t> &buffer, uint32_t &totword) {
0035   // buffer validity, should already be pretty clean as this is exactly what
0036   // goes into the FEDRawDataobject.
0037 
0038   // code copied directly from A. Ryd's fill word checker in
0039   // PixelFEDInterface::PwordSlink64
0040 
0041   int fif2cnt = 0;
0042   int dumcnt = 0;
0043   int gapcnt = 0;
0044   uint32_t gap[9];
0045   uint32_t dum[9];
0046   uint32_t word[2] = {0, 0};
0047   uint32_t chan = 0;
0048   uint32_t roc = 0;
0049 
0050   const uint32_t rocmsk = 0x3e00000;
0051   const uint32_t chnlmsk = 0xfc000000;
0052 
0053   for (int jk = 1; jk < 9; jk++)
0054     gap[jk] = 0;
0055   for (int jk = 1; jk < 9; jk++)
0056     dum[jk] = 0;
0057 
0058   int fifcnt = 1;
0059   for (size_t kk = 0; kk < buffer.size(); ++kk) {
0060     word[0] = (uint32_t)buffer[kk];
0061     word[1] = (uint32_t)(buffer[kk] >> 32);
0062 
0063     for (size_t iw = 0; iw < 2; iw++) {
0064       chan = ((word[iw] & chnlmsk) >> 26);
0065       roc = ((word[iw] & rocmsk) >> 21);
0066 
0067       // count non-error words
0068       if (roc < 25) {
0069         if ((chan > 4) && (chan < 10) && (fifcnt != 2)) {
0070           fif2cnt = 0;
0071           fifcnt = 2;
0072         }
0073         if ((chan > 9) && (chan < 14) && (fifcnt != 3)) {
0074           fif2cnt = 0;
0075           fifcnt = 3;
0076         }
0077         if ((chan > 13) && (chan < 19) && (fifcnt != 4)) {
0078           fif2cnt = 0;
0079           fifcnt = 4;
0080         }
0081         if ((chan > 18) && (chan < 23) && (fifcnt != 5)) {
0082           fif2cnt = 0;
0083           fifcnt = 5;
0084         }
0085         if ((chan > 22) && (chan < 28) && (fifcnt != 6)) {
0086           fif2cnt = 0;
0087           fifcnt = 6;
0088         }
0089         if ((chan > 27) && (chan < 32) && (fifcnt != 7)) {
0090           fif2cnt = 0;
0091           fifcnt = 7;
0092         }
0093         if ((chan > 31) && (fifcnt != 8)) {
0094           fif2cnt = 0;
0095           fifcnt = 8;
0096         }
0097         fif2cnt++;
0098       }
0099       if (roc == 26) {
0100         gap[fifcnt] = (0x1000 + (word[iw] & 0xff));
0101         gapcnt++;
0102       }
0103 
0104       if ((roc == 27) && ((fif2cnt + dumcnt) < 6)) {
0105         dumcnt++;
0106         dum[fifcnt] = (0x1000 + (word[iw] & 0xff));
0107       } else if ((roc == 27) && ((fif2cnt + dumcnt) > 6)) {
0108         dumcnt = 1;
0109         fif2cnt = 0;
0110         fifcnt++;
0111       }
0112     }
0113 
0114     // word check complete
0115     if (((fif2cnt + dumcnt) == 6) && (dumcnt > 0))  // done with this fifo
0116     {
0117       dumcnt = 0;
0118       fif2cnt = 0;
0119       fifcnt++;
0120     }
0121     if ((gapcnt > 0) && ((dumcnt + fif2cnt) > 5))  // done with this fifo
0122     {
0123       gapcnt = 0;
0124       fifcnt++;
0125       fif2cnt = 0;
0126       dumcnt = 0;
0127     } else if ((gapcnt > 0) && ((dumcnt + fif2cnt) < 6))
0128       gapcnt = 0;
0129 
0130   }  // end of fifo-3 word loop-see what we got!
0131 
0132   int status = 0;
0133 
0134   if (gap[1] > 0) {
0135     totword = (gap[1] & 0xff);
0136     status = 1;
0137   } else if (gap[2] > 0) {
0138     totword = (gap[2] & 0xff);
0139     status = 1;
0140   } else if (dum[1] > 0) {
0141     totword = (dum[1] & 0xff);
0142     status = 1;
0143   } else if (dum[2] > 0) {
0144     totword = (dum[2] & 0xff);
0145     status = 1;
0146   }
0147 
0148   if (gap[3] > 0) {
0149     totword = totword | ((gap[3] & 0xff) << 8);
0150     status = status | 0x2;
0151   } else if (gap[4] > 0) {
0152     totword = totword | ((gap[4] & 0xff) << 8);
0153     status = status | 0x2;
0154   } else if (dum[3] > 0) {
0155     totword = totword | ((dum[3] & 0xff) << 8);
0156     status = status | 0x2;
0157   } else if (dum[4] > 0) {
0158     totword = totword | ((dum[4] & 0xff) << 8);
0159     status = status | 0x2;
0160   }
0161 
0162   if (gap[5] > 0) {
0163     totword = totword | ((gap[5] & 0xff) << 16);
0164     status = status | 0x4;
0165   } else if (gap[6] > 0) {
0166     totword = totword | ((gap[6] & 0xff) << 16);
0167     status = status | 0x4;
0168   } else if (dum[5] > 0) {
0169     totword = totword | ((dum[5] & 0xff) << 16);
0170     status = status | 0x4;
0171   } else if (dum[6] > 0) {
0172     totword = totword | ((dum[6] & 0xff) << 16);
0173     status = status | 0x4;
0174   }
0175 
0176   if (gap[7] > 0) {
0177     totword = totword | ((gap[7] & 0xff) << 24);
0178     status = status | 0x8;
0179   } else if (gap[8] > 0) {
0180     totword = totword | ((gap[8] & 0xff) << 24);
0181     status = status | 0x8;
0182   } else if (dum[7] > 0) {
0183     totword = totword | ((dum[7] & 0xff) << 24);
0184     status = status | 0x8;
0185   } else if (dum[8] > 0) {
0186     totword = totword | ((dum[8] & 0xff) << 24);
0187     status = status | 0x8;
0188   }
0189   return (status);
0190 }
0191 
0192 // constructor
0193 PixelSLinkDataInputSource::PixelSLinkDataInputSource(const edm::ParameterSet &pset,
0194                                                      const edm::InputSourceDescription &desc)
0195     : ProducerSourceFromFiles(pset, desc, true),
0196       m_fedid(pset.getUntrackedParameter<int>("fedid")),
0197       m_fileindex(0),
0198       m_runnumber(pset.getUntrackedParameter<int>("runNumber", -1)),
0199       m_currenteventnumber(0),
0200       m_currenttriggernumber(0),
0201       m_eventnumber_shift(0) {
0202   produces<FEDRawDataCollection>();
0203 
0204   if (m_fileindex >= fileNames(0).size()) {
0205     edm::LogInfo("") << "no more file to read " << std::endl;
0206     return;  // ???
0207   }
0208   std::string currentfilename = fileNames(0)[m_fileindex];
0209   edm::LogInfo("") << "now examining file " << currentfilename;
0210   m_fileindex++;
0211   // reading both castor and other ('normal'/dcap) files.
0212   using namespace edm::storage;
0213   IOOffset size = -1;
0214   StorageFactory::getToModify()->enableAccounting(true);
0215 
0216   edm::LogInfo("PixelSLinkDataInputSource")
0217       << " unsigned long int size = " << sizeof(unsigned long int)
0218       << "\n unsigned long size = " << sizeof(unsigned long)
0219       << "\n unsigned long long size = " << sizeof(unsigned long long) << "\n uint32_t size = " << sizeof(uint32_t)
0220       << "\n uint64_t size = " << sizeof(uint64_t) << std::endl;
0221 
0222   bool exists = StorageFactory::get()->check(currentfilename, &size);
0223 
0224   edm::LogInfo("PixelSLinkDataInputSource") << "file size " << size << std::endl;
0225 
0226   if (!exists) {
0227     edm::LogInfo("") << "file " << currentfilename << " cannot be found.";
0228     return;
0229   }
0230   // now open the file stream:
0231   storage = StorageFactory::get()->open(currentfilename);
0232   // (throw if storage is 0)
0233 
0234   // check run number by opening up data file...
0235 
0236   Storage &temp_file = *storage;
0237   //  IOSize n =
0238   temp_file.read((char *)&m_data, 8);
0239   if ((m_data >> 60) != 0x5) {
0240     uint32_t runnum = m_data;
0241     if (m_runnumber != -1)
0242       edm::LogInfo("") << "WARNING: observed run number encoded in S-Link dump. Overwriting "
0243                           "run number as defined in .cfg file!!! Run number now set to "
0244                        << runnum << " (was " << m_runnumber << ")";
0245     m_runnumber = runnum;
0246   }
0247   temp_file.read((char *)&m_data, 8);
0248   m_currenteventnumber = (m_data >> 32) & 0x00ffffff;
0249 }
0250 
0251 // destructor
0252 PixelSLinkDataInputSource::~PixelSLinkDataInputSource() {}
0253 
0254 bool PixelSLinkDataInputSource::setRunAndEventInfo(edm::EventID &id,
0255                                                    edm::TimeValue_t &time,
0256                                                    edm::EventAuxiliary::ExperimentType &) {
0257   edm::storage::Storage &m_file = *storage;
0258 
0259   // create product (raw data)
0260   buffers = std::make_unique<FEDRawDataCollection>();
0261 
0262   //  uint32_t currenteventnumber = (m_data >> 32)&0x00ffffff;
0263   uint32_t eventnumber = (m_data >> 32) & 0x00ffffff;
0264 
0265   do {
0266     std::vector<uint64_t> buffer;
0267 
0268     uint16_t count = 0;
0269     eventnumber = (m_data >> 32) & 0x00ffffff;
0270     if (m_currenteventnumber == 0)
0271       m_currenteventnumber = eventnumber;
0272     edm::LogInfo("PixelSLinkDataInputSource::produce()")
0273         << "**** event number = " << eventnumber << " global event number " << m_currenteventnumber << " data "
0274         << std::hex << m_data << std::dec << std::endl;
0275     while ((m_data >> 60) != 0x5) {
0276       //  std::cout << std::hex << m_data << std::dec << std::endl;
0277       if (count == 0) {
0278         edm::LogWarning("") << "DATA CORRUPTION!";
0279         edm::LogWarning("") << "Expected to find header, but read: 0x" << std::hex << m_data << std::dec;
0280       }
0281 
0282       count++;
0283       int n = m_file.read((char *)&m_data, 8);
0284       edm::LogWarning("") << "next data " << std::hex << m_data << std::dec << std::endl;
0285 
0286       if (n != 8) {
0287         edm::LogInfo("") << "End of input file";
0288         return false;
0289       }
0290     }
0291 
0292     if (count > 0) {
0293       edm::LogWarning("") << "Had to read " << count << " words before finding header!" << std::endl;
0294     }
0295 
0296     if (m_fedid > -1) {
0297       m_data = (m_data & 0xfffffffffff000ffLL) | ((m_fedid & 0xfff) << 8);
0298     }
0299 
0300     uint16_t fed_id = (m_data >> 8) & 0xfff;
0301     //   std::cout << "fed id = " << fed_id << std::endl;
0302     buffer.push_back(m_data);
0303 
0304     do {
0305       m_file.read((char *)&m_data, 8);
0306       buffer.push_back(m_data);
0307     } while ((m_data >> 60) != 0xa);
0308     //  std::cout << "read " <<  buffer.size() << " long words" << std::endl;
0309 
0310     auto rawData = std::make_unique<FEDRawData>(8 * buffer.size());
0311     //  FEDRawData * rawData = new FEDRawData(8*buffer.size());
0312     unsigned char *dataptr = rawData->data();
0313 
0314     for (uint16_t i = 0; i < buffer.size(); i++) {
0315       ((uint64_t *)dataptr)[i] = buffer[i];
0316     }
0317     uint32_t thetriggernumber = 0;
0318     int nfillwords = 0;  // getEventNumberFromFillWords(buffer,thetriggernumber);
0319 
0320     if (nfillwords > 0) {
0321       LogInfo("") << "n fill words = " << nfillwords << ", trigger numbers: " << thetriggernumber << ","
0322                   << m_currenttriggernumber << std::endl;
0323       m_eventnumber_shift = thetriggernumber - m_currenttriggernumber;
0324     }
0325     m_currenttriggernumber = thetriggernumber;
0326     FEDRawData &fedRawData = buffers->FEDData(fed_id);
0327     fedRawData = *rawData;
0328 
0329     // read the first data member of the next blob to check on event number
0330     int n = m_file.read((char *)&m_data, 8);
0331     if (n == 0) {
0332       edm::LogInfo("") << "End of input file";
0333     }
0334     m_currenteventnumber = (m_data >> 32) & 0x00ffffff;
0335     if (m_currenteventnumber < eventnumber)
0336       LogError("PixelSLinkDataInputSource")
0337           << " error, the previous event number (" << eventnumber << ") is LARGER than the next event number ("
0338           << m_currenteventnumber << ")" << std::endl;
0339 
0340   } while (eventnumber == m_currenteventnumber);
0341 
0342   uint32_t realeventno = synchronizeEvents();
0343   if (m_runnumber != 0)
0344     id = edm::EventID(m_runnumber, id.luminosityBlock(), realeventno);
0345   else
0346     id = edm::EventID(id.run(), id.luminosityBlock(), realeventno);
0347   return true;
0348 }
0349 
0350 // produce() method. This is the worker method that is called every event.
0351 void PixelSLinkDataInputSource::produce(edm::Event &event) {
0352   event.put(std::move(buffers));
0353   buffers.reset();
0354 }
0355 
0356 // this function sets the m_globaleventnumber quantity. It uses the
0357 // m_currenteventnumber and m_currenttriggernumber values as input
0358 uint32_t PixelSLinkDataInputSource::synchronizeEvents() {
0359   int32_t result = m_currenteventnumber - 1;
0360 
0361   return (uint32_t)result;
0362 }