Project
Loading...
Searching...
No Matches
DigitSink.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15#include <set>
16#include <fmt/format.h>
17#include "DigitSink.h"
18#include <iostream>
19#include "DigitSinkImpl.h"
20#include <map>
21#include <algorithm>
22#include <limits>
23
24namespace
25{
26template <typename T>
27std::string asString(T t);
28
29template <>
30std::string asString(o2::mch::ROFRecord rof)
31{
32 return fmt::format("{} FirstIdx: {:5d} LastIdx: {:5d}",
33 rof.getBCData().asString(), rof.getFirstIdx(), rof.getLastIdx());
34}
35template <>
36std::string asString(o2::mch::Digit d)
37{
38 return fmt::format("DetID {:4d} PadId {:10d} ADC {:10d} TFtime {:10d} NofSamples {:5d} {}",
39 d.getDetID(), d.getPadID(), d.getADC(), d.getTime(), d.getNofSamples(),
40 d.isSaturated() ? "(S)" : "");
41}
42
43std::map<o2::mch::ROFRecord, int64_t> computeMinTimeDistances(gsl::span<const o2::mch::ROFRecord> rofs)
44{
45 std::map<o2::mch::ROFRecord, int64_t> minTimeDistances;
46
47 for (auto i = 0; i < rofs.size() - 1; i++) {
48 auto const& r = rofs[i];
49 o2::InteractionRecord iri{r.getBCData().bc,
50 r.getBCData().orbit};
51 minTimeDistances[r] = std::numeric_limits<int64_t>::max();
52 auto j = i + 1;
53 o2::InteractionRecord irj{rofs[j].getBCData().bc,
54 rofs[j].getBCData().orbit};
55 auto d = irj.differenceInBC(iri);
56 if (d >= 0) {
57 minTimeDistances[rofs[i]] = std::min(minTimeDistances[rofs[i]], d);
58 }
59 }
60 return minTimeDistances;
61}
62
63void printRofs(std::ostream& os, gsl::span<const o2::mch::ROFRecord> rofs)
64{
65 auto minTimeDistances = computeMinTimeDistances(rofs);
66
67 os << fmt::format("{:=^70}\n", fmt::format("{} rofs", rofs.size()));
68 size_t i{0};
69 for (const auto& r : rofs) {
70 os << fmt::format("[{:6d}] {}", i, asString(r));
71 if (minTimeDistances[r] < 4) {
72 os << fmt::format(" min distance {} !", minTimeDistances[r]);
73 }
74 os << "\n";
75 ++i;
76 }
77}
78
79struct DigitIdComparator {
80 bool operator()(const o2::mch::Digit& d1, const o2::mch::Digit& d2) const
81 {
82 if (d1.getDetID() == d2.getDetID()) {
83 return d1.getPadID() < d2.getPadID();
84 }
85 return d1.getDetID() < d2.getDetID();
86 }
87};
88
89void printDigitsAndRofs(std::ostream& os,
90 gsl::span<const o2::mch::Digit> digits,
91 gsl::span<const o2::mch::ROFRecord> rofs)
92{
93 printRofs(os, rofs);
94 os << fmt::format("{:=^70}\n", fmt::format("{} digits", digits.size()));
95 size_t irof{0};
96 size_t digitIndex{0};
97 for (const auto& r : rofs) {
98 os << fmt::format("{:-^95}\n", fmt::format("ROF {:4d} with {:5d} digits",
99 irof, r.getNEntries()));
100 ++irof;
101 std::map<o2::mch::Digit, uint16_t, DigitIdComparator> dids;
102 for (auto j = r.getFirstIdx(); j <= r.getLastIdx(); j++) {
103 const auto& d = digits[j];
104 dids[d]++;
105 }
106 size_t i{0};
107 for (auto& p : dids) {
108 const auto& d = p.first;
109 os << fmt::format("[{:6d}] ({:6d}) {}\n", digitIndex, i, asString(d));
110 ++digitIndex;
111 ++i;
112 }
113 // check that, within a rof, each digit appears only once.
114 // if not, report that as an error
115 for (auto& p : dids) {
116 if (p.second != 1) {
117 os << "!!! ERROR : got a duplicated digit (not merged?) : " << p.first << " appears " << p.second << " times\n";
118 }
119 }
120 }
121}
122
123} // namespace
124
125namespace o2::mch::io
126{
127
128DigitSink::DigitSink(std::ostream& os, DigitFileFormat format, size_t maxSize) : mOutput(os), mBinary(true), mFileFormat(format), mMaxSize(maxSize)
129{
130 // write the tag to identify the file
131 os.write(reinterpret_cast<char*>(&mFileFormat), sizeof(DigitFileFormat));
132 mImpl = impl::createDigitSinkImpl(mFileFormat.fileVersion);
133}
134
135DigitSink::DigitSink(std::ostream& os) : mOutput(os), mBinary(false), mImpl{}
136{
137}
138
139DigitSink::~DigitSink() = default;
140
141bool DigitSink::write(gsl::span<const Digit> digits,
142 gsl::span<const ROFRecord> rofs)
143{
144 if (digits.empty()) {
145 return false;
146 }
147
148 bool ok{true};
149
150 if (mBinary) {
151 auto pos = static_cast<size_t>(mOutput.tellp());
152 auto newSize = (pos + digits.size_bytes() + rofs.size_bytes()) / 1024;
153 if (newSize >= mMaxSize) {
154 return false;
155 }
156 ok = mImpl->write(mOutput, digits, rofs);
157 } else {
158 printDigitsAndRofs(mOutput, digits, rofs);
159 }
160 return ok;
161}
162
163} // namespace o2::mch::io
std::string asString(TDataMember const &dm, char *pointer)
int32_t i
Definition of the MCH ROFrame record.
uint16_t pos
Definition RawData.h:3
uint32_t j
Definition RawData.h:0
MCH digit implementation.
Definition Digit.h:31
int getPadID() const
Definition Digit.h:54
int getDetID() const
Definition Digit.h:52
uint16_t getNofSamples() const
Definition Digit.cxx:39
bool isSaturated() const
Definition Digit.cxx:44
int32_t getTime() const
Definition Digit.h:44
uint32_t getADC() const
Definition Digit.h:57
int getLastIdx() const
get the index of the last associated object
Definition ROFRecord.h:59
const BCData & getBCData() const
get the interaction record
Definition ROFRecord.h:46
int getFirstIdx() const
get the index of the first associated object
Definition ROFRecord.h:57
GLboolean r
Definition glcorearb.h:1233
GLint GLint GLsizei GLint GLenum format
Definition glcorearb.h:275
std::unique_ptr< DigitSinkImpl > createDigitSinkImpl(int version)
value_T d2
Definition TrackUtils.h:135
std::string asString() const
uint16_t bc
bunch crossing ID of interaction
std::vector< Digit > digits