CMS 3D CMS Logo

FileReaderDDU.cc

Go to the documentation of this file.
00001 #include "FileReaderDDU.h"
00002 #include <iostream>    // cerr
00003 #include <errno.h>     // errno
00004 #include <string.h>    // bzero, memcpy
00005 #include <stdlib.h>    // exit
00006 #include <sys/types.h> // open
00007 #include <sys/stat.h>  // open
00008 #include <fcntl.h>     // open
00009 #include <unistd.h>    // read, close
00010 
00011 FileReaderDDU::FileReaderDDU(void){
00012         if( sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2 )
00013                 throw std::runtime_error(std::string("Wrong platform: sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2"));
00014         end = (file_buffer_end = file_buffer + sizeof(file_buffer)/sizeof(unsigned long long));
00015         bzero(raw_event,  sizeof(raw_event)  );
00016         bzero(file_buffer,sizeof(file_buffer));
00017         word_0=0; word_1=0; word_2=0;
00018         eventStatus = 0;
00019         selectCriteria = Header|Trailer;
00020         rejectCriteria = DDUoversize|FFFF|Unknown;
00021         acceptCriteria = 0x3F; // Everything
00022         fd = 0;
00023 }
00024 
00025 FileReaderDDU::~FileReaderDDU(void){ if( fd ) close(fd); }
00026 
00027 int FileReaderDDU::open(const char *filename) throw (std::runtime_error) {
00028         if( fd ) close(fd);
00029         fd = ::open(filename,O_RDONLY|O_LARGEFILE);
00030         if( fd == -1 ) throw ( std::runtime_error(std::string("Error opening ").append(filename).append(" data file.")) );
00031         return fd;
00032 }
00033 
00034 size_t FileReaderDDU::read(const unsigned short* &buf) throw (std::runtime_error) {
00035         // Check for ubnormal situation
00036         if( end>file_buffer_end || end<file_buffer ) throw ( std::runtime_error("Error of reading") );
00037         if( !fd ) throw ( std::runtime_error("Open some file first") );
00038 
00039         unsigned long long *start = end;
00040         unsigned short     *event = raw_event;
00041 
00042         eventStatus = 0;
00043         size_t dduWordCount = 0;
00044         end = 0;
00045 
00046         while( !end && dduWordCount<50000 ){
00047                 unsigned long long *dduWord = start;
00048                 unsigned long long preHeader = 0;
00049 
00050                 // Did we reach end of current buffer and want to read next block?
00051                 // If it was first time and we don't have file buffer then we won't get inside
00052                 while( dduWord<file_buffer_end && dduWordCount<50000 ){
00053                         word_0 =  word_1; // delay by 2 DDU words
00054                         word_1 =  word_2; // delay by 1 DDU word
00055                         word_2 = *dduWord;// current DDU word
00056                         if( (word_2&0xFFFFFFFFFFFF0000LL)==0x8000000180000000LL ){
00057                                 if( eventStatus&Header ){ // Second header
00058                                         word_2 = word_1; // Fall back to get rigth preHeader next time
00059                                         end = dduWord;   // Even if we end with preHeader of next evet put it to the end of this event too
00060                                         break;
00061                                 }
00062                                 if( dduWordCount>1 ){ // Extra words between trailer and header
00063                                         if( (word_0&0xFFFFFFFFFFFF0000LL)==0xFFFFFFFFFFFF0000LL ) eventStatus |= FFFF;
00064                                         word_2 = word_1; // Fall back to get rigth preHeader next time
00065                                         end = dduWord;
00066                                         break;
00067                                 }
00068                                 eventStatus |= Header;
00069                                 if( event==raw_event ) preHeader = word_1; // If preHeader not yet in event then put it there
00070                                 start = dduWord;
00071                         }
00072                         if( (word_0&0xFFFFFFFFFFFF0000LL)==0x8000FFFF80000000LL ){
00073                                 eventStatus |= Trailer;
00074                                 end = ++dduWord;
00075                                 break;
00076                         }
00077                         // Increase counters by one DDU word
00078                         dduWord++;
00079                         dduWordCount++;
00080                 }
00081 
00082                 // If have DDU Header
00083                 if( preHeader ){
00084                         // Need to account first word of DDU Header
00085                         memcpy(event,&preHeader,sizeof(preHeader));
00086                         event += sizeof(preHeader)/sizeof(unsigned short);
00087                 }
00088 
00089                 // Take care of the rest
00090                 memcpy(event,start,(dduWord-start)*sizeof(unsigned long long));
00091                 event += (dduWord-start)*sizeof(unsigned long long)/sizeof(unsigned short);
00092 
00093                 // If reach max length
00094                 if( dduWordCount==50000 ){ end = dduWord; break; }
00095 
00096                 if( !end ){
00097                         // Need to read next block for the rest of this event
00098                         ssize_t length = ::read(fd,file_buffer,sizeof(file_buffer));
00099                         if( length==-1 ) throw ( std::runtime_error("Error of reading") );
00100                         if( length== 0 ){
00101                                 eventStatus |= EndOfStream;
00102                                 end = (file_buffer_end = file_buffer + sizeof(file_buffer)/sizeof(unsigned long long));
00103                                 break;
00104                         }
00105                         file_buffer_end = file_buffer + length/sizeof(unsigned long long);
00106 
00107                         // Will start from the beginning of new buffer next time we read it
00108                         start = file_buffer;
00109                 }
00110         }
00111 
00112         if( !end ) eventStatus |= DDUoversize;
00113         if( !(eventStatus&Header) && !(eventStatus&Trailer) && !(eventStatus&FFFF) ) eventStatus |= Unknown;
00114 
00115         buf = (const unsigned short*)raw_event;
00116         return (eventStatus&FFFF?event-raw_event-4:event-raw_event);
00117 }
00118 
00119 size_t FileReaderDDU::next(const unsigned short* &buf) throw(std::runtime_error) {
00120         size_t size=0;
00121         do {
00122                 if( (size = read(buf)) == 0 ) break;
00123         } while( rejectCriteria&eventStatus || !(acceptCriteria&eventStatus) || (selectCriteria?selectCriteria!=eventStatus:0) );
00124         return size;
00125 }

Generated on Tue Jun 9 17:39:23 2009 for CMSSW by  doxygen 1.5.4