GCC Code Coverage Report


Directory: ./
File: include/na64event/hdql-augments.hh
Date: 2025-09-01 06:19:01
Exec Total Coverage
Lines: 42 51 82.4%
Functions: 9 42 21.4%
Branches: 38 57 66.7%

Line Branch Exec Source
1 #pragma once
2
3 /**\file
4 * \brief HDQL-related assets for events structures */
5
6 #include "na64sw-config.h"
7 #include <hdql/context.h>
8
9 #if defined(hdql_FOUND) && hdql_FOUND
10
11 #include "na64event/data/event.hh"
12
13 #include "na64detID/TBName.hh"
14 #include "na64calib/dispatcher.hh" // todo: violates lib.dependency?
15 #include "na64util/na64/event-id.hh"
16 #include "na64detID/detectorID.hh"
17 #include "na64detID/trackID.hh"
18 #include "na64detID/wireID.hh"
19
20 #include <hdql/helpers/compounds.hh>
21
22 #include <stdexcept>
23
24 namespace na64dp {
25 /**\brief Detector selector implementation for collections
26 *
27 * ... todo: doc
28 * */
29 struct DetIDSelection
30 : protected calib::Handle<nameutils::DetectorNaming> {
31 private:
32 /// DSuL expression in a string form
33 std::string _expression;
34 /// Compiled DSuL selector
35 DetSelect * _detSelect;
36 protected:
37 /// Implements `calib::Handle` iface
38 void handle_update(const nameutils::DetectorNaming & nm) override;
39 public:
40 ///\brief Main ctr for selection object
41 ///
42 /// Must be used with DSuL string expression optionally prepended with
43 /// naming suffix, calibration dispatcher instance to handle detector
44 /// naming updates and detector naming class.
45 DetIDSelection( const char * expression
46 , calib::Dispatcher & cdsp
47 , const std::string & detNameClass="default"
48 );
49
50 ///\brief Returns true if detector ID matches selector
51 bool matches(DetID did) const;
52
53 ///\brief Returns true if selection is "compiled"
54 ///
55 /// Returns true when string expression was used used to produce DSuL
56 /// selector taking into account detectors naming object -- i.e.
57 /// `handle_update()` was called.
58 bool is_compiled() const { return _detSelect; }
59 }; // struct DetIDSelection
60
61 namespace util {
62 const nameutils::DetectorNaming & get_naming_handle(hdql_Context_t context);
63 } // namespace ::na64dp::util
64 } // namespace na64dp
65
66
67 // Override HDQL helper traits for EventID type to consider it as a compound
68 // type
69
70 namespace hdql {
71 namespace helpers {
72
73 namespace detail {
74 template<> struct ArithTypeNames<::na64dp::DetID> { static constexpr const char * name = "DetID"; };
75 template<> struct ArithTypeNames<::na64dp::PlaneKey> { static constexpr const char * name = "PlaneKey"; };
76 template<> struct ArithTypeNames<::na64dp::TrackID> { static constexpr const char * name = "TrackID"; };
77 };
78
79 // ____________________________________________________________
80 // _____________/ Helpers specialization for EventID type as a scalar compound
81
82 // Should be called before auto-generate compound creation routines to provide
83 // helpers with existing definition for event ID
84 void create_event_id_compound(hdql::helpers::CompoundTypes &, hdql_Context * context);
85
86 template<>
87 struct TypeInfoMixin<::na64dp::EventID> {
88 static constexpr bool isCompound = true;
89 static hdql_Compound *
90 9 type_info(const hdql_ValueTypes * valTypes, Compounds & compounds) {
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 assert(valTypes);
92
1/1
✓ Branch 2 taken 9 times.
9 auto it = compounds.find(typeid(::na64dp::EventID));
93
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 assert(compounds.end() != it);
94 18 return it->second;
95 }
96 }; // TypeInfoMixin<EventID>
97
98 ///\brief DetID scalar attribute traits
99 template<typename OwnerT, ::na64dp::EventID OwnerT::*ptr>
100 struct IFace<ptr>
101 : public TypeInfoMixin<::na64dp::EventID> {
102 static constexpr bool isCollection = false;
103
104 static hdql_Datum_t
105 dereference( hdql_Datum_t root // owning object
106 , hdql_Datum_t dynData // allocated with `instantiate()`
107 , struct hdql_CollectionKey * // may be NULL
108 , const hdql_Datum_t // may be NULL
109 , hdql_Context_t
110 ) {
111 auto p = &(reinterpret_cast<OwnerT *>(root)->*ptr);
112 return reinterpret_cast<hdql_Datum_t>(p);
113 }
114
115 9 static hdql_ScalarAttrInterface iface() {
116 return hdql_ScalarAttrInterface{
117 // NOTE: definition data here can be used to forward some
118 // global auxiliary assets and in principle we can use it
119 // to forward calibration manager instance or
120 // `util::gDetIDGetters` to `compile()`, but since we sould
121 // like to have rather thread-local subscriptions, this
122 // mechanism is not used (hdql_context_custom_data_get()`)
123 .definitionData = NULL
124 , .instantiate = NULL
125 , .dereference = dereference
126 , .reset = NULL
127 , .destroy = NULL
128 9 };
129 }
130
131 static constexpr auto create_attr_def = detail::AttrDefCallback<true, false>::create_attr_def;
132 }; // scalar compound attribute
133
134
135 // ____________________________________________________________________
136 // _____/ Helpers specialization for event time type as a scalar compound type
137
138 // Caveat: pair of integers of the same type can, in principle, appear in the
139 // event structures. In that case an automated interface instantiation will
140 // follow this specialization as well.
141 template<>
142 struct TypeInfoMixin<std::pair<time_t, uint32_t>> {
143 static constexpr bool isCompound = true;
144 static hdql_Compound *
145 9 type_info(const hdql_ValueTypes * valTypes, Compounds & compounds) {
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 assert(valTypes);
147
1/1
✓ Branch 2 taken 9 times.
9 auto it = compounds.find(typeid(std::pair<time_t, uint32_t>));
148
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 assert(compounds.end() != it);
149 18 return it->second;
150 }
151 }; // TypeInfoMixin<std::pair<time_t, uint32_t>>
152
153 // contrary to `TypeInfoMixin<pair<...>>` above this specialization is
154 // parameterized with pointer-to member explicitly and won't appear in other
155 // structs
156 template<>
157 struct IFace<&::na64dp::event::Event::time >
158 : public TypeInfoMixin< std::pair<time_t, uint32_t> > {
159 static constexpr bool isCollection = false;
160
161 static hdql_Datum_t
162 dereference( hdql_Datum_t root // owning object
163 , hdql_Datum_t dynData // allocated with `instantiate()`
164 , struct hdql_CollectionKey * // may be NULL
165 , const hdql_Datum_t // may be NULL
166 , hdql_Context_t
167 ) {
168 auto p = &(reinterpret_cast<::na64dp::event::Event *>(root)->time);
169 return reinterpret_cast<hdql_Datum_t>(p);
170 }
171
172 9 static hdql_ScalarAttrInterface iface() {
173 return hdql_ScalarAttrInterface{
174 .definitionData = NULL
175 , .instantiate = NULL
176 , .dereference = dereference
177 , .reset = NULL
178 , .destroy = NULL
179 9 };
180 }
181
182 static constexpr auto create_attr_def = detail::AttrDefCallback<true, false>::create_attr_def;
183 }; // scalar compound attribute
184
185
186 ///\brief Collection indexed by DetID helper traits for HDQL C++ API
187 template<typename T>
188 struct SelectionTraits< na64dp::DetIDSelection
189 , T
190 , typename std::enable_if<std::is_convertible<typename T::key_type, na64dp::DetID>::value>::type
191 > {
192 typedef typename T::iterator Iterator;
193 //static_assert(std::is_same<na64dp::DetID, typename T::key_type>::value, "");
194 22 static Iterator advance( T & owner
195 , const na64dp::DetIDSelection * sel
196 , Iterator current
197 ) {
198
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
22 if(!sel) return ++current;
199
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
4 assert(owner.end() != current);
200
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
4 assert(sel->matches(current->first));
201 4 for( ++current
202
7/7
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
✓ Branch 6 taken 2 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 2 times.
6 ; current != owner.end() && !sel->matches(current->first)
203 2 ; ++current ) {}
204 //assert(owner.end() == current);
205
4/5
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
4 assert(current == owner.end() || sel->matches(current->first));
206 4 return current;
207 }
208
209 12 static Iterator reset( T & owner
210 , const na64dp::DetIDSelection * sel
211 , Iterator current
212 ) {
213
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
12 if(!sel) return owner.begin();
214
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
4 if(owner.empty()) return owner.end();
215 4 for( current = owner.begin()
216
4/7
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
4 ; current != owner.end() && !sel->matches(current->first)
217 ; ++current ) {
218 }
219
3/5
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
2 assert(current == owner.end() || sel->matches(current->first));
220 2 return current;
221 }
222
223 4 static na64dp::DetIDSelection * compile( const char * expression
224 , const hdql_Datum_t defData // userdata
225 , hdql_Context & ctx
226 ) {
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 assert(expression);
228 4 auto cdsp_ = hdql_context_custom_data_get(&ctx, "na64sw/calib-dispatcher-ptr");
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 if(!cdsp_) {
230 char errBuf[256];
231 snprintf( errBuf, sizeof(errBuf)
232 , "Cannot compile DSuL expression \"%s\" as current HDQLang"
233 " context %p does not provide custom data item"
234 " \"na64sw/calib-dispatcher-ptr\"."
235 , expression, &ctx );
236 throw std::runtime_error(errBuf);
237 }
238 const char * detIDClassName;
239 4 auto detIDClassName_ = hdql_context_custom_data_get(&ctx, "na64sw/det-ID-class-name");
240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 if(!detIDClassName_) detIDClassName = "default";
241 4 else detIDClassName = reinterpret_cast<const char *>(detIDClassName_);
242
2/2
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
12 return new na64dp::DetIDSelection(expression
243 , *reinterpret_cast<na64dp::calib::Dispatcher *>(cdsp_)
244 , detIDClassName
245
0/1
✗ Branch 2 not taken.
12 ); // TODO: use hdql context for allocation?
246 }
247
248 4 static void destroy( na64dp::DetIDSelection * sel
249 , const hdql_Datum_t
250 , hdql_Context &
251 ) {
252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
4 assert(sel);
253
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 delete sel; // TODO: use hdql context for deletio?
254 }
255 };
256
257 } // namespace ::hdql::helpers
258 } // namespace hdql
259
260 #endif // defined(hdql_FOUND) && hdql_FOUND
261
262