Back Midas Rome Roody Rootana
  Midas DAQ System, Page 2 of 136  Not logged in ELOG logo
New entries since:Wed Dec 31 16:00:00 1969
ID Date Authordown Topic Subject
  154   08 Oct 2004 chris pearsonInfoIncreased number of clients in midas.h, important!
> > For one thing, looking at a given midas-using executable, how do I tell what version of midas it has inside?
> 
> Ther is a function cm_get_version() returning the version. As for the executable, all you can do is a
> 
> strings <executable> | grep 1.9

   A lot of programs have a commandline option, such as "--version", where they return the program version number then exit.  As well as the
program version number, the version number of the midas library it's linked with could also be returned (There can be more than one
libmidas.so on a system and this would show which one was currently being linked)

   Something I would find useful would be for the version number to identify precisely which version you have, i.e. not to have different
versions of midas given the same version number.  I've had problems earlier this year due to midas-1.9.3 changing several times between
January and July, while keeping the same number.  I think if "in-between" versions of midas are to be made available, they should contain a
revision number or date or something in the version number to identify them.

> For remote connections (through mserver), there is already a version check. If the minor version differs, you get a warning, if the major
> versions differ (1.>>9<<.4), the client won't start. So at least for remote connection you get a clue.

   Safety measures like these can sometimes get in the way, if you know what you're doing.  So unless there is absolutely no possibility of
success, I think checks such as this one should be overrideable (by a client option).

Chris
  175   24 Nov 2004 chris pearsonInfomidas on 64bit opteron
   Midas, version 1.9.5 of 7th October, was installed, with a few changes, on a
64 bit opteron computer, running linux.  For this processor, as for the alpha
processor, long integers and addresses are 64 bits.  We added a new flag in the
Makefile,

250a251
> ARCH   = $(shell uname -m)
377a379,381
> ifeq ($(ARCH),x86_64)
> OSFLAGS := $(OSFLAGS) -DX86_64
> endif

and extended the alpha-specific definitions, of DWORD and PTYPE, in midas.h to
include this case,

549c549
< #ifdef __alpha
---
> #if defined(__alpha) || defined(X86_64)
598c598
< #ifdef __alpha
---
> #if defined(__alpha) || defined(X86_64)

apart from this, there are a large number of cases where pointers are cast to
integers, without using the PTYPE definition.  These all need to be changed by
hand, although these conversions should probably be removed anyway - in almost
all cases they are unnecessary, as just differences are being calculated.

There were also a number of warnings, which we ignored, where printf format
strings specified long integers, but the argument was not a long integer.  Casts
should probably be added in all cases where the type of the argument can vary
depending on the machine.

A midas analyser was made, which was able to successfully replay some data, but
this was all that was tested.

Chris
  176   25 Nov 2004 chris pearsonForumuse of assert in mhttpd
   We've had mhttpd aborting regularly since upgrading from midas-1.9.3.  This
happens during elog queries, and is due to an elog file that was incorrectly
modified by hand.  The modification to the file occurred 6 months ago.
   el_retrieve(midas.c:15683) now has several assert statements, one of which
aborts the program on reading the bad entry.

   Why is assert used, instead of an error return from the function (if
necessary), and maybe an error message in the log file?  Assert statements are
often removed, using NDEBUG, for normal use.

Chris

   The problem elog entry had one character removed, so end-of-file came before
the end of the message.  This could probably occur without the file being
altered, if the disk containing the elog fills.
  730   02 Nov 2010 chris pearsonInfomhttpd: Extra entries on status page
   A couple of experiments at triumf wanted certain important odb variables
displayed on their status page.  (There was already the possibility to show the
run comment)
   A new folder "/Experiment/Status Items" was created containing links to the
variables of interest, these items are show on the status page, under the run
comment (if any), in 3 columns.

the code from mhttpd.c:show_status_page()
between
   /*---- run comment ----*/
and
   /*---- Equipment list ----*/
is attached
Attachment 1: status.c
   /*---- run comment ----*/

   /* Also Status items values (including run comment)               */
   /* want Run Comment to be shown first but, instead of             */
   /* storing everything and then displaying in our chosen order     */
   /* find comment first, and then show other items as they are seen */
   db_find_key(hDB,0,"/Experiment/Status Items", &hkey);
   if( hkey ){                               /* If this Directory exists ... */
      char status_data[1000];              /* same size as str defined above */
      db_find_key(hDB,0,"/Experiment/Status Items/comment", &hsubkey);
      if( hsubkey ){               /* Show Run comment before other items ...*/
         db_get_key(hDB, hsubkey, &key);
         size = sizeof(status_data);
         if( (status = db_get_data(hDB, hsubkey, status_data, &size, key.type))
	     == DB_SUCCESS && key.num_values == 1 && key.type != TID_KEY ){
            db_sprintf(str, status_data, key.item_size, 0, key.type);
            rsprintf("<tr align=center><td colspan=6 bgcolor=#E0E0FF><b>%s</b></td></tr>\n", str);
	 }
     }
     /* each key can also be a link: we want link data and original key name */
     /* => get key twice: follwing links(for data) not follow (for org name) */
     int item_count=0;                       /* Total number of things shown */
     for(i=0; ; i++){                       /* Loop over status-item subkeys */
        db_enum_key(hDB, hkey, i, &hsubkey);/*get ith key data, follow links */
        if( ! hsubkey ){ break; }                        /* (end of subkeys) */
        db_get_key(hDB, hsubkey, &key);     /*          ...                  */
        /* key data has unknown type, copy to status_data then conv -> string*/
        size = sizeof(status_data);   /* Don't try to display arrays/subdirs */
        if( (status=db_get_data(hDB,hsubkey, status_data, &size, key.type)) != 
           DB_SUCCESS || key.num_values>1 || key.type == TID_KEY ){ continue; }
        db_sprintf(str, status_data, key.item_size, 0, key.type); /*->string */

        db_enum_link(hDB, hkey, i, &hsubkey);    /* Get ith subkey link name */
        db_get_key(hDB, hsubkey, &key);          /*           ...            */
        if( strstr(key.name,"comment") ){ continue; } /* skip comment (done) */

        if( ! (item_count % 3) ){ rsprintf("<tr>"); }
        rsprintf("<td colspan=2 align=center bgcolor=#%06X>%s: <b>%s</b></td>",
           0xD0D0FF, key.name, str );
        if( ! (++item_count % 3) ){ rsprintf("</tr>\n"); }
     }
     while( (item_count % 3) ){         /* complete any partial row of 3 ... */
        rsprintf("<td colspan=2 bgcolor=#%06x></td>", 0xD0D0FF );
        if( (++item_count % 3) == 0 ){ rsprintf("</tr>\n"); }
     }
   } /* end of if existence of "status items" hkey */

   // Original Run Comment Section ...
   //   size = sizeof(str);
   //   if (db_get_value(hDB, 0, "/Experiment/Run parameters/Comment", str,
   //                    &size, TID_STRING, FALSE) == DB_SUCCESS)
   //      rsprintf("<tr align=center><td colspan=6 bgcolor=#E0E0FF><b>%s</b></td></tr>\n", str);

   /*---- Equipment list ----*/
  590   04 Jun 2009 bazinskiBug Reportmhttpd command line experiment specifying
Hi

Not sure how the rest of you specify mhttpd to work with multiple experiments on
one machine, but it would seem not the same as me ;-)

when executing mhttpd with 

mhttpd -e "experimentname" -p "experimentport" -D 

that experiment name is not transfered to transitions as cm_transition never
specifies the experiment in the call to "transition STOP" etc.
the only flag it sends is a -d for debug if selected.

The result is that the stop and start button of the webinterface does not work,
and transitions sit endlessly doing nothing but consuming all the processor,
odbedit works fine though.

Does everyone else use an apache reverse proxy and or explicit experiment choice
in the url ?

As an aside in mhttpd.c in the reply to -? it states 2 -h options the second
should be a -e. line 13378.


Thanks
Sean
  592   05 Jun 2009 bazinskiBug Reportmhttpd command line experiment specifying
Hi

> > Not sure how the rest of you specify mhttpd to work with multiple experiments on
> > one machine, but it would seem not the same as me ;-)
> 
> Please note that there has been a change concerning multiple experiments inside 
> mhttpd. From revision 4346 on, mhttpd can only connect to one single experiment, 
> and the experiment name in the URL (aka ?exp=name) is not supported any more. So if 
> you have several experiments, you start several instances of mhttpd now on 
> different ports.

