Back Midas Rome Roody Rootana
  Midas DAQ System, Page 84 of 142  Not logged in ELOG logo
ID Date Author Topic Subjectdown
  2315   26 Jan 2022 Konstantin OlchanskiBug ReportOff-by-one in sequencer documentation
> > 3 LOOP n,4
> > 4   MESSAGE $n,1
> > 5 ENDLOOP
> 
> Indeed you're right. The loop variable runs from 1...n. I fixed that in the documentation.

Shades/ghosts of FORTRAN. c/c++/perl/python loops loop from 0 to n-1.

K.O.
  2319   26 Jan 2022 Stefan RittBug ReportOff-by-one in sequencer documentation
> Shades/ghosts of FORTRAN. c/c++/perl/python loops loop from 0 to n-1.

   for (i=1 ; i<=10 ; i++);     ;-)
  2321   26 Jan 2022 Konstantin OlchanskiBug ReportOff-by-one in sequencer documentation
> > Shades/ghosts of FORTRAN. c/c++/perl/python loops loop from 0 to n-1.
> 
>    for (i=1 ; i<=10 ; i++);     ;-)

Similar code made big news just recently: (scroll down to the example main() program)

https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-
vulnerability-discovered-in-polkits-pkexec-cve-2021-4034

I forget if the FORTRAN rules were "loop once" or "never loop" or if it was different
between Fortran-4, fortran-77, DEC extensions and IBM extension, or if it was a compiler switch.

We should check that we do something reasonable with such loops to zero:

LOOP n,0
   MESSAGE $n,1
ENDLOOP

P.S. Yup. "man g77" option "-fonetrip".

K.O.
  2447   11 Nov 2022 Frederik WautersBug FixO_CREAT in open in split.cxx
midas currently does not compile on linux

/usr/include/x86_64-linux-gnu/bits/fcntl2.h:50:24: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments
   50 |    __open_missing_mode ();

giving the mode is mandatory: https://man7.org/linux/man-pages/man2/open.2.html

fix is to give open in midas/examples/lowlevel/split.cxx a default mode, e.g. 006600
  2448   12 Nov 2022 Stefan RittBug FixO_CREAT in open in split.cxx
> midas currently does not compile on linux
> 
> /usr/include/x86_64-linux-gnu/bits/fcntl2.h:50:24: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments
>    50 |    __open_missing_mode ();
> 
> giving the mode is mandatory: https://man7.org/linux/man-pages/man2/open.2.html
> 
> fix is to give open in midas/examples/lowlevel/split.cxx a default mode, e.g. 006600

Thanks. Fixed.

Stefan
  2449   17 Nov 2022 Konstantin OlchanskiBug FixO_CREAT in open in split.cxx
> > midas currently does not compile on linux
> > fix is to give open in midas/examples/lowlevel/split.cxx a default mode, e.g. 006600

I got more warnings from split.cxx, looked at the code and see so many problems that it is easier
to delete it than it is to fix it.

Check for end of file is done incorrectly (check for read() return 0, -1 or short read),
memory overrun if given file name is longer than 80 bytes, no check for valid event length
read from the file, and so on and so on.

A better example for reading and writing midas files is in midasio/test_midasio.cxx. Proper c++ coding, and can read compressed files.

K.O.
  2282   30 Sep 2021 Francesco RengaForumOPC client within MIDAS
Dear all,
     I need to integrate in my MIDAS project the communication with an OPC UA 
server. My plan is to develop an OPC UA client as a "device" in 
midas/drivers/device.

Two questions:

1) Is anybody aware of some similar effort for some other project, so that I can 
get some example?

2) What could be the more appropriate driver's class to be used? generic.cxx? 
multi.cxx?

Thank you for your help,
           Francesco
  2334   10 Feb 2022 Francesco RengaForumOPC client within MIDAS
Dear all,
        I finally succeeded to get a working driver for the communication with an OPC 
UA server. It is based on the open62541 library and I use it in combination with the 
generic.h driver class. This is still a crude implementation, but let me post it here, 
maybe it can be useful to somebody else.

