CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/IORawData/SiPixelInputSources/src/PixelSLinkDataInputSource.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    SiPixelInputSources
00004 // Class:      PixelSLinkDataInputSource
00005 // 
00013 //
00014 // Original Author:  Freya Blekman
00015 //         Created:  Fri Sep  7 15:46:34 CEST 2007
00016 // $Id: PixelSLinkDataInputSource.cc,v 1.21 2012/11/19 20:22:07 wmtan Exp $
00017 //
00018 //
00019 
00020 #include <memory>
00021 #include "FWCore/Framework/interface/Frameworkfwd.h"
00022 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00023 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00024 #include "IORawData/SiPixelInputSources/interface/PixelSLinkDataInputSource.h"
00025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00026 #include "Utilities/StorageFactory/interface/StorageFactory.h"
00027 #include "Utilities/StorageFactory/interface/StorageAccount.h"
00028 #include "Utilities/StorageFactory/interface/IOTypes.h"
00029 #include <iostream>
00030 
00031 using namespace edm;
00032 
00033 // function to get the trigger number from fill words
00034 int PixelSLinkDataInputSource::getEventNumberFromFillWords(std::vector<uint64_t> buffer, uint32_t & totword ){
00035   // buffer validity, should already be pretty clean as this is exactly what goes into the FEDRawDataobject.
00036   
00037   // code copied directly from A. Ryd's fill word checker in PixelFEDInterface::PwordSlink64
00038 
00039   int fif2cnt=0;
00040   int dumcnt=0;
00041   int gapcnt=0;
00042   uint32_t gap[9];
00043   uint32_t dum[9];
00044   uint32_t word[2]={0,0};
00045   uint32_t chan=0;
00046   uint32_t roc=0;
00047 
00048   const uint32_t rocmsk = 0x3e00000;
00049   const uint32_t chnlmsk = 0xfc000000;
00050   
00051   for(int jk=1;jk<9;jk++)gap[jk]=0;
00052   for(int jk=1;jk<9;jk++)dum[jk]=0;
00053   
00054   int fifcnt=1;
00055   for(size_t kk=0; kk<buffer.size(); ++kk)
00056     {
00057 
00058       word[0] = (uint32_t) buffer[kk];
00059       word[1] = (uint32_t) (buffer[kk]>>32);
00060 
00061       for(size_t iw=0; iw<2; iw++)
00062         {
00063           chan= ((word[iw]&chnlmsk)>>26);
00064           roc= ((word[iw]&rocmsk)>>21);
00065 
00066           //count non-error words
00067           if(roc<25){
00068             if((chan>4)&&(chan<10)&&(fifcnt!=2)) {fif2cnt=0;fifcnt=2;}
00069             if((chan>9)&&(chan<14)&&(fifcnt!=3)) {fif2cnt=0;fifcnt=3;}
00070             if((chan>13)&&(chan<19)&&(fifcnt!=4)){fif2cnt=0;fifcnt=4;}
00071             if((chan>18)&&(chan<23)&&(fifcnt!=5)){fif2cnt=0;fifcnt=5;}
00072             if((chan>22)&&(chan<28)&&(fifcnt!=6)){fif2cnt=0;fifcnt=6;}
00073             if((chan>27)&&(chan<32)&&(fifcnt!=7)){fif2cnt=0;fifcnt=7;}
00074             if((chan>31)&&(fifcnt!=8)){fif2cnt=0;fifcnt=8;} 
00075             fif2cnt++;
00076           }
00077           if(roc==26){gap[fifcnt]=(0x1000+(word[iw]&0xff));gapcnt++;}
00078           
00079           if((roc==27)&&((fif2cnt+dumcnt)<6)){dumcnt++;dum[fifcnt]=(0x1000+(word[iw]&0xff));}
00080           else if((roc==27)&&((fif2cnt+dumcnt)>6)){dumcnt=1;fif2cnt=0;fifcnt++;}
00081         }
00082 
00083       //word check complete
00084       if(((fif2cnt+dumcnt)==6)&&(dumcnt>0)) //done with this fifo
00085         {dumcnt=0;fif2cnt=0;fifcnt++;}
00086       if((gapcnt>0)&&((dumcnt+fif2cnt)>5))//done with this fifo
00087         {gapcnt=0;fifcnt++;fif2cnt=0;dumcnt=0;}
00088       else if((gapcnt>0)&&((dumcnt+fif2cnt)<6)) gapcnt=0;
00089 
00090     }//end of fifo-3 word loop-see what we got!
00091 
00092   int status=0;
00093 
00094   if(gap[1]>0) {totword=(gap[1]&0xff);status=1;}
00095   else if(gap[2]>0){totword=(gap[2]&0xff);status=1;}
00096   else if(dum[1]>0){totword=(dum[1]&0xff);status=1;}
00097   else if(dum[2]>0){totword=(dum[2]&0xff);status=1;}
00098 
00099   if(gap[3]>0) {totword=totword|((gap[3]&0xff)<<8);status=status|0x2;}
00100   else if(gap[4]>0){totword=totword|((gap[4]&0xff)<<8);status=status|0x2;}
00101   else if(dum[3]>0){totword=totword|((dum[3]&0xff)<<8);status=status|0x2;}
00102   else if(dum[4]>0){totword=totword|((dum[4]&0xff)<<8);status=status|0x2;}
00103 
00104   if(gap[5]>0) {totword=totword|((gap[5]&0xff)<<16);status=status|0x4;}
00105   else if(gap[6]>0){totword=totword|((gap[6]&0xff)<<16);status=status|0x4;}
00106   else if(dum[5]>0){totword=totword|((dum[5]&0xff)<<16);status=status|0x4;}
00107   else if(dum[6]>0){totword=totword|((dum[6]&0xff)<<16);status=status|0x4;}
00108 
00109   if(gap[7]>0){totword=totword|((gap[7]&0xff)<<24);status=status|0x8;}
00110   else if(gap[8]>0){totword=totword|((gap[8]&0xff)<<24);status=status|0x8;}
00111   else if(dum[7]>0){totword=totword|((dum[7]&0xff)<<24);status=status|0x8;}
00112   else if(dum[8]>0){totword=totword|((dum[8]&0xff)<<24);status=status|0x8;}
00113   return(status);
00114 
00115 }
00116 
00117 // constructor
00118 PixelSLinkDataInputSource::PixelSLinkDataInputSource(const edm::ParameterSet& pset, 
00119                                                      const edm::InputSourceDescription& desc) :
00120   ProducerSourceFromFiles(pset,desc,true),
00121   m_fedid(pset.getUntrackedParameter<int>("fedid")),
00122   m_fileindex(0),
00123   m_runnumber(pset.getUntrackedParameter<int>("runNumber",-1)),
00124   m_currenteventnumber(0),
00125   m_currenttriggernumber(0),
00126   m_eventnumber_shift(0)
00127 {
00128   produces<FEDRawDataCollection>();
00129 
00130   if (m_fileindex>=fileNames().size()) {
00131     edm::LogInfo("") << "no more file to read " << std::endl;
00132     return;// ???
00133   }
00134   std::string currentfilename = fileNames()[m_fileindex];
00135   edm::LogInfo("") << "now examining file "<< currentfilename ;
00136   m_fileindex++;
00137   // reading both castor and other ('normal'/dcap) files.
00138   IOOffset size = -1;
00139   StorageFactory::get()->enableAccounting(true);
00140     
00141   edm::LogInfo("PixelSLinkDataInputSource") << " unsigned long int size = " << sizeof(unsigned long int) <<"\n unsigned long size = " << sizeof(unsigned long)<<"\n unsigned long long size = " << sizeof(unsigned long long) <<  "\n uint32_t size = " << sizeof(uint32_t) << "\n uint64_t size = " << sizeof(uint64_t) << std::endl;
00142 
00143   bool exists = StorageFactory::get() -> check(currentfilename.c_str(), &size);
00144   
00145   edm::LogInfo("PixelSLinkDataInputSource") << "file size " << size << std::endl;
00146   
00147   if(!exists){
00148     edm::LogInfo("") << "file " << currentfilename << " cannot be found.";
00149     return;
00150   }
00151   // now open the file stream:
00152   storage.reset(StorageFactory::get()->open(currentfilename.c_str()));
00153   // (throw if storage is 0)
00154 
00155   // check run number by opening up data file...
00156   
00157   Storage & temp_file = *storage;
00158   //  IOSize n =
00159   temp_file.read((char*)&m_data,8);
00160   if((m_data >> 60) != 0x5){ 
00161     uint32_t runnum = m_data;
00162     if(m_runnumber!=-1)
00163       edm::LogInfo("") << "WARNING: observed run number encoded in S-Link dump. Overwriting run number as defined in .cfg file!!! Run number now set to " << runnum << " (was " << m_runnumber << ")";
00164     m_runnumber=runnum;
00165   } 
00166   temp_file.read((char*)&m_data,8);
00167   m_currenteventnumber = (m_data >> 32)&0x00ffffff ;
00168 }
00169     
00170 // destructor
00171 PixelSLinkDataInputSource::~PixelSLinkDataInputSource() {
00172 
00173 
00174 }
00175 
00176 bool PixelSLinkDataInputSource::setRunAndEventInfo(edm::EventID& id, edm::TimeValue_t& time) {
00177   Storage & m_file = *storage;
00178 
00179   // create product (raw data)
00180   buffers.reset( new FEDRawDataCollection );
00181     
00182   //  uint32_t currenteventnumber = (m_data >> 32)&0x00ffffff;
00183   uint32_t eventnumber =(m_data >> 32)&0x00ffffff ;
00184   
00185   do{
00186     std::vector<uint64_t> buffer;
00187   
00188  
00189   
00190     uint16_t count=0;
00191     eventnumber = (m_data >> 32)&0x00ffffff ;
00192     if(m_currenteventnumber==0)
00193       m_currenteventnumber=eventnumber;
00194     edm::LogInfo("PixelSLinkDataInputSource::produce()") << "**** event number = " << eventnumber << " global event number " << m_currenteventnumber << " data " << std::hex << m_data << std::dec << std::endl;
00195     while ((m_data >> 60) != 0x5){
00196       //  std::cout << std::hex << m_data << std::dec << std::endl;
00197       if (count==0){
00198         edm::LogWarning("") << "DATA CORRUPTION!" ;
00199         edm::LogWarning("") << "Expected to find header, but read: 0x"
00200                             << std::hex<<m_data<<std::dec ;
00201       }
00202    
00203       count++;
00204       int n=m_file.read((char*)&m_data,8);
00205       edm::LogWarning("") << "next data " << std::hex << m_data << std::dec << std::endl;
00206     
00207       if (n!=8) {
00208         edm::LogInfo("") << "End of input file" ;
00209         return false;
00210       }
00211     }
00212  
00213 
00214     if (count>0) {
00215       edm::LogWarning("")<<"Had to read "<<count<<" words before finding header!"<<std::endl;
00216     }
00217 
00218     if (m_fedid>-1) {
00219       m_data=(m_data&0xfffffffffff000ffLL)|((m_fedid&0xfff)<<8);
00220     }
00221 
00222     uint16_t fed_id=(m_data>>8)&0xfff;
00223     //   std::cout << "fed id = " << fed_id << std::endl;
00224     buffer.push_back(m_data);
00225   
00226     do{
00227       m_file.read((char*)&m_data,8);
00228       buffer.push_back(m_data);
00229     }
00230     while((m_data >> 60) != 0xa);
00231     //  std::cout << "read " <<  buffer.size() << " long words" << std::endl;
00232 
00233     std::auto_ptr<FEDRawData> rawData(new FEDRawData(8*buffer.size()));
00234     //  FEDRawData * rawData = new FEDRawData(8*buffer.size());
00235     unsigned char* dataptr=rawData->data();
00236 
00237     for (uint16_t i=0;i<buffer.size();i++){
00238       ((uint64_t *)dataptr)[i]=buffer[i];
00239     }
00240     uint32_t thetriggernumber=0;
00241     int nfillwords = 0;//getEventNumberFromFillWords(buffer,thetriggernumber);
00242 
00243     if(nfillwords>0){
00244       LogInfo("") << "n fill words = " << nfillwords <<  ", trigger numbers: " << thetriggernumber << "," << m_currenttriggernumber << std::endl;
00245       m_eventnumber_shift = thetriggernumber - m_currenttriggernumber;
00246     }
00247     m_currenttriggernumber = thetriggernumber;
00248     FEDRawData& fedRawData = buffers->FEDData( fed_id );
00249     fedRawData=*rawData;
00250     
00251     // read the first data member of the next blob to check on event number
00252     int n =m_file.read((char*)&m_data,8);
00253     if (n==0) {
00254       edm::LogInfo("") << "End of input file" ;
00255     }
00256     m_currenteventnumber = (m_data >> 32)&0x00ffffff ;
00257     if(m_currenteventnumber<eventnumber)
00258       LogError("PixelSLinkDataInputSource") << " error, the previous event number (" << eventnumber << ") is LARGER than the next event number (" << m_currenteventnumber << ")" << std::endl;
00259 
00260   }
00261   while( eventnumber == m_currenteventnumber);
00262   
00263   uint32_t realeventno = synchronizeEvents();
00264   if(m_runnumber!=0)
00265     id = edm::EventID(m_runnumber, id.luminosityBlock(), realeventno);
00266   else
00267     id = edm::EventID(id.run(), id.luminosityBlock(), realeventno);
00268   return true;
00269 }
00270 
00271 // produce() method. This is the worker method that is called every event.
00272 void PixelSLinkDataInputSource::produce(edm::Event& event) {
00273   event.put(buffers);
00274   buffers.reset();  
00275 }
00276 
00277 // this function sets the m_globaleventnumber quantity. It uses the m_currenteventnumber and m_currenttriggernumber values as input
00278 uint32_t PixelSLinkDataInputSource::synchronizeEvents(){
00279   int32_t result= m_currenteventnumber -1;
00280       
00281   return(uint32_t) result;
00282 }