FileReader.cpp 8.89 KB
Newer Older
1
2
#include "FileReader.h"

3
using namespace corryvreckan;
4
using namespace std;
5

6
7
FileReader::FileReader(Configuration config, std::vector<Detector*> detectors)
    : Algorithm(std::move(config), std::move(detectors)) {
8
9
10
11
12
13
14

    m_onlyDUT = m_config.get<bool>("onlyDUT", false);
    m_readPixels = m_config.get<bool>("readPixels", true);
    m_readClusters = m_config.get<bool>("readClusters", false);
    m_readTracks = m_config.get<bool>("readTracks", false);
    m_fileName = m_config.get<std::string>("fileName", "outputTuples.root");
    m_timeWindow = m_config.get<double>("timeWindow", 1.);
15
    m_readMCParticles = m_config.get<bool>("readMCParticles", false);
16

Simon Spannagel's avatar
Simon Spannagel committed
17
    m_currentTime = 0.;
18
19
20
}

/*
21

22
23
 This algorithm reads an input file containing trees with data previously
 written out by the FileWriter.
24

25
26
27
28
29
30
31
 Any object which inherits from TestBeamObject can in principle be read
 from file. In order to enable this for a new type, the TestBeamObject::Factory
 function must know how to return an instantiation of that type (see
 TestBeamObject.C file to see how to do this). The new type can then simply
 be added to the object list and will be read in correctly. This is the same
 as for the FileWriter, so if the data has been written then the reading will
 run without problems.
32

33
34
 */

35
void FileReader::initialise() {
36

Simon Spannagel's avatar
Simon Spannagel committed
37
38
39
40
41
42
43
    // Decide what objects will be read in
    if(m_readPixels)
        m_objectList.push_back("pixels");
    if(m_readClusters)
        m_objectList.push_back("clusters");
    if(m_readTracks)
        m_objectList.push_back("tracks");
44
45
    if(m_readMCParticles)
        m_objectList.push_back("mcparticles");
46

Simon Spannagel's avatar
Simon Spannagel committed
47
48
49
    // Get input file
    LOG(INFO) << "Opening file " << m_fileName;
    m_inputFile = new TFile(m_fileName.c_str(), "READ");
50
51
52
    if(!m_inputFile->IsOpen()) {
        throw AlgorithmError("Cannot open input file \"" + m_fileName + "\".");
    }
Simon Spannagel's avatar
Simon Spannagel committed
53
    m_inputFile->cd();
54

Simon Spannagel's avatar
Simon Spannagel committed
55
56
    // Loop over all objects to be read from file, and get the trees
    for(unsigned int itList = 0; itList < m_objectList.size(); itList++) {
57

Simon Spannagel's avatar
Simon Spannagel committed
58
59
        // Check the type of object
        string objectType = m_objectList[itList];
60

Simon Spannagel's avatar
Simon Spannagel committed
61
        // Section to set up object reading per detector (such as pixels, clusters)
62
        if(objectType == "pixels" || objectType == "clusters" || objectType == "mcparticles") {
63

Simon Spannagel's avatar
Simon Spannagel committed
64
            // Loop over all detectors and search for data
65
            for(auto& detector : get_detectors()) {
66

Simon Spannagel's avatar
Simon Spannagel committed
67
                // Get the detector ID and type
68
69
                string detectorID = detector->name();
                string detectorType = detector->type();
70

Simon Spannagel's avatar
Simon Spannagel committed
71
                // If only reading information for the DUT
72
                if(m_onlyDUT && detectorID != m_config.get<std::string>("DUT"))
Simon Spannagel's avatar
Simon Spannagel committed
73
                    continue;
74

Simon Spannagel's avatar
Simon Spannagel committed
75
                LOG(DEBUG) << "Looking for " << objectType << " for device " << detectorID;
76

Simon Spannagel's avatar
Simon Spannagel committed
77
78
79
80
                // Get the tree
                string objectID = detectorID + "_" + objectType;
                string treePath = objectType + "/" + detectorID + "_" + detectorType + "_" + objectType;
                m_inputTrees[objectID] = (TTree*)gDirectory->Get(treePath.c_str());
81

Simon Spannagel's avatar
Simon Spannagel committed
82
83
                // Set the branch addresses
                m_inputTrees[objectID]->SetBranchAddress("time", &m_time);
84

Simon Spannagel's avatar
Simon Spannagel committed
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
                // Cast the TestBeamObject as a specific type using a Factory
                m_objects[objectID] = TestBeamObject::Factory(detectorType, objectType);
                m_inputTrees[objectID]->SetBranchAddress(objectType.c_str(), &m_objects[objectID]);
                m_currentPosition[objectID] = 0;
            }
        }
        // If not an object to be written per pixel
        else {
            // Make the tree
            string treePath = objectType + "/" + objectType;
            m_inputTrees[objectType] = (TTree*)gDirectory->Get(treePath.c_str());
            // Branch the tree to the timestamp and object
            m_inputTrees[objectType]->SetBranchAddress("time", &m_time);
            m_objects[objectType] = TestBeamObject::Factory(objectType);
            m_inputTrees[objectType]->SetBranchAddress(objectType.c_str(), &m_objects[objectType]);
        }
101
    }
102

Simon Spannagel's avatar
Simon Spannagel committed
103
104
    // Initialise member variables
    m_eventNumber = 0;
105
106
}