BTW, if there is somebody more skilled than me with OPC UA and MIDAS drivers, who is 
willing to give suggestions for improving the implementation, it would be extremely 
appreciated.

Best Regards,
      Francesco



> Dear all,
>      I need to integrate in my MIDAS project the communication with an OPC UA 
> server. My plan is to develop an OPC UA client as a "device" in 
> midas/drivers/device.
> 
> Two questions:
> 
> 1) Is anybody aware of some similar effort for some other project, so that I can 
> get some example?
> 
> 2) What could be the more appropriate driver's class to be used? generic.cxx? 
> multi.cxx?
> 
> Thank you for your help,
>            Francesco
Attachment 1: opc.cxx
/********************************************************************\

  Name:         opc.cxx
  Created by:   Francesco Renga

  Contents:     Device Driver for generic OPC server

  $Id: mscbdev.c 3428 2006-12-06 08:49:38Z ritt $

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

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "midas.h"
#include "msystem.h"
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/client_subscriptions.h>
#include <open62541/plugin/log_stdout.h>


#ifndef _MSC_VER
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#endif

#include <vector>

using namespace std;

/*---- globals -----------------------------------------------------*/

typedef struct {
  char Name[32];                // System Name (duplication)
  char ip[32];                  // IP# for network access
  int nsIndex;
  char TagsGuid[64];
} OPC_SETTINGS;

#define OPC_SETTINGS_STR "\
System Name = STRING : [32] gassys\n\
IP = STRING : [32] 172.17.19.70:4870\n\
Namespace Index = INT : 3\n\
Tags Guid = STRING : [64] ecef81d5-c834-4379-ab79-c8fa3133a311\n\
"

typedef struct {
  OPC_SETTINGS opc_settings;
  UA_Client* client;
  int num_channels;
  vector<string> channel_name;
  vector<int> channel_type;
} OPC_INFO;

/*---- device driver routines --------------------------------------*/