That i do with : 
mhttpd -p xx -e experiment_name -D

> 
> > that experiment name is not transfered to transitions as cm_transition never
> > specifies the experiment in the call to "transition STOP" etc.
> > the only flag it sends is a -d for debug if selected.
> 
> When connecting to an experiment, any midas client uses the ODB from that 
> experiment so lives in that "namespace". So one client can never call any client 
> from another experiment. So your problem must be something else. Of course there is 
> not parameter "experiment" passed to cm_transition() since the experiment is 
> implicitly defined by the ODB mhttpd is attached to.

Will have to look else where.

> 
> > The result is that the stop and start button of the webinterface does not work,
> > and transitions sit endlessly doing nothing but consuming all the processor,
> > odbedit works fine though.
> 
> I guess you have to do some debugging there. Note that "detached" transitions have 
> been implemented recently by Konstantin, so maybe your problem is related to that. 
> In this case Konstantin should check what's wrong.

cm_transition does a "system(str)" on line 3243 inside the "if(async_flag == DETACH)" of
line 3219, how does an external program know about the state of the originating mhttpd
process ? Surely that str which executes "mtransition ......." should get a -e
specifying the experiment explicitly ? probably a -h as well to be thorough.
The only other way that mtransition.cxx will be able to pull in the experimentname is
from the environment variable in its call to cm_get_environment(....) on its startup.


Ok after some testing .... 
If i start the mhttpd with the environment variable MIDAS_EXPT_NAME set then its happy
as mtransition inherits the environment of mhttpd so cm_get_environment(...) of
mtransition picks up the experiment. Similarly if i insert "-e experimentname" into the
string "str" that is passed in system(str) of line 3243. Then start and stop buttons work. 

Konstantin any comments.

I suppose i can live with starting mhttpd with the environment set before running, but
that kind of negates the command line argument to mhttpd. 

Thanks for the help

Sean
  1164   22 Feb 2016 ZiyiGuoForumProblem with BLTRead
Dear all,

I'm using MIDAS system and CAEN V1721 to digitize the waveform from photomultipliers ( 
and the link bridge to PC is V2718 ). I use BLTRead to read data of the digitizer, but 
I found that if the event counting rate is high ( about 100KB/s ), the communication 
of V1721 and PC would be suspended randomly, and I get an error code of -2. Could you 
give me some suggestion? Thanks a lot.
  1167   02 Mar 2016 ZiyiGuoForumProblem with BLTRead
> > Dear all,
> >
> > I'm using MIDAS system and CAEN V1721 to digitize the waveform from photomultipliers (
> > and the link bridge to PC is V2718 ). I use BLTRead to read data of the digitizer, but
> > I found that if the event counting rate is high ( about 100KB/s ), the communication
> > of V1721 and PC would be suspended randomly, and I get an error code of -2. Could you
> > give me some suggestion? Thanks a lot.
>
> Hi,
>
> Can you provide the BLTread call fragment code and the PC /var/log/messages at the time of
> the hang up.
> What is needed to restart the daq?
>
> PAA

Hi Pierre-Andre,

Sorry for my late reply, because the data acquisition system now is running other experiment.
Here is my code. Is there something wrong? Thanks!




/* Read FADC data */
int NByteOfOneEvent = HeadSize + SampSize * NChannel;
int NDWordOfOneEvent = NByteOfOneEvent/4;


/* 1. Create FADC bank. One bank for one branch of a tree or one array branch with length. */
bk_create(pevent, "FADC", TID_DWORD, (void**)&pdata);

uint32_t size_remaining_dwords;
int dwords_read;

/* 2. Read out the event and assign them to pdata (bank buffer) */
//read size of event to be read
sCAEN = CAENComm_Read32(hFADC[card], V1721_EVENT_SIZE, &size_remaining_dwords);

if( size_remaining_dwords < NDWordOfOneEvent ) {
printf("\r\nSize of available data is less than the required size of one event.\r\n");
}

/* Read */
DWORD *pFadcData;
sCAEN = CAENComm_BLTRead(hFADC[card], V1721_EVENT_READOUT_BUFFER, pdata, NDWordOfOneEvent, &dwords_read);

// These code in "if" is for restart communication and save the time information if the communication was suspended

if(sCAEN != 0)
{
//printf("sCAEN =%d \n", sCAEN);
time_t t = time(0);
char tmp[64];
strftime(tmp,sizeof(tmp),"%Y/%m/%d %X %Z",localtime(&t));
fprintf(logfile,tmp);
fprintf(logfile,"\n Here met communication error \n");
printf(" Here met communication error \n");

//re-establish communication
sCAEN = CAENComm_CloseDevice(hFADC[card]);
fprintf(logfile,"sCAEN =%d, device closed **********\n", sCAEN);

ss_sleep(2000);

sCAEN = CAENComm_OpenDevice(CAENComm_PCIE_OpticalLink, l, d, FADCBA[card], &(hFADC[card]));

if (sCAEN == CAENComm_Success) {
fprintf(logfile,"re-establish communication, handle:%d, sCAEN=%d \n", hFADC[card], sCAEN);
}
else {
sCAEN = CAENComm_OpenDevice(CAENComm_PCIE_OpticalLink, l, d, FADCBA[card], &(hFADC[card]));
fprintf(logfile,"try open device again sCAEN= %d\n", sCAEN); }

//pause ongoing reading process
sCAEN = ov1721_AcqCtl(hFADC[card], V1721_RUN_STOP);
sCAEN = CAENComm_Read32(hFADC[card], V1721_EVENT_STORED, &eStored);

//discard FADC buffer
sCAEN = CAENComm_Write32(hFADC[card], V1721_SW_CLEAR, 0);
fprintf(logfile," number of %d events discarded \n\n", eStored);
sCAEN = ov1721_AcqCtl(hFADC[card], V1721_RUN_START);
}

//dwords_read: Number of the words that actually read from the device.
if( dwords_read != NDWordOfOneEvent ) {
printf("\r\nSize of data read out doesn't equal to the required size of one event. \r\n");
}

EvtCounterFadc[card] = *(pdata+2) & 0x00ffffff;

/* 3. Update bank pointer position */
pdata += dwords_read;

/* 4. Finish one bank */
bk_close(pevent, pdata);
  811   22 Jun 2012 Zisis PapandreouInfoadding 2nd ADC and TDC to crate
Hi folks:

we've been running midas-1.9.5 for a few years here at Regina.  We are now
working on a larger cosmic ray testing that requires a second ADC and second TDC
module in our Camac crate (we use the hytek1331 controller by the way).  We're
baffled as to how to set this up properly.  Specifically we have tried:

frontend.c

/* number of channels */
#define N_ADC  12 
(changed this from the old '8' to '12', and it seems to work for Lecroy 2249)

#define SLOT_ADC0   10
#define SLOT_TDC0   9
#define SLOT_ADC1   15
#define SLOT_TDC1   14

Is this the way to define the additional slots (by adding 0, 1 indices)?

Also, we were not able to get a new bank (ADC1) working, so we used a loop to
tag the second ADC values onto those of the first.

If someone has an example of how to handle multiple ADCs and TDCs and
suggestions as to where changes need to be made (header files, analyser, etc)
this would be great.

Thanks, Zisis...

