Low-Energy Muon (LEM) Experiment  0.5.1
analyzer.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: analyzer.c
4  Created by: Thomas Prokscha, 14-May-2004
5  Andreas Suter, 08-March-2012 Adopted to MusrRoot
6  Zaher Salman 18-March-2012 Aded LEM spin rotator
7 
8  Contents: System part of Analyzer code for LEM experiment.
9  Sep/2006: save histograms every
10  "HISTOGRAM_WRITE_PERIOD" s (300sec at the moment).
11 
12  The module creates the /Info structure in ODB that contains
13  important information for the LEM experiment.
14  Additional functions to write histogram files, histograms
15  file header generation:
16 
17  write_histogram_file();
18  get_sum_filename(char *filename);
19  extract_summary_data(); // from .summ files
20  update_info(); // update t0's, energy loss, B-field, LEM setup
21  update_run_header();
22  energy_loss(float moderator_hv); // calculate energy loss in C-foil according to a 3rd order polynomial
23  get_magnetic_field(float current); // calculate magnetic field at sample from ZeroFlux reading according
24  // to magnet chosen (WEW or Bpar)
25  get_t0(); // scale t0's with 1/sqrt(E), starting at t0(12kV) and with TOF(12kV)
26  get_t0L3RA(); // scale t0 as a function of L3 and TD potentials
27  receive_message(...) // receive alarm message; if enabled sent warning as SMS/EMail to user specified
28  // in /Info/Alarm Notification/Recipients
29  2009-06-20: disabled receive_message; sending SMS/e-mail nottifications now done
30  by extra Midas client send_message.
31  read_intel_log(INTEL_LOG *info) // read lem00 main board parameters (temperature, fan speed...)
32  update_t0shift() // update t0 shifts when changing from Bpar to WEW setup
33  beam_shutter_open(HNDLE hDB) // check beam shutter position on run start and run resume and give a
34  // warning if still closed
35  set_spin_rot_angle() // using the angle parameter and moderator energy calculate and set appropriate SR
36  // magnet current and plates potential
37 
38 
39 ********************************************************************/
40 
41 #include <vector>
42 using namespace std;
43 
44 // standard includes
45 #include <stdio.h>
46 #include <string.h>
47 #include <time.h>
48 #include <stdlib.h>
49 
50 // midas includes
51 #include "midas.h"
52 #include "experim.h"
53 #include "nemu_experim.h"
54 
55 // cernlib includes
56 #ifdef OS_WINNT
57 #define VISUAL_CPLUSPLUS
58 #endif
59 #ifdef __linux__
60 #define f2cFortran
61 #endif
62 
63 #ifdef HAVE_HBOOK
64 #include <cfortran.h>
65 #include <hbook.h>
66 PAWC_DEFINE(8000000);
67 #else
68 // root includes
69 #include <TROOT.h>
70 #include <TSystem.h>
71 #include <TMath.h>
72 #include <TH1F.h>
73 #include <TH2F.h>
74 #include <TTree.h>
75 #include <TDirectory.h>
76 #include <TFile.h>
77 //as #include <TLemRunHeader.h>
78 #include <TMusrRunHeader.h>
79 #endif
80 
81 //-- Globals -------------------------------------------------------
82 
83 // The analyzer name (client name) as seen by other MIDAS clients
84 const char *analyzer_name = "Analyzer";
85 
86 // analyzer_loop is called with this interval in ms (0 to disable)
88 
89 // default ODB size
90 INT odb_size = DEFAULT_ODB_SIZE;
91 
92 char runname[256];
95 RUNINFO runinfo;
100 RATE_BANK_STR(rate_bank_str);
102 SRAT_BANK_STR(srat_bank_str);
104 POSI_BANK_STR(posi_bank_str);
108 // SCS900_EVENT scs900_event;
110 
113 extern MEAN_BANK mean;
114 
117 
118 extern TFolder *gManaHistosFolder;
119 static TFolder *gRunHeader = NULL;
120 //as static TLemRunHeader *header = NULL;
121 static TMusrRunHeader *header = NULL;
122 static TObjArray Slist(0);
123 
124 static DWORD last_histogram_write;
126 #define HISTOGRAM_WRITE_PERIOD 300 // write histograms every 300s to file
127 #define UPDATE_INFO_PERIOD 10 // update info structure with eloss and B-field every 10sec
128 #define UPDATE_INFO_PERIOD_INTEL 300 // update lem00 intel log info structure every 300s
129 static INT write_flag;
130 static INT sum_count;
131 
132 static float rotation_angle; // spin rotation angle hotlink variable
133 
134 //-- Module declarations -------------------------------------------
138 extern ANA_MODULE decay_ana_module;
139 extern ANA_MODULE tof_ana_module;
140 extern ANA_MODULE pileup_ana_module;
141 extern ANA_MODULE mcp1_ana_module;
142 extern ANA_MODULE scaler_rate_sum;
143 extern ANA_MODULE sc_ana_module;
144 
145 ANA_MODULE *trigger_module[] = {
150  NULL
151 };
152 
153 ANA_MODULE *scaler_module[] = {
155  NULL
156 };
157 
158 ANA_MODULE *sc_module[] = {
159  &sc_ana_module,
160  NULL
161 };
162 
163 //-- Bank definitions ----------------------------------------------
170 BANK_LIST trigger_bank_list[] = {
171  // online banks
172  { "TDC0", TID_DWORD},
173 
174  // calculated banks
175  { "POSI", TID_STRUCT, sizeof(posi_bank), (char **)posi_bank_str },
176  { "" },
177 };
178 
179 BANK_LIST scaler_bank_list[] = {
180  // online banks
181  { "SCL0", TID_DWORD},
182 
183  // calculated banks
184  { "SSUM", TID_DOUBLE},
185  { "RATE", TID_STRUCT, sizeof(rate_bank), (char **)rate_bank_str },
186  { "SRAT", TID_STRUCT, sizeof(srat_bank), (char **)srat_bank_str },
187  { "RAAV", TID_INT},
188  { "" },
189 };
190 
191 BANK_LIST sc_bank_list[] = {
192  { "DBEA", TID_FLOAT},
193  { "MBEA", TID_FLOAT},
194  { "MVAC", TID_FLOAT},
195  { "MMOD", TID_FLOAT},
196  { "MSAM", TID_FLOAT},
197  { "M900", TID_FLOAT},
198  { "MHVT", TID_FLOAT},
199  { "MHVD", TID_FLOAT},
200  // calculated banks
201  //{ "MEAN", TID_STRUCT, sizeof(mean_bank), mean_bank_str },
202  { "" },
203 };
204 
205 //-- Event request list --------------------------------------------
206 ANALYZE_REQUEST analyze_request[] = {
207  { "Trigger",
208  {1,
209  TRIGGER_ALL,
210  GET_ALL,
211  "SYSTEM",
212  TRUE,
213  "", "",},
214  NULL,
217  1000,
218  TRUE,
219  },
220 
221  { "Scaler",
222  {2,
223  TRIGGER_ALL,
224  GET_ALL,
225  "SYSTEM",
226  TRUE,
227  "", "",},
228  NULL,
229  scaler_module,
231  100,
232  },
233 
234  { "SlowControl",
235  {3,
236  TRIGGER_ALL,
237  GET_ALL,
238  "SYSTEM",
239  TRUE,
240  "", "",},
241  NULL,
242  sc_module,
243  sc_bank_list,
244  100,
245  },
246 
247  { "" }
248 };
249 
250 //-- functions ---------------------------------------------------
256 void get_sum_filename(char *filename);
257 void extract_summary_data();
258 void update_info();
259 void update_run_header();
260 INT beam_shutter_open(HNDLE hDB);
261 float energy_loss(float moderator_hv);
262 float get_magnetic_field(float current);
263 void get_t0();
264 void get_t0L3RA();
265 //void receive_message(HNDLE hBuf, HNDLE id, EVENT_HEADER *evHeader, void *message);
268 void update_t0shift(INT dummy1, INT dummy2, void *dummy3);
269 void set_spin_rot_angle(INT hDB, INT hKey, void *dummy);
270 extern void disp_scaler(INT n);
271 
272 //-- Analyzer Init -------------------------------------------------
274 {
275  HNDLE hDB, hKey;
276  char str[80];
277  char fname[256], exp_name[32];
278  char lazy_fname[128];
279  INT size, status;
280  struct tm *tms; // for getting the year from the binary date
281  time_t now;
282  char timestr[32];
283  BOOL flag_Bpar,flag_spinrot;
284 
285  RUNINFO_STR(runinfo_str);
286  EXP_PARAM_STR(exp_param_str);
287  EXP_EDIT_STR(exp_edit_str);
288  SCALER_SETTINGS_STR(scaler_settings_str);
289  T0SHIFT_PARAM_STR(t0shift_param_str);
290  TDSAMPLETOF_PARAM_STR(tdsampletof_param_str);
291  INFO_STR(info_str);
292  MEAN_BANK_STR(mean_bank_str);
293 
294  //----------------------------------------------------------------
295  // open ODB structures
296  //----------------------------------------------------------------
297 
298  cm_get_experiment_database(&hDB, NULL);
299 
300  db_create_record(hDB, 0, "/Runinfo", strcomb(runinfo_str));
301  db_find_key(hDB, 0, "/Runinfo", &hKey);
302  if (db_open_record(hDB, hKey, &runinfo, sizeof(runinfo), MODE_READ, NULL, NULL) != DB_SUCCESS) {
303  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Runinfo\" tree in ODB");
304  return 0;
305  }
306 
307  db_create_record(hDB, 0, "/Experiment/Run Parameters", strcomb(exp_param_str));
308  db_find_key(hDB, 0, "/Experiment/Run Parameters", &hKey);
309  if (db_open_record(hDB, hKey, &exp_param, sizeof(exp_param), MODE_READ, NULL, NULL) != DB_SUCCESS) {
310  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Experiment/Run Parameters\" tree in ODB");
311  return 0;
312  }
313 
314  sprintf(str, "/Experiment/Name");
315  size = sizeof(exp_name);
316  if (db_get_value(hDB, 0, str, exp_name, &size, TID_STRING, TRUE) != DB_SUCCESS ) {
317  sprintf(exp_name, "nemu");
318  }
319 
320  db_create_record(hDB, 0, "/Experiment/Edit on start", strcomb(exp_edit_str));
321  db_find_key(hDB, 0, "/Equipment/Trigger/Settings", &hKey);
322  if (db_open_record(hDB, hKey, &trigger_settings, sizeof(trigger_settings), MODE_READ,
323  NULL, NULL) != DB_SUCCESS) {
324  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/Trigger/Settings\" tree in ODB");
325  return 0;
326  }
327 
328  db_create_record(hDB, 0, "/Equipment/Scaler/Settings", strcomb(scaler_settings_str));
329  db_find_key(hDB, 0, "/Equipment/Scaler/Settings", &hKey);
330  if (db_open_record(hDB, hKey, &scaler_settings, sizeof(scaler_settings), MODE_READ,
331  NULL, NULL) != DB_SUCCESS) {
332  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/Scaler/Settings\" tree in ODB");
333  return 0;
334  }
335  // create t0Shift structure
336  sprintf(str, "/%s/Parameters/t0Shift", analyzer_name);
337  db_create_record(hDB, 0, str, strcomb(t0shift_param_str));
338  db_find_key(hDB, 0, str, &hKey);
339  if (db_open_record(hDB, hKey, &t0shift_param, sizeof(t0shift_param),
340  MODE_READ, NULL, NULL) != DB_SUCCESS) {
341  cm_msg(MERROR, "analyzer_init", "Cannot open \"%s\" tree in ODB", str);
342  return 0;
343  }
344 
345  // create TDSampleTOF structure
346  sprintf(str, "/%s/Parameters/TDSampleTOF", analyzer_name);
347  db_create_record(hDB, 0, str, strcomb(tdsampletof_param_str));
348  db_find_key(hDB, 0, str, &hKey);
349  if (db_open_record(hDB, hKey, &tdsampletof_param, sizeof(tdsampletof_param),
350  MODE_READ, NULL, NULL) != DB_SUCCESS) {
351  cm_msg(MERROR, "analyzer_init", "Cannot open \"%s\" tree in ODB", str);
352  return 0;
353  }
354 
355  //create /Info structure
356  db_create_record(hDB, 0, "/Info", strcomb(info_str));
357  db_find_key(hDB, 0, "/Info", &hKey);
358  if (db_open_record(hDB, hKey, &info, sizeof(info), MODE_READ, NULL, NULL) != DB_SUCCESS) {
359  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Info\" tree in ODB");
360  return 0;
361  }
362 
363  db_find_key(hDB, 0, "/Info/LEM_Setup_Parameter/Bpar", &hKey);
364  if (db_open_record(hDB, hKey, &flag_Bpar, sizeof(BOOL), MODE_READ, &update_t0shift, NULL) != DB_SUCCESS) {
365  cm_msg(MERROR, "analyzer_init", "Cannot open /Info/LEM_Setup_Parameter/Bpar tree in ODB");
366  return 0;
367  }
368 
369  // spin rotator hotlinks on angle
370  db_find_key(hDB, 0, "/Info/SpinRot_Parameter/RotationAngle", &hKey);
371  if (db_open_record(hDB, hKey, &rotation_angle, sizeof(float), MODE_READ, &set_spin_rot_angle, NULL) != DB_SUCCESS) {
372  cm_msg(MERROR, "analyzer_init", "Cannot open /Info/SpinRot_Parameter/RotationAngle tree in ODB");
373  return 0;
374  }
375 
376  // open ODB records for use in TLemRunHeader and energy loss/B-field calculation
377  db_find_key(hDB, 0, "/Equipment/HV/Variables", &hKey);
378  if (db_open_record(hDB, hKey, &hv_event, sizeof(hv_event), MODE_READ, NULL, NULL) != DB_SUCCESS) {
379  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/HV/Variables\" tree in ODB");
380  return 0;
381  }
382 
383 /*
384  db_find_key(hDB, 0, "/Equipment/SampleCryo/Variables", &hKey);
385  if (db_open_record(hDB, hKey, &samplecryo_event, sizeof(samplecryo_event),
386  MODE_READ, NULL, NULL) != DB_SUCCESS) {
387  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/SampleCryo/Variables\" tree in ODB");
388  return 0;
389  }
390 
391  db_find_key(hDB, 0, "/Equipment/SCS900/Variables", &hKey);
392  if (db_open_record(hDB, hKey, &scs900_event, sizeof(scs900_event),
393  MODE_READ, NULL, NULL) != DB_SUCCESS) {
394  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/SCS900/Variables\" tree in ODB");
395  return 0;
396  }
397 */
398  db_find_key(hDB, 0, "/Equipment/SCS2001M/Variables", &hKey);
399  if (db_open_record(hDB, hKey, &scs2001m_event, sizeof(scs2001m_event),
400  MODE_READ, NULL, NULL) != DB_SUCCESS) {
401  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/SCS2001M/Variables\" tree in ODB");
402  return 0;
403  }
404 
405  db_create_record(hDB, 0, "/Equipment/SlowControl/Variables/MEAN", strcomb(mean_bank_str));
406  db_find_key(hDB, 0, "/Equipment/SlowControl/Variables/MEAN", &hKey);
407  if (db_open_record(hDB, hKey, &mean, sizeof(mean), MODE_READ, NULL, NULL) != DB_SUCCESS) {
408  cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/SlowControl/Variables/MEAN\" tree in ODB");
409  return 0;
410  }
411 
412  //----------------------------------------------------------------------
413  // reset SRAT bank
414  //----------------------------------------------------------------------
415 
416  if ( db_find_key(hDB, 0, "/Equipment/Scaler/Variables/SRAT", &hKey) == DB_SUCCESS ) {
417  memset(&srat_bank, 0, sizeof(srat_bank));
418  db_set_record(hDB, hKey, &srat_bank, sizeof(srat_bank), 0);
419  }
420 
421  //---------------------------------------------------------------------
422  //
423  // change filenames to lem%02d_%04d where %02d is replaced by the year
424  // modulo 100 (2001 becomes 01, for example).
425  //
426  // File names are presently in odb keys
427  //
428  // /Analyzer/Output/Filename ascii dump ??
429  // /Analyzer/Output/Histo Dump Filename hsn file
430  // /Lazy/Tape0/Settings/Filename format for tape backup of mid,odb,hsn,summ,rz files
431  // /Lazy/Tape1/Settings/Filename format - " -
432  // /Logger/ODB Dump file odb file
433  // /Logger/Channels/0/Settings/Filename mid file
434  //
435  // summ and rz files are generated in programs ../util/write_summary.c and
436  // ../util/data2ntp.c. Filenames to be changed there.
437  //---------------------------------------------------------------------
438 
439  if ( runinfo.online_mode == 1) {
440  time(&now);
441  tms = localtime(&now);
442 
443  sprintf(str, "/%s/Output/Filename", analyzer_name);
444  size = sizeof(fname);
445  /* check if entry exists, if yes, change */
446  if ( db_get_value(hDB, 0, str, fname, &size, TID_STRING, TRUE) == DB_SUCCESS ) {
447  sprintf(fname, "lem%02d_%%04d.asc", tms->tm_year%100);
448  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
449  }
450 
451  sprintf(str, "/%s/Output/Histo Dump Filename", analyzer_name);
452  size = sizeof(fname);
453 
454 #ifdef HAVE_HBOOK
455  if ( db_get_value(hDB, 0, str, fname, &size, TID_STRING, TRUE) == DB_SUCCESS ) {
456  // tms->tm_year yield "Year - 1900"
457  sprintf(fname, "../his/%04d/lem%02d_%%04d.hsn", tms->tm_year+1900, tms->tm_year%100);
458  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
459  }
460 #else
461  if ( db_get_value(hDB, 0, str, fname, &size, TID_STRING, TRUE) == DB_SUCCESS ) {
462  sprintf(fname, "../his/%04d/lem%02d_his_%%04d.root", tms->tm_year+1900, tms->tm_year%100);
463  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
464  }
465 #endif
466 
467  // Overwrite logger defaults for data directories and
468  // file names.
469  sprintf(str, "/Logger/Data dir");
470  size = sizeof(fname);
471  if ( db_get_value(hDB, 0, str, fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
472  sprintf(fname, "/data/%s/dlog", exp_name);
473  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
474  }
475 
476  sprintf(str, "/Logger/Message file");
477  size = sizeof(fname);
478  if ( db_get_value(hDB, 0, str, fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
479  sprintf(fname, "/data/%s/midas.log", exp_name);
480  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
481  }
482 
483  sprintf(str, "/Logger/ODB Dump File");
484  size = sizeof(fname);
485  if ( db_get_value(hDB, 0, str, fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
486  sprintf(fname, "/data/%s/odb/%04d/lem%02d_%%04d.odb", exp_name, tms->tm_year+1900, tms->tm_year%100);
487  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
488  }
489 
490  sprintf(str, "/Logger/Channels/0/Settings/Filename");
491  size = sizeof(fname);
492  if ( db_get_value(hDB, 0, str, fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
493  sprintf(fname, "lem%02d_%%04d.root", tms->tm_year%100);
494  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
495  }
496 
497  sprintf(str, "/Logger/History Dir");
498  sprintf(fname, "/data/%s/history", exp_name);
499  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
500 
501  sprintf(str, "/Logger/History Path");
502  sprintf(fname, "");
503  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
504 
505  sprintf(str, "/Logger/Elog Dir");
506  //sprintf(fname, "/home/%s/elog/LEM_Experiment", exp_name);
507  sprintf(fname, "/home/nemu/elog/LEM_Experiment");
508  db_set_value(hDB, 0, str, &fname, sizeof(fname), 1, TID_STRING);
509 
510 // for lazylogger, use filesize of 128 to agree with string lengths there
511  sprintf(str, "/Lazy/FTP/Settings/Filename format");
512  size = sizeof(lazy_fname);
513  if ( db_get_value(hDB, 0, str, lazy_fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
514  sprintf(lazy_fname, "lem%02d_%%04d.root", tms->tm_year%100);
515  db_set_value(hDB, 0, str, &lazy_fname, size, 1, TID_STRING);
516  }
517  /*
518  sprintf(str, "/Lazy/Tape0/Settings/Filename format");
519  size = sizeof(lazy_fname);
520  if ( db_get_value(hDB, 0, str, lazy_fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
521  sprintf(lazy_fname, "lem%02d_%%04d", tms->tm_year%100);
522  db_set_value(hDB, 0, str, &lazy_fname, size, 1, TID_STRING);
523  }
524  sprintf(str, "/Lazy/Tape0/Settings/HisFilename format");
525  size = sizeof(lazy_fname);
526  if ( db_get_value(hDB, 0, str, lazy_fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
527  sprintf(lazy_fname, "lem%02d_his_%%04d", tms->tm_year%100);
528  db_set_value(hDB, 0, str, &lazy_fname, size, 1, TID_STRING);
529  }
530 
531  sprintf(str, "/Lazy/Tape1/Settings/Filename format");
532  size = sizeof(lazy_fname);
533  if ( db_get_value(hDB, 0, str, lazy_fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
534  sprintf(lazy_fname, "lem%02d_%%04d", tms->tm_year%100);
535  db_set_value(hDB, 0, str, &lazy_fname, size, 1, TID_STRING);
536  }
537  sprintf(str, "/Lazy/Tape1/Settings/HisFilename format");
538  size = sizeof(lazy_fname);
539  if ( db_get_value(hDB, 0, str, lazy_fname, &size, TID_STRING, FALSE) == DB_SUCCESS ) {
540  sprintf(lazy_fname, "lem%02d_his_%%04d", tms->tm_year%100);
541  db_set_value(hDB, 0, str, &lazy_fname, size, 1, TID_STRING);
542  }
543  */
544  } /* if (runinfo.online_mode == 1) */
545 
546  // to create Run Name in histograms in analyzer modules
547  sprintf(str, "/%s/Output/Filename", analyzer_name);
548  size = sizeof(fname);
549  db_get_value(hDB, 0, str, fname, &size, TID_STRING, TRUE);
550  strcpy(runname, fname);
551  runname[5] = 0; // truncate run number and extension
552 
553  timestr[0] = 0;
554  sprintf(timestr, "%s", ctime(&now));
555  timestr[24] = 0; // delete new line \n
556  db_set_value(hDB, 0, "/Info/Scaler Update time", &timestr, sizeof(timestr), 1, TID_STRING);
557 
558  // update energy loss, implantation energy etc. in /Info structure
559  update_info();
560 
561  // root file header related things
562  gRunHeader = gROOT->GetRootFolder()->AddFolder("RunHeader", "LEM Run Header Info");
563  gROOT->GetListOfBrowsables()->Add(gRunHeader, "RunHeader");
564 //as header = new TLemRunHeader();
565  header = new TMusrRunHeader(true);
566  header->FillFolder(gRunHeader);
567 //as gRunHeader->Add(header); //add header to RunInfo folder
568  gRunHeader->Add(&Slist);
569  Slist.SetName("RunSummary");
570 
572  write_flag = 1;
573 
574  // Register callback for messages to allow for SMS/E-Mail send in case of an Alarm
575  // cm_msg_register(receive_message);
576 
577  return SUCCESS;
578 }
579 
580 //-- Analyzer Exit -------------------------------------------------
581 
583 {
584  return CM_SUCCESS;
585 }
586 
587 //-- Begin of Run --------------------------------------------------
588 
589 INT ana_begin_of_run(INT run_number, char *error)
590 {
591  HNDLE hDB, hkey;
592 
593  cm_get_experiment_database(&hDB, NULL);
594 
595  //----------------------------------------------------------------------
596  // reset SRAT bank
597  //----------------------------------------------------------------------
598 
599  if ( db_find_key(hDB, 0, "/Equipment/Scaler/Variables/SRAT", &hkey) == DB_SUCCESS ) {
600  memset(&srat_bank, 0, sizeof(srat_bank));
601  db_set_record(hDB, hkey, &srat_bank, sizeof(srat_bank), 0);
602  }
603 
604  //-- display scaler in analyzer window when running online -------------
605  if ( runinfo.online_mode == 1) {
606 
607  /*
608  a bit strange: runinfo.state is still STATE_STOPPED when arriving here,
609  although other ODB parameters like run number and Start time are already
610  set properly for Run start; problem could be that the change of the ODB value
611  for
612  runinfo.state is done at the end of the cm_transition() function, maybe
613  too late for analyzer programs which already reads the runinfo.state value.
614  To avoid this problem I force runinfo.state to have the right value for
615  the analyzer/scaler functions.
616  */
617  runinfo.state = STATE_RUNNING;
619  }
620 
621  versionCounter = 0;
622 
623  // update Run header
624  update_info();
626 
627  write_flag = 1;
628  sum_count = 0;
629 
630  // check if beam shutter is open; if not send a warning to the MIDAS alarm system
631  if (beam_shutter_open(hDB) == 0)
632  al_trigger_alarm( "ana_begin_of_run", "Beam Shutters KV61/62 still closed at begin-of-run!",
633  "Warning", "BeamLine Shutters KV61/62 still closed at BOR!", AT_INTERNAL);
634 
635  return CM_SUCCESS;
636 }
637 
638 //-- End of Run ----------------------------------------------------
639 
640 INT ana_end_of_run(INT run_number, char *error)
641 {
642  FILE *f;
643  time_t now;
644  char str[256], logdir[256], cmd[256], file_name[256];
645  char year[5];
646  INT size, len, status;
647  double n;
648  HNDLE hDB, hkey;
649  BOOL flag;
650 
651  cm_get_experiment_database(&hDB, NULL);
652 
653  // update run log if run was written and running online
654  size = sizeof(flag);
655  db_get_value(hDB, 0, "/Logger/Write data", &flag, &size, TID_BOOL, FALSE);
656  if (flag && runinfo.online_mode == 1) {
657  // update run log
658  size = sizeof(str);
659  str[0] = 0;
660  file_name[0] = 0;
661  year[0] = 0;
662  db_get_value(hDB, 0, "/Logger/Data Dir", str, &size, TID_STRING, FALSE);
663  if (str[0] != 0)
664  if (str[strlen(str)-1] != DIR_SEPARATOR)
665  strcat(str, DIR_SEPARATOR_STR);
666  strcpy(logdir, str); /* save copy of logger dir */
667  strcat(str, "runlog.txt");
668  strcpy(file_name, str);
669  f = fopen(file_name, "a");
670 
671  time(&now);
672  strcpy(str, ctime(&now));
673  year[0] = str[20];
674  year[1] = str[21];
675  year[2] = str[22];
676  year[3] = str[23];
677  year[4] = 0;
678  str[10] = 0;
679 
680  fprintf(f, "%5d\t%s %s", runinfo.run_number, str, year);
681 
682  strcpy(str, runinfo.start_time);
683  str[19] = 0;
684  fprintf(f, "::%s --- ", str+11);
685 
686  strcpy(str, ctime(&now));
687  str[19] = 0;
688  fprintf(f, "%s\t", str+11);
689 
690  size = sizeof(n);
691  db_get_value(hDB, 0, "/Equipment/Trigger/Statistics/Events sent", &n, &size, TID_DOUBLE, FALSE);
692 
693  fprintf(f, "%6.1lfk\t", n/1000);
694  fprintf(f, "%s --- ", exp_param.comment);
695 
696  fprintf(f, "PN: %d\n", info.file_header_info.proposal_number);
697 
698  fclose(f);
699 
700  runinfo.state = STATE_STOPPED;
701  runinfo.stop_time_binary = now;
702  strcpy(runinfo.stop_time, ctime(&now));
703 
704  // delete \n in runinfo.stop_time if present
705  len = strlen(runinfo.stop_time);
706  if (runinfo.stop_time[len-1] == '\n' )
707  runinfo.stop_time[len-1] = 0;
708 
709  //-------- update ODB ----------------------
710  //
711  // also a bit strange here: the ODB dump does not contain the correct Stop time
712  // of a run; it appears to be written too late to the ODB, i.e. a f t e r saving
713  // the ODB.
714  // I force setting the right values to ODB here in analyzer.
715  //------------------------------------------
716 
717  db_set_value(hDB, 0, "/Runinfo/State", &runinfo.state, sizeof(runinfo.state), 1, TID_INT);
718  db_set_value(hDB, 0, "/Runinfo/Stop time", &runinfo.stop_time,
719  sizeof(runinfo.stop_time), 1, TID_STRING);
720  db_set_value(hDB, 0, "/Runinfo/Stop time binary", &runinfo.stop_time_binary,
721  sizeof(runinfo.stop_time_binary), 1, TID_DWORD);
722 
724  ss_printf(0,50,"Rates at EOR are a v e r a g e d rates !");
725  }
726 
727  // update run header
728  update_info();
730 
731  return CM_SUCCESS;
732 }
733 
734 //-- Pause Run -----------------------------------------------------
735 
736 INT ana_pause_run(INT run_number, char *error)
737 {
738  runinfo.state = STATE_PAUSED;
740  return CM_SUCCESS;
741 }
742 
743 //-- Resume Run ----------------------------------------------------
744 
745 INT ana_resume_run(INT run_number, char *error)
746 {
747  HNDLE hDB;
748 
749  cm_get_experiment_database(&hDB, NULL);
750 
751  // check if beam shutter is open; if not send a warning to the MIDAS alarm system
752  if (beam_shutter_open(hDB) == 0)
753  al_trigger_alarm( "ana_begin_of_run", "Beam Shutters KV61/62 still closed at run resume!",
754  "Warning", "BeamLine Shutters KV61/62 still closed at run resume!", AT_INTERNAL);
755 
756  runinfo.state = STATE_RUNNING;
758  return CM_SUCCESS;
759 }
760 
761 //-- Analyzer Loop -------------------------------------------------
762 
764 {
765  DWORD nowtime, difftime;
766 
767  nowtime = ss_time();
768  difftime = nowtime - last_update_info_write;
769  if (difftime > UPDATE_INFO_PERIOD) {
770  update_info();
771  last_update_info_write = nowtime;
772  }
773 
774  if ( runinfo.state == STATE_PAUSED ) return CM_SUCCESS;
775 
776  if ( runinfo.state == STATE_RUNNING ) {
777  write_flag = 0;
778  difftime = nowtime - last_histogram_write;
779  if ( difftime > HISTOGRAM_WRITE_PERIOD ) {
782  last_histogram_write = nowtime;
783  if ( sum_count == 1 ) { // extract summary file when we reach this point
784  Slist.Delete();
785  extract_summary_data(); // the 2nd time
786  }
787  sum_count++;
788  }
789  }
790 
791  if ( runinfo.state == STATE_STOPPED && !write_flag ) {
792  ss_sleep(3000); // wait 3sec for final summary file
793  Slist.Delete();
796  write_flag = 1;
797  }
798 
799  return CM_SUCCESS;
800 }
801 
802 // ------------------------------------------------------------------
807 {
808  HNDLE hDB, hkey;
809  char fname[256], str[256], file_name[256], save_file_name[256], cmd[256];
810  INT size, status;
811 
812  cm_get_experiment_database(&hDB, NULL);
813  sprintf(str, "/%s/Output/Histo Dump Filename", analyzer_name);
814  size = sizeof(fname);
815  db_get_value(hDB, 0, str, fname, &size, TID_STRING, TRUE);
816 
817  if (strchr(fname, '%') != NULL)
818  sprintf(file_name, fname, runinfo.run_number);
819  else
820  strcpy(file_name, fname);
821 
822  db_find_key(hDB, 0, "/Logger/Data dir", &hkey);
823  if (hkey) {
824  size = sizeof(str);
825  db_get_data(hDB, hkey, str, &size, TID_STRING);
826  if (str[strlen(str) - 1] != DIR_SEPARATOR)
827  strcat(str, DIR_SEPARATOR_STR);
828  strcat(str, file_name);
829  strcpy(file_name, str);
830  }
831 
832  strcpy(save_file_name, file_name);
833  //
834  // before May-10, 2013: save histogram as lemYY_his_RunNr.V.root
835  //
836  // May-10, 2013: changed to lemYY_his_RunNr.root.V
837  //
838  // *strstr(file_name, ".root") = 0;
839  sprintf(str, ".%d", versionCounter);
840  strcat(file_name, str);
841  // strcat(file_name, ".root");
842  versionCounter++;
843 
844  // the following is adapted from SaveRootHistograms() in mana.c
845  TDirectory *savedir = gDirectory;
846  TFile *outf = new TFile(file_name, "RECREATE", "Midas Analyzer Histograms");
847  if (outf == 0) {
848  cm_msg(MERROR, "SaveRootHistograms", "Cannot create output file %s", file_name);
849  return 0;
850  }
851  outf->cd();
852  gManaHistosFolder->Write();
853  if (header->FillFolder(gRunHeader))
854  gRunHeader->Write();
855  else
856  cm_msg(MERROR, "write_histogram_file", "analyzer error: couldn't fill the run header information!");
857  outf->Close();
858  delete outf;
859  // restore current directory
860  savedir->cd();
861  //
862  // copy lemYY_his_RunNr.V.root to lemYY_his_RunNr.root
863  //
864  ss_sleep(1000);
865  status = gSystem->CopyFile(file_name, save_file_name, kTRUE);
866  if (status != 0) {
867  if (status == -1) {
868  cm_msg(MINFO, "analyzer", "**WARNING** cp in write histogram file failed. (file open failure of %s)", file_name);
869  } else if (status == -2) {
870  cm_msg(MINFO, "analyzer", "**WARNING** cp in write histogram file failed. (write protection error of %s)", save_file_name);
871  } else if (status == -3) {
872  cm_msg(MINFO, "analyzer", "**WARNING** cp in write histogram file failed. (error during copying (%s->%s))", file_name, save_file_name);
873  }
874  }
875 
876  //cm_msg(MINFO, "analyzer_loop", "saved histograms in %s", file_name);
877 
878  return CM_SUCCESS;
879 }
880 
881 //-----------------------------------------------------------------
887 void get_sum_filename(char *filename)
888 {
889  struct tm *tms;
890  time_t now;
891  char dir[256], filebody[256];
892 
893  dir[0] = 0;
894  filebody[0] = 0;
895 
896  if ( getenv("MIDAS_DATA") ) {
897  strcpy(dir, getenv("MIDAS_DATA"));
898  strcat(dir, DIR_SEPARATOR_STR);
899  strcat(dir, "summ");
900  strcat(dir, DIR_SEPARATOR_STR);
901  } else {
902 #if defined (OS_UNIX)
903  strcpy(dir, getenv("HOME"));
904 #elif defined (OS_WINNT)
905  strcpy(dir, getenv("HOMEPATH"));
906 #endif
907  strcat(dir, DIR_SEPARATOR_STR);
908  cm_msg(MINFO, "get_sum_filename",
909  "MIDAS_DATA path not defined, use home directory %s instead\n", dir);
910  }
911 
912  time(&now);
913  tms = localtime(&now);
914  // tms->tm_year yields "Year - 1900"
915  strcpy(filename, dir);
916  sprintf(filebody, "%04d/lem%02d_%04d.summ", tms->tm_year+1900, tms->tm_year%100, runinfo.run_number);
917  strcat(filename, filebody);
918 }
919 
920 //-----------------------------------------------------------------
925 {
926  INT i;
927  char fileName[256], line[256], enumline[256];
928  TObjString *s;
929 
930  get_sum_filename(fileName);
931 
932  i = 0;
933  FILE *fp = fopen(fileName,"r");
934  if ( fp == NULL ) {
935  printf("File %s does not exist!\n", fileName);
936  return;
937  }
938 
939  while (fgets(line,256,fp)) {
940  sprintf(enumline, "%04d ", i);
941  strcat(enumline, line);
942  s = new TObjString(enumline);
943  Slist.Add(s);
944  i++;
945  }
946 
947  fclose(fp);
948 }
949 
950 //-----------------------------------------------------------------
961 float energy_loss( float moderator_hv)
962 {
963  float deltaE, x, p0, p1, p2, p3;
964 
965  if ( moderator_hv > 20.1 ) {
966  deltaE = 0.23;
967  } else {
972  x = moderator_hv;
973  deltaE = p0 + p1*x + p2*x*x + p3*x*x*x;
974  }
975 
976  return deltaE;
977 }
978 
979 //-----------------------------------------------------------------
987 float get_magnetic_field(float current)
988 {
989  float Bfield, x, p0, p1;
990 
992  p0 = info.magnet_parameter.wew[0];
993  p1 = info.magnet_parameter.wew[1];
994  } else if (info.lem_setup_parameter.bpar) {
995  p0 = info.magnet_parameter.bpar[0];
996  p1 = info.magnet_parameter.bpar[1];
997  } else if (info.lem_setup_parameter.helmholtz) {
1000  } else {
1001  p0 = 0.;
1002  p1 = 0.;
1003  }
1004 
1005  Bfield = p0 + p1*current;
1006 
1007  return Bfield;
1008 }
1009 
1010 //-----------------------------------------------------------------
1015 {
1016  HNDLE hDB, hKey, hSubKey;
1017  INT i, size, result;
1018  float eloss, impEnergy, modHV, sampleHV, current, Bfield;
1019  char lem_setup[STR_SIZE], lem_cryostat[NAME_LENGTH], old_lem_cryostat[NAME_LENGTH];
1020  KEY cryoKey;
1021  BOOL flag, cryo_not_found;
1022 // INTEL_LOG info; // for lem01
1023  IPMI_LOG info; // for lem00
1024 
1025  cm_get_experiment_database(&hDB, NULL);
1026 
1027  // update energy loss and implantation energy
1030  eloss = energy_loss( modHV);
1031  impEnergy = modHV - eloss - sampleHV;
1032  db_set_value(hDB, 0, "/Info/Energy Loss (C-foil)", &eloss, sizeof(eloss), 1, TID_FLOAT);
1033  db_set_value(hDB, 0, "/Info/Implantation Energy (keV)", &impEnergy, sizeof(impEnergy), 1, TID_FLOAT);
1034 
1035  // update B-field, get current from zero flux (Danfyisk of Bruker supply) or from Bruker (I>500A)
1036  // current = scs900_event.input[sc_ana_param.sample_zeroflux_channel];
1037  // this needs to be modified for the new power supply.
1039  if (current < 9.9) // max. output of zero flux meter is 10V = 500A
1040  current = current/10. * 500.; // 10V Zero Flux voltage corresponds to 500A
1041  else { // we have a current >500A, which ZeroFlux can't display anymore;
1042  size = sizeof(float); // get current directly from Bruker in this case
1043  db_get_value(hDB, 0, "/Equipment/Bruker/Variables/Input[3]", &current, &size, TID_FLOAT, FALSE);
1044  }
1045 
1046  Bfield = get_magnetic_field(current);
1047  db_set_value(hDB, 0, "/Info/Magnetic Field (G)", &Bfield, sizeof(Bfield), 1, TID_FLOAT);
1048 
1049  // update t0's
1050  // get_t0();
1051  get_t0L3RA();
1052 
1053  // for lem00
1054  result = read_ipmi_log(&info);
1055 
1056  if (result > 0) { // i.e. all entries found
1057  db_find_key(hDB, 0, "/Info/Lem00IPMILog", &hKey);
1058  db_set_record(hDB, hKey, &info, sizeof(info), 0);
1059  }
1060 /*
1061  // for lem01
1062  result = read_intel_log(&info);
1063  if (result == 43) {
1064  db_find_key(hDB, 0, "/Info/Lem00IntelLog", &hKey);
1065  db_set_record(hDB, hKey, &info, sizeof(info), 0);
1066  }
1067 */
1068 }
1069 
1070 //-----------------------------------------------------------------
1075 {
1076  HNDLE hDB, hKey;
1077  INT size, i, ival;
1078  vector<int> ivec;
1079  char lem_setup[STR_SIZE+NAME_LENGTH];
1080  char str[256], str1[256], str2[256], *p_str;
1081  double ip_sum, scaler_clock_sum, tdc_clock_sum, n_events, dval;
1082  double td_sum, td_clean_sum, td_good_sum, pos_sum[N_DECAY_HISTS];
1083  long time_bin;
1084 
1085  // get the main ODB handle
1086  cm_get_experiment_database(&hDB, NULL);
1087 
1088  sprintf(lem_setup, "%s, ", info.lem_setup);
1089  strcat(lem_setup, info.sample_cryo);
1090 
1091  //----------------------------
1092  // RunInfo (required)
1093  //----------------------------
1094 
1095  // 1st write all the required RunInfo entries
1096 
1097  header->Set("RunInfo/Generic Validator URL", "http://lmu.web.psi.ch/facilities/software/MusrRoot/validation/MusrRoot.xsd");
1098  header->Set("RunInfo/Specific Validator URL", "http://lmu.web.psi.ch/facilities/software/MusrRoot/validation/MusrRootLEM.xsd");
1099  header->Set("RunInfo/Generator", "nemu_analyzer");
1100 
1101  // write proposal number and PI info
1102  header->Set("RunInfo/Proposal Number", info.file_header_info.proposal_number);
1103  header->Set("RunInfo/Main Proposer", info.file_header_info.main_proposer);
1104 
1105  // compose the file name
1106  size = sizeof(str);
1107  db_find_key(hDB, 0, "/Analyzer/Output/Histo Dump Filename", &hKey);
1108  db_get_data(hDB, hKey, &str, &size, TID_STRING);
1109  // filter out the last part of the string spearted by "/", str should have the format <something>/lem<yy>_his_%04d.root
1110  i = 0;
1111  p_str = 0;
1112  do {
1113  if (str[i] == '/')
1114  p_str = &str[i];
1115  i++;
1116  } while (str[i] != '\0');
1117  if (p_str == 0) {
1118  cm_msg(MERROR, "update_run_header", "Couldn't obtain run file name template! ODB corrupted?");
1119  return;
1120  }
1121  p_str++;
1122  // replace "%04d" through the run number
1123  strcpy(str1, p_str);
1124  p_str = strstr(str1, "%");
1125  if (p_str == 0) {
1126  cm_msg(MERROR, "update_run_header", "Wrong run file name template! ODB corrupted?");
1127  return;
1128  }
1129  *p_str = '\0';
1130  sprintf(str, "%04d.root", runinfo.run_number);
1131  strcat(str1, str);
1132  header->Set("RunInfo/File Name", str1);
1133 
1134  header->Set("RunInfo/Run Title", exp_param.comment);
1135  header->Set("RunInfo/Run Number", runinfo.run_number);
1136 
1137  // handle start and stop time
1138  time_bin = (long)runinfo.start_time_binary; // for 64bit this conversion is needed
1139  struct tm *tm = localtime((time_t*)&time_bin);
1140  strftime(str, sizeof(str), "%F %T", tm);
1141  header->Set("RunInfo/Run Start Time", str);
1142  time_bin = (long)runinfo.stop_time_binary;
1143  tm = localtime((time_t*)&time_bin);
1144  strftime(str, sizeof(str), "%F %T", tm);
1145  header->Set("RunInfo/Run Stop Time", str);
1146  if (runinfo.stop_time_binary < runinfo.start_time_binary) // ongoing run
1147  ival = -1;
1148  else
1149  ival = (int)runinfo.stop_time_binary - (int)runinfo.start_time_binary;
1150 
1151  TMusrRunPhysicalQuantity prop;
1152  prop.Set("Run Duration", ival, "sec");
1153  header->Set("RunInfo/Run Duration", prop);
1154 
1155  header->Set("RunInfo/Laboratory", "PSI");
1156  header->Set("RunInfo/Instrument", "LEM");
1157 
1158  prop.Set("Muon Beam Momentum", 28.1, "MeV/c");
1159  header->Set("RunInfo/Muon Beam Momentum", prop);
1160 
1161  header->Set("RunInfo/Muon Species", "positive muon");
1162  header->Set("RunInfo/Muon Source", "Target E - Low Energy Muons");
1163  header->Set("RunInfo/Setup", lem_setup);
1164  header->Set("RunInfo/Comment", "n/a");
1165  header->Set("RunInfo/Sample Name", info.sample_name);
1166 
1167  prop.Set("Sample Temperature", MRH_UNDEFINED, mean.sample_t, mean.var_sample_t, "K");
1168  header->Set("RunInfo/Sample Temperature", prop);
1169  prop.Set("Sample Magnetic Field", MRH_UNDEFINED, mean.sample_b, mean.var_sample_b, "G");
1170  header->Set("RunInfo/Sample Magnetic Field", prop);
1171 
1172  header->Set("RunInfo/No of Histos", N_DECAY_HISTS);
1173 
1174  prop.Set("Time Resolution", 0.1953125, "ns", "TDC CAEN V1190");
1175  header->Set("RunInfo/Time Resolution", prop);
1176 
1177  ivec.push_back(0);
1178  ivec.push_back(N_OFFSET_PPC_HISTOGRAMS);
1179  ivec.push_back(N_OFFSET_ONOFF_HISTOGRAMS);
1181  header->Set("RunInfo/RedGreen Offsets", ivec);
1182 
1183  // 2nd write all the LEM specifiy RunInfo entries
1184 
1185  header->Set("RunInfo/Moderator", info.moderator);
1186  prop.Set("Moderator HV", MRH_UNDEFINED, mean.moderator_hv, mean.var_moderator_hv, "kV");
1187  header->Set("RunInfo/Moderator HV", prop);
1188  prop.Set("Sample HV", MRH_UNDEFINED, mean.sample_hv, mean.var_sample_hv, "kV");
1189  header->Set("RunInfo/Sample HV", prop);
1190  prop.Set("Implantation Energy", info.implantation_energy, "keV");
1191  header->Set("RunInfo/Implantation Energy", prop);
1192  prop.Set("Muon Spin Angle", info.spinrot_parameter.rotation_angle, "degree");
1193  header->Set("RunInfo/Muon Spin Angle", prop);
1194  header->Set("RunInfo/Cuts", "none");
1195 
1196  //----------------------------
1197  // DetectorInfo (required)
1198  //----------------------------
1199  // In the future, this part should probably being filled in a more abstract manner, especially if it comes to
1200  // real red/green mode experiments and histo fillings.
1201 
1202  // NPP's, EXT. OFF
1203  for (i=0; i<N_DECAY_HISTS; i++) {
1204  // Name
1205  sprintf(str, "DetectorInfo/Detector%03d", i+1);
1206  snprintf(str1, sizeof(str1), "%s/Name", str);
1207  sprintf(str2, "%s, EXT. OFF", decay_ana_param.histotitles.decaytitles.titles[i]);
1208  header->Set(str1, str2);
1209  // Histo Number
1210  snprintf(str1, sizeof(str1), "%s/Histo Number", str);
1211  header->Set(str1, i+1);
1212  // Histo Length
1213  snprintf(str1, sizeof(str1), "%s/Histo Length", str);
1214  header->Set(str1, decay_ana_param.histobinning.decaybin.histonbin[i]);
1215  // Time Zero Bin
1216  snprintf(str1, sizeof(str1), "%s/Time Zero Bin", str);
1217  dval = (double) info.t0_parameter.t0[i];
1218  header->Set(str1, dval);
1219  // First Good Bin
1220  snprintf(str1, sizeof(str1), "%s/First Good Bin", str);
1221  ival = (int) ceil(dval);
1222  header->Set(str1, ival);
1223  // Last Good Bin
1224  snprintf(str1, sizeof(str1), "%s/Last Good Bin", str);
1225  header->Set(str1, decay_ana_param.histobinning.decaybin.histonbin[i]-1);
1226  }
1227 
1228  // PPC's, EXT. OFF
1229  for (i=0; i<N_DECAY_HISTS; i++) {
1230  // Name
1231  sprintf(str, "DetectorInfo/Detector%03d", i+1+N_OFFSET_PPC_HISTOGRAMS);
1232  snprintf(str1, sizeof(str1), "%s/Name", str);
1233  sprintf(str2, "%s, EXT. OFF", decay_ana_param.histotitles.decaytitles.titles[i+N_DECAY_HISTS]);
1234  header->Set(str1, str2);
1235  // Histo Number
1236  snprintf(str1, sizeof(str1), "%s/Histo Number", str);
1237  header->Set(str1, i+1+N_OFFSET_PPC_HISTOGRAMS);
1238  // Histo Length
1239  snprintf(str1, sizeof(str1), "%s/Histo Length", str);
1240  header->Set(str1, decay_ana_param.histobinning.decaybin.histonbin[i+N_DECAY_HISTS]);
1241  // Time Zero Bin
1242  snprintf(str1, sizeof(str1), "%s/Time Zero Bin", str);
1243  dval = (double) info.t0_parameter.t0[i];
1244  header->Set(str1, dval);
1245  // First Good Bin
1246  snprintf(str1, sizeof(str1), "%s/First Good Bin", str);
1247  ival = (int) ceil(dval);
1248  header->Set(str1, ival);
1249  // Last Good Bin
1250  snprintf(str1, sizeof(str1), "%s/Last Good Bin", str);
1251  header->Set(str1, decay_ana_param.histobinning.decaybin.histonbin[i+N_DECAY_HISTS]-1);
1252  }
1253 
1254  // NPP's, EXT. ON
1255  for (i=0; i<N_DECAY_HISTS; i++) {
1256  // Name
1257  sprintf(str, "DetectorInfo/Detector%03d", i+1+N_OFFSET_ONOFF_HISTOGRAMS);
1258  snprintf(str1, sizeof(str1), "%s/Name", str);
1259  sprintf(str2, "%s, EXT. ON", decay_ana_param.histotitles.decaytitles.titles[i]);
1260  header->Set(str1, str2);
1261  // Histo Number
1262  snprintf(str1, sizeof(str1), "%s/Histo Number", str);
1263  header->Set(str1, i+1);
1264  // Histo Length
1265  snprintf(str1, sizeof(str1), "%s/Histo Length", str);
1266  header->Set(str1, decay_ana_param.histobinning.decaybin.histonbin[i]);
1267  // Time Zero Bin
1268  snprintf(str1, sizeof(str1), "%s/Time Zero Bin", str);
1269  dval = (double) info.t0_parameter.t0[i];
1270  header->Set(str1, dval);
1271  // First Good Bin
1272  snprintf(str1, sizeof(str1), "%s/First Good Bin", str);
1273  ival = (int) ceil(dval);
1274  header->Set(str1, ival);
1275  // Last Good Bin
1276  snprintf(str1, sizeof(str1), "%s/Last Good Bin", str);
1277  header->Set(str1, decay_ana_param.histobinning.decaybin.histonbin[i]-1);
1278  }
1279 
1280  // PPC's, EXT. ON
1281  for (i=0; i<N_DECAY_HISTS; i++) {
1282  // Name
1283  sprintf(str, "DetectorInfo/Detector%03d", i+1+N_OFFSET_PPC_HISTOGRAMS+N_OFFSET_ONOFF_HISTOGRAMS);
1284  snprintf(str1, sizeof(str1), "%s/Name", str);
1285  sprintf(str2, "%s, EXT. ON", decay_ana_param.histotitles.decaytitles.titles[i+N_DECAY_HISTS]);
1286  header->Set(str1, str2);
1287  // Histo Number
1288  snprintf(str1, sizeof(str1), "%s/Histo Number", str);
1289  header->Set(str1, i+1+N_OFFSET_PPC_HISTOGRAMS);
1290  // Histo Length
1291  snprintf(str1, sizeof(str1), "%s/Histo Length", str);
1292  header->Set(str1, decay_ana_param.histobinning.decaybin.histonbin[i+N_DECAY_HISTS]);
1293  // Time Zero Bin
1294  snprintf(str1, sizeof(str1), "%s/Time Zero Bin", str);
1295  dval = (double) info.t0_parameter.t0[i];
1296  header->Set(str1, dval);
1297  // First Good Bin
1298  snprintf(str1, sizeof(str1), "%s/First Good Bin", str);
1299  ival = (int) ceil(dval);
1300  header->Set(str1, ival);
1301  // Last Good Bin
1302  snprintf(str1, sizeof(str1), "%s/Last Good Bin", str);
1303  header->Set(str1, decay_ana_param.histobinning.decaybin.histonbin[i+N_DECAY_HISTS]-1);
1304  }
1305 
1306 
1307  //-----------------------------------
1308  // SampleEnvironmentInfo (required)
1309  //-----------------------------------
1310 
1311  // 1st required entries for SampleEnvironmentInfo
1312 
1313  header->Set("SampleEnvironmentInfo/Cryo", info.sample_cryo);
1314 
1315  // 2nd LEM specific entries for SampleEnvironmentInfo
1316 
1317  // nothing to be set yet
1318 
1319 
1320  //-----------------------------------------
1321  // MagneticFieldEnvironmentInfo (required)
1322  //-----------------------------------------
1323 
1324  // 1st required entries for MagneticFieldEnvironmentInfo
1325 
1326  header->Set("MagneticFieldEnvironmentInfo/Magnet Name", info.lem_setup);
1327 
1328  // 2nd LEM specific entries for MagneticFieldEnvironmentInfo
1329 
1330  // nothing to be set yet
1331 
1332  //----------------------------
1333  // BeamlineInfo (required)
1334  //----------------------------
1335 
1336  // 1st required entries for BeamlineInfo
1337 
1338  header->Set("BeamlineInfo/Name", "muE4");
1339 
1340  // 2nd LEM specific entries for MagneticFieldEnvironmentInfo
1341 
1342  header->Set("BeamlineInfo/Beamline Settings", info.beamline_settings);
1343 
1344  //---------------------------------------------
1345  // ScalerInfo (NOT required, i.e LEM specific)
1346  //--------------------------------------------
1347 
1348  size = sizeof(double);
1349  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[0]", &ip_sum, &size, TID_DOUBLE, FALSE);
1350  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[1]", &scaler_clock_sum, &size, TID_DOUBLE, FALSE);
1351  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[4]", &td_sum, &size, TID_DOUBLE, FALSE);
1352  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[40]", &pos_sum[0], &size, TID_DOUBLE, FALSE);
1353  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[41]", &pos_sum[1], &size, TID_DOUBLE, FALSE);
1354  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[42]", &pos_sum[2], &size, TID_DOUBLE, FALSE);
1355  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[43]", &pos_sum[3], &size, TID_DOUBLE, FALSE);
1356  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[44]", &pos_sum[4], &size, TID_DOUBLE, FALSE);
1357  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[45]", &pos_sum[5], &size, TID_DOUBLE, FALSE);
1358  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[46]", &pos_sum[6], &size, TID_DOUBLE, FALSE);
1359  db_get_value(hDB, 0, "/Equipment/Scaler/Variables/SSUM[47]", &pos_sum[7], &size, TID_DOUBLE, FALSE);
1360  db_get_value(hDB, 0, "/Equipment/Trigger/VME_Statistics/TD clean", &td_clean_sum, &size, TID_DOUBLE, FALSE);
1361  db_get_value(hDB, 0, "/Equipment/Trigger/VME_Statistics/TD good" , &td_good_sum, &size, TID_DOUBLE, FALSE);
1362  db_get_value(hDB, 0, "/Equipment/Trigger/VME_Statistics/channelCounts[1]" , &tdc_clock_sum, &size, TID_DOUBLE, FALSE);
1363  db_get_value(hDB, 0, "/Equipment/Trigger/VME_Statistics/SlowMuonEvents" , &n_events, &size, TID_DOUBLE, FALSE);
1364 
1365  header->Set("ScalerInfo/Sum Ip", ip_sum);
1366  header->Set("ScalerInfo/Sum Clock (Scaler)", scaler_clock_sum);
1367  header->Set("ScalerInfo/Sum Clock (TDC)", tdc_clock_sum);
1368  header->Set("ScalerInfo/Sum Slow Muon Events", n_events);
1369  header->Set("ScalerInfo/Sum TD", td_sum);
1370  header->Set("ScalerInfo/Sum TD_Clean", td_clean_sum);
1371  header->Set("ScalerInfo/Sum TD_Good", td_good_sum);
1372 
1373  TIntVector posSumVec;
1374  for (unsigned int i=0; i<8; i++)
1375  posSumVec.push_back((int)pos_sum[i]);
1376  header->Set("ScalerInfo/Sum Positrons", posSumVec);
1377 }
1378 
1379 //-----------------------------------------------------------------
1396 void get_t0()
1397 {
1398  HNDLE hDB, hKey;
1399  INT t0[N_DECAY_HISTS];
1400  INT size, i;
1401  float moderator_hv, energy_after_TD_XXkV;
1402  float tofXXkV, muon_mass, c_light, l_eff, scale;
1403 
1404  moderator_hv = hv_event.demand[sc_ana_param.mod_hv_channel];
1405 
1406  if (moderator_hv < 5.0)
1407  return;
1408 
1409  energy_after_TD_XXkV = moderator_hv - energy_loss(moderator_hv);
1410 
1411  muon_mass = 105658.370; // keV
1412  c_light = 299.792458; // speed of light, mm/ns
1413 
1414  //check, if WEW is installed and if WEW field is <> 130G; RA is off for B>130G
1415  if ((strstr(info.lem_setup, "WEW") != NULL && fabs(info.magnetic_field) < 130.) ||
1416  strstr(info.lem_setup, "Bpar") != NULL)
1417  l_eff = info.t0_parameter.leff_RAon;
1418  else
1419  l_eff = info.t0_parameter.leff_RAoff;
1420 
1421  scale = l_eff/c_light*sqrt(muon_mass/2.);
1422 
1423  tofXXkV = scale/sqrt(energy_after_TD_XXkV);
1424 
1425  tofXXkV = tofXXkV/0.1953125; //offset in TDC channels
1426 
1427  for (i=0; i<N_DECAY_HISTS; i++)
1428  t0[i] = info.t0_parameter.t0Hist[i] + (int) roundf(tofXXkV);
1429 
1430  cm_get_experiment_database(&hDB, NULL);
1431  db_find_key(hDB, 0, "/Info/t0_parameter/t0", &hKey);
1432  db_set_record(hDB, hKey, &t0, sizeof(t0), 0);
1433 }
1434 
1435 //-----------------------------------------------------------------
1499 {
1500  HNDLE hDB, hKey;
1501  INT t0[N_DECAY_HISTS];
1502  INT size, i;
1503  float moderatorHV, energyAfterTD;
1504  float tofXXkV, muonMass, cLight;
1505  float dTotal, dFree, dL3, dRA;
1506  float tofFree, tofL3, tofRA;
1507  float scaleL3, scaleRA;
1508  float UL3, URA;
1509 
1511 
1512  if (moderatorHV < 5.0)
1513  return;
1514 
1515  energyAfterTD = moderatorHV - energy_loss(moderatorHV);
1516  muonMass = 105658.37; // keV
1517  cLight = 299.792458; // speed of light, mm/ns
1518 
1524  URA = 0.25*URA;
1525 
1526  dTotal = tdsampletof_param.dtotalp0 + tdsampletof_param.dtotalp1*moderatorHV;
1527  dL3 = tdsampletof_param.dl3;
1528  dRA = tdsampletof_param.dra;
1529  dFree = dTotal - dL3 - dRA;
1530  scaleL3 = tdsampletof_param.scalel3p0 + tdsampletof_param.scalel3p1*moderatorHV;
1531  scaleRA = tdsampletof_param.scalerap0 + tdsampletof_param.scalerap1*moderatorHV;
1532  UL3 = scaleL3 * UL3;
1533  URA = scaleRA * URA;
1534 
1535  if ( UL3 == 0. ) UL3 = 0.0001; //to avoid division by zero later
1536  if ( URA == 0. ) URA = 0.0001; //to avoid division by zero later
1537 
1538  //calculate tof's
1539  tofFree = dFree/sqrt(2.*energyAfterTD/muonMass)/cLight;
1540  if (UL3 <= energyAfterTD)
1541  tofL3 = dL3/UL3/cLight * sqrt(2.*muonMass*energyAfterTD) * (1. - sqrt(1.-UL3/energyAfterTD));
1542  else
1543  tofL3 = dL3/UL3/cLight * sqrt(2.*muonMass*energyAfterTD);
1544  if (URA <= energyAfterTD)
1545  tofRA = dRA/URA/cLight * sqrt(2.*muonMass*energyAfterTD) * (1. - sqrt(1.-URA/energyAfterTD));
1546  else
1547  tofRA = dRA/URA/cLight * sqrt(2.*muonMass*energyAfterTD);
1548 
1549  tofXXkV = tofFree + tofL3 + tofRA;
1550  tofXXkV = tofXXkV/0.1953125; //TOF in TDC channels
1551 
1552  for (i=0; i<N_DECAY_HISTS; i++)
1553  t0[i] = info.t0_parameter.t0Hist[i] + (int) roundf(tofXXkV);
1554 
1555  cm_get_experiment_database(&hDB, NULL);
1556  db_find_key(hDB, 0, "/Info/t0_parameter/t0", &hKey);
1557  db_set_record(hDB, hKey, &t0, sizeof(t0), 0);
1558 }
1559 
1560 /* ---------------------------------------------------------------------------
1561 void receive_message(HNDLE hBuf, HNDLE id, EVENT_HEADER * evHeader, void *message)
1562 /* *****************************************************************************\
1563 
1564  Name: receive_message
1565  Author: Thomas Prokscha
1566  Date: 05-May-2007
1567 
1568  Purpose: if enabled send SMS/E-mail to recipient specified in
1569  "/Info/Alarm Notification"
1570  /Info/Alarm Notification/Enabled y/n
1571  /Info/Alarm Notification/Recipients <Phone>@sms.switch.ch <EMail>@psi.ch...
1572 
1573  Method: template taken from Midas code mlxspeaker.c
1574 
1575 \* *****************************************************************************
1576 {
1577  char cmd[256], *pc, *sp;
1578  char dir[256], filename[256], hostname[256];
1579 
1580  dir[0] = cmd[0] = filename[0] = hostname[0] = 0;
1581 
1582  if ( !info.alarm_notification.enabled ) return;
1583 
1584  // skip none talking message
1585  if (evHeader->trigger_mask == MT_TALK || evHeader->trigger_mask == MT_USER) {
1586  pc = strchr((char *) (message), ']') + 2;
1587  sp = pc + strlen(pc) - 1;
1588  while (*sp == ' ' || *sp == '\t')
1589  sp--;
1590  *(++sp) = '\0';
1591 
1592  // create filename containing message to be sent
1593  if ( getenv("MIDAS_WORK") ) {
1594  strcpy(dir, getenv("MIDAS_WORK"));
1595  strcat(dir, DIR_SEPARATOR_STR);
1596  }
1597  else{
1598  strcpy(dir, getenv("HOME"));
1599  strcat(dir, DIR_SEPARATOR_STR);
1600  }
1601  strcpy(filename, dir);
1602  strcat(filename, "Nemu_AlarmMessage.dat");
1603 
1604  // create message to be sent
1605  strcpy(hostname, getenv("HOSTNAME"));
1606  FILE *fp = fopen(filename,"w");
1607  fprintf(fp, "Midas alarm detected for experiment Nemu on host %s.\n", hostname);
1608  fprintf(fp, "%s.\n", pc);
1609  fclose(fp);
1610 
1611  //create command to be sent by "mail"
1612  sprintf(cmd, "cat %s | mail -s \"Midas Alarm\" %s", filename, info.alarm_notification.recipients);
1613  system(cmd);
1614  }
1615  return;
1616 }
1617 */
1618 
1619 //---------------------------------------------------------------------------
1629 {
1630  FILE *fp;
1631  char line[128], *str_p;
1632  int status, ival;
1633  float fval;
1634  int lineNo=0;
1635  static DWORD last = 0;
1636  DWORD now;
1637 
1638  now = ss_time();
1639  if (now - last < UPDATE_INFO_PERIOD_INTEL) {
1640  return -1;
1641  }
1642 
1643  last = now; // keep current time stamp
1644 
1645  // init info structure
1646  info->cpu1_temp = -1.0;
1647  info->cpu2_temp = -1.0;
1648  info->system_temp = -1.0;
1649  info->peripherial_temp = -1.0;
1650  info->pch_temp = -1.0;
1651  info->p1_dimma1_temp = -1.0;
1652  info->p1_dimmb1_temp = -1.0;
1653  info->p2_dimme1_temp = -1.0;
1654  info->p2_dimmf1_temp = -1.0;
1655  info->fan1 = -1;
1656  info->fan2 = -1;
1657  info->fan3 = -1;
1658  info->fan5 = -1;
1659  info->fan6 = -1;
1660  info->vtt = -9999.0;
1661  info->cpu1_vcore = -9999.0;
1662  info->cpu2_vcore = -9999.0;
1663  info->vdimm_ab = -9999.0;
1664  info->vdimm_cd = -9999.0;
1665  info->vdimm_ef = -9999.0;
1666  info->vdimm_gh = -9999.0;
1667  info->p1_1v = -9999.0;
1668  info->p1_5v = -9999.0;
1669  info->p3_3v = -9999.0;
1670  info->p3_3vsb = -9999.0;
1671  info->p5v = -9999.0;
1672  info->p5vsb = -9999.0;
1673  info->p12v = -9999.0;
1674  info->vbat = -9999.0;
1675  info->chassis_intru = -1;
1676  info->ps1_status = -1;
1677  info->ps2_status = -1;
1678 
1679  fp = fopen("/var/log/lem00.psi.ch_ipmi.log", "r");
1680  if (fp == NULL) {
1681  printf("\nCouldn't open log file.\n");
1682  return -1;
1683  }
1684 
1685  while (!feof(fp)) {
1686  fgets(line, sizeof(line), fp);
1687  lineNo++;
1688 
1689  if (strstr(line, "CPU1 Temp")) {
1690  str_p = strstr(line, "|");
1691  if (str_p == NULL) { // couldn't find '|' within the line
1692  fclose(fp);
1693  return lineNo;
1694  }
1695  status = sscanf(str_p+1, "%f", &fval);
1696  if (status != 1) { // couldn't properly parse the line
1697  fclose(fp);
1698  return lineNo;
1699  }
1700  info->cpu1_temp = fval;
1701  } else if (strstr(line, "CPU2 Temp")) {
1702  str_p = strstr(line, "|");
1703  if (str_p == NULL) { // couldn't find '|' within the line
1704  fclose(fp);
1705  return lineNo;
1706  }
1707  status = sscanf(str_p+1, "%f", &fval);
1708  if (status != 1) { // couldn't properly parse the line
1709  fclose(fp);
1710  return lineNo;
1711  }
1712  info->cpu2_temp = fval;
1713  } else if (strstr(line, "System Temp")) {
1714  str_p = strstr(line, "|");
1715  if (str_p == NULL) { // couldn't find '|' within the line
1716  fclose(fp);
1717  return lineNo;
1718  }
1719  status = sscanf(str_p+1, "%f", &fval);
1720  if (status != 1) { // couldn't properly parse the line
1721  fclose(fp);
1722  return lineNo;
1723  }
1724  info->system_temp = fval;
1725  } else if (strstr(line, "Peripheral Temp")) {
1726  str_p = strstr(line, "|");
1727  if (str_p == NULL) { // couldn't find '|' within the line
1728  fclose(fp);
1729  return lineNo;
1730  }
1731  status = sscanf(str_p+1, "%f", &fval);
1732  if (status != 1) { // couldn't properly parse the line
1733  fclose(fp);
1734  return lineNo;
1735  }
1736  info->peripherial_temp = fval;
1737  } else if (strstr(line, "PCH Temp")) {
1738  str_p = strstr(line, "|");
1739  if (str_p == NULL) { // couldn't find '|' within the line
1740  fclose(fp);
1741  return lineNo;
1742  }
1743  status = sscanf(str_p+1, "%f", &fval);
1744  if (status != 1) { // couldn't properly parse the line
1745  fclose(fp);
1746  return lineNo;
1747  }
1748  info->pch_temp = fval;
1749  } else if (strstr(line, "P1-DIMMA1 TEMP")) {
1750  str_p = strstr(line, "|");
1751  if (str_p == NULL) { // couldn't find '|' within the line
1752  fclose(fp);
1753  return lineNo;
1754  }
1755  status = sscanf(str_p+1, "%f", &fval);
1756  if (status != 1) { // couldn't properly parse the line
1757  fclose(fp);
1758  return lineNo;
1759  }
1760  info->p1_dimma1_temp = fval;
1761  } else if (strstr(line, "P1-DIMMB1 TEMP")) {
1762  str_p = strstr(line, "|");
1763  if (str_p == NULL) { // couldn't find '|' within the line
1764  fclose(fp);
1765  return lineNo;
1766  }
1767  status = sscanf(str_p+1, "%f", &fval);
1768  if (status != 1) { // couldn't properly parse the line
1769  fclose(fp);
1770  return lineNo;
1771  }
1772  info->p1_dimmb1_temp = fval;
1773  } else if (strstr(line, "P2-DIMME1 TEMP")) {
1774  str_p = strstr(line, "|");
1775  if (str_p == NULL) { // couldn't find '|' within the line
1776  fclose(fp);
1777  return lineNo;
1778  }
1779  status = sscanf(str_p+1, "%f", &fval);
1780  if (status != 1) { // couldn't properly parse the line
1781  fclose(fp);
1782  return lineNo;
1783  }
1784  info->p2_dimme1_temp = fval;
1785  } else if (strstr(line, "P2-DIMMF1 TEMP")) {
1786  str_p = strstr(line, "|");
1787  if (str_p == NULL) { // couldn't find '|' within the line
1788  fclose(fp);
1789  return lineNo;
1790  }
1791  status = sscanf(str_p+1, "%f", &fval);
1792  if (status != 1) { // couldn't properly parse the line
1793  fclose(fp);
1794  return lineNo;
1795  }
1796  info->p2_dimmf1_temp = fval;
1797  } else if (strstr(line, "FAN1")) {
1798  str_p = strstr(line, "|");
1799  if (str_p == NULL) { // couldn't find '|' within the line
1800  fclose(fp);
1801  return lineNo;
1802  }
1803  status = sscanf(str_p+1, "%d", &ival);
1804  if (status != 1) { // couldn't properly parse the line
1805  fclose(fp);
1806  return lineNo;
1807  }
1808  info->fan1 = ival;
1809  } else if (strstr(line, "FAN2")) {
1810  str_p = strstr(line, "|");
1811  if (str_p == NULL) { // couldn't find '|' within the line
1812  fclose(fp);
1813  return lineNo;
1814  }
1815  status = sscanf(str_p+1, "%d", &ival);
1816  if (status != 1) { // couldn't properly parse the line
1817  fclose(fp);
1818  return lineNo;
1819  }
1820  info->fan2 = ival;
1821  } else if (strstr(line, "FAN3")) {
1822  str_p = strstr(line, "|");
1823  if (str_p == NULL) { // couldn't find '|' within the line
1824  fclose(fp);
1825  return lineNo;
1826  }
1827  status = sscanf(str_p+1, "%d", &ival);
1828  if (status != 1) { // couldn't properly parse the line
1829  fclose(fp);
1830  return lineNo;
1831  }
1832  info->fan3 = ival;
1833  } else if (strstr(line, "FAN5")) {
1834  str_p = strstr(line, "|");
1835  if (str_p == NULL) { // couldn't find '|' within the line
1836  fclose(fp);
1837  return lineNo;
1838  }
1839  status = sscanf(str_p+1, "%d", &ival);
1840  if (status != 1) { // couldn't properly parse the line
1841  fclose(fp);
1842  return lineNo;
1843  }
1844  info->fan5 = ival;
1845  } else if (strstr(line, "FAN6")) {
1846  str_p = strstr(line, "|");
1847  if (str_p == NULL) { // couldn't find '|' within the line
1848  fclose(fp);
1849  return lineNo;
1850  }
1851  status = sscanf(str_p+1, "%d", &ival);
1852  if (status != 1) { // couldn't properly parse the line
1853  fclose(fp);
1854  return lineNo;
1855  }
1856  info->fan6 = ival;
1857  } else if (strstr(line, "VTT")) {
1858  str_p = strstr(line, "|");
1859  if (str_p == NULL) { // couldn't find '|' within the line
1860  fclose(fp);
1861  return lineNo;
1862  }
1863  status = sscanf(str_p+1, "%f", &fval);
1864  if (status != 1) { // couldn't properly parse the line
1865  fclose(fp);
1866  return lineNo;
1867  }
1868  info->vtt = fval;
1869  } else if (strstr(line, "CPU1 Vcore")) {
1870  str_p = strstr(line, "|");
1871  if (str_p == NULL) { // couldn't find '|' within the line
1872  fclose(fp);
1873  return lineNo;
1874  }
1875  status = sscanf(str_p+1, "%f", &fval);
1876  if (status != 1) { // couldn't properly parse the line
1877  fclose(fp);
1878  return lineNo;
1879  }
1880  info->cpu1_vcore = fval;
1881  } else if (strstr(line, "CPU2 Vcore")) {
1882  str_p = strstr(line, "|");
1883  if (str_p == NULL) { // couldn't find '|' within the line
1884  fclose(fp);
1885  return lineNo;
1886  }
1887  status = sscanf(str_p+1, "%f", &fval);
1888  if (status != 1) { // couldn't properly parse the line
1889  fclose(fp);
1890  return lineNo;
1891  }
1892  info->cpu2_vcore = fval;
1893  } else if (strstr(line, "VDIMM AB")) {
1894  str_p = strstr(line, "|");
1895  if (str_p == NULL) { // couldn't find '|' within the line
1896  fclose(fp);
1897  return lineNo;
1898  }
1899  status = sscanf(str_p+1, "%f", &fval);
1900  if (status != 1) { // couldn't properly parse the line
1901  fclose(fp);
1902  return lineNo;
1903  }
1904  info->vdimm_ab = fval;
1905  } else if (strstr(line, "VDIMM CD")) {
1906  str_p = strstr(line, "|");
1907  if (str_p == NULL) { // couldn't find '|' within the line
1908  fclose(fp);
1909  return lineNo;
1910  }
1911  status = sscanf(str_p+1, "%f", &fval);
1912  if (status != 1) { // couldn't properly parse the line
1913  fclose(fp);
1914  return lineNo;
1915  }
1916  info->vdimm_cd = fval;
1917  } else if (strstr(line, "VDIMM EF")) {
1918  str_p = strstr(line, "|");
1919  if (str_p == NULL) { // couldn't find '|' within the line
1920  fclose(fp);
1921  return lineNo;
1922  }
1923  status = sscanf(str_p+1, "%f", &fval);
1924  if (status != 1) { // couldn't properly parse the line
1925  fclose(fp);
1926  return lineNo;
1927  }
1928  info->vdimm_ef = fval;
1929  } else if (strstr(line, "VDIMM GH")) {
1930  str_p = strstr(line, "|");
1931  if (str_p == NULL) { // couldn't find '|' within the line
1932  fclose(fp);
1933  return lineNo;
1934  }
1935  status = sscanf(str_p+1, "%f", &fval);
1936  if (status != 1) { // couldn't properly parse the line
1937  fclose(fp);
1938  return lineNo;
1939  }
1940  info->vdimm_gh = fval;
1941  } else if (strstr(line, "+1.1 V")) {
1942  str_p = strstr(line, "|");
1943  if (str_p == NULL) { // couldn't find '|' within the line
1944  fclose(fp);
1945  return lineNo;
1946  }
1947  status = sscanf(str_p+1, "%f", &fval);
1948  if (status != 1) { // couldn't properly parse the line
1949  fclose(fp);
1950  return lineNo;
1951  }
1952  info->p1_1v = fval;
1953  } else if (strstr(line, "+1.5 V")) {
1954  str_p = strstr(line, "|");
1955  if (str_p == NULL) { // couldn't find '|' within the line
1956  fclose(fp);
1957  return lineNo;
1958  }
1959  status = sscanf(str_p+1, "%f", &fval);
1960  if (status != 1) { // couldn't properly parse the line
1961  fclose(fp);
1962  return lineNo;
1963  }
1964  info->p1_5v = fval;
1965  } else if (strstr(line, "3.3V ")) {
1966  str_p = strstr(line, "|");
1967  if (str_p == NULL) { // couldn't find '|' within the line
1968  fclose(fp);
1969  return lineNo;
1970  }
1971  status = sscanf(str_p+1, "%f", &fval);
1972  if (status != 1) { // couldn't properly parse the line
1973  fclose(fp);
1974  return lineNo;
1975  }
1976  info->p3_3v = fval;
1977  } else if (strstr(line, "+3.3VSB")) {
1978  str_p = strstr(line, "|");
1979  if (str_p == NULL) { // couldn't find '|' within the line
1980  fclose(fp);
1981  return lineNo;
1982  }
1983  status = sscanf(str_p+1, "%f", &fval);
1984  if (status != 1) { // couldn't properly parse the line
1985  fclose(fp);
1986  return lineNo;
1987  }
1988  info->p3_3vsb = fval;
1989  } else if (strstr(line, "5V ")) {
1990  str_p = strstr(line, "|");
1991  if (str_p == NULL) { // couldn't find '|' within the line
1992  fclose(fp);
1993  return lineNo;
1994  }
1995  status = sscanf(str_p+1, "%f", &fval);
1996  if (status != 1) { // couldn't properly parse the line
1997  fclose(fp);
1998  return lineNo;
1999  }
2000  info->p5v = fval;
2001  } else if (strstr(line, "+5VSB")) {
2002  str_p = strstr(line, "|");
2003  if (str_p == NULL) { // couldn't find '|' within the line
2004  fclose(fp);
2005  return lineNo;
2006  }
2007  status = sscanf(str_p+1, "%f", &fval);
2008  if (status != 1) { // couldn't properly parse the line
2009  fclose(fp);
2010  return lineNo;
2011  }
2012  info->p5vsb = fval;
2013  } else if (strstr(line, "12V")) {
2014  str_p = strstr(line, "|");
2015  if (str_p == NULL) { // couldn't find '|' within the line
2016  fclose(fp);
2017  return lineNo;
2018  }
2019  status = sscanf(str_p+1, "%f", &fval);
2020  if (status != 1) { // couldn't properly parse the line
2021  fclose(fp);
2022  return lineNo;
2023  }
2024  info->p12v = fval;
2025  } else if (strstr(line, "VBAT")) {
2026  str_p = strstr(line, "|");
2027  if (str_p == NULL) { // couldn't find '|' within the line
2028  fclose(fp);
2029  return lineNo;
2030  }
2031  status = sscanf(str_p+1, "%f", &fval);
2032  if (status != 1) { // couldn't properly parse the line
2033  fclose(fp);
2034  return lineNo;
2035  }
2036  info->vbat = fval;
2037  } else if (strstr(line, "Chassis Intru")) {
2038  str_p = strstr(line, "|");
2039  if (str_p == NULL) { // couldn't find '|' within the line
2040  fclose(fp);
2041  return lineNo;
2042  }
2043  status = sscanf(str_p+1, "%d", &ival);
2044  if (status != 1) { // couldn't properly parse the line
2045  fclose(fp);
2046  return lineNo;
2047  }
2048  info->chassis_intru = ival;
2049  } else if (strstr(line, "PS1 Status")) {
2050  str_p = strstr(line, "|");
2051  if (str_p == NULL) { // couldn't find '|' within the line
2052  fclose(fp);
2053  return lineNo;
2054  }
2055  status = sscanf(str_p+1, "%x", &ival);
2056  if (status != 1) { // couldn't properly parse the line
2057  fclose(fp);
2058  return lineNo;
2059  }
2060  info->ps1_status = ival;
2061  } else if (strstr(line, "PS2 Status")) {
2062  str_p = strstr(line, "|");
2063  if (str_p == NULL) { // couldn't find '|' within the line
2064  fclose(fp);
2065  return lineNo;
2066  }
2067  status = sscanf(str_p+1, "%x", &ival);
2068  if (status != 1) { // couldn't properly parse the line
2069  fclose(fp);
2070  return lineNo;
2071  }
2072  info->ps2_status = ival;
2073  }
2074  }
2075 
2076  fclose(fp);
2077 
2078  return lineNo;
2079 }
2080 
2081 //---------------------------------------------------------------------------
2091 {
2092  FILE *fp;
2093  char line[128], *str_p, ok_string[32];
2094  int status, ival[4];
2095  float fval;
2096  int lineNo=0;
2097  static DWORD last = 0;
2098  DWORD now;
2099 
2100  now = ss_time();
2101  if (now - last < UPDATE_INFO_PERIOD_INTEL) {
2102  return 44; // no of lines would be 43 ;-)
2103  }
2104 
2105  last = now; // keep current time stamp
2106 
2107  fp = fopen("/var/Intel/logs/lem01_ipmi.log", "r");
2108  if (fp == NULL) {
2109  printf("\nCouldn't open log file.\n");
2110  return -1;
2111  }
2112 
2113  while (!feof(fp)) {
2114  fgets(line, sizeof(line), fp);
2115  if (line[0] == '0') {
2116  switch (lineNo) {
2117  case 0: // LAN Scrty
2118  str_p = strstr(line, "=");
2119  if (str_p == NULL) { // couldn't find '=' within the line
2120  fclose(fp);
2121  return lineNo;
2122  }
2123  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2124  if (status != 5) // couldn't properly parse the line
2125  return lineNo;
2126  if (!strcmp(ok_string, "OK")) {
2127  info->lan_scrty = 1;
2128  } else {
2129  info->lan_scrty = 0;
2130  }
2131  break;
2132  case 1: // Password
2133  str_p = strstr(line, "=");
2134  if (str_p == NULL) { // couldn't find '=' within the line
2135  fclose(fp);
2136  return lineNo;
2137  }
2138  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2139  if (status != 5) // couldn't properly parse the line
2140  return lineNo;
2141  if (!strcmp(ok_string, "OK")) {
2142  info->password = 1;
2143  } else {
2144  info->password = 0;
2145  }
2146  break;
2147  case 2: // PWRGOOD#
2148  str_p = strstr(line, "=");
2149  if (str_p == NULL) { // couldn't find '=' within the line
2150  fclose(fp);
2151  return lineNo;
2152  }
2153  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2154  if (status != 5) // couldn't properly parse the line
2155  return lineNo;
2156  if (!strcmp(ok_string, "OK")) {
2157  info->pwrgood = 1;
2158  } else {
2159  info->pwrgood = 0;
2160  }
2161  break;
2162  case 3: // Button
2163  str_p = strstr(line, "=");
2164  if (str_p == NULL) { // couldn't find '=' within the line
2165  fclose(fp);
2166  return lineNo;
2167  }
2168  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2169  if (status != 5) // couldn't properly parse the line
2170  return lineNo;
2171  if (!strcmp(ok_string, "OK")) {
2172  info->button = 1;
2173  } else {
2174  info->button = 0;
2175  }
2176  break;
2177  case 4: // Watchdog2
2178  str_p = strstr(line, "=");
2179  if (str_p == NULL) { // couldn't find '=' within the line
2180  fclose(fp);
2181  return lineNo;
2182  }
2183  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2184  if (status != 5) // couldn't properly parse the line
2185  return lineNo;
2186  if (!strcmp(ok_string, "OK")) {
2187  info->watchdog2 = 1;
2188  } else {
2189  info->watchdog2 = 0;
2190  }
2191  break;
2192  case 5: // SyS Boot Init
2193  str_p = strstr(line, "=");
2194  if (str_p == NULL) { // couldn't find '=' within the line
2195  fclose(fp);
2196  return lineNo;
2197  }
2198  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2199  if (status != 5) // couldn't properly parse the line
2200  return lineNo;
2201  if (!strcmp(ok_string, "OK")) {
2202  info->sys_boot_init = 1;
2203  } else {
2204  info->sys_boot_init = 0;
2205  }
2206  break;
2207  case 6: // Sys Evnt
2208  str_p = strstr(line, "=");
2209  if (str_p == NULL) { // couldn't find '=' within the line
2210  fclose(fp);
2211  return lineNo;
2212  }
2213  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2214  if (status != 5) // couldn't properly parse the line
2215  return lineNo;
2216  if (!strcmp(ok_string, "OK")) {
2217  info->sys_evnt = 1;
2218  } else {
2219  info->sys_evnt = 0;
2220  }
2221  break;
2222  case 7: // Pltfrm Evnt
2223  str_p = strstr(line, "=");
2224  if (str_p == NULL) { // couldn't find '=' within the line
2225  fclose(fp);
2226  return lineNo;
2227  }
2228  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2229  if (status != 5) // couldn't properly parse the line
2230  return lineNo;
2231  if (!strcmp(ok_string, "OK")) {
2232  info->pltfrm_evnt = 1;
2233  } else {
2234  info->pltfrm_evnt = 0;
2235  }
2236  break;
2237  case 9: // Chassis Intru.
2238  str_p = strstr(line, "=");
2239  if (str_p == NULL) { // couldn't find '=' within the line
2240  fclose(fp);
2241  return lineNo;
2242  }
2243  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2244  if (status != 5) // couldn't properly parse the line
2245  return lineNo;
2246  if (!strcmp(ok_string, "OK")) {
2247  info->chassis_intru = 1;
2248  } else {
2249  info->chassis_intru = 0;
2250  }
2251  break;
2252  case 10: // CPU1 12V
2253  str_p = strstr(line, "OK");
2254  if (str_p == NULL) { // couldn't find 'OK' within the line
2255  fclose(fp);
2256  return lineNo;
2257  }
2258  status = sscanf(str_p+2, "%f Volts", &fval);
2259  if (status != 1) // couldn't properly parse the line
2260  return lineNo;
2261  info->cpu1_12v = fval;
2262  break;
2263  case 11: // CPU2 12V
2264  str_p = strstr(line, "OK");
2265  if (str_p == NULL) { // couldn't find 'OK' within the line
2266  fclose(fp);
2267  return lineNo;
2268  }
2269  status = sscanf(str_p+2, "%f Volts", &fval);
2270  if (status != 1) // couldn't properly parse the line
2271  return lineNo;
2272  info->cpu2_12v = fval;
2273  break;
2274  case 12: // Baseboard 1.5V
2275  str_p = strstr(line, "OK");
2276  if (str_p == NULL) { // couldn't find 'OK' within the line
2277  fclose(fp);
2278  return lineNo;
2279  }
2280  status = sscanf(str_p+2, "%f Volts", &fval);
2281  if (status != 1) // couldn't properly parse the line
2282  return lineNo;
2283  info->baseboard_1_5v = fval;
2284  break;
2285  case 13: // Baseboard 3.3V
2286  str_p = strstr(line, "OK");
2287  if (str_p == NULL) { // couldn't find 'OK' within the line
2288  fclose(fp);
2289  return lineNo;
2290  }
2291  status = sscanf(str_p+2, "%f Volts", &fval);
2292  if (status != 1) // couldn't properly parse the line
2293  return lineNo;
2294  info->baseboard_3_3v = fval;
2295  break;
2296  case 14: // Baseboard 5.0V
2297  str_p = strstr(line, "OK");
2298  if (str_p == NULL) { // couldn't find 'OK' within the line
2299  fclose(fp);
2300  return lineNo;
2301  }
2302  status = sscanf(str_p+2, "%f Volts", &fval);
2303  if (status != 1) // couldn't properly parse the line
2304  return lineNo;
2305  info->baseboard_5_0v = fval;
2306  break;
2307  case 15: // Baseboard 12.0V
2308  str_p = strstr(line, "OK");
2309  if (str_p == NULL) { // couldn't find 'OK' within the line
2310  fclose(fp);
2311  return lineNo;
2312  }
2313  status = sscanf(str_p+2, "%f Volts", &fval);
2314  if (status != 1) // couldn't properly parse the line
2315  return lineNo;
2316  info->baseboard_p12_0v = fval;
2317  break;
2318  case 16: // Baseboard -12.0V
2319  str_p = strstr(line, "OK");
2320  if (str_p == NULL) { // couldn't find 'OK' within the line
2321  fclose(fp);
2322  return lineNo;
2323  }
2324  status = sscanf(str_p+2, "%f Volts", &fval);
2325  if (status != 1) // couldn't properly parse the line
2326  return lineNo;
2327  info->baseboard_m12_0v = fval;
2328  break;
2329  case 17: // FSB Vtt
2330  str_p = strstr(line, "OK");
2331  if (str_p == NULL) { // couldn't find 'OK' within the line
2332  fclose(fp);
2333  return lineNo;
2334  }
2335  status = sscanf(str_p+2, "%f Volts", &fval);
2336  if (status != 1) // couldn't properly parse the line
2337  return lineNo;
2338  info->fsb_vtt = fval;
2339  break;
2340  case 18: // Mem Core 1.8V
2341  str_p = strstr(line, "OK");
2342  if (str_p == NULL) { // couldn't find 'OK' within the line
2343  fclose(fp);
2344  return lineNo;
2345  }
2346  status = sscanf(str_p+2, "%f Volts", &fval);
2347  if (status != 1) // couldn't properly parse the line
2348  return lineNo;
2349  info->mem_core_1_8v = fval;
2350  break;
2351  case 19: // GBit Core 1.2V
2352  str_p = strstr(line, "OK");
2353  if (str_p == NULL) { // couldn't find 'OK' within the line
2354  fclose(fp);
2355  return lineNo;
2356  }
2357  status = sscanf(str_p+2, "%f Volts", &fval);
2358  if (status != 1) // couldn't properly parse the line
2359  return lineNo;
2360  info->gbit_core_1_2v = fval;
2361  break;
2362  case 20: // BB 3.3V Aux
2363  str_p = strstr(line, "OK");
2364  if (str_p == NULL) { // couldn't find 'OK' within the line
2365  fclose(fp);
2366  return lineNo;
2367  }
2368  status = sscanf(str_p+2, "%f Volts", &fval);
2369  if (status != 1) // couldn't properly parse the line
2370  return lineNo;
2371  info->bb_3_3v_aux = fval;
2372  break;
2373  case 21: // Proc1 VCCP
2374  str_p = strstr(line, "=");
2375  if (str_p == NULL) { // couldn't find '=' within the line
2376  fclose(fp);
2377  return lineNo;
2378  }
2379  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2380  if (status != 5) // couldn't properly parse the line
2381  return lineNo;
2382  if (!strcmp(ok_string, "OK")) {
2383  info->proc1_vccp = 1;
2384  } else {
2385  info->proc1_vccp = 0;
2386  }
2387  break;
2388  case 22: // Proc2 VCCP
2389  str_p = strstr(line, "=");
2390  if (str_p == NULL) { // couldn't find '=' within the line
2391  fclose(fp);
2392  return lineNo;
2393  }
2394  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2395  if (status != 5) // couldn't properly parse the line
2396  return lineNo;
2397  if (!strcmp(ok_string, "OK")) {
2398  info->proc2_vccp = 1;
2399  } else {
2400  info->proc2_vccp = 0;
2401  }
2402  break;
2403  case 23: // Baseboard Temp
2404  str_p = strstr(line, "OK");
2405  if (str_p == NULL) { // couldn't find 'OK' within the line
2406  fclose(fp);
2407  return lineNo;
2408  }
2409  status = sscanf(str_p+2, "%f degrees C", &fval);
2410  if (status != 1) // couldn't properly parse the line
2411  return lineNo;
2412  info->baseboard_temp = fval;
2413  break;
2414  case 24: // Proc1 CoreTemp
2415  str_p = strstr(line, "OK");
2416  if (str_p == NULL) { // couldn't find 'OK' within the line
2417  fclose(fp);
2418  return lineNo;
2419  }
2420  status = sscanf(str_p+2, "%f degrees C", &fval);
2421  if (status != 1) // couldn't properly parse the line
2422  return lineNo;
2423  info->proc1_coretemp = fval;
2424  break;
2425  case 25: // Proc2 CoreTemp
2426  str_p = strstr(line, "OK");
2427  if (str_p == NULL) { // couldn't find 'OK' within the line
2428  fclose(fp);
2429  return lineNo;
2430  }
2431  status = sscanf(str_p+2, "%f degrees C", &fval);
2432  if (status != 1) // couldn't properly parse the line
2433  return lineNo;
2434  info->proc2_coretemp = fval;
2435  break;
2436  case 26: // Sys Fan1
2437  str_p = strstr(line, "OK");
2438  if (str_p == NULL) { // couldn't find 'OK' within the line
2439  fclose(fp);
2440  return lineNo;
2441  }
2442  status = sscanf(str_p+2, "%f RPM", &fval);
2443  if (status != 1) // couldn't properly parse the line
2444  return lineNo;
2445  info->sys_fan1 = fval;
2446  break;
2447  case 27: // Sys Fan2
2448  str_p = strstr(line, "OK");
2449  if (str_p == NULL) { // couldn't find 'OK' within the line
2450  fclose(fp);
2451  return lineNo;
2452  }
2453  status = sscanf(str_p+2, "%f RPM", &fval);
2454  if (status != 1) // couldn't properly parse the line
2455  return lineNo;
2456  info->sys_fan2 = fval;
2457  break;
2458  case 28: // Sys Fan3
2459  str_p = strstr(line, "OK");
2460  if (str_p == NULL) { // couldn't find 'OK' within the line
2461  fclose(fp);
2462  return lineNo;
2463  }
2464  status = sscanf(str_p+2, "%f RPM", &fval);
2465  if (status != 1) // couldn't properly parse the line
2466  return lineNo;
2467  info->sys_fan3 = fval;
2468  break;
2469  case 29: // Sys Fan4
2470  str_p = strstr(line, "OK");
2471  if (str_p == NULL) { // couldn't find 'OK' within the line
2472  fclose(fp);
2473  return lineNo;
2474  }
2475  status = sscanf(str_p+2, "%f RPM", &fval);
2476  if (status != 1) // couldn't properly parse the line
2477  return lineNo;
2478  info->sys_fan4 = fval;
2479  break;
2480  case 30: // Proc1 IERR
2481  str_p = strstr(line, "=");
2482  if (str_p == NULL) { // couldn't find '=' within the line
2483  fclose(fp);
2484  return lineNo;
2485  }
2486  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2487  if (status != 5) // couldn't properly parse the line
2488  return lineNo;
2489  if (!strcmp(ok_string, "OK")) {
2490  info->proc1_ierr = 1;
2491  } else {
2492  info->proc1_ierr = 0;
2493  }
2494  break;
2495  case 31: // Proc2 IERR
2496  str_p = strstr(line, "=");
2497  if (str_p == NULL) { // couldn't find '=' within the line
2498  fclose(fp);
2499  return lineNo;
2500  }
2501  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2502  if (status != 5) // couldn't properly parse the line
2503  return lineNo;
2504  if (!strcmp(ok_string, "OK")) {
2505  info->proc2_ierr = 1;
2506  } else {
2507  info->proc2_ierr = 0;
2508  }
2509  break;
2510  case 32: // P1 Thermal Trip
2511  str_p = strstr(line, "=");
2512  if (str_p == NULL) { // couldn't find '=' within the line
2513  fclose(fp);
2514  return lineNo;
2515  }
2516  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2517  if (status != 5) // couldn't properly parse the line
2518  return lineNo;
2519  if (!strcmp(ok_string, "OK")) {
2520  info->p1_thermal_trip = 1;
2521  } else {
2522  info->p1_thermal_trip = 0;
2523  }
2524  break;
2525  case 33: // P2 Thermal Trip
2526  str_p = strstr(line, "=");
2527  if (str_p == NULL) { // couldn't find '=' within the line
2528  fclose(fp);
2529  return lineNo;
2530  }
2531  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2532  if (status != 5) // couldn't properly parse the line
2533  return lineNo;
2534  if (!strcmp(ok_string, "OK")) {
2535  info->p2_thermal_trip = 1;
2536  } else {
2537  info->p2_thermal_trip = 0;
2538  }
2539  break;
2540  case 34: // Int Button
2541  str_p = strstr(line, "=");
2542  if (str_p == NULL) { // couldn't find '=' within the line
2543  fclose(fp);
2544  return lineNo;
2545  }
2546  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2547  if (status != 5) // couldn't properly parse the line
2548  return lineNo;
2549  if (!strcmp(ok_string, "OK")) {
2550  info->int_button = 1;
2551  } else {
2552  info->int_button = 0;
2553  }
2554  break;
2555  case 35: // ID Button
2556  str_p = strstr(line, "=");
2557  if (str_p == NULL) { // couldn't find '=' within the line
2558  fclose(fp);
2559  return lineNo;
2560  }
2561  status = sscanf(str_p+1, "%x %x %x %x %s", &ival[0], &ival[1], &ival[2], &ival[3], ok_string);
2562  if (status != 5) // couldn't properly parse the line
2563  return lineNo;
2564  if (!strcmp(ok_string, "OK")) {
2565  info->id_button = 1;
2566  } else {
2567  info->id_button = 0;
2568  }
2569  break;
2570  case 36: // CPU1 Therm Ctrl
2571  str_p = strstr(line, "=");
2572  if (str_p == NULL) { // couldn't find '=' within the line
2573  fclose(fp);
2574  return lineNo;
2575  }
2576  status = sscanf(str_p+1, "%x %s", &ival[0], ok_string);
2577  if (status != 2) // couldn't properly parse the line
2578  return lineNo;
2579  if (!strcmp(ok_string, "OK")) {
2580  info->cpu1_therm_ctrl = 1;
2581  } else {
2582  info->cpu1_therm_ctrl = 0;
2583  }
2584  break;
2585  case 37: // CPU2 Therm Ctrl
2586  str_p = strstr(line, "=");
2587  if (str_p == NULL) { // couldn't find '=' within the line
2588  fclose(fp);
2589  return lineNo;
2590  }
2591  status = sscanf(str_p+1, "%x %s", &ival[0], ok_string);
2592  if (status != 2) // couldn't properly parse the line
2593  return lineNo;
2594  if (!strcmp(ok_string, "OK")) {
2595  info->cpu2_therm_ctrl = 1;
2596  } else {
2597  info->cpu2_therm_ctrl = 0;
2598  }
2599  break;
2600  case 38: // FrontPanel Temp
2601  str_p = strstr(line, "OK");
2602  if (str_p == NULL) { // couldn't find 'OK' within the line
2603  fclose(fp);
2604  return lineNo;
2605  }
2606  status = sscanf(str_p+2, "%f degrees C", &fval);
2607  if (status != 1) // couldn't properly parse the line
2608  return lineNo;
2609  info->frontpanel_temp = fval;
2610  break;
2611  default:
2612  break;
2613  }
2614  lineNo++;
2615  }
2616  }
2617 
2618  fclose(fp);
2619 
2620  return lineNo;
2621 }
2622 
2623 //------------------------------------------------------------------
2634 {
2635  INT i, indexKV61, indexKV62, size;
2636  HNDLE hkey, hsubkey;
2637  KEY key;
2638  char magnetNames[100*32]; // just too lazy, assume max. array size of 100 beam line elements
2639  float measuredKV61, measuredKV62;
2640 
2641  measuredKV61 = measuredKV62 = 0.;
2642  indexKV61 = indexKV62 = 0;
2643 
2644  // determine index of KV61 and KV62
2645  if (db_find_key(hDB, 0, "/Equipment/Beamline/Settings/Names", &hkey) != DB_SUCCESS) {
2646  cm_msg(MERROR, "beam_shutter_open", "Warning: can't get Names array for beam shutter status.");
2647  return 1;
2648  }
2649 
2650  db_get_key(hDB, hkey, &key);
2651  size = key.num_values*32;
2652  db_get_data(hDB, hkey, magnetNames, &size, TID_STRING);
2653 
2654  for (i=0; i<key.num_values; i++) {
2655  if (strstr(magnetNames+NAME_LENGTH*i, "KV61 (1=open)") != NULL) indexKV61 = i;
2656  if (strstr(magnetNames+NAME_LENGTH*i, "KV62 (1=open)") != NULL) indexKV62 = i;
2657  }
2658 
2659  // now, get the measured values of the KV position
2660  if (db_find_key(hDB, 0, "/Equipment/Beamline/Variables/Measured", &hkey) != DB_SUCCESS) {
2661  cm_msg(MERROR, "beam_shutter_open", "Warning: can't determine status of beam shutters.");
2662  return 1;
2663  }
2664 
2665  size = sizeof(float);
2666 
2667  if (db_get_data_index(hDB, hkey, &measuredKV61, &size, indexKV61, TID_FLOAT) != DB_SUCCESS) {
2668  cm_msg(MERROR, "beam_shutter_open", "Warning: can't get measured value of KV61.");
2669  return 1;
2670  }
2671  if (db_get_data_index(hDB, hkey, &measuredKV62, &size, indexKV62, TID_FLOAT) != DB_SUCCESS) {
2672  cm_msg(MERROR, "beam_shutter_open", "Warning: can't get measured value of KV62.");
2673  return 1;
2674  }
2675 
2676  if (measuredKV61 == 1. && measuredKV62 == 1.)
2677  return 1;
2678 
2679  //cm_msg(MINFO, "beam_shutter_open", "KV61 = %f, KV62 = %f", measuredKV61, measuredKV62);
2680 
2681  return 0;
2682 }
2683 
2684 //------------------------------------------------------------------
2685 //-- Global hotlink dispatcher routines ----------------------------
2693 void update_t0shift(INT dummy1, INT dummy2, void *dummy3)
2694 {
2695  HNDLE hDB, hKey;
2696  INT i, size;
2697  char str[80];
2698 
2699  cm_get_experiment_database(&hDB, NULL);
2700 
2701  // the following is necessary to get the right value of Bpar
2702  size = sizeof(info.lem_setup_parameter.bpar);
2703  db_get_value(hDB, 0, "/Info/LEM_Setup_Parameter/Bpar", &info.lem_setup_parameter.bpar, &size, TID_BOOL, FALSE);
2704 
2706  cm_msg(MINFO,"update_t0shift","Changed t0 shifts of decay histograms for magnet Bpar...");
2707  for ( i=0; i<N_DECAY_HISTS; i++)
2709  } else {
2710  for ( i=0; i<N_DECAY_HISTS; i++)
2712  cm_msg(MINFO,"update_t0shift","Changed t0 shifts of decay histograms for magnet WEW...");
2713  }
2714 
2715  sprintf(str, "/%s/Parameters/t0Shift", analyzer_name);
2716  db_find_key(hDB, 0, str, &hKey);
2717  db_set_record(hDB, hKey, &t0shift_param, sizeof(t0shift_param), 0);
2718 
2719  return;
2720 }
2721 
2722 //-- end -------------------------------------------------------------------------
2723 
2724 
2725 //------------------------------------------------------------------
2730 void set_spin_rot_angle(INT hDB, INT hKey, void *dummy)
2731 {
2732  INT i, size;
2733  BOOL flag_spinrot;
2734  char str[80];
2735  float sr_current, right_plate, left_plate, right_rod, left_rod;
2736  float moderator_hv, a[4];
2737 
2738  // Check if the spin rotator is enable or disabled
2739  flag_spinrot = info.spinrot_parameter.SRenable;
2740 
2741  cm_msg(MINFO,"set_spin_rot_angle","Spin rotator called with %i enable/disable and angle of %f degrees", flag_spinrot, rotation_angle);
2742 
2743  if (flag_spinrot) {
2744  // Get moderator energy into moderator_hv
2745  moderator_hv = hv_event.demand[sc_ana_param.mod_hv_channel];
2746  // Check if moderator is set at a sensible value
2747  if ((moderator_hv <= 1.0) || (moderator_hv >= 21.0)) {
2748  al_trigger_alarm( "ana_Spin_rotator", "Moderator HV should be between 1 and 20kV for spin rotation!",
2749  "Warning", "Moderator HV should be between 1 and 20kV for spin rotation!", AT_INTERNAL);
2750  return;
2751  }
2752 
2753  // Check if rotation angle is within allowed range
2754  if ((rotation_angle >= 91.0) || (rotation_angle <= -91.0)) {
2755  al_trigger_alarm( "ana_Spin_rotator", "Rotation angle is out of range, +/- 90 degrees!",
2756  "Warning", "Rotation angle is out of range, +/- 90 degrees!", AT_INTERNAL);
2757  return;
2758  }
2759 
2760  // get parameters for spin rotator calibration
2761  a[0] = info.spinrot_parameter.a0;
2762  a[1] = info.spinrot_parameter.a1;
2763  a[2] = info.spinrot_parameter.a2;
2764  a[3] = info.spinrot_parameter.a3;
2765  a[4] = info.spinrot_parameter.a4;
2766 
2767  sr_current=((rotation_angle-90.)/a[0]+a[1])*sqrt(moderator_hv);
2768  right_plate=(sr_current*sqrt(moderator_hv))/(a[2]+pow(fabs(sr_current/sqrt(moderator_hv)+a[3]),a[4]));
2769  left_plate=-1.0*right_plate;
2770  right_rod=0.5*right_plate;
2771  left_rod=0.5*left_plate;
2772 
2773  // Now set the appropriate odb values
2774 
2775  // Set SR current into "/Equipment/Danfysik_Spin_Rot/Variables/Output[2]" SRCurrent
2776  if (db_find_key(hDB, 0, "/Equipment/Danfysik_Spin_Rot/Variables/Output", &hKey) == DB_SUCCESS ) {
2777  db_set_data_index(hDB, hKey, &sr_current, sizeof(sr_current), 2, TID_FLOAT); }
2778  if (db_find_key(hDB, 0, "/Equipment/HV/Variables/Demand", &hKey) == DB_SUCCESS ) {
2779  // Set SR Right plate into "/Equipment/HV/Variables/Demand[3]" right_plate
2780  db_set_data_index(hDB, hKey, &right_plate, sizeof(right_plate), 3, TID_FLOAT);
2781  // Set SR Left plate into "/Equipment/HV/Variables/Demand[2]" -1.0*right_plate
2782  db_set_data_index(hDB, hKey, &left_plate, sizeof(left_plate), 2, TID_FLOAT);
2783  // Set SR Left Rod into "/Equipment/HV/Variables/Demand[1]" -0.5*right_plate
2784  db_set_data_index(hDB, hKey, &left_rod, sizeof(left_rod), 1, TID_FLOAT);
2785  // Set SR Right Rod into "/Equipment/HV/Variables/Demand[0]" +0.5*right_plate
2786  db_set_data_index(hDB, hKey, &right_rod, sizeof(right_rod), 0, TID_FLOAT);}
2787 
2788  // Add messages to log
2789  cm_msg(MINFO,"set_spin_rot_angle","Changed spin rotation angle to %f degrees", rotation_angle);
2790  cm_msg(MINFO,"set_spin_rot_angle","SR current %f and potential %f", sr_current, right_plate);
2791  } else {
2792  // SR disabled, igonre angle change
2793  cm_msg(MINFO,"set_spin_rot_angle","Spin rotator disabled, angle not changed.");
2794  }
2795  return;
2796 }
2797 
2798 //-- end -------------------------------------------------------------------------
void set_spin_rot_angle(INT hDB, INT hKey, void *dummy)
Definition: analyzer.c:2730
MEAN_BANK mean
Definition: sc_ana_module.c:52
float input[44]
Definition: experim.h:8605
int proc2_ierr
Definition: nemu_experim.h:230
ANA_MODULE mcp1_ana_module
float vbat
Definition: nemu_experim.h:269
BANK_LIST trigger_bank_list[]
Definition: analyzer.c:170
float implantation_energy
Definition: nemu_experim.h:284
float cpu1_vcore
Definition: nemu_experim.h:256
static TObjArray Slist(0)
float sys_fan4
Definition: nemu_experim.h:228
INT beam_shutter_open(HNDLE hDB)
Definition: analyzer.c:2633
float bb_3_3v_aux
Definition: nemu_experim.h:219
float energy_loss(float moderator_hv)
Definition: analyzer.c:961
INFO info
Definition: vme_fe.c:206
#define UPDATE_INFO_PERIOD_INTEL
Definition: analyzer.c:128
int chassis_intru
Definition: nemu_experim.h:270
#define T0SHIFT_PARAM_STR(_name)
Definition: experim.h:523
float vtt
Definition: nemu_experim.h:255
void update_info()
Definition: analyzer.c:1014
ANA_MODULE * sc_module[]
Definition: analyzer.c:158
float moderator_hv
Definition: experim.h:1339
struct DECAYANAMODULE_PARAM::@1::@3 decaybin
ANA_MODULE * trigger_module[]
Definition: analyzer.c:145
void disp_scaler(INT n)
float sys_fan1
Definition: nemu_experim.h:225
#define EXP_EDIT_STR(_name)
Definition: experim.h:54
INT moderator_channel
Definition: experim.h:561
float p2
Definition: nemu_experim.h:290
float var_sample_hv
Definition: experim.h:1344
static INT sum_count
Definition: analyzer.c:130
INT read_intel_log(INTEL_LOG *info)
Definition: analyzer.c:2090
char lem_setup[STR_SIZE]
Definition: nemu_experim.h:279
INT analyzer_exit()
Definition: analyzer.c:582
int ps2_status
Definition: nemu_experim.h:272
float var_moderator_hv
Definition: experim.h:1343
#define INFO_STR(_name)
Definition: nemu_experim.h:388
POSI_BANK_STR(posi_bank_str)
EXP_PARAM exp_param
Definition: analyzer.c:97
int int_button
Definition: nemu_experim.h:233
int proc2_vccp
Definition: nemu_experim.h:221
float sys_fan2
Definition: nemu_experim.h:226
SRAT_BANK_STR(srat_bank_str)
#define N_OFFSET_PPC_HISTOGRAMS
ID offset of postpileup-rejected histograms.
Definition: nemu_experim.h:72
float p2_dimme1_temp
Definition: nemu_experim.h:248
int ps1_status
Definition: nemu_experim.h:271
int pltfrm_evnt
Definition: nemu_experim.h:207
ANA_MODULE scaler_rate_sum
char moderator[STR_SIZE]
Definition: nemu_experim.h:277
float mem_core_1_8v
Definition: nemu_experim.h:217
DECAYANAMODULE_PARAM decay_ana_param
struct DECAYANAMODULE_PARAM::@0 histotitles
T0SHIFT_PARAM t0shift_param
Definition: analyzer.c:111
float a1
Definition: nemu_experim.h:323
float baseboard_m12_0v
Definition: nemu_experim.h:215
INT odb_size
Definition: analyzer.c:90
SCALER_SETTINGS scaler_settings
Definition: vme_fe.c:189
EXP_EDIT exp_edit
Definition: analyzer.c:96
#define HISTOGRAM_WRITE_PERIOD
Definition: analyzer.c:126
INT ana_begin_of_run(INT run_number, char *error)
Definition: analyzer.c:589
float p3_3v
Definition: nemu_experim.h:264
float p1_5v
Definition: nemu_experim.h:263
float sample_b
Definition: experim.h:1342
BANK_LIST scaler_bank_list[]
Definition: analyzer.c:179
float p5vsb
Definition: nemu_experim.h:267
float var_sample_b
Definition: experim.h:1346
ANA_MODULE sc_ana_module
Definition: sc_ana_module.c:64
BOOL SRenable
Definition: nemu_experim.h:328
char runname[256]
Definition: analyzer.c:92
INT ana_end_of_run(INT run_number, char *error)
Definition: analyzer.c:640
float baseboard_temp
Definition: nemu_experim.h:222
struct DECAYANAMODULE_PARAM::@1 histobinning
static TFolder * gRunHeader
Definition: analyzer.c:119
RUNINFO runinfo
/Runinfo ODB key, defined in from midas.h
Definition: vme_fe.c:193
struct DECAYANAMODULE_PARAM::@0::@2 decaytitles
float p1_dimmb1_temp
Definition: nemu_experim.h:247
float sample_t
Definition: experim.h:1341
void extract_summary_data()
Definition: analyzer.c:924
char sample_name[128]
Definition: nemu_experim.h:280
float baseboard_5_0v
Definition: nemu_experim.h:213
float delta_t0[8]
Definition: experim.h:519
HNDLE hKey
Definition: write_summary.c:97
RATE_BANK_STR(rate_bank_str)
#define STR_SIZE
Definition: nemu_experim.h:275
INT write_histogram_file()
Definition: analyzer.c:806
float a3
Definition: nemu_experim.h:325
float proc2_coretemp
Definition: nemu_experim.h:224
float a4
Definition: nemu_experim.h:326
float rotation_angle
Definition: nemu_experim.h:327
static float rotation_angle
Definition: analyzer.c:132
int sys_boot_init
Definition: nemu_experim.h:205
float measured[16]
Definition: experim.h:4953
float a0
Definition: nemu_experim.h:322
const char * analyzer_name
Definition: analyzer.c:84
char line[MAXLINE]
Definition: write_summary.c:96
ANA_MODULE tof_ana_module
INT ana_resume_run(INT run_number, char *error)
Definition: analyzer.c:745
char comment[136]
Definition: experim.h:27
struct INFO::@284 t0_parameter
float vdimm_cd
Definition: nemu_experim.h:259
void get_t0L3RA()
Definition: analyzer.c:1498
INT versionCounter
Definition: analyzer.c:93
HNDLE hDB
Definition: write_summary.c:97
#define TDSAMPLETOF_PARAM_STR(_name)
Definition: experim.h:569
float p1_dimma1_temp
Definition: nemu_experim.h:246
float p1_1v
Definition: nemu_experim.h:262
struct INFO::@282 magnet_parameter
void get_sum_filename(char *filename)
Definition: analyzer.c:887
INT proposal_number
Definition: nemu_experim.h:376
void update_run_header()
Definition: analyzer.c:1074
float a2
Definition: nemu_experim.h:324
float sys_fan3
Definition: nemu_experim.h:227
void update_t0shift(INT dummy1, INT dummy2, void *dummy3)
Definition: analyzer.c:2693
struct INFO::@283 lem_setup_parameter
ANALYZE_REQUEST analyze_request[]
Definition: analyzer.c:206
float wew[2]
Definition: nemu_experim.h:294
int proc1_vccp
Definition: nemu_experim.h:220
HV_EVENT hv_event
Definition: vme_fe.c:201
INT analyzer_init()
Definition: analyzer.c:273
float vdimm_ef
Definition: nemu_experim.h:260
float sample_hv
Definition: experim.h:1340
float p2_dimmf1_temp
Definition: nemu_experim.h:249
char beamline_settings[132]
Definition: nemu_experim.h:286
int cpu2_therm_ctrl
Definition: nemu_experim.h:236
int proc1_ierr
Definition: nemu_experim.h:229
float cpu2_12v
Definition: nemu_experim.h:210
RATE_BANK rate_bank
Definition: analyzer.c:99
#define UPDATE_INFO_PERIOD
Definition: analyzer.c:127
INT analyzer_loop_period
Definition: analyzer.c:87
char sample_cryo[NAME_LENGTH]
Definition: nemu_experim.h:281
float p1
Definition: nemu_experim.h:289
struct INFO::@285 spinrot_parameter
float baseboard_3_3v
Definition: nemu_experim.h:212
float p0
Definition: nemu_experim.h:288
float gbit_core_1_2v
Definition: nemu_experim.h:218
float cpu2_vcore
Definition: nemu_experim.h:257
int cpu1_therm_ctrl
Definition: nemu_experim.h:235
BANK_LIST sc_bank_list[]
Definition: analyzer.c:191
float p3
Definition: nemu_experim.h:291
static DWORD last_histogram_write
Definition: analyzer.c:124
INT ana_pause_run(INT run_number, char *error)
Definition: analyzer.c:736
float shift_delta_t0[8]
Definition: experim.h:520
ANA_MODULE decay_ana_module
static INT write_flag
Definition: analyzer.c:129
int chassis_intru
Definition: nemu_experim.h:208
INT sample_zeroflux_channel
Definition: experim.h:481
float baseboard_1_5v
Definition: nemu_experim.h:211
float p3_3vsb
Definition: nemu_experim.h:265
float p12v
Definition: nemu_experim.h:268
float p5v
Definition: nemu_experim.h:266
float leff_RAoff
Definition: nemu_experim.h:319
TRIGGER_SETTINGS trigger_settings
/Equipment/Trigger/Settings
Definition: vme_fe.c:188
TDSAMPLETOF_PARAM tdsampletof_param
Definition: analyzer.c:112
ANA_MODULE * scaler_module[]
Definition: analyzer.c:153
float cpu2_temp
Definition: nemu_experim.h:242
#define SCALER_SETTINGS_STR(_name)
Definition: experim.h:1195
float magnetic_field
Definition: nemu_experim.h:285
#define MEAN_BANK_STR(_name)
Definition: experim.h:1349
#define N_SCALER
total number of scaler channels
Definition: nemu_experim.h:63
float demand[16]
Definition: experim.h:4952
float helmholtz[2]
Definition: nemu_experim.h:296
INT read_ipmi_log(IPMI_LOG *info)
Definition: analyzer.c:1628
INT sample_hv_channel
Definition: experim.h:480
INT t0[N_DECAY_HISTS]
Definition: nemu_experim.h:316
INT t0Hist[N_DECAY_HISTS]
Definition: nemu_experim.h:317
#define EXP_PARAM_STR(_name)
Definition: experim.h:30
float baseboard_p12_0v
Definition: nemu_experim.h:214
float system_temp
Definition: nemu_experim.h:243
INT analyzer_loop()
Definition: analyzer.c:763
float var_sample_t
Definition: experim.h:1345
SRAT_BANK srat_bank
Definition: analyzer.c:101
float bpar[2]
Definition: nemu_experim.h:295
char main_proposer[80]
Definition: nemu_experim.h:377
float fsb_vtt
Definition: nemu_experim.h:216
#define N_OFFSET_ONOFF_HISTOGRAMS
ID offset for &quot;on/off&quot;, &quot;red/green&quot; histograms: no offset means &quot;off&quot;.
Definition: nemu_experim.h:73
int p2_thermal_trip
Definition: nemu_experim.h:232
#define N_DECAY_HISTS
number of LE-uSR npp decay histograms
Definition: nemu_experim.h:71
float cpu1_temp
Definition: nemu_experim.h:241
static DWORD last_update_info_write
Definition: analyzer.c:125
float proc1_coretemp
Definition: nemu_experim.h:223
SCS2001M_EVENT scs2001m_event
Definition: vme_fe.c:200
struct INFO::@290 file_header_info
POSI_BANK posi_bank
Definition: analyzer.c:103
float leff_RAon
Definition: nemu_experim.h:318
void get_t0()
Definition: analyzer.c:1396
ANA_MODULE pileup_ana_module
float peripherial_temp
Definition: nemu_experim.h:244
int p1_thermal_trip
Definition: nemu_experim.h:231
static TMusrRunHeader * header
Definition: analyzer.c:121
float vdimm_ab
Definition: nemu_experim.h:258
float cpu1_12v
Definition: nemu_experim.h:209
float get_magnetic_field(float current)
Definition: analyzer.c:987
struct INFO::@281 energy_loss_parameter
float vdimm_gh
Definition: nemu_experim.h:261
SCANAMODULE_PARAM sc_ana_param
Definition: sc_ana_module.c:53
float pch_temp
Definition: nemu_experim.h:245
float frontpanel_temp
Definition: nemu_experim.h:237
TFolder * gManaHistosFolder