Detector.hpp 14 KB
Newer Older
1
2
/** @file
 *  @brief Detector model class
3
 *  @copyright Copyright (c) 2017-2020 CERN and the Corryvreckan authors.
4
5
6
7
8
 * 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.
 */

9
10
#ifndef CORRYVRECKAN_DETECTOR_H
#define CORRYVRECKAN_DETECTOR_H
11
12
13
14
15
16
17
18
19
20
21

#include <fstream>
#include <map>
#include <string>

#include <Math/DisplacementVector2D.h>
#include <Math/Vector2D.h>
#include <Math/Vector3D.h>
#include "Math/Transform3D.h"
#include "Math/Vector3D.h"

22
23
24
#include "core/config/Configuration.hpp"
#include "core/utils/ROOT.h"
#include "core/utils/log.h"
Simon Spannagel's avatar
Simon Spannagel committed
25
#include "objects/Track.hpp"
26
27

namespace corryvreckan {
28
    using namespace ROOT::Math;
Simon Spannagel's avatar
Simon Spannagel committed
29
30
31
32

    /**
     * @brief Role of the detector
     */
33
34
35
36
    enum class DetectorRole : int {
        NONE = 0x0,      ///< No specific detector role
        REFERENCE = 0x1, ///< Reference detector
        DUT = 0x2,       ///< Detector used as device under test
37
38
        AUXILIARY = 0x4, ///< Auxiliary device which should not participate in regular reconstruction but might provide
                         /// additional information
Simon Spannagel's avatar
Simon Spannagel committed
39
40
    };

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    inline constexpr DetectorRole operator&(DetectorRole x, DetectorRole y) {
        return static_cast<DetectorRole>(static_cast<int>(x) & static_cast<int>(y));
    }

    inline constexpr DetectorRole operator|(DetectorRole x, DetectorRole y) {
        return static_cast<DetectorRole>(static_cast<int>(x) | static_cast<int>(y));
    }

    inline DetectorRole& operator&=(DetectorRole& x, DetectorRole y) {
        x = x & y;
        return x;
    }

    inline DetectorRole& operator|=(DetectorRole& x, DetectorRole y) {
        x = x | y;
        return x;
    }

Simon Spannagel's avatar
Simon Spannagel committed
59
    /**
60
     * @brief Detector interface in the reconstruction chain
Simon Spannagel's avatar
Simon Spannagel committed
61
     *
Jin Zhang's avatar
format    
Jin Zhang committed
62
     * Contains the detector with common properties such as type, name, coordinate
63
     * etc.
Simon Spannagel's avatar
Simon Spannagel committed
64
     */
65
66
    class Detector {
    public:
67
68
69
        /**
         * Delete default constructor
         */
70
        Detector() = delete;
71

Jin Zhang's avatar
format    
Jin Zhang committed
72
        /**
73
         * Default destructor
Jin Zhang's avatar
format    
Jin Zhang committed
74
75
76
         */
        virtual ~Detector() = default;

77
78
79
80
81
        /**
         * @brief Constructs a detector in the geometry
         * @param config Configuration object describing the detector
         */
        Detector(const Configuration& config);
82

83
84
        /**
         * @brief Factory to dynamically create detectors
Jin Zhang's avatar
Jin Zhang committed
85
86
         * @param config Configuration object describing the detector
         * @return shared_ptr that contains the real detector
87
         */
Jin Zhang's avatar
Jin Zhang committed
88
        static std::shared_ptr<Detector> factory(const Configuration& config);
89

90
91
92
93
        /**
         * @brief Get type of the detector
         * @return Type of the detector model
         */
Jin Zhang's avatar
Jin Zhang committed
94
        std::string getType() const;
95
96
97
98
99

        /**
         * @brief Get name of the detector
         * @return Detector name
         */
Jin Zhang's avatar
Jin Zhang committed
100
        std::string getName() const;
101
102
103
104
105

        /**
         * @brief Check whether detector is registered as reference
         * @return Reference status
         */
106
        bool isReference() const;
107
108
109
110
111

