JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwAlarmHandler.cc
Go to the documentation of this file.
1/*!
2 * \file QwAlarmHandler.cc
3 * \brief Implementation of alarm handling data handler for monitoring
4 * \author wdconinc
5 * \date 2010-10-22
6 */
7
8#include "QwAlarmHandler.h"
9
10// Qweak headers
11#include "VQwDataElement.h"
12#include "QwVQWK_Channel.h"
13#include "QwParameterFile.h"
14#include "QwHelicityPattern.h"
15
16// Register this handler with the factory
18
19
20/// \brief Constructor with name
22{
23 ParseSeparator = "_";
24 //fKeepRunningSum = kTRUE;
25}
26
30
31// Just use the base class version for now....
32
34{
36 //name = MyAlarmHandler
37 //priority = 20
38 //map = prex_alarm_handler.map
39 file.PopValue("alarm-output-file",fAlarmOutputFile);
40 file.PopValue("alarm-loop-N-update",fAlarmNupdate);
41 file.PopValue("alarm-active",fAlarmActive);
42 // Check for and process key-value pairs
43 //file.PopValue("new-key-word",fsomething); // These need = signs in map files
44}
45
46std::pair<std::string,std::string> QwAlarmHandler::ParseAlarmMapVariable(const std::string& variable, char delim) {
47 std::pair<std::string,std::string> type_name;
48 size_t len = variable.length();
49 size_t pos1 = variable.find_first_of(delim);
50 size_t pos2 = variable.find_first_not_of(delim,pos1);
51 if (pos1 == string::npos) {
52 type_name.first = "NULL";
53 type_name.second = "NULL";
54 } else {
55 string type = variable.substr(0,pos1);
56 string name = variable.substr(pos2,len-pos2);
57 type_name.first = type;
58 type_name.second = name;
59 }
60 return type_name;
61}
62
63//******************************************************************************************************************************************************
64
65/** Load the channel map
66 *
67 * @param mapfile Filename of map file
68 * @return Zero when success
69 */
70Int_t QwAlarmHandler::LoadChannelMap(const std::string& mapfile)
71{
72 // Open the file
73 QwParameterFile map(mapfile);
74
75 // Read the sections of dependent variables
76 std::pair<EQwHandleType,std::string> type_name;
77 std::pair<std::string,std::string> tmpPair;
78
79 // Add independent variables and sensitivities
80 while (map.ReadNextLine()) {
81 // Throw away comments, whitespace, empty lines
82 map.TrimComment();
83 map.TrimWhitespace();
84 if (map.LineIsEmpty()) continue;
85 // Get first token: label (dv or iv), second token is the name like "asym_blah"
86// Type, Channel, Ana, tree, channel, highhigh, high, low, lowlow, ringLength, pat-tolerance
87// Kind=Main-Det Chan=usr Tree=mul Channel=asym_usr HighHigh=1000 High=100 Low=-100 LowLow=-1000 Ring-Length=200 Tolerance=2
88 alarmObject tmpAlarmObject;
89 // Do while tmpVal = map.GetNextToken parse
90 // Do map[tmpVal.type] = tmpVal.value
91 std::string tmpToken = map.GetNextToken(" ");
92 while ( tmpToken != "" ) {
93 tmpPair = ParseAlarmMapVariable(tmpToken,'='); // This refers to the object under scrutiny, finds type of object - asym, yield, diff, etc. Check on yields FIXME
94 if (tmpPair.first=="Channel") {
95 type_name = ParseHandledVariable(tmpPair.second);
96 tmpAlarmObject.alarmParameterMapStr["Analysis"] = tmpPair.second;
97 tmpAlarmObject.analysisType = type_name.first;
98 tmpAlarmObject.alarmParameterMapStr["Channel-Name"] = type_name.second;
99 tmpAlarmObject.alarmParameterMapStr["Type-Name"] = tmpPair.second;
100 }
101 else if (tmpPair.first == "Kind") {
102 tmpAlarmObject.alarmParameterMapStr[tmpPair.first] = tmpPair.second;
103 }
104 else if (tmpPair.first == "Chan") {
105 tmpAlarmObject.alarmParameterMapStr[tmpPair.first] = tmpPair.second;
106 }
107 else if (tmpPair.first == "Error-Code") {
108 tmpAlarmObject.alarmParameterMapStr[tmpPair.first] = tmpPair.second;
109 }
110 else {
111 tmpAlarmObject.alarmParameterMap[tmpPair.first] = std::stod(tmpPair.second);
112 }
113 tmpToken = map.GetNextToken(" ");
114 }
115 if (!tmpAlarmObject.alarmParameterMap.count("Ring-Length")) {
116 tmpAlarmObject.alarmParameterMap["Ring-Length"] = 1e9;
117 }
118 if (!tmpAlarmObject.alarmParameterMap.count("Tolerance")) {
119 tmpAlarmObject.alarmParameterMap["Tolerance"] = 0;
120 }
121
122 /* tmpAlarmObject.type = map.GetNextToken(" ");
123 tmpAlarmObject.channel = map.GetNextToken(" ");
124 tmpAlarmObject.ana = map.GetNextToken(" ");
125 tmpAlarmObject.tree = map.GetNextToken(" ");
126 std::string localAna_token = map.GetNextToken(" ");
127 // Parse current token into independent variable type and name
128 type_name = ParseHandledVariable(localAna_token); // This refers to the object under scrutiny, finds type of object - asym, yield, diff, etc. Check on yields FIXME
129 tmpAlarmObject.analysisType = type_name.first;
130 tmpAlarmObject.analysisName = type_name.second;
131 tmpAlarmObject.highHigh = map.GetNextToken(" ");
132 tmpAlarmObject.high = map.GetNextToken(" ");
133 tmpAlarmObject.low = map.GetNextToken(" ");
134 tmpAlarmObject.lowLow = map.GetNextToken(" ");
135 tmpAlarmObject.ringLength = map.GetNextToken(" ");
136 tmpAlarmObject.tolerance = map.GetNextToken(" "); // This is all hardcoded.... how to do with keywords? FIXME
137 */
138 // Default Initializations
139 tmpAlarmObject.alarmStatus = "OK";
140 tmpAlarmObject.Nviolated = 0;
141 tmpAlarmObject.NsinceLastViolation = 1e9;
142 tmpAlarmObject.value = NULL;
143 tmpAlarmObject.eventcutErrorFlag = NULL;
144 fAlarmObjectList.push_back(tmpAlarmObject);
145
146 /*else if (primary_token == "treetype") {
147 QwMessage << "Tree Type read, ignoring." << QwLog::endl;
148 }
149 else {
150 QwError << "Function LoadChannelMap in QwCorrelator.cc read in invalid primary_token." << QwLog::endl;
151 }*/
152 }
153 return 0;
154}
155
156// Connect to the dependent and independent channels (implementation). Parameters are documented in the header.
161{
162 /// Fill vector of pointers to the relevant data elements
163 for (size_t anaInd = 0; anaInd < fAlarmObjectList.size(); anaInd++) {
164 // Get the dependent variables
165 if (fAlarmObjectList.at(anaInd).analysisType==kHandleTypeMps || fAlarmObjectList.at(anaInd).alarmParameterMapStr.count("Channel-Name") == 0){
166 // Quietly ignore the MPS type when we're connecting the asym & diff
167 continue;
168 }
169 const VQwHardwareChannel* ana_ptr = NULL;
170 const UInt_t* eventcut = NULL;
171 switch (fAlarmObjectList.at(anaInd).analysisType) {
172 case kHandleTypeYield:
174 ana_ptr = yield.ReturnInternalValue(fAlarmObjectList.at(anaInd).alarmParameterMapStr.at("Channel-Name"));
175 eventcut = yield.GetEventcutErrorFlagPointer();
176 break;
177 case kHandleTypeAsym:
179 ana_ptr = asym.ReturnInternalValue(fAlarmObjectList.at(anaInd).alarmParameterMapStr.at("Channel-Name"));
180 eventcut = asym.GetEventcutErrorFlagPointer();
181 break;
182 case kHandleTypeDiff:
184 ana_ptr = diff.ReturnInternalValue(fAlarmObjectList.at(anaInd).alarmParameterMapStr.at("Channel-Name"));
185 eventcut = diff.GetEventcutErrorFlagPointer();
186 break;
187 default:
188 QwWarning << "Independent variable for AlarmHandler has unknown type."
189 << QwLog::endl;
190 break;
191 }
192 if (ana_ptr != NULL) {
193 fAlarmObjectList.at(anaInd).value = ana_ptr;
194 //QwError << "ana_ptr = " << ana_ptr <<QwLog::endl;
195 //QwError << "fAlarmObjectList.at(" << anaInd << ").value = " << fAlarmObjectList.at(anaInd).value <<QwLog::endl;
196 fAlarmObjectList.at(anaInd).eventcutErrorFlag = eventcut;
197 } else {
198 fAlarmObjectList.at(anaInd).value = NULL;
199 //QwWarning << "Independent variable " << fAlarmObjectList.at(anaInd).alarmParameterMapStr.at("Channel-Name") << " missing in alarm map "
200 // << QwLog::endl;
201 }
202 }
203 return 0;
204}
205
206// Connect to the dependent and independent channels (overload)
207/*Int_t QwAlarmHandler::ConnectChannels(QwSubsystemArrayParity& event)
208{
209 // Return if correction is not enabled
210
211 /// Fill vector of pointers to the relevant data elements
212 for (size_t dv = 0; dv < fAlarmObjectList.size(); dv++) {
213 // Get the dependent variables
214
215 const VQwHardwareChannel* dv_ptr = 0;
216 QwVQWK_Channel* new_vqwk = NULL;
217 QwVQWK_Channel* vqwk = NULL;
218 string name = " s";
219 string calc = "calc_";
220
221 if (fAnalysisType.at(dv)==kHandleTypeAsym || fAnalysisType.at(dv)==kHandleTypeDiff){
222 // Quietly skip the asymmetry or difference types.
223 continue;
224 } else if(fAnalysisType.at(dv) != kHandleTypeMps){
225 QwWarning << "QwAlarmHandler::ConnectChannels(QwSubsystemArrayParity& event): Dependent variable, "
226 << fAnalysisName.at(dv)
227 << ", for MPS alarm handler does not have MPS type, type=="
228 << fAnalysisType.at(dv) << "."<< QwLog::endl;
229 continue;
230 } else {
231 if(fAnalysisName.at(dv).at(0) == '@' ){
232 name = fAnalysisName.at(dv).substr(1,fAnalysisName.at(dv).length());
233 new_vqwk = new QwVQWK_Channel(name, VQwDataElement::kDerived);
234 } else {
235 dv_ptr = event.RequestExternalPointer(fAnalysisName.at(dv));
236
237 vqwk = dynamic_cast<QwVQWK_Channel*>(dv_ptr);
238 name = vqwk.GetElementName().Data();
239 new_vqwk = new QwVQWK_Channel(*vqwk, VQwDataElement::kDerived);
240 new_vqwk.SetElementName(name);
241 }
242 new_vqwk.SetSubsystemName(fName);
243 }
244
245 // alias
246 if(new_vqwk==NULL){
247 QwWarning << "Dependent variable " << fAnalysisName.at(dv) << " could not be found, "
248 << "or is not a VQWK channel." << QwLog::endl;
249 continue;
250 } else {
251 //QwMessage << "dv: " << new_vqwk.GetElementName() << QwLog::endl;
252 // pair creation
253 fAnalysisType.push_back(fAnalysisType.at(dv));
254 fDependentVar.push_back(vqwk);
255 fOutputVar.push_back(new_vqwk);
256 //fDependentVar.push_back(std::make_pair(vqwk, new_vqwk));
257 }
258 }
259 return 0; // FIXME this won't work, and the pointers are all wrong anyway...
260}*/
261
263 // for (size_t i = 0; i < fDependentVar.size(); ++i) {
264 // *(fOutputVar.at(i)) = *(fDependentVar[i]);
265 // }
266 // for (size_t i = 0; i < fDependentValues.size(); ++i) {
267 // fValue.at(i) = fDependentValues[i];
268 // }
269 fCounter++;
270 if (fAlarmActive) {
271 CheckAlarms();
272 if (fCounter % fAlarmNupdate == 0) {
274 }
275 }
276} // FIXME do I even need a process data method? Probably not
277
278/* Want to define new methods that will evaluate alarm status of config file variables (and combined variables -> correlations)
279 * Per multiplet calculate the asym, diffs, and yields, and compare these results to user set defined high or low values (if defined)
280 * Per multiplet check device_error_code and check eventCuts failed due to device in question and compare with tolerances defined by user
281 * Per failed low/high limit and per failed error_code and eventCut increment fail count++ and check if count > user tolerance
282 * If > tolerance then update alarm status with status (degree of failure, or Not OK status) and print to alarm.csv file the limits and value
283 * for the alarm handler GUI to pick up and parse
284 * Else if status changes to OK then print updated status to file too
285 * Else if no change then don't change the text file
286 *
287 * Probably need to interface with event cuts definitions in order to access their number-coding
288 * Probably need to define either some sort of event ring or counts decay procedure (+1 for bad, -1 for good...) to allow ignoring old failed events
289 * Probably need to define my own map nomenclature to hold stuff like what alarm.csv needs
290 * Parameter List:
291 *
292 * Japan Main Detectors,usr,asym_mean,Alarm Status,OK/saturated/high/low/nsamples/highhigh/lowlow/invalid/trip/eventcuter (I'm the cause)
293 * Japan Main Detectors,usr,asym_mean,Analysis,mean/rms/eventcuts/device_error_code
294 * Japan Main Detectors,usr,asym_mean,High,10000
295 * Japan Main Detectors,usr,asym_mean,Value,500
296 * Japan Main Detectors,usr,asym_mean,Low,50
297 * Japan Main Detectors,usr,asym_mean,Alarm Type,Japan
298 * Japan Main Detectors,usr,asym_mean,Variable Name,yield_usr
299 * Japan Main Detectors,usr,asym_mean,Tree,mul
300 * Japan Main Detectors,usr,asym_mean,Pattern Tolerance,2
301 *
302 * Type, Channel, Ana, tree, channel, highhigh, high, low, lowlow, pat tol
303 * J-m-d, usr, asym_mean, mul, usr, 1000, 100, -100, -1000, 2
304 *
305 *
306 * Make sure I update "canContain" method in /analysis/src/qwdatahandlerarray to include alarmhandler
307 */
308 /* FIXME Available VQwHardwareChannel methods
309 size_t GetNumberOfDataWords() {return fNumberOfDataWords;}
310 size_t GetNumberOfSubelements() {return fNumberOfSubElements;};
311
312 Int_t GetRawValue() const {return this.GetRawValue(0);};
313 Double_t GetValue() const {return this->GetValue(0);};
314 Double_t GetValueM2() const {return this->GetValueM2(0);};
315 Double_t GetValueError() const {return this->GetValueError(0);};
316 Double_t GetValueWidth() const {return this->GetValueWidth(0);};
317 virtual Int_t GetRawValue(size_t element) const = 0;
318 virtual Double_t GetValue(size_t element) const = 0;
319 virtual Double_t GetValueM2(size_t element) const = 0;
320 virtual Double_t GetValueError(size_t element) const = 0;
321 Double_t GetValueWidth(size_t element) const {*/
322
324 // If user-name-of-variable exists then grab it, grab its value from memory, and then compare to the upper and lower limits defined by user (if they were defined)
325 std::string tmpAlarmStat = "OK";
326 for ( size_t numAna = 0; numAna < fAlarmObjectList.size() ; numAna++ ) {
327 if (fAlarmObjectList.at(numAna).value != NULL){
328 //QwWarning << "fAlarmObjectList.at("<<numAna<<").value == " << fAlarmObjectList.at(numAna).value <<QwLog::endl;
329 //QwWarning << "fAlarmObjectList.at("<<numAna<<").value->GetValue() == " << fAlarmObjectList.at(numAna).value->GetValue() <<QwLog::endl;
330 if ( fAlarmObjectList.at(numAna).alarmParameterMapStr.count("Error-Code") != 0
331 && ((TString)fAlarmObjectList.at(numAna).alarmParameterMapStr.at("Error-Code")).IsHex() && ((std::stoul(fAlarmObjectList.at(numAna).alarmParameterMapStr.at("Error-Code"),nullptr,16)) & *fAlarmObjectList.at(numAna).eventcutErrorFlag) != 0 ) {
332 fAlarmObjectList.at(numAna).Nviolated++;
333 fAlarmObjectList.at(numAna).NsinceLastViolation = 0;
334 tmpAlarmStat = "Error-Code";
335 }
336 else if (fAlarmObjectList.at(numAna).alarmParameterMap.count("Exactly") != 0
337 && fAlarmObjectList.at(numAna).value->GetValue() != fAlarmObjectList.at(numAna).alarmParameterMap.at("Exactly")) {
338 fAlarmObjectList.at(numAna).Nviolated++;
339 fAlarmObjectList.at(numAna).NsinceLastViolation = 0;
340 tmpAlarmStat = "Not-Exactly";
341 }
342 else if ( fAlarmObjectList.at(numAna).alarmParameterMap.count("HighHigh") != 0
343 && fAlarmObjectList.at(numAna).value->GetValue() >= fAlarmObjectList.at(numAna).alarmParameterMap.at("HighHigh") ) {
344 fAlarmObjectList.at(numAna).Nviolated++;
345 fAlarmObjectList.at(numAna).NsinceLastViolation = 0;
346 tmpAlarmStat = "HighHigh";
347 }
348 else if ( fAlarmObjectList.at(numAna).alarmParameterMap.count("High") != 0
349 && fAlarmObjectList.at(numAna).value->GetValue() >= fAlarmObjectList.at(numAna).alarmParameterMap.at("High") ) {
350 fAlarmObjectList.at(numAna).Nviolated++;
351 fAlarmObjectList.at(numAna).NsinceLastViolation = 0;
352 tmpAlarmStat = "High";
353 }
354 else if ( fAlarmObjectList.at(numAna).alarmParameterMap.count("LowLow") != 0
355 && fAlarmObjectList.at(numAna).value->GetValue() <= fAlarmObjectList.at(numAna).alarmParameterMap.at("LowLow") ) {
356 fAlarmObjectList.at(numAna).Nviolated++;
357 fAlarmObjectList.at(numAna).NsinceLastViolation = 0;
358 tmpAlarmStat = "LowLow";
359 }
360 else if ( fAlarmObjectList.at(numAna).alarmParameterMap.count("Low") != 0
361 && fAlarmObjectList.at(numAna).value->GetValue() <= fAlarmObjectList.at(numAna).alarmParameterMap.at("Low") ) {
362 fAlarmObjectList.at(numAna).Nviolated++;
363 fAlarmObjectList.at(numAna).NsinceLastViolation = 0;
364 tmpAlarmStat = "Low";
365 }
366 else {
367 fAlarmObjectList.at(numAna).NsinceLastViolation++;
368 }
369 if ( fAlarmObjectList.at(numAna).Nviolated > 0 && fAlarmObjectList.at(numAna).NsinceLastViolation > fAlarmObjectList.at(numAna).alarmParameterMap.at("Ring-Length") ) {
370 fAlarmObjectList.at(numAna).Nviolated--;
371 }
372 if ( fAlarmObjectList.at(numAna).Nviolated > fAlarmObjectList.at(numAna).alarmParameterMap.at("Tolerance") ) {
373 fAlarmObjectList.at(numAna).alarmStatus = tmpAlarmStat;
374 }
375 else {
376 fAlarmObjectList.at(numAna).alarmStatus = "OK";
377 }
378 }
379 else {
380 QwError << "Null: fAlarmObjectList.at("<<numAna<<").value == NULL" <<QwLog::endl;
381 }
382 }
383}
384
386 std::ofstream file_out;
387 // Format of alarmObject struct contents
388 // std::map <std::string,std::string> alarmParameterMap;
389 // VQwDataHandler::EQwHandleType analysisType;
390 // const VQwHardwareChannel* value;
391 // UInt_t eventcutErrorFlag;
392 // std::string alarmStatus;
393 // int Nviolated; // Vector of 0's for history tracking
394 // int NsinceLastViolation; // Vector of 0's for history tracking
395
396 file_out.open(fAlarmOutputFile,std::ofstream::trunc);
397 for (size_t ite = 0 ; ite<fAlarmObjectList.size(); ite++){
398 if (fAlarmObjectList.at(ite).value != NULL && fAlarmObjectList.at(ite).alarmParameterMapStr.count("Kind") && fAlarmObjectList.at(ite).alarmParameterMapStr.count("Chan") && fAlarmObjectList.at(ite).alarmParameterMapStr.count("Analysis")) {
399 if (fAlarmObjectList.at(ite).value != 0) { // Check if non-trivial value object...
400 file_out<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Kind")<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Chan")<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Analysis")<<","<<"Value"<<","<<fAlarmObjectList.at(ite).value->GetValue()<<std::endl;
401 }
402 else continue;
403 if (fAlarmObjectList.at(ite).alarmStatus != "") { // Check if non-trivial value object...
404 file_out<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Kind")<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Chan")<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Analysis")<<","<<"Alarm Status"<<","<<fAlarmObjectList.at(ite).alarmStatus<<std::endl;
405 }
406 else continue;
407 if (fAlarmObjectList.at(ite).alarmParameterMapStr.count("Error-Code")) { // Check if non-trivial value object...
408 file_out<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Kind")<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Chan")<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Analysis")<<","<<"Error-Code"<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Error-Code")<<std::endl;
409 }
410 }
411 else continue;
412 for (auto jte : fAlarmObjectList.at(ite).alarmParameterMap){ // Loop through parameter list
413 file_out<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Kind")<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Chan")<<","<<fAlarmObjectList.at(ite).alarmParameterMapStr.at("Analysis")<<","<<jte.first<<","<<jte.second<<std::endl;
414 }
415 }
416 file_out.close();
417}
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
Parameter file parsing and management.
Definition of the pure virtual base class of all data elements.
Decoding and management for VQWK ADC channels (6x32-bit datawords)
#define REGISTER_DATA_HANDLER_FACTORY(A)
Definition QwFactory.h:263
Alarm handling data handler for monitoring system alerts.
Helicity pattern analysis and management.
virtual const VQwHardwareChannel * ReturnInternalValue(const TString &name) const
Retrieve an internal variable by name (pointer version) Searches for the named variable among publish...
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Configuration file parser with flexible tokenization and search capabilities.
Bool_t PopValue(const std::string keyname, T &retvalue)
void TrimWhitespace(TString::EStripType head_tail=TString::kBoth)
void TrimComment(const char commentchar)
std::string GetNextToken(const std::string &separatorchars)
Get next token as a string.
Abstract base for concrete hardware channels implementing dual-operator pattern.
Data handler that evaluates alarm conditions and writes status outputs.
std::string fAlarmOutputFile
void ParseConfigFile(QwParameterFile &) override
std::vector< alarmObject > fAlarmObjectList
QwAlarmHandler()
Default constructor (Protected for child class access)
QwAlarmHandler(const TString &name)
Constructor with name.
std::pair< std::string, std::string > ParseAlarmMapVariable(const string &, char)
void ProcessData() override
Process a single event: update alarm states and outputs.
Int_t ConnectChannels(QwSubsystemArrayParity &yield, QwSubsystemArrayParity &asym, QwSubsystemArrayParity &diff) override
Connect to Channels (event only)
const VQwHardwareChannel * value
VQwDataHandler::EQwHandleType analysisType
std::map< std::string, double > alarmParameterMap
std::map< std::string, std::string > alarmParameterMapStr
Subsystem array container specialized for parity analysis with asymmetry calculations.
const UInt_t * GetEventcutErrorFlagPointer() const
void SetEventcutErrorFlagPointer(const UInt_t *errorflagptr)
virtual void ParseConfigFile(QwParameterFile &file)
VQwDataHandler(const TString &name)
std::string ParseSeparator
std::pair< EQwHandleType, std::string > ParseHandledVariable(const std::string &variable)