P.S.  I am attaching the relevant files.
Attachment 1: frontend.c
/********************************************************************\

  Name:         frontend.c
  Created by:   Stefan Ritt

  Contents:     Experiment specific readout code (user part) of
                Midas frontend. This example simulates a "trigger
                event" and a "scaler event" which are filled with
                CAMAC or random data. The trigger event is filled 
                with two banks (ADC0 and TDC0), the scaler event 
                with one bank (SCLR).

  $Log: frontend.c,v $
  Revision 1.14  2002/05/16 21:09:53  midas
  Added max_event_size_frag

  Revision 1.11  2000/08/21 10:32:51  midas
  Added max_event_size, set event_buffer_size = 10*max_event_size

  Revision 1.10  2000/03/13 18:53:29  pierre
  - Added 2nd arg in readout functions (offset for Super event)

  Revision 1.9  2000/03/02 22:00:00  midas
  Added number of subevents as zero

  Revision 1.8  1999/02/24 16:27:01  midas
  Added some "real" readout code

  Revision 1.7  1999/01/20 09:03:38  midas
  Added LAM_SOURCE_CRATE and LAM_SOURCE_STATION macros

  Revision 1.6  1999/01/19 10:27:30  midas
  Use new LAM_SOURCE and LAM_STATION macros

  Revision 1.5  1998/11/09 09:14:41  midas
  Added code to simulate random data

  Revision 1.4  1998/10/29 14:27:46  midas
  Added note about FE_ERR_HW in frontend_init()

  Revision 1.3  1998/10/28 15:50:58  midas
  Changed lam to DWORD

  Revision 1.2  1998/10/12 12:18:58  midas
  Added Log tag in header


\********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "midas.h"
#include "mcstd.h"
#include "experim.h"

/* make frontend functions callable from the C framework */
#ifdef __cplusplus
extern "C" {frontend.c
#endif

/*-- Globals -------------------------------------------------------*/

/* The frontend name (client name) as seen by other MIDAS clients   */
char *frontend_name = "Sample Frontend";
/* The frontend file name, don't change it */
char *frontend_file_name = __FILE__;

/* frontend_loop is called periodically if this variable is TRUE    */
BOOL frontend_call_loop = FALSE;

/* a frontend status page is displayed with this frequency in ms */
INT display_period = 3000;

/* maximum event size produced by this frontend */
INT max_event_size = 10000;

/* maximum event size for fragmented events (EQ_FRAGMENTED) */
INT max_event_size_frag = 5*1024*1024;

/* buffer size to hold events */
INT event_buffer_size = 10*10000;

/* number of channels */
#define N_ADC  12  
#define N_TDC  8  
#define N_SCLR 8

/* CAMAC crate and slots */
#define CRATE      0
#define SLOT_IO   23
#define SLOT_ADC0   10
#define SLOT_TDC0   9 
#define SLOT_ADC1   15
#define SLOT_TDC1   14
#define SLOT_SCLR  12

/*-- Function declarations -----------------------------------------*/

INT frontend_init();
INT frontend_exit();
INT begin_of_run(INT run_number, char *error);
INT end_of_run(INT run_number, char *error);
INT pause_run(INT run_number, char *error);
INT resume_run(INT run_number, char *error);
INT frontend_loop();

INT read_trigger_event(char *pevent, INT off);
INT read_scaler_event(char *pevent, INT off);

/*-- Equipment list ------------------------------------------------*/

#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(CRATE,LAM_STATION(SLOT_TDC0)), /* event source crate 0, TDC */
    "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 */
  },

  { "Scaler",             /* equipment name */
    2, 0,                 /* event ID, trigger mask */
    "SYSTEM",             /* event buffer */
    EQ_PERIODIC | 
    EQ_MANUAL_TRIG,       /* equipment type */
    0,                    /* event source */
    "MIDAS",              /* format */
    TRUE,                 /* enabled */
    RO_RUNNING |
    RO_TRANSITIONS |      /* read when running and on transitions */
    RO_ODB,               /* and update ODB */ 
    10000,                /* read every 10 sec */
    0,                    /* stop run after this event limit */
    0,                    /* number of sub events */
    0,                    /* log history */
    "", "", "",
    read_scaler_event,    /* readout routine */
  },

  { "" }
};

#ifdef __cplusplus
}
#endif

/********************************************************************\
              Callback routines for system transitions

  These routines are called whenever a system transition like start/
  stop of a run occurs. The routines are called on the following
  occations:

  frontend_init:  When the frontend program is started. This routine
                  should initialize the hardware.
  
  frontend_exit:  When the frontend program is shut down. Can be used
                  to releas any locked resources like memory, commu-
                  nications ports etc.

  begin_of_run:   When a new run is started. Clear scalers, open
                  rungates, etc.

  end_of_run:     Called on a request to stop a run. Can send 
                  end-of-run event and close run gates.

  pause_run:      When a run is paused. Should disable trigger events.

  resume_run:     When a run is resumed. Should enable trigger events.

\********************************************************************/

/*-- Frontend Init -------------------------------------------------*/

INT frontend_init()
{
  /* hardware initialization */

  cam_init();
  cam_crate_clear(CRATE);
  cam_crate_zinit(CRATE);
  cam_inhibit_set(CRATE);

  /* enable LAM in IO unit */
  /* camc(CRATE, SLOT_IO, 0, 26); */

  /* enable LAM in crate controller */
  /* cam_lam_enable(CRATE, SLOT_IO); */
  
  /* reset external LAM Flip-Flop */
  /* camo(CRATE, SLOT_IO, 1, 16, 0xFF); */
  /* camo(CRATE, SLOT_IO, 1, 16, 0); */

  /* print message and return FE_ERR_HW if frontend should not be started */

  return SUCCESS;
}

/*-- Frontend Exit -------------------------------------------------*/

INT frontend_exit()
{
  return SUCCESS;
}

/*-- Begin of Run --------------------------------------------------*/

INT begin_of_run(INT run_number, char *error)
{
  /* put here clear scalers etc. */


  /* clear TDC units */
  camc(CRATE, SLOT_TDC0, 0, 9);
  camc(CRATE, SLOT_TDC1, 0, 9); 
  /* clear ADC units */
  camc(CRATE, SLOT_ADC0, 0, 9);
  camc(CRATE, SLOT_ADC1, 0, 9); 

  /* disable LAM in ADC and TDC1 units */
  camc(CRATE, SLOT_ADC0, 0, 24);
  camc(CRATE, SLOT_ADC1, 0, 24); 
  camc(CRATE, SLOT_TDC1, 0, 24); 
  /* enable LAM in TDC0 unit */
  camc(CRATE, SLOT_TDC0, 0, 26);
  cam_inhibit_clear(CRATE);
  cam_lam_enable(CRATE, SLOT_TDC0);
  
  return SUCCESS;
}

/*-- End of Run ----------------------------------------------------*/

INT end_of_run(INT run_number, char *error)
{
  camc(CRATE, SLOT_TDC0, 0, 24);
  camc(CRATE, SLOT_ADC0, 0, 24); 
  camc(CRATE, SLOT_TDC1, 0, 24);
  camc(CRATE, SLOT_ADC1, 0, 24); 
  cam_inhibit_set(CRATE);

  return SUCCESS;
}

/*-- Pause Run -----------------------------------------------------*/

INT pause_run(INT run_number, char *error)
{
  return SUCCESS;
}

/*-- Resuem Run ----------------------------------------------------*/

INT resume_run(INT run_number, char *error)
{
  return SUCCESS;
}

/*-- Frontend Loop -------------------------------------------------*/

INT frontend_loop()
{
  /* if frontend_call_loop is true, this routine gets called when
     the frontend is idle or once between every event */
  return SUCCESS;
}

/*------------------------------------------------------------------*/

/********************************************************************\
  
  Readout routines for different events

\********************************************************************/

/*-- 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;
... 155 more lines ...
Attachment 2: analyzer.c
/********************************************************************\

  Name:         analyzer.c
  Created by:   Stefan Ritt

  Contents:     System part of Analyzer code for sample experiment

  $Log: analyzer.c,v $
  Revision 1.4  2000/03/02 22:00:18  midas
  Changed events sent to double

  Revision 1.3  1998/10/29 14:18:19  midas
  Used hDB consistently

  Revision 1.2  1998/10/12 12:18:58  midas
  Added Log tag in header


\********************************************************************/
                                                        
/* standard includes */
#include <stdio.h>
#include <time.h>

/* midas includes */
#include "midas.h"
#include "experim.h"
#include "analyzer.h"

/* cernlib includes */
#ifdef OS_WINNT
#define VISUAL_CPLUSPLUS
#endif
#ifdef __linux__
#define f2cFortran
#endif
#ifndef MANA_LITE
#include <cfortran.h>
#include <hbook.h>

PAWC_DEFINE(1000000);
#endif
/*-- Globals -------------------------------------------------------*/

/* The analyzer name (client name) as seen by other MIDAS clients   */
char *analyzer_name = "Analyzer";

/* analyzer_loop is called with this interval in ms (0 to disable)  */
INT  analyzer_loop_period = 0;

/* default ODB size */
INT  odb_size = DEFAULT_ODB_SIZE;

/* ODB structures */ 

RUNINFO          runinfo;
GLOBAL_PARAM     global_param;
EXP_PARAM        exp_param;
TRIGGER_SETTINGS trigger_settings;

/*-- Module declarations -------------------------------------------*/

extern ANA_MODULE scaler_accum_module;
extern ANA_MODULE adc_calib_module;
extern ANA_MODULE adc_summing_module;