        /**
         * @brief Check whether detector is registered as DUT
         * @return DUT status
         */
112
        bool isDUT() const;
113

114
115
116
117
118
119
        /**
         * @brief Check whether detector is registered as auxiliary device and should not parttake in the reconstruction
         * @return Auxiliary status
         */
        bool isAuxiliary() const;

120
121
122
123
        /**
         * @brief Retrieve configuration object from detector, containing all (potentially updated) parameters
         * @return Configuration object for this detector
         */
124
        Configuration getConfiguration() const;
125

126
127
128
        /**
         * @brief Get the total size of the active matrix, i.e. pitch * number of pixels in both dimensions
         * @return 2D vector with the dimensions of the pixle matrix in X and Y
Jin Zhang's avatar
Jin Zhang committed
129
         * @to do: this is designed for PixelDetector, find a proper interface for other Detector type
130
         */
Jin Zhang's avatar
Jin Zhang committed
131
        virtual XYVector getSize() const = 0;
132
133
134
135

        /**
         * @brief Get pitch of a single pixel
         * @return Pitch of a pixel
Jin Zhang's avatar
Jin Zhang committed
136
         * @to do: this is designed for PixelDetector, find a proper interface for other Detector type
137
         */
Jin Zhang's avatar
Jin Zhang committed
138
        virtual XYVector getPitch() const = 0;
139
140

        /**
141
142
         * @brief Get intrinsic spatial resolution of the detector
         * @return Intrinsic spatial resolution in X and Y
Jin Zhang's avatar
Jin Zhang committed
143
         * @to do: this is designed for PixelDetector, find a proper interface for other Detector type
144
         */
145
        virtual XYVector getSpatialResolution() const = 0;
Simon Spannagel's avatar
Simon Spannagel committed
146

147
148
149
        /**
         * @brief Get number of pixels in x and y
         * @return Number of two dimensional pixels
Jin Zhang's avatar
Jin Zhang committed
150
         * @to do: this is designed for PixelDetector, find a proper interface for other Detector type
151
         */
152
        virtual ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<int>> nPixels() const = 0;
153
154
155

        /**
         * @brief Get detector time offset from global clock, can be used to correct for constant shifts or time of flight
156
         * @return Time offset of respective detector
157
         */
158
        double timeOffset() const { return m_timeOffset; }
159

160
        /**
161
162
         * @brief Get detector time resolution, used for timing cuts during clustering, track formation, etc.
         * @return Time resolutiom of respective detector
163
         */
164
        double getTimeResolution() const;
165

166
167
168
169
        /**
         * @brief Update detector position in the world
         * @param displacement Vector with three position coordinates
         */
170
        virtual void displacement(XYZPoint displacement) = 0;
171
172
173
174
175

        /**
         * @brief Get position in the world
         * @return Global position in Cartesian coordinates
         */
176
        virtual XYZPoint displacement() const = 0;
177

178
179
180
181
        /**
         * @brief Get orientation in the world
         * @return Vector with three rotation angles
         */
182
        virtual XYZVector rotation() const = 0;
183
184
185
186
187

        /**
         * @brief Update detector orientation in the world
         * @param rotation Vector with three rotation angles
         */
188
        virtual void rotation(XYZVector rotation) = 0;
189

190
191
192
193
        /**
         * @brief Get normal vector to sensor surface
         * @return Normal vector to sensor surface
         */
194
        PositionVector3D<Cartesian3D<double>> normal() const { return m_normal; }
195
196

        /**
197
         * @brief Get origin vector to sensor surface
198
199
         * @return Origin vector to sensor surface
         */
200
        PositionVector3D<Cartesian3D<double>> origin() const { return m_origin; }
201

202
203
204
205
206
207
208
209
210
        /**
         * @brief Get path of the file with calibration information
         * @return Path of the calibration file
         *
         * @note The data contained in the calibration file is detector-specific and is
         * not parsed. This is left to the individual modules decoding the detector data.
         */
        std::string calibrationFile() const { return m_calibrationfile; }

211
212
213
214
215
216
        /**
         * @brief Set the file with pixel mask information
         * @param file New mask file name
         */
        void maskFile(std::string file);

217
218
219
220
        /**
         * @brief Get path of the file with pixel mask information
         * @return Path of the pixel mask file
         */
221
        std::string maskFile() const { return m_maskfile; }
222
223
224
225
226