Simon Spannagel's avatar
Simon Spannagel committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
StatusCode FileReader::run(Clipboard* clipboard) {

    LOG_PROGRESS(INFO, "file_reader") << "Running over event " << m_eventNumber;

    bool newEvent = true;
    // Loop over all objects read from file, and place the objects on the
    // Clipboard
    bool dataLoaded = false;
    for(unsigned int itList = 0; itList < m_objectList.size(); itList++) {

        // Check the type of object
        string objectType = m_objectList[itList];

        // If this is written per device, loop over all devices
121
        if(objectType == "pixels" || objectType == "clusters" || objectType == "mcparticles") {
Simon Spannagel's avatar
Simon Spannagel committed
122
123

            // Loop over all detectors
124
            for(auto& detector : get_detectors()) {
Simon Spannagel's avatar
Simon Spannagel committed
125
126

                // Get the detector and object ID
127
128
                string detectorID = detector->name();
                string detectorType = detector->type();
Simon Spannagel's avatar
Simon Spannagel committed
129
130
131
                string objectID = detectorID + "_" + objectType;

                // If only writing information for the DUT
132
                if(m_onlyDUT && detectorID != m_config.get<std::string>("DUT"))
Simon Spannagel's avatar
Simon Spannagel committed
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
                    continue;

                // If there is no data for this device, continue
                if(!m_inputTrees[objectID])
                    continue;

                // Create the container that will go on the clipboard
                TestBeamObjects* objectContainer = new TestBeamObjects();
                LOG(DEBUG) << "Looking for " << objectType << " on detector " << detectorID;

                // Continue looping over this device while there is still data
                while(m_currentPosition[objectID] < m_inputTrees[objectID]->GetEntries()) {

                    // Get the new event from the tree
                    m_inputTrees[objectID]->GetEvent(m_currentPosition[objectID]);

                    // If the event is outwith the current time window, stop loading data
                    if((m_time - m_currentTime) > m_timeWindow) {
                        if(newEvent) {
                            m_currentTime = m_time;
                            newEvent = false;
                        } else {
                            break;
                        }
                    }
                    dataLoaded = true;
                    m_currentPosition[objectID]++;

                    // Make a copy of the object from the tree, and place it in the object
                    // container
                    TestBeamObject* object = TestBeamObject::Factory(detectorType, objectType, m_objects[objectID]);
                    objectContainer->push_back(object);
                }

                // Put the data on the clipboard
                clipboard->put(detectorID, objectType, objectContainer);
                LOG(DEBUG) << "Picked up " << objectContainer->size() << " " << objectType << " from device " << detectorID;
            }
        } // If object is not written per device
        else {

            // If there is no data for this device, continue
            if(!m_inputTrees[objectType])
                continue;

            // Create the container that will go on the clipboard
            TestBeamObjects* objectContainer = new TestBeamObjects();
            LOG(DEBUG) << "Looking for " << objectType;

            // Continue looping over this device while there is still data
            while(m_currentPosition[objectType] < m_inputTrees[objectType]->GetEntries()) {

                // Get the new event from the tree
                m_inputTrees[objectType]->GetEvent(m_currentPosition[objectType]);

                // If the event is outwith the current time window, stop loading data
                if((m_time - m_currentTime) > m_timeWindow) {
                    if(newEvent) {
                        m_currentTime = m_time;
                        newEvent = false;
                    } else {
                        break;
                    }
                }
                dataLoaded = true;
                m_currentPosition[objectType]++;

                // Make a copy of the object from the tree, and place it in the object
                // container
                TestBeamObject* object = TestBeamObject::Factory(objectType, m_objects[objectType]);
                objectContainer->push_back(object);
204
            }
205

Simon Spannagel's avatar
Simon Spannagel committed
206
207
208
            // Put the data on the clipboard
            clipboard->put(objectType, objectContainer);
            LOG(DEBUG) << "Picked up " << objectContainer->size() << " " << objectType;
209
        }
210
    }
211

Simon Spannagel's avatar
Simon Spannagel committed
212
213
214
215
    // If no data was loaded then do nothing
    if(!dataLoaded && m_eventNumber != 0) {
        return Failure;
    }
216

Simon Spannagel's avatar
Simon Spannagel committed
217
218
    // Increment event counter
    m_eventNumber++;
219

Simon Spannagel's avatar
Simon Spannagel committed
220
221
    // Return value telling analysis to keep running
    return Success;
222
223
}

Simon Spannagel's avatar
Simon Spannagel committed
224
void FileReader::finalise() {
225

Simon Spannagel's avatar
Simon Spannagel committed
226
227
    // Close the input file
    m_inputFile->Close();
228

Simon Spannagel's avatar
Simon Spannagel committed
229
    LOG(DEBUG) << "Analysed " << m_eventNumber << " events";
230
}