ANA_MODULE *scaler_module[] = {
  &scaler_accum_module,
  NULL
};

ANA_MODULE *trigger_module[] = {
  &adc_calib_module,
  &adc_summing_module,
  NULL
};

/*-- Bank definitions ----------------------------------------------*/

ASUM_BANK_STR(asum_bank_str);

BANK_LIST trigger_bank_list[] = {
  /* online banks */
  { "ADC0", TID_WORD, 2*N_ADC, NULL },
/*  { "ADC1", TID_WORD, N_ADC, NULL },
  { "TDC1", TID_WORD, N_TDC, NULL }, */
  { "TDC0", TID_WORD, 2*N_TDC, NULL },

  /* calculated banks */
  { "CADC", TID_FLOAT, N_ADC, NULL },
  { "ASUM", TID_STRUCT, sizeof(ASUM_BANK), asum_bank_str },

  { "" },
};

BANK_LIST scaler_bank_list[] = {
  /* online banks */
  { "SCLR", TID_DWORD,  N_ADC, NULL },

  /* calculated banks */
  { "ACUM", TID_DOUBLE, N_ADC, NULL },
  { "" },
};

/*-- Event request list --------------------------------------------*/

ANALYZE_REQUEST analyze_request[] = {
  { "Trigger",            /* equipment name */
    1,                    /* event ID */
    TRIGGER_ALL,          /* trigger mask */
    GET_SOME,             /* get some events */
    "SYSTEM",             /* event buffer */
    TRUE,                 /* enabled */
    "", "", 
    NULL,                 /* analyzer routine */
    trigger_module,       /* module list */
    trigger_bank_list,    /* bank list */
    1000,                 /* RWNT buffer size */
    TRUE,                 /* Use tests for this event */
  },

  { "Scaler",             /* equipment name */
    2,                    /* event ID */
    TRIGGER_ALL,          /* trigger mask */
    GET_ALL,              /* get all events */
    "SYSTEM",             /* event buffer */
    TRUE,                 /* enabled */
    "", "", 
    NULL,                 /* analyzer routine */
    scaler_module,        /* module list */
    scaler_bank_list,     /* bank list */
    100,                  /* RWNT buffer size */
  },

  { "" }
};

/*-- Analyzer Init -------------------------------------------------*/

INT analyzer_init()
{
HNDLE hDB, hKey;
char  str[80];

RUNINFO_STR(runinfo_str);
EXP_PARAM_STR(exp_param_str);
EXP_EDIT_STR(exp_edit_str);
GLOBAL_PARAM_STR(global_param_str);
TRIGGER_SETTINGS_STR(trigger_settings_str);

  /* open ODB structures */
  cm_get_experiment_database(&hDB, NULL);
  db_create_record(hDB, 0, "/Runinfo", strcomb(runinfo_str));
  db_find_key(hDB, 0, "/Runinfo", &hKey);
  if (db_open_record(hDB, hKey, &runinfo, sizeof(runinfo), MODE_READ, NULL, NULL) != DB_SUCCESS)
    {
    cm_msg(MERROR, "analyzer_init", "Cannot open \"/Runinfo\" tree in ODB");
    return 0;
    }

  db_create_record(hDB, 0, "/Experiment/Run Parameters", strcomb(exp_param_str));
  db_find_key(hDB, 0, "/Experiment/Run Parameters", &hKey);
  if (db_open_record(hDB, hKey, &exp_param, sizeof(exp_param), MODE_READ, NULL, NULL) != DB_SUCCESS)
    {
    cm_msg(MERROR, "analyzer_init", "Cannot open \"/Experiment/Run Parameters\" tree in ODB");
    return 0;
    }

  db_create_record(hDB, 0, "/Experiment/Edit on start", strcomb(exp_edit_str));

  sprintf(str, "/%s/Parameters/Global", analyzer_name);
  db_create_record(hDB, 0, str, strcomb(global_param_str));
  db_find_key(hDB, 0, str, &hKey);
  if (db_open_record(hDB, hKey, &global_param, sizeof(global_param), MODE_READ, NULL, NULL) != DB_SUCCESS)
    {
    cm_msg(MERROR, "analyzer_init", "Cannot open \"%s\" tree in ODB", str);
    return 0;
    }

  db_create_record(hDB, 0, "/Equipment/Trigger/Settings", strcomb(trigger_settings_str));
  db_find_key(hDB, 0, "/Equipment/Trigger/Settings", &hKey);

  if (db_open_record(hDB, hKey, &trigger_settings, sizeof(trigger_settings), MODE_READ, NULL, NULL) != DB_SUCCESS)
    {
    cm_msg(MERROR, "analyzer_init", "Cannot open \"/Equipment/Trigger/Settings\" tree in ODB");
    return 0;
    }

  return SUCCESS;
}

/*-- Analyzer Exit -------------------------------------------------*/

INT analyzer_exit()
{
  return CM_SUCCESS;
}

/*-- Begin of Run --------------------------------------------------*/

INT ana_begin_of_run(INT run_number, char *error)
{
  return CM_SUCCESS;
}

/*-- End of Run ----------------------------------------------------*/

INT ana_end_of_run(INT run_number, char *error)
{
FILE   *f;
time_t now;
char   str[256];
int    size;
double n;
HNDLE  hDB;
BOOL   flag;

  cm_get_experiment_database(&hDB, NULL);

  /* update run log if run was written and running online */

  size = sizeof(flag);
  db_get_value(hDB, 0, "/Logger/Write data", &flag, &size, TID_BOOL, TRUE);
  /* if (flag && runinfo.online_mode == 1) */
  if (flag )
    {
    /* update run log */
    size = sizeof(str);
    str[0] = 0;
    db_get_value(hDB, 0, "/Logger/Data Dir", str, &size, TID_STRING, TRUE);
    if (str[0] != 0)
      if (str[strlen(str)-1] != DIR_SEPARATOR)
        strcat(str, DIR_SEPARATOR_STR);
    strcat(str, "runlog.txt");
    
    f = fopen(str, "a");

    time(&now);
    strcpy(str, ctime(&now));
    str[10] = 0;

    fprintf(f, "%s\t%3d\t", str, runinfo.run_number);

    strcpy(str, runinfo.start_time);
    str[19] = 0;
    fprintf(f, "%s\t", str+11);

    strcpy(str, ctime(&now));
    str[19] = 0;
    fprintf(f, "%s\t", str+11);

    size = sizeof(n);
    db_get_value(hDB, 0, "/Equipment/Trigger/Statistics/Events sent", &n, &size, TID_DOUBLE, TRUE);

    fprintf(f, "%5.1lfk\t", n/1000);
    fprintf(f, "%s\n", exp_param.comment);

    fclose(f);
    }

  return CM_SUCCESS;
}

/*-- Pause Run -----------------------------------------------------*/

INT ana_pause_run(INT run_number, char *error)
{
  return CM_SUCCESS;
}

/*-- Resume Run ----------------------------------------------------*/

INT ana_resume_run(INT run_number, char *error)
{
  return CM_SUCCESS;
}

/*-- Analyzer Loop -------------------------------------------------*/

INT analyzer_loop()
{
  return CM_SUCCESS;
}

/*------------------------------------------------------------------*/
Attachment 3: analyzer.h
/********************************************************************\

  Name:         analyzer.h
  Created by:   Stefan Ritt

  Contents:     Analyzer global include file

  $Log: analyzer.h,v $
  Revision 1.2  1998/10/12 12:18:58  midas
  Added Log tag in header


\********************************************************************/
                                                        
/*-- Parameters ----------------------------------------------------*/

/* number of channels */
#define N_ADC              12
#define N_TDC               8
#define N_SCLR              8

/*-- Histo ID bases ------------------------------------------------*/

#define ADCCALIB_ID_BASE 2000
#define ADCSUM_ID_BASE   3000
  985   17 Mar 2014 Zhi LiForum[need help] simple example frontend for CAEN VX1721
Dear guys,

I’m Zhi Li from China, and I’m now working on my graduation project, which now
basically gets stuck in the part of preparing the frontend for my FADC (CAEN
VX1721) using Midas.

Now the current set-up includes a VME crate, a CAEN v2718 (Optical Bridge and
Controller) and a CAEN VX1721(8ch 8bit 500MS/s Waveform digitizer). The hardware
set-up has been finished and I could capture the analog waveform using CAEN
software(wavedump). 

