CMS 3D CMS Logo

FileReaderDCC.cc

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

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