63 LOG(DEBUG) <<
"DriftTubeUnpack : Unpacking frame... size/bytes = " << size ;
65 auto df =
reinterpret_cast<DataFrame *
>(data);
66 assert(df->header.size == size);
67 switch (df->header.frameTime) {
68 case SoS: LOG(DEBUG) <<
"DriftTubeUnpacker: SoS frame." ;
return kTRUE;
69 case EoS: LOG(DEBUG) <<
"DriftTubeUnpacker: EoS frame." ;
return kTRUE;
72 LOG(DEBUG) <<
"Sequential trigger number " << df->header.timeExtent ;
73 auto nhits = df->getHitCount();
75 int nhitsLateTubes = 0;
76 int nhitsScintillator = 0;
77 int nhitsBeamCounter = 0;
78 int nhitsMasterTrigger = 0;
79 int nhitsTriggers = 0;
80 auto flags = df->header.flags;
82 int expected_triggers = 5;
84 LOG(DEBUG) <<
"All TDCs are OK" ;
86 LOG(DEBUG) <<
"Not all TDCs are OK:" << std::bitset<16>(flags) ;
87 for (
auto i : ROOT::MakeSeq(5)) {
88 if ((flags & 1 << (i + 1)) == 1 << (i + 1)) {
90 LOG(WARNING) <<
"TDC " << i <<
" NOT OK" ;
92 LOG(DEBUG) <<
"TDC " << i <<
" OK" ;
96 ROOT::VecOps::RVec<RawDataHit> hits(df->hits, df->hits + nhits);
97 ROOT::VecOps::RVec<RawDataHit> leading, trailing;
100 std::set<uint16_t> channels;
101 for (
auto &&hit : hits) {
102 channels.emplace(hit.channelId % 0x1000);
103 (hit.channelId < 0x1000 ? leading : trailing).emplace_back(hit);
105 assert(leading.size() + trailing.size() == hits.size());
106 LOG(DEBUG) << leading.size() <<
'\t' << trailing.size() <<
'\t' << hits.size();
107 const int n_leading = leading.size();
108 auto compare_hit_time = [](
const RawDataHit &a,
const RawDataHit &b) {
return a.hitTime < b.hitTime; };
109 std::sort(leading.begin(), leading.end(), compare_hit_time);
110 std::sort(trailing.begin(), trailing.end(), compare_hit_time);
111 std::unordered_map<uint16_t, ROOT::VecOps::RVec<RawDataHit>> channel_leading;
112 for (
auto &&hit : leading) {
113 assert(hit.channelId < 0x1000);
114 channel_leading[hit.channelId % 0x1000].emplace_back(hit);
116 std::unordered_map<uint16_t, ROOT::VecOps::RVec<RawDataHit>> channel_trailing;
117 for (
auto &&hit : trailing) {
118 assert(hit.channelId >= 0x1000);
119 channel_trailing[hit.channelId % 0x1000].emplace_back(hit);
121 ROOT::VecOps::RVec<std::tuple<uint16_t, uint16_t, Float_t, bool, bool>> matches;
122 for (
auto &&channel : channels) {
124 LOG(DEBUG) <<
"Channel: " << channel;
125 assert(channel < 0x1000);
126 auto leading_hits = channel_leading[channel];
127 auto trailing_hits = channel_trailing[channel];
128 auto difference = int(leading_hits.size() - trailing_hits.size());
129 if (difference != 0) {
130 LOG(DEBUG) <<
"Difference between leading/trailing edges: " << difference;
132 for (
int i = 0, j = 0; i < leading_hits.size(); i++) {
133 LOG(DEBUG) <<
"i=" << i <<
"\tj=" << j;
134 LOG(DEBUG) <<
"leading_hits.size()=" << leading_hits.size()
135 <<
"\ttrailing_hits.size()=" << trailing_hits.size();
136 assert(i < leading_hits.size());
137 if (j < trailing_hits.size() && leading_hits.at(i).hitTime < trailing_hits.at(j).hitTime &&
138 (i + 1 >= leading_hits.size() || trailing_hits.at(j).hitTime < leading_hits.at(i + 1).hitTime)) {
140 LOG(DEBUG) <<
"Successful match on channel " << channel;
141 uint16_t time = leading_hits.at(i).hitTime;
142 Float_t time_over_threshold = 0.098 * (trailing_hits.at(j).hitTime - leading_hits.at(i).hitTime);
143 matches.emplace_back(channel, time, time_over_threshold, first,
true);
147 }
else if (j < trailing_hits.size() && leading_hits.at(i).hitTime > trailing_hits.at(j).hitTime &&
148 (j + 1) < trailing_hits.size()) {
151 LOG(DEBUG) <<
"Try again for hit on channel " << channel;
155 LOG(DEBUG) <<
"No match found for hit on channel " << channel;
157 uint16_t time = leading_hits.at(i).hitTime;
158 Float_t time_over_threshold = 167.2;
159 matches.emplace_back(channel, time, time_over_threshold, first,
false);
165 assert(n_matched + n_unmatched == n_leading);
166 LOG(DEBUG) <<
"Successfully matched " << n_matched <<
"/" << n_leading <<
"(" << hits.size() <<
" hits)";
168 std::unordered_map<int, uint16_t> trigger_times;
169 ROOT::VecOps::RVec<std::tuple<uint16_t, uint16_t, Float_t, bool, uint16_t>> drifttube_hits;
170 uint16_t master_trigger_time = 0;
171 for (
auto &&match : matches) {
172 uint16_t channel, hit_time;
173 Float_t time_over_threshold;
175 std::tie(channel, hit_time, time_over_threshold, first, matched) = match;
177 auto id = *(
reinterpret_cast<ChannelId *
>(&channel));
178 auto detectorId =
fCharm ?
id.GetDetectorIdCharm() :
id.GetDetectorId();
180 if (detectorId == 0) {
183 if (trigger_times.find(TDC) != trigger_times.end()) {
184 LOG(DEBUG) <<
"Found time " << trigger_times[TDC] <<
" for TDC " << TDC ;
185 trigger_times[TDC] = std::min(hit_time, trigger_times[TDC]);
187 LOG(DEBUG) <<
"Inserting new time " << hit_time ;
188 trigger_times[TDC] = hit_time;
190 LOG(DEBUG) << TDC <<
'\t' << hit_time <<
'\t' << trigger_times[TDC] ;
191 new ((*fRawTriggers)[nhitsTriggers])
192 ScintillatorHit(detectorId, 0.098 * Float_t(hit_time), time_over_threshold, hit_flags, channel);
194 }
else if (detectorId == -2) {
197 }
else if (detectorId == 1) {
201 if (nhitsMasterTrigger == 0 || hit_time < master_trigger_time) {
202 master_trigger_time = hit_time;
204 new ((*fRawMasterTrigger)[nhitsMasterTrigger])
205 ScintillatorHit(detectorId, 0.098 * Float_t(hit_time), time_over_threshold, hit_flags, channel);
206 nhitsMasterTrigger++;
207 }
else if (detectorId == -1) {
209 new ((*fRawBeamCounter)[nhitsBeamCounter])
210 ScintillatorHit(detectorId, 0.098 * Float_t(hit_time), time_over_threshold, hit_flags, channel);
212 }
else if (detectorId == 6 || detectorId == 7) {
215 LOG(ERROR) <<
"Scintillator hit found! There should not be any in the charmxsec measurement!"
219 new ((*fRawScintillator)[nhitsScintillator])
220 ScintillatorHit(detectorId, 0.098 * Float_t(hit_time), time_over_threshold, hit_flags, channel);
223 drifttube_hits.emplace_back(channel, hit_time, time_over_threshold, first, hit_flags);
227 int32_t delay = 13500;
228 if (!trigger_times[4]) {
229 LOG(WARNING) <<
"No trigger in TDC 4, guessing delay" ;
231 }
else if (master_trigger_time == 0) {
232 LOG(WARNING) <<
"No master trigger, guessing delay" ;
235 delay = trigger_times[4] - master_trigger_time;
236 LOG(DEBUG) <<
"Delay [ns]:";
237 LOG(DEBUG) << 0.098 * delay <<
" = " << 0.098 * trigger_times[4] <<
" - " << 0.098 * master_trigger_time;
240 for (
auto &&hit : drifttube_hits) {
241 uint16_t channel, raw_time, hit_flags;
242 Float_t time_over_threshold;
244 std::tie(channel, raw_time, time_over_threshold, first, hit_flags) = hit;
246 auto id = *(
reinterpret_cast<ChannelId *
>(&channel));
247 auto detectorId =
fCharm ?
id.GetDetectorIdCharm() :
id.GetDetectorId();
251 auto trigger_time = trigger_times.at(TDC);
252 time = 0.098 * (delay - trigger_time + raw_time);
253 }
catch (
const std::out_of_range &e) {
254 LOG(WARNING) << e.what() <<
"\t TDC " << TDC <<
"\t Detector ID " << detectorId <<
"\t Channel " << channel
255 <<
"\t Sequential trigger number " << df->header.timeExtent ;
256 time = 0.098 * raw_time;
260 LOG(WARNING) <<
"Late event found with time [ns]:";
261 LOG(WARNING) << time <<
" = " << 0.098 * delay <<
" - " << 0.098 * (delay + raw_time) - time <<
" - "
266 MufluxSpectrometerHit(detectorId, time, time_over_threshold, hit_flags, channel);
267 (first ? nhitsTubes : nhitsLateTubes)++;
270 if (trigger < expected_triggers) {
271 LOG(INFO) << trigger <<
" triggers." ;
273 LOG(DEBUG) << trigger <<
" triggers." ;