EventLoaderEUDAQ2.cpp 7.96 KB
Newer Older
1
2
/**
 * @file
3
 * @brief Implementation of EventLoaderEUDAQ2 module
4
 * @copyright Copyright (c) 2019 CERN and the Corryvreckan authors.
5
6
7
8
9
10
 * This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
 * In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
 * Intergovernmental Organization or submit itself to any jurisdiction.
 */

#include "EventLoaderEUDAQ2.h"
11
#include "eudaq/FileReader.hh"
12
13
14

using namespace corryvreckan;

15
16
EventLoaderEUDAQ2::EventLoaderEUDAQ2(Configuration config, std::shared_ptr<Detector> detector)
    : Module(std::move(config), detector), m_detector(detector) {
17

18
    m_filename = m_config.getPath("file_name", true);
19
    m_skip_time = m_config.get("skip_time", 0.);
20
}
21

22
void EventLoaderEUDAQ2::initialise() {
23

24
25
26
27
28
29
30
31
    // open the input file with the eudaq reader
    try {
        reader_ = eudaq::Factory<eudaq::FileReader>::MakeUnique(eudaq::str2hash("native"), m_filename);
    } catch(...) {
        LOG(ERROR) << "eudaq::FileReader could not read the input file ' " << m_filename
                   << " '. Please verify that the path and file name are correct.";
        throw InvalidValueError(m_config, "file_path", "Parsing error!");
    }
32
33
}

34
35
36
37
38
39
40
41
42
43
44
45
46
std::shared_ptr<eudaq::StandardEvent> EventLoaderEUDAQ2::get_next_event() {
    auto stdevt = eudaq::StandardEvent::MakeShared();
    bool decoding_failed = true;

    do {
        // Check if we need a new full event or if we still have some in the cache:
        if(events_.empty()) {
            LOG(TRACE) << "Reading new EUDAQ event from file";
            auto new_event = reader_->GetNextEvent();
            if(!new_event) {
                LOG(DEBUG) << "Reached EOF";
                throw EndOfFile();
            }
47
            // Build buffer from all sub-events:
48
            events_ = new_event->GetSubEvents();
49
            // The main event might also contain data, so add it to the buffer:
Simon Spannagel's avatar
Simon Spannagel committed
50
51
52
            if(events_.empty()) {
                events_.push_back(new_event);
            }
53

54
            // FIXME get TLU events with trigger IDs before Ni - sort by name, reversed
55
56
57
58
59
            sort(events_.begin(), events_.end(), [](const eudaq::EventSPC& a, const eudaq::EventSPC& b) -> bool {
                return a->GetDescription() > b->GetDescription();
            });
        }
        LOG(TRACE) << "Buffer contains " << events_.size() << " (sub-) events";
60

61
62
63
        auto event = events_.front();
        events_.erase(events_.begin());
        decoding_failed = !eudaq::StdEventConverter::Convert(event, stdevt, nullptr);
Simon Spannagel's avatar
Simon Spannagel committed
64
        LOG(DEBUG) << event->GetDescription() << ": Decoding " << (decoding_failed ? "failed" : "succeeded");
65
66
67
    } while(decoding_failed);
    return stdevt;
}
68