Could anyone please tell me what are the basic things to do for using MIDAS?
I’ve installed MIDAS in PC and it works well for CAMAC, but do I need any extra
hardware module on using VME crate? Also, how to download
Universe-II VME driver?

Thanks,
Li
  989   17 Mar 2014 Zhi LiForum[need help] simple example frontend for CAEN VX1721
Hi Pierre,

Thanks for your instructions. Before I run the wavedump software, I need to load a driver file for A2818, thus I think I've got this interface of A2818.

I would be grateful to have a look at the frontend example used for v1720 (closer to v1721 I suppose), would you be so kind to offer me the Makefile as well? I
really want to have a compilable/executable DAQ frontend for vme modules, and know better how to link to CAEN library in the Makefile.

About hardware currently used in the vme crate(A2818), there is a VME controller(V2718, CONET VME Bridge), and a FADC(VX1721 waveform digitizer). I'm now preparing
this DAQ system to compare relative quantum efficiency, timing resolution, 1 pe distribution of photomultipliers, also measure decay time of cosmic muons, and
electron spectrum. Humbly, I want to know your opinion on whether I need additional hardware to finish these experiments.

Thanks,
Li

> Hi Li,
> 
> You mention that you've got the wavedump working. It suggests that you have a A3818 
> interface, can you confirm that?
> 
> If so, you can make a Midas frontend using the CAEN libraries to access your VX1721. I can provide you with a frontend example used for the V1720 or V1740. The 
> modifications for the VX1721 shouldn't be too hard as most of the CAEN digitizers 
> are fortunately based on a similar configuration mechanism.
> If you have a Midas CAMAC frontend, the trick would be to replace the CAMAC calls by 
> the appropriate CAENComm_xxx() for the equivalent functionality.
> 
> Can you remind me what hardware do you have in your lab for acquisition?
> CAMAC controller, VME controller etc.
> 
> Cheers, PAA
> 
> > Dear guys,
> > 
> > I’m Zhi Li from China, and I’m now working on my graduation project, which now
> > basically gets stuck in the part of preparing the frontend for my FADC (CAEN
> > VX1721) using Midas.
> > 
> > Now the current set-up includes a VME crate, a CAEN v2718 (Optical Bridge and
> > Controller) and a CAEN VX1721(8ch 8bit 500MS/s Waveform digitizer). The hardware
> > set-up has been finished and I could capture the analog waveform using CAEN
> > software(wavedump). 
> > 
> > Could anyone please tell me what are the basic things to do for using MIDAS?
> > I’ve installed MIDAS in PC and it works well for CAMAC, but do I need any extra
> > hardware module on using VME crate? Also, how to download
> > Universe-II VME driver?
> > 
> > Thanks,
> > Li
  1183   06 Jul 2016 Zhe WangSuggestionFrontend crush on high event rate
Dear friends,

We have some questions on using midas.
We use a Caen digitizer V1751 to take waveforms.
When testing with caen provided programs, we roughly know it can work fine at 1000 Hz event rate, and 30 M/s data can be written to disk.
The test with Midas, however, is a little confusing. We use CAENDigitizer library with Midas. First, it works, data were taken, and there seems no error.
The only problem is we cannot go to a higher event rate, for example we can only work on a rate of 40 Hz, and only 3 M/s data recording. Otherwise it will crush.

We may miss something really simple. Would you please give some suggestions? for example, other people's discussions or documents?

Thank you very much.
  1184   09 Jul 2016 Zhe WangSuggestionFrontend crush on high event rate
Dear friends,

I may add a little more information.
For polling event, we check the data-ready register for the status of the digitizer.
In the readout routine, we create a bank, readout the data and write it out.

We commented out or made some replacement for each part of the subroutines to figure our where exactly goes wrong.
for example, replace the readout from the digitizer with a random generation of some fake events.
By replacing the readout by a random generation, the program runs fine and reach a very high event rates.

Any suggestions or ideas from experts?

Thank you very much.

--
Best regards,
Zhe Wang


> Dear friends,
> 
> We have some questions on using midas.
> We use a Caen digitizer V1751 to take waveforms.
> When testing with caen provided programs, we roughly know it can work fine at 1000 Hz event rate, and 30 M/s data can be written to disk.
> The test with Midas, however, is a little confusing. We use CAENDigitizer library with Midas. First, it works, data were taken, and there seems no error.
> The only problem is we cannot go to a higher event rate, for example we can only work on a rate of 40 Hz, and only 3 M/s data recording. Otherwise it will crush.
> 
> We may miss something really simple. Would you please give some suggestions? for example, other people's discussions or documents?
> 
> Thank you very much.
  1185   10 Jul 2016 Zhe WangSuggestionFrontend crush on high event rate
Dear friends,

In case anyone need the source code, it is attached. 
We use optic fiber to connect to a VME controler, which talks to V1751 via VME bus.

--
Zhe Wang

> Dear friends,
> 
> I may add a little more information.
> For polling event, we check the data-ready register for the status of the digitizer.
> In the readout routine, we create a bank, readout the data and write it out.
> 
> We commented out or made some replacement for each part of the subroutines to figure our where exactly goes wrong.
> for example, replace the readout from the digitizer with a random generation of some fake events.
> By replacing the readout by a random generation, the program runs fine and reach a very high event rates.
> 
> Any suggestions or ideas from experts?
> 
> Thank you very much.
> 
> --
> Best regards,
> Zhe Wang
> 
> 
> > Dear friends,
> > 
> > We have some questions on using midas.
> > We use a Caen digitizer V1751 to take waveforms.
> > When testing with caen provided programs, we roughly know it can work fine at 1000 Hz event rate, and 30 M/s data can be written to disk.
> > The test with Midas, however, is a little confusing. We use CAENDigitizer library with Midas. First, it works, data were taken, and there seems no error.
> > The only problem is we cannot go to a higher event rate, for example we can only work on a rate of 40 Hz, and only 3 M/s data recording. Otherwise it will crush.
> > 
> > We may miss something really simple. Would you please give some suggestions? for example, other people's discussions or documents?
> > 
> > Thank you very much.
Attachment 1: frontend.c
/*****************************************************************\

Name:         frontend.c
Created by: 	Zhe Wang 
Date:         03/16/2015 

Modified by: Mohan Li
Date: 07/04/2016

Contents:     Experiment specific readout code (user part) of Midas frontend.
Supported VME modules:
CAEN V2718 VME-CONET Bridge
CAEN V1751 10-Bits 1-GHz Flash ADC

Experiment: Dark noise

Currently: Use CAEN_Digitizer lib. Use Ramdom number to avoid disconnection. 

$Id: $

\********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "midas.h"
#include "mcstd.h"
#include "mvmestd.h"
#include "experim.h"
#include "v1751.h"
#include "v775n.h"
#include "v785n.h"
#include "v1751Infc.h"
#include "v775nInfc.h"
#include "CAENDigitizer.h"

/* make frontend functions callable from the C framework */
#ifdef __cplusplus
extern "C" {
#endif

	/*-- Globals -------------------------------------------------------*/

	/* The frontend name (client name) as seen by other MIDAS clients   */
	char *frontend_name = "Frontend";
	/* The frontend file name, don't change it */
	char *frontend_file_name = __FILE__;

	/* frontend_loop is called periodically if this variable is TRUE    */
	BOOL frontend_call_loop = FALSE;

	/* a frontend status page is displayed with this frequency in ms */
	INT display_period = 500;

	/* maximum event size produced by this frontend */
	//INT max_event_size = 10000;
	INT max_event_size = 100000; //modified according to feov1721.cxx

	/* maximum event size for fragmented events (EQ_FRAGMENTED) */
	INT max_event_size_frag = 5 * 1024 * 1024;

	/* buffer size to hold events */
	INT event_buffer_size = 200 * 100000;

#define NFADC 1
#define NMax 4
	int hFADC[NFADC];

	/* VMEBaseAddress */
	uint32_t FADCBA[NMax] = {0x000C0000,0,0,0};  // FADC base address 0x80000000

	uint32_t EvtCounterFadc[NMax];

	/* Time in second*/
	uint32_t TimeInSec;

	/* initiate variables */

	FILE* logfile;

	//CAENComm_ErrorCode sCAENc;

	int l=0, d=0, h=0, Nh;
	uint32_t i, lcount, temp, lam, reg, data[50000];
	int Nmodulo=10; //print transmission information every Nmodulo events
	int tcount=0, eloop=0;
	DWORD  eStored, eSize;
	DWORD eventReady;
	DWORD BLTNB;
	DWORD recordlength;
	uint32_t recordsize = 0x1000;
	int loop, Nloop=10;
	int bshowData=0; // 1 to enable data print
	int debug = 0;
	uint32_t pct=0, ct;
	struct timeval t1;
	int   dt1, savelcount=0;
	float trg_rate =0;
	int data_test = 0; // 1 for stored data check
	int simulation = 0;// 1 for simulation mode
	

	/*-------------CAEN Digitier vairables----------*/
	int card=0;
	CAEN_DGTZ_ErrorCode sCAEN;
	CAEN_DGTZ_BoardInfo_t BoardInfo;
	char *buffer = NULL; //pointer to the read out buffer
	int c = 0;
	uint32_t size; //buffer allocated for reading data
	uint32_t bsize;
#define INTERRUPT_TIMEOUT 20000 //20000ms = 20s
#define VME_INTERRUPT_LEVEL 1
#define VME_INTERRUPT_STATUS_ID 0xAAAA
#define IRQ_EVENT_NUMBER 1
	unsigned int counter = 0;
	unsigned int preScaler = 100;



	/*-- Function declarations -----------------------------------------*/

	INT frontend_init(); 
	INT frontend_exit();
	INT begin_of_run(INT run_number, char *error);
	INT end_of_run(INT run_number, char *error);
	INT pause_run(INT run_number, char *error);
	INT resume_run(INT run_number, char *error);
	INT frontend_loop();

	INT read_trigger_event(char *pevent, INT off);
	INT frontend_config();

	/*-- Equipment list ------------------------------------------------*/

#undef USE_INT
//#define 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(CRATE, LAM_STATION(SLOT_ADC)), /* event source */
				LAM_SOURCE(0, 0xFFFFFF),   /* event source crate 0, all stations, by Li*/
				"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 */
		},

		{""}
	};

