00001
00002 #include "artdaq/DAQdata/Globals.hh"
00003 #include "artdaq/ArtModules/detail/RawEventQueueReader.hh"
00004 #include "artdaq-core/Data/ContainerFragment.hh"
00005
00006 #include "art/Framework/IO/Sources/put_product_in_principal.h"
00007 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
00008 #include "canvas/Utilities/Exception.h"
00009 #include "artdaq-core/Data/Fragment.hh"
00010 #include <sys/time.h>
00011 #define TRACE_NAME "RawEventQueueReader"
00012 #include "trace.h"
00013
00014 using std::string;
00015
00016 artdaq::detail::RawEventQueueReader::RawEventQueueReader(fhicl::ParameterSet const& ps,
00017 art::ProductRegistryHelper& help,
00018 art::SourceHelper const& pm) :
00019 pmaker(pm)
00020 , incoming_events(getGlobalQueue())
00021 , waiting_time(ps.get<double>("waiting_time", 86400.0))
00022 , resume_after_timeout(ps.get<bool>("resume_after_timeout", true))
00023 , pretend_module_name(ps.get<std::string>("raw_data_label","daq"))
00024 , unidentified_instance_name("unidentified")
00025 , shutdownMsgReceived(false)
00026 , outputFileCloseNeeded(false)
00027 , bytesRead(0)
00028 , fragment_type_map_(Fragment::MakeSystemTypeMap())
00029 , readNext_calls_(0)
00030 {
00031 help.reconstitutes<Fragments, art::InEvent>(pretend_module_name,
00032 unidentified_instance_name);
00033 help.reconstitutes<Fragments, art::InEvent>(pretend_module_name, "ContainerEmpty");
00034 for (auto it = fragment_type_map_.begin(); it != fragment_type_map_.end(); ++it)
00035 {
00036 help.reconstitutes<Fragments, art::InEvent>(pretend_module_name, it->second);
00037 }
00038 }
00039
00040 void artdaq::detail::RawEventQueueReader::closeCurrentFile() {}
00041
00042 void artdaq::detail::RawEventQueueReader::readFile(string const&,
00043 art::FileBlock*& fb)
00044 {
00045 fb = new art::FileBlock(art::FileFormatVersion(1, "RawEvent2011"), "nothing");
00046 }
00047
00048 bool artdaq::detail::RawEventQueueReader::readNext(art::RunPrincipal* const & inR,
00049 art::SubRunPrincipal* const & inSR,
00050 art::RunPrincipal*& outR,
00051 art::SubRunPrincipal*& outSR,
00052 art::EventPrincipal*& outE)
00053 {
00054
00055
00056
00057
00058 if (readNext_calls_++ == 0)
00059 {
00060 incoming_events.setReaderIsReady();
00061 TRACE(50, "RawEventQueueReader::readNext after incoming_events.setReaderIsReady()");
00062 }
00063
00064 outR = 0;
00065 outSR = 0;
00066 outE = 0;
00067 RawEvent_ptr popped_event;
00068
00069
00070
00071
00072
00073 bool keep_looping = true;
00074 bool got_event = false;
00075 while (keep_looping)
00076 {
00077 keep_looping = false;
00078 got_event = incoming_events.deqTimedWait(popped_event, waiting_time);
00079 if (!got_event)
00080 {
00081 TLOG_INFO("RawEventQueueReader")
00082 << "InputFailure: Reading timed out in RawEventQueueReader::readNext()" << TLOG_ENDL;
00083 keep_looping = resume_after_timeout;
00084 }
00085 }
00086
00087
00088
00089
00090
00091 if (!got_event || !popped_event)
00092 {
00093 TLOG_DEBUG("RawEventQueueReader") << "Received shutdown message, returning false" << TLOG_ENDL;
00094 shutdownMsgReceived = true;
00095 return false;
00096 }
00097
00098 size_t qsize=incoming_events.size();
00099
00100
00101
00102
00103 art::Timestamp currentTime = time(0);
00104
00105
00106 if (inR == 0 || inR->run() != popped_event->runID())
00107 {
00108 outR = pmaker.makeRunPrincipal(popped_event->runID(),
00109 currentTime);
00110 }
00111
00112 if (popped_event->numFragments() == 1)
00113 {
00114 if (popped_event->releaseProduct(Fragment::EndOfRunFragmentType)->size() == 1)
00115 {
00116 art::EventID const evid(art::EventID::flushEvent());
00117 outR = pmaker.makeRunPrincipal(evid.runID(), currentTime);
00118 outSR = pmaker.makeSubRunPrincipal(evid.subRunID(), currentTime);
00119 outE = pmaker.makeEventPrincipal(evid, currentTime);
00120 return true;
00121 }
00122 else if (popped_event->releaseProduct(Fragment::EndOfSubrunFragmentType)->size() == 1)
00123 {
00124
00125 if (inR == 0 || inR->run() != popped_event->runID())
00126 {
00127 outSR = pmaker.makeSubRunPrincipal(popped_event->runID(),
00128 popped_event->subrunID(),
00129 currentTime);
00130 #ifdef ARTDAQ_ART_EVENTID_HAS_EXPLICIT_RUNID
00131 art::EventID const evid(art::EventID::flushEvent(outR->id(), outSR->id()));
00132 #else
00133 art::EventID const evid(art::EventID::flushEvent(outSR->id()));
00134 #endif
00135 outE = pmaker.makeEventPrincipal(evid, currentTime);
00136 }
00137 else
00138 {
00139
00140
00141
00142
00143 if (inSR != 0 && !inSR->id().isFlush() && inSR->subRun() == popped_event->subrunID())
00144 {
00145 art::EventID const evid(art::EventID::flushEvent(inR->id()));
00146 outSR = pmaker.makeSubRunPrincipal(evid.subRunID(), currentTime);
00147 outE = pmaker.makeEventPrincipal(evid, currentTime);
00148
00149
00150
00151 }
00152 else
00153 {
00154 outSR = pmaker.makeSubRunPrincipal(popped_event->runID(),
00155 popped_event->subrunID(),
00156 currentTime);
00157 #ifdef ARTDAQ_ART_EVENTID_HAS_EXPLICIT_RUNID
00158 art::EventID const evid(art::EventID::flushEvent(inR->id(), outSR->id()));
00159 #else
00160 art::EventID const evid(art::EventID::flushEvent(outSR->id()));
00161 #endif
00162 outE = pmaker.makeEventPrincipal(evid, currentTime);
00163
00164
00165 }
00166 outR = 0;
00167 }
00168
00169 return true;
00170 }
00171 }
00172
00173
00174 art::SubRunID subrun_check(popped_event->runID(), popped_event->subrunID());
00175 if (inSR == 0 || subrun_check != inSR->id())
00176 {
00177 outSR = pmaker.makeSubRunPrincipal(popped_event->runID(),
00178 popped_event->subrunID(),
00179 currentTime);
00180 }
00181 outE = pmaker.makeEventPrincipal(popped_event->runID(),
00182 popped_event->subrunID(),
00183 popped_event->sequenceID(),
00184 currentTime);
00185
00186 std::vector<Fragment::type_t> type_list;
00187 popped_event->fragmentTypes(type_list);
00188
00189 std::map<Fragment::type_t, std::string>::const_iterator iter_end =
00190 fragment_type_map_.end();
00191 for (size_t idx = 0; idx < type_list.size(); ++idx)
00192 {
00193 std::map<Fragment::type_t, std::string>::const_iterator iter =
00194 fragment_type_map_.find(type_list[idx]);
00195 auto product = popped_event->releaseProduct(type_list[idx]);
00196 for (auto &frag : *product)
00197 bytesRead += frag.sizeBytes();
00198 if (iter != iter_end)
00199 {
00200 if (type_list[idx] == artdaq::Fragment::ContainerFragmentType)
00201 {
00202 std::unordered_map<std::string, std::unique_ptr<Fragments>> derived_fragments;
00203 derived_fragments[iter->second] = std::make_unique<Fragments>();
00204
00205 for(size_t ii = 0; ii < product->size(); ++ii)
00206 {
00207 ContainerFragment cf(product->at(ii));
00208 auto contained_type = fragment_type_map_.find(cf.fragment_type());
00209 if (contained_type != iter_end)
00210 {
00211 auto label = iter->second + contained_type->second;
00212 if (!derived_fragments.count(label))
00213 {
00214 derived_fragments[label] = std::make_unique<Fragments>();
00215 }
00216 derived_fragments[label]->emplace_back(std::move(product->at(ii)));
00217 }
00218 else
00219 {
00220 derived_fragments[iter->second]->emplace_back(std::move(product->at(ii)));
00221 }
00222 }
00223
00224 for (auto& type : derived_fragments)
00225 {
00226 put_product_in_principal(std::move(type.second),
00227 *outE,
00228 pretend_module_name,
00229 type.first);
00230 }
00231
00232 }
00233 else
00234 {
00235 put_product_in_principal(std::move(product),
00236 *outE,
00237 pretend_module_name,
00238 iter->second);
00239 }
00240 }
00241 else
00242 {
00243 put_product_in_principal(std::move(product),
00244 *outE,
00245 pretend_module_name,
00246 unidentified_instance_name);
00247 TLOG_WARNING("RawEventQueueReader")
00248 << "UnknownFragmentType: The product instance name mapping for fragment type \""
00249 << ((int)type_list[idx]) << "\" is not known. Fragments of this "
00250 << "type will be stored in the event with an instance name of \""
00251 << unidentified_instance_name << "\"." << TLOG_ENDL;
00252 }
00253 }
00254 TRACE( 10, "readNext: bytesRead=%lu qsize=%zu cap=%zu metricMan=%p", bytesRead, qsize, incoming_events.capacity(), (void*)metricMan );
00255 if (metricMan) {
00256 metricMan->sendMetric( "bytesRead", bytesRead>>20, "MB", 5, MetricMode::Accumulate, "", true );
00257 metricMan->sendMetric( "queue%Used", static_cast<unsigned long int>(qsize*100/incoming_events.capacity()), "%", 5, MetricMode::LastPoint, "", true );
00258 }
00259
00260 return true;
00261 }