GCC Code Coverage Report


Directory: ./
File: src/calib/config-yaml.cc
Date: 2025-09-01 06:19:01
Exec Total Coverage
Lines: 0 87 0.0%
Functions: 0 5 0.0%
Branches: 0 20 0.0%

Line Branch Exec Source
1 #include "na64calib/config-yaml.hh"
2
3 #include "na64detID/TBName.hh"
4 #include "na64calib/evType.hh"
5 #include "na64util/str-fmt.hh"
6
7 #include "na64detID/cellID.hh"
8 #include "na64detID/wireID.hh"
9
10 #include "na64calib/master-time.hh"
11
12 #include <fstream>
13 #include <cmath>
14 #include <stdexcept>
15 #include <yaml-cpp/node/node.h>
16
17 namespace na64dp {
18 namespace calib {
19
20 #if 0
21 /**\brief Appends run index / data index configuration wrt YAML document
22 *
23 * This utility function fills run index and data loader indexes according
24 * to information provided in YAML node at the runtime. The given node has to
25 * be a list of entries each of that contains the validity period
26 * (`validFromRun`) and type string key referencing particular data loader
27 * instance.
28 * */
29 void
30 configure_from_YAML( YAML::Node & rootNode
31 , RangeOverrideRunIndex * runIndex
32 , GenericLoader * loader
33 , const std::string & loaderName
34 , std::unordered_map<std::string, YAMLCalibInfoCtr> & ciCtrs
35 ) {
36 auto & L = log4cpp::Category::getInstance( "calibrations.yaml" );
37 // Iterate over the node
38 for( YAML::const_iterator nodeIt = rootNode.begin()
39 ; rootNode.end() != nodeIt
40 ; ++nodeIt ) {
41 const std::string calibTypeName = nodeIt->first.as<std::string>();
42 // Get the calibration index constructor by type
43 auto ctrIt = ciCtrs.find( calibTypeName );
44 if( ciCtrs.end() == ctrIt ) {
45 if( "APIVersion" != calibTypeName ) {
46 L.warn( "Unable to get the calibration index constructor"
47 " \"%s\" (calibration data type is unknown, omitted)."
48 , calibTypeName.c_str() );
49 }
50 continue;
51 }
52 const YAML::Node & node = nodeIt->second;
53 YAMLCalibInfoCtr & ctr = ctrIt->second;
54 // Construct the data index if it is not yet constructed (e.g. by
55 // previous calls)
56 if( ! ctr.dataIndexPtr ) {
57 assert( ctr.ctr );
58 // Construct new data index
59 ctr.dataIndexPtr = ctr.ctr();
60 L.info( "New calibration data index constructed %s: %p"
61 , util::calib_id_to_str(ctr.ciDataID).c_str()
62 , ctr.dataIndexPtr );
63 // Add index to loader
64 loader->add_data_index( ctr.ciDataID, ctr.dataIndexPtr );
65 }
66 // Add into both indexes
67 for( const auto & cdNode : node ) {
68 EventID validFromEvent( cdNode["validFromRun"].as<na64sw_runNo_t>()
69 , 0, 0 );
70 // It is important to keep this two calls covariant:
71 // - add run index entry
72 runIndex->add_entry( validFromEvent
73 , ctr.ciDataID
74 , loaderName );
75 // - add data entry
76 try {
77 ctr.dataIndexPtr->append( validFromEvent, cdNode );
78 } catch( std::exception & e ) {
79 L.error( "While appending entry for %s event of \"%s\" data"
80 " an error occured."
81 , validFromEvent.to_str().c_str(), calibTypeName.c_str() );
82 }
83 L.info( "Run (%p) and data (%p) indexes %s added from YAML on event %s."
84 , runIndex
85 , ctr.dataIndexPtr
86 , util::calib_id_to_str(ctr.ciDataID).c_str()
87 , validFromEvent.to_str().c_str() );
88 }
89 }
90 }
91 #endif
92
93 /// Internal function reading the YAML node with detector naming description
94 /// into `DetectorNaming` object.
95 ///
96 /// \todo Document the naming config API of v.0.2
97 static nameutils::DetectorNaming
98 mappings_from_yaml_API02( const YAML::Node & root ) {
99 auto & L = log4cpp::Category::getInstance( "calib" );
100 nameutils::DetectorNaming r;
101 for( auto kv : root["chips"] ) {
102 const YAML::Node & pl = kv.second;
103 const std::string chipName = kv.first.as<std::string>();
104 // add chip with name and id
105 nameutils::DetectorNaming::ChipFeatures & ct
106 = r.chip_add( chipName, pl["id"].as<int>());
107 // get basic fields from the YAML chip description
108 // - description string is rarely used, human-readable description of
109 // the chip
110 ct.description = pl["desc"].as<std::string>();
111
112 const YAML::Node & pats = pl["patterns"];
113 // - pathFormat is slash-separated path of objects, used to organaize
114 // various artifacts related to the detector entity: files,
115 // histograms, etc.
116 ct.pathFormat = pats["path"].as<std::string>();
117 ct.nameFormat = pats["name"].as<std::string>();
118 ct.dddNameFormat = pats["tbname"].as<std::string>();
119 // TODO: think on better separation of the per-chip from-/to-string
120 // conversion routines as it is generally not a good idea to provide
121 // APV's conversion function to other chips (Straws TDC and F1)
122 if( "SADC" == chipName ) {
123 ct.append_completion_context = CellID::append_completion_context;
124 ct.to_string = CellID::to_string;
125 ct.from_string = CellID::from_string;
126 } else if( "NA64WB" == chipName ) {
127 ct.append_completion_context = CellID::append_completion_context;
128 ct.to_string = CellID::to_string;
129 ct.from_string = CellID::from_string;
130 } else if( "APV" == chipName ) {
131 ct.append_completion_context = WireID::append_completion_context;
132 ct.to_string = WireID::to_string;
133 ct.from_string = WireID::from_string;
134 } else if( "NA64TDC" == chipName ) {
135 ct.append_completion_context = WireID::append_completion_context;
136 ct.to_string = WireID::to_string;
137 ct.from_string = WireID::from_string;
138 } else if( "F1" == chipName ) {
139 ct.append_completion_context = WireID::append_completion_context;
140 ct.to_string = WireID::to_string;
141 ct.from_string = WireID::from_string;
142 /* ... add other chips here ... */
143 } else {
144 L.warn( "No to-/from-string conversion and text context appender"
145 " functions will be defined for chip \"%s\"."
146 , chipName.c_str() );
147 }
148 }
149 for( auto kv : root["kins"] ) {
150 const YAML::Node & pl = kv.second;
151 try {
152 if( pl["patterns"] ) {
153 const YAML::Node & pats = pl["patterns"];
154 auto & kinFts = r.define_kin( kv.first.as<std::string>()
155 , pl["id"].as<int>()
156 , pl["chip"].as<std::string>()
157 , pats["name"].as<std::string>()
158 , pl["desc"].as<std::string>()
159 , pats["path"].as<std::string>()
160 );
161 kinFts.dddNameFormat = pats["tbname"].as<std::string>();
162 } else {
163 r.define_kin( kv.first.as<std::string>()
164 , pl["id"].as<int>()
165 , pl["chip"].as<std::string>()
166 , ""
167 , pl["desc"].as<std::string>()
168 , ""
169 );
170 }
171 } catch(std::exception & e) {
172 L.error( "Exception occured on kin description \"%s\"."
173 , kv.first.as<std::string>().c_str() );
174 throw;
175 }
176 }
177 return r;
178 }
179
180 void
181 YAML2Naming( const YAML::Node & node
182 , Dispatcher & d) {
183 //if( node["version"] ?? ) ...
184 d.set<nameutils::DetectorNaming>( "default"
185 , mappings_from_yaml_API02( node ) );
186 }
187
188 void
189 YAML2EventTags( const YAML::Node & node
190 , Dispatcher & d ) {
191 EventBitTags bitTags(node);
192 d.set<EventBitTags>( "default"
193 , bitTags );
194 }
195
196 static void
197 _dispatch_master_time_setting( const YAML::Node & node
198 , Dispatcher & d ) {
199 std::string detName;
200 float offset;
201 std::vector<std::string> triggerTypes;
202 if( node.IsScalar() ) {
203 // If scalar is provided we assume it to be just a detector name,
204 // referring to the instance where master time must be taken from
205 detName = node.as<std::string>();
206 offset = std::nanf("0");
207 triggerTypes.push_back("phys");
208 } else if( node.IsMap() ) {
209 // If it is a map we expect it to have "detector" and "offset" fields
210 // denoting detector name and offset to use
211 detName = node["detector"].as<std::string>();
212 offset = node["offset"] ? node["offset"].as<float>() : std::nanf("0");
213 if(node["triggerTypes"]) {
214 triggerTypes = node["triggerTypes"].as<std::vector<std::string>>();
215 } else {
216 triggerTypes.push_back("masterTimeSource");
217 }
218 } else if( node.IsSequence() ) {
219 // A sequence must be interpreted as list of items for various item
220 // types
221 throw std::runtime_error("TODO: master time for multiple triggers is"
222 " not yet supported"); // TODO
223 } else {
224 NA64DP_RUNTIME_ERROR("Bad YAML node type for master time setting.");
225 }
226 for(const auto & mtsType : triggerTypes) {
227 if(!d.has_subscribers<MasterTimeSource>(mtsType)) {
228 log4cpp::Category::getInstance("calib").debug("No subscribers for"
229 " master time source info of type \"%s\";"
230 " (\"%s\" with offset is %f ns is not handled)"
231 , mtsType.c_str()
232 , detName.c_str(), offset );
233 continue;
234 }
235 log4cpp::Category::getInstance("calib").debug("Notifying that time from"
236 " \"%s\" shall be considered as"
237 " master time for \"%s\" event type, offset is %f ns."
238 , detName.c_str()
239 , mtsType.c_str()
240 , offset );
241 d.set< MasterTimeSource >( mtsType, {detName, offset} );
242 }
243 }
244
245 void
246 dispatch_master_time_setting( const YAML::Node & node
247 , Dispatcher & d ) {
248 if( node.IsSequence() ) {
249 for(size_t nItem = 0; nItem < node.size(); ++nItem ) {
250 _dispatch_master_time_setting(node[nItem], d);
251 }
252 } else {
253 _dispatch_master_time_setting(node, d);
254 }
255 }
256
257 } // namespace na64dp::calib
258 } // namespace na64dp
259
260