00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "DaqFormatModules/DaqFormatWriter.h"
00010
00011 #include <ctime>
00012
00013 #include "DaqReadoutSvc/IDaqReadoutSvc.h"
00014 #include "Event/ReadoutHeader.h"
00015 #include "EventReadoutFormat/EventHeader.h"
00016 #include "EventReadoutFormat/EventReadout.h"
00017 #include "FileReadoutFormat/DataSeparatorRecord.h"
00018 #include "FileReadoutFormat/FileBuffer.h"
00019 #include "FileReadoutFormat/FileEndRecord.h"
00020 #include "FileReadoutFormat/FileNameStrings.h"
00021 #include "FileReadoutFormat/DaqToOStream.h"
00022 #include "FileReadoutFormat/FileStartRecord.h"
00023 #include "FileReadoutFormat/FileTraits.h"
00024 #include "FileReadoutFormat/RunParametersRecord.h"
00025 #include "FileReadoutFormat/MetadataStrings.h"
00026
00027 using DayaBay::ReadoutHeader;
00028 using DybDaq::DataSeparatorRecord;
00029 using DybDaq::DaqFormatWriter;
00030 using DybDaq::EventHeader;
00031 using DybDaq::EventReadout;
00032 using DybDaq::FileBuffer;
00033 using DybDaq::FileEndRecord;
00034 using DybDaq::FileNameStrings;
00035 using DybDaq::DaqToOStream;
00036 using DybDaq::FileStartRecord;
00037 using DybDaq::FileTraits;
00038 using DybDaq::RunParametersRecord;
00039 using DybDaq::MetadataStrings;
00040
00041 static const unsigned int kBytesInInt = 4;
00042 static const unsigned int kBytesInMegabyte = 1024 * 1024;
00043
00044 using namespace DayaBay;
00045
00046 DaqFormatWriter::DaqFormatWriter(const std::string& name,
00047 ISvcLocator* svc) :
00048 DybAlgorithm<DayaBay::ReadoutHeader>(name,
00049 svc),
00050 m_traits(0),
00051 m_daqSvc(0),
00052 m_daqToOStream(0),
00053 m_fileByteCount(0),
00054 m_fileByteLimit(0),
00055 m_fileBlockCount(0),
00056 m_fileBlockLimit(0) {
00057 declareProperty("OutputBase",
00058 m_outputBase,
00059 "The base from which to construct the output file names");
00060 }
00061
00062 DaqFormatWriter::~DaqFormatWriter() {
00063 if (0 != m_daqToOStream) {
00064 delete m_daqToOStream;
00065 }
00066 }
00067
00068 StatusCode DaqFormatWriter::initialize() {
00069 m_traits = &(FileTraits::defaultTraits());
00070 StatusCode status = service("DaqReadoutSvc",
00071 "DaqReadoutSvc",
00072 m_daqSvc);
00073 if (status.isFailure() ) {
00074 return status;
00075 }
00076 return StatusCode::SUCCESS;
00077 }
00078
00079 StatusCode DaqFormatWriter::execute() {
00080 const ReadoutHeader* readoutHeader = get<ReadoutHeader>("/Event/Readout/ReadoutHeader");
00081 if (0 == readoutHeader) {
00082 error() << "Failed to get readout header." << endreq;
00083 return StatusCode::FAILURE;
00084 }
00085
00086 const DaqCrate* daqCrate = readoutHeader->daqCrate();
00087 if (0 == daqCrate) {
00088 error() << "Failed to get crate readout from header" << endreq;
00089 return StatusCode::FAILURE;
00090 }
00091 StatusCode status = writeFileHead(daqCrate);
00092 if (status.isFailure() ) {
00093 return status;
00094 }
00095 return writeData(daqCrate);
00096 }
00097
00098 StatusCode DaqFormatWriter::finalize() {
00099 const StatusCode status = writeFileFoot();
00100 if (status.isFailure()) {
00101 return status;
00102 }
00103 return StatusCode::SUCCESS;
00104 }
00105
00106 StatusCode DaqFormatWriter::writeFileHead(const DaqCrate* daqCrate) {
00107 bool freshFile = false;
00108 if (0 == m_daqToOStream) {
00109 if (m_daqSvc->hasFileStartRecord()) {
00110 const FileStartRecord& record = m_daqSvc->fileStartRecord();
00111 m_daqToOStream = createDaqToOStream(record.fileTraits());
00112 if (!(m_daqToOStream->openSequence(m_outputBase,
00113 record))) {
00114 return StatusCode::FAILURE;
00115 }
00116 } else {
00117 m_daqToOStream = createDaqToOStream(*m_traits);
00118 const FileTraits::FileDateTime* dateTime = m_traits->makeDateTime(time(0));
00119 const FileStartRecord* record = m_daqToOStream->openSequence(m_outputBase,
00120 *dateTime,
00121 m_fileBlockLimit,
00122 (m_fileByteLimit / kBytesInMegabyte));
00123 delete dateTime;
00124 if (0 == record) {
00125 return StatusCode::FAILURE;
00126 }
00127 delete record;
00128 }
00129 } else {
00130 if (m_daqSvc->hasFileEndRecord()) {
00131 if (m_daqSvc->hasFileStartRecord()) {
00132 if (!m_daqToOStream->close(m_daqSvc->fileEndRecord())) {
00133 return StatusCode::FAILURE;
00134 }
00135 wroteFileFoot();
00136 if (!m_daqToOStream->open(m_daqSvc->fileStartRecord())) {
00137 return StatusCode::FAILURE;
00138 }
00139 } else {
00140 if (!(m_daqToOStream->close(m_daqSvc->fileEndRecord()))) {
00141 return StatusCode::FAILURE;
00142 }
00143 wroteFileFoot();
00144 delete m_daqToOStream;
00145 m_daqToOStream = 0;
00146 return StatusCode::SUCCESS;
00147 }
00148 } else {
00149 const EventReadout& eventReadout = daqCrate->eventReadout();
00150 const EventHeader& eventHeader = eventReadout.header();
00151 ++m_fileBlockCount;
00152 m_fileByteCount += eventHeader.totalSize() * kBytesInInt;
00153 if (((0 != m_fileBlockLimit) && (0 == (m_fileBlockCount > m_fileBlockLimit))) ||
00154 ((0 != m_fileByteLimit) && (0 == (m_fileByteCount > m_fileByteLimit)))) {
00155 const FileTraits::FileDateTime* dateTime = m_traits->makeDateTime(time(0));
00156 const FileStartRecord* record = m_daqToOStream->openNext(*dateTime);
00157 delete dateTime;
00158 if (0 == record) {
00159 return StatusCode::FAILURE;
00160 }
00161 delete record;
00162 m_fileBlockCount = 1;
00163 m_fileByteCount = eventHeader.totalSize() * kBytesInInt;
00164 freshFile = true;
00165 } else {
00166 return StatusCode::SUCCESS;
00167 }
00168 }
00169 }
00170 if (m_daqSvc->hasFileNameStrings()) {
00171 if (!(m_daqToOStream->saveFileNameStrings(m_daqSvc->fileNameStrings()))) {
00172 return StatusCode::FAILURE;
00173 }
00174 } else {
00175 const FileNameStrings* record = m_daqToOStream->saveFileNameStrings("DaqFormatWriter");
00176 if (0 == record) {
00177 return StatusCode::FAILURE;
00178 }
00179 delete record;
00180 }
00181 if (m_daqSvc->hasMetadataStrings()) {
00182 if (!(m_daqToOStream->saveMetadataStrings(m_daqSvc->metadataStrings()))) {
00183 return StatusCode::FAILURE;
00184 }
00185 } else {
00186 MetadataStrings::MetadataStringPtrList* metadataStrings = new MetadataStrings::MetadataStringPtrList();
00187 MetadataStrings::MetadataString metaString("type","MC");
00188 metadataStrings->push_back(&metaString);
00189 const MetadataStrings* record = m_daqToOStream->saveMetadataStrings(*metadataStrings);
00190 if (0 == record) {
00191 return StatusCode::FAILURE;
00192 }
00193 delete record;
00194 }
00195 if (m_daqSvc->hasRunParametersRecord()) {
00196 if (!(m_daqToOStream->saveRunParametersRecord(m_daqSvc->runParametersRecord()))) {
00197 return StatusCode::FAILURE;
00198 }
00199 } else {
00200 const RunParametersRecord* record = m_daqToOStream->saveRunParametersRecord(m_daqSvc->runNumber(daqCrate->detector()),
00201 true,
00202 0,
00203 0);
00204 if (0 == record) {
00205 return StatusCode::FAILURE;
00206 }
00207 delete record;
00208 }
00209 if (m_daqSvc->hasCalibrationParametersRecord()) {
00210 if (!(m_daqToOStream->saveCalibrationParametersRecord(m_daqSvc->calibrationParametersRecord()))) {
00211 return StatusCode::FAILURE;
00212 }
00213 }
00214 wroteFileHead();
00215 return StatusCode::SUCCESS;
00216 }
00217
00218 StatusCode DaqFormatWriter::writeData(const DaqCrate* daqCrate) {
00219 if (0 == m_daqToOStream) {
00220 return StatusCode::FAILURE;
00221 }
00222 const DataSeparatorRecord* record = m_daqToOStream->saveEvent(daqCrate->eventReadout());
00223 if (0 == record) {
00224 return StatusCode::FAILURE;
00225 }
00226 delete record;
00227 wroteData();
00228 return StatusCode::SUCCESS;
00229 }
00230
00231 StatusCode DaqFormatWriter::writeFileFoot() {
00232 if (0 == m_daqToOStream) {
00233 return StatusCode::SUCCESS;
00234 }
00235 if (m_daqSvc->hasFileEndRecord()) {
00236 if (!(m_daqToOStream->close(m_daqSvc->fileEndRecord()))) {
00237 return StatusCode::FAILURE;
00238 }
00239 } else {
00240 const FileTraits::FileDateTime* dateTime = m_traits->makeDateTime(time(0));
00241 const FileEndRecord* record = m_daqToOStream->close(*dateTime);
00242 delete dateTime;
00243 if (0 == record) {
00244 return StatusCode::FAILURE;
00245 }
00246 delete const_cast<FileEndRecord*>(record);
00247 }
00248 wroteFileFoot();
00249 delete m_daqToOStream;
00250 m_daqToOStream = 0;
00251 return StatusCode::SUCCESS;
00252 }