GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TRlmdFile.cxx
Go to the documentation of this file.
1#include <iostream>
2#include <bitset>
3#include <fstream>
4#include <sstream>
5#include <cstdio>
6#include <cstring>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <fcntl.h>
10#include <cerrno>
11#include <cassert>
12#include <cstdlib>
13#include <locale>
14#include <time.h>
15
16#ifdef HAVE_ZLIB
17#include <zlib.h>
18#endif
19
20#include "TString.h"
21
22#include "TRlmdFile.h"
23#include "TRlmdEvent.h"
24#include "TRunInfo.h"
26#include "THILMnemonic.h"
27#include "HILDataVersion.h"
28
29/// \cond CLASSIMP
31/// \endcond
32
34{
35 // Default Constructor
36 fBytesRead = 0;
37 fFileSize = 0;
38}
39
40TRlmdFile::TRlmdFile(const char* filename, TRawFile::EOpenType open_type) : TRlmdFile()
41{
42 switch(open_type) {
43 case TRawFile::EOpenType::kRead: Open(filename); break;
45 }
46}
47
49{
50 // Default dtor. It closes the read in lmd file as well as the output lmd file.
51 Close();
52}
53
54std::string TRlmdFile::Status(bool)
55{
56 return Form(HIDE_CURSOR " Processed event, have processed %.2fMB/%.2f MB " SHOW_CURSOR "\r",
57 (fInputStream.tellg() / 1000000.0), (fFileSize / 1000000.0));
58}
59
60/// Open a lmd .lmd file with given file name.
61///
62/// Remote files can be accessed using these special file names:
63/// - pipein://command - read data produced by given command, see examples below
64/// - ssh://username\@hostname/path/file.mid - read remote file through an ssh pipe
65/// - ssh://username\@hostname/path/file.mid.gz and file.mid.bz2 - same for compressed files
66/// - dccp://path/file.mid (also file.mid.gz and file.mid.bz2) - read data from dcache, requires dccp in the PATH
67///
68/// Examples:
69/// - ./event_dump.exe /ladd/data9/t2km11/data/run02696.mid.gz - read normal compressed file
70/// - ./event_dump.exe ssh://ladd09//ladd/data9/t2km11/data/run02696.mid.gz - read compressed file through ssh to ladd09
71/// (note double "/")
72/// - ./event_dump.exe pipein://"cat /ladd/data9/t2km11/data/run02696.mid.gz | gzip -dc" - read data piped from a
73/// command or script (note quotes)
74/// - ./event_dump.exe pipein://"gzip -dc /ladd/data9/t2km11/data/run02696.mid.gz" - another way to read compressed
75/// files
76/// - ./event_dump.exe dccp:///pnfs/triumf.ca/data/t2km11/aug2008/run02837.mid.gz - read file directly from a dcache
77/// pool (note triple "/")
78///
79/// \param[in] filename The file to open.
80/// \returns "true" for succes, "false" for error, use GetLastError() to see why
81bool TRlmdFile::Open(const char* filename)
82{
83 fFilename = filename;
84
85 try {
86 fInputStream.open(GetFilename(), std::ifstream::in | std::ifstream::binary);
87 fInputStream.seekg(0, std::ifstream::end);
88 if(fInputStream.tellg() < 0) {
89 std::cout<<R"(Failed to open ")"<<GetFilename()<<"/"<<fFilename<<R"("!)"<<std::endl;
90 return false;
91 }
92 fFileSize = fInputStream.tellg();
93 fInputStream.seekg(0, std::ifstream::beg);
94 //std::ofstream debugFile("debug.txt", std::ios::app);
95 //debugFile<<"Total file size is "<<fFileSize<<" bytes"<<std::endl;
96
97 // Read Header Information
98 RlmdFileHeader header;
99 fInputStream.read(reinterpret_cast<char *>(&header), sizeof(RlmdFileHeader));
100
101 //debugFile<<"read header of size "<<sizeof(RlmdFileHeader)<<" bytes"<<std::endl;
102 fStartDate = header.date;
103 fStartDate = fStartDate.substr(0, 12);
104 fStartTime = header.time;
105 fStartTime = fStartTime.substr(0, 8);
106 fTemplate = header.templateName;
107 fTemplate = fTemplate.substr(0, 1480);
108 } catch(std::exception& e) {
109 std::cout<<"Caught "<<e.what()<<" at "<<__FILE__<<" : "<<__LINE__<<std::endl;
110 }
111
112 // setup TChannel to use our mnemonics
113 TChannel::SetMnemonicClass(THILMnemonic::Class());
114
118 TRunInfo::SetVersion(HILDATA_RELEASE);
119
120 fBytesRead = fInputStream.tellg();
121 std::cout<<"Successfully read "<<fBytesRead<<" bytes of header with start date "<<fStartDate<<" "<<fStartTime<<" and template "<<fTemplate<<"!"<<std::endl;
122
125
126 return true;
127}
128
130{
131 fInputStream.close();
132 fBytesRead = fFileSize; // just to make sure we don't try to read more data after the file was closed
133}
134
135/// \param [in] Event Pointer to an empty TRlmdEvent
136/// \returns "true" for success, "false" for failure, see GetLastError() to see why
137///
138/// EDITED FROM THE ORIGINAL TO RETURN TOTAL SUCESSFULLY BYTES READ INSTEAD OF TRUE/FALSE, PCB
139///
140int TRlmdFile::Read(std::shared_ptr<TRawEvent> Event)
141{
142 if(Event == nullptr) return -1;
143
144 size_t LastReadSize = 0;
145 std::shared_ptr<TRlmdEvent> RlmdEvent = std::static_pointer_cast<TRlmdEvent>(Event);
146 RlmdEvent->Clear();
147
148 if(fBytesRead < fFileSize) {
149 //std::ofstream debugFile("debug.txt", std::ios::app);
150 //debugFile<<std::hex;
151 //debugFile<<"buffer 0x"<<fBuffersRead<<": starting to read at 0x"<<fInputStream.tellg()<<std::endl;
152 // Read the buffer header
153 fInputStream.read(reinterpret_cast<char*>(&fBufferHeader), sizeof(RlmdBufferHeader));
154 LastReadSize += static_cast<size_t>(fInputStream.gcount());
155
156 switch(fBufferHeader.type) {
157 case 2: // normal event so we read the buffer data into the event and send it on
158 //debugFile<<"read buffer header of size 0x"<<sizeof(RlmdBufferHeader)<<", reading buffer of size 0x"<<2*fBufferHeader.dataLength<<" starting at 0x"<<fInputStream.tellg()<<std::endl;
159 try {
160 // the data length never changes, so this should only resize the vector once
161 fReadBuffer.resize(2*fBufferHeader.dataLength); // 2* accounts for the size of uint16_t
163 LastReadSize += static_cast<size_t>(fInputStream.gcount());
164 fBytesRead += LastReadSize;
165 //std::cout<<"Read normal buffer with "<<2*fBufferHeader.dataLength<<"/"<<LastReadSize<<" bytes, now at byte "<<fBytesRead<<std::endl;
166 RlmdEvent->SetData(fReadBuffer);
167 ++fBuffersRead;
168 } catch(std::exception& e) {
169 std::cout<<"Caught "<<e.what()<<" at "<<__FILE__<<" : "<<__LINE__<<std::endl;
170 return -1;
171 }
172 break;
173 case 3: // file footer so we "unread" the buffer header, read the footer and then close the file
174 fInputStream.seekg(-sizeof(RlmdBufferHeader), std::ifstream::cur);
175 RlmdFileFooter footer;
176 //debugFile<<"tail buffer 0x"<<fBuffersRead<<": starting to read at 0x"<<fInputStream.tellg()<<std::endl;
177 fInputStream.read(reinterpret_cast<char *>(&footer), sizeof(RlmdFileFooter));
178 fStopDate = footer.date;
179 fStopDate = fStopDate.substr(0,12);
180 fStopTime = footer.time;
181 fStopTime = fStopTime.substr(0,8);
185 Close();
186 LastReadSize = 0; // setting this to zero as it doesn't matter in this case?
187 break;
188 default:
189 std::cerr<<"Unknown buffer type "<<fBufferHeader.type<<std::endl;
190 break;
191 }
192 }
193 return LastReadSize;
194}
195
196void TRlmdFile::Skip(size_t)
197{
198 // this might be wrong, in the case of the rlmd file we could check the data length from the buffer header, skip that far ahead
199 // and read the next buffer header
200 std::cerr<<"Sorry, but we can't skip events in an RLMD file, the whole file is treated as a single event!"<<std::endl;
201 return;
202}
203
205{
206 // Parse the run number from the current TRlmdFile. This assumes a format of
207 // <name>###.rlmd.
208 if(fFilename.length() == 0) {
209 return 0;
210 }
211 std::size_t found = fFilename.rfind(".rlmd");
212 if(found == std::string::npos) {
213 return 0;
214 }
215 std::string temp;
216 temp = fFilename.substr(found - 3, 3);
217 return atoi(temp.c_str());
218}
219
221{
222 // There are no subruns in .lmd files
223 return -1;
224}
225
226time_t TRlmdFile::ConvertToEpoch(const std::string& date, const std::string& time)
227{
228 std::stringstream str;
229 str<<date<<time;
230 std::tm t = {};
231 str>>std::get_time(&t, "%d-%b-%Y %H:%M:S");
232 return std::mktime(&t);
233}
234
235// end
#define SHOW_CURSOR
Definition Globals.h:33
#define HIDE_CURSOR
Definition Globals.h:32
ClassImp(THILMnemonic) void THILMnemonic
static void SetMnemonicClass(const TClassRef &cls)
Definition TChannel.h:80
size_t fFileSize
Definition TRawFile.h:88
virtual const char * GetFilename() const
Get the name of this file.
Definition TRawFile.h:56
size_t fBytesRead
Definition TRawFile.h:87
std::vector< char > fReadBuffer
Definition TRawFile.h:85
std::string fFilename
name of the currently open file
Definition TRawFile.h:83
RlmdBufferHeader fBufferHeader
Definition TRlmdFile.h:127
std::ifstream fInputStream
Definition TRlmdFile.h:125
int GetSubRunNumber() override
void Close() override
Close input file.
int Read(std::shared_ptr< TRawEvent > rlmdEvent) override
Read one event from the file.
TRlmdFile()
default constructor
Definition TRlmdFile.cxx:33
std::string fTemplate
Definition TRlmdFile.h:124
~TRlmdFile() override
destructor
Definition TRlmdFile.cxx:48
std::string fStopDate
Definition TRlmdFile.h:122
std::string Status(bool long_file_description=true) override
Definition TRlmdFile.cxx:54
std::string fStartDate
Definition TRlmdFile.h:120
std::string fStartTime
Definition TRlmdFile.h:121
time_t ConvertToEpoch(const std::string &date, const std::string &time)
std::string fStopTime
Definition TRlmdFile.h:123
int GetRunNumber() override
size_t fBuffersRead
Definition TRlmdFile.h:128
void Skip(size_t nofEvents) override
Skip nofEvents from the file.
bool Open(const char *filename) override
Open input file.
Definition TRlmdFile.cxx:81
static void ClearVersion()
Definition TRunInfo.h:136
static void SetRunStart(double tmp)
Definition TRunInfo.h:222
static void SetRunStop(double tmp)
Definition TRunInfo.h:223
static void SetRunInfo(int runnum=0, int subrunnum=-1)
Definition TRunInfo.cxx:135
static void SetVersion(const char *ver)
Definition TRunInfo.h:137
static void SetDetectorInformation(TDetectorInformation *inf)
Definition TRunInfo.h:271
static void SetRunLength()
Definition TRunInfo.h:225
uint16_t dataLength
Definition TRlmdFile.h:82
uint16_t type
Definition TRlmdFile.h:84
char time[8]
Definition TRlmdFile.h:51
char templateName[TEMPLEN]
Definition TRlmdFile.h:67
char date[12]
Definition TRlmdFile.h:50