INT opc_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd) (INT cmd, ...))
{
  
   int status, size;
   OPC_INFO *info;
   HNDLE hDB;
   
   /* allocate info structure */
   info = (OPC_INFO *)calloc(1, sizeof(OPC_INFO));
   *pinfo = info;
   
   cm_get_experiment_database(&hDB, NULL);

   /* create PSI_BEAMBLOCKER settings record */
   status = db_create_record(hDB, hKey, "", OPC_SETTINGS_STR);
   if (status != DB_SUCCESS)
      return FE_ERR_ODB;

   size = sizeof(info->opc_settings);
   db_get_record(hDB, hKey, &info->opc_settings, &size, 0);

   info->client = UA_Client_new();
   UA_ClientConfig_setDefault(UA_Client_getConfig(info->client));

   char address[32];
   sprintf(address,"opc.tcp://%s",info->opc_settings.ip);
   printf("Connecting to %s...\n",address);
   UA_StatusCode retval = UA_Client_connect(info->client, address);
   if(retval != UA_STATUSCODE_GOOD) {
     UA_Client_delete(info->client);
     return FE_ERR_HW;
   }

   ////Scan of variables
   UA_BrowseRequest bReq;
   UA_BrowseRequest_init(&bReq);
   bReq.requestedMaxReferencesPerNode = 0;
   bReq.nodesToBrowse = UA_BrowseDescription_new();
   bReq.nodesToBrowseSize = 1;
   UA_Guid guid1;
   UA_Guid_parse(&guid1, UA_STRING(info->opc_settings.TagsGuid));
   bReq.nodesToBrowse[0].nodeId = UA_NODEID_GUID(info->opc_settings.nsIndex, guid1);
   bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */
   
   UA_BrowseResponse bResp = UA_Client_Service_browse(info->client, bReq);
   
   for(size_t i = 0; i < bResp.resultsSize; ++i) {

     for(size_t j = 0; j < bResp.results[i].referencesSize; ++j) {

       UA_ReferenceDescription *ref = &(bResp.results[i].references[j]);
       if ((ref->nodeClass == UA_NODECLASS_OBJECT || ref->nodeClass == UA_NODECLASS_VARIABLE||ref->nodeClass == UA_NODECLASS_METHOD)) {

	 if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) {
	   UA_NodeId dataType;
	   UA_Client_readDataTypeAttribute(info->client, UA_NODEID_STRING(info->opc_settings.nsIndex, ref->nodeId.nodeId.identifier.string.data), &dataType);
	   (info->channel_type).push_back(dataType.identifier.numeric-1);
	   (info->channel_name).push_back((char*)(ref->nodeId.nodeId.identifier.string.data));
	 }

       }

     }
     
   }
   
   UA_BrowseNextRequest bNextReq;
   UA_BrowseNextResponse bNextResp;				    
   UA_BrowseNextRequest_init(&bNextReq);
   
   bNextReq.releaseContinuationPoints = UA_FALSE;
   bNextReq.continuationPoints = &bResp.results[0].continuationPoint;
   bNextReq.continuationPointsSize = 1;
   
   bool hasRef;
   
   do {
     
     hasRef = false;
     
     bNextResp = UA_Client_Service_browseNext(info->client, bNextReq);
     
     for (size_t i = 0; i < bNextResp.resultsSize; i++) {
       for (size_t j = 0; j < bNextResp.results[i].referencesSize; j++) {
	     
	 hasRef = true;
	 
	 UA_ReferenceDescription *ref = &(bNextResp.results[i].references[j]);
	 if ((ref->nodeClass == UA_NODECLASS_OBJECT || ref->nodeClass == UA_NODECLASS_VARIABLE||ref->nodeClass == UA_NODECLASS_METHOD)) {
	   
	   if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) {
	     UA_NodeId dataType;
	     UA_Client_readDataTypeAttribute(info->client, UA_NODEID_STRING(info->opc_settings.nsIndex, ref->nodeId.nodeId.identifier.string.data), &dataType);
	     (info->channel_type).push_back(dataType.identifier.numeric-1);
	     (info->channel_name).push_back((char*)(ref->nodeId.nodeId.identifier.string.data));
	   }
	   
	 }
	 
       }

     }
       
     bNextReq.continuationPoints = &bNextResp.results[0].continuationPoint;
     bNextReq.continuationPointsSize = 1;
     
   } while(hasRef);

   info->num_channels = info->channel_name.size();
   
   UA_BrowseRequest_deleteMembers(&bReq);
   UA_BrowseResponse_deleteMembers(&bResp);
   
   UA_BrowseRequest_clear(&bReq);
   UA_BrowseResponse_clear(&bResp);

   return FE_SUCCESS;

}

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

INT opc_exit(OPC_INFO * info)
{

   UA_Client_disconnect(info->client);
   UA_Client_delete(info->client);

   if (info)
      free(info);

   return FE_SUCCESS;
   
}

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

INT opc_get(OPC_INFO * info, INT channel, float *pvalue)
{

  ////Read value
  UA_Variant *val = UA_Variant_new();
  UA_StatusCode retval = UA_Client_readValueAttribute(info->client, UA_NODEID_STRING(info->opc_settings.nsIndex, info->channel_name[channel].c_str()), val);
  if (retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(val) &&
      val->type == &UA_TYPES[info->channel_type[channel]]
      ) {

    if(info->channel_type[channel] == UA_TYPES_FLOAT){
      *pvalue = *(UA_Float*)val->data;
    }

    else if(info->channel_type[channel] == UA_TYPES_DOUBLE){
      *pvalue = *(UA_Double*)val->data;
    }

    else if(info->channel_type[channel] == UA_TYPES_INT16){
      *pvalue = *(UA_Int16*)val->data;
    }
    
    else if(info->channel_type[channel] == UA_TYPES_INT32){
      *pvalue = *(UA_Int32*)val->data;
    }
    
    else if(info->channel_type[channel] == UA_TYPES_INT64){
      *pvalue = *(UA_Int64*)val->data;
    }
    
    else if(info->channel_type[channel] == UA_TYPES_BOOLEAN){
      *pvalue = (*(UA_Boolean*)val->data) ? 1.0 : 0.0;
    }

    else if(info->channel_type[channel] == UA_TYPES_BYTE){
      *pvalue = *(UA_Byte*)val->data;
    }

    else {
      *pvalue = 0.;
    }

  }

  UA_Variant_delete(val);
  
  return FE_SUCCESS;

}


