$treeview $search $mathjax $extrastylesheet
artdaq_demo
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "artdaq-demo/Generators/AsciiSimulator.hh" 00002 00003 #include "canvas/Utilities/Exception.h" 00004 00005 #include "artdaq/Application/GeneratorMacros.hh" 00006 #include "cetlib_except/exception.h" 00007 #include "artdaq-core-demo/Overlays/AsciiFragment.hh" 00008 #include "artdaq-core-demo/Overlays/AsciiFragmentWriter.hh" 00009 #include "artdaq-core-demo/Overlays/FragmentType.hh" 00010 #include "fhiclcpp/ParameterSet.h" 00011 #include "artdaq-core/Utilities/SimpleLookupPolicy.hh" 00012 00013 #include <fstream> 00014 #include <iomanip> 00015 #include <iterator> 00016 #include <iostream> 00017 00018 #include <unistd.h> 00019 00020 namespace 00021 { 00028 template <typename T> 00029 T convertToASCII(std::string input) 00030 { 00031 if (input.size() < sizeof(T) / sizeof(char)) 00032 { 00033 input.insert(0, sizeof(T) / sizeof(char) - input.size(), ' '); 00034 } 00035 else if (input.size() > sizeof(T) / sizeof(char)) 00036 { 00037 input.erase(0, input.size() - sizeof(T) / sizeof(char)); 00038 } 00039 00040 uint64_t bigOutput = 0ull; 00041 // std::ofstream outputStr ("/tmp/ASCIIConverter.bin", std::ios::out | std::ios::app | std::ios::binary ); 00042 for (uint i = 0; i < input.length(); ++i) 00043 { 00044 //outputStr.write((char*)&input[i],sizeof(char)); 00045 bigOutput *= 0x100; 00046 bigOutput += input[input.length() - i - 1]; 00047 } 00048 00049 //outputStr.close(); 00050 return static_cast<T>(bigOutput); 00051 } 00052 } 00053 00054 demo::AsciiSimulator::AsciiSimulator(fhicl::ParameterSet const& ps) 00055 : 00056 CommandableFragmentGenerator(ps) 00057 , throttle_usecs_(ps.get<size_t>("throttle_usecs", 100000)) 00058 , string1_(ps.get<std::string>("string1", "All work and no play makes ARTDAQ a dull library")) 00059 , string2_(ps.get<std::string>("string2", "Hey, look at what ARTDAQ can do!")) 00060 { 00061 } 00062 00063 bool demo::AsciiSimulator::getNext_(artdaq::FragmentPtrs& frags) 00064 { 00065 // JCF, 9/23/14 00066 00067 // If throttle_usecs_ is greater than zero (i.e., user requests a 00068 // sleep interval before generating the pseudodata) then during that 00069 // interval perform a periodic check to see whether a stop request 00070 // has been received 00071 00072 // Values for throttle_usecs_ and throttle_usecs_check_ will have 00073 // been tested for validity in constructor 00074 00075 if (throttle_usecs_ > 0) 00076 { 00077 size_t nchecks = throttle_usecs_ / 10000; 00078 00079 for (size_t i_c = 0; i_c < nchecks; ++i_c) 00080 { 00081 usleep(throttle_usecs_ / 10000); 00082 00083 if (should_stop()) 00084 { 00085 return false; 00086 } 00087 } 00088 } 00089 else 00090 { 00091 if (should_stop()) 00092 { 00093 return false; 00094 } 00095 } 00096 00097 // Set fragment's metadata 00098 size_t data_size = ev_counter() % 2 ? string1_.length() + 2 : string2_.length() + 2; 00099 AsciiFragment::Metadata metadata; 00100 std::string size_string = "S:" + std::to_string(data_size) + ","; 00101 metadata.charsInLine = convertToASCII<AsciiFragment::Metadata::chars_in_line_t>(size_string); 00102 00103 // And use it, along with the artdaq::Fragment header information 00104 // (fragment id, sequence id, and user type) to create a fragment 00105 00106 // We'll use the static factory function 00107 00108 // artdaq::Fragment::FragmentBytes(std::size_t payload_size_in_bytes, sequence_id_t sequence_id, 00109 // fragment_id_t fragment_id, type_t type, const T & metadata) 00110 00111 // which will then return a unique_ptr to an artdaq::Fragment 00112 // object. The advantage of this approach over using the 00113 // artdaq::Fragment constructor is that, if we were to want to 00114 // initialize the artdaq::Fragment with a nonzero-size payload (data 00115 // after the artdaq::Fragment header and metadata), we could provide 00116 // the size of the payload in bytes, rather than in units of the 00117 // artdaq::Fragment's RawDataType (8 bytes, as of 3/26/14). The 00118 // artdaq::Fragment constructor itself was not altered so as to 00119 // maintain backward compatibility. 00120 00121 std::size_t initial_payload_size = 0; 00122 00123 frags.emplace_back(artdaq::Fragment::FragmentBytes(initial_payload_size, 00124 ev_counter(), fragment_id(), 00125 FragmentType::ASCII, metadata)); 00126 00127 // Then any overlay-specific quantities next; will need the 00128 // AsciiFragmentWriter class's setter-functions for this 00129 00130 AsciiFragmentWriter newfrag(*frags.back()); 00131 00132 newfrag.set_hdr_line_number(convertToASCII<AsciiFragment::Header::line_number_t>("LN:" + std::to_string(ev_counter()) + ",")); 00133 00134 newfrag.resize(data_size); 00135 00136 // Now, generate the payload, based on the string to use 00137 std::string string_to_use = ev_counter() % 2 ? string1_ : string2_; 00138 string_to_use += "\r\n"; 00139 00140 // std::ofstream output ("/tmp/ASCIIGenerator.bin", std::ios::out | std::ios::app | std::ios::binary ); 00141 for (uint i = 0; i < string_to_use.length(); ++i) 00142 { 00143 //output.write((char*)&string_to_use[i],sizeof(char)); 00144 *(newfrag.dataBegin() + i) = string_to_use[i]; 00145 } 00146 // output.close(); 00147 00148 ev_counter_inc(); 00149 00150 return true; 00151 } 00152 00153 // The following macro is defined in artdaq's GeneratorMacros.hh header 00154 DEFINE_ARTDAQ_COMMANDABLE_GENERATOR(demo::AsciiSimulator)