Low-Energy Muon (LEM) Experiment  0.5.2
hv_detectors_scfe.cxx
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: hv_detectors_scfe.cxx
4  Created by: Andreas Suter
5 
6  Contents: Midas frontend for the detector high voltage
7 
8 \********************************************************************/
9 
10 #include <cstdio>
11 #include <cstdlib>
12 #include <cstring>
13 #include <cmath>
14 
15 #include "midas.h"
16 #include "mfe.h"
17 
18 #include "class/hv.h"
19 #include "hv_nhr.h"
20 #include "hvr400.h"
21 #include "hv_scs2001_apd.h"
22 #include "hpx30_107.h"
23 #include "tcpip_rs232.h"
24 #include "bus/null.h"
25 
26 //-- Globals -------------------------------------------------------
27 
29 const char *frontend_name = "HV Detectors";
31 const char *frontend_file_name = __FILE__;
32 
34 BOOL frontend_call_loop = TRUE;
35 
37 INT display_period = 1000;
38 
40 INT max_event_size = 10000;
41 
43 INT max_event_size_frag = 5*1024*1024;
44 
46 INT event_buffer_size = 10*10000;
47 
48 // -- HV Monitoring Variables -----------------------------------------
49 
50 #define LEMVAC_GAS_INLET_ON 0x80
51 #define LEMVAC_MC_STATUS_WORD_2 15
52 #define LEMVAC_TC_STATUS_WORD_2 18
53 #define LEMVAC_SC_STATUS_WORD_2 21
54 #define TD_FIRST_CH 0
55 #define TD_LAST_CH 3
56 #define MCP1_CH 4
57 #define MCP2_FIRST_CH 6
58 #define MCP2_LAST_CH 7
59 #define POS_MCP1_I 12
60 #define POS_MCP1_O 13
61 
62 #define HV_TD_MAX_COUNT 30
63 
64 #define HV_DETECTOR_CHANNELS 94
65 
66 #define HV_DETECTOR_READ_TIME 10
67 
70 
76 
77 // Monitoring stuff
80 
81 // Gas inlet stuff
82 float lemvac_in[27];
83 
85 
86 //-- Equipment list ------------------------------------------------
87 
89 DEVICE_DRIVER hv_driver[] = {
90  { "TD", hv_nhr, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP | DF_REPORT_STATUS | DF_REPORT_TEMP },
91  { "MCP", hv_nhr, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP | DF_REPORT_STATUS | DF_REPORT_TEMP },
92  { "PHVR400_1", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
93  { "PHVR400_2", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
94  { "PHVR400_3", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
95  { "NHVR400_1", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
96  { "NHVR400_2", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
97  { "HPP30_107", hpx30_107, 1, tcpip_rs232, DF_PRIO_DEVICE | DF_REPORT_STATUS | DF_REPORT_TEMP },
98  { "HPN30_107", hpx30_107, 1, tcpip_rs232, DF_PRIO_DEVICE | DF_REPORT_STATUS | DF_REPORT_TEMP },
99  { "HV_APD", hv_scs2001_apd, 64, null, DF_PRIO_DEVICE | DF_HW_RAMP },
100  { "" }
101 };
102 
112 
114 EQUIPMENT equipment[] = {
115 
116  { "HV Detectors", // equipment name
117  {73, 0, // event ID, trigger mask
118  "SYSTEM", // event buffer
119  EQ_SLOW, // equipment type
120  0, // event source
121  "FIXED", // format
122  TRUE, // enabled
123  RO_RUNNING |
124  RO_TRANSITIONS, // read when running and on transitions
125  30000, // read every 30 sec
126  0, // stop run after this event limit
127  0, // number of sub events
128  1, // log history every event
129  "", "", "",},
130  cd_hv_read, // readout routine
131  cd_hv, // class driver main routine
132  hv_driver, // device driver list
133  NULL, // init string
134  },
135 
136  { "" }
137 };
138 
139 
140 
141 //-- Dummy routines ------------------------------------------------
142 
143 INT poll_event(INT source, INT count, BOOL test) {return 1;};
144 INT interrupt_configure(INT cmd, INT source, POINTER_T adr) {return 1;};
145 
146 // -- HV monitoring routines ---------------------------------------
163 void hv_detectors_scfe_gas_inlet(INT hDB, INT hKey, void *dummy)
164 {
165  char str[128];
166  int status, ival, i;
167  float value;
168  HNDLE hv_hKey;
169 
170  ival = (int)lemvac_in[LEMVAC_MC_STATUS_WORD_2];
171  if (ival & LEMVAC_GAS_INLET_ON) {
172  // get hv demand odb key
173  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
174  status = db_find_key(hDB, 0, str, &hv_hKey);
175  if (status != DB_SUCCESS) {
176  cm_msg(MERROR, "hv_detectors_scfe_gas_inlet", "hv_detectors_scfe_gas_inlet: Couldn't find %s", str);
177  return;
178  }
179 
180  // set all hv detector values of the moderator chamber to zero
181  value = 0.0;
182  // MCP1 HV
183  db_set_data_index(hDB, hv_hKey, &value, sizeof(value), MCP1_CH, TID_FLOAT);
184  }
185 
186  ival = (int)lemvac_in[LEMVAC_TC_STATUS_WORD_2];
187  if (ival & LEMVAC_GAS_INLET_ON) {
188  // get hv demand odb key
189  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
190  status = db_find_key(hDB, 0, str, &hv_hKey);
191  if (status != DB_SUCCESS) {
192  cm_msg(MERROR, "hv_detectors_scfe_gas_inlet", "hv_detectors_scfe_gas_inlet: Couldn't find %s", str);
193  return;
194  }
195 
196  // set all hv detector values of the trigger chamber to zero
197  value = 0.0;
198  // Trigger HV's
199  for (i=TD_FIRST_CH; i<=TD_LAST_CH; i++) {
200  db_set_data_index(hDB, hv_hKey, &value, sizeof(value), i, TID_FLOAT);
201  }
202  }
203 
204  ival = (int)lemvac_in[LEMVAC_SC_STATUS_WORD_2];
205  if (ival & LEMVAC_GAS_INLET_ON) {
206  // get hv demand odb key
207  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
208  status = db_find_key(hDB, 0, str, &hv_hKey);
209  if (status != DB_SUCCESS) {
210  cm_msg(MERROR, "hv_detectors_scfe_gas_inlet", "hv_detectors_scfe_gas_inlet: Couldn't find %s", str);
211  return;
212  }
213 
214  // set all hv detector values of the sample chamber to zero
215  value = 0.0;
216  // MCP2 HV's
217  for (i=MCP2_FIRST_CH; i<=MCP2_LAST_CH; i++) {
218  db_set_data_index(hDB, hv_hKey, &value, sizeof(value), i, TID_FLOAT);
219  }
220  }
221 }
222 
223 //------------------------------------------------------------------
229 void hv_detectors_scfe_td_check(INT hDB, INT hKey, void *dummy)
230 {
231  // check if the difference between the measured TD HV's are smaller 1.0kV
232  if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH])-fabs(hv_detectors_measured[TD_FIRST_CH+1]))>1.0)
234  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH])-fabs(hv_detectors_measured[TD_FIRST_CH+2]))>1.0)
236  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH])-fabs(hv_detectors_measured[TD_FIRST_CH+3]))>1.0)
238  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH+1])-fabs(hv_detectors_measured[TD_FIRST_CH+2]))>1.0)
240  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH+1])-fabs(hv_detectors_measured[TD_FIRST_CH+3]))>1.0)
242  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH+2])-fabs(hv_detectors_measured[TD_FIRST_CH+3]))>1.0)
244  else // everything OK, reset counter
246 
247  if (hv_td_hv_check_counter > HV_TD_MAX_COUNT) { // at least one HV is hanging
248  al_trigger_alarm( "hv_detectors_scfe_td_check", "TD HV's need to be checked!!",
249  "Warning", "TD HV's need to be checked!!", AT_INTERNAL);
250  }
251 
252 }
253 
254 //-- Frontend Init -------------------------------------------------
263 {
264  HNDLE hDB, hKey;
265  int i, size;
266  INT status;
267  char str[128];
268 
269  // de-register run-transition notifications
270  cm_deregister_transition(TR_START);
271  cm_deregister_transition(TR_STOP);
272  cm_deregister_transition(TR_PAUSE);
273  cm_deregister_transition(TR_RESUME);
274 
275  // init global variables
276  hv_monitoring_enabled = FALSE;
277  hv_hvAlreadyOff = FALSE;
278 
279  // get ODB main handle
280  cm_get_experiment_database(&hDB, NULL);
281 
282  // keep main handle to ODB
284 
285  // hotlink lemvac input
286  strcpy(str, "/Equipment/LEMVAC/Variables/Input");
287  status = db_find_key(hDB, 0, str, &hKey);
288  if (status != DB_SUCCESS) {
289  cm_msg(MERROR, "frontend_init", "hv_detectors_scfe: Couldn't find %s", str);
290  return CM_SUCCESS;
291  }
292 
293  status = db_open_record(hDB, hKey, &lemvac_in, sizeof(lemvac_in), MODE_READ,
295 
296  // init drop counters
297  for (i=0; i<HV_DETECTOR_CHANNELS; i++) {
299  }
300 
301  // get HV Detector names
302  strcpy(str, "/Equipment/HV Detectors/Settings/Names");
303  status = db_find_key(hDB, 0, str, &hKey);
304  if (status != DB_SUCCESS) {
305  cm_msg(MERROR, "frontend_init", "hv_detectors_scfe: Couldn't find %s", str);
306  return CM_SUCCESS;
307  }
308 
309  size = sizeof(hv_detectors_names);
310  status = db_get_record(hDB, hKey, &hv_detectors_names, &size, 0);
311 
312  // hotlink demand detector HV's
313  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
314  status = db_find_key(hDB, 0, str, &hKey);
315  if (status != DB_SUCCESS) {
316  cm_msg(MERROR, "frontend_init", "hv_detectors_scfe: Couldn't find %s", str);
317  return CM_SUCCESS;
318  }
319 
320  status = db_open_record(hDB, hKey, &hv_detectors_demand, sizeof(hv_detectors_demand), MODE_READ,
321  NULL, NULL);
322 
323  // hotlink measured detector HV's
324  strcpy(str, "/Equipment/HV Detectors/Variables/Measured");
325  status = db_find_key(hDB, 0, str, &hKey);
326  if (status != DB_SUCCESS) {
327  cm_msg(MERROR, "frontend_init", "hv_detectors_scfe: Couldn't find %s", str);
328  return CM_SUCCESS;
329  }
330 
331  // keep measured key for cyclic reading in frontend loop
333 
335 
336  status = db_open_record(hDB, hKey, &hv_detectors_measured, sizeof(hv_detectors_measured), MODE_READ,
338 
339  // start cyclic timer for hv checks
340  hv_dectector_timestamp = ss_time();
341 
342  return CM_SUCCESS;
343 }
344 
345 //-- Frontend Exit -------------------------------------------------
351 {
352  char str[128];
353  int status;
354  HNDLE hDB, hKey;
355 
356  // get ODB main handle
357  cm_get_experiment_database(&hDB, NULL);
358 
359  // unlink lemvac input
360  strcpy(str, "/Equipment/LEMVAC/Variables/Input");
361  status = db_find_key(hDB, 0, str, &hKey);
362  if (status != DB_SUCCESS) {
363  cm_msg(MERROR, "frontend_exit", "hv_detectors_scfe: Couldn't find %s, status=%d", str, status);
364  return CM_SUCCESS;
365  }
366  db_close_record(hDB, hKey);
367 
368  // unlink demand HV's
369  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
370  status = db_find_key(hDB, 0, str, &hKey);
371  if (status != DB_SUCCESS) {
372  cm_msg(MERROR, "frontend_exit", "hv_detectors_scfe: Couldn't find %s, status=%d", str, status);
373  return CM_SUCCESS;
374  }
375  db_close_record(hDB, hKey);
376 
377  // unlink measured HV's
378  strcpy(str, "/Equipment/HV Detectors/Variables/Measured");
379  status = db_find_key(hDB, 0, str, &hKey);
380  if (status != DB_SUCCESS) {
381  cm_msg(MERROR, "frontend_exit", "hv_detectors_scfe: Couldn't find %s, status=%d", str, status);
382  return CM_SUCCESS;
383  }
384  db_close_record(hDB, hKey);
385 
386  return CM_SUCCESS;
387 }
388 
389 //-- Frontend Loop -------------------------------------------------
397 {
398  HNDLE hKey;
399  DWORD now;
400  int size, i, status;
401  float measured[HV_DETECTOR_CHANNELS], fval;
402  static int offset;
403  char name[NAME_LENGTH];
404  char str[512];
405 
406  offset = -1;
407 
408  // time to read hv measured?
409  now = ss_time();
411  // reset timer
413  // read hv measured values from ODB
414  size = sizeof(measured);
415  db_get_record(hv_detectors_hDB, hv_detectors_measured_hKey, &measured[0], &size, 0);
416  // check if measured one is deviating too strongly from the demand
417  for (i=0; i<HV_DETECTOR_CHANNELS; i++) {
418  if ((hv_detectors_demand[i] != 0.0) && (fabs(fabs(hv_detectors_demand[i])-fabs(measured[i]))>0.2)) {
420  // check of limit is reached
421  if (hv_detectors_drop_counter[i]>18) { // 3 mins HV demand != measured
422  strncpy(name, &hv_detectors_names[i*NAME_LENGTH], NAME_LENGTH*sizeof(char));
423  sprintf(str, "HV Detector %s: measured = %f, demand = %f, check!!",
425  al_trigger_alarm( "hv_detectors_scfe", str, "Warning", str, AT_INTERNAL);
426  }
427  if ((i == POS_MCP1_I) || (i == POS_MCP1_O)) {
428  // toggle offset between -1 and 1
429  if (offset == 1)
430  offset = -1;
431  else if (offset == -1)
432  offset = 1;
433 
434  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
435  status = db_find_key(hv_detectors_hDB, 0, str, &hKey);
436  if (status != DB_SUCCESS) {
437  cm_msg(MERROR, "frontend_loop", "hv_detectors_scfe: Couldn't find %s, status=%d", str, status);
438  return CM_SUCCESS;
439  }
440 
441  fval = hv_detectors_demand[i] + offset*0.001;
442  if (i == POS_MCP1_I) {
443  status = db_set_data_index(hv_detectors_hDB, hKey, &fval, sizeof(fval), POS_MCP1_I, TID_FLOAT);
444  cm_msg(MINFO, "hv_detectors_scfe", "hv_detectors_scfe: try to self-reset POS_MCP1_I HV");
445  } else {
446  status = db_set_data_index(hv_detectors_hDB, hKey, &fval, sizeof(fval), POS_MCP1_O, TID_FLOAT);
447  cm_msg(MINFO, "hv_detectors_scfe", "hv_detectors_scfe: try to self-reset POS_MCP1_O HV");
448  }
449  }
450  } else { // reset drop counter since readback is OK
452  }
453  }
454  }
455 
456  return CM_SUCCESS;
457 }
458 
459 //-- Begin of Run --------------------------------------------------
464 INT begin_of_run(INT run_number, char *error)
465 {
466  return CM_SUCCESS;
467 }
468 
469 //-- End of Run ----------------------------------------------------
474 INT end_of_run(INT run_number, char *error)
475 {
476  return CM_SUCCESS;
477 }
478 
479 //-- Pause Run -----------------------------------------------------
484 INT pause_run(INT run_number, char *error)
485 {
486  return CM_SUCCESS;
487 }
488 
489 //-- Resume Run ----------------------------------------------------
494 INT resume_run(INT run_number, char *error)
495 {
496  return CM_SUCCESS;
497 }
498 
499 //------------------------------------------------------------------
const char * frontend_name
&lt; created by ODBedit, command &quot;make&quot;
Definition: vme_fe.cxx:167
float hv_detectors_measured[HV_DETECTOR_CHANNELS]
INT max_event_size
maximum event size produced by this frontend
Definition: vme_fe.cxx:179
BOOL frontend_call_loop
frontend_loop is called periodically if this variable is TRUE
Definition: vme_fe.cxx:173
INT display_period
a frontend status page is displayed with this frequency in ms
Definition: vme_fe.cxx:176
#define MCP2_LAST_CH
void hv_detectors_scfe_td_check(INT hDB, INT hKey, void *dummy)
INT event_buffer_size
buffer size to hold events
Definition: vme_fe.cxx:185
DWORD hv_dectector_timestamp
cyclic timer to check hv&#39;s
HNDLE hv_detectors_measured_hKey
#define TD_LAST_CH
static INT offset
INT hv_hvAlreadyOff
HV already switched off.
HNDLE hv_detectors_hDB
#define POS_MCP1_O
INT frontend_exit()
Definition: vme_fe.cxx:565
EQUIPMENT equipment[]
Definition: vme_fe.cxx:343
INT begin_of_run(INT run_number, char *error)
Definition: vme_fe.cxx:597
DEVICE_DRIVER hv_driver[]
device driver list
INT interrupt_configure(INT cmd, INT source, PTYPE adr)
Definition: vme_fe.cxx:2105
#define TD_FIRST_CH
INT frontend_loop()
Definition: vme_fe.cxx:957
INT resume_run(INT run_number, char *error)
Definition: vme_fe.cxx:900
int hv_detectors_drop_counter[HV_DETECTOR_CHANNELS]
INT max_event_size_frag
maximum event size for fragmented events (EQ_FRAGMENTED)
Definition: vme_fe.cxx:182
#define HV_DETECTOR_READ_TIME
float hv_detectors_demand[HV_DETECTOR_CHANNELS]
INT hv_monitoring_enabled
Monitoring enabled (hotlinked)
float lemvac_in[27]
holds the status info of lemvac input variables
INT frontend_init()
Definition: vme_fe.cxx:429
char hv_detectors_names[HV_DETECTOR_CHANNELS *NAME_LENGTH]
HNDLE hKey
BOOL equipment_common_overwrite
Definition: vme_fe.cxx:341
INT end_of_run(INT run_number, char *error)
Definition: vme_fe.cxx:865
INT poll_event(INT source, INT count, BOOL test)
Definition: vme_fe.cxx:2088
#define POS_MCP1_I
#define LEMVAC_TC_STATUS_WORD_2
int hv_td_hv_check_counter
counter needed in the TD HV check
#define LEMVAC_GAS_INLET_ON
#define LEMVAC_SC_STATUS_WORD_2
HNDLE hDB
#define HV_DETECTOR_CHANNELS
#define HV_TD_MAX_COUNT
void hv_detectors_scfe_gas_inlet(INT hDB, INT hKey, void *dummy)
#define MCP1_CH
INT pause_run(INT run_number, char *error)
Definition: vme_fe.cxx:893
#define LEMVAC_MC_STATUS_WORD_2
INT hvr400(INT cmd,...)
#define MCP2_FIRST_CH
const char * frontend_file_name
The frontend file name, don&#39;t change it.
Definition: vme_fe.cxx:170