69
70
EventLoaderEUDAQ2::EventPosition EventLoaderEUDAQ2::is_within_event(std::shared_ptr<Clipboard> clipboard,
                                                                    std::shared_ptr<eudaq::StandardEvent> evt) {
71

72
    // Check if this event has timestamps available:
73
    if(evt->GetTimeBegin() == 0) {
Simon Spannagel's avatar
Simon Spannagel committed
74
        LOG(DEBUG) << evt->GetDescription() << ": Event has no timestamp, comparing trigger number";
75

76
77
78
79
80
        // If there is no event defined yet or the trigger number is unkown, there is little we can do:
        if(!clipboard->event_defined() || !clipboard->get_event()->hasTriggerID(evt->GetTriggerN())) {
            LOG(DEBUG) << "Trigger ID not found in current event.";
            return EventPosition::UNKNOWN;
        }
81

82
83
84
85
86
87
        // Store trigger timestamp in event:
        auto trigger_time = clipboard->get_event()->getTriggerTime(evt->GetTriggerN());
        LOG(DEBUG) << "Assigning trigger time " << Units::display(trigger_time, {"us", "ns"}) << " to event with trigger ID "
                   << evt->GetTriggerN();
        evt->SetTimeBegin(trigger_time);
        evt->SetTimeEnd(trigger_time);
88
    }
89

90
91
    double event_start = evt->GetTimeBegin();
    double event_end = evt->GetTimeEnd();
Jens Kroeger's avatar
Jens Kroeger committed
92

93
94
95
96
97
98
99
    // Skip if later start is requested:
    if(event_start < m_skip_time) {
        LOG(DEBUG) << "Event start before requested skip time: " << Units::display(event_start, {"us", "ns"}) << " < "
                   << Units::display(m_skip_time, {"us", "ns"});
        return EventPosition::BEFORE;
    }

100
    if(!clipboard->event_defined()) {
101
        LOG(DEBUG) << "Defining Corryvreckan event: " << Units::display(event_start, {"us", "ns"}) << " - "
Simon Spannagel's avatar
Simon Spannagel committed
102
103
                   << Units::display(event_end, {"us", "ns"}) << ", length "
                   << Units::display(event_end - event_start, {"us", "ns"});
104
        clipboard->put_event(std::make_shared<Event>(event_start, event_end));
105
    }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

    double clipboard_start = clipboard->get_event()->start();
    double clipboard_end = clipboard->get_event()->end();

    if(event_start < clipboard_start) {
        LOG(DEBUG) << "Event start before Corryvreckan event: " << Units::display(event_start, {"us", "ns"}) << " < "
                   << Units::display(clipboard_start, {"us", "ns"});
        return EventPosition::BEFORE;
    } else if(clipboard_end < event_end) {
        LOG(DEBUG) << "Event end after Corryvreckan event: " << Units::display(event_end, {"us", "ns"}) << " > "
                   << Units::display(clipboard_end, {"us", "ns"});
        return EventPosition::AFTER;
    } else {
        // Store potential trigger numbers, assign to center of event:
        clipboard->get_event()->addTrigger(evt->GetTriggerN(), (event_start + event_start) / 2);
        LOG(DEBUG) << "Stored trigger ID " << evt->GetTriggerN() << " at "
                   << Units::display((event_start + event_start) / 2, {"us", "ns"});
        return EventPosition::DURING;
124
    }
125
}
126

127
void EventLoaderEUDAQ2::store_data(std::shared_ptr<Clipboard> clipboard, std::shared_ptr<eudaq::StandardEvent> evt) {
128

129
130
    Pixels* pixels = new Pixels();

131
132
133
    // Loop over all planes, select the relevant detector:
    for(size_t i_plane = 0; i_plane < evt->NumPlanes(); i_plane++) {
        auto plane = evt->GetPlane(i_plane);
134

135
        // Concatenate plane name according to naming convention: sensor_type + "_" + int
136
137
138
139
        auto plane_name = plane.Sensor() + "_" + std::to_string(i_plane);
        if(m_detector->name() != plane_name) {
            continue;
        }
Jens Kroeger's avatar
Jens Kroeger committed
140

141
        // Loop over all hits and add to pixels vector:
142
        for(unsigned int i = 0; i < plane.GetPixels<int>().size(); i++) {
143
144
            auto col = static_cast<int>(plane.GetX(i));
            auto row = static_cast<int>(plane.GetY(i));
145
146
147
            if(m_detector->masked(col, row)) {
                continue;
            }
148

149
150
            Pixel* pixel =
                new Pixel(m_detector->name(), row, col, static_cast<int>(plane.GetPixel(i)), plane.GetTimestamp(i));
151
            pixels->push_back(pixel);
152
153
        }
    }
154

155
    if(!pixels->empty()) {
156
        LOG(DEBUG) << "Detector " << m_detector->name() << " has " << pixels->size() << " pixels";
157
158
159
        clipboard->put(m_detector->name(), "pixels", reinterpret_cast<Objects*>(pixels));
    } else {
        delete pixels;
160
161
162
163
164
    }
}

StatusCode EventLoaderEUDAQ2::run(std::shared_ptr<Clipboard> clipboard) {

165
    EventPosition current_position = EventPosition::UNKNOWN;
166
    while(1) {
167
168
169
170
171
172
        // Retrieve next event from file/buffer:
        if(!event_) {
            try {
                event_ = get_next_event();
            } catch(EndOfFile&) {
                return StatusCode::EndRun;
173
            }
174
        }
175

176
177
178
179
180
181
182
        // Check if this event is within the currently defined Corryvreckan event:
        current_position = is_within_event(clipboard, event_);
        if(current_position == EventPosition::DURING) {
            LOG(DEBUG) << "Is withing current event, storing data";
            // Store data on the clipboard
            store_data(clipboard, event_);
        }
183

184
185
186
187
        // If this event was after the current event, stop reading:
        if(current_position == EventPosition::AFTER) {
            break;
        }
188

189
190
        // Reset this event to get a new one:
        event_.reset();
191
    }
192

193
    LOG(DEBUG) << "Finished Corryvreckan event";
194
    return StatusCode::Success;
195
}