Internal features

previous.gif Quick Start - Top - Utilities next.gif

This section refers to the Midas built-in capabilities. The following sections describe in more details the essential aspect of each feature starting from the frontend to the Electronic Logbook.



Frontend code

Under MIDAS, experiment hardware is structured into "equipment" which refers to a collection of hardware devices such as: a set of high voltage supplies, one or more crates of digitizing electronics like ADCs and TDCs or a set of scaler. On a software point of view, we keep that same equipment term to refer to the mean of collecting the data related to this "hardware equipment". The data from this equipment is then gathered into an "event" and send to the back-end computer for logging and/or analysis.

The frontend program (image) consists of a system framework contained in mfe.c (hidden to the user) and a user part contained in frontend.c . The hardware access is only apparent in the user code. Several libraries and drivers exist for various bus systems like CAMAC VME or RS232. They are located in the drivers directory of the MIDAS distribution. Some libraries consist only of a header file, others of a C file plus a header file. The file names usually refer to the manufacturer abbreviation followed by the model number of the device. The libraries are continuously expanding to widen Midas support.

ESONE standard routines for CAMAC are supplied and permit to re-use the frontend code between different platform as well as different CAMAC hardware interface without the need of modification of the code.

The user frontend code consists of a several sections described in order below. Example of frontend code can be found under the ../examples/experiment directory:

The argument {run_number provides the current run number being started. The argument {error can be used for returning a message to the system. This string will be logged into the {midas.log file.

    // clear units
    camc(CRATE, SLOT_C212, 0, 9);
    camc(CRATE, SLOT_2249A, 0, 9);
    camc(CRATE, SLOT_SC2, 0, 9);
    camc(CRATE, SLOT_SC3, 0, 9);

    camc(CRATE, SLOT_C212, 0, 26);              // Enable LAM generation

    cam_inhibit_clear(CRATE);                   // Remove I

    cam_lam_enable(CRATE, SLOT_C212);           // Declare Station to CC as LAM source

    // set and clear OR1320 pattern bits
    camo(CRATE, SLOT_OR1320, 0, 18, 0x0330);
    camo(CRATE, SLOT_OR1320, 0, 21, 0x0663);    // Open run gate, reset latch
    return SUCCESS;

  // Trigger event routines ---------------------------------------
  INT poll_event(INT source, INT count, BOOL test)
      // Polling routine for events. Returns TRUE if event
      // is available. If test equals TRUE, don't return. The test
      // flag is used to time the polling.
  {
    int   i;
    DWORD lam;

    for (i=0 ; i<count ; i++)
      {
        cam_lam_read(LAM_SOURCE_CRATE(source), &lam);
        if (lam & LAM_SOURCE_STATION(source)) // Any of the equipment LAM
     // *** or *** 
        if (lam)                              // Any LAM (independent of the equipment)
           if (!test)
            return lam;

    return 0; 

The polling function will pass to the readout function the actual LAM pattern read during the last polling. This pattern is a bitwise LAM station. The content of the {pevent will be overwritten. This option allows you to determine which of the station has been the real source of the LAM.

INT read_trigger_event(char *pevent, INT off)
{
  DWORD lam;

  lam = *((DWORD *)pevent);

  // check LAM versus MCS station
  // The clear is performed at the end of the readout function
  if (lam & LAM_STATION(JW_N))
  {
   ...
     ... 

  // Event readout -------------------------------------------------
  INT read_trigger_event(char *pevent, INT off)
  {
    WORD *pdata, a;

    // init bank structure
    bk_init(pevent);

    // create ADC bank
    bk_create(pevent, "ADC0", TID_WORD, &pdata);
    ...

The argument run_number provides the current run number being paused/resumed. The argument error can be used for returning a message to the system. This string will be logged into the midas.log file.

The argument run_number provides the current run number being ended. The argument error can be used for returning a message to the system. This string will be logged into the midas.log file.

    // set and clear OR1320 pattern bits or close run gate.
    camo(CRATE, SLOT_OR1320, 0, 18, 0x0CC3);
    camo(CRATE, SLOT_OR1320, 0, 21, 0x0990);

    camc(CRATE, SLOT_C212, 0, 26);            // Enable LAM generation
    cam_lam_disable(CRATE, SLOT_C212);        // disable LAM in crate controller
    cam_inhibit_set(CRATE);                   // set crate inhibit

The Equipment structure

To write a frontend program, the user section (frontend.c) has to have an equipment list organized as a structure definition. Here is the structure listing for a trigger and scaler equipment from the sample experiment example frontend.c.

#undef USE_INT
EQUIPMENT equipment[] = {

  { "Trigger",            // equipment name 
    1, 0,                 // event ID, trigger mask 
    "SYSTEM",             // event buffer
#ifdef USE_INT
    EQ_INTERRUPT,         // equipment type #else
    EQ_POLLED,            // equipment type 
#endif
    LAM_SOURCE(0,0xFFFFFF),// event source crate 0, all stations 
    "MIDAS",              // format 
    TRUE,                 // enabled 
    RO_RUNNING |          // read only when running 
    RO_ODB,               // and update ODB  
    500,                  // poll for 500ms 
    0,                    // stop run after this event limit 
    0,                    // number of sub events
    0,                    // don't log history 
    "", "", "",
    read_trigger_event,   // readout routine 
   ,
  ...   

MIDAS and YBOS or FIXED and YBOS data format can be mixed at the frontend level, but the data logger (mlogger) is not able to handle this format diversity on a event-by-event basis. In practice a given experiment should keep the data format identical throughout the equipment definition.

RO_RUNNING Read on state "running"
RO_STOPPEDRead on state "stopped"
RO_PAUSED Read on state "paused"
RO_BOR Read after begin-of-run
RO_EOR Read before end-of-run
RO_PAUSE Read when run gets paused
RO_RESUME Read when run gets resumed
RO_TRANSITIONS Read on all transitions
RO_ALWAYS Read independently of the states and force a read for all transitions.
RO_ODB Equipment event mirrored into ODB under variables

These flags can be combined with the logical OR operator. Trigger events in the above example are read out only when running while scaler events is read out when running and additionally on all transitions. A special flag RO_ODB tells the system to copy the event to the /Equipment/<equipment name>/Variables ODB tree once every ten seconds for diagnostic. Later on, the event content can then be displayed with ODBEdit.

FIXED event construction

The FIXED format is the simplest event format. The event length is fixed and maps to a C structure that is filled by the readout routine. Since the standard MIDAS analyzer cannot work with this format, it is only recommended for experiment, which use its own analyzer and want to avoid the overhead of a bank structure. For fixed events, the structure has to be defined twice: Once for the compiler in form of a C structure and once for the ODB in form of an ASCII representation. The ASCII string is supplied to the system as the "init string" in the equipment list.

Following statements would define a fixed event with two ADC and TDC values:

typedef struct {
  int adc0;
  int adc1;
  int tdc0;
  int tdc1;
  TRIGGER_EVENT;
char *trigger_event_str[] = {
"adc0 = INT : 0",
"adc1 = INT : 0",
"tdc0 = INT : 0",
"tdc1 = INT : 0",
  ASUM_BANK;

The trigger_event_str has to be defined before the equipment list and a reference to it has to be placed in the equipment list like:

{
...
  read_trigger_event, // readout routine 
  poll_trigger_event, // polling routine 
  trigger_event_str,  // init string 
 ,

The readout routine could then look like this, where the <...> statements have to be filled with the appropriate code accessing the hardware:

INT read_trigger_event(char *pevent)
{
TRIGGER_EVENT *ptrg;

  ptrg = (TRIGGER_EVENT *) pevent;
  ptrg->adc0 = <...>;
  ptrg->adc1 = <...>;
  ptrg->tdc0 = <...>;
  ptrg->tdc1 = <...>;

  return sizeof(TRIGGER_EVENT);


MIDAS event construction

The MIDAS event format is a variable length event format. It uses "banks" as subsets of an event. A bank is composed of a bank header followed by the data. The bank header itself is made of 4 fields i.e: bank name (4 char max), bank type, bank length. Usually a bank contains an array of values that logically belong together. For example, an experiment can generate an ADC bank, a TDC bank and a bank with trigger information. The length of a bank can vary from one event to another due to zero suppression from the hardware. Beside the variable data length support of the bank structure, onother main advantage is the possibility for the analyzer to add more (calculated) banks during the analysis process to the event in process. After the first analysis stage, the event can contain additionally to the raw ADC bank a bank with calibrated ADC values called CADC bank for example. In this CADC bank the raw ADC values could be offset or gain corrected.

MIDAS banks are created in the frontend readout code with calls to the MIDAS library. Following routines exist:

INT read_trigger_event(char *pevent)
{
INT *pdata;

  bk_init(pevent);

  bk_create(pevent, "ADC0", TID_INT, &pdata);
  *pdata++ = <ADC0>
  *pdata++ = <ADC1>
  bk_close(pevent, pdata);

  bk_create(pevent, "TDC0", TID_INT, &pdata);
  *pdata++ = <TDC0>
  *pdata++ = <TDC1>
  bk_close(pevent, pdata);

  return bk_size(pevent);

Upon normal completion, the readout routine returns the event size in bytes. If the event is not valid, the routine can return zero. In this case no event is sent to the back-end. This can be used to implement a software event filter (sometimes called "third level trigger").

INT read_trigger_event(char *pevent)
{
WORD *pdata, a;

  // init bank structure 
  bk_init(pevent);

  // create ADC bank 
  bk_create(pevent, "ADC0", TID_WORD, &pdata);

  // read ADC bank 
  for (a=0 ; a<8 ; a++)
    cami(1, 1, a, 0, pdata++);

  bk_close(pevent, pdata);

  // create TDC bank 
  bk_create(pevent, "TDC0", TID_WORD, &pdata);

  // read TDC bank 
  for (a=0 ; a<8 ; a++)
    cami(1, 2, a, 0, pdata++);

  bk_close(pevent, pdata);

  return bk_size(pevent);


YBOS event construction

The YBOS event format is also a bank format used in other DAQ systems. The advantage of using this format is the fact that recorded data can be analyzed with pre-existing analyzers understanding YBOS format. The disadvantage is that it has a slightly larger overhead than the MIDAS format and it supports fewer different bank types. An introduction to YBOS can be found under:

YBOS

The scheme of bank creation is exactly the same as for MIDAS events, only the routines are named differently. The YBOS format is double word oriented i.e. all incrementation are done in 4 bytes steps. Following routines exist:

The following code creates an ADC0 bank in YBOS format:

INT read_trigger_event(char *pevent)
{
  DWORD i;
  DWORD *pbkdat;

  ybk_init((DWORD *) pevent);

  // collect user hardware data 
  ybk_create((DWORD *)pevent, "ADC0", I4_BKTYPE, (DWORD *)(&pbkdat));
  for (i=0 ; i<8 ; i++)
    *pbkdat++ = i & 0xFFF;
  ybk_close((DWORD *)pevent, pbkdat);

  ybk_create((DWORD *)pevent, "TDC0", I2_BKTYPE, (DWORD *)(&pbkdat));
  for (i=0 ; i<8 ; i++)
    *((WORD *)pbkdat)++ = (WORD)(0x10+i) & 0xFFF;
  ybk_close((DWORD *) pevent, pbkdat);

  ybk_create((DWORD *)pevent, "SIMU", I2_BKTYPE, (DWORD *)(&pbkdat));
  for (i=0 ; i<9 ; i++)
    *((WORD *)pbkdat)++ = (WORD) (0x20+i) & 0xFFF;
  ybk_close((DWORD *) pevent, I2_BKTYPE, pbkdat);

  return (ybk_size((DWORD *)pevent));


Deferred Transition

This option permits the user to postpone any transition issued by any requester until some condition are satisfied. As examples:

In these examples, any application having access to the state of the hardware can register to be a "transition Deferred" client. It will then catch any transition request and postpone the trigger of such transition until condition is satisfied. The Deferred_Transition requires 3 steps for setup:


Super Event

The Super Event is a option implemented in the frontend code in order to reduce the amount of data to be transfered to the backend by removing the bank header for each event constructed. In other words, when an equipment readout in either MIDAS or YBOS format (bank format) is complete, the event is composed of the bank header followed by the data section. The overhead in bytes of the bank structure is 16 bytes for bk_init(), 20 bytes for bk_init32() and ybk_init(). If the data section size is close to the number above, the data transfer as well as the data storage has an non-negligible overhead. To address this problem, the equipment can be setup to generate a so called Super Event which is an event composed of the initial standard bank header for the first event on the super event and up to number of sub event maximum successive data section before closing of the bank.

To demonstrate the use of it, let see the following example:


Slow Control System

Instead of talking directly to each other, frontend and control programs exchange information through the ODB. Each slow control equipment gets a corresponding ODB tree under /Equipment. This tree contains variables needed to control the equipment as well as variables measured by the equipment. In case of a high voltage equipment this is a Demand array with contains voltages to be set, a Measured array which contains read back voltages and a Current array which contains the current drawn from each channel. To change the voltage of a channel, a control program writes to the Demand array the desired value. This array is connected to the high voltage frontend via a ODB hot-link. Each time it gets modified, the frontend receives a notification and sets the new value. In the other direction the frontend continuously reads the voltage and current values from all channels and updates the according ODB arrays if there has been a significant change. This design has a possible inconvenience due to fact that ODB is the key element of that control. Any failure or corruption of the database can results in wrong driver control. Therefore it is not recommended to use this system to control systems that need redundancy for safety purposes. On the other hand this system has several advantages:

Class driver, Device and Bus driver in the slow control system
classes2.jpg

The separation into class and device drivers has the advantage that it is very easy to add new devices, because only the simple device driver needs to be written. All higher functionality is inherited from the class driver. he device driver can implement richer functionality, depending on the hardware. For some high voltage devices there is a current read-back for example. This is usually reflected by additional variables in the ODB, i.e. a Current array. Frontend equipment uses exactly one class driver, but a class driver can use more than one device driver. This makes it possible to control several high voltage devices for example with one frontend in one equipment. The number of channels for each device driver is defined in the slow control frontend. Several equipment with different class drivers can be defined in a single frontend.

Key name                        Type    #Val  Size  Last Opn Mode Value
---------------------------------------------------------------------------
Epics                           DIR
    Settings                    DIR
        Channels                DIR
            Epics               INT     1     4     25h  0   RWD  3
        Devices                 DIR
            Epics               DIR
                Channel name    STRING  10    32    25h  0   RWD  
                                        [0]             GPS:VAR1
                                        [1]             GPS:VAR2
                                        [2]             GPS:VAR3
        Names                   STRING  10    32    17h  1   RWD  
                                        [0]             Current
                                        [1]             Voltage
                                        [2]             Watchdog
        Update Threshold MeasureFLOAT   10    4     17h  0   RWD  
                                        [0]             2
                                        [1]             2
                                        [2]             2
    Common                      DIR
        Event ID                WORD    1     2     17h  0   RWD  3
        Trigger mask            WORD    1     2     17h  0   RWD  0
        Buffer                  STRING  1     32    17h  0   RWD  SYSTEM
        Type                    INT     1     4     17h  0   RWD  4
        Source                  INT     1     4     17h  0   RWD  0
        Format                  STRING  1     8     17h  0   RWD  FIXED
        Enabled                 BOOL    1     4     17h  0   RWD  y
        Read on                 INT     1     4     17h  0   RWD  121
        Period                  INT     1     4     17h  0   RWD  60000
        Event limit             DOUBLE  1     8     17h  0   RWD  0
        Num subevents           DWORD   1     4     17h  0   RWD  0
        Log history             INT     1     4     17h  0   RWD  1
        Frontend host           STRING  1     32    17h  0   RWD  hostname
        Frontend name           STRING  1     32    17h  0   RWD  Epics
        Frontend file name      STRING  1     256   17h  0   RWD  feepic.c
    Variables                   DIR
        Demand                  FLOAT   10    4     0s   1   RWD  
                                        [0]             1.56
                                        [1]             120
                                        [2]             87
        Measured                FLOAT   10    4     2s   0   RWD  
                                        [0]             1.56
                                        [1]             120
                                        [2]             87
    Statistics                  DIR
        Events sent             DOUBLE  1     8     17h  0   RWDE 26
        Events per sec.         DOUBLE  1     8     17h  0   RWDE 0
        kBytes per sec.         DOUBLE  1     8     17h  0   RWDE 0


Electronic Logbook

The Electronic logbook is an alternative way of recording experiment information. This is implemented through the Midas web server mhttpd task (see Elog page). The definition of the options can be found in the ODB data base under ODB /Elog Tree.


Log file

Midas provides a general log file midas.log for recording system and user messages across the different components of the data acquisition clients. The location of this file is dependent on the mode of installation of the system.
  1. [without ODB /Logger Tree] In this case the location is defined by either the MIDAS_DIR environment (see Environment variables ) or the definition of the experiment in the exptab file (see Experiment_Definition ). In both case the log file will be in the experiment specific directory.
  2. [with /Logger Tree] The midas.log will be sitting into the defined directory specified by Data Dir .

midas.log file will contains system and user messages generated by any application connected to the given experiment.

The MIDAS Macros definition provides a list of possible type of messages.

Fri Mar 24 10:48:40 2000 [CHAOS] Run 8362 started
Fri Mar 24 10:48:40 2000 [Logger] Run #8362 started
Fri Mar 24 10:55:04 2000 [Lazy_Tape] cni-043[10] (cp:383.6s) /dev/nst0/run08360.ybs 849.896MB file NEW
Fri Mar 24 11:24:03 2000 [MStatus] Program MStatus on host umelba started
Fri Mar 24 11:24:03 2000 [MStatus] Program MStatus on host umelba stopped
Fri Mar 24 11:27:02 2000 [Logger] stopping run after having received 1200000 events
Fri Mar 24 11:27:03 2000 [CHAOS] Run 8362 stopped
Fri Mar 24 11:27:03 2000 [SUSIYBOS] saving info in run log
Fri Mar 24 11:27:03 2000 [Logger] Run #8362 stopped
Fri Mar 24 11:27:13 2000 [Logger] starting new run
Fri Mar 24 11:27:14 2000 [CHAOS] Run 8363 started
Fri Mar 24 11:27:14 2000 [CHAOS] odb_access_file -I- /Equipment/kos_trigger/Dump not found
Fri Mar 24 11:27:14 2000 [Logger] Run #8363 started
Fri Mar 24 11:33:47 2000 [Lazy_Tape] cni-043[11] (cp:391.8s) /dev/nst0/run08361.ybs 850.209MB file NEW
Fri Mar 24 11:42:35 2000 [CHAOS] Run 8363 stopped
Fri Mar 24 11:42:40 2000 [SUSIYBOS] saving info in run log
Fri Mar 24 11:42:41 2000 [ODBEdit] Run #8363 stopped
Fri Mar 24 12:19:57 2000 [MChart] client [umelba.Triumf.CA]MChart failed watchdog test after 10 sec
Fri Mar 24 12:19:57 2000 [MChart] Program MChart on host koslx0 stopped

previous.gif Quick Start - Top - Utilities next.gif


Midas DOC Version 1.9.3 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Suzannah Daviel - Doxygen - Peter Green - Greg Hackman - Gertjan Hofman - Paul Knowles - Rudi Meier - Glenn Moloney - Dave Morris - Konstantin Olchanski - Renee Poutissou - Andreas Suter - Piotr Adam Zolnierczuk