Low-Energy Muon (LEM) Experiment  0.5.1
hv_detectors_scfe.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: hv_detectors_scfe.c
4  Created by: Andreas Suter
5 
6  Contents: Midas frontend for the detector high voltage
7 
8 \********************************************************************/
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <math.h>
14 
15 #include "midas.h"
16 #include "class/hv.h"
17 #include "hv_nhr.h"
18 #include "hvr400.h"
19 #include "hv_scs2001_apd.h"
20 #include "hpx30_107.h"
21 #include "tcpip_rs232.h"
22 #include "bus/null.h"
23 
24 //-- Globals -------------------------------------------------------
25 
27 char *frontend_name = "HV Detectors";
29 char *frontend_file_name = __FILE__;
30 
32 BOOL frontend_call_loop = TRUE;
33 
35 INT display_period = 1000;
36 
38 INT max_event_size = 10000;
39 
41 INT max_event_size_frag = 5*1024*1024;
42 
44 INT event_buffer_size = 10*10000;
45 
46 // -- HV Monitoring Variables -----------------------------------------
47 
48 #define LEMVAC_GAS_INLET_ON 0x80
49 #define LEMVAC_MC_STATUS_WORD_2 15
50 #define LEMVAC_TC_STATUS_WORD_2 18
51 #define LEMVAC_SC_STATUS_WORD_2 21
52 #define TD_FIRST_CH 0
53 #define TD_LAST_CH 3
54 #define MCP1_CH 4
55 #define MCP2_FIRST_CH 6
56 #define MCP2_LAST_CH 7
57 #define POS_MCP1_I 12
58 #define POS_MCP1_O 13
59 
60 #define HV_TD_MAX_COUNT 30
61 
62 #define HV_DETECTOR_CHANNELS 94
63 
64 #define HV_DETECTOR_READ_TIME 10
65 
68 
74 
75 // Monitoring stuff
78 
79 // Gas inlet stuff
80 float lemvac_in[27];
81 
83 
84 //-- Equipment list ------------------------------------------------
85 
87 DEVICE_DRIVER hv_driver[] = {
88  { "TD", hv_nhr, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP | DF_REPORT_STATUS | DF_REPORT_TEMP },
89  { "MCP", hv_nhr, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP | DF_REPORT_STATUS | DF_REPORT_TEMP },
90  { "PHVR400_1", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
91  { "PHVR400_2", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
92  { "PHVR400_3", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
93  { "NHVR400_1", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
94  { "NHVR400_2", hvr400, 4, null, DF_PRIO_DEVICE | DF_HW_RAMP },
95  { "HPP30_107", hpx30_107, 1, tcpip_rs232, DF_PRIO_DEVICE },
96  { "HPN30_107", hpx30_107, 1, tcpip_rs232, DF_PRIO_DEVICE },
97  { "HV_APD", hv_scs2001_apd, 64, null, DF_PRIO_DEVICE | DF_HW_RAMP },
98  { "" }
99 };
100 
102 EQUIPMENT equipment[] = {
103 
104  { "HV Detectors", // equipment name
105  {73, 0, // event ID, trigger mask
106  "SYSTEM", // event buffer
107  EQ_SLOW, // equipment type
108  0, // event source
109  "FIXED", // format
110  TRUE, // enabled
111  RO_RUNNING |
112  RO_TRANSITIONS, // read when running and on transitions
113  30000, // read every 30 sec
114  0, // stop run after this event limit
115  0, // number of sub events
116  1, // log history every event
117  "", "", "",},
118  cd_hv_read, // readout routine
119  cd_hv, // class driver main routine
120  hv_driver, // device driver list
121  NULL, // init string
122  },
123 
124  { "" }
125 };
126 
127 
128 
129 //-- Dummy routines ------------------------------------------------
130 
131 INT poll_event(INT source[], INT count, BOOL test) {return 1;};
132 INT interrupt_configure(INT cmd, INT source[], PTYPE adr) {return 1;};
133 
134 // -- HV monitoring routines ---------------------------------------
151 void hv_detectors_scfe_gas_inlet(INT hDB, INT hKey, void *dummy)
152 {
153  char str[128];
154  int status, ival, i;
155  float value;
156  HNDLE hv_hKey;
157 
158  ival = (int)lemvac_in[LEMVAC_MC_STATUS_WORD_2];
159  if (ival & LEMVAC_GAS_INLET_ON) {
160  // get hv demand odb key
161  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
162  status = db_find_key(hDB, 0, str, &hv_hKey);
163  if (status != DB_SUCCESS) {
164  cm_msg(MERROR, "hv_detectors_scfe_gas_inlet", "hv_detectors_scfe_gas_inlet: Couldn't find %s", str);
165  return;
166  }
167 
168  // set all hv detector values of the moderator chamber to zero
169  value = 0.0;
170  // MCP1 HV
171  db_set_data_index(hDB, hv_hKey, &value, sizeof(value), MCP1_CH, TID_FLOAT);
172  }
173 
174  ival = (int)lemvac_in[LEMVAC_TC_STATUS_WORD_2];
175  if (ival & LEMVAC_GAS_INLET_ON) {
176  // get hv demand odb key
177  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
178  status = db_find_key(hDB, 0, str, &hv_hKey);
179  if (status != DB_SUCCESS) {
180  cm_msg(MERROR, "hv_detectors_scfe_gas_inlet", "hv_detectors_scfe_gas_inlet: Couldn't find %s", str);
181  return;
182  }
183 
184  // set all hv detector values of the trigger chamber to zero
185  value = 0.0;
186  // Trigger HV's
187  for (i=TD_FIRST_CH; i<=TD_LAST_CH; i++) {
188  db_set_data_index(hDB, hv_hKey, &value, sizeof(value), i, TID_FLOAT);
189  }
190  }
191 
192  ival = (int)lemvac_in[LEMVAC_SC_STATUS_WORD_2];
193  if (ival & LEMVAC_GAS_INLET_ON) {
194  // get hv demand odb key
195  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
196  status = db_find_key(hDB, 0, str, &hv_hKey);
197  if (status != DB_SUCCESS) {
198  cm_msg(MERROR, "hv_detectors_scfe_gas_inlet", "hv_detectors_scfe_gas_inlet: Couldn't find %s", str);
199  return;
200  }
201 
202  // set all hv detector values of the sample chamber to zero
203  value = 0.0;
204  // MCP2 HV's
205  for (i=MCP2_FIRST_CH; i<=MCP2_LAST_CH; i++) {
206  db_set_data_index(hDB, hv_hKey, &value, sizeof(value), i, TID_FLOAT);
207  }
208  }
209 }
210 
211 //------------------------------------------------------------------
217 void hv_detectors_scfe_td_check(INT hDB, INT hKey, void *dummy)
218 {
219  // check if the difference between the measured TD HV's are smaller 1.0kV
220  if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH])-fabs(hv_detectors_measured[TD_FIRST_CH+1]))>1.0)
222  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH])-fabs(hv_detectors_measured[TD_FIRST_CH+2]))>1.0)
224  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH])-fabs(hv_detectors_measured[TD_FIRST_CH+3]))>1.0)
226  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH+1])-fabs(hv_detectors_measured[TD_FIRST_CH+2]))>1.0)
228  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH+1])-fabs(hv_detectors_measured[TD_FIRST_CH+3]))>1.0)
230  else if (fabs(fabs(hv_detectors_measured[TD_FIRST_CH+2])-fabs(hv_detectors_measured[TD_FIRST_CH+3]))>1.0)
232  else // everything OK, reset counter
234 
235  if (hv_td_hv_check_counter > HV_TD_MAX_COUNT) { // at least one HV is hanging
236  al_trigger_alarm( "hv_detectors_scfe_td_check", "TD HV's need to be checked!!",
237  "Warning", "TD HV's need to be checked!!", AT_INTERNAL);
238  }
239 
240 }
241 
242 //-- Frontend Init -------------------------------------------------
251 {
252  HNDLE hDB, hKey;
253  int i, size;
254  INT status;
255  char str[128];
256 
257  // de-register run-transition notifications
258  cm_deregister_transition(TR_START);
259  cm_deregister_transition(TR_STOP);
260  cm_deregister_transition(TR_PAUSE);
261  cm_deregister_transition(TR_RESUME);
262 
263  // init global variables
264  hv_monitoring_enabled = FALSE;
265  hv_hvAlreadyOff = FALSE;
266 
267  // get ODB main handle
268  cm_get_experiment_database(&hDB, NULL);
269 
270  // keep main handle to ODB
272 
273  // hotlink lemvac input
274  strcpy(str, "/Equipment/LEMVAC/Variables/Input");
275  status = db_find_key(hDB, 0, str, &hKey);
276  if (status != DB_SUCCESS) {
277  cm_msg(MERROR, "frontend_init", "hv_detectors_scfe: Couldn't find %s", str);
278  return CM_SUCCESS;
279  }
280 
281  status = db_open_record(hDB, hKey, &lemvac_in, sizeof(lemvac_in), MODE_READ,
283 
284  // init drop counters
285  for (i=0; i<HV_DETECTOR_CHANNELS; i++) {
287  }
288 
289  // get HV Detector names
290  strcpy(str, "/Equipment/HV Detectors/Settings/Names");
291  status = db_find_key(hDB, 0, str, &hKey);
292  if (status != DB_SUCCESS) {
293  cm_msg(MERROR, "frontend_init", "hv_detectors_scfe: Couldn't find %s", str);
294  return CM_SUCCESS;
295  }
296 
297  size = sizeof(hv_detectors_names);
298  status = db_get_record(hDB, hKey, &hv_detectors_names, &size, 0);
299 
300  // hotlink demand detector HV's
301  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
302  status = db_find_key(hDB, 0, str, &hKey);
303  if (status != DB_SUCCESS) {
304  cm_msg(MERROR, "frontend_init", "hv_detectors_scfe: Couldn't find %s", str);
305  return CM_SUCCESS;
306  }
307 
308  status = db_open_record(hDB, hKey, &hv_detectors_demand, sizeof(hv_detectors_demand), MODE_READ,
309  NULL, NULL);
310 
311  // hotlink measured detector HV's
312  strcpy(str, "/Equipment/HV Detectors/Variables/Measured");
313  status = db_find_key(hDB, 0, str, &hKey);
314  if (status != DB_SUCCESS) {
315  cm_msg(MERROR, "frontend_init", "hv_detectors_scfe: Couldn't find %s", str);
316  return CM_SUCCESS;
317  }
318 
319  // keep measured key for cyclic reading in frontend loop
321 
323 
324  status = db_open_record(hDB, hKey, &hv_detectors_measured, sizeof(hv_detectors_measured), MODE_READ,
326 
327  // start cyclic timer for hv checks
328  hv_dectector_timestamp = ss_time();
329 
330  return CM_SUCCESS;
331 }
332 
333 //-- Frontend Exit -------------------------------------------------
339 {
340  char str[128];
341  int status;
342  HNDLE hDB, hKey;
343 
344  // get ODB main handle
345  cm_get_experiment_database(&hDB, NULL);
346 
347  // unlink lemvac input
348  strcpy(str, "/Equipment/LEMVAC/Variables/Input");
349  status = db_find_key(hDB, 0, str, &hKey);
350  if (status != DB_SUCCESS) {
351  cm_msg(MERROR, "frontend_exit", "hv_detectors_scfe: Couldn't find %s, status=%d", str, status);
352  return CM_SUCCESS;
353  }
354  db_close_record(hDB, hKey);
355 
356  // unlink demand HV's
357  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
358  status = db_find_key(hDB, 0, str, &hKey);
359  if (status != DB_SUCCESS) {
360  cm_msg(MERROR, "frontend_exit", "hv_detectors_scfe: Couldn't find %s, status=%d", str, status);
361  return CM_SUCCESS;
362  }
363  db_close_record(hDB, hKey);
364 
365  // unlink measured HV's
366  strcpy(str, "/Equipment/HV Detectors/Variables/Measured");
367  status = db_find_key(hDB, 0, str, &hKey);
368  if (status != DB_SUCCESS) {
369  cm_msg(MERROR, "frontend_exit", "hv_detectors_scfe: Couldn't find %s, status=%d", str, status);
370  return CM_SUCCESS;
371  }
372  db_close_record(hDB, hKey);
373 
374  return CM_SUCCESS;
375 }
376 
377 //-- Frontend Loop -------------------------------------------------
385 {
386  HNDLE hKey;
387  DWORD now;
388  int size, i, status;
389  float measured[HV_DETECTOR_CHANNELS], fval;
390  static int offset;
391  char name[NAME_LENGTH];
392  char str[512];
393 
394  offset = -1;
395 
396  // time to read hv measured?
397  now = ss_time();
399  // reset timer
401  // read hv measured values from ODB
402  size = sizeof(measured);
403  db_get_record(hv_detectors_hDB, hv_detectors_measured_hKey, &measured[0], &size, 0);
404  // check if measured one is deviating too strongly from the demand
405  for (i=0; i<HV_DETECTOR_CHANNELS; i++) {
406  if ((hv_detectors_demand[i] != 0.0) && (fabs(fabs(hv_detectors_demand[i])-fabs(measured[i]))>0.2)) {
408  // check of limit is reached
409  if (hv_detectors_drop_counter[i]>18) { // 3 mins HV demand != measured
410  strncpy(name, &hv_detectors_names[i*NAME_LENGTH], NAME_LENGTH*sizeof(char));
411  sprintf(str, "HV Detector %s: measured = %f, demand = %f, check!!",
413  al_trigger_alarm( "hv_detectors_scfe", str, "Warning", str, AT_INTERNAL);
414  }
415  if ((i == POS_MCP1_I) || (i == POS_MCP1_O)) {
416  // toggle offset between -1 and 1
417  if (offset == 1)
418  offset = -1;
419  else if (offset == -1)
420  offset = 1;
421 
422  strcpy(str, "/Equipment/HV Detectors/Variables/Demand");
423  status = db_find_key(hv_detectors_hDB, 0, str, &hKey);
424  if (status != DB_SUCCESS) {
425  cm_msg(MERROR, "frontend_loop", "hv_detectors_scfe: Couldn't find %s, status=%d", str, status);
426  return CM_SUCCESS;
427  }
428 
429  fval = hv_detectors_demand[i] + offset*0.001;
430  if (i == POS_MCP1_I) {
431  status = db_set_data_index(hv_detectors_hDB, hKey, &fval, sizeof(fval), POS_MCP1_I, TID_FLOAT);
432  cm_msg(MINFO, "hv_detectors_scfe", "hv_detectors_scfe: try to self-reset POS_MCP1_I HV");
433  } else {
434  status = db_set_data_index(hv_detectors_hDB, hKey, &fval, sizeof(fval), POS_MCP1_O, TID_FLOAT);
435  cm_msg(MINFO, "hv_detectors_scfe", "hv_detectors_scfe: try to self-reset POS_MCP1_O HV");
436  }
437  }
438  } else { // reset drop counter since readback is OK
440  }
441  }
442  }
443 
444  return CM_SUCCESS;
445 }
446 
447 //-- Begin of Run --------------------------------------------------
452 INT begin_of_run(INT run_number, char *error)
453 {
454  return CM_SUCCESS;
455 }
456 
457 //-- End of Run ----------------------------------------------------
462 INT end_of_run(INT run_number, char *error)
463 {
464  return CM_SUCCESS;
465 }
466 
467 //-- Pause Run -----------------------------------------------------
472 INT pause_run(INT run_number, char *error)
473 {
474  return CM_SUCCESS;
475 }
476 
477 //-- Resume Run ----------------------------------------------------
482 INT resume_run(INT run_number, char *error)
483 {
484  return CM_SUCCESS;
485 }
486 
487 //------------------------------------------------------------------
#define HV_TD_MAX_COUNT
void hv_detectors_scfe_gas_inlet(INT hDB, INT hKey, void *dummy)
INT interrupt_configure(INT cmd, INT source, PTYPE adr)
Definition: vme_fe.c:2119
#define LEMVAC_GAS_INLET_ON
int hv_detectors_drop_counter[HV_DETECTOR_CHANNELS]
#define MCP2_FIRST_CH
char * frontend_name
experiment specific ODB structures
Definition: vme_fe.c:159
EQUIPMENT equipment[]
Definition: vme_fe.c:326
INT max_event_size_frag
maximum event size for fragmented events (EQ_FRAGMENTED)
Definition: vme_fe.c:174
#define MCP1_CH
INT hv_monitoring_enabled
Monitoring enabled (hotlinked)
DEVICE_DRIVER hv_driver[]
device driver list
Definition: hv_fug_scfe.c:107
void hv_detectors_scfe_td_check(INT hDB, INT hKey, void *dummy)
INT end_of_run(INT run_number, char *error)
Definition: vme_fe.c:858
int hv_td_hv_check_counter
counter needed in the TD HV check
INT frontend_init()
Definition: vme_fe.c:416
HNDLE hKey
Definition: write_summary.c:97
char hv_detectors_names[HV_DETECTOR_CHANNELS *NAME_LENGTH]
INT frontend_loop()
Definition: vme_fe.c:949
#define LEMVAC_SC_STATUS_WORD_2
BOOL frontend_call_loop
frontend_loop is called periodically if this variable is TRUE
Definition: vme_fe.c:165
HNDLE hDB
Definition: write_summary.c:97
#define LEMVAC_TC_STATUS_WORD_2
#define POS_MCP1_O
INT max_event_size
maximum event size produced by this frontend
Definition: vme_fe.c:171
INT pause_run(INT run_number, char *error)
Definition: vme_fe.c:886
INT hv_hvAlreadyOff
HV already switched off.
INT frontend_exit()
Definition: vme_fe.c:557
#define TD_FIRST_CH
#define HV_DETECTOR_CHANNELS
float * hv_detectors_measured
hotlink variable holding the measured TD HV&#39;s
Definition: hv_fug_scfe.c:66
INT event_buffer_size
buffer size to hold events
Definition: vme_fe.c:177
char * frontend_file_name
The frontend file name, don&#39;t change it.
Definition: vme_fe.c:162
INT poll_event(INT source, INT count, BOOL test)
Definition: vme_fe.c:2102
float lemvac_in[27]
holds the lemvac input variables
Definition: hv_fug_scfe.c:94
float hv_detectors_demand[HV_DETECTOR_CHANNELS]
static INT offset
Definition: sc_ana_module.c:89
#define TD_LAST_CH
HNDLE hv_detectors_measured_hKey
HNDLE hv_detectors_hDB
#define POS_MCP1_I
#define MCP2_LAST_CH
INT begin_of_run(INT run_number, char *error)
Definition: vme_fe.c:589
INT hvr400(INT cmd,...)
Definition: hvr400.c:670
#define LEMVAC_MC_STATUS_WORD_2
DWORD hv_dectector_timestamp
cyclic timer to check hv&#39;s
INT display_period
a frontend status page is displayed with this frequency in ms
Definition: vme_fe.c:168
INT resume_run(INT run_number, char *error)
Definition: vme_fe.c:893
#define HV_DETECTOR_READ_TIME