32 #include "nusimdata/SimulationBase/MCParticle.h"
33 #include "nusimdata/SimulationBase/MCTruth.h"
36 #include "sbndaq-artdaq-core/Overlays/Common/BernCRTFragmentV2.hh"
37 #include "sbndaq-artdaq-core/Overlays/FragmentType.hh"
38 #include "artdaq-core/Data/Fragment.hh"
41 #include "art/Framework/Core/EDProducer.h"
42 #include "art/Framework/Principal/Event.h"
43 #include "art/Framework/Principal/Handle.h"
44 #include "art/Framework/Services/Registry/ServiceHandle.h"
45 #include "art_root_io/TFileService.h"
46 #include "art/Framework/Core/ModuleMacros.h"
47 #include "canvas/Persistency/Common/FindManyP.h"
48 #include "canvas/Utilities/Exception.h"
53 #include "messagefacility/MessageLogger/MessageLogger.h"
54 #include "fhiclcpp/ParameterSet.h"
55 #include "fhiclcpp/types/Table.h"
56 #include "fhiclcpp/types/Atom.h"
57 #include "cetlib/pow.h"
74 class CRTArtdaqFragmentProducer;
88 void produce(art::Event&
e)
override;
132 fSimModuleLabel(
p.get<std::string>(
"SimModuleLabel",
"largeant")),
133 fCRTSimLabel(
p.get<std::string>(
"CRTSimLabel",
"crt")),
134 fFEBDataLabel(
p.get<std::string>(
"FEBDataLabel",
"crtsim")),
135 fVerbose(
p.get<
bool>(
"Verbose",
false)),
136 fClockSpeedCRT(
p.get<
double>(
"ClockSpeedCRT")),
137 fFirstFEBMac5(
p.get<
size_t>(
"FirstFEBMac5", 0))
141 produces< std::vector<artdaq::Fragment> >();
144 fGeometryService = lar::providerFrom<geo::Geometry>();
155 fSubrun = e.subRun();
156 fEvent = e.id().event();
158 std::cout<<
"============================================"<<std::endl
159 <<
"Run = "<<fRun<<
", SubRun = "<<fSubrun<<
", Event = "<<fEvent<<std::endl
160 <<
"============================================"<<std::endl;
164 for(
int i=0; i<num_febs; i++){empty_fragment[i]=
true;}
166 int num_module = fCrtGeo.NumModules();
173 art::Handle<std::vector<sbnd::crt::FEBData>> feb_data_h;
174 e.getByLabel(fFEBDataLabel, feb_data_h);
177 if (!feb_data_h.isValid()) {
178 throw art::Exception(art::errors::Configuration) <<
"could not locate FEBData." << std::endl;;
181 std::vector<art::Ptr<sbnd::crt::FEBData>> feb_data_v;
182 art::fill_ptr_vector(feb_data_v, feb_data_h);
184 art::FindManyP<sim::AuxDetIDE, sbnd::crt::FEBTruthInfo> febdata_to_ides (feb_data_h, e, fFEBDataLabel);
187 std::fill(feb_hits_in_fragments, feb_hits_in_fragments +
sizeof(feb_hits_in_fragments), 0);
190 std::unique_ptr<std::vector<artdaq::Fragment>> vecFrag = std::make_unique<std::vector<artdaq::Fragment>>();
194 uint16_t lostcpu = 0;
195 uint16_t lostfpga = 0;
197 uint16_t lost_hits = 0;
201 uint64_t run_start_time = 0;
202 uint64_t this_poll_start = 0;
203 uint64_t this_poll_end = 0;
204 int32_t system_clock_deviation = 0;
205 uint32_t feb_hits_in_poll = 0;
208 uint64_t sequence_id = fEvent;
210 uint64_t temp_last_time = 0;
214 std::normal_distribution<double> distribution(175.0,23.0);
224 for (
size_t feb_i = 0; feb_i < feb_data_v.size(); feb_i++) {
226 auto const feb_data = feb_data_v[feb_i];
228 if(fVerbose){
std::cout <<
"FEB " << feb_i <<
" with mac " << feb_data->Mac5() << std::endl;}
230 empty_fragment[feb_data->Mac5()] =
false;
232 int channel = feb_data->Mac5() * 32;
233 std::string stripName = fCrtGeo.ChannelToStripName(channel);
234 std::string
tagger = fCrtGeo.GetTaggerName(stripName);
235 taggers[feb_data->Mac5()] = tagger;
237 T0s[feb_data->Mac5()][feb_hits_in_fragments[feb_data->Mac5()]] = feb_data->Ts0();
238 T1s[feb_data->Mac5()][feb_hits_in_fragments[feb_data->Mac5()]] = feb_data->Ts1();
239 for (
int i_adc = 0; i_adc<32; i_adc++){
241 if (feb_data->ADC()[i_adc] > 4089){
243 }
else if (feb_data->ADC()[i_adc] == 0){
245 adc = distribution(generator);
247 adc = feb_data->ADC()[i_adc];
249 ADCs[feb_data->Mac5()][feb_hits_in_fragments[feb_data->Mac5()]][i_adc] = adc;
252 feb_hits_in_fragments[feb_data->Mac5()]++;
257 for (
size_t feb_i = fFirstFEBMac5; feb_i < num_module+fFirstFEBMac5; feb_i++){
259 if (empty_fragment[feb_i]){
261 feb_hits_in_fragments[feb_i] = 1;
262 int channel = feb_i * 32;
263 std::string stripName = fCrtGeo.ChannelToStripName(channel);
264 std::string
tagger = fCrtGeo.GetTaggerName(stripName);
265 taggers[feb_i] = tagger;
269 for (
int i_adc = 0; i_adc<32; i_adc++){
270 uint16_t adc = distribution(generator);
271 ADCs[feb_i][0][i_adc] = adc;
275 if (feb_hits_in_fragments[feb_i]==0)
continue;
278 uint8_t mac5 = (uint8_t)feb_i;
279 uint16_t feb_hits_in_fragment = feb_hits_in_fragments[feb_i];
281 sbndaq::BernCRTFragmentMetadataV2 metadata;
283 metadata.set_mac5(mac5);
284 metadata.set_clock_deviation(system_clock_deviation);
285 metadata.set_hits_in_poll(feb_hits_in_poll);
286 metadata.set_hits_in_fragment(feb_hits_in_fragment);
287 metadata.set_run_start_time(run_start_time);
288 metadata.update_poll_time(this_poll_start, this_poll_end);
290 uint64_t timestamp = (uint64_t)(T0s[feb_i][feb_hits_in_fragments[feb_i]]/fClockSpeedCRT);
294 uint16_t fragmentIDVal = 32768 + 12288 + (plane_num * 256) + (uint16_t)mac5;
295 if(fVerbose){
std::cout<<
"fragmentID: "<<std::bitset<16>{fragmentIDVal}<<std::endl;}
296 auto fragment_uptr = artdaq::Fragment::FragmentBytes(
sizeof(sbndaq::BernCRTHitV2)*metadata.hits_in_fragment(),
299 sbndaq::detail::FragmentType::BERNCRTV2,
305 std::vector<sbndaq::BernCRTHitV2> data_vec;
306 for (
int i_frag = 0; i_frag<feb_hits_in_fragments[feb_i]; i_frag++){
307 sbndaq::BernCRTHitV2
hit;
310 uint32_t ts0 = T0s[feb_i][i_frag];
311 uint32_t ts1 = T1s[feb_i][i_frag];
313 if (ts1==0){flags=11;}
else if (ts0==0){flags=7;}
315 uint64_t feb_hit_number = feb_hits_in_fragments[feb_i];
316 timestamp = (uint64_t)ts0/fClockSpeedCRT;
317 uint64_t last_accepted_timestamp = temp_last_time;
318 temp_last_time = timestamp;
320 hit.flags = (uint16_t)flags;
321 hit.lostcpu = (uint16_t)lostcpu;
322 hit.lostfpga = (uint16_t)lostfpga;
323 hit.ts0 = (uint32_t)ts0;
324 hit.ts1 = (uint32_t)ts1;
325 for (
int i_adc = 0; i_adc<32; i_adc++){
326 hit.adc[i_adc] = ADCs[feb_i][i_frag][i_adc];
328 hit.coinc = (uint32_t)coinc;
329 hit.feb_hit_number = (uint64_t)feb_hit_number;
330 hit.timestamp = (uint64_t)timestamp;
331 hit.last_accepted_timestamp = (uint64_t)last_accepted_timestamp;
332 hit.lost_hits = (uint16_t)lost_hits;
334 data_vec.emplace_back(hit);
338 std::memcpy(fragment_uptr->dataBeginBytes(), data_vec.data(),
sizeof(sbndaq::BernCRTHitV2)*metadata.hits_in_fragment());
341 vecFrag->push_back(*fragment_uptr);
345 if(fVerbose)
std::cout <<
"Fragments written: " << vecFrag->size() << std::endl;
347 e.put(std::move(vecFrag));
bool empty_fragment[num_febs]
bool fVerbose
print information about what's going on
size_t fFirstFEBMac5
lowest mac5 address for CRT FEBs
art::InputTag fSimModuleLabel
name of detsim producer
geo::GeometryCore const * fGeometryService
Access the description of detector geometry.
object containing MC truth information necessary for making RawDigits and doing back tracking ...
void produce(art::Event &e) override
art framework interface to geometry description for auxiliary detectors
enum::sbnd::CRTPlane GetPlaneIndex(std::string tagger)
CRTArtdaqFragmentProducer & operator=(CRTArtdaqFragmentProducer const &)=delete
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
art::InputTag fCRTSimLabel
name of CRT producer
uint32_t T1s[num_febs][max_hits_in_fragment]
Description of geometry of one entire detector.
Definition of data types for geometry description.
uint16_t ADCs[num_febs][max_hits_in_fragment][num_channels]
uint32_t T0s[num_febs][max_hits_in_fragment]
CRTArtdaqFragmentProducer(fhicl::ParameterSet const &p)
stream1 can override from command line with o or output services user sbnd
std::string fFEBDataLabel
name of FEBData producer
uint16_t feb_hits_in_fragments[num_febs]
std::string taggers[num_febs]
art framework interface to geometry description
BEGIN_PROLOG could also be cout