INT opc_set(OPC_INFO * info, INT channel, float value)
{

  ////Write value
  UA_Variant *myVariant = UA_Variant_new();

  if(info->channel_type[channel] == UA_TYPES_FLOAT){
    UA_Float typevalue = value;
    UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
  }

  else if(info->channel_type[channel] == UA_TYPES_DOUBLE){
    UA_Double typevalue = value;
    UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
  }

  else if(info->channel_type[channel] == UA_TYPES_INT16){
    UA_Int16 typevalue = value;
    UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
  }

  else if(info->channel_type[channel] == UA_TYPES_INT32){
    UA_Int32 typevalue = value;
    UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
  }

  else if(info->channel_type[channel] == UA_TYPES_INT64){
    UA_Int64 typevalue = value;
    UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
  }

  else if(info->channel_type[channel] == UA_TYPES_BOOLEAN){
    UA_Boolean typevalue = (value != 0) ? true : false;
    UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
  }

  else if(info->channel_type[channel] == UA_TYPES_BYTE){
    UA_Byte typevalue = value;
    UA_Variant_setScalarCopy(myVariant, &typevalue, &UA_TYPES[info->channel_type[channel]]);
  }
  
  else return FE_SUCCESS;
  
  UA_Client_writeValueAttribute(info->client, UA_NODEID_STRING(info->opc_settings.nsIndex, info->channel_name[channel].c_str()), myVariant);
  UA_Variant_delete(myVariant);
  
  return FE_SUCCESS;

}

/*---- device driver entry point -----------------------------------*/

... 62 more lines ...
Attachment 2: opc.h
/********************************************************************\

  Name:         dd_sy4527.h
  Created by:   based on null.h / Stefan Ritt

  Contents:     Device driver function declarations for SY4527 device

  $Id$

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

INT opc(INT cmd, ...);
  403   29 Aug 2007 Konstantin OlchanskiForumODBv3, second try - Midas on a x86_64 - incompatible with x86_32
> > > I agree to make 32-bit and 64-bit compatible. In the long run, everything will be 64-bit, so I would suggest
> > > in breaking the 32-bit ODB, add some padding there where needed, probably with some conditional compiling.
> > 1) midas.h: remove unused field "dispatch" from EVENT_REQUEST and bump DATABASE_VERSION from 2 to 3
> > 2) msystem.h: add 32-bit padding to CHN_STATISTICS and CHN_SETTINGS

I am now trying a different solution of to fixing the issue of CHN_STATISTICS and CHN_SETTINGS changing size.

1) midas.h: (same as before) remove unused field "dispatch" from EVENT_REQUEST and bump DATABASE_VERSION from 2 to 3
2) msystem.h: in CHN_STATISTICS and CHN_SETTINGS change type of "event_limit" and "files_written" from int to "double".

Below are the latest ODBv3 meta patches:

ladd03:midas$ svn diff
Index: include/midas.h
===================================================================
--- include/midas.h     (revision 3844)
+++ include/midas.h     (working copy)
 /* has to be changed whenever binary ODB format changes */
-#define DATABASE_VERSION 2
+#define DATABASE_VERSION 3
.........
    short int trigger_mask;       /**< trigger mask                    */
    INT sampling_type;            /**< GET_ALL, GET_SOME, GET_FARM     */
-                                 /**< dispatch function */
-   void (*dispatch) (HNDLE, HNDLE, EVENT_HEADER *, void *);
 } EVENT_REQUEST;

Index: include/msystem.h
===================================================================
--- include/msystem.h   (revision 3845)
+++ include/msystem.h   (working copy)
-"Event limit = DWORD : 0",\
+"Event limit = DOUBLE : 0",\
..................
-"Files written = INT : 0",\
+"Files written = DOUBLE : 0",\
..................
-   DWORD event_limit;
+   double event_limit;
..................
-   INT files_written;
+   double files_written;

