Low-Energy Muon (LEM) Experiment  0.5.1
scaler_rate_sum.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: scaler_rate_sum.c
4  Created by: Thomas Prokscha, use scaler.c module of sample experiment
5  by Stefan Ritt as template.
6 
7  Contents: sis3820 scaler handling module. It looks
8  for SCL0 bank and accumulates scalers into an
9  SSUM bank; rates are written to RATE bank.
10 
11 
12 \********************************************************************/
13 
14 /*-- Include files -------------------------------------------------*/
15 
16 /* standard includes */
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <time.h>
20 #include <string.h>
21 #include <math.h>
22 
23 /* midas includes */
24 #include "midas.h"
25 #include "experim.h"
26 #include "nemu_experim.h"
27 
28 /*-- ODB Parameters ------------------------------------------------*/
29 extern RUNINFO runinfo;
30 extern EXP_PARAM exp_param;
33 SCALERSUMRATE_PARAM_STR(scaler_param_str);
34 
35 /*-- Module declaration --------------------------------------------*/
36 INT scaler_init(void);
37 INT scaler_sum(EVENT_HEADER*,void*);
38 INT scaler_clear(INT run_number);
39 INT scaler_eor(INT run_number);
40 
41 ANA_MODULE scaler_rate_sum = {
42  "ScalerSumRate", /* module name */
43  "Thomas Prokscha", /* author */
44  scaler_sum, /* event routine */
45  scaler_clear, /* BOR routine */
46  scaler_eor, /* EOR routine */
47  scaler_init, /* init routine */
48  NULL, /* exit routine */
49  &scaler_param, /* parameter structure */
50  sizeof(scaler_param), /* structure size */
51  (const char **)scaler_param_str, /* initial parameters */
52 };
53 
54 /*-- accumulated scalers -------------------------------------------*/
55 static double scaler[N_SCALER];
56 static INT rate[N_SCALER]; /* rates */
57 static double last_lem_events, lem_events;
58 
59 /*-- for mean Ip calculation --*/
62 
63 /* to print scaler Totals and Rates in Analyzer window */
64 void disp_scaler(INT nscal);
65 
66 /*-- INIT routine --------------------------------------------------*/
67 
68 INT scaler_init(void)
69 {
70  INT nscaler, status, size;
71  HNDLE hDB, hkey;
72 
73  cm_get_experiment_database(&hDB, NULL);
74 
75  nscaler = N_SCALER;
76  status = db_find_key(hDB, 0, "/Equipment/Scaler/Variables/SCL0", &hkey);
77  if (status == DB_SUCCESS )
78  db_set_num_values(hDB, hkey, nscaler);
79  else
80  cm_msg(MERROR, "scaler_init", "Error setting array length of SCL0.");
81 
82  status = db_find_key(hDB, 0, "/Equipment/Scaler/Variables/SSUM", &hkey);
83  if (status == DB_SUCCESS )
84  db_set_num_values(hDB, hkey, nscaler);
85  else
86  cm_msg(MERROR, "scaler_init", "Error setting array length of SSUM.");
87 
88  size = sizeof(lem_events);
89  db_get_value(hDB, 0, "/Equipment/Trigger/VME_Statistics/SlowMuonEvents", &lem_events, &size, TID_DOUBLE, FALSE);
91 
92  //setting up ring buffer for mean Ip rate calculation
93  if (scaler_param.n_rate_average <= 0)
94  ring_buffer_size = 100;
95  else
96  ring_buffer_size = scaler_param.n_rate_average;
97 
98  pring_buffer = (INT*)malloc(ring_buffer_size*sizeof(INT));
100  nwrite_ring_buffer = 0;
101  memset(pring_buffer, 0x00, sizeof(pring_buffer));
102 
103  return SUCCESS;
104 }
105 
106 /*-- BOR routine ---------------------------------------------------*/
107 
108 INT scaler_clear(INT run_number)
109 {
110  HNDLE hDB;
111  INT size;
112 
113  cm_get_experiment_database(&hDB, NULL);
114 
115  memset(scaler, 0, sizeof(scaler));
116  memset(rate, 0, sizeof(rate));
117 
118  size = sizeof(lem_events);
119  db_get_value(hDB, 0, "/Equipment/Trigger/VME_Statistics/SlowMuonEvents", &lem_events, &size, TID_DOUBLE, FALSE);
121 
122  return SUCCESS;
123 }
124 
125 /*-- EOR routine ---------------------------------------------------*/
126 
127 INT scaler_eor(INT run_number)
128 {
129  return SUCCESS;
130 }
131 
132 /*-- event routine -------------------------------------------------*/
139 INT scaler_sum(EVENT_HEADER *pheader, void *pevent)
140 {
141 HNDLE hDB;
142 INT n, i, size, sum_Ip_rate, mean_Ip_rate, *pmean_rate;
143 double norm=1.;
144 DWORD *psclr, mask_scaler[N_SCALER];
145 double *psum;
146 INT *pd, *psratio;
147 RATE_BANK *prate;
148 SRAT_BANK *psrat;
149 double new_lem_events;
150 
151  cm_get_experiment_database(&hDB, NULL);
152 
153  /* look for SCL0 bank */
154  n = bk_locate(pevent, "SCL0", &psclr);
155  if (n == 0 || n > N_SCALER)
156  return 1;
157 
158  for ( i=0; i<n; i++){
159  if ( scaler_settings.input_mode_3 )
160  mask_scaler[i] = psclr[i] & MASK24;
161  else
162  mask_scaler[i] = psclr[i];
163  }
164 
165  /* --- create bank of scaler sums --- */
166  bk_create(pevent, "SSUM", TID_DOUBLE, (void**)&psum);
167 
168  for (i=0 ; i<n ; i++){
169  if (runinfo.state == STATE_RUNNING ){
170  scaler[i] += mask_scaler[i];
171  }
172  psum[i] = scaler[i];
173  }
174 
175  bk_close(pevent, psum+n);
176 
177  /* --- create rate bank and calculate rates --- */
178  bk_create(pevent, "RATE", TID_STRUCT, (void **)&prate);
179 
180  pd = &prate->ip; // copy address of first element of structure to pointer pd
181  // this is useful if the structure contains n elements of same type,
182  // i.e. (double) in our case. If element names should be different
183  // then this offers a simple way to assign values to the elements
184  // without explicitly entering the element name.
185  // This will work with the statement
186  // *(pd+i) = rate[i]; see below
187  for (i=0 ; i<n ; i++){
188 #ifdef HAVE_TEST_RUN
189  norm = 10.;
190  if ( i == scaler_param.channel_norm_time )
191  rate[i] = 1000;
192  else
193  rate[i] = (int) rint(mask_scaler[i]/norm);
194 #else
195  if ( mask_scaler[scaler_param.channel_norm_time] > 0 ){
196  norm = (double)mask_scaler[scaler_param.channel_norm_time]/(double)scaler_param.rate_norm_time;
197  rate[i] = (int) rint(mask_scaler[i]/norm);
198  }
199  else
200  rate[i] = -1;
201 #endif
202  //prate->rat0[i] = rate[i];
203  *(pd+i) = rate[i]; // increment pointer address by the size of one double, assign
204  // value of rate[i] to new address,
205  // which is the ith entry of the structure prate
206  }
207 
208  // get LEM events from VME_STATS key in ODB
209  new_lem_events = 0.;
210  size = sizeof(lem_events);
211  db_get_value(hDB, 0, "/Equipment/Trigger/VME_Statistics/SlowMuonEvents", &lem_events, &size, TID_DOUBLE, FALSE);
212  new_lem_events = lem_events - last_lem_events;
213  last_lem_events = lem_events;
214  if (new_lem_events < 0.) new_lem_events = 0.; // this may happen at BOR
215  if ( mask_scaler[scaler_param.channel_norm_time] > 0 )
216  rate[i] = (int) rint(new_lem_events/norm);
217  else
218  rate[i] = -1;
219  *(pd+i) = rate[i];
220 
221  bk_close(pevent, prate+1);
222 
223 /*----------------------------------------------------------------
224  calculate scaler ratios
225  ----------------------------------------------------------------
226 */
227  /* create calculated bank */
228  bk_create(pevent, "SRAT", TID_STRUCT, (void **)&psrat);
229  psratio = &psrat->ip; // copy address of first element of structure to pointer psratio
230 
231  /*---- perform calculations --------------------------------------*/
232  if ( pd[scaler_param.ip_channel] > scaler_param.ip_threshold_current_ua_*100 ){
233 // psrat->ch1_ip = IpSCALE * (float) prate->rat0[0] / (float) prate->rat0[scaler_analysis_param.ip_channel];
234 // psrat->ch1_ip = IpSCALE * (float) pd[0] / (float) pd[scaler_param.ip_channel];
235  for (i=0; i<n+1; i++)
236  *(psratio+i) = (int) rint(IpSCALE * (float) pd[i] / (float) pd[scaler_param.ip_channel]);
237  }
238  else{
239  for (i=0; i<n+1; i++)
240  *(psratio+i) = 0;
241  }
242  /* computer busy time = 1 - LAM2/Trig2 */
243 /*
244  if ( pscl0[hrates_param.trig2] != 0 )
245  phrti->compbusy = 1. - (float) pscl0[hrates_param.lam2] / (float) pscl0[hrates_param.trig2];
246  else
247 */
248  bk_close(pevent, psrat+1);
249 
250  //fill ring buffer for Ip
252  *pwrite_ring_buffer++ = rate[scaler_param.ip_channel];
253  else{
255  *pwrite_ring_buffer++ = rate[scaler_param.ip_channel];
256  }
257  if (nwrite_ring_buffer < ring_buffer_size)
259 
260  //calculate mean Ip rate
261  sum_Ip_rate = 0;
262  for (i=0; i< ring_buffer_size; i++)
263  sum_Ip_rate += pring_buffer[i];
264 
265  if (nwrite_ring_buffer < ring_buffer_size)
266  mean_Ip_rate = sum_Ip_rate/nwrite_ring_buffer;
267  else
268  mean_Ip_rate = sum_Ip_rate/ring_buffer_size;
269 
270  // --- create bank and fill mean rates ---
271  bk_create(pevent, "RAAV", TID_INT, (void **)&pmean_rate);
272  *pmean_rate = mean_Ip_rate;
273  bk_close(pevent, pmean_rate+1);
274 
275  //display scalers in terminal
276  if ( runinfo.online_mode == 1)
278 
279  return SUCCESS;
280 }
281 
282 /* --------------------------------------------------------------------------
283 
284  function to display scalers in analyzer info
285 
286  --------------------------------------------------------------------------
287 */
288 void disp_scaler(INT nscal)
289 {
290 HNDLE hDB, hKey;
291 const char *state[] = {"", "Stopped", "Paused", "Running" };
292 const char *line[] =
293 {"--------------------------------------------------------------------------"};
294 const char *empty[] =
295 {" "};
296 const char *top[] =
297 {" # Label Total Rate/s "};
298 time_t now, difftime;
299 INT i;
300 //double norm;
301 char timestr[32];
302 
303  ss_clear_screen();
304  ss_printf(0, 0, "%s", line[0]);
305 
306  ss_printf(0,1, " Run Number: %10d started at: %s",
307  runinfo.run_number, runinfo.start_time);
308 
309  if ( runinfo.state == STATE_STOPPED){
310  ss_printf(0,2, " Run State : %10s last update: %s",
311  state[runinfo.state], runinfo.stop_time);
312  }
313  else{
314  time(&now);
315  ss_printf(0,2, " Run State : %10s last update: %s",
316  state[runinfo.state], ctime(&now));
317  }
318  ss_printf(0,3, "%s", empty[0]);
319  ss_printf(0,4, "%s", top[0]);
320  ss_printf(0,5, "%s", line[0]);
321  ss_printf(0,6, "%s", empty[0]);
322 
323  for (i=0 ; i<nscal ; i++){
324  if ( scaler[i] > 1e7 )
325  ss_printf(0, i+7, "%2d %-24s %15.5e\t\t %13d", i,
326  scaler_settings.names_scl0[i], scaler[i], rate[i]);
327 // ss_printf(0, i+7, "%2d %-24s 0x%08x\t\t 0x%08x", i,
328 // scaler_settings.names_scl0[i], scaler[i], rate[i]);
329 
330  else
331  ss_printf(0, i+7, "%2d %-24s %15.0f\t\t %13d", i,
332  scaler_settings.names_scl0[i], scaler[i], rate[i]);
333  }
334  ss_printf(0, 47, "%s", line[0]);
335  if (runinfo.state == STATE_STOPPED)
336  difftime = runinfo.stop_time_binary - runinfo.start_time_binary;
337  else
338  difftime = now - runinfo.start_time_binary;
339 
340  ss_printf(0, 49, "Elapsed time: %dh%02dm%02ds",
341  difftime/3600, difftime%3600/60,difftime%60);
342 
343  /* -------------------------------------------------
344 
345  update "/Info/Scaler Update Time"; this is used
346  for Scaler display via mhttpd
347 
348  -------------------------------------------------
349  */
350  cm_get_experiment_database(&hDB, NULL);
351  if ( db_find_key(hDB, 0, "/Info/Scaler Update time", &hKey) != DB_SUCCESS ){
352  if ( db_create_key(hDB, 0, "/Info/Scaler Update time", TID_STRING) != DB_SUCCESS ){
353  cm_msg(MERROR, "display_scaler", "Cannot create \"/Info/Scaler Update time\" key in ODB");
354  return;
355  }
356  }
357  time(&now);
358  timestr[0] = 0;
359  sprintf(timestr, "%s", ctime(&now));
360  timestr[24] = 0; /* delete new line \n */
361  db_set_value(hDB, 0, "/Info/Scaler Update time", &timestr, sizeof(timestr), 1, TID_STRING);
362 
363  return;
364 }
365 /* ----------------------------------------------------------------------------
366 
367  EOF frontend/vme/scaler.c
368 
369  ----------------------------------------------------------------------------
370 */
INT scaler_sum(EVENT_HEADER *, void *)
#define MASK24
Definition: nemu_experim.h:85
static INT nwrite_ring_buffer
void disp_scaler(INT n)
EXP_PARAM exp_param
Definition: analyzer.c:97
ANA_MODULE scaler_rate_sum
SCALER_SETTINGS scaler_settings
Definition: vme_fe.c:189
INT ip_threshold_current_ua_
Definition: experim.h:455
RUNINFO runinfo
/Runinfo ODB key, defined in from midas.h
Definition: vme_fe.c:193
INT scaler_eor(INT run_number)
HNDLE hKey
Definition: write_summary.c:97
char line[MAXLINE]
Definition: write_summary.c:96
static INT rate[N_SCALER]
static INT * pwrite_ring_buffer
HNDLE hDB
Definition: write_summary.c:97
static INT * pring_buffer
static double lem_events
static double last_lem_events
char names_scl0[64][32]
Definition: experim.h:1191
INT scaler_init(void)
SCALERSUMRATE_PARAM_STR(scaler_param_str)
static INT ring_buffer_size
INT ip
Definition: experim.h:863
INT scaler_clear(INT run_number)
INT ip
Definition: experim.h:1003
#define N_SCALER
total number of scaler channels
Definition: nemu_experim.h:63
#define IpSCALE
Definition: nemu_experim.h:79
static double scaler[N_SCALER]
SCALERSUMRATE_PARAM scaler_param