FileWriter.cpp 8.14 KB
Newer Older
1
#include "FileWriter.h"
2
#include "core/utils/file.h"
3

4
using namespace corryvreckan;
5
using namespace std;
6

7
FileWriter::FileWriter(Configuration config, std::vector<std::shared_ptr<Detector>> detectors)
8
    : Module(std::move(config), std::move(detectors)) {
9

10
11
12
13
14
    m_onlyDUT = m_config.get<bool>("only_dut", true);
    m_writePixels = m_config.get<bool>("write_pixels", true);
    m_writeClusters = m_config.get<bool>("write_clusters", false);
    m_writeTracks = m_config.get<bool>("write_tracks", true);
    m_fileName = m_config.get<std::string>("file_name", "outputTuples.root");
15
16
17
}

/*
18

19
 This algorithm writes an output file and fills it with trees containing
20
21
 the requested data.

22
23
 Any object which inherits from Object can in principle be written
 to file. In order to enable this for a new type, the Object::Factory
24
 function must know how to return an instantiation of that type (see
25
 Object.C file to see how to do this). The new type can then simply
26
 be added to the object list and will be written out correctly.
27

28
29
 */

30
void FileWriter::initialise() {
31

Simon Spannagel's avatar
Simon Spannagel committed
32
33
34
35
36
37
38
    // Decide what objects will be written out
    if(m_writePixels)
        m_objectList.push_back("pixels");
    if(m_writeClusters)
        m_objectList.push_back("clusters");
    if(m_writeTracks)
        m_objectList.push_back("tracks");
39

Simon Spannagel's avatar
Simon Spannagel committed
40
    // Create output file and directories
41
42
    auto path = createOutputFile(add_file_extension(m_fileName, "root"), true);
    m_outputFile = new TFile(path.c_str(), "RECREATE");
Simon Spannagel's avatar
Simon Spannagel committed
43
    m_outputFile->cd();
44

Simon Spannagel's avatar
Simon Spannagel committed
45
46
    // Loop over all objects to be written to file, and set up the trees
    for(unsigned int itList = 0; itList < m_objectList.size(); itList++) {
47

Simon Spannagel's avatar
Simon Spannagel committed
48
49
        // Check the type of object
        string objectType = m_objectList[itList];
50

Simon Spannagel's avatar
Simon Spannagel committed
51
52
53
        // Make a directory in the ouput folder
        m_outputFile->mkdir(objectType.c_str());
        m_outputFile->cd(objectType.c_str());
54

Simon Spannagel's avatar
Simon Spannagel committed
55
56
        // Section to set up object writing per detector (such as pixels, clusters)
        if(objectType == "pixels" || objectType == "clusters") {
57

Simon Spannagel's avatar
Simon Spannagel committed
58
            // Loop over all detectors and make trees for data
59
            for(auto& detector : get_detectors()) {
60

Simon Spannagel's avatar
Simon Spannagel committed
61
                // Get the detector ID and type
62
63
                string detectorID = detector->name();
                string detectorType = detector->type();
64

Simon Spannagel's avatar
Simon Spannagel committed
65
                // If only writing information for the DUT
66
                if(m_onlyDUT && !detector->isDUT())
Simon Spannagel's avatar
Simon Spannagel committed
67
                    continue;
68

Simon Spannagel's avatar
Simon Spannagel committed
69
70
71
72
73
                // Create the tree
                string objectID = detectorID + "_" + objectType;
                string treeName = detectorID + "_" + detectorType + "_" + objectType;
                m_outputTrees[objectID] = new TTree(treeName.c_str(), treeName.c_str());
                m_outputTrees[objectID]->Branch("time", &m_time);
74

75
                // Cast the Object as a specific type using a Factory
Simon Spannagel's avatar
Simon Spannagel committed
76
                // This will return a Timepix1Pixel*, Timepix3Pixel* etc.
77
                m_objects[objectID] = Object::Factory(detectorType, objectType);
Simon Spannagel's avatar
Simon Spannagel committed
78
79
80
81
82
83
84
85
86
87
                m_outputTrees[objectID]->Branch(objectType.c_str(), &m_objects[objectID]);
            }
        }
        // If not an object to be written per detector
        else {
            // Make the tree
            string treeName = objectType;
            m_outputTrees[objectType] = new TTree(treeName.c_str(), treeName.c_str());
            // Branch the tree to the timestamp and object
            m_outputTrees[objectType]->Branch("time", &m_time);
88
            m_objects[objectType] = Object::Factory(objectType);
Simon Spannagel's avatar
Simon Spannagel committed
89
90
            m_outputTrees[objectType]->Branch(objectType.c_str(), &m_objects[objectType]);
        }
91
    }
92

Simon Spannagel's avatar
Simon Spannagel committed
93
94
    // Initialise member variables
    m_eventNumber = 0;
95
96
}