K.O.
  417   21 Nov 2007 Konstantin OlchanskiForumODBv3, second try - Midas on a x86_64 - incompatible with x86_32
These changes to make 32-bit and 64-bit ODB binary compatible with each other are now commited to midas svn, revision 4080.

Starting with this revision, ODB version changes from 2 to 3, breaking binary compatibility with previous releases.

Before upgrading to this revision, save your ODB as an XML file, *and* try to reload it, to catch any potential problems with parsing of the XML file.

Part of this commit are checks for sizes of important midas data structures stored in ODB shared memory - if the compiled size does not match the expected 
value, binary compatibility is broken and the program will abort - to avoid further corruption of ODB shared memory. This feature is only enabled on Linux and 
it is expected to trigger only on compiler malfunctions (generates wrong data size) and on accidental or intentional changes to important data structures in 
midas, to warn the user that they broke ODB binary compatibility.

K.O.

> > > > I agree to make 32-bit and 64-bit compatible. In the long run, everything will be 64-bit, so I would suggest
> > > > in breaking the 32-bit ODB, add some padding there where needed, probably with some conditional compiling.
> > > 1) midas.h: remove unused field "dispatch" from EVENT_REQUEST and bump DATABASE_VERSION from 2 to 3
> > > 2) msystem.h: add 32-bit padding to CHN_STATISTICS and CHN_SETTINGS
> 
> I am now trying a different solution of to fixing the issue of CHN_STATISTICS and CHN_SETTINGS changing size.
> 
> 1) midas.h: (same as before) remove unused field "dispatch" from EVENT_REQUEST and bump DATABASE_VERSION from 2 to 3
> 2) msystem.h: in CHN_STATISTICS and CHN_SETTINGS change type of "event_limit" and "files_written" from int to "double".
> 
> Below are the latest ODBv3 meta patches:
> 
> ladd03:midas$ svn diff
> Index: include/midas.h
> ===================================================================
> --- include/midas.h     (revision 3844)
> +++ include/midas.h     (working copy)
>  /* has to be changed whenever binary ODB format changes */
> -#define DATABASE_VERSION 2
> +#define DATABASE_VERSION 3
> .........
>     short int trigger_mask;       /**< trigger mask                    */
>     INT sampling_type;            /**< GET_ALL, GET_SOME, GET_FARM     */
> -                                 /**< dispatch function */
> -   void (*dispatch) (HNDLE, HNDLE, EVENT_HEADER *, void *);
>  } EVENT_REQUEST;
> 
> Index: include/msystem.h
> ===================================================================
> --- include/msystem.h   (revision 3845)
> +++ include/msystem.h   (working copy)
> -"Event limit = DWORD : 0",\
> +"Event limit = DOUBLE : 0",\
> ..................
> -"Files written = INT : 0",\
> +"Files written = DOUBLE : 0",\
> ..................
> -   DWORD event_limit;
> +   double event_limit;
> ..................
> -   INT files_written;
> +   double files_written;
> 
> K.O.
  2021   24 Nov 2020 Amy RobertsSuggestionODBSET wildcards with array keys in Sequencer files
I'm interested in using the matching feature for ODBSET explained on 
https://midas.triumf.ca/MidasWiki/index.php/Sequencer for settings that are in an 
array, like:

COMMENT "Ground the detectors"
ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[?]" 0

Currently I get an error when I try to run this script.  Is this expected?  Would it 
be possible to implement matching for array values?

Thanks!
  2022   25 Nov 2020 Marco FrancesconiSuggestionODBSET wildcards with array keys in Sequencer files
Hi,
I guess the issue is in the "[?]" part of the command, the indexing is handled differently from the odb path and does not 
support "?".
Are you trying to set only the first 9 channels?
Could you try with "[*]" or "[0-9]" instead?

Marco

