Low-Energy Muon (LEM) Experiment  0.5.1
hv_fug_scfe.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: hv_fug_scfe.c
4  Created by: Andreas Suter
5 
6  Contents: Midas frontend for the high voltage FUG devices
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 "msystem.h"
17 #include "class/hv.h"
18 #include "hv_scs3000.h"
19 #include "bus/null.h"
20 
21 // -- Globals -------------------------------------------------------
22 
24 char *frontend_name = "FUG";
26 char *frontend_file_name = __FILE__;
27 
29 BOOL frontend_call_loop = TRUE;
30 
32 INT display_period = 1000;
33 
35 INT max_event_size = 10000;
36 
38 INT max_event_size_frag = 5*1024*1024;
39 
41 INT event_buffer_size = 10*10000;
42 
43 // -- HV Monitoring Variables -----------------------------------------
44 
45 #define LEMVAC_GAS_INLET_ON 0x80
46 #define LEMVAC_MC_STATUS_WORD_2 15
47 #define LEMVAC_TC_STATUS_WORD_2 18
48 #define LEMVAC_SC_STATUS_WORD_2 21
49 
50 #define FUG_CHS 16
51 #define FUG_READ_TIME 10
52 #define FUG_DEMAND_CHANGED_TIMEOUT 300
53 #define FUG_MC 0
54 #define FUG_TC 1
55 #define FUG_SC 2
56 
57 #define TD_FIRST_CH 0
58 #define TD_LAST_CH 3
59 #define FUG_BEAMLINE_KV61_CH 28
60 #define FUG_BEAMLINE_KV62_CH 29
61 
62 // detector rate
64 
65 // Detector HV's
67 
68 // keep handle to ODB
69 HNDLE hv_fug_hDB;
71 
72 // fug demand HV's
74 // flag array telling which channel is belonging to which chamber
76 // fug demand HV's changed timer
78 // fug demand <-> measured check timestamp
80 // fug demand HV drop counter
82 
83 // debug flag, when enabled sending additional messages to the message system
84 int hv_fug_debug = 0;
85 
86 // Monitoring stuff
88 char hv_fug_trip_rate_source[NAME_LENGTH];
92 
93 // Gas inlet stuff
94 float lemvac_in[27];
95 
96 // FUG Monitoring default. Is used in case FUG Monitoring ODB structure is not in place yet.
97 const char *hv_fug_monitoring_str =
98 "FUG Monitoring = INT : 0\n\
99 Trip Rate Source = STRING : [32] TD\n\
100 Trip Enabled = INT : 1\n\
101 Trip Level = INT : 1500000\n\
102 ";
103 
104 //-- Equipment list ------------------------------------------------
105 
107 DEVICE_DRIVER hv_driver[] = {
108  { "hv_spin_rot", hv_scs3000, 4, null, DF_PRIO_DEVICE },
109  { "hv_mc_tc", hv_scs3000, 7, null, DF_PRIO_DEVICE },
110  { "hv_sc", hv_scs3000, 5, null, DF_PRIO_DEVICE }
111 };
112 
114 EQUIPMENT equipment[] = {
115 
116  { "HV", // equipment name
117  {72, 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[], PTYPE adr) {return 1;};
145 
146 //-- prototype declaration -----------------------------------------
147 
148 void hv_fug_check_trip_level(INT, INT, void *);
149 
150 // -- HV monitoring routines ---------------------------------------
159 void hv_fug_trip_rate_source_changed(INT hDB, INT hKey, void *dummy)
160 {
161  INT status;
162  char str[128];
163  char svalue[NAME_LENGTH];
164 
165  if (strstr(hv_fug_trip_rate_source, "TD")) { // rate switched to TD
166 
167  // close MCP1 rate hotlink
168  strcpy(str, "/Equipment/Scaler/Variables/RATE/MCP1");
169  status = db_find_key(hDB, 0, str, &hKey);
170  if (status != DB_SUCCESS) {
171  cm_msg(MERROR, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Couldn't find %s", str);
172  return;
173  }
174  db_close_record(hDB, hKey);
175 
176  // establish TD rate hotlink
177  strcpy(str, "/Equipment/Scaler/Variables/RATE/TD");
178  status = db_find_key(hDB, 0, str, &hKey);
179  if (status != DB_SUCCESS) {
180  cm_msg(MERROR, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Couldn't find %s", str);
181  return;
182  }
183  status = db_open_record(hDB, hKey, &hv_fug_detector_rate, sizeof(hv_fug_detector_rate),
184  MODE_READ, &hv_fug_check_trip_level, NULL);
185  if (status != DB_SUCCESS) {
186  cm_msg(MERROR, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Couldn't establish hotlink to %s", str);
187  return;
188  }
189 
190  // message that the rates where switched to TD
191  cm_msg(MINFO, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Switched to the TD rate for the HV trip monitoring");
192 
193  } else if (strstr(hv_fug_trip_rate_source, "MCP1")) { // rate switched to MCP1
194 
195  // close TD rate hotlink
196  strcpy(str, "/Equipment/Scaler/Variables/RATE/TD");
197  status = db_find_key(hDB, 0, str, &hKey);
198  if (status != DB_SUCCESS) {
199  cm_msg(MERROR, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Couldn't find %s", str);
200  return;
201  }
202  db_close_record(hDB, hKey);
203 
204  // establish MCP1 rate hotlink
205  strcpy(str, "/Equipment/Scaler/Variables/RATE/MCP1");
206  status = db_find_key(hDB, 0, str, &hKey);
207  if (status != DB_SUCCESS) {
208  cm_msg(MERROR, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Couldn't find %s", str);
209  return;
210  }
211  status = db_open_record(hDB, hKey, &hv_fug_detector_rate, sizeof(hv_fug_detector_rate),
212  MODE_READ, &hv_fug_check_trip_level, NULL);
213  if (status != DB_SUCCESS) {
214  cm_msg(MERROR, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Couldn't establish hotlink to %s", str);
215  return;
216  }
217 
218  // message that the rates where switched to MCP1
219  cm_msg(MINFO, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Switched to the MCP1 rate for the HV trip monitoring");
220 
221  } else { // garbage hence will set hv_fug_trip_rate_source to TD
222  cm_msg(MERROR, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: %s not allowed, will switch to TD", hv_fug_trip_rate_source);
223  strcpy(str, "/Equipment/HV/Monitoring/Trip Rate Source");
224  status = db_find_key(hDB, 0, str, &hKey);
225  if (status != DB_SUCCESS) {
226  cm_msg(MERROR, "hv_fug_trip_rate_source_changed", "hv_fug_scfe: Couldn't find %s", str);
227  return;
228  }
229  strcpy(svalue, "TD");
230  db_set_data(hDB, hKey, svalue, sizeof(svalue), 1, TID_STRING);
231  }
232 }
233 
234 //------------------------------------------------------------------
245 void hv_fug_check_trip_level(INT hDB, INT hKey, void *hv)
246 {
247  char str[128];
248  INT status, size, i, run_state;
249  float value;
250  float hv_demand_value[FUG_CHS];
251  HNDLE demandKey, runStateKey;
252  KEY key;
253 
254  if (!hv_fug_tripEnabled) // trip monitoring not enabled, hence do nothing
255  return;
256 
257  if (hv_fug_detector_rate > hv_fug_tripRate) { // measured TD/MCP1 rate larger than the trip level
258  strcpy(str, "/Equipment/HV/Variables/Demand");
259  status = db_find_key(hDB, 0, str, &demandKey);
260  if (status != DB_SUCCESS) {
261  cm_msg(MERROR, "hv_fug_check_trip_level", "Couldn't find %s", str);
262  return;
263  }
264  status = db_get_key(hDB, demandKey, &key);
265  if (status != DB_SUCCESS) {
266  cm_msg(MERROR, "hv_fug_check_trip_level", "Couldn't get key info of %s", str);
267  return;
268  }
269  // check if already tripped
270  size = sizeof(hv_demand_value);
271  db_get_data(hDB, demandKey, &hv_demand_value, &size, TID_FLOAT);
272  for (i=0; i < key.num_values; i++) {
273  if (hv_demand_value[i] != 0)
274  break;
275  }
276 
277  if (i<key.num_values) { // at least one demand value != 0
278  // set all demand values to zero
279  value = 0.f;
280  for (i=0; i < key.num_values; i++)
281  db_set_data_index(hDB, demandKey, &value, sizeof(value), i, TID_FLOAT);
282 
283  if (strstr(hv_fug_trip_rate_source, "TD")) // TD
284  sprintf(str, "HV tripped due to too high rate (TD=%d/trip level=%d)",
286  else // MCP1
287  sprintf(str, "HV tripped due to too high rate (MCP1=%d/trip level=%d)",
289 
290  cm_msg(MERROR, "hv_fug_check_trip_level", str);
291 
292  al_trigger_alarm( "hv_fug_check_trip_level", str, "Warning", "High Voltage tripped. Will also close KV61, KV62!", AT_INTERNAL);
293 
294  // check if a run is active, and if yes pause it ----------------------------
295 
296  // get the run state and check if a run is active
297  strcpy(str, "/Runinfo/State");
298  status = db_find_key(hDB, 0, str, &runStateKey);
299  if (status != DB_SUCCESS) {
300  cm_msg(MERROR, "hv_fug_check_trip_level", "Couldn't find %s", str);
301  return;
302  }
303  size = sizeof(run_state);
304  db_get_data(hDB, runStateKey, &run_state, &size, TID_INT);
305  if (run_state == STATE_RUNNING) {
306  // pause the run
307  status = cm_transition(TR_PAUSE, 0, str, sizeof(str), TR_SYNC, 0);
308  if (status != CM_SUCCESS) {
309  cm_msg(MERROR, "hv_fug_check_trip_level", "%s", str);
310  }
311  }
312 
313  // close KV61, KV62
314  // get the demand array of the beamline frontend
315  strcpy(str, "/Equipment/Beamline/Variables/Demand");
316  status = db_find_key(hDB, 0, str, &demandKey);
317  if (status != DB_SUCCESS) {
318  cm_msg(MERROR, "hv_fug_check_trip_level", "Couldn't find %s", str);
319  return;
320  }
321  // close KV61
322  value = 0.0;
323  db_set_data_index(hDB, demandKey, &value, sizeof(value), FUG_BEAMLINE_KV61_CH, TID_FLOAT);
324  // close KV62
325  value = 0.0;
326  db_set_data_index(hDB, demandKey, &value, sizeof(value), FUG_BEAMLINE_KV62_CH, TID_FLOAT);
327  }
328  }
329 }
330 
331 //------------------------------------------------------------------
341 void hv_fug_scfe_monitoring(INT hDB, INT hKey, void *hv)
342 {
343  int i;
344  int trip = FALSE;
345  int status;
346  HNDLE demandKey;
347  KEY key;
348  char str[128];
349  float value;
350  float *hv_measured;
351 
352  // check if HV monitoring is enabled
354  return;
355 
356  hv_measured = (float *)hv;
357 
358  // check if TD HV is too small
359  for (i=TD_FIRST_CH; i<TD_LAST_CH; i++) {
360  if (fabs(hv_measured[i]) < 0.1f) { // i.e. smaller 100V
361  trip = TRUE;
362  break;
363  }
364  }
365 
366  if (!trip) // if TD HV are set
367  hv_fug_hvAlreadyOff = FALSE;
368 
369  // at least on TD HV < 100V and not already tripped
370  if (trip && !hv_fug_hvAlreadyOff) {
371  hv_fug_hvAlreadyOff = TRUE;
372  cm_msg(MERROR, "hv_fug_scfe_monitoring", "TD HV off!! Will switch off all HV :-(");
373  strcpy(str, "/Equipment/HV/Variables/Demand");
374  status = db_find_key(hDB, 0, str, &demandKey);
375  if (status != DB_SUCCESS) {
376  cm_msg(MERROR, "hv_fug_scfe_monitoring", "Couldn't find %s", str);
377  return;
378  }
379  status = db_get_key(hDB, demandKey, &key);
380  if (status != DB_SUCCESS) {
381  cm_msg(MERROR, "hv_fug_scfe_monitoring", "Couldn't get key info of %s", str);
382  return;
383  }
384  value = 0.f;
385  for (i=0; i < key.num_values; i++)
386  db_set_data_index(hDB, demandKey, &value, sizeof(value), i, TID_FLOAT);
387  }
388 }
389 
390 //------------------------------------------------------------------
407 void hv_fug_scfe_gas_inlet(INT hDB, INT hKey, void *dummy)
408 {
409  char str[128];
410  int status, i, ival;
411  float value;
412  HNDLE fug_hKey;
413 
414  // check moderator chamber
415  ival = (int)lemvac_in[LEMVAC_MC_STATUS_WORD_2];
416  if (ival & LEMVAC_GAS_INLET_ON) {
417  // get FUG hv demand odb key
418  strcpy(str, "/Equipment/HV/Variables/Demand");
419  status = db_find_key(hDB, 0, str, &fug_hKey);
420  if (status != DB_SUCCESS) {
421  cm_msg(MERROR, "hv_fug_scfe_gas_inlet", "Couldn't find %s", str);
422  return;
423  }
424 
425  // set all hv values of the moderator chamber (Moderator, Mod_Guard, Mod_Grid, Lense_1, Mirror) to zero
426  value = 0.0;
427  for (i=0; i<FUG_CHS; i++) {
428  if (hv_fug_chamber_flag[i] == FUG_MC)
429  db_set_data_index(hDB, fug_hKey, &value, sizeof(value), i, TID_FLOAT);
430  }
431  }
432 
433  // check trigger chamber
434  ival = (int)lemvac_in[LEMVAC_TC_STATUS_WORD_2];
435  if (ival & LEMVAC_GAS_INLET_ON) {
436  // get FUG hv demand odb key
437  strcpy(str, "/Equipment/HV/Variables/Demand");
438  status = db_find_key(hDB, 0, str, &fug_hKey);
439  if (status != DB_SUCCESS) {
440  cm_msg(MERROR, "hv_fug_scfe_gas_inlet", "Couldn't find %s", str);
441  return;
442  }
443 
444  // set all hv values of the trigger chamber (Lense_2, Lense_3) to zero
445  value = 0.0;
446  for (i=0; i<FUG_CHS; i++) {
447  if (hv_fug_chamber_flag[i] == FUG_TC)
448  db_set_data_index(hDB, fug_hKey, &value, sizeof(value), i, TID_FLOAT);
449  }
450  }
451 
452  // check sample chamber
453  ival = (int)lemvac_in[LEMVAC_SC_STATUS_WORD_2];
454  if (ival & LEMVAC_GAS_INLET_ON) {
455  // get FUG hv demand odb key
456  strcpy(str, "/Equipment/HV/Variables/Demand");
457  status = db_find_key(hDB, 0, str, &fug_hKey);
458  if (status != DB_SUCCESS) {
459  cm_msg(MERROR, "hv_fug_scfe_gas_inlet", "Couldn't find %s", str);
460  return;
461  }
462 
463  // set all hv values of the sample chamber (RA-L, RA-R, RA-T, RA-B, Sample) to zero
464  value = 0.0;
465  for (i=0; i<FUG_CHS; i++) {
466  if (hv_fug_chamber_flag[i] == FUG_SC)
467  db_set_data_index(hDB, fug_hKey, &value, sizeof(value), i, TID_FLOAT);
468  }
469  }
470 }
471 
472 //------------------------------------------------------------------
481 void hv_fug_demand_changed(INT hDB, INT hKey, void *dummy)
482 {
483  hv_fug_demand_changed_timer = ss_time();
484 }
485 
486 //-- Frontend Init -------------------------------------------------
496 {
497  HNDLE hDB, hKey;
498  KEY keyInfo;
499  INT status, i;
500  char str[128];
501 
502  // de-register run-transition notifications
503  cm_deregister_transition(TR_START);
504  cm_deregister_transition(TR_STOP);
505  cm_deregister_transition(TR_PAUSE);
506  cm_deregister_transition(TR_RESUME);
507 
508  // fill the FUG chamber flag array
509  hv_fug_chamber_flag[0] = FUG_TC; // Right rod of the spin rotator
510  hv_fug_chamber_flag[1] = FUG_TC; // Left rod of the spin rotator
511  hv_fug_chamber_flag[2] = FUG_TC; // Left plate of the spin rotator
512  hv_fug_chamber_flag[3] = FUG_TC; // Right plate of the spin rotator
513  hv_fug_chamber_flag[4] = FUG_MC; // Moderator
514  hv_fug_chamber_flag[5] = FUG_MC; // Moderator guard
515  hv_fug_chamber_flag[6] = FUG_MC; // Moderator grid
516  hv_fug_chamber_flag[7] = FUG_MC; // Lense 1
517  hv_fug_chamber_flag[8] = FUG_MC; // Mirror
518  hv_fug_chamber_flag[9] = FUG_TC; // Lense 2
519  hv_fug_chamber_flag[10] = FUG_TC; // Lense 3
520  hv_fug_chamber_flag[11] = FUG_SC; // RA-L
521  hv_fug_chamber_flag[12] = FUG_SC; // RA-R
522  hv_fug_chamber_flag[13] = FUG_SC; // RA-T
523  hv_fug_chamber_flag[14] = FUG_SC; // RA-B
524  hv_fug_chamber_flag[15] = FUG_SC; // Sample
525 
526 
527  // init global variables
529  hv_fug_hvAlreadyOff = FALSE;
530  hv_detectors_measured = NULL;
531  hv_fug_demand_changed_timer = ss_time();
532 
533  // get ODB main handle
534  cm_get_experiment_database(&hDB, NULL);
535 
536  // keep global handle
537  hv_fug_hDB = hDB;
538 
539  // hotlink monitoring
540  strcpy(str, "/Equipment/HV/Monitoring/FUG Monitoring");
541  status = db_find_key(hDB, 0, str, &hKey);
542  if (status != DB_SUCCESS) {
543  cm_msg(MINFO, "frontend_init", "hv_fug_scfe: Couldn't find %s. Will try to generate it.", str);
544  cm_yield(0);
545  status = db_create_record(hDB, 0, "/Equipment/HV/Monitoring", hv_fug_monitoring_str);
546  if (status != DB_SUCCESS) {
547  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: **ERROR** Couldn't find %s", str);
548  cm_yield(0);
549  return CM_SUCCESS;
550  }
551  return CM_SUCCESS;
552  }
553  status = db_open_record(hDB, hKey, &hv_fug_monitoring_enabled, sizeof(hv_fug_monitoring_enabled),
554  MODE_READ, NULL, NULL);
555  if (status != DB_SUCCESS) {
556  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't establish hotlink to %s", str);
557  return CM_SUCCESS;
558  }
559 
560  // hotlink trip rate source: TD or MCP1
561  strcpy(str, "/Equipment/HV/Monitoring/Trip Rate Source");
562  status = db_find_key(hDB, 0, str, &hKey);
563  if (status != DB_SUCCESS) {
564  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't find %s", str);
565  return CM_SUCCESS;
566  }
567  status = db_open_record(hDB, hKey, &hv_fug_trip_rate_source, sizeof(hv_fug_trip_rate_source),
568  MODE_READ, &hv_fug_trip_rate_source_changed, NULL);
569  if (status != DB_SUCCESS) {
570  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't establish hotlink to %s", str);
571  return CM_SUCCESS;
572  }
573 
574  // hotlink trip enable flag
575  strcpy(str, "/Equipment/HV/Monitoring/Trip Enabled");
576  status = db_find_key(hDB, 0, str, &hKey);
577  if (status != DB_SUCCESS) {
578  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't find %s", str);
579  return CM_SUCCESS;
580  }
581  status = db_open_record(hDB, hKey, &hv_fug_tripEnabled, sizeof(hv_fug_tripEnabled),
582  MODE_READ, NULL, NULL);
583  if (status != DB_SUCCESS) {
584  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't establish hotlink to %s", str);
585  return CM_SUCCESS;
586  }
587 
588  // hotlink trip rate
589  strcpy(str, "/Equipment/HV/Monitoring/Trip Level");
590  status = db_find_key(hDB, 0, str, &hKey);
591  if (status != DB_SUCCESS) {
592  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't find %s", str);
593  return CM_SUCCESS;
594  }
595  status = db_open_record(hDB, hKey, &hv_fug_tripRate, sizeof(hv_fug_tripRate),
596  MODE_READ, NULL, NULL);
597  if (status != DB_SUCCESS) {
598  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't establish hotlink to %s", str);
599  return CM_SUCCESS;
600  }
601 
602  if (strstr(hv_fug_trip_rate_source, "TD")) { // hotlink TD rate
603  cm_msg(MINFO, "frontend_init", "hv_fug_scfe: will used TD rate for HV rate monitoring");
604  strcpy(str, "/Equipment/Scaler/Variables/RATE/TD");
605  } else { // hotlink MCP1 rate
606  cm_msg(MINFO, "frontend_init", "hv_fug_scfe: will used MCP1 rate for HV rate monitoring");
607  strcpy(str, "/Equipment/Scaler/Variables/RATE/MCP1");
608  }
609  status = db_find_key(hDB, 0, str, &hKey);
610  if (status != DB_SUCCESS) {
611  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't find %s", str);
612  return CM_SUCCESS;
613  }
614  status = db_open_record(hDB, hKey, &hv_fug_detector_rate, sizeof(hv_fug_detector_rate),
615  MODE_READ, &hv_fug_check_trip_level, NULL);
616  if (status != DB_SUCCESS) {
617  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't establish hotlink to %s", str);
618  return CM_SUCCESS;
619  }
620 
621  // hotlink Detector HV measured
622  strcpy(str, "/Equipment/HV Detectors/Variables/Measured");
623  status = db_find_key(hDB, 0, str, &hKey);
624  if (status != DB_SUCCESS) {
625  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't find %s", str);
626  return CM_SUCCESS;
627  }
628  status = db_get_key(hDB, hKey, &keyInfo);
629  if (status != DB_SUCCESS) {
630  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't get key info of %s", str);
631  return CM_SUCCESS;
632  }
633 
634  hv_detectors_measured = (float *)calloc(keyInfo.num_values, sizeof(float));
635 
636  status = db_open_record(hDB, hKey, hv_detectors_measured,
637  keyInfo.num_values*sizeof(float),
639  if (status != DB_SUCCESS) {
640  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't establish hotlink to %s", str);
641  return CM_SUCCESS;
642  }
643 
644  // keep measured key for cyclic reading in frontend loop
645  strcpy(str, "/Equipment/HV/Variables/Measured");
646  status = db_find_key(hDB, 0, str, &hKey);
647  if (status != DB_SUCCESS) {
648  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't find %s", str);
649  return CM_SUCCESS;
650  }
652 
653  // hotlink lemvac input variables needed to check the gas inlet state
654  strcpy(str, "/Equipment/LEMVAC/Variables/Input");
655  status = db_find_key(hDB, 0, str, &hKey);
656  if (status != DB_SUCCESS) {
657  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't find %s", str);
658  return CM_SUCCESS;
659  }
660 
661  status = db_open_record(hDB, hKey, &lemvac_in, sizeof(lemvac_in), MODE_READ,
662  &hv_fug_scfe_gas_inlet, NULL);
663 
664  // hotlink FUG HV demand
665  strcpy(str, "/Equipment/HV/Variables/Demand");
666  status = db_find_key(hDB, 0, str, &hKey);
667  if (status != DB_SUCCESS) {
668  cm_msg(MERROR, "frontend_init", "hv_fug_scfe: Couldn't find %s", str);
669  return CM_SUCCESS;
670  }
671 
672  status = db_open_record(hDB, hKey, &hv_fug_demand, sizeof(hv_fug_demand), MODE_READ,
673  &hv_fug_demand_changed, NULL);
674 
675  // init FUG HV demand <-> measured drop counter
676  for (i=0; i<FUG_CHS; i++)
677  hv_fug_drop_counter[i] = 0;
678 
679  // init FUG HV demand <-> measured read timer
680  hv_fug_check_timestamp = ss_time();
681 
682  return CM_SUCCESS;
683 }
684 
685 //-- Frontend Exit -------------------------------------------------
691 {
692  char str[128];
693  int status;
694  HNDLE hDB, hKey;
695 
696  // get ODB main handle
697  cm_get_experiment_database(&hDB, NULL);
698 
699  // unlink fug monitoring
700  strcpy(str, "/Equipment/HV/Monitoring/FUG Monitoring");
701  status = db_find_key(hDB, 0, str, &hKey);
702  if (status != DB_SUCCESS) {
703  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
704  return CM_SUCCESS;
705  }
706  db_close_record(hDB, hKey);
707 
708  // unlink trip rate source
709  strcpy(str, "/Equipment/HV/Monitoring/Trip Rate Source");
710  status = db_find_key(hDB, 0, str, &hKey);
711  if (status != DB_SUCCESS) {
712  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
713  return CM_SUCCESS;
714  }
715  db_close_record(hDB, hKey);
716 
717  // unlink trip enabled
718  strcpy(str, "/Equipment/HV/Monitoring/Trip Enabled");
719  status = db_find_key(hDB, 0, str, &hKey);
720  if (status != DB_SUCCESS) {
721  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
722  return CM_SUCCESS;
723  }
724  db_close_record(hDB, hKey);
725 
726  // unlink trip level
727  strcpy(str, "/Equipment/HV/Monitoring/Trip Level");
728  status = db_find_key(hDB, 0, str, &hKey);
729  if (status != DB_SUCCESS) {
730  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
731  return CM_SUCCESS;
732  }
733  db_close_record(hDB, hKey);
734 
735  // unlink TD/MCP1 rates
736  if (strstr(hv_fug_trip_rate_source, "TD")) { // unlink TD rate
737  strcpy(str, "/Equipment/Scaler/Variables/RATE/TD");
738  status = db_find_key(hDB, 0, str, &hKey);
739  if (status != DB_SUCCESS) {
740  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
741  return CM_SUCCESS;
742  }
743  db_close_record(hDB, hKey);
744  } else { // unlink MCP1 rate
745  strcpy(str, "/Equipment/Scaler/Variables/RATE/MCP1");
746  status = db_find_key(hDB, 0, str, &hKey);
747  if (status != DB_SUCCESS) {
748  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
749  return CM_SUCCESS;
750  }
751  db_close_record(hDB, hKey);
752  }
753 
754  // unlink detector hv measured
755  strcpy(str, "/Equipment/HV Detectors/Variables/Measured");
756  status = db_find_key(hDB, 0, str, &hKey);
757  if (status != DB_SUCCESS) {
758  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
759  return CM_SUCCESS;
760  }
761  db_close_record(hDB, hKey);
762 
763  // free memory
765  free(hv_detectors_measured);
766 
767  // unlink lemvac input
768  strcpy(str, "/Equipment/LEMVAC/Variables/Input");
769  status = db_find_key(hDB, 0, str, &hKey);
770  if (status != DB_SUCCESS) {
771  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
772  return CM_SUCCESS;
773  }
774  db_close_record(hDB, hKey);
775 
776  // unlink FUG HV demand values
777  strcpy(str, "/Equipment/HV/Variables/Demand");
778  status = db_find_key(hDB, 0, str, &hKey);
779  if (status != DB_SUCCESS) {
780  cm_msg(MERROR, "frontend_exit", "hv_fug_scfe: Couldn't find %s, status=%d", str, status);
781  return CM_SUCCESS;
782  }
783  db_close_record(hDB, hKey);
784 
785  return CM_SUCCESS;
786 }
787 
788 //-- Frontend Loop -------------------------------------------------
794 {
795  HNDLE hKey;
796  DWORD now;
797  int size, i;
798  float measured[FUG_CHS];
799  char str[256];
800  char name[NAME_LENGTH];
801 
802  // check if FUG HV demand values just recently changed. If so, do nothing
803  now = ss_time();
805  return CM_SUCCESS;
806  } else {
807  if (hv_fug_debug)
808  cm_msg(MINFO, "frontend_loop", "hv_fug_scfe: time to do something ...");
809  }
810 
811  // check if FUG HV demand - FUG HV measured is within the tolerance
812  // time to read hv measured?
813  now = ss_time();
815  if (hv_fug_debug)
816  cm_msg(MINFO, "frontend_loop", "hv_fug_scfe: will read hv measured");
817  // reset timer
819  // read hv measured values from ODB
820  size = sizeof(measured);
821  db_get_record(hv_fug_hDB, hv_fug_measured_hKey, &measured[0], &size, 0);
822  // check if measured one is deviating too strongly from the demand
823  for (i=0; i<FUG_CHS; i++) {
824  if ((hv_fug_demand[i] != 0.0) && (fabs(hv_fug_demand[i]-measured[i])>0.2)) {
825  hv_fug_drop_counter[i]++;
826  if (hv_fug_debug)
827  cm_msg(MINFO, "frontend_loop", "hv_fug_scfe: ch = %d, drop counter = %d", i, hv_fug_drop_counter[i]);
828  // check of limit is reached
829  if (hv_fug_drop_counter[i]>5) {
830  // get name from ODB
831  strcpy(str, "/Equipment/HV/Settings/Names");
832  db_find_key(hv_fug_hDB, 0, str, &hKey);
833  size = sizeof(name);
834  db_get_data_index(hv_fug_hDB, hKey, name, &size, i, TID_STRING);
835  sprintf(str, "HV FUG %s: measured = %f, demand = %f, check!!",
836  name, measured[i], hv_fug_demand[i]);
837  al_trigger_alarm( "hv_fug_scfe", str, "Warning", str, AT_INTERNAL);
838  }
839  } else { // reset drop counter since readback is OK
840  hv_fug_drop_counter[i] = 0;
841  }
842  }
843  }
844 
845  return CM_SUCCESS;
846 }
847 
848 //-- Begin of Run --------------------------------------------------
853 INT begin_of_run(INT run_number, char *error)
854 {
855  return CM_SUCCESS;
856 }
857 
858 //-- End of Run ----------------------------------------------------
863 INT end_of_run(INT run_number, char *error)
864 {
865  return CM_SUCCESS;
866 }
867 
868 //-- Pause Run -----------------------------------------------------
873 INT pause_run(INT run_number, char *error)
874 {
875  return CM_SUCCESS;
876 }
877 
878 //-- Resume Run ----------------------------------------------------
883 INT resume_run(INT run_number, char *error)
884 {
885  return CM_SUCCESS;
886 }
887 
888 //------------------------------------------------------------------
INT interrupt_configure(INT cmd, INT source, PTYPE adr)
Definition: vme_fe.c:2119
int hv_fug_debug
Definition: hv_fug_scfe.c:84
DWORD hv_fug_demand_changed_timer
Definition: hv_fug_scfe.c:77
#define LEMVAC_MC_STATUS_WORD_2
Definition: hv_fug_scfe.c:46
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 FUG_BEAMLINE_KV61_CH
Definition: hv_fug_scfe.c:59
DWORD hv_fug_check_timestamp
Definition: hv_fug_scfe.c:79
void hv_fug_trip_rate_source_changed(INT hDB, INT hKey, void *dummy)
Definition: hv_fug_scfe.c:159
DEVICE_DRIVER hv_driver[]
device driver list
Definition: hv_fug_scfe.c:107
float hv_fug_demand[FUG_CHS]
Definition: hv_fug_scfe.c:73
#define FUG_MC
Definition: hv_fug_scfe.c:53
void hv_fug_demand_changed(INT hDB, INT hKey, void *dummy)
Definition: hv_fug_scfe.c:481
void hv_fug_check_trip_level(INT, INT, void *)
Definition: hv_fug_scfe.c:245
INT end_of_run(INT run_number, char *error)
Definition: vme_fe.c:858
int hv_fug_chamber_flag[FUG_CHS]
Definition: hv_fug_scfe.c:75
INT hv_fug_hvAlreadyOff
HV already switched off.
Definition: hv_fug_scfe.c:91
HNDLE hv_fug_hDB
Definition: hv_fug_scfe.c:69
#define FUG_SC
Definition: hv_fug_scfe.c:55
INT frontend_init()
Definition: vme_fe.c:416
INT hv_fug_tripRate
hotlink variable holding the TD trip rate
Definition: hv_fug_scfe.c:90
HNDLE hKey
Definition: write_summary.c:97
INT frontend_loop()
Definition: vme_fe.c:949
BOOL frontend_call_loop
frontend_loop is called periodically if this variable is TRUE
Definition: vme_fe.c:165
#define FUG_BEAMLINE_KV62_CH
Definition: hv_fug_scfe.c:60
HNDLE hDB
Definition: write_summary.c:97
#define TD_FIRST_CH
Definition: hv_fug_scfe.c:57
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 frontend_exit()
Definition: vme_fe.c:557
#define TD_LAST_CH
Definition: hv_fug_scfe.c:58
#define FUG_CHS
Definition: hv_fug_scfe.c:50
int hv_fug_drop_counter[FUG_CHS]
Definition: hv_fug_scfe.c:81
float * hv_detectors_measured
hotlink variable holding the measured TD HV&#39;s
Definition: hv_fug_scfe.c:66
const char * hv_fug_monitoring_str
Definition: hv_fug_scfe.c:97
#define FUG_TC
Definition: hv_fug_scfe.c:54
char hv_fug_trip_rate_source[NAME_LENGTH]
hotlink variable holding the name of the detector which is to monitor the rate
Definition: hv_fug_scfe.c:88
INT event_buffer_size
buffer size to hold events
Definition: vme_fe.c:177
HNDLE hv_fug_measured_hKey
Definition: hv_fug_scfe.c:70
INT hv_fug_detector_rate
hotlink variable holding the TD or MCP1 rate
Definition: hv_fug_scfe.c:63
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
#define LEMVAC_GAS_INLET_ON
Definition: hv_fug_scfe.c:45
INT hv_fug_tripEnabled
hotlink variable holding the trip enabled flag
Definition: hv_fug_scfe.c:89
INT hv_fug_monitoring_enabled
hotlink variable holding the monitoring enabled flag
Definition: hv_fug_scfe.c:87
#define FUG_READ_TIME
Definition: hv_fug_scfe.c:51
void hv_fug_scfe_monitoring(INT hDB, INT hKey, void *hv)
Definition: hv_fug_scfe.c:341
INT begin_of_run(INT run_number, char *error)
Definition: vme_fe.c:589
#define FUG_DEMAND_CHANGED_TIMEOUT
Definition: hv_fug_scfe.c:52
#define LEMVAC_TC_STATUS_WORD_2
Definition: hv_fug_scfe.c:47
#define LEMVAC_SC_STATUS_WORD_2
Definition: hv_fug_scfe.c:48
INT display_period
a frontend status page is displayed with this frequency in ms
Definition: vme_fe.c:168
void hv_fug_scfe_gas_inlet(INT hDB, INT hKey, void *dummy)
Definition: hv_fug_scfe.c:407
INT resume_run(INT run_number, char *error)
Definition: vme_fe.c:893