lemAutoRun  1.0
PLemAutoRun.cpp
Go to the documentation of this file.
1 /********************************************************************************************
2 
3  PLemAutoRun.cpp
4 
5 *********************************************************************************************
6 
7  begin : Andreas Suter, 2006/03/14
8  modfied: :
9  copyright : (C) 2006 by
10  email : andreas.suter@psi.ch
11 
12 ********************************************************************************************/
13 
14 /***************************************************************************
15  * *
16  * This program is free software; you can redistribute it and/or modify *
17  * it under the terms of the GNU General Public License as published by *
18  * the Free Software Foundation; either version 2 of the License, or *
19  * (at your option) any later version. *
20  * *
21  ***************************************************************************/
22 
23 #include <iostream>
24 using namespace std;
25 
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <math.h>
29 #include <string.h>
30 
31 #include <QCoreApplication>
32 #include <QFile>
33 #include <QFileInfo>
34 #include <QDateTime>
35 #include <QStringList>
36 #include <QMapIterator>
37 
38 #include "lemAutoRun.h"
39 #include "PLemAutoRun.h"
40 
41 // defines ------------------------------------------------------------
42 
43 // Cryo related tags
44 #define CRYO_NO -1
45 #define CRYO_KONTI 0
46 #define CRYO_LOWTEMP 1
47 #define CRYO_OVEN_OMEGA 2
48 
49 // MIDAS flags
50 #define RUN_STOPPED 1
51 #define RUN_PAUSED 2
52 #define RUN_RUNNING 3
53 
54 #define BPVX 0
55 #define BPVY 1
56 #define BPV_CLOSE 3
57 #define BPV_OPEN 2
58 #define BPVX_ENABLED 0
59 #define BPVX_SET 1
60 #define BPVY_ENABLED 2
61 #define BPVY_SET 3
62 #define BPVX_STATE 25
63 #define BPVY_STATE 26
64 #define BPV_STATE_OPEN 5120
65 #define BPV_STATE_CLOSED 3072
66 
67 #define SC_VENT_ENABLED 6
68 #define SC_VENT_CMD 7
69 
70 // LS340 control commands
71 #define LS340_CTRL_PID 1
72 #define LS340_CTRL_ZONE 2
73 // LS340 input
74 #define LS340_INPUT_CF1 0
75 #define LS340_INPUT_CF2 1
76 #define LS340_INPUT_PRESSURE 2
77 #define LS340_INPUT_HEATER 7
78 #define LS340_INPUT_SETPOINT 8
79 #define LS340_INPUT_PID_P 9
80 #define LS340_INPUT_PID_I 10
81 #define LS340_INPUT_PID_D 11
82 #define LS340_INPUT_HEATER_RANGE 12
83 #define LS340_INPUT_HEATER_MODE 13
84 #define LS340_INPUT_RAMP 14
85 // LS340 output
86 #define LS340_OUTPUT_REMOTE 0
87 #define LS340_OUTPUT_SETPOINT 1
88 #define LS340_OUTPUT_PID_P 2
89 #define LS340_OUTPUT_PID_I 3
90 #define LS340_OUTPUT_PID_D 4
91 #define LS340_OUTPUT_HEATER_RANGE 5
92 #define LS340_OUTPUT_HEATER_MODE 6
93 #define LS340_OUTPUT_RAMP 7
94 // Omega oven input
95 #define OMEGA_OVEN_INPUT_TEMP 0
96 #define OMEGA_OVEN_INPUT_SETPOINT 6
97 // Omega oven output
98 #define OMEGA_OVEN_OUTPUT_SETPOINT 0
99 
100 // NeedleValve input
101 #define SM_INPUT_NEEDLEVALVE 0
102 // NeedleValve output
103 #define SM_OUTPUT_NEEDLEVALVE 0
104 #define SM_MODUS_NEEDLEVALVE 1
105 // Bronkhorst input
106 #define BH_INPUT_FLOW 0
107 #define BH_INPUT_VALVE 1
108 // Bronkhorst output
109 #define BH_OUTPUT_FLOW 0
110 // Danfsik Spin Rotator Magnet Current
111 #define SPINT_ROT_OUTPUT_CURRENT 2
112 #define SPINT_ROT_INPUT_CURRENT 3
113 // Danfysik input
114 #define DANFYSIK_INPUT_CURRENT 3
115 // Danfysik output
116 #define DANFYSIK_OUTPUT_CURRENT 2
117 // WEW input
118 #define WEWL_INPUT_STATUS 0
119 #define WEWL_INPUT_CURRENT 1
120 #define WEWH_INPUT_STATUS 3
121 #define WEWH_INPUT_CURRENT 4
122 // WEW output
123 #define WEWL_OUTPUT_CMD 0
124 #define WEWL_OUTPUT_CURRENT 1
125 #define WEWH_OUTPUT_CMD 2
126 #define WEWH_OUTPUT_CURRENT 3
127 #define WEW_SSP_LOCK 4
128 // HV FUG
129 #define HV_FUG_MAX_TRY 5
130 #define HV_FUG_CHS 16
131 #define HV_FUG_RIGHT_RODS 0
132 #define HV_FUG_LEFT_RODS 1
133 #define HV_FUG_LEFT_PLATE 2
134 #define HV_FUG_RIGHT_PLATE 3
135 #define HV_FUG_MOD 4
136 #define HV_FUG_MIRROR 8
137 #define HV_FUG_LENSE_2 9
138 #define HV_FUG_LENSE_3 10
139 #define HV_FUG_RAL 11
140 #define HV_FUG_RAR 12
141 #define HV_FUG_RAT 13
142 #define HV_FUG_RAB 14
143 #define HV_FUG_SAMPLE 15
144 // HV NHQ
145 #define HV_NHQ_TD_FIRST 0
146 #define HV_NHQ_TD_LAST 3
147 #define HV_NHQ_MCP1 4
148 // FOM input
149 #define FOM_CURRENT_MEASURED 0
150 #define FOM_VOLTAGE_MEASURED 1
151 #define FOM_BATTERY 2
152 // FOM ouput
153 #define FOM_CURRENT_DEMAND 0
154 #define FOM_STANDBY 1
155 // Beamline KV61, KV62 indices
156 #define BEAMLINE_KV61_DEMAND_CH 26
157 #define BEAMLINE_KV62_DEMAND_CH 28
158 
159 // web related stuff
160 #define HTML_LOAD 0
161 #define HTML_START 1
162 #define HTML_RUNNING 2
163 #define HTML_STOP 3
164 #define HTML_ABORTED 4
165 #define HTML_ALARM 5
166 #define HTML_WARMUP 6
167 #define HTML_STRANGE 7
168 #define HTML_PARSE_ERROR 8
169 #define HTML_FATAL 9
170 
171 // TEMP parameter tags
172 #define TEMP_DEMAND_TEMP 0
173 #define TEMP_DELTA_T 1
174 #define TEMP_STABILITY_TIMEOUT 2
175 #define TEMP_RAMP 3
176 #define TEMP_HEATER_RANGE 4
177 #define TEMP_P_PID 5
178 #define TEMP_I_PID 6
179 #define TEMP_D_PID 7
180 #define TEMP_FLOW 8
181 
182 // autorun transition tags
183 #define LAR_TT_IDLE 0
184 #define LAR_TT_FINISHED 1
185 #define LAR_TT_ABORTED 2
186 #define LAR_TT_WARMUP 3
187 
188 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189 // implementation of PLemAutoRunXMLParser
190 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191 
192 //**********************************************************************
193 // constructor
194 //**********************************************************************
201 {
202  fLar = lar;
203 }
204 
205 //**********************************************************************
206 // destructor
207 //**********************************************************************
212 {
213 }
214 
215 //**********************************************************************
216 // startDocument
217 //**********************************************************************
222 {
223  return true;
224 }
225 
226 //**********************************************************************
227 // startElement
228 //**********************************************************************
234 bool PLemAutoRunXMLParser::startElement(const QString&, const QString&,
235  const QString& qName,
236  const QXmlAttributes& qAttr)
237 {
238  if (qName == "xmlSchemaFln") {
239  fKey = eXmlSchemaFln;
240  } else if (qName == "xmlAutoRunFln") {
241  fKey = eXmlAutoRunFln;
242  } else if (qName == "xmlAutoRunValidateFln") {
243  fKey = eXmlAutoRunValidateFln;
244  } else if (qName == "xmlAutoRunHTML") {
245  fKey = eXmlAutoRunHTML;
246  } else if (qName == "enable_all") {
247  fKey = eEnableAll;
248  } else if (qName == "autoRunPath") {
249  fKey = eAutoRunPath;
250  } else if (qName == "hvSettingsPath") {
251  fKey = eHvSettingsPath;
252  } else if (qName == "debug") {
253  fKey = eDebug;
254  } else if (qName == "ignore_clients") {
255  fKey = eIgnore_clients;
256  } else if (qName == "ignore_alarms") {
257  fKey = eIgnore_alarms;
258  } else if (qName == "fug_hv_check") {
259  fKey = eFugHvCheck;
260  } else if (qName == "field_timeout") {
261  fKey = eField_timeout;
262  } else if (qName == "field_accuracy") {
263  fKey = eField_accuracy;
264  } else if (qName == "hv_timeout") {
265  fKey = eHv_timeout;
266  } else if (qName == "hv_accuracy") {
267  fKey = eHv_accuracy;
268  } else if (qName == "fom_current_accuracy") {
269  fKey = eFOM_current_accuracy;
270  } else if (qName == "wew_critical_current_ra") {
271  fKey = eWEW_critical_current_ra;
272  } else if (qName == "wewl_max_current") {
273  fKey = eWEWL_max_current;
274  } else if (qName == "wewh_max_current") {
275  fKey = eWEWH_max_current;
276  } else if (qName == "danfysik_max_current") {
277  fKey = eDanfysik_max_current;
278  } else if (qName == "trigger_events") {
279  fKey = eTrigger_events;
280  setAttribute("trigger_events_odb", qAttr);
281  } else if (qName == "enable_on_off_mode") {
282  fKey = eEnable_OnOff_Mode;
283  setAttribute("enable_on_off_mode_odb", qAttr);
284  } else if (qName == "alarms") {
285  fKey = eAlarms;
286  setAttribute("alarms_odb", qAttr);
287  } else if (qName == "alarms_td_hv_trip") {
288  fKey = eAlarm_td_hv_trip;
289  setAttribute("alarms_td_hv_trip_odb", qAttr);
290  } else if (qName == "run_info") {
291  fKey = eRun_info;
292  } else if (qName == "run_comment") {
293  fKey = eRun_comment;
294  setAttribute("run_comment_odb", qAttr);
295  } else if (qName == "tof_min") {
296  fKey = eTof_min;
297  setAttribute("tof_min_odb", qAttr);
298  } else if (qName == "tof_max") {
299  fKey = eTof_max;
300  setAttribute("tof_max_odb", qAttr);
301  } else if (qName == "mod_name") {
302  fKey = eMod_name;
303  setAttribute("mod_name_odb", qAttr);
304  } else if (qName == "mod_date") {
305  fKey = eMod_date;
306  setAttribute("mod_date_odb", qAttr);
307  } else if (qName == "lem_setup") {
308  fKey = eLem_setup;
309  setAttribute("lem_setup_odb", qAttr);
310  } else if (qName == "sample_name") {
311  fKey = eSample_name;
312  setAttribute("sample_name_info_odb", qAttr);
313  } else if (qName == "spin_rot_enabled") {
314  fKey = eSpin_rot_enabled;
315  setAttribute("spin_rot_calib_odb", qAttr);
316  } else if (qName == "spin_rot_angle") {
317  fKey = eSpin_rot_angle;
318  setAttribute("spin_rot_angle_odb", qAttr);
319  } else if (qName == "mag_param_wew") {
320  fKey = eMag_param_wew;
321  setAttribute("mag_param_wew_odb", qAttr);
322  } else if (qName == "mag_param_bpar") {
323  fKey = eMag_param_bpar;
324  setAttribute("mag_param_bpar_odb", qAttr);
325  } else if (qName == "setup_sample_enabled") {
326  fKey = eSetup_sample_enabled;
327  setAttribute("setup_sample_odb", qAttr);
328  } else if (qName == "setup_wew_enabled") {
329  fKey = eSetup_wew_enabled;
330  setAttribute("setup_wew_odb", qAttr);
331  } else if (qName == "setup_bpar_enabled") {
332  fKey = eSetup_bpar_enabled;
333  setAttribute("setup_bpar_odb", qAttr);
334  } else if (qName == "sample_cryo") {
335  fKey = eSample_cryo;
336  setAttribute("sample_cryo_info_odb", qAttr);
337  } else if (qName == "energy_loss_param") {
338  fKey = eEnergy_loss_param;
339  setAttribute("energy_loss_param_odb", qAttr);
340  } else if (qName == "clients") {
341  fKey = eClients;
342  } else if (qName == "clients_analyzer") {
343  fKey = eClients_analyzer;
344  setAttribute("analyzer_fe", qAttr);
345  } else if (qName == "clients_frontend") {
346  fKey = eClients_frontend;
347  setAttribute("vme_fe", qAttr);
348  } else if (qName == "clients_tfl") {
349  fKey = eClients_tfl;
350  setAttribute("tfl_scfe", qAttr);
351  } else if (qName == "clients_sample") {
352  fKey = eClients_sample;
353  setAttribute("sample_scfe", qAttr);
354  } else if (qName == "clients_sample_omega") {
355  fKey = eClients_sample_omega;
356  setAttribute("omega_scfe", qAttr);
357  } else if (qName == "clients_wew") {
358  fKey = eClients_WEW;
359  setAttribute("wew_scfe", qAttr);
360  } else if (qName == "clients_danfysik") {
361  fKey = eClients_danfysik;
362  setAttribute("danfysik_scfe", qAttr);
363  } else if (qName == "clients_hv") {
364  fKey = eClients_hv;
365  setAttribute("fug_scfe", qAttr);
366  } else if (qName == "clients_lemvac") {
367  fKey = eClients_lemvac;
368  setAttribute("lemvac_scfe", qAttr);
369  } else if (qName == "hv_demand") {
370  fKey = eHv_demand;
371  setAttribute("fug_eq", qAttr);
372  } else if (qName == "hv_measured") {
373  fKey = eHv_measured;
374  setAttribute("fug_eq", qAttr);
375  } else if (qName == "hv_current") {
376  fKey = eHv_current;
377  setAttribute("fug_eq", qAttr);
378  } else if (qName == "hv_detectors_demand") {
379  fKey = eHvDetector_demand;
380  setAttribute("hv_detectors_eq", qAttr);
381  } else if (qName == "hv_detectors_measured") {
382  fKey = eHvDetector_measured;
383  setAttribute("hv_detectors_eq", qAttr);
384  } else if (qName == "spin_rot_mag_input") {
385  fKey = eSpin_rot_mag_input;
386  setAttribute("danfysik_spin_rot_eq", qAttr);
387  } else if (qName == "spin_rot_mag_output") {
388  fKey = eSpin_rot_mag_output;
389  setAttribute("danfysik_spin_rot_eq", qAttr);
390  } else if (qName == "danfysik_input") {
391  fKey = eDanfysik_input;
392  setAttribute("danfysik_eq", qAttr);
393  } else if (qName == "danfysik_output") {
394  fKey = eDanfysik_output;
395  setAttribute("danfysik_eq", qAttr);
396  } else if (qName == "wew_output") {
397  fKey = eWEW_output;
398  setAttribute("wew_eq", qAttr);
399  } else if (qName == "wew_input") {
400  fKey = eWEW_input;
401  setAttribute("wew_eq", qAttr);
402  } else if (qName == "mag_field") {
403  fKey = eMag_field;
404  setAttribute("magnet_field_info", qAttr);
405  } else if (qName == "tfl_input") {
406  fKey = eTfl_input;
407  setAttribute("tfl_eq", qAttr);
408  } else if (qName == "tfl_output") {
409  fKey = eTfl_output;
410  setAttribute("tfl_eq", qAttr);
411  } else if (qName == "sample_ctrl_ch") {
412  fKey = eSample_ctrl_ch;
413  setAttribute("sample_eq", qAttr);
414  } else if (qName == "sample_channel") {
415  fKey = eSample_channel;
416  setAttribute("sample_eq", qAttr);
417  } else if (qName == "sample_sensor_type") {
418  fKey = eSample_sensor_type;
419  setAttribute("sample_eq", qAttr);
420  } else if (qName == "sample_input") {
421  fKey = eSample_input;
422  setAttribute("sample_eq", qAttr);
423  } else if (qName == "sample_output") {
424  fKey = eSample_output;
425  setAttribute("sample_eq", qAttr);
426  } else if (qName == "sample_datetime") {
427  fKey = eSample_datetime;
428  setAttribute("sample_eq", qAttr);
429  } else if (qName == "sample_rawvoltage") {
430  fKey = eSample_rawvoltage;
431  setAttribute("sample_eq", qAttr);
432  } else if (qName == "sample_no_connection") {
433  fKey = eSample_no_connection;
434  setAttribute("sample_eq", qAttr);
435  } else if (qName == "sample_bh_odb_offset_input") {
436  fKey = eSample_bh_odb_offset_input;
437  setAttribute("sample_eq", qAttr);
438  } else if (qName == "sample_bh_odb_offset_output") {
439  fKey = eSample_bh_odb_offset_output;
440  setAttribute("sample_eq", qAttr);
441  } else if (qName == "sample_oven_omega_input") {
442  fKey = eSample_oven_omega_input;
443  setAttribute("omega_eq", qAttr);
444  } else if (qName == "sample_oven_omega_output") {
445  fKey = eSample_oven_omega_output;
446  setAttribute("omega_eq", qAttr);
447  } else if (qName == "lemvac_input") {
448  fKey = eLemvac_input;
449  setAttribute("lemvac_eq", qAttr);
450  } else if (qName == "lemvac_output") {
451  fKey = eLemvac_output;
452  setAttribute("lemvac_eq", qAttr);
453  } else if (qName == "fom_input") {
454  fKey = eFOM_input;
455  setAttribute("fom_eq", qAttr);
456  } else if (qName == "fom_output") {
457  fKey = eFOM_output;
458  setAttribute("fom_eq", qAttr);
459  } else if (qName == "beamline_demand") {
460  fKey = eBeamline_demand;
461  setAttribute("beamline_eq", qAttr);
462  }
463 
464  return true;
465 }
466 
467 //**********************************************************************
468 // endElement
469 //**********************************************************************
473 bool PLemAutoRunXMLParser::endElement( const QString&, const QString&, const QString& )
474 {
475  fKey = eEmpty; // no key word anymore
476 
477  return true;
478 }
479 
480 //**********************************************************************
481 // characters
482 //**********************************************************************
488 bool PLemAutoRunXMLParser::characters(const QString &str)
489 {
490  int number;
491  bool ok;
492  QStringList strList;
493 
494  switch (fKey) {
495  case eXmlSchemaFln:
496  fLar->fXMLSchemaFln = str;
497  break;
498  case eXmlAutoRunFln:
499  fLar->fXMLAutoRunFln = str;
500  break;
501  case eXmlAutoRunValidateFln:
502  fLar->fXMLAutoRunValidateFln = str;
503  break;
504  case eXmlAutoRunHTML:
505  fLar->fXMLAutoRunHTML = str;
506  break;
507  case eEnableAll:
508  if (str == "yes") {
509  fLar->fEnableAll = true;
510  fLar->SetEnabled("all", true);
511  }
512  break;
513  case eAutoRunPath:
514  fLar->fAutoRunPath = str;
515  break;
516  case eHvSettingsPath:
517  fLar->fHvSettingsPath = str;
518  break;
519  case eDebug:
520  if (str == "true")
521  fLar->fDebug = true;
522  else
523  fLar->fDebug = false;
524  break;
525  case eIgnore_clients:
526  if (str == "true")
527  fLar->fIgnoreClients = true;
528  else
529  fLar->fIgnoreClients = false;
530  break;
531  case eIgnore_alarms:
532  if (str == "true")
533  fLar->fIgnoreAlarms = true;
534  else
535  fLar->fIgnoreAlarms = false;
536  break;
537  case eField_timeout:
538  fLar->fFieldTimeout = str.toFloat();
539  break;
540  case eFugHvCheck:
541  if (str == "false")
542  fLar->fFugHvCheck = false;
543  else
544  fLar->fFugHvCheck = true;
545  break;
546  case eField_accuracy:
547  fLar->fFieldAccuracy = str.toFloat();
548  break;
549  case eHv_timeout:
550  fLar->fHVTimeout = str.toFloat();
551  break;
552  case eHv_accuracy:
553  fLar->fHVAccuracy = str.toFloat();
554  break;
555  case eFOM_current_accuracy:
556  fLar->fFOMCurrentAccuracy = str.toFloat();
557  break;
558  case eWEW_critical_current_ra:
559  fLar->fWEWCriticalCurrentRA = str.toFloat();
560  break;
561  case eWEWL_max_current:
562  fLar->fWEWLMaxCurrent = str.toFloat();
563  break;
564  case eWEWH_max_current:
565  fLar->fWEWHMaxCurrent = str.toFloat();
566  break;
567  case eDanfysik_max_current:
568  fLar->fDanfysikMaxCurrent = str.toFloat();
569  break;
570  case eTrigger_events:
571  fLar->fTriggerEventsPath = str;
572  break;
573  case eEnable_OnOff_Mode:
574  fLar->fEnableOnOffModePath = str;
575  break;
576  case eAlarms:
577  fLar->fAlarmsPath = str;
578  break;
579  case eAlarm_td_hv_trip:
580  fLar->fAlarmTdHvTripPath = str;
581  break;
582  case eRun_info:
583  fLar->fRunInfoPath = str;
584  break;
585  case eRun_comment:
586  fLar->fRunCommentPath = str;
587  break;
588  case eTof_min:
589  fLar->fTofMinPath = str;
590  break;
591  case eTof_max:
592  fLar->fTofMaxPath = str;
593  break;
594  case eMod_name:
595  fLar->fModNamePath = str;
596  break;
597  case eMod_date:
598  fLar->fModDatePath = str;
599  break;
600  case eLem_setup:
601  fLar->fLemSetupPath = str;
602  break;
603  case eSample_name:
604  fLar->fSampleNamePath = str;
605  break;
606  case eSpin_rot_enabled:
607  fLar->fSpinRotEnabledPath = str;
608  break;
609  case eSpin_rot_angle:
610  fLar->fSpinRotAnglePath = str;
611  break;
612  case eMag_param_wew:
613  fLar->fMagParamWewPath = str;
614  break;
615  case eMag_param_bpar:
616  fLar->fMagParamBparPath = str;
617  break;
618  case eSetup_sample_enabled:
619  fLar->fSetupSampleEnabledPath = str;
620  break;
621  case eSetup_wew_enabled:
622  fLar->fSetupWewEnabledPath = str;
623  break;
624  case eSetup_bpar_enabled:
625  fLar->fSetupBparEnabledPath = str;
626  break;
627  case eSample_cryo:
628  fLar->fSampleCryoPath = str;
629  break;
630  case eEnergy_loss_param:
631  fLar->fEnergyLossParamPath = str;
632  break;
633  case eClients:
634  fLar->fClientsPath = str;
635  break;
636  case eClients_analyzer:
637  fLar->fAnalyzerName = str;
638  break;
639  case eClients_frontend:
640  fLar->fFrontendName = str;
641  break;
642  case eClients_tfl:
643  fLar->fTflFeName = str;
644  break;
645  case eClients_sample:
646  fLar->fSampleFeName = str;
647  break;
648  case eClients_sample_omega:
649  fLar->fSampleOvenOmegaFeName = str;
650  break;
651  case eClients_WEW:
652  fLar->fWEWFeName = str;
653  break;
654  case eClients_danfysik:
655  fLar->fDanfysikFeName = str;
656  break;
657  case eClients_hv:
658  fLar->fHVFeName = str;
659  break;
660  case eClients_lemvac:
661  fLar->fLemvacFeName = str;
662  break;
663  case eHv_demand:
664  fLar->fHVDemandPath = str;
665  break;
666  case eHv_measured:
667  fLar->fHVMeasuredPath = str;
668  break;
669  case eHv_current:
670  fLar->fHVCurrentPath = str;
671  break;
672  case eHvDetector_demand:
673  fLar->fHVDetectorDemandPath = str;
674  break;
675  case eHvDetector_measured:
676  fLar->fHVDetectorMeasuredPath = str;
677  break;
678  case eSpin_rot_mag_input:
679  fLar->fSpinRotMagInputPath = str;
680  break;
681  case eSpin_rot_mag_output:
682  fLar->fSpinRotMagOutputPath = str;
683  break;
684  case eDanfysik_input:
685  fLar->fDanfysikInputPath = str;
686  break;
687  case eDanfysik_output:
688  fLar->fDanfysikOutputPath = str;
689  break;
690  case eWEW_output:
691  fLar->fWEWOutputPath = str;
692  break;
693  case eWEW_input:
694  fLar->fWEWInputPath = str;
695  break;
696  case eMag_field:
697  fLar->fMagFieldPath = str;
698  break;
699  case eTfl_input:
700  fLar->fTflInputPath = str;
701  break;
702  case eTfl_output:
703  fLar->fTflOutputPath = str;
704  break;
705  case eSample_ctrl_ch:
706  fLar->fSampleCtrlChPath = str;
707  break;
708  case eSample_channel:
709  fLar->fSampleChannelPath = str;
710  break;
711  case eSample_sensor_type:
712  fLar->fSampleSensorTypePath = str;
713  break;
714  case eSample_input:
715  fLar->fSampleInputPath = str;
716  break;
717  case eSample_output:
718  fLar->fSampleOutputPath = str;
719  break;
720  case eSample_datetime:
721  fLar->fSampleDatetimePath = str;
722  break;
723  case eSample_rawvoltage:
724  fLar->fSampleRawVoltagePath = str;
725  break;
726  case eSample_no_connection:
727  fLar->fSampleNoConnectionPath = str;
728  break;
729  case eSample_bh_odb_offset_input:
730  number = str.toInt(&ok);
731  if (ok)
732  fLar->fSampleBhOdbOffsetInput = number;
733  break;
734  case eSample_bh_odb_offset_output:
735  number = str.toInt(&ok);
736  if (ok)
737  fLar->fSampleBhOdbOffsetOutput = number;
738  break;
739  case eSample_oven_omega_input:
740  fLar->fSampleOvenOmegaInputPath = str;
741  break;
742  case eSample_oven_omega_output:
743  fLar->fSampleOvenOmegaOutputPath = str;
744  break;
745  case eLemvac_input:
746  fLar->fLemvacInputPath = str;
747  break;
748  case eLemvac_output:
749  fLar->fLemvacOutputPath = str;
750  break;
751  case eFOM_input:
752  fLar->fFOMInputPath = str;
753  break;
754  case eFOM_output:
755  fLar->fFOMOutputPath = str;
756  break;
757  case eBeamline_demand:
758  fLar->fBeamlineDemandPath = str;
759  break;
760  default:
761  break;
762  }
763 
764  return true;
765 }
766 
767 //**********************************************************************
768 // endDocument
769 //**********************************************************************
777 {
778  QString errorMsg;
779 
780  // check if all expected input is found
781 
782  if (fLar->fXMLSchemaFln.isEmpty()) { // no XML-schema path given
783  fLar->fXMLSchemaFln = "/home/nemu/nemu/lemQt5/lemAutoRun/lemAutoRun.xsd";
784  errorMsg = "lemAutoRun: Couldn't find XML-schema path, will try hard-wired one (no warranty that it works): " +
785  fLar->fXMLSchemaFln;
786  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
787  }
788 
789  if (fLar->fXMLAutoRunFln.isEmpty()) { // no XML autorun sequence path is given
790  fLar->fXMLAutoRunFln = "/home/nemu/nemu/lemQt5/lemAutoRun/lar_seq.xml";
791  errorMsg = QString("lemAutoRun: Couldn't find XML autorun sequence path, ") +
792  QString("will try hard-wired one (no warranty that it works): ") +
793  fLar->fXMLAutoRunFln;
794  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
795  }
796 
797  if (fLar->fXMLAutoRunValidateFln.isEmpty()) { // no XML validate autorun sequence path is given
798  fLar->fXMLAutoRunFln = "/home/nemu/nemu/lemQt5/lemAutoRun/lar_seq_validate.xml";
799  errorMsg = QString("lemAutoRun: Couldn't find XML validate autorun sequence path, ") +
800  QString("will try hard-wired one (no warranty that it works): ") +
801  fLar->fXMLAutoRunValidateFln;
802  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
803  }
804 
805  if (fLar->fXMLAutoRunHTML.isEmpty()) { // no HTML autorun status page path is given
806  fLar->fXMLAutoRunHTML = "/home/nemu/nemu/midas/experiment/nemu/custom_pages/lemAutoRun.html";
807  errorMsg = QString("lemAutoRun: Couldn't find XML autorun sequence path, ") +
808  QString("will try hard-wired one (no warranty that it works): ") +
809  fLar->fXMLAutoRunHTML;
810  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
811  }
812 
813  if (fLar->fAutoRunPath.isEmpty()) { // no autorun path is given
814  fLar->fAutoRunPath = "/home/nemu/autoRun/";
815  errorMsg = QString("lemAutoRun: Couldn't find XML autorun sequence path, ") +
816  QString("will try hard-wired one (no warranty that it works): ") +
817  fLar->fAutoRunPath;
818  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
819  }
820 
821  // no field reaching timeout given, hence set it to 300 (sec)
822  if (fLar->fFieldTimeout == 0.0)
823  fLar->fFieldTimeout = 300;
824 
825  // no field accuracy needed to be reached before going on: default = 0.01 (A)
826  if (fLar->fFieldAccuracy == 0.0)
827  fLar->fFieldAccuracy = 0.01;
828 
829  // no HV reaching timeout given, hence set it to 300 (sec)
830  if (fLar->fHVTimeout == 0.0)
831  fLar->fHVTimeout = 300;
832 
833  // HV accuracy needed to be reached before going on: default = 0.02 (kV)
834  if (fLar->fHVAccuracy == 0.0)
835  fLar->fHVAccuracy = 0.02;
836 
837  // FOM current accuracy needed to be reached before going on: default = 1.0e-4 (mA)
838  if (fLar->fFOMCurrentAccuracy == 0.0)
839  fLar->fFOMCurrentAccuracy = 1.0e-4;
840 
841  // WEW critical current value above which the Penning trap problems is happening, default = 22.65A -> ~130G
842  if (fLar->fWEWCriticalCurrentRA == 0.0)
843  fLar->fWEWCriticalCurrentRA = 22.65;
844 
845  // WEWL max. current not given check
846  if (fLar->fWEWLMaxCurrent == 0.0)
847  fLar->fWEWLMaxCurrent = 50.0;
848 
849  // WEWH max. current not given check
850  if (fLar->fWEWHMaxCurrent == 0.0)
851  fLar->fWEWHMaxCurrent = 595.0;
852 
853  // Danfysik max. current not given check
854  if (fLar->fDanfysikMaxCurrent == 0.0)
855  fLar->fDanfysikMaxCurrent = 20.0;
856 
857  if (fLar->fTriggerEventsPath.isEmpty() && fLar->fEnabled["trigger_events_odb"]) { // odb path to the trigger events missing
858  fLar->fTriggerEventsPath = "/Equipment/Trigger/Statistics/Events sent";
859  errorMsg = QString("lemAutoRun: Couldn't find the path to the trigger events in the ODB, ") +
860  QString("will try hard-wired one (no warranty that it works): ") +
861  fLar->fTriggerEventsPath;
862  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
863  }
864 
865  if (fLar->fEnableOnOffModePath.isEmpty() && fLar->fEnabled["enable_on_off_mode_odb"]) { // odb path to the Enable_OnOff_Mode missing
866  fLar->fEnableOnOffModePath = "/Equipment/Trigger/Settings/Enable_OnOff_Mode";
867  errorMsg = QString("lemAutoRun: Couldn't find the path to the Enable_OnOff_Mode in the ODB, ") +
868  QString("will try hard-wired one (no warranty that it works): ") +
869  fLar->fEnableOnOffModePath;
870  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
871  }
872 
873  if (fLar->fAlarmsPath.isEmpty() && fLar->fEnabled["alarms_odb"]) { // odb path to the alarms missing
874  fLar->fAlarmsPath = "/Alarms/Alarms";
875  errorMsg = QString("lemAutoRun: Couldn't find the path to alarms in the ODB, ") +
876  QString("will try hard-wired one (no warranty that it works): ") +
877  fLar->fAlarmsPath;
878  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
879  }
880 
881  if (fLar->fAlarmTdHvTripPath.isEmpty() && fLar->fEnabled["alarms_td_hv_trip_odb"]) { // odb path to the alarms missing
882  fLar->fAlarmTdHvTripPath = "/Alarms/Alarms/hv_fug_check_trip_level/Triggered";
883  errorMsg = QString("lemAutoRun: Couldn't find the path to TD HV Trip flag in the ODB, ") +
884  QString("will try hard-wired one (no warranty that it works): ") +
885  fLar->fAlarmTdHvTripPath;
886  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
887  }
888 
889  if (fLar->fRunInfoPath.isEmpty()) { // odb path to run info missing
890  fLar->fRunInfoPath = "/Runinfo";
891  errorMsg = QString("lemAutoRun: Couldn't find the path to the run info in the ODB, ") +
892  QString("will try hard-wired one (no warranty that it works): ") +
893  fLar->fRunInfoPath;
894  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
895  }
896 
897  if (fLar->fRunCommentPath.isEmpty() && fLar->fEnabled["run_comment_odb"]) { // odb path to run comments missing
898  fLar->fRunCommentPath = "/Experiment/Run Parameters/comment";
899  errorMsg = QString("lemAutoRun: Couldn't find the path to the run title in the ODB, ") +
900  QString("will try hard-wired one (no warranty that it works): ") +
901  fLar->fRunCommentPath;
902  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
903  }
904 
905  if (fLar->fTofMinPath.isEmpty() && fLar->fEnabled["tof_min_odb"]) { // odb path to TOF Min missing
906  fLar->fTofMinPath = "/Analyzer/Parameters/MCP2AnaModule/TofM2Fmin";
907  errorMsg = QString("lemAutoRun: Couldn't find the path to TOF Min in the ODB, ") +
908  QString("will try hard-wired one (no warranty that it works): ") +
909  fLar->fTofMinPath;
910  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
911  }
912 
913  if (fLar->fTofMaxPath.isEmpty() && fLar->fEnabled["tof_max_odb"]) { // odb path to TOF Max missing
914  fLar->fTofMaxPath = "/Analyzer/Parameters/MCP2AnaModule/TofM2Fmax";
915  errorMsg = QString("lemAutoRun: Couldn't find the path to TOF Max in the ODB, ") +
916  QString("will try hard-wired one (no warranty that it works): ") +
917  fLar->fTofMaxPath;
918  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
919  }
920 
921  if (fLar->fModNamePath.isEmpty() && fLar->fEnabled["mod_name_odb"]) { // odb path to moderator name
922  fLar->fModNamePath = "/Info/Moderator";
923  errorMsg = QString("lemAutoRun: Couldn't find the path to the moderator name in the ODB, ") +
924  QString("will try hard-wired one (no warranty that it works): ") +
925  fLar->fModNamePath;
926  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
927  }
928 
929  if (fLar->fModDatePath.isEmpty() && fLar->fEnabled["mod_date_odb"]) { // odb path to moderator date
930  fLar->fModDatePath = "/Info/ModeratorDATE";
931  errorMsg = QString("lemAutoRun: Couldn't find the path to the moderator date in the ODB, ") +
932  QString("will try hard-wired one (no warranty that it works): ") +
933  fLar->fModDatePath;
934  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
935  }
936 
937  if (fLar->fLemSetupPath.isEmpty() && fLar->fEnabled["lem_setup_odb"]) { // odb path to LEM setup
938  fLar->fLemSetupPath = "/Info/LEM_Setup";
939  errorMsg = QString("lemAutoRun: Couldn't find the path to the LEM setup in the ODB, ") +
940  QString("will try hard-wired one (no warranty that it works): ") +
941  fLar->fLemSetupPath;
942  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
943  }
944 
945  if (fLar->fSampleNamePath.isEmpty() && fLar->fEnabled["sample_name_info_odb"]) { // odb path to Sample Name
946  fLar->fSampleNamePath = "/Info/Sample Name";
947  errorMsg = QString("lemAutoRun: Couldn't find the path to the Sample Name in the ODB, ") +
948  QString("will try hard-wired one (no warranty that it works): ") +
949  fLar->fSampleNamePath;
950  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
951  }
952 
953  if (fLar->fSpinRotEnabledPath.isEmpty() && fLar->fEnabled["spin_rot_calib_odb"]) { // odb path to spin rotation enabled flag
954  fLar->fSpinRotEnabledPath = "/Info/SpinRot_Parameter/Enable spin rotator calibration";
955  errorMsg = QString("lemAutoRun: Couldn't find the path to the spin rotation enabled flag in the ODB, ") +
956  QString("will try hard-wired one (no warranty that it works): ") +
957  fLar->fSpinRotEnabledPath;
958  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
959  }
960 
961  if (fLar->fSpinRotAnglePath.isEmpty() && fLar->fEnabled["spin_rot_angle_odb"]) { // odb path to spin rotation angle
962  fLar->fSpinRotAnglePath = "/Info/SpinRot_Parameter/RotationAngle";
963  errorMsg = QString("lemAutoRun: Couldn't find the path to the spin rotation angle in the ODB, ") +
964  QString("will try hard-wired one (no warranty that it works): ") +
965  fLar->fSpinRotAnglePath;
966  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
967  }
968 
969  if (fLar->fMagParamWewPath.isEmpty() && fLar->fEnabled["mag_param_wew_odb"]) { // odb path to the WEW calibration (A->G)
970  fLar->fMagParamWewPath = "/Info/Magnet_Parameter/WEW";
971  errorMsg = QString("lemAutoRun: Couldn't find the path to the WEW magnet calibration (A->G) in the ODB, ") +
972  QString("will try hard-wired one (no warranty that it works): ") +
973  fLar->fMagParamWewPath;
974  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
975  }
976 
977  if (fLar->fMagParamBparPath.isEmpty() && fLar->fEnabled["mag_param_bpar_odb"]) { // odb path to the Bpar calibration (A->G)
978  fLar->fMagParamBparPath = "/Info/Magnet_Parameter/Bpar";
979  errorMsg = QString("lemAutoRun: Couldn't find the path to the Bpar magnet calibration (A->G) in the ODB, ") +
980  QString("will try hard-wired one (no warranty that it works): ") +
981  fLar->fMagParamBparPath;
982  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
983  }
984 
985  if (fLar->fSetupSampleEnabledPath.isEmpty() && fLar->fEnabled["setup_sample_odb"]) { // odb path to sample enable flag
986  fLar->fSetupSampleEnabledPath = "/Info/LEM_Setup_Parameter/Sample";
987  errorMsg = QString("lemAutoRun: Couldn't find the path to the sample enable flag in the ODB, ") +
988  QString("will try hard-wired one (no warranty that it works): ") +
989  fLar->fSetupSampleEnabledPath;
990  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
991  }
992 
993  if (fLar->fSetupWewEnabledPath.isEmpty() && fLar->fEnabled["setup_wew_odb"]) { // odb path to WEW enable flag
994  fLar->fSetupWewEnabledPath = "/Info/LEM_Setup_Parameter/WEW";
995  errorMsg = QString("lemAutoRun: Couldn't find the path to the WEW enable flag in the ODB, ") +
996  QString("will try hard-wired one (no warranty that it works): ") +
997  fLar->fSetupWewEnabledPath;
998  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
999  }
1000 
1001  if (fLar->fSetupBparEnabledPath.isEmpty() && fLar->fEnabled["setup_bpar_odb"]) { // odb path to Bpar enable flag
1002  fLar->fSetupBparEnabledPath = "/Info/LEM_Setup_Parameter/Bpar";
1003  errorMsg = QString("lemAutoRun: Couldn't find the path to the Bpar enable flag in the ODB, ") +
1004  QString("will try hard-wired one (no warranty that it works): ") +
1005  fLar->fSetupBparEnabledPath;
1006  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1007  }
1008 
1009  if (fLar->fSampleCryoPath.isEmpty() && fLar->fEnabled["sample_cryo_info_odb"]) { // odb path to Sample Cryo
1010  fLar->fSampleCryoPath = "/Info/Sample Cryo";
1011  errorMsg = QString("lemAutoRun: Couldn't find the path to the Sample Cryo in the ODB, ") +
1012  QString("will try hard-wired one (no warranty that it works): ") +
1013  fLar->fSampleCryoPath;
1014  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1015  }
1016 
1017  if (fLar->fEnergyLossParamPath.isEmpty() && fLar->fEnabled["energy_loss_param_odb"]) { // odb path to energy loss parameters
1018  fLar->fEnergyLossParamPath = "/Info/EnergyLoss_Parameter";
1019  errorMsg = QString("lemAutoRun: Couldn't find the path to the energy loss parameters in the ODB, ") +
1020  QString("will try hard-wired one (no warranty that it works): ") +
1021  fLar->fEnergyLossParamPath;
1022  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1023  }
1024 
1025  if (fLar->fClientsPath.isEmpty()) { // odb path to the system/clients missing
1026  fLar->fClientsPath = "/System/Clients";
1027  errorMsg = QString("lemAutoRun: Couldn't find the path to clients in the ODB, ") +
1028  QString("will try hard-wired one (no warranty that it works): ") +
1029  fLar->fClientsPath;
1030  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1031  }
1032 
1033  if (fLar->fAnalyzerName.isEmpty() && fLar->fEnabled["analyzer_fe"]) { // no analyzer ODB name found
1034  fLar->fAnalyzerName = "Analyzer";
1035  errorMsg = QString("lemAutoRun: Couldn't find ODB name for the analyzer, ") +
1036  QString("will try hard-wired one (no warranty that it works): ") +
1037  fLar->fAnalyzerName;
1038  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1039  }
1040 
1041  if (fLar->fFrontendName.isEmpty() && fLar->fEnabled["vme_fe"]) { // no frontend ODB name found
1042  fLar->fFrontendName = "VME_FE";
1043  errorMsg = QString("lemAutoRun: Couldn't find ODB name for the frontend, ") +
1044  QString("will try hard-wired one (no warranty that it works): ") +
1045  fLar->fFrontendName;
1046  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1047  }
1048 
1049  if (fLar->fTflFeName.isEmpty() && fLar->fEnabled["tfl_scfe"]) { // no tfl_scfe ODB name found
1050  fLar->fTflFeName = "TFL_SC";
1051  errorMsg = QString("lemAutoRun: Couldn't find ODB name for tfl_scfe, ") +
1052  QString("will try hard-wired one (no warranty that it works): ") +
1053  fLar->fTflFeName;
1054  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1055  }
1056 
1057  if (fLar->fSampleFeName.isEmpty() && fLar->fEnabled["sample_scfe"]) { // no sample_scfe ODB name found
1058  fLar->fSampleFeName = "Sample_SC";
1059  errorMsg = QString("lemAutoRun: Couldn't find ODB name for sample_scfe, ") +
1060  QString("will try hard-wired one (no warranty that it works): ") +
1061  fLar->fSampleFeName;
1062  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1063  }
1064 
1065  if (fLar->fSampleOvenOmegaFeName.isEmpty() && fLar->fEnabled["omega_scfe"]) { // no sample oven omega scfe ODB name found
1066  fLar->fSampleOvenOmegaFeName = "Omega SC";
1067  errorMsg = QString("lemAutoRun: Couldn't find ODB name for Oven Omega SCFE, ") +
1068  QString("will try hard-wired one (no warranty that it works): ") +
1069  fLar->fSampleOvenOmegaFeName;
1070  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1071  }
1072 
1073  if (fLar->fWEWFeName.isEmpty() && fLar->fEnabled["wew_scfe"]) { // no WEW scfe ODB name found
1074  fLar->fWEWFeName = "WEW SC";
1075  errorMsg = QString("lemAutoRun: Couldn't find ODB name for WEW SCFE, ") +
1076  QString("will try hard-wired one (no warranty that it works): ") +
1077  fLar->fWEWFeName;
1078  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1079  }
1080 
1081  if (fLar->fDanfysikFeName.isEmpty() && fLar->fEnabled["danfysik_scfe"]) { // no danfysik scfe ODB name found
1082  fLar->fDanfysikFeName = "Danfysik_SC";
1083  errorMsg = QString("lemAutoRun: Couldn't find ODB name for Danfysik SCFE, ") +
1084  QString("will try hard-wired one (no warranty that it works): ") +
1085  fLar->fDanfysikFeName;
1086  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1087  }
1088 
1089  if (fLar->fHVFeName.isEmpty() && fLar->fEnabled["fug_scfe"]) { // no hv_fug_scfe ODB name found
1090  fLar->fHVFeName = "FUG";
1091  errorMsg = QString("lemAutoRun: Couldn't find ODB name for hv_fug_scfe, ") +
1092  QString("will try hard-wired one (no warranty that it works): ") +
1093  fLar->fHVFeName;
1094  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1095  }
1096 
1097  if (fLar->fLemvacFeName.isEmpty() && fLar->fEnabled["lemvac_scfe"]) { // no lemvac_scfe ODB name found
1098  fLar->fLemvacFeName = "LEMVAC_SC";
1099  errorMsg = QString("lemAutoRun: Couldn't find ODB name for lemvac_scfe, ") +
1100  QString("will try hard-wired one (no warranty that it works): ") +
1101  fLar->fLemvacFeName;
1102  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1103  }
1104 
1105  if (fLar->fHVDemandPath.isEmpty() && fLar->fEnabled["fug_eq"]) { // path to the HV demand values
1106  fLar->fHVDemandPath = "/Equipment/HV/Variables/Demand";
1107  errorMsg = QString("lemAutoRun: Couldn't find the path to HV demand values in the ODB, ") +
1108  QString("will try hard-wired one (no warranty that it works): ") +
1109  fLar->fHVDemandPath;
1110  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1111  }
1112 
1113  if (fLar->fHVMeasuredPath.isEmpty() && fLar->fEnabled["fug_eq"]) { // path to the HV measured values
1114  fLar->fHVMeasuredPath = "/Equipment/HV/Variables/Measured";
1115  errorMsg = QString("lemAutoRun: Couldn't find the path to HV measured values in the ODB, ") +
1116  QString("will try hard-wired one (no warranty that it works): ") +
1117  fLar->fHVMeasuredPath;
1118  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1119  }
1120 
1121  if (fLar->fHVCurrentPath.isEmpty() && fLar->fEnabled["fug_eq"]) { // path to the HV current values
1122  fLar->fHVCurrentPath = "/Equipment/HV/Variables/Current";
1123  errorMsg = QString("lemAutoRun: Couldn't find the path to HV current values in the ODB, ") +
1124  QString("will try hard-wired one (no warranty that it works): ") +
1125  fLar->fHVCurrentPath;
1126  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1127  }
1128 
1129  if (fLar->fHVDetectorDemandPath.isEmpty() && fLar->fEnabled["hv_detectors_eq"]) { // path to the HV Detectors demand values
1130  fLar->fHVDetectorDemandPath = "/Equipment/HV Detectors/Variables/Demand";
1131  errorMsg = QString("lemAutoRun: Couldn't find the path to the HV Detectors demand values in the ODB, ") +
1132  QString("will try hard-wired one (no warranty that it works): ") +
1133  fLar->fHVDetectorDemandPath;
1134  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1135  }
1136 
1137  if (fLar->fHVDetectorMeasuredPath.isEmpty() && fLar->fEnabled["hv_detectors_eq"]) { // path to the HV Detectors measured values
1138  fLar->fHVDetectorMeasuredPath = "/Equipment/HV Detectors/Variables/Measured";
1139  errorMsg = QString("lemAutoRun: Couldn't find the path to the HV Detectors measured values in the ODB, ") +
1140  QString("will try hard-wired one (no warranty that it works): ") +
1141  fLar->fHVDetectorMeasuredPath;
1142  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1143  }
1144 
1145  if (fLar->fSpinRotMagInputPath.isEmpty() && fLar->fEnabled["danfysik_spin_rot_eq"]) { // path to the Danfysik spin rotator power supply
1146  fLar->fSpinRotMagInputPath = "/Equipment/Danfysik_Spin_Rot/Variables/Input";
1147  errorMsg = QString("lemAutoRun: Couldn't find the path to the Danfysik Spin Rotator power supply input values in the ODB, ") +
1148  QString("will try hard-wired one (no warranty that it works): ") +
1149  fLar->fSpinRotMagInputPath;
1150  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1151  }
1152 
1153  if (fLar->fSpinRotMagOutputPath.isEmpty() && fLar->fEnabled["danfysik_spin_rot_eq"]) { // path to the Danfysik spin rotator power supply
1154  fLar->fSpinRotMagOutputPath = "/Equipment/Danfysik_Spin_Rot/Variables/Output";
1155  errorMsg = QString("lemAutoRun: Couldn't find the path to the Danfysik Spin Rotator power supply output values in the ODB, ") +
1156  QString("will try hard-wired one (no warranty that it works): ") +
1157  fLar->fSpinRotMagOutputPath;
1158  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1159  }
1160 
1161  if (fLar->fDanfysikInputPath.isEmpty() && fLar->fEnabled["danfysik_eq"]) { // path to the Danfysik input values
1162  fLar->fDanfysikInputPath = "/Equipment/Danfysik/Variables/Input";
1163  errorMsg = QString("lemAutoRun: Couldn't find the path to Danfysik input values in the ODB, ") +
1164  QString("will try hard-wired one (no warranty that it works): ") +
1165  fLar->fDanfysikInputPath;
1166  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1167  }
1168 
1169  if (fLar->fDanfysikOutputPath.isEmpty() && fLar->fEnabled["danfysik_eq"]) { // path to the Danfysik output values
1170  fLar->fDanfysikOutputPath = "/Equipment/Danfysik/Variables/Output";
1171  errorMsg = QString("lemAutoRun: Couldn't find the path to Danfysik output values in the ODB, ") +
1172  QString("will try hard-wired one (no warranty that it works): ") +
1173  fLar->fDanfysikOutputPath;
1174  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1175  }
1176 
1177  if (fLar->fWEWOutputPath.isEmpty() && fLar->fEnabled["wew_eq"]) { // path to the WEW output values
1178  fLar->fWEWOutputPath = "/Equipment/WEW/Variables/Output";
1179  errorMsg = QString("lemAutoRun: Couldn't find the path to WEW output values in the ODB, ") +
1180  QString("will try hard-wired one (no warranty that it works): ") +
1181  fLar->fWEWOutputPath;
1182  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1183  }
1184 
1185  if (fLar->fWEWInputPath.isEmpty() && fLar->fEnabled["wew_eq"]) { // path to the WEW input values
1186  fLar->fWEWInputPath = "/Equipment/WEW/Variables/Input";
1187  errorMsg = QString("lemAutoRun: Couldn't find the path to WEW input values in the ODB, ") +
1188  QString("will try hard-wired one (no warranty that it works): ") +
1189  fLar->fWEWInputPath;
1190  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1191  }
1192 
1193  if (fLar->fMagFieldPath.isEmpty() && fLar->fEnabled["magnet_field_info"]) { // path to the magnet field value
1194  fLar->fMagFieldPath = "/Info/Magnetic Field (G)";
1195  errorMsg = QString("lemAutoRun: Couldn't find the path to magnet field parameters of the WEW in the ODB, ") +
1196  QString("will try hard-wired one (no warranty that it works): ") +
1197  fLar->fMagFieldPath;
1198  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1199  }
1200 
1201  if (fLar->fTflInputPath.isEmpty() && fLar->fEnabled["tfl_eq"]) { // path to the tfl input values
1202  fLar->fTflInputPath = "/Equipment/TFL/Variables/Input";
1203  errorMsg = QString("lemAutoRun: Couldn't find the path to tfl input values in the ODB, ") +
1204  QString("will try hard-wired one (no warranty that it works): ") +
1205  fLar->fTflInputPath;
1206  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1207  }
1208 
1209  if (fLar->fTflOutputPath.isEmpty() && fLar->fEnabled["tfl_eq"]) { // path to the tfl output values
1210  fLar->fTflOutputPath = "/Equipment/TFL/Variables/Output";
1211  errorMsg = QString("lemAutoRun: Couldn't find the path to tfl input values in the ODB, ") +
1212  QString("will try hard-wired one (no warranty that it works): ") +
1213  fLar->fTflOutputPath;
1214  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1215  }
1216 
1217  if (fLar->fSampleCtrlChPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample cryo ctrl channel of the LS340
1218  fLar->fSampleCtrlChPath = "/Equipment/SampleCryo/Settings/Devices/Lake340_Sample_0/DD/Loop1/CTRL_CH";
1219  errorMsg = QString("lemAutoRun: Couldn't find the path to ctrl channel of the LS340 in the ODB, ") +
1220  QString("will try hard-wired one (no warranty that it works): ") +
1221  fLar->fSampleCtrlChPath;
1222  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1223  }
1224 
1225  if (fLar->fSampleChannelPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample cryo channel assignment of the LS340
1226  fLar->fSampleChannelPath = "/Equipment/SampleCryo/Settings/Devices/Lake340_Sample_0/DD/Sensors/Channel";
1227  errorMsg = QString("lemAutoRun: Couldn't find the path to channel assignment of the LS340 in the ODB, ") +
1228  QString("will try hard-wired one (no warranty that it works): ") +
1229  fLar->fSampleChannelPath;
1230  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1231  }
1232 
1233  if (fLar->fSampleSensorTypePath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample cryo sensor type assignment of the LS340
1234  fLar->fSampleSensorTypePath = "/Equipment/SampleCryo/Settings/Devices/Lake340_Sample_0/DD/Sensors/Sensor Type";
1235  errorMsg = QString("lemAutoRun: Couldn't find the path to sensor type assignment of the LS340 in the ODB, ") +
1236  QString("will try hard-wired one (no warranty that it works): ") +
1237  fLar->fSampleSensorTypePath;
1238  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1239  }
1240 
1241  if (fLar->fSampleInputPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample input values
1242  fLar->fSampleInputPath = "/Equipment/SampleCryo/Variables/Input";
1243  errorMsg = QString("lemAutoRun: Couldn't find the path to sample cryo input values in the ODB, ") +
1244  QString("will try hard-wired one (no warranty that it works): ") +
1245  fLar->fSampleInputPath;
1246  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1247  }
1248 
1249  if (fLar->fSampleOutputPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample output values
1250  fLar->fSampleOutputPath = "/Equipment/SampleCryo/Variables/Output";
1251  errorMsg = QString("lemAutoRun: Couldn't find the path to sample cryo output values in the ODB, ") +
1252  QString("will try hard-wired one (no warranty that it works): ") +
1253  fLar->fSampleOutputPath;
1254  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1255  }
1256 
1257  if (fLar->fSampleDatetimePath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample DD date time variable
1258  fLar->fSampleDatetimePath = "/Equipment/SampleCryo/Settings/Devices/Lake340_Sample_0/DD/Sensors/Date and Time";
1259  errorMsg = QString("lemAutoRun: Couldn't find the path to sample cryo 'date and time' in the ODB, ") +
1260  QString("will try hard-wired one (no warranty that it works): ") +
1261  fLar->fSampleDatetimePath;
1262  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1263  }
1264 
1265  if (fLar->fSampleRawVoltagePath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample DD raw voltage variable
1266  fLar->fSampleRawVoltagePath = "/Equipment/SampleCryo/Settings/Devices/Lake340_Sample_0/DD/Sensors/Raw Input Ch";
1267  errorMsg = QString("lemAutoRun: Couldn't find the path to sample cryo 'RawVoltage' in the ODB, ") +
1268  QString("will try hard-wired one (no warranty that it works): ") +
1269  fLar->fSampleRawVoltagePath;
1270  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1271  }
1272 
1273  if (fLar->fSampleNoConnectionPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample DD no connection flag
1274  fLar->fSampleNoConnectionPath = "/Equipment/SampleCryo/Settings/Devices/Lake340_Sample_0/DD/Internal/No Connection";
1275  errorMsg = QString("lemAutoRun: Couldn't find the path to sample cryo 'no connection' flag in the ODB, ") +
1276  QString("will try hard-wired one (no warranty that it works): ") +
1277  fLar->fSampleNoConnectionPath;
1278  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1279  }
1280 
1281  if ((fLar->fSampleBhOdbOffsetInput == -1) && fLar->fEnabled["sample_eq"]) { // odb offset for bronkhorst input missing
1282  fLar->fSampleBhOdbOffsetInput = 10;
1283  errorMsg = QString("lemAutoRun: Couldn't find input ODB offset for the bronkhorst flow meter, ") +
1284  QString("will try hard-wired one (no warranty that it works):%1 ").arg(fLar->fSampleBhOdbOffsetInput);
1285  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1286  }
1287 
1288  if ((fLar->fSampleBhOdbOffsetOutput == -1) && fLar->fEnabled["sample_eq"]) { // odb offset for bronkhorst output missing
1289  fLar->fSampleBhOdbOffsetOutput = 7;
1290  errorMsg = QString("lemAutoRun: Couldn't find output ODB offset for the bronkhorst flow meter, ") +
1291  QString("will try hard-wired one (no warranty that it works):%1 ").arg(fLar->fSampleBhOdbOffsetOutput);
1292  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1293  }
1294 
1295  if (fLar->fSampleOvenOmegaInputPath.isEmpty() && fLar->fEnabled["omega_eq"]) { // path to the sample oven omega input values
1296  fLar->fSampleOvenOmegaInputPath = "/Equipment/Omega/Variables/Input";
1297  errorMsg = QString("lemAutoRun: Couldn't find the path to sample oven omega input values in the ODB, ") +
1298  QString("will try hard-wired one (no warranty that it works): ") +
1299  fLar->fSampleOvenOmegaInputPath;
1300  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1301  }
1302 
1303  if (fLar->fSampleOvenOmegaOutputPath.isEmpty() && fLar->fEnabled["omega_eq"]) { // path to the sample oven omega output values
1304  fLar->fSampleOvenOmegaOutputPath = "/Equipment/Oven/Variables/Output";
1305  errorMsg = QString("lemAutoRun: Couldn't find the path to sample oven output values in the ODB, ") +
1306  QString("will try hard-wired one (no warranty that it works): ") +
1307  fLar->fSampleOvenOmegaOutputPath;
1308  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1309  }
1310 
1311  if (fLar->fLemvacInputPath.isEmpty() && fLar->fEnabled["lemvac_eq"]) { // path to the lemvac input values
1312  fLar->fLemvacInputPath = "/Equipment/LEMVAC/Variables/Input";
1313  errorMsg = QString("lemAutoRun: Couldn't find the path to lemvac input values in the ODB, ") +
1314  QString("will try hard-wired one (no warranty that it works): ") +
1315  fLar->fLemvacInputPath;
1316  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1317  }
1318 
1319  if (fLar->fLemvacOutputPath.isEmpty() && fLar->fEnabled["lemvac_eq"]) { // path to the lemvac output values
1320  fLar->fLemvacOutputPath = "/Equipment/LEMVAC/Variables/Output";
1321  errorMsg = QString("lemAutoRun: Couldn't find the path to lemvac output values in the ODB, ") +
1322  QString("will try hard-wired one (no warranty that it works): ") +
1323  fLar->fLemvacOutputPath;
1324  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1325  }
1326 
1327  if (fLar->fFOMInputPath.isEmpty() && fLar->fEnabled["fom_eq"]) { // path to the FOM input values
1328  fLar->fFOMInputPath = "/Equipment/FOM/Variables/Input";
1329  errorMsg = QString("lemAutoRun: Couldn't find the path to FOM input values in the ODB, ") +
1330  QString("will try hard-wired one (no warranty that it works): ") +
1331  fLar->fFOMInputPath;
1332  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1333  }
1334 
1335  if (fLar->fFOMOutputPath.isEmpty() && fLar->fEnabled["fom_eq"]) { // path to the FOM output values
1336  fLar->fFOMOutputPath = "/Equipment/FOM/Variables/Output";
1337  errorMsg = QString("lemAutoRun: Couldn't find the path to FOM output values in the ODB, ") +
1338  QString("will try hard-wired one (no warranty that it works): ") +
1339  fLar->fFOMOutputPath;
1340  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1341  }
1342 
1343  if (fLar->fBeamlineDemandPath.isEmpty() && fLar->fEnabled["beamline_eq"]) { // path to the Beamline demand values
1344  fLar->fBeamlineDemandPath = "/Equipment/Beamline/Variables/Demand";
1345  errorMsg = QString("lemAutoRun: Couldn't find the path to the Beamline demand values in the ODB, ") +
1346  QString("will try hard-wired one (no warranty that it works): ") +
1347  fLar->fBeamlineDemandPath;
1348  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1349  }
1350 
1351  return true;
1352 }
1353 
1354 //**********************************************************************
1355 // setAttribute
1356 //**********************************************************************
1362 void PLemAutoRunXMLParser::setAttribute(const QString key, const QXmlAttributes &qAttr)
1363 {
1364  if (qAttr.index("enabled") != -1) {
1365  if (qAttr.value("enabled") == "yes") {
1366  fLar->SetEnabled(key, true);
1367  } else if (qAttr.value("enabled") == "no") {
1368  fLar->SetEnabled(key, false);
1369  }
1370  }
1371 }
1372 
1373 
1374 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1375 // implementation of PLemSampleCryoXMLParser
1376 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1377 
1378 //**********************************************************************
1379 // constructor
1380 //**********************************************************************
1387 {
1388  fLar = lar;
1389 }
1390 
1391 //**********************************************************************
1392 // destructor
1393 //**********************************************************************
1398 {
1399 }
1400 
1401 //**********************************************************************
1402 // startDocument
1403 //**********************************************************************
1408 {
1409  return true;
1410 }
1411 
1412 //**********************************************************************
1413 // startElement
1414 //**********************************************************************
1420 bool PLemSampleCryoXMLParser::startElement(const QString&, const QString&,
1421  const QString& qName,
1422  const QXmlAttributes&)
1423 {
1424  if (qName == "temp_regulation") {
1425  fKey = eTemp_regulation;
1426  } else if (qName == "max_temp_increase") {
1427  fKey = eMax_temp_increase;
1428  } else if (qName == "bh_max_flow") {
1429  fKey = eBh_max_flow;
1430  } else if (qName == "bh_min_flow") {
1431  fKey = eBh_min_flow;
1432  } else if (qName == "bh_flow_p_heat_0") {
1433  fKey = eBh_flow_p_heat_0;
1434  } else if (qName == "bh_flow_p_heat_1") {
1435  fKey = eBh_flow_p_heat_1;
1436  } else if (qName == "bh_flow_d_heat") {
1437  fKey = eBh_flow_d_heat;
1438  } else if (qName == "bh_flow_temp") {
1439  fKey = eBh_flow_temp;
1440  } else if (qName == "bh_flow_temp_offset") {
1441  fKey = eBh_flow_temp_offset;
1442  } else if (qName == "bh_flow_offset") {
1443  fKey = eBh_flow_offset;
1444  } else if (qName == "d_set_ratio") {
1445  fKey = eD_set_ratio;
1446  } else if (qName == "abs_max_temp_diff") {
1447  fKey = eAbs_max_temp_diff;
1448  } else if (qName == "rel_max_temp_diff") {
1449  fKey = eRel_max_temp_diff;
1450  } else if (qName == "max_temp_trend") {
1451  fKey = eMax_temp_trend;
1452  } else if (qName == "heater_min") {
1453  fKey = eHeater_min;
1454  } else if (qName == "heater_max") {
1455  fKey = eHeater_max;
1456  } else if (qName == "flow_factor") {
1457  fKey = eFlow_factor;
1458  } else if (qName == "flow_set_ratio") {
1459  fKey = eFlow_set_ratio;
1460  } else if (qName == "flow_set_absolute") {
1461  fKey = eFlow_set_absolute;
1462  } else if (qName == "flow_timeout_reduction") {
1463  fKey = eFlow_timeout_reduction;
1464  } else if (qName == "timeout_flow_set") {
1465  fKey = eTimeout_flow_set;
1466  } else if (qName == "flowLowestFlowToConsider") {
1467  fKey = eFlowLowestFlowToConsider;
1468  } else if (qName == "flowMaxRelFlowDiffToConsider") {
1469  fKey = eFlowMaxRelFlowDiffToConsider;
1470  } else if (qName == "dFlowDp0") {
1471  fKey = eDFlowDp0;
1472  } else if (qName == "dFlowDp1") {
1473  fKey = eDFlowDp1;
1474  } else if (qName == "dFlowDpExp") {
1475  fKey = eDFlowDpExp;
1476  } else if (qName == "heatCapCof1") {
1477  fKey = eHeatCapCof1;
1478  } else if (qName == "heatCapCof2") {
1479  fKey = eHeatCapCof2;
1480  } else if (qName == "heatCapCof3") {
1481  fKey = eHeatCapCof3;
1482  } else if (qName == "needleValveInUse") {
1483  fKey = eNeedleValveInUse;
1484  } else if (qName == "prefNeedleValveCof_1_0") {
1485  fKey = ePrefNeedleValveCof_1_0;
1486  } else if (qName == "prefNeedleValveCof_1_1") {
1487  fKey = ePrefNeedleValveCof_1_1;
1488  } else if (qName == "prefNeedleValveCof_2_0") {
1489  fKey = ePrefNeedleValveCof_2_0;
1490  } else if (qName == "prefNeedleValveCof_2_1") {
1491  fKey = ePrefNeedleValveCof_2_1;
1492  } else if (qName == "prefNeedleValveCof_3_0") {
1493  fKey = ePrefNeedleValveCof_3_0;
1494  } else if (qName == "prefNeedleValveCof_3_1") {
1495  fKey = ePrefNeedleValveCof_3_1;
1496  } else if (qName == "prefNeedleValveCof_4_0") {
1497  fKey = ePrefNeedleValveCof_4_0;
1498  } else if (qName == "prefNeedleValveCof_4_1") {
1499  fKey = ePrefNeedleValveCof_4_1;
1500  } else if (qName == "prefNeedleValveRelStep") {
1501  fKey = ePrefNeedleValveRelStep;
1502  } else if (qName == "prefNeedleValveAbsStep") {
1503  fKey = ePrefNeedleValveAbsStep;
1504  }
1505 
1506  return true;
1507 }
1508 
1509 //**********************************************************************
1510 // endElement
1511 //**********************************************************************
1515 bool PLemSampleCryoXMLParser::endElement( const QString&, const QString&, const QString& )
1516 {
1517  fKey = eEmpty; // no key word anymore
1518 
1519  return true;
1520 }
1521 
1522 //**********************************************************************
1523 // characters
1524 //**********************************************************************
1530 bool PLemSampleCryoXMLParser::characters(const QString &str)
1531 {
1532  switch (fKey) {
1533  case eTemp_regulation:
1534  if (str == "true")
1535  fLar->fSampleTempRegulation = true;
1536  else
1537  fLar->fSampleTempRegulation = false;
1538  break;
1539  case eMax_temp_increase:
1540  fLar->fMaxTempIncrease = str.toFloat();
1541  break;
1542  case eBh_max_flow:
1543  fLar->fBHMaxFlow = str.toFloat();
1544  break;
1545  case eBh_min_flow:
1546  fLar->fBHMinFlow = str.toFloat();
1547  break;
1548  case eBh_flow_p_heat_0:
1549  fLar->fBHFlowPHeat0 = str.toFloat();
1550  break;
1551  case eBh_flow_p_heat_1:
1552  fLar->fBHFlowPHeat1 = str.toFloat();
1553  break;
1554  case eBh_flow_d_heat:
1555  fLar->fBHFlowDHeat = str.toFloat();
1556  break;
1557  case eBh_flow_temp:
1558  fLar->fBHFlowTemp = str.toFloat();
1559  break;
1560  case eBh_flow_temp_offset:
1561  fLar->fBHFlowTempOffset = str.toFloat();
1562  break;
1563  case eBh_flow_offset:
1564  fLar->fBHFlowOffset = str.toFloat();
1565  break;
1566  case eD_set_ratio:
1567  fLar->fDSetRatio = str.toFloat();
1568  break;
1569  case eAbs_max_temp_diff:
1570  fLar->fAbsMaxTempDiff = str.toFloat();
1571  break;
1572  case eRel_max_temp_diff:
1573  fLar->fRelMaxTempDiff = str.toFloat();
1574  break;
1575  case eMax_temp_trend:
1576  fLar->fMaxTempTrend = str.toFloat();
1577  break;
1578  case eHeater_min:
1579  fLar->fHeaterMin = str.toFloat();
1580  break;
1581  case eHeater_max:
1582  fLar->fHeaterMax = str.toFloat();
1583  break;
1584  case eTimeout_flow_set:
1585  fLar->fTimeoutFlowSet = 1000.0 * str.toFloat(); // in (msec)
1586  break;
1587  case eFlow_factor:
1588  fLar->fFlowFactor = str.toFloat();
1589  break;
1590  case eFlow_set_ratio:
1591  fLar->fFlowSetRatio = str.toFloat();
1592  break;
1593  case eFlow_set_absolute:
1594  fLar->fFlowSetAbsolute = str.toFloat();
1595  break;
1596  case eFlow_timeout_reduction:
1597  fLar->fFlowTimeoutReduction = 1000.0 * str.toFloat(); // in (msec)
1598  break;
1599  case eFlowLowestFlowToConsider:
1600  fLar->fFlowLowestFlowToConsider = str.toFloat();
1601  break;
1602  case eFlowMaxRelFlowDiffToConsider:
1603  fLar->fFlowMaxRelFlowDiffToConsider = str.toFloat();
1604  break;
1605  case eDFlowDp0:
1606  fLar->fDFlowDp0 = str.toFloat();
1607  break;
1608  case eDFlowDp1:
1609  fLar->fDFlowDp1 = str.toFloat();
1610  break;
1611  case eDFlowDpExp:
1612  fLar->fDFlowDpExp = str.toFloat();
1613  break;
1614  case eHeatCapCof1:
1615  fLar->fHeatCapCof1 = str.toFloat();
1616  break;
1617  case eHeatCapCof2:
1618  fLar->fHeatCapCof2 = str.toFloat();
1619  break;
1620  case eHeatCapCof3:
1621  fLar->fHeatCapCof3 = str.toFloat();
1622  break;
1623  case eNeedleValveInUse:
1624  fLar->fNeedleValveInUse = (bool) str.toInt();
1625  break;
1626  case ePrefNeedleValveCof_1_0:
1627  fLar->fPrefNeedleValveCof_1_0 = str.toFloat();
1628  break;
1629  case ePrefNeedleValveCof_1_1:
1630  fLar->fPrefNeedleValveCof_1_1 = str.toFloat();
1631  break;
1632  case ePrefNeedleValveCof_2_0:
1633  fLar->fPrefNeedleValveCof_2_0 = str.toFloat();
1634  break;
1635  case ePrefNeedleValveCof_2_1:
1636  fLar->fPrefNeedleValveCof_2_1 = str.toFloat();
1637  break;
1638  case ePrefNeedleValveCof_3_0:
1639  fLar->fPrefNeedleValveCof_3_0 = str.toFloat();
1640  break;
1641  case ePrefNeedleValveCof_3_1:
1642  fLar->fPrefNeedleValveCof_3_1 = str.toFloat();
1643  break;
1644  case ePrefNeedleValveCof_4_0:
1645  fLar->fPrefNeedleValveCof_4_0 = str.toFloat();
1646  break;
1647  case ePrefNeedleValveCof_4_1:
1648  fLar->fPrefNeedleValveCof_4_1 = str.toFloat();
1649  break;
1650  case ePrefNeedleValveRelStep:
1651  fLar->fPrefNeedleValveRelStep = str.toFloat();
1652  break;
1653  case ePrefNeedleValveAbsStep:
1654  fLar->fPrefNeedleValveAbsStep = str.toFloat();
1655  break;
1656 
1657  default:
1658  break;
1659  }
1660 
1661  return true;
1662 }
1663 
1664 //**********************************************************************
1665 // endDocument
1666 //**********************************************************************
1674 {
1675  QString errorMsg;
1676 
1677  // check if all expected input is found
1678 
1679  // no max temp increase given, hence set it to 20 (K)
1680  if (fLar->fMaxTempIncrease == 0.0)
1681  fLar->fMaxTempIncrease = 20.0;
1682 
1683  return true;
1684 }
1685 
1686 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1687 // implementation of PLemHvSettingsFileParser
1688 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1689 
1690 //**********************************************************************
1691 // constructor
1692 //**********************************************************************
1698 {
1699  fValid = true;
1700  fErrorMsg = "";
1701 
1702  fHvDeviceName = "";
1703 }
1704 
1705 //**********************************************************************
1706 // destructor
1707 //**********************************************************************
1712 {
1713  fHvChNo.clear();
1714  fHvChName.clear();
1715  fHvDemand.clear();
1716  fCurrentLimit.clear();
1717 }
1718 
1719 //**********************************************************************
1720 // startDocument
1721 //**********************************************************************
1726 {
1727  fKey = eEmpty;
1728 
1729  return true;
1730 }
1731 
1732 //**********************************************************************
1733 // startElement
1734 //**********************************************************************
1740 bool PLemHvSettingsFileParser::startElement(const QString&, const QString&,
1741  const QString& qName,
1742  const QXmlAttributes&)
1743 {
1744  if (qName == "hvDeviceName") {
1745  fKey = eHvDeviceName;
1746  } else if (qName == "chNo") {
1747  fKey = eHvChNo;
1748  } else if (qName == "name") {
1749  fKey = eHvChName;
1750  } else if (qName == "hvDemand") {
1751  fKey = eHvDemand;
1752  } else if (qName == "currentLimit") {
1753  fKey = eCurrentLimit;
1754  }
1755 
1756  return true;
1757 }
1758 
1759 //**********************************************************************
1760 // endElement
1761 //**********************************************************************
1765 bool PLemHvSettingsFileParser::endElement( const QString&, const QString&, const QString& )
1766 {
1767  fKey = eEmpty; // no key word anymore
1768 
1769  return true;
1770 }
1771 
1772 //**********************************************************************
1773 // characters
1774 //**********************************************************************
1781 {
1782  int ival=0;
1783  float fval=0.0;
1784  bool ok;
1785 
1786  switch (fKey) {
1787  case eHvDeviceName:
1788  fHvDeviceName = str.trimmed();
1789  if (fHvDeviceName != "FUG") {
1790  fErrorMsg = "**ERROR** only handle FUG's, i.e. transport settings, but found '" + fHvDeviceName + "'";
1791  fValid = false;
1792  return false;
1793  }
1794  break;
1795  case eHvChNo:
1796  ival = str.toInt(&ok);
1797  if (ok) {
1798  fHvChNo.push_back(ival);
1799  } else {
1800  fErrorMsg = "**ERROR** found HV channel '" + str + "' at position" + QString("%1").arg(fHvChNo.size()) + " which is not an integer?!?";
1801  fValid = false;
1802  return false;
1803  }
1804  break;
1805  case eHvChName:
1806  fHvChName.push_back(str);
1807  break;
1808  case eHvDemand:
1809  fval = str.toFloat(&ok);
1810  if (ok) {
1811  fHvDemand.push_back(fval);
1812  } else {
1813  fErrorMsg = "**ERROR** found HV demand '" + str + "' at position" + QString("%1").arg(fHvChNo.size()) + " which is not an double?!?";
1814  fValid = false;
1815  return false;
1816  }
1817  break;
1818  case eCurrentLimit:
1819  fval = str.toFloat(&ok);
1820  if (ok) {
1821  fCurrentLimit.push_back(fval);
1822  } else {
1823  fErrorMsg = "**ERROR** found current limit '" + str + "' at position" + QString("%1").arg(fHvChNo.size()) + " which is not an double?!?";
1824  fValid = false;
1825  return false;
1826  }
1827  break;
1828  default:
1829  break;
1830  }
1831 
1832  return true;
1833 }
1834 
1835 //**********************************************************************
1836 // endDocument
1837 //**********************************************************************
1845 {
1846  QString errorMsg;
1847 
1848  if (!fValid) {
1849  fHvChNo.clear();
1850  fHvChName.clear();
1851  fHvDemand.clear();
1852  fCurrentLimit.clear();
1853  }
1854 
1855  return true;
1856 }
1857 
1858 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1859 // implementation of PLemAutoRun
1860 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1861 
1862 //**********************************************************************
1863 // constructor
1864 //**********************************************************************
1871 PLemAutoRun::PLemAutoRun(QString &host, QString &exp) :
1872  fHostName(host),
1873  fExpName(exp)
1874 {
1875  fEnableAll = false;
1876  InitEnabled(); // initialize all the enable flags to 'false'
1877 
1878  fXMLSchemaFln = "";
1879  fXMLAutoRunFln = "";
1880  fXMLAutoRunHTML = "";
1881  fAutoRunPath = "";
1882 
1883  fAutoRunSequence = "";
1884  fShowComments = true;
1885  fGotoLine = -1;
1886  fNextAutoRunSequence = "";
1887  fAutoRunStatusMsg = "";
1888  fAutoRunState = 0;
1889 
1890  fHvTripFlag = 0;
1891  fFieldPwrSupply = "";
1892 
1893  fNoOfAutoRunCmds = 0;
1894  fCurrentAutoRunCmd = 0;
1895  fAutoRunCurrentIter = 0;
1896 
1898 
1899  // init system 'constants'
1900  for (int i=0; i<NO_ENERGY_LOSS_PARAM; i++)
1901  fEnergyLossParam[i] = 0.0;
1902  fMaxTempIncrease = 0.0;
1903  fFieldTimeout = 0.0;
1904  fFieldAccuracy = 0.0;
1905  fHVTimeout = 0.0;
1906  fHVAccuracy = 0.0;
1907  fBHMaxFlow = 25000.0;
1908  fBHMinFlow = 500.0;
1909  fBHFlowTemp = 1.0e5;
1910  fBHFlowTempOffset = 0.0;
1911  fBHFlowOffset = 300.0;
1912  fDSetRatio = 0.1;
1913  fAbsMaxTempDiff = 1.0e-2;
1914  fRelMaxTempDiff = 1.0e-4;
1915  fMaxTempTrend = 1.0e-3;
1916  fHeaterMax = 95.0;
1917  fHeaterMin = 5.0;
1918  fTimeoutFlowSet = 60.0e3; // in (msec)
1919  fFlowFactor = 0.05;
1920  fFlowSetRatio = 0.02;
1921  fFlowSetAbsolute = 1.0;
1922  fFlowTimeoutReduction = 30.0e3; // in (msec)
1923  fSampleHistoLastTime = 0.0;
1924  fFlowLowestFlowToConsider = 0.0; //<! lowest demand flow to consider
1925  fFlowMaxRelFlowDiffToConsider = 100.0; //<! maximum rel flow error to consider
1926  fDFlowDp0 = 0.0; //<! calculates d(flow)/dP from d(flow)/dP =
1927  fDFlowDp1 = 0.0; //<! fDFlowDp0 + fDFlowDp1 * exp( fDFlowDpExp * Temp )
1928  fDFlowDpExp = -1.0;
1929 
1930  // heat capacity related coefficients
1931  fHeatCapCof1 = 0.0; //<! heat Capacity of cryo =
1932  fHeatCapCof2 = 0.0; //<! fHeatCapCof1 * T + fHeatCapCof2 * T + fHeatCapCof3 * T
1933  fHeatCapCof3 = 0.0;
1934 
1935  // Coefficients for preferred needle valve settings
1936  fNeedleValveInUse = FALSE; //<! Tag for use of electric needle valve
1937  fPrefNeedleValveCof_1_0 = 0.0; //<! NV setting = _1_0 * _1_1 * T for T<8
1939  fPrefNeedleValveCof_2_0 = 0.0; //<! NV setting = _1_0 * _1_1 * T for 8<T<10
1941  // Test changes for T ranges
1942  fPrefNeedleValveCof_3_0 = 0.0; //<! NV setting = _1_0 * _1_1 * T for 10<T<20
1944  fPrefNeedleValveCof_4_0 = 0.0; //<! NV setting = _1_0 * _1_1 * T for 20<T
1946  fPrefNeedleValveRelStep = 0.0; //<! relative change in SampleTempConsiderNeedleValve
1947  fPrefNeedleValveAbsStep = 0.0; //<! absolute change in SampleTempConsiderNeedleValve
1948 
1949  // critical current for the WEW. For larger currents, the RA HV's should be switched off due to the Penning trap problem
1950  fWEWCriticalCurrentRA = 22.65; // ~130G
1951 
1952  // maximal currents for the magnet power supplied
1953  fWEWLMaxCurrent = 50.0;
1954  fWEWHMaxCurrent = 595.0;
1955  fDanfysikMaxCurrent = 20.0;
1956 
1957  // FOM related variables int
1958  fFOMCurrentAccuracy = 0.0;
1959 
1960  // init warmup related variables
1961  fWarmUpWished = false;
1962  fWarmUpVent = false;
1963 
1964  // init debug flag, which is used to print out additional information
1965  fDebug = false;
1966 
1967  // init ignore clients flag, if set true it will be ignored if frontends are running or not!! ONLY FOR TESTING!!
1968  fIgnoreClients = false;
1969  // init ignore alarms flag, if set true it will ignore alarm messages. ONLY FOR TESTING!!
1970  fIgnoreAlarms = false;
1971  // init FUG HV check flag, if set to true it will perform a check that demand==measured, otherwise not. This should be set the false ONLY FOR TESTING!!
1972  fFugHvCheck = true;
1973 
1974  // init temperature regulation flag
1975  fSampleTempRegulation = true;
1976  fSampleTempUnstable = false;
1977 
1978  // init temperature tolerance
1979  fSampleTempAccuracy = 0.1;
1980 
1981  // init run related variables
1982  fRunStopped = true;
1983  fRunCheckEvents = true;
1984  fRunNoEventsNeeded = 0;
1985  fRunTimeout = 0;
1986 
1987  // init hotlink variables
1988  for (int i=0; i<SAMPLE_CRYO_INPUT; i++)
1989  fSampleInput[i] = 0.0;
1990  for (int i=0; i<SAMPLE_CRYO_OUTPUT; i++)
1991  fSampleOutput[i] = 0.0;
1992 
1993  // init temperature history related variables
1995  fSampleHistoPos = 0;
1996 
1997  // init raw voltage dumps to be made
1998  fDumpInUse = false;
1999  fDumpCounter = 0;
2000  fDumpFileName = "";
2001 
2002  // init setup related variables
2003  fSetupSampleEnabled = false;
2004  fSetupWewEnabled = false;
2005  fSetupBparEnabled = false;
2006 
2007  // default HV settings path, in case it is not found int the lemAutoRun.xml
2008  fHvSettingsPath = QString("/home/nemu/nemu/midas/experiment/nemu/hv_settings/");
2009 
2010  // init odb related variables
2011  fTriggerEventsPath = "";
2012  fEnableOnOffModePath = "";
2013  fAlarmsPath = "";
2014  fAlarmTdHvTripPath = "";
2015  fRunInfoPath = "";
2016  fRunCommentPath = "";
2017  fTofMinPath = "";
2018  fTofMaxPath = "";
2019  fModNamePath = "";
2020  fModDatePath = "";
2021  fLemSetupPath = "";
2022  fSampleCryoPath = "";
2023  fSpinRotEnabledPath = "";
2024  fSpinRotAnglePath = "";
2025  fEnergyLossParamPath = "";
2026  fClientsPath = "";
2027  fHVDemandPath = "";
2028  fHVMeasuredPath = "";
2029  fHVCurrentPath = "";
2030  fHVDetectorDemandPath = "";
2032  fSpinRotMagInputPath = "";
2033  fSpinRotMagOutputPath = "";
2034  fDanfysikInputPath = "";
2035  fDanfysikOutputPath = "";
2036  fWEWOutputPath = "";
2037  fWEWInputPath = "";
2038  fMagFieldPath = "";
2039  fTflInputPath = "";
2040  fTflOutputPath = "";
2041  fSampleCtrlChPath = "";
2042  fSampleChannelPath = "";
2043  fSampleSensorTypePath = "";
2044  fSampleInputPath = "";
2045  fSampleOutputPath = "";
2046  fSampleDatetimePath = "";
2047  fSampleRawVoltagePath = "";
2051  fLemvacInputPath = "";
2052  fLemvacOutputPath = "";
2053  fFOMInputPath = "";
2054  fFOMOutputPath = "";
2055  fBeamlineDemandPath = "";
2056  fMagParamWewPath = "";
2057  fMagParamBparPath = "";
2059  fSetupWewEnabledPath = "";
2060  fSetupBparEnabledPath = "";
2061 
2064 
2065  // initialize running client flags
2066  fAnalyzerName = "";
2067  fFrontendName = "";
2068  fSampleFeName = "";
2069  fWEWFeName = "";
2070  fDanfysikFeName = "";
2071  fHVFeName = "";
2072  fLemvacFeName = "";
2073  fAnalyzerRunning = false;
2074  fFrontendRunning = false;
2075  fSampleFeRunning = false;
2076  fSampleOvenOmegaFeRunning = false;
2077  fWEWFeRunning = false;
2078  fDanfysikFeRunning = false;
2079  fHVFeRunning = false;
2080  fLemvacFeRunning = false;
2081 
2082  // initialize pointers
2083  fExp = 0;
2084  fTriggerEventsKey = 0;
2085  fAlarmsKey = 0;
2086  fAlarmTdHvTripKey = 0;
2087  fRunInfoKey = 0;
2088  fRunCommentKey = 0;
2089  fTofMinKey = 0;
2090  fTofMaxKey = 0;
2091  fModNameKey = 0;
2092  fModDateKey = 0;
2093  fLemSetupKey = 0;
2094  fSampleCryoKey = 0;
2095  fSpinRotEnabledKey = 0;
2096  fSpinRotAngleKey = 0;
2097  fEnergyLossParamKey = 0;
2098  fClientsKey = 0;
2099  fHVDemandKey = 0;
2100  fHVMeasuredKey = 0;
2101  fHVCurrentKey = 0;
2104  fSpinRotMagInputKey = 0;
2106  fDanfysikInputKey = 0;
2107  fDanfysikOutputKey = 0;
2108  fWEWOutputKey = 0;
2109  fWEWInputKey = 0;
2110  fMagFieldKey = 0;
2111  fTflInputKey = 0;
2112  fTflOutputKey = 0;
2113  fSampleCtrlChKey = 0;
2114  fSampleChannelKey = 0;
2116  fSampleInputKey = 0;
2117  fSampleOutputKey = 0;
2118  fSampleDatetimeKey = 0;
2122  fLemvacInputKey = 0;
2123  fLemvacOutputKey = 0;
2124  fFOMInputKey = 0;
2125  fFOMOutputKey = 0;
2126  fBeamlineDemandKey = 0;
2127  fMagParamWewKey = 0;
2128  fMagParamBparKey = 0;
2130  fSetupWewEnabledKey = 0;
2132  for (int i=0; i<10; i++)
2133  fSampleRawVoltageKey[i] = 0;
2134 
2135  fRAPulsingEnabled = false;
2136 
2137  // connect internal signal and slot
2138  QObject::connect(this, SIGNAL(StatusMsg(QString)), this, SLOT(UpdateStatusMsg(QString)));
2139 }
2140 
2141 //**********************************************************************
2142 // destructor
2143 //**********************************************************************
2148 {
2149  if (fExp) {
2150  delete fExp;
2151  fExp = 0;
2152  }
2153  if (fTriggerEventsKey) {
2154  delete fTriggerEventsKey;
2155  fTriggerEventsKey = 0;
2156  }
2157  if (fAlarmsKey) {
2158  delete fAlarmsKey;
2159  fAlarmsKey = 0;
2160  }
2161  if (fAlarmTdHvTripKey) {
2162  delete fAlarmTdHvTripKey;
2163  fAlarmTdHvTripKey = 0;
2164  }
2165  if (fRunInfoKey) {
2166  delete fRunInfoKey;
2167  fRunInfoKey = 0;
2168  }
2169  if (fRunCommentKey) {
2170  delete fRunCommentKey;
2171  fRunCommentKey = 0;
2172  }
2173  if (fTofMinKey) {
2174  delete fTofMinKey;
2175  fTofMinKey = 0;
2176  }
2177  if (fTofMaxKey) {
2178  delete fTofMaxKey;
2179  fTofMaxKey = 0;
2180  }
2181  if (fModNameKey) {
2182  delete fModNameKey;
2183  fModNameKey = 0;
2184  }
2185  if (fModDateKey) {
2186  delete fModDateKey;
2187  fModDateKey = 0;
2188  }
2189  if (fLemSetupKey) {
2190  delete fLemSetupKey;
2191  fLemSetupKey = 0;
2192  }
2193  if (fSampleCryoKey) {
2194  delete fSampleCryoKey;
2195  fSampleCryoKey = 0;
2196  }
2197  if (fSpinRotEnabledKey) {
2198  delete fSpinRotEnabledKey;
2199  fSpinRotEnabledKey = 0;
2200  }
2201  if (fSpinRotAngleKey) {
2202  delete fSpinRotAngleKey;
2203  fSpinRotAngleKey = 0;
2204  }
2205  if (fEnergyLossParamKey) {
2206  delete fEnergyLossParamKey;
2207  fEnergyLossParamKey = 0;
2208  }
2209  if (fClientsKey) {
2210  delete fClientsKey;
2211  fClientsKey = 0;
2212  }
2213  if (fHVDemandKey) {
2214  delete fHVDemandKey;
2215  fHVDemandKey = 0;
2216  }
2217  if (fHVMeasuredKey) {
2218  delete fHVMeasuredKey;
2219  fHVMeasuredKey = 0;
2220  }
2221  if (fHVCurrentKey) {
2222  delete fHVCurrentKey;
2223  fHVCurrentKey = 0;
2224  }
2225  if (fHVDetectorDemandKey) {
2226  delete fHVDetectorDemandKey;
2228  }
2229  if (fHVDetectorMeasuredKey) {
2230  delete fHVDetectorMeasuredKey;
2232  }
2233 
2234  if (fSpinRotMagInputKey) {
2235  delete fSpinRotMagInputKey;
2236  fSpinRotMagInputKey = 0;
2237  }
2238  if (fSpinRotMagOutputKey) {
2239  delete fSpinRotMagOutputKey;
2241  }
2242  if (fDanfysikInputKey) {
2243  delete fDanfysikInputKey;
2244  fDanfysikInputKey = 0;
2245  }
2246  if (fDanfysikOutputKey) {
2247  delete fDanfysikOutputKey;
2248  fDanfysikOutputKey = 0;
2249  }
2250  if (fWEWOutputKey) {
2251  delete fWEWOutputKey;
2252  fWEWOutputKey = 0;
2253  }
2254  if (fWEWInputKey) {
2255  delete fWEWInputKey;
2256  fWEWInputKey = 0;
2257  }
2258  if (fMagFieldKey) {
2259  delete fMagFieldKey;
2260  fMagFieldKey = 0;
2261  }
2262  if (fTflInputKey) {
2263  delete fTflInputKey;
2264  fTflInputKey = 0;
2265  }
2266  if (fTflOutputKey) {
2267  delete fTflOutputKey;
2268  fTflOutputKey = 0;
2269  }
2270  if (fSampleCtrlChKey) {
2271  delete fSampleCtrlChKey;
2272  fSampleCtrlChKey = 0;
2273  }
2274  if (fSampleChannelKey) {
2275  delete fSampleChannelKey;
2276  fSampleChannelKey = 0;
2277  }
2278  if (fSampleSensorTypeKey) {
2279  delete fSampleSensorTypeKey;
2281  }
2282  if (fSampleInputKey) {
2283  delete fSampleInputKey;
2284  fSampleInputKey = 0;
2285  }
2286  if (fSampleOutputKey) {
2287  delete fSampleOutputKey;
2288  fSampleOutputKey = 0;
2289  }
2290  if (fSampleDatetimeKey) {
2291  delete fSampleDatetimeKey;
2292  fSampleDatetimeKey = 0;
2293  }
2294  for (int i=0; i<10; i++) {
2295  if (fSampleRawVoltageKey[i]) {
2296  delete fSampleRawVoltageKey[i];
2297  fSampleRawVoltageKey[i] = 0;
2298  }
2299  }
2300  if (fSampleNoConnectionKey) {
2301  delete fSampleNoConnectionKey;
2303  }
2305  delete fSampleOvenOmegaInputKey;
2307  }
2311  }
2312  if (fLemvacInputKey) {
2313  delete fLemvacInputKey;
2314  fLemvacInputKey = 0;
2315  }
2316  if (fLemvacOutputKey) {
2317  delete fLemvacOutputKey;
2318  fLemvacOutputKey = 0;
2319  }
2320  if (fFOMInputKey) {
2321  delete fFOMInputKey;
2322  fFOMInputKey = 0;
2323  }
2324  if (fFOMOutputKey) {
2325  delete fFOMOutputKey;
2326  fFOMOutputKey = 0;
2327  }
2328  if (fBeamlineDemandKey) {
2329  delete fBeamlineDemandKey;
2330  fBeamlineDemandKey = 0;
2331  }
2332  if (fMagParamWewKey) {
2333  delete fMagParamWewKey;
2334  fMagParamWewKey = 0;
2335  }
2336  if (fMagParamBparKey) {
2337  delete fMagParamBparKey;
2338  fMagParamBparKey = 0;
2339  }
2340  if (fSetupSampleEnabledKey) {
2341  delete fSetupSampleEnabledKey;
2343  }
2344  if (fSetupWewEnabledKey) {
2345  delete fSetupWewEnabledKey;
2346  fSetupWewEnabledKey = 0;
2347  }
2348  if (fSetupBparEnabledKey) {
2349  delete fSetupBparEnabledKey;
2351  }
2352 }
2353 
2354 //**********************************************************************
2355 // ReadStartupXML
2356 //**********************************************************************
2361 {
2362  QString fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun.xml";
2363  if (!QFile::exists(fln)) {
2364  QString err = "lemAutoRun: Couldn't find XML startup file " + fln;
2365  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, err);
2366  return;
2367  }
2368 
2369  PLemAutoRunXMLParser handler(this);
2370  QFile xmlFile(fln);
2371  QXmlInputSource source( &xmlFile );
2372  QXmlSimpleReader reader;
2373  reader.setContentHandler( &handler );
2374  reader.parse( source );
2375 }
2376 
2377 //**********************************************************************
2378 // ReadSampleCryoXML
2379 //**********************************************************************
2384 {
2385  char str[NAME_LENGTH];
2386  int size;
2387  QString sampleCryoName = "";
2388  QString fln = "";
2389 
2390  if (!fEnabled["sample_eq"] || !fEnabled["sample_cryo_info_odb"]) {
2391  cm_msg(MERROR, "lemAutoRun", "Either SampleCryo Equipment is not enabled, or /Info/Sample Cryo in ODB is missing! LEM AutoRun will not work.");
2392  return;
2393  }
2394 
2395  // get the sample cryo name
2396  size = sizeof(str);
2397  fSampleCryoKey->GetData((void *)&str, &size, TID_STRING);
2398  sampleCryoName = QString(str);
2399 
2400  if (sampleCryoName == "Konti-1") {
2401  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_KontiCryo1.xml";
2403  } else if (sampleCryoName == "Konti-2") {
2404  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_KontiCryo2.xml";
2406  } else if (sampleCryoName == "Konti-3") {
2407  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_KontiCryo3.xml";
2409  } else if (sampleCryoName == "Konti-4") {
2410  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_KontiCryo4.xml";
2412  } else if (sampleCryoName == "LowTemp-1") { // former Mango
2413  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_LowTemp1.xml";
2415  } else if (sampleCryoName == "LowTemp-2") { // former Lemon
2416  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_LowTemp2.xml";
2418  } else if (sampleCryoName == "Omega") {
2419  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_Oven.xml";
2421  } else if (sampleCryoName == "NoCryo") {
2423  return;
2424  }
2425 
2426  if (!QFile::exists(fln)) {
2427  QString err = "lemAutoRun: Couldn't find XML startup file " + fln + " ";
2428  err += "Perhaps the sample cryo name (" + sampleCryoName + ") is wrong?!";
2429  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, err);
2430  return;
2431  }
2432 
2433  PLemSampleCryoXMLParser handler(this);
2434  QFile xmlFile(fln);
2435  QXmlInputSource source( &xmlFile );
2436  QXmlSimpleReader reader;
2437  reader.setContentHandler( &handler );
2438  reader.parse( source );
2439 
2440 }
2441 
2442 //**********************************************************************
2443 // InitEnabled
2444 //**********************************************************************
2449 {
2450  // feed ODB stuff
2451  fEnabled.insert("trigger_events_odb", false);
2452  fEnabled.insert("enable_on_off_mode_odb", false);
2453  fEnabled.insert("alarms_odb", false);
2454  fEnabled.insert("alarms_td_hv_trip_odb", false);
2455  fEnabled.insert("run_comment_odb", false);
2456  fEnabled.insert("tof_min_odb", false);
2457  fEnabled.insert("tof_max_odb", false);
2458  fEnabled.insert("mod_name_odb", false);
2459  fEnabled.insert("mod_date_odb", false);
2460  fEnabled.insert("lem_setup_odb", false);
2461  fEnabled.insert("energy_loss_param_odb", false);
2462  fEnabled.insert("sample_cryo_info_odb", false);
2463  fEnabled.insert("sample_name_info_odb", false);
2464  fEnabled.insert("spin_rot_calib_odb", false);
2465  fEnabled.insert("spin_rot_angle_odb", false);
2466  fEnabled.insert("mag_param_wew_odb", false);
2467  fEnabled.insert("mag_param_bpar_odb", false);
2468  fEnabled.insert("setup_sample_odb", false);
2469  fEnabled.insert("setup_wew_odb", false);
2470  fEnabled.insert("setup_bpar_odb", false);
2471 
2472  // feed all clients
2473  fEnabled.insert("analyzer_fe", false);
2474  fEnabled.insert("vme_fe", false);
2475  fEnabled.insert("tfl_scfe", false);
2476  fEnabled.insert("sample_scfe", false);
2477  fEnabled.insert("omega_scfe", false);
2478  fEnabled.insert("wew_scfe", false);
2479  fEnabled.insert("danfysik_scfe", false);
2480  fEnabled.insert("fug_scfe", false);
2481  fEnabled.insert("lemvac_scfe", false);
2482 
2483  // feed all equipment
2484  fEnabled.insert("fug_eq", false);
2485  fEnabled.insert("hv_detectors_eq", false);
2486  fEnabled.insert("danfysik_spin_rot_eq", false);
2487  fEnabled.insert("danfysik_eq", false);
2488  fEnabled.insert("wew_eq", false);
2489  fEnabled.insert("magnet_field_info", false);
2490  fEnabled.insert("tfl_eq", false);
2491  fEnabled.insert("sample_eq", false);
2492  fEnabled.insert("omega_eq", false);
2493  fEnabled.insert("lemvac_eq", false);
2494  fEnabled.insert("fom_eq", false);
2495  fEnabled.insert("beamline_eq", false);
2496 }
2497 
2498 //**********************************************************************
2499 // SetEnabled
2500 //**********************************************************************
2506 void PLemAutoRun::SetEnabled(const QString key, bool val)
2507 {
2508  if (!key.compare("all", Qt::CaseInsensitive)) { // change all
2509  QMapIterator<QString, bool> i(fEnabled);
2510  while (i.hasNext()) {
2511  i.next();
2512  fEnabled[i.key()] = val;
2513  }
2514  } else {
2515  if (fEnabled.contains(key)) {
2516  fEnabled[key] = val;
2517  }
2518  }
2519 }
2520 
2521 //**********************************************************************
2522 // ConnectExp
2523 //**********************************************************************
2529 {
2530  // create object
2531  fExp = new PExperiment("lemAutoRun1");
2532  if (!fExp) {
2533  QString err = "lemAutoRun: Couldn't allocate memory for midas experiment handler.";
2534  emit ErrorMsg(1, 0, LAR_OUT_OF_MEMORY, -1, err);
2535  return;
2536  }
2537 
2538  // connect to MIDAS
2539  fExp->Connect(fHostName, fExpName, "lemAutoRun1");
2540  if (!fExp->IsConnected()) {
2541  QString err = QString("lemAutoRun: Couldn't connect to %1, %2").arg(fHostName).arg(fExpName);
2542  emit ErrorMsg(1, 0, LAR_MIDAS_CONNECTION_FAILED, -1, err);
2543  return;
2544  }
2545 
2546  // start watchdog timer
2547  fExp->StartTimer();
2548 
2549  // make sure that we start from a clean state
2550  CleanLiveData();
2551 
2552  // get all the ODB keys needed to work
2553  if (!GetAllKeys()) {
2554  QString err = QString("lemAutoRun: Couldn't collect the necessary ODB keys");
2555  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
2556  return;
2557  }
2558 
2559  // check if setup flags do make sense
2560  if (!fSetupSampleEnabled) {
2561  QString err = QString("lemAutoRun: **WARNING** MCP2 setup detected.");
2562  emit ErrorMsg(1, 0, LAR_MSG, -1, err);
2563  }
2564  if (fEnabled["wew_eq"] && fEnabled["danfysik_eq"]) {
2566  QString err = QString("lemAutoRun: Setup flags doesn't make any sense: WEW enabled=%1, Bpar enabled=%2").arg(fSetupWewEnabled).arg(fSetupBparEnabled);
2567  emit ErrorMsg(1, 0, LAR_FATAL, -1, err);
2568  return;
2569  }
2570  }
2571 
2572  // get information which magnet power supply is in use
2573  if (fSetupWewEnabled)
2574  fFieldPwrSupply = QString("wew");
2575  else
2576  fFieldPwrSupply = QString("danfysik");
2577 
2578  if (fEnabled["enable_on_off_mode_odb"]) {
2579  // get the Enable_OnOff_Mode flag which shows if RA are operated in pulsed mode
2580  PKey *onOffMode = new PKey(fExp, fEnableOnOffModePath);
2581  if (!onOffMode->IsValid()) {
2582  QString err = QString("lemAutoRun: Enable_OnOff_Mode key not found.");
2583  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
2584  } else {
2585  int ival, size=sizeof(int);
2586  onOffMode->GetData(&ival, &size, TID_BOOL);
2587  if (ival == 1)
2588  fRAPulsingEnabled = true;
2589  else
2590  fRAPulsingEnabled = false;
2591  }
2592  // clean up
2593  delete onOffMode;
2594  }
2595 
2596  QObject::connect(fExp, SIGNAL(NetworkConnectionLost()), this, SLOT(NetworkConnectionLost()));
2597  QObject::connect(fExp, SIGNAL(ReceivedShutdownCmd()), this, SLOT(ReceivedShutdownCmd()));
2598 
2599 }
2600 
2601 //**********************************************************************
2602 // NetworkConnectionLost (SLOT)
2603 //**********************************************************************
2609 {
2610  QString err = QString("lemAutoRun: Lost Network Connection");
2611  emit ErrorMsg(1, 0, LAR_LOST_NETWORK_CONNECTION, -1, err);
2612 }
2613 
2614 //**********************************************************************
2615 // ReceivedShutdownCmd (SLOT)
2616 //**********************************************************************
2622 {
2623  QString err;
2624 
2625  // set autoRun state to stopped
2626  int runState = LAR_STATE_STOPPED;
2627  PKey runStateKey(fExp, "/AutoRun/Run State");
2628  if (runStateKey.IsValid()) {
2629  runStateKey.SetData((void*)&runState, 1, TID_INT);
2630  }
2631 
2632  if (fAutoRunCurrentIter)
2634 
2635  err = QString("Autorun aborted.");
2636  emit StatusMsg(err);
2637 
2638  err = QString("lemAutoRun: Received Shutdown Command");
2639  emit ErrorMsg(1, 0, LAR_RECIEVED_SHUTDOWN_CMD, -1, err);
2640 
2642 }
2643 
2644 //**********************************************************************
2645 // UpdateStatusMsg (SLOT)
2646 //**********************************************************************
2650 void PLemAutoRun::UpdateStatusMsg(const QString statusMsg)
2651 {
2652  QDateTime dt = QDateTime::currentDateTime();
2653  QString msg;
2654 
2655  msg = "["+dt.toString("dd.MM.yy, hh:mm:ss")+"] " + statusMsg;
2656 
2657  PKey statusMsgKey(fExp, "/AutoRun/Status");
2658  if (statusMsgKey.IsValid()) {
2659  char cmsg[128];
2660  memset(cmsg, 0, sizeof(cmsg));
2661  strncpy(cmsg, msg.toLatin1().data(), sizeof(cmsg)-1);
2662  statusMsgKey.SetData(cmsg, 1, TID_STRING);
2663  }
2664 }
2665 
2666 //**********************************************************************
2667 // GetRunState
2668 //**********************************************************************
2674 {
2675  int state = -1;
2676  PKey key(fExp, "/AutoRun/Run State");
2677  if (key.IsValid()) {
2678  int ival;
2679  int size = sizeof(ival);
2680  int status = key.GetData(&ival, &size, TID_INT);
2681  if (status == DB_SUCCESS) {
2682  state = ival;
2683  }
2684  }
2685 
2686  return state;
2687 }
2688 
2689 //**********************************************************************
2690 // UpdateRunState
2691 //**********************************************************************
2696 void PLemAutoRun::UpdateRunState(const int state)
2697 {
2698  PKey key(fExp, "/AutoRun/Run State");
2699  if (key.IsValid()) {
2700  key.SetData((void*)&state, 1, TID_INT);
2701  }
2702 }
2703 
2704 //**********************************************************************
2705 // GetAutoRunSequence
2706 //**********************************************************************
2712 {
2713  QString fln("");
2714 
2715  PKey larSeqKey(fExp, "/AutoRun/Auto Run Sequence");
2716  if (larSeqKey.IsValid()) {
2717  char autoRunSequence[64];
2718  int size = sizeof(autoRunSequence);
2719  int status = larSeqKey.GetData(autoRunSequence, &size, TID_STRING);
2720  if (status == DB_SUCCESS)
2721  fln = autoRunSequence;
2722  }
2723 
2724  return fln;
2725 }
2726 
2727 //**********************************************************************
2728 // ShowComments
2729 //**********************************************************************
2735 {
2736  bool showComments = true;
2737 
2738  PKey key(fExp, "/AutoRun/Show Comments");
2739  if (key.IsValid()) {
2740  int ival;
2741  int size = sizeof(ival);
2742  int status = key.GetData(&ival, &size, TID_BOOL);
2743  if (status == DB_SUCCESS) {
2744  if (ival != 1)
2745  showComments = false;
2746  }
2747  }
2748 
2749  return showComments;
2750 }
2751 
2752 //**********************************************************************
2753 // SetGotoLine
2754 //**********************************************************************
2759 void PLemAutoRun::SetGotoLine(const int line)
2760 {
2761  PKey key(fExp, "/AutoRun/GotoLine");
2762  if (key.IsValid()) {
2763  key.SetData((void*)&line, 1, TID_INT);
2764  }
2765 }
2766 
2767 //**********************************************************************
2768 // GetGotoLine
2769 //**********************************************************************
2775 {
2776  int line = -1;
2777  PKey key(fExp, "/AutoRun/GotoLine");
2778  if (key.IsValid()) {
2779  int ival;
2780  int size = sizeof(ival);
2781  int status = key.GetData(&ival, &size, TID_INT);
2782  if (status == DB_SUCCESS) {
2783  line = ival;
2784  }
2785  }
2786 
2787  return line;
2788 }
2789 
2790 //**********************************************************************
2791 // CleanLiveData
2792 //**********************************************************************
2794 {
2795  // make sure that not already an autorun is ongoing
2796  PKey larRunStateKey(fExp, "/AutoRun/Run State");
2797  if (larRunStateKey.IsValid()) {
2798  int state = -1;
2799  int size = sizeof(int);
2800  larRunStateKey.GetData(&state, &size, TID_INT);
2801  if ((state == LAR_STATE_STARTING) || (state == LAR_STATE_RUNNING))
2802  return;
2803  }
2804 
2805  // clean
2806  PKey liveDataKey(fExp, "/AutoRun/LiveData");
2807 
2808  if (liveDataKey.IsValid()) {
2809  // clean ErrorInLine
2810  PKey *errorInLineKey = new PKey(&liveDataKey, "ErrorInLine");
2811  if (errorInLineKey == 0) {
2812  cm_msg(MDEBUG, "lemAutoRun", "**ERROR** couldn't invoke errorInLineKey");
2813  return;
2814  }
2815  if (errorInLineKey->IsValid()) {
2816  int ival[10];
2817  for (int i=0; i<10; i++) {
2818  ival[i] = -1;
2819  }
2820  errorInLineKey->SetData((void *)&ival[0], 10, TID_INT);
2821  }
2822  delete errorInLineKey;
2823 
2824  // clean ErrorMsg
2825  PKey *errorMsgKey = new PKey(&liveDataKey, "ErrorMsg");
2826  if (errorMsgKey == 0) {
2827  cm_msg(MDEBUG, "lemAutoRun", "**ERROR** couldn't invoke errorMsgKey");
2828  return;
2829  }
2830  if (errorMsgKey->IsValid()) {
2831  char msg[10][128];
2832  for (int i=0; i<10; i++) {
2833  memset(msg[i], 0, 128);
2834  strcpy(msg[i], "empty");
2835  }
2836  errorMsgKey->SetData((void*)msg, 10, TID_STRING);
2837  }
2838  delete errorMsgKey;
2839  } else { // key not valid, i.e. likely doesn't exist yet -> try to create it
2840  cm_msg(MINFO, "lemAutoRun", "try to create default /AutoRun/LiveData record.");
2841  cm_yield(0);
2842  // AutoRun LiveData initial record
2843  const char *lar_live_data_settings =
2844 "ErrorInLine = INT[10] : \n\
2845 [0] -1,\n\
2846 [1] -1,\n\
2847 [2] -1,\n\
2848 [3] -1,\n\
2849 [4] -1,\n\
2850 [5] -1,\n\
2851 [6] -1,\n\
2852 [7] -1,\n\
2853 [8] -1,\n\
2854 [9] -1,\n\
2855 ErrorMsg = STRING[10] : \n\
2856 [128] empty\n\
2857 [128] empty\n\
2858 [128] empty\n\
2859 [128] empty\n\
2860 [128] empty\n\
2861 [128] empty\n\
2862 [128] empty\n\
2863 [128] empty\n\
2864 [128] empty\n\
2865 [128] empty\n\
2866 CurrentLineNo = INT : -1\n\
2867 LoopVal = STRING : [32] empty\n\
2868 TransitionTag = INT : 0\n\
2869 AutoRun = STRING : [32] empty\n\
2870 ";
2871  if (db_create_record(fExp->GetHdb(), 0, "/AutoRun/LiveData", lar_live_data_settings) != DB_SUCCESS) { // error
2872  cm_msg(MERROR, "lemAutoRun", "**ERROR** couldn't create /AutoRun/LiveData default record.");
2873  cm_yield(0);
2874  return;
2875  }
2876  }
2877 }
2878 
2879 //**********************************************************************
2880 // FeedLiveDataErrors
2881 //**********************************************************************
2882 void PLemAutoRun::FeedLiveDataErrors(int noOfErrors, int idx, int /*errorNo*/, int line, QString errorMsg)
2883 {
2884  cm_msg(MDEBUG, "lemAutoRun", "debug> noOfErrors=%d, idx=%d, line=%d, errMsg=%s", noOfErrors, idx, line, errorMsg.toLatin1().data()); cm_yield(0);
2885 
2886  PKey errorInLineKey(fExp, "/AutoRun/LiveData/ErrorInLine");
2887  PKey errorMsgKey(fExp, "/AutoRun/LiveData/ErrorMsg");
2888  PKey transTagKey(fExp, "/AutoRun/LiveData/TransitionTag");
2889 
2890  int ival = LAR_TT_IDLE;
2891  transTagKey.SetData((void*)&ival, 1, TID_INT);
2892 
2893  int i=0;
2894  if (noOfErrors != 0) {
2895  i = idx;
2896  }
2897 
2898  ival=0;
2899  if (line != -1)
2900  ival = line;
2901  if (errorInLineKey.IsValid()) {
2902  errorInLineKey.SetDataIndex((void *)&ival, i, TID_INT);
2903  }
2904  if (errorMsgKey.IsValid()) {
2905  char msg[128];
2906  memset(msg, 0, sizeof(msg));
2907  strncpy(msg, errorMsg.toLatin1().data(), sizeof(msg));
2908  errorMsgKey.SetDataIndex(msg, i, TID_STRING);
2909  }
2910 }
2911 
2912 //**********************************************************************
2913 // DisconnectFromExp
2914 //**********************************************************************
2919 {
2920  QString runStatePath = "/AutoRun/Run State";
2921  PKey key(fExp, runStatePath);
2922  if (key.IsValid()) {
2923  INT ival;
2924  int size = sizeof(ival);
2925  // check if run state is LAR_STATE_NEXT
2926  key.GetData((void*)&ival, &size, TID_INT);
2927 
2928  if (ival != LAR_STATE_NEXT) {
2929  ival = LAR_STATE_STOPPED;
2930  key.SetData((void*)&ival, 1, TID_INT);
2931  }
2932  }
2933 
2934  if (fExp)
2935  fExp->Disconnect();
2936 }
2937 
2938 //**********************************************************************
2939 // HandleParseError (SLOT)
2940 //**********************************************************************
2944 void PLemAutoRun::HandleParseError(int noOfErrors, int idx, int errorNo, int line, QString errorMsg)
2945 {
2946  // set autorun state to stopped
2948 
2949  // set autorun status message
2950  char msg[128];
2951  if (line > 0)
2952  sprintf(msg, "**ERROR** in line no %d (errorNo: %d)", line, errorNo);
2953  else
2954  sprintf(msg, "**ERROR** errorNo: %d", errorNo);
2955 
2956  FeedLiveDataErrors(noOfErrors, idx, errorNo, line, errorMsg);
2957 
2958  UpdateStatusMsg(msg);
2959  UpdateWebPage(0, HTML_PARSE_ERROR, line, errorMsg);
2960 }
2961 
2962 //**********************************************************************
2963 // DisconnectAndQuit (SLOT)
2964 //**********************************************************************
2969 {
2971 
2972  QCoreApplication::exit(0);
2973  exit(0);
2974 }
2975 
2976 //**********************************************************************
2977 // IsIdle
2978 //**********************************************************************
2983 {
2984  bool isIdle = true;
2985 
2986  // check if more than one lemAutoRun is present and if yes, idle=false
2987  int count=0;
2988  HNDLE hKey;
2989  int size, status;
2990  char str[NAME_LENGTH];
2991  for (int i=0; ; i++) {
2992  // check if there is a subkey
2993  if (fClientsKey->EnumSubKey(i, &hKey) == DB_NO_MORE_SUBKEYS)
2994  break;
2995  // get the content of the variable Name from the subkey
2996  size = sizeof(str);
2997  status = db_get_value(fClientsKey->GetHdb(), hKey, "Name", str, &size, TID_STRING, FALSE);
2998  if (status != DB_SUCCESS) {
2999  QString err = QString("Autorun: check clients failure ...");
3000  emit StatusMsg(err);
3001  err = QString("PLemAutoRun::CheckClients(): Couldn't get value from subkey.");
3002  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3003  }
3004  // check if the name is one of the monitored frontends
3005  if (!strncmp(str, "lemAutoRun", sizeof(str)))
3006  count++;
3007  }
3008 
3009  if (count > 1)
3010  isIdle = false;
3011 
3012  return isIdle;
3013 }
3014 
3015 //**********************************************************************
3016 // GetUserAutoRunSeqFln
3017 //**********************************************************************
3023 {
3024  QString result = fAutoRunPath;
3025 
3026  result += GetAutoRunSequence();
3027 
3028  return result;
3029 }
3030 
3031 //**********************************************************************
3032 // GetAllKeys
3033 //**********************************************************************
3038 {
3039  int size, status;
3040  QString err;
3041 
3042  // get key to the trigger events
3043  if (fEnabled["trigger_events_odb"]) {
3045  if (!fTriggerEventsKey->IsValid()) {
3046  err = QString("lemAutoRun: Trigger Events key not found.");
3047  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3048  return false;
3049  }
3050  }
3051 
3052  // get key to the alarms
3053  if (fEnabled["alarms_odb"]) {
3054  fAlarmsKey = new PKey(fExp, fAlarmsPath);
3055  if (!fAlarmsKey->IsValid()) {
3056  err = QString("lemAutoRun: Alarms key not found.");
3057  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3058  return false;
3059  }
3060  }
3061 
3062  // get key to the Alarm: TD HV trip trigger
3063  if (fEnabled["alarms_td_hv_trip_odb"]) {
3065  if (!fAlarmTdHvTripKey->IsValid()) {
3066  err = QString("lemAutoRun: Alarm TD HV trip trigger key not found.");
3067  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3068  return false;
3069  }
3070  // hotlink TD HV trip trigger flag
3071  size = sizeof(fHvTripFlag);
3072  status = fAlarmTdHvTripKey->HotLink(&fHvTripFlag, size, MODE_READ, TdHvTripFlagChanged, this);
3073  if (status != DB_SUCCESS) {
3074  err = QString("lemAutoRun: Couldn't hotlink Alarm TD HV trip trigger flag.");
3075  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3076  return false;
3077  }
3078  }
3079 
3080  // get run info and hotlink runinfo structure
3081  fRunInfoKey = new PKey(fExp, fRunInfoPath);
3082  if (!fRunInfoKey->IsValid()) {
3083  err = QString("lemAutoRun: Run info key not found.");
3084  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3085  return false;
3086  }
3087 
3088  // get key to run comment
3089  if (fEnabled["run_comment_odb"]) {
3090  fRunCommentKey = new PKey(fExp, fRunCommentPath);
3091  if (!fRunCommentKey->IsValid()) {
3092  err = QString("lemAutoRun: Run comment key not found.");
3093  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3094  return false;
3095  }
3096  }
3097 
3098  // get key to TOF Min
3099  if (fEnabled["tof_min_odb"]) {
3100  fTofMinKey = new PKey(fExp, fTofMinPath);
3101  if (!fTofMinKey->IsValid()) {
3102  err = QString("lemAutoRun: TOF Min key not found.");
3103  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3104  return false;
3105  }
3106  }
3107 
3108  // get key to TOF Max
3109  if (fEnabled["tof_max_odb"]) {
3110  fTofMaxKey = new PKey(fExp, fTofMaxPath);
3111  if (!fTofMaxKey->IsValid()) {
3112  err = QString("lemAutoRun: TOF Max key not found.");
3113  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3114  return false;
3115  }
3116  }
3117 
3118  // get key to moderator name
3119  if (fEnabled["mod_name_odb"]) {
3120  fModNameKey = new PKey(fExp, fModNamePath);
3121  if (!fModNameKey->IsValid()) {
3122  err = QString("lemAutoRun: Moderator name key not found.");
3123  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3124  return false;
3125  }
3126  }
3127 
3128  // get key to moderator date
3129  if (fEnabled["mod_date_odb"]) {
3130  fModDateKey = new PKey(fExp, fModDatePath);
3131  if (!fModDateKey->IsValid()) {
3132  err = QString("lemAutoRun: Moderator date key not found.");
3133  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3134  return false;
3135  }
3136  }
3137 
3138  // get key to LEM Setup
3139  if (fEnabled["lem_setup_odb"]) {
3140  fLemSetupKey = new PKey(fExp, fLemSetupPath);
3141  if (!fLemSetupKey->IsValid()) {
3142  err = QString("lemAutoRun: LEM setup key not found.");
3143  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3144  return false;
3145  }
3146  }
3147 
3148  // get key to Sample Name
3149  if (fEnabled["sample_name_info_odb"]) {
3150  fSampleNameKey = new PKey(fExp, fSampleNamePath);
3151  if (!fSampleNameKey->IsValid()) {
3152  err = QString("lemAutoRun: Sample Name key not found.");
3153  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3154  return false;
3155  }
3156  }
3157 
3158  // get key to Spin Rotation Enabled flag
3159  if (fEnabled["spin_rot_calib_odb"]) {
3161  if (!fSpinRotEnabledKey->IsValid()) {
3162  err = QString("lemAutoRun: spin rotation enabled key not found.");
3163  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3164  return false;
3165  }
3166  }
3167 
3168  // get key to Spin Rotation Angle
3169  if (fEnabled["spin_rot_angle_odb"]) {
3171  if (!fSpinRotAngleKey->IsValid()) {
3172  err = QString("lemAutoRun: spin rotation angle key not found.");
3173  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3174  return false;
3175  }
3176  }
3177 
3178  // get key to Sample Cryo
3179  if (fEnabled["sample_cryo_info_odb"]) {
3180  fSampleCryoKey = new PKey(fExp, fSampleCryoPath);
3181  if (!fSampleCryoKey->IsValid()) {
3182  err = QString("lemAutoRun: Sample Cryo key not found.");
3183  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3184  return false;
3185  }
3186  }
3187 
3188  // get key to the energy loss parameters
3189  if (fEnabled["energy_loss_param_odb"]) {
3190  QString path;
3191  for (int i=0; i<NO_ENERGY_LOSS_PARAM; i++) {
3192  path = fEnergyLossParamPath + QString("/p%1").arg(i);
3193  fEnergyLossParamKey = new PKey(fExp, path);
3194  if (!fEnergyLossParamKey->IsValid()) {
3195  err = QString("lemAutoRun: Energy loss parameter p%1 key not found.").arg(i);
3196  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3197  return false;
3198  }
3199  size = sizeof(float);
3200  fEnergyLossParamKey->GetData((void *)&fEnergyLossParam[i], &size, TID_FLOAT);
3201  delete fEnergyLossParamKey;
3202  fEnergyLossParamKey = 0;
3203  }
3204  }
3205 
3206  // get key to system/clients
3207  fClientsKey = new PKey(fExp, fClientsPath);
3208  if (!fClientsKey->IsValid()) {
3209  err = QString("lemAutoRun: Clients key not found.");
3210  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3211  return false;
3212  }
3213 
3214  if (fEnabled["fug_eq"]) {
3215  // get key to the HV demand values of the FUG's
3216  fHVDemandKey = new PKey(fExp, fHVDemandPath);
3217  if (!fHVDemandKey->IsValid()) {
3218  err = QString("lemAutoRun: HV demand key not found.");
3219  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3220  return false;
3221  }
3222 
3223  // get key to the HV measured values of the FUG's
3224  fHVMeasuredKey = new PKey(fExp, fHVMeasuredPath);
3225  if (!fHVMeasuredKey->IsValid()) {
3226  err = QString("lemAutoRun: HV measured key not found.");
3227  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3228  return false;
3229  }
3230 
3231  // get key to the HV current values of the FUG's
3232  fHVCurrentKey = new PKey(fExp, fHVCurrentPath);
3233  if (!fHVCurrentKey->IsValid()) {
3234  err = QString("lemAutoRun: HV current key not found.");
3235  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3236  return false;
3237  }
3238  }
3239 
3240  if (fEnabled["hv_detectors_eq"]) {
3241  // get key to the HV Detectors demand values
3243  if (!fHVDetectorDemandKey->IsValid()) {
3244  err = QString("lemAutoRun: HV Detectors demand key not found.");
3245  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3246  return false;
3247  }
3248 
3249  // get key to the HV Detectors measured values
3251  if (!fHVDetectorMeasuredKey->IsValid()) {
3252  err = QString("lemAutoRun: HV Detectors measured key not found.");
3253  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3254  return false;
3255  }
3256  }
3257 
3258  if (fEnabled["danfysik_spin_rot_eq"]) {
3259  // get key to the Danfysik Spin Rotator input values
3261  if (!fSpinRotMagInputKey->IsValid()) {
3262  err = QString("lemAutoRun: Danfysik Spin Rotator input key not found.");
3263  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3264  return false;
3265  }
3266 
3267  // get key to the Danfysik Spin Rotator output values
3269  if (!fSpinRotMagOutputKey->IsValid()) {
3270  err = QString("lemAutoRun: Danfysik Spin Rotator output key not found.");
3271  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3272  return false;
3273  }
3274  }
3275 
3276  if (fEnabled["danfysik_eq"]) {
3277  // get key to the Danfysik input values
3279  if (!fDanfysikInputKey->IsValid()) {
3280  err = QString("lemAutoRun: Danfysik input key not found.");
3281  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3282  return false;
3283  }
3284 
3285  // get key to the Danfysik output values
3287  if (!fDanfysikOutputKey->IsValid()) {
3288  err = QString("lemAutoRun: Danfysik output key not found.");
3289  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3290  return false;
3291  }
3292  }
3293 
3294  if (fEnabled["wew_eq"]) {
3295  // get key to the WEW output values
3296  fWEWOutputKey = new PKey(fExp, fWEWOutputPath);
3297  if (!fWEWOutputKey->IsValid()) {
3298  err = QString("lemAutoRun: WEW output key not found.");
3299  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3300  return false;
3301  }
3302 
3303  // get key to the WEW input values
3304  fWEWInputKey = new PKey(fExp, fWEWInputPath);
3305  if (!fWEWInputKey->IsValid()) {
3306  err = QString("lemAutoRun: WEW input key not found.");
3307  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3308  return false;
3309  }
3310  }
3311 
3312  if (fEnabled["magnet_field_info"]) {
3313  // get key to the magnetic field parameters key of the WEW
3314  fMagFieldKey = new PKey(fExp, fMagFieldPath);
3315  if (!fMagFieldKey->IsValid()) {
3316  err = QString("lemAutoRun: magnetic field value key not found.");
3317  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3318  return false;
3319  }
3320  }
3321 
3322  if (fEnabled["tfl_eq"]) {
3323  // get key to TFL input
3324  fTflInputKey = new PKey(fExp, fTflInputPath);
3325  if (!fTflInputKey->IsValid()) {
3326  err = QString("lemAutoRun: tfl input key not found.");
3327  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3328  return false;
3329  }
3330 
3331  // get key to TFL output
3332  fTflOutputKey = new PKey(fExp, fTflOutputPath);
3333  if (!fTflOutputKey->IsValid()) {
3334  err = QString("lemAutoRun: tfl output key not found.");
3335  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3336  return false;
3337  }
3338  }
3339 
3340  if (fEnabled["sample_eq"]) {
3341  // get key to the ctrl channel of the sample cryo LS340
3343  if (!fSampleCtrlChKey->IsValid()) {
3344  err = QString("lemAutoRun: sample cryo LS340 ctrl channel key not found.");
3345  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3346  return false;
3347  }
3348  // check if the ctrl channel is valid
3349  char ctrl_ch[4];
3350  size = sizeof(ctrl_ch);
3351  fSampleCtrlChKey->GetData(ctrl_ch, &size, TID_STRING);
3352  if (strstr(ctrl_ch, "A")) {
3354  } else if (strstr(ctrl_ch, "B")) {
3356  } else { // neither 'A' or 'B', set it to 'A'
3357  err = QString("lemAutoRun: sample cryo LS340 ctrl channel neither 'A' or 'B'. Needs to be fixed first!");
3358  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3359  return false;
3360  }
3361 
3362  // get key to the channel assignment of the sample cryo LS340
3364  if (!fSampleChannelKey->IsValid()) {
3365  err = QString("lemAutoRun: sample cryo LS340 channel assignment key not found.");
3366  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3367  return false;
3368  }
3369 
3370  // get key to the sensor type assignment of the sample cryo LS340
3372  if (!fSampleSensorTypeKey->IsValid()) {
3373  err = QString("lemAutoRun: sample cryo LS340 sensor type assignment key not found.");
3374  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3375  return false;
3376  }
3377 
3378  // get key to the sample cryo input values
3379  fSampleInputKey = new PKey(fExp, fSampleInputPath);
3380  if (!fSampleInputKey->IsValid()) {
3381  err = QString("lemAutoRun: sample cryo input key not found.");
3382  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3383  return false;
3384  }
3385  // hotlink input variables
3386  size = sizeof(fSampleInput);
3387  status = fSampleInputKey->HotLink(&fSampleInput, size, MODE_READ, NULL, NULL);
3388  if (status != DB_SUCCESS) {
3389  err = QString("lemAutoRun: Couldn't hotlink sample input variables.");
3390  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3391  return false;
3392  }
3393 
3394  // get key to the sample cryo output values
3396  if (!fSampleOutputKey->IsValid()) {
3397  err = QString("lemAutoRun: sample cryo output key not found.");
3398  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3399  return false;
3400  }
3401  // hotlink output variables
3402  size = sizeof(fSampleOutput);
3403  status = fSampleOutputKey->HotLink(&fSampleOutput, size, MODE_READ, NULL, NULL);
3404  if (status != DB_SUCCESS) {
3405  err = QString("lemAutoRun: Couldn't hotlink sample output variables.");
3406  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3407  return false;
3408  }
3409  // get key to the sample date and times values
3411  if (!fSampleDatetimeKey->IsValid()) {
3412  err = QString("lemAutoRun: sample cryo 'date and time' key not found.");
3413  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3414  return false;
3415  }
3416  // get key to the sample raw voltages
3417  char number[4];
3418  for (int i = 0; i<10; i++) {
3419  sprintf(number, " %d", i+1);
3420  QString str = QString(fSampleRawVoltagePath + number);
3421  fSampleRawVoltageKey[i] = new PKey(fExp, str);
3422  if (!fSampleRawVoltageKey[i]->IsValid()) {
3423  err = QString("lemAutoRun: sample cryo 'raw voltage key' key not found.");
3424  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3425  return false;
3426  }
3427  }
3428 
3429  // get key to the sample 'no connection' flag
3431  if (!fSampleNoConnectionKey->IsValid()) {
3432  err = QString("lemAutoRun: sample cryo 'no connection' key not found.");
3433  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3434  return false;
3435  }
3436  }
3437 
3438  if (fEnabled["omega_scfe"]) {
3439  // get key to the sample oven omega input values
3441  if (!fSampleOvenOmegaInputKey->IsValid()) {
3442  err = QString("lemAutoRun: sample oven omega output key not found.");
3443  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3444  return false;
3445  }
3446  // hotlink input variables
3447  size = sizeof(fSampleOvenOmegaInput);
3448  status = fSampleOvenOmegaInputKey->HotLink(&fSampleOvenOmegaInput, size, MODE_READ, NULL, NULL);
3449  if (status != DB_SUCCESS) {
3450  err = QString("lemAutoRun: Couldn't hotlink sample oven omega input variables.");
3451  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3452  return false;
3453  }
3454 
3455  // get key to the sample oven omega output values
3457  if (!fSampleOvenOmegaOutputKey->IsValid()) {
3458  err = QString("lemAutoRun: sample oven omega output key not found.");
3459  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3460  return false;
3461  }
3462  // hotlink input variables
3463  size = sizeof(fSampleOvenOmegaOutput);
3464  status = fSampleOvenOmegaOutputKey->HotLink(&fSampleOvenOmegaOutput, size, MODE_READ, NULL, NULL);
3465  if (status != DB_SUCCESS) {
3466  err = QString("lemAutoRun: Couldn't hotlink sample oven omega output variables.");
3467  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3468  return false;
3469  }
3470  }
3471 
3472  if (fEnabled["lemvac_scfe"]) {
3473  // get key to the lemvac input values
3474  fLemvacInputKey = new PKey(fExp, fLemvacInputPath);
3475  if (!fLemvacInputKey->IsValid()) {
3476  err = QString("lemAutoRun: lemvac input key not found.");
3477  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3478  return false;
3479  }
3480 
3481  // get key to the lemvac output values
3483  if (!fLemvacOutputKey->IsValid()) {
3484  err = QString("lemAutoRun: lemvac output key not found.");
3485  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3486  return false;
3487  }
3488  }
3489 
3490  if (fEnabled["fom_eq"]) {
3491  // get key to the FOM input values
3492  fFOMInputKey = new PKey(fExp, fFOMInputPath);
3493  if (!fFOMInputKey->IsValid()) {
3494  err = QString("lemAutoRun: FOM input key not found.");
3495  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3496  return false;
3497  }
3498 
3499  // get key to the FOM output values
3500  fFOMOutputKey = new PKey(fExp, fFOMOutputPath);
3501  if (!fFOMOutputKey->IsValid()) {
3502  err = QString("lemAutoRun: FOM output key not found.");
3503  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3504  return false;
3505  }
3506  }
3507 
3508  if (fEnabled["beamline_eq"]) {
3509  // get key to the Beamline demand values
3511  if (!fBeamlineDemandKey->IsValid()) {
3512  err = QString("lemAutoRun: Beamline demand key not found.");
3513  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3514  return false;
3515  }
3516  }
3517 
3518  if (fEnabled["mag_param_wew_odb"]) {
3519  // get key to the WEW calibration (A->G)
3520  fMagParamWewKey = new PKey(fExp, fMagParamWewPath);
3521  if (!fMagParamWewKey->IsValid()) {
3522  err = QString("lemAutoRun: Mag. Param. WEW calibration key not found.");
3523  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3524  return false;
3525  }
3526  // get the calibration parameters
3527  size = sizeof(fMagParamWew);
3528  fMagParamWewKey->GetData(&fMagParamWew, &size, TID_FLOAT);
3529  if (fMagParamWew[1] == 0.0) { // the linear part in the calibration musn't be zero!!
3530  err = QString("lemAutoRun: Mag. Param. WEW calibration with linear part == 0! Something is wrong!!");
3531  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3532  return false;
3533  }
3534  }
3535 
3536  if (fEnabled["mag_param_bpar_odb"]) {
3537  // get key to the Bpar calibration (A->G)
3539  if (!fMagParamBparKey->IsValid()) {
3540  err = QString("lemAutoRun: Mag. Param. Bpar calibration key not found.");
3541  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3542  return false;
3543  }
3544  // get the calibration parameters
3545  size = sizeof(fMagParamBpar);
3546  fMagParamBparKey->GetData(&fMagParamBpar, &size, TID_FLOAT);
3547  if (fMagParamBpar[1] == 0.0) { // the linear part in the calibration musn't be zero!!
3548  err = QString("lemAutoRun: Mag. Param. Bpar calibration with linear part == 0! Something is wrong!!");
3549  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3550  return false;
3551  }
3552  }
3553 
3554  if (fEnabled["setup_sample_odb"]) {
3555  // get the sample setup enabled flag
3557  if (!fSetupSampleEnabledKey->IsValid()) {
3558  err = QString("lemAutoRun: Sample setup enabled key not found.");
3559  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3560  return false;
3561  }
3562  int ival = -1;
3563  size = sizeof(ival);
3564  fSetupSampleEnabledKey->GetData(&ival, &size, TID_BOOL);
3565  if (ival == 1)
3566  fSetupSampleEnabled = true;
3567  }
3568 
3569  if (fEnabled["setup_wew_odb"]) {
3570  // get the WEW setup enabled flag
3572  if (!fSetupWewEnabledKey->IsValid()) {
3573  err = QString("lemAutoRun: WEW setup enabled key not found.");
3574  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3575  return false;
3576  }
3577  int ival = -1;
3578  size = sizeof(ival);
3579  fSetupWewEnabledKey->GetData(&ival, &size, TID_BOOL);
3580  if (ival == 1)
3581  fSetupWewEnabled = true;
3582  }
3583 
3584  if (fEnabled["setup_bpar_odb"]) {
3585  // get the Bpar setup enabled flag
3587  if (!fSetupBparEnabledKey->IsValid()) {
3588  err = QString("lemAutoRun: Bpar setup enabled key not found.");
3589  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3590  return false;
3591  }
3592  int ival = -1;
3593  size = sizeof(ival);
3594  fSetupBparEnabledKey->GetData(&ival, &size, TID_BOOL);
3595  if (ival == 1)
3596  fSetupBparEnabled = true;
3597  }
3598 
3599  // create RawVoltage dump file name
3600  if (fEnabled["sample_eq"]) {
3601  fDumpFileName = "RawVoltageOutput-";
3602  char cryoName[NAME_LENGTH];
3603  size = sizeof(cryoName);
3604  if (fEnabled["sample_cryo_info_odb"])
3605  fSampleCryoKey->GetData(cryoName, &size, TID_STRING);
3606  else
3607  strcpy(cryoName, "cryo");
3608  fDumpFileName += cryoName;
3609  fDumpFileName += "-";
3610  QDateTime dt(QDate::currentDate(), QTime::currentTime());
3611  QString dtStr = dt.toString("ddMMyy-hhmm");
3612  fDumpFileName += dtStr + ".dat";
3613  }
3614 
3615  return true;
3616 }
3617 
3618 //**********************************************************************
3619 // GetEnergyLoss
3620 //**********************************************************************
3626 float PLemAutoRun::GetEnergyLoss(float hv_mod)
3627 {
3628  float energy_loss = 0.0;
3629 
3630  if (!fEnabled["energy_loss_param_odb"])
3631  return 0.0;
3632 
3633  if (hv_mod < 20.1) {
3634  for (int i=0; i<NO_ENERGY_LOSS_PARAM; i++)
3635  energy_loss += fEnergyLossParam[i] * powf(hv_mod, i);
3636  } else {
3637  energy_loss = 0.23;
3638  }
3639 
3640  return energy_loss;
3641 }
3642 
3643 //**********************************************************************
3644 // CheckClients
3645 //**********************************************************************
3652 {
3653  if (fIgnoreClients) {
3654  fAnalyzerRunning = true;
3655  fFrontendRunning = true;
3656  fTflFeRunning = true;
3657  fSampleFeRunning = true;
3659  fWEWFeRunning = true;
3660  fDanfysikFeRunning = true;
3661  fHVFeRunning = true;
3662  fLemvacFeRunning = true;
3663  return;
3664  }
3665 
3666  HNDLE subKey;
3667  char str[128];
3668  INT size, status;
3669  QString name;
3670 
3671  fAnalyzerRunning = false;
3672  fFrontendRunning = false;
3673  fTflFeRunning = false;
3674  fSampleFeRunning = false;
3675  fSampleOvenOmegaFeRunning = false;
3676  fWEWFeRunning = false;
3677  fDanfysikFeRunning = false;
3678  fHVFeRunning = false;
3679  fLemvacFeRunning = false;
3680 
3681  for (int i=0; ; i++) {
3682  // check if there is a subkey
3683  if (fClientsKey->EnumSubKey(i, &subKey) == DB_NO_MORE_SUBKEYS)
3684  break;
3685  // get the content of the variable Name from the subkey
3686  size = sizeof(str);
3687  status = db_get_value(fClientsKey->GetHdb(), subKey, "Name", str, &size, TID_STRING, FALSE);
3688  if (status != DB_SUCCESS) {
3689  QString err = QString("Autorun: check clients failure ...");
3690  emit StatusMsg(err);
3691  err = QString("PLemAutoRun::CheckClients(): Couldn't get value from subkey.");
3692  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3693  }
3694  // check if the name is one of the monitored frontends
3695  name = QString(str);
3696  if (name == fAnalyzerName)
3697  fAnalyzerRunning = true;
3698  else if (name == fFrontendName)
3699  fFrontendRunning = true;
3700  else if (name == fTflFeName)
3701  fTflFeRunning = true;
3702  else if (name == fSampleFeName)
3703  fSampleFeRunning = true;
3704  else if (name == fSampleOvenOmegaFeName)
3706  else if (name == fWEWFeName)
3707  fWEWFeRunning = true;
3708  else if (name == fDanfysikFeName)
3709  fDanfysikFeRunning = true;
3710  else if (name == fHVFeName)
3711  fHVFeRunning = true;
3712  else if (name == fLemvacFeName)
3713  fLemvacFeRunning = true;
3714 
3715  // if analyzer_fe is disabled -> running to true
3716  if (!fEnabled["analyzer_fe"])
3717  fAnalyzerRunning = true;
3718  // if vme_fe is disabled -> running to true
3719  if (!fEnabled["vme_fe"])
3720  fFrontendRunning = true;
3721  // if tfl_scfe is disabled -> running to true
3722  if (!fEnabled["tfl_scfe"])
3723  fTflFeRunning = true;
3724  // if sample_scfe is disabled -> running to true
3725  if (!fEnabled["sample_scfe"])
3726  fSampleFeRunning = true;
3727  // if omega_scfe is disabled -> running to true
3728  if (!fEnabled["omega_scfe"])
3730  // if WEW scfe is disabled -> running to true
3731  if (!fEnabled["wew_scfe"])
3732  fWEWFeRunning = true;
3733  // if Danfysik scfe (Bpar) is disabled -> running to true
3734  if (!fEnabled["danfysik_scfe"])
3735  fDanfysikFeRunning = true;
3736  // if FUG handling is disabled, fake the FUG FE to running
3737  if (!fEnabled["fug_scfe"])
3738  fHVFeRunning = true;
3739  // if LEMVAC handling is disabled, fake the FUG FE to running
3740  if (!fEnabled["lemvac_scfe"])
3741  fLemvacFeRunning = true;
3742  }
3743 }
3744 
3745 //**********************************************************************
3746 // CheckMidasAlarms
3747 //**********************************************************************
3751 void PLemAutoRun::CheckMidasAlarms(PAutoRunCmdVector::Iterator iter)
3752 {
3753  if (!fEnabled["alarms_odb"])
3754  return;
3755 
3756  if (fIgnoreAlarms)
3757  return;
3758 
3759  HNDLE subKey;
3760  INT size, status;
3761 
3762  struct {
3763  BOOL active;
3764  INT triggered;
3765  INT type;
3766  INT check_interval;
3767  DWORD checked_last;
3768  char trigger_first[32];
3769  char trigger_last[32];
3770  char condition[256];
3771  char alarm_class[32];
3772  char alarm_msg[80];
3773  } alarmData;
3774 
3775  for (int i=0; ; i++) {
3776  if (fAlarmsKey->EnumSubKey(i, &subKey) == DB_NO_MORE_SUBKEYS)
3777  break;
3778  // get the trigger flag if the current alarm
3779  size = sizeof(alarmData);
3780  status = db_get_record(fAlarmsKey->GetHdb(), subKey, &alarmData, &size, 0);
3781  if (status != DB_SUCCESS) {
3782  QString err = QString("Autorun: check alarms failure ...");
3783  emit StatusMsg(err);
3784  err = QString("PLemAutoRun::CheckMidasAlarms(): Couldn't get value from subkey.");
3785  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3786  }
3787  if (alarmData.triggered && strstr(alarmData.alarm_class, "Alarm")) { // found an alarm which fired
3788  UpdateWebPage(iter, HTML_ALARM);
3789 
3790  QString err = QString("Autorun: Alarm fired ...");
3791  emit StatusMsg(err);
3792  err = QString("PLemAutoRun::CheckMidasAlarms: Alarm fired! ")+
3793  QString(" msg: %1 ").arg(alarmData.alarm_msg)+
3794  QString(" Error too severe, will stop.");
3795  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
3797  QCoreApplication::exit(0);
3798  exit(0);
3799  }
3800  }
3801 }
3802 
3803 //**********************************************************************
3804 // LakeShoreTime
3805 //**********************************************************************
3817 {
3818  int status;
3819  int imonth, day, year, hour, min, sec, msec;
3820  double days = 0, result;
3821  int month[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
3822 
3823  // extract date and time values
3824  status = sscanf(str, "%d,%d,%d,%d,%d,%d,%d", &imonth, &day, &year, &hour, &min, &sec, &msec);
3825  if (status != 7) { // str does not have the proper format
3826  return -1.0;
3827  }
3828 
3829  // check for leap year
3830  for (int i=2006; i<year; i++) {
3831  if ( ((i % 4) == 0 && (i % 100) != 0) || (i % 400) == 0 )
3832  days = days + 366;
3833  else
3834  days = days + 365;
3835  }
3836  if ( ((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0 ) month[1] = 29;
3837 
3838  for (int i = 1; i<imonth; i++ ) days = days + month[i-1];
3839 
3840  days = days + day;
3841  result = (double)days * 86400.0 + (double)hour * 3600.0 + (double)min * 60.0 +
3842  (double)sec + (double)msec / 1000.0;
3843 
3844  return result;
3845 }
3846 
3847 //**********************************************************************
3848 // SampleTempTrend
3849 //**********************************************************************
3874 {
3875  double x[SAMPLE_TEMP_HISTO_MAX];
3876  double s = 0.0;
3877  double sx = 0.0;
3878  double sxx = 0.0;
3879  double sxxx = 0.0;
3880  double sxxxx = 0.0;
3881  double sT = 0.0;
3882  double sh = 0.0;
3883  double sf = 0.0;
3884  double sp = 0.0;
3885  double sxT = 0.0;
3886  double sxh = 0.0;
3887  double sxf = 0.0;
3888  double sxp = 0.0;
3889  double sxxT = 0.0;
3890  double sxxh = 0.0;
3891  double sxxf = 0.0;
3892  double sxxp = 0.0;
3893 
3894  double help = 0.0;
3895  double xx = 0.0;
3896 
3897  if ( fSampleHistoNoEntries < 4 )
3898  return;
3899 
3900  for (int i=0; i<fSampleHistoNoEntries; i++) {
3901  s += 1.0;
3902  sx += fSampleTempHisto[i].datetime;
3903  }
3904 
3905  sx = sx / s; // average time
3907  // to calculate the time difference between the current and the previous temp
3908  // one needs to be careful since the data are stored in a ring buffer.
3909  // The current counter 'fSampleHistoPos' is always one count ahead!
3910  switch (fSampleHistoPos) {
3911  case 0: // current counter at the begining
3912  fSampleTempTrend.datetime = fSampleTempHisto[fSampleHistoNoEntries-1].datetime -
3913  fSampleTempHisto[fSampleHistoNoEntries-2].datetime;
3914  break;
3915  case 1: // current counter at the 2nd entry
3917  fSampleTempHisto[fSampleHistoNoEntries-1].datetime;
3918  break;
3919  default:
3922  break;
3923  }
3924 
3925  for (int i=0; i<fSampleHistoNoEntries; i++)
3926  x[i] = fSampleTempHisto[i].datetime - sx;
3927 
3928  sx = 0.0;
3929  for (int i=0; i<fSampleHistoNoEntries; i++) {
3930  xx = x[i] * x[i];
3931  sx += x[i];
3932  sxx += xx;
3933  sxxx += xx * x[i];
3934  sxxxx += xx * xx;
3935  sT += fSampleTempHisto[i].measured_T;
3936  sh += fSampleTempHisto[i].heater;
3937  sf += fSampleTempHisto[i].flow;
3938  sp += fSampleTempHisto[i].pressure;
3939  sxT += x[i] * fSampleTempHisto[i].measured_T;
3940  sxh += x[i] * fSampleTempHisto[i].heater;
3941  sxf += x[i] * fSampleTempHisto[i].flow;
3942  sxp += x[i] * fSampleTempHisto[i].pressure;
3943  sxxT += xx * fSampleTempHisto[i].measured_T;
3944  sxxh += xx * fSampleTempHisto[i].heater;
3945  sxxf += xx * fSampleTempHisto[i].flow;
3946  sxxp += xx * fSampleTempHisto[i].pressure;
3947 
3948  }
3949 
3950  double denominator = -s * sxx * sxxxx + s * sxxx * sxxx + sx * sx * sxxxx
3951  - 2.0 * sxxx * sx * sxx + sxx * sxx * sxx;
3952 
3953  if ( fabs( denominator ) > 0.0 ) {
3954  fSampleTempAverage.measured_T = -(sx * sxxx * sxxT - sx * sxT * sxxxx + sxx * sxxx * sxT - sxx * sxx * sxxT +
3955  sT * sxx * sxxxx - sT * sxxx * sxxx) / denominator;
3956  fSampleTempAverage.heater = -(sx * sxxx * sxxh - sx * sxh * sxxxx + sxx * sxxx * sxh - sxx * sxx * sxxh +
3957  sh * sxx * sxxxx - sh * sxxx * sxxx) / denominator;
3958  fSampleTempAverage.flow = -(sx * sxxx * sxxf - sx * sxf * sxxxx + sxx * sxxx * sxf - sxx * sxx * sxxf +
3959  sf * sxx * sxxxx - sf * sxxx * sxxx) / denominator;
3960  fSampleTempAverage.pressure = -(sx * sxxx * sxxp - sx * sxp * sxxxx + sxx * sxxx * sxp - sxx * sxx * sxxp +
3961  sp * sxx * sxxxx - sp * sxxx * sxxx) / denominator;
3962  fSampleTempTrend.measured_T = -(- s * sxxx * sxxT + s * sxT * sxxxx - sxT * sxx * sxx + sxx * sx * sxxT +
3963  sxx * sxxx * sT - sx * sT * sxxxx) / denominator;
3964  fSampleTempTrend.heater = -(- s * sxxx * sxxh + s * sxh * sxxxx - sxh * sxx * sxx + sxx * sx * sxxh +
3965  sxx * sxxx * sh - sx * sh * sxxxx) / denominator;
3966  fSampleTempTrend.flow = -(- s * sxxx * sxxf + s * sxf * sxxxx - sxf * sxx * sxx + sxx * sx * sxxf +
3967  sxx * sxxx * sf - sx * sf * sxxxx) / denominator;
3968  fSampleTempTrend.pressure = -(- s * sxxx * sxxp + s * sxp * sxxxx - sxp * sxx * sxx + sxx * sx * sxxp +
3969  sxx * sxxx * sp - sx * sp * sxxxx) / denominator;
3970  fSampleTempSecond.measured_T = (- sxxx * sx * sT + sx * sx * sxxT + s * sxxx * sxT - s * sxx * sxxT -
3971  sxx * sx * sxT + sxx * sxx * sT) / denominator;
3972  fSampleTempSecond.heater = (- sxxx * sx * sh + sx * sx * sxxh + s * sxxx * sxh - s * sxx * sxxh -
3973  sxx * sx * sxh + sxx * sxx * sh) / denominator;
3974  fSampleTempSecond.flow = (- sxxx * sx * sf + sx * sx * sxxf + s * sxxx * sxf - s * sxx * sxxf -
3975  sxx * sx * sxf + sxx * sxx * sf) / denominator;
3976  fSampleTempSecond.pressure = (- sxxx * sx * sp + sx * sx * sxxp + s * sxxx * sxp - s * sxx * sxxp -
3977  sxx * sx * sxp + sxx * sxx * sp) / denominator;
3978 
3979  }
3980 
3982  fSampleTempRmsqd.heater = 0.0;
3983  fSampleTempRmsqd.flow = 0.0;
3984  fSampleTempRmsqd.pressure = 0.0;
3985  for (int i=0; i<fSampleHistoNoEntries; i++) {
3986  xx = x[i] * x[i];
3989  fSampleTempRmsqd.measured_T += help * help;
3991  fSampleTempSecond.heater * xx);
3992  fSampleTempRmsqd.heater += help * help;
3994  fSampleTempSecond.flow * xx);
3995  fSampleTempRmsqd.flow += help * help;
3998  fSampleTempRmsqd.pressure += help * help;
3999  }
4004 
4005  if (fDebug) {
4006  cout << endl << "SampleTempTrend:";
4007  cout << endl << " fSampleTempAverage (T, heater, flow, pressure):";
4008  cout << " " << fSampleTempAverage.measured_T;
4009  cout << ", " << fSampleTempAverage.heater;
4010  cout << ", " << fSampleTempAverage.flow;
4011  cout << ", " << fSampleTempAverage.pressure;
4012  cout << endl << " fSampleTempTrend (T, heater, flow, pressure):";
4013  cout << " " << fSampleTempTrend.measured_T;
4014  cout << ", " << fSampleTempTrend.heater;
4015  cout << ", " << fSampleTempTrend.flow;
4016  cout << ", " << fSampleTempTrend.pressure;
4017  cout << endl << " fSampleTempSecond (T, heater, flow, pressure):";
4018  cout << " " << fSampleTempSecond.measured_T;
4019  cout << ", " << fSampleTempSecond.heater;
4020  cout << ", " << fSampleTempSecond.flow;
4021  cout << ", " << fSampleTempSecond.pressure;
4022  cout << endl << " fSampleTempRmsqd (T, heater, flow, pressure):";
4023  cout << " " << fSampleTempRmsqd.measured_T;
4024  cout << ", " << fSampleTempRmsqd.heater;
4025  cout << ", " << fSampleTempRmsqd.flow;
4026  cout << ", " << fSampleTempRmsqd.pressure;
4027  cout << endl;
4028  }
4029 
4030 }
4031 
4032 //**********************************************************************
4033 // SampleTempPrefHeaterOutput
4034 //**********************************************************************
4045 {
4046  float value = 0;
4047  int hr = (int)heaterRange;
4048 
4049  if (fDebug)
4050  cout << endl << "in SampleTempPrefHeaterOutput: hr = " << hr;
4051 
4052  switch (hr) {
4053  case 3:
4054  value = 50.0;
4055  break;
4056  case 4:
4057  value = 40.0;
4058  break;
4059  case 5:
4060  value = 10.0 + 0.04 * fSampleOutput[LS340_OUTPUT_SETPOINT];
4061  break;
4062  default:
4063  break;
4064  }
4065 
4066  return value;
4067 }
4068 
4069 //**********************************************************************
4070 // SampleTempAdjustFlow
4071 //**********************************************************************
4076 {
4077  float change = 1.0;
4078  float value;
4079  float p_heat, d_heat, pref_heat;
4080 
4081  if (fDebug)
4082  cout << endl << "in SampleTempAdjustFlow ...";
4083 
4084  p_heat = -(fBHFlowPHeat0 + fBHFlowPHeat1 *
4086 
4087  d_heat = fBHFlowDHeat;
4089  change = exp( p_heat * (( fSampleInput[LS340_INPUT_HEATER] - pref_heat ) + d_heat * fSampleTempTrend.heater ));
4090 
4092 
4093  if (fDebug) {
4094  cout << endl << "--------------------";
4095  cout << endl << "SampleTempAdjustFlow: p0 = " << fBHFlowPHeat0 << ", p1 = " << fBHFlowPHeat1;
4096  cout << endl << "SampleTempAdjustFlow: p_heat = " << p_heat << ", d_heat = " << d_heat << ", pref_heat = " << pref_heat;
4097  cout << endl << "SampleTempAdjustFlow: heater = " << fSampleInput[LS340_INPUT_HEATER] << ", dH/dt = " << fSampleTempTrend.heater;
4098  cout << endl << "change = " << change;
4099  cout << endl << "SampleTempAdjustFlow: new flow value = " << value;
4100  }
4101 
4102  if ( value > fBHMaxFlow ) value = fBHMaxFlow;
4103  if ( value < fBHMinFlow ) value = fBHMinFlow;
4104 
4105  fSampleOutputKey->SetDataIndex(&value, fSampleBhOdbOffsetOutput+BH_OUTPUT_FLOW, TID_FLOAT);
4106 
4107  // also have a look at the needle valve
4108 
4110 }
4111 
4112 //**********************************************************************
4113 // SampleTempStable
4114 //**********************************************************************
4119 {
4121 
4122  if (maxdiff < fAbsMaxTempDiff) {
4123  maxdiff = fAbsMaxTempDiff;
4124  }
4125 
4126  if (fDebug)
4127  cout << endl << "in SampleTempStable. maxdiff = " << maxdiff;
4128 
4131  (fSampleTempRmsqd.measured_T < maxdiff) &&
4134  if (fDebug)
4135  cout << endl << "in SampleTempStable. stability reached.";
4136  return true;
4137  }
4138 
4139  return false;
4140 }
4141 
4142 //**********************************************************************
4143 // SampleTempConsiderNeedleValve
4144 //**********************************************************************
4150 {
4151  float value = 1.0e6;
4152  float modus = 0.0;
4153  float bh_valve;
4154  float needle_valve;
4155  int size;
4156  float demand_flow;
4157 
4158  if (fDebug)
4159  cout << endl << "in SampleTempConsiderNeedleValve ...";
4160 
4161  // check the modus of the needle valve.
4162  size = sizeof(modus);
4163  fTflOutputKey->GetDataIndex(&modus, &size, SM_MODUS_NEEDLEVALVE, TID_FLOAT);
4164 
4165  if (fNeedleValveInUse && modus > 1.0) { // only set the needle valve when it is in_use and in auto-modus
4166  size = sizeof(bh_valve);
4167  fSampleInputKey->GetDataIndex(&bh_valve, &size, fSampleBhOdbOffsetInput + BH_INPUT_VALVE,
4168  TID_FLOAT);
4169 
4170  size = sizeof(needle_valve);
4171  fTflInputKey->GetDataIndex(&needle_valve, &size, SM_INPUT_NEEDLEVALVE, TID_FLOAT);
4172  if (bh_valve > 0.9) { // almost open bronkhorst needle valve
4173  size = sizeof(demand_flow);
4174  fSampleOutputKey->GetDataIndex(&demand_flow, &size,
4176  TID_FLOAT);
4177  if (demand_flow > 2.0*fSampleTempAverage.flow) // measured flow far off demand flow -> open transferline needle valve quickly
4178  value = needle_valve + fPrefNeedleValveAbsStep;
4179  else // measured flow not too far off demand flow -> open transferline needle valve more gradually
4180  value = ( 1.0 + fPrefNeedleValveRelStep ) * needle_valve;
4181  }
4182 
4183  // pressure on the cryo exhaust too high -> close transferline needle valve a bit
4184  if (fSampleTempAverage.pressure > 0.8)
4185  value = ( 1.0 - fPrefNeedleValveRelStep ) * needle_valve;
4186 
4187  if (fDebug)
4188  cout << endl << "in SampleTempConsiderNeedleValve: value = " << value;
4189 
4190  // value still 1.0e6, i.e. nothing to be done, get out
4191  if (value == 1.0e6)
4192  return;
4193 
4194  // something changed, but lets check if value is out of range
4195  if (value > 99.0)
4196  value = 99.0;
4197 
4198  if (value < fPrefNeedleValveCof_4_0)
4199  value = fPrefNeedleValveCof_4_0;
4200 
4201  fTflOutputKey->SetDataIndex(&value, SM_OUTPUT_NEEDLEVALVE, TID_FLOAT);
4202  }
4203 }
4204 
4205 //**********************************************************************
4206 // SampleTempSetNeedleValve
4207 //**********************************************************************
4214 {
4215  float modus = 0.0;
4216  float tempSP = 0.0;
4217  int size = sizeof(float);
4218 
4219  if (!fEnabled["tfl_eq"] || !fEnabled["sample_eq"]) {
4220  QString err = QString("PLemAutoRun::SampleTempSetNeedleValve(): TFL(%1) and/or Sample(%2) equipment not available. Do nothing here.").arg(fEnabled["tfl_eq"]).arg(fEnabled["sample_eq"]);
4221  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
4222  return;
4223  }
4224 
4225  // get demand temperature
4226  fSampleOutputKey->GetDataIndex(&tempSP, &size, LS340_OUTPUT_SETPOINT, TID_FLOAT);
4227 
4228  // check the modus of the needlevalve.
4229  size = sizeof(float);
4230  fTflOutputKey->GetDataIndex(&modus, &size, SM_MODUS_NEEDLEVALVE, TID_FLOAT);
4231 
4232  // make sure that value is within proper bounds
4233  if (value > 100.0)
4234  value = 98.0;
4235  if (value < 0.0)
4236  value = 0.0;
4237 
4238  // only set the needle valve when it is in_use and in auto-modus
4239  if (fNeedleValveInUse && modus > 1.0) {
4240  if (tempSP < 5.0) // do not tweak NV for demand T<5K
4241  value = fPrefNeedleValveCof_1_0;
4242  fTflOutputKey->SetDataIndex((void *)&value, SM_OUTPUT_NEEDLEVALVE, TID_FLOAT);
4243  }
4244 }
4245 
4246 
4247 //**********************************************************************
4248 // SampleTempConsiderFlow
4249 //**********************************************************************
4255 {
4256  float change = 1.0;
4257  float value;
4258  float demand;
4259  int size = sizeof(float);
4260 
4261  if (fDebug)
4262  cout << endl << "in SampleTempConsiderFlow ...";
4263 
4264  // if at large flow do nothing. Only used if no ramping while cooling
4265  if (fLargeFlow)
4266  return;
4267 
4268  fSampleOutputKey->GetDataIndex(&demand, &size, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW,
4269  TID_FLOAT);
4270 
4271  // if the demand value < fFlowLowestFlowToConsider (given in the XML startup file) do nothing
4272  if ( demand < fFlowLowestFlowToConsider ) {
4273  cm_msg(MINFO,"SampleTempConsiderFlow", "SampleTempConsiderFlow, demand = %e", demand);
4274  cm_yield(0);
4275  return;
4276  }
4277 
4278  // if the real flow is far off from the demand value do nothing
4279  if ( fabs( fSampleTempAverage.flow - demand ) / demand > fFlowMaxRelFlowDiffToConsider ) {
4280  cm_msg(MINFO,"SampleTempConsiderFlow",
4281  "SampleTempConsiderFlow skipped consideration, demand = %e, present flow = %e",
4282  demand, fSampleTempAverage.flow);
4283  cm_yield(0);
4284  return;
4285  }
4286 
4287  // flow is relatively close to the demand value -> only tweak it
4288  if ((fSampleTempAverage.measured_T < fSampleInput[LS340_INPUT_SETPOINT]) && // it is too cold
4289  (fSampleTempTrend.measured_T < 0.05) && // and it is not warming
4290  (fSampleTempSecond.measured_T < 0.005) && // and it is not going to warm
4291  (fSampleTempAverage.heater > fHeaterMax)) // while the heater is doing its utmost
4292  change -= fFlowFactor; // then DECREASE flow
4293 
4294  if ((fSampleTempAverage.measured_T > fSampleInput[LS340_INPUT_SETPOINT]) && // it is too warm
4295  (fSampleTempTrend.measured_T > -0.05) && // and it is not cooling
4296  (fSampleTempSecond.measured_T > -0.005) && // and it is not going to cool
4297  (fSampleTempAverage.heater < fHeaterMin)) // while the heater is doing nothing
4298  change += fFlowFactor; // then INCREASE flow
4299 
4300  if (fabs( change - 1.0 ) > 0.001 ) { // change flow
4302 
4303  // try to learn from this consideration of the flow; fBHFlowTemp is used to estimate
4304  // the initial flow for a given temperature: flow = fBHFlowTemp/(T+fBHFlowTempOffset) + fBHFlowOffset
4305  fBHFlowTemp = change * fBHFlowTemp;
4306 
4307  if ( value > fBHMaxFlow )
4308  value = fBHMaxFlow;
4309 
4310  if ( value < fBHMinFlow )
4311  value = fBHMinFlow;
4312 
4313  fSampleOutputKey->SetDataIndex(&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
4314  }
4315 
4316  if (fDebug) {
4317  cout << endl << "SampleTempConsiderFlow: new flow value = " << fSampleTempAverage.flow * change;
4318  cout << " (change = " << change << ", fSampleTempAverage.flow = " << fSampleTempAverage.flow << ")";
4319  }
4320 }
4321 
4322 //**********************************************************************
4323 // CheckTempStability
4324 //**********************************************************************
4329 {
4330  int size;
4331  char str[NAME_LENGTH];
4332  QString err;
4333 
4334  if (!fEnabled["sample_eq"])
4335  return;
4336 
4337  static int tempDeviationToHighCounter = 0; // counter needed to eliminate error messages due to readback errors
4338 
4339  if (fDebug)
4340  cout << endl << "in CheckTempStability ...";
4341 
4342  if (fSampleInput[fSampleCtrlCh] <= 0.0) { // CF1 or CF2 temperature <= 0, i.e. frontend error
4343  err = QString("PLemAutoRun::CheckTempStability(): CF1 readback = %1. ").arg(fSampleInput[fSampleCtrlCh]);
4344  err += QString("Does not make any sense!");
4345  emit ErrorMsg(1, 0, LAR_LS340_INPUT_NONSENSE, -1, err);
4346  return;
4347  }
4348 
4349  if (!fSampleTempRegulation) { // no temperature adjustment wanted
4351  if (!fSampleTempUnstable) { // to reduce the number of error messages
4352  fSampleTempUnstable = true;
4353  err = QString("PLemAutoRun::CheckTempStability(): | Setpoint=%1 ").arg(fSampleInput[LS340_INPUT_SETPOINT]);
4354  err += QString("- CF1=%1 | > %2").arg(fSampleInput[fSampleCtrlCh]).arg(fSampleTempAccuracy);
4355  emit ErrorMsg(1, 0, LAR_LS340_TEMP_NOT_STABLE, -1, err);
4356  }
4357  } else {
4358  fSampleTempUnstable = false;
4359  }
4360  return;
4361  }
4362 
4363  // feed history ring buffer ----------------------------------------------
4364  // get LS340 date and time
4365  size = sizeof(str);
4366  fSampleDatetimeKey->GetData(str, &size, TID_STRING);
4368  if (fSampleHistoTime == -1.0) { // no LakeShore time available, will take local one
4369  fSampleHistoTime = ss_time();
4370  }
4372  fSampleHistoLastTime = fSampleHistoTime; // keep as previous time for next time
4373  else
4374  return; // no new timestamp available, therefore return
4375 
4376  // update counter of how many elements are present in the history buffer
4379  // feed data to the history buffer
4386  // increment history buffer counter modulo its length
4388 
4389  QString datetime;
4390  if (fDebug) {
4391  cout << endl << "Timedate History: " << fSampleHistoPos << endl;
4392  for (int i=0; i<SAMPLE_TEMP_HISTO_MAX; i++) {
4393  if (i>fSampleHistoNoEntries)
4394  break;
4395  datetime.setNum(fSampleTempHisto[i].datetime, 'f', 2);
4396  cout << datetime.toLatin1().data() << ", ";
4397  }
4398  cout << endl;
4399  cout << endl << "Temperature History: " << fSampleHistoPos << endl;
4400  for (int i=0; i<SAMPLE_TEMP_HISTO_MAX; i++) {
4401  if (i>fSampleHistoNoEntries)
4402  break;
4403  cout << fSampleTempHisto[i].measured_T << ", ";
4404  }
4405  cout << endl;
4406  }
4407 
4408  // calculate trend parameters
4409  SampleTempTrend();
4410 
4411  // check if temperature within the required boundaries
4413  tempDeviationToHighCounter++;
4414  if (!fSampleTempUnstable && (tempDeviationToHighCounter > 5)) { // to reduce the number of error messages
4415  fSampleTempUnstable = true;
4416  err = QString("PLemAutoRun::CheckTempStability(): | Setpoint=%1 ").arg(fSampleInput[LS340_INPUT_SETPOINT]);
4417  err += QString("- CF1=%1 | > %2").arg(fSampleInput[fSampleCtrlCh]).arg(fSampleTempAccuracy);
4418  emit ErrorMsg(1, 0, LAR_LS340_TEMP_NOT_STABLE, -1, err);
4419  }
4420  } else {
4421  tempDeviationToHighCounter = 0;
4422  }
4423 }
4424 
4425 //**********************************************************************
4426 // CheckTempStabilityOvenOmega
4427 //**********************************************************************
4432 {
4433  QString err;
4434 
4435  fSampleTempAccuracy = 2.0; // the omega controller has an accuracy of 1°C only!!
4437  if (!fSampleTempUnstable) { // to reduce the number of error messages
4438  fSampleTempUnstable = true;
4439  err = QString("PLemAutoRun::CheckTempStabilityOvenOmega(): | Setpoint=%1 ").arg(fSampleOvenOmegaOutput[OMEGA_OVEN_OUTPUT_SETPOINT]);
4440  err += QString("- Temp.Measured=%1 | > %2").arg(fSampleOvenOmegaInput[OMEGA_OVEN_INPUT_TEMP]).arg(fSampleTempAccuracy);
4441  emit ErrorMsg(1, 0, LAR_LS340_TEMP_NOT_STABLE, -1, err);
4442  }
4443  } else {
4444  fSampleTempUnstable = false;
4445  }
4446 }
4447 
4448 //**********************************************************************
4449 // UpdateWebPage
4450 //**********************************************************************
4468 void PLemAutoRun::UpdateWebPage(PAutoRunCmdVector::Iterator currentIter, int tag, int errLineNo, QString errMsg)
4469 {
4470  PAutoRunCmdVector::Iterator iter;
4471  QFile file(fXMLAutoRunHTML);
4472 
4473  // open HTML file
4474  if ( !file.open( QIODevice::WriteOnly ) ) { // couldn't open file
4475  QString err = QString("PLemAutoRun::UpdateWebPage(): Couldn't open %1").arg(fXMLAutoRunHTML);
4476  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
4477  return;
4478  }
4479 
4480  // write HTML code
4481  QTextStream stream( &file );
4482 
4483  // write HTML start tag
4484  stream << "<html>" << endl;
4485 
4486  // write header
4487  stream << " <head>" << endl;
4488  stream << "<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />" << endl;
4489  stream << " <title>LEM Autorun Parameter Page</title>" << endl;
4490  stream << " <meta http-equiv=\"Refresh\" content=\"30\">" << endl;
4491  stream << " <script type=\"text/javascript\" src=\"../mhttpd.js\"></script>" << endl;
4492  stream << " <script type=\"text/javascript\" src=\"../midas.js\"></script>" << endl;
4493  stream << " <script type=\"text/javascript\" src=\"../obsolete.js\"></script>" << endl;
4494  stream << " <script type=\"text/javascript\">" << endl;
4495  stream << " var lar_state;" << endl;
4496  stream << " function lar_running()" << endl;
4497  stream << " {" << endl;
4498  stream << " var result=confirm(\"Are you sure you want to start the autorun?\")" << endl;
4499  stream << " if (result==true) {" << endl;
4500  stream << " ODBSet(\"/AutoRun/Run State\", \"2\");" << endl;
4501  stream << " setTimeout(\"lar_refresh()\", 4000);" << endl;
4502  stream << " }" << endl;
4503  stream << " }" << endl;
4504  stream << endl;
4505  stream << " function lar_resume()" << endl;
4506  stream << " {" << endl;
4507  stream << " ODBSet(\"/AutoRun/Run State\", \"3\");" << endl;
4508  stream << " setTimeout(\"lar_refresh()\", 4000);" << endl;
4509  stream << " }" << endl;
4510  stream << endl;
4511  stream << " function lar_stop()" << endl;
4512  stream << " {" << endl;
4513  stream << " var result=confirm(\"Are you sure you want to stop the autorun?\")" << endl;
4514  stream << " if (result==true) {" << endl;
4515  stream << " ODBSet(\"/AutoRun/Run State\", \"0\");" << endl;
4516  stream << " setTimeout(\"lar_refresh()\", 4000);" << endl;
4517  stream << " }" << endl;
4518  stream << " }" << endl;
4519  stream << endl;
4520  stream << " function lar_pause()" << endl;
4521  stream << " {" << endl;
4522  stream << " ODBSet(\"/AutoRun/Run State\", \"1\");" << endl;
4523  stream << " setTimeout(\"lar_refresh()\", 4000);" << endl;
4524  stream << " }" << endl;
4525  stream << endl;
4526  stream << " function lar_load()" << endl;
4527  stream << " {" << endl;
4528  stream << " ODBSet(\"/AutoRun/Run State\", \"4\");" << endl;
4529  stream << " setTimeout(\"lar_refresh()\", 4000);" << endl;
4530  stream << " }" << endl;
4531  stream << endl;
4532  stream << " function lar_refresh()" << endl;
4533  stream << " {" << endl;
4534  stream << " window.location.reload(true);" << endl;
4535  stream << " }" << endl;
4536  stream << " function compProp(prop_odb) {" << endl;
4537  stream << " fetch('https://duo.psi.ch/duo/rest.php/cal/smus/lem?SECRET=change-bib-eva-grille',{method:'POST'})" << endl;
4538  stream << " .then( data => data.json(), console.error)" << endl;
4539  stream << " .then( data => {" << endl;
4540  stream << " console.log('propid_duo:', data.proposal);" << endl;
4541  stream << " if (data.proposal != prop_odb ) {" << endl;
4542  stream << " alert(\"The proposal number does NOT match the official schedule!\");" << endl;
4543  stream << " }" << endl;
4544  stream << " });" << endl;
4545  stream << " }" << endl;
4546  stream << " mjsonrpc_db_get_values([\"/Info/File_Header_Info/Proposal Number\"])" << endl;
4547  stream << " .then(function(rpc) {console.log('propid_odb:', rpc.result.data[0]);" << endl;
4548  stream << " compProp(rpc.result.data[0]);});" << endl;
4549  stream << " " << endl;
4550  stream << " " << endl;
4551  stream << " " << endl;
4552  stream << " </script>" << endl;
4553  stream << " </head>" << endl;
4554 
4555  // write body
4556  stream << " <body>" << endl;
4557  stream << " <form name=\"form1\" method=\"Get\" action=\"/CS/AutoRun&\">" << endl;
4558  stream << " <input type=\"hidden\" name=\"exp\" value=\"" << fExpName.toLatin1().data() << "\">" << endl;
4559  stream << " <table border=3 cellpadding=2 class=\"genericTable\">" << endl;
4560  stream << " <tr><th colspan=3 class=\"subStatusTitle\">NEMU Experiment: Autorun Parameters</th></tr>" << endl;
4561  stream << " <tr><td colspan=3>" << endl;
4562  stream << " <input value=\"Status\" name=\"cmd\" type=\"submit\">" << endl;
4563  stream << " <input value=\"ODB\" name=\"cmd\" type=\"submit\">" << endl;
4564  stream << " <input value=\"Messages\" name=\"cmd\" type=\"submit\">" << endl;
4565  stream << " </td></tr>" << endl;
4566  stream << " <tr><td colspan=3 style=\"text-align:left;\">" << endl;
4567  stream << " <script type=\"text/javascript\">" << endl;
4568  stream << " lar_state = ODBGet('/AutoRun/Run State');" << endl;
4569  stream << " if ((lar_state == 0) || (lar_state == 2) || (lar_state == 4) || (lar_state == 5)) { // stopped or starting up" << endl;
4570  stream << " document.write('<input type=\"button\" value=\"Start AutoRun\" onclick=\"lar_running()\">');" << endl;
4571  stream << " document.write('<input type=\"button\" value=\"Load Sequence\" onclick=\"lar_load()\">');" << endl;
4572  stream << " } else if (lar_state == 1) { // paused" << endl;
4573  stream << " document.write('<input type=\"button\" value=\"Resume AutoRun\" onclick=\"lar_resume()\">');" << endl;
4574  stream << " } else { // running" << endl;
4575  stream << " document.write('<input type=\"button\" value=\"Stop AutoRun\" onclick=\"lar_stop()\">');" << endl;
4576  stream << " document.write(' ');" << endl;
4577  stream << " document.write('<input type=\"button\" value=\"Pause AutoRun\" onclick=\"lar_pause()\">');" << endl;
4578  stream << " }" << endl;
4579  stream << " </script>" << endl;
4580  stream << " </td></tr>" << endl;
4581  stream << " <tr><td class=\"ODBtableEven\" colspan=3 style=\"text-align:left;\">Sample Name: <b><odb src=\"/Info/Sample Name\" edit=2></b></td>" << endl;
4582  stream << " <tr><td class=\"ODBtableOdd\" colspan=2 style=\"text-align:left;\">Proposal Number: <b><odb src=\"/Info/File_Header_Info/Proposal Number\" edit=2></b></td>" << endl;
4583  stream << " <td class=\"ODBtableOdd\" style=\"text-align:left;\">PI: <b><odb src=\"/Info/File_Header_Info/Main Proposer\" edit=2></b></td>" << endl;
4584  stream << " <tr><td class=\"ODBtableOdd\" colspan=2 style=\"text-align:left;\">Sequence: <b><odb src=\"/AutoRun/Auto Run Sequence\" edit=2></b></td>" << endl;
4585  stream << " <td class=\"ODBtableOdd\" style=\"text-align:left;\">Show Comments: <b><odb src=\"/AutoRun/Show Comments\" edit=2></b></td></tr>" << endl;
4586  stream << " <tr><td class=\"ODBtableEven\" colspan=2 style=\"text-align:left;\">Goto Line: <b><odb src=\"/AutoRun/GotoLine\" edit=2></b></td>" << endl;
4587  stream << " <td class=\"ODBtableEven\" style=\"text-align:left;\">Next : <b><odb src=\"/AutoRun/Next\" edit=2></b></td></tr>" << endl;
4588  stream << " <tr><td colspan=3 style=\"text-align:left;\">Status : <b><odb src=\"/AutoRun/Status\" edit=0></b></td></tr>" << endl;
4589 
4590  // write sequence
4591  stream << " <tr><td colspan=3 style=\"text-align:left;font-family:Fixed;line-height:1.25\" bgcolor=\"#FFFFFF\">" << endl;
4592  stream << " <pre>" << endl;
4593 
4594  if (tag == HTML_PARSE_ERROR) { // handle errors
4595  if (errLineNo > 0) {
4596  // get input file name
4597  QString pathFln = fAutoRunPath + GetAutoRunSequence();
4598  // read input file
4599  QFile f(pathFln);
4600  QTextStream fstream(&f);
4601  QString line;
4602  int lineNo = 1;
4603  if (f.exists()) {
4604  f.open(QIODevice::ReadOnly);
4605  while (!fstream.atEnd()) {
4606  line = fstream.readLine();
4607  stream << lineNo << ": " << line << endl;
4608  if (lineNo == errLineNo) {
4609  stream << "<span style=\"background-color: #FF8800;font-weight: bold;\">" << errMsg.toLatin1().data() << "</span>";
4610  stream << endl;
4611  }
4612  lineNo++;
4613  }
4614  f.close();
4615  } else {
4616  stream << "<span style=\"background-color: #FF8800;font-weight: bold;\">" << errMsg.toLatin1().data() << "</span>";
4617  }
4618  } else {
4619  stream << "<span style=\"background-color: #FF8800font-weight: bold;\">" << errMsg.toLatin1().data() << "</span>";
4620  }
4621  } else if (tag == HTML_FATAL) {
4622  stream << "<span style=\"background-color: #FF0000font-weight: bold;\">" << errMsg.toLatin1().data() << "</span>";
4623  } else { // normal command handling
4624  QString cmd;
4625 
4626  if (tag == HTML_LOAD) {
4627  QDateTime dt = QDateTime::currentDateTime();
4628  cmd = QString("<span style=\"background-color: #11FF11;font-weight: bold;\">&gt;&gt; %1: SEQUENCE LOADED ONLY, PRESS START AUTORUN BOTTOM IF YOU WANT TO START IT &lt;&lt;</span>").arg(dt.toString("dd.MM.yy, hh:mm:ss"));
4629  stream << cmd << endl;
4630  }
4631 
4632  // write commands
4633  int width = 0, count = 0;
4634  if (fAutoRunCmdVector->count()>0)
4635  width = (int)(log10(fAutoRunCmdVector->count())+1);
4636  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
4637 
4638  if (!ShowComments() && (iter->cmd == "comment"))
4639  continue;
4640 
4641  if ((iter == currentIter) && (tag != HTML_LOAD)) // current command start
4642  cmd = "<span style=\"background-color: #FFFF00;font-weight: bold;\">";
4643  else
4644  cmd = "";
4645 
4646  count++;
4647  cmd += QString("%1 (%2): ").arg(count, width).arg(iter->lineNo, width);
4648 
4649  // command
4650  if (iter->cmd == "comment")
4651  cmd += "<span style=\"color:grey;font-style:italic\">";
4652 
4653  cmd += iter->cmdString;
4654 
4655  if (iter->cmd == "comment")
4656  cmd += "</span>";
4657 
4658  if (iter == currentIter) { // current command end
4659  if (tag == HTML_ABORTED) {
4660  if (!errMsg.isEmpty())
4661  cmd += QString("\n<span style=\"background-color: #FF0000;font-weight: bold;\">%1</span></span>").arg(errMsg);
4662  cmd += "\n<span style=\"background-color: #FF0000;font-weight: bold;\">AUTORUN ABORTED ...</span></span>";
4663  } else if (tag == HTML_WARMUP) {
4664  cmd += "\nEXECUTING WARMUP COMMAND ...</span>";
4665  } else if (tag == HTML_ALARM) {
4666  cmd += "\n<span style=\"background-color: #FF0000;font-weight: bold;\">ALARM FIRED, HENCE AUTORUN STOPPED...</span></span>";
4667  } else if (tag == HTML_STRANGE) {
4668  cmd += "\n<span style=\"background-color: #FF0000;font-weight: bold;\">THERE IS ALREADY A RUN GOING ON. AUTORUN WILL ONLY START THE FIRST COMMAND AFTER THE CURRENT RUN WILL BE STOPPED ...</span></span>";
4669  } else {
4670  cmd += "</span>";
4671  }
4672  }
4673 
4674  stream << cmd << endl;
4675  }
4676 
4677  if (tag == HTML_STOP) {
4678  cmd = "<span style=\"background-color: #FFFF00;font-weight: bold;\">AUTORUN FINISHED ...</span>";
4679  stream << cmd << endl;
4680  }
4681  }
4682 
4683  stream << " </pre>" << endl;
4684  stream << " </td></tr>" << endl;
4685  stream << " </table>" << endl;
4686  stream << " </form>" << endl;
4687  stream << " </body>" << endl;
4688 
4689  // write HTML end tag
4690  stream << "</html>" << endl;
4691 
4692  file.close();
4693 }
4694 
4695 //**********************************************************************
4696 // FeedLiveDataAutoRun
4697 //**********************************************************************
4702 {
4703  // delete /AutoRun/LiveData/AutoRun
4704  HNDLE hKey;
4705  INT status = db_find_key(fExp->GetHdb(), 0, "/AutoRun/LiveData/AutoRun", &hKey);
4706  if (status == DB_SUCCESS) { // key found, hence delete it
4707  status = db_delete_key(fExp->GetHdb(), hKey, TRUE);
4708  }
4709 
4710  // get input file name from the current lar-file
4711  QString pathFln = fAutoRunPath + GetAutoRunSequence();
4712 
4713  // read current lar-file
4714  QFile f(pathFln);
4715  QTextStream fstream(&f);
4716  QString line;
4717  QVector<QString> data;
4718  if (f.exists()) {
4719  f.open(QIODevice::ReadOnly);
4720  while (!fstream.atEnd()) {
4721  line = fstream.readLine();
4722  data.push_back(line);
4723  }
4724  f.close();
4725  }
4726 
4727  // create /AutoRun/LiveData/AutoRun from the current lar-file
4728  char str[128];
4729  for (int i=0; i<data.size(); i++) {
4730  memset(str, 0, sizeof(str));
4731  strncpy(str, data[i].toLatin1(), sizeof(str));
4732  status = db_set_value_index(fExp->GetHdb(), 0, "/AutoRun/LiveData/AutoRun", str, sizeof(str), i, TID_STRING, FALSE);
4733  }
4734 }
4735 
4736 //**********************************************************************
4737 // ExecAutoRun
4738 //**********************************************************************
4743 {
4744  PAutoRunCmdVector::Iterator iter;
4745  int size;
4746  bool stopped;
4747  bool aborted = false;
4748  int maxCount = 0;
4749 
4750  // paranoia check to make sure that there are really autorun commands present
4751  if (fAutoRunCmdVector->size() == 0) {
4752  QString msg("**FATAL ERROR** no autorun commands present!!");
4753  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_FATAL, 0, msg);
4754  emit ErrorMsg(1, 0, LAR_FATAL, 0, msg);
4755  return;
4756  }
4757 
4758  // check that the magnet parameters are within range
4759  QString err("");
4760  int pos = CheckFieldCmd(err);
4761  if (pos != -1) {
4762  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_PARSE_ERROR, pos, err);
4763  emit ErrorMsg(1, 0, LAR_FATAL, 0, err);
4764  return;
4765  }
4766 
4767  // check for a warmup command
4769 
4770  // check if ODB_SET_DATA commands are present and if yes, check if the ODB path etc make sense
4772 
4773  // check if a TRANSPORT_HV <fln> command is present, and if yes, check if <fln> exists and is loadable
4774  if (!CheckForTransportHvCmd())
4775  return;
4776 
4777  // check if there is a setTemp command and if yes, set the sample LS340 ZONE settings
4778  // (in case somebody was fooling around with the LS340 sample, this will fix it)
4780 
4781  // autorun command counters
4783  // remove all the comments from the total number of autorun commands
4784  iter = fAutoRunCmdVector->begin();
4785  do {
4786  if (iter->cmd == "comment")
4787  fNoOfAutoRunCmds--;
4788  if (iter->lineNo > maxCount) // get the largest line number
4789  maxCount = iter->lineNo;
4790  iter++;
4791  } while (iter != fAutoRunCmdVector->end());
4792  fCurrentAutoRunCmd = 1;
4793 
4794  // key to set the transition tag
4795  PKey transTagKey(fExp, "/AutoRun/LiveData/TransitionTag");
4796  if (!transTagKey.IsValid()) {
4797  QString msg("**FATAL ERROR** cannot get necessary key /AutoRun/LiveData/TransitionTag!");
4798  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_FATAL, 0, msg);
4799  emit ErrorMsg(1, 0, LAR_FATAL, 0, msg);
4800  return;
4801  }
4802  int ival=LAR_TT_IDLE;
4803  transTagKey.SetData((void*)&ival, 1, TID_INT);
4804 
4805  // check if only load is wanted
4806  int runState = GetRunState();
4807  if ((runState == LAR_STATE_LOAD) || (runState == LAR_STATE_LOADING)) {
4808  // set autorun state to stopped
4810 
4811  QString msg("Loading Sequence ...");
4812  UpdateStatusMsg(msg);
4813 
4814  iter = fAutoRunCmdVector->begin();
4815  UpdateWebPage(iter, HTML_LOAD);
4816 
4817  return;
4818  }
4819 
4820  // check if there is already an ongoing run before entering the main loop
4821  // runningWhenStarting is needed to check the following:
4822  // run already underway when autorun is starting. If yes, make sure that the first
4823  // real command is a STOP and nothing else.
4824  bool runningWhenStarting = false;
4825  // get current runinfo state
4826  size = sizeof(fRunInfo);
4827  fRunInfoKey->GetRecord((void *)&fRunInfo, &size);
4829  runningWhenStarting = true;
4830 
4831  // key to the live data line number
4832  PKey lineNoKey(fExp, "/AutoRun/LiveData/CurrentLineNo");
4833  if (!lineNoKey.IsValid()) {
4834  QString msg("**FATAL ERROR** cannot get necessary key /AutoRun/LiveData/CurrentLineNo!");
4835  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_FATAL, 0, msg);
4836  emit ErrorMsg(1, 0, LAR_FATAL, 0, msg);
4837  return;
4838  }
4839  // key to the live data loop value
4840  PKey loopValKey(fExp, "/AutoRun/LiveData/LoopVal");
4841  if (!loopValKey.IsValid()) {
4842  QString msg("**FATAL ERROR** cannot get necessary key /AutoRun/LiveData/LoopVal!");
4843  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_FATAL, 0, msg);
4844  emit ErrorMsg(1, 0, LAR_FATAL, 0, msg);
4845  return;
4846  }
4847 
4848  // loop over all commands
4849  iter = fAutoRunCmdVector->begin();
4850  do {
4851  // set current line number for the live data
4852  lineNoKey.SetData(&(iter->lineNo), 1, TID_INT);
4853 
4854  // set potential loop value
4855  char loopValStr[32];
4856  memset(loopValStr, 0, sizeof(loopValStr));
4857  if (iter->loopVal.isEmpty())
4858  strncpy(loopValStr, "empty", sizeof(loopValStr));
4859  else
4860  strncpy(loopValStr, iter->loopVal.toLatin1().data(), sizeof(loopValStr));
4861  loopValKey.SetData(loopValStr, 1, TID_STRING);
4862 
4863  // get current runinfo state
4864  size = sizeof(fRunInfo);
4865  fRunInfoKey->GetRecord((void *)&fRunInfo, &size);
4866 
4867  // check if somebody was starting an autorun while a run is already underway
4868  if (((fRunInfo.state == RUN_RUNNING) || (fRunInfo.state == RUN_PAUSED)) && runningWhenStarting &&
4869  !((iter->cmd == "setWait") || (iter->cmd == "runStop") ||
4870  (iter->cmd == "warmUp") || (iter->cmd == "alias") || (iter->cmd == "comment") ||
4871  (iter->cmd == "odbTag"))) {
4872  UpdateWebPage(iter, HTML_STRANGE);
4873  } else {
4874  UpdateWebPage(iter, HTML_RUNNING);
4875  }
4876 
4877  // handle alias, odbTag and comment independently of the run state
4878  if ((iter->cmd == "alias") || (iter->cmd == "odbTag") || (iter->cmd == "comment")) {
4879  iter++;
4880  if (iter == fAutoRunCmdVector->end())
4881  break;
4882  if ((iter->cmd == "alias") || (iter->cmd == "odbTag"))
4884  UpdateWebPage(iter, HTML_RUNNING);
4885  continue;
4886  }
4887 
4888  // handle run stop command
4889  if (((fRunInfo.state == RUN_RUNNING) || (fRunInfo.state == RUN_PAUSED)) &&
4890  (iter->cmd == "runStop") && fRunStopped) {
4891  UpdateWebPage(iter, HTML_RUNNING);
4892  RunStop(iter);
4893  } else if ((fRunInfo.state == RUN_STOPPED) && (iter->cmd == "runStop")) { // i.e. run stop and STOP cmd pending: this doesn't make any sense
4894  QString err("STOP cmd for a stopped run doesn't make any sense. Will change the STOP to a START cmd!");
4895  emit ErrorMsg(1, 0, LAR_STOP_STOP_NONSENSE, -1, err);
4896  iter->cmd = "runStart";
4897  iter->cmdString = "START " + iter->param[0];
4898  if (iter->noElements == 2) {
4899  iter->cmdString += " sec";
4900  }
4901  }
4902 
4903  // check if a run needs to be stopped
4904  stopped = RunStopCheck();
4905  if (stopped) {
4906  runningWhenStarting = false;
4907  iter++;
4908  if (iter == fAutoRunCmdVector->end())
4909  break;
4910  }
4911 
4912  runState = GetRunState();
4913  if (runState == LAR_STATE_STOPPED) {
4914  UpdateWebPage(iter, HTML_ABORTED);
4915  aborted = true;
4916  continue;
4917  }
4918 
4919  // do next command only if run is stopped, TD rate HV trip didn't fire, and autorun not paused
4920  runState = GetRunState();
4921  if ((fRunInfo.state == RUN_STOPPED) && !fHvTripFlag && (runState != LAR_STATE_PAUSED)) {
4922  runningWhenStarting = false;
4923 
4924  // check for goto command
4925  if (GetGotoLine() > 0) {
4926  GotoLine(iter, maxCount);
4927  }
4928 
4929  UpdateWebPage(iter, HTML_RUNNING);
4930  // filter the command and execute it
4931  if (iter->cmd == "runStart") {
4932  RunStart(iter);
4933  } else if (iter->cmd == "degaussWEW") {
4934  DegaussWEW(iter);
4935  iter++;
4936  } else if (iter->cmd == "degaussDanfysik") {
4937  DegaussDanfysik(iter);
4938  iter++;
4939  } else if (iter->cmd == "degaussMagnet") {
4940  Degauss(iter);
4941  iter++;
4942  } else if (iter->cmd == "degaussSpinRot") {
4943  DegaussSpinRot(iter);
4944  iter++;
4945  } else if (iter->cmd == "ignore_alarms") {
4946  SetIgnoreAlarms(iter);
4947  iter++;
4948  } else if (iter->cmd == "ignore_clients") {
4949  SetIgnoreClients(iter);
4950  iter++;
4951  } else if (iter->cmd == "setBPV") {
4952  SetBPV(iter);
4953  iter++;
4954  } else if (iter->cmd == "setDump") {
4955  SetDump(iter);
4956  iter++;
4957  } else if (iter->cmd == "setFOM") {
4958  SetFOM(iter);
4959  iter++;
4960  } else if (iter->cmd == "setFieldWEWL") {
4961  SetFieldWEWL(iter);
4962  iter++;
4963  } else if (iter->cmd == "setFieldWEWH") {
4964  SetFieldWEWH(iter);
4965  iter++;
4966  } else if (iter->cmd == "setFieldDanfysik") {
4967  SetFieldDanfysik(iter);
4968  iter++;
4969  } else if (iter->cmd == "setField") {
4970  SetField(iter);
4971  iter++;
4972  } else if (iter->cmd == "setSpinRot") {
4973  SetSpinRot(iter);
4974  iter++;
4975  } else if (iter->cmd == "setLEMSetup") {
4976  SetLEMSetup(iter);
4977  iter++;
4978  } else if (iter->cmd == "setModInfo") {
4979  SetModInfo(iter);
4980  iter++;
4981  } else if (iter->cmd == "setOdbData") {
4982  SetOdbData(iter);
4983  iter++;
4984  } else if (iter->cmd == "setOdbDataArray") {
4985  SetOdbDataArray(iter);
4986  iter++;
4987  } else if (iter->cmd == "setSampleHV") {
4988  SetSampleHV(iter);
4989  iter++;
4990  } else if (iter->cmd == "setRA_HV") {
4991  SetRA_HV(iter);
4992  iter++;
4993  } else if (iter->cmd == "setTransportHV") {
4994  SetTransportHV(iter);
4995  iter++;
4996  } else if (iter->cmd == "setHVOff") {
4997  SetHvOff(iter);
4998  iter++;
4999  } else if (iter->cmd == "setTfl") {
5000  SetTfl(iter);
5001  iter++;
5002  } else if (iter->cmd == "setTemp") {
5003  SetTemp(iter);
5004  iter++;
5005  } else if (iter->cmd == "setTitle") {
5006  SetTitle(iter);
5007  iter++;
5008  } else if (iter->cmd == "setTOF") {
5009  SetTof(iter);
5010  iter++;
5011  } else if (iter->cmd == "setWait") {
5012  SetWait(iter);
5013  iter++;
5014  } else if (iter->cmd == "warmUp") { // already taken care of, just increment iterator
5015  iter++;
5017  }
5018  fAutoRunCurrentIter = iter;
5019  }
5020 
5021  // feed midas watchdog
5022  fExp->FeedMidasWatchdog();
5023 
5024  // check temperature stability
5027  else
5029 
5030  // see whether the raw voltage should be dumped to file
5031  if (fDumpInUse) {
5032  if (fDumpCounter > 0) {
5033  RawVoltageDump();
5034  } else {
5035  fDumpFile.close();
5036  fDumpInUse = false;
5037  }
5038  }
5039 
5040  if (fSampleCryoInUse == CRYO_KONTI) {
5041  // adjust flow
5044  }
5045  }
5046 
5047  // check alarm system
5048  CheckMidasAlarms(iter);
5049 
5050  // sleep for 5 sec before proceeding to keep the system happy
5051  Wait(5000);
5052 
5053  // check if the warmup command needs to be executed
5054  if (fWarmUpWished && (QDateTime::currentDateTime() > fWarmUpDateTime)) {
5055  fWarmUpWished = false;
5056  WarmUp(iter);
5057  break;
5058  }
5059 
5060  } while ((iter != fAutoRunCmdVector->end()) && !aborted);
5061 
5062  if (!aborted) {
5063  // auto run finished before warm up timer kicked in, therefore warm up now
5064  if (fWarmUpWished) {
5065  int ival = LAR_TT_WARMUP;
5066  transTagKey.SetData((void*)&ival, 1, TID_INT);
5067  WarmUp(iter);
5068  }
5069  int ival = LAR_TT_FINISHED;
5070  transTagKey.SetData((void*)&ival, 1, TID_INT);
5071 
5072  // increment CurrentLineNo so that nothing is 'active' anymore on the web-page
5073  int size = sizeof(ival);
5074  lineNoKey.GetData((void*)&ival, &size, TID_INT);
5075  ival += 1;
5076  lineNoKey.SetData((void*)&ival, 1, TID_INT);
5077 
5078  // update status
5079  QString msg = QString("Autorun finished.");
5080  emit StatusMsg(msg);
5081 
5083  Wait(5000);
5084 
5085  // handle autoRunState
5086  PKey nextAutoRun(fExp, "/AutoRun/Next");
5087  if (nextAutoRun.IsValid()) {
5088  char next[64];
5089  int size = sizeof(next);
5090  nextAutoRun.GetData(next, &size, TID_STRING);
5091  int runState = LAR_STATE_NEXT;
5092  if (!strcmp(next, "none")) { // set autoRunState to stopped
5093  runState = LAR_STATE_STOPPED;
5094  }
5095  UpdateRunState(runState);
5096  }
5097  } else { // aborted
5098  int ival = LAR_TT_ABORTED;
5099  transTagKey.SetData((void*)&ival, 1, TID_INT);
5100  }
5101 }
5102 
5103 //**********************************************************************
5104 // RunStart
5105 //**********************************************************************
5112 {
5113  // param: [0] events/time, [[1] "sec"]
5114 
5115  int status, size;
5116  QString msg, err;
5117 
5118  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5119  msg += arc->cmdString;
5120 
5121  if (arc->noElements == 1) {
5122  fRunCheckEvents = true;
5123  } else {
5124  fRunCheckEvents = false;
5125  fRunTimeout = arc->param[0].toFloat();
5126  }
5127  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5128 
5129  // check if the vme frontend and analyzer are enabled
5130  if (!fEnabled["vme_fe"] || !fEnabled["analyzer_fe"]) {
5131  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5132  QString err = msg + QString("PLemAutoRun::RunStart(): VME_FE(%1) and/or Analyzer(%2) not enabled. Do nothing here.").arg(fEnabled["vme_fe"]).arg(fEnabled["analyzer_fe"]);
5133  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
5135  return;
5136  }
5137 
5138  // check if frontend and analyzer are running
5139  CheckClients();
5140  if (!fFrontendRunning || !fAnalyzerRunning) { // frontend or analyzer NOT running
5141  err = QString("PLemAutoRun::RunStart: ");
5142  if (!fFrontendRunning)
5143  err += QString(" %1 ").arg(fFrontendName);
5144  if (!fAnalyzerRunning)
5145  err += QString(" %1 ").arg(fAnalyzerName);
5146  err += QString("not running, will stop! Fix it first ;-)");
5148  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5150  QCoreApplication::exit(0);
5151  exit(0);
5152  }
5153 
5154  if (fEnabled["lemvac_scfe"]) { // only check BPVX/Y if LEMVAC is enableds
5155  // check the BPVX/Y state
5156  GetBPV(); // get the current state of the BPVX/Y
5157  if (fLemVacValveInitialState[BPVX] == BPV_STATE_CLOSED) { // BPVX closed
5158  err = QString("PLemAutoRun::RunStart: BPVX still closed! Check also sample regions HV's");
5159  emit ErrorMsg(1, 0, LAR_BPV_CLOSED_AT_RUN_START, -1, err);
5160  }
5161  if (fLemVacValveInitialState[BPVY] == BPV_STATE_CLOSED) { // BPVY closed
5162  err = QString("PLemAutoRun::RunStart: BPVY still closed! Check also sample regions HV's");
5163  emit ErrorMsg(1, 0, LAR_BPV_CLOSED_AT_RUN_START, -1, err);
5164  }
5165  }
5166 
5167  if (fEnabled["fug_eq"]) { // only check FUG's if enabled
5168  // check if RA HV's are set for Bpar, and for Bperp < 130G
5169  float fval;
5170  if (fFieldPwrSupply == "danfysik") { // Bpar
5171  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
5172  size = sizeof(fval);
5173  fHVDemandKey->GetDataIndex(&fval, &size, i, TID_FLOAT);
5174  if (fval < 0.2) {
5175  err = QString("PLemAutoRun::RunStart: RA HV's < 0.2kV! Unlikely to be correct, please check!");
5176  emit ErrorMsg(1, 0, LAR_RA_HV_OFF_AT_RUN_START, -1, err);
5177  break;
5178  }
5179  }
5180  } else if (fFieldPwrSupply == "wew") { // Bperp
5181  if (fEnabled["wew_eq"]) { // only deal with WEW if equipment is enabled
5182  // get WEW input record
5183  float wew_input[11];
5184  size = sizeof(wew_input);
5185  fWEWInputKey->GetData(&wew_input, &size, TID_FLOAT);
5186 
5187  // find out if WEWL or WEWH is in use
5188  int current_idx;
5189  if (wew_input[WEWL_INPUT_STATUS] == 1.0) {
5190  current_idx = WEWL_INPUT_CURRENT;
5191  } else {
5192  current_idx = WEWH_INPUT_CURRENT;
5193  }
5194 
5195  // get the WEW current
5196  size = sizeof(fval);
5197  fWEWInputKey->GetDataIndex(&fval, &size, current_idx, TID_FLOAT);
5198  if (fval <= fWEWCriticalCurrentRA) {
5199  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
5200  size = sizeof(fval);
5201  fHVDemandKey->GetDataIndex(&fval, &size, i, TID_FLOAT);
5202  if (fval < 0.2) {
5203  err = QString("PLemAutoRun::RunStart: RA HV's < 0.2kV! Unlikely to be correct, please check!");
5204  emit ErrorMsg(1, 0, LAR_RA_HV_OFF_AT_RUN_START, -1, err);
5205  break;
5206  }
5207  }
5208  }
5209  }
5210  }
5211  }
5212 
5213  // keep the number of trigger events needed to complete a run
5214  fRunNoEventsNeeded = arc->param[0].toInt();
5215 
5216  // start run
5217  fRunInfo.run_number++;
5218  status = cm_transition(TR_START, fRunInfo.run_number, NULL, 0, TR_SYNC, FALSE);
5219  if (status != CM_SUCCESS) { // error
5221  err = QString("PLemAutoRun::RunStart: Cannot start the run.");
5222  emit ErrorMsg(1, 0, LAR_MIDAS_CANNOT_START_RUN, -1, err);
5223  }
5224 
5225  // check that the run really started
5226  QTime t;
5227  t.start();
5228  size = sizeof(fRunInfo);
5229  do {
5230  if (fDebug)
5231  cout << endl << "RunStart: Runinfo.state = " << fRunInfo.state;
5232  fRunInfoKey->GetRecord((void *)&fRunInfo, &size);
5233  Wait(2000);
5234  if (t.elapsed() > 60e3) {
5235  err = QString("PLemAutoRun::RunStart: Didn't get run transition after run started.");
5237  emit ErrorMsg(1, 0, LAR_MIDAS_NO_RUN_TRANSITION, -1, err);
5238  break;
5239  }
5240  } while (fRunInfo.state != RUN_RUNNING);
5241 
5242  // run is on the way
5243  fRunStopped = false;
5244 
5245  // time stamp run start
5246  fRunStarted.start();
5247 
5248  // increment command counter
5250 
5251  // update status
5252  msg = QString("Autorun running: ") + msg;
5253  emit StatusMsg(msg);
5254 }
5255 
5256 //**********************************************************************
5257 // RunStop
5258 //**********************************************************************
5263 {
5264  // param: [0] events/time, [[1] "sec"]
5265 
5266  QString msg, err;
5267 
5268  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5269  msg += arc->cmdString;
5270 
5271  if (arc->noElements == 1) {
5272  fRunCheckEvents = true;
5273  } else {
5274  fRunCheckEvents = false;
5275  fRunTimeout = arc->param[0].toFloat();
5276  }
5277  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5278 
5279  // check if the vme frontend and analyzer are enabled
5280  if (!fEnabled["vme_fe"] || !fEnabled["analyzer_fe"]) {
5281  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5282  QString err = msg + QString("PLemAutoRun::RunStop(): VME_FE(%1) and/or Analyzer(%2) not enabled. Do nothing here.").arg(fEnabled["vme_fe"]).arg(fEnabled["analyzer_fe"]);
5283  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
5285  return;
5286  }
5287 
5288  // check if frontend and analyzer are running
5289  CheckClients();
5290  if (!fFrontendRunning || !fAnalyzerRunning) { // frontend or analyzer NOT running
5292  QString err = QString("PLemAutoRun::RunStop: ");
5293  if (!fFrontendRunning)
5294  err += QString(" %1 ").arg(fFrontendName);
5295  if (!fAnalyzerRunning)
5296  err += QString(" %1 ").arg(fAnalyzerName);
5297  err += QString("not running, will stop! Fix it first ;-)");
5299  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5301  QCoreApplication::exit(0);
5302  exit(0);
5303  }
5304 
5305  // keep the number of trigger events needed to complete a run
5306  fRunNoEventsNeeded = arc->param[0].toInt();
5307 
5308  // run is on the way
5309  fRunStopped = false;
5310 
5311  // time stamp run start
5312  fRunStarted.start();
5313 
5314  // increment command counter
5316 }
5317 
5318 //**********************************************************************
5319 // RunStopCheck
5320 //**********************************************************************
5326 {
5327  int status, size;
5328  double value;
5329  QString err;
5330  bool stopped = false;
5331 
5332  // update Runinfo structure
5333  size = sizeof(fRunInfo);
5334  fRunInfoKey->GetRecord((void *)&fRunInfo, &size);
5335 
5336  // check only if Run is active 10sec after run start to allow the Trigger statistics to
5337  // the get the right Event stats
5338  if ((fRunInfo.state == RUN_RUNNING) && (fRunStarted.elapsed() > 10000)) {
5339  // check if frontend and analyzer are running
5340  CheckClients();
5341  if (!fFrontendRunning || !fAnalyzerRunning) { // frontend or analyzer NOT running
5343  QString err = QString("PLemAutoRun::RunStopCheck: ");
5344  if (!fFrontendRunning)
5345  err += QString(" %1 ").arg(fFrontendName);
5346  if (!fAnalyzerRunning)
5347  err += QString(" %1 ").arg(fAnalyzerName);
5348  err += QString("not running, will stop! Fix it first ;-)");
5349  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5351  QCoreApplication::exit(0);
5352  exit(0);
5353  }
5354 
5355  if (fRunCheckEvents) { // check if number of events criteria or time shall be used
5356  // get no of events
5357  size = sizeof(value);
5358  status = fTriggerEventsKey->GetData(&value, &size, TID_DOUBLE);
5359  if (status != DB_SUCCESS) { // error
5361  err = "PLemAutoRun::RunStopCheck: Couldn't get current number of events";
5362  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
5363  }
5364  // check if enough events to stop the current run
5365  if ((value >= fRunNoEventsNeeded) && !fRunStopped) { // run can be stopped if not already done so
5366  // stop run
5367  status = cm_transition(TR_STOP, fRunInfo.run_number, NULL, 0, TR_SYNC, FALSE);
5368  if (status != CM_SUCCESS) { // error
5370  err = QString("PLemAutoRun::RunStart: Cannot stop the run.");
5371  emit StatusMsg(err);
5372  emit ErrorMsg(1, 0, LAR_MIDAS_CANNOT_START_RUN, -1, err);
5373  }
5374  err = QString("Autorun running: run stopped.");
5375  emit StatusMsg(err);
5376  err = QString(">> End of run; read=%1 of requested = %2").arg(value).arg(fRunNoEventsNeeded);
5377  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
5378  fRunNoEventsNeeded = 0;
5379  fRunStopped = true;
5380  stopped = true;
5381  }
5382  } else { // check if the time elapsed passed the timing criterium
5383  if ((fRunStarted.elapsed() > (int)(1e3*fRunTimeout)) && !fRunStopped) { // stop the run
5384  // stop run
5385  status = cm_transition(TR_STOP, fRunInfo.run_number, NULL, 0, TR_SYNC, FALSE);
5386  if (status != CM_SUCCESS) { // error
5388  err = QString("PLemAutoRun::RunStart: Cannot stop the run.");
5389  emit StatusMsg(err);
5390  emit ErrorMsg(1, 0, LAR_MIDAS_CANNOT_START_RUN, -1, err);
5391  }
5392  err = QString("Autorun running: run stopped.");
5393  emit StatusMsg(err);
5394  err = QString(">> End of run; read=%1 of requested = %2").arg(value).arg(fRunNoEventsNeeded);
5395  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
5396  fRunNoEventsNeeded = 0;
5397  fRunStopped = true;
5398  stopped = true;
5399  }
5400  }
5401  }
5402 
5403  // check if run was stopped manually
5404  if ((fRunInfo.state == RUN_STOPPED) && (fRunStarted.elapsed() > 10000) && !fRunStopped) {
5405  fRunStopped = true;
5406  stopped = true;
5407  }
5408 
5409  return stopped;
5410 }
5411 
5412 //**********************************************************************
5413 // CheckFieldCmd
5414 //**********************************************************************
5419 int PLemAutoRun::CheckFieldCmd(QString &errMsg)
5420 {
5421  if (!fEnabled["mag_param_wew_odb"] || !fEnabled["mag_param_bpar_odb"])
5422  return -1;
5423 
5424  float fval, maxField;
5425  for (int i=0; i<fAutoRunCmdVector->size(); i++) {
5426  if (fAutoRunCmdVector->at(i).cmd == "setFieldWEWL") {
5427  fval = fAutoRunCmdVector->at(i).param[0].toFloat(); // field/current value
5428  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5429  if (fabs(fval) > fWEWLMaxCurrent) { // out of range current
5430  errMsg = QString("PLemAutoRun::CheckFieldCmd: WEWL current out of range (%1 A > %2 A) in line %3").arg(fval).arg(fWEWLMaxCurrent).arg(fAutoRunCmdVector->at(i).lineNo);
5431  emit StatusMsg(errMsg);
5432  return i;
5433  }
5434  } else { // value in Gauss
5435  maxField = fMagParamWew[0] + fMagParamWew[1] * fWEWLMaxCurrent;
5436  if (fabs(fval) > maxField) { // out of range field
5437  errMsg = QString("PLemAutoRun::CheckFieldCmd: WEW field out of range (%1 G > %2 G) in line %3").arg(fval).arg(maxField).arg(fAutoRunCmdVector->at(i).lineNo);
5438  emit StatusMsg(errMsg);
5439  return i;
5440  }
5441  }
5442  } else if (fAutoRunCmdVector->at(i).cmd == "setFieldWEWH") {
5443  fval = fAutoRunCmdVector->at(i).param[0].toFloat(); // field/current value
5444  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5445  if (fabs(fval) > fWEWHMaxCurrent) { // out of range current
5446  errMsg = QString("PLemAutoRun::CheckFieldCmd: WEWH current out of range (%1 A > %2 A) in line %3").arg(fval).arg(fWEWHMaxCurrent).arg(fAutoRunCmdVector->at(i).lineNo);
5447  emit StatusMsg(errMsg);
5448  return i;
5449  }
5450  } else { // value in Gauss
5451  maxField = fMagParamWew[0] + fMagParamWew[1] * fWEWHMaxCurrent;
5452  if (fabs(fval) > maxField) { // out of range field
5453  errMsg = QString("PLemAutoRun::CheckFieldCmd: WEW field out of range (%1 G > %2 G) in line %3").arg(fval).arg(maxField).arg(fAutoRunCmdVector->at(i).lineNo);
5454  emit StatusMsg(errMsg);
5455  return i;
5456  }
5457  }
5458  } else if (fAutoRunCmdVector->at(i).cmd == "setFieldDanfysik") {
5459  fval = fAutoRunCmdVector->at(i).param[0].toFloat(); // field/current value
5460  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5461  if (fabs(fval) > fDanfysikMaxCurrent) { // out of range current
5462  errMsg = QString("PLemAutoRun::CheckFieldCmd: Bpar current out of range (%1 A > %2 A) in line %3").arg(fval).arg(fDanfysikMaxCurrent).arg(fAutoRunCmdVector->at(i).lineNo);
5463  emit StatusMsg(errMsg);
5464  return i;
5465  }
5466  } else { // value in Gauss
5467  maxField = fMagParamBpar[0] + fMagParamBpar[1] * fDanfysikMaxCurrent;
5468  if (fabs(fval) > maxField) { // out of range field
5469  errMsg = QString("PLemAutoRun::CheckFieldCmd: Bpar field out of range (%1 G > %2 G) in line %3").arg(fval).arg(maxField).arg(fAutoRunCmdVector->at(i).lineNo);
5470  emit StatusMsg(errMsg);
5471  return i;
5472  }
5473  }
5474  } else if (fAutoRunCmdVector->at(i).cmd == "setField") {
5475  fval = fAutoRunCmdVector->at(i).param[0].toFloat(); // field/current value
5476  if (fSetupWewEnabled) {
5477  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5478  if (fabs(fval) > fWEWHMaxCurrent) { // out of range current
5479  errMsg = QString("PLemAutoRun::CheckFieldCmd: WEW current out of range (%1 A > %2 A) in line %3").arg(fval).arg(fWEWHMaxCurrent).arg(fAutoRunCmdVector->at(i).lineNo);
5480  emit StatusMsg(errMsg);
5481  return i;
5482  }
5483  } else { // value in Gauss
5484  maxField = fMagParamWew[0] + fMagParamWew[1] * fWEWHMaxCurrent;
5485  if (fabs(fval) > maxField) { // out of range field
5486  errMsg = QString("PLemAutoRun::CheckFieldCmd: WEW field out of range (%1 G > %2 G) in line %3").arg(fval).arg(maxField).arg(fAutoRunCmdVector->at(i).lineNo);
5487  emit StatusMsg(errMsg);
5488  return i;
5489  }
5490  }
5491  } else { // Bpar
5492  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5493  if (fabs(fval) > fDanfysikMaxCurrent) { // out of range current
5494  errMsg = QString("PLemAutoRun::CheckFieldCmd: Bpar current out of range (%1 A > %2 A) in line %3").arg(fval).arg(fDanfysikMaxCurrent).arg(fAutoRunCmdVector->at(i).lineNo);
5495  emit StatusMsg(errMsg);
5496  return i;
5497  }
5498  } else { // value in Gauss
5499  maxField = fMagParamBpar[0] + fMagParamBpar[1] * fDanfysikMaxCurrent;
5500  if (fabs(fval) > maxField) { // out of range field
5501  errMsg = QString("PLemAutoRun::CheckFieldCmd: Bpar field out of range (%1 G > %2 G) in line %3").arg(fval).arg(maxField).arg(fAutoRunCmdVector->at(i).lineNo);
5502  emit StatusMsg(errMsg);
5503  return i;
5504  }
5505  }
5506  }
5507  }
5508  }
5509 
5510  return -1;
5511 }
5512 
5513 //**********************************************************************
5514 // DegaussWEW
5515 //**********************************************************************
5526 {
5527  float hv[5], fval;
5528  float current_wewh[3] = {+600.0, -40.0, 0.0};
5529  float current_wewl[3] = {+50.0, -45.0, 0.0};
5530  int size;
5531  QString msg("");
5532 
5533  // check if FUG handling is disabled in lemAutoRun
5534  if (!fEnabled["fug_scfe"]) {
5535  msg = QString("(%1/%2) DEGAUSS_WEW: FUG disabled in lemAutoRun. Will do nothing here.").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5536  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5537  // increment command counter
5539  return;
5540  }
5541  // check of WEW equipment is disabled in lemAutoRun
5542  if (!fEnabled["wew_eq"]) {
5543  msg = QString("(%1/%2) DEGAUSS_WEW: WEW equipment disabled in lemAutoRun. Will do nothing here.").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5544  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5545  // increment command counter
5547  return;
5548  }
5549 
5550  // check if wew scfe is running
5551  CheckClients();
5552  if (!fWEWFeRunning) {
5554  QString err = QString("PLemAutoRun::DegaussWEW: WEW Slowcontrol Frontend NOT running. Error too severe, will stop.");
5555  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5557  QCoreApplication::exit(0);
5558  exit(0);
5559  }
5560 
5561  msg = QString("(%1/%2) DEGAUSS_WEW").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5562  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5563 
5564  msg = QString("Autorun running: ") + msg;
5565  emit StatusMsg(msg);
5566 
5567  // get current RA HV values
5568  // get RAL
5569  size = sizeof(fval);
5570  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_RAL, TID_FLOAT);
5571  hv[0] = fval;
5572  // get RAT
5573  size = sizeof(fval);
5574  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_RAT, TID_FLOAT);
5575  hv[1] = fval;
5576  // get RAR
5577  size = sizeof(fval);
5578  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_RAR, TID_FLOAT);
5579  hv[2] = fval;
5580  // get RAB
5581  size = sizeof(fval);
5582  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_RAB, TID_FLOAT);
5583  hv[3] = fval;
5584  // get SampleHV
5585  size = sizeof(fval);
5586  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_SAMPLE, TID_FLOAT);
5587  hv[4] = fval;
5588 
5589  // set RA HV values to zero
5590  fval = 0.0;
5591  fHVDemandKey->SetDataIndex(&fval, HV_FUG_RAL, TID_FLOAT);
5592  fHVDemandKey->SetDataIndex(&fval, HV_FUG_RAT, TID_FLOAT);
5593  fHVDemandKey->SetDataIndex(&fval, HV_FUG_RAR, TID_FLOAT);
5594  fHVDemandKey->SetDataIndex(&fval, HV_FUG_RAB, TID_FLOAT);
5595  fHVDemandKey->SetDataIndex(&fval, HV_FUG_SAMPLE, TID_FLOAT);
5596 
5597  // message to midas
5598  cm_msg(MINFO, "lemAutoRun", "DegaussWEW: RA HV down. Will wait 5 sec to settle things.");
5599  cm_yield(0);
5600 
5601  Wait(5000); // wait 5 sec
5602 
5603  // do the degaussing procedure which is the following current cycle:
5604  // 1) set WEWL/H demand current to zero
5605  // 2) switch off WEWL
5606  // 3) unlock WEW/SSP
5607  // 4) WEWH: 600A -> -40A -> 0
5608  // 5) WEWL: 50A -> -45A -> 0
5609  // 6) lock WEW/SSP
5610  // -------------------------------------------------
5611  // 1) set WEWL/H demand current to zero
5612  fval = 0.0;
5613  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CURRENT, TID_FLOAT);
5614  fval = 0.0;
5615  fWEWOutputKey->SetDataIndex(&fval, WEWH_OUTPUT_CURRENT, TID_FLOAT);
5616  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: set WEWL/H demand current to zero");
5617  cm_yield(0); // make the watchdog happy
5618  Wait(2000); // wait 2 sec
5619 
5620  // 2) switch off WEWL
5621  fval = 0.0;
5622  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CMD, TID_FLOAT);
5623  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: switch off WEWL");
5624  cm_yield(0); // make the watchdog happy
5625  Wait(2000); // wait 2 sec
5626 
5627  // 3) unlock WEW/SSP
5628  fval = 0.0;
5629  fWEWOutputKey->SetDataIndex(&fval, WEW_SSP_LOCK, TID_FLOAT);
5630  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: unlock WEW/SSP");
5631  cm_yield(0); // make the watchdog happy
5632  Wait(2000); // wait 2 sec
5633 
5634  // 4) WEWH: 600A -> -40A -> 0
5635  fval = 1.0;
5636  fWEWOutputKey->SetDataIndex(&fval, WEWH_OUTPUT_CMD, TID_FLOAT);
5637  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: switch on WEWH");
5638  cm_yield(0); // make the watchdog happy
5639  Wait(5000); // wait 5 sec
5640  for (unsigned int i=0; i<3; i++) {
5641  fval = current_wewh[i];
5642  fWEWOutputKey->SetDataIndex(&fval, WEWH_OUTPUT_CURRENT, TID_FLOAT);
5643  // message to midas
5644  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: set current %f A via WEWH.", fval);
5645  cm_yield(0); // make the watchdog happy
5646  // check that the field value is reached
5647  do {
5648  // wait a bit
5649  Wait(5000); // wait 5 sec
5650  size = sizeof(fval);
5651  fWEWInputKey->GetDataIndex(&fval, &size, WEWH_INPUT_CURRENT, TID_FLOAT);
5652  } while (fabs(fabs(fval)-fabs(current_wewh[i])) > 2.0); // 2A is needed for WEWH (zero is ~1.5)
5653  // keep the field for 15 sec
5654  Wait(15000);
5655  }
5656 
5657  // switch WEWH off and WEWL on
5658  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: switch WEWH off, WEWL on.");
5659  cm_yield(0); // make the watchdog happy
5660  fval = 0.0;
5661  fWEWOutputKey->SetDataIndex(&fval, WEWH_OUTPUT_CMD, TID_FLOAT);
5662  // check that WEWH is indeed switched off before proceeding
5663  QTime tt;
5664  tt.start();
5665  int timeDiff = 0;
5666  do {
5667  size = sizeof(fval);
5668  fWEWInputKey->GetDataIndex(&fval, &size, WEWH_INPUT_STATUS, TID_FLOAT);
5669  timeDiff = tt.elapsed();
5670  if (timeDiff % 500 < 50) // make sure cm_yield is called periodically to make the watchdog happy
5671  cm_yield(0); // make the watchdog happy
5672  } while ((fval != 0.0) && (timeDiff < 120000)); // wait no longer than 2 min
5673  if (timeDiff >= 120000) {
5675  QString err = QString("PLemAutoRun::DegaussWEW: Couldn't switch off WEWH - check. Error too severe, will stop.");
5676  emit ErrorMsg(1, 0, LAR_MIDAS_READBACK_FAILURE, -1, err);
5678  QCoreApplication::exit(0);
5679  exit(0);
5680  }
5681  // switch on WEWL
5682  Wait(2000); // wait 2 sec
5683  fval = 1.0;
5684  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CMD, TID_FLOAT);
5685  Wait(2000); // wait 2 sec
5686  // check that WEWL is indeed switched on before proceeding
5687  tt.start();
5688  timeDiff = 0;
5689  bool try_again = false;
5690  do {
5691  size = sizeof(fval);
5692  fWEWInputKey->GetDataIndex(&fval, &size, WEWL_INPUT_STATUS, TID_FLOAT);
5693  timeDiff = tt.elapsed();
5694  if (timeDiff % 500 < 50) // make sure cm_yield is called periodically to make the watchdog happy
5695  cm_yield(0); // make the watchdog happy
5696  if ((timeDiff >= 60000) && !try_again) {
5697  try_again = true;
5698  // will try to switch on WEWL once more. For this it needs to be switched off first (DD needs a change)
5699  // before it can switched on again.
5700  // switch off WEWL
5701  fval = 0.0;
5702  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CMD, TID_FLOAT);
5703  Wait(2000);
5704  // switch on WEWL
5705  fval = 1.0;
5706  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CMD, TID_FLOAT);
5707  cm_msg(MINFO, "lemAutoRun", "DegaussWEW: couldn't switch on the WEWL yet, will try again.");
5708  }
5709  } while ((fval != 1.0) && (timeDiff < 120000)); // wait no longer than 2 min
5710  if (timeDiff >= 120000) {
5712  QString err = QString("PLemAutoRun::DegaussWEW: Couldn't switch on WEWL - check. Error too severe, will stop.");
5713  emit ErrorMsg(1, 0, LAR_MIDAS_READBACK_FAILURE, -1, err);
5715  QCoreApplication::exit(0);
5716  exit(0);
5717  }
5718 
5719  // 5) WEWL: 50A -> -45A -> 0
5720  for (unsigned int i=0; i<3; i++) {
5721  fval = current_wewl[i];
5722  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CURRENT, TID_FLOAT);
5723  // message to midas
5724  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: set current %f A via WEWL.", fval);
5725  cm_yield(0); // make the watchdog happy
5726  // check that the field value is reached
5727  do {
5728  // wait a bit
5729  Wait(2000); // wait 2 sec
5730  size = sizeof(fval);
5731  fWEWInputKey->GetDataIndex(&fval, &size, WEWL_INPUT_CURRENT, TID_FLOAT);
5732  } while (fabs(fabs(fval)-fabs(current_wewl[i])) > 0.2);
5733  // keep the field for 15 sec
5734  Wait(15000);
5735  }
5736 
5737  // 6) lock WEW/SSP
5738  fval = 1.0;
5739  fWEWOutputKey->SetDataIndex(&fval, WEW_SSP_LOCK, TID_FLOAT);
5740  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: lock WEW/SSP");
5741  cm_yield(0); // make the watchdog happy
5742  Wait(2000); // wait 2 sec
5743 
5744  cm_msg(MINFO, "lemAutoRun", "DegaussWEW: ramping back RA HV's.");
5745  cm_yield(0);
5746 
5747  // ramp the RA HV's back
5748  fHVDemandKey->SetDataIndex(&hv[0], HV_FUG_RAL, TID_FLOAT);
5749  fHVDemandKey->SetDataIndex(&hv[1], HV_FUG_RAT, TID_FLOAT);
5750  fHVDemandKey->SetDataIndex(&hv[2], HV_FUG_RAR, TID_FLOAT);
5751  fHVDemandKey->SetDataIndex(&hv[3], HV_FUG_RAB, TID_FLOAT);
5752  fHVDemandKey->SetDataIndex(&hv[4], HV_FUG_SAMPLE, TID_FLOAT);
5753 
5754  if (fFugHvCheck) {
5755  // check that the RA HV's are back to its previous values
5756  int done = 0;
5757  tt.restart();
5758  do {
5759  // check RAL
5760  size = sizeof(fval);
5761  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_RAL, TID_FLOAT);
5762  if (fabs(fval-hv[0]) < 0.2)
5763  done++;
5764 
5765  // check RAT
5766  size = sizeof(fval);
5767  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_RAT, TID_FLOAT);
5768  if (fabs(fval-hv[1]) < 0.2)
5769  done++;
5770 
5771  // check RAR
5772  size = sizeof(fval);
5773  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_RAR, TID_FLOAT);
5774  if (fabs(fval-hv[2]) < 0.2)
5775  done++;
5776 
5777  // check RAB
5778  size = sizeof(fval);
5779  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_RAB, TID_FLOAT);
5780  if (fabs(fval-hv[3]) < 0.2)
5781  done++;
5782 
5783  // check SampleHV
5784  size = sizeof(fval);
5785  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_SAMPLE, TID_FLOAT);
5786  if (fabs(fval-hv[4]) < 0.2)
5787  done++;
5788 
5789  if (done < 5) {
5790  Wait(2000); // wait 2 sec
5791  }
5792 
5793  if (tt.elapsed() > 300000) { // it takes more than 5 min
5794  QString err = QString("lemAutoRun: **WARNING** Sample region HV's couldn't be ramped back within 5min.");
5795  emit ErrorMsg(1, 0, LAR_MSG, -1, err);
5796  done = 10;
5797  }
5798 
5799  } while (done < 5);
5800  } else { // NO FUG HV check, hence just wait a 1 min
5801  Wait(60000);
5802  }
5803 
5804  cm_msg(MINFO, "lemAutoRun", "DegaussWEW: degauss done.");
5805  cm_yield(0);
5806 }
5807 
5808 //**********************************************************************
5809 // DegaussDanfysik
5810 //**********************************************************************
5817 {
5818  float currentFieldValue;
5819  QString msg;
5820 
5821  // check of Danfysik equipment is disabled in lemAutoRun
5822  if (!fEnabled["danfysik_eq"]) {
5823  msg = QString("(%1/%2) DEGAUSS_DANFYSIK: danfysik equipment disabled in lemAutoRun. Will do nothing here.").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5824  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5825  // increment command counter
5827  return;
5828  }
5829 
5830  // check if danfysik scfe is running
5831  CheckClients();
5832  if (!fDanfysikFeRunning) {
5834  QString err = QString("PLemAutoRun::DegaussDanfysik: Danfysik Slowcontrol Frontend NOT running. Error too severe, will stop.");
5835  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5837  QCoreApplication::exit(0);
5838  exit(0);
5839  }
5840 
5841  msg = QString("(%1/%2) DEGAUSS_DANFYSIK").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5842  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5843 
5844  msg = QString("Autorun running: ") + msg;
5845  emit StatusMsg(msg);
5846 
5847  // set current field to -8A
5848  currentFieldValue = -8.0;
5849  fDanfysikOutputKey->SetDataIndex(&currentFieldValue, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
5850  cm_msg(MINFO, "lemAutoRun", "DegaussDanfysik: set Bpar current to -8.0A");
5851  cm_yield(0);
5852 
5853  // wait 60 sec
5854  Wait(60000);
5855 
5856  // set current field to +8A
5857  currentFieldValue = +8.0;
5858  fDanfysikOutputKey->SetDataIndex(&currentFieldValue, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
5859  cm_msg(MINFO, "lemAutoRun", "DegaussDanfysik: set Bpar current to +8.0A");
5860  cm_yield(0);
5861 
5862  // wait 60 sec
5863  Wait(60000);
5864 
5865  // reduce the current field value gradually
5866  do {
5867  // set the new field value
5868  currentFieldValue /= -2.0;
5869  fDanfysikOutputKey->SetDataIndex(&currentFieldValue, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
5870  cm_msg(MINFO, "lemAutoRun", "DegaussDanfysik: set Bpar current to %.2f A", currentFieldValue);
5871  cm_yield(0);
5872 
5873  // wait a bit
5874  Wait(30000);
5875  } while (fabs(currentFieldValue) > 0.1);
5876 
5877  // set field value to zero
5878  currentFieldValue = 0.0;
5879  fDanfysikOutputKey->SetDataIndex(&currentFieldValue, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
5880  cm_msg(MINFO, "lemAutoRun", "DegaussDanfysik: done");
5881  cm_yield(0);
5882 }
5883 
5884 //**********************************************************************
5885 // Degauss
5886 //**********************************************************************
5894 {
5895  if (fSetupWewEnabled)
5896  DegaussWEW(arc);
5897  else
5898  DegaussDanfysik(arc);
5899 }
5900 
5901 //**********************************************************************
5902 // DegaussSpinRot
5903 //**********************************************************************
5910 {
5911  QString msg("");
5912 
5913  // check if FUG handling is disabled in lemAutoRun
5914  if (!fEnabled["fug_scfe"]) {
5915  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5916  msg += arc->cmdString;
5917  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
5918  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5919  // increment command counter
5921  return;
5922  }
5923  // check the danfysik spin rot equipment is enabled
5924  if (!fEnabled["danfysik_spin_rot_eq"]) {
5925  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5926  msg += QString("PLemAutoRun::DegaussSpinRot: danfysik spin rot equipment is disabled. Will do nothing here.");
5927  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5928  // increment command counter
5930  return;
5931  }
5932 
5933  // check if the hv_fug_scfe frontend is running
5934  CheckClients();
5935  if (!fHVFeRunning) { // error too severe to going on
5937  QString err = QString("PLemAutoRun::DegaussSpinRot: Slowcontrol Frontend NOT running. Error too severe, will stop.");
5938  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5940  QCoreApplication::exit(0);
5941  exit(0);
5942  }
5943 
5944  msg = QString("(%1/%2) DEGAUSS_SPIN_ROT").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5945  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5946 
5947  msg = QString("Autorun running: ") + msg;
5948  emit StatusMsg(msg);
5949 
5950  // set spin rotator HV's to zero
5951  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: shut down Spin Rot HV's.");
5952  cm_yield(0);
5953  // Loop over set HV. This is done this way to reduce hangers due to network problems
5954  int i, size;
5955  float hv_measured[HV_FUG_CHS];
5956  float value;
5957  float timeout;
5958  bool done, happy;
5959  QTime t;
5960  for (i=0; i<HV_FUG_MAX_TRY; i++) {
5961  // set spin rotator hv's to zero
5962  value = 0.0;
5963  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_RIGHT_RODS, TID_FLOAT);
5964  value = 0.0;
5965  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_LEFT_RODS, TID_FLOAT);
5966  value = 0.0;
5967  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_LEFT_PLATE, TID_FLOAT);
5968  value = 0.0;
5969  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_RIGHT_PLATE, TID_FLOAT);
5970 
5971  if (fFugHvCheck) {
5972  // check that the spin rotator HV's are all zero
5973  done = false;
5974  happy = false;
5975  timeout = fHVTimeout * 1e3;
5976  t.start();
5977  do {
5978  // sleep for 5 sec before reading the next value
5979  Wait(5000);
5980 
5981  // read sample hv
5982  size = HV_FUG_CHS*sizeof(float);
5983  fHVMeasuredKey->GetData(&hv_measured, &size, TID_FLOAT);
5984 
5985  // check if all measured spin rotator HV's are zero
5986  int count = 0;
5987  for (int j=HV_FUG_RIGHT_RODS; j<=HV_FUG_RIGHT_PLATE; j++) {
5988  if (fabs(hv_measured[j]) < fHVAccuracy)
5989  count++;
5990  }
5991  if (count == 4) { // all spin rotator HV's down
5992  done = true;
5993  happy = true;
5994  }
5995 
5996  // check if too much time elapsed to reach the final sample hv
5997  if (t.elapsed() > timeout) {
5998  done = true; // quit loop
5999  // emit warning
6000  msg = QString("Couldn't shut down Spin Rot HVs within %1 sec: will give it another try in 120 sec.").arg(fHVTimeout);
6001  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6002  }
6003  } while (!done);
6004 
6005  if (happy) // everything is OK, get out of the loop
6006  break;
6007 
6008  // wait 120 sec before retrial
6009  Wait(120000);
6010  } else { // NO FUG HV check, hence just wait a 1 min
6011  Wait(60000);
6012  break;
6013  }
6014  }
6015 
6016  if (i == HV_FUG_MAX_TRY) {
6018  // emit error
6019  msg = QString("Couldn't shut down the Spin Rotator HV, even after a few trials :-( .");
6020  emit ErrorMsg(1, 0, LAR_SAMPLE_HV_NOT_REACHED, arc->lineNo, msg);
6021  }
6022 
6023  // degauss spin rotator magnet
6024  // 1st set current to 0
6025  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: set Spin Rot Magnet current to 0.");
6026  cm_yield(0);
6027  value = 0.0;
6028  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6029  // check that measured current is going to 0
6030  done = false;
6031  timeout = fFieldTimeout * 1e3; // ms -> sec
6032  t.start(); // start timer
6033  do {
6034  // sleep for 1 sec before reading the next value
6035  Wait(1000);
6036 
6037  size = sizeof(value);
6038  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6039 
6040  if (fabs(value) < 0.1)
6041  done = true;
6042 
6043  // check if too much time elapsed to reach the final spin rotator magnet current
6044  if (t.elapsed() > timeout) {
6045  done = true; // quit loop
6046  // emit warning
6047  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6048  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6049  }
6050  } while (!done);
6051 
6052  // wait 10 sec
6053  Wait(10000);
6054 
6055  // 2nd set current to +12.0
6056  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: set Spin Rot Magnet current to 12.0 A.");
6057  cm_yield(0);
6058  value = 12.0;
6059  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6060  // check that measured current is going to 12A
6061  done = false;
6062  timeout = fFieldTimeout * 1e3; // ms -> sec
6063  t.start(); // start timer
6064  do {
6065  // sleep for 1 sec before reading the next value
6066  Wait(1000);
6067 
6068  size = sizeof(value);
6069  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6070 
6071  if (fabs(value-12.0) < 0.1)
6072  done = true;
6073 
6074  // check if too much time elapsed to reach the final spin rotator magnet current
6075  if (t.elapsed() > timeout) {
6076  done = true; // quit loop
6077  // emit warning
6078  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6079  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6080  }
6081  } while (!done);
6082 
6083  // wait 30 sec
6084  Wait(30000);
6085 
6086  // 3rd set current to -1.3A
6087  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: set Spin Rot Magnet current to -1.3 A.");
6088  cm_yield(0);
6089  value = -1.3;
6090  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6091  // check that measured current is going to -1.3A
6092  done = false;
6093  timeout = fFieldTimeout * 1e3; // ms -> sec
6094  t.start(); // start timer
6095  do {
6096  // sleep for 1 sec before reading the next value
6097  Wait(1000);
6098 
6099  size = sizeof(value);
6100  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6101 
6102  if (fabs(value+1.3) < 0.1)
6103  done = true;
6104 
6105  // check if too much time elapsed to reach the final spin rotator magnet current
6106  if (t.elapsed() > timeout) {
6107  done = true; // quit loop
6108  // emit warning
6109  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6110  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6111  }
6112  } while (!done);
6113 
6114  // wait 30 sec
6115  Wait(30000);
6116 
6117  // 4th set current to 0
6118  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: set Spin Rot Magnet current to 0 - done.");
6119  cm_yield(0);
6120  value = 0.0;
6121  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6122  // check that measured current is going to 0
6123  done = false;
6124  timeout = fFieldTimeout * 1e3; // ms -> sec
6125  t.start(); // start timer
6126  do {
6127  // sleep for 1 sec before reading the next value
6128  Wait(1000);
6129 
6130  size = sizeof(value);
6131  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6132 
6133  if (fabs(value) < 0.1)
6134  done = true;
6135 
6136  // check if too much time elapsed to reach the final spin rotator magnet current
6137  if (t.elapsed() > timeout) {
6138  done = true; // quit loop
6139  // emit warning
6140  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6141  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6142  }
6143  } while (!done);
6144 
6145  // set spin rot angle to its virgin value, i.e. +11.1965°
6146  value = 11.1965;
6147  fSpinRotAngleKey->SetData((void*)&value, 1, TID_FLOAT);
6148 
6149  // increment command counter
6151 }
6152 
6153 //**********************************************************************
6154 // SetIgnoreAlarms
6155 //**********************************************************************
6162 {
6163  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6164  msg += arc->cmdString;
6165  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6166 
6167  msg = QString("Autorun running: ") + msg;
6168  emit StatusMsg(msg);
6169 
6170  if ((arc->param[0] == "yes") || (arc->param[0] == "1") || (arc->param[0] == "true"))
6171  fIgnoreAlarms = true;
6172  else
6173  fIgnoreAlarms = false;
6174 
6175  // increment command counter
6177 }
6178 
6179 //**********************************************************************
6180 // SetIgnoreClients
6181 //**********************************************************************
6188 {
6189  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6190  msg += arc->cmdString;
6191  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6192 
6193  msg = QString("Autorun running: ") + msg;
6194  emit StatusMsg(msg);
6195 
6196  if ((arc->param[0] == "yes") || (arc->param[0] == "1") || (arc->param[0] == "true"))
6197  fIgnoreClients = true;
6198  else
6199  fIgnoreClients = false;
6200 
6201  // increment command counter
6203 }
6204 
6205 //**********************************************************************
6206 // SetDump
6207 //**********************************************************************
6214 {
6215  QString msg("");
6216 
6217  // check the danfysik spin rot equipment is enabled
6218  if (!fEnabled["sample_eq"]) {
6219  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6220  msg += QString("PLemAutoRun::SetDump: sample equipment is disabled. Will do nothing here.");
6221  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6222  // increment command counter
6224  return;
6225  }
6226 
6227  msg = QString("(%1/%2) DUMP %3 (times)").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds).arg(arc->param[0]);
6228  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6229 
6230  msg = QString("Autorun running: ") + msg;
6231  emit StatusMsg(msg);
6232 
6233  // indicate that there is a dump
6234  fDumpInUse = true;
6235 
6236  // open file
6237  fDumpFile.setFileName(fAutoRunPath + fDumpFileName);
6238  fDumpFile.open(QIODevice::WriteOnly | QIODevice::Append);
6239 
6240  // get necessary information from the ODB
6241  static bool write_header = true;
6242 
6243  if (write_header) {
6244  write_header = false;
6245 
6246  // get temperature control channel
6247  char ctrl_ch[4];
6248  int size = sizeof(ctrl_ch);
6249  fSampleCtrlChKey->GetData(ctrl_ch, &size, TID_STRING);
6250 
6251  // get raw data voltage channels
6252  char sensor_ch[10][4];
6253  size = sizeof(sensor_ch[0]);
6254  for (int i=0; i<fSampleChannelKey->GetNumValues(); i++) {
6255  fSampleChannelKey->GetDataIndex(sensor_ch[i], &size, i, TID_STRING);
6256  }
6257 
6258  // get raw data sensor type assignement
6259  int sensor_type[10];
6260  size = sizeof(int);
6261  for (int i=0; i<fSampleSensorTypeKey->GetNumValues(); i++) {
6262  fSampleSensorTypeKey->GetDataIndex(&sensor_type[i], &size, i, TID_INT);
6263  }
6264 
6265  // write header (there can be more than one header in the RawVoltageOutput data file!!)
6266  QTextStream stream( &fDumpFile );
6267  stream << "%--------------------------------------------------------------------------" << endl;
6268  stream << "% Number of Entries : 23" << endl;
6269  stream << "% Number of Raw Data Reading : 10" << endl;
6270  stream << "% First Raw Data Reading Entry : 14" << endl;
6271  stream << "% Entry 1 : month" << endl;
6272  stream << "% Entry 2 : day" << endl;
6273  stream << "% Entry 3 : year" << endl;
6274  stream << "% Entry 4 : hour" << endl;
6275  stream << "% Entry 5 : minutes" << endl;
6276  stream << "% Entry 6 : seconds" << endl;
6277  stream << "% Entry 7 : msec" << endl;
6278  stream << "% Entry 8 : measured temperature of control channel = " << ctrl_ch << endl;
6279  stream << "% Entry 9 : pressure" << endl;
6280  stream << "% Entry 10 : heater output" << endl;
6281  stream << "% Entry 11 : setpoint temperature" << endl;
6282  stream << "% Entry 12 : heater range" << endl;
6283  stream << "% Entry 13 : BH1 flow measured" << endl;
6284  for (int i=0; i<10; i++) {
6285  stream << "% Entry " << 14+i << " : Raw Data Reading Entry " << i << " : Channel " << sensor_ch[i] << " : Sensor Type " << sensor_type[i] << endl;
6286  }
6287  stream << "%--------------------------------------------------------------------------" << endl;
6288  fDumpFile.flush();
6289  }
6290 
6291 
6292  // set the number of dumps to be made
6293  fDumpCounter = arc->param[0].toInt();
6294 
6295  // increment command counter
6297 }
6298 
6299 //**********************************************************************
6300 // SetFieldWEWL
6301 //**********************************************************************
6309 {
6310  // param: [0] field value, [1] field unit (A | G)
6311  float value, demand;
6312  int size, err_count;
6313  QString msg("");
6314 
6315  // check if FUG handling is disabled in lemAutoRun
6316  if (!fEnabled["fug_scfe"]) {
6317  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6318  msg += arc->cmdString;
6319  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
6320  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6321  // increment command counter
6323  return;
6324  }
6325 
6326  // set field power supply (possibly needed in setTitle)
6327  fFieldPwrSupply = "wew";
6328 
6329  // check if the wew_scfe frontend is running
6330  CheckClients();
6331  if (!fWEWFeRunning) { // error too severe to going on
6333  QString err = QString("PLemAutoRun::SetFieldWEWL: WEW Slowcontrol Frontend NOT running.\n")+
6334  QString(" Error too severe, will stop.");
6335  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
6337  QCoreApplication::exit(0);
6338  exit(0);
6339  }
6340 
6341  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6342  msg += arc->cmdString;
6343  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6344 
6345  msg = QString("Autorun running: ") + msg;
6346  emit StatusMsg(msg);
6347 
6348  // 2 things to be checked at this point: 1) WEWH needs to be OFF, 2) WEWL needs to be ON
6349  // make sure WEWH is OFF
6350  size = sizeof(value);
6351  fWEWOutputKey->GetDataIndex(&value, &size, WEWH_OUTPUT_CMD, TID_FLOAT);
6352  if (value == 1.0) {
6353  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWL", "**WARNING** WEWH still ON! Will ramp it to zero and switch it off first.");
6354  cm_yield(0);
6355  // WEWH demand to zero
6356  demand = 0.0;
6357  fWEWOutputKey->SetDataIndex((void*)&demand, WEWH_OUTPUT_CURRENT, TID_FLOAT);
6358  // make sure that WEWH demand current is zero
6359  err_count = 0;
6360  do {
6361  size = sizeof(value);
6362  fWEWInputKey->GetDataIndex(&value, &size, WEWH_INPUT_CURRENT, TID_FLOAT);
6363  Wait(500);
6364  } while ((value > 2.0) && (err_count++ < 120));
6365  // switch WEWH OFF
6366  demand = 0.0;
6367  fWEWOutputKey->SetDataIndex((void*)&demand, WEWH_OUTPUT_CMD, TID_FLOAT);
6368  // make sure WEWH is switched OFF
6369  err_count = 0;
6370  do {
6371  size = sizeof(value);
6372  fWEWInputKey->GetDataIndex(&value, &size, WEWH_INPUT_STATUS, TID_FLOAT);
6373  Wait(500);
6374  } while ((value != 0.0) && (err_count++ < 120));
6375  if (err_count >= 120) {
6376  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWL", "**WARNING** WEWH status is still ON. Please check! EPICS Gateway Problems?");
6377  cm_yield(0);
6378  }
6379  }
6380  Wait(500);
6381  // make sure WEWL is ON
6382  size = sizeof(value);
6383  fWEWOutputKey->GetDataIndex(&value, &size, WEWL_OUTPUT_CMD, TID_FLOAT);
6384  if (value == 0.0) {
6385  // just out of paranoia set the demand current first to zero
6386  demand = 0.0;
6387  fWEWOutputKey->SetDataIndex((void*)&demand, WEWL_OUTPUT_CURRENT, TID_FLOAT);
6388  Wait(500);
6389  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWL", "**WARNING** WEWL still OFF! Will switch it on first.");
6390  cm_yield(0);
6391  demand = 1.0;
6392  fWEWOutputKey->SetDataIndex((void*)&demand, WEWL_OUTPUT_CMD, TID_FLOAT);
6393  Wait(2000);
6394  }
6395 
6396  value = arc->param[0].toFloat();
6397  if (arc->param[1] == "G") { // field given in Gauss, convert it to Ampere for the WEWL
6398  float curVal = (value - fMagParamWew[0]) / fMagParamWew[1];
6399  value = curVal;
6400  }
6401 
6402  // check if WEW current value is too large for having the RA's on, if so switch the RA HV's off first
6403  // in the RA pulsed mode, this is not needed
6404  if ((value > fWEWCriticalCurrentRA) && !fRAPulsingEnabled) {
6405  float fval;
6406  int count = 0;
6407  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
6408  size = sizeof(fval);
6409  fHVDemandKey->GetDataIndex(&fval, &size, i, TID_FLOAT);
6410  if (fval > 2.0) {
6411  count++;
6412  }
6413  }
6414  if (count == 4) { // all RA HV's on
6415  // emit warning
6416  msg = QString("PLemAutoRun::SetFieldWEWL: demand current %1 > %2, hence RA HV's will be shut down").arg(value).arg(fWEWCriticalCurrentRA);
6417  emit ErrorMsg(1, 0, LAR_FORCED_RA_OFF, arc->lineNo, msg);
6418  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
6419  fval = 0.0;
6420  fHVDemandKey->SetDataIndex(&fval, i, TID_FLOAT);
6421  }
6422  Wait(5000); // sleep 5sec before proceeding
6423  }
6424  }
6425 
6426  // set field value
6427  fWEWOutputKey->SetDataIndex((void *)&value, WEWL_OUTPUT_CURRENT, TID_FLOAT);
6428 
6429  // check if field value is reached
6430  bool done = false;
6431  float timeout = fFieldTimeout * 1e3; // timeout in (msec)
6432  QTime t;
6433  t.start();
6434  demand = value; // keep demand current
6435  do {
6436  // sleep for 5 sec before reading the next value
6437  Wait(5000);
6438 
6439  // read current value
6440  size = sizeof(value);
6441  fWEWInputKey->GetDataIndex(&value, &size, WEWL_INPUT_CURRENT, TID_FLOAT);
6442 
6443  // check if final current is reached
6444  if (fabs(demand-value) < fFieldAccuracy) {
6445  done = true;
6446  }
6447 
6448  if (t.elapsed() > timeout) {
6449  done = true; // quit loop
6450  // emit error
6451  msg = QString("Field (WEW) was not reached within %1 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand).arg(value);
6452  emit ErrorMsg(1, 0, LAR_FIELD_NOT_REACHED, arc->lineNo, msg);
6453  }
6454  } while (!done);
6455 
6456  // increment command counter
6458 }
6459 
6460 //**********************************************************************
6461 // SetFieldWEWH
6462 //**********************************************************************
6470 {
6471  // param: [0] field value, [1] field unit (A | G)
6472  float value, demand;
6473  int size, err_count;
6474  QString msg("");
6475 
6476  // check if FUG handling is disabled in lemAutoRun
6477  if (!fEnabled["fug_scfe"]) {
6478  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6479  msg += arc->cmdString;
6480  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
6481  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6482  // increment command counter
6484  return;
6485  }
6486 
6487  // set field power supply (possibly needed in setTitle)
6488  fFieldPwrSupply = "wew";
6489 
6490  // check if the wew_scfe frontend is running
6491  CheckClients();
6492  if (!fWEWFeRunning) { // error too severe to going on
6494  QString err = QString("PLemAutoRun::SetFieldWEWH: WEW Slowcontrol Frontend NOT running.\n")+
6495  QString(" Error too severe, will stop.");
6496  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
6498  QCoreApplication::exit(0);
6499  exit(0);
6500  }
6501 
6502  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6503  msg += arc->cmdString;
6504  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6505 
6506  msg = QString("Autorun running: ") + msg;
6507  emit StatusMsg(msg);
6508 
6509  // 2 things to be checked at this point: 1) WEWL needs to be OFF, 2) WEWH needs to be ON
6510  // make sure WEWL is OFF
6511  size = sizeof(value);
6512  fWEWOutputKey->GetDataIndex(&value, &size, WEWL_OUTPUT_CMD, TID_FLOAT);
6513  if (value == 1.0) {
6514  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWH", "**WARNING** WEWL still ON! Will ramp it to zero and switch it off first.");
6515  cm_yield(0);
6516  // WEWL demand to zero
6517  demand = 0.0;
6518  fWEWOutputKey->SetDataIndex((void*)&demand, WEWL_OUTPUT_CURRENT, TID_FLOAT);
6519  // make sure that WEWL demand current is zero
6520  err_count = 0;
6521  do {
6522  size = sizeof(value);
6523  fWEWInputKey->GetDataIndex(&value, &size, WEWL_INPUT_CURRENT, TID_FLOAT);
6524  Wait(500);
6525  } while ((value > 0.1) && (err_count++ < 120));
6526  // switch WEWL off
6527  demand = 0.0;
6528  fWEWOutputKey->SetDataIndex((void*)&demand, WEWL_OUTPUT_CMD, TID_FLOAT);
6529  // make sure WEWL is switched OFF
6530  err_count = 0;
6531  do {
6532  size = sizeof(value);
6533  fWEWInputKey->GetDataIndex(&value, &size, WEWL_INPUT_STATUS, TID_FLOAT);
6534  Wait(500);
6535  } while ((value != 0.0) && (err_count++ < 120));
6536  if (err_count >= 120) {
6537  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWH", "**WARNING** WEWL status is still ON. Please check! EPICS Gateway Problems?");
6538  cm_yield(0);
6539  }
6540  }
6541  Wait(500);
6542  // make sure WEWH is ON
6543  size = sizeof(value);
6544  fWEWOutputKey->GetDataIndex(&value, &size, WEWH_OUTPUT_CMD, TID_FLOAT);
6545  if (value == 0.0) {
6546  // just out of paranoia set the demand current first to zero
6547  demand = 0.0;
6548  fWEWOutputKey->SetDataIndex((void*)&demand, WEWH_OUTPUT_CURRENT, TID_FLOAT);
6549  Wait(500);
6550  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWH", "**WARNING** WEWH still OFF! Will switch it on first.");
6551  cm_yield(0);
6552  demand = 1.0;
6553  fWEWOutputKey->SetDataIndex((void*)&demand, WEWH_OUTPUT_CMD, TID_FLOAT);
6554  Wait(1000);
6555  }
6556 
6557  value = arc->param[0].toFloat();
6558  if (arc->param[1] == "G") { // field given in Gauss, convert it to Ampere for the WEWH
6559  float curVal = (value - fMagParamWew[0]) / fMagParamWew[1];
6560  value = curVal;
6561  }
6562 
6563  // check if WEW current value is too large for having the RA's on, if so switch the RA HV's off first
6564  // in the RA pulsed mode, this is not needed
6565  if ((value > fWEWCriticalCurrentRA) && !fRAPulsingEnabled) {
6566  float fval;
6567  int count = 0;
6568  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
6569  size = sizeof(fval);
6570  fHVDemandKey->GetDataIndex(&fval, &size, i, TID_FLOAT);
6571  if (fval > 2.0) {
6572  count++;
6573  }
6574  }
6575  if (count == 4) { // all RA HV's on
6576  // emit warning
6577  msg = QString("PLemAutoRun::SetFieldWEWH: demand current %1 > %2, hence RA HV's will be shut down").arg(value).arg(fWEWCriticalCurrentRA);
6578  emit ErrorMsg(1, 0, LAR_FORCED_RA_OFF, arc->lineNo, msg);
6579  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
6580  fval = 0.0;
6581  fHVDemandKey->SetDataIndex(&fval, i, TID_FLOAT);
6582  }
6583  Wait(5000); // sleep 5sec before proceeding
6584  }
6585  }
6586 
6587  // set field value
6588  fWEWOutputKey->SetDataIndex((void *)&value, WEWH_OUTPUT_CURRENT, TID_FLOAT);
6589 
6590  // check if field value is reached
6591  bool done = false;
6592  float timeout = fFieldTimeout * 1e3; // timeout in (msec)
6593  QTime t;
6594  t.start();
6595  demand = value; // keep demand current
6596  do {
6597  // sleep for 5 sec before reading the next value
6598  Wait(5000);
6599 
6600  // read current value
6601  size = sizeof(value);
6602  fWEWInputKey->GetDataIndex(&value, &size, WEWH_INPUT_CURRENT, TID_FLOAT);
6603 
6604  // check if final current is reached
6605  if (fabs(demand) < 2.0) {
6606  if (fabs(demand-value) < 2.0)
6607  done = true;
6608  } else if (fabs(demand-value) < fFieldAccuracy) {
6609  done = true;
6610  }
6611 
6612  if (t.elapsed() > timeout) {
6613  done = true; // quit loop
6614  // emit error
6615  msg = QString("Field (WEW) was not reached within %1 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand).arg(value);
6616  emit ErrorMsg(1, 0, LAR_FIELD_NOT_REACHED, arc->lineNo, msg);
6617  }
6618  } while (!done);
6619 
6620  // increment command counter
6622 }
6623 
6624 //**********************************************************************
6625 // SetFieldDanfysik
6626 //**********************************************************************
6634 {
6635  // param: [0] current
6636 
6637  float value, demand;
6638  int size;
6639  QString msg("");
6640 
6641  // check if danfysik equipment is disabled in lemAutoRun
6642  if (!fEnabled["danfysik_eq"]) {
6643  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6644  msg += ": PLemAutoRun::SetFieldDanfysik: danfysik equipment disabled in lemAutoRun. Will do nothing here.";
6645  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6646  // increment command counter
6648  return;
6649  }
6650 
6651 
6652  // set field power supply (possibly needed in setTitle)
6653  fFieldPwrSupply = "danfysik";
6654 
6655  // check if the danfysik_scfe frontend is running
6656  CheckClients();
6657  if (!fDanfysikFeRunning) { // error too severe to going on
6659  QString err = QString("PLemAutoRun::SetFieldDanfysik: Danfysik Slowcontrol Frontend NOT running.\n")+
6660  QString(" Error too severe, will stop.");
6661  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
6663  QCoreApplication::exit(0);
6664  exit(0);
6665  }
6666 
6667  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6668  msg += arc->cmdString;
6669  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6670 
6671  msg = QString("Autorun running: ") + msg;
6672  emit StatusMsg(msg);
6673 
6674  value = arc->param[0].toFloat();
6675  if (arc->param[1] == "G") { // field given in Gauss, convert it to Ampere for the Danfysik
6676  float curVal = (value - fMagParamBpar[0]) / fMagParamBpar[1];
6677  value = curVal;
6678  }
6679 
6680  // set field value
6681  fDanfysikOutputKey->SetDataIndex((void *)&value, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
6682 
6683  // check if field value is reached
6684  bool done = false;
6685  float timeout = fFieldTimeout * 1e3; // timeout in (msec)
6686  QTime t;
6687  t.start();
6688  demand = value; // keep demand current
6689  do {
6690  // sleep for 5 sec before reading the next value
6691  Wait(5000);
6692 
6693  // read current value
6694  size = sizeof(value);
6695  fDanfysikInputKey->GetDataIndex(&value, &size, DANFYSIK_INPUT_CURRENT, TID_FLOAT);
6696 
6697  // check if final current is reached
6698  if (fabs(demand-value) < fFieldAccuracy) {
6699  done = true;
6700  }
6701 
6702  if (t.elapsed() > timeout) {
6703  done = true; // quit loop
6704  // emit error
6705  msg = QString("Field (Danfysik) was not reached within %1 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand).arg(value);
6706  emit ErrorMsg(1, 0, LAR_FIELD_NOT_REACHED, arc->lineNo, msg);
6707  }
6708  } while (!done);
6709 
6710  // increment command counter
6712 }
6713 
6714 //**********************************************************************
6715 // SetField
6716 //**********************************************************************
6725 {
6726  if (fSetupWewEnabled) { // WEW in use
6727  // get the current to decide which power supply to be used
6728  float value = arc->param[0].toFloat();
6729  if (arc->param[1] == "G") {
6730  float curVal = (value - fMagParamWew[0]) / fMagParamWew[1];
6731  value = curVal;
6732  }
6733  if (fabs(value) < 50.0)
6734  SetFieldWEWL(arc);
6735  else
6736  SetFieldWEWH(arc);
6737  } else if (fSetupBparEnabled) { // Bpar in use
6738  SetFieldDanfysik(arc);
6739  } else { // no magnets are enabled
6740  QString msg("");
6741  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6742  msg += "PLemAutoRun::SetField: no magnet is enabled. Will do nothing here.";
6743  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6744  // increment command counter
6746  }
6747 }
6748 
6749 //**********************************************************************
6750 // SetSpinRot
6751 //**********************************************************************
6758 {
6759  // param: [0] angle or 'off'; [1] 'ndg' if present
6760 
6761  QString msg("");
6762 
6763  // check if FUG handling is disabled in lemAutoRun
6764  if (!fEnabled["fug_scfe"]) {
6765  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6766  msg += arc->cmdString;
6767  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
6768  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6769  // increment command counter
6771  return;
6772  }
6773  if (!fEnabled["danfysik_spin_rot_eq"]) {
6774  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6775  msg += QString("PLemAutoRun::SetSpinRot: danfysik spin rot equipment disabled. Will do nothing here.");
6776  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6777  // increment command counter
6779  return;
6780  }
6781 
6782  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6783  msg += arc->cmdString;
6784  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6785 
6786  msg = QString("Autorun running: ") + msg;
6787  emit StatusMsg(msg);
6788 
6789  BOOL enabled;
6790 
6791  // only degauss if no 'ndg' is present and not SPIN_ROT off command is present
6792  if (((arc->noElements != 2) || (arc->param[1] != "ndg")) || (arc->param[0] == "off")) {
6793  // always first degauss the spin rotator. This way, the user doesn't need to think about the spin rotator's history
6794  enabled = FALSE;
6795  fSpinRotEnabledKey->SetData((void*)&enabled, 1, TID_BOOL);
6796 
6797  // set spin rotator HV's to zero
6798  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: start Spin Rot shutdown and degauss procedure.");
6799  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: shut down Spin Rot HV's.");
6800  cm_yield(0);
6801  // Loop over set HV. This is done this way to reduce hangers due to network problems
6802  int i, size;
6803  float hv_measured[HV_FUG_CHS];
6804  float value;
6805  float timeout;
6806  bool done, happy;
6807  QTime t;
6808  for (i=0; i<HV_FUG_MAX_TRY; i++) {
6809  // set spin rotator hv's to zero
6810  value = 0.0;
6811  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_RIGHT_RODS, TID_FLOAT);
6812  value = 0.0;
6813  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_LEFT_RODS, TID_FLOAT);
6814  value = 0.0;
6815  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_LEFT_PLATE, TID_FLOAT);
6816  value = 0.0;
6817  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_RIGHT_PLATE, TID_FLOAT);
6818 
6819  if (fFugHvCheck) {
6820  // check that the spin rotator HV's are all zero
6821  done = false;
6822  happy = false;
6823  timeout = fHVTimeout * 1e3;
6824  t.start();
6825  do {
6826  // sleep for 5 sec before reading the next value
6827  Wait(5000);
6828 
6829  // read sample hv
6830  size = HV_FUG_CHS*sizeof(float);
6831  fHVMeasuredKey->GetData(&hv_measured, &size, TID_FLOAT);
6832 
6833  // check if all measured spin rotator HV's are zero
6834  int count = 0;
6835  for (int j=HV_FUG_RIGHT_RODS; j<=HV_FUG_RIGHT_PLATE; j++) {
6836  if (fabs(hv_measured[j]) < fHVAccuracy)
6837  count++;
6838  }
6839  if (count == 4) { // all spin rotator HV's down
6840  done = true;
6841  happy = true;
6842  }
6843 
6844  // check if too much time elapsed to reach the final sample hv
6845  if (t.elapsed() > timeout) {
6846  done = true; // quit loop
6847  // emit warning
6848  msg = QString("Couldn't shut down Spin Rot HVs within %1 sec: will give it another try in 120 sec.").arg(fHVTimeout);
6849  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6850  }
6851  } while (!done);
6852 
6853  if (happy) // everything is OK, get out of the loop
6854  break;
6855 
6856  // wait 120 sec before retrial
6857  Wait(120000);
6858  } else { // NO FUG HV check, hence just wait a 1 min
6859  Wait(60000);
6860  break;
6861  }
6862  }
6863 
6864  if (i == HV_FUG_MAX_TRY) {
6866  // emit error
6867  msg = QString("Couldn't shut down the Spin Rotator HV, even after a few trials :-( .");
6868  emit ErrorMsg(1, 0, LAR_SAMPLE_HV_NOT_REACHED, arc->lineNo, msg);
6869  }
6870 
6871  // degauss spin rotator magnet
6872  // 1st set current to 0
6873  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set Spin Rot Magnet current to 0.");
6874  cm_yield(0);
6875  value = 0.0;
6876  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6877  // check that measured current is going to 0
6878  done = false;
6879  timeout = fFieldTimeout * 1e3; // ms -> sec
6880  t.start(); // start timer
6881  do {
6882  // sleep for 1 sec before reading the next value
6883  Wait(1000);
6884 
6885  size = sizeof(value);
6886  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6887 
6888  if (fabs(value) < 0.1)
6889  done = true;
6890 
6891  // check if too much time elapsed to reach the final spin rotator magnet current
6892  if (t.elapsed() > timeout) {
6893  done = true; // quit loop
6894  // emit warning
6895  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6896  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6897  }
6898  } while (!done);
6899 
6900  // wait 10 sec
6901  Wait(10000);
6902 
6903  // 2nd set current to +12.0
6904  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set Spin Rot Magnet current to 12.0 A.");
6905  cm_yield(0);
6906  value = 12.0;
6907  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6908  // check that measured current is going to 12A
6909  done = false;
6910  timeout = fFieldTimeout * 1e3; // ms -> sec
6911  t.start(); // start timer
6912  do {
6913  // sleep for 1 sec before reading the next value
6914  Wait(1000);
6915 
6916  size = sizeof(value);
6917  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6918 
6919  if (fabs(value-12.0) < 0.1)
6920  done = true;
6921 
6922  // check if too much time elapsed to reach the final spin rotator magnet current
6923  if (t.elapsed() > timeout) {
6924  done = true; // quit loop
6925  // emit warning
6926  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6927  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6928  }
6929  } while (!done);
6930 
6931  // wait 30 sec
6932  Wait(30000);
6933 
6934  // 3rd set current to -1.3A
6935  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set Spin Rot Magnet current to -1.3 A.");
6936  cm_yield(0);
6937  value = -1.3;
6938  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6939  // check that measured current is going to -1.3A
6940  done = false;
6941  timeout = fFieldTimeout * 1e3; // ms -> sec
6942  t.start(); // start timer
6943  do {
6944  // sleep for 1 sec before reading the next value
6945  Wait(1000);
6946 
6947  size = sizeof(value);
6948  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6949 
6950  if (fabs(value+1.3) < 0.1)
6951  done = true;
6952 
6953  // check if too much time elapsed to reach the final spin rotator magnet current
6954  if (t.elapsed() > timeout) {
6955  done = true; // quit loop
6956  // emit warning
6957  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6958  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6959  }
6960  } while (!done);
6961 
6962  // wait 30 sec
6963  Wait(30000);
6964 
6965  // 4th set current to 0
6966  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set Spin Rot Magnet current to 0 - done.");
6967  cm_yield(0);
6968  value = 0.0;
6969  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6970  // check that measured current is going to 0
6971  done = false;
6972  timeout = fFieldTimeout * 1e3; // ms -> sec
6973  t.start(); // start timer
6974  do {
6975  // sleep for 1 sec before reading the next value
6976  Wait(1000);
6977 
6978  size = sizeof(value);
6979  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6980 
6981  if (fabs(value) < 0.1)
6982  done = true;
6983 
6984  // check if too much time elapsed to reach the final spin rotator magnet current
6985  if (t.elapsed() > timeout) {
6986  done = true; // quit loop
6987  // emit warning
6988  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6989  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6990  }
6991  } while (!done);
6992  }
6993 
6994  if (arc->param[0] != "off") { // set spin rotation angle
6995  // check if it is necessary to enable the spin rotator
6996  int size = sizeof(enabled);
6997  fSpinRotEnabledKey->GetData((void*)&enabled, &size, TID_BOOL);
6998  cm_msg(MDEBUG, "SetSpinRot", "SetSpinRot: enabled=%d.", enabled);
6999  cm_yield(0);
7000  if (enabled == FALSE) {
7001  enabled = TRUE;
7002  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: enable spin rotator.");
7003  cm_yield(0);
7004  fSpinRotEnabledKey->SetData((void*)&enabled, 1, TID_BOOL);
7005  // wait for 10 sec in order to make sure that the analyzer got it enough time to have it updated
7006  Wait(10000);
7007  }
7008  float angle = arc->param[0].toFloat();
7009  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set spin rotation angle to %f", angle);
7010  cm_yield(0);
7011  fSpinRotAngleKey->SetData((void*)&angle, 1, TID_FLOAT);
7012 
7013  // wait 120 sec
7014  Wait(120000);
7015  }
7016 
7017  // increment command counter
7019 }
7020 
7021 //**********************************************************************
7022 // SetFOM
7023 //**********************************************************************
7030 {
7031  // param: [0] current
7032 
7033  int size, status;
7034  float standby, demand_current, measured_current;
7035  bool done;
7036  float timeout;
7037  QTime t;
7038  QString msg("");
7039 
7040  if (!fEnabled["fom_eq"]) {
7041  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7042  msg += QString("PLemAutoRun::SetFOM: fom equipment disabled. Will do nothing here.");
7043  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7044  // increment command counter
7046  return;
7047  }
7048 
7049  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7050  msg += arc->cmdString;
7051  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7052 
7053  msg = QString("Autorun running: ") + msg;
7054  emit StatusMsg(msg);
7055 
7056  // get FOM standby flag from ODB
7057  size = sizeof(standby);
7058  status = fFOMOutputKey->GetDataIndex(&standby, &size, FOM_STANDBY, TID_FLOAT);
7059  if (status != DB_SUCCESS) { // error ODB reading
7060  msg = QString("(%1/%2) FOM %3: Couldn't get standby status, therefore the command will be ignored").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds).arg(arc->param[0]);
7061  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7062 
7063  // increment command counter
7065  return;
7066  }
7067 
7068  // get current from parameter list
7069  demand_current = arc->param[0].toFloat();
7070 
7071  if (demand_current == 0.0) {
7072 
7073  // set current
7074  fFOMOutputKey->SetDataIndex(&demand_current, FOM_CURRENT_DEMAND, TID_FLOAT);
7075 
7076  // check that current is actually set
7077  done = false;
7078  timeout = 300 * 1e3; // timeout in (msec), i.e. 300 sec
7079  QTime t;
7080  t.start();
7081  do {
7082  // sleep for 5 sec before reading the next value
7083  Wait(5000);
7084 
7085  // read current value
7086  size = sizeof(measured_current);
7087  fFOMInputKey->GetDataIndex(&measured_current, &size, FOM_CURRENT_MEASURED, TID_FLOAT);
7088 
7089  // check if final current is reached
7090  if (fabs(demand_current-measured_current) < fFOMCurrentAccuracy) {
7091  done = true;
7092  }
7093 
7094  if (t.elapsed() > timeout) {
7095  done = true; // quit loop
7096  // emit error
7097  msg = QString("Current (FOM) was not reached within 300 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand_current).arg(measured_current);
7098  emit ErrorMsg(1, 0, LAR_FOM_CURRENT_NOT_REACHED, arc->lineNo, msg);
7099  }
7100  } while (!done);
7101 
7102  // set FOM into standby mode
7103  standby = 1.0;
7104  fFOMOutputKey->SetDataIndex(&standby, FOM_STANDBY, TID_FLOAT);
7105 
7106  } else { // current != 0
7107 
7108  // check if FOM is on standby and, if yes, bring it back into operation
7109  if (standby != 0.0) {
7110  standby = 0.0;
7111  fFOMOutputKey->SetDataIndex(&standby, FOM_STANDBY, TID_FLOAT);
7112  }
7113 
7114  // wait 20sec so that FOM has the chance to wake up
7115  Wait(20000);
7116 
7117  // set current
7118  fFOMOutputKey->SetDataIndex(&demand_current, FOM_CURRENT_DEMAND, TID_FLOAT);
7119 
7120  // check that current is actually set
7121  done = false;
7122  timeout = 300 * 1e3; // timeout in (msec), i.e. 300 sec
7123  QTime t;
7124  t.start();
7125  do {
7126  // sleep for 5 sec before reading the next value
7127  Wait(5000);
7128 
7129  // read current value
7130  size = sizeof(measured_current);
7131  fFOMInputKey->GetDataIndex(&measured_current, &size, FOM_CURRENT_MEASURED, TID_FLOAT);
7132 
7133  // check if final current is reached
7134  if (fabs(demand_current-measured_current) < fFOMCurrentAccuracy) {
7135  done = true;
7136  }
7137 
7138  if (t.elapsed() > timeout) {
7139  done = true; // quit loop
7140  // emit error
7141  msg = QString("Current (FOM) was not reached within 300 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand_current).arg(measured_current);
7142  emit ErrorMsg(1, 0, LAR_FOM_CURRENT_NOT_REACHED, arc->lineNo, msg);
7143  }
7144  } while (!done);
7145 
7146  }
7147 
7148  // increment command counter
7150 }
7151 
7152 //**********************************************************************
7153 // SetLEMSetup
7154 //**********************************************************************
7161 {
7162  QString msg("");
7163 
7164  if (!fEnabled["lem_setup_odb"]) {
7165  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7166  msg += QString("PLemAutoRun::SetLEMSetup: setup info ODB entries disabled. Will do nothing here.");
7167  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7168  // increment command counter
7170  return;
7171  }
7172 
7173  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7174  msg += arc->cmdString;
7175  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7176 
7177  msg = QString("Autorun running: ") + msg;
7178  emit StatusMsg(msg);
7179 
7180  fLemSetupKey->SetData((void *)arc->param[0].toLatin1().data(), 1, TID_STRING);
7181 
7182  // increment command counter
7184 }
7185 
7186 //**********************************************************************
7187 // SetModInfo
7188 //**********************************************************************
7195 {
7196  QString msg("");
7197 
7198  if (!fEnabled["mod_name_odb"] || !fEnabled["mod_date_odb"]) {
7199  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7200  msg += QString("PLemAutoRun::SetModInfo: moderator info ODB entries disabled. Will do nothing here.");
7201  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7202  // increment command counter
7204  return;
7205  }
7206 
7207  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7208  msg += arc->cmdString;
7209  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7210 
7211  msg = QString("Autorun running: ") + msg;
7212  emit StatusMsg(msg);
7213 
7214  fModNameKey->SetData((void *)arc->param[0].toLatin1().data(), 1, TID_STRING);
7215  fModDateKey->SetData((void *)arc->param[1].toLatin1().data(), 1, TID_STRING);
7216 
7217  // increment command counter
7219 }
7220 
7221 //**********************************************************************
7222 // CheckOdbType
7223 //**********************************************************************
7228 {
7229  int ival;
7230  float fval;
7231  double dval;
7232  bool ok;
7233  QString str(arc->param[2]);
7234 
7235  switch (type) {
7236  case TID_BYTE:
7237  case TID_CHAR:
7238  ival = str.toInt(&ok);
7239  if (!ok) { // conversion error
7240  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_BYTE/TID_CHAR is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7241  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7242  return false;
7243  }
7244  if ((ival < 0) || (ival > 255)) { // range error
7245  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_BYTE/TID_CHAR; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7246  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7247  return false;
7248  }
7249  break;
7250  case TID_SBYTE:
7251  ival = str.toInt(&ok);
7252  if (!ok) { // conversion error
7253  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_SBYTE is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7254  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7255  return false;
7256  }
7257  if ((ival < -128) || (ival > 127)) { // range error
7258  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_SBYTE; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7259  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7260  return false;
7261  }
7262  break;
7263  case TID_WORD:
7264  ival = str.toInt(&ok);
7265  if (!ok) { // conversion error
7266  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_WORD is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7267  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7268  return false;
7269  }
7270  if ((ival < 0) || (ival > 65535)) { // range error
7271  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_WORD; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7272  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7273  return false;
7274  }
7275  break;
7276  case TID_SHORT:
7277  ival = str.toInt(&ok);
7278  if (!ok) { // conversion error
7279  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_SHORT is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7280  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7281  return false;
7282  }
7283  if ((ival < -32768) || (ival > 32767)) { // range error
7284  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_SHORT; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7285  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7286  return false;
7287  }
7288  break;
7289  case TID_DWORD:
7290  ival = str.toInt(&ok);
7291  if (!ok) { // conversion error
7292  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_DWORD is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7293  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7294  return false;
7295  }
7296  if (ival < 0) { // range error 0 .. 2^31 - 1
7297  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_DWORD; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7298  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7299  return false;
7300  }
7301  break;
7302  case TID_INT:
7303  ival = str.toInt(&ok);
7304  if (!ok) { // conversion error
7305  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_INT is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7306  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7307  return false;
7308  }
7309  break;
7310  case TID_BOOL:
7311  ival = str.toInt(&ok);
7312  if (!ok) { // conversion error
7313  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_BOOL is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7314  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7315  return false;
7316  }
7317  if ((ival != 1) && (ival != 0)) { // range error 0 or 1
7318  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_BOOL; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7319  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7320  return false;
7321  }
7322  break;
7323  case TID_FLOAT:
7324  fval = str.toFloat(&ok);
7325  if (!ok) { // conversion error
7326  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_FLOAT is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7327  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7328  return false;
7329  }
7330  break;
7331  case TID_DOUBLE:
7332  dval = str.toDouble(&ok);
7333  if (!ok) { // conversion error
7334  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_DOUBLE is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7335  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7336  return false;
7337  }
7338  break;
7339  case TID_STRING:
7340  break;
7341  default:
7342  QString err = QString("PLemAutoRun::CheckOdbType: Do not now how to handle key type %1 of an ODB_SET_DATA cmd. See line no %2").arg(type).arg(arc->lineNo);
7343  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7344  return false;
7345  break;
7346  }
7347 
7348  return true;
7349 }
7350 
7351 //**********************************************************************
7352 // CheckForOdbSetDataCmds
7353 //**********************************************************************
7362 {
7363  PAutoRunCmdVector::Iterator iter;
7364 
7365  // go through all the cmd's and check for setOdbData cmds in order to perform the
7366  // necessary tests **before** starting the autorun.
7367  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
7368  if (iter->cmd == "setOdbData") {
7369  // check if set path makes sense
7370  PKey *setKey = 0;
7371  QString setPath = iter->param[0];
7372  setKey = new PKey(fExp, setPath);
7373  if (!setKey->IsValid()) { // key not found
7374  // error message
7375  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: Couldn't access ODB set key %1 from the ODB_SET_DATA cmd.").arg(iter->param[0]);
7376  emit StatusMsg(err);
7377  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7378  // clean up
7379  if (setKey) {
7380  delete setKey;
7381  setKey = 0;
7382  }
7383  return;
7384  }
7385 
7386  // check if the set index is within bounds
7387  if (!iter->param[1].isEmpty()) { // i.e. set_key_index is present
7388  int index = iter->param[1].toInt();
7389  if (index > setKey->GetNumValues()) { // index out of range
7390  // error message
7391  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: ODB_SET_DATA set index '%1' out of range (%2)!").arg(iter->param[1]).arg(setKey->GetNumValues());
7392  emit StatusMsg(err);
7393  emit ErrorMsg(1, 0, LAR_MIDAS_ODB_FAILURE, -1, err);
7394  // clean up
7395  if (setKey) {
7396  delete setKey;
7397  setKey = 0;
7398  }
7399  return;
7400  }
7401  }
7402 
7403  // check if the data type makes sense
7404  if (!CheckOdbType(setKey->GetType(), iter)) {
7405  // clean up
7406  if (setKey) {
7407  delete setKey;
7408  setKey = 0;
7409  }
7410  return;
7411  }
7412 
7413  // check if there is a readback part
7414  if (!iter->param[3].isEmpty()) { // i.e. odb_readback_key_path is present
7415 
7416  // get read path and check for aliases
7417  QString readPath = iter->param[3];;
7418 
7419  PKey *readKey = new PKey(fExp, readPath);
7420  if (!readKey->IsValid()) { // key not found
7421  // error message
7422  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: Couldn't access ODB read key %1 from the ODB_SET_DATA cmd.").arg(iter->param[3]);
7423  emit StatusMsg(err);
7424  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7425  // clean up
7426  if (setKey) {
7427  delete setKey;
7428  setKey = 0;
7429  }
7430  if (readKey) {
7431  delete readKey;
7432  readKey = 0;
7433  }
7434  return;
7435  }
7436 
7437  if (!iter->param[4].isEmpty()) {
7438  int index = iter->param[4].toInt();
7439  if (index > readKey->GetNumValues()) { // index out of range
7440  // error message
7441  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: ODB_SET_DATA read index '%1'' out of range (%2)!").arg(index).arg(readKey->GetNumValues());
7442  emit StatusMsg(err);
7443  emit ErrorMsg(1, 0, LAR_MIDAS_ODB_FAILURE, -1, err);
7444  // clean up
7445  if (setKey) {
7446  delete setKey;
7447  setKey = 0;
7448  }
7449  if (readKey) {
7450  delete readKey;
7451  readKey = 0;
7452  }
7453  return;
7454  }
7455  }
7456  // clean up
7457  if (readKey) {
7458  delete readKey;
7459  readKey = 0;
7460  }
7461  }
7462 
7463  // clean up
7464  if (setKey) {
7465  delete setKey;
7466  setKey = 0;
7467  }
7468  }
7469 
7470  if (iter->cmd == "setOdbDataArray") {
7471  // check if set path makes sense
7472  PKey *setKey = 0;
7473  QString setPath = iter->param[0];
7474  setKey = new PKey(fExp, setPath);
7475  if (!setKey->IsValid()) { // key not found
7476  // error message
7477  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: Couldn't access ODB set key %1 from the ODB_SET_DATA_ARRAY cmd.").arg(iter->param[0]);
7478  emit StatusMsg(err);
7479  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7480  // clean up
7481  if (setKey) {
7482  delete setKey;
7483  setKey = 0;
7484  }
7485  return;
7486  }
7487 
7488  // check type
7489  bool ok;
7490  QString type;
7491  for (int i=1; i<iter->noElements; i++) {
7492  // get out what type the key is in order to convert the set value string
7493  switch (setKey->GetType()) {
7494  case TID_BYTE:
7495  type = "TID_BYTE";
7496  if (iter->param[i].length() > 1)
7497  ok = false;
7498  break;
7499  case TID_CHAR:
7500  type = "TID_CHAR";
7501  if (iter->param[i].length() > 1)
7502  ok = false;
7503  break;
7504  case TID_SBYTE:
7505  type = "TID_SBYTE";
7506  if (iter->param[i].length() > 1)
7507  ok = false;
7508  break;
7509  case TID_WORD:
7510  type = "TID_WORD";
7511  iter->param[i].toInt(&ok);
7512  break;
7513  case TID_SHORT:
7514  type = "TID_SHORT";
7515  iter->param[i].toInt(&ok);
7516  break;
7517  case TID_DWORD:
7518  type = "TID_DWORD";
7519  iter->param[i].toInt(&ok);
7520  break;
7521  case TID_INT:
7522  type = "TID_INT";
7523  iter->param[i].toInt(&ok);
7524  break;
7525  case TID_BOOL:
7526  type = "TID_BOOL";
7527  iter->param[i].toInt(&ok);
7528  break;
7529  case TID_FLOAT:
7530  type = "TID_FLOAT";
7531  iter->param[i].toFloat(&ok);
7532  break;
7533  case TID_DOUBLE:
7534  type = "TID_DOUBLE";
7535  iter->param[i].toDouble(&ok);
7536  break;
7537  default:
7538  type = "TID_STRING";
7539  return;
7540  }
7541  if (!ok) { // error occured
7542  // error message
7543  QString err = QString("CheckForOdbSetDataCmds: Wrong data type of element '%1', should be '%2'").arg(iter->param[i]).arg(type);
7544  emit StatusMsg(err);
7545  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7546  }
7547  }
7548 
7549  // make sure that the number of elements fit
7550  if (iter->noElements-1 != setKey->GetNumValues()) {
7551  // error message
7552  QString err = QString("CheckForOdbSetDataCmds: Wrong number of element '%1', should be '%2'").arg(iter->noElements-1).arg(setKey->GetNumValues());
7553  emit StatusMsg(err);
7554  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7555  }
7556 
7557  // clean up
7558  if (setKey) {
7559  delete setKey;
7560  setKey = 0;
7561  }
7562  }
7563  }
7564 }
7565 
7566 //**********************************************************************
7567 // SetOdbData
7568 //**********************************************************************
7578 {
7579  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7580  msg += arc->cmdString;
7581  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7582 
7583  msg = QString("Autorun running: ") + msg;
7584  emit StatusMsg(msg);
7585 
7586  // convert all the necessary values
7587  int timeout = 0;
7588  double tolerance = 0.0;
7589  int ival = 0;
7590  float fval = 0.0;
7591  double dval = 0.0;
7592  double setVal;
7593  char sval[256];
7594  int typeTag = 0; // 0 = int etc.; 1 = float; 2 = double; 3 = string
7595  int setIndex;
7596  int readIndex;
7597 
7598  // check odb set path for alias
7599  QString setPath = arc->param[0];
7600 
7601  if (!arc->param[5].isEmpty()) // timeout given
7602  timeout = arc->param[5].toInt() * 1000; // timeout in (ms)
7603 
7604  if (!arc->param[6].isEmpty()) // tolerance given
7605  tolerance = arc->param[6].toDouble();
7606 
7607  // open set key
7608  PKey *setKey = 0;
7609  setKey = new PKey(fExp, setPath);
7610  if (!setKey->IsValid()) { // key not found
7611  // error message
7612  QString err = QString("PLemAutoRun::SetOdbData: Couldn't access ODB set key %1 from the ODB_SET_DATA cmd.").arg(arc->param[0]);
7613  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7614  // clean up
7615  if (setKey) {
7616  delete setKey;
7617  setKey = 0;
7618  }
7619  return;
7620  }
7621 
7622  // get out what type the key is in order to convert the set value string
7623  switch (setKey->GetType()) {
7624  case TID_BYTE:
7625  case TID_CHAR:
7626  case TID_SBYTE:
7627  case TID_WORD:
7628  case TID_SHORT:
7629  case TID_DWORD:
7630  case TID_INT:
7631  case TID_BOOL:
7632  ival = arc->param[2].toInt();
7633  setVal = ival;
7634  typeTag = 0;
7635  break;
7636  case TID_FLOAT:
7637  fval = arc->param[2].toFloat();
7638  setVal = fval;
7639  typeTag = 1;
7640  break;
7641  case TID_DOUBLE:
7642  dval = arc->param[2].toDouble();
7643  setVal = dval;
7644  typeTag = 2;
7645  break;
7646  case TID_STRING:
7647  typeTag = 3;
7648  break;
7649  default:
7650  return;
7651  }
7652 
7653  // open read key if needed
7654  PKey *readKey = 0;
7655  if (!arc->param[3].isEmpty()) { // i.e. odb_readback_key_path is present
7656  QString readPath = arc->param[3];
7657 
7658  readKey = new PKey(fExp, readPath);
7659  if (!readKey->IsValid()) { // key not found
7660  // error message
7661  QString err = QString("PLemAutoRun::SetOdbData: Couldn't access ODB read key %1 from the ODB_SET_DATA cmd.").arg(arc->param[3]);
7662  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7663  // clean up
7664  if (setKey) {
7665  delete setKey;
7666  setKey = 0;
7667  }
7668  if (readKey) {
7669  delete readKey;
7670  readKey = 0;
7671  }
7672  return;
7673  }
7674  }
7675 
7676  // set value
7677  if (arc->param[1].isEmpty()) { // no index given
7678  switch (typeTag) {
7679  case 0: // int etc.
7680  setKey->SetData(&ival, 1, setKey->GetType());
7681  break;
7682  case 1: // float
7683  setKey->SetData(&fval, 1, setKey->GetType());
7684  break;
7685  case 2: // double
7686  setKey->SetData(&dval, 1, setKey->GetType());
7687  break;
7688  case 3: // int etc.
7689  strcpy(sval, arc->param[2].toLatin1().data());
7690  setKey->SetData(sval, 1, setKey->GetType());
7691  break;
7692  default:
7693  break;
7694  }
7695  } else { // index given
7696  setIndex = arc->param[1].toInt();
7697  switch (typeTag) {
7698  case 0: // int etc.
7699  setKey->SetDataIndex(&ival, setIndex, setKey->GetType());
7700  break;
7701  case 1: // float
7702  setKey->SetDataIndex(&fval, setIndex, setKey->GetType());
7703  break;
7704  case 2: // double
7705  setKey->SetDataIndex(&dval, setIndex, setKey->GetType());
7706  break;
7707  case 3: // int etc.
7708  strcpy(sval, arc->param[2].toLatin1().data());
7709  setKey->SetDataIndex(sval, setIndex, setKey->GetType());
7710  break;
7711  default:
7712  break;
7713  }
7714  }
7715 
7716  if (readKey) { // readback key given, i.e. not only set ODB value, but compare it with its readback value
7717  // check if read index is given
7718  if (!arc->param[4].isEmpty())
7719  readIndex = arc->param[4].toInt();
7720  else
7721  readIndex = -1;
7722 
7723  QTime time;
7724  bool done = false;
7725  INT size;
7726  double readVal = 0.0;
7727 
7728  time.start();
7729  do {
7730  // get value
7731  if (readIndex < 0) { // not an array
7732  switch (readKey->GetType()) {
7733  case TID_BYTE:
7734  case TID_CHAR:
7735  case TID_SBYTE:
7736  case TID_WORD:
7737  case TID_SHORT:
7738  case TID_DWORD:
7739  case TID_INT:
7740  case TID_BOOL:
7741  size = sizeof(ival);
7742  readKey->GetData(&ival, &size, readKey->GetType());
7743  readVal = ival;
7744  break;
7745  case TID_FLOAT:
7746  size = sizeof(fval);
7747  readKey->GetData(&fval, &size, readKey->GetType());
7748  readVal = fval;
7749  break;
7750  case TID_DOUBLE:
7751  size = sizeof(dval);
7752  readKey->GetData(&dval, &size, readKey->GetType());
7753  readVal = dval;
7754  break;
7755  default:
7756  break;
7757  }
7758  } else { // value from an array
7759  switch (readKey->GetType()) {
7760  case TID_BYTE:
7761  case TID_CHAR:
7762  case TID_SBYTE:
7763  case TID_WORD:
7764  case TID_SHORT:
7765  case TID_DWORD:
7766  case TID_INT:
7767  case TID_BOOL:
7768  size = sizeof(ival);
7769  readKey->GetDataIndex(&ival, &size, readIndex, readKey->GetType());
7770  readVal = ival;
7771  break;
7772  case TID_FLOAT:
7773  size = sizeof(fval);
7774  readKey->GetDataIndex(&fval, &size, readIndex, readKey->GetType());
7775  readVal = fval;
7776  break;
7777  case TID_DOUBLE:
7778  size = sizeof(dval);
7779  readKey->GetDataIndex(&dval, &size, readIndex, readKey->GetType());
7780  readVal = dval;
7781  break;
7782  default:
7783  break;
7784  }
7785  }
7786 
7787  // check if job is done
7788  if (fabs(setVal-readVal) < tolerance) {
7789  done = true;
7790  }
7791 
7792  // sleep for 2 sec before reading the next value
7793  Wait(2000);
7794  } while((time.elapsed() < timeout) && !done);
7795 
7796  if (!done) { // timeout fired before job was done
7797  QString err = QString("WARNING: Couldn't reach demand value: | demand = %1 - measured = %2 | > %3 after timeout of %4 (sec) was reached.").arg(setVal).arg(readVal).arg(tolerance).arg(timeout/1000.0);
7798  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
7799  return;
7800  }
7801  }
7802 
7803  // clean up
7804  if (setKey) {
7805  delete setKey;
7806  setKey = 0;
7807  }
7808  if (readKey) {
7809  delete readKey;
7810  readKey = 0;
7811  }
7812 
7813  // increment command counter
7815 }
7816 
7817 //**********************************************************************
7818 // SetOdbDataArray
7819 //**********************************************************************
7826 {
7827  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7828  msg += arc->cmdString;
7829  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7830 
7831  msg = QString("Autorun running: ") + msg;
7832  emit StatusMsg(msg);
7833 
7834  // check odb set path for alias
7835  QString setPath = arc->param[0];
7836 
7837  // open set key
7838  PKey *setKey = 0;
7839  setKey = new PKey(fExp, setPath);
7840  if (!setKey->IsValid()) { // key not found
7841  // error message
7842  QString err = QString("PLemAutoRun::SetOdbData: Couldn't access ODB set key %1 from the ODB_SET_DATA cmd.").arg(arc->param[0]);
7843  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7844  // clean up
7845  if (setKey) {
7846  delete setKey;
7847  setKey = 0;
7848  }
7849  return;
7850  }
7851 
7852  // fill data
7853  float *data = new float[arc->noElements-1];
7854  for (int i=1; i<arc->noElements; i++)
7855  data[i-1] = arc->param[i].toFloat();
7856 
7857  // set it in ODB
7858  setKey->SetData(data, arc->noElements-1, TID_FLOAT);
7859 
7860  // clean up
7861  if (data) {
7862  delete data;
7863  data = 0;
7864  }
7865  if (setKey) {
7866  delete setKey;
7867  setKey = 0;
7868  }
7869 
7870  // increment command counter
7872 }
7873 
7874 //**********************************************************************
7875 // SetSampleHV
7876 //**********************************************************************
7883 {
7884  int size;
7885  int i;
7886  float value;
7887  float demand;
7888  QString msg("");
7889 
7890  // check if FUG handling is disabled in lemAutoRun
7891  if (!fEnabled["fug_scfe"]) {
7892  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7893  msg += arc->cmdString;
7894  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
7895  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7896  // increment command counter
7898  return;
7899  }
7900  // check if FUG equipment is disabled in lemAutoRun
7901  if (!fEnabled["fug_eq"]) {
7902  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7903  msg += "PLemAutoRun::SetSampleHV: FUG equipment disabled in lemAutoRun. Will do nothing here.";
7904  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7905  // increment command counter
7907  return;
7908  }
7909 
7910  // check if the hv_fug_scfe frontend is running
7911  CheckClients();
7912  if (!fHVFeRunning) { // error too severe to going on
7914  QString err = QString("PLemAutoRun::SetSampleHV: Slowcontrol Frontend NOT running.\n")+
7915  QString(" Error too severe, will stop.");
7916  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
7918  QCoreApplication::exit(0);
7919  exit(0);
7920  }
7921 
7922  // send command notifier
7923  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7924  msg += arc->cmdString;
7925  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7926 
7927  msg = QString("Autorun running: ") + msg;
7928  emit StatusMsg(msg);
7929 
7930  // Loop over set HV. This is done this way to reduce hangers due to network problems
7931  for (i=0; i<HV_FUG_MAX_TRY; i++) {
7932  // set sample hv
7933  size = sizeof(value);
7934  value = arc->param[0].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
7935  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_SAMPLE, TID_FLOAT);
7936 
7937  if (fFugHvCheck) {
7938  // check that the final sample hv is reached reached it
7939  bool done = false;
7940  bool happy = false;
7941  float timeout = fHVTimeout * 1e3;
7942  QTime t;
7943  t.start();
7944  demand = value; // keep demand hv
7945  do {
7946  // sleep for 5 sec before reading the next value
7947  Wait(5000);
7948 
7949  // read sample hv
7950  size = sizeof(value);
7951  fHVMeasuredKey->GetDataIndex(&value, &size, HV_FUG_SAMPLE, TID_FLOAT);
7952 
7953  // check if final sample hv is reached
7954  if (fabs(demand-value) < fHVAccuracy) { // final hv reached within fHVAccuracy
7955  done = true;
7956  happy = true;
7957  }
7958 
7959  // check if too much time elapsed to reach the final sample hv
7960  if (t.elapsed() > timeout) {
7961  done = true; // quit loop
7962  // emit warning
7963  msg = QString("Sample HV of demand=%1 (kV) was not reached (measured=%2 (kV)) within %3 sec: will give it another try in 120 sec.").arg(demand).arg(value).arg(fHVTimeout);
7964  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
7965  }
7966  } while (!done);
7967 
7968  if (happy) // everything is OK, get out of the loop
7969  break;
7970 
7971  // wait 120 sec before retrial
7972  Wait(120000);
7973  } else { // NO FUG HV check, hence just wait a 1 min
7974  Wait(60000);
7975  break;
7976  }
7977  }
7978 
7979  if (i == HV_FUG_MAX_TRY) {
7981  // emit error
7982  msg = QString("Couldn't set Sample HV of %1 (kV), even after a few trials :-( .").arg(demand);
7983  emit ErrorMsg(1, 0, LAR_SAMPLE_HV_NOT_REACHED, arc->lineNo, msg);
7984  }
7985 
7986  // increment command counter
7988 }
7989 
7990 //**********************************************************************
7991 // SetRA_HV
7992 //**********************************************************************
8000 {
8001  int size;
8002  int i;
8003  float value[4];
8004  float demand[4];
8005  QString msg("");
8006 
8007  // check if FUG handling is disabled in lemAutoRun
8008  if (!fEnabled["fug_scfe"]) {
8009  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8010  msg += arc->cmdString;
8011  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
8012  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8013  // increment command counter
8015  return;
8016  }
8017  // check if FUG equipment is disabled in lemAutoRun
8018  if (!fEnabled["fug_eq"]) {
8019  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8020  msg += "PLemAutoRun::SetRA_HV: FUG equipment disabled in lemAutoRun. Will do nothing here.";
8021  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8022  // increment command counter
8024  return;
8025  }
8026 
8027  // check if the hv_fug_scfe frontend is running
8028  CheckClients();
8029  if (!fHVFeRunning) { // error too severe to going on
8031  QString err = QString("PLemAutoRun::SetRA_HV: Slowcontrol Frontend NOT running.\n")+
8032  QString(" Error too severe, will stop.");
8033  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
8035  QCoreApplication::exit(0);
8036  exit(0);
8037  }
8038 
8039  // send command notifier
8040  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8041  msg += arc->cmdString;
8042  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8043 
8044  msg = QString("Autorun running: ") + msg;
8045  emit StatusMsg(msg);
8046 
8047  // Loop over set HV. This is done this way to reduce hangers due to network problems
8048  for (i=0; i<HV_FUG_MAX_TRY; i++) {
8049  // set RA HV left
8050  size = sizeof(float);
8051  value[0] = arc->param[0].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8052  fHVDemandKey->SetDataIndex((void *)&value[0], HV_FUG_RAL, TID_FLOAT);
8053  // set RA HV right
8054  size = sizeof(float);
8055  value[1] = arc->param[1].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8056  fHVDemandKey->SetDataIndex((void *)&value[1], HV_FUG_RAR, TID_FLOAT);
8057  if (arc->noElements == 4) {
8058  // set RA HV top
8059  size = sizeof(float);
8060  value[2] = arc->param[2].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8061  fHVDemandKey->SetDataIndex((void *)&value[2], HV_FUG_RAT, TID_FLOAT);
8062  // set RA HV bottom
8063  size = sizeof(float);
8064  value[3] = arc->param[3].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8065  fHVDemandKey->SetDataIndex((void *)&value[3], HV_FUG_RAB, TID_FLOAT);
8066  }
8067 
8068  if (fFugHvCheck) {
8069  // check that the final sample hv is reached reached it
8070  bool done = false;
8071  bool happy = false;
8072  float timeout = fHVTimeout * 1e3;
8073  QTime t;
8074  t.start();
8075  // keep demand hv
8076  for (int j=0; j<arc->noElements; j++) {
8077  demand[j] = value[j];
8078  }
8079 
8080  do {
8081  // sleep for 5 sec before reading the next value
8082  Wait(5000);
8083 
8084  // read RA left HV
8085  size = sizeof(float);
8086  fHVMeasuredKey->GetDataIndex(&value[0], &size, HV_FUG_RAL, TID_FLOAT);
8087  // read RA right HV
8088  size = sizeof(float);
8089  fHVMeasuredKey->GetDataIndex(&value[1], &size, HV_FUG_RAR, TID_FLOAT);
8090  if (arc->noElements == 4) { // L,R,T,B given
8091  // read RA top HV
8092  size = sizeof(float);
8093  fHVMeasuredKey->GetDataIndex(&value[2], &size, HV_FUG_RAT, TID_FLOAT);
8094  // read RA bottom HV
8095  size = sizeof(float);
8096  fHVMeasuredKey->GetDataIndex(&value[3], &size, HV_FUG_RAB, TID_FLOAT);
8097  }
8098 
8099  // check if final RA hv's are reached
8100  if (arc->noElements == 4) { // L,R,T,B given
8101  if ((fabs(demand[0]-value[0]) < fHVAccuracy) &&
8102  (fabs(demand[1]-value[1]) < fHVAccuracy) &&
8103  (fabs(demand[2]-value[2]) < fHVAccuracy) &&
8104  (fabs(demand[3]-value[3]) < fHVAccuracy)) { // final hv reached within fHVAccuracy
8105  done = true;
8106  happy = true;
8107  }
8108  } else {// L,R given
8109  if ((fabs(demand[0]-value[0]) < fHVAccuracy) &&
8110  (fabs(demand[1]-value[1]) < fHVAccuracy)) { // final hv reached within fHVAccuracy
8111  done = true;
8112  happy = true;
8113  }
8114  }
8115 
8116  // check if too much time elapsed to reach the final sample hv
8117  if (t.elapsed() > timeout) {
8118  done = true; // quit loop
8119  // emit warning
8120  if (arc->noElements == 2) { // L,R given
8121  msg = QString("RA HV of demand=(%1/%2), measured=(%3/%4) (kV), was not reached within %5 sec: will give it another try in 120 sec.").arg(demand[0]).arg(demand[1]).arg(value[0]).arg(value[1]).arg(fHVTimeout);
8122  } else { // L,R,T,B given
8123  msg = QString("RA HV of demand=(%1/%2/%3/%4), measured=(%5/%6/%7/%8) (kV), was not reached within %9 sec: will give it another try in 120 sec.").arg(demand[0]).arg(demand[1]).arg(demand[2]).arg(demand[3]).arg(value[0]).arg(value[1]).arg(value[2]).arg(value[3]).arg(fHVTimeout);
8124  }
8125  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
8126  }
8127  } while (!done);
8128 
8129  if (happy) // everything is OK, get out of the loop
8130  break;
8131 
8132  // wait 120 sec before retrial
8133  Wait(120000);
8134  } else { // NO FUG HV check, hence just wait a 1 min
8135  Wait(60000);
8136  break;
8137  }
8138  }
8139 
8140  if (i == HV_FUG_MAX_TRY) {
8142  if (arc->noElements == 2) { // L,R given
8143  msg = QString("RA HV of (%1/%2) (kV), was not reached even after several trials :-( ").arg(arc->param[0]).arg(arc->param[1]);
8144  } else { // L,R,T,B given
8145  msg = QString("RA HV of (%1/%2/%3/%4) (kV), was not reached even after several trials :-( ").arg(arc->param[0]).arg(arc->param[1]).arg(arc->param[2]).arg(arc->param[3]);
8146  }
8147  emit ErrorMsg(1, 0, LAR_SAMPLE_HV_NOT_REACHED, arc->lineNo, msg);
8148  }
8149 
8150  // increment command counter
8152 }
8153 
8154 //**********************************************************************
8155 // CheckForTransportHvCmd
8156 //**********************************************************************
8167 {
8168  PAutoRunCmdVector::Iterator iter;
8169 
8170  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
8171  if (iter->cmd == "setTransportHV") {
8172  // check if the hv setting file exists
8173  QString filePath = fHvSettingsPath + iter->param[0];
8174  QFileInfo fileInfo(filePath);
8175  if (!fileInfo.exists()) {
8176  QString msg = filePath + QString(" does not exist! Fix that first!");
8177  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
8178 
8179  UpdateWebPage(iter, HTML_PARSE_ERROR, iter->lineNo, msg);
8180 
8181  msg = QString("Autorun stopped: Skript failure");
8182  emit StatusMsg(msg);
8183 
8184  return false;
8185  }
8186 
8187  // check the file is a proper hv setting file
8188  if (!LoadHvSettings(iter, filePath, iter->lineNo, true)) {
8189  return false;
8190  }
8191  }
8192  }
8193 
8194  return true;
8195 }
8196 
8197 //**********************************************************************
8198 // LoadHvSettings
8199 //**********************************************************************
8209 bool PLemAutoRun::LoadHvSettings(PAutoRunCmdVector::Iterator iter, QString fln, int lineNo, bool simulated)
8210 {
8211  // check if FUG equipment is disabled in lemAutoRun
8212  if (!fEnabled["fug_eq"]) {
8213  return true;
8214  }
8215 
8216  // try to load the HV settings file
8217  if (!QFile::exists(fln)) {
8218  QString err = "lemAutoRun: Couldn't find HV setting file: " + fln;
8219  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, err);
8220  return false;
8221  }
8222 
8223  PLemHvSettingsFileParser handler;
8224  QFile xmlFile(fln);
8225  QXmlInputSource source( &xmlFile );
8226  QXmlSimpleReader reader;
8227  reader.setContentHandler( &handler );
8228  reader.parse( source );
8229 
8230  QString errMsg = "";
8231  if (!handler.isValid(errMsg)) {
8232  UpdateWebPage(iter, HTML_PARSE_ERROR, iter->lineNo, errMsg);
8233 
8234  QString err = "lemAutoRun: Couldn't read HV setting file: " + fln;
8235  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, errMsg);
8236 
8237  return false;
8238  }
8239 
8240  if (simulated)
8241  return true;
8242 
8243  QVector<int> *hvCh = handler.GetChNo();
8244  QVector<float> *hvDemand = handler.GetHvDemands();
8245  QVector<float> *currentLimit = handler.GetCurrentLimits();
8246 
8247  float *pHvDemand = (float*)malloc(hvDemand->size()*sizeof(float));
8248  float *pCurrentLimit = (float*)malloc(currentLimit->size()*sizeof(float));
8249  float *pHvMeasured = (float*)malloc(hvDemand->size()*sizeof(float));
8250 
8251  for (int i=0; i<hvCh->size(); i++) {
8252  pHvDemand[hvCh->at(i)-1] = hvDemand->at(i);
8253  pCurrentLimit[hvCh->at(i)-1] = currentLimit->at(i);
8254  }
8255 
8256  // set current limit values
8257  QString path = QString("/Equipment/HV/Settings/Current Limit");
8258  PKey currentLimitKey(fExp, path);
8259  if (!currentLimitKey.IsValid()) {
8260  errMsg = "**ERROR** couldn't obtain the current limit ODB key";
8261 
8262  UpdateWebPage(iter, HTML_PARSE_ERROR, iter->lineNo, errMsg);
8263 
8264  QString err = "lemAutoRun: Couldn't read HV setting file: " + fln;
8265  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, errMsg);
8266 
8267  // clean up
8268  free(pHvDemand);
8269  free(pCurrentLimit);
8270 
8271  return false;
8272  }
8273  currentLimitKey.SetData(pCurrentLimit, currentLimit->size(), TID_FLOAT);
8274 
8275  // set HV values
8276  fHVDemandKey->SetData(pHvDemand, hvDemand->size(), TID_FLOAT);
8277 
8278  if (fFugHvCheck) {
8279  // make sure that the demanded HV's are actually reached within a given time
8280  bool done = false;
8281  QVector<int> hv_reached;
8282  hv_reached.resize(hvDemand->size());
8283  for (int i=0; i<hv_reached.size(); i++)
8284  hv_reached[i] = 0;
8285  float timeout = fHVTimeout * 1e3;
8286  QTime t;
8287  t.start();
8288  int size;
8289  do {
8290  // sleep for 5 sec before reading the next value
8291  Wait(5000);
8292 
8293  // get the measured HV's
8294  size = hvDemand->size()*sizeof(float);
8295  fHVMeasuredKey->GetData(pHvMeasured, &size, TID_FLOAT);
8296 
8297  // check if the HV's reached the demand values
8298  size = 0;
8299  for (int i=0; i<hvDemand->size(); i++) {
8300  if (fabs(pHvDemand[i]-pHvMeasured[i]) < fHVAccuracy) { // final hv reached within fHVAccuracy
8301  hv_reached[i] = 1;
8302  }
8303  size += hv_reached[i];
8304  }
8305 
8306  // if all HV's reached their demand values
8307  if (size == (int)hvDemand->size())
8308  done = true;
8309 
8310  // check if too much time elapsed to reach the final HV settings
8311  if (t.elapsed() > timeout) {
8312  done = true; // quit loop
8313  // emit warning
8314  QString msg = QString("HV settings could not be reached within %3 sec.").arg(fHVTimeout);
8315  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, lineNo, msg);
8316  }
8317  } while (!done);
8318  } else { // NO FUG HV check, hence just wait a 1 min
8319  Wait(60000);
8320  }
8321 
8322  // clean up
8323  free(pHvDemand);
8324  free(pCurrentLimit);
8325  free(pHvMeasured);
8326 
8327  return true;
8328 }
8329 
8330 //**********************************************************************
8331 // SetTransportHV
8332 //**********************************************************************
8339 {
8340  QString msg("");
8341 
8342  // check if FUG handling is disabled in lemAutoRun
8343  if (!fEnabled["fug_scfe"]) {
8344  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8345  msg += arc->cmdString;
8346  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
8347  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8348  // increment command counter
8350  return;
8351  }
8352  // check if FUG equipment is disabled in lemAutoRun
8353  if (!fEnabled["fug_eq"]) {
8354  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8355  msg += "PLemAutoRun::SetTransportHV: FUG equipment disabled in lemAutoRun. Will do nothing here.";
8356  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8357  // increment command counter
8359  return;
8360  }
8361 
8362  // send command notifier
8363  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8364  msg += arc->cmdString;
8365  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8366 
8367  msg = QString("Autorun running: ") + msg;
8368  emit StatusMsg(msg);
8369 
8370  QString filePath = fHvSettingsPath + arc->param[0];
8371  LoadHvSettings(arc, filePath, arc->lineNo);
8372 
8373  // increment command counter
8375 }
8376 
8377 //**********************************************************************
8378 // SetHvOff
8379 //**********************************************************************
8384 {
8385  QString msg("");
8386 
8387  // check if FUG handling is disabled in lemAutoRun
8388  if (!fEnabled["fug_scfe"]) {
8389  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8390  msg += arc->cmdString;
8391  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
8392  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8393  // increment command counter
8395  return;
8396  }
8397  // check if FUG equipment is disabled in lemAutoRun
8398  if (!fEnabled["fug_eq"]) {
8399  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8400  msg += "PLemAutoRun::SetHvOff: FUG equipment disabled in lemAutoRun. Will do nothing here.";
8401  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8402  // increment command counter
8404  return;
8405  }
8406 
8407  // send command notifier
8408  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8409  msg += arc->cmdString;
8410  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8411 
8412  msg = QString("Autorun running: ") + msg;
8413  emit StatusMsg(msg);
8414 
8415  int size;
8416  float fval[4] = {0.0, 0.0, 0.0, 0.0};
8417  QTime t;
8418  float timeout = 300 * 1e3; // 5 min
8419  bool done=false;
8420  if (arc->param[0].contains("mc", Qt::CaseInsensitive)) {
8421  // switch off FUG's in the MC
8422  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down FUG HV's in the Moderator Chamber ...");
8423  cm_yield(0);
8424  for (int i=HV_FUG_MOD; i<=HV_FUG_MIRROR; i++)
8425  fHVDemandKey->SetDataIndex((void *)&fval[0], i, TID_FLOAT);
8426  // switch off MCP1 HV
8427  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down MCP1 HV in the Moderator Chamber ...");
8428  cm_yield(0);
8429  fHVDetectorDemandKey->SetDataIndex((void *)&fval[0], HV_NHQ_MCP1, TID_FLOAT);
8430  // wait until MCP1 HV is small enough
8431  t.start();
8432  do {
8433  // sleep for 5 sec before reading the next value
8434  Wait(5000);
8435 
8436  // read MCP1 HV
8437  size = sizeof(float);
8438  fHVDetectorMeasuredKey->GetDataIndex(&fval[0], &size, HV_NHQ_MCP1, TID_FLOAT);
8439 
8440  if (fabs(fval[0]) < 0.3) {
8441  done = true;
8442  }
8443 
8444  // check if too much time elapsed to reach the final sample hv
8445  if (t.elapsed() > timeout) {
8446  done = true; // quit loop
8447  // emit warning
8448  msg = QString("HV_OFF MC: demand=0.0kV [measured=(%5/%6/%7/%8) (kV)] was not reached within 180 sec. will go to the next command.").arg(fval[0]).arg(fval[1]).arg(fval[2]).arg(fval[3]);
8449  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
8450  }
8451  } while (!done);
8452  } else if (arc->param[0].contains("tc", Qt::CaseInsensitive)) {
8453  // switch off FUG's in the TC
8454  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down FUG HV's in the Trigger Chamber ...");
8455  cm_yield(0);
8456  // Spin Rot Off
8457  for (int i=HV_FUG_RIGHT_RODS; i<=HV_FUG_RIGHT_PLATE; i++)
8458  fHVDemandKey->SetDataIndex((void *)&fval[0], i, TID_FLOAT);
8459  for (int i=HV_FUG_LENSE_2; i<=HV_FUG_LENSE_3; i++)
8460  fHVDemandKey->SetDataIndex((void *)&fval[0], i, TID_FLOAT);
8461  // switch off TD HV
8462  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down TD HV's in the Trigger Chamber ...");
8463  cm_yield(0);
8464  for (int i=HV_NHQ_TD_FIRST; i<=HV_NHQ_TD_LAST; i++)
8465  fHVDetectorDemandKey->SetDataIndex((void *)&fval[0], i, TID_FLOAT);
8466  // wait until TD HV is small enough
8467  t.start();
8468  do {
8469  // sleep for 5 sec before reading the next value
8470  Wait(5000);
8471 
8472  // read TD HV's
8473  for (int i=HV_NHQ_TD_FIRST; i<=HV_NHQ_TD_LAST; i++) {
8474  size = sizeof(float);
8475  fHVDetectorMeasuredKey->GetDataIndex(&fval[i], &size, i, TID_FLOAT);
8476  }
8477 
8478  if ((fabs(fval[0]) < 0.3) && (fabs(fval[1]) < 0.3) && (fabs(fval[2]) < 0.3) && (fabs(fval[4]) < 0.3)) {
8479  done = true;
8480  }
8481 
8482  // check if too much time elapsed to reach the final sample hv
8483  if (t.elapsed() > timeout) {
8484  done = true; // quit loop
8485  // emit warning
8486  msg = QString("HV_OFF TC: demand=0.0kV [measured=(%5/%6/%7/%8) (kV)] was not reached within 180 sec. will go to the next command.").arg(fval[0]).arg(fval[1]).arg(fval[2]).arg(fval[3]);
8487  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
8488  }
8489  } while (!done);
8490  } else if (arc->param[0].contains("sc", Qt::CaseInsensitive)) {
8491  // switch off FUG's in the SC
8492  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down FUG HV's in the Trigger Chamber ...");
8493  cm_yield(0);
8494  for (int i=HV_FUG_RAL; i<=HV_FUG_SAMPLE; i++)
8495  fHVDemandKey->SetDataIndex((void *)&fval, i, TID_FLOAT);
8496  }
8497 
8498  // increment command counter
8500 }
8501 
8502 //**********************************************************************
8503 // SetSampleLS340ZoneSettings
8504 //**********************************************************************
8511 {
8512  // check if sample equipment is disabled in lemAutoRun
8513  if (!fEnabled["sample_eq"]) {
8514  return;
8515  }
8516 
8517  PAutoRunCmdVector::Iterator iter;
8518  bool check_needed = false;
8519  int status, size;
8520 
8521  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
8522  if (iter->cmd == "setTemp") {
8523  check_needed = true;
8524  break;
8525  }
8526  }
8527 
8528  if (!check_needed) // no check needed: get out of here
8529  return;
8530 
8531  // check if CMODE==2, i.e. ZONE setting active
8532  // if yes -> overwrite potential rubbish
8533  // if no -> it is the experimenters business what he/she is doing
8534  float cmode;
8535  size = sizeof(cmode);
8536  fSampleOutputKey->GetDataIndex(&cmode, &size, LS340_OUTPUT_HEATER_MODE, TID_FLOAT);
8537  if (cmode != 2) // control mode different than ZONE setting -> nothing to be done
8538  return;
8539 
8540  // get ZONE settings key
8541  PKey *zoneKey;
8542  QString str = QString("/Equipment/SampleCryo/Settings/Devices/Lake340_Sample_0/DD/Zone/Zone");
8543 
8544  zoneKey = new PKey(fExp, str);
8545  if (!zoneKey->IsValid()) {
8546  QString err = QString("sample cryo ZONE settings key not found.");
8547  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
8548  return;
8549  }
8550 
8551  // get current demand temperature
8552  float temp;
8553  size = sizeof(float);
8554  fSampleOutputKey->GetDataIndex(&temp, &size, LS340_OUTPUT_SETPOINT, TID_FLOAT);
8555 
8556  char zone_str[32];
8557  size = sizeof(zone_str);
8558  float loop, zone, top_value, p_pid, i_pid, d_pid, mount_value, range;
8559  for (int i=0; i<10; i++) {
8560  // get ith zone setting
8561  zoneKey->GetDataIndex(zone_str, &size, i, TID_STRING);
8562  // extract parameters
8563  status = sscanf(zone_str, "%f,%f,%f,%f,%f,%f,%f,%f", &loop, &zone, &top_value,
8564  &p_pid, &i_pid, &d_pid, &mount_value, &range);
8565  if (status != 8) {
8566  QString err = QString("Couldn't extract sample cryo ZONE settings (%1/%2).").arg(status).arg(zone_str);
8567  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
8568  return;
8569  }
8570  if (temp < top_value) // found proper zone
8571  break;
8572  }
8573 
8574  // set all the proper parameters
8575  fSampleOutputKey->SetDataIndex(&p_pid, LS340_OUTPUT_PID_P ,TID_FLOAT);
8576  fSampleOutputKey->SetDataIndex(&i_pid, LS340_OUTPUT_PID_I ,TID_FLOAT);
8577  fSampleOutputKey->SetDataIndex(&d_pid, LS340_OUTPUT_PID_D ,TID_FLOAT);
8578  fSampleOutputKey->SetDataIndex(&range, LS340_OUTPUT_HEATER_RANGE ,TID_FLOAT);
8579  float mode = 2; // ZONE settings
8580  fSampleOutputKey->SetDataIndex(&mode, LS340_OUTPUT_HEATER_MODE ,TID_FLOAT);
8581 }
8582 
8583 //**********************************************************************
8584 // NeedleValve (Konti-Cryos only)
8585 //**********************************************************************
8591 float PLemAutoRun::NeedleValve(float Tset)
8592 {
8593  float value;
8594 
8595  if ( Tset < 8.0 ) {
8597  } else {
8598  if ( Tset < 10.0 ) {
8600  } else {
8601  // Test changes of ranges
8602  if ( Tset < 20.0 ) {
8604  } else {
8606  }
8607  }
8608  }
8609 
8610  if (fDebug) {
8611  cm_msg(MINFO,"NeedleValve", "NeedleValve: demand = %e", value);
8612  cm_yield(0);
8613  }
8614 
8615  if ( value > 100.0 )
8616  value = 100.0;
8617 
8618  if ( value < fPrefNeedleValveCof_4_0 )
8619  value = fPrefNeedleValveCof_4_0;
8620  return value;
8621 }
8622 
8623 //**********************************************************************
8624 // Empirical_Flow (Konti-Cryos only)
8625 //**********************************************************************
8632 float PLemAutoRun::EmpiricalFlow(float Tset, float rampSpeed)
8633 {
8634  float demandflow;
8635 
8636  demandflow = fBHFlowTemp / (Tset + fBHFlowTempOffset) + fBHFlowOffset
8637  /* speed of ramp in K/sec */
8638  + (rampSpeed / 60.0) *
8639  /* heat capacity in J/K */
8640  ( fHeatCapCof1 * Tset
8641  + fHeatCapCof2 * Tset * Tset
8642  + fHeatCapCof3 * Tset * Tset * Tset )
8643  /* d(flow)/dP in BH_units / Watt */
8644  * (fDFlowDp0 + fDFlowDp1 * exp( fDFlowDpExp * log(Tset)));
8645 
8646  if (fDebug) {
8647  cm_msg(MINFO,"EmpircalFlow", "EmpiricalFlow: demandflow = %e", demandflow);
8648  cm_yield(0);
8649  }
8650 
8651  if ( demandflow > fBHMaxFlow )
8652  demandflow = fBHMaxFlow;
8653 
8654  if ( demandflow < fBHMinFlow )
8655  demandflow = fBHMinFlow;
8656 
8657  return demandflow;
8658 }
8659 
8660 
8661 //**********************************************************************
8662 // SetDemandTempRamping
8663 //**********************************************************************
8669 float PLemAutoRun::SetDemandTempRamping(QString rampParam)
8670 {
8671  float rampSpeed=0.0;
8672  float value=0.0;
8673 
8674  if (!rampParam.isEmpty()) { // demand temp ramp given
8675  rampSpeed = rampParam.toFloat();
8676  }
8677 
8678  fSampleOutputKey->SetDataIndex((void *)&rampSpeed, LS340_OUTPUT_RAMP, TID_FLOAT);
8679 
8680  // check that the demand temperature ramping is indeed set (for maximal 1 min).
8681  QTime t;
8682  t.start();
8683  do {
8684  if (value == fSampleInput[LS340_INPUT_RAMP])
8685  break;
8686  Wait(1000);
8687  } while (t.elapsed() < 60e3);
8688 
8689  return rampSpeed;
8690 }
8691 
8692 //**********************************************************************
8693 // SetFlowAndNeedleValve (Konti-Cryos only)
8694 //**********************************************************************
8717 void PLemAutoRun::SetFlowAndNeedleValve(QString flowParam, float &rampSpeed, float newDemandTemp,
8718  float deltaT, float flowScale)
8719 {
8720  float value;
8721 
8722  if (rampSpeed == 0.0) { // no ramping
8723  if (!flowParam.isEmpty()) { // Flow
8724  value = flowParam.toFloat();
8725  } else { // no explicit flow was given will get the empirical one
8726  value = EmpiricalFlow(newDemandTemp, 0.0);
8727  }
8728  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
8729  value = NeedleValve(newDemandTemp);
8730  SampleTempSetNeedleValve(value);
8731  } else { // ramping
8732  // calculate the flow according to the new setpoint
8733  if (!flowParam.isEmpty()) { // flow explicitly given
8734  value = newDemandTemp / fSampleInput[LS340_INPUT_SETPOINT] * (flowParam.toFloat() - fBHFlowOffset) + fBHFlowOffset;
8735  } else { // no explicit flow was given will get the empirical one
8737  // correct flow to the optimized one
8738  value *= (flowScale-1.0)*(fSampleInput[LS340_INPUT_SETPOINT]-newDemandTemp)/deltaT+1.0;
8739  }
8740  // set flow
8741  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
8742 
8743  //
8744  // Do not set the needlevalve in case of ramping, leave that to ConsiderNeedleValve
8745  //
8746  // value = NeedleValve(fSampleInput[LS340_INPUT_SETPOINT]);
8747  // SampleTempSetNeedleValve(value);
8748  // check if final setpoint is reached, than it is necessary to disable flow ramping,
8749  // since otherwise the flow adjustment will not work!
8750  if (fabs(fSampleInput[LS340_INPUT_SETPOINT] - newDemandTemp) < 0.1)
8751  rampSpeed = 0.0;
8752  }
8753 }
8754 
8755 
8756 //**********************************************************************
8757 // SetFlow (LowTemp only)
8758 //**********************************************************************
8764 void PLemAutoRun::SetFlow(QString flowParam)
8765 {
8766  if (flowParam.isEmpty())
8767  return;
8768 
8769  float value = flowParam.toFloat();
8770 
8771  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
8772 }
8773 
8774 //**********************************************************************
8775 // SetLS340Mode
8776 //**********************************************************************
8784 {
8785  float value;
8786 
8787  // check if it is necessary to switch the LS340 from CMODE == 2 (Zone), i.e. internal settings
8788  // to CMODE == 1 (manual PID) or vice versa
8789  if (!arc->param[TEMP_HEATER_RANGE].isEmpty() || !arc->param[TEMP_P_PID].isEmpty() ||
8790  !arc->param[TEMP_I_PID].isEmpty() || !arc->param[TEMP_D_PID].isEmpty()) { // parameters given which require CMODE==1
8792  value = LS340_CTRL_PID;
8793  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_HEATER_MODE, TID_FLOAT);
8794  }
8795  } else { // no parameters given, switch to CMODE == 2 (Zone) if necessary
8797  value = LS340_CTRL_ZONE;
8798  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_HEATER_MODE, TID_FLOAT);
8799  }
8800  }
8801 }
8802 
8803 //**********************************************************************
8804 // SetLS340HeaterRangeAndPIDs
8805 //**********************************************************************
8813 {
8814  float value;
8815 
8816  if (!arc->param[TEMP_HEATER_RANGE].isEmpty()) { // heater Range
8817  value = arc->param[TEMP_HEATER_RANGE].toFloat();
8818  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_HEATER_RANGE, TID_FLOAT);
8819  }
8820  if (!arc->param[TEMP_P_PID].isEmpty()) { // P
8821  value = arc->param[TEMP_P_PID].toFloat();
8822  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_PID_P, TID_FLOAT);
8823  }
8824  if (!arc->param[TEMP_I_PID].isEmpty()) { // I
8825  value = arc->param[TEMP_I_PID].toFloat();
8826  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_PID_I, TID_FLOAT);
8827  }
8828  if (!arc->param[TEMP_D_PID].isEmpty()) { // D
8829  value = arc->param[TEMP_D_PID].toFloat();
8830  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_PID_D, TID_FLOAT);
8831  }
8832 }
8833 
8834 //**********************************************************************
8835 // WaitUntilSampleLS340Ready
8836 //**********************************************************************
8841 {
8842  int size, status;
8843  QTime t;
8844 
8845  // check if the DD is happy at the moment
8846  t.start();
8847  do {
8848  size = sizeof(status);
8849  fSampleNoConnectionKey->GetData((void *)&status, &size, TID_INT);
8850  if (!status) { // connection OK
8851  break;
8852  }
8853  Wait(5000);
8854  } while (t.elapsed() < 300e3); // try for 5 min.
8855 }
8856 
8857 //**********************************************************************
8858 // SetLS340Setpoint
8859 //**********************************************************************
8866 void PLemAutoRun::SetLS340Setpoint(float setpoint, float rampSpeed)
8867 {
8868  QTime t;
8869 
8870  // set the temperature setpoint
8871  fSampleOutputKey->SetDataIndex((void *)&setpoint, LS340_OUTPUT_SETPOINT, TID_FLOAT);
8872 
8873  // check that the readback setpoint is the demand one before going on if no demand temp ramping
8874  Wait(3000);
8875  if (rampSpeed == 0.0) { // no ramping
8876  float fvalue;
8877  bool setpoint_readback_failure = true;
8878  t.start();
8879  do {
8880  if (fabs(setpoint - fSampleInput[LS340_INPUT_SETPOINT])<1.0e-4) {
8881  setpoint_readback_failure = false;
8882  break;
8883  }
8884  // set the temperature setpoint again (the additional tiny random number is necessary
8885  // otherwise MIDAS will not do anything).
8886  fvalue = setpoint + 1.0e-4 * (float)rand()/(float)RAND_MAX;
8887  fSampleOutputKey->SetDataIndex((void *)&fvalue, LS340_OUTPUT_SETPOINT, TID_FLOAT);
8888  Wait(5000);
8889  } while (t.elapsed() < 600e3);
8890  if (setpoint_readback_failure) {
8892  QString err = QString("setTemp: Couldn't get new setpoint readback value within 10 min!");
8893  emit ErrorMsg(1, 0, LAR_MIDAS_READBACK_FAILURE, -1, err);
8894  }
8895  }
8896 }
8897 
8898 //**********************************************************************
8899 // SetLS340Setpoint
8900 //**********************************************************************
8906 void PLemAutoRun::SetOmegaSetpoint(float setpoint)
8907 {
8908  QTime t;
8909 
8910  // set the temperature setpoint
8911  fSampleOvenOmegaOutputKey->SetDataIndex((void *)&setpoint, OMEGA_OVEN_OUTPUT_SETPOINT, TID_FLOAT);
8912 
8913  // check that the readback setpoint is the demand one before going on if no demand temp ramping
8914  Wait(3000);
8915 
8916  float fvalue;
8917  bool setpoint_readback_failure = true;
8918  t.start();
8919  do {
8920  if (fabs(setpoint - fSampleOvenOmegaInput[OMEGA_OVEN_INPUT_SETPOINT])<1) {
8921  setpoint_readback_failure = false;
8922  break;
8923  }
8924  // set the temperature setpoint again (the additional tiny random number is necessary
8925  // otherwise MIDAS will not do anything).
8926  fvalue = setpoint + 1.0e-4 * (float)rand()/(float)RAND_MAX;
8927  fSampleOvenOmegaOutputKey->SetDataIndex((void *)&fvalue, OMEGA_OVEN_OUTPUT_SETPOINT, TID_FLOAT);
8928  Wait(5000);
8929  } while (t.elapsed() < 600e3);
8930  if (setpoint_readback_failure) {
8932  QString err = QString("setTempOvenOmega: Couldn't get new setpoint readback value within 10 min!");
8933  emit ErrorMsg(1, 0, LAR_MIDAS_READBACK_FAILURE, -1, err);
8934  }
8935 }
8936 
8937 //**********************************************************************
8938 // SetFlowTweak (Konti-Cryos only)
8939 //**********************************************************************
8946 {
8947  QTime t;
8948 
8949  fSampleOutputKey->SetDataIndex((void *)&flow, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
8950 
8951  t.start();
8952  do {
8953  // wait a bit and feed the watchdog
8954  Wait(2000); // sleep 2 sec
8955 
8956  // check temperature stability and feed history buffer
8958  } while (t.elapsed() > fFlowTimeoutReduction);
8959 }
8960 
8961 //**********************************************************************
8962 // SetTfl
8963 //**********************************************************************
8969 {
8970  QString msg("");
8971 
8972  // check if tfl equipment is disabled in lemAutoRun
8973  if (!fEnabled["tfl_eq"]) {
8974  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8975  msg += "PLemAutoRun::SetHvOff: TFL equipment disabled in lemAutoRun. Will do nothing here.";
8976  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8977  // increment command counter
8979  return;
8980  }
8981 
8982  float tfl_pos = arc->param[0].toFloat();
8983  float tfl_mode = arc->param[1].toFloat();
8984 
8985  if (fDebug)
8986  cout << endl << "in SetTfl ...";
8987 
8988  // check that tfl_scfe is running
8989  CheckClients();
8990  if (!fTflFeRunning) {
8992  QString err = QString("PLemAutoRun::SetTfl: TFL Slowcontrol Frontend NOT running.\n")+
8993  QString(" Error too severe, will stop.");
8994  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
8996  QCoreApplication::exit(0);
8997  exit(0);
8998  }
8999 
9000  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9001  msg += arc->cmdString;
9002  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9003 
9004  msg = QString("Autorun running: ") + msg;
9005  emit StatusMsg(msg);
9006 
9007  // set mode value
9008  fTflOutputKey->SetDataIndex((void*)&tfl_mode, SM_MODUS_NEEDLEVALVE, TID_FLOAT);
9009 
9010  ss_sleep(200);
9011 
9012  // set NV position
9013  fTflOutputKey->SetDataIndex((void*)&tfl_pos, SM_OUTPUT_NEEDLEVALVE, TID_FLOAT);
9014 
9015  // no readback NV position check will be done
9016 
9017  // increment command counter
9019 }
9020 
9021 //**********************************************************************
9022 // SetTemp
9023 //**********************************************************************
9030 {
9031  int size;
9032  float value;
9033  float newDemandTemp;
9034  float newDemandFlow = -1.0;
9035  float currentPID_D;
9036  float rampSpeed = 0.0;
9037  QTime t;
9038  QString msg("");
9039 
9040  // check if sample equipment is disabled in lemAutoRun
9041  if (!fEnabled["sample_eq"]) {
9042  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9043  msg += "PLemAutoRun::SetTemp: sample equipment disabled in lemAutoRun. Will do nothing here.";
9044  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9045  // increment command counter
9047  return;
9048  }
9049 
9050  if (fDebug)
9051  cout << endl << "in SetTemp ...";
9052 
9053  // get the name of the current Cryo/Oven
9054  char cryoName[NAME_LENGTH];
9055  size = sizeof(cryoName);
9056  fSampleCryoKey->GetData(cryoName, &size, TID_STRING);
9057  if (QString(cryoName).startsWith("omega", Qt::CaseInsensitive)) {
9058  SetTempOvenOmega(arc);
9059  return;
9060  }
9061 
9062  // keep temp stability tolerance
9063  fSampleTempAccuracy = arc->param[TEMP_DELTA_T].toFloat();
9064 
9065  // before do anything, check if the currently set demand temperature is the same as
9066  // the target demand temperature. Furthermore check if the target demand temperature
9067  // and the currently measured temperature are within fSampleTempAccuracy.
9068  // If both conditions are fullfilled, do not do anything and just get out
9069  newDemandTemp = arc->param[TEMP_DEMAND_TEMP].toFloat();
9070  if ((fabs(newDemandTemp-fSampleInput[LS340_INPUT_SETPOINT]) < fSampleTempAccuracy) &&
9071  (fabs(newDemandTemp-fSampleInput[fSampleCtrlCh]) < fSampleTempAccuracy)) {
9072  // notify that the command is executed
9073  QString msg = QString("(%1/%2) TEMP ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9074  for (int i=0; i<arc->noElements; i++) {
9075  msg += arc->param[i];
9076  if (i<arc->noElements-1)
9077  msg += ", ";
9078  }
9079  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9080  // increment command counter
9082  // get out of here
9083  return;
9084  }
9085 
9086  // set the temperature unstable flag to true
9087  fSampleTempUnstable = true;
9088 
9089  if (fDebug)
9090  cout << endl << "in SetTemp: will check clients ...";
9091 
9092  // check if the sample_scfe is running
9093  CheckClients();
9094  if (!fSampleFeRunning) { // error too severe to going on
9096  QString err = QString("PLemAutoRun::SetTemp: Slowcontrol Frontend NOT running.\n")+
9097  QString(" Error too severe, will stop.");
9098  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9100  QCoreApplication::exit(0);
9101  exit(0);
9102  }
9103 
9104  // check if the sample controller is remote
9105  if (fSampleOutput[LS340_OUTPUT_REMOTE] == 0.0) { // not remote
9107  QString err = QString("PLemAutoRun::SetTemp: LakeShore is not remote.\n")+
9108  QString(" Error too severe, will stop.");
9109  emit ErrorMsg(1, 0, LAR_MIDAS_DEVICE_NOT_REMOTE, -1, err);
9111  QCoreApplication::exit(0);
9112  exit(0);
9113  }
9114 
9115  // notify that the command is executed
9116  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9117  msg += arc->cmdString;
9118  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9119 
9120  msg = QString("Autorun running: ") + msg;
9121  emit StatusMsg(msg);
9122 
9123  if (fDebug)
9124  cout << endl << "in SetTemp: check lemvac and BPVX/Y positions ...";
9125 
9126  if (fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
9127  // check if lemvac_scfe is running
9128  if (!fLemvacFeRunning) { // error too severe to going on
9130  QString err = QString("PLemAutoRun::SetTemp: Lemvac NOT running. Error too severe, will stop.");
9131  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9133  QCoreApplication::exit(0);
9134  exit(0);
9135  }
9136 
9137  // get BPV settings (both valves)
9138  if (!GetBPV()) {
9140  QString err = QString("PLemAutoRun::SetTemp: Couldn't read BPVX/Y. Error too severe, will stop.");
9141  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9142  }
9143 
9145  // close BPVX
9146  if (!SetBPV(BPVX, BPV_CLOSE)) {
9148  QString err = QString("PLemAutoRun::SetTemp: Couldn't close BPVX. Error too severe, will stop.");
9149  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9150  }
9151  }
9152  }
9153 
9154  // keep new demand temperature
9155  newDemandTemp = arc->param[TEMP_DEMAND_TEMP].toFloat();
9156 
9157  // set demand temperature and check stability. The procedure is different for increasing or decreasing
9158  // temperature.
9159  if (newDemandTemp-fSampleInput[fSampleCtrlCh] > 0.0) { // increasing temperature ******************
9160 
9161  if (fDebug)
9162  cout << endl << "in SetTemp: increasing temperature ..." << endl;
9163 
9164  // check if it is necessary to shut down the hv's and to close BPVY
9165  if (fDebug)
9166  cout << endl << "in SetTemp: check if it is necessary to shut down the hv's and to close BPVY ...";
9167  bool shut = false;
9168  // requested demand more than fMaxTempIncrease (K) higher than current one, need to shut HV
9169  // fMaxTempIncrease is defined in the startup XML.
9170  if ((newDemandTemp-fSampleInput[fSampleCtrlCh] > fMaxTempIncrease) && fEnabled["fug_eq"]) {
9171  shut = true;
9172 
9173  // get HV's from the sample region
9174  if (fDebug)
9175  cout << endl << "in SetTemp: get HV's from the sample region ...";
9177 
9178  // shut down the sample HV's
9179  if (fDebug)
9180  cout << endl << "in SetTemp: shut down the sample HV's ...";
9181  ChangeSampleChamberHV(true);
9182  }
9183 
9184  if (fDebug)
9185  cout << endl << "in SetTemp: set demand temperature, ramping, flow ...";
9186 
9187  // set demand temperature ramping if wished
9188  rampSpeed = SetDemandTempRamping(arc->param[TEMP_RAMP]);
9189 
9190  float flowScale;
9191  float deltaT;
9192  if (fSampleCryoInUse == CRYO_KONTI) {
9193  // factor needed to pick up the flow at its current value if ramping is used
9194  // current BH flow divided by the estimated flow for the current temperature
9195  flowScale = fSampleOutput[fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW] / EmpiricalFlow(fSampleInput[LS340_INPUT_SETPOINT], 0.0);
9196  // temperature difference between the current temperature and the new demand temperature, need: see comment above
9197  deltaT = fSampleInput[LS340_INPUT_SETPOINT] - newDemandTemp;
9198 
9199  // set the new bronkhorst flow and needle valve
9200  if (fDebug)
9201  cout << endl << "in SetTemp: set the new bronkhorst flow and needle valve ...";
9202  SetFlowAndNeedleValve(arc->param[TEMP_FLOW], rampSpeed, newDemandTemp, deltaT, flowScale);
9203  } else if (fSampleCryoInUse == CRYO_LOWTEMP) {
9204  SetFlow(arc->param[TEMP_FLOW]);
9205  }
9206 
9207  // set the parameters of the LS340 -------------------------------------------
9208  if (fDebug)
9209  cout << endl << "in SetTemp: set the parameters of the LS340 ...";
9210 
9211  // set the control mode of the LS340 (see 'User's Manual' p.9-28)
9212  SetLS340Mode(arc);
9213 
9214  // set heaterRange, PID's
9216 
9217  // wait 1 sec
9218  Wait(1000);
9219 
9220  // check if the DD is happy at the moment
9222 
9223  SetLS340Setpoint(newDemandTemp, rampSpeed);
9224 
9225  // get the current D from the PID
9226  currentPID_D = fSampleInput[LS340_INPUT_PID_D];
9227  // set D to zero while approaching the temperature
9228  value = 0.0;
9229  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_PID_D, TID_FLOAT);
9230 
9231  // check and tweak temperature until stability is reached or timeout happend
9232  if (fDebug)
9233  cout << endl << "in SetTemp: check and tweak temperature until stability is reached or timeout happend ...";
9234  bool done = false;
9235  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9236  QTime t_flow_set;
9237  t.start();
9238  t_flow_set.start();
9239  do {
9240 
9241  if (fSampleCryoInUse == CRYO_KONTI) {
9242  // if ramping, adjust the flow according to the current temperature
9243  SetFlowAndNeedleValve(arc->param[TEMP_FLOW], rampSpeed, newDemandTemp, deltaT, flowScale);
9244  }
9245 
9246  // time to set the D value back
9248  if (fabs(value-fSampleInput[fSampleCtrlCh])/value < fDSetRatio) {
9249  fSampleOutputKey->SetDataIndex((void *)&currentPID_D, LS340_OUTPUT_PID_D, TID_FLOAT);
9250  }
9251 
9252  // check temperature stability and feed history buffer
9254 
9255  if (fSampleCryoInUse == CRYO_KONTI) {
9256  // see if a flow tweaking is needed
9257  if (t_flow_set.elapsed() >= fTimeoutFlowSet) {
9260  t_flow_set.start(); // restart timer
9261  }
9262  }
9263 
9264  // wait a bit and feed the watchdog
9265  Wait(2000); // sleep 2 sec
9266 
9267  if (t.elapsed() > timeout) { // timeout fired
9268  QString err = QString("PLemAutoRun::SetTemp: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9269  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9270  emit ErrorMsg(1, 0, LAR_LS340_TEMP_NOT_STABLE, -1, err);
9271  done = true;
9272  }
9273 
9274  if (SampleTempStable())
9275  done = true;
9276  } while (!done);
9277 
9278  // if HV is shut down: (i) open BPVY, than (ii) ramp sample HV's back
9279  if (fDebug)
9280  cout << endl << "in SetTemp: if HV is shut down: (i) open BPVY, than (ii) ramp sample HV's back ...";
9281  if (shut) {
9282  // ramp sample region HV's back
9283  ChangeSampleChamberHV(false);
9284  }
9285 
9286  } else { // decreasing temperature ****************************************************************
9287 
9288  if (fDebug)
9289  cout << endl << "in SetTemp: decreasing temperature ..." << endl;
9290 
9291  // set the parameters of the LS340 -------------------------------------------
9292  if (fDebug)
9293  cout << endl << "in SetTemp: set the parameters of the LS340 ...";
9294 
9295  // set the control mode of the LS340 (see 'User's Manual' p.9-28)
9296  SetLS340Mode(arc);
9297 
9298  // set demand temperature ramping if wished, if not, it is set to zero
9299  // this assures that cooling down is a quick procedure even ramping was set
9300  // previously and the user has forgotten to set it to zero.
9301  rampSpeed = SetDemandTempRamping(arc->param[TEMP_RAMP]);
9302 
9303  // check if the DD is happy at the moment
9305 
9306  // set the temperature setpoint
9307  SetLS340Setpoint(newDemandTemp, rampSpeed);
9308 
9309  // wait 1 sec
9310  Wait(1000);
9311 
9312  // set heaterRange, PID's
9314 
9315  // wait 1 sec
9316  Wait(1000);
9317 
9318  // get ramping
9319  value = 0.0;
9320  size = sizeof(value);
9321  fSampleInputKey->GetDataIndex((void *)&value, &size, LS340_INPUT_RAMP, TID_FLOAT);
9322  if ((value == 0.0) && arc->param[TEMP_FLOW].isEmpty()) { // no ramping and no flow given: the normal case
9323  // get the current D from the PID
9324  currentPID_D = fSampleInput[LS340_INPUT_PID_D];
9325  // set D to zero while approaching the temperature
9326  value = 0.0;
9327  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_PID_D, TID_FLOAT);
9328 
9329  if (fSampleCryoInUse == CRYO_KONTI) {
9330  // check what temporary flow is needed and set it (only if ramping is NOT enabled!!)
9331  if (newDemandTemp > 50.0)
9332  value = 1.0e4;
9333  else
9334  value = 3.0e4;
9335  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9336  fLargeFlow = true;
9337  // Needle valve should be set to the maximum value here, otherwise we will not reach the high flow
9338  value = 95.0;
9339  SampleTempSetNeedleValve(value);
9340  }
9341 
9342  // check and tweak temperature until stability is reached or timeout happend
9343  if (fDebug)
9344  cout << endl << "in SetTemp: check and tweak temperature until stability is reached or timeout happend ...";
9345  bool done = false;
9346  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9347  // get the new bronkhorst flow value
9348  if (fSampleCryoInUse == CRYO_KONTI) {
9349  if (!arc->param[TEMP_FLOW].isEmpty()) { // Flow given explicitly
9350  newDemandFlow = arc->param[TEMP_FLOW].toFloat();
9351  } else { // no explicit flow was given will get the empirical one
9352  newDemandFlow = fBHFlowTemp / (newDemandTemp + fBHFlowTempOffset) + fBHFlowOffset;
9353  }
9354  }
9355 
9356  QTime t_flow_set;
9357  t.start();
9358  do {
9359  if (fSampleCryoInUse == CRYO_KONTI) {
9360  // start reducing the flow if getting close to the setpoint
9361  if (((fSampleInput[fSampleCtrlCh] - newDemandTemp) / newDemandTemp < fFlowSetRatio) &&
9362  ((fSampleInput[fSampleCtrlCh] - newDemandTemp) < fFlowSetAbsolute) &&
9363  fLargeFlow) {
9364 
9365  // set the needle valve to temperature set point
9366  value = NeedleValve(newDemandTemp);
9367  SampleTempSetNeedleValve(value);
9368 
9369  // reduce to 1.5 * the final flow
9370  value = 1.5 * newDemandFlow;
9371  SetFlowTweak(value);
9372 
9373  // reduce to 1.2 * the final flow
9374  value = 1.2 * newDemandFlow;
9375  SetFlowTweak(value);
9376 
9377  // reduce to 1.1 * the final flow
9378  value = 1.1 * newDemandFlow;
9379  SetFlowTweak(value);
9380 
9381  // reduce to the final flow
9382  value = newDemandFlow;
9383  SetFlowTweak(value);
9384 
9385  fLargeFlow = false;
9386 
9387  // the following is needed in the situation where the previous demand temp is too close
9388  // to the newDemandTemp. What happens then? The TFL NV is still opening and is not
9389  // accepting the new closing command already, hence the TFL NV is set once more here
9390 
9391  // wait a bit and feed the watchdog
9392  Wait(5000); // sleep 5 sec
9393 
9394  // set the needle valve to temperature set point
9395  value = NeedleValve(newDemandTemp)-0.01;
9396  SampleTempSetNeedleValve(value);
9397  }
9398  }
9399 
9400  // time to set the D value back
9402  if (fabs(value-fSampleInput[fSampleCtrlCh])/value < fDSetRatio) {
9403  fSampleOutputKey->SetDataIndex((void *)&currentPID_D, LS340_OUTPUT_PID_D, TID_FLOAT);
9404  }
9405 
9406  // check temperature stability and feed history buffer
9408 
9409  if (fSampleCryoInUse == CRYO_KONTI) {
9410  // see if a flow tweaking is needed
9411  if (t_flow_set.elapsed() >= fTimeoutFlowSet) {
9414  t_flow_set.start(); // restart timer
9415  }
9416  }
9417 
9418  // wait a bit and feed the watchdog
9419  Wait(2000); // sleep 2 sec
9420 
9421  if (t.elapsed() > timeout) { // timeout fired
9422  QString err = QString("PLemAutoRun::SetTemp: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9423  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9424  emit ErrorMsg(1, 0, LAR_LS340_TEMP_NOT_STABLE, -1, err);
9425  done = true;
9426  }
9427 
9428  if (SampleTempStable())
9429  done = true;
9430  } while (!done);
9431 
9432  } else { // ramping enabled for cooling down or flow explicitly given!!
9433  // Here it is not possible to increase to flow initially
9434 
9435  if (fDebug)
9436  cout << endl << "in SetTemp: ramping enabled for cooling down or flow explicitly given ...";
9437 
9438  if (fSampleCryoInUse == CRYO_KONTI) {
9439  // get the new bronkhorst flow value and set it
9440  if (!arc->param[TEMP_FLOW].isEmpty()) { // Flow
9441  newDemandFlow = arc->param[TEMP_FLOW].toFloat();
9442  } else { // no explicit flow was given will get the empirical one
9443  newDemandFlow = EmpiricalFlow(fSampleInput[LS340_INPUT_SETPOINT], rampSpeed);
9444  }
9445  } else if (fSampleCryoInUse == CRYO_LOWTEMP) {
9446  // get the new bronkhorst flow value and set it
9447  if (!arc->param[TEMP_FLOW].isEmpty()) { // Flow
9448  newDemandFlow = arc->param[TEMP_FLOW].toFloat();
9449  } else { // flow not explicitly given, get the currently set one
9450  size = sizeof(newDemandFlow);
9451  fSampleOutputKey->GetDataIndex(&newDemandFlow, &size, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9452  }
9453  }
9454 
9455  fSampleOutputKey->SetDataIndex((void *)&newDemandFlow, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9456 
9457  if (fSampleCryoInUse == CRYO_KONTI) {
9458  value = NeedleValve(fSampleInput[LS340_INPUT_SETPOINT]);
9459  if ( rampSpeed == 0.0 )
9460  SampleTempSetNeedleValve(value); // only if not ramping
9461  }
9462 
9463  // check and tweak temperature until stability is reached or timeout happend
9464  if (fDebug)
9465  cout << endl << "in SetTemp: check and tweak temperature until stability is reached or timeout happend ...";
9466  bool done = false;
9467  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9468  QTime t_flow_set;
9469  t.start();
9470  t_flow_set.start();
9471  do {
9472  if (fSampleCryoInUse == CRYO_KONTI) {
9473  // if ramping, adjust the flow according to the current temperature
9474  if (rampSpeed != 0.0) {
9475  // calculate the flow according to the new setpoint
9476  if (!arc->param[TEMP_FLOW].isEmpty()) // flow explicitly given
9477  value = newDemandTemp / fSampleInput[LS340_INPUT_SETPOINT] *
9478  (arc->param[TEMP_FLOW].toFloat() - fBHFlowOffset) + fBHFlowOffset;
9479  else { // no explicit flow was given will get the empirical one
9480  if ( t_flow_set.elapsed() >= fTimeoutFlowSet ) {
9483  Wait(500);
9484  t_flow_set.start(); // restart timer
9485  }
9486  value = EmpiricalFlow(fSampleInput[LS340_INPUT_SETPOINT], rampSpeed);
9487  }
9488 
9489  if (fDebug)
9490  cout << endl << "in SetTemp: set flow and adjust the needle valve of the transferline ...";
9491  // set flow
9492  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9493 
9494  // adjust needle valve
9496 
9497  // check if final setpoint is reached, than it is necessary to disable flow ramping,
9498  // since otherwise the flow adjustment will not work!
9499  if (fDebug)
9500  cout << endl << "in SetTemp: check if final setpoint is reached ...";
9501  if (fabs(fSampleInput[LS340_INPUT_SETPOINT] - newDemandTemp) < 0.1) {
9502  // gradually reduce the flow to steady value if flow was not given explicitly
9503  if (fDebug)
9504  cout << endl << "in SetTemp: gradually reduce the flow to steady value if flow was not given explicitly ...";
9505  if (arc->param[TEMP_FLOW].isEmpty()) {
9506  float value2 = 0.3 * rampSpeed;
9507  value = EmpiricalFlow(fSampleInput[LS340_INPUT_SETPOINT], value2);
9508  SetFlowTweak(value);
9510 
9511  value2 = 0.2 * rampSpeed;
9512  value = EmpiricalFlow(fSampleInput[LS340_INPUT_SETPOINT], value2);
9513  SetFlowTweak(value);
9515 
9516  value2 = 0.1 * rampSpeed;
9517  value = EmpiricalFlow(fSampleInput[LS340_INPUT_SETPOINT], value2);
9518  SetFlowTweak(value);
9520 
9521  value2 = 0.0;
9522  value = EmpiricalFlow(fSampleInput[LS340_INPUT_SETPOINT], value2);
9523  SetFlowTweak(value);
9525  }
9526  rampSpeed = 0.0;
9527  }
9528  }
9529  }
9530 
9531  // check temperature stability and feed history buffer
9532  if (fDebug)
9533  cout << endl << "in SetTemp: check temperature stability and feed history buffer ...";
9535 
9536  if (fSampleCryoInUse == CRYO_KONTI) {
9537  // see if a flow tweaking is needed
9538  if (fDebug)
9539  cout << endl << "in SetTemp: see if a flow tweaking is needed ...";
9540  if (t_flow_set.elapsed() >= fTimeoutFlowSet) {
9543  t_flow_set.start(); // restart timer
9544  }
9545  }
9546 
9547  // wait a bit and feed the watchdog
9548  Wait(2000); // sleep 2 sec
9549 
9550  if (t.elapsed() > timeout) { // timeout fired
9551  QString err = QString("PLemAutoRun::SetTemp: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9552  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9553  emit ErrorMsg(1, 0, LAR_LS340_TEMP_NOT_STABLE, -1, err);
9554  done = true;
9555  }
9556 
9557  if (SampleTempStable())
9558  done = true;
9559  } while (!done);
9560  }
9561  }
9562 
9563  if (fEnabled["lemvac_scfe"]) { // only check if LEMVAC is enabled
9564  // only open the BPVX when it initially was open
9565  if (fDebug)
9566  cout << endl << "in SetTemp: only open the BPVX when it initially was open ...";
9568  // open BPVX
9569  if (!SetBPV(BPVX, BPV_OPEN)) {
9571  QString err = QString("PLemAutoRun::SetTemp: Couldn't open BPVX. Error too severe, will stop.");
9572  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9573  }
9574  }
9575  }
9576 
9577  // set the temperature unstable flag to false
9578  fSampleTempUnstable = false;
9579 
9580  // increment command counter
9582 }
9583 
9584 //**********************************************************************
9585 // SetTempOvenOmega
9586 //**********************************************************************
9593  float newDemandTemp;
9594  float rampSpeed = 0.0;
9595  QTime t;
9596  QString msg("");
9597 
9598  // check if omega equipment is disabled in lemAutoRun
9599  if (!fEnabled["omega_eq"]) {
9600  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9601  msg += "PLemAutoRun::SetTempOvenOmega: omega equipment disabled in lemAutoRun. Will do nothing here.";
9602  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9603  // increment command counter
9605  return;
9606  }
9607 
9608  // set the temperature unstable flag to true
9609  fSampleTempUnstable = true;
9610 
9611  // check if the sample_scfe is running
9612  CheckClients();
9613  if (!fSampleOvenOmegaFeRunning) { // error too severe to going on
9615  QString err = QString("PLemAutoRun::SetTempOvenOmega: Slowcontrol Frontend (Omega SC) NOT running. Error too severe, will stop.");
9616  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9618  QCoreApplication::exit(0);
9619  exit(0);
9620  }
9621 
9622  // notify that the command is executed
9623  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9624  msg += arc->cmdString;
9625  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9626 
9627  msg = QString("Autorun running: ") + msg;
9628  emit StatusMsg(msg);
9629 
9630  if (fDebug)
9631  cout << endl << "in SetTempOvenOmega: check lemvac and BPVX/Y positions ...";
9632 
9633  if (fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
9634  // check if lemvac_scfe is running
9635  if (!fLemvacFeRunning) { // error too severe to going on
9637  QString err = QString("PLemAutoRun::SetTemp: Lemvac NOT running. Error too severe, will stop.");
9638  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9640  QCoreApplication::exit(0);
9641  exit(0);
9642  }
9643 
9644  // get BPV settings (both valves)
9645  if (!GetBPV()) {
9647  QString err = QString("PLemAutoRun::SetTempOvenOmega: Couldn't read BPVX/Y. Error too severe, will stop.");
9648  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9649  }
9650 
9652  // close BPVX
9653  if (!SetBPV(BPVX, BPV_CLOSE)) {
9655  QString err = QString("PLemAutoRun::SetTempOvenOmega: Couldn't close BPVX. Error too severe, will stop.");
9656  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9657  }
9658  }
9659  }
9660 
9661  // keep new demand temperature
9662  newDemandTemp = arc->param[TEMP_DEMAND_TEMP].toFloat() - 273.16; // K -> °C
9663 
9664  // set demand temperature and check stability. The procedure is different for increasing or decreasing
9665  // temperature.
9666  if (newDemandTemp-fSampleOvenOmegaInput[OMEGA_OVEN_INPUT_TEMP] > 0.0) { // increasing temperature ******************
9667 
9668  if (fDebug)
9669  cout << endl << "in SetTempOvenOmega: increasing temperature ..." << endl;
9670 
9671  bool shut = false;
9672  // requested demand more than fMaxTempIncrease (K) higher than current one, need to shut HV
9673  // fMaxTempIncrease is defined in the startup XML.
9675  shut = true;
9676 
9677  // get HV's from the sample region
9678  if (fDebug)
9679  cout << endl << "in SetTempOvenOmega: get HV's from the sample region ...";
9681 
9682  // shut down the sample HV's
9683  if (fDebug)
9684  cout << endl << "in SetTempOvenOmega: shut down the sample HV's ...";
9685  ChangeSampleChamberHV(true);
9686  }
9687 
9688  if (fDebug)
9689  cout << endl << "in SetTempOvenOmega: set demand temperature, ramping, flow ...";
9690 
9691  // set demand temperature ramping if wished
9692  // NOT YET IMPLEMENTED
9693 
9694  // set the parameters of the LS340 -------------------------------------------
9695  if (fDebug)
9696  cout << endl << "in SetTempOvenOmega: set the parameters of the LS340 ...";
9697 
9698  // set heaterRange, PID's
9699  // NOT YET IMPLEMENTED
9700 
9701  // wait 1 sec
9702  Wait(1000);
9703 
9704  SetOmegaSetpoint(newDemandTemp);
9705 
9706  // check the temperature until stability is reached or timeout happend
9707  if (fDebug)
9708  cout << endl << "in SetTempOvenOmega: check and tweak temperature until stability is reached or timeout happend ...";
9709  bool done = false;
9710  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9711  int stabilityCounter = 0;
9712  t.start();
9713  do {
9714  // check temperature stability and feed history buffer
9716 
9717  // wait a bit and feed the watchdog
9718  Wait(5000); // sleep 5 sec
9719 
9720  if (t.elapsed() > timeout) { // timeout fired
9721  QString err = QString("PLemAutoRun::SetTempOvenOmega: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9722  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9723  emit ErrorMsg(1, 0, LAR_LS340_TEMP_NOT_STABLE, -1, err);
9724  done = true;
9725  }
9726 
9727  if (!fSampleTempUnstable) {
9728  stabilityCounter++;
9729  if (stabilityCounter == 60) // i.e. 5 min
9730  done = true;
9731  } else {
9732  stabilityCounter = 0;
9733  }
9734  } while (!done);
9735 
9736  // if HV is shut down: ramp sample HV's back
9737  if (fDebug)
9738  cout << endl << "in SetTempOvenOmega: if HV is shut down: ramp sample HV's back ...";
9739  if (shut) { // ramp sample region HV's back
9740  ChangeSampleChamberHV(false);
9741  }
9742  } else { // decreasing temperature ****************************************************************
9743 
9744  if (fDebug)
9745  cout << endl << "in SetTempOvenOmega: decreasing temperature ..." << endl;
9746 
9747  // set the parameters of the Omega -------------------------------------------
9748  if (fDebug)
9749  cout << endl << "in SetTempOvenOmega: set the parameters of the Omega ...";
9750 
9751  // set demand temperature ramping if wished
9752  // NOT YET IMPLEMENTED
9753 
9754  // set the temperature setpoint
9755  SetOmegaSetpoint(newDemandTemp);
9756 
9757  // wait 1 sec
9758  Wait(1000);
9759 
9760  // set PID's
9761  // NOT YET IMPLEMENTED
9762 
9763  // check and tweak temperature until stability is reached or timeout happend
9764  if (fDebug)
9765  cout << endl << "in SetTempOvenOmega: check the temperature until stability is reached or timeout happend ...";
9766  bool done = false;
9767  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9768  int stabilityCounter = 0;
9769  t.start();
9770  do {
9771  // check temperature stability and feed history buffer
9773 
9774  // wait a bit and feed the watchdog
9775  Wait(5000); // sleep 5 sec
9776 
9777  if (t.elapsed() > timeout) { // timeout fired
9778  QString err = QString("PLemAutoRun::SetTempOvenOmega: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9779  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9780  emit ErrorMsg(1, 0, LAR_LS340_TEMP_NOT_STABLE, -1, err);
9781  done = true;
9782  }
9783 
9784  if (!fSampleTempUnstable) {
9785  stabilityCounter++;
9786  if (stabilityCounter == 60) // i.e. 5 min
9787  done = true;
9788  } else {
9789  stabilityCounter = 0;
9790  }
9791  } while (!done);
9792  }
9793 
9794  if (fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
9795  // only open the BPVX when it initially was open
9796  if (fDebug)
9797  cout << endl << "in SetTempOvenOmega: only open the BPVX when it initially was open ...";
9799  // open BPVX
9800  if (!SetBPV(BPVX, BPV_OPEN)) {
9802  QString err = QString("PLemAutoRun::SetTempOvenOmega: Couldn't open BPVX. Error too severe, will stop.");
9803  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9804  }
9805  }
9806  }
9807 
9808  // set the temperature unstable flag to false
9809  fSampleTempUnstable = false;
9810 
9811  // increment command counter
9813 }
9814 
9815 //**********************************************************************
9816 // SetTitle
9817 //**********************************************************************
9824 {
9825  // arc->param:
9826  // 0 = title string of the title command
9827  // 1 = ODB_SAMPLE
9828  // 2 = ODB_TEMP
9829  // 3 = ODB_FIELD
9830  // 4 = ODB_TRANSP
9831  // 5 = ODB_HV_SAMP
9832  // 6 = ODB_ENERGY
9833  // 7 = ODB_RA_DIFF_LR
9834  // 8 = ODB_RA_DIFF_TB
9835  // 9 = ODB_SPIN_ROT
9836 
9837  int size;
9838  float fvalue;
9839  double dvalue;
9840  QString valueStr;
9841  QString msg("");
9842 
9843  // check if necessary ODB info is disabled in lemAutoRun
9844  if (!fEnabled["sample_name_info_odb"] || !fEnabled["sample_cryo_info_odb"]) {
9845  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9846  msg += "PLemAutoRun::SetTitle: not all necessary ODB settings are enabled in lemAutoRun. Will do nothing here.";
9847  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9848  // increment command counter
9850  return;
9851  }
9852 
9853  msg= QString("%1").arg(arc->param[0]);
9854 
9855  // check if odb tags are used
9856  if (arc->param[1] == "true") { // ODB_SAMPLE flag set
9857  char str[128];
9858  size = sizeof(str);
9859  if (fSampleNameKey)
9860  fSampleNameKey->GetData((void *)str, &size, TID_STRING);
9861  msg.replace("ODB_SAMPLE", str);
9862  }
9863  if (arc->param[2] == "true") { // ODB_TEMP flag set
9864  // get the name of the current Cryo/Oven
9865  char cryoName[NAME_LENGTH];
9866  size = sizeof(cryoName);
9867  if (fSampleCryoKey) {
9868  fSampleCryoKey->GetData(cryoName, &size, TID_STRING);
9869 
9870  if (QString(cryoName).startsWith("omega", Qt::CaseInsensitive)) { // Oven Omega in place
9871  size = sizeof(fvalue);
9873  fSampleOvenOmegaInputKey->GetDataIndex((void*)&fvalue, &size, OMEGA_OVEN_INPUT_TEMP, TID_FLOAT);
9874  dvalue = fvalue + 273.16; // °C -> K
9875  }
9876  } else { // Cryo in place
9877  size = sizeof(fvalue);
9878  if (fSampleInputKey) {
9879  fSampleInputKey->GetDataIndex((void *)&fvalue, &size, fSampleCtrlCh, TID_FLOAT);
9880  dvalue = fvalue;
9881  }
9882  }
9883  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
9884  msg.replace("ODB_TEMP", QString("%1").arg(valueStr));
9885  }
9886  }
9887  if (arc->param[3] == "true") { // ODB_FIELD flag set
9888  if (fFieldPwrSupply == "wew") {
9889  // check which WEW power supply is used
9890  size = sizeof(float);
9891  if (fWEWInputKey) {
9892  fWEWInputKey->GetDataIndex((void *)&fvalue, &size, WEWL_INPUT_STATUS, TID_FLOAT);
9893  if (fvalue == 1.0)
9894  fWEWInputKey->GetDataIndex((void *)&fvalue, &size, WEWL_INPUT_CURRENT, TID_FLOAT);
9895  else
9896  fWEWInputKey->GetDataIndex((void *)&fvalue, &size, WEWH_INPUT_CURRENT, TID_FLOAT);
9897  valueStr = QString("~%1(G)/%2(A)").arg(fMagParamWew[0]+fMagParamWew[1]*fvalue, 0, 'f', 0).arg(fvalue, 0, 'f', 2);
9898  msg.replace("ODB_FIELD", QString("%1").arg(valueStr));
9899  }
9900  } else if (fFieldPwrSupply == "danfysik") {
9901  if (fDanfysikInputKey) {
9902  fDanfysikInputKey->GetDataIndex((void *)&fvalue, &size, DANFYSIK_INPUT_CURRENT, TID_FLOAT);
9903  valueStr = QString("~%1(G)/%2(A)").arg(fMagParamBpar[0]+fMagParamBpar[1]*fvalue, 0, 'f', 0).arg(fvalue, 0, 'f', 2);
9904  msg.replace("ODB_FIELD", QString("%1").arg(valueStr));
9905  }
9906  } else {
9907  msg.replace("ODB_FIELD", "??(G)/??(A)");
9908  }
9909  }
9910  if (arc->param[4] == "true") { // ODB_TRANSP flag set
9911  if (fFugHvCheck) {
9912  size = sizeof(fvalue);
9913  if (fHVMeasuredKey) {
9914  fHVMeasuredKey->GetDataIndex((void *)&fvalue, &size, HV_FUG_MOD, TID_FLOAT);
9915  dvalue = fvalue;
9916  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
9917  msg.replace("ODB_TRANSP", QString("%1").arg(valueStr));
9918  }
9919  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
9920  size = sizeof(fvalue);
9921  if (fHVDemandKey) {
9922  fHVDemandKey->GetDataIndex((void *)&fvalue, &size, HV_FUG_MOD, TID_FLOAT);
9923  dvalue = fvalue;
9924  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
9925  msg.replace("ODB_TRANSP", QString("%1").arg(valueStr));
9926  }
9927  }
9928  }
9929  if (arc->param[5] == "true") { // ODB_HV_SAMP flag set
9930  if (fFugHvCheck) {
9931  size = sizeof(fvalue);
9932  if (fHVMeasuredKey) {
9933  fHVMeasuredKey->GetDataIndex((void *)&fvalue, &size, HV_FUG_SAMPLE, TID_FLOAT);
9934  dvalue = fvalue;
9935  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
9936  msg.replace("ODB_HV_SAMP", QString("%1").arg(valueStr));
9937  }
9938  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
9939  size = sizeof(fvalue);
9940  if (fHVDemandKey) {
9941  fHVDemandKey->GetDataIndex((void *)&fvalue, &size, HV_FUG_SAMPLE, TID_FLOAT);
9942  dvalue = fvalue;
9943  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
9944  msg.replace("ODB_HV_SAMP", QString("%1").arg(valueStr));
9945  }
9946  }
9947  }
9948  if (arc->param[6] == "true") { // ODB_ENERGY flag set
9949  if (fFugHvCheck) {
9950  if (fHVMeasuredKey) {
9951  float hv_mod, hv_samp, energy_loss;
9952  // get hv of the moderator
9953  size = sizeof(hv_mod);
9954  fHVMeasuredKey->GetDataIndex((void *)&hv_mod, &size, HV_FUG_MOD, TID_FLOAT);
9955  // get hv of the sample
9956  size = sizeof(hv_samp);
9957  fHVMeasuredKey->GetDataIndex((void *)&hv_samp, &size, HV_FUG_SAMPLE, TID_FLOAT);
9958  // get energy loss
9959  energy_loss = GetEnergyLoss(hv_mod);
9960  // calculate implantation energy
9961  dvalue = hv_mod - energy_loss - hv_samp;
9962  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
9963  msg.replace("ODB_ENERGY", QString("%1").arg(valueStr));
9964  }
9965  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
9966  if (fHVDemandKey) {
9967  float hv_mod, hv_samp, energy_loss;
9968  // get hv of the moderator
9969  size = sizeof(hv_mod);
9970  fHVDemandKey->GetDataIndex((void *)&hv_mod, &size, HV_FUG_MOD, TID_FLOAT);
9971  // get hv of the sample
9972  size = sizeof(hv_samp);
9973  fHVDemandKey->GetDataIndex((void *)&hv_samp, &size, HV_FUG_SAMPLE, TID_FLOAT);
9974  // get energy loss
9975  energy_loss = GetEnergyLoss(hv_mod);
9976  // calculate implantation energy
9977  dvalue = hv_mod - energy_loss - hv_samp;
9978  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
9979  msg.replace("ODB_ENERGY", QString("%1").arg(valueStr));
9980  }
9981  }
9982  }
9983  if (arc->param[7] == "true") { // ODB_RA_DIFF_LR flag set
9984  if (fFugHvCheck) {
9985  if (fHVMeasuredKey) {
9986  float ral, rar;
9987  // get hv of the RA-L
9988  size = sizeof(ral);
9989  fHVMeasuredKey->GetDataIndex((void *)&ral, &size, HV_FUG_RAL, TID_FLOAT);
9990  // get hv of the RA-R
9991  size = sizeof(rar);
9992  fHVMeasuredKey->GetDataIndex((void *)&rar, &size, HV_FUG_RAR, TID_FLOAT);
9993  dvalue = ral-rar;
9994  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
9995  msg.replace("ODB_RA_DIFF_LR", QString("%1").arg(valueStr));
9996  }
9997  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
9998  if (fHVDemandKey) {
9999  float ral, rar;
10000  // get hv of the RA-L
10001  size = sizeof(ral);
10002  fHVDemandKey->GetDataIndex((void *)&ral, &size, HV_FUG_RAL, TID_FLOAT);
10003  // get hv of the RA-R
10004  size = sizeof(rar);
10005  fHVDemandKey->GetDataIndex((void *)&rar, &size, HV_FUG_RAR, TID_FLOAT);
10006  dvalue = ral-rar;
10007  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10008  msg.replace("ODB_RA_DIFF_LR", QString("%1").arg(valueStr));
10009  }
10010  }
10011  }
10012  if (arc->param[8] == "true") { // ODB_RA_DIFF_TB flag set
10013  if (fFugHvCheck) {
10014  if (fHVMeasuredKey) {
10015  float rat, rab;
10016  // get hv of the RA-T
10017  size = sizeof(rat);
10018  fHVMeasuredKey->GetDataIndex((void *)&rat, &size, HV_FUG_RAT, TID_FLOAT);
10019  // get hv of the RA-B
10020  size = sizeof(rab);
10021  fHVMeasuredKey->GetDataIndex((void *)&rab, &size, HV_FUG_RAB, TID_FLOAT);
10022  dvalue = rat-rab;
10023  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10024  msg.replace("ODB_RA_DIFF_TB", QString("%1").arg(valueStr));
10025  }
10026  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
10027  if (fHVDemandKey) {
10028  float rat, rab;
10029  // get hv of the RA-T
10030  size = sizeof(rat);
10031  fHVDemandKey->GetDataIndex((void *)&rat, &size, HV_FUG_RAT, TID_FLOAT);
10032  // get hv of the RA-B
10033  size = sizeof(rab);
10034  fHVDemandKey->GetDataIndex((void *)&rab, &size, HV_FUG_RAB, TID_FLOAT);
10035  dvalue = rat-rab;
10036  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10037  msg.replace("ODB_RA_DIFF_TB", QString("%1").arg(valueStr));
10038  }
10039  }
10040  }
10041  if (arc->param[9] == "true") { // ODB_SPIN_ROT flag set
10043  // get spin rot value, and spin rot enable flag
10044  BOOL srEnabled;
10045  float srAngle;
10046  int size = sizeof(srEnabled);
10047  fSpinRotEnabledKey->GetData(&srEnabled, &size, TID_BOOL);
10048  size = sizeof(srAngle);
10049  fSpinRotAngleKey->GetData(&srAngle, &size, TID_FLOAT);
10050  if (srEnabled == FALSE) {
10051  msg.replace("ODB_SPIN_ROT", "disabled");
10052  } else {
10053  valueStr = QString("%1").arg(srAngle, 0, 'f', 2);
10054  msg.replace("ODB_SPIN_ROT", valueStr);
10055  }
10056  }
10057  }
10058 
10059  // check if they were ODB_TAG entries
10060  HandleOdbTitleTags(msg);
10061 
10062  // set title
10063  msg.truncate(131); // truncate overly long title to 131 characters in order to keep the ODB happy
10064  if (fEnabled["run_comment_odb"])
10065  fRunCommentKey->SetData((void *)msg.toLatin1().data(), 1, TID_STRING);
10066 
10067  // send command notifier
10068  msg = QString("(%1/%2) TITLE ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds) + msg;
10069  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10070 
10071  msg = QString("Autorun running: ") + msg;
10072  emit StatusMsg(msg);
10073 
10074  // increment command counter
10076 }
10077 
10078 //**********************************************************************
10079 // HandleOdbTitleTags
10080 //**********************************************************************
10087 {
10088  int idx=-1, status=0, size;
10089  char bval;
10090  int ival;
10091  float fval;
10092  double dval;
10093  char str[1024];
10094  PKey *key=0;
10095  QString subStr("??");
10096  for (int i=0; i<fOdbTagVector->size(); i++) {
10097  // check if an ODB tag is found in the title
10098  idx = title.indexOf(fOdbTagVector->at(i).tag);
10099  if (idx != -1) { // something found
10100  // check that the ODB tag entry is a valid ODB midas entry
10101  key = new PKey(fExp, fOdbTagVector->at(i).odb_path);
10102  if (key->IsValid()) {
10103  if (fOdbTagVector->at(i).idx+1 > key->GetNumValues()) {
10104  cm_msg(MINFO, "HandleOdbTitleTags", "HandleOdbTitleTags: %s: idx=%d >= number of entries=%d, will ignore it.",
10105  fOdbTagVector->at(i).odb_path.toLatin1().data(), fOdbTagVector->at(i).idx, key->GetNumValues());
10106  cm_yield(0);
10107  } else if ((key->GetType() != TID_BYTE) &&
10108  (key->GetType() != TID_SBYTE) &&
10109  (key->GetType() != TID_CHAR) &&
10110  (key->GetType() != TID_WORD) &&
10111  (key->GetType() != TID_SHORT) &&
10112  (key->GetType() != TID_DWORD) &&
10113  (key->GetType() != TID_INT) &&
10114  (key->GetType() != TID_BOOL) &&
10115  (key->GetType() != TID_FLOAT) &&
10116  (key->GetType() != TID_DOUBLE) &&
10117  (key->GetType() != TID_STRING)) {
10118  cm_msg(MINFO, "HandleOdbTitleTags", "HandleOdbTitleTags: %s: wrong data type (%d), will ignore it.",
10119  fOdbTagVector->at(i).odb_path.toLatin1().data(), key->GetType());
10120  cm_yield(0);
10121  } else {
10122  if (fOdbTagVector->at(i).idx != -1) { // data is an array
10123  switch (key->GetType()) {
10124  case TID_BYTE:
10125  size = sizeof(char);
10126  status = key->GetDataIndex(&bval, &size, fOdbTagVector->at(i).idx, TID_BYTE);
10127  subStr = QString("%1").arg(bval);
10128  break;
10129  case TID_SBYTE:
10130  size = sizeof(char);
10131  status = key->GetDataIndex(&bval, &size, fOdbTagVector->at(i).idx, TID_SBYTE);
10132  subStr = QString("%1").arg(bval);
10133  break;
10134  case TID_CHAR:
10135  size = sizeof(char);
10136  status = key->GetDataIndex(&bval, &size, fOdbTagVector->at(i).idx, TID_CHAR);
10137  subStr = QString("%1").arg(bval);
10138  break;
10139  case TID_WORD:
10140  size = 2*sizeof(char);
10141  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_WORD);
10142  subStr = QString("%1").arg(ival);
10143  break;
10144  case TID_SHORT:
10145  size = sizeof(int);
10146  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_SHORT);
10147  subStr = QString("%1").arg(ival);
10148  break;
10149  case TID_DWORD:
10150  size = sizeof(int);
10151  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_DWORD);
10152  subStr = QString("%1").arg(ival);
10153  break;
10154  case TID_INT:
10155  size = sizeof(int);
10156  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_INT);
10157  subStr = QString("%1").arg(ival);
10158  break;
10159  case TID_BOOL:
10160  size = sizeof(int);
10161  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_BOOL);
10162  subStr = QString("%1").arg(ival);
10163  break;
10164  case TID_FLOAT:
10165  size = sizeof(float);
10166  status = key->GetDataIndex(&fval, &size, fOdbTagVector->at(i).idx, TID_FLOAT);
10167  subStr = QString("%1").arg(fval);
10168  break;
10169  case TID_DOUBLE:
10170  size = sizeof(double);
10171  status = key->GetDataIndex(&dval, &size, fOdbTagVector->at(i).idx, TID_DOUBLE);
10172  subStr = QString("%1").arg(dval);
10173  break;
10174  case TID_STRING:
10175  size = key->GetItemSize()*sizeof(float);
10176  if (size < 1024) {
10177  status = key->GetDataIndex(&str, &size, fOdbTagVector->at(i).idx, TID_STRING);
10178  subStr = str;
10179  } else {
10180  subStr = "?!?!";
10181  }
10182  break;
10183  default:
10184  break;
10185  }
10186  if (status == DB_SUCCESS) {
10187  title.replace(fOdbTagVector->at(i).tag, subStr);
10188  }
10189  } else { // data is a single value
10190  switch (key->GetType()) {
10191  case TID_BYTE:
10192  size = sizeof(char);
10193  status = key->GetData(&bval, &size, TID_BYTE);
10194  subStr = QString("%1").arg(bval);
10195  break;
10196  case TID_SBYTE:
10197  size = sizeof(char);
10198  status = key->GetData(&bval, &size, TID_SBYTE);
10199  subStr = QString("%1").arg(bval);
10200  break;
10201  case TID_CHAR:
10202  size = sizeof(char);
10203  status = key->GetData(&bval, &size, TID_CHAR);
10204  subStr = QString("%1").arg(bval);
10205  break;
10206  case TID_WORD:
10207  size = 2*sizeof(char);
10208  status = key->GetData(&ival, &size, TID_WORD);
10209  subStr = QString("%1").arg(ival);
10210  break;
10211  case TID_SHORT:
10212  size = sizeof(int);
10213  status = key->GetData(&ival, &size, TID_SHORT);
10214  subStr = QString("%1").arg(ival);
10215  break;
10216  case TID_DWORD:
10217  size = sizeof(int);
10218  status = key->GetData(&ival, &size, TID_DWORD);
10219  subStr = QString("%1").arg(ival);
10220  break;
10221  case TID_INT:
10222  size = sizeof(int);
10223  status = key->GetData(&ival, &size, TID_INT);
10224  subStr = QString("%1").arg(ival);
10225  break;
10226  case TID_BOOL:
10227  size = sizeof(int);
10228  status = key->GetData(&ival, &size, TID_BOOL);
10229  subStr = QString("%1").arg(ival);
10230  break;
10231  case TID_FLOAT:
10232  size = sizeof(float);
10233  status = key->GetData(&fval, &size, TID_FLOAT);
10234  subStr = QString("%1").arg(fval);
10235  break;
10236  case TID_DOUBLE:
10237  size = sizeof(double);
10238  status = key->GetData(&dval, &size, TID_DOUBLE);
10239  subStr = QString("%1").arg(dval);
10240  break;
10241  case TID_STRING:
10242  size = key->GetItemSize()*sizeof(char);
10243  if (size < 1024) {
10244  status = key->GetData(&str, &size, TID_STRING);
10245  subStr = str;
10246  } else {
10247  subStr = "?!?!";
10248  }
10249  break;
10250  default:
10251  break;
10252  }
10253  if (status == DB_SUCCESS) {
10254  title.replace(fOdbTagVector->at(i).tag, subStr);
10255  }
10256  }
10257  }
10258  }
10259  // clean up
10260  if (key) {
10261  delete key;
10262  key = 0;
10263  }
10264  subStr = QString("??");
10265  }
10266  }
10267 }
10268 
10269 //**********************************************************************
10270 // SetTof
10271 //**********************************************************************
10278 {
10279  float value;
10280  QString msg("");
10281 
10282  // check if TOF ODB entries are disabled in lemAutoRun
10283  if (!fEnabled["tof_min_odb"] || !fEnabled["tof_max_odb"]) {
10284  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10285  msg += "PLemAutoRun::SetTof: TOF ODB entires disabled in lemAutoRun. Will do nothing here.";
10286  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10287  // increment command counter
10289  return;
10290  }
10291 
10292  // send command notifier
10293  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10294  msg += arc->cmdString;
10295  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10296 
10297  msg = QString("Autorun running: ") + msg;
10298  emit StatusMsg(msg);
10299 
10300  // set values
10301  value = arc->param[0].toFloat();
10302  fTofMinKey->SetData((void *)&value, 1, TID_FLOAT);
10303 
10304  value = arc->param[1].toFloat();
10305  fTofMaxKey->SetData((void *)&value, 1, TID_FLOAT);
10306 
10307  // increment command counter
10309 }
10310 
10311 //**********************************************************************
10312 // SetWait
10313 //**********************************************************************
10320 {
10321  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10322  msg += arc->cmdString;
10323  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10324 
10325  msg = QString("Autorun running: ") + msg;
10326  emit StatusMsg(msg);
10327 
10328  int wait = arc->param[0].toInt();
10329 
10330  for (int i=0; i<wait; i++) {
10331  Wait(1000); // sleep 1 sec
10332 
10333  if ( ((i+1) % 5) == 0 ) { // once every 5 seconds
10334 
10335  // adjust flow when needed, but only when regulation is whished, the temperature is stable, and
10336  // there is a long enough history for a reliable regulation
10338  if (fEnabled["omega_eq"]) // only deal with omega oven if enabled
10340  } else {
10341  if (fEnabled["sample_eq"]) // only deal with sample cryo if enabled
10343  }
10344  if (fSampleCryoInUse == CRYO_KONTI) {
10346  if (fEnabled["sample_eq"]) // only deal with sample cryo if enabled
10348  }
10349  }
10350 
10351  // dump raw voltage when needed
10352  if (fEnabled["sample_eq"]) { // only deal with sample cryo if enabled
10353  if (fDumpInUse) {
10354  if (fDumpCounter > 0) {
10355  RawVoltageDump();
10356  } else {
10357  fDumpFile.close();
10358  fDumpInUse = false;
10359  }
10360  }
10361  }
10362  }
10363  }
10364 
10365  // increment command counter
10367 }
10368 
10369 //**********************************************************************
10370 // CheckForWarmUpCmd
10371 //**********************************************************************
10376 {
10377  PAutoRunCmdVector::Iterator iter;
10378  int yy, MM, dd, hh, mm, ss;
10379  QDate d;
10380  QTime t;
10381 
10382  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
10383  if (iter->cmd == "warmUp") {
10384  fWarmUpWished = true;
10385  sscanf(iter->param[0].toLatin1().data(), "%d-%d-%d", &yy, &MM, &dd);
10386  d = QDate(yy, MM, dd);
10387  fWarmUpDateTime.setDate(d);
10388  sscanf(iter->param[1].toLatin1().data(), "%d:%d:%d", &hh, &mm, &ss);
10389  t = QTime(hh, mm, ss);
10390  fWarmUpDateTime.setTime(t);
10391  if (iter->param[2] == "1")
10392  fWarmUpVent = true;
10393  break;
10394  }
10395  }
10396 }
10397 
10398 //**********************************************************************
10399 // WarmUp
10400 //**********************************************************************
10406 void PLemAutoRun::WarmUp(PAutoRunCmdVector::Iterator iter)
10407 {
10408  int status, size;
10409  QString err, msg;
10410  unsigned int i, j;
10411  float value;
10412  float hv[HV_FUG_CHS];
10413  bool done, happy;
10414  QTime t;
10415 
10416  // check if sample equipment is disabled in lemAutoRun
10417  if (!fEnabled["sample_eq"]) {
10418  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10419  msg += "PLemAutoRun::WarmUp: sample equipment disabled in lemAutoRun. Will do nothing here.";
10420  emit ErrorMsg(1, 0, LAR_MSG, 0, msg);
10421  // increment command counter
10423  return;
10424  }
10425 
10426  // notifier
10427  msg = QString("PLemAutoRun::WarmUp(): warm up procedure starts. Will stop any pending runs, shutdown HV's, ...");
10428  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10429 
10430  // update web-page
10431  UpdateWebPage(iter, HTML_WARMUP);
10432 
10433  // if there is an active run, stop it
10434  if (fRunInfo.state == RUN_RUNNING) {
10435  // stop run
10436  status = cm_transition(TR_STOP, fRunInfo.run_number, NULL, 0, TR_SYNC, FALSE);
10437  if (status != CM_SUCCESS) { // error
10438  err = QString("PLemAutoRun::RunStart: Cannot stop the run.");
10439  emit ErrorMsg(1, 0, LAR_MIDAS_CANNOT_START_RUN, -1, err);
10440  emit StatusMsg(err);
10441  }
10442  err = QString("Autorun running: run stopped.");
10443  emit StatusMsg(err);
10444  fRunNoEventsNeeded = 0;
10445  fRunStopped = true;
10446  }
10447 
10448  // close KV61 and KV62
10449  msg = QString("PLemAutoRun::WarmUp(): close KV61 and KV62");
10450  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10451 
10452  value = 0.0;
10453  fBeamlineDemandKey->SetDataIndex(&value, BEAMLINE_KV61_DEMAND_CH, TID_FLOAT);
10454  value = 0.0;
10455  fBeamlineDemandKey->SetDataIndex(&value, BEAMLINE_KV62_DEMAND_CH, TID_FLOAT);
10456 
10457  // switch off all the FUG HV's **************************************************************
10458 
10459  msg = QString("PLemAutoRun::WarmUp(): switch off all the FUG HV's");
10460  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10461 
10462  if (fEnabled["fug_scfe"]) { // only do something if FUG is enabled
10463  // Loop over set HV. This is done this way to reduce hangers due to network problems
10464  for (j=0; j<HV_FUG_MAX_TRY; j++) {
10465 
10466  // set HV's to 0.0
10467  value = 0.0 + j*0.001; // j-term to force the DD set command being executed
10468  for (i=0; i<HV_FUG_CHS; i++)
10469  hv[i] = value;
10470  fHVDemandKey->SetData((void *)&hv, HV_FUG_CHS, TID_FLOAT);
10471 
10472  if (fFugHvCheck) {
10473  // check that HV is really down
10474  done = false;
10475  happy = false;
10476  t.start();
10477  do {
10478  Wait(2000); // sleep for 2 sec
10479 
10480  // read measured HV's
10481  size = sizeof(hv);
10482  fHVMeasuredKey->GetData(&hv, &size, TID_FLOAT);
10483 
10484  // calculate the sum of all sample region HV's
10485  value = 0.0;
10486  for (i=0; i<HV_FUG_CHS; i++)
10487  value += hv[i];
10488 
10489  // if sum of all HV's is smaller than 500V leave the loop
10490  if (fabs(value) < 0.5) {
10491  done = true;
10492  happy = true;
10493  }
10494 
10495  // check if timeout occured
10496  if (t.elapsed() > 3e5) { // 5 min. timeout
10497  done = true;
10498  err = QString("PLemAutoRun::WarmUp(): Couldn't shut down HV's. Will give it another try in 120 sec.");
10499  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
10500  }
10501  } while (!done);
10502 
10503  if (happy) // everything perfect, get out of the loop
10504  break;
10505 
10506  // wait 120 sec before retrial
10507  Wait(120000);
10508  } else { // NO FUG HV check, hence just wait a 1 min
10509  Wait(60000);
10510  j = 0;
10511  }
10512  }
10513 
10514  if (j == HV_FUG_MAX_TRY) {
10515  err = QString("PLemAutoRun::WarmUp(): Couldn't shut down sample region HV's. Error too severe, will stop.");
10516  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10517  }
10518  }
10519 
10520  // disable the RA pulsing
10521  msg = QString("PLemAutoRun::WarmUp(): disable potentially set RA pulsing.");
10522  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10523 
10524  PKey *enable_RA_pulsing = new PKey(fExp, "/Equipment/Trigger/Settings/Enable_OnOff_Mode");
10525  if (!enable_RA_pulsing->IsValid()) {
10526  err = QString("PLemAutoRun::WarmUp(): Couldn't get the Enable_OnOff_Mode key for the RA pulsing. Please check instantly! Error too severe, will stop.");
10527  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10528  }
10529  int ival = 0;
10530  enable_RA_pulsing->SetData((void*)&ival, 1,TID_BOOL);
10531  if (enable_RA_pulsing) {
10532  delete enable_RA_pulsing;
10533  enable_RA_pulsing = 0;
10534  }
10535 
10536  // close the BPVX/Y *****************************************************************************
10537  msg = QString("PLemAutoRun::WarmUp(): close BPVX/Y");
10538  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10539 
10540  // close BPVX
10541  if (!SetBPV(BPVX, BPV_CLOSE)) {
10542  QString err = QString("PLemAutoRun::WarmUp(): Couldn't close BPVX. Error too severe, will stop.");
10543  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, -1, err);
10544  }
10545 
10546  // close BPVY
10547  if (!SetBPV(BPVY, BPV_CLOSE)) {
10548  QString err = QString("PLemAutoRun::WarmUp(): Couldn't close BPVY. Error too severe, will stop.");
10549  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, -1, err);
10550  }
10551 
10552  // set the He Flow (Bronkhorst) to minimal *********************************************************
10553  msg = QString("PLemAutoRun::WarmUp(): sample He flow set to minimum value");
10554  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10555  value = fBHFlowTemp / (300.0 + fBHFlowTempOffset) + fBHFlowOffset;
10556  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
10557 
10558  // set demand temperature ramping to zero
10559  msg = QString("PLemAutoRun::WarmUp(): set demand temperature ramping to zero");
10560  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10561  value = 0.0;
10562  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_RAMP, TID_FLOAT);
10563 
10564  // check that the demand temperature ramping is set before proceeding
10565  t.start();
10566  do {
10567  Wait(3000);
10568  if (fSampleInput[LS340_INPUT_RAMP] == 0.0)
10569  break;
10570  } while (t.elapsed() < 60e3);
10571 
10572  // set the sample cryo temperature to 300K
10573  msg = QString("PLemAutoRun::WarmUp(): set sample cryo temperature to 300K");
10574  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10575  value = 300.0;
10576  fSampleOutputKey->SetDataIndex((void *)&value, LS340_OUTPUT_SETPOINT, TID_FLOAT);
10577 
10578  // read back temperature, if T>250K set the He Flow to zero, if T>90K and vent shall be performed: vent
10579  done = false;
10580  do {
10581  Wait(3000); // sleep for 3 sec
10582 
10583  size = sizeof(value);
10584  fSampleInputKey->GetDataIndex((void *)&value, &size, fSampleCtrlCh, TID_FLOAT);
10585 
10586  if ((value > 90.0) && fWarmUpVent && fEnabled["lemvac_scfe"]) {
10587  msg = QString("PLemAutoRun::WarmUp(): vent the sample chamber.");
10588  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10589  value = 1.0; // enable SC vent
10590  fLemvacOutputKey->SetDataIndex((void*)&value, SC_VENT_ENABLED, TID_FLOAT);
10591  value = 2.0; // SC vent command
10592  fLemvacOutputKey->SetDataIndex((void*)&value, SC_VENT_CMD, TID_FLOAT);
10593  fWarmUpVent = false;
10594  }
10595 
10596  if (value > 250.0) {
10597  done = true;
10598  // set the He Flow (Bronkhorst) to minimal
10599  msg = QString("PLemAutoRun::WarmUp(): sample He flow set to zero");
10600  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10601  value = 0.0;
10602  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
10603  }
10604  } while (!done);
10605 }
10606 
10607 
10608 //**********************************************************************
10609 // GotoLine
10610 //**********************************************************************
10617 void PLemAutoRun::GotoLine(PAutoRunCmdVector::Iterator &iter, int max)
10618 {
10619  int count=0, pos=0, gotoLine=GetGotoLine();
10620  QString msg;
10621 
10622  // check if goto line is within autorun
10623  if (gotoLine <= max) {
10624  for (PAutoRunCmdVector::Iterator loopIter=fAutoRunCmdVector->begin(); loopIter != fAutoRunCmdVector->end(); ++loopIter) {
10625  if (loopIter->cmd == "comment") {
10626  if (ShowComments() == true)
10627  pos++;
10628  } else {
10629  count++;
10630  pos++;
10631  }
10632  if (pos == gotoLine) {
10633  iter = loopIter;
10634  fCurrentAutoRunCmd = count;
10635  cm_msg(MINFO, "ExecAutoRun", "ExecAutoRun: will goto line %d", gotoLine);
10636  cm_yield(0);
10637  msg = QString("will go to line %1").arg(gotoLine);
10638  emit StatusMsg(msg);
10639  break;
10640  }
10641  }
10642  } else { // out of range
10643  cm_msg(MERROR, "ExecAutoRun", "ExecAutoRun: goto line %d > max. line number (%d). Doesn't make sense. Will ignore it!", gotoLine, max);
10644  cm_yield(0);
10645  msg = QString("line number %1 > max. line number (%2). Doesn't make sense. Will ignore it.").arg(gotoLine).arg(max);
10646  emit StatusMsg(msg);
10647  }
10648 
10649  // set goto line back to zero
10650  SetGotoLine(0);
10651  do { // wait until the hotlink is updated
10652  cm_yield(100);
10653  } while (GetGotoLine() != 0);
10654 }
10655 
10656 //**********************************************************************
10657 // GetDemandHVSampleChamber
10658 //**********************************************************************
10663 {
10664  int size, status;
10665  float demands[HV_FUG_CHS];
10666 
10667  size = sizeof(demands);
10668  status = fHVDemandKey->GetData(&demands, &size, TID_FLOAT);
10669  if (status != DB_SUCCESS) {
10671  QString err = QString("PLemAutoRun::GetDemandHVSampleChamber: Couldn't get demand HV's. Error too severe, will stop.");
10672  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10673  }
10674 
10675  for (int i=0; i<5; i++)
10676  fHVDemandSampleChamber[i] = demands[i+HV_FUG_RAL];
10677 }
10678 
10679 //**********************************************************************
10680 // ChangeSampleChamberHV
10681 //**********************************************************************
10686 {
10687  int i, j, ok, size;
10688  float value;
10689  float measured[HV_FUG_CHS];
10690  int hv_down;
10691  bool done, happy;
10692  QTime t;
10693  QString err, msg;
10694 
10695  // check if FUG handling is disabled in lemAutoRun
10696  if (!fEnabled["fug_scfe"]) {
10697  return;
10698  }
10699 
10700  if (down) { // shut down sample region HV's
10701 
10702  // notifiy about down ramping
10703  msg = QString("ramp sample region HV's down.");
10704  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10705 
10706  // Loop over set HV. This is done this way to reduce hangers due to network problems
10707  for (j=0; j<HV_FUG_MAX_TRY; j++) {
10708 
10709  // set sample region HV's to 0.0
10710  value = 0.0 + j*0.001; // j-term to force the DD set command being executed
10711  for (i=0; i<5; i++)
10712  fHVDemandKey->SetDataIndex((void *)&value, i+HV_FUG_RAL, TID_FLOAT);
10713 
10714  if (fFugHvCheck) {
10715  // check that HV is really down
10716  done = false;
10717  happy = false;
10718  t.start();
10719  do {
10720  Wait(2000); // sleep for 2 sec
10721 
10722  // init hv_down tag
10723  hv_down = 0;
10724 
10725  // read measured HV's
10726  size = sizeof(measured);
10727  fHVMeasuredKey->GetData(&measured, &size, TID_FLOAT);
10728 
10729  // calculate the sum of all sample region HV's
10730  value = 0.0;
10731  for (i=0; i<5; i++) {
10732  value += measured[i+HV_FUG_RAL];
10733  if (measured[i+HV_FUG_RAL] < 0.35) // measured HV of a single channel < 350V
10734  hv_down += 1;
10735  }
10736 
10737  // if sum of all the sample region HV's is smaller than 100V leave the loop
10738  if ((fabs(value) < 0.1) || (hv_down == 5)) {
10739  done = true;
10740  happy = true;
10741  }
10742 
10743  // check if timeout occured
10744  if (t.elapsed() > 3e5) { // 5 min. timeout
10745  done = true;
10746  err = QString("PLemAutoRun::ChangeSampleChamberHV: Couldn't shut down sample region HV's. Will give it another try in 120 sec.");
10747  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
10748  }
10749  } while (!done);
10750 
10751  if (happy) // everything perfect, get out of the loop
10752  break;
10753 
10754  // wait 120 sec before retrial
10755  Wait(120000);
10756  } else { // NO FUG HV check, hence just wait a 1 min
10757  Wait(60000);
10758  j = 0;
10759  }
10760  }
10761  if (j == HV_FUG_MAX_TRY) {
10763  err = QString("PLemAutoRun::ChangeSampleChamberHV: Couldn't shut down sample region HV's. Error too severe, will stop.");
10764  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10765  for (int k=0; k<5; k++) {
10766  if (measured[k+HV_FUG_RAL] > 0.25) {
10767  cm_msg(MERROR, "lemAutoRun", "FUG channel %d should be 0.0 but found %f", k+HV_FUG_RAL, measured[k+HV_FUG_RAL]);
10768  cm_yield(0);
10769  }
10770  }
10771  }
10772  } else { // ramp back sample region HV's
10773 
10774  // notifiy about up ramping
10775  msg = QString("ramp sample region HV's back up.");
10776  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10777 
10778  // Loop over set HV. This is done this way to reduce hangers due to network problems
10779  for (j=0; j<HV_FUG_MAX_TRY; j++) {
10780 
10781  // set sample region HV's to it's previous value
10782  for (i=0; i<5; i++) {
10783  value = fHVDemandSampleChamber[i] + (-1)*(j%2)*0.001; // j-term to force the DD set command being executed
10784  fHVDemandKey->SetDataIndex((void *)&value, i+HV_FUG_RAL, TID_FLOAT);
10785  }
10786 
10787  if (fFugHvCheck) {
10788  // check that HV are ramped back
10789  done = false;
10790  happy = false;
10791  t.start();
10792  do {
10793  Wait(2000); // sleep for 2 sec
10794 
10795  // read measured HV's
10796  size = sizeof(measured);
10797  fHVMeasuredKey->GetData(&measured, &size, TID_FLOAT);
10798 
10799  // check if HV is ok
10800  ok = 0;
10801  for (i=0; i<5; i++) {
10802  if (fabs(measured[i+HV_FUG_RAL]-fHVDemandSampleChamber[i]) < 0.2)
10803  ok++;
10804  }
10805 
10806  // if all the sample region HV's are ok within 200V leave the loop
10807  if (ok == 5) {
10808  done = true;
10809  happy = true;
10810  }
10811 
10812  // check if timeout occured
10813  if (t.elapsed() > 3e5) { // 5 min. timeout
10814  done = true;
10815  err = QString("PLemAutoRun::ChangeSampleChamberHV: Couldn't ramp back sample region HV's. Will give it another try in 120 sec.");
10816  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
10817  }
10818  } while (!done);
10819 
10820  if (happy) // everything perfect, get out of the loop
10821  break;
10822 
10823  // wait 120 sec before retrial
10824  Wait(120000);
10825  } else { // NO FUG HV check, hence just wait a 1 min
10826  Wait(60000);
10827  j = 0;
10828  }
10829  }
10830 
10831  if (j == HV_FUG_MAX_TRY) {
10833  err = QString("PLemAutoRun::ChangeSampleChamberHV: Couldn't ramp back sample region HV's. Error too severe, will stop.");
10834  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10835  }
10836  }
10837 }
10838 
10839 //**********************************************************************
10840 // SetBPV - AutoRunCmd
10841 //**********************************************************************
10848 {
10849  QString msg("");
10850 
10851  // check if lemvac equipment is disabled in lemAutoRun
10852  if (!fEnabled["lemvac_eq"]) {
10853  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10854  msg += "PLemAutoRun::SetBPV: lemvac equipment disabled in lemAutoRun. Will do nothing here.";
10855  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10856  // increment command counter
10858  return;
10859  }
10860 
10861  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10862  msg += arc->cmdString;
10863  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10864 
10865  msg = QString("Autorun running: ") + msg;
10866  emit StatusMsg(msg);
10867 
10868  int label=BPVX, state=BPV_CLOSE;
10869  // get valve label
10870  if (arc->param[0] == "X")
10871  label = BPVX;
10872  else
10873  label = BPVY;
10874 
10875  // get valve state
10876  if ((arc->param[1] == "1") || (arc->param[1] == "open"))
10877  state = BPV_OPEN;
10878 
10879  SetBPV(label, state);
10880 
10881  // increment command counter
10883 }
10884 
10885 //**********************************************************************
10886 // SetBPV
10887 //**********************************************************************
10898 bool PLemAutoRun::SetBPV(int valve, int cmd)
10899 {
10900  int size;
10901  int index;
10902  float value;
10903 
10904  if (!fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
10905  return true;
10906  }
10907 
10908  // check if BPVX/Y is enabled
10909  size = sizeof(value);
10910  if (valve == BPVX)
10911  index = BPVX_ENABLED;
10912  else
10913  index = BPVY_ENABLED;
10914  fLemvacOutputKey->GetDataIndex(&value, &size, index, TID_FLOAT);
10915 
10916  if (value != 1) { // BPVX/Y NOT enabled
10917  return false;
10918  }
10919 
10920  // set new state of the BPVX/Y
10921  value = cmd;
10922  if (valve == BPVX)
10923  index = BPVX_SET;
10924  else
10925  index = BPVY_SET;
10926 
10927  fLemvacOutputKey->SetDataIndex(&value, index, TID_FLOAT);
10928 
10929  // check if the state really has changed
10930  if (valve == BPVX)
10931  index = BPVX_STATE;
10932  else
10933  index = BPVY_STATE;
10934  bool done = false;
10935  QTime t;
10936  t.start();
10937  do {
10938  Wait(2000); // sleep for 2 sec
10939 
10940  size = sizeof(value);
10941  fLemvacInputKey->GetDataIndex(&value, &size, index, TID_FLOAT);
10942 
10943  if (cmd == BPV_CLOSE) { // close command
10944  if (value == BPV_STATE_CLOSED)
10945  done = true;
10946  } else { // open command
10947  if (value == BPV_STATE_OPEN)
10948  done = true;
10949  }
10950 
10951  if (t.elapsed() > 6e4) { // no correct read back within 60 sec
10952  return false;
10953  }
10954  } while (!done);
10955 
10956  return true;
10957 }
10958 
10959 //**********************************************************************
10960 // GetBPV
10961 //**********************************************************************
10970 {
10971  int size;
10972  int index;
10973  float value;
10974 
10975  if (!fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
10976  return true;
10977  }
10978 
10979  index = BPVX_STATE;
10980  size = sizeof(value);
10981  fLemvacInputKey->GetDataIndex(&value, &size, index, TID_FLOAT);
10982  if ((value != BPV_STATE_OPEN) && (value != BPV_STATE_CLOSED))
10983  return false;
10984  fLemVacValveInitialState[BPVX] = value;
10985 
10986  fExp->FeedMidasWatchdog();
10987 
10988  index = BPVY_STATE;
10989  fLemvacInputKey->GetDataIndex(&value, &size, index, TID_FLOAT);
10990  if ((value != BPV_STATE_OPEN) && (value != BPV_STATE_CLOSED))
10991  return false;
10992  fLemVacValveInitialState[BPVY] = value;
10993 
10994  return true;
10995 }
10996 
10997 //**********************************************************************
10998 // RawVoltageDump
10999 //**********************************************************************
11005 {
11006  float rv[10];
11007  float value, value1, value2, value3, value4, value5, value6;
11008  char LSDateTime[32];
11009  int size4 = sizeof(value);
11010  int size32 = 32;
11011 
11012  fSampleDatetimeKey->GetData( LSDateTime, &size32, TID_STRING); // read time
11013  fSampleInputKey->GetDataIndex(&value1, &size4, fSampleCtrlCh, TID_FLOAT);
11014  fSampleInputKey->GetDataIndex(&value2, &size4, LS340_INPUT_PRESSURE, TID_FLOAT);
11015  fSampleInputKey->GetDataIndex(&value3, &size4, LS340_INPUT_HEATER, TID_FLOAT);
11016  fSampleInputKey->GetDataIndex(&value4, &size4, LS340_INPUT_SETPOINT, TID_FLOAT);
11017  fSampleInputKey->GetDataIndex(&value5, &size4, LS340_INPUT_HEATER_RANGE, TID_FLOAT);
11018  fSampleInputKey->GetDataIndex(&value6, &size4,
11020 
11021  for (int i = 0; i < 10; i++ ) {
11022  fSampleRawVoltageKey[i]->GetData( &value, &size4, TID_FLOAT);
11023  rv[i] = value;
11024  }
11025 
11026  QTextStream stream( &fDumpFile );
11027  stream << LSDateTime << "," <<
11028  value1 << "," <<
11029  value2 << "," <<
11030  value3 << "," <<
11031  value4 << "," <<
11032  value5 << "," <<
11033  value6;
11034  for( int i = 0; i < 10; i++ ) stream << "," << rv[i];
11035  stream << endl;
11036  fDumpFile.flush();
11037 
11038  fDumpCounter--;
11039 }
11040 
11041 //**********************************************************************
11042 // Wait
11043 //**********************************************************************
11051 void PLemAutoRun::Wait(int timeout)
11052 {
11053  int count = timeout / 1000; // how many 1 sec steps needed
11054 
11055  for (int i=0; i<count; i++) {
11056  ss_sleep(1000); // sleep 1 sec
11057  fExp->FeedMidasWatchdog();
11058  }
11059 
11060  // deal with the sub-second rest
11061  if ((timeout % 1000) != 0) {
11062  ss_sleep(timeout % 1000);
11063  fExp->FeedMidasWatchdog();
11064  }
11065 }
11066 
11067 
11068 //**********************************************************************
11069 // TdHvTripFlagChanged
11070 //**********************************************************************
11076 void TdHvTripFlagChanged(HNDLE, HNDLE, void *info)
11077 {
11078  PLemAutoRun *lar;
11079  lar = (PLemAutoRun *)info;
11080 
11081  // check if TD HV Trip Alarm flag is true
11082  if (lar->fHvTripFlag) {
11083  QString err = QString("PLemAutoRun: HV trip due to TD rate trip! Will wait until the problem is resolved.");
11084  emit lar->ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
11085  }
11086 }
11087 
11088 //---------------------------------------------------------------------------------------
11089 // end
11090 //---------------------------------------------------------------------------------------
QString fDanfysikOutputPath
ODB path to the danfysik output variables.
Definition: PLemAutoRun.h:414
QString fModDatePath
ODB path to the moderator growing date.
Definition: PLemAutoRun.h:398
float fPrefNeedleValveAbsStep
absolute change in SampleTempConsiderNeedleValve
Definition: PLemAutoRun.h:332
PKey * fTofMaxKey
pointer to the ODB key: TOF max
Definition: PLemAutoRun.h:489
#define LS340_OUTPUT_PID_D
ODB Offset for D output.
Definition: PLemAutoRun.cpp:90
#define LAR_STATE_PAUSED
auto run state paused
Definition: lemAutoRun.h:38
void SampleTempConsiderFlow()
void SetOdbData(AutoRunCmd *arc)
QString fSetupBparEnabledPath
ODB path to the Bpar enabled flag.
Definition: PLemAutoRun.h:439
void NetworkConnectionLost()
slot executed if the network connection is lost
PKey * fAlarmsKey
pointer to the ODB key: alarms
Definition: PLemAutoRun.h:484
#define LAR_STATE_LOADING
tag needed to update the web-page without starting the run, process underway
Definition: lemAutoRun.h:42
QString fDanfysikFeName
name of the danfysik scfe in the ODB
Definition: PLemAutoRun.h:450
PKey * fFOMOutputKey
pointer to the ODB key: FOM output values
Definition: PLemAutoRun.h:526
QString fWEWInputPath
ODB path to the WEW input variable.
Definition: PLemAutoRun.h:415
void setAttribute(const QString key, const QXmlAttributes &qAttr)
PLemAutoRunXMLParser::setAttribute.
#define LAR_LOST_NETWORK_CONNECTION
lost network connection error tag
Definition: lemAutoRun.h:48
#define HTML_STOP
html stop tag
#define RUN_RUNNING
MIDAS run active tag.
Definition: PLemAutoRun.cpp:52
void RunStart(AutoRunCmd *arc)
void SetFieldWEWL(AutoRunCmd *arc)
int fAutoRunState
autorun run state as defined under /AutoRun/Run State
Definition: PLemAutoRun.h:261
#define LAR_MIDAS_CONNECTION_FAILED
MIDAS connection failed error tag.
Definition: lemAutoRun.h:67
void UpdateWebPage(PAutoRunCmdVector::Iterator currentIter, int tag, int lineNo=0, QString errMsg="")
float demand_T
setpoint to be reached
Definition: PLemAutoRun.h:59
#define TEMP_HEATER_RANGE
heater range parameter tag
float fDFlowDp1
DFDP_0 + DFDP_1 * exp( DFDP_EXP * Temp )
Definition: PLemAutoRun.h:312
QVector< float > * GetCurrentLimits()
Definition: PLemAutoRun.h:202
void SetSampleHV(AutoRunCmd *arc)
bool fWarmUpVent
warmup with vent flag, false=no vent, true=vent
Definition: PLemAutoRun.h:374
void SetGotoLine(const int line)
PLemAutoRun::SetGotoLine.
bool fNeedleValveInUse
Tag for use of electric needle valve.
Definition: PLemAutoRun.h:322
QString fTflFeName
Definition: PLemAutoRun.h:446
QString GetUserAutoRunSeqFln()
PLemAutoRun::GetUserAutoRunSeqFln.
#define BH_INPUT_FLOW
ODB Offset for the measured flow value.
#define LAR_MIDAS_CANNOT_START_RUN
MIDAS cannot start run error tag.
Definition: lemAutoRun.h:72
#define HTML_FATAL
html fatal error, e.g. no autorun commands present
bool fSetupBparEnabled
true if the Bpar magnet is in use. This is fed with the Danfysik power supply.
Definition: PLemAutoRun.h:386
QString fHVDetectorDemandPath
ODB path to the HV Detectors demand variables.
Definition: PLemAutoRun.h:409
#define BEAMLINE_KV62_DEMAND_CH
ODB Index of the KV62 demand channel.
void ChangeSampleChamberHV(bool down)
bool fSampleFeRunning
flag indicating if the sample_scfe is running (LS340, BH)
Definition: PLemAutoRun.h:456
#define TEMP_STABILITY_TIMEOUT
stability timeout parameter tag
float fBHFlowOffset
variable needed to calculate the flow if non is explicitly given (see SetTemp())
Definition: PLemAutoRun.h:297
#define LAR_FATAL
something unexpected really bad happend
Definition: lemAutoRun.h:35
float fHeatCapCof1
heat Capacity of cryo =
Definition: PLemAutoRun.h:317
QString fSampleNamePath
ODB path to the sample name.
Definition: PLemAutoRun.h:400
#define LS340_INPUT_CF1
ODB Offset for the cold finger 1 sensor.
Definition: PLemAutoRun.cpp:74
#define WEWL_OUTPUT_CURRENT
ODB Offset for the demand current of the WEWL.
void SetRA_HV(AutoRunCmd *arc)
PKey * fTflInputKey
pointer to the ODB key: tfl input values
Definition: PLemAutoRun.h:511
PKey * fSetupWewEnabledKey
pointer to the ODB key: WEW enabled flag
Definition: PLemAutoRun.h:531
#define WEW_SSP_LOCK
ODB Offset for the WEW-SSP lock.
#define RUN_PAUSED
MIDAS run paused tag.
Definition: PLemAutoRun.cpp:51
#define BPVX
BPVX label.
Definition: PLemAutoRun.cpp:54
QString fSampleOvenOmegaFeName
name of the oven omega scfe in the ODB
Definition: PLemAutoRun.h:448
float GetEnergyLoss(float mod_hv)
void SampleTempTrend()
void HandleOdbTitleTags(QString &title)
PLemAutoRun::HandleOdbTitleTags.
PKey * fClientsKey
pointer to the ODB key: running clients
Definition: PLemAutoRun.h:498
#define LAR_MSG
message tag for the message/error handler
Definition: lemAutoRun.h:33
bool fTflFeRunning
flag indicating if the tfl_scfe is running
Definition: PLemAutoRun.h:455
PKey * fSetupSampleEnabledKey
pointer to the ODB key: Sample enabled flag
Definition: PLemAutoRun.h:530
float fPrefNeedleValveCof_4_0
NV setting = _1_0 * _1_1 * T for 15&lt;T.
Definition: PLemAutoRun.h:329
QString GetAutoRunSequence()
PLemAutoRun::GetAutoRunSequence.
void SetTemp(AutoRunCmd *arc)
QVector< float > * GetHvDemands()
Definition: PLemAutoRun.h:201
PKey * fModNameKey
pointer to the ODB key: moderator info
Definition: PLemAutoRun.h:490
void SetFieldWEWH(AutoRunCmd *arc)
QString fTflInputPath
ODB path to the tfl input variables.
Definition: PLemAutoRun.h:418
float fFlowMaxRelFlowDiffToConsider
maximum rel flow error to consider
Definition: PLemAutoRun.h:310
float fBHMinFlow
min. allowed flow for the bronkhorst flow meter
Definition: PLemAutoRun.h:291
bool fSetupWewEnabled
true if the WEW magnet is in use. This is fed with the WEWL/H power supplies.
Definition: PLemAutoRun.h:385
void ReadSampleCryoXML()
#define BPVX_SET
ODB offset for BPVX set cmd (output)
Definition: PLemAutoRun.cpp:59
bool fSetupSampleEnabled
true if the sample frontend is enabled (normal operation), otherwise MCP2 setup.
Definition: PLemAutoRun.h:384
QString fLemvacOutputPath
ODB path to the lemvac output variables.
Definition: PLemAutoRun.h:431
#define LS340_INPUT_HEATER_MODE
ODB Offset for the heater control mode read back.
Definition: PLemAutoRun.cpp:83
#define LAR_TT_IDLE
PAutoRunCmdVector::Iterator fAutoRunCurrentIter
current autorun cmd
Definition: PLemAutoRun.h:468
PKey * fDanfysikInputKey
pointer to the ODB key: danfysik input variables
Definition: PLemAutoRun.h:506
bool fHVFeRunning
flag indicating if the hv_fug_scfe is running
Definition: PLemAutoRun.h:460
#define HV_FUG_MAX_TRY
number of HV update trials
#define LAR_FOM_CURRENT_NOT_REACHED
FOM current not reached.
Definition: lemAutoRun.h:83
#define SM_OUTPUT_NEEDLEVALVE
ODB offset for the demand value for the needlevalve.
bool fAnalyzerRunning
flag indicating if the analyzer is running
Definition: PLemAutoRun.h:453
void SetFlowAndNeedleValve(QString flowParam, float &rampSpeed, float newDemandTemp, float deltaT, float flowScale)
#define HV_FUG_RIGHT_RODS
ODB Offset for the FUG HV of the right rods of the spin rotator.
QString fSpinRotAnglePath
ODB path to the spin rotation angle.
Definition: PLemAutoRun.h:402
QString fMagFieldPath
ODB path to the magnetic field value.
Definition: PLemAutoRun.h:417
QString fLemSetupPath
ODB path to the LEM setup info.
Definition: PLemAutoRun.h:399
PKey * fDanfysikOutputKey
pointer to the ODB key: danfysik output variables
Definition: PLemAutoRun.h:507
float fPrefNeedleValveCof_3_1
Definition: PLemAutoRun.h:328
bool fRunCheckEvents
if true check number of events, otherwise check time
Definition: PLemAutoRun.h:475
float fBHFlowPHeat0
see SampleTempAdjustFlow()
Definition: PLemAutoRun.h:292
#define LS340_INPUT_CF2
ODB Offset for the cold finger 2 sensor.
Definition: PLemAutoRun.cpp:75
#define BPVX_STATE
ODB offset for BPVX state (input)
Definition: PLemAutoRun.cpp:62
#define LAR_TT_ABORTED
double datetime
time as obtained from the LS340
Definition: PLemAutoRun.h:58
#define LAR_BPV_CLOSED_AT_RUN_START
BPVX/Y closed at run start.
Definition: lemAutoRun.h:84
float fDanfysikMaxCurrent
maximal allowed current for the danfysik power supply
Definition: PLemAutoRun.h:354
#define WEWH_OUTPUT_CMD
ODB Offset for the WEWH cmd (0=off, 1=on, 2=reset, 3=reset-dsp.
#define HTML_WARMUP
html warmup tag
int fCurrentAutoRunCmd
number of the current autorun cmd
Definition: PLemAutoRun.h:470
QString fFieldPwrSupply
name of the power supply to generate the magnetic field (WEWL, WEWH, danfysik)
Definition: PLemAutoRun.h:279
void SetFOM(AutoRunCmd *arc)
bool fDumpInUse
flag telling if a raw data dump is going on
Definition: PLemAutoRun.h:367
void CheckMidasAlarms(PAutoRunCmdVector::Iterator iter)
void SetTfl(AutoRunCmd *arc)
PLemAutoRun::SetTfl.
#define WEWH_INPUT_CURRENT
ODB Offset for the measured current of the WEWH.
SampleTempInfo fSampleTempHisto[SAMPLE_TEMP_HISTO_MAX]
array holding the sample temperature history
Definition: PLemAutoRun.h:344
QString fFOMOutputPath
ODB path to the FOM output variables.
Definition: PLemAutoRun.h:433
#define WEWH_OUTPUT_CURRENT
ODB Offset for the demand current of the WEWH.
void StatusMsg(const QString statusMsg)
float fAbsMaxTempDiff
absolute temperature deviation allowed in stability test
Definition: PLemAutoRun.h:299
int noElements
number of parameters used for this command
Definition: lemAutoRun.h:224
float fHeaterMin
min. acceptable heater value
Definition: PLemAutoRun.h:303
float flow
helium flow (read back)
Definition: PLemAutoRun.h:62
#define NO_ENERGY_LOSS_PARAM
Definition: PLemAutoRun.h:47
float fWEWHMaxCurrent
maximal allowed current for the WEWH power supply
Definition: PLemAutoRun.h:352
QString fLemvacFeName
name of the lemvac_scfe in the ODB
Definition: PLemAutoRun.h:452
#define LAR_FIELD_NOT_REACHED
field not reached within timeout error tag
Definition: lemAutoRun.h:77
float fHVDemandSampleChamber[5]
demand HV of the sample chamber
Definition: PLemAutoRun.h:288
QString fAutoRunSequence
autorun sequence file name as found under /AutoRun/Auto Run Sequence
Definition: PLemAutoRun.h:256
void GetDemandHVSampleChamber()
void RawVoltageDump()
#define BH_INPUT_VALVE
ODB Offset for the measured BH valve opening.
QString param[LAR_MAX_PARAM]
parameter list of the command
Definition: lemAutoRun.h:225
#define LS340_INPUT_PID_D
ODB Offset for the D value of the PID (read back)
Definition: PLemAutoRun.cpp:81
#define LAR_SAMPLE_HV_NOT_REACHED
sample high voltage not reached within timeout error tag
Definition: lemAutoRun.h:76
void SetFieldDanfysik(AutoRunCmd *arc)
#define DANFYSIK_INPUT_CURRENT
ODB Offset for the measured current of the danfysik.
void SetOmegaSetpoint(float setpoint)
#define HTML_STRANGE
html strange autorun starting condition tag
void ErrorMsg(int noOfErrors, int idx, int errorNo, int line, QString errorMsg)
QString fSampleOvenOmegaInputPath
ODB path to the sample oven omega: input variables.
Definition: PLemAutoRun.h:428
void SetLEMSetup(AutoRunCmd *arc)
QString fAlarmsPath
ODB path to the alarms.
Definition: PLemAutoRun.h:392
bool RunStopCheck()
float fBHFlowTemp
variable needed to calculate the flow if non is explicitly given (see SetTemp())
Definition: PLemAutoRun.h:295
QString fMagParamBparPath
ODB path to the Bpar parameters (A -&gt; G)
Definition: PLemAutoRun.h:436
#define TEMP_I_PID
I (PID) parameter tag.
PKey * fSampleSensorTypeKey
pointer to the ODB key: sample cryo LS340 sensor type assignement
Definition: PLemAutoRun.h:515
QString fAutoRunPath
path to the autorun sequence directory
Definition: PLemAutoRun.h:278
QString fXMLAutoRunHTML
path-file name of the HTML autorun status page
Definition: PLemAutoRun.h:277
#define LAR_TT_WARMUP
QString fBeamlineDemandPath
ODB path to the beamline demand variables.
Definition: PLemAutoRun.h:434
float fDSetRatio
ratio at which the PID-D has to be switched back (for temperature increase)
Definition: PLemAutoRun.h:298
#define LAR_LS340_TEMP_NOT_STABLE
sample temperature is out of the tolerance band
Definition: lemAutoRun.h:81
void CheckClients()
int fGotoLine
address to jump to within a running autorun. Defined under /AutoRun/GotoLine
Definition: PLemAutoRun.h:258
float fPrefNeedleValveCof_1_1
Definition: PLemAutoRun.h:324
#define HV_FUG_SAMPLE
ODB Offset for the FUG HV of the sample.
QString fRunInfoPath
ODB path to the run info.
Definition: PLemAutoRun.h:389
#define HV_FUG_RAT
ODB Offset for the FUG HV of the top ring anode.
PKey * fSpinRotMagOutputKey
pointer to the ODB key: danfysik spin rotator output variables
Definition: PLemAutoRun.h:505
int state
1 = stopped, 2 = paused, 3 = running
Definition: PLemAutoRun.h:71
void DegaussDanfysik(AutoRunCmd *arc)
QString fAlarmTdHvTripPath
ODB path to the TD HV trip alarm/warning.
Definition: PLemAutoRun.h:393
void FeedLiveDataAutoRun()
PLemAutoRun::FeedLiveDataAutoRun.
QString fNextAutoRunSequence
next autorun sequence file name as found under /AutoRun/Next
Definition: PLemAutoRun.h:259
#define LAR_MIDAS_READBACK_FAILURE
MIDAS readback verification timeout fired.
Definition: lemAutoRun.h:74
QString fSampleFeName
name of the tfl_scfe in the ODB
Definition: PLemAutoRun.h:447
#define SAMPLE_CRYO_OUTPUT
Definition: PLemAutoRun.h:42
#define TEMP_P_PID
P (PID) parameter tag.
PKey * fSampleDatetimeKey
pointer to the ODB key: sample cryo date and time
Definition: PLemAutoRun.h:518
void Wait(int timeout)
float fDFlowDp0
calculates d(flow)/dP from d(flow)/dP =
Definition: PLemAutoRun.h:311
double fSampleHistoTime
time stamp of the current reading in seconds since 1-1-2000
Definition: PLemAutoRun.h:340
float fHeatCapCof3
Definition: PLemAutoRun.h:319
PKey * fHVDetectorMeasuredKey
pointer to the ODB key: HV Detector measured values
Definition: PLemAutoRun.h:503
PKey * fSampleChannelKey
pointer to the ODB key: sample cryo LS340 channel assignement
Definition: PLemAutoRun.h:514
bool fEnableAll
flag telling if all watched clients and equipments will be enabled/disabled by default.
Definition: PLemAutoRun.h:263
float SetDemandTempRamping(QString rampParam)
#define HTML_ABORTED
html abortion tag
QFile fDumpFile
file for dumping raw_voltage
Definition: PLemAutoRun.h:370
bool ShowComments()
PLemAutoRun::ShowComments.
float fFlowTimeoutReduction
timeout between gradual flow reduction while cooling
Definition: PLemAutoRun.h:308
#define BPVY_STATE
ODB offset for BPVY state (input)
Definition: PLemAutoRun.cpp:63
float fFieldTimeout
time in which the field ramping must be accomplished (in (sec))
Definition: PLemAutoRun.h:284
void UpdateRunState(const int state)
UpdateRunState.
#define BPV_CLOSE
closing command for BPVX/Y
Definition: PLemAutoRun.cpp:56
PKey * fSpinRotAngleKey
pointer to the ODB key: spin rotation angle
Definition: PLemAutoRun.h:495
float fMaxTempIncrease
maximal temperature increase without shuting down the HV
Definition: PLemAutoRun.h:283
#define BEAMLINE_KV61_DEMAND_CH
ODB Index of the KV61 demand channel.
float fBHMaxFlow
max. allowed flow for the bronkhorst flow meter
Definition: PLemAutoRun.h:290
int CheckFieldCmd(QString &errMsg)
#define LAR_STATE_STOPPED
auto run state stopped, i.e. idle
Definition: lemAutoRun.h:37
PLemAutoRun(QString &host, QString &exp)
#define LAR_MIDAS_KEY_FAILURE
MIDAS key failure error tag.
Definition: lemAutoRun.h:68
#define LAR_FUG_NO_RESPONSE
FUG high voltage not responding error tag.
Definition: lemAutoRun.h:79
SampleTempInfo fSampleTempTrend
1st derivative of the quadratic model of the temperature control parameters
Definition: PLemAutoRun.h:346
QString fHVMeasuredPath
ODB path to the FUG HV measured variables.
Definition: PLemAutoRun.h:407
int fHvTripFlag
flag: set if the TD HV trip alarm fired
Definition: PLemAutoRun.h:270
#define HV_FUG_RAL
ODB Offset for the FUG HV of the left ring anode.
QString fTofMaxPath
ODB path to the TOF max.
Definition: PLemAutoRun.h:396
bool CheckForTransportHvCmd()
bool fFrontendRunning
flag indicating if the frontend is running
Definition: PLemAutoRun.h:454
#define SPINT_ROT_OUTPUT_CURRENT
ODB Offset for the demand current of the Spin Rotator Magnet output.
float fFOMCurrentAccuracy
current accuracy needed before going on (in (mA))
Definition: PLemAutoRun.h:361
QString fHvSettingsPath
Definition: PLemAutoRun.h:364
#define HTML_PARSE_ERROR
html autorun script parse error tag
bool characters(const QString &)
void ConnectToExp()
PKey * fLemvacInputKey
pointer to the ODB key: lemvac input values
Definition: PLemAutoRun.h:523
#define BPVY_ENABLED
ODB offset for BPVY enabled flag (output)
Definition: PLemAutoRun.cpp:60
#define HV_FUG_LEFT_RODS
ODB Offset for the FUG HV of the left rods of the spin rotator.
void SetSampleLS340ZoneSettings()
#define LS340_OUTPUT_SETPOINT
ODB Offset for the setpoint.
Definition: PLemAutoRun.cpp:87
int lineNo
line number from where in the user auto run sequence the command originates
Definition: lemAutoRun.h:223
#define HTML_RUNNING
html running tag
QString fModNamePath
ODB path to the moderator info.
Definition: PLemAutoRun.h:397
#define TEMP_RAMP
ramping parameter tag
float fHeatCapCof2
HC_1 * T + HC_2 * T² + HC_3 * T³
Definition: PLemAutoRun.h:318
#define LAR_XML_FILE_MISSING
XML file missing error tag.
Definition: lemAutoRun.h:64
#define LS340_OUTPUT_RAMP
ODB Offset for the demand temperature ramping.
Definition: PLemAutoRun.cpp:93
#define HV_FUG_MOD
ODB Offset for the FUG HV of the moderator.
bool fWEWFeRunning
flag indicating if the wew_scfe is running
Definition: PLemAutoRun.h:457
float fSampleOvenOmegaInput[SAMPLE_OVEN_OMEGA_INPUT]
Definition: PLemAutoRun.h:380
QString fSampleCtrlChPath
ODB path to the sample cryo LS340 control channel.
Definition: PLemAutoRun.h:420
void SetBPV(AutoRunCmd *arc)
bool fWarmUpWished
warmup command present
Definition: PLemAutoRun.h:373
#define HV_FUG_LENSE_2
ODB Offset for the FUG HV of the lense 2.
bool fRAPulsingEnabled
flag: if true, the RA pulsing is enabled and hence WEW can take any field values. ...
Definition: PLemAutoRun.h:269
#define WEWL_INPUT_CURRENT
ODB Offset for the measured current of the WEWL.
POdbTagVector * fOdbTagVector
pointer to the ODB tag list
Definition: PLemAutoRun.h:466
PKey * fEnergyLossParamKey
pointer to the ODB key: energy loss parameters
Definition: PLemAutoRun.h:497
#define HV_FUG_RIGHT_PLATE
ODB Offset for the FUG HV of the right plate of the spin rotator.
QString fTriggerEventsPath
ODB path to the trigger events.
Definition: PLemAutoRun.h:390
#define LS340_INPUT_RAMP
ODB Offset for the demand temperature ramping read back.
Definition: PLemAutoRun.cpp:84
float fRunTimeout
time in sec after which the run shall be stopped.
Definition: PLemAutoRun.h:478
void GotoLine(PAutoRunCmdVector::Iterator &iter, int max)
#define HTML_ALARM
html alarm tag
PKey * fSampleOvenOmegaOutputKey
pointer to the ODB key: sample oven omega output values
Definition: PLemAutoRun.h:522
float fPrefNeedleValveCof_4_1
Definition: PLemAutoRun.h:330
#define WEWL_OUTPUT_CMD
ODB Offset for the WEWL cmd (0=off, 1=on, 2=reset, 3=reset-dsp.
float fFlowSetAbsolute
absolute flow deviation allowed in stability test
Definition: PLemAutoRun.h:307
float fFlowSetRatio
relative flow deviation allowed in stability test
Definition: PLemAutoRun.h:306
QString fSampleOvenOmegaOutputPath
ODB path to the sample oven omega: output variables.
Definition: PLemAutoRun.h:429
float fMaxTempTrend
max. acceptable temperature trend
Definition: PLemAutoRun.h:301
QString fMagParamWewPath
ODB path to the WEW parameters (A -&gt; G)
Definition: PLemAutoRun.h:435
#define BPVX_ENABLED
ODB offset for BPVX enabled flag (output)
Definition: PLemAutoRun.cpp:58
bool fDanfysikFeRunning
flag indicating if the danfysik_scfe is running
Definition: PLemAutoRun.h:458
bool startElement(const QString &, const QString &, const QString &, const QXmlAttributes &qAttr)
QString fClientsPath
ODB path to the running clients.
Definition: PLemAutoRun.h:405
#define CRYO_LOWTEMP
LowTemp cryo in use.
Definition: PLemAutoRun.cpp:46
QString fSampleSensorTypePath
ODB path to the sample cryo LS340 sensor type assignement.
Definition: PLemAutoRun.h:422
#define LS340_OUTPUT_HEATER_MODE
ODB Offset for the heater control mode.
Definition: PLemAutoRun.cpp:92
bool characters(const QString &)
#define LAR_RA_HV_OFF_AT_RUN_START
RA HV&#39;s off at run starts.
Definition: lemAutoRun.h:85
PKey * fSpinRotEnabledKey
pointer to the ODB key: spin rotation enabled flag
Definition: PLemAutoRun.h:494
void SetTitle(AutoRunCmd *arc)
void SampleTempSetNeedleValve(float value)
int run_number
run number
Definition: PLemAutoRun.h:73
PKey * fHVDetectorDemandKey
pointer to the ODB key: HV Detector demand values
Definition: PLemAutoRun.h:502
void Degauss(AutoRunCmd *arc)
float SampleTempPrefHeaterOutput(float heaterRange)
#define LAR_STATE_LOAD
tag needed to update the web-page without starting the run, process starting
Definition: lemAutoRun.h:41
PKey * fBeamlineDemandKey
pointer to the ODB key: Beamline demand values
Definition: PLemAutoRun.h:527
#define SPINT_ROT_INPUT_CURRENT
ODB Offset for the demand current of the Spin Rotator Magnet output.
PKey * fTofMinKey
pointer to the ODB key: TOF min
Definition: PLemAutoRun.h:488
#define LS340_OUTPUT_PID_P
ODB Offset for P output.
Definition: PLemAutoRun.cpp:88
double fSampleHistoLastTime
time stamp of the previous reading in seconds since 1-1-2000
Definition: PLemAutoRun.h:341
#define LAR_BPVY_NO_RESPONSE
BPVY not responding error tag.
Definition: lemAutoRun.h:78
float fHVTimeout
time in which the HV ramping must be accomplished (in (sec))
Definition: PLemAutoRun.h:286
bool SampleTempStable()
#define BH_OUTPUT_FLOW
ODB Offset for the demand flow value.
#define OMEGA_OVEN_INPUT_SETPOINT
ODB Offset for the setpoint read back.
Definition: PLemAutoRun.cpp:96
bool fSampleTempUnstable
flag: true if the temperature is out of bound
Definition: PLemAutoRun.h:339
PKey * fTflOutputKey
pointer to the ODB key: tfl output values
Definition: PLemAutoRun.h:512
PKey * fHVDemandKey
pointer to the ODB key: FUG HV demand values
Definition: PLemAutoRun.h:499
#define SC_VENT_CMD
ODB offset for SC vent command tag (output)
Definition: PLemAutoRun.cpp:68
#define CRYO_OVEN_OMEGA
Oven in use, controlled by Omega Controller.
Definition: PLemAutoRun.cpp:47
float fTimeoutFlowSet
timeout before the flow can be changed next time (see SetTemp())
Definition: PLemAutoRun.h:304
QString fSpinRotEnabledPath
ODB path to the spin rotation enabled flag.
Definition: PLemAutoRun.h:401
#define TEMP_D_PID
D (PID) parameter tag.
PLemAutoRunXMLParser(PLemAutoRun *lar)
QString fAnalyzerName
name of the analyzer in the ODB
Definition: PLemAutoRun.h:444
PKey * fMagParamWewKey
pointer to the ODB key: WEW magnet parameters (A -&gt; G)
Definition: PLemAutoRun.h:528
void SetIgnoreClients(AutoRunCmd *arc)
#define HV_NHQ_TD_LAST
ODB Offset for the NHQ HV of the last element of the TD.
QString fDumpFileName
file name of the raw voltage dump. It will be RawVoltageOutput-&lt;cryo&gt;-&lt;datatime&gt;.dat, e.g. RawVoltageOutput-Konti4-220316-1235.dat
Definition: PLemAutoRun.h:369
float fRelMaxTempDiff
relative temperature deviation allowed in stability test
Definition: PLemAutoRun.h:300
float fBHFlowDHeat
see SampleTempAdjustFlow()
Definition: PLemAutoRun.h:294
PKey * fMagFieldKey
pointer to the ODB key: magnetic field value
Definition: PLemAutoRun.h:510
PKey * fSampleOvenOmegaInputKey
pointer to the ODB key: sample oven omega input values
Definition: PLemAutoRun.h:521
float fBHFlowTempOffset
variable needed to calculate the flow if non is explicitly given (see SetTemp())
Definition: PLemAutoRun.h:296
QString fDanfysikInputPath
ODB path to the danfysik input variables.
Definition: PLemAutoRun.h:413
QString fHVCurrentPath
ODB path to the FUG HV measured current variables.
Definition: PLemAutoRun.h:408
void SetFlow(QString flowParam)
QString fTofMinPath
ODB path to the TOF min.
Definition: PLemAutoRun.h:395
void WaitUntilSampleLS340Ready()
#define LS340_INPUT_HEATER
ODB Offset for the heater read back.
Definition: PLemAutoRun.cpp:77
#define TEMP_FLOW
flow parameter tag
#define LS340_OUTPUT_HEATER_RANGE
ODB Offset for the heater range.
Definition: PLemAutoRun.cpp:91
float measured_T
measured temperature of the sample
Definition: PLemAutoRun.h:60
bool CheckOdbType(INT type, AutoRunCmd *arc)
bool fLemvacFeRunning
flag indicating if the lemvac_scfe is running
Definition: PLemAutoRun.h:461
void SetLS340Setpoint(float setpoint, float rampSpeed)
#define FOM_CURRENT_DEMAND
ODB Index of the FOM current setpoint.
#define DANFYSIK_OUTPUT_CURRENT
ODB Offset for the demand current of the danfysik.
float fFlowFactor
constant used in SampleTempConsiderFlow()
Definition: PLemAutoRun.h:305
bool GetAllKeys()
QString fXMLSchemaFln
path-file name of the XML-schema for the parsing process
Definition: PLemAutoRun.h:274
QString fEnergyLossParamPath
ODB path to the energy loss parameters.
Definition: PLemAutoRun.h:404
SampleTempInfo fSampleTempAverage
average temperature control parameters
Definition: PLemAutoRun.h:345
float heater
sample heater
Definition: PLemAutoRun.h:61
#define LAR_RECIEVED_SHUTDOWN_CMD
recieved shutdown cmd tag
Definition: lemAutoRun.h:49
void SetModInfo(AutoRunCmd *arc)
QString fExpName
experiment name
Definition: PLemAutoRun.h:273
void SetTempOvenOmega(AutoRunCmd *arc)
int fDumpCounter
counter of raw voltage dumps
Definition: PLemAutoRun.h:368
PKey * fSampleCryoKey
pointer to the ODB key: sample cryo name
Definition: PLemAutoRun.h:496
float fPrefNeedleValveCof_2_1
Definition: PLemAutoRun.h:326
float fMagParamBpar[2]
calibration array for the Bpar
Definition: PLemAutoRun.h:355
void FeedLiveDataErrors(int noOfErrors, int idx, int, int line, QString errorMsg)
int fSampleBhOdbOffsetInput
ODB offset of the bronkhorst within the ODB (input variables)
Definition: PLemAutoRun.h:441
QString fXMLAutoRunFln
path-file name of the generated XML-autorun sequence
Definition: PLemAutoRun.h:275
void SetLS340HeaterRangeAndPIDs(AutoRunCmd *arc)
int fSampleHistoNoEntries
number of entries in the history
Definition: PLemAutoRun.h:342
#define SC_VENT_ENABLED
ODB offset for SC vent enable flag (output)
Definition: PLemAutoRun.cpp:67
#define TEMP_DELTA_T
delta T parameter tag
#define HV_NHQ_MCP1
ODB Offset for the NHQ HV of the MCP1.
float fDFlowDpExp
Definition: PLemAutoRun.h:313
#define SAMPLE_CRYO_INPUT
Definition: PLemAutoRun.h:41
#define LAR_MIDAS_DEVICE_NOT_REMOTE
MIDAS device not remote error tag.
Definition: lemAutoRun.h:71
void UpdateStatusMsg(const QString statusMsg)
void SetTof(AutoRunCmd *arc)
void SetIgnoreAlarms(AutoRunCmd *arc)
bool endElement(const QString &, const QString &, const QString &)
void DisconnectAndQuit()
void SetOdbDataArray(AutoRunCmd *arc)
void RunStop(AutoRunCmd *arc)
int fSampleHistoPos
index of the start of the ring buffer
Definition: PLemAutoRun.h:343
#define LAR_STATE_NEXT
tag showing that a next autrun shall be executed
Definition: lemAutoRun.h:43
void SetHvOff(AutoRunCmd *arc)
#define WEWL_INPUT_STATUS
ODB Offset for the WEWL status.
#define HV_FUG_RAR
ODB Offset for the FUG HV of the right ring anode.
void WarmUp(PAutoRunCmdVector::Iterator iter)
PKey * fLemSetupKey
pointer to the ODB key: LEM setup info
Definition: PLemAutoRun.h:492
int fSampleBhOdbOffsetOutput
ODB offset of the bronkhorst within the ODB (output variables.
Definition: PLemAutoRun.h:442
void CheckForOdbSetDataCmds()
QString fSampleChannelPath
ODB path to the sample cryo LS340 channel assignement.
Definition: PLemAutoRun.h:421
#define HV_FUG_LENSE_3
ODB Offset for the FUG HV of the lense 3.
float NeedleValve(float Tset)
#define LAR_STATE_STARTING
auto run state is: starting up
Definition: lemAutoRun.h:39
void SetSpinRot(AutoRunCmd *arc)
bool fSampleTempRegulation
flag: if true temperature regulation algorithm is active, otherwise not
Definition: PLemAutoRun.h:338
#define FOM_STANDBY
ODB Index of the FOM stanby flag.
#define BPV_OPEN
opening command for BPVX/Y
Definition: PLemAutoRun.cpp:57
PKey * fSetupBparEnabledKey
pointer to the ODB key: Bpar enabled flag
Definition: PLemAutoRun.h:532
int fSampleCtrlCh
index of channel A or B
Definition: PLemAutoRun.h:335
friend void TdHvTripFlagChanged(HNDLE, HNDLE, void *)
float fPrefNeedleValveRelStep
relative change in SampleTempConsiderNeedleValve
Definition: PLemAutoRun.h:331
#define BPVY
BPVY label.
Definition: PLemAutoRun.cpp:55
#define LS340_CTRL_ZONE
LS340 in table driven PID mode.
Definition: PLemAutoRun.cpp:72
#define BPV_STATE_CLOSED
BPVX/Y closed.
Definition: PLemAutoRun.cpp:65
QMap< QString, bool > fEnabled
map holding the enable/disable info of all the clients and equipments
Definition: PLemAutoRun.h:264
bool fSampleOvenOmegaFeRunning
flag indicating if the omega_scfe is running
Definition: PLemAutoRun.h:459
void SetTransportHV(AutoRunCmd *arc)
#define LS340_OUTPUT_PID_I
ODB Offset for I output.
Definition: PLemAutoRun.cpp:89
bool fRunStopped
flag telling if a run is stopped
Definition: PLemAutoRun.h:473
void DegaussWEW(AutoRunCmd *arc)
QDateTime fWarmUpDateTime
when the warmup shall take place
Definition: PLemAutoRun.h:375
#define LS340_OUTPUT_REMOTE
ODB Offset for the remote output flag.
Definition: PLemAutoRun.cpp:86
void SetFlowTweak(float flow)
PKey * fTriggerEventsKey
pointer to the ODB key: trigger event
Definition: PLemAutoRun.h:483
#define LS340_INPUT_HEATER_RANGE
ODB Offset for the heater range read back.
Definition: PLemAutoRun.cpp:82
PKey * fSampleInputKey
pointer to the ODB key: sample cryo input values
Definition: PLemAutoRun.h:516
bool startElement(const QString &, const QString &, const QString &, const QXmlAttributes &)
float pressure
helium pressure at cryo outlet
Definition: PLemAutoRun.h:63
float fMagParamWew[2]
calibration array for the WEW
Definition: PLemAutoRun.h:353
#define CRYO_KONTI
Konti cryo in use.
Definition: PLemAutoRun.cpp:45
PKey * fModDateKey
pointer to the ODB key: moderator growing date
Definition: PLemAutoRun.h:491
void CheckForWarmUpCmd()
QString fTflOutputPath
ODB path to the tfl output variables.
Definition: PLemAutoRun.h:419
QTime fRunStarted
time stamp, when a run started
Definition: PLemAutoRun.h:477
QString fHVDemandPath
ODB path to the FUG HV demand variables.
Definition: PLemAutoRun.h:406
SampleTempInfo fSampleTempSecond
2nd derivative of the quadratic model of the temperature control parameters
Definition: PLemAutoRun.h:347
bool LoadHvSettings(PAutoRunCmdVector::Iterator currentIter, QString fln, int lineNo, bool simulated=false)
void HandleParseError(int noOfErrors, int idx, int errorNo, int line, QString errorMsg)
#define OMEGA_OVEN_INPUT_TEMP
ODB Offset for the temperature read back.
Definition: PLemAutoRun.cpp:95
QString fSetupWewEnabledPath
ODB path to the WEW enabled flag.
Definition: PLemAutoRun.h:438
PKey * fWEWInputKey
pointer to the ODB key: WEW input values
Definition: PLemAutoRun.h:508
PKey * fAlarmTdHvTripKey
pointer to the ODB key: TD HV trip trigger flag
Definition: PLemAutoRun.h:485
#define LAR_MSG_NO_LINE_NO
message tag for the message/error handler for no line number information
Definition: lemAutoRun.h:34
bool characters(const QString &)
bool fIgnoreClients
flag: if true checking of clients will not performed: only for testing!!
Definition: PLemAutoRun.h:266
void ReceivedShutdownCmd()
slot executed if a shutdown command has been received
float EmpiricalFlow(float Tset, float rampSpeed)
QString fSampleInputPath
ODB path to the sample cryo (LS340, bronkhorst) input variables.
Definition: PLemAutoRun.h:423
#define WEWH_INPUT_STATUS
ODB Offset for the WEWH status.
int GetRunState()
PLemAutoRun::GetRunState.
PKey * fSampleNameKey
pointer to the ODB key: Sample Name
Definition: PLemAutoRun.h:493
#define RUN_STOPPED
MIDAS run stopped tag.
Definition: PLemAutoRun.cpp:50
#define LAR_OUT_OF_MEMORY
out of memory error tag
Definition: lemAutoRun.h:47
#define FOM_CURRENT_MEASURED
ODB Index of the FOM current reading.
#define HV_FUG_MIRROR
ODB Offset for the FUG HV of the mirror.
QString fSampleOutputPath
ODB path to the sample cryo (LS340, bronkhorst) output variables.
Definition: PLemAutoRun.h:424
#define LS340_INPUT_SETPOINT
ODB Offset for the setpoint read back.
Definition: PLemAutoRun.cpp:78
PKey * fSampleOutputKey
pointer to the ODB key: sample cryo output values
Definition: PLemAutoRun.h:517
PKey * fHVMeasuredKey
pointer to the ODB key: FUG HV measured values
Definition: PLemAutoRun.h:500
QString fSampleNoConnectionPath
ODB path to the sample cryo (LS340, bronkhorst) DD &#39;no connection&#39; flag.
Definition: PLemAutoRun.h:427
QString fWEWOutputPath
ODB path to the WEW output variable.
Definition: PLemAutoRun.h:416
#define SAMPLE_TEMP_HISTO_MAX
Definition: PLemAutoRun.h:45
PKey * fSampleNoConnectionKey
pointer to the ODB key: sample cryo no connection
Definition: PLemAutoRun.h:520
QString fFOMInputPath
ODB path to the FOM input variables.
Definition: PLemAutoRun.h:432
QString fHVDetectorMeasuredPath
ODB path to the HV Detectors measured variables.
Definition: PLemAutoRun.h:410
int GetGotoLine()
PLemAutoRun::GetGotoLine.
#define LS340_CTRL_PID
LS340 in manual PID mode.
Definition: PLemAutoRun.cpp:71
float fSampleOutput[SAMPLE_CRYO_OUTPUT]
Definition: PLemAutoRun.h:379
float fSampleOvenOmegaOutput[SAMPLE_OVEN_OMEGA_OUTPUT]
Definition: PLemAutoRun.h:381
float fFlowLowestFlowToConsider
lowest demand flow to consider
Definition: PLemAutoRun.h:309
float fSampleInput[SAMPLE_CRYO_INPUT]
Definition: PLemAutoRun.h:378
#define CRYO_NO
no cryo in use
Definition: PLemAutoRun.cpp:44
double LakeShoreTime(char *str)
#define HV_FUG_RAB
ODB Offset for the FUG HV of the bottom ring anode.
float fWEWCriticalCurrentRA
critical current for the WEW. For larger currents, the RA HV&#39;s should be switched off due to the Penn...
Definition: PLemAutoRun.h:358
PKey * fRunCommentKey
pointer to the ODB key: run comment
Definition: PLemAutoRun.h:487
float fWEWLMaxCurrent
maximal allowed current for the WEWL power supply
Definition: PLemAutoRun.h:351
float fEnergyLossParam[NO_ENERGY_LOSS_PARAM]
energy loss parameters
Definition: PLemAutoRun.h:282
void SetLS340Mode(AutoRunCmd *arc)
bool endElement(const QString &, const QString &, const QString &)
bool endElement(const QString &, const QString &, const QString &)
int fSampleCryoInUse
-1 = no cryo in use, 0 = Konti-Cryo in use, 1 = LowTemp-Cryo, 2 = Oven in use
Definition: PLemAutoRun.h:336
QString fAutoRunStatusMsg
autorun status message as defined under /AutoRun/Status
Definition: PLemAutoRun.h:260
void CheckTempStabilityOvenOmega()
bool fDebug
flag: if true additional messages will be sent to the stdin
Definition: PLemAutoRun.h:265
bool fShowComments
flag indicating if comments shall be suppressed. Defined under /AutoRun/Shows Comments ...
Definition: PLemAutoRun.h:257
int fNoOfAutoRunCmds
number of autorun cmd&#39;s
Definition: PLemAutoRun.h:469
PKey * fSampleRawVoltageKey[10]
pointer to the ODB key: sample cryo raw voltage
Definition: PLemAutoRun.h:519
bool fLargeFlow
signaling extra large flow during cool down
Definition: PLemAutoRun.h:314
void CleanLiveData()
#define HV_FUG_CHS
number of HV channels
void SampleTempAdjustFlow()
void ReadStartupXML()
void SampleTempConsiderNeedleValve()
void DegaussSpinRot(AutoRunCmd *arc)
QString fHVFeName
name of the hv_fug_scfe in the ODB
Definition: PLemAutoRun.h:451
PAutoRunCmdVector * fAutoRunCmdVector
pointer to the autorun cmd list
Definition: PLemAutoRun.h:467
float fHVAccuracy
HV accuracy needed before going on (in (kV))
Definition: PLemAutoRun.h:287
void InitEnabled()
PLemAutoRun::InitEnabled.
QString fSpinRotMagInputPath
ODB path to the danfysik spin rotator magnet power supply input variables.
Definition: PLemAutoRun.h:411
QString fLemvacInputPath
ODB path to the lemvac input variables.
Definition: PLemAutoRun.h:430
#define LAR_TT_FINISHED
#define TEMP_DEMAND_TEMP
demand temperature parameter tag
void TdHvTripFlagChanged(HNDLE, HNDLE, void *)
PKey * fHVCurrentKey
pointer to the ODB key: FUG HV measured current values
Definition: PLemAutoRun.h:501
PLemSampleCryoXMLParser(PLemAutoRun *lar)
QVector< int > * GetChNo()
Definition: PLemAutoRun.h:200
float fPrefNeedleValveCof_3_0
NV setting = _1_0 * _1_1 * T for 10&lt;T&lt;15.
Definition: PLemAutoRun.h:327
PKey * fWEWOutputKey
pointer to the ODB key: WEW output values
Definition: PLemAutoRun.h:509
QString fSampleDatetimePath
ODB path to the sample cryo (LS340, bronkhorst) DD date and time variable.
Definition: PLemAutoRun.h:425
PKey * fMagParamBparKey
pointer to the ODB key: Bpar magnet parameters (A -&gt; G)
Definition: PLemAutoRun.h:529
PKey * fLemvacOutputKey
pointer to the ODB key: lemvac output values
Definition: PLemAutoRun.h:524
float fFieldAccuracy
field accuracy needed before going on (in (A))
Definition: PLemAutoRun.h:285
float fPrefNeedleValveCof_2_0
NV setting = _1_0 * _1_1 * T for 8&lt;T&lt;10.
Definition: PLemAutoRun.h:325
#define LAR_MIDAS_FE_NOT_RUNNING
MIDAS frontend not running error tag.
Definition: lemAutoRun.h:70
#define LAR_MIDAS_ODB_FAILURE
MIDAS odb failure error tag.
Definition: lemAutoRun.h:69
float fBHFlowPHeat1
see SampleTempAdjustFlow()
Definition: PLemAutoRun.h:293
void SetDump(AutoRunCmd *arc)
#define LAR_LS340_INPUT_NONSENSE
sample lakshore readback doesn&#39;t make any sense
Definition: lemAutoRun.h:80
#define LAR_STOP_STOP_NONSENSE
run stopped and STOP command called: doesn&#39;t make any sense
Definition: lemAutoRun.h:87
QString fSpinRotMagOutputPath
ODB path to the danfysik spin rotator magnet power supply output variables.
Definition: PLemAutoRun.h:412
PKey * fFOMInputKey
pointer to the ODB key: FOM input values
Definition: PLemAutoRun.h:525
void SetField(AutoRunCmd *arc)
QString fWEWFeName
name of the WEW scfe in the ODB
Definition: PLemAutoRun.h:449
QString fFrontendName
name of the frontend in the ODB
Definition: PLemAutoRun.h:445
#define SM_MODUS_NEEDLEVALVE
ODB offset for the modus value for the needlevalve.
bool isValid(QString &errMsg)
Definition: PLemAutoRun.h:198
PExperiment * fExp
pointer to the midas experiment
Definition: PLemAutoRun.h:482
void SetWait(AutoRunCmd *arc)
#define SM_INPUT_NEEDLEVALVE
ODB offset for the read_back for the needlevalve.
bool fFugHvCheck
flag: if true demand==measured checks for the FUG HV devices will be performed, otherwise not...
Definition: PLemAutoRun.h:268
float fLemVacValveInitialState[2]
states of BPVX, BPVY before set temperature
Definition: PLemAutoRun.h:289
void CheckTempStability()
bool fIgnoreAlarms
flag: if true checking for any alarms will not performed: only for testing!!
Definition: PLemAutoRun.h:267
#define HV_FUG_LEFT_PLATE
ODB Offset for the FUG HV of the left plate of the spin rotator.
QString fHostName
host name on which the experiment is running
Definition: PLemAutoRun.h:272
#define LAR_MIDAS_NO_RUN_TRANSITION
MIDAS no run transition notification obtained within 60sec.
Definition: lemAutoRun.h:73
RunInfo fRunInfo
run info structure (mirror of the ODB /Runinfo)
Definition: PLemAutoRun.h:474
#define LAR_XML_MISSING_ENTRY
XML missing entry error tag.
Definition: lemAutoRun.h:65
SampleTempInfo fSampleTempRmsqd
RMS of the quadratic model of the temperature control parameters.
Definition: PLemAutoRun.h:348
float fPrefNeedleValveCof_1_0
NV setting = _1_0 * _1_1 * T for T&lt;8.
Definition: PLemAutoRun.h:323
float fHeaterMax
max. acceptable heater value
Definition: PLemAutoRun.h:302
PKey * fRunInfoKey
pointer to the ODB key: run info
Definition: PLemAutoRun.h:486
#define LAR_FORCED_RA_OFF
forced switch off of the RA HV&#39;s
Definition: lemAutoRun.h:86
#define LS340_INPUT_PRESSURE
ODB Offset for the He pressure before the bronkhorst.
Definition: PLemAutoRun.cpp:76
#define BPV_STATE_OPEN
BPVX/Y open.
Definition: PLemAutoRun.cpp:64
QString fEnableOnOffModePath
ODB path to the enable On/Off mode, e.g. red/green, pulsing RA.
Definition: PLemAutoRun.h:391
#define LAR_STATE_RUNNING
auto run state running
Definition: lemAutoRun.h:40
int fRunNoEventsNeeded
number of events needed to complete a run
Definition: PLemAutoRun.h:476
bool startElement(const QString &, const QString &, const QString &, const QXmlAttributes &)
QString fSetupSampleEnabledPath
ODB path to the sample enabled flag.
Definition: PLemAutoRun.h:437
QString cmdString
untouched original lar-cmd string
Definition: lemAutoRun.h:221
void ExecAutoRun()
QString fSampleRawVoltagePath
ODB path to the LS340 Raw Voltage.
Definition: PLemAutoRun.h:426
#define HV_NHQ_TD_FIRST
ODB Offset for the NHQ HV of the first element of the TD.
#define BPVY_SET
ODB offset for BPVY set cmd (output)
Definition: PLemAutoRun.cpp:61
QString fSampleCryoPath
ODB path to the sample cryo name used.
Definition: PLemAutoRun.h:403
#define OMEGA_OVEN_OUTPUT_SETPOINT
ODB Offset for the setpoint.
Definition: PLemAutoRun.cpp:98
QString fRunCommentPath
ODB path to the run comment.
Definition: PLemAutoRun.h:394
void SetEnabled(const QString key, bool val)
PLemAutoRun::SetEnabled.
void DisconnectFromExp()
float fSampleTempAccuracy
temperature tolerance
Definition: PLemAutoRun.h:337
PKey * fSpinRotMagInputKey
pointer to the ODB key: danfysik spin rotator input variables
Definition: PLemAutoRun.h:504
PKey * fSampleCtrlChKey
pointer to the ODB key: sample cryo LS340 control channel
Definition: PLemAutoRun.h:513
#define HTML_LOAD
html load tag