        /**
         * @brief Mark a detector channel as masked
         * @param chX X coordinate of the pixel to be masked
         * @param chY Y coordinate of the pixel to be masked
Jin Zhang's avatar
Jin Zhang committed
227
         * @to do: This is designed for PixelDetector, the parameters can be different with other type of Detector
228
         */
Jin Zhang's avatar
Jin Zhang committed
229
        virtual void maskChannel(int chX, int chY) = 0;
230
231
232
233
234
235

        /**
         * @brief Check if a detector channel is masked
         * @param chX X coordinate of the pixel to check
         * @param chY Y coordinate of the pixel to check
         * @return    Mask status of the pixel in question
Jin Zhang's avatar
Jin Zhang committed
236
         * @to do: This is designed for PixelDetector, the parameters can be different with other type of Detector
237
         */
Jin Zhang's avatar
Jin Zhang committed
238
        virtual bool masked(int chX, int chY) const = 0;
239

240
241
242
        /**
         * @brief Update coordinate transformations based on currently configured position and orientation values
         */
243
244
245
        void update();

        // Function to get global intercept with a track
246
        virtual PositionVector3D<Cartesian3D<double>> getIntercept(const Track* track) const = 0;
247
        // Function to get local intercept with a track
248
        virtual PositionVector3D<Cartesian3D<double>> getLocalIntercept(const Track* track) const = 0;
249
250

        // Function to check if a track intercepts with a plane
251
        virtual bool hasIntercept(const Track* track, double pixelTolerance = 0.) const = 0;
252
253

        // Function to check if a track goes through/near a masked pixel
254
        virtual bool hitMasked(const Track* track, int tolerance = 0.) const = 0;
255
256

        // Functions to get row and column from local position
257
        virtual double getRow(PositionVector3D<Cartesian3D<double>> localPosition) const = 0;
Jin Zhang's avatar
format    
Jin Zhang committed
258
        virtual double getColumn(PositionVector3D<Cartesian3D<double>> localPosition) const = 0;
259

260
        // Function to get local position from column (x) and row (y) coordinates
261
        virtual PositionVector3D<Cartesian3D<double>> getLocalPosition(double column, double row) const = 0;
262

263
264
        /**
         * Transformation from local (sensor) coordinates to in-pixel coordinates
265
266
         * @param  column Column address ranging from int_column-0.5*pitch to int_column+0.5*pitch
         * @param  row Row address ranging from int_column-0.5*pitch to int_column+0.5*pitch
267
268
         * @return               Position within a single pixel cell, given in units of length
         */
269
        virtual XYVector inPixel(const double column, const double row) const = 0;
270

271
272
        /**
         * Transformation from local (sensor) coordinates to in-pixel coordinates
273
         * @param  localPosition Local position on the sensor
274
275
         * @return               Position within a single pixel cell, given in units of length
         */
Jin Zhang's avatar
format    
Jin Zhang committed
276
        virtual XYVector inPixel(PositionVector3D<Cartesian3D<double>> localPosition) const = 0;
277

278
279
280
281
282
        /**
         * @brief Transform local coordinates of this detector into global coordinates
         * @param  local Local coordinates in the reference frame of this detector
         * @return       Global coordinates
         */
283
        XYZPoint localToGlobal(XYZPoint local) const { return m_localToGlobal * local; };
284
285
286
287
288
289

        /**
         * @brief Transform global coordinates into detector-local coordinates
         * @param  global Global coordinates
         * @return        Local coordinates in the reference frame of this detector
         */
290
        XYZPoint globalToLocal(XYZPoint global) const { return m_globalToLocal * global; };
291

292
293
294
295
296
        /**
         * @brief Check whether given track is within the detector's region-of-interest
         * @param  track The track to be checked
         * @return       Boolean indicating cluster affiliation with region-of-interest
         */
297
        virtual bool isWithinROI(const Track* track) const = 0;
298
299
300
301
302
303