> I'm interested in using the matching feature for ODBSET explained on 
> https://midas.triumf.ca/MidasWiki/index.php/Sequencer for settings that are in an 
> array, like:
> 
> COMMENT "Ground the detectors"
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[?]" 0
> 
> Currently I get an error when I try to run this script.  Is this expected?  Would it 
> be possible to implement matching for array values?
> 
> Thanks!
  2023   25 Nov 2020 Amy RobertsSuggestionODBSET wildcards with array keys in Sequencer files
The following all fail with "Cannot find ODB key "<key>""

ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[*]" 0
ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[0-9]" 0
ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[1]" 0
ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)*" 0
ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)" 0


> Hi,
> I guess the issue is in the "[?]" part of the command, the indexing is handled differently from the odb path and does not 
> support "?".
> Are you trying to set only the first 9 channels?
> Could you try with "[*]" or "[0-9]" instead?
> 
> Marco
> 
> > I'm interested in using the matching feature for ODBSET explained on 
> > https://midas.triumf.ca/MidasWiki/index.php/Sequencer for settings that are in an 
> > array, like:
> > 
> > COMMENT "Ground the detectors"
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[?]" 0
> > 
> > Currently I get an error when I try to run this script.  Is this expected?  Would it 
> > be possible to implement matching for array values?
> > 
> > Thanks!
  2024   25 Nov 2020 Marco FrancesconiSuggestionODBSET wildcards with array keys in Sequencer files
I created some keys in my ODB to try to match yours.
The ODBSET commands you wrote are all working fine (of course with different results), except only for the "/Detectors/Det*/Settings/Charge/Bias (V)*" which I will have to 
look into.
In any case the error message I'm getting is "could not match ay key" and not the one you are reporting.

Now I'm a bit puzzled:
Are you sure your ODB contains those keys?
Are you testing the ODBSET inside a more complex sequencer or on its own?

Maybe I can try to reproduce it using your ODB setup.
Could you send an ODB dump of the "/Detectors" folder using the "save" command of odbedit ("cd /Detectors" and then "save detector.odb")?

Best,

Marco


> The following all fail with "Cannot find ODB key "<key>""
> 
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[*]" 0
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[0-9]" 0
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[1]" 0
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)*" 0
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)" 0
> 
> 
> > Hi,
> > I guess the issue is in the "[?]" part of the command, the indexing is handled differently from the odb path and does not 
> > support "?".
> > Are you trying to set only the first 9 channels?
> > Could you try with "[*]" or "[0-9]" instead?
> > 
> > Marco
> > 
> > > I'm interested in using the matching feature for ODBSET explained on 
> > > https://midas.triumf.ca/MidasWiki/index.php/Sequencer for settings that are in an 
> > > array, like:
> > > 
> > > COMMENT "Ground the detectors"
> > > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[?]" 0
> > > 
> > > Currently I get an error when I try to run this script.  Is this expected?  Would it 
> > > be possible to implement matching for array values?
> > > 
> > > Thanks!
  2025   25 Nov 2020 Amy RobertsSuggestionODBSET wildcards with array keys in Sequencer files
I think the issue may be the version of MIDAS I'm using.  Mine is current as of February 4, 2020.  

But since then there have been changes to the sequencer code, specifically parts that handle indexing.

I'll try this out with an updated version of MIDAS and report back if there are still any issues after updating.

