Low-Energy Muon (LEM) Experiment  0.5.2
vme_fe.cxx
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: vme_fe.cxx
4  Created by: Thomas Prokscha 21-Sep-2005, PSI
5  22-Jan-2010, PSI
6 
7  Copyright (c) 2009 by Paul Scherrer Institut, 5232 Villigen PSI, Switzerland
8 
9  Contents: Midas frontend for periodic readout of the
10  Struck SIS3820 VME multiscaler and test
11  readout of a CAEN V1190B 64-channel multihit
12  TDC.
13  It uses the sis3820.c library which communicates with the VME
14  module using a SIS3100/1100 VME-PCI interface.
15 
16  December 2020: for Mu-MASS/Lambshift experiment, see *Dec 2020*
17  - always enable BC channels in event1
18  - comment checking of BC channels in evaluate_slow_muon_event:
19  -- check_tof_and_pileup() not used
20  -- TDC data of all BC channels written to data stream
21  - added MWAV data bank for microwave data
22 
23 
24  January 2010: extend to 64 channels to cope with new APD spectrometer.
25  Add red/green mode.
26 
27  For the V1190 readout:
28  -----------------------
29  ch 00 empty (Ip in scaler)
30  #define CLOCK 1 (10kHz)
31  #define MCP1 2
32  #define TD 4
33  #define BCL1 5
34  #define BCL2 6
35  #define BCL3 7
36  #define BCL4 8
37  #define BCR1 9
38  #define BCR2 10
39  #define BCR3 11
40  #define BCR4 12
41  #define POSMCP1I 13
42  #define POSMCP1O 14
43 
44  #define POSLDI 16
45  #define POSLDO 17
46  #define POSLUI 18
47  #define POSLUO 19
48 
49  #define POSBDI 20
50  #define POSBDO 21
51  #define POSBUI 22
52  #define POSBUO 23
53 
54  #define POSRDI 24
55  #define POSRDO 25
56  #define POSRUI 26
57  #define POSRUO 27
58 
59  #define POSTDI 28
60  #define POSTDO 29
61  #define POSTUI 30
62  #define POSTUO 31
63 
64  // for "red/green mode"
65  #define EXTON1 32
66  #define EXTOFF1 33
67 
68  #define MCP2F 34 MCP2-T1(Front MCP signal)
69  #define MCP2R 35 MCP2-T2(Rear MCP signal)
70  #define MCP2X1 36 MCP2-T3(X1)
71  #define MCP2X2 37 MCP2-T4(X2)
72  #define MCP2Y1 38 MCP2-T5(Y1)
73  #define MCP2Y2 39 MCP2-T6(Y2)
74 
75  - read TDC in frontend_loop(), scan TDC output buffer for
76  possible events; call evaluate_event() if a candidate for a "good"
77  event is found
78  - build events in evaluate_event(), put data into a ring buffer
79  - poll on read/write pointer position in ring buffer; if positions
80  are different read data from ring buffer, else do nothing
81  - 0.2ns resolution
82  - set ALM_FULL bit to 1024 (register 0x1022)
83  - check if ALM_FULL bit is set (0x2) (register 0x1002)
84  - if yes read the TDC output buffer completely in BLT32 mode, if not skip
85  - after read check if ALM_FULL bit is still set: if yes
86  - repeat read, if not, return
87  - three event types: Ev0 (BC)-MCP1-(e+MCP1)
88  Ev1 (BC)-TD-MCP2-(e+)
89  Ev2 (BC)-TD-e+ (LE-muSR setup)
90  For all event types the e+ are now always active in TDC
91  whereas the BC is only active in TDC if it is required
92  in the trigger condition
93  ( trigger_settings.event_(0,1,2)_settings.beamcounter_active = true)
94 
95  - if one adds a 1MHz clock one has to poll in order to
96  get all events, but >80% CPU load, about 0.5% loss of data;
97  -- reading periodically every millisec leads to a BUFFER FULL at TDC
98  -- poll and ss_sleep(1ms): about 1% data loss due to output buffer full,
99  low CPU load
100  - 200kHz can be read periodically with 1ms period
101 
102  - For time-of-flight (TOF) measurements with the beam counter (BC) we have the problem
103  that in a sequence of BC-MCP1/2/TD-e+ the "master" detector is after the BC and before the positrons.
104  The easiest way to solve the problem of finding all correlated events in the software trigger is to
105  have all signals a f t e r the master. This means that BC has to be delayed. This will be implemented
106  after version 1718 from 14-Mar-2006, 15:37. As an example, let's have a look on BC-MCP1:
107  -- all the pileup checking is done with the original TDC times
108  -- to get a BC-MCP1 "trigger" (a valid TOF within the TOF gate):
109  in original timing the corresponding detector flags are set if we have "clean" (no pre-pileup)
110  signals. If the detector pattern requested by the Event definition is found start to "evaluate"
111  the event, i.e. check if the timing between detector hits is ok. For this we will use the modified
112  times
113  t_BC --> t'_BC = t_BC + trigger_settings.tof_bc_window (delay BC time by TOF window length)
114  t_MCP1 --> t'_MCP1 = t_MCP1 + trigger_settings.event_0_settings.mcp1_delay
115  In evaluate_fast_muon() search the first t'_BC hit after t'_MCP1 which falls within the TOF window
116  If this is a "clean" we have an event;
117  to be continued...
118  - further improvement to avoid losses of BC events:
119  -- do not use time exceeding anymore; an event gets evaluated after the first "clean" (no pre-pileup)
120  master detector (MCP1 or TD or MCP2) is found, and if additional event-specific detector hits are
121  registered; in this case the event evaluation starts at the earliest at t = t_Master + t_dataWindow.
122  -- keep reverse timing for BC
123 
124  - 26-Apr-2006: add new banks for saving selected slow control ODB structure in DATA file
125  introduce new Event type "3" = "SlowControl";
126  create ODB hot-links to selected ODB structures, and write corresponding ODB
127  values periodically every 60sec to MIDAS banks.
128 
129 \********************************************************************/
130 
131 #include <linux/version.h>
132 
133 #include <stdio.h>
134 #include <stdlib.h>
135 #include <errno.h>
136 #include <string.h>
137 #include <unistd.h>
138 #include <sys/time.h>
139 #include <sys/types.h>
140 #include <sys/stat.h>
141 #include <fcntl.h>
142 #include <math.h>
143 
144 #include "midas.h"
145 #include "mfe.h"
146 #include "mcstd.h"
147 
148 #ifdef __cplusplus
149 extern "C" {
150 #endif
151 #include "sis3820.h"
152 #include "v1190.h"
153 #include "sis3100_vme_calls.h"
154 #ifdef __cplusplus
155 }
156 #endif
157 
159 #include "experim.h"
160 
162 #include "nemu_experim.h"
163 
164 /*------------------------- Globals --------------------------------*/
165 
167 const char *frontend_name = "VME_FE";
168 
170 const char *frontend_file_name = __FILE__;
171 
173 BOOL frontend_call_loop = TRUE;
174 
176 INT display_period = 3000;
177 
179 INT max_event_size = 128000;
180 
182 INT max_event_size_frag = 5*1024*1024;
183 
185 INT event_buffer_size = 60*10000;
186 
187 /* ---------------- ODB structures ---------------------------*/
195 //EXP_PARAM exp_param; //!< /Experiment/Run parameters
198 RUNINFO runinfo;
202 
214 /*HV_VACCLEANER hv_vaccleaner; //!< ODB key which contains information about pulsing of RA segments*/
215 
217 #define SIS3820_ADDRESS_0 0x38000000
218 #define SIS3820_ADDRESS_1 0x39000000
219 #define V1190_ADDRESS 0xEE000000
220 #define MAX_NUMBER_LWORDS 1024
221 #define ALMOST_FULL_LEVEL 1024
222 #define DATABUFFER_SIZE 131072
223 #define DIFF_TOLERANCE -12200
224 #define TD_EVENT (1<<0)
227 #define LE_POSITRON_EVENT (1<<1)
228 #define M2_EVENT (1<<2)
229 #define BC_EVENT (1<<3)
230 #define M1_EVENT (1<<4)
231 #define M1_POSITRON_EVENT (1<<5)
232 
234 #define MASTERLAST 1
235 #define MASTERFIRST 2
236 
237 typedef struct {
249  INT tdc_data[N_TDC_CHANNELS*DATA_N_HITS];
250  INT set_t0;
252  INT foundChannel[N_TDC_CHANNELS];
253  INT tdc_event[N_TDC_CHANNELS][N_HITS];
254  INT pileup[N_TDC_CHANNELS][N_HITS];
256  INT indexFastMuon, indexFastMuonSet;
257  INT indexSlowMuon, indexSlowMuonSet;
258  DWORD thisTimeSlowMuon, thisTimeFastMuon, lastTimeSlowMuon, lastTimeFastMuon;
263 
264 typedef struct{
271 } TDC_PILEUP;
272 
276 static INT hdev;
277 static DWORD *databuffer;
278 static DWORD *p_read, *p_write;
279 static DWORD masterFlagSlowMuon;
280 static DWORD eventDefinedSlowMuon;
281 static DWORD eventDefinedFastMuon;
282 static DWORD masterChannelSlowMuon;
283 static DWORD masterChannelFastMuon;
284 static U_LONG runTime;
287 static INT t0_offset;
288 static BOOL flag_external_on;
290 INT mode;
291 static struct timeval tvLastTime;
292 static BOOL flag_on_puls;
293 // static float ra_hv_1, ra_hv_2;
294 // static BOOL vacuum_cleaner_active;
295 // static DWORD lasttime;
296 
297 /*-- Function declarations -----------------------------------------*/
298 INT frontend_init();
299 INT frontend_exit();
300 INT begin_of_run(INT run_number, char *error);
301 INT end_of_run(INT run_number, char *error);
302 INT pause_run(INT run_number, char *error);
303 INT resume_run(INT run_number, char *error);
304 INT frontend_loop();
305 INT read_trigger_event(char *pevent, INT off);
306 INT poll_event(INT source, INT count, BOOL test);
307 INT read_scaler_event(char *pevent, INT off);
308 INT read_slowcontrol_event(char *pevent, INT off);
309 INT do_channel(INT ch, INT time);
310 INT do_master_channel(INT ch, INT event_type);
311 U_LONG pileup_end(INT pileupWindow);
314 BOOL check_tof_and_pileup(INT timing, INT tofWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex,
315  INT *channel, INT *ind);
316 BOOL check_positron(INT decWindow, INT coincWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex,
317  INT *channel, INT *ind);
318 
319 void scaler_mode(u_int32_t module_address);
320 int init_sis3820(u_int32_t module_address);
321 int init_v1190(u_int32_t module_address);
322 void OnOff_mode();
323 /*void vacuum_cleaner();*/
324 
325 //#define TESTOUT
326 #ifdef TESTOUT
327 FILE *fp;
328 #endif
329 
330 /*-- Equipment list ------------------------------------------------*/
331 #undef USE_INT
332 
342 
343 EQUIPMENT equipment[] = {
344 
345  { "Trigger", /* equipment name */
346  { 1, 0, /* event ID, trigger mask */
347  "SYSTEM", /* event buffer */
348  EQ_POLLED, /* equipment type */
349  LAM_SOURCE(0,0xFFFFFF),/* event source crate 0, all stations */
350  "MIDAS", /* format */
351  TRUE, /* enabled */
352  RO_RUNNING | RO_ODB, /* read only when running */
353  100, /* poll 100ms */
354  0, /* stop run after this event limit */
355  0, /* number of sub events */
356  0, /* don't log history */
357  "", "", "",},
358  read_trigger_event, /* readout routine */
359  },
360 
361  { "Scaler", /* equipment name */
362  { 2, 0, /* event ID, trigger mask */
363  "SYSTEM", /* event buffer */
364  EQ_PERIODIC, /* equipment type, MAN trigger disabled */
365  0, /* event source */
366  "MIDAS", /* format */
367  TRUE, /* enabled */
368  RO_ALWAYS |
369  RO_TRANSITIONS | /* read when running and on transitions */
370  RO_ODB, /* and update ODB */
371  3000, /* read every 3 sec */
372  0, /* stop run after this event limit */
373  0, /* number of sub events */
374  0, /* log history */
375  "", "", "",},
376  read_scaler_event, /* readout routine */
377  },
378 
379  { "SlowControl", /* equipment name */
380  { 3, 0, /* event ID, trigger mask */
381  "SYSTEM", /* event buffer */
382  EQ_PERIODIC, /* equipment type, MAN trigger disabled */
383  0, /* event source */
384  "MIDAS", /* format */
385  TRUE, /* enabled */
386  RO_RUNNING |
387  RO_TRANSITIONS | /* read when running and on transitions */
388  RO_ODB, /* and update ODB */
389  5000, /* read every 5 sec */
390  0, /* stop run after this event limit */
391  0, /* number of sub events */
392  0, /* log history */
393  "", "", "",},
394  read_slowcontrol_event, /* readout routine */
395  },
396 
397 
398  { "" }
399 };
400 
401 /********************************************************************\
402  Callback routines for system transitions
403 
404  These routines are called whenever a system transition like start/
405  stop of a run occurs. The routines are called on the following
406  occations:
407 
408  frontend_init: When the frontend program is started. This routine
409  should initialize the hardware.
410 
411  frontend_exit: When the frontend program is shut down. Can be used
412  to releas any locked resources like memory, commu-
413  nications ports etc.
414 
415  begin_of_run: When a new run is started. Clear scalers, open
416  rungates, etc.
417 
418  end_of_run: Called on a request to stop a run. Can send
419  end-of-run event and close run gates.
420 
421  pause_run: When a run is paused. Should disable trigger events.
422 
423  resume_run: When a run is resumed. Should enable trigger events.
424 
425 \********************************************************************/
426 
427 /*-- Frontend Init -------------------------------------------------*/
428 
430 {
431  HNDLE hDB, hkey;
432  char vme_device[32];
433  EXP_PARAM_STR(exp_param_str);
434  TRIGGER_SETTINGS_STR(trigger_settings_str);
435  SCALER_SETTINGS_STR(scaler_settings_str);
436  VME_STATS_STR(vme_stats_str);
437  BEAMLINE_SETTINGS_STR(beamline_settings_str);
438  BEAMLINE_EVENT_STR(beamline_event_str);
439  LEMVAC_SETTINGS_STR(lemvac_settings_str);
440  LEMVAC_EVENT_STR(lemvac_event_str);
441  MODCRYO_SETTINGS_STR(modcryo_settings_str);
442  MODCRYO_EVENT_STR(modcryo_event_str);
443  SAMPLECRYO_SETTINGS_STR(samplecryo_settings_str);
444  SAMPLECRYO_EVENT_STR(samplecryo_event_str);
445  SCS2001M_SETTINGS_STR(scs2001m_settings_str);
446  SCS2001M_EVENT_STR(scs2001m_event_str);
447  HV_SETTINGS_STR(hv_settings_str);
448  HV_EVENT_STR(hv_event_str);
449  HV_DETECTORS_SETTINGS_STR(hv_detectors_settings_str);
450  HV_DETECTORS_EVENT_STR(hv_detectors_event_str);
451 // HV_VACCLEANER_STR(hv_vaccleaner_str);
452  // ------------------------ ODB ------------------------------------------
453  //
454  // open (or create, if not exist) ODB structures;
455  //
456  cm_get_experiment_database(&hDB, NULL);
457 
458  db_create_record(hDB, 0, "/Experiment/Run Parameters", strcomb(exp_param_str));
459  db_create_record(hDB, 0, "/Equipment/Trigger/Settings", strcomb(trigger_settings_str));
460  db_create_record(hDB, 0, "/Equipment/Scaler/Settings", strcomb(scaler_settings_str));
461  db_create_record(hDB, 0, "/Equipment/Trigger/Vme_Statistics", strcomb(vme_stats_str));
462  db_create_record(hDB, 0, "/Equipment/Beamline/Settings", strcomb(beamline_settings_str));
463  db_create_record(hDB, 0, "/Equipment/Beamline/Variables", strcomb(beamline_event_str));
464  db_create_record(hDB, 0, "/Equipment/LEMVAC/Settings", strcomb(lemvac_settings_str));
465  db_create_record(hDB, 0, "/Equipment/LEMVAC/Variables", strcomb(lemvac_event_str));
466  db_create_record(hDB, 0, "/Equipment/ModCryo/Settings", strcomb(modcryo_settings_str));
467  db_create_record(hDB, 0, "/Equipment/ModCryo/Variables", strcomb(modcryo_event_str));
468  db_create_record(hDB, 0, "/Equipment/SampleCryo/Settings", strcomb(samplecryo_settings_str));
469  db_create_record(hDB, 0, "/Equipment/SampleCryo/Variables", strcomb(samplecryo_event_str));
470  db_create_record(hDB, 0, "/Equipment/SCS2001M/Settings", strcomb(scs2001m_settings_str));
471  db_create_record(hDB, 0, "/Equipment/SCS2001M/Variables", strcomb(scs2001m_event_str));
472  db_create_record(hDB, 0, "/Equipment/HV/Settings", strcomb(hv_settings_str));
473  db_create_record(hDB, 0, "/Equipment/HV/Variables", strcomb(hv_event_str));
474  db_create_record(hDB, 0, "/Equipment/HV Detectors/Settings", strcomb(hv_detectors_settings_str));
475  db_create_record(hDB, 0, "/Equipment/HV Detectors/Variables", strcomb(hv_detectors_event_str));
476 // db_create_record(hDB, 0, "/VacuumCleaner", strcomb(hv_vaccleaner_str));
477 
479  if (db_find_key(hDB, 0, "/Equipment/Trigger/Settings", &hkey))
480  db_open_record(hDB, hkey, &trigger_settings, sizeof(trigger_settings), MODE_READ, NULL, NULL);
481 
482  if (db_find_key(hDB, 0, "/Equipment/Trigger/Vme_Statistics", &hkey))
483  db_open_record(hDB, hkey, &vme_stats, sizeof(vme_stats), MODE_WRITE, NULL, NULL);
484 
485  if (db_find_key(hDB, 0, "/Runinfo", &hkey))
486  db_open_record(hDB, hkey, &runinfo, sizeof(runinfo), MODE_READ, NULL, NULL);
487 
488 /* if (db_find_key(hDB, 0, "/VacuumCleaner", &hkey))
489  db_open_record(hDB, hkey, &hv_vaccleaner, sizeof(hv_vaccleaner), MODE_READ, NULL, NULL);*/
490 
491  if (db_find_key(hDB, 0, "/Info", &hkey))
492  db_open_record(hDB, hkey, &info, sizeof(info), MODE_READ, NULL, NULL);
493 
495  if (db_find_key(hDB, 0, "/Equipment/Beamline/Variables", &hkey))
496  db_open_record(hDB, hkey, &beamline_event, sizeof(beamline_event), MODE_READ, NULL, NULL);
497  if (db_find_key(hDB, 0, "/Equipment/LEMVAC/Variables", &hkey))
498  db_open_record(hDB, hkey, &lemvac_event, sizeof(lemvac_event), MODE_READ, NULL, NULL);
499  if (db_find_key(hDB, 0, "/Equipment/ModCryo/Variables", &hkey))
500  db_open_record(hDB, hkey, &moddy_event, sizeof(moddy_event), MODE_READ, NULL, NULL);
501  if (db_find_key(hDB, 0, "/Equipment/SampleCryo/Variables", &hkey))
502  db_open_record(hDB, hkey, &sample_event, sizeof(sample_event), MODE_READ, NULL, NULL);
503  if (db_find_key(hDB, 0, "/Equipment/Omega/Variables", &hkey))
504  db_open_record(hDB, hkey, &omega_event, sizeof(omega_event), MODE_READ, NULL, NULL);
505  if (db_find_key(hDB, 0, "/Equipment/SCS2001M/Variables", &hkey))
506  db_open_record(hDB, hkey, &scs2001m_event, sizeof(scs2001m_event), MODE_READ, NULL, NULL);
507  if (db_find_key(hDB, 0, "/Equipment/HV/Variables", &hkey))
508  db_open_record(hDB, hkey, &hv_event, sizeof(hv_event), MODE_READ, NULL, NULL);
509  if (db_find_key(hDB, 0, "/Equipment/HV Detectors/Variables", &hkey))
510  db_open_record(hDB, hkey, &hvdet_event, sizeof(hvdet_event), MODE_READ, NULL, NULL);
511  memset(&vme_stats, 0x00, sizeof(vme_stats));
512  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
513  memset(&tdc_pileup, 0x00, sizeof(tdc_pileup));
514  databuffer = (DWORD*)malloc(DATABUFFER_SIZE * sizeof(DWORD));//allocate memory for data buffer
515  p_read = &databuffer[0];
516  p_write = &databuffer[0];
517  eventDefinedSlowMuon = 0xffff;
518  eventDefinedFastMuon = 0xffff;
519  flag_external_on = FALSE;
520  flag_scaler_address_0 = TRUE;
521  flag_scaler_address_1 = TRUE;
522  flag_on_puls = FALSE;
523 
524  /*--- VME initialization ---*/
525 #ifdef HAVE_TEST_RUN
526  hdev = 0;
527 #else
528  cm_msg(MINFO, "frontend_init","LINUX_VERSION = 0x%x",LINUX_VERSION_CODE);
529  cm_yield(0);
530  if (LINUX_VERSION_CODE < 0x20600) // for sis1100 drivers < V2, Linux kernel 2.4
531  sprintf(vme_device, "/dev/sis1100");
532  else // for sis1100 driver V2.02, Linux kernel 2.6.9, V2.04 for kernel 2.6.18
533  sprintf(vme_device, "/dev/sis1100_00remote");
534 
535  if ((hdev = open(vme_device, O_RDWR, 0)) < 0) {
536  cm_msg(MERROR, "frontend_init", "Error on opening VME device %s", vme_device);
537  cm_yield(0);
538  return FE_ERR_HW;
539  }
540 #endif
541 
542  //SIS3820 scaler initialization
543  if (init_sis3820(SIS3820_ADDRESS_0) == FE_ERR_HW)
544  flag_scaler_address_0 = FALSE;
545 
546  if (init_sis3820(SIS3820_ADDRESS_1) == FE_ERR_HW)
547  flag_scaler_address_1 = FALSE;
548 
549  cm_msg(MINFO,"frontend_init","scaler flags, address 0x%8.8x = %d, 0x%8.8x = %d",
551  cm_yield(0);
552 
553  // V1190 TDC initialisation
554  if (init_v1190(V1190_ADDRESS) == FE_ERR_HW)
555  return FE_ERR_HW;
556 
557  gettimeofday(&tvLastTime, 0);
558 // lasttime = ss_millitime();
559 /* vacuum_cleaner_active = FALSE;*/
560  return SUCCESS;
561 }
562 
563 /*-- Frontend Exit -------------------------------------------------*/
564 
566 {
567  int status;
568 
569  /* reset SIS3820 */
570  if (flag_scaler_address_0) {
572  if (status != 0) {
573  cm_msg(MERROR, "frontend_exit",
574  "Error on access to SIS3820_0, key reset failed, return code %x\n", status);
575  cm_yield(0);
576  }
577  }
578  if (flag_scaler_address_1) {
580  if (status != 0) {
581  cm_msg(MERROR, "frontend_exit",
582  "Error on access to SIS3820_1, key reset failed, return code %x\n", status);
583  cm_yield(0);
584  }
585  }
586  /* close VME device */
587  if (hdev >= 0)
588  close(hdev);
589 
590  free (databuffer);
591 
592  return SUCCESS;
593 }
594 
595 /*-- Begin of Run --------------------------------------------------*/
596 
597 INT begin_of_run(INT run_number, char *error)
598 {
599  int status, i;
600  WORD ch_pattern[4];
601  DWORD pattern_1stChip, pattern_2ndChip;
602 
603  // ------------------------------------------------------------
604  // on TDC enable active channels according to event definition in ODB
605  //
606  memset(&ch_pattern, 0x00, sizeof(ch_pattern));
607  pattern_1stChip = pattern_2ndChip = 0;
608 
609  for (i = 0; i<N_TDC_CHANNELS; i++) {
610  switch (i) {
611  case CLOCK:
612  if (i < 32)
613  pattern_1stChip = pattern_1stChip | (1<<i); //clock always enabled
614  else
615  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
616  break;
617 
618  case EXTON1: case EXTOFF1:
619  if ( !trigger_settings.enable_onoff_mode) break; //continue if not enabled
620  if (i < 32)
621  pattern_1stChip = pattern_1stChip | (1<<i);
622  else
623  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
624  break;
625 
626  case MCP1: case POSMCP1I: case POSMCP1O:
627  if ( !trigger_settings.events.event_0_active) break;
628  if (i < 32)
629  pattern_1stChip = pattern_1stChip | (1<<i);
630  else
631  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
632  break;
633 
634  case BCL1: case BCL2: case BCL3: case BCL4:
635  case BCR1: case BCR2: case BCR3: case BCR4:
636  if ((trigger_settings.event_0_settings.beamcounter_active && trigger_settings.events.event_0_active) ||
637 // (trigger_settings.event_1_settings.beamcounter_active && trigger_settings.events.event_1_active) ||
638  (trigger_settings.events.event_1_active) || //always enable beamcounter channels if event1 is active, *Dec 2020*
639  (trigger_settings.event_2_settings.beamcounter_active && trigger_settings.events.event_2_active)){
640  if (i < 32)
641  pattern_1stChip = pattern_1stChip | (1<<i);
642  else
643  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
644  }
645  break;
646 
647  case TD:
648  case POSLDI: case POSLDO: case POSLUI: case POSLUO:
649  case POSTDI: case POSTDO: case POSTUI: case POSTUO:
650  case POSRDI: case POSRDO: case POSRUI: case POSRUO:
651  case POSBDI: case POSBDO: case POSBUI: case POSBUO:
652  if (trigger_settings.events.event_1_active ||
653  trigger_settings.events.event_2_active){
654  if (i < 32)
655  pattern_1stChip = pattern_1stChip | (1<<i);
656  else
657  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
658  }
659  break;
660 
661  case MCP2F: case MCP2R:
662  case MCP2X1: case MCP2X2: case MCP2Y1: case MCP2Y2:
663  if ( !trigger_settings.events.event_1_active) break;
664  if (i < 32)
665  pattern_1stChip = pattern_1stChip | (1<<i);
666  else
667  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
668 
669  break;
670 
671  default:
672  break;
673  }
674  }
675 
676  cm_msg(MINFO,"begin_of_run","pattern_1stChip = 0x%08x", pattern_1stChip);
677  cm_msg(MINFO,"begin_of_run","pattern_2ndChip = 0x%08x", pattern_2ndChip);
678  cm_yield(0);
679  ch_pattern[0] = pattern_1stChip & 0xFFFF;
680  ch_pattern[1] = (pattern_1stChip & 0xFFFF0000)>>16;
681  ch_pattern[2] = pattern_2ndChip & 0xFFFF;
682  ch_pattern[3] = (pattern_2ndChip & 0xFFFF0000)>>16;
683 
684 #ifndef HAVE_TEST_RUN
685  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, 0x4600); // pattern for 1st TDC chip
686  for (i=0; i<2; i++) {
687  ss_sleep(20);
688  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, ch_pattern[i]);
689  cm_msg(MINFO, "begin_of_run", "V1190 1st Chip channel pattern: pattern = 0x%04x", ch_pattern[i]);
690  cm_yield(0);
691  }
692  if (status != 0) {
693  cm_msg(MERROR, "begin_of_run", "Error writing channel pattern to TDC V1190, return code %x\n", status);
694  cm_yield(0);
695  return FE_ERR_HW;
696  }
697 
698  ss_sleep(50);
699  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, 0x4601); // pattern for 2nd TDC chip
700  for (i=2; i<4; i++) {
701  ss_sleep(20);
702  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, ch_pattern[i]);
703  cm_msg(MINFO, "begin_of_run", "V1190 2nd Chip channel pattern: pattern = 0x%04x", ch_pattern[i]);
704  cm_yield(0);
705  }
706  if (status != 0) {
707  cm_msg(MERROR, "begin_of_run", "Error writing channel pattern to TDC V1190, return code %x\n", status);
708  cm_yield(0);
709  return FE_ERR_HW;
710  }
711 
712  ss_sleep(20);
713 
714  // -----------------------------------------------------------------------
715  // clear TDC
716  //
717  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_SOFTWARE_CLEAR, 0x0);
718  if (status !=0) {
719  cm_msg(MERROR, "begin_of_run",
720  "Error on resetting TDC V1190, return code %x\n", status);
721  cm_yield(0);
722  return FE_ERR_HW;
723  }
724 #endif
725  // -----------------------------------------------------------------------
726  // reset 1st Scaler module SIS3820_0
727  //
728  // disable SIS3820
729  if (flag_scaler_address_0) {
731  if (status !=0) {
732  cm_msg(MERROR, "begin_of_run",
733  "Error on access to SIS3820_0, key disable failed, return code %x\n", status);
734  cm_yield(0);
735  return FE_ERR_HW;
736  }
737  // reset SIS3820
739  if (status !=0) {
740  cm_msg(MERROR, "begin_of_run",
741  "Error on access to SIS3820_0, key reset failed, return code %x\n", status);
742  cm_yield(0);
743  return FE_ERR_HW;
744  }
745  // check/change scaler mode
747  // enable SIS3820
749  if (status !=0) {
750  cm_msg(MERROR, "begin_of_run",
751  "Error on access to SIS3820_0, key enable failed, return code %x\n", status);
752  cm_yield(0);
753  return FE_ERR_HW;
754  }
755  }
756  // -----------------------------------------------------------------------
757  // reset 2nd Scaler module SIS3820_1
758  //
759  // disable SIS3820
760  if (flag_scaler_address_1) {
762  if (status !=0) {
763  cm_msg(MERROR, "begin_of_run",
764  "Error on access to SIS3820_1, key disable failed, return code %x\n", status);
765  cm_yield(0);
766  return FE_ERR_HW;
767  }
768  // reset SIS3820
770  if (status !=0) {
771  cm_msg(MERROR, "begin_of_run",
772  "Error on access to SIS3820_1, key reset failed, return code %x\n", status);
773  cm_yield(0);
774  return FE_ERR_HW;
775  }
776  // check/change scaler mode
778  // enable SIS3820
780  if (status !=0) {
781  cm_msg(MERROR, "begin_of_run",
782  "Error on access to SIS3820_1, key enable failed, return code %x\n", status);
783  cm_yield(0);
784  return FE_ERR_HW;
785  }
786  }
787 
788  // event definition
789  eventDefinedSlowMuon = 0x8000;
790  eventDefinedFastMuon = 0x8000;
791  t0_offset = trigger_settings.t0_offset;
794  flag_external_on = FALSE;
795  flag_on_puls = FALSE;
796 
797  if (trigger_settings.events.event_0_active) { // "fast" muons on MCP1
800  if (trigger_settings.event_0_settings.beamcounter_active)
802 
803  if (trigger_settings.event_0_settings.positrons_active)
805  }
806 
807  if (trigger_settings.events.event_1_active) { // "slow" muons on TD/MCP2/Sample
809  if (trigger_settings.event_1_settings.td_active)
811  else
813 
814  if (trigger_settings.event_1_settings.mcp2_active)
816 
817  if (trigger_settings.event_1_settings.beamcounter_active)
819 
820  if (trigger_settings.event_1_settings.positrons_active)
822 
823  if (trigger_settings.event_1_settings.td_master) {
826  } else {
829  }
830  } else if (trigger_settings.events.event_2_active) {
835  if (trigger_settings.event_2_settings.beamcounter_active)
837  }
838 
839  cm_msg(MINFO,"begin_of_run","Fast Muon event_defined = 0x%04x, master channel fast muon= %d",
841  cm_yield(0);
842  cm_msg(MINFO,"begin_of_run","Slow Muon event_defined = 0x%04x, master channel slow muon= %d",
844  cm_yield(0);
845 
846  // reset array and pointers
847  memset(&vme_stats, 0x00, sizeof(vme_stats));
848  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
849  memset(&tdc_pileup, 0x00, sizeof(tdc_pileup));
850  memset(databuffer, 0x00, sizeof(databuffer));
851  p_read = &databuffer[0]; // set read data pointer to beginning of data buffer
852  p_write = &databuffer[0]; // set write data pointer to beginning of data buffer
853  runTime = t0_offset;
854  nextGoodTime = 0;
855  vme_stats.last_TDCtime = -1; //signal that last_TDCime has not been set
856 #ifdef TESTOUT
857  fp = fopen( "/data/nemu/fe.log", "w");
858  if ( fp == NULL ) return FE_ERR_HW;
859 #endif
860  return SUCCESS;
861 }
862 
863 /*-- End of Run ----------------------------------------------------*/
864 
865 INT end_of_run(INT run_number, char *error)
866 {
867  INT return_code;
868 
869  /* disable all channels if set in ODB */
870  if (trigger_settings.tdc_disable_atstartup) {
871  return_code = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, V1190_DISABLE_ALL_CHANNEL);
872  cm_msg(MINFO, "end_of_run", "V1190 Disabled all channels: return_code = 0x%08x", return_code);
873  cm_yield(0);
874  }
875 
876  cm_msg(MINFO, "end_of_run","total number of written slow muon events = %15.0f", vme_stats.slowMuonEvents);
877  cm_msg(MINFO, "end_of_run","total number of written fast muon events = %15.0f", vme_stats.fastMuonEvents);
878  cm_msg(MINFO, "end_of_run","total number of read events = %15.0f", vme_stats.readcounts);
879  cm_msg(MINFO, "end_of_run","TDC error counts = %15.0f", vme_stats.tdc_error_counts);
880  cm_msg(MINFO, "end_of_run","p_read = 0x%x, p_write = 0x%x", p_read, p_write);
881  cm_msg(MINFO, "end_of_run","total Run time in TDC bins (double) = %18.0f", vme_stats.run_time);
882  cm_msg(MINFO, "end_of_run","total Run time 10kHz clock = %18.5f", vme_stats.channelCounts[1]/10000.);
883  cm_yield(0);
884 #ifdef TESTOUT
885  fclose(fp);
886 #endif
887 
888  return SUCCESS;
889 }
890 
891 /*-- Pause Run -----------------------------------------------------*/
892 
893 INT pause_run(INT run_number, char *error)
894 {
895  return SUCCESS;
896 }
897 
898 /*-- Resume Run ----------------------------------------------------*/
899 
900 INT resume_run(INT run_number, char *error)
901 {
902  int status;
903 
904  // clear TDC
905  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_SOFTWARE_CLEAR, 0x0);
906  if (status !=0) {
907  cm_msg(MERROR, "resume_run",
908  "Error on resetting TDC V1190, return code %x\n", status);
909  cm_yield(0);
910  return FE_ERR_HW;
911  }
912 
913  if (flag_scaler_address_0) {
917  }
918  if (flag_scaler_address_1) {
922  }
923 
924  return SUCCESS;
925 }
926 
927 /*-- Frontend Loop -------------------------------------------------*/
928 
958 {
959  /* if frontend_call_loop is true, this routine gets called when
960  the frontend is idle or once between every event */
961  u_int16_t data;
962  u_int32_t blt_data[MAX_NUMBER_LWORDS] ;
963  u_int32_t *output_buffer; //[V1190_OUTPUT_BUFFER_SIZE];
964  u_int32_t get_lwords, sum_lwords;
965  INT return_code;
966  INT i, j, k;
967  INT tdc_time, channel, diffTimeSlowMuon, diffTimeFastMuon;
968  V1190_DATA *v1190_data;
969 
970  //-----------------------------------------------------------------------------------
971  // pulse RA high voltage, if requested; return from frontend loop if
972  // vacuum_cleaner is active, i.e. RA potentials are changing
973  /* if (hv_vaccleaner.pulse || vacuum_cleaner_active){
974  vacuum_cleaner();
975  if (vacuum_cleaner_active) return SUCCESS;
976  }*/
977 
978  //-----------------------------------------------------------------------------------
979  // in case of On_Off_Mode enabled generate a short pulse on SIS3100 output 1
980  //
981  if (trigger_settings.enable_onoff_mode) {
982  OnOff_mode();
983  }
984 
985 
986 #ifdef HAVE_TEST_RUN
987  return SUCCESS;
988 #endif
989 
990 
991  if ( runinfo.state != STATE_RUNNING ) // don't read TDC if we are not running
992  return SUCCESS;
993 
994  vme_stats.frontend_loop_counts++; // for test purposes only
995  diffTimeSlowMuon = diffTimeFastMuon = 0;
996 
997  if (!trigger_settings.event_0_settings.simulation_flag) {
998  //------------------------------------------------------------------------------------
999  // check fill level of TDC output buffer; return if ALMOST_FULL_BIT is not yet set
1000  //
1001  return_code = vme_A32D16_read(hdev, V1190_ADDRESS+V1190_STATUS_REGISTER, &data );
1002  if (!(data & V1190_ALMFULL_BIT)) return SUCCESS;
1003 
1004  vme_stats.frontend_loop_readtdc++;
1005  //cm_msg(MINFO, "frontend_loop","p_read = 0x%x, p_write = 0x%x", p_read, p_write);
1006  }
1007  //--------------------------------------------------------------------------------------
1008  // read complete TDC output buffer; break if no more data are present in output buffer
1009  //
1010  sum_lwords = 0;
1011  output_buffer = (u_int32_t*)malloc(V1190_OUTPUT_BUFFER_SIZE * sizeof(u_int32_t));
1012 
1013  // ----------------------------
1014  // simulate pure, uncorrelated background
1015  //
1016  if (trigger_settings.event_0_settings.simulation_flag) {
1017 #define BINNING 0.1953125 // TDC bin in ns
1018  double rate[4], ran; // rates 1/ns
1019  U_LONG time[4];
1020  DWORD mincounter, tdctime; // times in TDC channels, assume 0.1953125ns LSB
1021 
1022  rate[0] = 1.e-5; // 10kHz clock
1023  rate[1] = trigger_settings.event_0_settings.mcp1_rate; // MCP1, counts/ns
1024  rate[2] = trigger_settings.event_0_settings.bc_rate; // BCL2, counts/ns
1025  rate[3] = trigger_settings.event_0_settings.bc_rate; // BCL3, counts/ns
1026  ss_sleep(10);
1027  memset(&time, 0x00, sizeof(time));
1028  sum_lwords = V1190_OUTPUT_BUFFER_SIZE/2;
1029  for (i=0; i<sum_lwords; i++) {
1030  if (i == 0) {
1031  ran = (double) rand()/ (double) RAND_MAX;
1032  time[0] = ran*1.e+5/BINNING; // next occurence of 10kHz
1033  for (j=1; j<4; j++) {
1034  ran = (double) rand()/ (double) RAND_MAX;
1035  time[j] = (-1./rate[j]*log(1.- ran))/BINNING;
1036  }
1037  }
1038 
1039  for (j=0; j<4; j++) {// find the next event
1040  mincounter = 0;
1041  for (k=0; k<4; k++) {
1042  if (j!=k && time[j] <= time[k]) mincounter++;
1043  }
1044  if (mincounter == 3) break;
1045  }
1046 
1047  switch (j) {
1048  case 0:
1049  channel = CLOCK;
1050  tdctime = time[0]%TDC_BIT_RANGE;
1051  tdctime = tdctime | (channel<<19);
1052  time[0] = time[0] + (U_LONG) 1.e+5/BINNING; // the next 10kHz clock time
1053  break;
1054 
1055  case 1:
1056  channel = MCP1;
1057  tdctime = time[1]%TDC_BIT_RANGE;
1058  tdctime = tdctime | (channel<<19);
1059  ran = (double) rand()/(double) RAND_MAX;
1060  time[1] = time[1] + (U_LONG) (-1./rate[j]*log(1. - ran))/BINNING;;
1061  break;
1062 
1063  case 2:
1064  channel = BCL2;
1065  tdctime = time[2]%TDC_BIT_RANGE;
1066  tdctime = tdctime | (channel<<19);
1067  ran = (double) rand()/(double) RAND_MAX;
1068  time[2] = time[2] + (U_LONG) (-1./rate[j]*log(1. - ran))/BINNING;;
1069  break;
1070 
1071  case 3:
1072  channel = BCL3;
1073  tdctime = time[3]%TDC_BIT_RANGE;
1074  tdctime = tdctime | (channel<<19);
1075  ran = (double) rand()/(double) RAND_MAX;
1076  time[3] = time[3] + (U_LONG) (-1./rate[j]*log(1. - ran))/BINNING;;
1077  break;
1078 
1079  default:
1080  break;
1081  }
1082  //fprintf(fp,"i=%6d, times = %12u %12u %12u %12u\n",i,time[0],time[1],time[2],time[3]);
1083  output_buffer[i] = tdctime;
1084  }
1085  }
1086  // -----------------------------
1087  // read TDC data
1088  else {
1089  for (i=0; i<32; i++) {
1090  return_code = vme_A32BLT32_read(hdev, V1190_ADDRESS, blt_data, MAX_NUMBER_LWORDS, &get_lwords);
1091  memcpy(output_buffer + sum_lwords, &blt_data, get_lwords * sizeof(u_int32_t));
1092  sum_lwords += get_lwords;
1093  if (return_code == 0x211) // VME Bus error indicating that output buffer is empty
1094  break; // this does not work at rates > 1MHz; new events in output buffer
1095  }
1096  }
1097  //-----------------------------------------------------------------------------------------
1098  // scan output buffer and search events; if a possible event is found evaluate_event()
1099  // is executed
1100  //
1101  for (i=0; i<sum_lwords; i++) {
1102  v1190_data = (V1190_DATA *) &output_buffer[i];
1103  tdc_time = v1190_data->data;
1104  channel = v1190_data->channel;
1105  if (vme_stats.last_TDCtime == -1) //at BOR last_TDCtime is set to -1
1106  vme_stats.last_TDCtime = tdc_time;
1107 
1108  if (v1190_data->buffer == 4) { //this means a TDC error occured, bit 29 is set; this can happen
1109  //if input rate is > 1MHz; in this case the error condition
1110  //above (return_code == 0x211) does not work
1111 #ifdef TESTOUT
1112  fprintf(fp,"found TDC error\n");
1113 #endif
1114  vme_stats.tdc_error_counts++;
1115  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event)); // reset structure for next event
1116  continue;
1117  }
1118 
1119  if (tdc_eval_event.foundChannel[channel] > N_HITS-1) { // didn't yet find an event
1120 #ifdef TESTOUT
1121  fprintf(fp,"Event reset due to channel %d overflow\n", channel);
1122 #endif
1123  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event)); // reset structure for next event to avoid
1124  continue; // buffer overflow
1125  }
1126 
1127  vme_stats.channelCounts[channel]++;
1128  do_channel(channel, tdc_time); //update channel statistics, copy TDC times in temporary buffer
1129  //tdc_event[ch][index] to be used in evaluate_event():
1130 
1131  //check pre-pileups for "master" channels, set event flags, add delays to TDC times
1132  switch (channel) {
1133 /* --------------------------------------------------------------------------------------------------------
1134 the "Master" detectors for event types 0 (BC-MCP1-e+), Event 1 (BC-TD-MCP2-e+), Event 2 (BC-TD-e+, LEmuSR)
1135 --------------------------------------------------------------------------------------------------------*/
1136  case MCP1:
1137  tdc_eval_event.tdc_event[MCP1][tdc_eval_event.foundChannel[MCP1]-1] += // incremented by do_channel()
1138  trigger_settings.event_0_settings.mcp1_delay;
1139 
1140  if (masterChannelFastMuon == MCP1)
1141  do_master_channel(MCP1, EVENT_0_TYPE); //to determine pre-pileup
1142 
1143  // set detector flag only if "clean" signal, i.e. no pre-pileup
1144  if ( tdc_eval_event.pileup[MCP1][tdc_eval_event.foundChannel[MCP1]-1] == 0 &&
1146  tdc_eval_event.doEvaluateFastMuonEvent = tdc_eval_event.doEvaluateFastMuonEvent | M1_EVENT;
1147  break;
1148 
1149  case MCP2F:
1150  //add time delay
1151  if (masterChannelSlowMuon == MCP2F) {
1152  tdc_eval_event.tdc_event[MCP2F][tdc_eval_event.foundChannel[MCP2F]-1] +=
1153  trigger_settings.event_1_settings.master_delay;
1154  do_master_channel(MCP2F, EVENT_1_TYPE); //to determine pre-pileup
1155  }
1156  // set detector flag only if "clean" signal, i.e. no pre-pileup, and if event enabled
1157  // in case of MCP2F not used as "master" tdc_eval_event.pileup[MCP2F][j]=0 for all j
1158  if (tdc_eval_event.pileup[MCP2F][tdc_eval_event.foundChannel[MCP2F]-1] == 0 && // incremented by do_channel()
1160  tdc_eval_event.doEvaluateSlowMuonEvent = tdc_eval_event.doEvaluateSlowMuonEvent | M2_EVENT;
1161  break;
1162 
1163  case TD:
1164  // add time delay
1165  if (trigger_settings.events.event_1_active && masterChannelSlowMuon == TD)
1166  tdc_eval_event.tdc_event[TD][tdc_eval_event.foundChannel[TD]-1] += // incremented by do_channel()
1167  trigger_settings.event_1_settings.master_delay;
1168  else if (trigger_settings.events.event_2_active)
1169  tdc_eval_event.tdc_event[TD][tdc_eval_event.foundChannel[TD]-1] += // incremented by do_channel()
1170  trigger_settings.event_2_settings.td_delay;
1171 
1172  if (masterChannelSlowMuon == TD)
1173  do_master_channel(TD, EVENT_1_TYPE | EVENT_2_TYPE); //to determine pre-pileup
1174 
1175  // set detector flag only if "clean" signal, i.e. no pre-pileup, and if event enabled
1176  // in case of TD not used as "master" tdc_eval_event.pileup[TD][j]=0 for all j
1177  if (tdc_eval_event.pileup[TD][tdc_eval_event.foundChannel[TD]-1] == 0 &&
1178  (eventDefinedSlowMuon & TD_EVENT)) // incremented by do_channel()
1179  tdc_eval_event.doEvaluateSlowMuonEvent = tdc_eval_event.doEvaluateSlowMuonEvent | TD_EVENT;
1180  break;
1181  /* -------------------- e n d of "Master" detectors -----------------------------------------------*/
1182 
1183  /* ------------------- beam counter with 8 segments ------------------------------------------------*/
1184  case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1185  // check pre-pileup
1186  if ((tdc_pileup.endBeamCounterEvent - runTime) < (U_LONG) trigger_settings.tof_bc_pileup_window)
1187  tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1] = 1;
1188  else if ((tdc_pileup.endBeamCounterEvent - runTime) > (U_LONG) trigger_settings.tof_bc_pileup_window)
1189  vme_stats.bc_clean++;
1190  else // this means tdc_pileup.endBeamCounterEvent - runTime = bc_pileup_window; event "re-evaluated"
1191  tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1] = tdc_pileup.lastBeamCounterEventPileup;
1192 
1193  tdc_pileup.lastBeamCounterEventPileup = tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1];
1194  tdc_pileup.endBeamCounterEvent = pileup_end(trigger_settings.tof_bc_pileup_window);
1195 
1196  // set detector flag only if "clean" signal, i.e. no pre-pileup
1197  if (tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1] == 0 &&
1199  tdc_eval_event.doEvaluateFastMuonEvent = tdc_eval_event.doEvaluateFastMuonEvent | BC_EVENT;
1200 
1201  if (tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1] == 0 &&
1202  (eventDefinedSlowMuon & BC_EVENT))
1203  tdc_eval_event.doEvaluateSlowMuonEvent = tdc_eval_event.doEvaluateSlowMuonEvent | BC_EVENT;
1204 
1205  // problem: BC appears before the "Master" detectors MCP1 or TD/MCP2; for event evaluation it is more simple
1206  // to have the master first, otherwise, there can be data lost accross a new event evaluation.
1207  // BC event losses can be avoided by "reverse" timing: delay BC by TOF window width; add this delay
1208  // to the tdc_eval_event.thisTime's: in this way an event evaluation can be initiated by a BC instead of
1209  // a nearby MCP1 - if the MCP1 is less than TOF window later than BC
1210  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] += trigger_settings.tof_bc_window;
1211  if (eventDefinedFastMuon & BC_EVENT)
1212  tdc_eval_event.thisTimeFastMuon += trigger_settings.tof_bc_window;
1213  if (eventDefinedSlowMuon & BC_EVENT)
1214  tdc_eval_event.thisTimeSlowMuon += trigger_settings.tof_bc_window;
1215 
1216  break;
1217  /* ---------------- e n d of beam counter -----------------------------------------------------------*/
1218 
1219  case POSMCP1I: case POSMCP1O:
1220  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] +=
1221  trigger_settings.event_0_settings.positron_delay;
1222  if (tdc_eval_event.foundChannel[channel] == 1 && (eventDefinedFastMuon & M1_POSITRON_EVENT))
1223  tdc_eval_event.doEvaluateFastMuonEvent |= M1_POSITRON_EVENT;
1224  break;
1225 
1226  case POSLDI: case POSLDO: case POSLUI: case POSLUO:
1227  case POSTDI: case POSTDO: case POSTUI: case POSTUO:
1228  case POSRDI: case POSRDO: case POSRUI: case POSRUO:
1229  case POSBDI: case POSBDO: case POSBUI: case POSBUO:
1230  if (trigger_settings.events.event_1_active)
1231  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] +=
1232  trigger_settings.event_1_settings.positron_delay;
1233  else
1234  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] +=
1235  trigger_settings.event_2_settings.positron_delay;
1236 
1237  if (tdc_eval_event.foundChannel[channel] == 1 && (eventDefinedSlowMuon & LE_POSITRON_EVENT))
1238  tdc_eval_event.doEvaluateSlowMuonEvent |= LE_POSITRON_EVENT;
1239  break;
1240 
1241  case MCP2R: case MCP2X1: case MCP2X2: case MCP2Y1: case MCP2Y2:
1243  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] +=
1244  trigger_settings.event_1_settings.master_delay;
1245  break;
1246 
1247  case EXTON1:
1248  flag_external_on = TRUE;
1249  nextGoodTime = runTime + (U_LONG) 5120*trigger_settings.delay_daq_usec_; // 1usec = 5120 TDC bins
1250  break;
1251 
1252  case EXTOFF1:
1253  flag_external_on = FALSE;
1254  nextGoodTime = runTime + (U_LONG) 5120*trigger_settings.delay_daq_usec_; // 1usec = 5120 TDC bins
1255  break;
1256 
1257  case CLOCK:
1258  break;
1259 
1260  default:
1261  break;
1262  }
1263 
1264  diffTimeFastMuon = tdc_eval_event.thisTimeFastMuon - tdc_eval_event.lastTimeFastMuon;
1265  diffTimeSlowMuon = tdc_eval_event.thisTimeSlowMuon - tdc_eval_event.lastTimeSlowMuon;
1266  // 28-Mar-2006: the following corrections on diffTimeFast/SlowMuon are still needed,
1267  // ----------- since tdc_eval_event.t0 is obsolete
1268  //
1269  // the following is needed to avoid segmentation fault of the frontend in case of
1270  // enabled events 0 and 1 (M1,TD/M2); due to non-ascening order of time stamps in
1271  // TDC it may happen that we have a new event like
1272  // 1 (clock) 336 = t0 event time 0
1273  // 2 (MCP1) 312 event time -24 --> 524264, difftime 0
1274  // 2 (MCP1) 1012 event time 676 --> difftime to last MCP1 -523588 instead of 700
1275  // in this case the MCP1
1276  //
1277  if (diffTimeFastMuon < 0 && abs(diffTimeFastMuon) >= t0_offset)
1278  diffTimeFastMuon += TDC_BIT_RANGE;
1279  else if ( diffTimeFastMuon < 0 && abs(diffTimeFastMuon) < t0_offset )
1280  diffTimeFastMuon += t0_offset;
1281 
1282  if (diffTimeSlowMuon < 0 && abs(diffTimeSlowMuon) >= t0_offset)
1283  diffTimeSlowMuon += TDC_BIT_RANGE;
1284  else if ( diffTimeSlowMuon < 0 && abs(diffTimeSlowMuon) < t0_offset )
1285  diffTimeSlowMuon += t0_offset;
1286 
1287 #ifdef TESTOUT
1288  fprintf(fp,
1289  "raw data = %6d %3d %7d 0x%08x, vmeTime = %10.5e, difftime = %8d, ev.time = %8d, pu-flag = %2d, 0x%04x\n",
1290  i, channel, tdc_time, output_buffer[i],
1291  vme_stats.run_time,
1292  diffTimeSlowMuon, tdc_eval_event.event_time,
1293  tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1],
1294  tdc_eval_event.doEvaluateSlowMuonEvent);
1295 #endif
1296 
1297  if ((tdc_eval_event.doEvaluateSlowMuonEvent == eventDefinedSlowMuon) &&
1298  (diffTimeSlowMuon > (dataWindowSlowMuon + t0_offset))) {
1300  i--; // we have to check if the current hit is a candidate for a new event
1301  vme_stats.channelCounts[channel]--; // avoid double counting
1302  } else if ((tdc_eval_event.doEvaluateFastMuonEvent == eventDefinedFastMuon) &&
1303  (diffTimeFastMuon > (dataWindowFastMuon + t0_offset))) {
1305  i--; // we have to check if the current hit is a candidate for a new event
1306  vme_stats.channelCounts[channel]--; // avoid double counting
1307  } else if (channel == CLOCK ) {
1308  //check for successice clock events; if present reset tdc_eval_event structure
1309  if (i - tdc_eval_event.clockIndex == 1 && i !=1) {
1310  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1311  //continue;
1312  }
1313  if (i == sum_lwords - 1) // two handle successive clock events correctly when new
1314  tdc_eval_event.clockIndex = -1; // output buffer is scanned
1315  else
1316  tdc_eval_event.clockIndex = i;
1317  }
1318 
1319  // removed all the time exceeding handling which appeared here at versions <= 1738
1320  }
1321 
1322  free(output_buffer);
1323 
1324  return SUCCESS;
1325 }
1326 /*-----------------------------------------------------------------------------------------*/
1333 INT do_channel(INT ch, INT TDCtime)
1334 {
1335  INT diff_toLastEvent;
1336 
1337  //introduce a trigger_settings.t0_offset to handle events like:
1338  // MCP1 380
1339  // e+_I 370
1340  // e+_O 375
1341  // without special handling this would lead to a diff_time = diff_time + TDC_BIT_RANGE
1342  // which is a big number and can be greater than the data gate - in which case the event
1343  // would be rejected
1344  if ( tdc_eval_event.set_t0 == 0) { //a new event evaluation has started;
1345  tdc_eval_event.event_time = t0_offset;
1346  tdc_eval_event.set_t0++;
1347  }
1348 
1349  diff_toLastEvent = TDCtime - vme_stats.last_TDCtime;
1350  if (diff_toLastEvent < DIFF_TOLERANCE)
1351  diff_toLastEvent += TDC_BIT_RANGE; //only add TDC_BIT_RANGE if time difference is > abs(DIFF_TOLERANCE)
1352  //allow for "small" negative time differences, i.e. for event sequences
1353  //as shown above
1354  vme_stats.last_TDCtime = TDCtime;
1355  tdc_eval_event.event_time += diff_toLastEvent;
1356  //calculate the absolute run time in TDC LSB units
1357  runTime += (U_LONG) diff_toLastEvent;
1358  vme_stats.run_time = (double) runTime; //copy to ODB structure
1359 
1360  tdc_eval_event.thisTimeFastMuon = tdc_eval_event.thisTimeSlowMuon = tdc_eval_event.event_time;
1361 
1362  tdc_eval_event.tdc_event[ch][tdc_eval_event.foundChannel[ch]] = tdc_eval_event.event_time;
1363  tdc_eval_event.foundChannel[ch]++;
1364 
1365  return SUCCESS;
1366 }
1367 /*-----------------------------------------------------------------------------------------*/
1368 INT do_master_channel(INT ch, INT event_type)
1369 {
1370  switch (event_type){
1371  case EVENT_0_TYPE: // "fast" muons
1372  //check pre-pileup
1373  //the following works because we're using unsigned integers:
1374  //for a clean signal, tdc_pileup.endMasterEvent0 - runTime < 0, but this becomes
1375  //"a large number > 0" if we are dealing with unsigned integers only.
1376  if ((tdc_pileup.endMasterEvent0 - runTime) < (U_LONG) dataWindowFastMuon) // we had a pre-pileup
1377  tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1] = 1;
1378  else if ((tdc_pileup.endMasterEvent0 - runTime) > (U_LONG) dataWindowFastMuon) { // this is a "clean" signal
1379  vme_stats.mcp1_clean++; // i.e. no pre-pileup
1380  vme_stats.mcp1_good++; //this could be a potential "good" event
1381  if (tdc_eval_event.doEvaluateFastMuonEvent != eventDefinedFastMuon ){
1382  tdc_eval_event.lastTimeFastMuon = tdc_eval_event.thisTimeFastMuon;
1383  tdc_eval_event.indexFastMuon = tdc_eval_event.foundChannel[ch]-1;
1384  tdc_eval_event.indexFastMuonSet++;
1385  }
1386  } else { // this means tdc_pileup.endMasterEvent0 - runTime = dataWindowFastMuon; event "re-evaluated"
1387  tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1] = tdc_pileup.lastMasterEvent0Pileup;
1388  // for mcp1_good event determination across two tdc_eval_event's
1389  if (tdc_pileup.lastMasterEvent0Pileup == 0) tdc_eval_event.indexFastMuonSet++;
1390  }
1391 
1392  // check for post-pileup to count "mcp1_good" event (no pre- and post-pileup)
1393  // - check, if we had a pile-up
1394  // - then check, if previous event was a clean event; in this case lower mcp1_good;
1395  // in case of subsequent pileup events don't decrease mcp1_good
1396  // - the "tdc_eval_event.indexFastMuonSet > 0" condition is needed to get the correct
1397  // counting across two event evaluations
1398  if (tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1] == 1) {
1399  if ((tdc_eval_event.foundChannel[ch]-1 - tdc_eval_event.indexFastMuon == 1) &&
1400  tdc_eval_event.indexFastMuonSet > 0)
1401  vme_stats.mcp1_good--;
1402  }
1403  tdc_pileup.lastMasterEvent0Pileup = tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1];
1404  tdc_pileup.endMasterEvent0 = pileup_end(dataWindowFastMuon);
1405 #ifdef TESTOUT
1406  fprintf(fp,"runTime = %12d, PUend = %12d, pu = %04d, clean = %6d, good = %6d\n",
1407  (int) runTime,
1408  (int) tdc_pileup.endMasterEvent0,
1409  tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1],
1410  (int) vme_stats.mcp1_clean, (int) vme_stats.mcp1_good);
1411 #endif
1412  break;
1413 
1414  case EVENT_1_TYPE: case EVENT_2_TYPE: case EVENT_1_TYPE | EVENT_2_TYPE: // "slow" muons
1415  //check pre-pileup
1416  if ((tdc_pileup.endMasterEvent1or2 - runTime) < (U_LONG) dataWindowSlowMuon) // we have a pre-pileup
1417  tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1] = 1;
1418  else if ((tdc_pileup.endMasterEvent1or2 - runTime) > (U_LONG) dataWindowSlowMuon) { // this is a "clean" signal
1419  if (ch == MCP2F) {
1420  vme_stats.mcp2_clean++; // i.e. no pre-pileup
1421  vme_stats.mcp2_good++; // a potential candidate without post-pileup
1422  }
1423  if (ch == TD ) {
1424  vme_stats.td_clean++; // i.e. no pre-pileup
1425  vme_stats.td_good++; // a potential candidate without post-pileup
1426  }
1427 
1428  if (tdc_eval_event.doEvaluateSlowMuonEvent != eventDefinedSlowMuon) {
1429  // to avoid that an event sequence like
1430  // 4-26-27-28-29-30-31-4 (== TD-MCP2F-MCP2R-MCP2X1-MCP2X2-MCP2Y1-MCP2Y2-TD)
1431  // get's the wrong TD_clean signal for event evaluatio (the 2nd one in this example)
1432  tdc_eval_event.lastTimeSlowMuon = tdc_eval_event.thisTimeSlowMuon;
1433  tdc_eval_event.indexSlowMuon = tdc_eval_event.foundChannel[ch]-1;
1434  tdc_eval_event.indexSlowMuonSet++;
1435  }
1436  } else { // this means tdc_pileup.endMasterEvent1or2 - runTime = dataWindowSlowMuon; event "re-evaluated"
1437  tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1] = tdc_pileup.lastMasterEvent1or2Pileup;
1438  // for mcp2/TD_good event determination across two tdc_eval_event's
1439  if (tdc_pileup.lastMasterEvent1or2Pileup == 0) tdc_eval_event.indexSlowMuonSet++;
1440  }
1441  // check for post-pileup to count "mcp2/TD_good" event (no pre- and post-pileup)
1442  // - check, if we had a pile-up
1443  // - then check, if previous event was a clean event; in this case lower mcp1_good;
1444  // in case of subsequent pileup events don't decrease mcp2/TD_good
1445  // - the "tdc_eval_event.indexSlowMuonSet > 0" condition is needed to get the correct
1446  // counting across two event evaluations
1447  if (tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1] == 1) {
1448  if ((tdc_eval_event.foundChannel[ch]-1 - tdc_eval_event.indexSlowMuon == 1) &&
1449  tdc_eval_event.indexSlowMuonSet > 0) {
1450  if ( ch == MCP2F ) vme_stats.mcp2_good--;
1451  if ( ch == TD ) vme_stats.td_good--;
1452  }
1453  }
1454  tdc_pileup.lastMasterEvent1or2Pileup = tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1];
1455  tdc_pileup.endMasterEvent1or2 = pileup_end(dataWindowSlowMuon);
1456  break;
1457 
1458  default:
1459  break;
1460  }
1461 
1462  return 0;
1463 }
1464 /*-----------------------------------------------------------------------------------------*/
1471 U_LONG pileup_end(INT pileupWindow)
1472 {
1473  U_LONG end_time;
1474 
1475  end_time = runTime + (U_LONG) pileupWindow;
1476  return end_time;
1477 }
1478 /*-----------------------------------------------------------------------------------------*/
1487 {
1488  INT i, j, k, masterIndex;
1489  INT decChannel[8], decInd[8], bcChannel, bcInd, tdChannel, tdInd, m2Channel, m2Ind;
1490  DWORD dataWindow;
1491  BOOL good_event, pos_event, bc_event, posL_event, posT_event, posR_event, posB_event;
1492  BOOL mcp2_event;
1493  LEM_DATA *lem_data;
1494  U_LONG masterRunTime;
1495 
1496 #ifdef TESTOUT
1497  fprintf(fp,"evaluate_slow_muon_event, M2clean = %10.0f, TDclean = %10.0f\n", vme_stats.mcp2_clean, vme_stats.td_clean);
1498 #endif
1499 
1500  good_event = pos_event = bc_event = mcp2_event = FALSE;
1501  posL_event = posT_event = posR_event = posB_event = FALSE;
1502  masterIndex = tdc_eval_event.indexSlowMuon;
1503 
1504  //for "on/off" ("red/green") mode check if we are ready for next event after waiting
1505  //trigger_settings.delay_onoff_mode TDC channels
1506  //we have to check if the last "clean" master channel time in absolute runTime is > nextGoodTime.
1507  //if not, return immediately
1508  if (trigger_settings.enable_onoff_mode) {
1509  masterRunTime = runTime -
1510  (U_LONG) (tdc_eval_event.event_time - tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex]);
1511  if (masterRunTime < nextGoodTime){
1512  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1513  return SUCCESS;
1514  }
1515  }
1516 
1517  bcChannel = bcInd = m2Channel = m2Ind = tdChannel = tdInd = -1; //initialize
1518 
1519  for (i=0; i<8; i++)
1520  decChannel[i] = decInd[i] = -1;
1521 
1522  if (trigger_settings.events.event_1_active) {
1523  dataWindow = trigger_settings.event_1_settings.data_window;
1524  //always check TOF TD-MCP2 for Event1 type
1525  if ( masterChannelSlowMuon == TD )
1526  mcp2_event = check_tof_and_pileup( MASTERFIRST, trigger_settings.event_1_settings.tof_m2_window,
1527  MCP2F, MCP2F, TD, masterIndex, &m2Channel, &m2Ind);
1528  else
1529  mcp2_event = check_tof_and_pileup( MASTERLAST, trigger_settings.event_1_settings.tof_m2_window,
1530  TD, TD, MCP2F, masterIndex, &tdChannel, &tdInd);
1531  }
1532  else
1533  dataWindow = trigger_settings.event_2_settings.data_window;
1534 
1535  //check positrons always, since they are always enabled in TDC
1536  posL_event = check_positron(dataWindow, 50, POSLDI, POSLDO, masterChannelSlowMuon, masterIndex,
1537  &decChannel[0], &decInd[0]) ||
1538  check_positron(dataWindow, 50, POSLUI, POSLUO, masterChannelSlowMuon, masterIndex,
1539  &decChannel[1], &decInd[1]);
1540  posT_event = check_positron(dataWindow, 50, POSTDI, POSTDO, masterChannelSlowMuon, masterIndex,
1541  &decChannel[2], &decInd[2]) ||
1542  check_positron(dataWindow, 50, POSTUI, POSTUO, masterChannelSlowMuon, masterIndex,
1543  &decChannel[3], &decInd[3]);
1544  posR_event = check_positron(dataWindow, 50, POSRDI, POSRDO, masterChannelSlowMuon, masterIndex,
1545  &decChannel[4], &decInd[4]) ||
1546  check_positron(dataWindow, 50, POSRUI, POSRUO, masterChannelSlowMuon, masterIndex,
1547  &decChannel[5], &decInd[5]);
1548  posB_event = check_positron(dataWindow, 50, POSBDI, POSBDO, masterChannelSlowMuon, masterIndex,
1549  &decChannel[6], &decInd[6]) ||
1550  check_positron(dataWindow, 50, POSBUI, POSBUO, masterChannelSlowMuon, masterIndex,
1551  &decChannel[7], &decInd[7]);
1552  pos_event = posL_event || posT_event || posR_event || posB_event;
1553 
1554 // check BC if enabled in Event definition, *Dec 2020*
1555 /* if (eventDefinedSlowMuon & BC_EVENT)
1556  bc_event = check_tof_and_pileup( MASTERFIRST, trigger_settings.tof_bc_window, BCL1, BCR4, masterChannelSlowMuon, masterIndex,
1557  &bcChannel, &bcInd);
1558  */
1559 
1560  switch (eventDefinedSlowMuon) {
1561  case (M2_EVENT):
1562  case (TD_EVENT):
1563  good_event = TRUE;
1564  break;
1565 
1566  case (TD_EVENT | M2_EVENT):
1567  good_event = mcp2_event;
1568  break;
1569 
1570  case ( M2_EVENT | BC_EVENT):
1571  case ( TD_EVENT | BC_EVENT ):
1572  good_event = bc_event;
1573  break;
1574 
1575  case ( M2_EVENT | LE_POSITRON_EVENT ):
1576  case ( TD_EVENT | LE_POSITRON_EVENT ):
1577  good_event = pos_event;
1578  break;
1579 
1580  case ( M2_EVENT | BC_EVENT | LE_POSITRON_EVENT ):
1581  case ( TD_EVENT | BC_EVENT | LE_POSITRON_EVENT ):
1582  good_event = pos_event && bc_event;
1583  break;
1584 
1585  case (TD_EVENT | M2_EVENT | BC_EVENT):
1586  good_event = mcp2_event && bc_event;
1587  break;
1588 
1589  case (TD_EVENT | M2_EVENT | LE_POSITRON_EVENT):
1590  good_event = mcp2_event && pos_event;
1591  break;
1592 
1594  good_event = mcp2_event && pos_event && bc_event;
1595  break;
1596 
1597  default:
1598  break;
1599  }
1600 
1601  // ----------------------
1602  // no event found, reset arrays and return
1603  if (!good_event) {
1604  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1605  return SUCCESS;
1606  }
1607 
1608  // -----------------------
1609  // we have a valid event
1610  // build event in the form
1611  // ch4:1st Hit (1st MCP2/TD clean)
1612  // ch4:2nd Hit
1613  // ...
1614  // ch6:1st Hit
1615  // ...
1616  k = 0;
1617 // for (i=2; i<N_TDC_CHANNELS; i++) { // i=0 is Ip, i=1 10kHz clock
1618  for (i=1; i<N_TDC_CHANNELS; i++) { // i=0 is Ip, i=1 10kHz clock: put in channel 1 the run time from vme_stats.channelCounts[1]/100. *June 2021*
1619  switch (i) {
1620 // --- *Dec 2020* ---
1621 // case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1622 // if ( bcChannel == -1 ) continue;
1623 // break;
1624  case CLOCK: // *June 2021*: put incremented 10 kHz count/100 into first TDC channel data
1625  tdc_eval_event.tdc_event[CLOCK][0] = (INT) vme_stats.channelCounts[CLOCK]/100.;
1626  tdc_eval_event.foundChannel[CLOCK] = 1;
1627  break;
1628  case POSLDI: case POSLDO:
1629  if ( decChannel[0] == -1 ) continue;
1630  break;
1631  case POSLUI: case POSLUO:
1632  if ( decChannel[1] == -1 ) continue;
1633  break;
1634  case POSTDI: case POSTDO:
1635  if ( decChannel[2] == -1 ) continue;
1636  break;
1637  case POSTUI: case POSTUO:
1638  if ( decChannel[3] == -1 ) continue;
1639  break;
1640  case POSRDI: case POSRDO:
1641  if ( decChannel[4] == -1 ) continue;
1642  break;
1643  case POSRUI: case POSRUO:
1644  if ( decChannel[5] == -1 ) continue;
1645  break;
1646  case POSBDI: case POSBDO:
1647  if ( decChannel[6] == -1 ) continue;
1648  break;
1649  case POSBUI: case POSBUO:
1650  if ( decChannel[7] == -1 ) continue;
1651  break;
1652 
1653  default:
1654  break;
1655  }
1656  for (j=0; j<tdc_eval_event.foundChannel[i]; j++) {
1657  switch (i) {
1658  case TD:
1659  if ( masterChannelSlowMuon == TD && j < masterIndex ) // this is not a "clean" signal
1660  continue;
1661  if ( masterChannelSlowMuon == MCP2F )
1662  if ( j < tdInd || tdInd == -1) continue; // one could "save" the || if default would be 2^(16) instead of
1663  break; // -1, for example; with -1 it may be better "readable" for human
1664  // beings
1665  case MCP2F: case MCP2R:
1666  if ( masterChannelSlowMuon == MCP2F && j < masterIndex ) // this is not a "clean" signal
1667  continue;
1668  if ( masterChannelSlowMuon == TD)
1669  if ( j < m2Ind || m2Ind == -1 ) continue;
1670  break;
1671 
1672  case MCP2X1: case MCP2X2: case MCP2Y1: case MCP2Y2:
1673  if ( masterChannelSlowMuon == MCP2F){
1674  if ( (tdc_eval_event.tdc_event[MCP2F][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0 )
1675  continue;
1676  }
1677  if ( masterChannelSlowMuon == TD) {
1678  if ( m2Ind == -1) continue;
1679  if ( (tdc_eval_event.tdc_event[MCP2F][m2Ind] - tdc_eval_event.tdc_event[i][j]) > 0 )
1680  continue;
1681  }
1682  break;
1683 // *Dec 2020*
1684 // case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1685 // // don't put BC data to data buffer if they are more than "tofPileupWindow" from the "good" BC count
1686 // if ( abs(tdc_eval_event.tdc_event[i][j] - tdc_eval_event.tdc_event[bcChannel][bcInd]) >
1687 // trigger_settings.tof_bc_pileup_window)
1688 // continue;
1689 // break;
1690  case POSLDI: case POSLDO:
1691  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1692  if ( i == decChannel[0] && j < decInd[0] ) // the first e+ event in the data of i=decChannel
1693  continue; // will be the first coincidence found
1694  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1695  continue;
1696  break;
1697  case POSLUI: case POSLUO:
1698  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1699  if ( i == decChannel[1] && j < decInd[1] ) // the first e+ event in the data of i=decChannel
1700  continue; // will be the first coincidence found
1701  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1702  continue;
1703  break;
1704  case POSTDI: case POSTDO:
1705  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1706  if ( i == decChannel[2] && j < decInd[2] ) // the first e+ event in the data of i=decChannel
1707  continue; // will be the first coincidence found
1708  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1709  continue;
1710  break;
1711  case POSTUI: case POSTUO:
1712  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1713  if ( i == decChannel[3] && j < decInd[3] ) // the first e+ event in the data of i=decChannel
1714  continue; // will be the first coincidence found
1715  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1716  continue;
1717  break;
1718  case POSRDI: case POSRDO:
1719  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1720  if ( i == decChannel[4] && j < decInd[4] ) // the first e+ event in the data of i=decChannel
1721  continue; // will be the first coincidence found
1722  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1723  continue;
1724  break;
1725  case POSRUI: case POSRUO:
1726  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1727  if ( i == decChannel[5] && j < decInd[5] ) // the first e+ event in the data of i=decChannel
1728  continue; // will be the first coincidence found
1729  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1730  continue;
1731  break;
1732  case POSBDI: case POSBDO:
1733  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1734  if ( i == decChannel[6] && j < decInd[6] ) // the first e+ event in the data of i=decChannel
1735  continue; // will be the first coincidence found
1736  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1737  continue;
1738  break;
1739  case POSBUI: case POSBUO:
1740  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1741  if ( i == decChannel[7] && j < decInd[7] ) // the first e+ event in the data of i=decChannel
1742  continue; // will be the first coincidence found
1743  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1744  continue;
1745  break;
1746 
1747  default:
1748  break;
1749  }
1750  k = ++tdc_eval_event.eventSize;
1751  if (k > DATA_N_HITS) { //max. DATA_N_HITS hits to output data stream
1752  tdc_eval_event.eventSize -= 1;
1753  break;
1754  }
1755  lem_data = (LEM_DATA *) &tdc_eval_event.tdc_data[k];
1756  lem_data->data = tdc_eval_event.tdc_event[i][j];
1757  lem_data->channel = i;
1758  // tdc_eval_event.tdc_data[k] =
1759  // ((tdc_eval_event.tdc_data[k] | i)<<24 ) | tdc_eval_event.tdc_event[i][j]; //copy channel
1760  }
1761  }
1762  if (trigger_settings.events.event_1_active)
1763  tdc_eval_event.eventType = EVENT_1_TYPE;
1764  else
1765  tdc_eval_event.eventType = EVENT_2_TYPE;
1766 
1767  if (flag_external_on) {
1768  tdc_eval_event.tdc_data[0] =
1769  (tdc_eval_event.tdc_data[0] | NEW_EVENT_MASK) | // bits 24-30 set indicating new event
1770  (tdc_eval_event.tdc_data[0] | EXTON1_FLAG) |
1771  ((tdc_eval_event.tdc_data[0] | tdc_eval_event.eventType)<<16) |
1772  tdc_eval_event.eventSize;
1773  } else {
1774  tdc_eval_event.tdc_data[0] =
1775  (tdc_eval_event.tdc_data[0] | NEW_EVENT_MASK) | // bits 24-30 set indicating new event
1776  (tdc_eval_event.tdc_data[0] | EXTOFF1_FLAG) |
1777  ((tdc_eval_event.tdc_data[0] | tdc_eval_event.eventType)<<16) |
1778  tdc_eval_event.eventSize;
1779  }
1780  for (j=0; j < tdc_eval_event.eventSize+1; j++) {
1782  *p_write++ = tdc_eval_event.tdc_data[j];
1783  } else { //jump to beginning of ring buffer
1784  p_write = &databuffer[0];
1785  *p_write++ = tdc_eval_event.tdc_data[j];
1786  }
1787 #ifdef TESTOUT
1788  lem_data = (LEM_DATA *) &tdc_eval_event.tdc_data[j];
1789  fprintf(fp,"tdc data = %02d, %8d, channel %4d, hex = 0x%08x\n", j,
1790  lem_data->data,
1791  lem_data->channel,
1792  tdc_eval_event.tdc_data[j]);
1793 #endif
1794  }
1795 
1796  vme_stats.slowMuonEvents++;
1797  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1798 
1799  return SUCCESS;
1800 }
1801 /*-----------------------------------------------------------------------------------------*/
1810 {
1811  INT i, j, k, bcChannel, bcInd, decChannel, decInd, masterIndex;
1812  BOOL good_event, bc_event, pos_event;
1813  LEM_DATA *lem_data;
1814 
1815 #ifdef TESTOUT
1816  fprintf(fp,"evaluate_fast_muon_event, mcp1 = %10.0f, mcp1 clean = %10.0f\n",
1817  vme_stats.channelCounts[MCP1], vme_stats.mcp1_clean);
1818 #endif
1819 
1820  good_event = bc_event = pos_event = FALSE;
1821  masterIndex = tdc_eval_event.indexFastMuon;
1822  bcChannel = bcInd = decChannel = decInd = -1; //initialize
1823 
1824  //always check positron since they are always enabled if Ev0 is active
1825  pos_event = check_positron(trigger_settings.event_0_settings.data_window, 50, POSMCP1I, POSMCP1O, MCP1, masterIndex, &decChannel, &decInd);
1826 
1828  bc_event = check_tof_and_pileup( MASTERFIRST, trigger_settings.tof_bc_window, BCL1, BCR4, MCP1, masterIndex, &bcChannel, &bcInd);
1829 
1830  switch (eventDefinedFastMuon) {
1831  case (BC_EVENT | M1_EVENT):
1832  good_event = bc_event;
1833  break;
1834 
1835  case (M1_EVENT | M1_POSITRON_EVENT ):
1836  good_event = pos_event;
1837  break;
1838 
1839  case (M1_EVENT | M1_POSITRON_EVENT | BC_EVENT):
1840  good_event = bc_event && pos_event;
1841  break;
1842 
1843  default:
1844  break;
1845  }
1846 
1847  // ----------------------
1848  // if no event found, reset arrays and return
1849  if (!good_event) {
1850  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1851  return SUCCESS;
1852  }
1853  // -----------------------
1854  // we have a valid event
1855  // build event in the form
1856  // ch2:1st Hit (1st MCP1 clean)
1857  // ch2:2nd Hit
1858  // ...
1859  // ch6:1st Hit
1860  // ...
1861  k = 0;
1862  for (i=2; i<N_TDC_CHANNELS; i++) {// i=0 is Ip, i=1 10kHz clock
1863  switch (i){
1864  case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1865  if ( bcChannel == -1 ) continue;
1866  break;
1867 
1868  case POSMCP1I: case POSMCP1O:
1869  if ( decChannel == -1 ) continue;
1870  break;
1871 
1872  default:
1873  break;
1874  }
1875 
1876  for (j=0; j<tdc_eval_event.foundChannel[i]; j++) {
1877  switch (i) {
1878  case MCP1:
1879  if (masterChannelFastMuon == MCP1 && j < masterIndex) // this is not a "clean" signal
1880  continue;
1881  break;
1882 
1883  case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1884  // don't put BC data to data buffer if they are more than 1musec from the "good" BC count
1885  if ( abs(tdc_eval_event.tdc_event[i][j] - tdc_eval_event.tdc_event[bcChannel][bcInd]) >
1886  trigger_settings.tof_bc_pileup_window)
1887  continue;
1888  break;
1889 
1890  case POSMCP1I: case POSMCP1O:
1891  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1892  if ( i == decChannel && j < decInd ) // the first e+ event in the data of i=decChannel
1893  continue; // will be the first coincidence found
1894  if ( (tdc_eval_event.tdc_event[MCP1][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1895  continue;
1896  break;
1897 
1898  default:
1899  break;
1900  }
1901  k = ++tdc_eval_event.eventSize;
1902  if (k > DATA_N_HITS) { //max. DATA_N_HITS hits to output data stream
1903  tdc_eval_event.eventSize -= 1;
1904  break;
1905  }
1906  lem_data = (LEM_DATA *) &tdc_eval_event.tdc_data[k];
1907  lem_data->data = tdc_eval_event.tdc_event[i][j];
1908  lem_data->channel = i;
1909  // tdc_eval_event.tdc_data[k] =
1910  // ((tdc_eval_event.tdc_data[k] | i)<<24 ) | tdc_eval_event.tdc_event[i][j]; //copy channel
1911  }
1912  }
1913  tdc_eval_event.tdc_data[0] =
1914  (tdc_eval_event.tdc_data[0] | NEW_EVENT_MASK) | // bits 24-30 set indicating new event
1915  ((tdc_eval_event.tdc_data[0] | EVENT_0_TYPE)<<16) |
1916  tdc_eval_event.eventSize;
1917 
1918  for (j = 0; j < tdc_eval_event.eventSize+1; j++) {
1920  *p_write++ = tdc_eval_event.tdc_data[j];
1921  } else { //jump to beginning of ring buffer
1922  p_write = &databuffer[0];
1923  *p_write++ = tdc_eval_event.tdc_data[j];
1924  }
1925 #ifdef TESTOUT
1926  lem_data = (LEM_DATA *) &tdc_eval_event.tdc_data[j];
1927  fprintf(fp,"tdc data = %02d, %8d, channel %4d, hex = 0x%08x, ch = %4d, index = %4d\n",
1928  j,
1929  lem_data->data,
1930  lem_data->channel,
1931  tdc_eval_event.tdc_data[j],
1932  bcChannel, bcInd);
1933 #endif
1934  }
1935 
1936  vme_stats.fastMuonEvents++;
1937  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1938 
1939  return SUCCESS;
1940 }
1941 /* -------------------------------------------------------------------- */
1958 BOOL check_tof_and_pileup(INT timing, INT tofWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex,
1959  INT *channel, INT *ind)
1960 {
1961  INT i, j;
1962  INT difftime_now, difftime_last;
1963 
1964  if ( timing == MASTERLAST )
1965  difftime_now = difftime_last = 0;
1966  else
1967  difftime_now = difftime_last = 2 * tofWindow;
1968  *channel = *ind = -1;
1969  for (i=firstCh; i <= lastCh; i++) {
1970  //the following is for "MasterLast" timing; may lead to loss of some events
1971  if ( timing == MASTERLAST){
1972  for ( j = 0; j < tdc_eval_event.foundChannel[i]; j++){ // get the most distant hit within the TOF window
1973  difftime_now = tdc_eval_event.tdc_event[masterChannel][masterIndex] - tdc_eval_event.tdc_event[i][j];
1974 
1975  if (difftime_now < tofWindow && difftime_now > 0) {
1976  if (difftime_now > difftime_last) {
1977  difftime_last = difftime_now;
1978  *channel = i;
1979  *ind = j;
1980  }
1981  }
1982  }
1983  } else {
1984  // for "MasterFirst" timing: each "good" hit is assumed to appear after the master detector hit
1985  for (j=0; j < tdc_eval_event.foundChannel[i]; j++) { // get the nearest hit within the TOF window
1986  difftime_now = tdc_eval_event.tdc_event[i][j] - tdc_eval_event.tdc_event[masterChannel][masterIndex];
1987 
1988  if (difftime_now < tofWindow && difftime_now > 0) {
1989  if (difftime_now < difftime_last) {
1990  difftime_last = difftime_now;
1991  *channel = i;
1992  *ind = j;
1993  }
1994  }
1995  }
1996  }
1997  }
1998  if ( *channel == -1 ) return FALSE; // we didn't find an tof/decay event
1999 
2000  // ----------------------
2001  // check pileup;
2002  //
2003  if ( tdc_eval_event.pileup[*channel][*ind] == 1 ) {
2004 #ifdef TESTOUT
2005  fprintf(fp, " TOF pileup at channel %d, hit %d\n", *channel, *ind);
2006 #endif
2007  return FALSE;
2008  }
2009  return TRUE; // if we come to this point we found an event and no pre-pileup
2010 }
2011 /* -------------------------------------------------------------------- */
2026 BOOL check_positron(INT decWindow, INT coincWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex,
2027  INT *channel, INT *ind)
2028 {
2029  INT i, j;
2030  INT difftime_now, difftime_last, difftime;
2031 
2032  difftime_now = difftime_last = 2*decWindow; // initialise variables
2033  *channel = *ind = -1;
2034 
2035  if (coincWindow < 0) {
2036  // the following is for single e+ counters
2037  for (i=firstCh; i <= lastCh; i++) {
2038  for (j=0; j < tdc_eval_event.foundChannel[i]; j++) { // get the nearest hit within the decay window
2039  difftime_now = tdc_eval_event.tdc_event[i][j] - tdc_eval_event.tdc_event[masterChannel][masterIndex];
2040 
2041  if (difftime_now < decWindow && difftime_now > 0) {
2042  if ( difftime_now < difftime_last ) {
2043  difftime_last = difftime_now;
2044  *channel = i;
2045  *ind = j;
2046  }
2047  }
2048  }
2049  }
2050  } else {// search for coincidences
2051  if ((tdc_eval_event.foundChannel[firstCh] == 0) || (tdc_eval_event.foundChannel[lastCh] == 0)) return FALSE;
2052 
2053  // check now for coincidences;
2054  // here: assume that corresponding detectors have the ID's
2055  // firstCh, lastCh
2056  // search the next nearest e+ coincidence with respect to the masterChannel
2057  // firstCh makes the timing
2058  for (i=0; i < tdc_eval_event.foundChannel[firstCh]; i++) {
2059  for (j=0; j < tdc_eval_event.foundChannel[lastCh]; j++) {
2060  difftime = abs(tdc_eval_event.tdc_event[firstCh][i] - tdc_eval_event.tdc_event[lastCh][j]);
2061 
2062  if (difftime < coincWindow) {
2063  difftime_now = tdc_eval_event.tdc_event[firstCh][i] - tdc_eval_event.tdc_event[masterChannel][masterIndex];
2064  if (difftime_now < decWindow && difftime_now > 0) {
2065  if (difftime_now < difftime_last) {
2066  difftime_last = difftime_now;
2067  *channel = firstCh;
2068  *ind = i;
2069  }
2070  }
2071  }
2072  }
2073  }
2074  }
2075 
2076  if ( *channel == -1 ) return FALSE; // we didn't find a decay event
2077 
2078  return TRUE; // if we come to this point we found a positron event
2079 }
2080 /********************************************************************\
2081 
2082  Readout routines for different events
2083 
2084 \********************************************************************/
2085 
2086 /*-- Trigger event routines ----------------------------------------*/
2087 
2088 INT poll_event(INT source, INT count, BOOL test)
2089 /* Polling routine for events. Returns TRUE if event
2090  is available. If test equals TRUE, don't return. The test
2091  flag is used to time the polling */
2092 {
2093  //frontend_loop();
2094  if ( vme_stats.poll_counts == 0 ) ss_sleep(100); //if count==1 first call of poll_event from mfe.c
2095  vme_stats.poll_counts++;
2096  if ( (p_read != p_write) && !test ){
2097  //fprintf(fp, "p_read = 0x%x, p_write = 0x%x\n", p_read, p_write);
2098  return 1;
2099  }
2100  return 0;
2101 }
2102 
2103 /*-- Interrupt configuration ---------------------------------------*/
2104 
2105 INT interrupt_configure(INT cmd, INT source, PTYPE adr)
2106 {
2107  switch(cmd) {
2108  case CMD_INTERRUPT_ENABLE:
2109  break;
2110  case CMD_INTERRUPT_DISABLE:
2111  break;
2112  case CMD_INTERRUPT_ATTACH:
2113  break;
2114  case CMD_INTERRUPT_DETACH:
2115  break;
2116  default:
2117  break;
2118  }
2119 
2120  return SUCCESS;
2121 }
2122 
2123 /*-- Event readout -------------------------------------------------*/
2129 INT read_trigger_event(char *pevent, INT off)
2130 {
2131  INT i;
2132  DWORD *pdata;
2133  DWORD ndata;
2134  /*
2135  // SUPER event does not work properly, has to be checked...
2136  //init bank structure, Super event
2137  if ( off == 0 ){
2138  // FIRST event of Super event
2139  bk_init(pevent);
2140  bk_create(pevent, "TDC0", TID_DWORD, &pdata);
2141  }
2142  else if ( off == -1 ){
2143  bk_close(pevent, pdata); //close the super event if off=-1, from mfe.c
2144  return bk_size(pevent);
2145  }
2146 */
2147  //init bank structure
2148  bk_init(pevent);
2149  bk_create(pevent, "TDC0", TID_DWORD, (void**)&pdata);
2150 
2151  // read data from output buffer;
2152  if (p_read == &databuffer[DATABUFFER_SIZE]) //we are 4 bytes off the end of the data buffer, jump
2153  p_read = &databuffer[0]; //to the beginning of the data buffer
2154 
2155  if ( ( *p_read & NEW_EVENT_MASK) != NEW_EVENT_MASK ) return 0; //causes event rate to be 0
2156  //this happens if the read pointer is
2157  //out of sync to the write pointer
2158  ndata = (*p_read & 0x0000FFFF) + 1; //the first entry in the data buffer contains the event size - 1
2159  //fprintf(fp,"eventSize = %d, p_read=0x%08x, p_write=0x%08x\n",ndata, p_read, p_write);
2160  for (i=0; i < ndata; i++) {
2161  if (p_read < &databuffer[DATABUFFER_SIZE]) {
2162  *pdata++ = *p_read;
2163  *p_read = 0;
2164  p_read++;
2165  } else { //jump to beginning of ring buffer
2166  p_read = &databuffer[0];
2167  *pdata++ = *p_read;
2168  *p_read = 0;
2169  p_read++;
2170  }
2171  }
2172 
2173  vme_stats.readcounts++;
2174  /*
2175  if (off == 0){
2176  // Compute the proper event length on the FIRST event in the Super Event
2177  // N_TDC correspond to the !! N_TDC DWORD above !!
2178  // sizeof(BANK_HEADER) + sizeof(BANK) will make the 16 bytes header
2179  // sizeof(DWORD) is defined by the TID_DWORD in bk_create()
2180  return N_TDC * sizeof(DWORD) + sizeof(BANK_HEADER) + sizeof(BANK);
2181  }
2182  else{
2183  // Return the data section size only
2184  // sizeof(DWORD) is defined by the TID_DWORD in bk_create()
2185 
2186  return N_TDC * sizeof(DWORD);
2187  }
2188 */
2189  bk_close(pevent, pdata);
2190  return bk_size(pevent);
2191 }
2192 
2207 INT read_scaler_event(char *pevent, INT off)
2208 {
2209  int status;
2210  u_int32_t data[100];
2211  DWORD *pdata, i;
2212 
2213  /* init bank structure */
2214  bk_init(pevent);
2215 
2216  /* create SCL0 bank */
2217  bk_create(pevent, "SCL0", TID_DWORD, (void**)&pdata);
2218 
2219  /* read out scaler module */
2220 #ifdef HAVE_TEST_RUN
2221  for (i=0; i<N_SCALER ; i++) {
2222  /*---------------------------------------------------------
2223  simulate the case when user bits and channel number are sent
2224  in the first 8 bits, scaler data in the remaining 24 bits
2225  ---------------------------------------------------------
2226  */
2227  if ( scaler_settings.input_mode_3 )
2228  channel = i << 24;
2229  else
2230  channel = 0;
2231  *pdata++ = (100 + rand()%40-20) | channel;
2232  }
2233 #else
2234  //read 1st scaler
2235  if (flag_scaler_address_0) {
2237  if ( status != 0 ){
2238  for ( i = 0; i<N_SCALER_MODULE; i++)
2239  *pdata++ = -1;
2240  cm_msg(MERROR, "read_scaler_event", "Error reading data from VME Scaler SIS3820!");
2241  cm_yield(0);
2242  } else {
2243  for ( i = 0; i<N_SCALER_MODULE; i++)
2244  *pdata++ = data[i];
2245  }
2246  } else { //scaler disabled or not present
2247  for ( i = 0; i<N_SCALER_MODULE; i++)
2248  *pdata++ = 0;
2249  }
2250 
2251  //read 2nd scaler
2252  if (flag_scaler_address_1) {
2254  if ( status != 0 ) {
2255  for (i=0; i<N_SCALER_MODULE; i++)
2256  *pdata++ = -1;
2257  cm_msg(MERROR, "read_scaler_event", "Error reading data from VME Scaler SIS3820!");
2258  cm_yield(0);
2259  } else {
2260  for (i=0; i<N_SCALER_MODULE; i++)
2261  *pdata++ = data[i];
2262  }
2263  } else { //scaler disabled or not present
2264  for (i=0; i<N_SCALER_MODULE; i++)
2265  *pdata++ = 0;
2266  }
2267 #endif
2268 
2269  bk_close(pevent, pdata);
2270  return bk_size(pevent);
2271 }
2278 INT read_slowcontrol_event(char *pevent, INT off)
2279 {
2280  INT i, n_max;
2281  float *pdata;
2282  double *pDoubleData;
2283 
2284  /* init bank structure */
2285  bk_init(pevent);
2286 
2287  /* --- beamline demand values ----------- */
2288  bk_create(pevent, "DBEA", TID_FLOAT, (void**)&pdata);
2289  n_max = sizeof(beamline_event.demand)/sizeof(float);
2290  for (i = 0; i < n_max; i++)
2291  *pdata++ = beamline_event.demand[i];
2292  bk_close(pevent, pdata);
2293 
2294  /* --- beamline measured values ---------- */
2295  bk_create(pevent, "MBEA", TID_FLOAT, (void**)&pdata);
2296  n_max = sizeof(beamline_event.measured)/sizeof(float);
2297  for (i = 0; i < n_max; i++)
2298  *pdata++ = beamline_event.measured[i];
2299  bk_close(pevent, pdata);
2300 
2301  /* --- lemvac measured values ---------- */
2302  bk_create(pevent, "MVAC", TID_FLOAT, (void**)&pdata);
2303  n_max = sizeof(lemvac_event.input)/sizeof(float);
2304  for (i = 0; i < n_max; i++)
2305  *pdata++ = lemvac_event.input[i];
2306  bk_close(pevent, pdata);
2307 
2308  /* --- Moderator Cryo measured values ---------- */
2309  bk_create(pevent, "MMOD", TID_FLOAT, (void**)&pdata);
2310  n_max = sizeof(moddy_event.input)/sizeof(float);
2311  for (i = 0; i < n_max; i++)
2312  *pdata++ = moddy_event.input[i];
2313  bk_close(pevent, pdata);
2314 
2315  /* --- Sample Cryo measured values ---------- */
2316  bk_create(pevent, "MSAM", TID_FLOAT, (void**)&pdata);
2317  n_max = sizeof(sample_event.input)/sizeof(float);
2318  if (strstr(info.sample_cryo, "Omega"))
2319  sample_event.input[0] = omega_event.input[0]+273.16; // Omega temperature in °C whereas sample temp. should be in K
2320  for (i = 0; i < n_max; i++)
2321  *pdata++ = sample_event.input[i];
2322  bk_close(pevent, pdata);
2323 
2324  /* --- SCS2001M measured values ---------- */
2325  bk_create(pevent, "M900", TID_FLOAT, (void**)&pdata);
2326  n_max = sizeof(scs2001m_event.input)/sizeof(float);
2327  for (i = 0; i < n_max; i++)
2328  *pdata++ = scs2001m_event.input[i];
2329  bk_close(pevent, pdata);
2330 
2331  /* --- HV transport (FUG) measured values ---------- */
2332  bk_create(pevent, "MHVT", TID_FLOAT, (void**)&pdata);
2333  n_max = sizeof(hv_event.measured)/sizeof(float);
2334  for (i = 0; i < n_max; i++)
2335  *pdata++ = hv_event.measured[i];
2336  bk_close(pevent, pdata);
2337 
2338  /* --- HV Detectors measured values ---------- */
2339  bk_create(pevent, "MHVD", TID_FLOAT, (void**)&pdata);
2340  n_max = sizeof(hvdet_event.measured)/sizeof(float);
2341  for (i = 0; i < n_max; i++)
2342  *pdata++ = hvdet_event.measured[i];
2343  bk_close(pevent, pdata);
2344 
2345  /* --- Microwave data for Mu-Lambshift experiment *Dec 2020* ---------- */
2346  bk_create(pevent, "MWAV", TID_DOUBLE, (void**)&pDoubleData);
2347  *pDoubleData++ = info.microwave_log.tektronix_timestamp;
2348  *pDoubleData++ = info.microwave_log.tektronix_set_power;
2349  *pDoubleData++ = info.microwave_log.tektronix_set_frequency;
2350  *pDoubleData++ = info.microwave_log.ana_pico_timestamp;
2351  *pDoubleData++ = info.microwave_log.ana_pico_set_power;
2352  *pDoubleData++ = info.microwave_log.ana_pico_set_frequency;
2353  *pDoubleData++ = info.microwave_log.keysight_u2002a_timestamp;
2354  *pDoubleData++ = info.microwave_log.keysight_u2002a_measured_power;
2355  *pDoubleData++ = info.microwave_log.keysight_u8481a_timestamp;
2356  *pDoubleData++ = info.microwave_log.keysight_u8481a_measured_power;
2357  *pDoubleData++ = info.microwave_log.pressure_1;
2358  *pDoubleData++ = info.microwave_log.pressure_2;
2359  *pDoubleData++ = info.microwave_log.pressure_3;
2360  bk_close(pevent, pDoubleData);
2361 
2362  return bk_size(pevent);
2363 }
2364 
2365 /* -------------- other functions -----------
2366 void scaler_mode(u_int32_t module_address )
2367 int init_sis3820(u_int32_t module_address)
2368 int init_v1190(u_int32_t module_address)
2369 */
2370 
2383 void scaler_mode(u_int32_t module_address)
2384 {
2385  INT size, status;
2386  u_int32_t control;
2387  HNDLE hDB, hkey;
2388 
2389  cm_get_experiment_database(&hDB, NULL);
2390 
2391  status = 0;
2392  control = 0;
2393 
2394  size = sizeof(scaler_settings);
2395  db_find_key(hDB, 0, "/Equipment/Scaler/Settings", &hkey);
2396  db_get_record(hDB, hkey, &scaler_settings, &size, 0);
2397 
2398  if (scaler_settings.input_mode_3)
2400  else
2402 
2403  status = sis3820_operation_mode_write( hdev, module_address, control);
2404  if (status !=0) {
2405  cm_msg(MERROR, "scaler_mode", "Error on setting mode of SIS3820, return code %x\n", status);
2406  cm_yield(0);
2407  }
2408 
2409  if (scaler_settings.reference_ch1)
2410  status = sis3820_control_write( hdev, module_address, CTRL_REFERENCE_CH1_ENABLE);
2411  else
2412  status = sis3820_control_write( hdev, module_address, CTRL_REFERENCE_CH1_DISABLE);
2413 
2414  if (status !=0) {
2415  cm_msg(MERROR, "scaler_mode", "Error on setting control status of SIS3820, return code %x\n", status);
2416  cm_yield(0);
2417  }
2418 
2419  /* read control status and operation mode */
2420  status = sis3820_control_read( hdev, module_address, &control);
2421  if (status !=0)
2422  cm_msg(MERROR, "scaler_mode", "Error on reading control status of SIS3820, return code %x\n", status);
2423  else
2424  cm_msg(MINFO,"scaler_mode","SIS3820 control status reads: 0x%8.8x \n",control);
2425  cm_yield(0);
2426 
2427  status =sis3820_operation_mode_read( hdev, module_address, &control);
2428  if (status != 0)
2429  cm_msg(MERROR, "scaler_mode", "Error on reading operation mode of SIS3820, return code %x\n", status);
2430  else
2431  cm_msg(MINFO,"scaler_mode","SIS3820 operation mode reads: 0x%8.8x \n",control);
2432  cm_yield(0);
2433 
2434 }
2435 
2452 int init_sis3820(u_int32_t module_address)
2453 {
2454  int status;
2455  u_int32_t modid, control, mode;
2456 
2457  /* reset SIS3820 */
2458  status = sis3820_key_reset( hdev, module_address);
2459  if (status !=0) {
2460  cm_msg(MERROR, "frontend_init",
2461  "Error on access to SIS3820 0x%8.8x, key reset failed, return code %x\n", module_address, status);
2462  cm_yield(0);
2463  return FE_ERR_HW;
2464  }
2465 
2466  status = 0;
2467  status += sis3820_modid_read( hdev, module_address, &modid);
2468  status += sis3820_control_read( hdev, module_address, &control);
2469  status += sis3820_operation_mode_read( hdev, module_address, &mode);
2470  if (status !=0) {
2471  cm_msg(MERROR, "frontend_init",
2472  "Error on access to SIS3820, couldn't get module info, return code %x\n", status);
2473  cm_yield(0);
2474  return FE_ERR_HW;
2475  }
2476  cm_msg(MINFO,"frontend_init", "SIS3820 modid and firmware = 0x%8.8x", modid);
2477  cm_msg(MINFO,"frontend_init", "SIS3820 control status = 0x%8.8x", control);
2478  cm_msg(MINFO,"frontend_init", "SIS3820 operation mode = 0x%8.8x", mode);
2479  cm_yield(0);
2480 
2481  /* enable SIS3820 for counting, default mode (scaler, 32 bit) */
2482  status = sis3820_key_enable( hdev, module_address);
2483  if (status !=0) {
2484  cm_msg(MERROR, "frontend_init",
2485  "Error on access to SIS3820, key enable failed, return code %x\n", status);
2486  cm_yield(0);
2487  return FE_ERR_HW;
2488  }
2489  cm_msg(MINFO, "frontent_init","SIS3820 enabled for counting");
2490  cm_yield(0);
2491 
2492  return FE_SUCCESS;
2493 }
2494 /*----------------------------------------------------------------------*/
2503 int init_v1190(u_int32_t module_address)
2504 {
2505  u_int16_t data;
2506  int return_code;
2507 
2508 #ifdef HAVE_TEST_RUN
2509  return FE_SUCCESS;
2510 #endif
2511  /* reset module to its default configuration */
2512  data = 0x0;
2513  return_code = vme_A32D16_write(hdev, module_address+V1190_MODULE_RESET, data) ;
2514  cm_msg(MINFO, "init_v1190","V1190 Module Reset: return_code = 0x%08x", return_code );
2515  cm_yield(0);
2516  if ( return_code != 0x0 ) return FE_ERR_HW;
2517  sleep(1);
2518 
2519  /* set leading edge mode */
2520  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_SET_DETECTION);
2521  cm_msg(MINFO, "init_v1190","V1190 Set_Detection: return_code = 0x%08x", return_code );
2522  cm_yield(0);
2523  if ( return_code != 0x0 ) return FE_ERR_HW;
2524  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_EDGE_LEADING_MODE);
2525  cm_msg(MINFO, "init_v1190", "V1190 Set_to_Leading_Edge: return_code = 0x%08x", return_code );
2526  cm_yield(0);
2527  if ( return_code != 0x0 ) return FE_ERR_HW;
2528  sleep(1);
2529 
2530  /* set 200ps LSB */
2531  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_SET_TR_LEAD_LSB);
2532  cm_msg(MINFO, "init_v1190", "V1190 Set_LSB: return_code = 0x%08x", return_code );
2533  cm_yield(0);
2534  if ( return_code != 0x0 ) return FE_ERR_HW;
2535  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_LSB_200PS);
2536  cm_msg(MINFO, "init_v1190", "V1190 Set_LSB_200ps: return_code = 0x%08x", return_code );
2537  cm_yield(0);
2538  if ( return_code != 0x0 ) return FE_ERR_HW;
2539  sleep(1);
2540 
2541  /* disable all channels if set in ODB */
2542  if ( trigger_settings.tdc_disable_atstartup ){
2543  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_DISABLE_ALL_CHANNEL);
2544  cm_msg(MINFO, "init_v1190", "V1190 Disable all channels: return_code = 0x%08x", return_code);
2545  cm_yield(0);
2546  sleep(1);
2547  }
2548 
2549  /* set continuous storage mode */
2550  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_CONT_STOR);
2551  cm_msg(MINFO, "init_v1190","V1190 Set_Continuous storage: return_code = 0x%08x", return_code );
2552  cm_yield(0);
2553 
2554  if ( return_code != 0x0 ) return FE_ERR_HW;
2555  sleep(1);
2556 
2557  /* set almost full level */
2558  return_code = vme_A32D16_write(hdev, module_address+V1190_ALMOST_FULL_LEVEL, ALMOST_FULL_LEVEL);
2559  cm_msg(MINFO, "init_v1190","V1190 Set_Almost_Full_Level: return_code = 0x%08x", return_code );
2560  cm_yield(0);
2561 
2562  /* enable VME Bus error to indicate that Output Buffer is empty */
2563  data = 0x21;
2564  return_code = vme_A32D16_write(hdev, module_address+V1190_CONTROL_REGISTER, data);
2565  cm_msg(MINFO, "init_v1190","V1190 Control_Register: return_code = 0x%08x", return_code );
2566  cm_yield(0);
2567 
2568  /* read module status */
2569  return_code = vme_A32D16_read(hdev, module_address+V1190_ALMOST_FULL_LEVEL, &data ) ;
2570  cm_msg(MINFO, "init_v1190", "V1190 Almost Full Level: return_code = 0x%08x", return_code);
2571  cm_msg(MINFO, "init_v1190", "V1190 Almost Full Level: data = 0x%04x", data );
2572  cm_yield(0);
2573 
2574  return_code = vme_A32D16_read(hdev, module_address+V1190_STATUS_REGISTER, &data ) ;
2575  cm_msg(MINFO, "init_v1190", "V1190 Modul status: return_code = 0x%08x", return_code);
2576  cm_msg(MINFO, "init_v1190", "V1190 Modul status: data = 0x%04x", data );
2577  cm_yield(0);
2578 
2579  return_code = vme_A32D16_read(hdev, module_address+V1190_CONTROL_REGISTER, &data ) ;
2580  cm_msg(MINFO, "init_v1190", "V1190 Control Register: return_code = 0x%08x", return_code);
2581  cm_msg(MINFO, "init_v1190", "V1190 Control Register: data = 0x%04x", data );
2582  cm_yield(0);
2583 
2584  if ( return_code != 0x0 ) return FE_ERR_HW;
2585 
2586  return FE_SUCCESS;
2587 }
2588 /*----------------------------------------------------------------------*/
2594 {
2595  struct timeval tvNowTime, tvDiffTime;
2596 
2597  gettimeofday(&tvNowTime, 0);
2598 
2599  timersub(&tvNowTime, &tvLastTime, &tvDiffTime);
2600 
2601  if (1000000*tvDiffTime.tv_sec+tvDiffTime.tv_usec > trigger_settings.period_onpuls_usec_){
2602  s3100_control_write(hdev, 0x80, 1<<28); // 12.5 ns NIM pulse on output 1
2603  gettimeofday(&tvLastTime, 0);
2604  flag_on_puls = TRUE;
2605  }
2606 
2607  if (flag_on_puls){
2608  // gettimeofday(&tvNowTime, 0);
2609  timersub(&tvNowTime, &tvLastTime, &tvDiffTime);
2610 
2611  if (1000000*tvDiffTime.tv_sec+tvDiffTime.tv_usec > trigger_settings.delay_offpuls_usec_){//turn puls off
2612  s3100_control_write(hdev, 0x80, 1<<29); // 12.5 ns NIM pulse on output 2
2613  flag_on_puls = FALSE;
2614  }
2615  }
2616 }
2617 
2618 /*----------------------------------------------------------------------*/
2622 // void vacuum_cleaner()
2623 // {
2624 // HNDLE hDB, hkey;
2625 // DWORD nowtime, difftime, deltapulsetime;
2626 // int size, status;
2627 // float pulse_hv_1, pulse_hv_2, ramp, current_limit;
2628 //
2629 // nowtime = ss_millitime();
2630 // difftime = nowtime - lasttime;
2631 //
2632 // /* if ( hv_vaccleaner.deltatime_msec_ > 0.99* hv_vaccleaner.period_msec_)
2633 // return FALSE;*/
2634 //
2635 // if ( difftime > hv_vaccleaner.period_msec_ && !vacuum_cleaner_active){
2636 // /* set current limit and ramping speed */
2637 // vacuum_cleaner_active = TRUE;
2638 // ramp = 0.;
2639 // current_limit = 0.6;
2640 // size = sizeof(float);
2641 // cm_get_experiment_database(&hDB, NULL);
2642 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Up Speed", &hkey);
2643 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_1, TID_FLOAT);
2644 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Down Speed", &hkey);
2645 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_1, TID_FLOAT);
2646 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Current Limit", &hkey);
2647 // db_set_data_index(hDB, hkey, &current_limit, size, hv_vaccleaner.channel_1, TID_FLOAT);
2648 //
2649 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Up Speed", &hkey);
2650 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_2, TID_FLOAT);
2651 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Down Speed", &hkey);
2652 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_2, TID_FLOAT);
2653 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Current Limit", &hkey);
2654 // db_set_data_index(hDB, hkey, &current_limit, size, hv_vaccleaner.channel_2, TID_FLOAT);
2655 //
2656 // /* change pulse direction each time automatically */
2657 // /* hv_vaccleaner.deltau_1_kv_ = -1.0*hv_vaccleaner.deltau_1_kv_;
2658 // hv_vaccleaner.deltau_2_kv_ = -1.0*hv_vaccleaner.deltau_2_kv_;*/
2659 // ra_hv_1 = hv_event.demand[hv_vaccleaner.channel_1];
2660 // pulse_hv_1 = ra_hv_1 + hv_vaccleaner.deltau_1_kv_;
2661 // ra_hv_2 = hv_event.demand[hv_vaccleaner.channel_2];
2662 // pulse_hv_2 = ra_hv_2 + hv_vaccleaner.deltau_2_kv_;
2663 //
2664 // lasttime = ss_millitime();
2665 // if ( pulse_hv_1 > 0 && pulse_hv_2 > 0 ){
2666 // /* change RAs to pulse_hv */
2667 // db_find_key(hDB, 0, "/Equipment/HV/Variables/Demand", &hkey);
2668 // db_set_data_index(hDB, hkey, &pulse_hv_1, size, hv_vaccleaner.channel_1, TID_FLOAT);
2669 // db_set_data_index(hDB, hkey, &pulse_hv_2, size, hv_vaccleaner.channel_2, TID_FLOAT);
2670 // }
2671 // return;
2672 // }
2673 //
2674 // deltapulsetime = ss_millitime() - lasttime;
2675 // if ( deltapulsetime > hv_vaccleaner.deltatime_msec_ && vacuum_cleaner_active){
2676 // /* restore old RA values */
2677 // db_set_data_index(hDB, hkey, &ra_hv_1, size, hv_vaccleaner.channel_1, TID_FLOAT);
2678 // db_set_data_index(hDB, hkey, &ra_hv_2, size, hv_vaccleaner.channel_2, TID_FLOAT);
2679 // ss_sleep(1000); /* wait 1000ms to ramp up HV */
2680 //
2681 // ramp = 0.1;
2682 // current_limit = 0.001;
2683 // size = sizeof(float);
2684 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Up Speed", &hkey);
2685 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_1, TID_FLOAT);
2686 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Current Limit", &hkey);
2687 // db_set_data_index(hDB, hkey, &current_limit, size, hv_vaccleaner.channel_1, TID_FLOAT);
2688 //
2689 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Up Speed", &hkey);
2690 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_2, TID_FLOAT);
2691 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Current Limit", &hkey);
2692 // db_set_data_index(hDB, hkey, &current_limit, size, hv_vaccleaner.channel_2, TID_FLOAT);
2693 //
2694 // vacuum_cleaner_active = FALSE;
2695 //
2696 // #ifndef HAVE_TEST_RUN
2697 // // clear TDC
2698 // status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_SOFTWARE_CLEAR, 0x0);
2699 // if ( status !=0)
2700 // cm_msg(MERROR, "vacuum_cleaner",
2701 // "vacuum_cleaner: Error on resetting TDC V1190, return code %x\n", status);
2702 // cm_yield(0);
2703 // #endif
2704 // }
2705 //
2706 // return;
2707 // }
2708 /* -----------------------------------------------------------------------
2709  E O F vme_fe.c
2710  ------------------------------------------------------------------------
2711 */
double frontend_loop_counts
Definition: nemu_experim.h:105
#define BCR1
Definition: nemu_experim.h:22
OMEGA_EVENT omega_event
Definition: vme_fe.cxx:212
#define TD_EVENT
Event flags.
Definition: vme_fe.cxx:226
#define POSRDI
Definition: nemu_experim.h:39
double pressure_3
Definition: nemu_experim.h:290
#define POSLUO
Definition: nemu_experim.h:32
#define HV_DETECTORS_EVENT_STR(_name)
Definition: experim.h:4951
WORD channel
Definition: nemu_experim.h:93
#define V1190_SET_TR_LEAD_LSB
Definition: v1190.h:86
#define BEAMLINE_EVENT_STR(_name)
Definition: experim.h:1425
float input[44]
Definition: experim.h:11083
float input[10]
Definition: experim.h:12864
#define MCP2R
Definition: nemu_experim.h:50
static struct timeval tvLastTime
Definition: vme_fe.cxx:291
double keysight_u8481a_timestamp
Definition: nemu_experim.h:286
#define HV_EVENT_STR(_name)
Definition: experim.h:3919
#define BINNING
const char * frontend_name
&lt; created by ODBedit, command &quot;make&quot;
Definition: vme_fe.cxx:167
BOOL positrons_active
Definition: experim.h:664
#define A32BLT32
Definition: sis3820.h:206
INT max_event_size
maximum event size produced by this frontend
Definition: vme_fe.cxx:179
INT32 reference_ch1
Definition: experim.h:1194
#define MASTERFIRST
Definition: vme_fe.cxx:235
#define ALMOST_FULL_LEVEL
Definition: vme_fe.cxx:221
VME_STATS vme_stats
Required ODB structures.
Definition: analyzer.cxx:82
DWORD thisTimeSlowMuon
Definition: vme_fe.cxx:258
LEMVAC_EVENT lemvac_event
Definition: vme_fe.cxx:205
SCALER_SETTINGS scaler_settings
Definition: analyzer.cxx:86
UINT32 tof_bc_window
Definition: experim.h:694
double channelCounts[N_TDC_CHANNELS]
Definition: nemu_experim.h:104
double run_time
Definition: nemu_experim.h:99
#define SCS2001M_EVENT_STR(_name)
Definition: experim.h:11087
float demand[40]
Definition: experim.h:1421
static TDC_PILEUP tdc_pileup
Definition: vme_fe.cxx:275
#define EXTON1
Definition: nemu_experim.h:57
#define DIFF_TOLERANCE
Definition: vme_fe.cxx:223
#define HV_DETECTORS_SETTINGS_STR(_name)
Definition: experim.h:5647
#define SIS3820_ADDRESS_0
Local definitions to connect to VME module.
Definition: vme_fe.cxx:217
static DWORD dataWindowFastMuon
Definition: vme_fe.cxx:286
double slowMuonEvents
Definition: nemu_experim.h:101
#define BCR4
Definition: nemu_experim.h:25
#define MCP2X2
Definition: nemu_experim.h:52
#define POSBUI
Definition: nemu_experim.h:36
double tektronix_set_power
Definition: nemu_experim.h:279
BOOL frontend_call_loop
frontend_loop is called periodically if this variable is TRUE
Definition: vme_fe.cxx:173
#define BCL4
Definition: nemu_experim.h:21
#define LEMVAC_SETTINGS_STR(_name)
Definition: experim.h:7540
UINT32 tof_bc_pileup_window
Definition: experim.h:695
struct TRIGGER_SETTINGS::@20 event_2_settings
#define V1190_ALMFULL_BIT
Definition: v1190.h:193
INT display_period
a frontend status page is displayed with this frequency in ms
Definition: vme_fe.cxx:176
static DWORD dataWindowSlowMuon
Definition: vme_fe.cxx:286
BOOL simulation_flag
Definition: experim.h:669
INT read_scaler_event(char *pevent, INT off)
Definition: vme_fe.cxx:2207
BOOL event_2_active
Definition: experim.h:661
DWORD doEvaluateFastMuonEvent
M1 = 0x10, M1-e+ = 0x20.
Definition: vme_fe.cxx:260
int sis3820_key_disable(int device, u_int32_t sis3820_base)
Definition: sis3820.c:84
double tektronix_timestamp
Definition: nemu_experim.h:278
BOOL check_positron(INT decWindow, INT coincWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex, INT *channel, INT *ind)
Definition: vme_fe.cxx:2026
INT event_buffer_size
buffer size to hold events
Definition: vme_fe.cxx:185
#define MCP2Y2
Definition: nemu_experim.h:54
U_LONG endBeamCounterEvent
Definition: vme_fe.cxx:267
#define HV_SETTINGS_STR(_name)
Definition: experim.h:4424
#define SAMPLECRYO_SETTINGS_STR(_name)
Definition: experim.h:3034
#define SIS3820_CONTROL_INPUT_MODE3
Definition: sis3820.h:179
#define N_HITS
a single detector may have up to N_HITS hits for event evaluation
Definition: nemu_experim.h:65
BOOL check_tof_and_pileup(INT timing, INT tofWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex, INT *channel, INT *ind)
Definition: vme_fe.cxx:1958
BOOL event_1_active
Definition: experim.h:660
BOOL beamcounter_active
Definition: experim.h:665
INT evaluate_slow_muon_event()
Definition: vme_fe.cxx:1486
#define EXTOFF1
Definition: nemu_experim.h:58
static DWORD * databuffer
ring buffer for TDC data
Definition: vme_fe.cxx:277
double mcp1_good
Definition: nemu_experim.h:103
#define V1190_MODULE_RESET
Definition: v1190.h:39
static INT hdev
handle for VME-PCI device
Definition: vme_fe.cxx:276
UINT32 tof_m2_window
Definition: experim.h:680
static BOOL flag_scaler_address_0
Definition: vme_fe.cxx:289
#define POSMCP1O
Definition: nemu_experim.h:27
#define SIS3820_SCALER_DATA_FORMAT_32BIT
Definition: sis3820.h:162
#define EXTON1_FLAG
flag for &quot;red/green&quot;, &quot;on/off&quot; mode: ON
Definition: nemu_experim.h:68
HV_EVENT hv_event
Definition: analyzer.cxx:95
#define SIS3820_CONTROL_INPUT_MODE0
Definition: sis3820.h:176
int sis3820_key_enable(int device, u_int32_t sis3820_base)
Definition: sis3820.c:62
INT32 mcp1_delay
Definition: experim.h:667
INT32 t0_offset
Definition: experim.h:692
DWORD doEvaluateSlowMuonEvent
bit pattern for trigger condition:
Definition: vme_fe.cxx:259
INT pileup[N_TDC_CHANNELS][N_HITS]
save information for each hit if it had a pre pileup or not
Definition: vme_fe.cxx:255
double keysight_u2002a_timestamp
Definition: nemu_experim.h:284
double ana_pico_timestamp
Definition: nemu_experim.h:281
#define V1190_CONTROL_REGISTER
Definition: v1190.h:31
INT mode
scaler mode, see scaler_mode()
Definition: vme_fe.cxx:290
#define SIS3820_SCALER_DATA_FORMAT_24BIT
Definition: sis3820.h:163
double pressure_1
Definition: nemu_experim.h:288
static U_LONG runTime
absolute run time in TDC LSB units
Definition: vme_fe.cxx:284
INT foundChannel[N_TDC_CHANNELS]
count appearance of channel i
Definition: vme_fe.cxx:252
INT read_trigger_event(char *pevent, INT off)
Definition: vme_fe.cxx:2129
#define M2_EVENT
Definition: vme_fe.cxx:228
INT indexSlowMuonSet
Definition: vme_fe.cxx:257
#define POSTDI
Definition: nemu_experim.h:44
INT evaluate_fast_muon_event()
Definition: vme_fe.cxx:1809
double keysight_u2002a_measured_power
Definition: nemu_experim.h:285
DWORD lastTimeFastMuon
Definition: vme_fe.cxx:258
unsigned long long U_LONG
GNU C-Compiler 64bit integer.
Definition: nemu_experim.h:87
int init_v1190(u_int32_t module_address)
Definition: vme_fe.cxx:2503
INT lastBeamCounterEventPileup
Definition: vme_fe.cxx:269
#define TDC_BIT_RANGE
2^19 is the bit range of the TDC in 100ps and 200ps mode
Definition: nemu_experim.h:70
INT32 master_delay
Definition: experim.h:683
static BOOL flag_scaler_address_1
flags to indicate status of VME scalers
Definition: vme_fe.cxx:289
#define V1190_DISABLE_ALL_CHANNEL
Definition: v1190.h:111
#define MCP2Y1
Definition: nemu_experim.h:53
INT frontend_exit()
Definition: vme_fe.cxx:565
EQUIPMENT equipment[]
Definition: vme_fe.cxx:343
float measured[16]
Definition: experim.h:3915
static TDC_EVAL_EVENT tdc_eval_event
Definition: vme_fe.cxx:274
static U_LONG nextGoodTime
absolute run time when new events are accepted (for on/off mode)
Definition: vme_fe.cxx:285
static DWORD masterChannelSlowMuon
&quot;master&quot; TDC channel for slow muons (TD or M2)
Definition: vme_fe.cxx:282
#define BCL1
Definition: nemu_experim.h:18
#define CTRL_REFERENCE_CH1_DISABLE
Definition: sis3820.h:147
#define VME_STATS_STR(_name)
Definition: nemu_experim.h:112
#define MODCRYO_EVENT_STR(_name)
Definition: experim.h:1899
#define BCL3
Definition: nemu_experim.h:20
INT lastMasterEvent1or2Pileup
Definition: vme_fe.cxx:270
static DWORD eventDefinedFastMuon
bit pattern containing trigger mode for fast muons (BC-M1)
Definition: vme_fe.cxx:281
HV_SETTINGS hv_settings
Definition: vme_fe.cxx:211
INT indexFastMuonSet
Definition: vme_fe.cxx:256
#define POSRUO
Definition: nemu_experim.h:42
INT begin_of_run(INT run_number, char *error)
Definition: vme_fe.cxx:597
int sis3820_operation_mode_read(int device, u_int32_t sis3820_base, u_int32_t *mode)
Definition: sis3820.c:97
INFO info
Definition: analyzer.cxx:94
static DWORD eventDefinedSlowMuon
bit pattern containing trigger mode for slow muons (BC-TD-M2)
Definition: vme_fe.cxx:280
INT set_t0
flag indicating if t0 has been set
Definition: vme_fe.cxx:250
TRIGGER_SETTINGS trigger_settings
Definition: analyzer.cxx:93
int sis3820_operation_mode_write(int device, u_int32_t sis3820_base, u_int32_t mode)
Definition: sis3820.c:165
struct TRIGGER_SETTINGS::@17 events
#define TRIGGER_SETTINGS_STR(_name)
Definition: experim.h:702
U_LONG endMasterEvent0
U_LONG==unsigned long long, GNU C-compiler 64bit integer.
Definition: vme_fe.cxx:265
U_LONG pileup_end(INT pileupWindow)
Definition: vme_fe.cxx:1471
int sis3820_control_read(int device, u_int32_t sis3820_base, u_int32_t *control_status)
Definition: sis3820.c:191
struct TRIGGER_SETTINGS::@19 event_1_settings
#define DATABUFFER_SIZE
set size of FiFo (ring) buffer, 2^17
Definition: vme_fe.cxx:222
DWORD thisTimeFastMuon
Definition: vme_fe.cxx:258
void OnOff_mode()
Definition: vme_fe.cxx:2593
#define MAX_NUMBER_LWORDS
max number of block data transfer */
Definition: vme_fe.cxx:220
static DWORD * p_write
read and write pointers for data ring buffer
Definition: vme_fe.cxx:278
INT interrupt_configure(INT cmd, INT source, PTYPE adr)
Definition: vme_fe.cxx:2105
#define V1190_LSB_200PS
Definition: v1190.h:163
INT frontend_loop()
Definition: vme_fe.cxx:957
INT tdc_data[N_TDC_CHANNELS *DATA_N_HITS]
this array is actually the Midas event
Definition: vme_fe.cxx:249
#define V1190_STATUS_REGISTER
Definition: v1190.h:32
INT resume_run(INT run_number, char *error)
Definition: vme_fe.cxx:900
RUNINFO runinfo
Definition: analyzer.cxx:83
INT read_slowcontrol_event(char *pevent, INT off)
Definition: vme_fe.cxx:2278
#define V1190_EDGE_LEADING_MODE
Definition: v1190.h:159
#define M1_POSITRON_EVENT
Definition: vme_fe.cxx:231
BOOL event_0_active
Definition: experim.h:659
WORD buffer
Definition: v1190.h:16
DWORD data
Definition: v1190.h:13
double tektronix_set_frequency
Definition: nemu_experim.h:280
HV_DETECTORS_EVENT hvdet_event
Definition: vme_fe.cxx:210
float input[41]
Definition: experim.h:1895
double mcp2_good
Definition: nemu_experim.h:103
INT32 td_delay
Definition: experim.h:689
#define BCR2
Definition: nemu_experim.h:23
#define MCP2F
Definition: nemu_experim.h:49
UINT32 delay_offpuls_usec_
Definition: experim.h:698
INT do_master_channel(INT ch, INT event_type)
Definition: vme_fe.cxx:1368
static BOOL flag_on_puls
flag to indicate that &quot;puls&quot; was turned on, &quot;on/off&quot; or &quot;red/green&quot; mode
Definition: vme_fe.cxx:292
double frontend_loop_readtdc
Definition: nemu_experim.h:106
MODCRYO_EVENT moddy_event
Definition: vme_fe.cxx:206
UINT32 data_window
Definition: experim.h:666
INT max_event_size_frag
maximum event size for fragmented events (EQ_FRAGMENTED)
Definition: vme_fe.cxx:182
#define POSMCP1I
Definition: nemu_experim.h:26
#define DATA_N_HITS
max. of DATA_N_HITS in data file
Definition: nemu_experim.h:66
#define EVENT_1_TYPE
Event type 1 = (BC)-TD-MC2-(e+)
Definition: nemu_experim.h:76
char sample_cryo[NAME_LENGTH]
Definition: nemu_experim.h:299
#define LEMVAC_EVENT_STR(_name)
Definition: experim.h:7413
#define MODCRYO_SETTINGS_STR(_name)
Definition: experim.h:2159
MICROWAVE_LOG microwave_log
Definition: nemu_experim.h:394
#define CTRL_REFERENCE_CH1_ENABLE
Definition: sis3820.h:148
WORD channel
Definition: v1190.h:14
double td_clean
Definition: nemu_experim.h:102
double mcp2_clean
Definition: nemu_experim.h:102
#define POSRUI
Definition: nemu_experim.h:41
#define M1_EVENT
Definition: vme_fe.cxx:230
static BOOL flag_external_on
flag to indicate &quot;on/off&quot;, &quot;red/green&quot; mode
Definition: vme_fe.cxx:288
INT frontend_init()
Definition: vme_fe.cxx:429
#define EXTOFF1_FLAG
flag for &quot;red/green&quot;, &quot;on/off&quot; mode: OFF
Definition: nemu_experim.h:69
INT event_time
absolute time in event after reset of structure
Definition: vme_fe.cxx:251
#define POSLDO
Definition: nemu_experim.h:30
static DWORD * p_read
Definition: vme_fe.cxx:278
BEAMLINE_EVENT beamline_event
for slow control parameters
Definition: vme_fe.cxx:204
BOOL mcp2_active
Definition: experim.h:677
#define BCR3
Definition: nemu_experim.h:24
#define V1190_SOFTWARE_CLEAR
Definition: v1190.h:40
INT lastMasterEvent0Pileup
Definition: vme_fe.cxx:268
double bc_rate
Definition: experim.h:671
INT do_channel(INT ch, INT time)
Definition: vme_fe.cxx:1333
UINT32 period_onpuls_usec_
Definition: experim.h:697
#define POSBDO
Definition: nemu_experim.h:35
#define V1190_ALMOST_FULL_LEVEL
Definition: v1190.h:45
#define V1190_OUTPUT_BUFFER_SIZE
Definition: v1190.h:27
void scaler_mode(u_int32_t module_address)
Definition: vme_fe.cxx:2383
#define NEW_EVENT_MASK
Definition: nemu_experim.h:67
double fastMuonEvents
Definition: nemu_experim.h:101
INT indexFastMuon
Definition: vme_fe.cxx:256
BOOL equipment_common_overwrite
Definition: vme_fe.cxx:341
#define POSBUO
Definition: nemu_experim.h:37
int sis3820_key_reset(int device, u_int32_t sis3820_base)
Definition: sis3820.c:39
INT32 positron_delay
Definition: experim.h:668
double readcounts
Definition: nemu_experim.h:108
#define N_TDC_CHANNELS
number of TDC channels
Definition: nemu_experim.h:64
static INT rate[N_SCALER]
#define BC_EVENT
Definition: vme_fe.cxx:229
#define LE_POSITRON_EVENT
Definition: vme_fe.cxx:227
INT end_of_run(INT run_number, char *error)
Definition: vme_fe.cxx:865
#define BCL2
Definition: nemu_experim.h:19
INT poll_event(INT source, INT count, BOOL test)
Definition: vme_fe.cxx:2088
float measured[94]
Definition: experim.h:4945
SCS2001M_EVENT scs2001m_event
Definition: analyzer.cxx:97
#define POSRDO
Definition: nemu_experim.h:40
#define SCALER_SETTINGS_STR(_name)
Definition: experim.h:1199
#define POSTDO
Definition: nemu_experim.h:45
#define SAMPLECRYO_EVENT_STR(_name)
Definition: experim.h:2664
INT32 input_mode_3
Definition: experim.h:1193
#define N_SCALER
total number of scaler channels
Definition: nemu_experim.h:63
#define POSBDI
Definition: nemu_experim.h:34
double td_good
Definition: nemu_experim.h:103
#define N_SCALER_MODULE
number of channels of one scaler module
Definition: nemu_experim.h:62
static DWORD masterChannelFastMuon
&quot;master&quot; TDC channel for BC-M1 (usually M1)
Definition: vme_fe.cxx:283
double bc_clean
Definition: nemu_experim.h:102
#define V1190_OPCODE_ADDRESS
Definition: v1190.h:51
#define POSTUO
Definition: nemu_experim.h:47
BOOL enable_onoff_mode
Definition: experim.h:696
static INT t0_offset
Definition: vme_fe.cxx:287
#define SCS2001M_SETTINGS_STR(_name)
Definition: experim.h:11227
#define EXP_PARAM_STR(_name)
Definition: experim.h:30
#define V1190_SET_DETECTION
Definition: v1190.h:84
float measured[40]
Definition: experim.h:1422
#define EVENT_2_TYPE
Event type 2 = TD-e+-(BC), LE-muSR.
Definition: nemu_experim.h:77
double mcp1_clean
Definition: nemu_experim.h:102
DWORD data
Definition: nemu_experim.h:92
#define CLOCK
TDC channel assignments.
Definition: nemu_experim.h:15
#define MASTERLAST
timing flags
Definition: vme_fe.cxx:234
UINT32 delay_daq_usec_
Definition: experim.h:699
#define BEAMLINE_SETTINGS_STR(_name)
Definition: experim.h:1530
#define MCP2X1
Definition: nemu_experim.h:51
double tdc_error_counts
Definition: nemu_experim.h:109
HNDLE hDB
int sis3820_scaler_read(int device, u_int32_t sis3820_base, int mode, int nwords, u_int32_t *data)
Definition: sis3820.c:281
float input[27]
Definition: experim.h:7409
#define MCP1
Definition: nemu_experim.h:16
int sis3820_modid_read(int device, u_int32_t sis3820_base, u_int32_t *modid)
Definition: sis3820.c:178
#define POSLDI
Definition: nemu_experim.h:29
#define POSTUI
Definition: nemu_experim.h:46
int init_sis3820(u_int32_t module_address)
Definition: vme_fe.cxx:2452
SAMPLECRYO_EVENT sample_event
Definition: vme_fe.cxx:207
double mcp1_rate
Definition: experim.h:670
int last_TDCtime
Definition: nemu_experim.h:100
#define POSLUI
Definition: nemu_experim.h:31
BOOL tdc_disable_atstartup
Definition: experim.h:693
DWORD lastTimeSlowMuon
Definition: vme_fe.cxx:258
#define TD
Definition: nemu_experim.h:17
INT pause_run(INT run_number, char *error)
Definition: vme_fe.cxx:893
static DWORD masterFlagSlowMuon
use either TD_EVENT or M2_EVENT as slow muon master
Definition: vme_fe.cxx:279
double ana_pico_set_frequency
Definition: nemu_experim.h:283
INT tdc_event[N_TDC_CHANNELS][N_HITS]
each channel may have up to N_HITS hits
Definition: vme_fe.cxx:253
int sis3820_control_write(int device, u_int32_t sis3820_base, u_int32_t control_status)
Definition: sis3820.c:229
struct TRIGGER_SETTINGS::@18 event_0_settings
#define SIS3820_ADDRESS_1
VME address of 2nd scaler module.
Definition: vme_fe.cxx:218
double ana_pico_set_power
Definition: nemu_experim.h:282
const char * frontend_file_name
The frontend file name, don&#39;t change it.
Definition: vme_fe.cxx:170
double poll_counts
Definition: nemu_experim.h:107
INT indexSlowMuon
Definition: vme_fe.cxx:257
U_LONG endMasterEvent1or2
Definition: vme_fe.cxx:266
#define EVENT_0_TYPE
EVENT type 0 = BC-MCP1-(e+)
Definition: nemu_experim.h:75
INT masterChannel
#define V1190_CONT_STOR
Definition: v1190.h:64
double keysight_u8481a_measured_power
Definition: nemu_experim.h:287
double pressure_2
Definition: nemu_experim.h:289
float input[30]
Definition: experim.h:2660
#define V1190_ADDRESS
the VME address of the CAEN V1190 TDC
Definition: vme_fe.cxx:219