97
StatusCode FileWriter::run(std::shared_ptr<Clipboard> clipboard) {
Simon Spannagel's avatar
Simon Spannagel committed
98
99
100
101
102
103
104
105
106
107
108
109

    // Loop over all objects to be written to file, and get the objects currently
    // held on the Clipboard
    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
        if(objectType == "pixels" || objectType == "clusters") {

            // Loop over all detectors
110
            for(auto& detector : get_detectors()) {
Simon Spannagel's avatar
Simon Spannagel committed
111
112

                // Get the detector and object ID
113
                string detectorID = detector->name();
Simon Spannagel's avatar
Simon Spannagel committed
114
115
116
                string objectID = detectorID + "_" + objectType;

                // If only writing information for the DUT
117
                if(m_onlyDUT && !detector->isDUT())
Simon Spannagel's avatar
Simon Spannagel committed
118
119
120
121
                    continue;

                // Get the objects, if they don't exist then continue
                LOG(DEBUG) << "Checking for " << objectType << " on device " << detectorID;
122
                Objects* objects = clipboard->get(detectorID, objectType);
123
                if(objects == nullptr)
Simon Spannagel's avatar
Simon Spannagel committed
124
125
126
127
128
129
130
131
                    continue;
                LOG(DEBUG) << "Picked up " << objects->size() << " " << objectType << " from device " << detectorID;

                // Check if the output tree exists
                if(!m_outputTrees[objectID])
                    continue;

                // Fill the objects into the tree
132
133
                for(auto& object : (*objects)) {
                    m_objects[objectID] = object;
Simon Spannagel's avatar
Simon Spannagel committed
134
135
136
137
138
139
140
141
142
                    m_time = m_objects[objectID]->timestamp();
                    m_outputTrees[objectID]->Fill();
                }
            }
        } // If object is not written per device
        else {

            // Get the objects, if they don't exist then continue
            LOG(DEBUG) << "Checking for " << objectType;
143
            Objects* objects = clipboard->get(objectType);
144
            if(objects == nullptr)
Simon Spannagel's avatar
Simon Spannagel committed
145
146
147
148
149
150
151
152
                continue;
            LOG(DEBUG) << "Picked up " << objects->size() << " " << objectType;

            // Check if the output tree exists
            if(!m_outputTrees[objectType])
                continue;

            // Fill the objects into the tree
153
154
            for(auto& object : (*objects)) {
                m_objects[objectType] = object;
Simon Spannagel's avatar
Simon Spannagel committed
155
156
157
158
                m_time = m_objects[objectType]->timestamp();
                m_outputTrees[objectType]->Fill();
            }
            LOG(DEBUG) << "Written " << objectType << " to file";
159
160
161
        }
    }

Simon Spannagel's avatar
Simon Spannagel committed
162
163
    // Increment event counter
    m_eventNumber++;
164

Simon Spannagel's avatar
Simon Spannagel committed
165
    // Return value telling analysis to keep running
166
    return StatusCode::Success;
167
168
}

Simon Spannagel's avatar
Simon Spannagel committed
169
void FileWriter::finalise() {
170

Simon Spannagel's avatar
Simon Spannagel committed
171
    // Write the trees to file
172
    // Loop over all objects to be written to file, and get the objects currently held on the Clipboard
Simon Spannagel's avatar
Simon Spannagel committed
173
    for(unsigned int itList = 0; itList < m_objectList.size(); itList++) {
174

Simon Spannagel's avatar
Simon Spannagel committed
175
176
        // Check the type of object
        string objectType = m_objectList[itList];
177

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

Simon Spannagel's avatar
Simon Spannagel committed
181
            // Loop over all detectors
182
            for(auto& detector : get_detectors()) {
183

Simon Spannagel's avatar
Simon Spannagel committed
184
                // Get the detector and object ID
185
                string detectorID = detector->name();
Simon Spannagel's avatar
Simon Spannagel committed
186
                string objectID = detectorID + "_" + objectType;
187

Simon Spannagel's avatar
Simon Spannagel committed
188
189
190
                // If there is no output tree then do nothing
                if(!m_outputTrees[objectID])
                    continue;
191

Simon Spannagel's avatar
Simon Spannagel committed
192
193
194
195
                // Move to the write output file
                m_outputFile->cd();
                m_outputFile->cd(objectType.c_str());
                m_outputTrees[objectID]->Write();
196

Simon Spannagel's avatar
Simon Spannagel committed
197
198
                // Clean up the tree and remove object pointer
                delete m_outputTrees[objectID];
199
                m_objects[objectID] = nullptr;
Simon Spannagel's avatar
Simon Spannagel committed
200
201
202
            }
        } // Write trees for devices which are not detector dependent
        else {
203

Simon Spannagel's avatar
Simon Spannagel committed
204
205
206
            // If there is no output tree then do nothing
            if(!m_outputTrees[objectType])
                continue;
207

Simon Spannagel's avatar
Simon Spannagel committed
208
209
210
211
            // Move to the write output file
            m_outputFile->cd();
            m_outputFile->cd(objectType.c_str());
            m_outputTrees[objectType]->Write();
212

Simon Spannagel's avatar
Simon Spannagel committed
213
214
            // Clean up the tree and remove object pointer
            delete m_outputTrees[objectType];
215
            m_objects[objectType] = nullptr;
Simon Spannagel's avatar
Simon Spannagel committed
216
        }
217
    }
218

219
220
    // Close the output file
    m_outputFile->Close();
Simon Spannagel's avatar
Simon Spannagel committed
221
    LOG(DEBUG) << "Analysed " << m_eventNumber << " events";
222
}