> I created some keys in my ODB to try to match yours.
> The ODBSET commands you wrote are all working fine (of course with different results), except only for the "/Detectors/Det*/Settings/Charge/Bias (V)*" which I will have to 
> look into.
> In any case the error message I'm getting is "could not match ay key" and not the one you are reporting.
> 
> Now I'm a bit puzzled:
> Are you sure your ODB contains those keys?
> Are you testing the ODBSET inside a more complex sequencer or on its own?
> 
> Maybe I can try to reproduce it using your ODB setup.
> Could you send an ODB dump of the "/Detectors" folder using the "save" command of odbedit ("cd /Detectors" and then "save detector.odb")?
> 
> Best,
> 
> Marco
> 
> 
> > The following all fail with "Cannot find ODB key "<key>""
> > 
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[*]" 0
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[0-9]" 0
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[1]" 0
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)*" 0
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)" 0
> > 
> > 
> > > Hi,
> > > I guess the issue is in the "[?]" part of the command, the indexing is handled differently from the odb path and does not 
> > > support "?".
> > > Are you trying to set only the first 9 channels?
> > > Could you try with "[*]" or "[0-9]" instead?
> > > 
> > > Marco
> > > 
> > > > I'm interested in using the matching feature for ODBSET explained on 
> > > > https://midas.triumf.ca/MidasWiki/index.php/Sequencer for settings that are in an 
> > > > array, like:
> > > > 
> > > > COMMENT "Ground the detectors"
> > > > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[?]" 0
> > > > 
> > > > Currently I get an error when I try to run this script.  Is this expected?  Would it 
> > > > be possible to implement matching for array values?
> > > > 
> > > > Thanks!
  2026   27 Nov 2020 Konstantin OlchanskiSuggestionODBSET wildcards with array keys in Sequencer files
> The following all fail with "Cannot find ODB key "<key>""
> 
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[*]" 0
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[0-9]" 0
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[1]" 0
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)*" 0
> ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)" 0
> 

It would be cool if ODB pattern matching in the sequencer
were consistent with the ODB pattern matching in the json-rpc
interface for web pages:

https://midas.triumf.ca/MidasWiki/index.php/Mjsonrpc#Supported_array_index_syntax

K.O.
  2038   30 Nov 2020 Marco FrancesconiSuggestionODBSET wildcards with array keys in Sequencer files
I totally agree that we should have a consistent formatting for array index expansion.
I had a look to the mjsonrpc code and I found the function parse_array_index_list(...) which does this job.
I have a similar function (adapted form previous code) in odb.cxx called strarrayindex(...) that is designed for the same "consistency" purposes between odbedit and sequencer.

Let me put few points that I noticed:
- mjsonrpc has a very different way to write the full array (no indexes given) while currently sequencer requires "[*]" to do the same (otherwise it only changes the first value of the array)
- currently the sequencer and the underlying ODB calls use two indexes (that are the same if you want to write only one key) so we will need a serious rewriting to allow something like "ODBSET array[1,3,5]"
- if I correctly understood the code, mjsonrpc instead generates a list of indices and then calls an ODB write on each of them. That's not always a good thing, for example if you are writing an array of n parameters on a DAQ 
board you will call the hotlink on that key n times
- in addition to that the sequencer will also have to cope with variable-based indexes like "ODBSET array[$val]", but then how it should parse something like "[$a,1]" or "[$a*]"?

For the very first point I do not see a clean way to do this without breaking the compatibility of existing sequencers or having a difference between the two implementations.
For the others I guess we can find a way out, however that's a major modification so I will put it on my todo list when I can find some free time.
In any case I would propose to merge the two functions, so we have only to maintain a single implementation of the parsing.

I guess it's a good moment to brainstorm about that, let me know what you think

Marco


> > The following all fail with "Cannot find ODB key "<key>""
> > 
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[*]" 0
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[0-9]" 0
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[1]" 0
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)*" 0
> > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)" 0
> > 
> 
> It would be cool if ODB pattern matching in the sequencer
> were consistent with the ODB pattern matching in the json-rpc
> interface for web pages:
> 
> https://midas.triumf.ca/MidasWiki/index.php/Mjsonrpc#Supported_array_index_syntax
> 
> K.O.
  2040   30 Nov 2020 Stefan RittSuggestionODBSET wildcards with array keys in Sequencer files
Hi Konstantin,

we are considering to make the range selection uniform among json, sequencer and 
odbedit "set" command. Having multiple ranges like [1,4-5] will be quite some work, so 
my question is did you just implement it on the json side because it was easy, or are 
there experiments who really need it? Wouldn't it be enough to have

[*]
[n]
[n-m]

This way we always have only one db_set_data() value behind that. Any set of indices 
we have to split into several db_set_data(), which especially for the front-end 
configuration can cause trouble by triggering a hot link on each access.

Stefan
  2043   30 Nov 2020 Konstantin OlchanskiSuggestionODBSET wildcards with array keys in Sequencer files