        /**
         * @brief Check whether given cluster is within the detector's region-of-interest
         * @param  cluster The cluster to be checked
         * @return         Boolean indicating cluster affiliation with region-of-interest
         */
304
        virtual bool isWithinROI(Cluster* cluster) const = 0;
305

Lennart Huth's avatar
Lennart Huth committed
306
        /**
307
         * @brief Return the thickness of the senosr assembly layer (sensor+support) in fractions of radiation length
Lennart Huth's avatar
Lennart Huth committed
308
         * @return thickness in fractions of radiation length
Lennart Huth's avatar
Lennart Huth committed
309
         */
310
        double materialBudget() const { return m_materialBudget; }
Lennart Huth's avatar
Lennart Huth committed
311

312
        /**
313
314
         * @brief toGlobal Get the transformation from local to global coordinates
         * @return Transform3D local to global
315
         */
Lennart Huth's avatar
Lennart Huth committed
316
        Transform3D toGlobal() const { return m_localToGlobal; }
317
318

        /**
319
320
         * @brief toLocal Get the transformation from global to local coordinates
         * @return Transform3D global to local
321
         */
Lennart Huth's avatar
Lennart Huth committed
322
323
        Transform3D toLocal() const { return m_globalToLocal; }

zhangjin's avatar
zhangjin committed
324
        /**
zhangjin's avatar
zhangjin committed
325
         * @brief Test whether one pixel touches the cluster
zhangjin's avatar
zhangjin committed
326
         * @return true if it fulfills the condition
zhangjin's avatar
zhangjin committed
327
328
         * @note users should define their specific clustering method in the detector class
         */
329
        virtual bool isNeighbor(const std::shared_ptr<Pixel>&, const std::shared_ptr<Cluster>&, const int, const int) = 0;
zhangjin's avatar
zhangjin committed
330

Jin Zhang's avatar
format    
Jin Zhang committed
331
    protected:
332
        // Roles of the detector
Simon Spannagel's avatar
Simon Spannagel committed
333
334
        DetectorRole m_role;

335
        // Initialize coordinate transformations
Jin Zhang's avatar
Jin Zhang committed
336
337
        virtual void initialise() = 0;

338
        // Build axis, for devices which are not auxiliary
Jin Zhang's avatar
Jin Zhang committed
339
        // Different in Pixel/Strip Detector
Jin Zhang's avatar
Jin Zhang committed
340
        virtual void build_axes(const Configuration& config) = 0;
Jin Zhang's avatar
Jin Zhang committed
341

342
        // Config detector, for devices which are not auxiliary
Jin Zhang's avatar
Jin Zhang committed
343
        // Different in Pixel/Strip Detector
Jin Zhang's avatar
Jin Zhang committed
344
        virtual void configure_detector(Configuration& config) const = 0;
345
        // Set position, orientation, mode of detector
Jin Zhang's avatar
Jin Zhang committed
346
        // Different in Pixel/Strip Detector
Jin Zhang's avatar
Jin Zhang committed
347
        virtual void configure_pos_and_orientation(Configuration& config) const = 0;
348

Jin Zhang's avatar
Jin Zhang committed
349
        virtual void process_mask_file() = 0;
350

351
352
353
        // Detector information
        std::string m_detectorType;
        std::string m_detectorName;
Jin Zhang's avatar
Jin Zhang committed
354

355
        double m_timeOffset;
356
        double m_timeResolution;
357
        double m_materialBudget;
358
359

        // Transforms from local to global and back
360
361
        Transform3D m_localToGlobal;
        Transform3D m_globalToLocal;
362
363
364
365
366

        // Normal to the detector surface and point on the surface
        PositionVector3D<Cartesian3D<double>> m_normal;
        PositionVector3D<Cartesian3D<double>> m_origin;

367
368
        // Path of calibration file
        std::string m_calibrationfile;
369

370
371
372
373
        // List of masked channels
        std::map<int, bool> m_masked;
        std::string m_maskfile;
    };
374
} // namespace corryvreckan
375

Jin Zhang's avatar
Jin Zhang committed
376
#include "PixelDetector.hpp"
377
#endif // CORRYVRECKAN_DETECTOR_H