GCC Code Coverage Report


Directory: ./
File: include/na64detID/wireID.hh
Date: 2025-09-01 06:19:01
Exec Total Coverage
Lines: 37 37 100.0%
Functions: 15 15 100.0%
Branches: 2 2 100.0%

Line Branch Exec Source
1 /* This file is a part of NA64SW software.
2 * Copyright (C) 2015-2022 NA64 Collaboration, CERN
3 *
4 * NA64SW is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17 #pragma once
18
19 #include "na64detID/detectorID.hh"
20
21 #include <limits>
22 #include <map>
23 #include <string>
24
25 namespace na64dp {
26
27 constexpr uint8_t gWireNoOffset = 4;
28 constexpr DetIDPayload_t gProjectionMask = 0b1111;
29
30 /**\brief Auxiliary identifier for APV plane ID
31 *
32 * Identifies plane for APV-based detectors, unique within a station.
33 * For globally uniuqe detector ID type, see `PlaneKey`.
34 *
35 * \todo Full support for from-string conversion for exotic projection codes...
36 * and cover it with UTs!
37 *
38 * \ingroup auxDetID
39 * */
40 struct APVPlaneID {
41 DetIDPayload_t id;
42
43 // 0000
44 // ^^^+- 1st/second coordinate (X,U -> 0, Y,U -> 1)
45 // ||+-- chooses pair X,Y or U/v
46 // |+--- supp pair, if set (i.e. X2, U2, etc)
47 // +---- when not set, is a special (reserved) code, e.g. "unknown"
48
49 /// Describes projection plane of the hit.
50 enum Projection { kUnknown = 0
51 /* Main projection codes */
52 , kX = 0x8, kY = 0x8 | 0x1
53 , kU = 0x8 | 0x2, kV = 0x8 | 0x2 | 0x1
54 /* Supplementary projection codes */
55 , kX2 = 0x8 | 0x4, kY2 = 0x8 | 0x4 | 0x1
56 , kU2 = 0x8 | 0x4 | 0x2, kV2 = 0x8 | 0x4 | 0x2 | 0x1
57 /* Special codes */
58 , kXY = 0x1, kUV = 0x2 // usually used by supplementary digits
59 , kP = 0x3, // this is for F1/BMS
60 };
61 /// Returns projection code conjugated to given (Y for X, X for Y, V for
62 /// U, etc).
63 static Projection conjugated_projection_code( Projection );
64 /// Returns a single character corresponding to projection enumeration
65 /// value: X, Y, U, V. For *2 adjoint codes returns ones without `2`.
66 static char proj_label( Projection );
67 /// Returns a projection code by single character
68 static Projection proj_code( char );
69 /// Returns adjoint projection code (X2 for X, V for V2, etc)
70 static Projection adjoint_proj_code( Projection );
71 /// Returns true if projection code is supplementary (e.g. true for 'X2',
72 /// false for 'Y'.
73 18 static bool proj_is_adjoint( Projection p ) { return 0x4 & p; }
74
75 /// Ctr, accepts numerical ID
76 32833 APVPlaneID( DetIDPayload_t id_ ) : id(id_) {}
77 /// Ctr, sets only the projection
78 1 APVPlaneID(Projection pj) : id(0) {
79 1 proj(pj);
80 1 }
81
82 /// Projection getter
83 49225 Projection proj() const {
84 assert( proj_is_set() ); // LCOV_EXCL_LINE
85 49225 return (Projection) (gProjectionMask & id);
86 }
87 /// Projection setter
88 32795 void proj( Projection p ) {
89 //assert( p < 5 ); // LCOV_EXCL_LINE
90 //assert( p < 7 ); // xxx, remove "P"-projection LCOV_EXCL_LINE
91 32795 unset_proj();
92 32795 id |= p;
93 32795 }
94 /// Unsets the projection value
95 49175 void unset_proj() {
96 49175 id &= ~gProjectionMask;
97 49175 }
98 /// Returns `true` if projection is set
99 98383 bool proj_is_set() const {
100 98383 return id & gProjectionMask;
101 }
102 /// Returns `true` for special (non-projection) codes
103 bool proj_is_special() const {
104 return !(proj() & 0x8);
105 }
106 };
107
108 /**\brief An on-wire hit identifier
109 *
110 * Define a bit structure of hit identifier related to certain wire on tracking
111 * detectors. Used within the DetectorID structure at payloads for APV
112 * detectors like GEMs or MuMegas.
113 *
114 * Stores projection axis identifier (X, Y, U, V) as well as the number of wire
115 * (physical or raw). Max wire number is limited by 2^(16-3) = 8192.
116 *
117 * One has to distinguish "unset" and zero identifier, similar to `CellID`
118 * class.
119 *
120 * \ingroup mainDetID
121 * */
122 struct WireID : public APVPlaneID {
123 constexpr static DetIDPayload_t wireMax
124 = (std::numeric_limits<DetIDPayload_t>::max() >> gWireNoOffset) - 1;
125
126 /// Unset ID ctr
127 32796 WireID() : APVPlaneID(0x0) {}
128 /// Copy ctr
129 37 WireID(DetIDPayload_t id_) : APVPlaneID(id_) {}
130 /// Initializes projection ID and wire number
131 1 WireID(Projection pj, uint16_t wn) : APVPlaneID(pj) {
132 1 wire_no(wn);
133 1 }
134
135 /// Wire number getter
136 32793 uint16_t wire_no() const {
137 32793 return (id >> gWireNoOffset) - 1;
138 }
139
140 /// Wire number setter
141 49174 void wire_no( uint16_t wn) {
142 49174 id &= ~((wireMax+1) << gWireNoOffset);
143 49174 id |= ((wn+1) << gWireNoOffset);
144 49174 }
145
146 /// Makes wire number be not set
147 16381 void unset_wire_no() {
148 16381 id &= ~((wireMax+1) << gWireNoOffset);
149 16381 }
150
151 /// Returns true if wire number is set
152 49158 bool wire_no_is_set() const {
153 49158 return id & ((wireMax+1) << gWireNoOffset);
154 }
155
156 /// Appends textual template completion context with `proj` and `wireNo`
157 static void append_completion_context( DetID
158 , std::map<std::string, std::string> & );
159 /// Converts from WireID to string
160 static void to_string( DetIDPayload_t, char *, size_t available );
161 /// Converts from string to WireID
162 static DetIDPayload_t from_string( const char * );
163 };
164
165 /**\brief ...
166 *
167 * \ingroup auxDetID
168 */
169 struct PlaneKey : public DetID {
170 /// Constructs unique plane key
171 PlaneKey( DetID_t id_ ) : DetID( id_ ) {
172 WireID wid(payload());
173 wid.unset_wire_no();
174 payload(wid.id);
175 }
176
177 1 explicit PlaneKey( DetID id_ ) : DetID( id_ ){
178
1/1
✓ Branch 1 taken 1 times.
1 WireID wid(payload());
179 1 wid.unset_wire_no();
180
1/1
✓ Branch 1 taken 1 times.
1 payload(wid.id);
181 1 }
182
183 PlaneKey( DetChip_t chip
184 , DetKin_t kin
185 , DetNumber_t num
186 , WireID::Projection pj
187 ) : DetID( chip, kin, num ) {
188 WireID wid;
189 wid.proj(pj);
190 payload(wid.id);
191 }
192
193 explicit PlaneKey() : DetID(0x0, 0x0, 0) {unset_payload();}
194
195 /// Projection getter
196 WireID::Projection proj() const {
197 return WireID(payload()).proj();
198 }
199 /// Projection setter
200 void proj( WireID::Projection p ) {
201 WireID wid(payload());
202 wid.proj(p);
203 payload(wid.id);
204 }
205 /// Unsets the projection value
206 void unset_proj() {
207 WireID wid;
208 wid.unset_wire_no();
209 payload(wid.id);
210 }
211 /// Returns `true` if projection is set
212 bool proj_is_set() const {
213 return WireID(payload()).proj_is_set();
214 }
215 };
216
217 } // namespace ::na64dp
218
219 namespace std {
220
221 template <> struct hash<na64dp::PlaneKey> {
222 std::size_t operator()(const na64dp::DetID & k) const {
223 return k.id;
224 }
225 };
226
227 template<>
228 struct less<na64dp::PlaneKey> {
229 bool operator()(const na64dp::PlaneKey a, const na64dp::PlaneKey & b) const {
230 return a.id < b.id;
231 }
232 };
233
234 }
235
236