#ifdef __cplusplus
}
#endif

/********************************************************************\
  Callback routines for system transitions

  These routines are called whenever a system transition like start/
  stop of a run occurs. The routines are called on the following
occations:

frontend_init:  When the frontend program is started. This routine
should initialize the hardware.

frontend_exit:  When the frontend program is shut down. Can be used
to releas any locked resources like memory, commu-
nications ports etc.

begin_of_run:   When a new run is started. Clear scalers, open
rungates, etc.

end_of_run:     Called on a request to stop a run. Can send
end-of-run event and close run gates.

pause_run:      When a run is paused. Should disable trigger events.

resume_run:     When a run is resumed. Should enable trigger events.

\********************************************************************/

/*-- Frontend Init -------------------------------------------------*/
INT frontend_init()
{
	// Open FADC digitizer
	for( card=0; card<NFADC; card++ )  {
		sCAEN = CAEN_DGTZ_OpenDigitizer(CAEN_DGTZ_PCI_OpticalLink, 0, card, FADCBA[card], &hFADC[card]);
		if(sCAEN != CAEN_DGTZ_Success) {
			printf("Can't open digitizer\n");
			sCAEN = CAEN_DGTZ_CloseDigitizer(hFADC[card]);
		}else{
			printf("Open Device successfully.\n");
			frontend_config();
		}
	}
	return SUCCESS;
}

INT frontend_config()
{
	/* ------FADC configuration------ */
	for( card=0; card<NFADC; card++ )  {  

		//Print Board Info
		sCAEN = CAEN_DGTZ_GetInfo(hFADC[card], &BoardInfo);
		printf("\nConnected to CAEN Digitizer Model %s, recognized as board %d\n", BoardInfo.ModelName, card);
		printf("\tROC FPGA Release is %s\n", BoardInfo.ROC_FirmwareRel);
		printf("\tAMC FPGA Release is %s\n", BoardInfo.AMC_FirmwareRel);
		//Reset Digitizer
		sCAEN = CAEN_DGTZ_Reset(hFADC[card]);
		//Calibrate temperatire
		sCAEN = CAEN_DGTZ_Calibrate(hFADC[card]);
		//Set the lenght of each waveform (in samples)
		sCAEN = CAEN_DGTZ_SetRecordLength(hFADC[card], 1792);
		//Generate a global trigger by AND opend channels. Set trigger on channel 0 to be ACQ_ONLY
		sCAEN = CAEN_DGTZ_SetChannelSelfTrigger(hFADC[card], CAEN_DGTZ_TRGMODE_ACQ_AND_EXTOUT, 0x01);
		//Enable channel 0
		sCAEN = CAEN_DGTZ_SetChannelEnableMask(hFADC[card], 0x01); 
		//Set selfTrigger threshold 0x3a7=-4mV
		sCAEN = CAEN_DGTZ_SetChannelTriggerThreshold(hFADC[card], 0, 0x3a9);
		//Trigger under threshold
		sCAEN = CAEN_DGTZ_SetTriggerPolarity(hFADC[card], 0, CAEN_DGTZ_TriggerOnFallingEdge);
		//Post trigger
		sCAEN = CAEN_DGTZ_SetPostTriggerSize(hFADC[card], 20);
		//DC offset
		sCAEN = CAEN_DGTZ_SetChannelDCOffset(hFADC[card], 0, 0x3333);
		//Set the acquisition mode
		sCAEN = CAEN_DGTZ_SetAcquisitionMode(hFADC[card], CAEN_DGTZ_SW_CONTROLLED);
		//IO Level
		sCAEN = CAEN_DGTZ_SetIOLevel(hFADC[card], CAEN_DGTZ_IOLevel_NIM);
		//Analog Monitor
		//sCAEN = CAEN_DGTZ_SetAnalogMonOutput(hFADC[card], CAEN_DGTZ_AM_BUFFER_OCCUPANCY);
		//sCAEN = CAEN_DGTZ_ReadRegister(hFADC[card], V1751_FRONT_PANEL_IO_CONTROL, &temp);
		//printf("V1751_FRONT_PANEL_IO_CONTROL = %d\n", temp);
		sCAEN = CAEN_DGTZ_WriteRegister(hFADC[card], V1751_FRONT_PANEL_IO_CONTROL, 0x3C);
		sCAEN = CAEN_DGTZ_WriteRegister(hFADC[card], V1751_FRONT_PANEL_TRIGGER_OUT_ENABLE_MASK, 0xFF);
		sCAEN = CAEN_DGTZ_ReadRegister(hFADC[card], V1751_FRONT_PANEL_IO_CONTROL, &temp);
		printf("V1751_FRONT_PANEL_IO_CONTROL = %d\n", temp);
		//Interrupt configuration
		sCAEN = CAEN_DGTZ_SetInterruptConfig(hFADC[card], CAEN_DGTZ_ENABLE, VME_INTERRUPT_LEVEL, VME_INTERRUPT_STATUS_ID, IRQ_EVENT_NUMBER, CAEN_DGTZ_IRQ_MODE_RORA);
		//Set the max number of events to transfer in a sigle readout
		sCAEN = CAEN_DGTZ_SetMaxNumEventsBLT(hFADC[card], 3);
		//Set the behaviour when a Software tirgger arrives
		//sCAEN = CAEN_DGTZ_SetSWTriggerMode(hFADC[card], CAEN_DGTZ_TRGMODE_ACQ_ONLY);

		//---------------------------------------------------------//
		//----- Last step: Allociate memory for readout buffer-----//
		//---------------------------------------------------------//
		sCAEN = CAEN_DGTZ_MallocReadoutBuffer(hFADC[card], &buffer, &size);


		if(sCAEN != CAEN_DGTZ_Success) {
			printf("Errors during Digitizer Configuration.\n");
			sCAEN = CAEN_DGTZ_FreeReadoutBuffer(&buffer);
			sCAEN = CAEN_DGTZ_CloseDigitizer(hFADC[card]);
		}else{
			printf("Digitizer Configuration Successfully.\n");
		}
	}//end of FADC Configuration
	return SUCCESS;
}

/*-- Frontend Exit -------------------------------------------------*/

INT frontend_exit()
{
	//Stop DAQ
	for (card=0;card<NFADC;card++) {
		sCAEN = CAEN_DGTZ_SWStopAcquisition(hFADC[card]);
	}
	//Free memory
	sCAEN = CAEN_DGTZ_FreeReadoutBuffer(&buffer);
	//Close digitizer
	for (card=0;card<NFADC;card++) {
		sCAEN = CAEN_DGTZ_CloseDigitizer(hFADC[card]);
	}
	if(sCAEN == CAEN_DGTZ_Success){
		printf("FADC Modules stopped.\n");
	}else{
		printf("FADC Modules can not be stopped.\n");
	}
	return SUCCESS;
}

