00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "FileReadoutFormat/DaqToOStream.h"
00010
00011 #include "EventReadoutFormat/EventHeader.h"
00012 #include "EventReadoutFormat/EventReadout.h"
00013 #include "FileReadoutFormat/CalibrationParametersRecord.h"
00014 #include "FileReadoutFormat/DataSeparatorRecord.h"
00015 #include "FileReadoutFormat/FileBuffer.h"
00016 #include "FileReadoutFormat/FileEndRecord.h"
00017 #include "FileReadoutFormat/FileNameStrings.h"
00018 #include "FileReadoutFormat/FileStartRecord.h"
00019 #include "FileReadoutFormat/FileTraits.h"
00020 #include "FileReadoutFormat/MetadataStrings.h"
00021 #include "FileReadoutFormat/RunParametersRecord.h"
00022
00023 using DybDaq::CalibrationParametersRecord;
00024 using DybDaq::DataSeparatorRecord;
00025 using DybDaq::EventReadout;
00026 using DybDaq::FileEndRecord;
00027 using DybDaq::FileNameStrings;
00028 using DybDaq::DaqToOStream;
00029 using DybDaq::FileStartRecord;
00030 using DybDaq::FileTraits;
00031 using DybDaq::MetadataStrings;
00032 using DybDaq::RunParametersRecord;
00033 using std::string;
00034
00035 static const unsigned int kBytesInMegabyte = 1024U * 1024U;
00036
00037 DaqToOStream::DaqToOStream(const FileTraits& traits) :
00038 m_traits(&traits),
00039 m_ostream(0),
00040 m_buffers(new DaqBuffer::OutputBufferList()),
00041 m_fileBase(0),
00042 m_filePayloadLength(0),
00043 m_payloadLengthTotal(0),
00044 m_lastRecord(FileTraits::kFileEndRecord),
00045 m_dataBlockLimit(0),
00046 m_megabyteLimit(0),
00047 m_fileCount(0),
00048 m_sequenceBlockCount(0),
00049 m_fileBlockCount(0),
00050 m_blockCountTotal(0) {
00051 }
00052
00053 DaqToOStream::~DaqToOStream() {
00054 if (0 != m_fileBase) {
00055 delete m_fileBase;
00056 }
00057 if (0 != m_buffers) {
00058 delete m_buffers;
00059 }
00060 if (0 != m_ostream) {
00061 delete m_ostream;
00062 }
00063 }
00064
00065 const string& DaqToOStream::getFileBase() const {
00066 return *m_fileBase;
00067 }
00068
00069 unsigned int DaqToOStream::getFileBlockCount() const {
00070 return m_fileBlockCount;
00071 }
00072
00073 unsigned int DaqToOStream::getFileCount() const {
00074 return m_fileCount;
00075 }
00076
00077 unsigned int DaqToOStream::getLastRecord() const {
00078 return m_lastRecord;
00079 }
00080
00081 bool DaqToOStream::hasFileBase() const {
00082 return 0 != m_fileBase;
00083 }
00084
00085 bool DaqToOStream::hasOStream() const {
00086 return 0 != m_ostream;
00087 }
00088
00089 void DaqToOStream::splitStream() {
00090 if (0 == m_ostream) {
00091 return;
00092 }
00093 closeStream(*m_ostream);
00094 delete m_ostream;
00095 m_ostream = openStream();
00096 }
00097
00098 bool DaqToOStream::open(const FileStartRecord& record) {
00099 if (hasOStream()) {
00100 return false;
00101 }
00102 if (FileTraits::kFileEndRecord != getLastRecord()) {
00103 return false;
00104 }
00105 m_ostream = openStream();
00106 m_dataBlockLimit = record.dataBlockLimit(),
00107 m_megabyteLimit = record.megabyteLimit();
00108 m_filePayloadLength = 0;
00109 m_fileBlockCount = 0;
00110
00111 saveBuffer(record);
00112 m_lastRecord = FileTraits::kFileStartRecord;
00113 return true;
00114 }
00115
00116 const FileStartRecord* DaqToOStream::openElement(const unsigned int fileCount,
00117 const FileTraits::FileDateTime& dateTime,
00118 const unsigned int dataBlockLimit,
00119 const unsigned int megabyteLimit) {
00120 m_fileCount = fileCount - 1;
00121 m_dataBlockLimit = dataBlockLimit,
00122 m_megabyteLimit = megabyteLimit;
00123 return openNext(dateTime);
00124 }
00125
00126 const FileStartRecord* DaqToOStream::openNext(const FileTraits::FileDateTime& dateTime) {
00127 if (hasOStream()) {
00128 return 0;
00129 }
00130 prepareNext();
00131 FileStartRecord* record = new FileStartRecord(++m_fileCount,
00132 dateTime,
00133 m_dataBlockLimit,
00134 m_megabyteLimit,
00135 *m_traits);
00136 if (open(*record)) {
00137 return record;
00138 }
00139 delete record;
00140 return 0;
00141 }
00142
00143 bool DaqToOStream::openSequence(const std::string& fileBase,
00144 const FileStartRecord& record) {
00145 setFileBase(fileBase);
00146 m_dataBlockLimit = record.dataBlockLimit(),
00147 m_megabyteLimit = record.megabyteLimit();
00148 return open(record);
00149 }
00150
00151 const FileStartRecord* DaqToOStream::openSequence(const std::string& fileBase,
00152 const FileTraits::FileDateTime& dateTime,
00153 const unsigned int dataBlockLimit,
00154 const unsigned int megabyteLimit) {
00155 setFileBase(fileBase);
00156 m_dataBlockLimit = dataBlockLimit,
00157 m_megabyteLimit = megabyteLimit;
00158 return openNext(dateTime);
00159 }
00160
00161 void DaqToOStream::saveBuffer(const FileBuffer& daqBuffer) {
00162 daqBuffer.gather(*m_buffers);
00163 DaqBuffer::OutputBufferList::const_iterator buffer;
00164 for (buffer = m_buffers->begin();
00165 buffer != m_buffers->end();
00166 ++buffer) {
00167 m_ostream->write((*buffer).first, (*buffer).second);
00168 }
00169 m_buffers->clear();
00170 }
00171
00172 void DaqToOStream::setFileBase(const std::string& fileBase) {
00173 if (0 != m_fileBase) {
00174 delete m_fileBase;
00175 }
00176 m_fileBase = new string(fileBase);
00177 }
00178
00179 bool DaqToOStream::saveFileNameStrings(const FileNameStrings& record) {
00180 if (FileTraits::kFileStartRecord != m_lastRecord) {
00181 return false;
00182 }
00183 saveBuffer(record);
00184 m_lastRecord = FileTraits::kFileNameStrings;
00185 return true;
00186 }
00187
00188 const FileNameStrings* DaqToOStream::saveFileNameStrings(const string& application,
00189 const string& fileBase) {
00190 string fileBaseToUse;
00191 if (0 == m_fileBase) {
00192 fileBaseToUse = fileBase;
00193 } else {
00194 fileBaseToUse = *m_fileBase;
00195 }
00196 FileNameStrings* record = new FileNameStrings(application,
00197 fileBaseToUse,
00198 *m_traits);
00199 if (saveFileNameStrings(*record)) {
00200 return record;
00201 }
00202 delete record;
00203 return 0;
00204 }
00205
00206 bool DaqToOStream::saveMetadataStrings(const MetadataStrings& record) {
00207 if (FileTraits::kFileNameStrings != m_lastRecord) {
00208 return false;
00209 }
00210 saveBuffer(record);
00211 m_lastRecord = FileTraits::kMetadataStrings;
00212 return true;
00213 }
00214
00215 const MetadataStrings* DaqToOStream::saveMetadataStrings(const MetadataStrings::MetadataStringPtrList& metadataStrings) {
00216 MetadataStrings* record = new MetadataStrings(metadataStrings,
00217 *m_traits);
00218 if (saveMetadataStrings(*record)) {
00219 return record;
00220 }
00221 delete record;
00222 return 0;
00223 }
00224
00225 bool DaqToOStream::saveRunParametersRecord(const RunParametersRecord& record) {
00226 if (FileTraits::kFileNameStrings != m_lastRecord
00227 && FileTraits::kMetadataStrings != m_lastRecord) {
00228 return false;
00229 }
00230 saveBuffer(record);
00231 m_lastRecord = FileTraits::kRunParametersRecord;
00232 return true;
00233 }
00234
00235 const RunParametersRecord* DaqToOStream::saveRunParametersRecord(const unsigned int runNumber,
00236 const bool recordEnabled,
00237 const unsigned int triggerType,
00238 const unsigned int detectorMask) {
00239 RunParametersRecord* record = new RunParametersRecord(runNumber,
00240 recordEnabled,
00241 triggerType,
00242 detectorMask,
00243 *m_traits);
00244 if (saveRunParametersRecord(*record)) {
00245 return record;
00246 }
00247 delete record;
00248 return 0;
00249 }
00250
00251 bool DaqToOStream::saveCalibrationParametersRecord(const CalibrationParametersRecord& record) {
00252 if (FileTraits::kRunParametersRecord != m_lastRecord) {
00253 return false;
00254 }
00255 saveBuffer(record);
00256 m_lastRecord = FileTraits::kCalibrationParametersRecord;
00257 return true;
00258 }
00259
00260 const CalibrationParametersRecord* DaqToOStream::saveCalibrationParametersRecord(const unsigned int detector,
00261 const unsigned int adNumber,
00262 const unsigned int sourceA,
00263 const unsigned int zPositionA,
00264 const unsigned int sourceB,
00265 const unsigned int zPositionB,
00266 const unsigned int sourceC,
00267 const unsigned int zPositionC,
00268 const unsigned int led1,
00269 const unsigned int led2,
00270 const unsigned int led1Voltage,
00271 const unsigned int led2Voltage,
00272 const unsigned int duration,
00273 const unsigned int ledFrequency,
00274 const unsigned int ledPulseSeparation,
00275 const unsigned int ltbMode,
00276 const unsigned int motorPower,
00277 const unsigned int cameraPower,
00278 const unsigned int ledFlashing) {
00279 CalibrationParametersRecord* record = new CalibrationParametersRecord(detector,
00280 adNumber,
00281 sourceA,
00282 zPositionA,
00283 sourceB,
00284 zPositionB,
00285 sourceC,
00286 zPositionC,
00287 led1,
00288 led2,
00289 led1Voltage,
00290 led2Voltage,
00291 duration,
00292 ledFrequency,
00293 ledPulseSeparation,
00294 ltbMode,
00295 motorPower,
00296 cameraPower,
00297 ledFlashing,
00298 *m_traits);
00299 if (saveCalibrationParametersRecord(*record)) {
00300 return record;
00301 }
00302 delete record;
00303 return 0;
00304 }
00305
00306 bool DaqToOStream::saveDataSeparatorRecord(const DataSeparatorRecord& record) {
00307 if (FileTraits::FileTraits::kRunParametersRecord != m_lastRecord
00308 && FileTraits::kCalibrationParametersRecord != m_lastRecord
00309 && FileTraits::kDataSeparatorRecord != m_lastRecord) {
00310 return false;
00311 }
00312 saveBuffer(record);
00313 m_lastRecord = FileTraits::kDataSeparatorRecord;
00314 return true;
00315 }
00316
00317 void DaqToOStream::eventSaved(unsigned int bytesSaved) {
00318 ++m_fileBlockCount;
00319 ++m_sequenceBlockCount;
00320 m_filePayloadLength += bytesSaved;
00321 }
00322
00323 const DataSeparatorRecord* DaqToOStream::saveEvent(const EventReadout& event) {
00324 const unsigned int bytesSaved = event.header().totalSize() * DaqBuffer::kBytesInInt;
00325 eventSaved(bytesSaved);
00326 const DataSeparatorRecord* record = new DataSeparatorRecord(event,
00327 m_sequenceBlockCount,
00328 *m_traits);
00329 if (saveDataSeparatorRecord(*record)) {
00330 return record;
00331 }
00332 m_filePayloadLength -= bytesSaved;
00333 --m_sequenceBlockCount;
00334 --m_fileBlockCount;
00335 delete record;
00336 return 0;
00337 }
00338
00339 bool DaqToOStream::close(const FileEndRecord& record) {
00340 if (FileTraits::FileTraits::kRunParametersRecord != m_lastRecord
00341 && FileTraits::kCalibrationParametersRecord != m_lastRecord
00342 && FileTraits::kDataSeparatorRecord != m_lastRecord) {
00343 return false;
00344 }
00345 saveBuffer(record);
00346 if (0 != m_ostream) {
00347 closeStream(*m_ostream);
00348 delete m_ostream;
00349 m_ostream = 0;
00350 }
00351 m_lastRecord = FileTraits::kFileEndRecord;
00352 return true;
00353 }
00354
00355 const FileEndRecord* DaqToOStream::close(const FileTraits::FileDateTime& dateTime) {
00356 return close(dateTime,
00357 m_blockCountTotal,
00358 m_payloadLengthTotal,
00359 0x01);
00360 }
00361
00362 const FileEndRecord* DaqToOStream::close(const FileTraits::FileDateTime& dateTime,
00363 const unsigned int blockCountBeforeFile,
00364 const unsigned long payloadLengthBeforeFile,
00365 const unsigned int status) {
00366 unsigned int runBlockCount = blockCountBeforeFile + m_fileBlockCount;
00367 unsigned long payloadLengthTotal = payloadLengthBeforeFile + m_filePayloadLength;
00368 const FileEndRecord* record = new FileEndRecord(dateTime,
00369 m_fileBlockCount,
00370 (unsigned int)(m_filePayloadLength / kBytesInMegabyte),
00371 runBlockCount,
00372 (unsigned int)(payloadLengthTotal / kBytesInMegabyte),
00373 status,
00374 *m_traits);
00375 if (close(*record)) {
00376 m_blockCountTotal = runBlockCount;
00377 m_payloadLengthTotal = payloadLengthTotal;
00378 return record;
00379 }
00380 delete record;
00381 return 0;
00382 }