> I totally agree that we should have a consistent formatting for array index expansion.
> I had a look to the mjsonrpc code and I found the function parse_array_index_list(...) which does this job.

Yes, it is good to review this stuff. I think the json-rpc call should accept more array index patterns:

a[*] - whole array (even though it is unnatural use in javascript, we do not say "let a[*] = b[*]", we say "let a = b".
a[5-] - from 5th element to the end (in the case we do not know the length)
a[-10] - from first element to element 10 (this is same as a[0-10], but needed for consistency with previous case).

K.O.

> I have a similar function (adapted form previous code) in odb.cxx called strarrayindex(...) that is designed for the same "consistency" purposes between odbedit and sequencer.
> 
> Let me put few points that I noticed:
> - mjsonrpc has a very different way to write the full array (no indexes given) while currently sequencer requires "[*]" to do the same (otherwise it only changes the first value of the array)
> - currently the sequencer and the underlying ODB calls use two indexes (that are the same if you want to write only one key) so we will need a serious rewriting to allow something like "ODBSET array[1,3,5]"
> - if I correctly understood the code, mjsonrpc instead generates a list of indices and then calls an ODB write on each of them. That's not always a good thing, for example if you are writing an array of n parameters on a DAQ 
> board you will call the hotlink on that key n times
> - in addition to that the sequencer will also have to cope with variable-based indexes like "ODBSET array[$val]", but then how it should parse something like "[$a,1]" or "[$a*]"?
> 
> For the very first point I do not see a clean way to do this without breaking the compatibility of existing sequencers or having a difference between the two implementations.
> For the others I guess we can find a way out, however that's a major modification so I will put it on my todo list when I can find some free time.
> In any case I would propose to merge the two functions, so we have only to maintain a single implementation of the parsing.
> 
> I guess it's a good moment to brainstorm about that, let me know what you think
> 
> Marco
> 
> 
> > > The following all fail with "Cannot find ODB key "<key>""
> > > 
> > > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[*]" 0
> > > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[0-9]" 0
> > > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)[1]" 0
> > > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)*" 0
> > > ODBSET "/Detectors/Det*/Settings/Charge/Bias (V)" 0
> > > 
> > 
> > It would be cool if ODB pattern matching in the sequencer
> > were consistent with the ODB pattern matching in the json-rpc
> > interface for web pages:
> > 
> > https://midas.triumf.ca/MidasWiki/index.php/Mjsonrpc#Supported_array_index_syntax
> > 
> > K.O.
  2044   30 Nov 2020 Konstantin OlchanskiSuggestionODBSET wildcards with array keys in Sequencer files
> 
> we are considering to make the range selection uniform among json, sequencer and 
> odbedit "set" command. Having multiple ranges like [1,4-5] will be quite some work, so 
> my question is did you just implement it on the json side because it was easy, or are 
> there experiments who really need it? Wouldn't it be enough to have
> 
> [*]
> [n]
> [n-m]
> 

It has been a long time, but most likely I designed the interface to work this
way to permit maximum flexibility for writing into an array using just one
rpc operation.

The generalized form is:
[range,range,range...]

where range is:
array index or
index1-index2 or
index2-index1 (write in reverse order)

This is all documented here:
https://midas.triumf.ca/MidasWiki/index.php/Mjsonrpc#Supported_array_index_syntax

I think it is too late to change it.

>
> This way we always have only one db_set_data() value behind that. Any set of indices 
> we have to split into several db_set_data()
> 

Sounds good. I think it is easy to have a common implementation:

One would need following functions:
parse range selection from string into std::vector<int> of array indices (we already have it)
call db_set_data_range() (this is easy to add).

>
> trouble by triggering a hot link on each access.
>

There is no escaping this trouble. Half the experiments want notification
"per array", the other half, "per array element". We cannot choose one or the other for them,
we have to provide a way for the user to say how they want it.

P.S. With existing ODB calls, you cannot do [n-m] ranges. You can do whole array or you
can do one-element-at-a-time.

K.O.
ELOG V3.1.4-2e1708b5