/*-- Begin of Run --------------------------------------------------*/
... 200 more lines ...
  1186   13 Jul 2016 Zhe WangSuggestionFrontend crush on high event rate
Somehow I don't understand why people's reply is only in my mail box.
So I pasted them here. I hope they don't mind and these information may be useful for others.

The following is some discussion.
==========================================================================================
> In read_trigger_event(), you creating a secondary bank with time in
> second. For your information, this time in second is already written in
> the event header. You can retrieve the time using macros from the
> midas.h   time = TIME_STAMP(pevent)

Removed.

>
> In frontend_init() you loop over NFADC (1) and call for each loop
> frontend_config() after opening the device on that card. In
> frontend_config() you redo a loop over NFADC, meaning that in case of
> more than one card you will find the second one not open on the first
> frontend_config (ok for one card though).
>

Corrected.

> In frontend_config() what is the return sCAEN from MallocReadoutBuffer()?
> What is the size of the requested allocated buffer?

The return size of allocated buffer is 134936.

>
> What is the value of the sCAEN from the ReadData() function in
> read_trigger_event()?

It is always 0 for success until it crashes.
However, even for the event it crashes, it also appears as 0.

>
> I didn't check all the config parameters!
>
> What is the value of count in the poll_event(). It is true if the test
> in poll_event() is too short, it cause timing corruption during
> calibration. 

Do you mean Midas timing calibration for poll_event() before all finally start up?
We havn't observed corruption at this stage.

> This never happen during CAMAC time... to be fixed!
> The alternative is to include a ss_sleep(1) instead of the prescale.
> a 1ms delay between every poll is short enough to ensure your 1KHz trigger.

We tried ss_sleep(1) in poll_event(), and it doesn't help.
We also tried add a ss_sleep(10) in the read_trigger_event().
This may work. But we can only reach 100 Hz and 1 MB/s rate. Still low.

>
> How long do you spend in the read_trigger_event()? To be measured.

We add some timers in this part of the program.
The time spent on CAEN_DGTZ_ReadData is about 100 us.
To sleep 1 ms in read_trigger_event may delay the crush, but just one minute.
To sleep 10 ms works.

>
> I still don't understand your setup as you mention using optic fiber to
> access the VME controller? do you have a A3818 or similar to the
> controller? If so why don't you connect directly the optic to the VX1751
> and prevent the use of the VME backplane?

Our connect is:
A2818 (PCI) - fiber - V2718 (Bridge) - VME - V1751
We probably need to configure other vme boards through VME at the same time,
however, these boards don't have a fiber connection.

We also tested direct fiber connect for V1751 today.
But it crashes with the same symptom.
==========================================================================================
Attachment 1: frontend.c
/*****************************************************************\

Name:         frontend.c
Created by: 	Zhe Wang 
Date:         03/16/2015 

Modified by: Mohan Li
Date: 07/04/2016

Contents:     Experiment specific readout code (user part) of Midas frontend.
Supported VME modules:
CAEN V2718 VME-CONET Bridge
CAEN V1751 10-Bits 1-GHz Flash ADC

Experiment: Dark noise

Currently: Use CAEN_Digitizer lib. Use Ramdom number to avoid disconnection. 

$Id: $

\********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "midas.h"
#include "mcstd.h"
#include "mvmestd.h"
#include "experim.h"
#include "v1751.h"
#include "CAENDigitizer.h"

/* make frontend functions callable from the C framework */
#ifdef __cplusplus
extern "C" {
#endif

	/*-- Globals -------------------------------------------------------*/

	/* The frontend name (client name) as seen by other MIDAS clients   */
	char *frontend_name = "Frontend";
	/* The frontend file name, don't change it */
	char *frontend_file_name = __FILE__;

	/* frontend_loop is called periodically if this variable is TRUE    */
	BOOL frontend_call_loop = FALSE;

	/* a frontend status page is displayed with this frequency in ms */
	INT display_period = 500;

	/* maximum event size produced by this frontend */
	//INT max_event_size = 10000;
	INT max_event_size = 100000; //modified according to feov1721.cxx

	/* maximum event size for fragmented events (EQ_FRAGMENTED) */
	INT max_event_size_frag = 5 * 1024 * 1024;

	/* buffer size to hold events */
	INT event_buffer_size = 200 * 100000;

#define NFADC 1
#define NMax 4
	int hFADC[NFADC];

	/* VMEBaseAddress */
	uint32_t FADCBA[NMax] = {0x000C0000,0,0,0};  // FADC base address 0x80000000

	uint32_t EvtCounterFadc[NMax];

	/* Time in second*/
	uint32_t TimeInSec;

	/* initiate variables */

	FILE* logfile;

	//CAENComm_ErrorCode sCAENc;

	int l=0, d=0, h=0, Nh;
	uint32_t i, lcount, temp, lam, reg, data[50000];
	int Nmodulo=10; //print transmission information every Nmodulo events
	int tcount=0, eloop=0;
	DWORD  eStored, eSize;
	DWORD eventReady;
	DWORD BLTNB;
	DWORD recordlength;
	uint32_t recordsize = 0x1000;
	int loop, Nloop=10;
	int bshowData=0; // 1 to enable data print
	int debug = 0;
	uint32_t pct=0, ct;
	struct timeval t1;
	int   dt1, savelcount=0;
	float trg_rate =0;
	int data_test = 0; // 1 for stored data check
	int simulation = 0;// 1 for simulation mode
	

	/*-------------CAEN Digitier vairables----------*/
	int card=0;
	CAEN_DGTZ_ErrorCode sCAEN;
	CAEN_DGTZ_BoardInfo_t BoardInfo;
	char *buffer = NULL; //pointer to the read out buffer
	int c = 0;
	uint32_t size; //buffer allocated for reading data
	uint32_t bsize;
#define INTERRUPT_TIMEOUT 20000 //20000ms = 20s
#define VME_INTERRUPT_LEVEL 1
#define VME_INTERRUPT_STATUS_ID 0xAAAA
#define IRQ_EVENT_NUMBER 1

	/*-- Function declarations -----------------------------------------*/

	INT frontend_init(); 
	INT frontend_exit();
	INT begin_of_run(INT run_number, char *error);
	INT end_of_run(INT run_number, char *error);
	INT pause_run(INT run_number, char *error);
	INT resume_run(INT run_number, char *error);
	INT frontend_loop();

	INT read_trigger_event(char *pevent, INT off);
	INT frontend_config();

	/*-- Equipment list ------------------------------------------------*/

#undef USE_INT
//#define 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(CRATE, LAM_STATION(SLOT_ADC)), /* event source */
				LAM_SOURCE(0, 0xFFFFFF),   /* event source crate 0, all stations, by Li*/
				"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 */
		},

		{""}
	};

#ifdef __cplusplus
}
#endif

/********************************************************************\
  Callback routines for system transitions

  These routines are called whenever a system transition like start/
  stop of a run occurs. The routines are called on the following
occations:

frontend_init:  When the frontend program is started. This routine
should initialize the hardware.

frontend_exit:  When the frontend program is shut down. Can be used
to releas any locked resources like memory, commu-
nications ports etc.

begin_of_run:   When a new run is started. Clear scalers, open
rungates, etc.

end_of_run:     Called on a request to stop a run. Can send
end-of-run event and close run gates.

pause_run:      When a run is paused. Should disable trigger events.

resume_run:     When a run is resumed. Should enable trigger events.

\********************************************************************/

/*-- Frontend Init -------------------------------------------------*/
INT frontend_init()
{
	// Open FADC digitizer
	for( card=0; card<NFADC; card++ )  {
                // through V2718
	        //sCAEN = CAEN_DGTZ_OpenDigitizer(CAEN_DGTZ_PCI_OpticalLink, 0, 0, FADCBA[card], &hFADC[card]);
	        // through fiber
	        sCAEN = CAEN_DGTZ_OpenDigitizer(CAEN_DGTZ_OpticalLink, 0, 0, 0, &hFADC[card]);
		if(sCAEN != CAEN_DGTZ_Success) {
			printf("Can't open digitizer\n");
			//sCAEN = CAEN_DGTZ_CloseDigitizer(hFADC[card]);
		}
	}

	frontend_config();
	
	return SUCCESS;
}

