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 
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <math.h>
28 #include <string.h>
29 #include <time.h>
30 
31 #include <QCoreApplication>
32 #include <QFile>
33 #include <QFileInfo>
34 #include <QDateTime>
35 #include <QStringList>
36 #include <QMapIterator>
37 #include <QElapsedTimer>
38 #include <QXmlStreamAttributes>
39 #include <QTextStream>
40 
41 #include "lemAutoRun.h"
42 #include "PLemAutoRun.h"
43 
44 // defines ------------------------------------------------------------
45 
46 // Cryo related tags
47 #define CRYO_NO -1
48 #define CRYO_KONTI 0
49 #define CRYO_LOWTEMP 1
50 #define CRYO_OVEN_OMEGA 2
51 
52 // MIDAS flags
53 #define RUN_STOPPED 1
54 #define RUN_PAUSED 2
55 #define RUN_RUNNING 3
56 
57 #define BPVX 0
58 #define BPVY 1
59 #define BPV_CLOSE 3
60 #define BPV_OPEN 2
61 #define BPVX_ENABLED 0
62 #define BPVX_SET 1
63 #define BPVY_ENABLED 2
64 #define BPVY_SET 3
65 #define BPVX_STATE 25
66 #define BPVY_STATE 26
67 #define BPV_STATE_OPEN 5120
68 #define BPV_STATE_CLOSED 3072
69 #define BPV_STATE_LOCKED 2048
70 
71 #define SC_VENT_ENABLED 6
72 #define SC_VENT_CMD 7
73 
74 // LS340/LS336 control commands
75 #define LS_CTRL_PID 1
76 #define LS_CTRL_ZONE 2
77 // LS340 input
78 #define LS340_INPUT_CF1 0
79 #define LS340_INPUT_CF2 1
80 #define LS340_INPUT_PRESSURE 2
81 #define LS340_INPUT_HEATER 7
82 #define LS340_INPUT_SETPOINT 8
83 #define LS340_INPUT_PID_P 9
84 #define LS340_INPUT_PID_I 10
85 #define LS340_INPUT_PID_D 11
86 #define LS340_INPUT_HEATER_RANGE 12
87 #define LS340_INPUT_HEATER_MODE 13
88 #define LS340_INPUT_RAMP 14
89 // LS340 output
90 #define LS340_OUTPUT_REMOTE 0
91 #define LS340_OUTPUT_SETPOINT 1
92 #define LS340_OUTPUT_PID_P 2
93 #define LS340_OUTPUT_PID_I 3
94 #define LS340_OUTPUT_PID_D 4
95 #define LS340_OUTPUT_HEATER_RANGE 5
96 #define LS340_OUTPUT_HEATER_MODE 6
97 #define LS340_OUTPUT_RAMP 7
98 // LS336 input
99 #define LS336_INPUT_CF1 0
100 #define LS336_INPUT_CF2 1
101 #define LS336_INPUT_PRESSURE 4
102 #define LS336_INPUT_HEATER 8
103 #define LS336_INPUT_SETPOINT 9
104 #define LS336_INPUT_PID_P 10
105 #define LS336_INPUT_PID_I 11
106 #define LS336_INPUT_PID_D 12
107 #define LS336_INPUT_HEATER_RANGE 13
108 #define LS336_INPUT_HEATER_MODE 14
109 #define LS336_INPUT_RAMP 15
110 // LS336 output
111 #define LS336_OUTPUT_SETPOINT 0
112 #define LS336_OUTPUT_PID_P 1
113 #define LS336_OUTPUT_PID_I 2
114 #define LS336_OUTPUT_PID_D 3
115 #define LS336_OUTPUT_HEATER_RANGE 4
116 #define LS336_OUTPUT_HEATER_MODE 5
117 #define LS336_OUTPUT_RAMP 6
118 
119 // Omega oven input
120 #define OMEGA_OVEN_INPUT_TEMP 0
121 #define OMEGA_OVEN_INPUT_SETPOINT 6
122 // Omega oven output
123 #define OMEGA_OVEN_OUTPUT_SETPOINT 0
124 
125 // NeedleValve input
126 #define SM_INPUT_NEEDLEVALVE 0
127 // NeedleValve output
128 #define SM_OUTPUT_NEEDLEVALVE 0
129 #define SM_MODUS_NEEDLEVALVE 1
130 // Bronkhorst input
131 #define BH_INPUT_FLOW 0
132 #define BH_INPUT_VALVE 1
133 // Bronkhorst output
134 #define BH_OUTPUT_FLOW 0
135 // Danfsik Spin Rotator Magnet Current
136 #define SPINT_ROT_OUTPUT_CURRENT 2
137 #define SPINT_ROT_INPUT_CURRENT 3
138 // Danfysik input
139 #define DANFYSIK_INPUT_CURRENT 3
140 // Danfysik output
141 #define DANFYSIK_OUTPUT_CURRENT 2
142 // WEW input
143 #define WEWL_INPUT_STATUS 0
144 #define WEWL_INPUT_CURRENT 1
145 #define WEWH_INPUT_STATUS 3
146 #define WEWH_INPUT_CURRENT 4
147 // WEW output
148 #define WEWL_OUTPUT_CMD 0
149 #define WEWL_OUTPUT_CURRENT 1
150 #define WEWH_OUTPUT_CMD 2
151 #define WEWH_OUTPUT_CURRENT 3
152 #define WEW_SSP_LOCK 4
153 // HV FUG
154 #define HV_FUG_MAX_TRY 5
155 #define HV_FUG_CHS 16
156 #define HV_FUG_RIGHT_RODS 0
157 #define HV_FUG_LEFT_RODS 1
158 #define HV_FUG_LEFT_PLATE 2
159 #define HV_FUG_RIGHT_PLATE 3
160 #define HV_FUG_MOD 4
161 #define HV_FUG_MIRROR 8
162 #define HV_FUG_LENSE_2 9
163 #define HV_FUG_LENSE_3 10
164 #define HV_FUG_RAL 11
165 #define HV_FUG_RAR 12
166 #define HV_FUG_RAT 13
167 #define HV_FUG_RAB 14
168 #define HV_FUG_SAMPLE 15
169 // HV NHQ
170 #define HV_NHQ_TD_FIRST 0
171 #define HV_NHQ_TD_LAST 3
172 #define HV_NHQ_MCP1 4
173 // FOM input
174 #define FOM_CURRENT_MEASURED 0
175 #define FOM_VOLTAGE_MEASURED 1
176 #define FOM_BATTERY 2
177 // FOM ouput
178 #define FOM_CURRENT_DEMAND 0
179 #define FOM_STANDBY 1
180 // Beamline KV61, KV62 indices
181 #define BEAMLINE_KV61_DEMAND_CH 26
182 #define BEAMLINE_KV62_DEMAND_CH 28
183 
184 // web related stuff
185 #define HTML_LOAD 0
186 #define HTML_START 1
187 #define HTML_RUNNING 2
188 #define HTML_STOP 3
189 #define HTML_ABORTED 4
190 #define HTML_ALARM 5
191 #define HTML_WARMUP 6
192 #define HTML_STRANGE 7
193 #define HTML_PARSE_ERROR 8
194 #define HTML_FATAL 9
195 
196 // TEMP parameter tags
197 #define TEMP_DEMAND_TEMP 0
198 #define TEMP_DELTA_T 1
199 #define TEMP_STABILITY_TIMEOUT 2
200 #define TEMP_RAMP 3
201 #define TEMP_HEATER_RANGE 4
202 #define TEMP_P_PID 5
203 #define TEMP_I_PID 6
204 #define TEMP_D_PID 7
205 #define TEMP_FLOW 8
206 
207 // autorun transition tags
208 #define LAR_TT_IDLE 0
209 #define LAR_TT_FINISHED 1
210 #define LAR_TT_ABORTED 2
211 #define LAR_TT_WARMUP 3
212 
213 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
214 // implementation of PLemAutoRunXMLParser
215 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
216 
217 //**********************************************************************
218 // constructor
219 //**********************************************************************
226 {
227  fLar = lar;
228 
229  QFile file(fln);
230  if (!file.open(QFile::ReadOnly | QFile::Text) || (file.size()==0))
231  return;
232 
233  fValid = parse(&file);
234 }
235 
236 //**********************************************************************
237 // destructor
238 //**********************************************************************
243 {
244 }
245 
246 //**********************************************************************
247 // parse
248 //**********************************************************************
256 bool PLemAutoRunXMLParser::parse(QIODevice *device)
257 {
258  fXml.setDevice(device);
259 
260  bool expectChars = false;
261  while (!fXml.atEnd()) {
262  fXml.readNext();
263  if (fXml.isStartDocument()) {
264  startDocument();
265  } else if (fXml.isStartElement()) {
266  startElement();
267  expectChars = true;
268  } else if (fXml.isCharacters() && expectChars) {
269  characters();
270  } else if (fXml.isEndElement()) {
271  endElement();
272  expectChars = false;
273  } else if (fXml.isEndDocument()) {
274  endDocument();
275  }
276  }
277  if (fXml.hasError()) {
278  QString msg;
279  msg = QString("%1 Line %2, column %3").arg(fXml.errorString()).arg(fXml.lineNumber()).arg(fXml.columnNumber());
280  cm_msg(MERROR, "lemAutoRun", msg.toLatin1().data());
281  cm_yield(0);
282  return false;
283  }
284 
285  return true;
286 }
287 
288 //**********************************************************************
289 // startDocument
290 //**********************************************************************
295 {
296  return true;
297 }
298 
299 //**********************************************************************
300 // startElement
301 //**********************************************************************
308 {
309  QString qName = fXml.name().toString();
310  QXmlStreamAttributes qAttr = fXml.attributes();
311 
312  if (qName == "xmlSchemaFln") {
314  } else if (qName == "xmlAutoRunFln") {
316  } else if (qName == "xmlAutoRunValidateFln") {
318  } else if (qName == "xmlAutoRunHTML") {
320  } else if (qName == "enable_all") {
321  fKey = eEnableAll;
322  } else if (qName == "autoRunPath") {
323  fKey = eAutoRunPath;
324  } else if (qName == "hvSettingsPath") {
326  } else if (qName == "debug") {
327  fKey = eDebug;
328  } else if (qName == "ignore_clients") {
330  } else if (qName == "ignore_alarms") {
332  } else if (qName == "fug_hv_check") {
333  fKey = eFugHvCheck;
334  } else if (qName == "field_timeout") {
336  } else if (qName == "field_accuracy") {
338  } else if (qName == "hv_timeout") {
339  fKey = eHv_timeout;
340  } else if (qName == "hv_accuracy") {
341  fKey = eHv_accuracy;
342  } else if (qName == "fom_current_accuracy") {
344  } else if (qName == "wew_critical_current_ra") {
346  } else if (qName == "wewl_max_current") {
348  } else if (qName == "wewh_max_current") {
350  } else if (qName == "danfysik_max_current") {
352  } else if (qName == "trigger_events") {
354  setAttribute("trigger_events_odb", qAttr);
355  } else if (qName == "enable_on_off_mode") {
357  setAttribute("enable_on_off_mode_odb", qAttr);
358  } else if (qName == "alarms") {
359  fKey = eAlarms;
360  setAttribute("alarms_odb", qAttr);
361  } else if (qName == "alarms_td_hv_trip") {
363  setAttribute("alarms_td_hv_trip_odb", qAttr);
364  } else if (qName == "run_info") {
365  fKey = eRun_info;
366  } else if (qName == "run_comment") {
367  fKey = eRun_comment;
368  setAttribute("run_comment_odb", qAttr);
369  } else if (qName == "tof_min") {
370  fKey = eTof_min;
371  setAttribute("tof_min_odb", qAttr);
372  } else if (qName == "tof_max") {
373  fKey = eTof_max;
374  setAttribute("tof_max_odb", qAttr);
375  } else if (qName == "mod_name") {
376  fKey = eMod_name;
377  setAttribute("mod_name_odb", qAttr);
378  } else if (qName == "mod_date") {
379  fKey = eMod_date;
380  setAttribute("mod_date_odb", qAttr);
381  } else if (qName == "lem_setup") {
382  fKey = eLem_setup;
383  setAttribute("lem_setup_odb", qAttr);
384  } else if (qName == "sample_name") {
385  fKey = eSample_name;
386  setAttribute("sample_name_info_odb", qAttr);
387  } else if (qName == "spin_rot_enabled") {
389  setAttribute("spin_rot_calib_odb", qAttr);
390  } else if (qName == "spin_rot_angle") {
392  setAttribute("spin_rot_angle_odb", qAttr);
393  } else if (qName == "mag_param_wew") {
395  setAttribute("mag_param_wew_odb", qAttr);
396  } else if (qName == "mag_param_bpar") {
398  setAttribute("mag_param_bpar_odb", qAttr);
399  } else if (qName == "setup_sample_enabled") {
401  setAttribute("setup_sample_odb", qAttr);
402  } else if (qName == "setup_wew_enabled") {
404  setAttribute("setup_wew_odb", qAttr);
405  } else if (qName == "setup_bpar_enabled") {
407  setAttribute("setup_bpar_odb", qAttr);
408  } else if (qName == "sample_cryo") {
409  fKey = eSample_cryo;
410  setAttribute("sample_cryo_info_odb", qAttr);
411  } else if (qName == "energy_loss_param") {
413  setAttribute("energy_loss_param_odb", qAttr);
414  } else if (qName == "clients") {
415  fKey = eClients;
416  } else if (qName == "clients_analyzer") {
418  setAttribute("analyzer_fe", qAttr);
419  } else if (qName == "clients_frontend") {
421  setAttribute("vme_fe", qAttr);
422  } else if (qName == "clients_tfl") {
423  fKey = eClients_tfl;
424  setAttribute("tfl_scfe", qAttr);
425  } else if (qName == "clients_sample") {
427  setAttribute("sample_scfe", qAttr);
428  } else if (qName == "clients_sample_omega") {
430  setAttribute("omega_scfe", qAttr);
431  } else if (qName == "clients_wew") {
432  fKey = eClients_WEW;
433  setAttribute("wew_scfe", qAttr);
434  } else if (qName == "clients_danfysik") {
436  setAttribute("danfysik_scfe", qAttr);
437  } else if (qName == "clients_hv") {
438  fKey = eClients_hv;
439  setAttribute("fug_scfe", qAttr);
440  } else if (qName == "clients_lemvac") {
442  setAttribute("lemvac_scfe", qAttr);
443  } else if (qName == "hv_demand") {
444  fKey = eHv_demand;
445  setAttribute("fug_eq", qAttr);
446  } else if (qName == "hv_measured") {
447  fKey = eHv_measured;
448  setAttribute("fug_eq", qAttr);
449  } else if (qName == "hv_current") {
450  fKey = eHv_current;
451  setAttribute("fug_eq", qAttr);
452  } else if (qName == "hv_detectors_demand") {
454  setAttribute("hv_detectors_eq", qAttr);
455  } else if (qName == "hv_detectors_measured") {
457  setAttribute("hv_detectors_eq", qAttr);
458  } else if (qName == "spin_rot_mag_input") {
460  setAttribute("danfysik_spin_rot_eq", qAttr);
461  } else if (qName == "spin_rot_mag_output") {
463  setAttribute("danfysik_spin_rot_eq", qAttr);
464  } else if (qName == "danfysik_input") {
466  setAttribute("danfysik_eq", qAttr);
467  } else if (qName == "danfysik_output") {
469  setAttribute("danfysik_eq", qAttr);
470  } else if (qName == "wew_output") {
471  fKey = eWEW_output;
472  setAttribute("wew_eq", qAttr);
473  } else if (qName == "wew_input") {
474  fKey = eWEW_input;
475  setAttribute("wew_eq", qAttr);
476  } else if (qName == "mag_field") {
477  fKey = eMag_field;
478  setAttribute("magnet_field_info", qAttr);
479  } else if (qName == "tfl_input") {
480  fKey = eTfl_input;
481  setAttribute("tfl_eq", qAttr);
482  } else if (qName == "tfl_output") {
483  fKey = eTfl_output;
484  setAttribute("tfl_eq", qAttr);
485  } else if (qName == "sample_ctrl_ch") {
487  setAttribute("sample_eq", qAttr);
488  } else if (qName == "sample_channel") {
490  setAttribute("sample_eq", qAttr);
491  } else if (qName == "sample_sensor_type") {
493  setAttribute("sample_eq", qAttr);
494  } else if (qName == "sample_input") {
496  setAttribute("sample_eq", qAttr);
497  } else if (qName == "sample_output") {
499  setAttribute("sample_eq", qAttr);
500  } else if (qName == "sample_rawvoltage") {
502  setAttribute("sample_eq", qAttr);
503  } else if (qName == "sample_bh_odb_offset_input") {
505  setAttribute("sample_eq", qAttr);
506  } else if (qName == "sample_bh_odb_offset_output") {
508  setAttribute("sample_eq", qAttr);
509  } else if (qName == "sample_oven_omega_input") {
511  setAttribute("omega_eq", qAttr);
512  } else if (qName == "sample_oven_omega_output") {
514  setAttribute("omega_eq", qAttr);
515  } else if (qName == "lemvac_input") {
517  setAttribute("lemvac_eq", qAttr);
518  } else if (qName == "lemvac_output") {
520  setAttribute("lemvac_eq", qAttr);
521  } else if (qName == "fom_input") {
522  fKey = eFOM_input;
523  setAttribute("fom_eq", qAttr);
524  } else if (qName == "fom_output") {
525  fKey = eFOM_output;
526  setAttribute("fom_eq", qAttr);
527  } else if (qName == "beamline_demand") {
529  setAttribute("beamline_eq", qAttr);
530  }
531 
532  return true;
533 }
534 
535 //**********************************************************************
536 // endElement
537 //**********************************************************************
542 {
543  fKey = eEmpty; // no key word anymore
544 
545  return true;
546 }
547 
548 //**********************************************************************
549 // characters
550 //**********************************************************************
557 {
558  QString str = fXml.text().toString();
559 
560  int number;
561  bool ok;
562 
563  switch (fKey) {
564  case eXmlSchemaFln:
565  fLar->fXMLSchemaFln = str;
566  break;
567  case eXmlAutoRunFln:
568  fLar->fXMLAutoRunFln = str;
569  break;
572  break;
573  case eXmlAutoRunHTML:
574  fLar->fXMLAutoRunHTML = str;
575  break;
576  case eEnableAll:
577  if (str == "yes") {
578  fLar->fEnableAll = true;
579  fLar->SetEnabled("all", true);
580  }
581  break;
582  case eAutoRunPath:
583  fLar->fAutoRunPath = str;
584  break;
585  case eHvSettingsPath:
586  fLar->fHvSettingsPath = str;
587  break;
588  case eDebug:
589  if (str == "true")
590  fLar->fDebug = true;
591  else
592  fLar->fDebug = false;
593  break;
594  case eIgnore_clients:
595  if (str == "true")
596  fLar->fIgnoreClients = true;
597  else
598  fLar->fIgnoreClients = false;
599  break;
600  case eIgnore_alarms:
601  if (str == "true")
602  fLar->fIgnoreAlarms = true;
603  else
604  fLar->fIgnoreAlarms = false;
605  break;
606  case eField_timeout:
607  fLar->fFieldTimeout = str.toFloat();
608  break;
609  case eFugHvCheck:
610  if (str == "false")
611  fLar->fFugHvCheck = false;
612  else
613  fLar->fFugHvCheck = true;
614  break;
615  case eField_accuracy:
616  fLar->fFieldAccuracy = str.toFloat();
617  break;
618  case eHv_timeout:
619  fLar->fHVTimeout = str.toFloat();
620  break;
621  case eHv_accuracy:
622  fLar->fHVAccuracy = str.toFloat();
623  break;
625  fLar->fFOMCurrentAccuracy = str.toFloat();
626  break;
628  fLar->fWEWCriticalCurrentRA = str.toFloat();
629  break;
630  case eWEWL_max_current:
631  fLar->fWEWLMaxCurrent = str.toFloat();
632  break;
633  case eWEWH_max_current:
634  fLar->fWEWHMaxCurrent = str.toFloat();
635  break;
637  fLar->fDanfysikMaxCurrent = str.toFloat();
638  break;
639  case eTrigger_events:
640  fLar->fTriggerEventsPath = str;
641  break;
642  case eEnable_OnOff_Mode:
643  fLar->fEnableOnOffModePath = str;
644  break;
645  case eAlarms:
646  fLar->fAlarmsPath = str;
647  break;
648  case eAlarm_td_hv_trip:
649  fLar->fAlarmTdHvTripPath = str;
650  break;
651  case eRun_info:
652  fLar->fRunInfoPath = str;
653  break;
654  case eRun_comment:
655  fLar->fRunCommentPath = str;
656  break;
657  case eTof_min:
658  fLar->fTofMinPath = str;
659  break;
660  case eTof_max:
661  fLar->fTofMaxPath = str;
662  break;
663  case eMod_name:
664  fLar->fModNamePath = str;
665  break;
666  case eMod_date:
667  fLar->fModDatePath = str;
668  break;
669  case eLem_setup:
670  fLar->fLemSetupPath = str;
671  break;
672  case eSample_name:
673  fLar->fSampleNamePath = str;
674  break;
675  case eSpin_rot_enabled:
676  fLar->fSpinRotEnabledPath = str;
677  break;
678  case eSpin_rot_angle:
679  fLar->fSpinRotAnglePath = str;
680  break;
681  case eMag_param_wew:
682  fLar->fMagParamWewPath = str;
683  break;
684  case eMag_param_bpar:
685  fLar->fMagParamBparPath = str;
686  break;
689  break;
690  case eSetup_wew_enabled:
691  fLar->fSetupWewEnabledPath = str;
692  break;
693  case eSetup_bpar_enabled:
695  break;
696  case eSample_cryo:
697  fLar->fSampleCryoPath = str;
698  break;
699  case eEnergy_loss_param:
700  fLar->fEnergyLossParamPath = str;
701  break;
702  case eClients:
703  fLar->fClientsPath = str;
704  break;
705  case eClients_analyzer:
706  fLar->fAnalyzerName = str;
707  break;
708  case eClients_frontend:
709  fLar->fFrontendName = str;
710  break;
711  case eClients_tfl:
712  fLar->fTflFeName = str;
713  break;
714  case eClients_sample:
715  fLar->fSampleFeName = str;
716  break;
719  break;
720  case eClients_WEW:
721  fLar->fWEWFeName = str;
722  break;
723  case eClients_danfysik:
724  fLar->fDanfysikFeName = str;
725  break;
726  case eClients_hv:
727  fLar->fHVFeName = str;
728  break;
729  case eClients_lemvac:
730  fLar->fLemvacFeName = str;
731  break;
732  case eHv_demand:
733  fLar->fHVDemandPath = str;
734  break;
735  case eHv_measured:
736  fLar->fHVMeasuredPath = str;
737  break;
738  case eHv_current:
739  fLar->fHVCurrentPath = str;
740  break;
741  case eHvDetector_demand:
743  break;
746  break;
747  case eSpin_rot_mag_input:
748  fLar->fSpinRotMagInputPath = str;
749  break;
752  break;
753  case eDanfysik_input:
754  fLar->fDanfysikInputPath = str;
755  break;
756  case eDanfysik_output:
757  fLar->fDanfysikOutputPath = str;
758  break;
759  case eWEW_output:
760  fLar->fWEWOutputPath = str;
761  break;
762  case eWEW_input:
763  fLar->fWEWInputPath = str;
764  break;
765  case eMag_field:
766  fLar->fMagFieldPath = str;
767  break;
768  case eTfl_input:
769  fLar->fTflInputPath = str;
770  break;
771  case eTfl_output:
772  fLar->fTflOutputPath = str;
773  break;
774  case eSample_ctrl_ch:
775  fLar->fSampleCtrlChPath = str;
776  break;
777  case eSample_channel:
778  fLar->fSampleChannelPath = str;
779  break;
780  case eSample_sensor_type:
782  break;
783  case eSample_input:
784  fLar->fSampleInputPath = str;
785  break;
786  case eSample_output:
787  fLar->fSampleOutputPath = str;
788  break;
789  case eSample_rawvoltage:
791  break;
793  number = str.toInt(&ok);
794  if (ok)
795  fLar->fSampleBhOdbOffsetInput = number;
796  break;
798  number = str.toInt(&ok);
799  if (ok)
800  fLar->fSampleBhOdbOffsetOutput = number;
801  break;
804  break;
807  break;
808  case eLemvac_input:
809  fLar->fLemvacInputPath = str;
810  break;
811  case eLemvac_output:
812  fLar->fLemvacOutputPath = str;
813  break;
814  case eFOM_input:
815  fLar->fFOMInputPath = str;
816  break;
817  case eFOM_output:
818  fLar->fFOMOutputPath = str;
819  break;
820  case eBeamline_demand:
821  fLar->fBeamlineDemandPath = str;
822  break;
823  default:
824  break;
825  }
826 
827  return true;
828 }
829 
830 //**********************************************************************
831 // endDocument
832 //**********************************************************************
840 {
841  QString errorMsg;
842 
843  // check if all expected input is found
844 
845  if (fLar->fXMLSchemaFln.isEmpty()) { // no XML-schema path given
846  fLar->fXMLSchemaFln = "/home/nemu/nemu/lemQt5/lemAutoRun/lemAutoRun.xsd";
847  errorMsg = "lemAutoRun: Couldn't find XML-schema path, will try hard-wired one (no warranty that it works): " +
849  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
850  }
851 
852  if (fLar->fXMLAutoRunFln.isEmpty()) { // no XML autorun sequence path is given
853  fLar->fXMLAutoRunFln = "/home/nemu/nemu/lemQt5/lemAutoRun/lar_seq.xml";
854  errorMsg = QString("lemAutoRun: Couldn't find XML autorun sequence path, ") +
855  QString("will try hard-wired one (no warranty that it works): ") +
857  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
858  }
859 
860  if (fLar->fXMLAutoRunValidateFln.isEmpty()) { // no XML validate autorun sequence path is given
861  fLar->fXMLAutoRunFln = "/home/nemu/nemu/lemQt5/lemAutoRun/lar_seq_validate.xml";
862  errorMsg = QString("lemAutoRun: Couldn't find XML validate autorun sequence path, ") +
863  QString("will try hard-wired one (no warranty that it works): ") +
865  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
866  }
867 
868  if (fLar->fXMLAutoRunHTML.isEmpty()) { // no HTML autorun status page path is given
869  fLar->fXMLAutoRunHTML = "/home/nemu/nemu/midas/experiment/nemu/custom_pages/lemAutoRun.html";
870  errorMsg = QString("lemAutoRun: Couldn't find XML autorun sequence path, ") +
871  QString("will try hard-wired one (no warranty that it works): ") +
873  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
874  }
875 
876  if (fLar->fAutoRunPath.isEmpty()) { // no autorun path is given
877  fLar->fAutoRunPath = "/home/nemu/autoRun/";
878  errorMsg = QString("lemAutoRun: Couldn't find XML autorun sequence path, ") +
879  QString("will try hard-wired one (no warranty that it works): ") +
881  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
882  }
883 
884  // no field reaching timeout given, hence set it to 300 (sec)
885  if (fLar->fFieldTimeout == 0.0)
886  fLar->fFieldTimeout = 300;
887 
888  // no field accuracy needed to be reached before going on: default = 0.01 (A)
889  if (fLar->fFieldAccuracy == 0.0)
890  fLar->fFieldAccuracy = 0.01;
891 
892  // no HV reaching timeout given, hence set it to 300 (sec)
893  if (fLar->fHVTimeout == 0.0)
894  fLar->fHVTimeout = 300;
895 
896  // HV accuracy needed to be reached before going on: default = 0.02 (kV)
897  if (fLar->fHVAccuracy == 0.0)
898  fLar->fHVAccuracy = 0.02;
899 
900  // FOM current accuracy needed to be reached before going on: default = 1.0e-4 (mA)
901  if (fLar->fFOMCurrentAccuracy == 0.0)
902  fLar->fFOMCurrentAccuracy = 1.0e-4;
903 
904  // WEW critical current value above which the Penning trap problems is happening, default = 22.65A -> ~130G
905  if (fLar->fWEWCriticalCurrentRA == 0.0)
906  fLar->fWEWCriticalCurrentRA = 22.65;
907 
908  // WEWL max. current not given check
909  if (fLar->fWEWLMaxCurrent == 0.0)
910  fLar->fWEWLMaxCurrent = 50.0;
911 
912  // WEWH max. current not given check
913  if (fLar->fWEWHMaxCurrent == 0.0)
914  fLar->fWEWHMaxCurrent = 595.0;
915 
916  // Danfysik max. current not given check
917  if (fLar->fDanfysikMaxCurrent == 0.0)
918  fLar->fDanfysikMaxCurrent = 20.0;
919 
920  if (fLar->fTriggerEventsPath.isEmpty() && fLar->fEnabled["trigger_events_odb"]) { // odb path to the trigger events missing
921  fLar->fTriggerEventsPath = "/Equipment/Trigger/Statistics/Events sent";
922  errorMsg = QString("lemAutoRun: Couldn't find the path to the trigger events in the ODB, ") +
923  QString("will try hard-wired one (no warranty that it works): ") +
925  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
926  }
927 
928  if (fLar->fEnableOnOffModePath.isEmpty() && fLar->fEnabled["enable_on_off_mode_odb"]) { // odb path to the Enable_OnOff_Mode missing
929  fLar->fEnableOnOffModePath = "/Equipment/Trigger/Settings/Enable_OnOff_Mode";
930  errorMsg = QString("lemAutoRun: Couldn't find the path to the Enable_OnOff_Mode in the ODB, ") +
931  QString("will try hard-wired one (no warranty that it works): ") +
933  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
934  }
935 
936  if (fLar->fAlarmsPath.isEmpty() && fLar->fEnabled["alarms_odb"]) { // odb path to the alarms missing
937  fLar->fAlarmsPath = "/Alarms/Alarms";
938  errorMsg = QString("lemAutoRun: Couldn't find the path to alarms in the ODB, ") +
939  QString("will try hard-wired one (no warranty that it works): ") +
940  fLar->fAlarmsPath;
941  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
942  }
943 
944  if (fLar->fAlarmTdHvTripPath.isEmpty() && fLar->fEnabled["alarms_td_hv_trip_odb"]) { // odb path to the alarms missing
945  fLar->fAlarmTdHvTripPath = "/Alarms/Alarms/hv_fug_check_trip_level/Triggered";
946  errorMsg = QString("lemAutoRun: Couldn't find the path to TD HV Trip flag in the ODB, ") +
947  QString("will try hard-wired one (no warranty that it works): ") +
949  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
950  }
951 
952  if (fLar->fRunInfoPath.isEmpty()) { // odb path to run info missing
953  fLar->fRunInfoPath = "/Runinfo";
954  errorMsg = QString("lemAutoRun: Couldn't find the path to the run info in the ODB, ") +
955  QString("will try hard-wired one (no warranty that it works): ") +
957  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
958  }
959 
960  if (fLar->fRunCommentPath.isEmpty() && fLar->fEnabled["run_comment_odb"]) { // odb path to run comments missing
961  fLar->fRunCommentPath = "/Experiment/Run Parameters/comment";
962  errorMsg = QString("lemAutoRun: Couldn't find the path to the run title in the ODB, ") +
963  QString("will try hard-wired one (no warranty that it works): ") +
965  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
966  }
967 
968  if (fLar->fTofMinPath.isEmpty() && fLar->fEnabled["tof_min_odb"]) { // odb path to TOF Min missing
969  fLar->fTofMinPath = "/Analyzer/Parameters/MCP2AnaModule/TofM2Fmin";
970  errorMsg = QString("lemAutoRun: Couldn't find the path to TOF Min in the ODB, ") +
971  QString("will try hard-wired one (no warranty that it works): ") +
972  fLar->fTofMinPath;
973  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
974  }
975 
976  if (fLar->fTofMaxPath.isEmpty() && fLar->fEnabled["tof_max_odb"]) { // odb path to TOF Max missing
977  fLar->fTofMaxPath = "/Analyzer/Parameters/MCP2AnaModule/TofM2Fmax";
978  errorMsg = QString("lemAutoRun: Couldn't find the path to TOF Max in the ODB, ") +
979  QString("will try hard-wired one (no warranty that it works): ") +
980  fLar->fTofMaxPath;
981  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
982  }
983 
984  if (fLar->fModNamePath.isEmpty() && fLar->fEnabled["mod_name_odb"]) { // odb path to moderator name
985  fLar->fModNamePath = "/Info/Moderator";
986  errorMsg = QString("lemAutoRun: Couldn't find the path to the moderator name in the ODB, ") +
987  QString("will try hard-wired one (no warranty that it works): ") +
989  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
990  }
991 
992  if (fLar->fModDatePath.isEmpty() && fLar->fEnabled["mod_date_odb"]) { // odb path to moderator date
993  fLar->fModDatePath = "/Info/ModeratorDATE";
994  errorMsg = QString("lemAutoRun: Couldn't find the path to the moderator date in the ODB, ") +
995  QString("will try hard-wired one (no warranty that it works): ") +
997  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
998  }
999 
1000  if (fLar->fLemSetupPath.isEmpty() && fLar->fEnabled["lem_setup_odb"]) { // odb path to LEM setup
1001  fLar->fLemSetupPath = "/Info/LEM_Setup";
1002  errorMsg = QString("lemAutoRun: Couldn't find the path to the LEM setup in the ODB, ") +
1003  QString("will try hard-wired one (no warranty that it works): ") +
1005  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1006  }
1007 
1008  if (fLar->fSampleNamePath.isEmpty() && fLar->fEnabled["sample_name_info_odb"]) { // odb path to Sample Name
1009  fLar->fSampleNamePath = "/Info/Sample Name";
1010  errorMsg = QString("lemAutoRun: Couldn't find the path to the Sample Name in the ODB, ") +
1011  QString("will try hard-wired one (no warranty that it works): ") +
1013  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1014  }
1015 
1016  if (fLar->fSpinRotEnabledPath.isEmpty() && fLar->fEnabled["spin_rot_calib_odb"]) { // odb path to spin rotation enabled flag
1017  fLar->fSpinRotEnabledPath = "/Info/SpinRot_Parameter/Enable spin rotator calibration";
1018  errorMsg = QString("lemAutoRun: Couldn't find the path to the spin rotation enabled flag in the ODB, ") +
1019  QString("will try hard-wired one (no warranty that it works): ") +
1021  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1022  }
1023 
1024  if (fLar->fSpinRotAnglePath.isEmpty() && fLar->fEnabled["spin_rot_angle_odb"]) { // odb path to spin rotation angle
1025  fLar->fSpinRotAnglePath = "/Info/SpinRot_Parameter/RotationAngle";
1026  errorMsg = QString("lemAutoRun: Couldn't find the path to the spin rotation angle in the ODB, ") +
1027  QString("will try hard-wired one (no warranty that it works): ") +
1029  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1030  }
1031 
1032  if (fLar->fMagParamWewPath.isEmpty() && fLar->fEnabled["mag_param_wew_odb"]) { // odb path to the WEW calibration (A->G)
1033  fLar->fMagParamWewPath = "/Info/Magnet_Parameter/WEW";
1034  errorMsg = QString("lemAutoRun: Couldn't find the path to the WEW magnet calibration (A->G) in the ODB, ") +
1035  QString("will try hard-wired one (no warranty that it works): ") +
1037  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1038  }
1039 
1040  if (fLar->fMagParamBparPath.isEmpty() && fLar->fEnabled["mag_param_bpar_odb"]) { // odb path to the Bpar calibration (A->G)
1041  fLar->fMagParamBparPath = "/Info/Magnet_Parameter/Bpar";
1042  errorMsg = QString("lemAutoRun: Couldn't find the path to the Bpar magnet calibration (A->G) in the ODB, ") +
1043  QString("will try hard-wired one (no warranty that it works): ") +
1045  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1046  }
1047 
1048  if (fLar->fSetupSampleEnabledPath.isEmpty() && fLar->fEnabled["setup_sample_odb"]) { // odb path to sample enable flag
1049  fLar->fSetupSampleEnabledPath = "/Info/LEM_Setup_Parameter/Sample";
1050  errorMsg = QString("lemAutoRun: Couldn't find the path to the sample enable flag in the ODB, ") +
1051  QString("will try hard-wired one (no warranty that it works): ") +
1053  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1054  }
1055 
1056  if (fLar->fSetupWewEnabledPath.isEmpty() && fLar->fEnabled["setup_wew_odb"]) { // odb path to WEW enable flag
1057  fLar->fSetupWewEnabledPath = "/Info/LEM_Setup_Parameter/WEW";
1058  errorMsg = QString("lemAutoRun: Couldn't find the path to the WEW enable flag in the ODB, ") +
1059  QString("will try hard-wired one (no warranty that it works): ") +
1061  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1062  }
1063 
1064  if (fLar->fSetupBparEnabledPath.isEmpty() && fLar->fEnabled["setup_bpar_odb"]) { // odb path to Bpar enable flag
1065  fLar->fSetupBparEnabledPath = "/Info/LEM_Setup_Parameter/Bpar";
1066  errorMsg = QString("lemAutoRun: Couldn't find the path to the Bpar enable flag in the ODB, ") +
1067  QString("will try hard-wired one (no warranty that it works): ") +
1069  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1070  }
1071 
1072  if (fLar->fSampleCryoPath.isEmpty() && fLar->fEnabled["sample_cryo_info_odb"]) { // odb path to Sample Cryo
1073  fLar->fSampleCryoPath = "/Info/Sample Cryo";
1074  errorMsg = QString("lemAutoRun: Couldn't find the path to the Sample Cryo in the ODB, ") +
1075  QString("will try hard-wired one (no warranty that it works): ") +
1077  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1078  }
1079 
1080  if (fLar->fEnergyLossParamPath.isEmpty() && fLar->fEnabled["energy_loss_param_odb"]) { // odb path to energy loss parameters
1081  fLar->fEnergyLossParamPath = "/Info/EnergyLoss_Parameter";
1082  errorMsg = QString("lemAutoRun: Couldn't find the path to the energy loss parameters in the ODB, ") +
1083  QString("will try hard-wired one (no warranty that it works): ") +
1085  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1086  }
1087 
1088  if (fLar->fClientsPath.isEmpty()) { // odb path to the system/clients missing
1089  fLar->fClientsPath = "/System/Clients";
1090  errorMsg = QString("lemAutoRun: Couldn't find the path to clients in the ODB, ") +
1091  QString("will try hard-wired one (no warranty that it works): ") +
1092  fLar->fClientsPath;
1093  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1094  }
1095 
1096  if (fLar->fAnalyzerName.isEmpty() && fLar->fEnabled["analyzer_fe"]) { // no analyzer ODB name found
1097  fLar->fAnalyzerName = "Analyzer";
1098  errorMsg = QString("lemAutoRun: Couldn't find ODB name for the analyzer, ") +
1099  QString("will try hard-wired one (no warranty that it works): ") +
1101  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1102  }
1103 
1104  if (fLar->fFrontendName.isEmpty() && fLar->fEnabled["vme_fe"]) { // no frontend ODB name found
1105  fLar->fFrontendName = "VME_FE";
1106  errorMsg = QString("lemAutoRun: Couldn't find ODB name for the frontend, ") +
1107  QString("will try hard-wired one (no warranty that it works): ") +
1109  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1110  }
1111 
1112  if (fLar->fTflFeName.isEmpty() && fLar->fEnabled["tfl_scfe"]) { // no tfl_scfe ODB name found
1113  fLar->fTflFeName = "TFL_SC";
1114  errorMsg = QString("lemAutoRun: Couldn't find ODB name for tfl_scfe, ") +
1115  QString("will try hard-wired one (no warranty that it works): ") +
1116  fLar->fTflFeName;
1117  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1118  }
1119 
1120  if (fLar->fSampleFeName.isEmpty() && fLar->fEnabled["sample_scfe"]) { // no sample_scfe ODB name found
1121  fLar->fSampleFeName = "Sample_SC";
1122  errorMsg = QString("lemAutoRun: Couldn't find ODB name for sample_scfe, ") +
1123  QString("will try hard-wired one (no warranty that it works): ") +
1125  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1126  }
1127 
1128  if (fLar->fSampleOvenOmegaFeName.isEmpty() && fLar->fEnabled["omega_scfe"]) { // no sample oven omega scfe ODB name found
1129  fLar->fSampleOvenOmegaFeName = "Omega SC";
1130  errorMsg = QString("lemAutoRun: Couldn't find ODB name for Oven Omega SCFE, ") +
1131  QString("will try hard-wired one (no warranty that it works): ") +
1133  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1134  }
1135 
1136  if (fLar->fWEWFeName.isEmpty() && fLar->fEnabled["wew_scfe"]) { // no WEW scfe ODB name found
1137  fLar->fWEWFeName = "WEW SC";
1138  errorMsg = QString("lemAutoRun: Couldn't find ODB name for WEW SCFE, ") +
1139  QString("will try hard-wired one (no warranty that it works): ") +
1140  fLar->fWEWFeName;
1141  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1142  }
1143 
1144  if (fLar->fDanfysikFeName.isEmpty() && fLar->fEnabled["danfysik_scfe"]) { // no danfysik scfe ODB name found
1145  fLar->fDanfysikFeName = "Danfysik_SC";
1146  errorMsg = QString("lemAutoRun: Couldn't find ODB name for Danfysik SCFE, ") +
1147  QString("will try hard-wired one (no warranty that it works): ") +
1149  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1150  }
1151 
1152  if (fLar->fHVFeName.isEmpty() && fLar->fEnabled["fug_scfe"]) { // no hv_fug_scfe ODB name found
1153  fLar->fHVFeName = "FUG";
1154  errorMsg = QString("lemAutoRun: Couldn't find ODB name for hv_fug_scfe, ") +
1155  QString("will try hard-wired one (no warranty that it works): ") +
1156  fLar->fHVFeName;
1157  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1158  }
1159 
1160  if (fLar->fLemvacFeName.isEmpty() && fLar->fEnabled["lemvac_scfe"]) { // no lemvac_scfe ODB name found
1161  fLar->fLemvacFeName = "LEMVAC_SC";
1162  errorMsg = QString("lemAutoRun: Couldn't find ODB name for lemvac_scfe, ") +
1163  QString("will try hard-wired one (no warranty that it works): ") +
1165  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1166  }
1167 
1168  if (fLar->fHVDemandPath.isEmpty() && fLar->fEnabled["fug_eq"]) { // path to the HV demand values
1169  fLar->fHVDemandPath = "/Equipment/HV/Variables/Demand";
1170  errorMsg = QString("lemAutoRun: Couldn't find the path to HV demand values in the ODB, ") +
1171  QString("will try hard-wired one (no warranty that it works): ") +
1173  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1174  }
1175 
1176  if (fLar->fHVMeasuredPath.isEmpty() && fLar->fEnabled["fug_eq"]) { // path to the HV measured values
1177  fLar->fHVMeasuredPath = "/Equipment/HV/Variables/Measured";
1178  errorMsg = QString("lemAutoRun: Couldn't find the path to HV measured values in the ODB, ") +
1179  QString("will try hard-wired one (no warranty that it works): ") +
1181  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1182  }
1183 
1184  if (fLar->fHVCurrentPath.isEmpty() && fLar->fEnabled["fug_eq"]) { // path to the HV current values
1185  fLar->fHVCurrentPath = "/Equipment/HV/Variables/Current";
1186  errorMsg = QString("lemAutoRun: Couldn't find the path to HV current values in the ODB, ") +
1187  QString("will try hard-wired one (no warranty that it works): ") +
1189  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1190  }
1191 
1192  if (fLar->fHVDetectorDemandPath.isEmpty() && fLar->fEnabled["hv_detectors_eq"]) { // path to the HV Detectors demand values
1193  fLar->fHVDetectorDemandPath = "/Equipment/HV Detectors/Variables/Demand";
1194  errorMsg = QString("lemAutoRun: Couldn't find the path to the HV Detectors demand values in the ODB, ") +
1195  QString("will try hard-wired one (no warranty that it works): ") +
1197  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1198  }
1199 
1200  if (fLar->fHVDetectorMeasuredPath.isEmpty() && fLar->fEnabled["hv_detectors_eq"]) { // path to the HV Detectors measured values
1201  fLar->fHVDetectorMeasuredPath = "/Equipment/HV Detectors/Variables/Measured";
1202  errorMsg = QString("lemAutoRun: Couldn't find the path to the HV Detectors measured values in the ODB, ") +
1203  QString("will try hard-wired one (no warranty that it works): ") +
1205  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1206  }
1207 
1208  if (fLar->fSpinRotMagInputPath.isEmpty() && fLar->fEnabled["danfysik_spin_rot_eq"]) { // path to the Danfysik spin rotator power supply
1209  fLar->fSpinRotMagInputPath = "/Equipment/Danfysik_Spin_Rot/Variables/Input";
1210  errorMsg = QString("lemAutoRun: Couldn't find the path to the Danfysik Spin Rotator power supply input values in the ODB, ") +
1211  QString("will try hard-wired one (no warranty that it works): ") +
1213  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1214  }
1215 
1216  if (fLar->fSpinRotMagOutputPath.isEmpty() && fLar->fEnabled["danfysik_spin_rot_eq"]) { // path to the Danfysik spin rotator power supply
1217  fLar->fSpinRotMagOutputPath = "/Equipment/Danfysik_Spin_Rot/Variables/Output";
1218  errorMsg = QString("lemAutoRun: Couldn't find the path to the Danfysik Spin Rotator power supply output values in the ODB, ") +
1219  QString("will try hard-wired one (no warranty that it works): ") +
1221  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1222  }
1223 
1224  if (fLar->fDanfysikInputPath.isEmpty() && fLar->fEnabled["danfysik_eq"]) { // path to the Danfysik input values
1225  fLar->fDanfysikInputPath = "/Equipment/Danfysik/Variables/Input";
1226  errorMsg = QString("lemAutoRun: Couldn't find the path to Danfysik input values in the ODB, ") +
1227  QString("will try hard-wired one (no warranty that it works): ") +
1229  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1230  }
1231 
1232  if (fLar->fDanfysikOutputPath.isEmpty() && fLar->fEnabled["danfysik_eq"]) { // path to the Danfysik output values
1233  fLar->fDanfysikOutputPath = "/Equipment/Danfysik/Variables/Output";
1234  errorMsg = QString("lemAutoRun: Couldn't find the path to Danfysik output values in the ODB, ") +
1235  QString("will try hard-wired one (no warranty that it works): ") +
1237  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1238  }
1239 
1240  if (fLar->fWEWOutputPath.isEmpty() && fLar->fEnabled["wew_eq"]) { // path to the WEW output values
1241  fLar->fWEWOutputPath = "/Equipment/WEW/Variables/Output";
1242  errorMsg = QString("lemAutoRun: Couldn't find the path to WEW output values in the ODB, ") +
1243  QString("will try hard-wired one (no warranty that it works): ") +
1245  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1246  }
1247 
1248  if (fLar->fWEWInputPath.isEmpty() && fLar->fEnabled["wew_eq"]) { // path to the WEW input values
1249  fLar->fWEWInputPath = "/Equipment/WEW/Variables/Input";
1250  errorMsg = QString("lemAutoRun: Couldn't find the path to WEW input values in the ODB, ") +
1251  QString("will try hard-wired one (no warranty that it works): ") +
1253  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1254  }
1255 
1256  if (fLar->fMagFieldPath.isEmpty() && fLar->fEnabled["magnet_field_info"]) { // path to the magnet field value
1257  fLar->fMagFieldPath = "/Info/Magnetic Field (G)";
1258  errorMsg = QString("lemAutoRun: Couldn't find the path to magnet field parameters of the WEW in the ODB, ") +
1259  QString("will try hard-wired one (no warranty that it works): ") +
1261  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1262  }
1263 
1264  if (fLar->fTflInputPath.isEmpty() && fLar->fEnabled["tfl_eq"]) { // path to the tfl input values
1265  fLar->fTflInputPath = "/Equipment/TFL/Variables/Input";
1266  errorMsg = QString("lemAutoRun: Couldn't find the path to tfl input values in the ODB, ") +
1267  QString("will try hard-wired one (no warranty that it works): ") +
1269  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1270  }
1271 
1272  if (fLar->fTflOutputPath.isEmpty() && fLar->fEnabled["tfl_eq"]) { // path to the tfl output values
1273  fLar->fTflOutputPath = "/Equipment/TFL/Variables/Output";
1274  errorMsg = QString("lemAutoRun: Couldn't find the path to tfl input values in the ODB, ") +
1275  QString("will try hard-wired one (no warranty that it works): ") +
1277  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1278  }
1279 
1280  if (fLar->fSampleCtrlChPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample cryo ctrl channel of the LS340
1281  fLar->fSampleCtrlChPath = "/Equipment/SampleCryo/Settings/Devices/Lake336_Sample_0/DD/Loop1/CTRL_CH";
1282  errorMsg = QString("lemAutoRun: Couldn't find the path to ctrl channel of the LS340 in the ODB, ") +
1283  QString("will try hard-wired one (no warranty that it works): ") +
1285  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1286  }
1287 
1288  if (fLar->fSampleChannelPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample cryo channel assignment of the LS340
1289  fLar->fSampleChannelPath = "/Equipment/SampleCryo/Settings/Devices/Lake336_Sample_0/DD/Sensors/Channel";
1290  errorMsg = QString("lemAutoRun: Couldn't find the path to channel assignment of the LS340 in the ODB, ") +
1291  QString("will try hard-wired one (no warranty that it works): ") +
1293  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1294  }
1295 
1296  if (fLar->fSampleSensorTypePath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample cryo sensor type assignment of the LS340
1297  fLar->fSampleSensorTypePath = "/Equipment/SampleCryo/Settings/Devices/Lake336_Sample_0/DD/Sensors/Sensor Type";
1298  errorMsg = QString("lemAutoRun: Couldn't find the path to sensor type assignment of the LS340 in the ODB, ") +
1299  QString("will try hard-wired one (no warranty that it works): ") +
1301  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1302  }
1303 
1304  if (fLar->fSampleInputPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample input values
1305  fLar->fSampleInputPath = "/Equipment/SampleCryo/Variables/Input";
1306  errorMsg = QString("lemAutoRun: Couldn't find the path to sample cryo input values in the ODB, ") +
1307  QString("will try hard-wired one (no warranty that it works): ") +
1309  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1310  }
1311 
1312  if (fLar->fSampleOutputPath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample output values
1313  fLar->fSampleOutputPath = "/Equipment/SampleCryo/Variables/Output";
1314  errorMsg = QString("lemAutoRun: Couldn't find the path to sample cryo output values in the ODB, ") +
1315  QString("will try hard-wired one (no warranty that it works): ") +
1317  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1318  }
1319 
1320  if (fLar->fSampleRawVoltagePath.isEmpty() && fLar->fEnabled["sample_eq"]) { // path to the sample DD raw voltage variable
1321  fLar->fSampleRawVoltagePath = "/Equipment/SampleCryo/Settings/Devices/Lake336_Sample_0/DD/Sensors/Raw Input Channel";
1322  errorMsg = QString("lemAutoRun: Couldn't find the path to sample cryo 'RawVoltage' in the ODB, ") +
1323  QString("will try hard-wired one (no warranty that it works): ") +
1325  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1326  }
1327 
1328  if ((fLar->fSampleBhOdbOffsetInput == -1) && fLar->fEnabled["sample_eq"]) { // odb offset for bronkhorst input missing
1330  errorMsg = QString("lemAutoRun: Couldn't find input ODB offset for the bronkhorst flow meter, ") +
1331  QString("will try hard-wired one (no warranty that it works):%1 ").arg(fLar->fSampleBhOdbOffsetInput);
1332  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1333  }
1334 
1335  if ((fLar->fSampleBhOdbOffsetOutput == -1) && fLar->fEnabled["sample_eq"]) { // odb offset for bronkhorst output missing
1337  errorMsg = QString("lemAutoRun: Couldn't find output ODB offset for the bronkhorst flow meter, ") +
1338  QString("will try hard-wired one (no warranty that it works):%1 ").arg(fLar->fSampleBhOdbOffsetOutput);
1339  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1340  }
1341 
1342  if (fLar->fSampleOvenOmegaInputPath.isEmpty() && fLar->fEnabled["omega_eq"]) { // path to the sample oven omega input values
1343  fLar->fSampleOvenOmegaInputPath = "/Equipment/Omega/Variables/Input";
1344  errorMsg = QString("lemAutoRun: Couldn't find the path to sample oven omega input values in the ODB, ") +
1345  QString("will try hard-wired one (no warranty that it works): ") +
1347  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1348  }
1349 
1350  if (fLar->fSampleOvenOmegaOutputPath.isEmpty() && fLar->fEnabled["omega_eq"]) { // path to the sample oven omega output values
1351  fLar->fSampleOvenOmegaOutputPath = "/Equipment/Oven/Variables/Output";
1352  errorMsg = QString("lemAutoRun: Couldn't find the path to sample oven output values in the ODB, ") +
1353  QString("will try hard-wired one (no warranty that it works): ") +
1355  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1356  }
1357 
1358  if (fLar->fLemvacInputPath.isEmpty() && fLar->fEnabled["lemvac_eq"]) { // path to the lemvac input values
1359  fLar->fLemvacInputPath = "/Equipment/LEMVAC/Variables/Input";
1360  errorMsg = QString("lemAutoRun: Couldn't find the path to lemvac input values in the ODB, ") +
1361  QString("will try hard-wired one (no warranty that it works): ") +
1363  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1364  }
1365 
1366  if (fLar->fLemvacOutputPath.isEmpty() && fLar->fEnabled["lemvac_eq"]) { // path to the lemvac output values
1367  fLar->fLemvacOutputPath = "/Equipment/LEMVAC/Variables/Output";
1368  errorMsg = QString("lemAutoRun: Couldn't find the path to lemvac output values in the ODB, ") +
1369  QString("will try hard-wired one (no warranty that it works): ") +
1371  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1372  }
1373 
1374  if (fLar->fFOMInputPath.isEmpty() && fLar->fEnabled["fom_eq"]) { // path to the FOM input values
1375  fLar->fFOMInputPath = "/Equipment/FOM/Variables/Input";
1376  errorMsg = QString("lemAutoRun: Couldn't find the path to FOM input values in the ODB, ") +
1377  QString("will try hard-wired one (no warranty that it works): ") +
1379  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1380  }
1381 
1382  if (fLar->fFOMOutputPath.isEmpty() && fLar->fEnabled["fom_eq"]) { // path to the FOM output values
1383  fLar->fFOMOutputPath = "/Equipment/FOM/Variables/Output";
1384  errorMsg = QString("lemAutoRun: Couldn't find the path to FOM output values in the ODB, ") +
1385  QString("will try hard-wired one (no warranty that it works): ") +
1387  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1388  }
1389 
1390  if (fLar->fBeamlineDemandPath.isEmpty() && fLar->fEnabled["beamline_eq"]) { // path to the Beamline demand values
1391  fLar->fBeamlineDemandPath = "/Equipment/Beamline/Variables/Demand";
1392  errorMsg = QString("lemAutoRun: Couldn't find the path to the Beamline demand values in the ODB, ") +
1393  QString("will try hard-wired one (no warranty that it works): ") +
1395  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1396  }
1397 
1398  if (fLar->fEnabled["sample_eq"] && !fLar->fEnabled["sample_cryo_info_odb"]) {
1399  errorMsg = QString("lemAutoRun: Sample Cryo enabled, but access to '/Info/Sample Cryo' disabled.") +
1400  QString("will most likely not work!") +
1402  emit fLar->ErrorMsg(1, 0, LAR_XML_MISSING_ENTRY, -1, errorMsg);
1403  }
1404 
1405  return true;
1406 }
1407 
1408 //**********************************************************************
1409 // setAttribute
1410 //**********************************************************************
1416 void PLemAutoRunXMLParser::setAttribute(const QString key, const QXmlStreamAttributes &qAttr)
1417 {
1418  if (qAttr.hasAttribute("enabled")) {
1419  if (qAttr.value("enabled") == "yes") {
1420  fLar->SetEnabled(key, true);
1421  } else if (qAttr.value("enabled") == "no") {
1422  fLar->SetEnabled(key, false);
1423  }
1424  }
1425 }
1426 
1427 
1428 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1429 // implementation of PLemSampleCryoXMLParser
1430 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1431 
1432 //**********************************************************************
1433 // constructor
1434 //**********************************************************************
1441 {
1442  fLar = lar;
1443 
1444  QFile file(fln);
1445  if (!file.open(QFile::ReadOnly | QFile::Text) || (file.size()==0))
1446  return;
1447 
1448  fValid = parse(&file);
1449 }
1450 
1451 //**********************************************************************
1452 // destructor
1453 //**********************************************************************
1458 {
1459 }
1460 
1461 //**********************************************************************
1462 // parse
1463 //**********************************************************************
1471 bool PLemSampleCryoXMLParser::parse(QIODevice *device)
1472 {
1473  fXml.setDevice(device);
1474 
1475  bool expectChars = false;
1476  while (!fXml.atEnd()) {
1477  fXml.readNext();
1478  if (fXml.isStartDocument()) {
1479  startDocument();
1480  } else if (fXml.isStartElement()) {
1481  startElement();
1482  expectChars = true;
1483  } else if (fXml.isCharacters() && expectChars) {
1484  characters();
1485  } else if (fXml.isEndElement()) {
1486  endElement();
1487  expectChars = false;
1488  } else if (fXml.isEndDocument()) {
1489  endDocument();
1490  }
1491  }
1492  if (fXml.hasError()) {
1493  QString msg;
1494  msg = QString("%1 Line %2, column %3").arg(fXml.errorString()).arg(fXml.lineNumber()).arg(fXml.columnNumber());
1495  cm_msg(MERROR, "lemAutoRun", msg.toLatin1().data());
1496  cm_yield(0);
1497  return false;
1498  }
1499 
1500  return true;
1501 }
1502 
1503 //**********************************************************************
1504 // startDocument
1505 //**********************************************************************
1510 {
1511  return true;
1512 }
1513 
1514 //**********************************************************************
1515 // startElement
1516 //**********************************************************************
1523 {
1524  QString qName = fXml.name().toString();
1525 
1526  if (qName == "temp_regulation") {
1528  } else if (qName == "max_temp_increase") {
1530  } else if (qName == "bh_max_flow") {
1531  fKey = eBh_max_flow;
1532  } else if (qName == "bh_min_flow") {
1533  fKey = eBh_min_flow;
1534  } else if (qName == "bh_flow_p_heat_0") {
1536  } else if (qName == "bh_flow_p_heat_1") {
1538  } else if (qName == "bh_flow_d_heat") {
1540  } else if (qName == "bh_flow_temp") {
1541  fKey = eBh_flow_temp;
1542  } else if (qName == "bh_flow_temp_offset") {
1544  } else if (qName == "bh_flow_offset") {
1546  } else if (qName == "d_set_ratio") {
1547  fKey = eD_set_ratio;
1548  } else if (qName == "abs_max_temp_diff") {
1550  } else if (qName == "rel_max_temp_diff") {
1552  } else if (qName == "max_temp_trend") {
1554  } else if (qName == "heater_min") {
1555  fKey = eHeater_min;
1556  } else if (qName == "heater_max") {
1557  fKey = eHeater_max;
1558  } else if (qName == "flow_factor") {
1559  fKey = eFlow_factor;
1560  } else if (qName == "flow_set_ratio") {
1562  } else if (qName == "flow_set_absolute") {
1564  } else if (qName == "flow_timeout_reduction") {
1566  } else if (qName == "timeout_flow_set") {
1568  } else if (qName == "flowLowestFlowToConsider") {
1570  } else if (qName == "flowMaxRelFlowDiffToConsider") {
1572  } else if (qName == "dFlowDp0") {
1573  fKey = eDFlowDp0;
1574  } else if (qName == "dFlowDp1") {
1575  fKey = eDFlowDp1;
1576  } else if (qName == "dFlowDpExp") {
1577  fKey = eDFlowDpExp;
1578  } else if (qName == "heatCapCof1") {
1579  fKey = eHeatCapCof1;
1580  } else if (qName == "heatCapCof2") {
1581  fKey = eHeatCapCof2;
1582  } else if (qName == "heatCapCof3") {
1583  fKey = eHeatCapCof3;
1584  } else if (qName == "needleValveInUse") {
1586  } else if (qName == "prefNeedleValveCof_1_0") {
1588  } else if (qName == "prefNeedleValveCof_1_1") {
1590  } else if (qName == "prefNeedleValveCof_2_0") {
1592  } else if (qName == "prefNeedleValveCof_2_1") {
1594  } else if (qName == "prefNeedleValveCof_3_0") {
1596  } else if (qName == "prefNeedleValveCof_3_1") {
1598  } else if (qName == "prefNeedleValveCof_4_0") {
1600  } else if (qName == "prefNeedleValveCof_4_1") {
1602  } else if (qName == "prefNeedleValveRelStep") {
1604  } else if (qName == "prefNeedleValveAbsStep") {
1606  }
1607 
1608  return true;
1609 }
1610 
1611 //**********************************************************************
1612 // endElement
1613 //**********************************************************************
1618 {
1619  fKey = eEmpty; // no key word anymore
1620 
1621  return true;
1622 }
1623 
1624 //**********************************************************************
1625 // characters
1626 //**********************************************************************
1633 {
1634  QString str = fXml.text().toString();
1635 
1636  switch (fKey) {
1637  case eTemp_regulation:
1638  if (str == "true")
1639  fLar->fSampleTempRegulation = true;
1640  else
1641  fLar->fSampleTempRegulation = false;
1642  break;
1643  case eMax_temp_increase:
1644  fLar->fMaxTempIncrease = str.toFloat();
1645  break;
1646  case eBh_max_flow:
1647  fLar->fBHMaxFlow = str.toFloat();
1648  break;
1649  case eBh_min_flow:
1650  fLar->fBHMinFlow = str.toFloat();
1651  break;
1652  case eBh_flow_p_heat_0:
1653  fLar->fBHFlowPHeat0 = str.toFloat();
1654  break;
1655  case eBh_flow_p_heat_1:
1656  fLar->fBHFlowPHeat1 = str.toFloat();
1657  break;
1658  case eBh_flow_d_heat:
1659  fLar->fBHFlowDHeat = str.toFloat();
1660  break;
1661  case eBh_flow_temp:
1662  fLar->fBHFlowTemp = str.toFloat();
1663  break;
1664  case eBh_flow_temp_offset:
1665  fLar->fBHFlowTempOffset = str.toFloat();
1666  break;
1667  case eBh_flow_offset:
1668  fLar->fBHFlowOffset = str.toFloat();
1669  break;
1670  case eD_set_ratio:
1671  fLar->fDSetRatio = str.toFloat();
1672  break;
1673  case eAbs_max_temp_diff:
1674  fLar->fAbsMaxTempDiff = str.toFloat();
1675  break;
1676  case eRel_max_temp_diff:
1677  fLar->fRelMaxTempDiff = str.toFloat();
1678  break;
1679  case eMax_temp_trend:
1680  fLar->fMaxTempTrend = str.toFloat();
1681  break;
1682  case eHeater_min:
1683  fLar->fHeaterMin = str.toFloat();
1684  break;
1685  case eHeater_max:
1686  fLar->fHeaterMax = str.toFloat();
1687  break;
1688  case eTimeout_flow_set:
1689  fLar->fTimeoutFlowSet = 1000.0 * str.toFloat(); // in (msec)
1690  break;
1691  case eFlow_factor:
1692  fLar->fFlowFactor = str.toFloat();
1693  break;
1694  case eFlow_set_ratio:
1695  fLar->fFlowSetRatio = str.toFloat();
1696  break;
1697  case eFlow_set_absolute:
1698  fLar->fFlowSetAbsolute = str.toFloat();
1699  break;
1701  fLar->fFlowTimeoutReduction = 1000.0 * str.toFloat(); // in (msec)
1702  break;
1704  fLar->fFlowLowestFlowToConsider = str.toFloat();
1705  break;
1707  fLar->fFlowMaxRelFlowDiffToConsider = str.toFloat();
1708  break;
1709  case eDFlowDp0:
1710  fLar->fDFlowDp0 = str.toFloat();
1711  break;
1712  case eDFlowDp1:
1713  fLar->fDFlowDp1 = str.toFloat();
1714  break;
1715  case eDFlowDpExp:
1716  fLar->fDFlowDpExp = str.toFloat();
1717  break;
1718  case eHeatCapCof1:
1719  fLar->fHeatCapCof1 = str.toFloat();
1720  break;
1721  case eHeatCapCof2:
1722  fLar->fHeatCapCof2 = str.toFloat();
1723  break;
1724  case eHeatCapCof3:
1725  fLar->fHeatCapCof3 = str.toFloat();
1726  break;
1727  case eNeedleValveInUse:
1728  fLar->fNeedleValveInUse = (bool) str.toInt();
1729  break;
1731  fLar->fPrefNeedleValveCof_1_0 = str.toFloat();
1732  break;
1734  fLar->fPrefNeedleValveCof_1_1 = str.toFloat();
1735  break;
1737  fLar->fPrefNeedleValveCof_2_0 = str.toFloat();
1738  break;
1740  fLar->fPrefNeedleValveCof_2_1 = str.toFloat();
1741  break;
1743  fLar->fPrefNeedleValveCof_3_0 = str.toFloat();
1744  break;
1746  fLar->fPrefNeedleValveCof_3_1 = str.toFloat();
1747  break;
1749  fLar->fPrefNeedleValveCof_4_0 = str.toFloat();
1750  break;
1752  fLar->fPrefNeedleValveCof_4_1 = str.toFloat();
1753  break;
1755  fLar->fPrefNeedleValveRelStep = str.toFloat();
1756  break;
1758  fLar->fPrefNeedleValveAbsStep = str.toFloat();
1759  break;
1760 
1761  default:
1762  break;
1763  }
1764 
1765  return true;
1766 }
1767 
1768 //**********************************************************************
1769 // endDocument
1770 //**********************************************************************
1778 {
1779  QString errorMsg;
1780 
1781  // check if all expected input is found
1782 
1783  // no max temp increase given, hence set it to 20 (K)
1784  if (fLar->fMaxTempIncrease == 0.0)
1785  fLar->fMaxTempIncrease = 20.0;
1786 
1787  return true;
1788 }
1789 
1790 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1791 // implementation of PLemHvSettingsFileParser
1792 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1793 
1794 //**********************************************************************
1795 // constructor
1796 //**********************************************************************
1802 {
1803  fValid = true;
1804  fErrorMsg = "";
1805 
1806  fHvDeviceName = "";
1807 
1808  QFile file(fln);
1809  if (!file.open(QFile::ReadOnly | QFile::Text) || (file.size()==0))
1810  return;
1811 
1812  fParseIsValid = parse(&file);
1813 }
1814 
1815 //**********************************************************************
1816 // destructor
1817 //**********************************************************************
1822 {
1823  fHvChNo.clear();
1824  fHvChName.clear();
1825  fHvDemand.clear();
1826  fCurrentLimit.clear();
1827 }
1828 
1829 //**********************************************************************
1830 // parse
1831 //**********************************************************************
1839 bool PLemHvSettingsFileParser::parse(QIODevice *device)
1840 {
1841  fXml.setDevice(device);
1842 
1843  bool expectChars = false;
1844  while (!fXml.atEnd()) {
1845  fXml.readNext();
1846  if (fXml.isStartDocument()) {
1847  startDocument();
1848  } else if (fXml.isStartElement()) {
1849  startElement();
1850  expectChars = true;
1851  } else if (fXml.isCharacters() && expectChars) {
1852  characters();
1853  } else if (fXml.isEndElement()) {
1854  endElement();
1855  expectChars = false;
1856  } else if (fXml.isEndDocument()) {
1857  endDocument();
1858  }
1859  }
1860  if (fXml.hasError()) {
1861  QString msg;
1862  msg = QString("%1 Line %2, column %3").arg(fXml.errorString()).arg(fXml.lineNumber()).arg(fXml.columnNumber());
1863  cm_msg(MERROR, "lemAutoRun", msg.toLatin1().data());
1864  cm_yield(0);
1865  return false;
1866  }
1867 
1868  return true;
1869 }
1870 
1871 //**********************************************************************
1872 // startDocument
1873 //**********************************************************************
1878 {
1879  fKey = eEmpty;
1880 
1881  return true;
1882 }
1883 
1884 //**********************************************************************
1885 // startElement
1886 //**********************************************************************
1893 {
1894  QString qName = fXml.name().toString();
1895 
1896  if (qName == "hvDeviceName") {
1897  fKey = eHvDeviceName;
1898  } else if (qName == "chNo") {
1899  fKey = eHvChNo;
1900  } else if (qName == "name") {
1901  fKey = eHvChName;
1902  } else if (qName == "hvDemand") {
1903  fKey = eHvDemand;
1904  } else if (qName == "currentLimit") {
1905  fKey = eCurrentLimit;
1906  }
1907 
1908  return true;
1909 }
1910 
1911 //**********************************************************************
1912 // endElement
1913 //**********************************************************************
1918 {
1919  fKey = eEmpty; // no key word anymore
1920 
1921  return true;
1922 }
1923 
1924 //**********************************************************************
1925 // characters
1926 //**********************************************************************
1933 {
1934  int ival=0;
1935  float fval=0.0;
1936  bool ok;
1937 
1938  QString str = fXml.text().toString();
1939 
1940  switch (fKey) {
1941  case eHvDeviceName:
1942  fHvDeviceName = str.trimmed();
1943  if (fHvDeviceName != "FUG") {
1944  fErrorMsg = "**ERROR** only handle FUG's, i.e. transport settings, but found '" + fHvDeviceName + "'";
1945  fValid = false;
1946  return false;
1947  }
1948  break;
1949  case eHvChNo:
1950  ival = str.toInt(&ok);
1951  if (ok) {
1952  fHvChNo.push_back(ival);
1953  } else {
1954  fErrorMsg = "**ERROR** found HV channel '" + str + "' at position" + QString("%1").arg(fHvChNo.size()) + " which is not an integer?!?";
1955  fValid = false;
1956  return false;
1957  }
1958  break;
1959  case eHvChName:
1960  fHvChName.push_back(str);
1961  break;
1962  case eHvDemand:
1963  fval = str.toFloat(&ok);
1964  if (ok) {
1965  fHvDemand.push_back(fval);
1966  } else {
1967  fErrorMsg = "**ERROR** found HV demand '" + str + "' at position" + QString("%1").arg(fHvChNo.size()) + " which is not an double?!?";
1968  fValid = false;
1969  return false;
1970  }
1971  break;
1972  case eCurrentLimit:
1973  fval = str.toFloat(&ok);
1974  if (ok) {
1975  fCurrentLimit.push_back(fval);
1976  } else {
1977  fErrorMsg = "**ERROR** found current limit '" + str + "' at position" + QString("%1").arg(fHvChNo.size()) + " which is not an double?!?";
1978  fValid = false;
1979  return false;
1980  }
1981  break;
1982  default:
1983  break;
1984  }
1985 
1986  return true;
1987 }
1988 
1989 //**********************************************************************
1990 // endDocument
1991 //**********************************************************************
1999 {
2000  QString errorMsg;
2001 
2002  if (!fValid) {
2003  fHvChNo.clear();
2004  fHvChName.clear();
2005  fHvDemand.clear();
2006  fCurrentLimit.clear();
2007  }
2008 
2009  return true;
2010 }
2011 
2012 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2013 // implementation of PLemAutoRun
2014 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2015 
2016 //**********************************************************************
2017 // constructor
2018 //**********************************************************************
2025 PLemAutoRun::PLemAutoRun(QString &host, QString &exp) :
2026  fHostName(host),
2027  fExpName(exp)
2028 {
2029  fEnableAll = false;
2030  InitEnabled(); // initialize all the enable flags to 'false'
2031 
2032  fXMLSchemaFln = "";
2033  fXMLAutoRunFln = "";
2034  fXMLAutoRunHTML = "";
2035  fAutoRunPath = "";
2036 
2037  fAutoRunSequence = "";
2038  fShowComments = true;
2039  fGotoLine = -1;
2040  fNextAutoRunSequence = "";
2041  fAutoRunStatusMsg = "";
2042  fAutoRunState = 0;
2043 
2044  fHvTripFlag = 0;
2045  fFieldPwrSupply = "";
2046 
2047  fNoOfAutoRunCmds = 0;
2048  fCurrentAutoRunCmd = 0;
2049  fAutoRunCurrentIter = 0;
2050 
2052 
2053  // init system 'constants'
2054  for (int i=0; i<NO_ENERGY_LOSS_PARAM; i++)
2055  fEnergyLossParam[i] = 0.0;
2056  fMaxTempIncrease = 0.0;
2057  fFieldTimeout = 0.0;
2058  fFieldAccuracy = 0.0;
2059  fHVTimeout = 0.0;
2060  fHVAccuracy = 0.0;
2061  fBHMaxFlow = 25000.0;
2062  fBHMinFlow = 500.0;
2063  fBHFlowTemp = 1.0e5;
2064  fBHFlowTempOffset = 0.0;
2065  fBHFlowOffset = 300.0;
2066  fDSetRatio = 0.1;
2067  fAbsMaxTempDiff = 1.0e-2;
2068  fRelMaxTempDiff = 1.0e-4;
2069  fMaxTempTrend = 1.0e-3;
2070  fHeaterMax = 95.0;
2071  fHeaterMin = 5.0;
2072  fTimeoutFlowSet = 60.0e3; // in (msec)
2073  fFlowFactor = 0.05;
2074  fFlowSetRatio = 0.02;
2075  fFlowSetAbsolute = 1.0;
2076  fFlowTimeoutReduction = 30.0e3; // in (msec)
2077  fSampleHistoLastTime = 0.0;
2078  fFlowLowestFlowToConsider = 0.0; //<! lowest demand flow to consider
2079  fFlowMaxRelFlowDiffToConsider = 100.0; //<! maximum rel flow error to consider
2080  fDFlowDp0 = 0.0; //<! calculates d(flow)/dP from d(flow)/dP =
2081  fDFlowDp1 = 0.0; //<! fDFlowDp0 + fDFlowDp1 * exp( fDFlowDpExp * Temp )
2082  fDFlowDpExp = -1.0;
2083 
2084  // heat capacity related coefficients
2085  fHeatCapCof1 = 0.0; //<! heat Capacity of cryo =
2086  fHeatCapCof2 = 0.0; //<! fHeatCapCof1 * T + fHeatCapCof2 * T + fHeatCapCof3 * T
2087  fHeatCapCof3 = 0.0;
2088 
2089  // Coefficients for preferred needle valve settings
2090  fNeedleValveInUse = FALSE; //<! Tag for use of electric needle valve
2091  fPrefNeedleValveCof_1_0 = 0.0; //<! NV setting = _1_0 * _1_1 * T for T<8
2093  fPrefNeedleValveCof_2_0 = 0.0; //<! NV setting = _1_0 * _1_1 * T for 8<T<10
2095  // Test changes for T ranges
2096  fPrefNeedleValveCof_3_0 = 0.0; //<! NV setting = _1_0 * _1_1 * T for 10<T<20
2098  fPrefNeedleValveCof_4_0 = 0.0; //<! NV setting = _1_0 * _1_1 * T for 20<T
2100  fPrefNeedleValveRelStep = 0.0; //<! relative change in SampleTempConsiderNeedleValve
2101  fPrefNeedleValveAbsStep = 0.0; //<! absolute change in SampleTempConsiderNeedleValve
2102 
2103  // critical current for the WEW. For larger currents, the RA HV's should be switched off due to the Penning trap problem
2104  fWEWCriticalCurrentRA = 22.65; // ~130G
2105 
2106  // maximal currents for the magnet power supplied
2107  fWEWLMaxCurrent = 50.0;
2108  fWEWHMaxCurrent = 595.0;
2109  fDanfysikMaxCurrent = 20.0;
2110 
2111  // FOM related variables int
2112  fFOMCurrentAccuracy = 0.0;
2113 
2114  // init warmup related variables
2115  fWarmUpWished = false;
2116  fWarmUpVent = false;
2117 
2118  // init debug flag, which is used to print out additional information
2119  fDebug = false;
2120 
2121  // init ignore clients flag, if set true it will be ignored if frontends are running or not!! ONLY FOR TESTING!!
2122  fIgnoreClients = false;
2123  // init ignore alarms flag, if set true it will ignore alarm messages. ONLY FOR TESTING!!
2124  fIgnoreAlarms = false;
2125  // 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!!
2126  fFugHvCheck = true;
2127 
2128  // init temperature regulation flag
2129  fSampleTempRegulation = true;
2130  fSampleTempUnstable = false;
2131 
2132  // init temperature tolerance
2133  fSampleTempAccuracy = 0.1;
2134 
2135  // init run related variables
2136  fRunStopped = true;
2137  fRunCheckEvents = true;
2138  fRunNoEventsNeeded = 0;
2139  fRunTimeout = 0;
2140 
2141  // init hotlink variables
2142  for (int i=0; i<SAMPLE_CRYO_INPUT; i++)
2143  fSampleInput[i] = 0.0;
2144  for (int i=0; i<SAMPLE_CRYO_OUTPUT; i++)
2145  fSampleOutput[i] = 0.0;
2146 
2147  // init temperature history related variables
2149  fSampleHistoPos = 0;
2150 
2151  // init raw voltage dumps to be made
2152  fDumpInUse = false;
2153  fDumpCounter = 0;
2154  fDumpFileName = "";
2155 
2156  // init setup related variables
2157  fSetupSampleEnabled = false;
2158  fSetupWewEnabled = false;
2159  fSetupBparEnabled = false;
2160 
2161  // default HV settings path, in case it is not found int the lemAutoRun.xml
2162  fHvSettingsPath = QString("/home/nemu/nemu/midas/experiment/nemu/hv_settings/");
2163 
2164  // init odb related variables
2165  fTriggerEventsPath = "";
2166  fEnableOnOffModePath = "";
2167  fAlarmsPath = "";
2168  fAlarmTdHvTripPath = "";
2169  fRunInfoPath = "";
2170  fRunCommentPath = "";
2171  fTofMinPath = "";
2172  fTofMaxPath = "";
2173  fModNamePath = "";
2174  fModDatePath = "";
2175  fLemSetupPath = "";
2176  fSampleCryoPath = "";
2177  fSpinRotEnabledPath = "";
2178  fSpinRotAnglePath = "";
2179  fEnergyLossParamPath = "";
2180  fClientsPath = "";
2181  fHVDemandPath = "";
2182  fHVMeasuredPath = "";
2183  fHVCurrentPath = "";
2184  fHVDetectorDemandPath = "";
2186  fSpinRotMagInputPath = "";
2187  fSpinRotMagOutputPath = "";
2188  fDanfysikInputPath = "";
2189  fDanfysikOutputPath = "";
2190  fWEWOutputPath = "";
2191  fWEWInputPath = "";
2192  fMagFieldPath = "";
2193  fTflInputPath = "";
2194  fTflOutputPath = "";
2195  fSampleCtrlChPath = "";
2196  fSampleChannelPath = "";
2197  fSampleSensorTypePath = "";
2198  fSampleInputPath = "";
2199  fSampleOutputPath = "";
2200  fSampleRawVoltagePath = "";
2203  fLemvacInputPath = "";
2204  fLemvacOutputPath = "";
2205  fFOMInputPath = "";
2206  fFOMOutputPath = "";
2207  fBeamlineDemandPath = "";
2208  fMagParamWewPath = "";
2209  fMagParamBparPath = "";
2211  fSetupWewEnabledPath = "";
2212  fSetupBparEnabledPath = "";
2213 
2216 
2217  // initialize running client flags
2218  fAnalyzerName = "";
2219  fFrontendName = "";
2220  fSampleFeName = "";
2221  fWEWFeName = "";
2222  fDanfysikFeName = "";
2223  fHVFeName = "";
2224  fLemvacFeName = "";
2225  fAnalyzerRunning = false;
2226  fFrontendRunning = false;
2227  fSampleFeRunning = false;
2228  fSampleOvenOmegaFeRunning = false;
2229  fWEWFeRunning = false;
2230  fDanfysikFeRunning = false;
2231  fHVFeRunning = false;
2232  fLemvacFeRunning = false;
2233 
2234  // initialize pointers
2235  fExp = nullptr;
2236  fTriggerEventsKey = nullptr;
2237  fAlarmsKey = nullptr;
2238  fAlarmTdHvTripKey = nullptr;
2239  fRunInfoKey = nullptr;
2240  fRunCommentKey = nullptr;
2241  fTofMinKey = nullptr;
2242  fTofMaxKey = nullptr;
2243  fModNameKey = nullptr;
2244  fModDateKey = nullptr;
2245  fLemSetupKey = nullptr;
2246  fSampleCryoKey = nullptr;
2247  fSpinRotEnabledKey = nullptr;
2248  fSpinRotAngleKey = nullptr;
2249  fEnergyLossParamKey = nullptr;
2250  fClientsKey = nullptr;
2251  fHVDemandKey = nullptr;
2252  fHVMeasuredKey = nullptr;
2253  fHVCurrentKey = nullptr;
2254  fHVDetectorDemandKey = nullptr;
2255  fHVDetectorMeasuredKey = nullptr;
2256  fSpinRotMagInputKey = nullptr;
2257  fSpinRotMagOutputKey = nullptr;
2258  fDanfysikInputKey = nullptr;
2259  fDanfysikOutputKey = nullptr;
2260  fWEWOutputKey = nullptr;
2261  fWEWInputKey = nullptr;
2262  fMagFieldKey = nullptr;
2263  fTflInputKey = nullptr;
2264  fTflOutputKey = nullptr;
2265  fSampleCtrlChKey = nullptr;
2266  fSampleChannelKey = nullptr;
2267  fSampleSensorTypeKey = nullptr;
2268  fSampleInputKey = nullptr;
2269  fSampleOutputKey = nullptr;
2270  fSampleNoConnectionKey = nullptr;
2271  fSampleOvenOmegaInputKey = nullptr;
2272  fSampleOvenOmegaOutputKey = nullptr;
2273  fLemvacInputKey = nullptr;
2274  fLemvacOutputKey = nullptr;
2275  fFOMInputKey = nullptr;
2276  fFOMOutputKey = nullptr;
2277  fBeamlineDemandKey = nullptr;
2278  fMagParamWewKey = nullptr;
2279  fMagParamBparKey = nullptr;
2280  fSetupSampleEnabledKey = nullptr;
2281  fSetupWewEnabledKey = nullptr;
2282  fSetupBparEnabledKey = nullptr;
2283  fSampleRawVoltageKey = nullptr;
2284 
2285  fRAPulsingEnabled = false;
2286 
2287  // connect internal signal and slot
2288  QObject::connect(this, SIGNAL(StatusMsg(QString)), this, SLOT(UpdateStatusMsg(QString)));
2289 }
2290 
2291 //**********************************************************************
2292 // destructor
2293 //**********************************************************************
2298 {
2299  if (fExp) {
2300  delete fExp;
2301  fExp = nullptr;
2302  }
2303  if (fTriggerEventsKey) {
2304  delete fTriggerEventsKey;
2305  fTriggerEventsKey = nullptr;
2306  }
2307  if (fAlarmsKey) {
2308  delete fAlarmsKey;
2309  fAlarmsKey = nullptr;
2310  }
2311  if (fAlarmTdHvTripKey) {
2312  delete fAlarmTdHvTripKey;
2313  fAlarmTdHvTripKey = nullptr;
2314  }
2315  if (fRunInfoKey) {
2316  delete fRunInfoKey;
2317  fRunInfoKey = nullptr;
2318  }
2319  if (fRunCommentKey) {
2320  delete fRunCommentKey;
2321  fRunCommentKey = nullptr;
2322  }
2323  if (fTofMinKey) {
2324  delete fTofMinKey;
2325  fTofMinKey = nullptr;
2326  }
2327  if (fTofMaxKey) {
2328  delete fTofMaxKey;
2329  fTofMaxKey = nullptr;
2330  }
2331  if (fModNameKey) {
2332  delete fModNameKey;
2333  fModNameKey = nullptr;
2334  }
2335  if (fModDateKey) {
2336  delete fModDateKey;
2337  fModDateKey = nullptr;
2338  }
2339  if (fLemSetupKey) {
2340  delete fLemSetupKey;
2341  fLemSetupKey = nullptr;
2342  }
2343  if (fSampleCryoKey) {
2344  delete fSampleCryoKey;
2345  fSampleCryoKey = nullptr;
2346  }
2347  if (fSpinRotEnabledKey) {
2348  delete fSpinRotEnabledKey;
2349  fSpinRotEnabledKey = nullptr;
2350  }
2351  if (fSpinRotAngleKey) {
2352  delete fSpinRotAngleKey;
2353  fSpinRotAngleKey = nullptr;
2354  }
2355  if (fEnergyLossParamKey) {
2356  delete fEnergyLossParamKey;
2357  fEnergyLossParamKey = nullptr;
2358  }
2359  if (fClientsKey) {
2360  delete fClientsKey;
2361  fClientsKey = nullptr;
2362  }
2363  if (fHVDemandKey) {
2364  delete fHVDemandKey;
2365  fHVDemandKey = nullptr;
2366  }
2367  if (fHVMeasuredKey) {
2368  delete fHVMeasuredKey;
2369  fHVMeasuredKey = nullptr;
2370  }
2371  if (fHVCurrentKey) {
2372  delete fHVCurrentKey;
2373  fHVCurrentKey = nullptr;
2374  }
2375  if (fHVDetectorDemandKey) {
2376  delete fHVDetectorDemandKey;
2377  fHVDetectorDemandKey = nullptr;
2378  }
2379  if (fHVDetectorMeasuredKey) {
2380  delete fHVDetectorMeasuredKey;
2381  fHVDetectorMeasuredKey = nullptr;
2382  }
2383 
2384  if (fSpinRotMagInputKey) {
2385  delete fSpinRotMagInputKey;
2386  fSpinRotMagInputKey = nullptr;
2387  }
2388  if (fSpinRotMagOutputKey) {
2389  delete fSpinRotMagOutputKey;
2390  fSpinRotMagOutputKey = nullptr;
2391  }
2392  if (fDanfysikInputKey) {
2393  delete fDanfysikInputKey;
2394  fDanfysikInputKey = nullptr;
2395  }
2396  if (fDanfysikOutputKey) {
2397  delete fDanfysikOutputKey;
2398  fDanfysikOutputKey = nullptr;
2399  }
2400  if (fWEWOutputKey) {
2401  delete fWEWOutputKey;
2402  fWEWOutputKey = nullptr;
2403  }
2404  if (fWEWInputKey) {
2405  delete fWEWInputKey;
2406  fWEWInputKey = nullptr;
2407  }
2408  if (fMagFieldKey) {
2409  delete fMagFieldKey;
2410  fMagFieldKey = nullptr;
2411  }
2412  if (fTflInputKey) {
2413  delete fTflInputKey;
2414  fTflInputKey = nullptr;
2415  }
2416  if (fTflOutputKey) {
2417  delete fTflOutputKey;
2418  fTflOutputKey = nullptr;
2419  }
2420  if (fSampleCtrlChKey) {
2421  delete fSampleCtrlChKey;
2422  fSampleCtrlChKey = nullptr;
2423  }
2424  if (fSampleChannelKey) {
2425  delete fSampleChannelKey;
2426  fSampleChannelKey = nullptr;
2427  }
2428  if (fSampleSensorTypeKey) {
2429  delete fSampleSensorTypeKey;
2430  fSampleSensorTypeKey = nullptr;
2431  }
2432  if (fSampleInputKey) {
2433  delete fSampleInputKey;
2434  fSampleInputKey = nullptr;
2435  }
2436  if (fSampleOutputKey) {
2437  delete fSampleOutputKey;
2438  fSampleOutputKey = nullptr;
2439  }
2440  if (fSampleRawVoltageKey) {
2441  delete fSampleRawVoltageKey;
2442  fSampleRawVoltageKey = nullptr;
2443  }
2444  if (fSampleNoConnectionKey) {
2445  delete fSampleNoConnectionKey;
2446  fSampleNoConnectionKey = nullptr;
2447  }
2449  delete fSampleOvenOmegaInputKey;
2450  fSampleOvenOmegaInputKey = nullptr;
2451  }
2454  fSampleOvenOmegaOutputKey = nullptr;
2455  }
2456  if (fLemvacInputKey) {
2457  delete fLemvacInputKey;
2458  fLemvacInputKey = nullptr;
2459  }
2460  if (fLemvacOutputKey) {
2461  delete fLemvacOutputKey;
2462  fLemvacOutputKey = nullptr;
2463  }
2464  if (fFOMInputKey) {
2465  delete fFOMInputKey;
2466  fFOMInputKey = nullptr;
2467  }
2468  if (fFOMOutputKey) {
2469  delete fFOMOutputKey;
2470  fFOMOutputKey = nullptr;
2471  }
2472  if (fBeamlineDemandKey) {
2473  delete fBeamlineDemandKey;
2474  fBeamlineDemandKey = nullptr;
2475  }
2476  if (fMagParamWewKey) {
2477  delete fMagParamWewKey;
2478  fMagParamWewKey = nullptr;
2479  }
2480  if (fMagParamBparKey) {
2481  delete fMagParamBparKey;
2482  fMagParamBparKey = nullptr;
2483  }
2484  if (fSetupSampleEnabledKey) {
2485  delete fSetupSampleEnabledKey;
2486  fSetupSampleEnabledKey = nullptr;
2487  }
2488  if (fSetupWewEnabledKey) {
2489  delete fSetupWewEnabledKey;
2490  fSetupWewEnabledKey = nullptr;
2491  }
2492  if (fSetupBparEnabledKey) {
2493  delete fSetupBparEnabledKey;
2494  fSetupBparEnabledKey = nullptr;
2495  }
2496 }
2497 
2498 //**********************************************************************
2499 // ReadStartupXML
2500 //**********************************************************************
2505 {
2506  QString fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun.xml";
2507  if (!QFile::exists(fln)) {
2508  QString err = "lemAutoRun: Couldn't find XML startup file " + fln;
2509  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, err);
2510  return;
2511  }
2512 
2513  PLemAutoRunXMLParser handler(fln, this);
2514  if (!handler.isValid()) {
2515  cm_msg(MERROR, "lemAutoRun", "**ERROR** lemAutoRun: couldn't read lemAutoRun.xml");
2516  cm_yield(0);
2517  }
2518 }
2519 
2520 //**********************************************************************
2521 // ReadSampleCryoXML
2522 //**********************************************************************
2527 {
2528  char str[NAME_LENGTH];
2529  int size;
2530  QString sampleCryoName = "";
2531  QString fln = "";
2532 
2533  if (!fEnabled["sample_eq"] || !fEnabled["sample_cryo_info_odb"]) {
2534  return;
2535  }
2536 
2537  // get the sample cryo name
2538  size = sizeof(str);
2539  fSampleCryoKey->GetData((void *)&str, &size, TID_STRING);
2540  sampleCryoName = QString(str);
2541 
2542  if (sampleCryoName == "Konti-1") {
2543  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_KontiCryo1.xml";
2545  } else if (sampleCryoName == "Konti-2") {
2546  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_KontiCryo2.xml";
2548  } else if (sampleCryoName == "Konti-3") {
2549  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_KontiCryo3.xml";
2551  } else if (sampleCryoName == "Konti-4") {
2552  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_KontiCryo4.xml";
2554  } else if (sampleCryoName == "LowTemp-1") { // former Mango
2555  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_LowTemp1.xml";
2557  } else if (sampleCryoName == "LowTemp-2") { // former Lemon
2558  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_LowTemp2.xml";
2560  } else if (sampleCryoName == "Omega") {
2561  fln = "/home/nemu/nemu/midas/bin/.lemXMLs/lemAutoRun_Oven.xml";
2563  } else if (sampleCryoName == "NoCryo") {
2565  return;
2566  }
2567 
2568  if (!QFile::exists(fln)) {
2569  QString err = "lemAutoRun: Couldn't find XML startup file " + fln + " ";
2570  err += "Perhaps the sample cryo name (" + sampleCryoName + ") is wrong?!";
2571  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, err);
2572  return;
2573  }
2574 
2575  PLemSampleCryoXMLParser handler(fln, this);
2576  if (!handler.isValid()) {
2577  QString msg = QString("**ERROR** lemAutoRun: Couldn't read cryo xml-file '%1'").arg(fln);
2578  cm_msg(MERROR, "lemAutoRun", msg.toLatin1().data());
2579  cm_yield(0);
2580  }
2581 }
2582 
2583 //**********************************************************************
2584 // InitEnabled
2585 //**********************************************************************
2590 {
2591  // feed ODB stuff
2592  fEnabled.insert("trigger_events_odb", false);
2593  fEnabled.insert("enable_on_off_mode_odb", false);
2594  fEnabled.insert("alarms_odb", false);
2595  fEnabled.insert("alarms_td_hv_trip_odb", false);
2596  fEnabled.insert("run_comment_odb", false);
2597  fEnabled.insert("tof_min_odb", false);
2598  fEnabled.insert("tof_max_odb", false);
2599  fEnabled.insert("mod_name_odb", false);
2600  fEnabled.insert("mod_date_odb", false);
2601  fEnabled.insert("lem_setup_odb", false);
2602  fEnabled.insert("energy_loss_param_odb", false);
2603  fEnabled.insert("sample_cryo_info_odb", false);
2604  fEnabled.insert("sample_name_info_odb", false);
2605  fEnabled.insert("spin_rot_calib_odb", false);
2606  fEnabled.insert("spin_rot_angle_odb", false);
2607  fEnabled.insert("mag_param_wew_odb", false);
2608  fEnabled.insert("mag_param_bpar_odb", false);
2609  fEnabled.insert("setup_sample_odb", false);
2610  fEnabled.insert("setup_wew_odb", false);
2611  fEnabled.insert("setup_bpar_odb", false);
2612 
2613  // feed all clients
2614  fEnabled.insert("analyzer_fe", false);
2615  fEnabled.insert("vme_fe", false);
2616  fEnabled.insert("tfl_scfe", false);
2617  fEnabled.insert("sample_scfe", false);
2618  fEnabled.insert("omega_scfe", false);
2619  fEnabled.insert("wew_scfe", false);
2620  fEnabled.insert("danfysik_scfe", false);
2621  fEnabled.insert("fug_scfe", false);
2622  fEnabled.insert("lemvac_scfe", false);
2623 
2624  // feed all equipment
2625  fEnabled.insert("fug_eq", false);
2626  fEnabled.insert("hv_detectors_eq", false);
2627  fEnabled.insert("danfysik_spin_rot_eq", false);
2628  fEnabled.insert("danfysik_eq", false);
2629  fEnabled.insert("wew_eq", false);
2630  fEnabled.insert("magnet_field_info", false);
2631  fEnabled.insert("tfl_eq", false);
2632  fEnabled.insert("sample_eq", false);
2633  fEnabled.insert("omega_eq", false);
2634  fEnabled.insert("lemvac_eq", false);
2635  fEnabled.insert("fom_eq", false);
2636  fEnabled.insert("beamline_eq", false);
2637 }
2638 
2639 //**********************************************************************
2640 // SetEnabled
2641 //**********************************************************************
2647 void PLemAutoRun::SetEnabled(const QString key, bool val)
2648 {
2649  if (!key.compare("all", Qt::CaseInsensitive)) { // change all
2650  QMapIterator<QString, bool> i(fEnabled);
2651  while (i.hasNext()) {
2652  i.next();
2653  fEnabled[i.key()] = val;
2654  }
2655  } else {
2656  if (fEnabled.contains(key)) {
2657  fEnabled[key] = val;
2658  }
2659  }
2660 }
2661 
2662 //**********************************************************************
2663 // ConnectExp
2664 //**********************************************************************
2670 {
2671  // create object
2672  fExp = new PExperiment("lemAutoRun1");
2673  if (!fExp) {
2674  return;
2675  }
2676 
2677  // connect to MIDAS
2678  fExp->Connect(fHostName, fExpName, "lemAutoRun1");
2679  if (!fExp->IsConnected()) {
2680  return;
2681  }
2682 
2683  // start watchdog timer
2684  fExp->StartTimer();
2685 
2686  // make sure that we start from a clean state
2687  CleanLiveData();
2688 
2689  // get all the ODB keys needed to work
2690  if (!GetAllKeys()) {
2691  QString err = QString("lemAutoRun: Couldn't collect the necessary ODB keys");
2692  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
2693  return;
2694  }
2695 
2696  if (fEnabled["sample_eq"]) {
2697  // check if setup flags do make sense
2698  if (!fSetupSampleEnabled) {
2699  QString err = QString("lemAutoRun: **WARNING** MCP2 setup detected.");
2700  emit ErrorMsg(1, 0, LAR_MSG, -1, err);
2701  }
2702  if (fEnabled["wew_eq"] && fEnabled["danfysik_eq"]) {
2704  QString err = QString("lemAutoRun: Setup flags doesn't make any sense: WEW enabled=%1, Bpar enabled=%2").arg(fSetupWewEnabled).arg(fSetupBparEnabled);
2705  emit ErrorMsg(1, 0, LAR_FATAL, -1, err);
2706  return;
2707  }
2708  }
2709  }
2710 
2711  // get information which magnet power supply is in use
2712  if (fSetupWewEnabled)
2713  fFieldPwrSupply = QString("wew");
2714  else
2715  fFieldPwrSupply = QString("danfysik");
2716 
2717  if (fEnabled["enable_on_off_mode_odb"]) {
2718  // get the Enable_OnOff_Mode flag which shows if RA are operated in pulsed mode
2719  PKey *onOffMode = new PKey(fExp, fEnableOnOffModePath);
2720  if (!onOffMode->IsValid()) {
2721  QString err = QString("lemAutoRun: Enable_OnOff_Mode key not found.");
2722  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
2723  } else {
2724  int ival, size=sizeof(int);
2725  onOffMode->GetData(&ival, &size, TID_BOOL);
2726  if (ival == 1)
2727  fRAPulsingEnabled = true;
2728  else
2729  fRAPulsingEnabled = false;
2730  }
2731  // clean up
2732  delete onOffMode;
2733  }
2734 
2735  QObject::connect(fExp, SIGNAL(NetworkConnectionLost()), this, SLOT(NetworkConnectionLost()));
2736  QObject::connect(fExp, SIGNAL(ReceivedShutdownCmd()), this, SLOT(ReceivedShutdownCmd()));
2737 
2738 }
2739 
2740 //**********************************************************************
2741 // NetworkConnectionLost (SLOT)
2742 //**********************************************************************
2748 {
2749  QString err = QString("lemAutoRun: Lost Network Connection");
2750  emit ErrorMsg(1, 0, LAR_LOST_NETWORK_CONNECTION, -1, err);
2751 }
2752 
2753 //**********************************************************************
2754 // ReceivedShutdownCmd (SLOT)
2755 //**********************************************************************
2761 {
2762  QString err;
2763 
2764  // set autoRun state to stopped
2765  int runState = LAR_STATE_STOPPED;
2766  PKey runStateKey(fExp, "/AutoRun/Run State");
2767  if (runStateKey.IsValid()) {
2768  runStateKey.SetData((void*)&runState, 1, TID_INT);
2769  }
2770 
2771  if (fAutoRunCurrentIter)
2773 
2774  err = QString("Autorun aborted.");
2775  emit StatusMsg(err);
2776 
2777  err = QString("lemAutoRun: Received Shutdown Command");
2778  emit ErrorMsg(1, 0, LAR_RECIEVED_SHUTDOWN_CMD, -1, err);
2779 
2781 }
2782 
2783 //**********************************************************************
2784 // UpdateStatusMsg (SLOT)
2785 //**********************************************************************
2789 void PLemAutoRun::UpdateStatusMsg(const QString statusMsg)
2790 {
2791  QDateTime dt = QDateTime::currentDateTime();
2792  QString msg;
2793 
2794  msg = "["+dt.toString("dd.MM.yy, hh:mm:ss")+"] " + statusMsg;
2795 
2796  PKey statusMsgKey(fExp, "/AutoRun/Status");
2797  if (statusMsgKey.IsValid()) {
2798  char cmsg[128];
2799  memset(cmsg, 0, sizeof(cmsg));
2800  strncpy(cmsg, msg.toLatin1().data(), sizeof(cmsg)-1);
2801  statusMsgKey.SetData(cmsg, 1, TID_STRING);
2802  }
2803 }
2804 
2805 //**********************************************************************
2806 // GetRunState
2807 //**********************************************************************
2813 {
2814  int state = -1;
2815  PKey key(fExp, "/AutoRun/Run State");
2816  if (key.IsValid()) {
2817  int ival;
2818  int size = sizeof(ival);
2819  int status = key.GetData(&ival, &size, TID_INT);
2820  if (status == DB_SUCCESS) {
2821  state = ival;
2822  }
2823  }
2824 
2825  return state;
2826 }
2827 
2828 //**********************************************************************
2829 // UpdateRunState
2830 //**********************************************************************
2835 void PLemAutoRun::UpdateRunState(const int state)
2836 {
2837  PKey key(fExp, "/AutoRun/Run State");
2838  if (key.IsValid()) {
2839  key.SetData((void*)&state, 1, TID_INT);
2840  }
2841 }
2842 
2843 //**********************************************************************
2844 // GetAutoRunSequence
2845 //**********************************************************************
2851 {
2852  QString fln("");
2853 
2854  PKey larSeqKey(fExp, "/AutoRun/Auto Run Sequence");
2855  if (larSeqKey.IsValid()) {
2856  char autoRunSequence[64];
2857  int size = sizeof(autoRunSequence);
2858  int status = larSeqKey.GetData(autoRunSequence, &size, TID_STRING);
2859  if (status == DB_SUCCESS)
2860  fln = autoRunSequence;
2861  }
2862 
2863  return fln;
2864 }
2865 
2866 //**********************************************************************
2867 // ShowComments
2868 //**********************************************************************
2874 {
2875  bool showComments = true;
2876 
2877  PKey key(fExp, "/AutoRun/Show Comments");
2878  if (key.IsValid()) {
2879  int ival;
2880  int size = sizeof(ival);
2881  int status = key.GetData(&ival, &size, TID_BOOL);
2882  if (status == DB_SUCCESS) {
2883  if (ival != 1)
2884  showComments = false;
2885  }
2886  }
2887 
2888  return showComments;
2889 }
2890 
2891 //**********************************************************************
2892 // SetGotoLine
2893 //**********************************************************************
2898 void PLemAutoRun::SetGotoLine(const int line)
2899 {
2900  PKey key(fExp, "/AutoRun/GotoLine");
2901  if (key.IsValid()) {
2902  key.SetData((void*)&line, 1, TID_INT);
2903  }
2904 }
2905 
2906 //**********************************************************************
2907 // GetGotoLine
2908 //**********************************************************************
2914 {
2915  int line = -1;
2916  PKey key(fExp, "/AutoRun/GotoLine");
2917  if (key.IsValid()) {
2918  int ival;
2919  int size = sizeof(ival);
2920  int status = key.GetData(&ival, &size, TID_INT);
2921  if (status == DB_SUCCESS) {
2922  line = ival;
2923  }
2924  }
2925 
2926  return line;
2927 }
2928 
2929 //**********************************************************************
2930 // CleanLiveData
2931 //**********************************************************************
2933 {
2934  // make sure that not already an autorun is ongoing
2935  PKey larRunStateKey(fExp, "/AutoRun/Run State");
2936  if (larRunStateKey.IsValid()) {
2937  int state = -1;
2938  int size = sizeof(int);
2939  larRunStateKey.GetData(&state, &size, TID_INT);
2940  if ((state == LAR_STATE_STARTING) || (state == LAR_STATE_RUNNING))
2941  return;
2942  }
2943 
2944  // clean
2945  PKey liveDataKey(fExp, "/AutoRun/LiveData");
2946 
2947  if (liveDataKey.IsValid()) {
2948  // clean ErrorInLine
2949  PKey *errorInLineKey = new PKey(&liveDataKey, "ErrorInLine");
2950  if (errorInLineKey == 0) {
2951  cm_msg(MDEBUG, "lemAutoRun", "**ERROR** couldn't invoke errorInLineKey");
2952  return;
2953  }
2954  if (errorInLineKey->IsValid()) {
2955  int ival[10];
2956  for (int i=0; i<10; i++) {
2957  ival[i] = -1;
2958  }
2959  errorInLineKey->SetData((void *)&ival[0], 10, TID_INT);
2960  }
2961  delete errorInLineKey;
2962 
2963  // clean ErrorMsg
2964  PKey *errorMsgKey = new PKey(&liveDataKey, "ErrorMsg");
2965  if (errorMsgKey == 0) {
2966  cm_msg(MDEBUG, "lemAutoRun", "**ERROR** couldn't invoke errorMsgKey");
2967  return;
2968  }
2969  if (errorMsgKey->IsValid()) {
2970  char msg[10][128];
2971  for (int i=0; i<10; i++) {
2972  memset(msg[i], 0, 128);
2973  strcpy(msg[i], "empty");
2974  }
2975  errorMsgKey->SetData((void*)msg, 10, TID_STRING);
2976  }
2977  delete errorMsgKey;
2978  } else { // key not valid, i.e. likely doesn't exist yet -> try to create it
2979  cm_msg(MINFO, "lemAutoRun", "try to create default /AutoRun/LiveData record.");
2980  cm_yield(0);
2981  // AutoRun LiveData initial record
2982  const char *lar_live_data_settings =
2983 "ErrorInLine = INT[10] : \n\
2984 [0] -1,\n\
2985 [1] -1,\n\
2986 [2] -1,\n\
2987 [3] -1,\n\
2988 [4] -1,\n\
2989 [5] -1,\n\
2990 [6] -1,\n\
2991 [7] -1,\n\
2992 [8] -1,\n\
2993 [9] -1,\n\
2994 ErrorMsg = STRING[10] : \n\
2995 [128] empty\n\
2996 [128] empty\n\
2997 [128] empty\n\
2998 [128] empty\n\
2999 [128] empty\n\
3000 [128] empty\n\
3001 [128] empty\n\
3002 [128] empty\n\
3003 [128] empty\n\
3004 [128] empty\n\
3005 CurrentLineNo = INT : -1\n\
3006 LoopVal = STRING : [32] empty\n\
3007 TransitionTag = INT : 0\n\
3008 AutoRun = STRING : [32] empty\n\
3009 ";
3010  if (db_create_record(fExp->GetHdb(), 0, "/AutoRun/LiveData", lar_live_data_settings) != DB_SUCCESS) { // error
3011  cm_msg(MERROR, "lemAutoRun", "**ERROR** couldn't create /AutoRun/LiveData default record.");
3012  cm_yield(0);
3013  return;
3014  }
3015  }
3016 }
3017 
3018 //**********************************************************************
3019 // FeedLiveDataErrors
3020 //**********************************************************************
3021 void PLemAutoRun::FeedLiveDataErrors(int noOfErrors, int idx, int /*errorNo*/, int line, QString errorMsg)
3022 {
3023  cm_msg(MDEBUG, "lemAutoRun", "debug> noOfErrors=%d, idx=%d, line=%d, errMsg=%s", noOfErrors, idx, line, errorMsg.toLatin1().data()); cm_yield(0);
3024 
3025  PKey errorInLineKey(fExp, "/AutoRun/LiveData/ErrorInLine");
3026  PKey errorMsgKey(fExp, "/AutoRun/LiveData/ErrorMsg");
3027  PKey transTagKey(fExp, "/AutoRun/LiveData/TransitionTag");
3028 
3029  int ival = LAR_TT_IDLE;
3030  transTagKey.SetData((void*)&ival, 1, TID_INT);
3031 
3032  int i=0;
3033  if (noOfErrors != 0) {
3034  i = idx;
3035  }
3036 
3037  ival=0;
3038  if (line != -1)
3039  ival = line;
3040  if (errorInLineKey.IsValid()) {
3041  errorInLineKey.SetDataIndex((void *)&ival, i, TID_INT);
3042  }
3043  if (errorMsgKey.IsValid()) {
3044  char msg[128];
3045  memset(msg, 0, sizeof(msg));
3046  strncpy(msg, errorMsg.toLatin1().data(), sizeof(msg));
3047  errorMsgKey.SetDataIndex(msg, i, TID_STRING);
3048  }
3049 }
3050 
3051 //**********************************************************************
3052 // DisconnectFromExp
3053 //**********************************************************************
3058 {
3059  QString runStatePath = "/AutoRun/Run State";
3060  PKey key(fExp, runStatePath);
3061  if (key.IsValid()) {
3062  INT ival;
3063  int size = sizeof(ival);
3064  // check if run state is LAR_STATE_NEXT
3065  key.GetData((void*)&ival, &size, TID_INT);
3066 
3067  if (ival != LAR_STATE_NEXT) {
3068  ival = LAR_STATE_STOPPED;
3069  key.SetData((void*)&ival, 1, TID_INT);
3070  }
3071  }
3072 
3073  if (fExp)
3074  fExp->Disconnect();
3075 }
3076 
3077 //**********************************************************************
3078 // HandleParseError (SLOT)
3079 //**********************************************************************
3083 void PLemAutoRun::HandleParseError(int noOfErrors, int idx, int errorNo, int line, QString errorMsg)
3084 {
3085  // set autorun state to stopped
3087 
3088  // set autorun status message
3089  char msg[128];
3090  if (line > 0)
3091  sprintf(msg, "**ERROR** in line no %d (errorNo: %d)", line, errorNo);
3092  else
3093  sprintf(msg, "**ERROR** errorNo: %d", errorNo);
3094 
3095  FeedLiveDataErrors(noOfErrors, idx, errorNo, line, errorMsg);
3096 
3097  UpdateStatusMsg(msg);
3098  UpdateWebPage(0, HTML_PARSE_ERROR, line, errorMsg);
3099 }
3100 
3101 //**********************************************************************
3102 // DisconnectAndQuit (SLOT)
3103 //**********************************************************************
3108 {
3110 
3111  QCoreApplication::exit(0);
3112  exit(0);
3113 }
3114 
3115 //**********************************************************************
3116 // IsIdle
3117 //**********************************************************************
3122 {
3123  bool isIdle = true;
3124 
3125  // check if more than one lemAutoRun is present and if yes, idle=false
3126  int count=0;
3127  HNDLE hKey;
3128  int size, status;
3129  char str[NAME_LENGTH];
3130  for (int i=0; ; i++) {
3131  // check if there is a subkey
3132  if (fClientsKey->EnumSubKey(i, &hKey) == DB_NO_MORE_SUBKEYS)
3133  break;
3134  // get the content of the variable Name from the subkey
3135  size = sizeof(str);
3136  status = db_get_value(fClientsKey->GetHdb(), hKey, "Name", str, &size, TID_STRING, FALSE);
3137  if (status != DB_SUCCESS) {
3138  QString err = QString("Autorun: check clients failure ...");
3139  emit StatusMsg(err);
3140  err = QString("PLemAutoRun::CheckClients(): Couldn't get value from subkey.");
3141  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3142  }
3143  // check if the name is one of the monitored frontends
3144  if (!strncmp(str, "lemAutoRun", sizeof(str)))
3145  count++;
3146  }
3147 
3148  if (count > 1)
3149  isIdle = false;
3150 
3151  return isIdle;
3152 }
3153 
3154 //**********************************************************************
3155 // GetUserAutoRunSeqFln
3156 //**********************************************************************
3162 {
3163  QString result = fAutoRunPath;
3164 
3165  result += GetAutoRunSequence();
3166 
3167  return result;
3168 }
3169 
3170 //**********************************************************************
3171 // GetAllKeys
3172 //**********************************************************************
3177 {
3178  int size, status;
3179  QString err;
3180 
3181  // get key to the trigger events
3182  if (fEnabled["trigger_events_odb"]) {
3184  if (!fTriggerEventsKey->IsValid()) {
3185  err = QString("lemAutoRun: Trigger Events key not found.");
3186  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3187  return false;
3188  }
3189  }
3190 
3191  // get key to the alarms
3192  if (fEnabled["alarms_odb"]) {
3193  fAlarmsKey = new PKey(fExp, fAlarmsPath);
3194  if (!fAlarmsKey->IsValid()) {
3195  err = QString("lemAutoRun: Alarms key not found.");
3196  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3197  return false;
3198  }
3199  }
3200 
3201  // get key to the Alarm: TD HV trip trigger
3202  if (fEnabled["alarms_td_hv_trip_odb"]) {
3204  if (!fAlarmTdHvTripKey->IsValid()) {
3205  err = QString("lemAutoRun: Alarm TD HV trip trigger key not found.");
3206  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3207  return false;
3208  }
3209  // hotlink TD HV trip trigger flag
3210  size = sizeof(fHvTripFlag);
3211  status = fAlarmTdHvTripKey->HotLink(&fHvTripFlag, size, MODE_READ, TdHvTripFlagChanged, this);
3212  if (status != DB_SUCCESS) {
3213  err = QString("lemAutoRun: Couldn't hotlink Alarm TD HV trip trigger flag.");
3214  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3215  return false;
3216  }
3217  }
3218 
3219  // get run info and hotlink runinfo structure
3220  fRunInfoKey = new PKey(fExp, fRunInfoPath);
3221  if (!fRunInfoKey->IsValid()) {
3222  err = QString("lemAutoRun: Run info key not found.");
3223  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3224  return false;
3225  }
3226 
3227  // get key to run comment
3228  if (fEnabled["run_comment_odb"]) {
3229  fRunCommentKey = new PKey(fExp, fRunCommentPath);
3230  if (!fRunCommentKey->IsValid()) {
3231  err = QString("lemAutoRun: Run comment key not found.");
3232  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3233  return false;
3234  }
3235  }
3236 
3237  // get key to TOF Min
3238  if (fEnabled["tof_min_odb"]) {
3239  fTofMinKey = new PKey(fExp, fTofMinPath);
3240  if (!fTofMinKey->IsValid()) {
3241  err = QString("lemAutoRun: TOF Min key not found.");
3242  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3243  return false;
3244  }
3245  }
3246 
3247  // get key to TOF Max
3248  if (fEnabled["tof_max_odb"]) {
3249  fTofMaxKey = new PKey(fExp, fTofMaxPath);
3250  if (!fTofMaxKey->IsValid()) {
3251  err = QString("lemAutoRun: TOF Max key not found.");
3252  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3253  return false;
3254  }
3255  }
3256 
3257  // get key to moderator name
3258  if (fEnabled["mod_name_odb"]) {
3259  fModNameKey = new PKey(fExp, fModNamePath);
3260  if (!fModNameKey->IsValid()) {
3261  err = QString("lemAutoRun: Moderator name key not found.");
3262  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3263  return false;
3264  }
3265  }
3266 
3267  // get key to moderator date
3268  if (fEnabled["mod_date_odb"]) {
3269  fModDateKey = new PKey(fExp, fModDatePath);
3270  if (!fModDateKey->IsValid()) {
3271  err = QString("lemAutoRun: Moderator date key not found.");
3272  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3273  return false;
3274  }
3275  }
3276 
3277  // get key to LEM Setup
3278  if (fEnabled["lem_setup_odb"]) {
3279  fLemSetupKey = new PKey(fExp, fLemSetupPath);
3280  if (!fLemSetupKey->IsValid()) {
3281  err = QString("lemAutoRun: LEM setup key not found.");
3282  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3283  return false;
3284  }
3285  }
3286 
3287  // get key to Sample Name
3288  if (fEnabled["sample_name_info_odb"]) {
3289  fSampleNameKey = new PKey(fExp, fSampleNamePath);
3290  if (!fSampleNameKey->IsValid()) {
3291  err = QString("lemAutoRun: Sample Name key not found.");
3292  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3293  return false;
3294  }
3295  }
3296 
3297  // get key to Spin Rotation Enabled flag
3298  if (fEnabled["spin_rot_calib_odb"]) {
3300  if (!fSpinRotEnabledKey->IsValid()) {
3301  err = QString("lemAutoRun: spin rotation enabled key not found.");
3302  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3303  return false;
3304  }
3305  }
3306 
3307  // get key to Spin Rotation Angle
3308  if (fEnabled["spin_rot_angle_odb"]) {
3310  if (!fSpinRotAngleKey->IsValid()) {
3311  err = QString("lemAutoRun: spin rotation angle key not found.");
3312  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3313  return false;
3314  }
3315  }
3316 
3317  // get key to Sample Cryo
3318  if (fEnabled["sample_cryo_info_odb"]) {
3319  fSampleCryoKey = new PKey(fExp, fSampleCryoPath);
3320  if (!fSampleCryoKey->IsValid()) {
3321  err = QString("lemAutoRun: Sample Cryo key not found.");
3322  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3323  return false;
3324  }
3325  }
3326 
3327  // get key to the energy loss parameters
3328  if (fEnabled["energy_loss_param_odb"]) {
3329  QString path;
3330  for (int i=0; i<NO_ENERGY_LOSS_PARAM; i++) {
3331  path = fEnergyLossParamPath + QString("/p%1").arg(i);
3332  fEnergyLossParamKey = new PKey(fExp, path);
3333  if (!fEnergyLossParamKey->IsValid()) {
3334  err = QString("lemAutoRun: Energy loss parameter p%1 key not found.").arg(i);
3335  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3336  return false;
3337  }
3338  size = sizeof(float);
3339  fEnergyLossParamKey->GetData((void *)&fEnergyLossParam[i], &size, TID_FLOAT);
3340  delete fEnergyLossParamKey;
3341  fEnergyLossParamKey = nullptr;
3342  }
3343  }
3344 
3345  // get key to system/clients
3346  fClientsKey = new PKey(fExp, fClientsPath);
3347  if (!fClientsKey->IsValid()) {
3348  err = QString("lemAutoRun: Clients key not found.");
3349  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3350  return false;
3351  }
3352 
3353  if (fEnabled["fug_eq"]) {
3354  // get key to the HV demand values of the FUG's
3355  fHVDemandKey = new PKey(fExp, fHVDemandPath);
3356  if (!fHVDemandKey->IsValid()) {
3357  err = QString("lemAutoRun: HV demand key not found.");
3358  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3359  return false;
3360  }
3361 
3362  // get key to the HV measured values of the FUG's
3363  fHVMeasuredKey = new PKey(fExp, fHVMeasuredPath);
3364  if (!fHVMeasuredKey->IsValid()) {
3365  err = QString("lemAutoRun: HV measured key not found.");
3366  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3367  return false;
3368  }
3369 
3370  // get key to the HV current values of the FUG's
3371  fHVCurrentKey = new PKey(fExp, fHVCurrentPath);
3372  if (!fHVCurrentKey->IsValid()) {
3373  err = QString("lemAutoRun: HV current key not found.");
3374  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3375  return false;
3376  }
3377  }
3378 
3379  if (fEnabled["hv_detectors_eq"]) {
3380  // get key to the HV Detectors demand values
3382  if (!fHVDetectorDemandKey->IsValid()) {
3383  err = QString("lemAutoRun: HV Detectors demand key not found.");
3384  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3385  return false;
3386  }
3387 
3388  // get key to the HV Detectors measured values
3390  if (!fHVDetectorMeasuredKey->IsValid()) {
3391  err = QString("lemAutoRun: HV Detectors measured key not found.");
3392  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3393  return false;
3394  }
3395  }
3396 
3397  if (fEnabled["danfysik_spin_rot_eq"]) {
3398  // get key to the Danfysik Spin Rotator input values
3400  if (!fSpinRotMagInputKey->IsValid()) {
3401  err = QString("lemAutoRun: Danfysik Spin Rotator input key not found.");
3402  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3403  return false;
3404  }
3405 
3406  // get key to the Danfysik Spin Rotator output values
3408  if (!fSpinRotMagOutputKey->IsValid()) {
3409  err = QString("lemAutoRun: Danfysik Spin Rotator output key not found.");
3410  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3411  return false;
3412  }
3413  }
3414 
3415  if (fEnabled["danfysik_eq"]) {
3416  // get key to the Danfysik input values
3418  if (!fDanfysikInputKey->IsValid()) {
3419  err = QString("lemAutoRun: Danfysik input key not found.");
3420  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3421  return false;
3422  }
3423 
3424  // get key to the Danfysik output values
3426  if (!fDanfysikOutputKey->IsValid()) {
3427  err = QString("lemAutoRun: Danfysik output key not found.");
3428  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3429  return false;
3430  }
3431  }
3432 
3433  if (fEnabled["wew_eq"]) {
3434  // get key to the WEW output values
3435  fWEWOutputKey = new PKey(fExp, fWEWOutputPath);
3436  if (!fWEWOutputKey->IsValid()) {
3437  err = QString("lemAutoRun: WEW output key not found.");
3438  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3439  return false;
3440  }
3441 
3442  // get key to the WEW input values
3443  fWEWInputKey = new PKey(fExp, fWEWInputPath);
3444  if (!fWEWInputKey->IsValid()) {
3445  err = QString("lemAutoRun: WEW input key not found.");
3446  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3447  return false;
3448  }
3449  }
3450 
3451  if (fEnabled["magnet_field_info"]) {
3452  // get key to the magnetic field parameters key of the WEW
3453  fMagFieldKey = new PKey(fExp, fMagFieldPath);
3454  if (!fMagFieldKey->IsValid()) {
3455  err = QString("lemAutoRun: magnetic field value key not found.");
3456  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3457  return false;
3458  }
3459  }
3460 
3461  if (fEnabled["tfl_eq"]) {
3462  // get key to TFL input
3463  fTflInputKey = new PKey(fExp, fTflInputPath);
3464  if (!fTflInputKey->IsValid()) {
3465  err = QString("lemAutoRun: tfl input key not found.");
3466  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3467  return false;
3468  }
3469 
3470  // get key to TFL output
3471  fTflOutputKey = new PKey(fExp, fTflOutputPath);
3472  if (!fTflOutputKey->IsValid()) {
3473  err = QString("lemAutoRun: tfl output key not found.");
3474  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3475  return false;
3476  }
3477  }
3478 
3479  if (fEnabled["sample_eq"]) {
3480  // get key to the ctrl channel of the sample cryo LS340
3482  if (!fSampleCtrlChKey->IsValid()) {
3483  err = QString("lemAutoRun: sample cryo LS340 ctrl channel key not found.");
3484  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3485  return false;
3486  }
3487  // check if the ctrl channel is valid
3488  char ctrl_ch[4];
3489  size = sizeof(ctrl_ch);
3490  fSampleCtrlChKey->GetData(ctrl_ch, &size, TID_STRING);
3491  if (strstr(ctrl_ch, "A")) {
3493  } else if (strstr(ctrl_ch, "B")) {
3495  } else { // neither 'A' or 'B', set it to 'A'
3496  err = QString("lemAutoRun: sample cryo LS340 ctrl channel neither 'A' or 'B'. Needs to be fixed first!");
3497  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3498  return false;
3499  }
3500 
3501  // get key to the channel assignment of the sample cryo LS340
3503  if (!fSampleChannelKey->IsValid()) {
3504  err = QString("lemAutoRun: sample cryo LS340 channel assignment key not found.");
3505  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3506  return false;
3507  }
3508 
3509  // get key to the sensor type assignment of the sample cryo LS340
3511  if (!fSampleSensorTypeKey->IsValid()) {
3512  err = QString("lemAutoRun: sample cryo LS340 sensor type assignment key not found.");
3513  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3514  return false;
3515  }
3516 
3517  // get key to the sample cryo input values
3518  fSampleInputKey = new PKey(fExp, fSampleInputPath);
3519  if (!fSampleInputKey->IsValid()) {
3520  err = QString("lemAutoRun: sample cryo input key not found.");
3521  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3522  return false;
3523  }
3524  // hotlink input variables
3525  size = sizeof(fSampleInput);
3526  status = fSampleInputKey->HotLink(&fSampleInput, size, MODE_READ, NULL, NULL);
3527  if (status != DB_SUCCESS) {
3528  err = QString("lemAutoRun: Couldn't hotlink sample input variables.");
3529  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3530  return false;
3531  }
3532 
3533  // get key to the sample cryo output values
3535  if (!fSampleOutputKey->IsValid()) {
3536  err = QString("lemAutoRun: sample cryo output key not found.");
3537  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3538  return false;
3539  }
3540  // hotlink output variables
3541  size = sizeof(fSampleOutput);
3542  status = fSampleOutputKey->HotLink(&fSampleOutput, size, MODE_READ, NULL, NULL);
3543  if (status != DB_SUCCESS) {
3544  err = QString("lemAutoRun: Couldn't hotlink sample output variables.");
3545  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3546  return false;
3547  }
3548  // get key to the sample raw voltages
3550  if (!fSampleRawVoltageKey->IsValid()) {
3551  err = QString("lemAutoRun: sample cryo 'raw voltage key' key not found.");
3552  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3553  return false;
3554  }
3555  }
3556 
3557  if (fEnabled["omega_scfe"]) {
3558  // get key to the sample oven omega input values
3560  if (!fSampleOvenOmegaInputKey->IsValid()) {
3561  err = QString("lemAutoRun: sample oven omega output key not found.");
3562  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3563  return false;
3564  }
3565  // hotlink input variables
3566  size = sizeof(fSampleOvenOmegaInput);
3567  status = fSampleOvenOmegaInputKey->HotLink(&fSampleOvenOmegaInput, size, MODE_READ, NULL, NULL);
3568  if (status != DB_SUCCESS) {
3569  err = QString("lemAutoRun: Couldn't hotlink sample oven omega input variables.");
3570  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3571  return false;
3572  }
3573 
3574  // get key to the sample oven omega output values
3576  if (!fSampleOvenOmegaOutputKey->IsValid()) {
3577  err = QString("lemAutoRun: sample oven omega output key not found.");
3578  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3579  return false;
3580  }
3581  // hotlink input variables
3582  size = sizeof(fSampleOvenOmegaOutput);
3583  status = fSampleOvenOmegaOutputKey->HotLink(&fSampleOvenOmegaOutput, size, MODE_READ, NULL, NULL);
3584  if (status != DB_SUCCESS) {
3585  err = QString("lemAutoRun: Couldn't hotlink sample oven omega output variables.");
3586  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3587  return false;
3588  }
3589  }
3590 
3591  if (fEnabled["lemvac_scfe"]) {
3592  // get key to the lemvac input values
3593  fLemvacInputKey = new PKey(fExp, fLemvacInputPath);
3594  if (!fLemvacInputKey->IsValid()) {
3595  err = QString("lemAutoRun: lemvac input key not found.");
3596  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3597  return false;
3598  }
3599 
3600  // get key to the lemvac output values
3602  if (!fLemvacOutputKey->IsValid()) {
3603  err = QString("lemAutoRun: lemvac output key not found.");
3604  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3605  return false;
3606  }
3607  }
3608 
3609  if (fEnabled["fom_eq"]) {
3610  // get key to the FOM input values
3611  fFOMInputKey = new PKey(fExp, fFOMInputPath);
3612  if (!fFOMInputKey->IsValid()) {
3613  err = QString("lemAutoRun: FOM input key not found.");
3614  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3615  return false;
3616  }
3617 
3618  // get key to the FOM output values
3619  fFOMOutputKey = new PKey(fExp, fFOMOutputPath);
3620  if (!fFOMOutputKey->IsValid()) {
3621  err = QString("lemAutoRun: FOM output key not found.");
3622  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3623  return false;
3624  }
3625  }
3626 
3627  if (fEnabled["beamline_eq"]) {
3628  // get key to the Beamline demand values
3630  if (!fBeamlineDemandKey->IsValid()) {
3631  err = QString("lemAutoRun: Beamline demand key not found.");
3632  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3633  return false;
3634  }
3635  }
3636 
3637  if (fEnabled["mag_param_wew_odb"]) {
3638  // get key to the WEW calibration (A->G)
3639  fMagParamWewKey = new PKey(fExp, fMagParamWewPath);
3640  if (!fMagParamWewKey->IsValid()) {
3641  err = QString("lemAutoRun: Mag. Param. WEW calibration key not found.");
3642  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3643  return false;
3644  }
3645  // get the calibration parameters
3646  size = sizeof(fMagParamWew);
3647  fMagParamWewKey->GetData(&fMagParamWew, &size, TID_FLOAT);
3648  if (fMagParamWew[1] == 0.0) { // the linear part in the calibration musn't be zero!!
3649  err = QString("lemAutoRun: Mag. Param. WEW calibration with linear part == 0! Something is wrong!!");
3650  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3651  return false;
3652  }
3653  }
3654 
3655  if (fEnabled["mag_param_bpar_odb"]) {
3656  // get key to the Bpar calibration (A->G)
3658  if (!fMagParamBparKey->IsValid()) {
3659  err = QString("lemAutoRun: Mag. Param. Bpar calibration key not found.");
3660  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3661  return false;
3662  }
3663  // get the calibration parameters
3664  size = sizeof(fMagParamBpar);
3665  fMagParamBparKey->GetData(&fMagParamBpar, &size, TID_FLOAT);
3666  if (fMagParamBpar[1] == 0.0) { // the linear part in the calibration musn't be zero!!
3667  err = QString("lemAutoRun: Mag. Param. Bpar calibration with linear part == 0! Something is wrong!!");
3668  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3669  return false;
3670  }
3671  }
3672 
3673  if (fEnabled["setup_sample_odb"]) {
3674  // get the sample setup enabled flag
3676  if (!fSetupSampleEnabledKey->IsValid()) {
3677  err = QString("lemAutoRun: Sample setup enabled key not found.");
3678  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3679  return false;
3680  }
3681  int ival = -1;
3682  size = sizeof(ival);
3683  fSetupSampleEnabledKey->GetData(&ival, &size, TID_BOOL);
3684  if (ival == 1)
3685  fSetupSampleEnabled = true;
3686  }
3687 
3688  if (fEnabled["setup_wew_odb"]) {
3689  // get the WEW setup enabled flag
3691  if (!fSetupWewEnabledKey->IsValid()) {
3692  err = QString("lemAutoRun: WEW setup enabled key not found.");
3693  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3694  return false;
3695  }
3696  int ival = -1;
3697  size = sizeof(ival);
3698  fSetupWewEnabledKey->GetData(&ival, &size, TID_BOOL);
3699  if (ival == 1)
3700  fSetupWewEnabled = true;
3701  }
3702 
3703  if (fEnabled["setup_bpar_odb"]) {
3704  // get the Bpar setup enabled flag
3706  if (!fSetupBparEnabledKey->IsValid()) {
3707  err = QString("lemAutoRun: Bpar setup enabled key not found.");
3708  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3709  return false;
3710  }
3711  int ival = -1;
3712  size = sizeof(ival);
3713  fSetupBparEnabledKey->GetData(&ival, &size, TID_BOOL);
3714  if (ival == 1)
3715  fSetupBparEnabled = true;
3716  }
3717 
3718  // create RawVoltage dump file name
3719  if (fEnabled["sample_eq"]) {
3720  fDumpFileName = "RawVoltageOutput-";
3721  char cryoName[NAME_LENGTH];
3722  size = sizeof(cryoName);
3723  if (fEnabled["sample_cryo_info_odb"])
3724  fSampleCryoKey->GetData(cryoName, &size, TID_STRING);
3725  else
3726  strcpy(cryoName, "cryo");
3727  fDumpFileName += cryoName;
3728  fDumpFileName += "-";
3729  QDateTime dt(QDate::currentDate(), QTime::currentTime());
3730  QString dtStr = dt.toString("ddMMyy-hhmm");
3731  fDumpFileName += dtStr + ".dat";
3732  }
3733 
3734  return true;
3735 }
3736 
3737 //**********************************************************************
3738 // GetEnergyLoss
3739 //**********************************************************************
3745 float PLemAutoRun::GetEnergyLoss(float hv_mod)
3746 {
3747  float energy_loss = 0.0;
3748 
3749  if (!fEnabled["energy_loss_param_odb"])
3750  return 0.0;
3751 
3752  if (hv_mod < 20.1) {
3753  for (int i=0; i<NO_ENERGY_LOSS_PARAM; i++)
3754  energy_loss += fEnergyLossParam[i] * powf(hv_mod, i);
3755  } else {
3756  energy_loss = 0.23;
3757  }
3758 
3759  return energy_loss;
3760 }
3761 
3762 //**********************************************************************
3763 // CheckClients
3764 //**********************************************************************
3771 {
3772  if (fIgnoreClients) {
3773  fAnalyzerRunning = true;
3774  fFrontendRunning = true;
3775  fTflFeRunning = true;
3776  fSampleFeRunning = true;
3778  fWEWFeRunning = true;
3779  fDanfysikFeRunning = true;
3780  fHVFeRunning = true;
3781  fLemvacFeRunning = true;
3782  return;
3783  }
3784 
3785  HNDLE subKey;
3786  char str[128];
3787  INT size, status;
3788  QString name;
3789 
3790  fAnalyzerRunning = false;
3791  fFrontendRunning = false;
3792  fTflFeRunning = false;
3793  fSampleFeRunning = false;
3794  fSampleOvenOmegaFeRunning = false;
3795  fWEWFeRunning = false;
3796  fDanfysikFeRunning = false;
3797  fHVFeRunning = false;
3798  fLemvacFeRunning = false;
3799 
3800  for (int i=0; ; i++) {
3801  // check if there is a subkey
3802  if (fClientsKey->EnumSubKey(i, &subKey) == DB_NO_MORE_SUBKEYS)
3803  break;
3804  // get the content of the variable Name from the subkey
3805  size = sizeof(str);
3806  status = db_get_value(fClientsKey->GetHdb(), subKey, "Name", str, &size, TID_STRING, FALSE);
3807  if (status != DB_SUCCESS) {
3808  QString err = QString("Autorun: check clients failure ...");
3809  emit StatusMsg(err);
3810  err = QString("PLemAutoRun::CheckClients(): Couldn't get value from subkey.");
3811  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3812  }
3813  // check if the name is one of the monitored frontends
3814  name = QString(str);
3815  if (name == fAnalyzerName)
3816  fAnalyzerRunning = true;
3817  else if (name == fFrontendName)
3818  fFrontendRunning = true;
3819  else if (name == fTflFeName)
3820  fTflFeRunning = true;
3821  else if (name == fSampleFeName)
3822  fSampleFeRunning = true;
3823  else if (name == fSampleOvenOmegaFeName)
3825  else if (name == fWEWFeName)
3826  fWEWFeRunning = true;
3827  else if (name == fDanfysikFeName)
3828  fDanfysikFeRunning = true;
3829  else if (name == fHVFeName)
3830  fHVFeRunning = true;
3831  else if (name == fLemvacFeName)
3832  fLemvacFeRunning = true;
3833 
3834  // if analyzer_fe is disabled -> running to true
3835  if (!fEnabled["analyzer_fe"])
3836  fAnalyzerRunning = true;
3837  // if vme_fe is disabled -> running to true
3838  if (!fEnabled["vme_fe"])
3839  fFrontendRunning = true;
3840  // if tfl_scfe is disabled -> running to true
3841  if (!fEnabled["tfl_scfe"])
3842  fTflFeRunning = true;
3843  // if sample_scfe is disabled -> running to true
3844  if (!fEnabled["sample_scfe"])
3845  fSampleFeRunning = true;
3846  // if omega_scfe is disabled -> running to true
3847  if (!fEnabled["omega_scfe"])
3849  // if WEW scfe is disabled -> running to true
3850  if (!fEnabled["wew_scfe"])
3851  fWEWFeRunning = true;
3852  // if Danfysik scfe (Bpar) is disabled -> running to true
3853  if (!fEnabled["danfysik_scfe"])
3854  fDanfysikFeRunning = true;
3855  // if FUG handling is disabled, fake the FUG FE to running
3856  if (!fEnabled["fug_scfe"])
3857  fHVFeRunning = true;
3858  // if LEMVAC handling is disabled, fake the FUG FE to running
3859  if (!fEnabled["lemvac_scfe"])
3860  fLemvacFeRunning = true;
3861  }
3862 }
3863 
3864 //**********************************************************************
3865 // CheckMidasAlarms
3866 //**********************************************************************
3870 void PLemAutoRun::CheckMidasAlarms(PAutoRunCmdVector::Iterator iter)
3871 {
3872  if (!fEnabled["alarms_odb"])
3873  return;
3874 
3875  if (fIgnoreAlarms)
3876  return;
3877 
3878  HNDLE subKey;
3879  INT size, status;
3880 
3881  struct {
3882  BOOL active;
3883  INT triggered;
3884  INT type;
3885  INT check_interval;
3886  DWORD checked_last;
3887  char trigger_first[32];
3888  char trigger_last[32];
3889  char condition[256];
3890  char alarm_class[32];
3891  char alarm_msg[80];
3892  } alarmData;
3893 
3894  for (int i=0; ; i++) {
3895  if (fAlarmsKey->EnumSubKey(i, &subKey) == DB_NO_MORE_SUBKEYS)
3896  break;
3897  // get the trigger flag if the current alarm
3898  size = sizeof(alarmData);
3899  status = db_get_record(fAlarmsKey->GetHdb(), subKey, &alarmData, &size, 0);
3900  if (status != DB_SUCCESS) {
3901  QString err = QString("Autorun: check alarms failure ...");
3902  emit StatusMsg(err);
3903  err = QString("PLemAutoRun::CheckMidasAlarms(): Couldn't get value from subkey.");
3904  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
3905  }
3906  if (alarmData.triggered && strstr(alarmData.alarm_class, "Alarm")) { // found an alarm which fired
3907  UpdateWebPage(iter, HTML_ALARM);
3908 
3909  QString err = QString("Autorun: Alarm fired ...");
3910  emit StatusMsg(err);
3911  err = QString("PLemAutoRun::CheckMidasAlarms: Alarm fired! ")+
3912  QString(" msg: %1 ").arg(alarmData.alarm_msg)+
3913  QString(" Error too severe, will stop.");
3914  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
3916  QCoreApplication::exit(0);
3917  exit(0);
3918  }
3919  }
3920 }
3921 
3922 //**********************************************************************
3923 // LakeShoreTime
3924 //**********************************************************************
3936 {
3937  int status;
3938  int imonth, day, year, hour, min, sec, msec;
3939  double days = 0, result;
3940  int month[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
3941 
3942  // extract date and time values
3943  status = sscanf(str, "%d,%d,%d,%d,%d,%d,%d", &imonth, &day, &year, &hour, &min, &sec, &msec);
3944  if (status != 7) { // str does not have the proper format
3945  return -1.0;
3946  }
3947 
3948  // check for leap year
3949  for (int i=2006; i<year; i++) {
3950  if ( ((i % 4) == 0 && (i % 100) != 0) || (i % 400) == 0 )
3951  days = days + 366;
3952  else
3953  days = days + 365;
3954  }
3955  if ( ((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0 ) month[1] = 29;
3956 
3957  for (int i = 1; i<imonth; i++ ) days = days + month[i-1];
3958 
3959  days = days + day;
3960  result = (double)days * 86400.0 + (double)hour * 3600.0 + (double)min * 60.0 +
3961  (double)sec + (double)msec / 1000.0;
3962 
3963  return result;
3964 }
3965 
3966 //**********************************************************************
3967 // SampleTempTrend
3968 //**********************************************************************
3993 {
3994  double x[SAMPLE_TEMP_HISTO_MAX];
3995  double s = 0.0;
3996  double sx = 0.0;
3997  double sxx = 0.0;
3998  double sxxx = 0.0;
3999  double sxxxx = 0.0;
4000  double sT = 0.0;
4001  double sh = 0.0;
4002  double sf = 0.0;
4003  double sp = 0.0;
4004  double sxT = 0.0;
4005  double sxh = 0.0;
4006  double sxf = 0.0;
4007  double sxp = 0.0;
4008  double sxxT = 0.0;
4009  double sxxh = 0.0;
4010  double sxxf = 0.0;
4011  double sxxp = 0.0;
4012 
4013  double help = 0.0;
4014  double xx = 0.0;
4015 
4016  if ( fSampleHistoNoEntries < 4 )
4017  return;
4018 
4019  for (int i=0; i<fSampleHistoNoEntries; i++) {
4020  s += 1.0;
4021  sx += fSampleTempHisto[i].datetime;
4022  }
4023 
4024  sx = sx / s; // average time
4026  // to calculate the time difference between the current and the previous temp
4027  // one needs to be careful since the data are stored in a ring buffer.
4028  // The current counter 'fSampleHistoPos' is always one count ahead!
4029  switch (fSampleHistoPos) {
4030  case 0: // current counter at the begining
4033  break;
4034  case 1: // current counter at the 2nd entry
4037  break;
4038  default:
4041  break;
4042  }
4043 
4044  for (int i=0; i<fSampleHistoNoEntries; i++)
4045  x[i] = fSampleTempHisto[i].datetime - sx;
4046 
4047  sx = 0.0;
4048  for (int i=0; i<fSampleHistoNoEntries; i++) {
4049  xx = x[i] * x[i];
4050  sx += x[i];
4051  sxx += xx;
4052  sxxx += xx * x[i];
4053  sxxxx += xx * xx;
4054  sT += fSampleTempHisto[i].measured_T;
4055  sh += fSampleTempHisto[i].heater;
4056  sf += fSampleTempHisto[i].flow;
4057  sp += fSampleTempHisto[i].pressure;
4058  sxT += x[i] * fSampleTempHisto[i].measured_T;
4059  sxh += x[i] * fSampleTempHisto[i].heater;
4060  sxf += x[i] * fSampleTempHisto[i].flow;
4061  sxp += x[i] * fSampleTempHisto[i].pressure;
4062  sxxT += xx * fSampleTempHisto[i].measured_T;
4063  sxxh += xx * fSampleTempHisto[i].heater;
4064  sxxf += xx * fSampleTempHisto[i].flow;
4065  sxxp += xx * fSampleTempHisto[i].pressure;
4066 
4067  }
4068 
4069  double denominator = -s * sxx * sxxxx + s * sxxx * sxxx + sx * sx * sxxxx
4070  - 2.0 * sxxx * sx * sxx + sxx * sxx * sxx;
4071 
4072  if ( fabs( denominator ) > 0.0 ) {
4073  fSampleTempAverage.measured_T = -(sx * sxxx * sxxT - sx * sxT * sxxxx + sxx * sxxx * sxT - sxx * sxx * sxxT +
4074  sT * sxx * sxxxx - sT * sxxx * sxxx) / denominator;
4075  fSampleTempAverage.heater = -(sx * sxxx * sxxh - sx * sxh * sxxxx + sxx * sxxx * sxh - sxx * sxx * sxxh +
4076  sh * sxx * sxxxx - sh * sxxx * sxxx) / denominator;
4077  fSampleTempAverage.flow = -(sx * sxxx * sxxf - sx * sxf * sxxxx + sxx * sxxx * sxf - sxx * sxx * sxxf +
4078  sf * sxx * sxxxx - sf * sxxx * sxxx) / denominator;
4079  fSampleTempAverage.pressure = -(sx * sxxx * sxxp - sx * sxp * sxxxx + sxx * sxxx * sxp - sxx * sxx * sxxp +
4080  sp * sxx * sxxxx - sp * sxxx * sxxx) / denominator;
4081  fSampleTempTrend.measured_T = -(- s * sxxx * sxxT + s * sxT * sxxxx - sxT * sxx * sxx + sxx * sx * sxxT +
4082  sxx * sxxx * sT - sx * sT * sxxxx) / denominator;
4083  fSampleTempTrend.heater = -(- s * sxxx * sxxh + s * sxh * sxxxx - sxh * sxx * sxx + sxx * sx * sxxh +
4084  sxx * sxxx * sh - sx * sh * sxxxx) / denominator;
4085  fSampleTempTrend.flow = -(- s * sxxx * sxxf + s * sxf * sxxxx - sxf * sxx * sxx + sxx * sx * sxxf +
4086  sxx * sxxx * sf - sx * sf * sxxxx) / denominator;
4087  fSampleTempTrend.pressure = -(- s * sxxx * sxxp + s * sxp * sxxxx - sxp * sxx * sxx + sxx * sx * sxxp +
4088  sxx * sxxx * sp - sx * sp * sxxxx) / denominator;
4089  fSampleTempSecond.measured_T = (- sxxx * sx * sT + sx * sx * sxxT + s * sxxx * sxT - s * sxx * sxxT -
4090  sxx * sx * sxT + sxx * sxx * sT) / denominator;
4091  fSampleTempSecond.heater = (- sxxx * sx * sh + sx * sx * sxxh + s * sxxx * sxh - s * sxx * sxxh -
4092  sxx * sx * sxh + sxx * sxx * sh) / denominator;
4093  fSampleTempSecond.flow = (- sxxx * sx * sf + sx * sx * sxxf + s * sxxx * sxf - s * sxx * sxxf -
4094  sxx * sx * sxf + sxx * sxx * sf) / denominator;
4095  fSampleTempSecond.pressure = (- sxxx * sx * sp + sx * sx * sxxp + s * sxxx * sxp - s * sxx * sxxp -
4096  sxx * sx * sxp + sxx * sxx * sp) / denominator;
4097 
4098  }
4099 
4101  fSampleTempRmsqd.heater = 0.0;
4102  fSampleTempRmsqd.flow = 0.0;
4103  fSampleTempRmsqd.pressure = 0.0;
4104  for (int i=0; i<fSampleHistoNoEntries; i++) {
4105  xx = x[i] * x[i];
4108  fSampleTempRmsqd.measured_T += help * help;
4110  fSampleTempSecond.heater * xx);
4111  fSampleTempRmsqd.heater += help * help;
4113  fSampleTempSecond.flow * xx);
4114  fSampleTempRmsqd.flow += help * help;
4117  fSampleTempRmsqd.pressure += help * help;
4118  }
4123 
4124  if (fDebug) {
4125  std::cout << std::endl << "SampleTempTrend:";
4126  std::cout << std::endl << " fSampleTempAverage (T, heater, flow, pressure):";
4127  std::cout << " " << fSampleTempAverage.measured_T;
4128  std::cout << ", " << fSampleTempAverage.heater;
4129  std::cout << ", " << fSampleTempAverage.flow;
4130  std::cout << ", " << fSampleTempAverage.pressure;
4131  std::cout << std::endl << " fSampleTempTrend (T, heater, flow, pressure):";
4132  std::cout << " " << fSampleTempTrend.measured_T;
4133  std::cout << ", " << fSampleTempTrend.heater;
4134  std::cout << ", " << fSampleTempTrend.flow;
4135  std::cout << ", " << fSampleTempTrend.pressure;
4136  std::cout << std::endl << " fSampleTempSecond (T, heater, flow, pressure):";
4137  std::cout << " " << fSampleTempSecond.measured_T;
4138  std::cout << ", " << fSampleTempSecond.heater;
4139  std::cout << ", " << fSampleTempSecond.flow;
4140  std::cout << ", " << fSampleTempSecond.pressure;
4141  std::cout << std::endl << " fSampleTempRmsqd (T, heater, flow, pressure):";
4142  std::cout << " " << fSampleTempRmsqd.measured_T;
4143  std::cout << ", " << fSampleTempRmsqd.heater;
4144  std::cout << ", " << fSampleTempRmsqd.flow;
4145  std::cout << ", " << fSampleTempRmsqd.pressure;
4146  std::cout << std::endl;
4147  }
4148 
4149 }
4150 
4151 //**********************************************************************
4152 // SampleTempPrefHeaterOutput
4153 //**********************************************************************
4164 {
4165  float value = 0;
4166  int hr = (int)heaterRange;
4167 
4168  if (fDebug)
4169  std::cout << std::endl << "in SampleTempPrefHeaterOutput: hr = " << hr;
4170 
4171  switch (hr) {
4172  case 3:
4173  value = 50.0;
4174  break;
4175  case 4:
4176  value = 40.0;
4177  break;
4178  case 5:
4179  value = 10.0 + 0.04 * fSampleOutput[LS336_OUTPUT_SETPOINT];
4180  break;
4181  default:
4182  break;
4183  }
4184 
4185  return value;
4186 }
4187 
4188 //**********************************************************************
4189 // SampleTempAdjustFlow
4190 //**********************************************************************
4195 {
4196  float change = 1.0;
4197  float value;
4198  float p_heat, d_heat, pref_heat;
4199 
4200  if (fDebug)
4201  std::cout << std::endl << "in SampleTempAdjustFlow ...";
4202 
4203  p_heat = -(fBHFlowPHeat0 + fBHFlowPHeat1 *
4205 
4206  d_heat = fBHFlowDHeat;
4208  change = exp( p_heat * (( fSampleInput[LS336_INPUT_HEATER] - pref_heat ) + d_heat * fSampleTempTrend.heater ));
4209 
4211 
4212  if (fDebug) {
4213  std::cout << std::endl << "--------------------";
4214  std::cout << std::endl << "SampleTempAdjustFlow: p0 = " << fBHFlowPHeat0 << ", p1 = " << fBHFlowPHeat1;
4215  std::cout << std::endl << "SampleTempAdjustFlow: p_heat = " << p_heat << ", d_heat = " << d_heat << ", pref_heat = " << pref_heat;
4216  std::cout << std::endl << "SampleTempAdjustFlow: heater = " << fSampleInput[LS336_INPUT_HEATER] << ", dH/dt = " << fSampleTempTrend.heater;
4217  std::cout << std::endl << "change = " << change;
4218  std::cout << std::endl << "SampleTempAdjustFlow: new flow value = " << value;
4219  }
4220 
4221  if ( value > fBHMaxFlow ) value = fBHMaxFlow;
4222  if ( value < fBHMinFlow ) value = fBHMinFlow;
4223 
4224  fSampleOutputKey->SetDataIndex(&value, fSampleBhOdbOffsetOutput+BH_OUTPUT_FLOW, TID_FLOAT);
4225 
4226  // also have a look at the needle valve
4227 
4229 }
4230 
4231 //**********************************************************************
4232 // SampleTempStable
4233 //**********************************************************************
4238 {
4240 
4241  if (maxdiff < fAbsMaxTempDiff) {
4242  maxdiff = fAbsMaxTempDiff;
4243  }
4244 
4245  if (fDebug)
4246  std::cout << std::endl << "in SampleTempStable. maxdiff = " << maxdiff;
4247 
4250  (fSampleTempRmsqd.measured_T < maxdiff) &&
4253  if (fDebug)
4254  std::cout << std::endl << "in SampleTempStable. stability reached.";
4255  return true;
4256  }
4257 
4258  return false;
4259 }
4260 
4261 //**********************************************************************
4262 // SampleTempConsiderNeedleValve
4263 //**********************************************************************
4269 {
4270  float value = 1.0e6;
4271  float modus = 0.0;
4272  float bh_valve;
4273  float needle_valve;
4274  int size;
4275  float demand_flow;
4276 
4277  if (fDebug)
4278  std::cout << std::endl << "in SampleTempConsiderNeedleValve ...";
4279 
4280  // check the modus of the needle valve.
4281  size = sizeof(modus);
4282  fTflOutputKey->GetDataIndex(&modus, &size, SM_MODUS_NEEDLEVALVE, TID_FLOAT);
4283 
4284  if (fNeedleValveInUse && modus > 1.0) { // only set the needle valve when it is in_use and in auto-modus
4285  size = sizeof(bh_valve);
4286  fSampleInputKey->GetDataIndex(&bh_valve, &size, fSampleBhOdbOffsetInput + BH_INPUT_VALVE,
4287  TID_FLOAT);
4288 
4289  size = sizeof(needle_valve);
4290  fTflInputKey->GetDataIndex(&needle_valve, &size, SM_INPUT_NEEDLEVALVE, TID_FLOAT);
4291  if (bh_valve > 0.9) { // almost open bronkhorst needle valve
4292  size = sizeof(demand_flow);
4293  fSampleOutputKey->GetDataIndex(&demand_flow, &size,
4295  TID_FLOAT);
4296  if (demand_flow > 2.0*fSampleTempAverage.flow) // measured flow far off demand flow -> open transferline needle valve quickly
4297  value = needle_valve + fPrefNeedleValveAbsStep;
4298  else // measured flow not too far off demand flow -> open transferline needle valve more gradually
4299  value = ( 1.0 + fPrefNeedleValveRelStep ) * needle_valve;
4300  }
4301 
4302  // pressure on the cryo exhaust too high -> close transferline needle valve a bit
4303  if (fSampleTempAverage.pressure > 0.8)
4304  value = ( 1.0 - fPrefNeedleValveRelStep ) * needle_valve;
4305 
4306  if (fDebug)
4307  std::cout << std::endl << "in SampleTempConsiderNeedleValve: value = " << value;
4308 
4309  // value still 1.0e6, i.e. nothing to be done, get out
4310  if (value == 1.0e6)
4311  return;
4312 
4313  // something changed, but lets check if value is out of range
4314  if (value > 99.0)
4315  value = 99.0;
4316 
4317  if (value < fPrefNeedleValveCof_4_0)
4318  value = fPrefNeedleValveCof_4_0;
4319 
4320  fTflOutputKey->SetDataIndex(&value, SM_OUTPUT_NEEDLEVALVE, TID_FLOAT);
4321  }
4322 }
4323 
4324 //**********************************************************************
4325 // SampleTempSetNeedleValve
4326 //**********************************************************************
4333 {
4334  float modus = 0.0;
4335  float tempSP = 0.0;
4336  int size = sizeof(float);
4337 
4338  if (!fEnabled["tfl_eq"] || !fEnabled["sample_eq"]) {
4339  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"]);
4340  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
4341  return;
4342  }
4343 
4344  // get demand temperature
4345  fSampleOutputKey->GetDataIndex(&tempSP, &size, LS336_OUTPUT_SETPOINT, TID_FLOAT);
4346 
4347  // check the modus of the needlevalve.
4348  size = sizeof(float);
4349  fTflOutputKey->GetDataIndex(&modus, &size, SM_MODUS_NEEDLEVALVE, TID_FLOAT);
4350 
4351  // make sure that value is within proper bounds
4352  if (value > 100.0)
4353  value = 98.0;
4354  if (value < 0.0)
4355  value = 0.0;
4356 
4357  // only set the needle valve when it is in_use and in auto-modus
4358  if (fNeedleValveInUse && modus > 1.0) {
4359  if (tempSP < 5.0) // do not tweak NV for demand T<5K
4360  value = fPrefNeedleValveCof_1_0;
4361  fTflOutputKey->SetDataIndex((void *)&value, SM_OUTPUT_NEEDLEVALVE, TID_FLOAT);
4362  }
4363 }
4364 
4365 
4366 //**********************************************************************
4367 // SampleTempConsiderFlow
4368 //**********************************************************************
4374 {
4375  float change = 1.0;
4376  float value;
4377  float demand;
4378  int size = sizeof(float);
4379 
4380  if (fDebug) {
4381  cm_msg(MDEBUG, "SampleTempConsiderFlow", "in SampleTempConsiderFlow ...");
4382  cm_yield(0);
4383  }
4384 
4385  // if at large flow do nothing. Only used if no ramping while cooling
4386  if (fLargeFlow)
4387  return;
4388 
4389  fSampleOutputKey->GetDataIndex(&demand, &size, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW,
4390  TID_FLOAT);
4391 
4392  // if the demand value < fFlowLowestFlowToConsider (given in the XML startup file) do nothing
4393  if ( demand < fFlowLowestFlowToConsider ) {
4394  cm_msg(MINFO,"SampleTempConsiderFlow", "SampleTempConsiderFlow, demand = %e", demand);
4395  cm_yield(0);
4396  return;
4397  }
4398 
4399  // if the real flow is far off from the demand value do nothing
4400  if ( fabs( fSampleTempAverage.flow - demand - 150.0 ) / demand > fFlowMaxRelFlowDiffToConsider ) { // the -150 are the typical BH offset at low flow values
4401  cm_msg(MINFO,"SampleTempConsiderFlow",
4402  "SampleTempConsiderFlow: skipped consideration, demand = %e, present flow = %e",
4403  demand, fSampleTempAverage.flow);
4404  cm_yield(0);
4405  return;
4406  }
4407 
4408  // flow is relatively close to the demand value -> only tweak it
4409  if ((fSampleTempAverage.measured_T < fSampleInput[LS336_INPUT_SETPOINT]) && // it is too cold
4410  (fSampleTempTrend.measured_T < 0.05) && // and it is not warming
4411  (fSampleTempSecond.measured_T < 0.005) && // and it is not going to warm
4412  (fSampleTempAverage.heater > fHeaterMax)) // while the heater is doing its utmost
4413  change -= fFlowFactor; // then DECREASE flow
4414 
4415  if ((fSampleTempAverage.measured_T > fSampleInput[LS336_INPUT_SETPOINT]) && // it is too warm
4416  (fSampleTempTrend.measured_T > -0.05) && // and it is not cooling
4417  (fSampleTempSecond.measured_T > -0.005) && // and it is not going to cool
4418  (fSampleTempAverage.heater < fHeaterMin)) // while the heater is doing nothing
4419  change += fFlowFactor; // then INCREASE flow
4420 
4421  if (fabs( change - 1.0 ) > 0.001 ) { // change flow
4423 
4424  // try to learn from this consideration of the flow; fBHFlowTemp is used to estimate
4425  // the initial flow for a given temperature: flow = fBHFlowTemp/(T+fBHFlowTempOffset) + fBHFlowOffset
4426  fBHFlowTemp = change * fBHFlowTemp;
4427 
4428  if ( value > fBHMaxFlow )
4429  value = fBHMaxFlow;
4430 
4431  if ( value < fBHMinFlow )
4432  value = fBHMinFlow;
4433 
4434  cm_msg(MDEBUG, "SampleTempConsiderFlow", "SampleTempConsiderFlow: new flow=%f", value);
4435  cm_yield(0);
4436 
4437  fSampleOutputKey->SetDataIndex(&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
4438  }
4439 
4440  if (fDebug) {
4441  cm_msg(MDEBUG, "SampleTempConsiderFlow", "SampleTempConsiderFlow: new flow value = %f", fSampleTempAverage.flow * change);
4442  cm_msg(MDEBUG, "SampleTempConsiderFlow", "SampleTempConsiderFlow: (change = %f, fSampleTempAverage.flow = %f)", change, fSampleTempAverage.flow);
4443  cm_yield(0);
4444  std::cout << std::endl << "SampleTempConsiderFlow: new flow value = " << fSampleTempAverage.flow * change;
4445  std::cout << " (change = " << change << ", fSampleTempAverage.flow = " << fSampleTempAverage.flow << ")";
4446  }
4447 }
4448 
4449 //**********************************************************************
4450 // CheckTempStability
4451 //**********************************************************************
4456 {
4457  QString err;
4458 
4459  if (!fEnabled["sample_eq"])
4460  return;
4461 
4462  if (!fSampleFeRunning)
4463  return;
4464 
4465  static int tempDeviationToHighCounter = 0; // counter needed to eliminate error messages due to readback errors
4466 
4467  if (fDebug)
4468  std::cout << std::endl << "in CheckTempStability ...";
4469 
4470  if ((fSampleInput[fSampleCtrlCh] <= 0.0) && !fIgnoreAlarms) { // CF1 or CF2 temperature <= 0, i.e. frontend error
4471  err = QString("PLemAutoRun::CheckTempStability(): CF1 readback = %1. ").arg(fSampleInput[fSampleCtrlCh]);
4472  err += QString("Does not make any sense!");
4473  emit ErrorMsg(1, 0, LAR_LS_INPUT_NONSENSE, -1, err);
4474  return;
4475  }
4476 
4477  if (!fSampleTempRegulation) { // no temperature adjustment wanted
4479  if (!fSampleTempUnstable) { // to reduce the number of error messages
4480  fSampleTempUnstable = true;
4481  err = QString("PLemAutoRun::CheckTempStability(): | Setpoint=%1 ").arg(fSampleInput[LS336_INPUT_SETPOINT]);
4482  err += QString("- CF1=%1 | > %2").arg(fSampleInput[fSampleCtrlCh]).arg(fSampleTempAccuracy);
4483  emit ErrorMsg(1, 0, LAR_LS_TEMP_NOT_STABLE, -1, err);
4484  }
4485  } else {
4486  fSampleTempUnstable = false;
4487  }
4488  return;
4489  }
4490 
4491  // feed history ring buffer ----------------------------------------------
4492  // get LS340/LS336 date and time
4493  fSampleHistoTime = ss_time();
4495  fSampleHistoLastTime = fSampleHistoTime; // keep as previous time for next time
4496  else
4497  return; // no new timestamp available, therefore return
4498 
4499  // update counter of how many elements are present in the history buffer
4502  // feed data to the history buffer
4509  // increment history buffer counter modulo its length
4511 
4512  QString datetime;
4513  if (fDebug) {
4514  std::cout << std::endl << "Timedate History: " << fSampleHistoPos << std::endl;
4515  for (int i=0; i<SAMPLE_TEMP_HISTO_MAX; i++) {
4516  if (i>fSampleHistoNoEntries)
4517  break;
4518  datetime.setNum(fSampleTempHisto[i].datetime, 'f', 2);
4519  std::cout << datetime.toLatin1().data() << ", ";
4520  }
4521  std::cout << std::endl;
4522  std::cout << std::endl << "Temperature History: " << fSampleHistoPos << std::endl;
4523  for (int i=0; i<SAMPLE_TEMP_HISTO_MAX; i++) {
4524  if (i>fSampleHistoNoEntries)
4525  break;
4526  std::cout << fSampleTempHisto[i].measured_T << ", ";
4527  }
4528  std::cout << std::endl;
4529  }
4530 
4531  // calculate trend parameters
4532  SampleTempTrend();
4533 
4534  // check if temperature within the required boundaries
4536  tempDeviationToHighCounter++;
4537  if (!fSampleTempUnstable && (tempDeviationToHighCounter > 5)) { // to reduce the number of error messages
4538  fSampleTempUnstable = true;
4539  err = QString("PLemAutoRun::CheckTempStability(): | Setpoint=%1 ").arg(fSampleInput[LS336_INPUT_SETPOINT]);
4540  err += QString("- CF1=%1 | > %2").arg(fSampleInput[fSampleCtrlCh]).arg(fSampleTempAccuracy);
4541  emit ErrorMsg(1, 0, LAR_LS_TEMP_NOT_STABLE, -1, err);
4542  }
4543  } else {
4544  tempDeviationToHighCounter = 0;
4545  }
4546 }
4547 
4548 //**********************************************************************
4549 // CheckTempStabilityOvenOmega
4550 //**********************************************************************
4555 {
4556  QString err;
4557 
4558  if (!fEnabled["sample_eq"])
4559  return;
4560 
4562  return;
4563 
4564  fSampleTempAccuracy = 2.0; // the omega controller has an accuracy of 1°C only!!
4566  if (!fSampleTempUnstable) { // to reduce the number of error messages
4567  fSampleTempUnstable = true;
4568  err = QString("PLemAutoRun::CheckTempStabilityOvenOmega(): | Setpoint=%1 ").arg(fSampleOvenOmegaOutput[OMEGA_OVEN_OUTPUT_SETPOINT]);
4569  err += QString("- Temp.Measured=%1 | > %2").arg(fSampleOvenOmegaInput[OMEGA_OVEN_INPUT_TEMP]).arg(fSampleTempAccuracy);
4570  emit ErrorMsg(1, 0, LAR_LS_TEMP_NOT_STABLE, -1, err);
4571  }
4572  } else {
4573  fSampleTempUnstable = false;
4574  }
4575 }
4576 
4577 //**********************************************************************
4578 // UpdateWebPage
4579 //**********************************************************************
4597 void PLemAutoRun::UpdateWebPage(PAutoRunCmdVector::Iterator currentIter, int tag, int errLineNo, QString errMsg)
4598 {
4599  PAutoRunCmdVector::Iterator iter;
4600  QFile file(fXMLAutoRunHTML);
4601 
4602  // open HTML file
4603  if ( !file.open( QIODevice::WriteOnly ) ) { // couldn't open file
4604  QString err = QString("PLemAutoRun::UpdateWebPage(): Couldn't open %1").arg(fXMLAutoRunHTML);
4605  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
4606  return;
4607  }
4608 
4609  // write HTML code
4610  QTextStream stream( &file );
4611 
4612  // write HTML start tag
4613  stream << "<html>" << Qt::endl;
4614 
4615  // write header
4616  stream << " <head>" << Qt::endl;
4617  stream << "<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />" << Qt::endl;
4618  stream << " <title>LEM Autorun Parameter Page</title>" << Qt::endl;
4619  stream << " <meta http-equiv=\"Refresh\" content=\"30\">" << Qt::endl;
4620  stream << " <script type=\"text/javascript\" src=\"mhttpd.js\"></script>" << Qt::endl;
4621  stream << " <script type=\"text/javascript\" src=\"midas.js\"></script>" << Qt::endl;
4622  stream << " <script type=\"text/javascript\" src=\"obsolete.js\"></script>" << Qt::endl;
4623  stream << " <script type=\"text/javascript\">" << Qt::endl;
4624  stream << " var lar_state;" << Qt::endl;
4625  stream << " function lar_running()" << Qt::endl;
4626  stream << " {" << Qt::endl;
4627  stream << " var result=confirm(\"Are you sure you want to start the autorun?\")" << Qt::endl;
4628  stream << " if (result==true) {" << Qt::endl;
4629  stream << " ODBSet(\"/AutoRun/Run State\", \"2\");" << Qt::endl;
4630  stream << " setTimeout(\"lar_refresh()\", 4000);" << Qt::endl;
4631  stream << " }" << Qt::endl;
4632  stream << " }" << Qt::endl;
4633  stream << Qt::endl;
4634  stream << " function lar_resume()" << Qt::endl;
4635  stream << " {" << Qt::endl;
4636  stream << " ODBSet(\"/AutoRun/Run State\", \"3\");" << Qt::endl;
4637  stream << " setTimeout(\"lar_refresh()\", 4000);" << Qt::endl;
4638  stream << " }" << Qt::endl;
4639  stream << Qt::endl;
4640  stream << " function lar_stop()" << Qt::endl;
4641  stream << " {" << Qt::endl;
4642  stream << " var result=confirm(\"Are you sure you want to stop the autorun?\")" << Qt::endl;
4643  stream << " if (result==true) {" << Qt::endl;
4644  stream << " ODBSet(\"/AutoRun/Run State\", \"0\");" << Qt::endl;
4645  stream << " setTimeout(\"lar_refresh()\", 4000);" << Qt::endl;
4646  stream << " }" << Qt::endl;
4647  stream << " }" << Qt::endl;
4648  stream << Qt::endl;
4649  stream << " function lar_pause()" << Qt::endl;
4650  stream << " {" << Qt::endl;
4651  stream << " ODBSet(\"/AutoRun/Run State\", \"1\");" << Qt::endl;
4652  stream << " setTimeout(\"lar_refresh()\", 4000);" << Qt::endl;
4653  stream << " }" << Qt::endl;
4654  stream << Qt::endl;
4655  stream << " function lar_load()" << Qt::endl;
4656  stream << " {" << Qt::endl;
4657  stream << " ODBSet(\"/AutoRun/Run State\", \"4\");" << Qt::endl;
4658  stream << " setTimeout(\"lar_refresh()\", 4000);" << Qt::endl;
4659  stream << " }" << Qt::endl;
4660  stream << Qt::endl;
4661  stream << " function lar_refresh()" << Qt::endl;
4662  stream << " {" << Qt::endl;
4663  stream << " window.location.reload(true);" << Qt::endl;
4664  stream << " }" << Qt::endl;
4665  stream << " function compProp(prop_odb) {" << Qt::endl;
4666  stream << " fetch('https://duo.psi.ch/duo/rest.php/cal/smus/lem?SECRET=change-bib-eva-grille',{method:'POST'})" << Qt::endl;
4667  stream << " .then( data => data.json(), console.error)" << Qt::endl;
4668  stream << " .then( data => {" << Qt::endl;
4669  stream << " console.log('propid_duo:', data.proposal);" << Qt::endl;
4670  stream << " if (data.proposal != prop_odb ) {" << Qt::endl;
4671  stream << " alert(\"The proposal number does NOT match the official schedule!\");" << Qt::endl;
4672  stream << " }" << Qt::endl;
4673  stream << " });" << Qt::endl;
4674  stream << " }" << Qt::endl;
4675  stream << " mjsonrpc_db_get_values([\"/Info/File_Header_Info/Proposal Number\"])" << Qt::endl;
4676  stream << " .then(function(rpc) {console.log('propid_odb:', rpc.result.data[0]);" << Qt::endl;
4677  stream << " compProp(rpc.result.data[0]);});" << Qt::endl;
4678  stream << " " << Qt::endl;
4679  stream << " " << Qt::endl;
4680  stream << " " << Qt::endl;
4681  stream << " </script>" << Qt::endl;
4682  stream << " </head>" << Qt::endl;
4683 
4684  // write body
4685  stream << " <body style=\"font-size: 10pt;\">" << Qt::endl;
4686  stream << " <form name=\"form1\" method=\"Get\" action=\"/CS/AutoRun&\">" << Qt::endl;
4687  stream << " <input type=\"hidden\" name=\"exp\" value=\"" << fExpName.toLatin1().data() << "\">" << Qt::endl;
4688  stream << " <table border=3 cellpadding=2 class=\"genericTable\">" << Qt::endl;
4689  stream << " <tr><th colspan=3 class=\"subStatusTitle\">NEMU Experiment: Autorun Parameters</th></tr>" << Qt::endl;
4690  stream << " <tr><td colspan=3>" << Qt::endl;
4691  stream << " <input value=\"Status\" name=\"cmd\" type=\"submit\">" << Qt::endl;
4692  stream << " <input value=\"ODB\" name=\"cmd\" type=\"submit\">" << Qt::endl;
4693  stream << " <input value=\"Messages\" name=\"cmd\" type=\"submit\">" << Qt::endl;
4694  stream << " </td></tr>" << Qt::endl;
4695  stream << " <tr><td colspan=3 style=\"text-align:left;\">" << Qt::endl;
4696  stream << " <script type=\"text/javascript\">" << Qt::endl;
4697  stream << " lar_state = ODBGet('/AutoRun/Run State');" << Qt::endl;
4698  stream << " if ((lar_state == 0) || (lar_state == 2) || (lar_state == 4) || (lar_state == 5)) { // stopped or starting up" << Qt::endl;
4699  stream << " document.write('<input type=\"button\" value=\"Start AutoRun\" onclick=\"lar_running()\">');" << Qt::endl;
4700  stream << " document.write('<input type=\"button\" value=\"Load Sequence\" onclick=\"lar_load()\">');" << Qt::endl;
4701  stream << " } else if (lar_state == 1) { // paused" << Qt::endl;
4702  stream << " document.write('<input type=\"button\" value=\"Resume AutoRun\" onclick=\"lar_resume()\">');" << Qt::endl;
4703  stream << " } else { // running" << Qt::endl;
4704  stream << " document.write('<input type=\"button\" value=\"Stop AutoRun\" onclick=\"lar_stop()\">');" << Qt::endl;
4705  stream << " document.write(' ');" << Qt::endl;
4706  stream << " document.write('<input type=\"button\" value=\"Pause AutoRun\" onclick=\"lar_pause()\">');" << Qt::endl;
4707  stream << " }" << Qt::endl;
4708  stream << " </script>" << Qt::endl;
4709  stream << " </td></tr>" << Qt::endl;
4710  stream << " <tr><td class=\"ODBtableEven\" colspan=3 style=\"text-align:left;\">Sample Name: <b><odb src=\"/Info/Sample Name\" edit=2></b></td>" << Qt::endl;
4711  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>" << Qt::endl;
4712  stream << " <td class=\"ODBtableOdd\" style=\"text-align:left;\">PI: <b><odb src=\"/Info/File_Header_Info/Main Proposer\" edit=2></b></td>" << Qt::endl;
4713  stream << " <tr><td class=\"ODBtableOdd\" colspan=2 style=\"text-align:left;\">Sequence: <b><odb src=\"/AutoRun/Auto Run Sequence\" edit=2></b></td>" << Qt::endl;
4714  stream << " <td class=\"ODBtableOdd\" style=\"text-align:left;\">Show Comments: <b><odb src=\"/AutoRun/Show Comments\" edit=2></b></td></tr>" << Qt::endl;
4715  stream << " <tr><td class=\"ODBtableEven\" colspan=2 style=\"text-align:left;\">Goto Line: <b><odb src=\"/AutoRun/GotoLine\" edit=2></b></td>" << Qt::endl;
4716  stream << " <td class=\"ODBtableEven\" style=\"text-align:left;\">Next : <b><odb src=\"/AutoRun/Next\" edit=2></b></td></tr>" << Qt::endl;
4717  stream << " <tr><td colspan=3 style=\"text-align:left;\">Status : <b><odb src=\"/AutoRun/Status\" edit=0></b></td></tr>" << Qt::endl;
4718 
4719  // write sequence
4720  stream << " <tr><td colspan=3 style=\"text-align:left;font-family:Fixed;line-height:1.25\" bgcolor=\"#FFFFFF\">" << Qt::endl;
4721  stream << " <pre>" << Qt::endl;
4722 
4723  if (tag == HTML_PARSE_ERROR) { // handle errors
4724  if (errLineNo > 0) {
4725  // get input file name
4726  QString pathFln = fAutoRunPath + GetAutoRunSequence();
4727  // read input file
4728  QFile f(pathFln);
4729  QTextStream fstream(&f);
4730  QString line;
4731  int lineNo = 1;
4732  if (f.exists()) {
4733  f.open(QIODevice::ReadOnly);
4734  while (!fstream.atEnd()) {
4735  line = fstream.readLine();
4736  stream << lineNo << ": " << line << Qt::endl;
4737  if (lineNo == errLineNo) {
4738  stream << "<span style=\"background-color: #FF8800;font-weight: bold;\">" << errMsg.toLatin1().data() << "</span>";
4739  stream << Qt::endl;
4740  }
4741  lineNo++;
4742  }
4743  f.close();
4744  } else {
4745  stream << "<span style=\"background-color: #FF8800;font-weight: bold;\">" << errMsg.toLatin1().data() << "</span>";
4746  }
4747  } else {
4748  stream << "<span style=\"background-color: #FF8800font-weight: bold;\">" << errMsg.toLatin1().data() << "</span>";
4749  }
4750  } else if (tag == HTML_FATAL) {
4751  stream << "<span style=\"background-color: #FF0000font-weight: bold;\">" << errMsg.toLatin1().data() << "</span>";
4752  } else { // normal command handling
4753  QString cmd;
4754 
4755  if (tag == HTML_LOAD) {
4756  QDateTime dt = QDateTime::currentDateTime();
4757  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"));
4758  stream << cmd << Qt::endl;
4759  }
4760 
4761  // write commands
4762  int width = 0, count = 0;
4763  if (fAutoRunCmdVector->count()>0)
4764  width = (int)(log10(fAutoRunCmdVector->count())+1);
4765  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
4766 
4767  if (!ShowComments() && (iter->cmd == "comment"))
4768  continue;
4769 
4770  if ((iter == currentIter) && (tag != HTML_LOAD)) // current command start
4771  cmd = "<span style=\"background-color: #FFFF00;font-weight: bold;\">";
4772  else
4773  cmd = "";
4774 
4775  count++;
4776  cmd += QString("%1 (%2): ").arg(count, width).arg(iter->lineNo, width);
4777 
4778  // command
4779  if (iter->cmd == "comment")
4780  cmd += "<span style=\"color:grey;font-style:italic\">";
4781 
4782  cmd += iter->cmdString;
4783 
4784  if (iter->cmd == "comment")
4785  cmd += "</span>";
4786 
4787  if (iter == currentIter) { // current command end
4788  if (tag == HTML_ABORTED) {
4789  if (!errMsg.isEmpty())
4790  cmd += QString("\n<span style=\"background-color: #FF0000;font-weight: bold;\">%1</span></span>").arg(errMsg);
4791  cmd += "\n<span style=\"background-color: #FF0000;font-weight: bold;\">AUTORUN ABORTED ...</span></span>";
4792  } else if (tag == HTML_WARMUP) {
4793  cmd += "\nEXECUTING WARMUP COMMAND ...</span>";
4794  } else if (tag == HTML_ALARM) {
4795  cmd += "\n<span style=\"background-color: #FF0000;font-weight: bold;\">ALARM FIRED, HENCE AUTORUN STOPPED...</span></span>";
4796  } else if (tag == HTML_STRANGE) {
4797  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>";
4798  } else {
4799  cmd += "</span>";
4800  }
4801  }
4802 
4803  stream << cmd << Qt::endl;
4804  }
4805 
4806  if (tag == HTML_STOP) {
4807  cmd = "<span style=\"background-color: #FFFF00;font-weight: bold;\">AUTORUN FINISHED ...</span>";
4808  stream << cmd << Qt::endl;
4809  }
4810  }
4811 
4812  stream << " </pre>" << Qt::endl;
4813  stream << " </td></tr>" << Qt::endl;
4814  stream << " </table>" << Qt::endl;
4815  stream << " </form>" << Qt::endl;
4816  stream << " </body>" << Qt::endl;
4817 
4818  // write HTML end tag
4819  stream << "</html>" << Qt::endl;
4820 
4821  file.close();
4822 }
4823 
4824 //**********************************************************************
4825 // FeedLiveDataAutoRun
4826 //**********************************************************************
4831 {
4832  // delete /AutoRun/LiveData/AutoRun
4833  HNDLE hKey;
4834  INT status = db_find_key(fExp->GetHdb(), 0, "/AutoRun/LiveData/AutoRun", &hKey);
4835  if (status == DB_SUCCESS) { // key found, hence delete it
4836  status = db_delete_key(fExp->GetHdb(), hKey, TRUE);
4837  }
4838 
4839  // get input file name from the current lar-file
4840  QString pathFln = fAutoRunPath + GetAutoRunSequence();
4841 
4842  // read current lar-file
4843  QFile f(pathFln);
4844  QTextStream fstream(&f);
4845  QString line;
4846  QVector<QString> data;
4847  if (f.exists()) {
4848  f.open(QIODevice::ReadOnly);
4849  while (!fstream.atEnd()) {
4850  line = fstream.readLine();
4851  data.push_back(line);
4852  }
4853  f.close();
4854  }
4855 
4856  // create /AutoRun/LiveData/AutoRun from the current lar-file
4857  char str[128];
4858  for (int i=0; i<data.size(); i++) {
4859  memset(str, 0, sizeof(str));
4860  strncpy(str, data[i].toLatin1(), sizeof(str));
4861  status = db_set_value_index(fExp->GetHdb(), 0, "/AutoRun/LiveData/AutoRun", str, sizeof(str), i, TID_STRING, FALSE);
4862  }
4863 }
4864 
4865 //**********************************************************************
4866 // ExecAutoRun
4867 //**********************************************************************
4872 {
4873  PAutoRunCmdVector::Iterator iter;
4874  int size;
4875  bool stopped;
4876  bool aborted = false;
4877  int maxCount = 0;
4878 
4879  // paranoia check to make sure that there are really autorun commands present
4880  if (fAutoRunCmdVector->size() == 0) {
4881  QString msg("**FATAL ERROR** no autorun commands present!!");
4882  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_FATAL, 0, msg);
4883  emit ErrorMsg(1, 0, LAR_FATAL, 0, msg);
4884  return;
4885  }
4886 
4887  // check that the magnet parameters are within range
4888  QString err("");
4889  int pos = CheckFieldCmd(err);
4890  if (pos != -1) {
4891  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_PARSE_ERROR, pos, err);
4892  emit ErrorMsg(1, 0, LAR_FATAL, 0, err);
4893  return;
4894  }
4895 
4896  // check for a warmup command
4898 
4899  // check if ODB_SET_DATA commands are present and if yes, check if the ODB path etc make sense
4901 
4902  // check if a TRANSPORT_HV <fln> command is present, and if yes, check if <fln> exists and is loadable
4903  if (!CheckForTransportHvCmd())
4904  return;
4905 
4906  // check if there is a setTemp command and if yes, set the sample LS340 ZONE settings
4907  // (in case somebody was fooling around with the LS340 sample, this will fix it)
4909 
4910  // autorun command counters
4912  // remove all the comments from the total number of autorun commands
4913  iter = fAutoRunCmdVector->begin();
4914  do {
4915  if (iter->cmd == "comment")
4916  fNoOfAutoRunCmds--;
4917  if (iter->lineNo > maxCount) // get the largest line number
4918  maxCount = iter->lineNo;
4919  iter++;
4920  } while (iter != fAutoRunCmdVector->end());
4921  fCurrentAutoRunCmd = 1;
4922 
4923  // key to set the transition tag
4924  PKey transTagKey(fExp, "/AutoRun/LiveData/TransitionTag");
4925  if (!transTagKey.IsValid()) {
4926  QString msg("**FATAL ERROR** cannot get necessary key /AutoRun/LiveData/TransitionTag!");
4927  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_FATAL, 0, msg);
4928  emit ErrorMsg(1, 0, LAR_FATAL, 0, msg);
4929  return;
4930  }
4931  int ival=LAR_TT_IDLE;
4932  transTagKey.SetData((void*)&ival, 1, TID_INT);
4933 
4934  // check if only load is wanted
4935  int runState = GetRunState();
4936  if ((runState == LAR_STATE_LOAD) || (runState == LAR_STATE_LOADING)) {
4937  // set autorun state to stopped
4939 
4940  QString msg("Loading Sequence ...");
4941  UpdateStatusMsg(msg);
4942 
4943  iter = fAutoRunCmdVector->begin();
4944  UpdateWebPage(iter, HTML_LOAD);
4945 
4946  return;
4947  }
4948 
4949  // check if there is already an ongoing run before entering the main loop
4950  // runningWhenStarting is needed to check the following:
4951  // run already underway when autorun is starting. If yes, make sure that the first
4952  // real command is a STOP and nothing else.
4953  bool runningWhenStarting = false;
4954  // get current runinfo state
4955  size = sizeof(fRunInfo);
4956  fRunInfoKey->GetRecord((void *)&fRunInfo, &size);
4958  runningWhenStarting = true;
4959 
4960  // key to the live data line number
4961  PKey lineNoKey(fExp, "/AutoRun/LiveData/CurrentLineNo");
4962  if (!lineNoKey.IsValid()) {
4963  QString msg("**FATAL ERROR** cannot get necessary key /AutoRun/LiveData/CurrentLineNo!");
4964  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_FATAL, 0, msg);
4965  emit ErrorMsg(1, 0, LAR_FATAL, 0, msg);
4966  return;
4967  }
4968  // key to the live data loop value
4969  PKey loopValKey(fExp, "/AutoRun/LiveData/LoopVal");
4970  if (!loopValKey.IsValid()) {
4971  QString msg("**FATAL ERROR** cannot get necessary key /AutoRun/LiveData/LoopVal!");
4972  UpdateWebPage(fAutoRunCmdVector->begin(), HTML_FATAL, 0, msg);
4973  emit ErrorMsg(1, 0, LAR_FATAL, 0, msg);
4974  return;
4975  }
4976 
4977  // loop over all commands
4978  iter = fAutoRunCmdVector->begin();
4979  do {
4980  // set current line number for the live data
4981  lineNoKey.SetData(&(iter->lineNo), 1, TID_INT);
4982 
4983  // set potential loop value
4984  char loopValStr[32];
4985  memset(loopValStr, 0, sizeof(loopValStr));
4986  if (iter->loopVal.isEmpty())
4987  strncpy(loopValStr, "empty", sizeof(loopValStr));
4988  else
4989  strncpy(loopValStr, iter->loopVal.toLatin1().data(), sizeof(loopValStr));
4990  loopValKey.SetData(loopValStr, 1, TID_STRING);
4991 
4992  // get current runinfo state
4993  size = sizeof(fRunInfo);
4994  fRunInfoKey->GetRecord((void *)&fRunInfo, &size);
4995 
4996  // check if somebody was starting an autorun while a run is already underway
4997  if (((fRunInfo.state == RUN_RUNNING) || (fRunInfo.state == RUN_PAUSED)) && runningWhenStarting &&
4998  !((iter->cmd == "setWait") || (iter->cmd == "runStop") ||
4999  (iter->cmd == "warmUp") || (iter->cmd == "alias") || (iter->cmd == "comment") ||
5000  (iter->cmd == "odbTag"))) {
5001  UpdateWebPage(iter, HTML_STRANGE);
5002  } else {
5003  UpdateWebPage(iter, HTML_RUNNING);
5004  }
5005 
5006  // handle alias, odbTag and comment independently of the run state
5007  if ((iter->cmd == "alias") || (iter->cmd == "odbTag") || (iter->cmd == "comment")) {
5008  iter++;
5009  if (iter == fAutoRunCmdVector->end())
5010  break;
5011  if ((iter->cmd == "alias") || (iter->cmd == "odbTag"))
5013  UpdateWebPage(iter, HTML_RUNNING);
5014  continue;
5015  }
5016 
5017  // handle run stop command
5018  if (((fRunInfo.state == RUN_RUNNING) || (fRunInfo.state == RUN_PAUSED)) &&
5019  (iter->cmd == "runStop") && fRunStopped) {
5020  UpdateWebPage(iter, HTML_RUNNING);
5021  RunStop(iter);
5022  } else if ((fRunInfo.state == RUN_STOPPED) && (iter->cmd == "runStop")) { // i.e. run stop and STOP cmd pending: this doesn't make any sense
5023  QString err("STOP cmd for a stopped run doesn't make any sense. Will change the STOP to a START cmd!");
5024  emit ErrorMsg(1, 0, LAR_STOP_STOP_NONSENSE, -1, err);
5025  iter->cmd = "runStart";
5026  iter->cmdString = "START " + iter->param[0];
5027  if (iter->noElements == 2) {
5028  iter->cmdString += " sec";
5029  }
5030  }
5031 
5032  // check if a run needs to be stopped
5033  stopped = RunStopCheck();
5034  if (stopped) {
5035  runningWhenStarting = false;
5036  iter++;
5037  if (iter == fAutoRunCmdVector->end())
5038  break;
5039  }
5040 
5041  runState = GetRunState();
5042  if (runState == LAR_STATE_STOPPED) {
5043  UpdateWebPage(iter, HTML_ABORTED);
5044  aborted = true;
5045  continue;
5046  }
5047 
5048  // do next command only if run is stopped, TD rate HV trip didn't fire, and autorun not paused
5049  runState = GetRunState();
5050  if ((fRunInfo.state == RUN_STOPPED) && !fHvTripFlag && (runState != LAR_STATE_PAUSED)) {
5051  runningWhenStarting = false;
5052 
5053  // check for goto command
5054  if (GetGotoLine() > 0) {
5055  GotoLine(iter, maxCount);
5056  }
5057 
5058  UpdateWebPage(iter, HTML_RUNNING);
5059  // filter the command and execute it
5060  if (iter->cmd == "runStart") {
5061  RunStart(iter);
5062  } else if (iter->cmd == "degaussWEW") {
5063  DegaussWEW(iter);
5064  iter++;
5065  } else if (iter->cmd == "degaussDanfysik") {
5066  DegaussDanfysik(iter);
5067  iter++;
5068  } else if (iter->cmd == "degaussMagnet") {
5069  Degauss(iter);
5070  iter++;
5071  } else if (iter->cmd == "degaussSpinRot") {
5072  DegaussSpinRot(iter);
5073  iter++;
5074  } else if (iter->cmd == "ignore_alarms") {
5075  SetIgnoreAlarms(iter);
5076  iter++;
5077  } else if (iter->cmd == "ignore_clients") {
5078  SetIgnoreClients(iter);
5079  iter++;
5080  } else if (iter->cmd == "setBPV") {
5081  SetBPV(iter);
5082  iter++;
5083  } else if (iter->cmd == "setDump") {
5084  SetDump(iter);
5085  iter++;
5086  } else if (iter->cmd == "setFOM") {
5087  SetFOM(iter);
5088  iter++;
5089  } else if (iter->cmd == "setFieldWEWL") {
5090  SetFieldWEWL(iter);
5091  iter++;
5092  } else if (iter->cmd == "setFieldWEWH") {
5093  SetFieldWEWH(iter);
5094  iter++;
5095  } else if (iter->cmd == "setFieldDanfysik") {
5096  SetFieldDanfysik(iter);
5097  iter++;
5098  } else if (iter->cmd == "setField") {
5099  SetField(iter);
5100  iter++;
5101  } else if (iter->cmd == "setSpinRot") {
5102  SetSpinRot(iter);
5103  iter++;
5104  } else if (iter->cmd == "setLEMSetup") {
5105  SetLEMSetup(iter);
5106  iter++;
5107  } else if (iter->cmd == "setModInfo") {
5108  SetModInfo(iter);
5109  iter++;
5110  } else if (iter->cmd == "setOdbData") {
5111  SetOdbData(iter);
5112  iter++;
5113  } else if (iter->cmd == "setOdbDataArray") {
5114  SetOdbDataArray(iter);
5115  iter++;
5116  } else if (iter->cmd == "setSampleHV") {
5117  SetSampleHV(iter);
5118  iter++;
5119  } else if (iter->cmd == "setRA_HV") {
5120  SetRA_HV(iter);
5121  iter++;
5122  } else if (iter->cmd == "setTransportHV") {
5123  SetTransportHV(iter);
5124  iter++;
5125  } else if (iter->cmd == "setHVOff") {
5126  SetHvOff(iter);
5127  iter++;
5128  } else if (iter->cmd == "setTfl") {
5129  SetTfl(iter);
5130  iter++;
5131  } else if (iter->cmd == "setTemp") {
5132  SetTemp(iter);
5133  iter++;
5134  } else if (iter->cmd == "setTitle") {
5135  SetTitle(iter);
5136  iter++;
5137  } else if (iter->cmd == "setTOF") {
5138  SetTof(iter);
5139  iter++;
5140  } else if (iter->cmd == "setWait") {
5141  SetWait(iter);
5142  iter++;
5143  } else if (iter->cmd == "warmUp") { // already taken care of, just increment iterator
5144  iter++;
5146  }
5147  fAutoRunCurrentIter = iter;
5148  }
5149 
5150  // feed midas watchdog
5151  fExp->FeedMidasWatchdog();
5152 
5153  // check temperature stability
5156  else
5158 
5159  // see whether the raw voltage should be dumped to file
5160  if (fDumpInUse) {
5161  if (fDumpCounter > 0) {
5162  RawVoltageDump();
5163  } else {
5164  fDumpFile.close();
5165  fDumpInUse = false;
5166  }
5167  }
5168 
5169  if (fSampleCryoInUse == CRYO_KONTI) {
5170  // adjust flow
5173  }
5174  }
5175 
5176  // check alarm system
5177  CheckMidasAlarms(iter);
5178 
5179  // sleep for 5 sec before proceeding to keep the system happy
5180  Wait(5000);
5181 
5182  // check if the warmup command needs to be executed
5183  if (fWarmUpWished && (QDateTime::currentDateTime() > fWarmUpDateTime)) {
5184  fWarmUpWished = false;
5185  WarmUp(iter);
5186  break;
5187  }
5188 
5189  } while ((iter != fAutoRunCmdVector->end()) && !aborted);
5190 
5191  if (!aborted) {
5192  // auto run finished before warm up timer kicked in, therefore warm up now
5193  if (fWarmUpWished) {
5194  int ival = LAR_TT_WARMUP;
5195  transTagKey.SetData((void*)&ival, 1, TID_INT);
5196  WarmUp(iter);
5197  }
5198  int ival = LAR_TT_FINISHED;
5199  transTagKey.SetData((void*)&ival, 1, TID_INT);
5200 
5201  // increment CurrentLineNo so that nothing is 'active' anymore on the web-page
5202  int size = sizeof(ival);
5203  lineNoKey.GetData((void*)&ival, &size, TID_INT);
5204  ival += 1;
5205  lineNoKey.SetData((void*)&ival, 1, TID_INT);
5206 
5207  // update status
5208  QString msg = QString("Autorun finished.");
5209  emit StatusMsg(msg);
5210 
5212  Wait(5000);
5213 
5214  // handle autoRunState
5215  PKey nextAutoRun(fExp, "/AutoRun/Next");
5216  if (nextAutoRun.IsValid()) {
5217  char next[64];
5218  int size = sizeof(next);
5219  nextAutoRun.GetData(next, &size, TID_STRING);
5220  int runState = LAR_STATE_NEXT;
5221  if (!strcmp(next, "none")) { // set autoRunState to stopped
5222  runState = LAR_STATE_STOPPED;
5223  }
5224  UpdateRunState(runState);
5225  }
5226  } else { // aborted
5227  int ival = LAR_TT_ABORTED;
5228  transTagKey.SetData((void*)&ival, 1, TID_INT);
5229  }
5230 }
5231 
5232 //**********************************************************************
5233 // RunStart
5234 //**********************************************************************
5241 {
5242  // param: [0] events/time, [[1] "sec"]
5243 
5244  int status, size;
5245  QString msg, err;
5246 
5247  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5248  msg += arc->cmdString;
5249 
5250  if (arc->noElements == 1) {
5251  fRunCheckEvents = true;
5252  } else {
5253  fRunCheckEvents = false;
5254  fRunTimeout = arc->param[0].toFloat();
5255  }
5256  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5257 
5258  // check if the vme frontend and analyzer are enabled
5259  if (!fEnabled["vme_fe"] || !fEnabled["analyzer_fe"]) {
5260  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5261  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"]);
5262  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
5264  return;
5265  }
5266 
5267  // check if frontend and analyzer are running
5268  CheckClients();
5269  if (!fFrontendRunning || !fAnalyzerRunning) { // frontend or analyzer NOT running
5270  err = QString("PLemAutoRun::RunStart: ");
5271  if (!fFrontendRunning)
5272  err += QString(" %1 ").arg(fFrontendName);
5273  if (!fAnalyzerRunning)
5274  err += QString(" %1 ").arg(fAnalyzerName);
5275  err += QString("not running, will stop! Fix it first ;-)");
5277  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5279  QCoreApplication::exit(0);
5280  exit(0);
5281  }
5282 
5283  if (fEnabled["lemvac_scfe"]) { // only check BPVX/Y if LEMVAC is enableds
5284  // check the BPVX/Y state
5285  GetBPV(); // get the current state of the BPVX/Y
5286  if (fLemVacValveInitialState[BPVX] == BPV_STATE_CLOSED) { // BPVX closed
5287  err = QString("PLemAutoRun::RunStart: BPVX still closed! Check also sample regions HV's");
5288  emit ErrorMsg(1, 0, LAR_BPV_CLOSED_AT_RUN_START, -1, err);
5289  }
5290  if (fLemVacValveInitialState[BPVY] == BPV_STATE_CLOSED) { // BPVY closed
5291  err = QString("PLemAutoRun::RunStart: BPVY still closed! Check also sample regions HV's");
5292  emit ErrorMsg(1, 0, LAR_BPV_CLOSED_AT_RUN_START, -1, err);
5293  }
5294  }
5295 
5296  if (fEnabled["fug_eq"]) { // only check FUG's if enabled
5297  // check if RA HV's are set for Bpar, and for Bperp < 130G
5298  float fval;
5299  if (fFieldPwrSupply == "danfysik") { // Bpar
5300  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
5301  size = sizeof(fval);
5302  fHVDemandKey->GetDataIndex(&fval, &size, i, TID_FLOAT);
5303  if (fval < 0.2) {
5304  err = QString("PLemAutoRun::RunStart: RA HV's < 0.2kV! Unlikely to be correct, please check!");
5305  emit ErrorMsg(1, 0, LAR_RA_HV_OFF_AT_RUN_START, -1, err);
5306  break;
5307  }
5308  }
5309  } else if (fFieldPwrSupply == "wew") { // Bperp
5310  if (fEnabled["wew_eq"]) { // only deal with WEW if equipment is enabled
5311  // get WEW input record
5312  float wew_input[11];
5313  size = sizeof(wew_input);
5314  fWEWInputKey->GetData(&wew_input, &size, TID_FLOAT);
5315 
5316  // find out if WEWL or WEWH is in use
5317  int current_idx;
5318  if (wew_input[WEWL_INPUT_STATUS] == 1.0) {
5319  current_idx = WEWL_INPUT_CURRENT;
5320  } else {
5321  current_idx = WEWH_INPUT_CURRENT;
5322  }
5323 
5324  // get the WEW current
5325  size = sizeof(fval);
5326  fWEWInputKey->GetDataIndex(&fval, &size, current_idx, TID_FLOAT);
5327  if (fval <= fWEWCriticalCurrentRA) {
5328  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
5329  size = sizeof(fval);
5330  fHVDemandKey->GetDataIndex(&fval, &size, i, TID_FLOAT);
5331  if (fval < 0.2) {
5332  err = QString("PLemAutoRun::RunStart: RA HV's < 0.2kV! Unlikely to be correct, please check!");
5333  emit ErrorMsg(1, 0, LAR_RA_HV_OFF_AT_RUN_START, -1, err);
5334  break;
5335  }
5336  }
5337  }
5338  }
5339  }
5340  }
5341 
5342  // keep the number of trigger events needed to complete a run
5343  fRunNoEventsNeeded = arc->param[0].toInt();
5344 
5345  // start run
5346  fRunInfo.run_number++;
5347  status = cm_transition(TR_START, fRunInfo.run_number, NULL, 0, TR_SYNC, FALSE);
5348  if (status != CM_SUCCESS) { // error
5350  err = QString("PLemAutoRun::RunStart: Cannot start the run.");
5351  emit ErrorMsg(1, 0, LAR_MIDAS_CANNOT_START_RUN, -1, err);
5352  }
5353 
5354  // check that the run really started
5355  QElapsedTimer t;
5356  t.start();
5357  size = sizeof(fRunInfo);
5358  do {
5359  if (fDebug)
5360  std::cout << std::endl << "RunStart: Runinfo.state = " << fRunInfo.state;
5361  fRunInfoKey->GetRecord((void *)&fRunInfo, &size);
5362  Wait(2000);
5363  if (t.elapsed() > 60e3) {
5364  err = QString("PLemAutoRun::RunStart: Didn't get run transition after run started.");
5366  emit ErrorMsg(1, 0, LAR_MIDAS_NO_RUN_TRANSITION, -1, err);
5367  break;
5368  }
5369  } while (fRunInfo.state != RUN_RUNNING);
5370 
5371  // run is on the way
5372  fRunStopped = false;
5373 
5374  // time stamp run start
5375  fRunStarted.start();
5376 
5377  // increment command counter
5379 
5380  // update status
5381  msg = QString("Autorun running: ") + msg;
5382  emit StatusMsg(msg);
5383 }
5384 
5385 //**********************************************************************
5386 // RunStop
5387 //**********************************************************************
5392 {
5393  // param: [0] events/time, [[1] "sec"]
5394 
5395  QString msg, err;
5396 
5397  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5398  msg += arc->cmdString;
5399 
5400  if (arc->noElements == 1) {
5401  fRunCheckEvents = true;
5402  } else {
5403  fRunCheckEvents = false;
5404  fRunTimeout = arc->param[0].toFloat();
5405  }
5406  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5407 
5408  // check if the vme frontend and analyzer are enabled
5409  if (!fEnabled["vme_fe"] || !fEnabled["analyzer_fe"]) {
5410  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5411  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"]);
5412  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
5414  return;
5415  }
5416 
5417  // check if frontend and analyzer are running
5418  CheckClients();
5419  if (!fFrontendRunning || !fAnalyzerRunning) { // frontend or analyzer NOT running
5421  QString err = QString("PLemAutoRun::RunStop: ");
5422  if (!fFrontendRunning)
5423  err += QString(" %1 ").arg(fFrontendName);
5424  if (!fAnalyzerRunning)
5425  err += QString(" %1 ").arg(fAnalyzerName);
5426  err += QString("not running, will stop! Fix it first ;-)");
5428  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5430  QCoreApplication::exit(0);
5431  exit(0);
5432  }
5433 
5434  // keep the number of trigger events needed to complete a run
5435  fRunNoEventsNeeded = arc->param[0].toInt();
5436 
5437  // run is on the way
5438  fRunStopped = false;
5439 
5440  // time stamp run start
5441  fRunStarted.start();
5442 
5443  // increment command counter
5445 }
5446 
5447 //**********************************************************************
5448 // RunStopCheck
5449 //**********************************************************************
5455 {
5456  int status, size;
5457  double value;
5458  QString err;
5459  bool stopped = false;
5460 
5461  // update Runinfo structure
5462  size = sizeof(fRunInfo);
5463  fRunInfoKey->GetRecord((void *)&fRunInfo, &size);
5464 
5465  // check only if Run is active 10sec after run start to allow the Trigger statistics to
5466  // the get the right Event stats
5467  if ((fRunInfo.state == RUN_RUNNING) && (fRunStarted.elapsed() > 10000)) {
5468  // check if frontend and analyzer are running
5469  CheckClients();
5470  if (!fFrontendRunning || !fAnalyzerRunning) { // frontend or analyzer NOT running
5472  QString err = QString("PLemAutoRun::RunStopCheck: ");
5473  if (!fFrontendRunning)
5474  err += QString(" %1 ").arg(fFrontendName);
5475  if (!fAnalyzerRunning)
5476  err += QString(" %1 ").arg(fAnalyzerName);
5477  err += QString("not running, will stop! Fix it first ;-)");
5478  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5480  QCoreApplication::exit(0);
5481  exit(0);
5482  }
5483 
5484  if (fRunCheckEvents) { // check if number of events criteria or time shall be used
5485  // get no of events
5486  size = sizeof(value);
5487  status = fTriggerEventsKey->GetData(&value, &size, TID_DOUBLE);
5488  if (status != DB_SUCCESS) { // error
5490  err = "PLemAutoRun::RunStopCheck: Couldn't get current number of events";
5491  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
5492  }
5493  // check if enough events to stop the current run
5494  if ((value >= fRunNoEventsNeeded) && !fRunStopped) { // run can be stopped if not already done so
5495  // stop run
5496  status = cm_transition(TR_STOP, fRunInfo.run_number, NULL, 0, TR_SYNC, FALSE);
5497  if (status != CM_SUCCESS) { // error
5499  err = QString("PLemAutoRun::RunStart: Cannot stop the run.");
5500  emit StatusMsg(err);
5501  emit ErrorMsg(1, 0, LAR_MIDAS_CANNOT_START_RUN, -1, err);
5502  }
5503  err = QString("Autorun running: run stopped.");
5504  emit StatusMsg(err);
5505  err = QString(">> End of run; read=%1 of requested = %2").arg(value).arg(fRunNoEventsNeeded);
5506  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
5507  fRunNoEventsNeeded = 0;
5508  fRunStopped = true;
5509  stopped = true;
5510  }
5511  } else { // check if the time elapsed passed the timing criterium
5512  if ((fRunStarted.elapsed() > (int)(1e3*fRunTimeout)) && !fRunStopped) { // stop the run
5513  // stop run
5514  status = cm_transition(TR_STOP, fRunInfo.run_number, NULL, 0, TR_SYNC, FALSE);
5515  if (status != CM_SUCCESS) { // error
5517  err = QString("PLemAutoRun::RunStart: Cannot stop the run.");
5518  emit StatusMsg(err);
5519  emit ErrorMsg(1, 0, LAR_MIDAS_CANNOT_START_RUN, -1, err);
5520  }
5521  err = QString("Autorun running: run stopped.");
5522  emit StatusMsg(err);
5523  err = QString(">> End of run; read=%1 of requested = %2").arg(value).arg(fRunNoEventsNeeded);
5524  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
5525  fRunNoEventsNeeded = 0;
5526  fRunStopped = true;
5527  stopped = true;
5528  }
5529  }
5530  }
5531 
5532  // check if run was stopped manually
5533  if ((fRunInfo.state == RUN_STOPPED) && (fRunStarted.elapsed() > 10000) && !fRunStopped) {
5534  fRunStopped = true;
5535  stopped = true;
5536  }
5537 
5538  return stopped;
5539 }
5540 
5541 //**********************************************************************
5542 // CheckFieldCmd
5543 //**********************************************************************
5548 int PLemAutoRun::CheckFieldCmd(QString &errMsg)
5549 {
5550  if (!fEnabled["mag_param_wew_odb"] || !fEnabled["mag_param_bpar_odb"])
5551  return -1;
5552 
5553  float fval, maxField;
5554  for (int i=0; i<fAutoRunCmdVector->size(); i++) {
5555  if (fAutoRunCmdVector->at(i).cmd == "setFieldWEWL") {
5556  fval = fAutoRunCmdVector->at(i).param[0].toFloat(); // field/current value
5557  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5558  if (fabs(fval) > fWEWLMaxCurrent) { // out of range current
5559  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);
5560  emit StatusMsg(errMsg);
5561  return i;
5562  }
5563  } else { // value in Gauss
5564  maxField = fMagParamWew[0] + fMagParamWew[1] * fWEWLMaxCurrent;
5565  if (fabs(fval) > maxField) { // out of range field
5566  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);
5567  emit StatusMsg(errMsg);
5568  return i;
5569  }
5570  }
5571  } else if (fAutoRunCmdVector->at(i).cmd == "setFieldWEWH") {
5572  fval = fAutoRunCmdVector->at(i).param[0].toFloat(); // field/current value
5573  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5574  if (fabs(fval) > fWEWHMaxCurrent) { // out of range current
5575  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);
5576  emit StatusMsg(errMsg);
5577  return i;
5578  }
5579  } else { // value in Gauss
5580  maxField = fMagParamWew[0] + fMagParamWew[1] * fWEWHMaxCurrent;
5581  if (fabs(fval) > maxField) { // out of range field
5582  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);
5583  emit StatusMsg(errMsg);
5584  return i;
5585  }
5586  }
5587  } else if (fAutoRunCmdVector->at(i).cmd == "setFieldDanfysik") {
5588  fval = fAutoRunCmdVector->at(i).param[0].toFloat(); // field/current value
5589  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5590  if (fabs(fval) > fDanfysikMaxCurrent) { // out of range current
5591  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);
5592  emit StatusMsg(errMsg);
5593  return i;
5594  }
5595  } else { // value in Gauss
5596  maxField = fMagParamBpar[0] + fMagParamBpar[1] * fDanfysikMaxCurrent;
5597  if (fabs(fval) > maxField) { // out of range field
5598  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);
5599  emit StatusMsg(errMsg);
5600  return i;
5601  }
5602  }
5603  } else if (fAutoRunCmdVector->at(i).cmd == "setField") {
5604  fval = fAutoRunCmdVector->at(i).param[0].toFloat(); // field/current value
5605  if (fSetupWewEnabled) {
5606  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5607  if (fabs(fval) > fWEWHMaxCurrent) { // out of range current
5608  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);
5609  emit StatusMsg(errMsg);
5610  return i;
5611  }
5612  } else { // value in Gauss
5613  maxField = fMagParamWew[0] + fMagParamWew[1] * fWEWHMaxCurrent;
5614  if (fabs(fval) > maxField) { // out of range field
5615  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);
5616  emit StatusMsg(errMsg);
5617  return i;
5618  }
5619  }
5620  } else { // Bpar
5621  if (fAutoRunCmdVector->at(i).param[1] == "A") { // value in Ampere
5622  if (fabs(fval) > fDanfysikMaxCurrent) { // out of range current
5623  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);
5624  emit StatusMsg(errMsg);
5625  return i;
5626  }
5627  } else { // value in Gauss
5628  maxField = fMagParamBpar[0] + fMagParamBpar[1] * fDanfysikMaxCurrent;
5629  if (fabs(fval) > maxField) { // out of range field
5630  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);
5631  emit StatusMsg(errMsg);
5632  return i;
5633  }
5634  }
5635  }
5636  }
5637  }
5638 
5639  return -1;
5640 }
5641 
5642 //**********************************************************************
5643 // DegaussWEW
5644 //**********************************************************************
5655 {
5656  float hv[5], fval;
5657  float current_wewh[3] = {+600.0, -40.0, 0.0};
5658  float current_wewl[3] = {+50.0, -45.0, 0.0};
5659  int size;
5660  QString msg("");
5661 
5662  // check if FUG handling is disabled in lemAutoRun
5663  if (!fEnabled["fug_scfe"]) {
5664  msg = QString("(%1/%2) DEGAUSS_WEW: FUG disabled in lemAutoRun. Will do nothing here.").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5665  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5666  // increment command counter
5668  return;
5669  }
5670  // check of WEW equipment is disabled in lemAutoRun
5671  if (!fEnabled["wew_eq"]) {
5672  msg = QString("(%1/%2) DEGAUSS_WEW: WEW equipment disabled in lemAutoRun. Will do nothing here.").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5673  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5674  // increment command counter
5676  return;
5677  }
5678 
5679  // check if wew scfe is running
5680  CheckClients();
5681  if (!fWEWFeRunning) {
5683  QString err = QString("PLemAutoRun::DegaussWEW: WEW Slowcontrol Frontend NOT running. Error too severe, will stop.");
5684  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5686  QCoreApplication::exit(0);
5687  exit(0);
5688  }
5689 
5690  msg = QString("(%1/%2) DEGAUSS_WEW").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5691  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5692 
5693  msg = QString("Autorun running: ") + msg;
5694  emit StatusMsg(msg);
5695 
5696  // get current RA HV values
5697  // get RAL
5698  size = sizeof(fval);
5699  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_RAL, TID_FLOAT);
5700  hv[0] = fval;
5701  // get RAT
5702  size = sizeof(fval);
5703  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_RAT, TID_FLOAT);
5704  hv[1] = fval;
5705  // get RAR
5706  size = sizeof(fval);
5707  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_RAR, TID_FLOAT);
5708  hv[2] = fval;
5709  // get RAB
5710  size = sizeof(fval);
5711  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_RAB, TID_FLOAT);
5712  hv[3] = fval;
5713  // get SampleHV
5714  size = sizeof(fval);
5715  fHVDemandKey->GetDataIndex(&fval, &size, HV_FUG_SAMPLE, TID_FLOAT);
5716  hv[4] = fval;
5717 
5718  // set RA HV values to zero
5719  fval = 0.0;
5720  fHVDemandKey->SetDataIndex(&fval, HV_FUG_RAL, TID_FLOAT);
5721  fHVDemandKey->SetDataIndex(&fval, HV_FUG_RAT, TID_FLOAT);
5722  fHVDemandKey->SetDataIndex(&fval, HV_FUG_RAR, TID_FLOAT);
5723  fHVDemandKey->SetDataIndex(&fval, HV_FUG_RAB, TID_FLOAT);
5724  fHVDemandKey->SetDataIndex(&fval, HV_FUG_SAMPLE, TID_FLOAT);
5725 
5726  // message to midas
5727  cm_msg(MINFO, "lemAutoRun", "DegaussWEW: RA HV down. Will wait 5 sec to settle things.");
5728  cm_yield(0);
5729 
5730  Wait(5000); // wait 5 sec
5731 
5732  // do the degaussing procedure which is the following current cycle:
5733  // 1) set WEWL/H demand current to zero
5734  // 2) switch off WEWL
5735  // 3) unlock WEW/SSP
5736  // 4) WEWH: 600A -> -40A -> 0
5737  // 5) WEWL: 50A -> -45A -> 0
5738  // 6) lock WEW/SSP
5739  // -------------------------------------------------
5740  // 1) set WEWL/H demand current to zero
5741  fval = 0.0;
5742  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CURRENT, TID_FLOAT);
5743  fval = 0.0;
5744  fWEWOutputKey->SetDataIndex(&fval, WEWH_OUTPUT_CURRENT, TID_FLOAT);
5745  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: set WEWL/H demand current to zero");
5746  cm_yield(0); // make the watchdog happy
5747  Wait(2000); // wait 2 sec
5748 
5749  // 2) switch off WEWL
5750  fval = 0.0;
5751  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CMD, TID_FLOAT);
5752  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: switch off WEWL");
5753  cm_yield(0); // make the watchdog happy
5754  Wait(2000); // wait 2 sec
5755 
5756  // 3) unlock WEW/SSP
5757  fval = 0.0;
5758  fWEWOutputKey->SetDataIndex(&fval, WEW_SSP_LOCK, TID_FLOAT);
5759  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: unlock WEW/SSP");
5760  cm_yield(0); // make the watchdog happy
5761  Wait(2000); // wait 2 sec
5762 
5763  // 4) WEWH: 600A -> -40A -> 0
5764  fval = 1.0;
5765  fWEWOutputKey->SetDataIndex(&fval, WEWH_OUTPUT_CMD, TID_FLOAT);
5766  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: switch on WEWH");
5767  cm_yield(0); // make the watchdog happy
5768  Wait(5000); // wait 5 sec
5769  for (unsigned int i=0; i<3; i++) {
5770  fval = current_wewh[i];
5771  fWEWOutputKey->SetDataIndex(&fval, WEWH_OUTPUT_CURRENT, TID_FLOAT);
5772  // message to midas
5773  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: set current %f A via WEWH.", fval);
5774  cm_yield(0); // make the watchdog happy
5775  // check that the field value is reached
5776  do {
5777  // wait a bit
5778  Wait(5000); // wait 5 sec
5779  size = sizeof(fval);
5780  fWEWInputKey->GetDataIndex(&fval, &size, WEWH_INPUT_CURRENT, TID_FLOAT);
5781  } while (fabs(fabs(fval)-fabs(current_wewh[i])) > 2.0); // 2A is needed for WEWH (zero is ~1.5)
5782  // keep the field for 15 sec
5783  Wait(15000);
5784  }
5785 
5786  // switch WEWH off and WEWL on
5787  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: switch WEWH off, WEWL on.");
5788  cm_yield(0); // make the watchdog happy
5789  fval = 0.0;
5790  fWEWOutputKey->SetDataIndex(&fval, WEWH_OUTPUT_CMD, TID_FLOAT);
5791  // check that WEWH is indeed switched off before proceeding
5792  QElapsedTimer tt;
5793  tt.start();
5794  int timeDiff = 0;
5795  do {
5796  size = sizeof(fval);
5797  fWEWInputKey->GetDataIndex(&fval, &size, WEWH_INPUT_STATUS, TID_FLOAT);
5798  timeDiff = tt.elapsed();
5799  if (timeDiff % 500 < 50) // make sure cm_yield is called periodically to make the watchdog happy
5800  cm_yield(0); // make the watchdog happy
5801  } while ((fval != 0.0) && (timeDiff < 120000)); // wait no longer than 2 min
5802  if (timeDiff >= 120000) {
5804  QString err = QString("PLemAutoRun::DegaussWEW: Couldn't switch off WEWH - check. Error too severe, will stop.");
5805  emit ErrorMsg(1, 0, LAR_MIDAS_READBACK_FAILURE, -1, err);
5807  QCoreApplication::exit(0);
5808  exit(0);
5809  }
5810  // switch on WEWL
5811  Wait(2000); // wait 2 sec
5812  fval = 1.0;
5813  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CMD, TID_FLOAT);
5814  Wait(2000); // wait 2 sec
5815  // check that WEWL is indeed switched on before proceeding
5816  tt.start();
5817  timeDiff = 0;
5818  bool try_again = false;
5819  do {
5820  size = sizeof(fval);
5821  fWEWInputKey->GetDataIndex(&fval, &size, WEWL_INPUT_STATUS, TID_FLOAT);
5822  timeDiff = tt.elapsed();
5823  if (timeDiff % 500 < 50) // make sure cm_yield is called periodically to make the watchdog happy
5824  cm_yield(0); // make the watchdog happy
5825  if ((timeDiff >= 60000) && !try_again) {
5826  try_again = true;
5827  // will try to switch on WEWL once more. For this it needs to be switched off first (DD needs a change)
5828  // before it can switched on again.
5829  // switch off WEWL
5830  fval = 0.0;
5831  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CMD, TID_FLOAT);
5832  Wait(2000);
5833  // switch on WEWL
5834  fval = 1.0;
5835  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CMD, TID_FLOAT);
5836  cm_msg(MINFO, "lemAutoRun", "DegaussWEW: couldn't switch on the WEWL yet, will try again.");
5837  }
5838  } while ((fval != 1.0) && (timeDiff < 120000)); // wait no longer than 2 min
5839  if (timeDiff >= 120000) {
5841  QString err = QString("PLemAutoRun::DegaussWEW: Couldn't switch on WEWL - check. Error too severe, will stop.");
5842  emit ErrorMsg(1, 0, LAR_MIDAS_READBACK_FAILURE, -1, err);
5844  QCoreApplication::exit(0);
5845  exit(0);
5846  }
5847 
5848  // 5) WEWL: 50A -> -45A -> 0
5849  for (unsigned int i=0; i<3; i++) {
5850  fval = current_wewl[i];
5851  fWEWOutputKey->SetDataIndex(&fval, WEWL_OUTPUT_CURRENT, TID_FLOAT);
5852  // message to midas
5853  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: set current %f A via WEWL.", fval);
5854  cm_yield(0); // make the watchdog happy
5855  // check that the field value is reached
5856  do {
5857  // wait a bit
5858  Wait(2000); // wait 2 sec
5859  size = sizeof(fval);
5860  fWEWInputKey->GetDataIndex(&fval, &size, WEWL_INPUT_CURRENT, TID_FLOAT);
5861  } while (fabs(fabs(fval)-fabs(current_wewl[i])) > 0.2);
5862  // keep the field for 15 sec
5863  Wait(15000);
5864  }
5865 
5866  // 6) lock WEW/SSP
5867  fval = 1.0;
5868  fWEWOutputKey->SetDataIndex(&fval, WEW_SSP_LOCK, TID_FLOAT);
5869  cm_msg(MDEBUG, "lemAutoRun", "DegaussWEW: lock WEW/SSP");
5870  cm_yield(0); // make the watchdog happy
5871  Wait(2000); // wait 2 sec
5872 
5873  cm_msg(MINFO, "lemAutoRun", "DegaussWEW: ramping back RA HV's.");
5874  cm_yield(0);
5875 
5876  // ramp the RA HV's back
5877  fHVDemandKey->SetDataIndex(&hv[0], HV_FUG_RAL, TID_FLOAT);
5878  fHVDemandKey->SetDataIndex(&hv[1], HV_FUG_RAT, TID_FLOAT);
5879  fHVDemandKey->SetDataIndex(&hv[2], HV_FUG_RAR, TID_FLOAT);
5880  fHVDemandKey->SetDataIndex(&hv[3], HV_FUG_RAB, TID_FLOAT);
5881  fHVDemandKey->SetDataIndex(&hv[4], HV_FUG_SAMPLE, TID_FLOAT);
5882 
5883  if (fFugHvCheck) {
5884  // check that the RA HV's are back to its previous values
5885  int done = 0;
5886  tt.restart();
5887  do {
5888  // check RAL
5889  size = sizeof(fval);
5890  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_RAL, TID_FLOAT);
5891  if (fabs(fval-hv[0]) < 0.2)
5892  done++;
5893 
5894  // check RAT
5895  size = sizeof(fval);
5896  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_RAT, TID_FLOAT);
5897  if (fabs(fval-hv[1]) < 0.2)
5898  done++;
5899 
5900  // check RAR
5901  size = sizeof(fval);
5902  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_RAR, TID_FLOAT);
5903  if (fabs(fval-hv[2]) < 0.2)
5904  done++;
5905 
5906  // check RAB
5907  size = sizeof(fval);
5908  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_RAB, TID_FLOAT);
5909  if (fabs(fval-hv[3]) < 0.2)
5910  done++;
5911 
5912  // check SampleHV
5913  size = sizeof(fval);
5914  fHVMeasuredKey->GetDataIndex(&fval, &size, HV_FUG_SAMPLE, TID_FLOAT);
5915  if (fabs(fval-hv[4]) < 0.2)
5916  done++;
5917 
5918  if (done < 5) {
5919  Wait(2000); // wait 2 sec
5920  }
5921 
5922  if (tt.elapsed() > 300000) { // it takes more than 5 min
5923  QString err = QString("lemAutoRun: **WARNING** Sample region HV's couldn't be ramped back within 5min.");
5924  emit ErrorMsg(1, 0, LAR_MSG, -1, err);
5925  done = 10;
5926  }
5927 
5928  } while (done < 5);
5929  } else { // NO FUG HV check, hence just wait a 1 min
5930  Wait(60000);
5931  }
5932 
5933  cm_msg(MINFO, "lemAutoRun", "DegaussWEW: degauss done.");
5934  cm_yield(0);
5935 }
5936 
5937 //**********************************************************************
5938 // DegaussDanfysik
5939 //**********************************************************************
5946 {
5947  float currentFieldValue;
5948  QString msg;
5949 
5950  // check of Danfysik equipment is disabled in lemAutoRun
5951  if (!fEnabled["danfysik_eq"]) {
5952  msg = QString("(%1/%2) DEGAUSS_DANFYSIK: danfysik equipment disabled in lemAutoRun. Will do nothing here.").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5953  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5954  // increment command counter
5956  return;
5957  }
5958 
5959  // check if danfysik scfe is running
5960  CheckClients();
5961  if (!fDanfysikFeRunning) {
5963  QString err = QString("PLemAutoRun::DegaussDanfysik: Danfysik Slowcontrol Frontend NOT running. Error too severe, will stop.");
5964  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
5966  QCoreApplication::exit(0);
5967  exit(0);
5968  }
5969 
5970  msg = QString("(%1/%2) DEGAUSS_DANFYSIK").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
5971  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
5972 
5973  msg = QString("Autorun running: ") + msg;
5974  emit StatusMsg(msg);
5975 
5976  // set current field to -8A
5977  currentFieldValue = -8.0;
5978  fDanfysikOutputKey->SetDataIndex(&currentFieldValue, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
5979  cm_msg(MINFO, "lemAutoRun", "DegaussDanfysik: set Bpar current to -8.0A");
5980  cm_yield(0);
5981 
5982  // wait 60 sec
5983  Wait(60000);
5984 
5985  // set current field to +8A
5986  currentFieldValue = +8.0;
5987  fDanfysikOutputKey->SetDataIndex(&currentFieldValue, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
5988  cm_msg(MINFO, "lemAutoRun", "DegaussDanfysik: set Bpar current to +8.0A");
5989  cm_yield(0);
5990 
5991  // wait 60 sec
5992  Wait(60000);
5993 
5994  // reduce the current field value gradually
5995  do {
5996  // set the new field value
5997  currentFieldValue /= -2.0;
5998  fDanfysikOutputKey->SetDataIndex(&currentFieldValue, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
5999  cm_msg(MINFO, "lemAutoRun", "DegaussDanfysik: set Bpar current to %.2f A", currentFieldValue);
6000  cm_yield(0);
6001 
6002  // wait a bit
6003  Wait(30000);
6004  } while (fabs(currentFieldValue) > 0.1);
6005 
6006  // set field value to zero
6007  currentFieldValue = 0.0;
6008  fDanfysikOutputKey->SetDataIndex(&currentFieldValue, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
6009  cm_msg(MINFO, "lemAutoRun", "DegaussDanfysik: done");
6010  cm_yield(0);
6011 }
6012 
6013 //**********************************************************************
6014 // Degauss
6015 //**********************************************************************
6023 {
6024  if (fSetupWewEnabled)
6025  DegaussWEW(arc);
6026  else
6027  DegaussDanfysik(arc);
6028 }
6029 
6030 //**********************************************************************
6031 // DegaussSpinRot
6032 //**********************************************************************
6039 {
6040  QString msg("");
6041 
6042  // check if FUG handling is disabled in lemAutoRun
6043  if (!fEnabled["fug_scfe"]) {
6044  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6045  msg += arc->cmdString;
6046  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
6047  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6048  // increment command counter
6050  return;
6051  }
6052  // check the danfysik spin rot equipment is enabled
6053  if (!fEnabled["danfysik_spin_rot_eq"]) {
6054  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6055  msg += QString("PLemAutoRun::DegaussSpinRot: danfysik spin rot equipment is disabled. Will do nothing here.");
6056  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6057  // increment command counter
6059  return;
6060  }
6061 
6062  // check if the hv_fug_scfe frontend is running
6063  CheckClients();
6064  if (!fHVFeRunning) { // error too severe to going on
6066  QString err = QString("PLemAutoRun::DegaussSpinRot: Slowcontrol Frontend NOT running. Error too severe, will stop.");
6067  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
6069  QCoreApplication::exit(0);
6070  exit(0);
6071  }
6072 
6073  msg = QString("(%1/%2) DEGAUSS_SPIN_ROT").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6074  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6075 
6076  msg = QString("Autorun running: ") + msg;
6077  emit StatusMsg(msg);
6078 
6079  // set spin rotator HV's to zero
6080  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: shut down Spin Rot HV's.");
6081  cm_yield(0);
6082  // Loop over set HV. This is done this way to reduce hangers due to network problems
6083  int i, size;
6084  float hv_measured[HV_FUG_CHS];
6085  float value;
6086  float timeout;
6087  bool done, happy;
6088  QElapsedTimer t;
6089  for (i=0; i<HV_FUG_MAX_TRY; i++) {
6090  // set spin rotator hv's to zero
6091  value = 0.0;
6092  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_RIGHT_RODS, TID_FLOAT);
6093  value = 0.0;
6094  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_LEFT_RODS, TID_FLOAT);
6095  value = 0.0;
6096  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_LEFT_PLATE, TID_FLOAT);
6097  value = 0.0;
6098  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_RIGHT_PLATE, TID_FLOAT);
6099 
6100  if (fFugHvCheck) {
6101  // check that the spin rotator HV's are all zero
6102  done = false;
6103  happy = false;
6104  timeout = fHVTimeout * 1e3;
6105  t.start();
6106  do {
6107  // sleep for 5 sec before reading the next value
6108  Wait(5000);
6109 
6110  // read sample hv
6111  size = HV_FUG_CHS*sizeof(float);
6112  fHVMeasuredKey->GetData(&hv_measured, &size, TID_FLOAT);
6113 
6114  // check if all measured spin rotator HV's are zero
6115  int count = 0;
6116  for (int j=HV_FUG_RIGHT_RODS; j<=HV_FUG_RIGHT_PLATE; j++) {
6117  if (fabs(hv_measured[j]) < fHVAccuracy)
6118  count++;
6119  }
6120  if (count == 4) { // all spin rotator HV's down
6121  done = true;
6122  happy = true;
6123  }
6124 
6125  // check if too much time elapsed to reach the final sample hv
6126  if (t.elapsed() > timeout) {
6127  done = true; // quit loop
6128  // emit warning
6129  msg = QString("Couldn't shut down Spin Rot HVs within %1 sec: will give it another try in 120 sec.").arg(fHVTimeout);
6130  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6131  }
6132  } while (!done);
6133 
6134  if (happy) // everything is OK, get out of the loop
6135  break;
6136 
6137  // wait 120 sec before retrial
6138  Wait(120000);
6139  } else { // NO FUG HV check, hence just wait a 1 min
6140  Wait(60000);
6141  break;
6142  }
6143  }
6144 
6145  if (i == HV_FUG_MAX_TRY) {
6147  // emit error
6148  msg = QString("Couldn't shut down the Spin Rotator HV, even after a few trials :-( .");
6149  emit ErrorMsg(1, 0, LAR_SAMPLE_HV_NOT_REACHED, arc->lineNo, msg);
6150  }
6151 
6152  // degauss spin rotator magnet
6153  // 1st set current to 0
6154  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: set Spin Rot Magnet current to 0.");
6155  cm_yield(0);
6156  value = 0.0;
6157  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6158  // check that measured current is going to 0
6159  done = false;
6160  timeout = fFieldTimeout * 1e3; // ms -> sec
6161  t.start(); // start timer
6162  do {
6163  // sleep for 1 sec before reading the next value
6164  Wait(1000);
6165 
6166  size = sizeof(value);
6167  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6168 
6169  if (fabs(value) < 0.1)
6170  done = true;
6171 
6172  // check if too much time elapsed to reach the final spin rotator magnet current
6173  if (t.elapsed() > timeout) {
6174  done = true; // quit loop
6175  // emit warning
6176  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6177  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6178  }
6179  } while (!done);
6180 
6181  // wait 10 sec
6182  Wait(10000);
6183 
6184  // 2nd set current to +12.0
6185  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: set Spin Rot Magnet current to 12.0 A.");
6186  cm_yield(0);
6187  value = 12.0;
6188  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6189  // check that measured current is going to 12A
6190  done = false;
6191  timeout = fFieldTimeout * 1e3; // ms -> sec
6192  t.start(); // start timer
6193  do {
6194  // sleep for 1 sec before reading the next value
6195  Wait(1000);
6196 
6197  size = sizeof(value);
6198  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6199 
6200  if (fabs(value-12.0) < 0.1)
6201  done = true;
6202 
6203  // check if too much time elapsed to reach the final spin rotator magnet current
6204  if (t.elapsed() > timeout) {
6205  done = true; // quit loop
6206  // emit warning
6207  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6208  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6209  }
6210  } while (!done);
6211 
6212  // wait 30 sec
6213  Wait(30000);
6214 
6215  // 3rd set current to -1.3A
6216  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: set Spin Rot Magnet current to -1.3 A.");
6217  cm_yield(0);
6218  value = -1.3;
6219  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6220  // check that measured current is going to -1.3A
6221  done = false;
6222  timeout = fFieldTimeout * 1e3; // ms -> sec
6223  t.start(); // start timer
6224  do {
6225  // sleep for 1 sec before reading the next value
6226  Wait(1000);
6227 
6228  size = sizeof(value);
6229  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6230 
6231  if (fabs(value+1.3) < 0.1)
6232  done = true;
6233 
6234  // check if too much time elapsed to reach the final spin rotator magnet current
6235  if (t.elapsed() > timeout) {
6236  done = true; // quit loop
6237  // emit warning
6238  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6239  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6240  }
6241  } while (!done);
6242 
6243  // wait 30 sec
6244  Wait(30000);
6245 
6246  // 4th set current to 0
6247  cm_msg(MINFO, "DegaussSpinRot", "DegaussSpinRot: set Spin Rot Magnet current to 0 - done.");
6248  cm_yield(0);
6249  value = 0.0;
6250  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
6251  // check that measured current is going to 0
6252  done = false;
6253  timeout = fFieldTimeout * 1e3; // ms -> sec
6254  t.start(); // start timer
6255  do {
6256  // sleep for 1 sec before reading the next value
6257  Wait(1000);
6258 
6259  size = sizeof(value);
6260  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
6261 
6262  if (fabs(value) < 0.1)
6263  done = true;
6264 
6265  // check if too much time elapsed to reach the final spin rotator magnet current
6266  if (t.elapsed() > timeout) {
6267  done = true; // quit loop
6268  // emit warning
6269  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
6270  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6271  }
6272  } while (!done);
6273 
6274  // set spin rot angle to its virgin value, i.e. +11.1965°
6275  value = 11.1965;
6276  fSpinRotAngleKey->SetData((void*)&value, 1, TID_FLOAT);
6277 
6278  // increment command counter
6280 }
6281 
6282 //**********************************************************************
6283 // SetIgnoreAlarms
6284 //**********************************************************************
6291 {
6292  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6293  msg += arc->cmdString;
6294  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6295 
6296  msg = QString("Autorun running: ") + msg;
6297  emit StatusMsg(msg);
6298 
6299  if ((arc->param[0] == "yes") || (arc->param[0] == "1") || (arc->param[0] == "true"))
6300  fIgnoreAlarms = true;
6301  else
6302  fIgnoreAlarms = false;
6303 
6304  // increment command counter
6306 }
6307 
6308 //**********************************************************************
6309 // SetIgnoreClients
6310 //**********************************************************************
6317 {
6318  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6319  msg += arc->cmdString;
6320  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6321 
6322  msg = QString("Autorun running: ") + msg;
6323  emit StatusMsg(msg);
6324 
6325  if ((arc->param[0] == "yes") || (arc->param[0] == "1") || (arc->param[0] == "true"))
6326  fIgnoreClients = true;
6327  else
6328  fIgnoreClients = false;
6329 
6330  // increment command counter
6332 }
6333 
6334 //**********************************************************************
6335 // SetDump
6336 //**********************************************************************
6343 {
6344  QString msg("");
6345 
6346  // check the danfysik spin rot equipment is enabled
6347  if (!fEnabled["sample_eq"]) {
6348  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6349  msg += QString("PLemAutoRun::SetDump: sample equipment is disabled. Will do nothing here.");
6350  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6351  // increment command counter
6353  return;
6354  }
6355 
6356  msg = QString("(%1/%2) DUMP %3 (times)").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds).arg(arc->param[0]);
6357  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6358 
6359  msg = QString("Autorun running: ") + msg;
6360  emit StatusMsg(msg);
6361 
6362  // indicate that there is a dump
6363  fDumpInUse = true;
6364 
6365  // open file
6366  fDumpFile.setFileName(fAutoRunPath + fDumpFileName);
6367  fDumpFile.open(QIODevice::WriteOnly | QIODevice::Append);
6368 
6369  // get necessary information from the ODB
6370  static bool write_header = true;
6371 
6372  if (write_header) {
6373  write_header = false;
6374 
6375  // get temperature control channel
6376  char ctrl_ch[4];
6377  int size = sizeof(ctrl_ch);
6378  fSampleCtrlChKey->GetData(ctrl_ch, &size, TID_STRING);
6379 
6380  // get raw data voltage channels
6381  char sensor_ch[10][4];
6382  size = sizeof(sensor_ch[0]);
6383  for (int i=0; i<fSampleChannelKey->GetNumValues(); i++) {
6384  fSampleChannelKey->GetDataIndex(sensor_ch[i], &size, i, TID_STRING);
6385  }
6386 
6387  // get raw data sensor type assignement
6388  int sensor_type[10];
6389  size = sizeof(int);
6390  for (int i=0; i<fSampleSensorTypeKey->GetNumValues(); i++) {
6391  fSampleSensorTypeKey->GetDataIndex(&sensor_type[i], &size, i, TID_INT);
6392  }
6393 
6394  // write header (there can be more than one header in the RawVoltageOutput data file!!)
6395  QTextStream stream( &fDumpFile );
6396  stream << "%--------------------------------------------------------------------------" << Qt::endl;
6397  stream << "% Number of Entries : 21" << Qt::endl;
6398  stream << "% Number of Raw Data Reading : 8" << Qt::endl;
6399  stream << "% First Raw Data Reading Entry : 14" << Qt::endl;
6400  stream << "% Entry 1 : month" << Qt::endl;
6401  stream << "% Entry 2 : day" << Qt::endl;
6402  stream << "% Entry 3 : year" << Qt::endl;
6403  stream << "% Entry 4 : hour" << Qt::endl;
6404  stream << "% Entry 5 : minutes" << Qt::endl;
6405  stream << "% Entry 6 : seconds" << Qt::endl;
6406  stream << "% Entry 7 : msec" << Qt::endl;
6407  stream << "% Entry 8 : measured temperature of control channel = " << ctrl_ch << Qt::endl;
6408  stream << "% Entry 9 : pressure" << Qt::endl;
6409  stream << "% Entry 10 : heater output" << Qt::endl;
6410  stream << "% Entry 11 : setpoint temperature" << Qt::endl;
6411  stream << "% Entry 12 : heater range" << Qt::endl;
6412  stream << "% Entry 13 : BH1 flow measured" << Qt::endl;
6413  for (int i=0; i<8; i++) {
6414  stream << "% Entry " << 14+i << " : Raw Data Reading Entry " << i << " : Channel " << sensor_ch[i] << " : Sensor Type " << sensor_type[i] << Qt::endl;
6415  }
6416  stream << "%--------------------------------------------------------------------------" << Qt::endl;
6417  fDumpFile.flush();
6418  }
6419 
6420 
6421  // set the number of dumps to be made
6422  fDumpCounter = arc->param[0].toInt();
6423 
6424  // increment command counter
6426 }
6427 
6428 //**********************************************************************
6429 // SetFieldWEWL
6430 //**********************************************************************
6438 {
6439  // param: [0] field value, [1] field unit (A | G)
6440  float value, demand;
6441  int size, err_count;
6442  QString msg("");
6443 
6444  // check if FUG handling is disabled in lemAutoRun
6445  if (!fEnabled["fug_scfe"]) {
6446  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6447  msg += arc->cmdString;
6448  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
6449  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6450  // increment command counter
6452  return;
6453  }
6454 
6455  // set field power supply (possibly needed in setTitle)
6456  fFieldPwrSupply = "wew";
6457 
6458  // check if the wew_scfe frontend is running
6459  CheckClients();
6460  if (!fWEWFeRunning) { // error too severe to going on
6462  QString err = QString("PLemAutoRun::SetFieldWEWL: WEW Slowcontrol Frontend NOT running.\n")+
6463  QString(" Error too severe, will stop.");
6464  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
6466  QCoreApplication::exit(0);
6467  exit(0);
6468  }
6469 
6470  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6471  msg += arc->cmdString;
6472  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6473 
6474  msg = QString("Autorun running: ") + msg;
6475  emit StatusMsg(msg);
6476 
6477  // 2 things to be checked at this point: 1) WEWH needs to be OFF, 2) WEWL needs to be ON
6478  // make sure WEWH is OFF
6479  size = sizeof(value);
6480  fWEWOutputKey->GetDataIndex(&value, &size, WEWH_OUTPUT_CMD, TID_FLOAT);
6481  if (value == 1.0) {
6482  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWL", "**WARNING** WEWH still ON! Will ramp it to zero and switch it off first.");
6483  cm_yield(0);
6484  // WEWH demand to zero
6485  demand = 0.0;
6486  fWEWOutputKey->SetDataIndex((void*)&demand, WEWH_OUTPUT_CURRENT, TID_FLOAT);
6487  // make sure that WEWH demand current is zero
6488  err_count = 0;
6489  do {
6490  size = sizeof(value);
6491  fWEWInputKey->GetDataIndex(&value, &size, WEWH_INPUT_CURRENT, TID_FLOAT);
6492  Wait(500);
6493  } while ((value > 2.0) && (err_count++ < 120));
6494  // switch WEWH OFF
6495  demand = 0.0;
6496  fWEWOutputKey->SetDataIndex((void*)&demand, WEWH_OUTPUT_CMD, TID_FLOAT);
6497  // make sure WEWH is switched OFF
6498  err_count = 0;
6499  do {
6500  size = sizeof(value);
6501  fWEWInputKey->GetDataIndex(&value, &size, WEWH_INPUT_STATUS, TID_FLOAT);
6502  Wait(500);
6503  } while ((value != 0.0) && (err_count++ < 120));
6504  if (err_count >= 120) {
6505  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWL", "**WARNING** WEWH status is still ON. Please check! EPICS Gateway Problems?");
6506  cm_yield(0);
6507  }
6508  }
6509  Wait(500);
6510  // make sure WEWL is ON
6511  size = sizeof(value);
6512  fWEWOutputKey->GetDataIndex(&value, &size, WEWL_OUTPUT_CMD, TID_FLOAT);
6513  if (value == 0.0) {
6514  // just out of paranoia set the demand current first to zero
6515  demand = 0.0;
6516  fWEWOutputKey->SetDataIndex((void*)&demand, WEWL_OUTPUT_CURRENT, TID_FLOAT);
6517  Wait(500);
6518  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWL", "**WARNING** WEWL still OFF! Will switch it on first.");
6519  cm_yield(0);
6520  demand = 1.0;
6521  fWEWOutputKey->SetDataIndex((void*)&demand, WEWL_OUTPUT_CMD, TID_FLOAT);
6522  Wait(2000);
6523  }
6524 
6525  value = arc->param[0].toFloat();
6526  if (arc->param[1] == "G") { // field given in Gauss, convert it to Ampere for the WEWL
6527  float curVal = (value - fMagParamWew[0]) / fMagParamWew[1];
6528  value = curVal;
6529  }
6530 
6531  // check if WEW current value is too large for having the RA's on, if so switch the RA HV's off first
6532  // in the RA pulsed mode, this is not needed
6533  if ((value > fWEWCriticalCurrentRA) && !fRAPulsingEnabled) {
6534  float fval;
6535  int count = 0;
6536  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
6537  size = sizeof(fval);
6538  fHVDemandKey->GetDataIndex(&fval, &size, i, TID_FLOAT);
6539  if (fval > 2.0) {
6540  count++;
6541  }
6542  }
6543  if (count == 4) { // all RA HV's on
6544  // emit warning
6545  msg = QString("PLemAutoRun::SetFieldWEWL: demand current %1 > %2, hence RA HV's will be shut down").arg(value).arg(fWEWCriticalCurrentRA);
6546  emit ErrorMsg(1, 0, LAR_FORCED_RA_OFF, arc->lineNo, msg);
6547  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
6548  fval = 0.0;
6549  fHVDemandKey->SetDataIndex(&fval, i, TID_FLOAT);
6550  }
6551  Wait(5000); // sleep 5sec before proceeding
6552  }
6553  }
6554 
6555  // set field value
6556  fWEWOutputKey->SetDataIndex((void *)&value, WEWL_OUTPUT_CURRENT, TID_FLOAT);
6557 
6558  // check if field value is reached
6559  bool done = false;
6560  float timeout = fFieldTimeout * 1e3; // timeout in (msec)
6561  QElapsedTimer t;
6562  t.start();
6563  demand = value; // keep demand current
6564  do {
6565  // sleep for 5 sec before reading the next value
6566  Wait(5000);
6567 
6568  // read current value
6569  size = sizeof(value);
6570  fWEWInputKey->GetDataIndex(&value, &size, WEWL_INPUT_CURRENT, TID_FLOAT);
6571 
6572  // check if final current is reached
6573  if (fabs(demand-value) < fFieldAccuracy) {
6574  done = true;
6575  }
6576 
6577  if (t.elapsed() > timeout) {
6578  done = true; // quit loop
6579  // emit error
6580  msg = QString("Field (WEW) was not reached within %1 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand).arg(value);
6581  emit ErrorMsg(1, 0, LAR_FIELD_NOT_REACHED, arc->lineNo, msg);
6582  }
6583  } while (!done);
6584 
6585  // increment command counter
6587 }
6588 
6589 //**********************************************************************
6590 // SetFieldWEWH
6591 //**********************************************************************
6599 {
6600  // param: [0] field value, [1] field unit (A | G)
6601  float value, demand;
6602  int size, err_count;
6603  QString msg("");
6604 
6605  // check if FUG handling is disabled in lemAutoRun
6606  if (!fEnabled["fug_scfe"]) {
6607  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6608  msg += arc->cmdString;
6609  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
6610  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6611  // increment command counter
6613  return;
6614  }
6615 
6616  // set field power supply (possibly needed in setTitle)
6617  fFieldPwrSupply = "wew";
6618 
6619  // check if the wew_scfe frontend is running
6620  CheckClients();
6621  if (!fWEWFeRunning) { // error too severe to going on
6623  QString err = QString("PLemAutoRun::SetFieldWEWH: WEW Slowcontrol Frontend NOT running.\n")+
6624  QString(" Error too severe, will stop.");
6625  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
6627  QCoreApplication::exit(0);
6628  exit(0);
6629  }
6630 
6631  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6632  msg += arc->cmdString;
6633  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6634 
6635  msg = QString("Autorun running: ") + msg;
6636  emit StatusMsg(msg);
6637 
6638  // 2 things to be checked at this point: 1) WEWL needs to be OFF, 2) WEWH needs to be ON
6639  // make sure WEWL is OFF
6640  size = sizeof(value);
6641  fWEWOutputKey->GetDataIndex(&value, &size, WEWL_OUTPUT_CMD, TID_FLOAT);
6642  if (value == 1.0) {
6643  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWH", "**WARNING** WEWL still ON! Will ramp it to zero and switch it off first.");
6644  cm_yield(0);
6645  // WEWL demand to zero
6646  demand = 0.0;
6647  fWEWOutputKey->SetDataIndex((void*)&demand, WEWL_OUTPUT_CURRENT, TID_FLOAT);
6648  // make sure that WEWL demand current is zero
6649  err_count = 0;
6650  do {
6651  size = sizeof(value);
6652  fWEWInputKey->GetDataIndex(&value, &size, WEWL_INPUT_CURRENT, TID_FLOAT);
6653  Wait(500);
6654  } while ((value > 0.1) && (err_count++ < 120));
6655  // switch WEWL off
6656  demand = 0.0;
6657  fWEWOutputKey->SetDataIndex((void*)&demand, WEWL_OUTPUT_CMD, TID_FLOAT);
6658  // make sure WEWL is switched OFF
6659  err_count = 0;
6660  do {
6661  size = sizeof(value);
6662  fWEWInputKey->GetDataIndex(&value, &size, WEWL_INPUT_STATUS, TID_FLOAT);
6663  Wait(500);
6664  } while ((value != 0.0) && (err_count++ < 120));
6665  if (err_count >= 120) {
6666  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWH", "**WARNING** WEWL status is still ON. Please check! EPICS Gateway Problems?");
6667  cm_yield(0);
6668  }
6669  }
6670  Wait(500);
6671  // make sure WEWH is ON
6672  size = sizeof(value);
6673  fWEWOutputKey->GetDataIndex(&value, &size, WEWH_OUTPUT_CMD, TID_FLOAT);
6674  if (value == 0.0) {
6675  // just out of paranoia set the demand current first to zero
6676  demand = 0.0;
6677  fWEWOutputKey->SetDataIndex((void*)&demand, WEWH_OUTPUT_CURRENT, TID_FLOAT);
6678  Wait(500);
6679  cm_msg(MINFO, "PLemAutoRun::SetFieldWEWH", "**WARNING** WEWH still OFF! Will switch it on first.");
6680  cm_yield(0);
6681  demand = 1.0;
6682  fWEWOutputKey->SetDataIndex((void*)&demand, WEWH_OUTPUT_CMD, TID_FLOAT);
6683  Wait(1000);
6684  }
6685 
6686  value = arc->param[0].toFloat();
6687  if (arc->param[1] == "G") { // field given in Gauss, convert it to Ampere for the WEWH
6688  float curVal = (value - fMagParamWew[0]) / fMagParamWew[1];
6689  value = curVal;
6690  }
6691 
6692  // check if WEW current value is too large for having the RA's on, if so switch the RA HV's off first
6693  // in the RA pulsed mode, this is not needed
6694  if ((value > fWEWCriticalCurrentRA) && !fRAPulsingEnabled) {
6695  float fval;
6696  int count = 0;
6697  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
6698  size = sizeof(fval);
6699  fHVDemandKey->GetDataIndex(&fval, &size, i, TID_FLOAT);
6700  if (fval > 2.0) {
6701  count++;
6702  }
6703  }
6704  if (count == 4) { // all RA HV's on
6705  // emit warning
6706  msg = QString("PLemAutoRun::SetFieldWEWH: demand current %1 > %2, hence RA HV's will be shut down").arg(value).arg(fWEWCriticalCurrentRA);
6707  emit ErrorMsg(1, 0, LAR_FORCED_RA_OFF, arc->lineNo, msg);
6708  for (int i=HV_FUG_RAL; i<=HV_FUG_RAB; i++) {
6709  fval = 0.0;
6710  fHVDemandKey->SetDataIndex(&fval, i, TID_FLOAT);
6711  }
6712  Wait(5000); // sleep 5sec before proceeding
6713  }
6714  }
6715 
6716  // set field value
6717  fWEWOutputKey->SetDataIndex((void *)&value, WEWH_OUTPUT_CURRENT, TID_FLOAT);
6718 
6719  // check if field value is reached
6720  bool done = false;
6721  float timeout = fFieldTimeout * 1e3; // timeout in (msec)
6722  QElapsedTimer t;
6723  t.start();
6724  demand = value; // keep demand current
6725  do {
6726  // sleep for 5 sec before reading the next value
6727  Wait(5000);
6728 
6729  // read current value
6730  size = sizeof(value);
6731  fWEWInputKey->GetDataIndex(&value, &size, WEWH_INPUT_CURRENT, TID_FLOAT);
6732 
6733  // check if final current is reached
6734  if (fabs(demand) < 2.0) {
6735  if (fabs(demand-value) < 2.0)
6736  done = true;
6737  } else if (fabs(demand-value) < fFieldAccuracy) {
6738  done = true;
6739  }
6740 
6741  if (t.elapsed() > timeout) {
6742  done = true; // quit loop
6743  // emit error
6744  msg = QString("Field (WEW) was not reached within %1 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand).arg(value);
6745  emit ErrorMsg(1, 0, LAR_FIELD_NOT_REACHED, arc->lineNo, msg);
6746  }
6747  } while (!done);
6748 
6749  // increment command counter
6751 }
6752 
6753 //**********************************************************************
6754 // SetFieldDanfysik
6755 //**********************************************************************
6763 {
6764  // param: [0] current
6765 
6766  float value, demand;
6767  int size;
6768  QString msg("");
6769 
6770  // check if danfysik equipment is disabled in lemAutoRun
6771  if (!fEnabled["danfysik_eq"]) {
6772  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6773  msg += ": PLemAutoRun::SetFieldDanfysik: danfysik equipment disabled in lemAutoRun. Will do nothing here.";
6774  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6775  // increment command counter
6777  return;
6778  }
6779 
6780 
6781  // set field power supply (possibly needed in setTitle)
6782  fFieldPwrSupply = "danfysik";
6783 
6784  // check if the danfysik_scfe frontend is running
6785  CheckClients();
6786  if (!fDanfysikFeRunning) { // error too severe to going on
6788  QString err = QString("PLemAutoRun::SetFieldDanfysik: Danfysik Slowcontrol Frontend NOT running.\n")+
6789  QString(" Error too severe, will stop.");
6790  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
6792  QCoreApplication::exit(0);
6793  exit(0);
6794  }
6795 
6796  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6797  msg += arc->cmdString;
6798  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6799 
6800  msg = QString("Autorun running: ") + msg;
6801  emit StatusMsg(msg);
6802 
6803  value = arc->param[0].toFloat();
6804  if (arc->param[1] == "G") { // field given in Gauss, convert it to Ampere for the Danfysik
6805  float curVal = (value - fMagParamBpar[0]) / fMagParamBpar[1];
6806  value = curVal;
6807  }
6808 
6809  // set field value
6810  fDanfysikOutputKey->SetDataIndex((void *)&value, DANFYSIK_OUTPUT_CURRENT, TID_FLOAT);
6811 
6812  // check if field value is reached
6813  bool done = false;
6814  float timeout = fFieldTimeout * 1e3; // timeout in (msec)
6815  QElapsedTimer t;
6816  t.start();
6817  demand = value; // keep demand current
6818  do {
6819  // sleep for 5 sec before reading the next value
6820  Wait(5000);
6821 
6822  // read current value
6823  size = sizeof(value);
6824  fDanfysikInputKey->GetDataIndex(&value, &size, DANFYSIK_INPUT_CURRENT, TID_FLOAT);
6825 
6826  // check if final current is reached
6827  if (fabs(demand-value) < fFieldAccuracy) {
6828  done = true;
6829  }
6830 
6831  if (t.elapsed() > timeout) {
6832  done = true; // quit loop
6833  // emit error
6834  msg = QString("Field (Danfysik) was not reached within %1 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand).arg(value);
6835  emit ErrorMsg(1, 0, LAR_FIELD_NOT_REACHED, arc->lineNo, msg);
6836  }
6837  } while (!done);
6838 
6839  // increment command counter
6841 }
6842 
6843 //**********************************************************************
6844 // SetField
6845 //**********************************************************************
6854 {
6855  if (fSetupWewEnabled) { // WEW in use
6856  // get the current to decide which power supply to be used
6857  float value = arc->param[0].toFloat();
6858  if (arc->param[1] == "G") {
6859  float curVal = (value - fMagParamWew[0]) / fMagParamWew[1];
6860  value = curVal;
6861  }
6862  if (fabs(value) < 50.0)
6863  SetFieldWEWL(arc);
6864  else
6865  SetFieldWEWH(arc);
6866  } else if (fSetupBparEnabled) { // Bpar in use
6867  SetFieldDanfysik(arc);
6868  } else { // no magnets are enabled
6869  QString msg("");
6870  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6871  msg += "PLemAutoRun::SetField: no magnet is enabled. Will do nothing here.";
6872  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6873  // increment command counter
6875  }
6876 }
6877 
6878 //**********************************************************************
6879 // SetSpinRot
6880 //**********************************************************************
6887 {
6888  // param: [0] angle or 'off'; [1] 'ndg' if present
6889 
6890  QString msg("");
6891 
6892  // check if FUG handling is disabled in lemAutoRun
6893  if (!fEnabled["fug_scfe"]) {
6894  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6895  msg += arc->cmdString;
6896  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
6897  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6898  // increment command counter
6900  return;
6901  }
6902  if (!fEnabled["danfysik_spin_rot_eq"]) {
6903  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6904  msg += QString("PLemAutoRun::SetSpinRot: danfysik spin rot equipment disabled. Will do nothing here.");
6905  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6906  // increment command counter
6908  return;
6909  }
6910 
6911  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
6912  msg += arc->cmdString;
6913  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
6914 
6915  msg = QString("Autorun running: ") + msg;
6916  emit StatusMsg(msg);
6917 
6918  BOOL enabled;
6919 
6920  // only degauss if no 'ndg' is present and not SPIN_ROT off command is present
6921  if (((arc->noElements != 2) || (arc->param[1] != "ndg")) || (arc->param[0] == "off")) {
6922  // always first degauss the spin rotator. This way, the user doesn't need to think about the spin rotator's history
6923  enabled = FALSE;
6924  fSpinRotEnabledKey->SetData((void*)&enabled, 1, TID_BOOL);
6925 
6926  // set spin rotator HV's to zero
6927  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: start Spin Rot shutdown and degauss procedure.");
6928  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: shut down Spin Rot HV's.");
6929  cm_yield(0);
6930  // Loop over set HV. This is done this way to reduce hangers due to network problems
6931  int i, size;
6932  float hv_measured[HV_FUG_CHS];
6933  float value;
6934  float timeout;
6935  bool done, happy;
6936  QElapsedTimer t;
6937  for (i=0; i<HV_FUG_MAX_TRY; i++) {
6938  // set spin rotator hv's to zero
6939  value = 0.0;
6940  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_RIGHT_RODS, TID_FLOAT);
6941  value = 0.0;
6942  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_LEFT_RODS, TID_FLOAT);
6943  value = 0.0;
6944  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_LEFT_PLATE, TID_FLOAT);
6945  value = 0.0;
6946  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_RIGHT_PLATE, TID_FLOAT);
6947 
6948  if (fFugHvCheck) {
6949  // check that the spin rotator HV's are all zero
6950  done = false;
6951  happy = false;
6952  timeout = fHVTimeout * 1e3;
6953  t.start();
6954  do {
6955  // sleep for 5 sec before reading the next value
6956  Wait(5000);
6957 
6958  // read sample hv
6959  size = HV_FUG_CHS*sizeof(float);
6960  fHVMeasuredKey->GetData(&hv_measured, &size, TID_FLOAT);
6961 
6962  // check if all measured spin rotator HV's are zero
6963  int count = 0;
6964  for (int j=HV_FUG_RIGHT_RODS; j<=HV_FUG_RIGHT_PLATE; j++) {
6965  if (fabs(hv_measured[j]) < fHVAccuracy)
6966  count++;
6967  }
6968  if (count == 4) { // all spin rotator HV's down
6969  done = true;
6970  happy = true;
6971  }
6972 
6973  // check if too much time elapsed to reach the final sample hv
6974  if (t.elapsed() > timeout) {
6975  done = true; // quit loop
6976  // emit warning
6977  msg = QString("Couldn't shut down Spin Rot HVs within %1 sec: will give it another try in 120 sec.").arg(fHVTimeout);
6978  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
6979  }
6980  } while (!done);
6981 
6982  if (happy) // everything is OK, get out of the loop
6983  break;
6984 
6985  // wait 120 sec before retrial
6986  Wait(120000);
6987  } else { // NO FUG HV check, hence just wait a 1 min
6988  Wait(60000);
6989  break;
6990  }
6991  }
6992 
6993  if (i == HV_FUG_MAX_TRY) {
6995  // emit error
6996  msg = QString("Couldn't shut down the Spin Rotator HV, even after a few trials :-( .");
6997  emit ErrorMsg(1, 0, LAR_SAMPLE_HV_NOT_REACHED, arc->lineNo, msg);
6998  }
6999 
7000  // degauss spin rotator magnet
7001  // 1st set current to 0
7002  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set Spin Rot Magnet current to 0.");
7003  cm_yield(0);
7004  value = 0.0;
7005  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
7006  // check that measured current is going to 0
7007  done = false;
7008  timeout = fFieldTimeout * 1e3; // ms -> sec
7009  t.start(); // start timer
7010  do {
7011  // sleep for 1 sec before reading the next value
7012  Wait(1000);
7013 
7014  size = sizeof(value);
7015  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
7016 
7017  if (fabs(value) < 0.1)
7018  done = true;
7019 
7020  // check if too much time elapsed to reach the final spin rotator magnet current
7021  if (t.elapsed() > timeout) {
7022  done = true; // quit loop
7023  // emit warning
7024  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
7025  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
7026  }
7027  } while (!done);
7028 
7029  // wait 10 sec
7030  Wait(10000);
7031 
7032  // 2nd set current to +12.0
7033  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set Spin Rot Magnet current to 12.0 A.");
7034  cm_yield(0);
7035  value = 12.0;
7036  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
7037  // check that measured current is going to 12A
7038  done = false;
7039  timeout = fFieldTimeout * 1e3; // ms -> sec
7040  t.start(); // start timer
7041  do {
7042  // sleep for 1 sec before reading the next value
7043  Wait(1000);
7044 
7045  size = sizeof(value);
7046  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
7047 
7048  if (fabs(value-12.0) < 0.1)
7049  done = true;
7050 
7051  // check if too much time elapsed to reach the final spin rotator magnet current
7052  if (t.elapsed() > timeout) {
7053  done = true; // quit loop
7054  // emit warning
7055  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
7056  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
7057  }
7058  } while (!done);
7059 
7060  // wait 30 sec
7061  Wait(30000);
7062 
7063  // 3rd set current to -1.3A
7064  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set Spin Rot Magnet current to -1.3 A.");
7065  cm_yield(0);
7066  value = -1.3;
7067  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
7068  // check that measured current is going to -1.3A
7069  done = false;
7070  timeout = fFieldTimeout * 1e3; // ms -> sec
7071  t.start(); // start timer
7072  do {
7073  // sleep for 1 sec before reading the next value
7074  Wait(1000);
7075 
7076  size = sizeof(value);
7077  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
7078 
7079  if (fabs(value+1.3) < 0.1)
7080  done = true;
7081 
7082  // check if too much time elapsed to reach the final spin rotator magnet current
7083  if (t.elapsed() > timeout) {
7084  done = true; // quit loop
7085  // emit warning
7086  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
7087  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
7088  }
7089  } while (!done);
7090 
7091  // wait 30 sec
7092  Wait(30000);
7093 
7094  // 4th set current to 0
7095  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set Spin Rot Magnet current to 0 - done.");
7096  cm_yield(0);
7097  value = 0.0;
7098  fSpinRotMagOutputKey->SetDataIndex((void*)&value, SPINT_ROT_OUTPUT_CURRENT, TID_FLOAT);
7099  // check that measured current is going to 0
7100  done = false;
7101  timeout = fFieldTimeout * 1e3; // ms -> sec
7102  t.start(); // start timer
7103  do {
7104  // sleep for 1 sec before reading the next value
7105  Wait(1000);
7106 
7107  size = sizeof(value);
7108  fSpinRotMagInputKey->GetDataIndex(&value, &size, SPINT_ROT_INPUT_CURRENT, TID_FLOAT);
7109 
7110  if (fabs(value) < 0.1)
7111  done = true;
7112 
7113  // check if too much time elapsed to reach the final spin rotator magnet current
7114  if (t.elapsed() > timeout) {
7115  done = true; // quit loop
7116  // emit warning
7117  msg = QString("Couldn't set the Spin Rot Magnet current within %1 sec.").arg(fFieldTimeout);
7118  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
7119  }
7120  } while (!done);
7121  }
7122 
7123  if (arc->param[0] != "off") { // set spin rotation angle
7124  // check if it is necessary to enable the spin rotator
7125  int size = sizeof(enabled);
7126  fSpinRotEnabledKey->GetData((void*)&enabled, &size, TID_BOOL);
7127  cm_msg(MDEBUG, "SetSpinRot", "SetSpinRot: enabled=%d.", enabled);
7128  cm_yield(0);
7129  if (enabled == FALSE) {
7130  enabled = TRUE;
7131  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: enable spin rotator.");
7132  cm_yield(0);
7133  fSpinRotEnabledKey->SetData((void*)&enabled, 1, TID_BOOL);
7134  // wait for 10 sec in order to make sure that the analyzer got it enough time to have it updated
7135  Wait(10000);
7136  }
7137  float angle = arc->param[0].toFloat();
7138  cm_msg(MINFO, "SetSpinRot", "SetSpinRot: set spin rotation angle to %f", angle);
7139  cm_yield(0);
7140  fSpinRotAngleKey->SetData((void*)&angle, 1, TID_FLOAT);
7141 
7142  // wait 120 sec
7143  Wait(120000);
7144  }
7145 
7146  // increment command counter
7148 }
7149 
7150 //**********************************************************************
7151 // SetFOM
7152 //**********************************************************************
7159 {
7160  // param: [0] current
7161 
7162  int size, status;
7163  float standby, demand_current, measured_current;
7164  bool done;
7165  float timeout;
7166  QString msg("");
7167 
7168  if (!fEnabled["fom_eq"]) {
7169  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7170  msg += QString("PLemAutoRun::SetFOM: fom equipment disabled. Will do nothing here.");
7171  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7172  // increment command counter
7174  return;
7175  }
7176 
7177  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7178  msg += arc->cmdString;
7179  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7180 
7181  msg = QString("Autorun running: ") + msg;
7182  emit StatusMsg(msg);
7183 
7184  // get FOM standby flag from ODB
7185  size = sizeof(standby);
7186  status = fFOMOutputKey->GetDataIndex(&standby, &size, FOM_STANDBY, TID_FLOAT);
7187  if (status != DB_SUCCESS) { // error ODB reading
7188  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]);
7189  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7190 
7191  // increment command counter
7193  return;
7194  }
7195 
7196  // get current from parameter list
7197  demand_current = arc->param[0].toFloat();
7198 
7199  if (demand_current == 0.0) {
7200 
7201  // set current
7202  fFOMOutputKey->SetDataIndex(&demand_current, FOM_CURRENT_DEMAND, TID_FLOAT);
7203 
7204  // check that current is actually set
7205  done = false;
7206  timeout = 300 * 1e3; // timeout in (msec), i.e. 300 sec
7207  QElapsedTimer t;
7208  t.start();
7209  do {
7210  // sleep for 5 sec before reading the next value
7211  Wait(5000);
7212 
7213  // read current value
7214  size = sizeof(measured_current);
7215  fFOMInputKey->GetDataIndex(&measured_current, &size, FOM_CURRENT_MEASURED, TID_FLOAT);
7216 
7217  // check if final current is reached
7218  if (fabs(demand_current-measured_current) < fFOMCurrentAccuracy) {
7219  done = true;
7220  }
7221 
7222  if (t.elapsed() > timeout) {
7223  done = true; // quit loop
7224  // emit error
7225  msg = QString("Current (FOM) was not reached within 300 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand_current).arg(measured_current);
7226  emit ErrorMsg(1, 0, LAR_FOM_CURRENT_NOT_REACHED, arc->lineNo, msg);
7227  }
7228  } while (!done);
7229 
7230  // set FOM into standby mode
7231  standby = 1.0;
7232  fFOMOutputKey->SetDataIndex(&standby, FOM_STANDBY, TID_FLOAT);
7233 
7234  } else { // current != 0
7235 
7236  // check if FOM is on standby and, if yes, bring it back into operation
7237  if (standby != 0.0) {
7238  standby = 0.0;
7239  fFOMOutputKey->SetDataIndex(&standby, FOM_STANDBY, TID_FLOAT);
7240  }
7241 
7242  // wait 20sec so that FOM has the chance to wake up
7243  Wait(20000);
7244 
7245  // set current
7246  fFOMOutputKey->SetDataIndex(&demand_current, FOM_CURRENT_DEMAND, TID_FLOAT);
7247 
7248  // check that current is actually set
7249  done = false;
7250  timeout = 300 * 1e3; // timeout in (msec), i.e. 300 sec
7251  QElapsedTimer t;
7252  t.start();
7253  do {
7254  // sleep for 5 sec before reading the next value
7255  Wait(5000);
7256 
7257  // read current value
7258  size = sizeof(measured_current);
7259  fFOMInputKey->GetDataIndex(&measured_current, &size, FOM_CURRENT_MEASURED, TID_FLOAT);
7260 
7261  // check if final current is reached
7262  if (fabs(demand_current-measured_current) < fFOMCurrentAccuracy) {
7263  done = true;
7264  }
7265 
7266  if (t.elapsed() > timeout) {
7267  done = true; // quit loop
7268  // emit error
7269  msg = QString("Current (FOM) was not reached within 300 sec. (demand=%2, measured=%3)").arg(fFieldTimeout).arg(demand_current).arg(measured_current);
7270  emit ErrorMsg(1, 0, LAR_FOM_CURRENT_NOT_REACHED, arc->lineNo, msg);
7271  }
7272  } while (!done);
7273 
7274  }
7275 
7276  // increment command counter
7278 }
7279 
7280 //**********************************************************************
7281 // SetLEMSetup
7282 //**********************************************************************
7289 {
7290  QString msg("");
7291 
7292  if (!fEnabled["lem_setup_odb"]) {
7293  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7294  msg += QString("PLemAutoRun::SetLEMSetup: setup info ODB entries disabled. Will do nothing here.");
7295  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7296  // increment command counter
7298  return;
7299  }
7300 
7301  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7302  msg += arc->cmdString;
7303  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7304 
7305  msg = QString("Autorun running: ") + msg;
7306  emit StatusMsg(msg);
7307 
7308  fLemSetupKey->SetData((void *)arc->param[0].toLatin1().data(), 1, TID_STRING);
7309 
7310  // increment command counter
7312 }
7313 
7314 //**********************************************************************
7315 // SetModInfo
7316 //**********************************************************************
7323 {
7324  QString msg("");
7325 
7326  if (!fEnabled["mod_name_odb"] || !fEnabled["mod_date_odb"]) {
7327  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7328  msg += QString("PLemAutoRun::SetModInfo: moderator info ODB entries disabled. Will do nothing here.");
7329  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7330  // increment command counter
7332  return;
7333  }
7334 
7335  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7336  msg += arc->cmdString;
7337  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7338 
7339  msg = QString("Autorun running: ") + msg;
7340  emit StatusMsg(msg);
7341 
7342  fModNameKey->SetData((void *)arc->param[0].toLatin1().data(), 1, TID_STRING);
7343  fModDateKey->SetData((void *)arc->param[1].toLatin1().data(), 1, TID_STRING);
7344 
7345  // increment command counter
7347 }
7348 
7349 //**********************************************************************
7350 // CheckOdbType
7351 //**********************************************************************
7356 {
7357  int ival;
7358  float fval;
7359  double dval;
7360  bool ok;
7361  QString str(arc->param[2]);
7362 
7363  switch (type) {
7364  case TID_BYTE:
7365  case TID_CHAR:
7366  ival = str.toInt(&ok);
7367  if (!ok) { // conversion error
7368  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);
7369  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7370  return false;
7371  }
7372  if ((ival < 0) || (ival > 255)) { // range error
7373  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);
7374  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7375  return false;
7376  }
7377  break;
7378  case TID_SBYTE:
7379  ival = str.toInt(&ok);
7380  if (!ok) { // conversion error
7381  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_SBYTE is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7382  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7383  return false;
7384  }
7385  if ((ival < -128) || (ival > 127)) { // range error
7386  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_SBYTE; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7387  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7388  return false;
7389  }
7390  break;
7391  case TID_WORD:
7392  ival = str.toInt(&ok);
7393  if (!ok) { // conversion error
7394  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_WORD is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7395  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7396  return false;
7397  }
7398  if ((ival < 0) || (ival > 65535)) { // range error
7399  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_WORD; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7400  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7401  return false;
7402  }
7403  break;
7404  case TID_SHORT:
7405  ival = str.toInt(&ok);
7406  if (!ok) { // conversion error
7407  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_SHORT is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7408  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7409  return false;
7410  }
7411  if ((ival < -32768) || (ival > 32767)) { // range error
7412  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_SHORT; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7413  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7414  return false;
7415  }
7416  break;
7417  case TID_DWORD:
7418  ival = str.toInt(&ok);
7419  if (!ok) { // conversion error
7420  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_DWORD is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7421  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7422  return false;
7423  }
7424  if (ival < 0) { // range error 0 .. 2^31 - 1
7425  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_DWORD; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7426  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7427  return false;
7428  }
7429  break;
7430  case TID_INT:
7431  ival = str.toInt(&ok);
7432  if (!ok) { // conversion error
7433  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_INT is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7434  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7435  return false;
7436  }
7437  break;
7438  case TID_BOOL:
7439  ival = str.toInt(&ok);
7440  if (!ok) { // conversion error
7441  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_BOOL is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7442  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7443  return false;
7444  }
7445  if ((ival != 1) && (ival != 0)) { // range error 0 or 1
7446  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_BOOL; %1 out of range. See line no %2").arg(str).arg(arc->lineNo);
7447  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7448  return false;
7449  }
7450  break;
7451  case TID_FLOAT:
7452  fval = str.toFloat(&ok);
7453  if (!ok) { // conversion error
7454  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_FLOAT is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7455  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7456  return false;
7457  }
7458  break;
7459  case TID_DOUBLE:
7460  dval = str.toDouble(&ok);
7461  if (!ok) { // conversion error
7462  QString err = QString("PLemAutoRun::CheckOdbType: ODB key type TID_DOUBLE is not compatible with %1. See line no %2").arg(str).arg(arc->lineNo);
7463  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7464  return false;
7465  }
7466  break;
7467  case TID_STRING:
7468  break;
7469  default:
7470  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);
7471  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7472  return false;
7473  break;
7474  }
7475 
7476  return true;
7477 }
7478 
7479 //**********************************************************************
7480 // CheckForOdbSetDataCmds
7481 //**********************************************************************
7490 {
7491  PAutoRunCmdVector::Iterator iter;
7492 
7493  // go through all the cmd's and check for setOdbData cmds in order to perform the
7494  // necessary tests **before** starting the autorun.
7495  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
7496  if (iter->cmd == "setOdbData") {
7497  // check if set path makes sense
7498  PKey *setKey = 0;
7499  QString setPath = iter->param[0];
7500  setKey = new PKey(fExp, setPath);
7501  if (!setKey->IsValid()) { // key not found
7502  // error message
7503  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: Couldn't access ODB set key %1 from the ODB_SET_DATA cmd.").arg(iter->param[0]);
7504  emit StatusMsg(err);
7505  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7506  // clean up
7507  if (setKey) {
7508  delete setKey;
7509  setKey = 0;
7510  }
7511  return;
7512  }
7513 
7514  // check if the set index is within bounds
7515  if (!iter->param[1].isEmpty()) { // i.e. set_key_index is present
7516  int index = iter->param[1].toInt();
7517  if (index > setKey->GetNumValues()) { // index out of range
7518  // error message
7519  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: ODB_SET_DATA set index '%1' out of range (%2)!").arg(iter->param[1]).arg(setKey->GetNumValues());
7520  emit StatusMsg(err);
7521  emit ErrorMsg(1, 0, LAR_MIDAS_ODB_FAILURE, -1, err);
7522  // clean up
7523  if (setKey) {
7524  delete setKey;
7525  setKey = 0;
7526  }
7527  return;
7528  }
7529  }
7530 
7531  // check if the data type makes sense
7532  if (!CheckOdbType(setKey->GetType(), iter)) {
7533  // clean up
7534  if (setKey) {
7535  delete setKey;
7536  setKey = 0;
7537  }
7538  return;
7539  }
7540 
7541  // check if there is a readback part
7542  if (!iter->param[3].isEmpty()) { // i.e. odb_readback_key_path is present
7543 
7544  // get read path and check for aliases
7545  QString readPath = iter->param[3];
7546 
7547  PKey *readKey = new PKey(fExp, readPath);
7548  if (!readKey->IsValid()) { // key not found
7549  // error message
7550  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: Couldn't access ODB read key %1 from the ODB_SET_DATA cmd.").arg(iter->param[3]);
7551  emit StatusMsg(err);
7552  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7553  // clean up
7554  if (setKey) {
7555  delete setKey;
7556  setKey = 0;
7557  }
7558  if (readKey) {
7559  delete readKey;
7560  readKey = 0;
7561  }
7562  return;
7563  }
7564 
7565  if (!iter->param[4].isEmpty()) {
7566  int index = iter->param[4].toInt();
7567  if (index > readKey->GetNumValues()) { // index out of range
7568  // error message
7569  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: ODB_SET_DATA read index '%1'' out of range (%2)!").arg(index).arg(readKey->GetNumValues());
7570  emit StatusMsg(err);
7571  emit ErrorMsg(1, 0, LAR_MIDAS_ODB_FAILURE, -1, err);
7572  // clean up
7573  if (setKey) {
7574  delete setKey;
7575  setKey = 0;
7576  }
7577  if (readKey) {
7578  delete readKey;
7579  readKey = 0;
7580  }
7581  return;
7582  }
7583  }
7584  // clean up
7585  if (readKey) {
7586  delete readKey;
7587  readKey = 0;
7588  }
7589  }
7590 
7591  // clean up
7592  if (setKey) {
7593  delete setKey;
7594  setKey = 0;
7595  }
7596  }
7597 
7598  if (iter->cmd == "setOdbDataArray") {
7599  // check if set path makes sense
7600  PKey *setKey = 0;
7601  QString setPath = iter->param[0];
7602  setKey = new PKey(fExp, setPath);
7603  if (!setKey->IsValid()) { // key not found
7604  // error message
7605  QString err = QString("PLemAutoRun::CheckForOdbSetDataCmds: Couldn't access ODB set key %1 from the ODB_SET_DATA_ARRAY cmd.").arg(iter->param[0]);
7606  emit StatusMsg(err);
7607  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7608  // clean up
7609  if (setKey) {
7610  delete setKey;
7611  setKey = 0;
7612  }
7613  return;
7614  }
7615 
7616  // check type
7617  bool ok;
7618  QString type;
7619  for (int i=1; i<iter->noElements; i++) {
7620  // get out what type the key is in order to convert the set value string
7621  switch (setKey->GetType()) {
7622  case TID_BYTE:
7623  type = "TID_BYTE";
7624  if (iter->param[i].length() > 1)
7625  ok = false;
7626  break;
7627  case TID_CHAR:
7628  type = "TID_CHAR";
7629  if (iter->param[i].length() > 1)
7630  ok = false;
7631  break;
7632  case TID_SBYTE:
7633  type = "TID_SBYTE";
7634  if (iter->param[i].length() > 1)
7635  ok = false;
7636  break;
7637  case TID_WORD:
7638  type = "TID_WORD";
7639  iter->param[i].toInt(&ok);
7640  break;
7641  case TID_SHORT:
7642  type = "TID_SHORT";
7643  iter->param[i].toInt(&ok);
7644  break;
7645  case TID_DWORD:
7646  type = "TID_DWORD";
7647  iter->param[i].toInt(&ok);
7648  break;
7649  case TID_INT:
7650  type = "TID_INT";
7651  iter->param[i].toInt(&ok);
7652  break;
7653  case TID_BOOL:
7654  type = "TID_BOOL";
7655  iter->param[i].toInt(&ok);
7656  break;
7657  case TID_FLOAT:
7658  type = "TID_FLOAT";
7659  iter->param[i].toFloat(&ok);
7660  break;
7661  case TID_DOUBLE:
7662  type = "TID_DOUBLE";
7663  iter->param[i].toDouble(&ok);
7664  break;
7665  default:
7666  type = "TID_STRING";
7667  return;
7668  }
7669  if (!ok) { // error occured
7670  // error message
7671  QString err = QString("CheckForOdbSetDataCmds: Wrong data type of element '%1', should be '%2'").arg(iter->param[i]).arg(type);
7672  emit StatusMsg(err);
7673  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7674  }
7675  }
7676 
7677  // make sure that the number of elements fit
7678  if (iter->noElements-1 != setKey->GetNumValues()) {
7679  // error message
7680  QString err = QString("CheckForOdbSetDataCmds: Wrong number of element '%1', should be '%2'").arg(iter->noElements-1).arg(setKey->GetNumValues());
7681  emit StatusMsg(err);
7682  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7683  }
7684 
7685  // clean up
7686  if (setKey) {
7687  delete setKey;
7688  setKey = 0;
7689  }
7690  }
7691  }
7692 }
7693 
7694 //**********************************************************************
7695 // SetOdbData
7696 //**********************************************************************
7706 {
7707  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7708  msg += arc->cmdString;
7709  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7710 
7711  msg = QString("Autorun running: ") + msg;
7712  emit StatusMsg(msg);
7713 
7714  // convert all the necessary values
7715  int timeout = 0;
7716  double tolerance = 0.0;
7717  int ival = 0;
7718  float fval = 0.0;
7719  double dval = 0.0;
7720  double setVal;
7721  char sval[256];
7722  int typeTag = 0; // 0 = int etc.; 1 = float; 2 = double; 3 = string
7723  int setIndex;
7724  int readIndex;
7725 
7726  // check odb set path for alias
7727  QString setPath = arc->param[0];
7728 
7729  if (!arc->param[5].isEmpty()) // timeout given
7730  timeout = arc->param[5].toInt() * 1000; // timeout in (ms)
7731 
7732  if (!arc->param[6].isEmpty()) // tolerance given
7733  tolerance = arc->param[6].toDouble();
7734 
7735  // open set key
7736  PKey *setKey = 0;
7737  setKey = new PKey(fExp, setPath);
7738  if (!setKey->IsValid()) { // key not found
7739  // error message
7740  QString err = QString("PLemAutoRun::SetOdbData: Couldn't access ODB set key %1 from the ODB_SET_DATA cmd.").arg(arc->param[0]);
7741  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7742  // clean up
7743  if (setKey) {
7744  delete setKey;
7745  setKey = 0;
7746  }
7747  return;
7748  }
7749 
7750  // get out what type the key is in order to convert the set value string
7751  switch (setKey->GetType()) {
7752  case TID_BYTE:
7753  case TID_CHAR:
7754  case TID_SBYTE:
7755  case TID_WORD:
7756  case TID_SHORT:
7757  case TID_DWORD:
7758  case TID_INT:
7759  case TID_BOOL:
7760  ival = arc->param[2].toInt();
7761  setVal = ival;
7762  typeTag = 0;
7763  break;
7764  case TID_FLOAT:
7765  fval = arc->param[2].toFloat();
7766  setVal = fval;
7767  typeTag = 1;
7768  break;
7769  case TID_DOUBLE:
7770  dval = arc->param[2].toDouble();
7771  setVal = dval;
7772  typeTag = 2;
7773  break;
7774  case TID_STRING:
7775  typeTag = 3;
7776  break;
7777  default:
7778  return;
7779  }
7780 
7781  // open read key if needed
7782  PKey *readKey = 0;
7783  if (!arc->param[3].isEmpty()) { // i.e. odb_readback_key_path is present
7784  QString readPath = arc->param[3];
7785 
7786  readKey = new PKey(fExp, readPath);
7787  if (!readKey->IsValid()) { // key not found
7788  // error message
7789  QString err = QString("PLemAutoRun::SetOdbData: Couldn't access ODB read key %1 from the ODB_SET_DATA cmd.").arg(arc->param[3]);
7790  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7791  // clean up
7792  if (setKey) {
7793  delete setKey;
7794  setKey = 0;
7795  }
7796  if (readKey) {
7797  delete readKey;
7798  readKey = 0;
7799  }
7800  return;
7801  }
7802  }
7803 
7804  // set value
7805  if (arc->param[1].isEmpty()) { // no index given
7806  switch (typeTag) {
7807  case 0: // int etc.
7808  setKey->SetData(&ival, 1, setKey->GetType());
7809  break;
7810  case 1: // float
7811  setKey->SetData(&fval, 1, setKey->GetType());
7812  break;
7813  case 2: // double
7814  setKey->SetData(&dval, 1, setKey->GetType());
7815  break;
7816  case 3: // int etc.
7817  strcpy(sval, arc->param[2].toLatin1().data());
7818  setKey->SetData(sval, 1, setKey->GetType());
7819  break;
7820  default:
7821  break;
7822  }
7823  } else { // index given
7824  setIndex = arc->param[1].toInt();
7825  switch (typeTag) {
7826  case 0: // int etc.
7827  setKey->SetDataIndex(&ival, setIndex, setKey->GetType());
7828  break;
7829  case 1: // float
7830  setKey->SetDataIndex(&fval, setIndex, setKey->GetType());
7831  break;
7832  case 2: // double
7833  setKey->SetDataIndex(&dval, setIndex, setKey->GetType());
7834  break;
7835  case 3: // int etc.
7836  strcpy(sval, arc->param[2].toLatin1().data());
7837  setKey->SetDataIndex(sval, setIndex, setKey->GetType());
7838  break;
7839  default:
7840  break;
7841  }
7842  }
7843 
7844  if (readKey) { // readback key given, i.e. not only set ODB value, but compare it with its readback value
7845  // check if read index is given
7846  if (!arc->param[4].isEmpty())
7847  readIndex = arc->param[4].toInt();
7848  else
7849  readIndex = -1;
7850 
7851  QElapsedTimer time;
7852  bool done = false;
7853  INT size;
7854  double readVal = 0.0;
7855 
7856  time.start();
7857  do {
7858  // get value
7859  if (readIndex < 0) { // not an array
7860  switch (readKey->GetType()) {
7861  case TID_BYTE:
7862  case TID_CHAR:
7863  case TID_SBYTE:
7864  case TID_WORD:
7865  case TID_SHORT:
7866  case TID_DWORD:
7867  case TID_INT:
7868  case TID_BOOL:
7869  size = sizeof(ival);
7870  readKey->GetData(&ival, &size, readKey->GetType());
7871  readVal = ival;
7872  break;
7873  case TID_FLOAT:
7874  size = sizeof(fval);
7875  readKey->GetData(&fval, &size, readKey->GetType());
7876  readVal = fval;
7877  break;
7878  case TID_DOUBLE:
7879  size = sizeof(dval);
7880  readKey->GetData(&dval, &size, readKey->GetType());
7881  readVal = dval;
7882  break;
7883  default:
7884  break;
7885  }
7886  } else { // value from an array
7887  switch (readKey->GetType()) {
7888  case TID_BYTE:
7889  case TID_CHAR:
7890  case TID_SBYTE:
7891  case TID_WORD:
7892  case TID_SHORT:
7893  case TID_DWORD:
7894  case TID_INT:
7895  case TID_BOOL:
7896  size = sizeof(ival);
7897  readKey->GetDataIndex(&ival, &size, readIndex, readKey->GetType());
7898  readVal = ival;
7899  break;
7900  case TID_FLOAT:
7901  size = sizeof(fval);
7902  readKey->GetDataIndex(&fval, &size, readIndex, readKey->GetType());
7903  readVal = fval;
7904  break;
7905  case TID_DOUBLE:
7906  size = sizeof(dval);
7907  readKey->GetDataIndex(&dval, &size, readIndex, readKey->GetType());
7908  readVal = dval;
7909  break;
7910  default:
7911  break;
7912  }
7913  }
7914 
7915  // check if job is done
7916  if (fabs(setVal-readVal) < tolerance) {
7917  done = true;
7918  }
7919 
7920  // sleep for 2 sec before reading the next value
7921  Wait(2000);
7922  } while((time.elapsed() < timeout) && !done);
7923 
7924  if (!done) { // timeout fired before job was done
7925  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);
7926  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
7927  return;
7928  }
7929  }
7930 
7931  // clean up
7932  if (setKey) {
7933  delete setKey;
7934  setKey = 0;
7935  }
7936  if (readKey) {
7937  delete readKey;
7938  readKey = 0;
7939  }
7940 
7941  // increment command counter
7943 }
7944 
7945 //**********************************************************************
7946 // SetOdbDataArray
7947 //**********************************************************************
7954 {
7955  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
7956  msg += arc->cmdString;
7957  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
7958 
7959  msg = QString("Autorun running: ") + msg;
7960  emit StatusMsg(msg);
7961 
7962  // check odb set path for alias
7963  QString setPath = arc->param[0];
7964 
7965  // open set key
7966  PKey *setKey = 0;
7967  setKey = new PKey(fExp, setPath);
7968  if (!setKey->IsValid()) { // key not found
7969  // error message
7970  QString err = QString("PLemAutoRun::SetOdbData: Couldn't access ODB set key %1 from the ODB_SET_DATA cmd.").arg(arc->param[0]);
7971  emit ErrorMsg(1, 0, LAR_MIDAS_KEY_FAILURE, -1, err);
7972  // clean up
7973  if (setKey) {
7974  delete setKey;
7975  setKey = 0;
7976  }
7977  return;
7978  }
7979 
7980  // fill data
7981  float *data = new float[arc->noElements-1];
7982  for (int i=1; i<arc->noElements; i++)
7983  data[i-1] = arc->param[i].toFloat();
7984 
7985  // set it in ODB
7986  setKey->SetData(data, arc->noElements-1, TID_FLOAT);
7987 
7988  // clean up
7989  if (data) {
7990  delete data;
7991  data = 0;
7992  }
7993  if (setKey) {
7994  delete setKey;
7995  setKey = 0;
7996  }
7997 
7998  // increment command counter
8000 }
8001 
8002 //**********************************************************************
8003 // SetSampleHV
8004 //**********************************************************************
8011 {
8012  int size;
8013  int i;
8014  float value;
8015  float demand;
8016  QString msg("");
8017 
8018  // check if FUG handling is disabled in lemAutoRun
8019  if (!fEnabled["fug_scfe"]) {
8020  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8021  msg += arc->cmdString;
8022  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
8023  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8024  // increment command counter
8026  return;
8027  }
8028  // check if FUG equipment is disabled in lemAutoRun
8029  if (!fEnabled["fug_eq"]) {
8030  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8031  msg += "PLemAutoRun::SetSampleHV: FUG equipment disabled in lemAutoRun. Will do nothing here.";
8032  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8033  // increment command counter
8035  return;
8036  }
8037 
8038  // check if the hv_fug_scfe frontend is running
8039  CheckClients();
8040  if (!fHVFeRunning) { // error too severe to going on
8042  QString err = QString("PLemAutoRun::SetSampleHV: Slowcontrol Frontend NOT running.\n")+
8043  QString(" Error too severe, will stop.");
8044  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
8046  QCoreApplication::exit(0);
8047  exit(0);
8048  }
8049 
8050  // send command notifier
8051  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8052  msg += arc->cmdString;
8053  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8054 
8055  msg = QString("Autorun running: ") + msg;
8056  emit StatusMsg(msg);
8057 
8058  // Loop over set HV. This is done this way to reduce hangers due to network problems
8059  for (i=0; i<HV_FUG_MAX_TRY; i++) {
8060  // set sample hv
8061  size = sizeof(value);
8062  value = arc->param[0].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8063  fHVDemandKey->SetDataIndex((void *)&value, HV_FUG_SAMPLE, TID_FLOAT);
8064 
8065  if (fFugHvCheck) {
8066  // check that the final sample hv is reached reached it
8067  bool done = false;
8068  bool happy = false;
8069  float timeout = fHVTimeout * 1e3;
8070  QElapsedTimer t;
8071  t.start();
8072  demand = value; // keep demand hv
8073  do {
8074  // sleep for 5 sec before reading the next value
8075  Wait(5000);
8076 
8077  // read sample hv
8078  size = sizeof(value);
8079  fHVMeasuredKey->GetDataIndex(&value, &size, HV_FUG_SAMPLE, TID_FLOAT);
8080 
8081  // check if final sample hv is reached
8082  if (fabs(demand-value) < fHVAccuracy) { // final hv reached within fHVAccuracy
8083  done = true;
8084  happy = true;
8085  }
8086 
8087  // check if too much time elapsed to reach the final sample hv
8088  if (t.elapsed() > timeout) {
8089  done = true; // quit loop
8090  // emit warning
8091  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);
8092  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
8093  }
8094  } while (!done);
8095 
8096  if (happy) // everything is OK, get out of the loop
8097  break;
8098 
8099  // wait 120 sec before retrial
8100  Wait(120000);
8101  } else { // NO FUG HV check, hence just wait a 1 min
8102  Wait(60000);
8103  break;
8104  }
8105  }
8106 
8107  if (i == HV_FUG_MAX_TRY) {
8109  // emit error
8110  msg = QString("Couldn't set Sample HV of %1 (kV), even after a few trials :-( .").arg(demand);
8111  emit ErrorMsg(1, 0, LAR_SAMPLE_HV_NOT_REACHED, arc->lineNo, msg);
8112  }
8113 
8114  // increment command counter
8116 }
8117 
8118 //**********************************************************************
8119 // SetRA_HV
8120 //**********************************************************************
8128 {
8129  int size;
8130  int i;
8131  float value[4];
8132  float demand[4];
8133  QString msg("");
8134 
8135  // check if FUG handling is disabled in lemAutoRun
8136  if (!fEnabled["fug_scfe"]) {
8137  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8138  msg += arc->cmdString;
8139  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
8140  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8141  // increment command counter
8143  return;
8144  }
8145  // check if FUG equipment is disabled in lemAutoRun
8146  if (!fEnabled["fug_eq"]) {
8147  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8148  msg += "PLemAutoRun::SetRA_HV: FUG equipment disabled in lemAutoRun. Will do nothing here.";
8149  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8150  // increment command counter
8152  return;
8153  }
8154 
8155  // check if the hv_fug_scfe frontend is running
8156  CheckClients();
8157  if (!fHVFeRunning) { // error too severe to going on
8159  QString err = QString("PLemAutoRun::SetRA_HV: Slowcontrol Frontend NOT running.\n")+
8160  QString(" Error too severe, will stop.");
8161  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
8163  QCoreApplication::exit(0);
8164  exit(0);
8165  }
8166 
8167  // send command notifier
8168  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8169  msg += arc->cmdString;
8170  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8171 
8172  msg = QString("Autorun running: ") + msg;
8173  emit StatusMsg(msg);
8174 
8175  // Loop over set HV. This is done this way to reduce hangers due to network problems
8176  for (i=0; i<HV_FUG_MAX_TRY; i++) {
8177  // set RA HV left
8178  size = sizeof(float);
8179  value[0] = arc->param[0].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8180  fHVDemandKey->SetDataIndex((void *)&value[0], HV_FUG_RAL, TID_FLOAT);
8181  // set RA HV right
8182  size = sizeof(float);
8183  value[1] = arc->param[1].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8184  fHVDemandKey->SetDataIndex((void *)&value[1], HV_FUG_RAR, TID_FLOAT);
8185  if (arc->noElements == 4) {
8186  // set RA HV top
8187  size = sizeof(float);
8188  value[2] = arc->param[2].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8189  fHVDemandKey->SetDataIndex((void *)&value[2], HV_FUG_RAT, TID_FLOAT);
8190  // set RA HV bottom
8191  size = sizeof(float);
8192  value[3] = arc->param[3].toFloat() + (-1)*(i%2)*0.001; // i-term to force the DD set command being executed
8193  fHVDemandKey->SetDataIndex((void *)&value[3], HV_FUG_RAB, TID_FLOAT);
8194  }
8195 
8196  if (fFugHvCheck) {
8197  // check that the final sample hv is reached reached it
8198  bool done = false;
8199  bool happy = false;
8200  float timeout = fHVTimeout * 1e3;
8201  QElapsedTimer t;
8202  t.start();
8203  // keep demand hv
8204  for (int j=0; j<arc->noElements; j++) {
8205  demand[j] = value[j];
8206  }
8207 
8208  do {
8209  // sleep for 5 sec before reading the next value
8210  Wait(5000);
8211 
8212  // read RA left HV
8213  size = sizeof(float);
8214  fHVMeasuredKey->GetDataIndex(&value[0], &size, HV_FUG_RAL, TID_FLOAT);
8215  // read RA right HV
8216  size = sizeof(float);
8217  fHVMeasuredKey->GetDataIndex(&value[1], &size, HV_FUG_RAR, TID_FLOAT);
8218  if (arc->noElements == 4) { // L,R,T,B given
8219  // read RA top HV
8220  size = sizeof(float);
8221  fHVMeasuredKey->GetDataIndex(&value[2], &size, HV_FUG_RAT, TID_FLOAT);
8222  // read RA bottom HV
8223  size = sizeof(float);
8224  fHVMeasuredKey->GetDataIndex(&value[3], &size, HV_FUG_RAB, TID_FLOAT);
8225  }
8226 
8227  // check if final RA hv's are reached
8228  if (arc->noElements == 4) { // L,R,T,B given
8229  if ((fabs(demand[0]-value[0]) < fHVAccuracy) &&
8230  (fabs(demand[1]-value[1]) < fHVAccuracy) &&
8231  (fabs(demand[2]-value[2]) < fHVAccuracy) &&
8232  (fabs(demand[3]-value[3]) < fHVAccuracy)) { // final hv reached within fHVAccuracy
8233  done = true;
8234  happy = true;
8235  }
8236  } else {// L,R given
8237  if ((fabs(demand[0]-value[0]) < fHVAccuracy) &&
8238  (fabs(demand[1]-value[1]) < fHVAccuracy)) { // final hv reached within fHVAccuracy
8239  done = true;
8240  happy = true;
8241  }
8242  }
8243 
8244  // check if too much time elapsed to reach the final sample hv
8245  if (t.elapsed() > timeout) {
8246  done = true; // quit loop
8247  // emit warning
8248  if (arc->noElements == 2) { // L,R given
8249  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);
8250  } else { // L,R,T,B given
8251  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);
8252  }
8253  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
8254  }
8255  } while (!done);
8256 
8257  if (happy) // everything is OK, get out of the loop
8258  break;
8259 
8260  // wait 120 sec before retrial
8261  Wait(120000);
8262  } else { // NO FUG HV check, hence just wait a 1 min
8263  Wait(60000);
8264  break;
8265  }
8266  }
8267 
8268  if (i == HV_FUG_MAX_TRY) {
8270  if (arc->noElements == 2) { // L,R given
8271  msg = QString("RA HV of (%1/%2) (kV), was not reached even after several trials :-( ").arg(arc->param[0]).arg(arc->param[1]);
8272  } else { // L,R,T,B given
8273  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]);
8274  }
8275  emit ErrorMsg(1, 0, LAR_SAMPLE_HV_NOT_REACHED, arc->lineNo, msg);
8276  }
8277 
8278  // increment command counter
8280 }
8281 
8282 //**********************************************************************
8283 // CheckForTransportHvCmd
8284 //**********************************************************************
8295 {
8296  PAutoRunCmdVector::Iterator iter;
8297 
8298  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
8299  if (iter->cmd == "setTransportHV") {
8300  // check if the hv setting file exists
8301  QString filePath = fHvSettingsPath + iter->param[0];
8302  QFileInfo fileInfo(filePath);
8303  if (!fileInfo.exists()) {
8304  QString msg = filePath + QString(" does not exist! Fix that first!");
8305  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
8306 
8307  UpdateWebPage(iter, HTML_PARSE_ERROR, iter->lineNo, msg);
8308 
8309  msg = QString("Autorun stopped: Skript failure");
8310  emit StatusMsg(msg);
8311 
8312  return false;
8313  }
8314 
8315  // check the file is a proper hv setting file
8316  if (!LoadHvSettings(iter, filePath, iter->lineNo, true)) {
8317  return false;
8318  }
8319  }
8320  }
8321 
8322  return true;
8323 }
8324 
8325 //**********************************************************************
8326 // LoadHvSettings
8327 //**********************************************************************
8338 bool PLemAutoRun::LoadHvSettings(PAutoRunCmdVector::Iterator iter, QString fln, int lineNo, bool simulated)
8339 {
8340  // check if FUG equipment is disabled in lemAutoRun
8341  if (!fEnabled["fug_eq"]) {
8342  return true;
8343  }
8344 
8345  // try to load the HV settings file
8346  if (!QFile::exists(fln)) {
8347  QString err = "lemAutoRun: Couldn't find HV setting file: " + fln;
8348  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, err);
8349  return false;
8350  }
8351 
8352  PLemHvSettingsFileParser handler(fln);
8353  if (!handler.parseIsValid()) {
8354  QString err = "lemAutoRun: Couldn't parse HV setting file: " + fln;
8355  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, err);
8356  return false;
8357  }
8358 
8359  QString errMsg = "";
8360  if (!handler.isValid(errMsg)) {
8361  UpdateWebPage(iter, HTML_PARSE_ERROR, iter->lineNo, errMsg);
8362 
8363  QString err = "lemAutoRun: Couldn't read HV setting file: " + fln;
8364  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, errMsg);
8365 
8366  return false;
8367  }
8368 
8369  if (simulated)
8370  return true;
8371 
8372  QVector<int> *hvCh = handler.GetChNo();
8373  QVector<QString> *hvChName = handler.GetHvChNames();
8374  QVector<float> *hvDemand = handler.GetHvDemands();
8375  QVector<float> *currentLimit = handler.GetCurrentLimits();
8376 
8377  float *pHvDemand = (float*)malloc(hvDemand->size()*sizeof(float));
8378  float *pCurrentLimit = (float*)malloc(currentLimit->size()*sizeof(float));
8379  float *pHvMeasured = (float*)malloc(hvDemand->size()*sizeof(float));
8380 
8381  // current magnetic field value
8382  int size = sizeof(float);
8383  float magFieldValue{0.0};
8384  fMagFieldKey->GetData(&magFieldValue, &size, TID_FLOAT);
8385  for (int i=0; i<hvCh->size(); i++) {
8386  if (fSetupWewEnabled && hvChName->at(i).startsWith("RA-") && (magFieldValue > 110.0)) { // WEW in use && HV RA channel && B>110G
8387  pHvDemand[hvCh->at(i)-1] = 0.0;
8388  if (hvChName->at(i).startsWith("RA-L")) {
8389  cm_msg(MINFO, "lemAutoRun", "The field of WEW (%0.2f G) > 110.0 G. Hence, the RA HV-values are set to 0.0kV.", magFieldValue);
8390  cm_yield(0);
8391  }
8392  } else {
8393  pHvDemand[hvCh->at(i)-1] = hvDemand->at(i);
8394  }
8395  pCurrentLimit[hvCh->at(i)-1] = currentLimit->at(i);
8396  }
8397 
8398  // set current limit values
8399  QString path = QString("/Equipment/HV/Settings/Current Limit");
8400  PKey currentLimitKey(fExp, path);
8401  if (!currentLimitKey.IsValid()) {
8402  errMsg = "**ERROR** couldn't obtain the current limit ODB key";
8403 
8404  UpdateWebPage(iter, HTML_PARSE_ERROR, iter->lineNo, errMsg);
8405 
8406  QString err = "lemAutoRun: Couldn't read HV setting file: " + fln;
8407  emit ErrorMsg(1, 0, LAR_XML_FILE_MISSING, -1, errMsg);
8408 
8409  // clean up
8410  free(pHvDemand);
8411  free(pCurrentLimit);
8412 
8413  return false;
8414  }
8415  currentLimitKey.SetData(pCurrentLimit, currentLimit->size(), TID_FLOAT);
8416 
8417  // set HV values
8418  fHVDemandKey->SetData(pHvDemand, hvDemand->size(), TID_FLOAT);
8419 
8420  if (fFugHvCheck) {
8421  // make sure that the demanded HV's are actually reached within a given time
8422  bool done = false;
8423  QVector<int> hv_reached;
8424  hv_reached.resize(hvDemand->size());
8425  for (int i=0; i<hv_reached.size(); i++)
8426  hv_reached[i] = 0;
8427  float timeout = fHVTimeout * 1e3;
8428  QElapsedTimer t;
8429  t.start();
8430  int size;
8431  do {
8432  // sleep for 5 sec before reading the next value
8433  Wait(5000);
8434 
8435  // get the measured HV's
8436  size = hvDemand->size()*sizeof(float);
8437  fHVMeasuredKey->GetData(pHvMeasured, &size, TID_FLOAT);
8438 
8439  // check if the HV's reached the demand values
8440  size = 0;
8441  for (int i=0; i<hvDemand->size(); i++) {
8442  if (fabs(pHvDemand[i]-pHvMeasured[i]) < fHVAccuracy) { // final hv reached within fHVAccuracy
8443  hv_reached[i] = 1;
8444  }
8445  size += hv_reached[i];
8446  }
8447 
8448  // if all HV's reached their demand values
8449  if (size == (int)hvDemand->size())
8450  done = true;
8451 
8452  // check if too much time elapsed to reach the final HV settings
8453  if (t.elapsed() > timeout) {
8454  done = true; // quit loop
8455  // emit warning
8456  QString msg = QString("HV settings could not be reached within %3 sec.").arg(fHVTimeout);
8457  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, lineNo, msg);
8458  }
8459  } while (!done);
8460  } else { // NO FUG HV check, hence just wait a 1 min
8461  Wait(60000);
8462  }
8463 
8464  // clean up
8465  free(pHvDemand);
8466  free(pCurrentLimit);
8467  free(pHvMeasured);
8468 
8469  return true;
8470 }
8471 
8472 //**********************************************************************
8473 // SetTransportHV
8474 //**********************************************************************
8481 {
8482  QString msg("");
8483 
8484  // check if FUG handling is disabled in lemAutoRun
8485  if (!fEnabled["fug_scfe"]) {
8486  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8487  msg += arc->cmdString;
8488  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
8489  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8490  // increment command counter
8492  return;
8493  }
8494  // check if FUG equipment is disabled in lemAutoRun
8495  if (!fEnabled["fug_eq"]) {
8496  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8497  msg += "PLemAutoRun::SetTransportHV: FUG equipment disabled in lemAutoRun. Will do nothing here.";
8498  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8499  // increment command counter
8501  return;
8502  }
8503 
8504  // send command notifier
8505  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8506  msg += arc->cmdString;
8507  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8508 
8509  msg = QString("Autorun running: ") + msg;
8510  emit StatusMsg(msg);
8511 
8512  QString filePath = fHvSettingsPath + arc->param[0];
8513  LoadHvSettings(arc, filePath, arc->lineNo);
8514 
8515  // increment command counter
8517 }
8518 
8519 //**********************************************************************
8520 // SetHvOff
8521 //**********************************************************************
8526 {
8527  QString msg("");
8528 
8529  // check if FUG handling is disabled in lemAutoRun
8530  if (!fEnabled["fug_scfe"]) {
8531  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8532  msg += arc->cmdString;
8533  msg += ": FUG disabled in lemAutoRun. Will do nothing here.";
8534  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8535  // increment command counter
8537  return;
8538  }
8539  // check if FUG equipment is disabled in lemAutoRun
8540  if (!fEnabled["fug_eq"]) {
8541  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8542  msg += "PLemAutoRun::SetHvOff: FUG equipment disabled in lemAutoRun. Will do nothing here.";
8543  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8544  // increment command counter
8546  return;
8547  }
8548 
8549  // send command notifier
8550  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
8551  msg += arc->cmdString;
8552  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
8553 
8554  msg = QString("Autorun running: ") + msg;
8555  emit StatusMsg(msg);
8556 
8557  int size;
8558  float fval[4] = {0.0, 0.0, 0.0, 0.0};
8559  QElapsedTimer t;
8560  float timeout = 300 * 1e3; // 5 min
8561  bool done=false;
8562  if (arc->param[0].contains("mc", Qt::CaseInsensitive)) {
8563  // switch off FUG's in the MC
8564  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down FUG HV's in the Moderator Chamber ...");
8565  cm_yield(0);
8566  for (int i=HV_FUG_MOD; i<=HV_FUG_MIRROR; i++)
8567  fHVDemandKey->SetDataIndex((void *)&fval[0], i, TID_FLOAT);
8568  // switch off MCP1 HV
8569  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down MCP1 HV in the Moderator Chamber ...");
8570  cm_yield(0);
8571  fHVDetectorDemandKey->SetDataIndex((void *)&fval[0], HV_NHQ_MCP1, TID_FLOAT);
8572  // wait until MCP1 HV is small enough
8573  t.start();
8574  do {
8575  // sleep for 5 sec before reading the next value
8576  Wait(5000);
8577 
8578  // read MCP1 HV
8579  size = sizeof(float);
8580  fHVDetectorMeasuredKey->GetDataIndex(&fval[0], &size, HV_NHQ_MCP1, TID_FLOAT);
8581 
8582  if (fabs(fval[0]) < 0.3) {
8583  done = true;
8584  }
8585 
8586  // check if too much time elapsed to reach the final sample hv
8587  if (t.elapsed() > timeout) {
8588  done = true; // quit loop
8589  // emit warning
8590  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]);
8591  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
8592  }
8593  } while (!done);
8594  } else if (arc->param[0].contains("tc", Qt::CaseInsensitive)) {
8595  // switch off FUG's in the TC
8596  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down FUG HV's in the Trigger Chamber ...");
8597  cm_yield(0);
8598  // Spin Rot Off
8599  for (int i=HV_FUG_RIGHT_RODS; i<=HV_FUG_RIGHT_PLATE; i++)
8600  fHVDemandKey->SetDataIndex((void *)&fval[0], i, TID_FLOAT);
8601  for (int i=HV_FUG_LENSE_2; i<=HV_FUG_LENSE_3; i++)
8602  fHVDemandKey->SetDataIndex((void *)&fval[0], i, TID_FLOAT);
8603  // switch off TD HV
8604  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down TD HV's in the Trigger Chamber ...");
8605  cm_yield(0);
8606  for (int i=HV_NHQ_TD_FIRST; i<=HV_NHQ_TD_LAST; i++)
8607  fHVDetectorDemandKey->SetDataIndex((void *)&fval[0], i, TID_FLOAT);
8608  // wait until TD HV is small enough
8609  t.start();
8610  do {
8611  // sleep for 5 sec before reading the next value
8612  Wait(5000);
8613 
8614  // read TD HV's
8615  for (int i=HV_NHQ_TD_FIRST; i<=HV_NHQ_TD_LAST; i++) {
8616  size = sizeof(float);
8617  fHVDetectorMeasuredKey->GetDataIndex(&fval[i], &size, i, TID_FLOAT);
8618  }
8619 
8620  if ((fabs(fval[0]) < 0.3) && (fabs(fval[1]) < 0.3) && (fabs(fval[2]) < 0.3) && (fabs(fval[4]) < 0.3)) {
8621  done = true;
8622  }
8623 
8624  // check if too much time elapsed to reach the final sample hv
8625  if (t.elapsed() > timeout) {
8626  done = true; // quit loop
8627  // emit warning
8628  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]);
8629  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, arc->lineNo, msg);
8630  }
8631  } while (!done);
8632  } else if (arc->param[0].contains("sc", Qt::CaseInsensitive)) {
8633  // switch off FUG's in the SC
8634  cm_msg(MINFO, "PLemAutoRun::SetHvOff", "PLemAutoRun::SetHvOff: shut down FUG HV's in the Trigger Chamber ...");
8635  cm_yield(0);
8636  for (int i=HV_FUG_RAL; i<=HV_FUG_SAMPLE; i++)
8637  fHVDemandKey->SetDataIndex((void *)&fval, i, TID_FLOAT);
8638  }
8639 
8640  // increment command counter
8642 }
8643 
8644 //**********************************************************************
8645 // SetSampleLSZoneSettings
8646 //**********************************************************************
8653 {
8654  // check if sample equipment is disabled in lemAutoRun
8655  if (!fEnabled["sample_eq"]) {
8656  return;
8657  }
8658 
8659  PAutoRunCmdVector::Iterator iter;
8660  bool check_needed = false;
8661  int status, size;
8662 
8663  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
8664  if (iter->cmd == "setTemp") {
8665  check_needed = true;
8666  break;
8667  }
8668  }
8669 
8670  if (!check_needed) // no check needed: get out of here
8671  return;
8672 
8673  // check if CMODE==2, i.e. ZONE setting active
8674  // if yes -> overwrite potential rubbish
8675  // if no -> it is the experimenters business what he/she is doing
8676  float cmode;
8677  size = sizeof(cmode);
8678  fSampleOutputKey->GetDataIndex(&cmode, &size, LS336_OUTPUT_HEATER_MODE, TID_FLOAT);
8679  if (cmode != 2) // control mode different than ZONE setting -> nothing to be done
8680  return;
8681 
8682  // get ZONE settings key
8683  PKey *zoneKey;
8684  QString str = QString("/Equipment/SampleCryo/Settings/Devices/Lake336_Sample_0/DD/Zone/Zone");
8685 
8686  zoneKey = new PKey(fExp, str);
8687  if (!zoneKey->IsValid()) {
8688  QString err = QString("sample cryo ZONE settings key not found.");
8689  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
8690  return;
8691  }
8692 
8693  // get current demand temperature
8694  float temp;
8695  size = sizeof(float);
8696  fSampleOutputKey->GetDataIndex(&temp, &size, LS336_OUTPUT_SETPOINT, TID_FLOAT);
8697 
8698  char zone_str[64];
8699  size = sizeof(zone_str);
8700  float loop, zone, top_value, p_pid, i_pid, d_pid, mount_value, range;
8701  for (int i=0; i<10; i++) {
8702  // get ith zone setting
8703  zoneKey->GetDataIndex(zone_str, &size, i, TID_STRING);
8704  // extract parameters
8705  status = sscanf(zone_str, "%f,%f,%f,%f,%f,%f,%f,%f", &loop, &zone, &top_value,
8706  &p_pid, &i_pid, &d_pid, &mount_value, &range);
8707  if (status != 8) {
8708  QString err = QString("Couldn't extract sample cryo ZONE settings (%1/%2).").arg(status).arg(zone_str);
8709  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
8710  return;
8711  }
8712  if (temp < top_value) // found proper zone
8713  break;
8714  }
8715 
8716  // set all the proper parameters
8717  fSampleOutputKey->SetDataIndex(&p_pid, LS336_OUTPUT_PID_P ,TID_FLOAT);
8718  fSampleOutputKey->SetDataIndex(&i_pid, LS336_OUTPUT_PID_I ,TID_FLOAT);
8719  fSampleOutputKey->SetDataIndex(&d_pid, LS336_OUTPUT_PID_D ,TID_FLOAT);
8720  fSampleOutputKey->SetDataIndex(&range, LS336_OUTPUT_HEATER_RANGE ,TID_FLOAT);
8721  float mode = 2; // ZONE settings
8722  fSampleOutputKey->SetDataIndex(&mode, LS336_OUTPUT_HEATER_MODE ,TID_FLOAT);
8723 }
8724 
8725 //**********************************************************************
8726 // NeedleValve (Konti-Cryos only)
8727 //**********************************************************************
8733 float PLemAutoRun::NeedleValve(float Tset)
8734 {
8735  float value;
8736 
8737  if ( Tset < 8.0 ) {
8739  } else {
8740  if ( Tset < 10.0 ) {
8742  } else {
8743  // Test changes of ranges
8744  if ( Tset < 20.0 ) {
8746  } else {
8748  }
8749  }
8750  }
8751 
8752  if (fDebug) {
8753  cm_msg(MDEBUG,"NeedleValve", "NeedleValve: demand = %e", value);
8754  cm_yield(0);
8755  }
8756 
8757  if ( value > 100.0 )
8758  value = 100.0;
8759 
8760  if ( value < fPrefNeedleValveCof_4_0 )
8761  value = fPrefNeedleValveCof_4_0;
8762  return value;
8763 }
8764 
8765 //**********************************************************************
8766 // Empirical_Flow (Konti-Cryos only)
8767 //**********************************************************************
8774 float PLemAutoRun::EmpiricalFlow(float Tset, float rampSpeed)
8775 {
8776  float demandflow;
8777 
8778  demandflow = fBHFlowTemp / (Tset + fBHFlowTempOffset) + fBHFlowOffset
8779  /* speed of ramp in K/sec */
8780  + (rampSpeed / 60.0) *
8781  /* heat capacity in J/K */
8782  ( fHeatCapCof1 * Tset
8783  + fHeatCapCof2 * Tset * Tset
8784  + fHeatCapCof3 * Tset * Tset * Tset )
8785  /* d(flow)/dP in BH_units / Watt */
8786  * (fDFlowDp0 + fDFlowDp1 * exp( fDFlowDpExp * log(Tset)));
8787 
8788  if (fDebug) {
8789  cm_msg(MDEBUG,"EmpircalFlow", "EmpiricalFlow: demandflow = %e", demandflow);
8790  cm_yield(0);
8791  }
8792 
8793  if ( demandflow > fBHMaxFlow )
8794  demandflow = fBHMaxFlow;
8795 
8796  if ( demandflow < fBHMinFlow )
8797  demandflow = fBHMinFlow;
8798 
8799  return demandflow;
8800 }
8801 
8802 
8803 //**********************************************************************
8804 // SetDemandTempRamping
8805 //**********************************************************************
8811 float PLemAutoRun::SetDemandTempRamping(QString rampParam)
8812 {
8813  float rampSpeed=0.0;
8814  float value=0.0;
8815 
8816  if (!rampParam.isEmpty()) { // demand temp ramp given
8817  rampSpeed = rampParam.toFloat();
8818  }
8819 
8820  fSampleOutputKey->SetDataIndex((void *)&rampSpeed, LS336_OUTPUT_RAMP, TID_FLOAT);
8821 
8822  // check that the demand temperature ramping is indeed set (for maximal 1 min).
8823  QElapsedTimer t;
8824  t.start();
8825  do {
8826  if (value == fSampleInput[LS336_INPUT_RAMP])
8827  break;
8828  Wait(1000);
8829  } while (t.elapsed() < 60e3);
8830 
8831  return rampSpeed;
8832 }
8833 
8834 //**********************************************************************
8835 // SetFlowAndNeedleValve (Konti-Cryos only)
8836 //**********************************************************************
8859 void PLemAutoRun::SetFlowAndNeedleValve(QString flowParam, float &rampSpeed, float newDemandTemp,
8860  float deltaT, float flowScale)
8861 {
8862  float value;
8863 
8864  if (rampSpeed == 0.0) { // no ramping
8865  if (!flowParam.isEmpty()) { // Flow
8866  value = flowParam.toFloat();
8867  } else { // no explicit flow was given will get the empirical one
8868  value = EmpiricalFlow(newDemandTemp, 0.0);
8869  }
8870  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
8871  value = NeedleValve(newDemandTemp);
8872  SampleTempSetNeedleValve(value);
8873  } else { // ramping
8874  // calculate the flow according to the new setpoint
8875  if (!flowParam.isEmpty()) { // flow explicitly given
8876  value = newDemandTemp / fSampleInput[LS336_INPUT_SETPOINT] * (flowParam.toFloat() - fBHFlowOffset) + fBHFlowOffset;
8877  } else { // no explicit flow was given will get the empirical one
8879  // correct flow to the optimized one
8880  value *= (flowScale-1.0)*(fSampleInput[LS336_INPUT_SETPOINT]-newDemandTemp)/deltaT+1.0;
8881  }
8882  // set flow
8883  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
8884 
8885  //
8886  // Do not set the needlevalve in case of ramping, leave that to ConsiderNeedleValve
8887  //
8888  // value = NeedleValve(fSampleInput[LS336_INPUT_SETPOINT]);
8889  // SampleTempSetNeedleValve(value);
8890  // check if final setpoint is reached, than it is necessary to disable flow ramping,
8891  // since otherwise the flow adjustment will not work!
8892  if (fabs(fSampleInput[LS336_INPUT_SETPOINT] - newDemandTemp) < 0.1)
8893  rampSpeed = 0.0;
8894  }
8895 }
8896 
8897 
8898 //**********************************************************************
8899 // SetFlow (LowTemp only)
8900 //**********************************************************************
8906 void PLemAutoRun::SetFlow(QString flowParam)
8907 {
8908  if (flowParam.isEmpty())
8909  return;
8910 
8911  float value = flowParam.toFloat();
8912 
8913  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
8914 }
8915 
8916 //**********************************************************************
8917 // SetLSMode
8918 //**********************************************************************
8926 {
8927  float value;
8928 
8929  // check if it is necessary to switch the LS340 from CMODE == 2 (Zone), i.e. internal settings
8930  // to CMODE == 1 (manual PID) or vice versa
8931  if (!arc->param[TEMP_HEATER_RANGE].isEmpty() || !arc->param[TEMP_P_PID].isEmpty() ||
8932  !arc->param[TEMP_I_PID].isEmpty() || !arc->param[TEMP_D_PID].isEmpty()) { // parameters given which require CMODE==1
8934  value = LS_CTRL_PID;
8935  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_HEATER_MODE, TID_FLOAT);
8936  }
8937  } else { // no parameters given, switch to CMODE == 2 (Zone) if necessary
8939 /* //as35, do nothing here for the LS336 since there we are working with soft Zone settings
8940  value = LS_CTRL_ZONE;
8941  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_HEATER_MODE, TID_FLOAT);
8942 */
8943  }
8944  }
8945 }
8946 
8947 //**********************************************************************
8948 // SetLSHeaterRangeAndPIDs
8949 //**********************************************************************
8958 {
8959  float value;
8960 
8961  if (!arc->param[TEMP_HEATER_RANGE].isEmpty()) { // heater Range
8962  value = arc->param[TEMP_HEATER_RANGE].toFloat();
8963  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_HEATER_RANGE, TID_FLOAT);
8964  }
8965  if (!arc->param[TEMP_P_PID].isEmpty()) { // P
8966  value = arc->param[TEMP_P_PID].toFloat();
8967  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_PID_P, TID_FLOAT);
8968  }
8969  if (!arc->param[TEMP_I_PID].isEmpty()) { // I
8970  value = arc->param[TEMP_I_PID].toFloat();
8971  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_PID_I, TID_FLOAT);
8972  }
8973  if (!arc->param[TEMP_D_PID].isEmpty()) { // D
8974  value = arc->param[TEMP_D_PID].toFloat();
8975  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_PID_D, TID_FLOAT);
8976  }
8977 }
8978 
8979 //**********************************************************************
8980 // WaitUntilSampleLSReady
8981 //**********************************************************************
8986 {
8987  int size, status;
8988  QElapsedTimer t;
8989 
8990  // check if the DD is happy at the moment
8991  t.start();
8992  do {
8993  size = sizeof(status);
8994  fSampleNoConnectionKey->GetData((void *)&status, &size, TID_INT);
8995  if (!status) { // connection OK
8996  break;
8997  }
8998  Wait(5000);
8999  } while (t.elapsed() < 300e3); // try for 5 min.
9000 }
9001 
9002 //**********************************************************************
9003 // SetLSSetpoint
9004 //**********************************************************************
9011 void PLemAutoRun::SetLSSetpoint(float setpoint, float rampSpeed)
9012 {
9013  QElapsedTimer t;
9014 
9015  // set the temperature setpoint
9016  fSampleOutputKey->SetDataIndex((void *)&setpoint, LS336_OUTPUT_SETPOINT, TID_FLOAT);
9017 
9018  // check that the readback setpoint is the demand one before going on if no demand temp ramping
9019  Wait(3000);
9020  if (rampSpeed == 0.0) { // no ramping
9021  float fvalue;
9022  bool setpoint_readback_failure = true;
9023  t.start();
9024  do {
9025  if (fabs(setpoint - fSampleInput[LS336_INPUT_SETPOINT])<1.0e-4) {
9026  setpoint_readback_failure = false;
9027  break;
9028  }
9029  // set the temperature setpoint again (the additional tiny random number is necessary
9030  // otherwise MIDAS will not do anything).
9031  fvalue = setpoint + 1.0e-4 * (float)rand()/(float)RAND_MAX;
9032  fSampleOutputKey->SetDataIndex((void *)&fvalue, LS336_OUTPUT_SETPOINT, TID_FLOAT);
9033  Wait(5000);
9034  } while (t.elapsed() < 600e3);
9035  if (setpoint_readback_failure) {
9037  QString err = QString("setTemp: Couldn't get new setpoint readback value within 10 min!");
9038  emit ErrorMsg(1, 0, LAR_MIDAS_READBACK_FAILURE, -1, err);
9039  }
9040  }
9041 }
9042 
9043 //**********************************************************************
9044 // SetOmegaSetpoint
9045 //**********************************************************************
9051 void PLemAutoRun::SetOmegaSetpoint(float setpoint)
9052 {
9053  QElapsedTimer t;
9054 
9055  // set the temperature setpoint
9056  fSampleOvenOmegaOutputKey->SetDataIndex((void *)&setpoint, OMEGA_OVEN_OUTPUT_SETPOINT, TID_FLOAT);
9057 
9058  // check that the readback setpoint is the demand one before going on if no demand temp ramping
9059  Wait(3000);
9060 
9061  float fvalue;
9062  bool setpoint_readback_failure = true;
9063  t.start();
9064  do {
9065  if (fabs(setpoint - fSampleOvenOmegaInput[OMEGA_OVEN_INPUT_SETPOINT])<1) {
9066  setpoint_readback_failure = false;
9067  break;
9068  }
9069  // set the temperature setpoint again (the additional tiny random number is necessary
9070  // otherwise MIDAS will not do anything).
9071  fvalue = setpoint + 1.0e-4 * (float)rand()/(float)RAND_MAX;
9072  fSampleOvenOmegaOutputKey->SetDataIndex((void *)&fvalue, OMEGA_OVEN_OUTPUT_SETPOINT, TID_FLOAT);
9073  Wait(5000);
9074  } while (t.elapsed() < 600e3);
9075  if (setpoint_readback_failure) {
9077  QString err = QString("setTempOvenOmega: Couldn't get new setpoint readback value within 10 min!");
9078  emit ErrorMsg(1, 0, LAR_MIDAS_READBACK_FAILURE, -1, err);
9079  }
9080 }
9081 
9082 //**********************************************************************
9083 // SetFlowTweak (Konti-Cryos only)
9084 //**********************************************************************
9091 {
9092  QElapsedTimer t;
9093 
9094  fSampleOutputKey->SetDataIndex((void *)&flow, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9095 
9096  t.start();
9097  do {
9098  // wait a bit and feed the watchdog
9099  Wait(2000); // sleep 2 sec
9100 
9101  // check temperature stability and feed history buffer
9103  } while (t.elapsed() > fFlowTimeoutReduction);
9104 }
9105 
9106 //**********************************************************************
9107 // SetTfl
9108 //**********************************************************************
9114 {
9115  QString msg("");
9116 
9117  // check if tfl equipment is disabled in lemAutoRun
9118  if (!fEnabled["tfl_eq"]) {
9119  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9120  msg += "PLemAutoRun::SetHvOff: TFL equipment disabled in lemAutoRun. Will do nothing here.";
9121  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9122  // increment command counter
9124  return;
9125  }
9126 
9127  float tfl_pos = arc->param[0].toFloat();
9128  float tfl_mode = arc->param[1].toFloat();
9129 
9130  if (fDebug)
9131  std::cout << std::endl << "in SetTfl ...";
9132 
9133  // check that tfl_scfe is running
9134  CheckClients();
9135  if (!fTflFeRunning) {
9137  QString err = QString("PLemAutoRun::SetTfl: TFL Slowcontrol Frontend NOT running.\n")+
9138  QString(" Error too severe, will stop.");
9139  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9141  QCoreApplication::exit(0);
9142  exit(0);
9143  }
9144 
9145  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9146  msg += arc->cmdString;
9147  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9148 
9149  msg = QString("Autorun running: ") + msg;
9150  emit StatusMsg(msg);
9151 
9152  // set mode value
9153  fTflOutputKey->SetDataIndex((void*)&tfl_mode, SM_MODUS_NEEDLEVALVE, TID_FLOAT);
9154 
9155  ss_sleep(200);
9156 
9157  // set NV position
9158  fTflOutputKey->SetDataIndex((void*)&tfl_pos, SM_OUTPUT_NEEDLEVALVE, TID_FLOAT);
9159 
9160  // no readback NV position check will be done
9161 
9162  // increment command counter
9164 }
9165 
9166 //**********************************************************************
9167 // SetTemp
9168 //**********************************************************************
9175 {
9176  int size;
9177  float value;
9178  float newDemandTemp;
9179  float newDemandFlow = -1.0;
9180  float currentPID_D;
9181  float rampSpeed = 0.0;
9182  QElapsedTimer t, t_flow_set;
9183  QString msg("");
9184 
9185  // check if sample equipment is disabled in lemAutoRun
9186  if (!fEnabled["sample_eq"]) {
9187  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9188  msg += "PLemAutoRun::SetTemp: sample equipment disabled in lemAutoRun. Will do nothing here.";
9189  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9190  // increment command counter
9192  return;
9193  }
9194 
9195  if (fDebug)
9196  std::cout << std::endl << "in SetTemp ...";
9197 
9198  // get the name of the current Cryo/Oven
9199  char cryoName[NAME_LENGTH];
9200  size = sizeof(cryoName);
9201  if (!fEnabled["sample_cryo_info_odb"]) {
9202  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9203  msg += "PLemAutoRun::SetTemp: '/Info/Sample Cryo' access disabled. Will do nothing here.";
9204  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9205  // increment command counter
9207  return;
9208  }
9209  fSampleCryoKey->GetData(cryoName, &size, TID_STRING);
9210  if (QString(cryoName).startsWith("omega", Qt::CaseInsensitive)) {
9211  SetTempOvenOmega(arc);
9212  return;
9213  }
9214 
9215  // keep temp stability tolerance
9216  fSampleTempAccuracy = arc->param[TEMP_DELTA_T].toFloat();
9217 
9218  // before do anything, check if the currently set demand temperature is the same as
9219  // the target demand temperature. Furthermore check if the target demand temperature
9220  // and the currently measured temperature are within fSampleTempAccuracy.
9221  // If both conditions are fullfilled, do not do anything and just get out
9222  newDemandTemp = arc->param[TEMP_DEMAND_TEMP].toFloat();
9223  if ((fabs(newDemandTemp-fSampleInput[LS336_INPUT_SETPOINT]) < fSampleTempAccuracy) &&
9224  (fabs(newDemandTemp-fSampleInput[fSampleCtrlCh]) < fSampleTempAccuracy)) {
9225  // notify that the command is executed
9226  QString msg = QString("(%1/%2) TEMP ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9227  for (int i=0; i<arc->noElements; i++) {
9228  msg += arc->param[i];
9229  if (i<arc->noElements-1)
9230  msg += ", ";
9231  }
9232  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9233  // increment command counter
9235  // get out of here
9236  return;
9237  }
9238 
9239  // set the temperature unstable flag to true
9240  fSampleTempUnstable = true;
9241 
9242  if (fDebug)
9243  std::cout << std::endl << "in SetTemp: will check clients ...";
9244 
9245  // check if the sample_scfe is running
9246  CheckClients();
9247  if (!fSampleFeRunning) { // error too severe to going on
9249  QString err = QString("PLemAutoRun::SetTemp: Slowcontrol Frontend NOT running.\n")+
9250  QString(" Error too severe, will stop.");
9251  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9253  QCoreApplication::exit(0);
9254  exit(0);
9255  }
9256 
9257 /* uncomment for LS340
9258  // check if the sample controller is remote
9259  if (fSampleOutput[LS340_OUTPUT_REMOTE] == 0.0) { // not remote
9260  UpdateWebPage(fAutoRunCurrentIter, HTML_ABORTED);
9261  QString err = QString("PLemAutoRun::SetTemp: LakeShore is not remote.\n")+
9262  QString(" Error too severe, will stop.");
9263  emit ErrorMsg(1, 0, LAR_MIDAS_DEVICE_NOT_REMOTE, -1, err);
9264  DisconnectFromExp();
9265  QCoreApplication::exit(0);
9266  exit(0);
9267  }
9268 */
9269 
9270  // notify that the command is executed
9271  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9272  msg += arc->cmdString;
9273  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9274 
9275  msg = QString("Autorun running: ") + msg;
9276  emit StatusMsg(msg);
9277 
9278  if (fDebug)
9279  std::cout << std::endl << "in SetTemp: check lemvac and BPVX/Y positions ...";
9280 
9281  if (fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
9282  // check if lemvac_scfe is running
9283  if (!fLemvacFeRunning) { // error too severe to going on
9285  QString err = QString("PLemAutoRun::SetTemp: Lemvac NOT running. Error too severe, will stop.");
9286  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9288  QCoreApplication::exit(0);
9289  exit(0);
9290  }
9291 
9292  // get BPV settings (both valves)
9293  if (!GetBPV()) {
9295  QString err = QString("PLemAutoRun::SetTemp: Couldn't read BPVX/Y. Error too severe, will stop.");
9296  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9297  }
9298 
9300  // close BPVX
9301  if (!SetBPV(BPVX, BPV_CLOSE)) {
9303  QString err = QString("PLemAutoRun::SetTemp: Couldn't close BPVX. Error too severe, will stop.");
9304  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9305  }
9306  }
9307  }
9308 
9309  // keep new demand temperature
9310  newDemandTemp = arc->param[TEMP_DEMAND_TEMP].toFloat();
9311 
9312  // set demand temperature and check stability. The procedure is different for increasing or decreasing
9313  // temperature.
9314  if (newDemandTemp-fSampleInput[fSampleCtrlCh] > 0.0) { // increasing temperature ******************
9315 
9316  if (fDebug)
9317  std::cout << std::endl << "in SetTemp: increasing temperature ..." << std::endl;
9318 
9319  // check if it is necessary to shut down the hv's and to close BPVY
9320  if (fDebug)
9321  std::cout << std::endl << "in SetTemp: check if it is necessary to shut down the hv's and to close BPVY ...";
9322  bool shut = false;
9323  // requested demand more than fMaxTempIncrease (K) higher than current one, need to shut HV
9324  // fMaxTempIncrease is defined in the startup XML.
9325  if ((newDemandTemp-fSampleInput[fSampleCtrlCh] > fMaxTempIncrease) && fEnabled["fug_eq"]) {
9326  shut = true;
9327 
9328  // get HV's from the sample region
9329  if (fDebug)
9330  std::cout << std::endl << "in SetTemp: get HV's from the sample region ...";
9332 
9333  // shut down the sample HV's
9334  if (fDebug)
9335  std::cout << std::endl << "in SetTemp: shut down the sample HV's ...";
9336  ChangeSampleChamberHV(true);
9337  }
9338 
9339  if (fDebug)
9340  std::cout << std::endl << "in SetTemp: set demand temperature, ramping, flow ...";
9341 
9342  // set demand temperature ramping if wished
9343  rampSpeed = SetDemandTempRamping(arc->param[TEMP_RAMP]);
9344 
9345  float flowScale;
9346  float deltaT;
9347  if (fSampleCryoInUse == CRYO_KONTI) {
9348  // factor needed to pick up the flow at its current value if ramping is used
9349  // current BH flow divided by the estimated flow for the current temperature
9351  // temperature difference between the current temperature and the new demand temperature, need: see comment above
9352  deltaT = fSampleInput[LS336_INPUT_SETPOINT] - newDemandTemp;
9353 
9354  // set the new bronkhorst flow and needle valve
9355  if (fDebug)
9356  std::cout << std::endl << "in SetTemp: set the new bronkhorst flow and needle valve ...";
9357  SetFlowAndNeedleValve(arc->param[TEMP_FLOW], rampSpeed, newDemandTemp, deltaT, flowScale);
9358  } else if (fSampleCryoInUse == CRYO_LOWTEMP) {
9359  SetFlow(arc->param[TEMP_FLOW]);
9360  }
9361 
9362  // set the parameters of the LS340 or LS336 -------------------------------------------
9363  if (fDebug)
9364  std::cout << std::endl << "in SetTemp: set the parameters of the LS340 or LS336...";
9365 
9366  // set the control mode of the LS340 (see 'User's Manual' p.9-28) or the LS336 (see 'User's Manual' p.140, cmd: OUTMODE)
9367  SetLSMode(arc);
9368 
9369  // set heaterRange, PID's
9371 
9372  // wait 1 sec
9373  Wait(1000);
9374 
9375  // check if the DD is happy at the moment
9376  // uncomment next line for the LS340
9377 // WaitUntilSampleLSReady();
9378 
9379  SetLSSetpoint(newDemandTemp, rampSpeed);
9380 
9381  // get the current D from the PID
9382  currentPID_D = fSampleInput[LS336_INPUT_PID_D];
9383  // set D to zero while approaching the temperature
9384  value = 0.0;
9385  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_PID_D, TID_FLOAT);
9386 
9387  // check and tweak temperature until stability is reached or timeout happend
9388  if (fDebug)
9389  std::cout << std::endl << "in SetTemp: check and tweak temperature until stability is reached or timeout happend ...";
9390  bool done = false;
9391  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9392  t.start();
9393  t_flow_set.start();
9394  do {
9395 
9396  if (fSampleCryoInUse == CRYO_KONTI) {
9397  // if ramping, adjust the flow according to the current temperature
9398  SetFlowAndNeedleValve(arc->param[TEMP_FLOW], rampSpeed, newDemandTemp, deltaT, flowScale);
9399  }
9400 
9401  // time to set the D value back
9403  if (fabs(value-fSampleInput[fSampleCtrlCh])/value < fDSetRatio) {
9404  fSampleOutputKey->SetDataIndex((void *)&currentPID_D, LS336_OUTPUT_PID_D, TID_FLOAT);
9405  }
9406 
9407  // check temperature stability and feed history buffer
9409 
9410  if (fSampleCryoInUse == CRYO_KONTI) {
9411  // see if a flow tweaking is needed
9412  if (t_flow_set.elapsed() >= fTimeoutFlowSet) {
9415  t_flow_set.start(); // restart timer
9416  }
9417  }
9418 
9419  // wait a bit and feed the watchdog
9420  Wait(2000); // sleep 2 sec
9421 
9422  if (t.elapsed() > timeout) { // timeout fired
9423  QString err = QString("PLemAutoRun::SetTemp: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9424  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9425  emit ErrorMsg(1, 0, LAR_LS_TEMP_NOT_STABLE, -1, err);
9426  done = true;
9427  }
9428 
9429  if (SampleTempStable())
9430  done = true;
9431  } while (!done);
9432 
9433  // if HV is shut down: (i) open BPVY, than (ii) ramp sample HV's back
9434  if (fDebug)
9435  std::cout << std::endl << "in SetTemp: if HV is shut down: (i) open BPVY, than (ii) ramp sample HV's back ...";
9436  if (shut) {
9437  // ramp sample region HV's back
9438  ChangeSampleChamberHV(false);
9439  }
9440 
9441  } else { // decreasing temperature ****************************************************************
9442 
9443  if (fDebug)
9444  std::cout << std::endl << "in SetTemp: decreasing temperature ..." << std::endl;
9445 
9446  // set the parameters of the LS340 or LS336 -------------------------------------------
9447  if (fDebug)
9448  std::cout << std::endl << "in SetTemp: set the parameters of the LS340 or LS336 ...";
9449 
9450  // set the control mode of the LS340 (see 'User's Manual' p.9-28) or the LS336 (see 'User's Manual' p.140, cmd: OUTMODE)
9451  SetLSMode(arc);
9452 
9453  // set demand temperature ramping if wished, if not, it is set to zero
9454  // this assures that cooling down is a quick procedure even ramping was set
9455  // previously and the user has forgotten to set it to zero.
9456  rampSpeed = SetDemandTempRamping(arc->param[TEMP_RAMP]);
9457 
9458  // check if the DD is happy at the moment
9459  // uncomment next line for the LS340
9460 // WaitUntilSampleLSReady();
9461 
9462  // set the temperature setpoint
9463  SetLSSetpoint(newDemandTemp, rampSpeed);
9464 
9465  // wait 1 sec
9466  Wait(1000);
9467 
9468  // set heaterRange, PID's
9470 
9471  // wait 1 sec
9472  Wait(1000);
9473 
9474  // get ramping
9475  value = 0.0;
9476  size = sizeof(value);
9477  fSampleInputKey->GetDataIndex((void *)&value, &size, LS336_INPUT_RAMP, TID_FLOAT);
9478  if ((value == 0.0) && arc->param[TEMP_FLOW].isEmpty()) { // no ramping and no flow given: the normal case
9479  // get the current D from the PID
9480  currentPID_D = fSampleInput[LS336_INPUT_PID_D];
9481  // set D to zero while approaching the temperature
9482  value = 0.0;
9483  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_PID_D, TID_FLOAT);
9484 
9485  if (fSampleCryoInUse == CRYO_KONTI) {
9486  // check what temporary flow is needed and set it (only if ramping is NOT enabled!!)
9487  if (newDemandTemp > 50.0)
9488  value = 1.0e4;
9489  else
9490  value = 3.0e4;
9491  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9492  fLargeFlow = true;
9493  // Needle valve should be set to the maximum value here, otherwise we will not reach the high flow
9494  value = 95.0;
9495  SampleTempSetNeedleValve(value);
9496  }
9497 
9498  // check and tweak temperature until stability is reached or timeout happend
9499  if (fDebug)
9500  std::cout << std::endl << "in SetTemp: check and tweak temperature until stability is reached or timeout happend ...";
9501  bool done = false;
9502  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9503  // get the new bronkhorst flow value
9504  if (fSampleCryoInUse == CRYO_KONTI) {
9505  if (!arc->param[TEMP_FLOW].isEmpty()) { // Flow given explicitly
9506  newDemandFlow = arc->param[TEMP_FLOW].toFloat();
9507  } else { // no explicit flow was given will get the empirical one
9508  newDemandFlow = fBHFlowTemp / (newDemandTemp + fBHFlowTempOffset) + fBHFlowOffset;
9509  }
9510  }
9511 
9512  t_flow_set.start();
9513  t.start();
9514  do {
9515  if (fSampleCryoInUse == CRYO_KONTI) {
9516  // start reducing the flow if getting close to the setpoint
9517  if (((fSampleInput[fSampleCtrlCh] - newDemandTemp) / newDemandTemp < fFlowSetRatio) &&
9518  ((fSampleInput[fSampleCtrlCh] - newDemandTemp) < fFlowSetAbsolute) &&
9519  fLargeFlow) {
9520 
9521  // set the needle valve to temperature set point
9522  value = NeedleValve(newDemandTemp);
9523  SampleTempSetNeedleValve(value);
9524 
9525  // reduce to 1.5 * the final flow
9526  value = 1.5 * newDemandFlow;
9527  SetFlowTweak(value);
9528 
9529  // reduce to 1.2 * the final flow
9530  value = 1.2 * newDemandFlow;
9531  SetFlowTweak(value);
9532 
9533  // reduce to 1.1 * the final flow
9534  value = 1.1 * newDemandFlow;
9535  SetFlowTweak(value);
9536 
9537  // reduce to the final flow
9538  value = newDemandFlow;
9539  SetFlowTweak(value);
9540 
9541  fLargeFlow = false;
9542 
9543  // the following is needed in the situation where the previous demand temp is too close
9544  // to the newDemandTemp. What happens then? The TFL NV is still opening and is not
9545  // accepting the new closing command already, hence the TFL NV is set once more here
9546 
9547  // wait a bit and feed the watchdog
9548  Wait(5000); // sleep 5 sec
9549 
9550  // set the needle valve to temperature set point
9551  value = NeedleValve(newDemandTemp)-0.01;
9552  SampleTempSetNeedleValve(value);
9553  }
9554  }
9555 
9556  // time to set the D value back
9558  if (fabs(value-fSampleInput[fSampleCtrlCh])/value < fDSetRatio) {
9559  fSampleOutputKey->SetDataIndex((void *)&currentPID_D, LS336_OUTPUT_PID_D, TID_FLOAT);
9560  }
9561 
9562  // check temperature stability and feed history buffer
9564 
9565  if (fSampleCryoInUse == CRYO_KONTI) {
9566  // see if a flow tweaking is needed
9567  if (t_flow_set.elapsed() >= fTimeoutFlowSet) {
9570  t_flow_set.start(); // restart timer
9571  }
9572  }
9573 
9574  // wait a bit and feed the watchdog
9575  Wait(2000); // sleep 2 sec
9576 
9577  if (t.elapsed() > timeout) { // timeout fired
9578  QString err = QString("PLemAutoRun::SetTemp: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9579  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9580  emit ErrorMsg(1, 0, LAR_LS_TEMP_NOT_STABLE, -1, err);
9581  done = true;
9582  }
9583 
9584  if (SampleTempStable())
9585  done = true;
9586  } while (!done);
9587 
9588  } else { // ramping enabled for cooling down or flow explicitly given!!
9589  // Here it is not possible to increase to flow initially
9590 
9591  if (fDebug)
9592  std::cout << std::endl << "in SetTemp: ramping enabled for cooling down or flow explicitly given ...";
9593 
9594  if (fSampleCryoInUse == CRYO_KONTI) {
9595  // get the new bronkhorst flow value and set it
9596  if (!arc->param[TEMP_FLOW].isEmpty()) { // Flow
9597  newDemandFlow = arc->param[TEMP_FLOW].toFloat();
9598  } else { // no explicit flow was given will get the empirical one
9599  newDemandFlow = EmpiricalFlow(fSampleInput[LS336_INPUT_SETPOINT], rampSpeed);
9600  }
9601  } else if (fSampleCryoInUse == CRYO_LOWTEMP) {
9602  // get the new bronkhorst flow value and set it
9603  if (!arc->param[TEMP_FLOW].isEmpty()) { // Flow
9604  newDemandFlow = arc->param[TEMP_FLOW].toFloat();
9605  } else { // flow not explicitly given, get the currently set one
9606  size = sizeof(newDemandFlow);
9607  fSampleOutputKey->GetDataIndex(&newDemandFlow, &size, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9608  }
9609  }
9610 
9611  fSampleOutputKey->SetDataIndex((void *)&newDemandFlow, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9612 
9613  if (fSampleCryoInUse == CRYO_KONTI) {
9615  if ( rampSpeed == 0.0 )
9616  SampleTempSetNeedleValve(value); // only if not ramping
9617  }
9618 
9619  // check and tweak temperature until stability is reached or timeout happend
9620  if (fDebug)
9621  std::cout << std::endl << "in SetTemp: check and tweak temperature until stability is reached or timeout happend ...";
9622  bool done = false;
9623  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9624  t.start();
9625  t_flow_set.start();
9626  do {
9627  if (fSampleCryoInUse == CRYO_KONTI) {
9628  // if ramping, adjust the flow according to the current temperature
9629  if (rampSpeed != 0.0) {
9630  // calculate the flow according to the new setpoint
9631  if (!arc->param[TEMP_FLOW].isEmpty()) // flow explicitly given
9632  value = newDemandTemp / fSampleInput[LS336_INPUT_SETPOINT] *
9633  (arc->param[TEMP_FLOW].toFloat() - fBHFlowOffset) + fBHFlowOffset;
9634  else { // no explicit flow was given will get the empirical one
9635  if ( t_flow_set.elapsed() >= fTimeoutFlowSet ) {
9638  Wait(500);
9639  t_flow_set.start(); // restart timer
9640  }
9641  value = EmpiricalFlow(fSampleInput[LS336_INPUT_SETPOINT], rampSpeed);
9642  }
9643 
9644  if (fDebug)
9645  std::cout << std::endl << "in SetTemp: set flow and adjust the needle valve of the transferline ...";
9646  // set flow
9647  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
9648 
9649  // adjust needle valve
9651 
9652  // check if final setpoint is reached, than it is necessary to disable flow ramping,
9653  // since otherwise the flow adjustment will not work!
9654  if (fDebug)
9655  std::cout << std::endl << "in SetTemp: check if final setpoint is reached ...";
9656  if (fabs(fSampleInput[LS336_INPUT_SETPOINT] - newDemandTemp) < 0.1) {
9657  // gradually reduce the flow to steady value if flow was not given explicitly
9658  if (fDebug)
9659  std::cout << std::endl << "in SetTemp: gradually reduce the flow to steady value if flow was not given explicitly ...";
9660  if (arc->param[TEMP_FLOW].isEmpty()) {
9661  float value2 = 0.3 * rampSpeed;
9663  SetFlowTweak(value);
9665 
9666  value2 = 0.2 * rampSpeed;
9668  SetFlowTweak(value);
9670 
9671  value2 = 0.1 * rampSpeed;
9673  SetFlowTweak(value);
9675 
9676  value2 = 0.0;
9678  SetFlowTweak(value);
9680  }
9681  rampSpeed = 0.0;
9682  }
9683  }
9684  }
9685 
9686  // check temperature stability and feed history buffer
9687  if (fDebug)
9688  std::cout << std::endl << "in SetTemp: check temperature stability and feed history buffer ...";
9690 
9691  if (fSampleCryoInUse == CRYO_KONTI) {
9692  // see if a flow tweaking is needed
9693  if (fDebug)
9694  std::cout << std::endl << "in SetTemp: see if a flow tweaking is needed ...";
9695  if (t_flow_set.elapsed() >= fTimeoutFlowSet) {
9698  t_flow_set.start(); // restart timer
9699  }
9700  }
9701 
9702  // wait a bit and feed the watchdog
9703  Wait(2000); // sleep 2 sec
9704 
9705  if (t.elapsed() > timeout) { // timeout fired
9706  QString err = QString("PLemAutoRun::SetTemp: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9707  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9708  emit ErrorMsg(1, 0, LAR_LS_TEMP_NOT_STABLE, -1, err);
9709  done = true;
9710  }
9711 
9712  if (SampleTempStable())
9713  done = true;
9714  } while (!done);
9715  }
9716  }
9717 
9718  if (fEnabled["lemvac_scfe"]) { // only check if LEMVAC is enabled
9719  // only open the BPVX when it initially was open
9720  if (fDebug)
9721  std::cout << std::endl << "in SetTemp: only open the BPVX when it initially was open ...";
9723  // open BPVX
9724  if (!SetBPV(BPVX, BPV_OPEN)) {
9726  QString err = QString("PLemAutoRun::SetTemp: Couldn't open BPVX. Error too severe, will stop.");
9727  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9728  }
9729  }
9730  }
9731 
9732  // set the temperature unstable flag to false
9733  fSampleTempUnstable = false;
9734 
9735  // increment command counter
9737 }
9738 
9739 //**********************************************************************
9740 // SetTempOvenOmega
9741 //**********************************************************************
9748  float newDemandTemp;
9749  float rampSpeed = 0.0;
9750  QElapsedTimer t;
9751  QString msg("");
9752 
9753  // check if omega equipment is disabled in lemAutoRun
9754  if (!fEnabled["omega_eq"]) {
9755  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9756  msg += "PLemAutoRun::SetTempOvenOmega: omega equipment disabled in lemAutoRun. Will do nothing here.";
9757  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9758  // increment command counter
9760  return;
9761  }
9762 
9763  // set the temperature unstable flag to true
9764  fSampleTempUnstable = true;
9765 
9766  // check if the sample_scfe is running
9767  CheckClients();
9768  if (!fSampleOvenOmegaFeRunning) { // error too severe to going on
9770  QString err = QString("PLemAutoRun::SetTempOvenOmega: Slowcontrol Frontend (Omega SC) NOT running. Error too severe, will stop.");
9771  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9773  QCoreApplication::exit(0);
9774  exit(0);
9775  }
9776 
9777  // notify that the command is executed
9778  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
9779  msg += arc->cmdString;
9780  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
9781 
9782  msg = QString("Autorun running: ") + msg;
9783  emit StatusMsg(msg);
9784 
9785  if (fDebug)
9786  std::cout << std::endl << "in SetTempOvenOmega: check lemvac and BPVX/Y positions ...";
9787 
9788  if (fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
9789  // check if lemvac_scfe is running
9790  if (!fLemvacFeRunning) { // error too severe to going on
9792  QString err = QString("PLemAutoRun::SetTemp: Lemvac NOT running. Error too severe, will stop.");
9793  emit ErrorMsg(1, 0, LAR_MIDAS_FE_NOT_RUNNING, -1, err);
9795  QCoreApplication::exit(0);
9796  exit(0);
9797  }
9798 
9799  // get BPV settings (both valves)
9800  if (!GetBPV()) {
9802  QString err = QString("PLemAutoRun::SetTempOvenOmega: Couldn't read BPVX/Y. Error too severe, will stop.");
9803  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9804  }
9805 
9807  // close BPVX
9808  if (!SetBPV(BPVX, BPV_CLOSE)) {
9810  QString err = QString("PLemAutoRun::SetTempOvenOmega: Couldn't close BPVX. Error too severe, will stop.");
9811  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9812  }
9813  }
9814  }
9815 
9816  // keep new demand temperature
9817  newDemandTemp = arc->param[TEMP_DEMAND_TEMP].toFloat() - 273.16; // K -> °C
9818 
9819  // set demand temperature and check stability. The procedure is different for increasing or decreasing
9820  // temperature.
9821  if (newDemandTemp-fSampleOvenOmegaInput[OMEGA_OVEN_INPUT_TEMP] > 0.0) { // increasing temperature ******************
9822 
9823  if (fDebug)
9824  std::cout << std::endl << "in SetTempOvenOmega: increasing temperature ..." << std::endl;
9825 
9826  bool shut = false;
9827  // requested demand more than fMaxTempIncrease (K) higher than current one, need to shut HV
9828  // fMaxTempIncrease is defined in the startup XML.
9830  shut = true;
9831 
9832  // get HV's from the sample region
9833  if (fDebug)
9834  std::cout << std::endl << "in SetTempOvenOmega: get HV's from the sample region ...";
9836 
9837  // shut down the sample HV's
9838  if (fDebug)
9839  std::cout << std::endl << "in SetTempOvenOmega: shut down the sample HV's ...";
9840  ChangeSampleChamberHV(true);
9841  }
9842 
9843  if (fDebug)
9844  std::cout << std::endl << "in SetTempOvenOmega: set demand temperature, ramping, flow ...";
9845 
9846  // set demand temperature ramping if wished
9847  // NOT YET IMPLEMENTED
9848 
9849  // set the parameters of the LS340 -------------------------------------------
9850  if (fDebug)
9851  std::cout << std::endl << "in SetTempOvenOmega: set the parameters of the LS340 ...";
9852 
9853  // set heaterRange, PID's
9854  // NOT YET IMPLEMENTED
9855 
9856  // wait 1 sec
9857  Wait(1000);
9858 
9859  SetOmegaSetpoint(newDemandTemp);
9860 
9861  // check the temperature until stability is reached or timeout happend
9862  if (fDebug)
9863  std::cout << std::endl << "in SetTempOvenOmega: check and tweak temperature until stability is reached or timeout happend ...";
9864  bool done = false;
9865  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9866  int stabilityCounter = 0;
9867  t.start();
9868  do {
9869  // check temperature stability and feed history buffer
9871 
9872  // wait a bit and feed the watchdog
9873  Wait(5000); // sleep 5 sec
9874 
9875  if (t.elapsed() > timeout) { // timeout fired
9876  QString err = QString("PLemAutoRun::SetTempOvenOmega: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9877  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9878  emit ErrorMsg(1, 0, LAR_LS_TEMP_NOT_STABLE, -1, err);
9879  done = true;
9880  }
9881 
9882  if (!fSampleTempUnstable) {
9883  stabilityCounter++;
9884  if (stabilityCounter == 60) // i.e. 5 min
9885  done = true;
9886  } else {
9887  stabilityCounter = 0;
9888  }
9889  } while (!done);
9890 
9891  // if HV is shut down: ramp sample HV's back
9892  if (fDebug)
9893  std::cout << std::endl << "in SetTempOvenOmega: if HV is shut down: ramp sample HV's back ...";
9894  if (shut) { // ramp sample region HV's back
9895  ChangeSampleChamberHV(false);
9896  }
9897  } else { // decreasing temperature ****************************************************************
9898 
9899  if (fDebug)
9900  std::cout << std::endl << "in SetTempOvenOmega: decreasing temperature ..." << std::endl;
9901 
9902  // set the parameters of the Omega -------------------------------------------
9903  if (fDebug)
9904  std::cout << std::endl << "in SetTempOvenOmega: set the parameters of the Omega ...";
9905 
9906  // set demand temperature ramping if wished
9907  // NOT YET IMPLEMENTED
9908 
9909  // set the temperature setpoint
9910  SetOmegaSetpoint(newDemandTemp);
9911 
9912  // wait 1 sec
9913  Wait(1000);
9914 
9915  // set PID's
9916  // NOT YET IMPLEMENTED
9917 
9918  // check and tweak temperature until stability is reached or timeout happend
9919  if (fDebug)
9920  std::cout << std::endl << "in SetTempOvenOmega: check the temperature until stability is reached or timeout happend ...";
9921  bool done = false;
9922  int timeout = 1000 * arc->param[TEMP_STABILITY_TIMEOUT].toInt(); // timeout in (msec)
9923  int stabilityCounter = 0;
9924  t.start();
9925  do {
9926  // check temperature stability and feed history buffer
9928 
9929  // wait a bit and feed the watchdog
9930  Wait(5000); // sleep 5 sec
9931 
9932  if (t.elapsed() > timeout) { // timeout fired
9933  QString err = QString("PLemAutoRun::SetTempOvenOmega: couldn't reach temperature %1 (K), ").arg(newDemandTemp) +
9934  QString("within required timeout %1 (sec).\n").arg(arc->param[TEMP_STABILITY_TIMEOUT]);
9935  emit ErrorMsg(1, 0, LAR_LS_TEMP_NOT_STABLE, -1, err);
9936  done = true;
9937  }
9938 
9939  if (!fSampleTempUnstable) {
9940  stabilityCounter++;
9941  if (stabilityCounter == 60) // i.e. 5 min
9942  done = true;
9943  } else {
9944  stabilityCounter = 0;
9945  }
9946  } while (!done);
9947  }
9948 
9949  if (fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
9950  // only open the BPVX when it initially was open
9951  if (fDebug)
9952  std::cout << std::endl << "in SetTempOvenOmega: only open the BPVX when it initially was open ...";
9954  // open BPVX
9955  if (!SetBPV(BPVX, BPV_OPEN)) {
9957  QString err = QString("PLemAutoRun::SetTempOvenOmega: Couldn't open BPVX. Error too severe, will stop.");
9958  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, arc->lineNo, err);
9959  }
9960  }
9961  }
9962 
9963  // set the temperature unstable flag to false
9964  fSampleTempUnstable = false;
9965 
9966  // increment command counter
9968 }
9969 
9970 //**********************************************************************
9971 // SetTitle
9972 //**********************************************************************
9979 {
9980  // arc->param:
9981  // 0 = title string of the title command
9982  // 1 = ODB_SAMPLE
9983  // 2 = ODB_TEMP
9984  // 3 = ODB_FIELD
9985  // 4 = ODB_TRANSP
9986  // 5 = ODB_HV_SAMP
9987  // 6 = ODB_ENERGY
9988  // 7 = ODB_RA_DIFF_LR
9989  // 8 = ODB_RA_DIFF_TB
9990  // 9 = ODB_SPIN_ROT
9991 
9992  int size;
9993  float fvalue;
9994  double dvalue;
9995  QString valueStr;
9996  QString msg("");
9997 
9998  // check if necessary ODB info is disabled in lemAutoRun
9999  if (!fEnabled["sample_name_info_odb"] || !fEnabled["sample_cryo_info_odb"]) {
10000  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10001  msg += "PLemAutoRun::SetTitle: not all necessary ODB settings are enabled in lemAutoRun. Will do nothing here.";
10002  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10003  // increment command counter
10005  return;
10006  }
10007 
10008  msg= QString("%1").arg(arc->param[0]);
10009 
10010  // check if odb tags are used
10011  if (arc->param[1] == "true") { // ODB_SAMPLE flag set
10012  char str[128];
10013  size = sizeof(str);
10014  if (fSampleNameKey)
10015  fSampleNameKey->GetData((void *)str, &size, TID_STRING);
10016  msg.replace("ODB_SAMPLE", str);
10017  }
10018  if (arc->param[2] == "true") { // ODB_TEMP flag set
10019  // get the name of the current Cryo/Oven
10020  char cryoName[NAME_LENGTH];
10021  size = sizeof(cryoName);
10022  if (fSampleCryoKey) {
10023  fSampleCryoKey->GetData(cryoName, &size, TID_STRING);
10024 
10025  if (QString(cryoName).startsWith("omega", Qt::CaseInsensitive)) { // Oven Omega in place
10026  size = sizeof(fvalue);
10028  fSampleOvenOmegaInputKey->GetDataIndex((void*)&fvalue, &size, OMEGA_OVEN_INPUT_TEMP, TID_FLOAT);
10029  dvalue = fvalue + 273.16; // °C -> K
10030  }
10031  } else { // Cryo in place
10032  size = sizeof(fvalue);
10033  if (fSampleInputKey) {
10034  fSampleInputKey->GetDataIndex((void *)&fvalue, &size, fSampleCtrlCh, TID_FLOAT);
10035  dvalue = fvalue;
10036  }
10037  }
10038  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10039  msg.replace("ODB_TEMP", QString("%1").arg(valueStr));
10040  }
10041  }
10042  if (arc->param[3] == "true") { // ODB_FIELD flag set
10043  if (fFieldPwrSupply == "wew") {
10044  // check which WEW power supply is used
10045  size = sizeof(float);
10046  if (fWEWInputKey) {
10047  fWEWInputKey->GetDataIndex((void *)&fvalue, &size, WEWL_INPUT_STATUS, TID_FLOAT);
10048  if (fvalue == 1.0)
10049  fWEWInputKey->GetDataIndex((void *)&fvalue, &size, WEWL_INPUT_CURRENT, TID_FLOAT);
10050  else
10051  fWEWInputKey->GetDataIndex((void *)&fvalue, &size, WEWH_INPUT_CURRENT, TID_FLOAT);
10052  valueStr = QString("~%1(G)/%2(A)").arg(fMagParamWew[0]+fMagParamWew[1]*fvalue, 0, 'f', 0).arg(fvalue, 0, 'f', 2);
10053  msg.replace("ODB_FIELD", QString("%1").arg(valueStr));
10054  }
10055  } else if (fFieldPwrSupply == "danfysik") {
10056  if (fDanfysikInputKey) {
10057  fDanfysikInputKey->GetDataIndex((void *)&fvalue, &size, DANFYSIK_INPUT_CURRENT, TID_FLOAT);
10058  valueStr = QString("~%1(G)/%2(A)").arg(fMagParamBpar[0]+fMagParamBpar[1]*fvalue, 0, 'f', 0).arg(fvalue, 0, 'f', 2);
10059  msg.replace("ODB_FIELD", QString("%1").arg(valueStr));
10060  }
10061  } else {
10062  msg.replace("ODB_FIELD", "??(G)/??(A)");
10063  }
10064  }
10065  if (arc->param[4] == "true") { // ODB_TRANSP flag set
10066  if (fFugHvCheck) {
10067  size = sizeof(fvalue);
10068  if (fHVMeasuredKey) {
10069  fHVMeasuredKey->GetDataIndex((void *)&fvalue, &size, HV_FUG_MOD, TID_FLOAT);
10070  dvalue = fvalue;
10071  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10072  msg.replace("ODB_TRANSP", QString("%1").arg(valueStr));
10073  }
10074  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
10075  size = sizeof(fvalue);
10076  if (fHVDemandKey) {
10077  fHVDemandKey->GetDataIndex((void *)&fvalue, &size, HV_FUG_MOD, TID_FLOAT);
10078  dvalue = fvalue;
10079  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10080  msg.replace("ODB_TRANSP", QString("%1").arg(valueStr));
10081  }
10082  }
10083  }
10084  if (arc->param[5] == "true") { // ODB_HV_SAMP flag set
10085  if (fFugHvCheck) {
10086  size = sizeof(fvalue);
10087  if (fHVMeasuredKey) {
10088  fHVMeasuredKey->GetDataIndex((void *)&fvalue, &size, HV_FUG_SAMPLE, TID_FLOAT);
10089  dvalue = fvalue;
10090  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10091  msg.replace("ODB_HV_SAMP", QString("%1").arg(valueStr));
10092  }
10093  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
10094  size = sizeof(fvalue);
10095  if (fHVDemandKey) {
10096  fHVDemandKey->GetDataIndex((void *)&fvalue, &size, HV_FUG_SAMPLE, TID_FLOAT);
10097  dvalue = fvalue;
10098  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10099  msg.replace("ODB_HV_SAMP", QString("%1").arg(valueStr));
10100  }
10101  }
10102  }
10103  if (arc->param[6] == "true") { // ODB_ENERGY flag set
10104  if (fFugHvCheck) {
10105  if (fHVMeasuredKey) {
10106  float hv_mod, hv_samp, energy_loss;
10107  // get hv of the moderator
10108  size = sizeof(hv_mod);
10109  fHVMeasuredKey->GetDataIndex((void *)&hv_mod, &size, HV_FUG_MOD, TID_FLOAT);
10110  // get hv of the sample
10111  size = sizeof(hv_samp);
10112  fHVMeasuredKey->GetDataIndex((void *)&hv_samp, &size, HV_FUG_SAMPLE, TID_FLOAT);
10113  // get energy loss
10114  energy_loss = GetEnergyLoss(hv_mod);
10115  // calculate implantation energy
10116  dvalue = hv_mod - energy_loss - hv_samp;
10117  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10118  msg.replace("ODB_ENERGY", QString("%1").arg(valueStr));
10119  }
10120  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
10121  if (fHVDemandKey) {
10122  float hv_mod, hv_samp, energy_loss;
10123  // get hv of the moderator
10124  size = sizeof(hv_mod);
10125  fHVDemandKey->GetDataIndex((void *)&hv_mod, &size, HV_FUG_MOD, TID_FLOAT);
10126  // get hv of the sample
10127  size = sizeof(hv_samp);
10128  fHVDemandKey->GetDataIndex((void *)&hv_samp, &size, HV_FUG_SAMPLE, TID_FLOAT);
10129  // get energy loss
10130  energy_loss = GetEnergyLoss(hv_mod);
10131  // calculate implantation energy
10132  dvalue = hv_mod - energy_loss - hv_samp;
10133  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10134  msg.replace("ODB_ENERGY", QString("%1").arg(valueStr));
10135  }
10136  }
10137  }
10138  if (arc->param[7] == "true") { // ODB_RA_DIFF_LR flag set
10139  if (fFugHvCheck) {
10140  if (fHVMeasuredKey) {
10141  float ral, rar;
10142  // get hv of the RA-L
10143  size = sizeof(ral);
10144  fHVMeasuredKey->GetDataIndex((void *)&ral, &size, HV_FUG_RAL, TID_FLOAT);
10145  // get hv of the RA-R
10146  size = sizeof(rar);
10147  fHVMeasuredKey->GetDataIndex((void *)&rar, &size, HV_FUG_RAR, TID_FLOAT);
10148  dvalue = ral-rar;
10149  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10150  msg.replace("ODB_RA_DIFF_LR", QString("%1").arg(valueStr));
10151  }
10152  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
10153  if (fHVDemandKey) {
10154  float ral, rar;
10155  // get hv of the RA-L
10156  size = sizeof(ral);
10157  fHVDemandKey->GetDataIndex((void *)&ral, &size, HV_FUG_RAL, TID_FLOAT);
10158  // get hv of the RA-R
10159  size = sizeof(rar);
10160  fHVDemandKey->GetDataIndex((void *)&rar, &size, HV_FUG_RAR, TID_FLOAT);
10161  dvalue = ral-rar;
10162  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10163  msg.replace("ODB_RA_DIFF_LR", QString("%1").arg(valueStr));
10164  }
10165  }
10166  }
10167  if (arc->param[8] == "true") { // ODB_RA_DIFF_TB flag set
10168  if (fFugHvCheck) {
10169  if (fHVMeasuredKey) {
10170  float rat, rab;
10171  // get hv of the RA-T
10172  size = sizeof(rat);
10173  fHVMeasuredKey->GetDataIndex((void *)&rat, &size, HV_FUG_RAT, TID_FLOAT);
10174  // get hv of the RA-B
10175  size = sizeof(rab);
10176  fHVMeasuredKey->GetDataIndex((void *)&rab, &size, HV_FUG_RAB, TID_FLOAT);
10177  dvalue = rat-rab;
10178  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10179  msg.replace("ODB_RA_DIFF_TB", QString("%1").arg(valueStr));
10180  }
10181  } else { // fug_hv_check NOT set, hence take the demand rather than the measured values!
10182  if (fHVDemandKey) {
10183  float rat, rab;
10184  // get hv of the RA-T
10185  size = sizeof(rat);
10186  fHVDemandKey->GetDataIndex((void *)&rat, &size, HV_FUG_RAT, TID_FLOAT);
10187  // get hv of the RA-B
10188  size = sizeof(rab);
10189  fHVDemandKey->GetDataIndex((void *)&rab, &size, HV_FUG_RAB, TID_FLOAT);
10190  dvalue = rat-rab;
10191  valueStr = QString("%1").arg(dvalue, 0, 'f', 2);
10192  msg.replace("ODB_RA_DIFF_TB", QString("%1").arg(valueStr));
10193  }
10194  }
10195  }
10196  if (arc->param[9] == "true") { // ODB_SPIN_ROT flag set
10198  // get spin rot value, and spin rot enable flag
10199  BOOL srEnabled;
10200  float srAngle;
10201  int size = sizeof(srEnabled);
10202  fSpinRotEnabledKey->GetData(&srEnabled, &size, TID_BOOL);
10203  size = sizeof(srAngle);
10204  fSpinRotAngleKey->GetData(&srAngle, &size, TID_FLOAT);
10205  if (srEnabled == FALSE) {
10206  msg.replace("ODB_SPIN_ROT", "disabled");
10207  } else {
10208  valueStr = QString("%1").arg(srAngle, 0, 'f', 2);
10209  msg.replace("ODB_SPIN_ROT", valueStr);
10210  }
10211  }
10212  }
10213 
10214  // check if they were ODB_TAG entries
10215  HandleOdbTitleTags(msg);
10216 
10217  // set title
10218  msg.truncate(220); // truncate overly long title to 220 characters in order to keep the ODB happy
10219  if (fEnabled["run_comment_odb"])
10220  fRunCommentKey->SetData((void *)msg.toLatin1().data(), 1, TID_STRING);
10221 
10222  // send command notifier
10223  msg = QString("(%1/%2) TITLE ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds) + msg;
10224  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10225 
10226  msg = QString("Autorun running: ") + msg;
10227  emit StatusMsg(msg);
10228 
10229  // increment command counter
10231 }
10232 
10233 //**********************************************************************
10234 // HandleOdbTitleTags
10235 //**********************************************************************
10242 {
10243  int idx=-1, status=0, size;
10244  char bval;
10245  int ival;
10246  float fval;
10247  double dval;
10248  char str[1024];
10249  PKey *key=0;
10250  QString subStr("??");
10251  for (int i=0; i<fOdbTagVector->size(); i++) {
10252  // check if an ODB tag is found in the title
10253  idx = title.indexOf(fOdbTagVector->at(i).tag);
10254  if (idx != -1) { // something found
10255  // check that the ODB tag entry is a valid ODB midas entry
10256  key = new PKey(fExp, fOdbTagVector->at(i).odb_path);
10257  if (key->IsValid()) {
10258  if (fOdbTagVector->at(i).idx+1 > key->GetNumValues()) {
10259  cm_msg(MINFO, "HandleOdbTitleTags", "HandleOdbTitleTags: %s: idx=%d >= number of entries=%d, will ignore it.",
10260  fOdbTagVector->at(i).odb_path.toLatin1().data(), fOdbTagVector->at(i).idx, key->GetNumValues());
10261  cm_yield(0);
10262  } else if ((key->GetType() != TID_BYTE) &&
10263  (key->GetType() != TID_SBYTE) &&
10264  (key->GetType() != TID_CHAR) &&
10265  (key->GetType() != TID_WORD) &&
10266  (key->GetType() != TID_SHORT) &&
10267  (key->GetType() != TID_DWORD) &&
10268  (key->GetType() != TID_INT) &&
10269  (key->GetType() != TID_BOOL) &&
10270  (key->GetType() != TID_FLOAT) &&
10271  (key->GetType() != TID_DOUBLE) &&
10272  (key->GetType() != TID_STRING)) {
10273  cm_msg(MINFO, "HandleOdbTitleTags", "HandleOdbTitleTags: %s: wrong data type (%d), will ignore it.",
10274  fOdbTagVector->at(i).odb_path.toLatin1().data(), key->GetType());
10275  cm_yield(0);
10276  } else {
10277  if (fOdbTagVector->at(i).idx != -1) { // data is an array
10278  switch (key->GetType()) {
10279  case TID_BYTE:
10280  size = sizeof(char);
10281  status = key->GetDataIndex(&bval, &size, fOdbTagVector->at(i).idx, TID_BYTE);
10282  subStr = QString("%1").arg(bval);
10283  break;
10284  case TID_SBYTE:
10285  size = sizeof(char);
10286  status = key->GetDataIndex(&bval, &size, fOdbTagVector->at(i).idx, TID_SBYTE);
10287  subStr = QString("%1").arg(bval);
10288  break;
10289  case TID_CHAR:
10290  size = sizeof(char);
10291  status = key->GetDataIndex(&bval, &size, fOdbTagVector->at(i).idx, TID_CHAR);
10292  subStr = QString("%1").arg(bval);
10293  break;
10294  case TID_WORD:
10295  size = 2*sizeof(char);
10296  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_WORD);
10297  subStr = QString("%1").arg(ival);
10298  break;
10299  case TID_SHORT:
10300  size = sizeof(int);
10301  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_SHORT);
10302  subStr = QString("%1").arg(ival);
10303  break;
10304  case TID_DWORD:
10305  size = sizeof(int);
10306  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_DWORD);
10307  subStr = QString("%1").arg(ival);
10308  break;
10309  case TID_INT:
10310  size = sizeof(int);
10311  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_INT);
10312  subStr = QString("%1").arg(ival);
10313  break;
10314  case TID_BOOL:
10315  size = sizeof(int);
10316  status = key->GetDataIndex(&ival, &size, fOdbTagVector->at(i).idx, TID_BOOL);
10317  subStr = QString("%1").arg(ival);
10318  break;
10319  case TID_FLOAT:
10320  size = sizeof(float);
10321  status = key->GetDataIndex(&fval, &size, fOdbTagVector->at(i).idx, TID_FLOAT);
10322  subStr = QString("%1").arg(fval);
10323  break;
10324  case TID_DOUBLE:
10325  size = sizeof(double);
10326  status = key->GetDataIndex(&dval, &size, fOdbTagVector->at(i).idx, TID_DOUBLE);
10327  subStr = QString("%1").arg(dval);
10328  break;
10329  case TID_STRING:
10330  size = key->GetItemSize()*sizeof(float);
10331  if (size < 1024) {
10332  status = key->GetDataIndex(&str, &size, fOdbTagVector->at(i).idx, TID_STRING);
10333  subStr = str;
10334  } else {
10335  subStr = "?!?!";
10336  }
10337  break;
10338  default:
10339  break;
10340  }
10341  if (status == DB_SUCCESS) {
10342  title.replace(fOdbTagVector->at(i).tag, subStr);
10343  }
10344  } else { // data is a single value
10345  switch (key->GetType()) {
10346  case TID_BYTE:
10347  size = sizeof(char);
10348  status = key->GetData(&bval, &size, TID_BYTE);
10349  subStr = QString("%1").arg(bval);
10350  break;
10351  case TID_SBYTE:
10352  size = sizeof(char);
10353  status = key->GetData(&bval, &size, TID_SBYTE);
10354  subStr = QString("%1").arg(bval);
10355  break;
10356  case TID_CHAR:
10357  size = sizeof(char);
10358  status = key->GetData(&bval, &size, TID_CHAR);
10359  subStr = QString("%1").arg(bval);
10360  break;
10361  case TID_WORD:
10362  size = 2*sizeof(char);
10363  status = key->GetData(&ival, &size, TID_WORD);
10364  subStr = QString("%1").arg(ival);
10365  break;
10366  case TID_SHORT:
10367  size = sizeof(int);
10368  status = key->GetData(&ival, &size, TID_SHORT);
10369  subStr = QString("%1").arg(ival);
10370  break;
10371  case TID_DWORD:
10372  size = sizeof(int);
10373  status = key->GetData(&ival, &size, TID_DWORD);
10374  subStr = QString("%1").arg(ival);
10375  break;
10376  case TID_INT:
10377  size = sizeof(int);
10378  status = key->GetData(&ival, &size, TID_INT);
10379  subStr = QString("%1").arg(ival);
10380  break;
10381  case TID_BOOL:
10382  size = sizeof(int);
10383  status = key->GetData(&ival, &size, TID_BOOL);
10384  subStr = QString("%1").arg(ival);
10385  break;
10386  case TID_FLOAT:
10387  size = sizeof(float);
10388  status = key->GetData(&fval, &size, TID_FLOAT);
10389  subStr = QString("%1").arg(fval);
10390  break;
10391  case TID_DOUBLE:
10392  size = sizeof(double);
10393  status = key->GetData(&dval, &size, TID_DOUBLE);
10394  subStr = QString("%1").arg(dval);
10395  break;
10396  case TID_STRING:
10397  size = key->GetItemSize()*sizeof(char);
10398  if (size < 1024) {
10399  status = key->GetData(&str, &size, TID_STRING);
10400  subStr = str;
10401  } else {
10402  subStr = "?!?!";
10403  }
10404  break;
10405  default:
10406  break;
10407  }
10408  if (status == DB_SUCCESS) {
10409  title.replace(fOdbTagVector->at(i).tag, subStr);
10410  }
10411  }
10412  }
10413  }
10414  // clean up
10415  if (key) {
10416  delete key;
10417  key = 0;
10418  }
10419  subStr = QString("??");
10420  }
10421  }
10422 }
10423 
10424 //**********************************************************************
10425 // SetTof
10426 //**********************************************************************
10433 {
10434  float value;
10435  QString msg("");
10436 
10437  // check if TOF ODB entries are disabled in lemAutoRun
10438  if (!fEnabled["tof_min_odb"] || !fEnabled["tof_max_odb"]) {
10439  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10440  msg += "PLemAutoRun::SetTof: TOF ODB entires disabled in lemAutoRun. Will do nothing here.";
10441  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10442  // increment command counter
10444  return;
10445  }
10446 
10447  // send command notifier
10448  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10449  msg += arc->cmdString;
10450  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10451 
10452  msg = QString("Autorun running: ") + msg;
10453  emit StatusMsg(msg);
10454 
10455  // set values
10456  value = arc->param[0].toFloat();
10457  fTofMinKey->SetData((void *)&value, 1, TID_FLOAT);
10458 
10459  value = arc->param[1].toFloat();
10460  fTofMaxKey->SetData((void *)&value, 1, TID_FLOAT);
10461 
10462  // increment command counter
10464 }
10465 
10466 //**********************************************************************
10467 // SetWait
10468 //**********************************************************************
10475 {
10476  QString msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10477  msg += arc->cmdString;
10478  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
10479 
10480  msg = QString("Autorun running: ") + msg;
10481  emit StatusMsg(msg);
10482 
10483  int wait = arc->param[0].toInt();
10484 
10485  for (int i=0; i<wait; i++) {
10486  Wait(1000); // sleep 1 sec
10487 
10488  if ( ((i+1) % 5) == 0 ) { // once every 5 seconds
10489 
10490  // adjust flow when needed, but only when regulation is whished, the temperature is stable, and
10491  // there is a long enough history for a reliable regulation
10493  if (fEnabled["omega_eq"]) // only deal with omega oven if enabled
10495  } else {
10496  if (fEnabled["sample_eq"]) // only deal with sample cryo if enabled
10498  }
10499  if (fSampleCryoInUse == CRYO_KONTI) {
10501  if (fEnabled["sample_eq"]) // only deal with sample cryo if enabled
10503  }
10504  }
10505 
10506  // dump raw voltage when needed
10507  if (fEnabled["sample_eq"]) { // only deal with sample cryo if enabled
10508  if (fDumpInUse) {
10509  if (fDumpCounter > 0) {
10510  RawVoltageDump();
10511  } else {
10512  fDumpFile.close();
10513  fDumpInUse = false;
10514  }
10515  }
10516  }
10517  }
10518  }
10519 
10520  // increment command counter
10522 }
10523 
10524 //**********************************************************************
10525 // CheckForWarmUpCmd
10526 //**********************************************************************
10531 {
10532  PAutoRunCmdVector::Iterator iter;
10533  int yy, MM, dd, hh, mm, ss;
10534  QDate d;
10535  QTime t;
10536 
10537  for (iter = fAutoRunCmdVector->begin(); iter != fAutoRunCmdVector->end(); ++iter) {
10538  if (iter->cmd == "warmUp") {
10539  fWarmUpWished = true;
10540  sscanf(iter->param[0].toLatin1().data(), "%d-%d-%d", &yy, &MM, &dd);
10541  d = QDate(yy, MM, dd);
10542  fWarmUpDateTime.setDate(d);
10543  sscanf(iter->param[1].toLatin1().data(), "%d:%d:%d", &hh, &mm, &ss);
10544  t = QTime(hh, mm, ss);
10545  fWarmUpDateTime.setTime(t);
10546  if (iter->param[2] == "1")
10547  fWarmUpVent = true;
10548  break;
10549  }
10550  }
10551 }
10552 
10553 //**********************************************************************
10554 // WarmUp
10555 //**********************************************************************
10561 void PLemAutoRun::WarmUp(PAutoRunCmdVector::Iterator iter)
10562 {
10563  int status, size;
10564  QString err, msg;
10565  unsigned int i, j;
10566  float value;
10567  float hv[HV_FUG_CHS];
10568  bool done, happy;
10569  QElapsedTimer t;
10570 
10571  // check if sample equipment is disabled in lemAutoRun
10572  if (!fEnabled["sample_eq"]) {
10573  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
10574  msg += "PLemAutoRun::WarmUp: sample equipment disabled in lemAutoRun. Will do nothing here.";
10575  emit ErrorMsg(1, 0, LAR_MSG, 0, msg);
10576  // increment command counter
10578  return;
10579  }
10580 
10581  // notifier
10582  msg = QString("PLemAutoRun::WarmUp(): warm up procedure starts. Will stop any pending runs, shutdown HV's, ...");
10583  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10584 
10585  // update web-page
10586  UpdateWebPage(iter, HTML_WARMUP);
10587 
10588  // if there is an active run, stop it
10589  if (fRunInfo.state == RUN_RUNNING) {
10590  // stop run
10591  status = cm_transition(TR_STOP, fRunInfo.run_number, NULL, 0, TR_SYNC, FALSE);
10592  if (status != CM_SUCCESS) { // error
10593  err = QString("PLemAutoRun::RunStart: Cannot stop the run.");
10594  emit ErrorMsg(1, 0, LAR_MIDAS_CANNOT_START_RUN, -1, err);
10595  emit StatusMsg(err);
10596  }
10597  err = QString("Autorun running: run stopped.");
10598  emit StatusMsg(err);
10599  fRunNoEventsNeeded = 0;
10600  fRunStopped = true;
10601  }
10602 
10603  // close KV61 and KV62
10604  msg = QString("PLemAutoRun::WarmUp(): close KV61 and KV62");
10605  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10606 
10607  value = 0.0;
10608  fBeamlineDemandKey->SetDataIndex(&value, BEAMLINE_KV61_DEMAND_CH, TID_FLOAT);
10609  value = 0.0;
10610  fBeamlineDemandKey->SetDataIndex(&value, BEAMLINE_KV62_DEMAND_CH, TID_FLOAT);
10611 
10612  // switch off all the FUG HV's **************************************************************
10613 
10614  msg = QString("PLemAutoRun::WarmUp(): switch off all the FUG HV's");
10615  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10616 
10617  if (fEnabled["fug_scfe"]) { // only do something if FUG is enabled
10618  // Loop over set HV. This is done this way to reduce hangers due to network problems
10619  for (j=0; j<HV_FUG_MAX_TRY; j++) {
10620 
10621  // set HV's to 0.0
10622  value = 0.0 + j*0.001; // j-term to force the DD set command being executed
10623  for (i=0; i<HV_FUG_CHS; i++)
10624  hv[i] = value;
10625  fHVDemandKey->SetData((void *)&hv, HV_FUG_CHS, TID_FLOAT);
10626 
10627  if (fFugHvCheck) {
10628  // check that HV is really down
10629  done = false;
10630  happy = false;
10631  t.start();
10632  do {
10633  Wait(2000); // sleep for 2 sec
10634 
10635  // read measured HV's
10636  size = sizeof(hv);
10637  fHVMeasuredKey->GetData(&hv, &size, TID_FLOAT);
10638 
10639  // calculate the sum of all sample region HV's
10640  value = 0.0;
10641  for (i=0; i<HV_FUG_CHS; i++)
10642  value += hv[i];
10643 
10644  // if sum of all HV's is smaller than 500V leave the loop
10645  if (fabs(value) < 0.5) {
10646  done = true;
10647  happy = true;
10648  }
10649 
10650  // check if timeout occured
10651  if (t.elapsed() > 3e5) { // 5 min. timeout
10652  done = true;
10653  err = QString("PLemAutoRun::WarmUp(): Couldn't shut down HV's. Will give it another try in 120 sec.");
10654  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
10655  }
10656  } while (!done);
10657 
10658  if (happy) // everything perfect, get out of the loop
10659  break;
10660 
10661  // wait 120 sec before retrial
10662  Wait(120000);
10663  } else { // NO FUG HV check, hence just wait a 1 min
10664  Wait(60000);
10665  j = 0;
10666  }
10667  }
10668 
10669  if (j == HV_FUG_MAX_TRY) {
10670  err = QString("PLemAutoRun::WarmUp(): Couldn't shut down sample region HV's. Error too severe, will stop.");
10671  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10672  }
10673  }
10674 
10675  // disable the RA pulsing
10676  msg = QString("PLemAutoRun::WarmUp(): disable potentially set RA pulsing.");
10677  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10678 
10679  PKey *enable_RA_pulsing = new PKey(fExp, "/Equipment/Trigger/Settings/Enable_OnOff_Mode");
10680  if (!enable_RA_pulsing->IsValid()) {
10681  err = QString("PLemAutoRun::WarmUp(): Couldn't get the Enable_OnOff_Mode key for the RA pulsing. Please check instantly! Error too severe, will stop.");
10682  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10683  }
10684  int ival = 0;
10685  enable_RA_pulsing->SetData((void*)&ival, 1,TID_BOOL);
10686  if (enable_RA_pulsing) {
10687  delete enable_RA_pulsing;
10688  enable_RA_pulsing = 0;
10689  }
10690 
10691  // close the BPVX/Y *****************************************************************************
10692  msg = QString("PLemAutoRun::WarmUp(): close BPVX/Y");
10693  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10694 
10695  // close BPVX
10696  if (!SetBPV(BPVX, BPV_CLOSE)) {
10697  QString err = QString("PLemAutoRun::WarmUp(): Couldn't close BPVX. Error too severe, will stop.");
10698  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, -1, err);
10699  }
10700 
10701  // close BPVY
10702  if (!SetBPV(BPVY, BPV_CLOSE)) {
10703  QString err = QString("PLemAutoRun::WarmUp(): Couldn't close BPVY. Error too severe, will stop.");
10704  emit ErrorMsg(1, 0, LAR_BPVY_NO_RESPONSE, -1, err);
10705  }
10706 
10707  // set the He Flow (Bronkhorst) to minimal *********************************************************
10708  msg = QString("PLemAutoRun::WarmUp(): sample He flow set to minimum value");
10709  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10710  value = fBHFlowTemp / (300.0 + fBHFlowTempOffset) + fBHFlowOffset;
10711  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
10712 
10713  // set demand temperature ramping to zero
10714  msg = QString("PLemAutoRun::WarmUp(): set demand temperature ramping to zero");
10715  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10716  value = 0.0;
10717  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_RAMP, TID_FLOAT);
10718 
10719  // check that the demand temperature ramping is set before proceeding
10720  t.start();
10721  do {
10722  Wait(3000);
10723  if (fSampleInput[LS336_INPUT_RAMP] == 0.0)
10724  break;
10725  } while (t.elapsed() < 60e3);
10726 
10727  // set the sample cryo temperature to 300K
10728  msg = QString("PLemAutoRun::WarmUp(): set sample cryo temperature to 300K");
10729  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10730  value = 300.0;
10731  fSampleOutputKey->SetDataIndex((void *)&value, LS336_OUTPUT_SETPOINT, TID_FLOAT);
10732 
10733  // read back temperature, if T>250K set the He Flow to zero, if T>90K and vent shall be performed: vent
10734  done = false;
10735  do {
10736  Wait(3000); // sleep for 3 sec
10737 
10738  size = sizeof(value);
10739  fSampleInputKey->GetDataIndex((void *)&value, &size, fSampleCtrlCh, TID_FLOAT);
10740 
10741  if ((value > 90.0) && fWarmUpVent && fEnabled["lemvac_scfe"]) {
10742  msg = QString("PLemAutoRun::WarmUp(): vent the sample chamber.");
10743  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10744  value = 1.0; // enable SC vent
10745  fLemvacOutputKey->SetDataIndex((void*)&value, SC_VENT_ENABLED, TID_FLOAT);
10746  value = 2.0; // SC vent command
10747  fLemvacOutputKey->SetDataIndex((void*)&value, SC_VENT_CMD, TID_FLOAT);
10748  fWarmUpVent = false;
10749  }
10750 
10751  if (value > 250.0) {
10752  done = true;
10753  // set the He Flow (Bronkhorst) to minimal
10754  msg = QString("PLemAutoRun::WarmUp(): sample He flow set to zero");
10755  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10756  value = 0.0;
10757  fSampleOutputKey->SetDataIndex((void *)&value, fSampleBhOdbOffsetOutput + BH_OUTPUT_FLOW, TID_FLOAT);
10758  }
10759  } while (!done);
10760 }
10761 
10762 
10763 //**********************************************************************
10764 // GotoLine
10765 //**********************************************************************
10772 void PLemAutoRun::GotoLine(PAutoRunCmdVector::Iterator &iter, int max)
10773 {
10774  int count=0, pos=0, gotoLine=GetGotoLine();
10775  QString msg;
10776 
10777  // check if goto line is within autorun
10778  if (gotoLine <= max) {
10779  for (PAutoRunCmdVector::Iterator loopIter=fAutoRunCmdVector->begin(); loopIter != fAutoRunCmdVector->end(); ++loopIter) {
10780  if (loopIter->cmd == "comment") {
10781  if (ShowComments() == true)
10782  pos++;
10783  } else {
10784  count++;
10785  pos++;
10786  }
10787  if (pos == gotoLine) {
10788  iter = loopIter;
10789  fCurrentAutoRunCmd = count;
10790  cm_msg(MINFO, "ExecAutoRun", "ExecAutoRun: will goto line %d", gotoLine);
10791  cm_yield(0);
10792  msg = QString("will go to line %1").arg(gotoLine);
10793  emit StatusMsg(msg);
10794  break;
10795  }
10796  }
10797  } else { // out of range
10798  cm_msg(MERROR, "ExecAutoRun", "ExecAutoRun: goto line %d > max. line number (%d). Doesn't make sense. Will ignore it!", gotoLine, max);
10799  cm_yield(0);
10800  msg = QString("line number %1 > max. line number (%2). Doesn't make sense. Will ignore it.").arg(gotoLine).arg(max);
10801  emit StatusMsg(msg);
10802  }
10803 
10804  // set goto line back to zero
10805  SetGotoLine(0);
10806  do { // wait until the hotlink is updated
10807  cm_yield(100);
10808  } while (GetGotoLine() != 0);
10809 }
10810 
10811 //**********************************************************************
10812 // GetDemandHVSampleChamber
10813 //**********************************************************************
10818 {
10819  int size, status;
10820  float demands[HV_FUG_CHS];
10821 
10822  size = sizeof(demands);
10823  status = fHVDemandKey->GetData(&demands, &size, TID_FLOAT);
10824  if (status != DB_SUCCESS) {
10826  QString err = QString("PLemAutoRun::GetDemandHVSampleChamber: Couldn't get demand HV's. Error too severe, will stop.");
10827  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10828  }
10829 
10830  for (int i=0; i<5; i++)
10831  fHVDemandSampleChamber[i] = demands[i+HV_FUG_RAL];
10832 }
10833 
10834 //**********************************************************************
10835 // ChangeSampleChamberHV
10836 //**********************************************************************
10841 {
10842  int i, j, ok, size;
10843  float value;
10844  float measured[HV_FUG_CHS];
10845  int hv_down;
10846  bool done, happy;
10847  QElapsedTimer t;
10848  QString err, msg;
10849 
10850  // check if FUG handling is disabled in lemAutoRun
10851  if (!fEnabled["fug_scfe"]) {
10852  return;
10853  }
10854 
10855  if (down) { // shut down sample region HV's
10856 
10857  // notifiy about down ramping
10858  msg = QString("ramp sample region HV's down.");
10859  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10860 
10861  // Loop over set HV. This is done this way to reduce hangers due to network problems
10862  for (j=0; j<HV_FUG_MAX_TRY; j++) {
10863 
10864  // set sample region HV's to 0.0
10865  value = 0.0 + j*0.001; // j-term to force the DD set command being executed
10866  for (i=0; i<5; i++)
10867  fHVDemandKey->SetDataIndex((void *)&value, i+HV_FUG_RAL, TID_FLOAT);
10868 
10869  if (fFugHvCheck) {
10870  // check that HV is really down
10871  done = false;
10872  happy = false;
10873  t.start();
10874  do {
10875  Wait(2000); // sleep for 2 sec
10876 
10877  // init hv_down tag
10878  hv_down = 0;
10879 
10880  // read measured HV's
10881  size = sizeof(measured);
10882  fHVMeasuredKey->GetData(&measured, &size, TID_FLOAT);
10883 
10884  // calculate the sum of all sample region HV's
10885  value = 0.0;
10886  for (i=0; i<5; i++) {
10887  value += measured[i+HV_FUG_RAL];
10888  if (measured[i+HV_FUG_RAL] < 0.35) // measured HV of a single channel < 350V
10889  hv_down += 1;
10890  }
10891 
10892  // if sum of all the sample region HV's is smaller than 100V leave the loop
10893  if ((fabs(value) < 0.1) || (hv_down == 5)) {
10894  done = true;
10895  happy = true;
10896  }
10897 
10898  // check if timeout occured
10899  if (t.elapsed() > 3e5) { // 5 min. timeout
10900  done = true;
10901  err = QString("PLemAutoRun::ChangeSampleChamberHV: Couldn't shut down sample region HV's. Will give it another try in 120 sec.");
10902  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
10903  }
10904  } while (!done);
10905 
10906  if (happy) // everything perfect, get out of the loop
10907  break;
10908 
10909  // wait 120 sec before retrial
10910  Wait(120000);
10911  } else { // NO FUG HV check, hence just wait a 1 min
10912  Wait(60000);
10913  j = 0;
10914  }
10915  }
10916  if (j == HV_FUG_MAX_TRY) {
10918  err = QString("PLemAutoRun::ChangeSampleChamberHV: Couldn't shut down sample region HV's. Error too severe, will stop.");
10919  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10920  for (int k=0; k<5; k++) {
10921  if (measured[k+HV_FUG_RAL] > 0.25) {
10922  cm_msg(MERROR, "lemAutoRun", "FUG channel %d should be 0.0 but found %f", k+HV_FUG_RAL, measured[k+HV_FUG_RAL]);
10923  cm_yield(0);
10924  }
10925  }
10926  }
10927  } else { // ramp back sample region HV's
10928 
10929  // notifiy about up ramping
10930  msg = QString("ramp sample region HV's back up.");
10931  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, msg);
10932 
10933  // Loop over set HV. This is done this way to reduce hangers due to network problems
10934  for (j=0; j<HV_FUG_MAX_TRY; j++) {
10935 
10936  // set sample region HV's to it's previous value
10937  for (i=0; i<5; i++) {
10938  value = fHVDemandSampleChamber[i] + (-1)*(j%2)*0.001; // j-term to force the DD set command being executed
10939  fHVDemandKey->SetDataIndex((void *)&value, i+HV_FUG_RAL, TID_FLOAT);
10940  }
10941 
10942  if (fFugHvCheck) {
10943  // check that HV are ramped back
10944  done = false;
10945  happy = false;
10946  t.start();
10947  do {
10948  Wait(2000); // sleep for 2 sec
10949 
10950  // read measured HV's
10951  size = sizeof(measured);
10952  fHVMeasuredKey->GetData(&measured, &size, TID_FLOAT);
10953 
10954  // check if HV is ok
10955  ok = 0;
10956  for (i=0; i<5; i++) {
10957  if (fabs(measured[i+HV_FUG_RAL]-fHVDemandSampleChamber[i]) < 0.2)
10958  ok++;
10959  }
10960 
10961  // if all the sample region HV's are ok within 200V leave the loop
10962  if (ok == 5) {
10963  done = true;
10964  happy = true;
10965  }
10966 
10967  // check if timeout occured
10968  if (t.elapsed() > 3e5) { // 5 min. timeout
10969  done = true;
10970  err = QString("PLemAutoRun::ChangeSampleChamberHV: Couldn't ramp back sample region HV's. Will give it another try in 120 sec.");
10971  emit ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
10972  }
10973  } while (!done);
10974 
10975  if (happy) // everything perfect, get out of the loop
10976  break;
10977 
10978  // wait 120 sec before retrial
10979  Wait(120000);
10980  } else { // NO FUG HV check, hence just wait a 1 min
10981  Wait(60000);
10982  j = 0;
10983  }
10984  }
10985 
10986  if (j == HV_FUG_MAX_TRY) {
10988  err = QString("PLemAutoRun::ChangeSampleChamberHV: Couldn't ramp back sample region HV's. Error too severe, will stop.");
10989  emit ErrorMsg(1, 0, LAR_FUG_NO_RESPONSE, -1, err);
10990  }
10991  }
10992 }
10993 
10994 //**********************************************************************
10995 // SetBPV - AutoRunCmd
10996 //**********************************************************************
11003 {
11004  QString msg("");
11005 
11006  // check if lemvac equipment is disabled in lemAutoRun
11007  if (!fEnabled["lemvac_eq"]) {
11008  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
11009  msg += "PLemAutoRun::SetBPV: lemvac equipment disabled in lemAutoRun. Will do nothing here.";
11010  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
11011  // increment command counter
11013  return;
11014  }
11015 
11016  msg = QString("(%1/%2) ").arg(fCurrentAutoRunCmd).arg(fNoOfAutoRunCmds);
11017  msg += arc->cmdString;
11018  emit ErrorMsg(1, 0, LAR_MSG, arc->lineNo, msg);
11019 
11020  msg = QString("Autorun running: ") + msg;
11021  emit StatusMsg(msg);
11022 
11023  int label=BPVX, state=BPV_CLOSE;
11024  // get valve label
11025  if (arc->param[0] == "X")
11026  label = BPVX;
11027  else
11028  label = BPVY;
11029 
11030  // get valve state
11031  if ((arc->param[1] == "1") || (arc->param[1] == "open"))
11032  state = BPV_OPEN;
11033 
11034  SetBPV(label, state);
11035 
11036  // increment command counter
11038 }
11039 
11040 //**********************************************************************
11041 // SetBPV
11042 //**********************************************************************
11053 bool PLemAutoRun::SetBPV(int valve, int cmd)
11054 {
11055  int size;
11056  int index;
11057  float value;
11058 
11059  if (!fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
11060  return true;
11061  }
11062 
11063  // check if BPVX/Y is enabled
11064  size = sizeof(value);
11065  if (valve == BPVX)
11066  index = BPVX_ENABLED;
11067  else
11068  index = BPVY_ENABLED;
11069  fLemvacOutputKey->GetDataIndex(&value, &size, index, TID_FLOAT);
11070 
11071  if (value != 1) { // BPVX/Y NOT enabled
11072  return false;
11073  }
11074 
11075  // set new state of the BPVX/Y
11076  value = cmd;
11077  if (valve == BPVX)
11078  index = BPVX_SET;
11079  else
11080  index = BPVY_SET;
11081 
11082  fLemvacOutputKey->SetDataIndex(&value, index, TID_FLOAT);
11083 
11084  // check if the state really has changed
11085  if (valve == BPVX)
11086  index = BPVX_STATE;
11087  else
11088  index = BPVY_STATE;
11089  bool done = false;
11090  QElapsedTimer t;
11091  t.start();
11092  do {
11093  Wait(2000); // sleep for 2 sec
11094 
11095  size = sizeof(value);
11096  fLemvacInputKey->GetDataIndex(&value, &size, index, TID_FLOAT);
11097 
11098  if (value == BPV_STATE_LOCKED)
11099  return true;
11100 
11101  if (cmd == BPV_CLOSE) { // close command
11102  if (value == BPV_STATE_CLOSED)
11103  done = true;
11104  } else { // open command
11105  if (value == BPV_STATE_OPEN)
11106  done = true;
11107  }
11108 
11109  if (t.elapsed() > 6e4) { // no correct read back within 60 sec
11110  return false;
11111  }
11112  } while (!done);
11113 
11114  return true;
11115 }
11116 
11117 //**********************************************************************
11118 // GetBPV
11119 //**********************************************************************
11128 {
11129  int size;
11130  int index;
11131  float value;
11132 
11133  if (!fEnabled["lemvac_scfe"]) { // only needed if LEMVAC is enabled
11134  return true;
11135  }
11136 
11137  index = BPVX_STATE;
11138  size = sizeof(value);
11139  fLemvacInputKey->GetDataIndex(&value, &size, index, TID_FLOAT);
11140  if ((value != BPV_STATE_OPEN) && (value != BPV_STATE_CLOSED) && (value != BPV_STATE_LOCKED))
11141  return false;
11142  fLemVacValveInitialState[BPVX] = value;
11143 
11144  fExp->FeedMidasWatchdog();
11145 
11146  index = BPVY_STATE;
11147  fLemvacInputKey->GetDataIndex(&value, &size, index, TID_FLOAT);
11148  if ((value != BPV_STATE_OPEN) && (value != BPV_STATE_CLOSED) && (value != BPV_STATE_LOCKED))
11149  return false;
11150  fLemVacValveInitialState[BPVY] = value;
11151 
11152  return true;
11153 }
11154 
11155 //**********************************************************************
11156 // RawVoltageDump
11157 //**********************************************************************
11163 {
11164  float rv[8];
11165  float value, value1, value2, value3, value4, value5, value6;
11166  int size4 = sizeof(value);
11167 
11168  // get the time in a LS340 compatible way
11169  struct timespec tp;
11170  clock_gettime(CLOCK_REALTIME, &tp);
11171  struct tm *timeinfo;
11172  timeinfo = localtime(&tp.tv_sec);
11173  char LSdateTime[32];
11174  snprintf(LSdateTime, sizeof(LSdateTime), "%02d,%02d,%04d,%02d,%02d,%02d,%03d",
11175  timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_year + 1900,
11176  timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec,
11177  (int)(tp.tv_nsec / 1000000));
11178 
11179  fSampleInputKey->GetDataIndex(&value1, &size4, fSampleCtrlCh, TID_FLOAT);
11180  fSampleInputKey->GetDataIndex(&value2, &size4, LS336_INPUT_PRESSURE, TID_FLOAT);
11181  fSampleInputKey->GetDataIndex(&value3, &size4, LS336_INPUT_HEATER, TID_FLOAT);
11182  fSampleInputKey->GetDataIndex(&value4, &size4, LS336_INPUT_SETPOINT, TID_FLOAT);
11183  fSampleInputKey->GetDataIndex(&value5, &size4, LS336_INPUT_HEATER_RANGE, TID_FLOAT);
11184  fSampleInputKey->GetDataIndex(&value6, &size4, fSampleBhOdbOffsetInput+BH_INPUT_FLOW, TID_FLOAT);
11185 
11186  for (int i=0; i<8; i++) {
11187  fSampleRawVoltageKey->GetDataIndex( &value, &size4, i, TID_FLOAT);
11188  rv[i] = value;
11189  }
11190 
11191  QTextStream stream( &fDumpFile );
11192  stream << LSdateTime << "," <<
11193  value1 << "," <<
11194  value2 << "," <<
11195  value3 << "," <<
11196  value4 << "," <<
11197  value5 << "," <<
11198  value6;
11199  for (int i=0; i<8; i++)
11200  stream << "," << rv[i];
11201  stream << Qt::endl;
11202  fDumpFile.flush();
11203 
11204  fDumpCounter--;
11205 }
11206 
11207 //**********************************************************************
11208 // Wait
11209 //**********************************************************************
11217 void PLemAutoRun::Wait(int timeout)
11218 {
11219  int count = timeout / 1000; // how many 1 sec steps needed
11220 
11221  for (int i=0; i<count; i++) {
11222  ss_sleep(1000); // sleep 1 sec
11223  fExp->FeedMidasWatchdog();
11224  }
11225 
11226  // deal with the sub-second rest
11227  if ((timeout % 1000) != 0) {
11228  ss_sleep(timeout % 1000);
11229  fExp->FeedMidasWatchdog();
11230  }
11231 }
11232 
11233 
11234 //**********************************************************************
11235 // TdHvTripFlagChanged
11236 //**********************************************************************
11242 void TdHvTripFlagChanged(HNDLE, HNDLE, void *info)
11243 {
11244  PLemAutoRun *lar;
11245  lar = (PLemAutoRun *)info;
11246 
11247  // check if TD HV Trip Alarm flag is true
11248  if (lar->fHvTripFlag) {
11249  QString err = QString("PLemAutoRun: HV trip due to TD rate trip! Will wait until the problem is resolved.");
11250  emit lar->ErrorMsg(1, 0, LAR_MSG_NO_LINE_NO, -1, err);
11251  }
11252 }
11253 
11254 //---------------------------------------------------------------------------------------
11255 // end
11256 //---------------------------------------------------------------------------------------
QString fDanfysikOutputPath
ODB path to the danfysik output variables.
Definition: PLemAutoRun.h:428
#define BPV_STATE_LOCKED
BPVX/Y locked.
Definition: PLemAutoRun.cpp:69
QVector< QString > fHvChName
Definition: PLemAutoRun.h:221
void WaitUntilSampleLSReady()
QString fModDatePath
ODB path to the moderator growing date.
Definition: PLemAutoRun.h:412
float fPrefNeedleValveAbsStep
absolute change in SampleTempConsiderNeedleValve
Definition: PLemAutoRun.h:346
PKey * fTofMaxKey
pointer to the ODB key: TOF max
Definition: PLemAutoRun.h:501
#define LS336_OUTPUT_PID_P
ODB Offset for P output L1.
ELemAutoRunKeyWords fKey
key tag for the parsing process
Definition: PLemAutoRun.h:139
#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:451
void NetworkConnectionLost()
slot executed if the network connection is lost
PKey * fAlarmsKey
pointer to the ODB key: alarms
Definition: PLemAutoRun.h:496
#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:462
PKey * fFOMOutputKey
pointer to the ODB key: FOM output values
Definition: PLemAutoRun.h:537
QString fWEWInputPath
ODB path to the WEW input variable.
Definition: PLemAutoRun.h:429
#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:55
void RunStart(AutoRunCmd *arc)
void SetFieldWEWL(AutoRunCmd *arc)
int fAutoRunState
autorun run state as defined under /AutoRun/Run State
Definition: PLemAutoRun.h:275
void UpdateWebPage(PAutoRunCmdVector::Iterator currentIter, int tag, int lineNo=0, QString errMsg="")
#define LS_CTRL_ZONE
LS340/LS336 in table driven PID mode (zone settings)
Definition: PLemAutoRun.cpp:76
float demand_T
setpoint to be reached
Definition: PLemAutoRun.h:62
#define TEMP_HEATER_RANGE
heater range parameter tag
float fDFlowDp1
DFDP_0 + DFDP_1 * exp( DFDP_EXP * Temp )
Definition: PLemAutoRun.h:326
QVector< float > * GetCurrentLimits()
Definition: PLemAutoRun.h:213
void SetSampleHV(AutoRunCmd *arc)
bool fWarmUpVent
warmup with vent flag, false=no vent, true=vent
Definition: PLemAutoRun.h:388
void SetGotoLine(const int line)
PLemAutoRun::SetGotoLine.
bool fNeedleValveInUse
Tag for use of electric needle valve.
Definition: PLemAutoRun.h:336
QString fTflFeName
Definition: PLemAutoRun.h:458
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
ELemHvSettingsKeyWords fKey
key tag for the parsing process
Definition: PLemAutoRun.h:226
bool fSetupBparEnabled
true if the Bpar magnet is in use. This is fed with the Danfysik power supply.
Definition: PLemAutoRun.h:400
QString fHVDetectorDemandPath
ODB path to the HV Detectors demand variables.
Definition: PLemAutoRun.h:423
#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 (LakeShore, BH)
Definition: PLemAutoRun.h:468
#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:311
void TdHvTripFlagChanged(HNDLE, HNDLE, void *info)
#define LAR_FATAL
something unexpected really bad happend
Definition: lemAutoRun.h:35
float fHeatCapCof1
heat Capacity of cryo =
Definition: PLemAutoRun.h:331
QString fSampleNamePath
ODB path to the sample name.
Definition: PLemAutoRun.h:414
#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:523
PKey * fSetupWewEnabledKey
pointer to the ODB key: WEW enabled flag
Definition: PLemAutoRun.h:542
#define WEW_SSP_LOCK
ODB Offset for the WEW-SSP lock.
#define RUN_PAUSED
MIDAS run paused tag.
Definition: PLemAutoRun.cpp:54
#define BPVX
BPVX label.
Definition: PLemAutoRun.cpp:57
QString fSampleOvenOmegaFeName
name of the oven omega scfe in the ODB
Definition: PLemAutoRun.h:460
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:510
#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:467
PKey * fSetupSampleEnabledKey
pointer to the ODB key: Sample enabled flag
Definition: PLemAutoRun.h:541
float fPrefNeedleValveCof_4_0
NV setting = _1_0 * _1_1 * T for 15<T.
Definition: PLemAutoRun.h:343
#define LS336_OUTPUT_SETPOINT
ODB Offset for the setpoint L1.
QString GetAutoRunSequence()
PLemAutoRun::GetAutoRunSequence.
void SetTemp(AutoRunCmd *arc)
#define LS336_INPUT_CF2
ODB Offset for the cold finger 2 sensor.
void SetSampleLSZoneSettings()
QVector< float > * GetHvDemands()
Definition: PLemAutoRun.h:212
PKey * fModNameKey
pointer to the ODB key: moderator info
Definition: PLemAutoRun.h:502
void SetFieldWEWH(AutoRunCmd *arc)
QString fTflInputPath
ODB path to the tfl input variables.
Definition: PLemAutoRun.h:432
float fFlowMaxRelFlowDiffToConsider
maximum rel flow error to consider
Definition: PLemAutoRun.h:324
float fBHMinFlow
min. allowed flow for the bronkhorst flow meter
Definition: PLemAutoRun.h:305
#define LS336_OUTPUT_HEATER_MODE
ODB Offset for the heater control mode L1.
bool parse(QIODevice *device)
bool fSetupWewEnabled
true if the WEW magnet is in use. This is fed with the WEWL/H power supplies.
Definition: PLemAutoRun.h:399
#define LS_CTRL_PID
LS340 in manual PID mode or LS336 in closed loop PID mode.
Definition: PLemAutoRun.cpp:75
#define LS336_OUTPUT_HEATER_RANGE
ODB Offset for the heater range L1.
void ReadSampleCryoXML()
#define BPVX_SET
ODB offset for BPVX set cmd (output)
Definition: PLemAutoRun.cpp:62
PLemAutoRunXMLParser(const QString fln, PLemAutoRun *lar)
bool fSetupSampleEnabled
true if the sample frontend is enabled (normal operation), otherwise MCP2 setup.
Definition: PLemAutoRun.h:398
QString fLemvacOutputPath
ODB path to the lemvac output variables.
Definition: PLemAutoRun.h:443
#define LAR_TT_IDLE
PAutoRunCmdVector::Iterator fAutoRunCurrentIter
current autorun cmd
Definition: PLemAutoRun.h:480
PKey * fDanfysikInputKey
pointer to the ODB key: danfysik input variables
Definition: PLemAutoRun.h:518
bool fHVFeRunning
flag indicating if the hv_fug_scfe is running
Definition: PLemAutoRun.h:472
#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:465
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:416
QString fMagFieldPath
ODB path to the magnetic field value.
Definition: PLemAutoRun.h:431
QString fLemSetupPath
ODB path to the LEM setup info.
Definition: PLemAutoRun.h:413
PKey * fDanfysikOutputKey
pointer to the ODB key: danfysik output variables
Definition: PLemAutoRun.h:519
bool parse(QIODevice *device)
float fPrefNeedleValveCof_3_1
Definition: PLemAutoRun.h:342
bool fRunCheckEvents
if true check number of events, otherwise check time
Definition: PLemAutoRun.h:487
float fBHFlowPHeat0
see SampleTempAdjustFlow()
Definition: PLemAutoRun.h:306
#define BPVX_STATE
ODB offset for BPVX state (input)
Definition: PLemAutoRun.cpp:65
#define LAR_TT_ABORTED
double datetime
time as obtained from the LS340 or the system
Definition: PLemAutoRun.h:61
QVector< int > fHvChNo
Definition: PLemAutoRun.h:220
#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:368
#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:482
QString fFieldPwrSupply
name of the power supply to generate the magnetic field (WEWL, WEWH, danfysik)
Definition: PLemAutoRun.h:293
void SetFOM(AutoRunCmd *arc)
bool fDumpInUse
flag telling if a raw data dump is going on
Definition: PLemAutoRun.h:381
QString fXMLAutoRunValidateFln
path-file name of the generated XML-autorun sequence for validation
Definition: PLemAutoRun.h:290
void CheckMidasAlarms(PAutoRunCmdVector::Iterator iter)
void SetTfl(AutoRunCmd *arc)
PLemAutoRun::SetTfl.
bool parse(QIODevice *device)
#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:358
QString fFOMOutputPath
ODB path to the FOM output variables.
Definition: PLemAutoRun.h:445
#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:313
int noElements
number of parameters used for this command
Definition: lemAutoRun.h:224
float fHeaterMin
min. acceptable heater value
Definition: PLemAutoRun.h:317
float flow
helium flow (read back)
Definition: PLemAutoRun.h:65
#define NO_ENERGY_LOSS_PARAM
Definition: PLemAutoRun.h:50
float fWEWHMaxCurrent
maximal allowed current for the WEWH power supply
Definition: PLemAutoRun.h:366
QString fLemvacFeName
name of the lemvac_scfe in the ODB
Definition: PLemAutoRun.h:464
#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:302
QString fAutoRunSequence
autorun sequence file name as found under /AutoRun/Auto Run Sequence
Definition: PLemAutoRun.h:270
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 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:440
void SetLEMSetup(AutoRunCmd *arc)
QString fAlarmsPath
ODB path to the alarms.
Definition: PLemAutoRun.h:406
bool RunStopCheck()
float fBHFlowTemp
variable needed to calculate the flow if non is explicitly given (see SetTemp())
Definition: PLemAutoRun.h:309
QString fMagParamBparPath
ODB path to the Bpar parameters (A -> G)
Definition: PLemAutoRun.h:448
#define TEMP_I_PID
I (PID) parameter tag.
PKey * fSampleSensorTypeKey
pointer to the ODB key: sample cryo LakeShore sensor type assignement
Definition: PLemAutoRun.h:527
QString fAutoRunPath
path to the autorun sequence directory
Definition: PLemAutoRun.h:292
QString fXMLAutoRunHTML
path-file name of the HTML autorun status page
Definition: PLemAutoRun.h:291
#define LAR_TT_WARMUP
QString fBeamlineDemandPath
ODB path to the beamline demand variables.
Definition: PLemAutoRun.h:446
float fDSetRatio
ratio at which the PID-D has to be switched back (for temperature increase)
Definition: PLemAutoRun.h:312
void CheckClients()
int fGotoLine
address to jump to within a running autorun. Defined under /AutoRun/GotoLine
Definition: PLemAutoRun.h:272
float fPrefNeedleValveCof_1_1
Definition: PLemAutoRun.h:338
#define HV_FUG_SAMPLE
ODB Offset for the FUG HV of the sample.
QString fRunInfoPath
ODB path to the run info.
Definition: PLemAutoRun.h:403
#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:517
int state
1 = stopped, 2 = paused, 3 = running
Definition: PLemAutoRun.h:74
#define LAR_LS_TEMP_NOT_STABLE
sample temperature is out of the tolerance band
Definition: lemAutoRun.h:81
#define LS336_OUTPUT_RAMP
ODB Offset for the demand temperature ramping L1.
void DegaussDanfysik(AutoRunCmd *arc)
QString fAlarmTdHvTripPath
ODB path to the TD HV trip alarm/warning.
Definition: PLemAutoRun.h:407
void FeedLiveDataAutoRun()
PLemAutoRun::FeedLiveDataAutoRun.
QString fNextAutoRunSequence
next autorun sequence file name as found under /AutoRun/Next
Definition: PLemAutoRun.h:273
#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:459
#define SAMPLE_CRYO_OUTPUT
Definition: PLemAutoRun.h:45
#define TEMP_P_PID
P (PID) parameter tag.
void Wait(int timeout)
float fDFlowDp0
calculates d(flow)/dP from d(flow)/dP =
Definition: PLemAutoRun.h:325
double fSampleHistoTime
time stamp of the current reading in seconds since 1-1-2000
Definition: PLemAutoRun.h:354
float fHeatCapCof3
Definition: PLemAutoRun.h:333
PLemAutoRun * fLar
pointer to the calling class
Definition: PLemAutoRun.h:183
PKey * fHVDetectorMeasuredKey
pointer to the ODB key: HV Detector measured values
Definition: PLemAutoRun.h:515
PKey * fSampleChannelKey
pointer to the ODB key: sample cryo LakeShore channel assignement
Definition: PLemAutoRun.h:526
bool fEnableAll
flag telling if all watched clients and equipments will be enabled/disabled by default.
Definition: PLemAutoRun.h:277
float SetDemandTempRamping(QString rampParam)
#define HTML_ABORTED
html abortion tag
QFile fDumpFile
file for dumping raw_voltage
Definition: PLemAutoRun.h:384
bool ShowComments()
PLemAutoRun::ShowComments.
float fFlowTimeoutReduction
timeout between gradual flow reduction while cooling
Definition: PLemAutoRun.h:322
#define BPVY_STATE
ODB offset for BPVY state (input)
Definition: PLemAutoRun.cpp:66
float fFieldTimeout
time in which the field ramping must be accomplished (in (sec))
Definition: PLemAutoRun.h:298
void UpdateRunState(const int state)
UpdateRunState.
#define BPV_CLOSE
closing command for BPVX/Y
Definition: PLemAutoRun.cpp:59
PKey * fSpinRotAngleKey
pointer to the ODB key: spin rotation angle
Definition: PLemAutoRun.h:507
float fMaxTempIncrease
maximal temperature increase without shuting down the HV
Definition: PLemAutoRun.h:297
#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:304
#define LS336_OUTPUT_PID_I
ODB Offset for I output L1.
#define LS336_INPUT_PID_D
ODB Offset for the D value of the PID L1 (read back)
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:360
QString fHVMeasuredPath
ODB path to the FUG HV measured variables.
Definition: PLemAutoRun.h:421
int fHvTripFlag
flag: set if the TD HV trip alarm fired
Definition: PLemAutoRun.h:284
#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:410
bool CheckForTransportHvCmd()
bool fFrontendRunning
flag indicating if the frontend is running
Definition: PLemAutoRun.h:466
#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:375
QString fHvSettingsPath
Definition: PLemAutoRun.h:378
#define HTML_PARSE_ERROR
html autorun script parse error tag
void ConnectToExp()
PKey * fLemvacInputKey
pointer to the ODB key: lemvac input values
Definition: PLemAutoRun.h:534
#define BPVY_ENABLED
ODB offset for BPVY enabled flag (output)
Definition: PLemAutoRun.cpp:63
#define HV_FUG_LEFT_RODS
ODB Offset for the FUG HV of the left rods of the spin rotator.
int lineNo
line number from where in the user auto run sequence the command originates
Definition: lemAutoRun.h:223
#define LS336_INPUT_SETPOINT
ODB Offset for the setpoint L1 read back.
#define HTML_RUNNING
html running tag
QString fModNamePath
ODB path to the moderator info.
Definition: PLemAutoRun.h:411
#define TEMP_RAMP
ramping parameter tag
float fHeatCapCof2
HC_1 * T + HC_2 * T² + HC_3 * T³
Definition: PLemAutoRun.h:332
#define LAR_XML_FILE_MISSING
XML file missing error tag.
Definition: lemAutoRun.h:64
#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:469
float fSampleOvenOmegaInput[SAMPLE_OVEN_OMEGA_INPUT]
Definition: PLemAutoRun.h:394
QString fSampleCtrlChPath
ODB path to the sample cryo LakeShore control channel.
Definition: PLemAutoRun.h:434
void SetBPV(AutoRunCmd *arc)
bool fWarmUpWished
warmup command present
Definition: PLemAutoRun.h:387
#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:283
#define WEWL_INPUT_CURRENT
ODB Offset for the measured current of the WEWL.
POdbTagVector * fOdbTagVector
pointer to the ODB tag list
Definition: PLemAutoRun.h:478
PKey * fEnergyLossParamKey
pointer to the ODB key: energy loss parameters
Definition: PLemAutoRun.h:509
#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:404
#define LS336_INPUT_PRESSURE
ODB Offset for the He pressure before the bronkhorst.
float fRunTimeout
time in sec after which the run shall be stopped.
Definition: PLemAutoRun.h:490
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:533
float fPrefNeedleValveCof_4_1
Definition: PLemAutoRun.h:344
#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:321
float fFlowSetRatio
relative flow deviation allowed in stability test
Definition: PLemAutoRun.h:320
QString fSampleOvenOmegaOutputPath
ODB path to the sample oven omega: output variables.
Definition: PLemAutoRun.h:441
float fMaxTempTrend
max. acceptable temperature trend
Definition: PLemAutoRun.h:315
QString fMagParamWewPath
ODB path to the WEW parameters (A -> G)
Definition: PLemAutoRun.h:447
#define BPVX_ENABLED
ODB offset for BPVX enabled flag (output)
Definition: PLemAutoRun.cpp:61
bool fDanfysikFeRunning
flag indicating if the danfysik_scfe is running
Definition: PLemAutoRun.h:470
QString fClientsPath
ODB path to the running clients.
Definition: PLemAutoRun.h:419
#define CRYO_LOWTEMP
LowTemp cryo in use.
Definition: PLemAutoRun.cpp:49
QString fSampleSensorTypePath
ODB path to the sample cryo LakeShore sensor type assignement.
Definition: PLemAutoRun.h:436
#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:506
void SetTitle(AutoRunCmd *arc)
void SampleTempSetNeedleValve(float value)
int run_number
run number
Definition: PLemAutoRun.h:76
PKey * fHVDetectorDemandKey
pointer to the ODB key: HV Detector demand values
Definition: PLemAutoRun.h:514
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:538
#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:500
double fSampleHistoLastTime
time stamp of the previous reading in seconds since 1-1-2000
Definition: PLemAutoRun.h:355
#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:300
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.
bool fSampleTempUnstable
flag: true if the temperature is out of bound
Definition: PLemAutoRun.h:353
PKey * fTflOutputKey
pointer to the ODB key: tfl output values
Definition: PLemAutoRun.h:524
PKey * fHVDemandKey
pointer to the ODB key: FUG HV demand values
Definition: PLemAutoRun.h:511
#define SC_VENT_CMD
ODB offset for SC vent command tag (output)
Definition: PLemAutoRun.cpp:72
#define CRYO_OVEN_OMEGA
Oven in use, controlled by Omega Controller.
Definition: PLemAutoRun.cpp:50
float fTimeoutFlowSet
timeout before the flow can be changed next time (see SetTemp())
Definition: PLemAutoRun.h:318
QString fSpinRotEnabledPath
ODB path to the spin rotation enabled flag.
Definition: PLemAutoRun.h:415
#define TEMP_D_PID
D (PID) parameter tag.
QString fAnalyzerName
name of the analyzer in the ODB
Definition: PLemAutoRun.h:456
PKey * fMagParamWewKey
pointer to the ODB key: WEW magnet parameters (A -> G)
Definition: PLemAutoRun.h:539
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-<cryo>-<datatime>.dat, e.g. RawVoltageOutput-Konti4-220316-1235.dat
Definition: PLemAutoRun.h:383
float fRelMaxTempDiff
relative temperature deviation allowed in stability test
Definition: PLemAutoRun.h:314
float fBHFlowDHeat
see SampleTempAdjustFlow()
Definition: PLemAutoRun.h:308
PKey * fMagFieldKey
pointer to the ODB key: magnetic field value
Definition: PLemAutoRun.h:522
PKey * fSampleOvenOmegaInputKey
pointer to the ODB key: sample oven omega input values
Definition: PLemAutoRun.h:532
float fBHFlowTempOffset
variable needed to calculate the flow if non is explicitly given (see SetTemp())
Definition: PLemAutoRun.h:310
QString fDanfysikInputPath
ODB path to the danfysik input variables.
Definition: PLemAutoRun.h:427
QString fHVCurrentPath
ODB path to the FUG HV measured current variables.
Definition: PLemAutoRun.h:422
void SetFlow(QString flowParam)
QString fTofMinPath
ODB path to the TOF min.
Definition: PLemAutoRun.h:409
QVector< QString > * GetHvChNames()
Definition: PLemAutoRun.h:211
#define TEMP_FLOW
flow parameter tag
#define LS336_INPUT_RAMP
ODB Offset for the demand temperature ramping read back.
float measured_T
measured temperature of the sample
Definition: PLemAutoRun.h:63
bool CheckOdbType(INT type, AutoRunCmd *arc)
bool fLemvacFeRunning
flag indicating if the lemvac_scfe is running
Definition: PLemAutoRun.h:473
#define FOM_CURRENT_DEMAND
ODB Index of the FOM current setpoint.
#define DANFYSIK_OUTPUT_CURRENT
ODB Offset for the demand current of the danfysik.
#define LS336_INPUT_HEATER_MODE
ODB Offset for the heater control mode read back.
float fFlowFactor
constant used in SampleTempConsiderFlow()
Definition: PLemAutoRun.h:319
bool GetAllKeys()
void SetLSSetpoint(float setpoint, float rampSpeed)
QVector< float > fHvDemand
Definition: PLemAutoRun.h:222
QString fXMLSchemaFln
path-file name of the XML-schema for the parsing process
Definition: PLemAutoRun.h:288
QString fEnergyLossParamPath
ODB path to the energy loss parameters.
Definition: PLemAutoRun.h:418
SampleTempInfo fSampleTempAverage
average temperature control parameters
Definition: PLemAutoRun.h:359
float heater
sample heater
Definition: PLemAutoRun.h:64
#define LAR_RECIEVED_SHUTDOWN_CMD
recieved shutdown cmd tag
Definition: lemAutoRun.h:49
void SetModInfo(AutoRunCmd *arc)
QString fExpName
experiment name
Definition: PLemAutoRun.h:287
void SetTempOvenOmega(AutoRunCmd *arc)
int fDumpCounter
counter of raw voltage dumps
Definition: PLemAutoRun.h:382
PKey * fSampleCryoKey
pointer to the ODB key: sample cryo name
Definition: PLemAutoRun.h:508
PKey * fSampleRawVoltageKey
pointer to the ODB key: sample cryo raw voltage
Definition: PLemAutoRun.h:530
float fPrefNeedleValveCof_2_1
Definition: PLemAutoRun.h:340
float fMagParamBpar[2]
calibration array for the Bpar
Definition: PLemAutoRun.h:369
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:453
QString fXMLAutoRunFln
path-file name of the generated XML-autorun sequence
Definition: PLemAutoRun.h:289
int fSampleHistoNoEntries
number of entries in the history
Definition: PLemAutoRun.h:356
#define SC_VENT_ENABLED
ODB offset for SC vent enable flag (output)
Definition: PLemAutoRun.cpp:71
#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:327
#define SAMPLE_CRYO_INPUT
Definition: PLemAutoRun.h:44
void UpdateStatusMsg(const QString statusMsg)
void SetTof(AutoRunCmd *arc)
void SetIgnoreAlarms(AutoRunCmd *arc)
void DisconnectAndQuit()
void SetOdbDataArray(AutoRunCmd *arc)
void RunStop(AutoRunCmd *arc)
int fSampleHistoPos
index of the start of the ring buffer
Definition: PLemAutoRun.h:357
#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.
PLemSampleCryoXMLParser(const QString fln, PLemAutoRun *lar)
void WarmUp(PAutoRunCmdVector::Iterator iter)
PKey * fLemSetupKey
pointer to the ODB key: LEM setup info
Definition: PLemAutoRun.h:504
int fSampleBhOdbOffsetOutput
ODB offset of the bronkhorst within the ODB (output variables.
Definition: PLemAutoRun.h:454
void CheckForOdbSetDataCmds()
QString fSampleChannelPath
ODB path to the sample cryo LakeShore channel assignement.
Definition: PLemAutoRun.h:435
#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:352
#define FOM_STANDBY
ODB Index of the FOM stanby flag.
#define BPV_OPEN
opening command for BPVX/Y
Definition: PLemAutoRun.cpp:60
PKey * fSetupBparEnabledKey
pointer to the ODB key: Bpar enabled flag
Definition: PLemAutoRun.h:543
int fSampleCtrlCh
index of channel A or B
Definition: PLemAutoRun.h:349
friend void TdHvTripFlagChanged(HNDLE, HNDLE, void *)
float fPrefNeedleValveRelStep
relative change in SampleTempConsiderNeedleValve
Definition: PLemAutoRun.h:345
#define BPVY
BPVY label.
Definition: PLemAutoRun.cpp:58
#define BPV_STATE_CLOSED
BPVX/Y closed.
Definition: PLemAutoRun.cpp:68
void SetLSHeaterRangeAndPIDs(AutoRunCmd *arc)
QMap< QString, bool > fEnabled
map holding the enable/disable info of all the clients and equipments
Definition: PLemAutoRun.h:278
bool fSampleOvenOmegaFeRunning
flag indicating if the omega_scfe is running
Definition: PLemAutoRun.h:471
void SetTransportHV(AutoRunCmd *arc)
bool fRunStopped
flag telling if a run is stopped
Definition: PLemAutoRun.h:485
void DegaussWEW(AutoRunCmd *arc)
QDateTime fWarmUpDateTime
when the warmup shall take place
Definition: PLemAutoRun.h:389
void SetFlowTweak(float flow)
ELemSampleCryoKeyWords fKey
key tag for the parsing process
Definition: PLemAutoRun.h:184
PKey * fTriggerEventsKey
pointer to the ODB key: trigger event
Definition: PLemAutoRun.h:495
PKey * fSampleInputKey
pointer to the ODB key: sample cryo input values
Definition: PLemAutoRun.h:528
float pressure
helium pressure at cryo outlet
Definition: PLemAutoRun.h:66
float fMagParamWew[2]
calibration array for the WEW
Definition: PLemAutoRun.h:367
#define CRYO_KONTI
Konti cryo in use.
Definition: PLemAutoRun.cpp:48
PKey * fModDateKey
pointer to the ODB key: moderator growing date
Definition: PLemAutoRun.h:503
void CheckForWarmUpCmd()
QString fTflOutputPath
ODB path to the tfl output variables.
Definition: PLemAutoRun.h:433
QString fHVDemandPath
ODB path to the FUG HV demand variables.
Definition: PLemAutoRun.h:420
QXmlStreamReader fXml
xml stream reader object
Definition: PLemAutoRun.h:225
SampleTempInfo fSampleTempSecond
2nd derivative of the quadratic model of the temperature control parameters
Definition: PLemAutoRun.h:361
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.
QString fSetupWewEnabledPath
ODB path to the WEW enabled flag.
Definition: PLemAutoRun.h:450
PKey * fWEWInputKey
pointer to the ODB key: WEW input values
Definition: PLemAutoRun.h:520
#define LS336_INPUT_HEATER
ODB Offset for the heater L1 read back.
PKey * fAlarmTdHvTripKey
pointer to the ODB key: TD HV trip trigger flag
Definition: PLemAutoRun.h:497
#define LAR_MSG_NO_LINE_NO
message tag for the message/error handler for no line number information
Definition: lemAutoRun.h:34
bool fIgnoreClients
flag: if true checking of clients will not performed: only for testing!!
Definition: PLemAutoRun.h:280
void ReceivedShutdownCmd()
slot executed if a shutdown command has been received
PLemHvSettingsFileParser(const QString fln)
float EmpiricalFlow(float Tset, float rampSpeed)
QString fSampleInputPath
ODB path to the sample cryo (LakeShore, bronkhorst) input variables.
Definition: PLemAutoRun.h:437
#define WEWH_INPUT_STATUS
ODB Offset for the WEWH status.
int GetRunState()
PLemAutoRun::GetRunState.
void SetLSMode(AutoRunCmd *arc)
PKey * fSampleNameKey
pointer to the ODB key: Sample Name
Definition: PLemAutoRun.h:505
#define RUN_STOPPED
MIDAS run stopped tag.
Definition: PLemAutoRun.cpp:53
#define LS336_INPUT_CF1
ODB Offset for the cold finger 1 sensor.
Definition: PLemAutoRun.cpp:99
#define FOM_CURRENT_MEASURED
ODB Index of the FOM current reading.
QElapsedTimer fRunStarted
time stamp, when a run started
Definition: PLemAutoRun.h:489
#define HV_FUG_MIRROR
ODB Offset for the FUG HV of the mirror.
QString fSampleOutputPath
ODB path to the sample cryo (LakeShore, bronkhorst) output variables.
Definition: PLemAutoRun.h:438
PKey * fSampleOutputKey
pointer to the ODB key: sample cryo output values
Definition: PLemAutoRun.h:529
PKey * fHVMeasuredKey
pointer to the ODB key: FUG HV measured values
Definition: PLemAutoRun.h:512
QVector< float > fCurrentLimit
Definition: PLemAutoRun.h:223
QString fWEWOutputPath
ODB path to the WEW output variable.
Definition: PLemAutoRun.h:430
#define SAMPLE_TEMP_HISTO_MAX
Definition: PLemAutoRun.h:48
PKey * fSampleNoConnectionKey
pointer to the ODB key: sample cryo no connection
Definition: PLemAutoRun.h:531
QString fFOMInputPath
ODB path to the FOM input variables.
Definition: PLemAutoRun.h:444
#define LAR_LS_INPUT_NONSENSE
sample lakshore readback doesn&#39;t make any sense
Definition: lemAutoRun.h:80
QString fHVDetectorMeasuredPath
ODB path to the HV Detectors measured variables.
Definition: PLemAutoRun.h:424
int GetGotoLine()
PLemAutoRun::GetGotoLine.
float fSampleOutput[SAMPLE_CRYO_OUTPUT]
Definition: PLemAutoRun.h:393
float fSampleOvenOmegaOutput[SAMPLE_OVEN_OMEGA_OUTPUT]
Definition: PLemAutoRun.h:395
float fFlowLowestFlowToConsider
lowest demand flow to consider
Definition: PLemAutoRun.h:323
float fSampleInput[SAMPLE_CRYO_INPUT]
Definition: PLemAutoRun.h:392
#define CRYO_NO
no cryo in use
Definition: PLemAutoRun.cpp:47
QXmlStreamReader fXml
xml stream reader object
Definition: PLemAutoRun.h:137
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:372
PKey * fRunCommentKey
pointer to the ODB key: run comment
Definition: PLemAutoRun.h:499
float fWEWLMaxCurrent
maximal allowed current for the WEWL power supply
Definition: PLemAutoRun.h:365
float fEnergyLossParam[NO_ENERGY_LOSS_PARAM]
energy loss parameters
Definition: PLemAutoRun.h:296
int fSampleCryoInUse
-1 = no cryo in use, 0 = Konti-Cryo in use, 1 = LowTemp-Cryo, 2 = Oven in use
Definition: PLemAutoRun.h:350
QString fAutoRunStatusMsg
autorun status message as defined under /AutoRun/Status
Definition: PLemAutoRun.h:274
void CheckTempStabilityOvenOmega()
bool fDebug
flag: if true additional messages will be sent to the stdin
Definition: PLemAutoRun.h:279
bool fShowComments
flag indicating if comments shall be suppressed. Defined under /AutoRun/Shows Comments ...
Definition: PLemAutoRun.h:271
int fNoOfAutoRunCmds
number of autorun cmd&#39;s
Definition: PLemAutoRun.h:481
#define LS336_INPUT_HEATER_RANGE
ODB Offset for the heater range read back.
bool fLargeFlow
signaling extra large flow during cool down
Definition: PLemAutoRun.h:328
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:463
PAutoRunCmdVector * fAutoRunCmdVector
pointer to the autorun cmd list
Definition: PLemAutoRun.h:479
float fHVAccuracy
HV accuracy needed before going on (in (kV))
Definition: PLemAutoRun.h:301
void InitEnabled()
PLemAutoRun::InitEnabled.
QString fSpinRotMagInputPath
ODB path to the danfysik spin rotator magnet power supply input variables.
Definition: PLemAutoRun.h:425
QString fLemvacInputPath
ODB path to the lemvac input variables.
Definition: PLemAutoRun.h:442
#define LAR_TT_FINISHED
#define TEMP_DEMAND_TEMP
demand temperature parameter tag
PKey * fHVCurrentKey
pointer to the ODB key: FUG HV measured current values
Definition: PLemAutoRun.h:513
PLemAutoRun * fLar
pointer to the calling class
Definition: PLemAutoRun.h:138
QVector< int > * GetChNo()
Definition: PLemAutoRun.h:210
float fPrefNeedleValveCof_3_0
NV setting = _1_0 * _1_1 * T for 10<T<15.
Definition: PLemAutoRun.h:341
PKey * fWEWOutputKey
pointer to the ODB key: WEW output values
Definition: PLemAutoRun.h:521
PKey * fMagParamBparKey
pointer to the ODB key: Bpar magnet parameters (A -> G)
Definition: PLemAutoRun.h:540
PKey * fLemvacOutputKey
pointer to the ODB key: lemvac output values
Definition: PLemAutoRun.h:535
float fFieldAccuracy
field accuracy needed before going on (in (A))
Definition: PLemAutoRun.h:299
float fPrefNeedleValveCof_2_0
NV setting = _1_0 * _1_1 * T for 8<T<10.
Definition: PLemAutoRun.h:339
#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:307
void SetDump(AutoRunCmd *arc)
#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:426
PKey * fFOMInputKey
pointer to the ODB key: FOM input values
Definition: PLemAutoRun.h:536
void SetField(AutoRunCmd *arc)
QString fWEWFeName
name of the WEW scfe in the ODB
Definition: PLemAutoRun.h:461
QString fFrontendName
name of the frontend in the ODB
Definition: PLemAutoRun.h:457
#define SM_MODUS_NEEDLEVALVE
ODB offset for the modus value for the needlevalve.
bool isValid(QString &errMsg)
Definition: PLemAutoRun.h:208
PExperiment * fExp
pointer to the midas experiment
Definition: PLemAutoRun.h:494
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:282
float fLemVacValveInitialState[2]
states of BPVX, BPVY before set temperature
Definition: PLemAutoRun.h:303
void CheckTempStability()
bool fIgnoreAlarms
flag: if true checking for any alarms will not performed: only for testing!!
Definition: PLemAutoRun.h:281
#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:286
#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:486
#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:362
float fPrefNeedleValveCof_1_0
NV setting = _1_0 * _1_1 * T for T<8.
Definition: PLemAutoRun.h:337
float fHeaterMax
max. acceptable heater value
Definition: PLemAutoRun.h:316
PKey * fRunInfoKey
pointer to the ODB key: run info
Definition: PLemAutoRun.h:498
#define LAR_FORCED_RA_OFF
forced switch off of the RA HV&#39;s
Definition: lemAutoRun.h:86
void setAttribute(const QString key, const QXmlStreamAttributes &qAttr)
PLemAutoRunXMLParser::setAttribute.
#define BPV_STATE_OPEN
BPVX/Y open.
Definition: PLemAutoRun.cpp:67
QString fEnableOnOffModePath
ODB path to the enable On/Off mode, e.g. red/green, pulsing RA.
Definition: PLemAutoRun.h:405
#define LAR_STATE_RUNNING
auto run state running
Definition: lemAutoRun.h:40
#define LS336_OUTPUT_PID_D
ODB Offset for D output L1.
int fRunNoEventsNeeded
number of events needed to complete a run
Definition: PLemAutoRun.h:488
QString fSetupSampleEnabledPath
ODB path to the sample enabled flag.
Definition: PLemAutoRun.h:449
QString cmdString
untouched original lar-cmd string
Definition: lemAutoRun.h:221
QXmlStreamReader fXml
xml stream reader object
Definition: PLemAutoRun.h:182
void ExecAutoRun()
QString fSampleRawVoltagePath
ODB path to the LakeShore Raw Voltage.
Definition: PLemAutoRun.h:439
#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:64
QString fSampleCryoPath
ODB path to the sample cryo name used.
Definition: PLemAutoRun.h:417
#define OMEGA_OVEN_OUTPUT_SETPOINT
ODB Offset for the setpoint.
QString fRunCommentPath
ODB path to the run comment.
Definition: PLemAutoRun.h:408
void SetEnabled(const QString key, bool val)
PLemAutoRun::SetEnabled.
void DisconnectFromExp()
float fSampleTempAccuracy
temperature tolerance
Definition: PLemAutoRun.h:351
PKey * fSpinRotMagInputKey
pointer to the ODB key: danfysik spin rotator input variables
Definition: PLemAutoRun.h:516
PKey * fSampleCtrlChKey
pointer to the ODB key: sample cryo LakeShore control channel
Definition: PLemAutoRun.h:525
#define HTML_LOAD
html load tag