INT frontend_config()
{
	/* ------FADC configuration------ */
	for( card=0; card<NFADC; card++ )  {  

		//Print Board Info
		sCAEN = CAEN_DGTZ_GetInfo(hFADC[card], &BoardInfo);
		printf("\nConnected to CAEN Digitizer Model %s, recognized as board %d\n", BoardInfo.ModelName, card);
		printf("\tROC FPGA Release is %s\n", BoardInfo.ROC_FirmwareRel);
		printf("\tAMC FPGA Release is %s\n", BoardInfo.AMC_FirmwareRel);
		//Reset Digitizer
		sCAEN = CAEN_DGTZ_Reset(hFADC[card]);
		//Calibrate temperatire
		sCAEN = CAEN_DGTZ_Calibrate(hFADC[card]);
		//Set the lenght of each waveform (in samples)
		sCAEN = CAEN_DGTZ_SetRecordLength(hFADC[card], 1792);
		//Generate a global trigger by AND opend channels. Set trigger on channel 0 to be ACQ_ONLY
		sCAEN = CAEN_DGTZ_SetChannelSelfTrigger(hFADC[card], CAEN_DGTZ_TRGMODE_ACQ_AND_EXTOUT, 0x01);
		//Enable channel 0
		sCAEN = CAEN_DGTZ_SetChannelEnableMask(hFADC[card], 0x01); 
		//Set selfTrigger threshold 0x3a7=-4mV
		sCAEN = CAEN_DGTZ_SetChannelTriggerThreshold(hFADC[card], 0, 0x3a9);
		//Trigger under threshold
		sCAEN = CAEN_DGTZ_SetTriggerPolarity(hFADC[card], 0, CAEN_DGTZ_TriggerOnFallingEdge);
		//Post trigger
		sCAEN = CAEN_DGTZ_SetPostTriggerSize(hFADC[card], 20);
		//DC offset
		sCAEN = CAEN_DGTZ_SetChannelDCOffset(hFADC[card], 0, 0x3333);
		//Set the acquisition mode
		sCAEN = CAEN_DGTZ_SetAcquisitionMode(hFADC[card], CAEN_DGTZ_SW_CONTROLLED);
		//IO Level
		sCAEN = CAEN_DGTZ_SetIOLevel(hFADC[card], CAEN_DGTZ_IOLevel_NIM);
		//Set the max number of events to transfer in a sigle readout
		sCAEN = CAEN_DGTZ_SetMaxNumEventsBLT(hFADC[card], 1);
		//Set the behaviour when a Software tirgger arrives
		//sCAEN = CAEN_DGTZ_SetSWTriggerMode(hFADC[card], CAEN_DGTZ_TRGMODE_ACQ_ONLY);

		//---------------------------------------------------------//
		//----- Last step: Allociate memory for readout buffer-----//
		//---------------------------------------------------------//
		sCAEN = CAEN_DGTZ_MallocReadoutBuffer(hFADC[card], &buffer, &size);
		printf("MallocReadoutBuffer returned with status %d and size %d.\n", sCAEN, size);

		if(sCAEN != CAEN_DGTZ_Success) {
			printf("Errors during Digitizer Configuration.\n");
			sCAEN = CAEN_DGTZ_FreeReadoutBuffer(&buffer);
			sCAEN = CAEN_DGTZ_CloseDigitizer(hFADC[card]);
		}else{
			printf("Digitizer Configuration Successfully.\n");
		}
	}//end of FADC Configuration
	return SUCCESS;
}

/*-- Frontend Exit -------------------------------------------------*/

INT frontend_exit()
{
	//Stop DAQ
	for (card=0;card<NFADC;card++) {
		sCAEN = CAEN_DGTZ_SWStopAcquisition(hFADC[card]);
	}
	//Free memory
	sCAEN = CAEN_DGTZ_FreeReadoutBuffer(&buffer);
	//Close digitizer
	for (card=0;card<NFADC;card++) {
		sCAEN = CAEN_DGTZ_CloseDigitizer(hFADC[card]);
	}
	if(sCAEN == CAEN_DGTZ_Success){
		printf("FADC Modules stopped.\n");
	}else{
		printf("FADC Modules can not be stopped.\n");
	}
	return SUCCESS;
}

/*-- Begin of Run --------------------------------------------------*/

INT begin_of_run(INT run_number, char *error)
{
	//Create log file
	logfile = fopen("log.txt","w");
	//Start FADC
	for (card=0;card<NFADC;card++) {
		sCAEN = CAEN_DGTZ_ClearData(hFADC[card]);
		sCAEN = CAEN_DGTZ_SWStartAcquisition(hFADC[card]);
	}  
	printf("begin of run.\n");
	return SUCCESS;
}

/*-- End of Run ----------------------------------------------------*/
... 194 more lines ...
  1187   13 Jul 2016 Zhe WangSuggestionFrontend crush on high event rate
Suggestion from John and my reply.

> We have achieved very high rates, but only with some care.

> The biggest issue was to make sure when you compile the CAEN driver for the A3818 board that you turn on the MIDAS switch.  Without that problems occur with some 
> probability given by the number of bytes processed - which translates into very soon if you have a high rate.  (The underlying cause is that both MIDAS and the A3818
> use unix Alarm signals, but the CAEN folks have a compile option to turn this off.)

> We use as little as possible of the CAENDigitizerLibrary - instead we program the registers directly on the board.

> There is still some kind of memory leak which we have not yet tracked down, so every few hours we shut down the frontend then restart it. 

We use A2818 (PCI) - fiber - V2718 (Bridge) - VME - V1751.
I actually didn't find a MIDAS switch in the Makefile.
  1188   13 Jul 2016 Zhe WangSuggestionFrontend crush on high event rate

More suggestions from John and my reply.

> we also don't use the VME back plane - it's just too slow - mixing VME commands to plain modules and digitizer modules is unreliable....

> We use CAEN fiberoptic version 2 to talk to the digitizers directly, we have upto 12 digitizers, and can use all channels for several hours, and can fill to about 75% 
of the A3818 bandwidth... 

So far we are limitted to 30 MB/s, if tested with CAEN examples, for example, the wavedump program by CAEN.
I think is kind of the limit by IDE hard drive.
Unfortunately we are still far from that limit, only ~ 1 MB/s now.  :(
  1043   03 Mar 2015 Zaher SalmanForumStarting program from custom page
I am trying to start a program (fronend) from a custom page. What is the best
way to do that? Would ODBRpc() do this? if so can anyone give me an example of
how to do this. Thanks.
  1045   03 Mar 2015 Zaher SalmanForumStarting program from custom page
> > I am trying to start a program (fronend) from a custom page. What is the best
> > way to do that? Would ODBRpc() do this? if so can anyone give me an example of
> > how to do this. Thanks.
> 
> You have a look at the documentation:
> 
> http://ladd00.triumf.ca/~daqweb/doc/midas-old/html/RC_mhttpd_defining_script_buttons.html
> 
> Cheers,
> Stefan

Hi Stefan, thanks for the quick reply. I guess my question was not clear enough.

My aim is to create a button which mimics the "Start/Stop" button functionality in the
"Programs" page where we start all the front-ends for the various equipment. The idea is that
the user will use a simple interface in a custom page (not the status page) which sets up the
equipment needed for a specific type of measurement.

thanks
Zaher
  1047   03 Mar 2015 Zaher SalmanForumStarting program from custom page
Thank you very much, this is exactly what I need and it works.

Zaher

> All functions in midas are controlled through special URLs. So the URL
> 
> http://<host:port>/?cmd=Start&value=10
> 
> will start run #10. Similarly with ?cmd=Stop. Now all you need is to set up a custom button, and use the 
> OnClick="" JavaScript method to fire off an Ajax request with the above URL. 
> 
> To send an Ajax request, you can use the function XMLHttpRequestGeneric which ships as part of midas in the 
> mhttpd.js file. Then the code would be
> 
> <input type="button" onclick="start()">
> 
> and in your JavaScript code:
> 
> ...
> function start()
> {
>    var request = XMLHttpRequestGeneric();
> 
>    url = '?cmd=Start&value=10';
>    request.open('GET', url, false);
>    request.send(null);
> }
> ...
> 
> 
> Cheers,
> Stefan
ELOG V3.1.4-2e1708b5