ETHZ_Logo RAMSES_Logo_Right   RAMSES   RAMSES_Logo_Left Systems Ecology  
Start    search button      Modules:   A-Z   Function   Layer        QuickRefs:   DM   AuxLib   AuxLibE   SciLib   EasyMW   MW   ISIS   RMSLib

DEFINITION MODULE SysStructure;

  (*******************************************************************

    Module  SysStructure     (ISIS_Version_1.2)

      Copyright (c) 1998-2006 by Andreas Fischlin and ETH Zurich.

    Purpose   Support the management of the structure of a
              complex system consisting of several so-called
              subsystems.

    Remarks   This module allows to configure subsystem variants
              and to send messages to subsystems to assign their
              data. It is useful while working with complex,
              structured systems consisting of several dynamic
              models, e.g. when studying entire ecosystems.

              See also modules SysStrctAux and SysVariants.

              This module belongs to ISIS
              Integrative Systems Implementation Software.

              IMPLEMENTATION RESTRICTION:

              Note, this module uses the module StructModAux
              from the RAMSES auxiliary library. In particular
              be aware that it preempties the latter's
              functionality. Thus, you should no longer use
              StructModAux at all (this module is a full
              replacement with additional features) or you
              might get unpredictable results.


    Programming

      o Design
        Andreas Fischlin          28/05/1998

      o Implementation
        Andreas Fischlin          28/05/1998


    ETH Zurich
    Systems Ecology
    CHN E 35.1
    Universitaetstrasse 16
    8092 Zurich
    SWITZERLAND

    URLs:
        <mailto:RAMSES@env.ethz.ch>
        <http://www.sysecol.ethz.ch>
        <http://www.sysecol.ethz.ch/SimSoftware/RAMSES>


    Last revision of definition:  21/01/2001  AF

  *******************************************************************)


  FROM SysModBase IMPORT System;

  (* Error constants: sysStructureMsgOffset = DMLanguage.userBase + 430 .. 460-1 *)


  (*********************************************************)
  (*#####   Declaring Subsystems & System Structure   #####*)
  (*********************************************************)

  (*-----------------------------*)
  (*=====   Master System   =====*)
  (*-----------------------------*)

  TYPE
    SystemStructure = BITSET;
    SubSystem = INTEGER; (* actually limited to range [0..Cardinality(SystemStructure)]! *)

    DefSysStructProc   = PROCEDURE (VAR SystemStructure);
    MakeMsgProcedure   = PROCEDURE (SubSystem, VAR ARRAY OF CHAR);
    PreparationRoutine = PROC;


  PROCEDURE UseAsMasterSystem(masterSys: System;
                              mainAnchor: ARRAY OF CHAR;
                              defSysStructP: DefSysStructProc;
                              configInitP: PROC;
                              makeSetVariCmdP: MakeMsgProcedure;
                              makeDatAssgnCmdP: MakeMsgProcedure;
                              configTermP: PROC );
    (*
      Proclaims masterSys as the main master system.  It also
      installs a few global procedures which are needed to manage
      the message exchange among the master and the subsystems
      during reconfigurations of the system structure (see also
      routine UseAsSubSystem from this module).  You have to be the
      owner of the system to proclaim it as master, i.e.  argument
      'masterSys' may not be the 'unknownSystem', but has to be
      declared prior to the call of UseAsMasterSystem by means of
      routines DeclSystem from module SysModBase.

      The meaning of the other arguments:

      mainAnchor        File name (possibly preceeded by a path) which
                        denotes the main data frame file used by the
                        system (see module DataFrames).  This file is
                        loaded into memory automatically during ISIS'
                        AUTOCONFIGURATION (see routine
                        ExecuteEntirePreparation, this module), but no
                        assignments are done (see module SysDatAccess).
                        The data frames in 'mainAnchor' are typically
                        used for an automatic configuration of the system
                        structure, given a data frame 'SystemStructure'
                        can be loaded (see also below the routines
                        GetSysStructureFromDTF, GetSubSysVariantFromDTF,
                        AddPreparationRoutine, section AUTOCONFIGURATION
                        of ExecuteEntirePreparation).  If the empty
                        string is passed as actual argument for
                        mainAnchor, a file opening dialog is offered (in
                        this case, should you want to learn about the
                        name of the file which was actually opened, you
                        need to use module DatFraAux (see procedure
                        InspectDataFrame, parameter storedOnFsWithName
                        and/or procedure InspectDataFrameFile)).  No
                        filtering takes place while loading the data
                        frames, i.e.  the filter range is set to
                        [DataFrames.minFilter..DataFrames.maxFilter].

      All following handlers are optional and can be passed as actual
      argument using the dummy procedures such as NoAction exported from
      this module (see below).

      defSysStructP     Procedure used to define the system structure.
                        It overrules the automatic self-configuration
                        ISIS will otherwise perform by retrieving and
                        analyzing the data frame 'SystemStructure'.
                        Typically the latter data frame is automatically
                        loaded via the data frame file 'mainAnchor'.
                        Note the argument is an in/out parameter; upon
                        entering the procedure it contains the system
                        structure as defined according to the priority
                        rules described in comment of routine
                        AddPreparationRoutine, section AUTOCONFIGURATION.
                        Thus defSysStructP serves as a filtering routine
                        possibly altering the system structure as
                        retrieved by ISIS (see also comments on routines
                        GetSysStructureFromDTF).

      configInitP       Procedure which is executed at the very begin
                        of a (re)configuration of the system's structure
                        which starts at the very end of all preparations
                        which have typically loaded data frames.  You
                        may set here global simulation parameters, e.g.
                        call routine AssignGlobalSimulationData from
                        ISIS module SysDatAccess.

      makeSetVariCmdP   Procedure used to construct a "set variant
                        command" on behalf of a particular subsystem
                        (see also below routine UseAsSubSystem) while
                        (re)configuring the system's structure.  A set
                        variant command typically consists of value
                        definitions according to the SML (System Message
                        Language) as provided by module SysMsgLingua.
                        The command is expected to contain at least the
                        reserved value definition 'variantList' (type
                        charstring).  A variant list typically defines a
                        combination of variants for a given subsystem by
                        listing the variants in the string delimited by
                        "|" (= variDelim from ISIS module SysVariants)
                        (see also comment of routine SetSubSysVariant
                        from this module).

                        This procedure is called whenever a variant
                        needs to be set, e.g.  after a (re)configuration
                        of a subsystem, i.e.  the subsystem is being
                        activated, or the entire system structure is to
                        be modified.

                        Note in case you pass DontMakeMsg as actual
                        argument for this procedure this module follows
                        a default strategy to define variants for its
                        subsystems by the following steps:

                         1) GetSubSysVariantFromDTF
                         2) GetSubSysVariant
                         3) GetDefltSubSysVariant

                        (all procedures from this module, see also their
                        comments).  As soon as one of the involved
                        procedures returns actually a variant list
                        (value definition 'variantList' is no longer
                        empty) no further steps are executed.


      makeDatAssgnCmdP  Procedure used to construct a data assignment
                        command on behalf of a particular subsystem
                        (see also below routine UseAsSubSystem) while
                        (re)configuring the system's structure.  A
                        data assignment command typically consists of
                        value definitions according to the SML (System
                        Message Language) as provided by module
                        SysMsgLingua.  This procedure is called whenever
                        some data assignment may have become necessary;
                        e.g.  after a (re)configuration of a subsystem,
                        i.e. a new variant has been set, or the entire
                        system structure is to be modified.

                        Note: ISIS does automatically publish in the
                        datAssgCmd string these reserved value
                        definitions in addition to what makeDatAssgnCmdP
                        has generated (see also formal parameter
                        assignDataP of procedure UseAsSubSystem, this
                        module):

                          ident             type
                          --------------    -------
                          newStructure      boolvar
                          newVariant        boolvar
                          dataAssigned      boolvar

                       Consequently, there is no need for
                       makeDatAssgnCmdP to maintain these value
                       definitions.  It is recommeded to reserve and
                       maintain from within makeDatAssgnCmdP also

                          ident             type
                          --------------    -------
                          dataAreNew        boolvar


      configTermP       Procedure which is executed at the very end
                        of a (re)configuration of the system's structure.
                        E.g. you may pass EstablishAllLinks (from ISIS
                        module SysModBase) as actual parameter for
                        configTermP.

      NOTE: None of the passed event handler routines is executed
      immediately, i.e.  while calling UseAsMasterSystem.  All event
      handler routines are used at a later time and may be called by
      the following routines:

        this module                   module SysStrctAux
        ------------------------      -------------------
        SetSysStructure               ConfigureSystem
        SetSubSysVariant              ChooseSubSysVariant
        AssignSystemsData
        AssignSubSysData              AssignDataToSubSysByDlg
        ExecuteEntirePreparation
        AUTOCONFIGURATION

    defSysStructP, configInitP, and configTermP are only called by
    SetSysStructure, ConfigureSystem, ExecuteEntirePreparation, and
    AUTOCONFIGURATION.  makeSetVariCmdP and makeDatAssgnCmdP are called
    by all tabulated routines.

  *)



  (*
    For your convenience use following routines as actual argument
    when calling UseAsMasterSystem in case you don't want to make use
    of any of the optional handlers.
  *)

  PROCEDURE DontSetSysStructure(VAR struct: SystemStructure);
    (* as defSysStructP *)
  PROCEDURE NoAction;
    (* as configInitP or configTermP *)
  PROCEDURE DontMakeMsg(subSys: SubSystem; VAR datAssgCmd: ARRAY OF CHAR);
    (* as makeSetVariCmdP or makeDatAssgnCmdP *)



  (*--------------------------*)
  (*=====   SubSystems   =====*)
  (*--------------------------*)

  TYPE
    SSShortID = ARRAY [0..7] OF CHAR; (* Sub System Short Identifier *)

    BooleanFct         = PROCEDURE (): BOOLEAN;
    SendMsgProcedure   = PROCEDURE (VAR (* In/Out *) ARRAY OF CHAR);

  VAR
    unknownSubSystem: SubSystem; (* read only! *)
    unknownSSShortID: SSShortID; (* read only! *)

  PROCEDURE UseAsSubSystem( subSysName, subsysShortId: ARRAY OF CHAR;
                            VAR subSys: SubSystem; declVariantsP: PROC;
                            activateSubSysP, deactivateSubSysP: PROC;
                            subSysIsActiveP: BooleanFct;
                            setVariantsP: SendMsgProcedure;
                            linkInsP: PROC;
                            assignDataP: SendMsgProcedure;
                            updateSysP: PROC);
    (*

      Proclaims system with name 'subSysName' as a subsystem.  It
      also installs associated procedures which are needed to manage
      its presence, structure via variants, and data.

      Parameter 'subSysName' is a string used to name the subsystem
      (see also parameter sysName of procedures DeclChildSystem (or
      DeclSystem) from module SysModBase; but note, for your
      convenience, subSysName may differ from sysName (not inforced
      by ISIS), but it is recommended to use the same name for clarity
      in the resulting user interface: For instance the automatic
      display of the variants in the about window of a system as
      provided by ISIS functions only if 'subSysName' and 'sysName'
      match exactly (of course case sensitively).

      Parameter 'subsysShortId' is a short identifier which
      denotes again uniquely the subsystem, e.g.  in data frames
      (see also SSShortID; note, may contain '_').

      Parameter 'subSys' denotes the subsystem and returns a
      unique value associated with the subsystem.  For instance
      use it to configure a particular system structure (see type
      SystemStructure) by listing the subsystem you wish to
      activate as an element in a set of type SystemStructure.

      All other parameters serve to exchange messages among this
      module, the master system, and the installed subsystems.  The
      procedures passed as actual arguments have to fulfill the
      following functions:

      declVariantsP   Declares all variants known by the subsystem
                      e.g.  if several variants of model equations can be
                      used, they are typically defined as so-called
                      variants of the subsystem.  Call routines
                      DeclareVariantSet and AddVariant from module
                      SysVariants from within this procedure.  Note, this
                      routine is executed only once during execution of
                      UseAsSubSystem.

      activateSubSysP   Activates the subsystem as a dynamic subsystem.
                        It typically declares all its dynamic models and
                        model objects whenever SetSysStructure or another
                        ISIS routine asks the subsystem to do so.  Note,
                        this routine is only called by ISIS, when the
                        subsystem is currently not dynamically active,
                        i.e.  subSysIsActiveP (see below) has returned
                        FALSE.

      deactivateSubSysP Deactivates the subsystem as a dynamic subsystem.
                        It typically undeclares all its dynamic models
                        and model objects.  Outputs required by other
                        subsystems ought still to be provided, e.g.  as
                        sample and hold values or, alternatively, if
                        other subsystems have installed an
                        AtLinkBreakProc, they can try to get the needed
                        inputs from other sources, e.g.  from a file (see
                        in this context also module SysIODivert).  Note,
                        this routine is only called by ISIS, when the
                        subsystem is currently dynamically active, i.e.
                        subSysIsActiveP (see below) has returned TRUE.

      subSysIsActiveP   Returns wether subsystem is currently active
                        as a dynamic subsystem (level DESS, SQM, or
                        DEVS)

      setVariantsP    Configures the subsystem according to a particular
                      new set of variants.  The latter is passed
                      within the argument message, which lists all
                      current variants in the same sequence as they
                      have been declared by declVariantsP (see above).

                      IMPORTANT NOTE: The string parameter is called by
                      name (not value), since the subsystem should deal
                      with this message string as an input/output
                      parameter.  It contains the variant list as the
                      reserved SML value definition 'variantList' (see
                      also module SysMsgLingua).  ISIS expects your
                      routine to retrieve this list with GetStrFrom from
                      SysMsgLingua, to set the variants and if successful
                      to report this back to ISIS by calling
                      PublishBool(msg,"variantSet",TRUE).  Only if this
                      result is returned, ISIS will actually store the
                      new variant by setting the current variant for each
                      variant set used by the subsystem (see also module
                      SysVariants). If the value definition 'variantSet'
                      is returned with value FALSE, ISIS produces an
                      error message.

                      The variantList is always checked by ISIS, and
                      setVariantsP is only called by ISIS if the
                      variant is really new, i.e.  different from that
                      possibly previously set, and is a legal one.

                      in summary ISIS does automatically publish in
                      the setVariantCmd string these reserved SML value
                      definitions (see module SysMsgLingua):

                          ident             type
                          --------------    -------
                          variantList       charstring
                          newStructure      boolvar
                          newVariant        boolvar
                          variantSet        boolvar

                      The current variant settings as returned by ISIS
                      (see e.g.  procedure GetCurOrdTuple, this module)
                      are not yet changed when ISIS calls setVariantsP.
                      This takes only place as soon as you return control
                      back to ISIS, i.e.  you can expect that a routine
                      like GetCurOrdTuple returns the new variants only
                      in the procedure(s) called next, e.g.  linkInsP or
                      assignDataP (see below).

      linkInsP        (Re)establishes links in case the subsystem
                      has some inputs which depend on outputs from
                      other subsystems.

                      For an autonomous subsystem pass as actual
                      argument NoInputs.

                      For a subsystem with only global inputs
                      (e.g.  provided by the master system), pass
                      as actual argument DontLinkIns.

                      For a subsystem with inputs which depend on the
                      outputs of other subsystems, but all unqualified
                      input identifiers match unqualified output
                      identifiers (see also routine EstablishAllLinks
                      from module SysModBase), pass as actual argument
                      DontLinkIns.  Then the global routine
                      EstablishAllLinks is sufficient, e.g.  passed as
                      actual argument for configTermP when calling
                      UseAsMasterSystem to establish all linking for all
                      your subsystems.  One call to the global
                      EstablishAllLinks is likely to be more efficient
                      when called at the end of the entire system
                      (re)configuration as if it would be called by every
                      subsystem repeatedly.

                      A non empty procedure linkInsP is only needed if
                      the subsystem subSys requires explicit pairing
                      between output variables of an another subsystem
                      and its inputs.  It typically calls routine
                      EstablishLink and AddLinkHandlers from module
                      SysModBase.

      assignDataP     Asks the subsystem to assign all data to its models
                      and model objects.  Data are typically taken from
                      data frames by using routines from module
                      DatFraUsage, e.g.  by announcing its interest in
                      particular data via routine AnnounceDataInterest.

                      IMPORTANT NOTE: The parameter is called by name
                      (not value), since the subsystem should deal with
                      this message string as an input/output parameter.
                      E.g.  the subsystem should set the value definition
                      "dataAssigned" (boolvar, see module SysMsgLingua)
                      to let the master know about the final success of
                      the data assignment.

                      IMPORTANT NOTE: ISIS does automatically publish in
                      the datAssgCmd string these reserved SML value
                      definitions (see module SysMsgLingua) in addition
                      to what makeDatAssgnCmdP has generated (see formal
                      parameter makeDatAssgnCmdP of procedure
                      UseAsMasterSystem, this module) before ISIS calls
                      assignDataP:

                          ident             type
                          --------------    -------
                          newStructure      boolvar
                          newVariant        boolvar
                          dataAssigned      boolvar


      updateSysP      Asks the subsystem to update its representation
                      e.g. according to current configuration

      See also routine HandOverSubSysMenuManagement from module
      SysStrctAux for further possibilities to manage subsystems,
      should you wish to have a subsystem specific user interface.

      NOTE: Routine declVariantsP is executed immediately, i.e.  while
      calling UseAsSubSystem.  All other installed event handler
      routines are used at a later time.

      For more details on the exact sequence of execution of the
      installed routines, see comments on AUTOCONFIGURATION and
      procedure ExecuteEntirePreparation from this module.

      IMPLEMENTATION RESTRICTION: Note, a proclamation of a subsystem
      is considered to be irreversible (There is no routine to revert
      this effect for an individual subsystem).  However, since the
      overall system dynamics depend on the status of individual
      subsystems, i.e.  whether particular subsystems are dynamically
      active or not (see parameters activateSubSysP or
      deactivateSubSysP), and since this status can be controlled at
      run time, this should not be a major restriction.  What is
      basically proclaimed irreversibly is only the maximum usable
      subsystems.  However, as an entire system, the master system and
      all subsystems can be deinstalled at once (routine
      ForgetSystemUsage), allowing for another round of usage of a
      master and its subsystems.

      IMPLEMENTATION RESTRICTION: This module supports only a
      single, structured system at a time which can consist of
      at most as many elements as fit into the basic Modula-2
      type BITSET (e.g. 16 subystems).
    *)

  (*
    for your convenience use following routines as actual arguments when
    calling UseAsMasterSystem or UseAsSubSystem in case you don't
    wanna use any of the optional functions.  Note, procedures
    activateSubSysP, deactivateSubSysP, and subSysIsActiveP are
    mandatory and need always to be provided.
  *)

  PROCEDURE NoInputs;
  PROCEDURE DontLinkIns;
  PROCEDURE NoVariants;
  PROCEDURE NoSetVariants(VAR (*In/Out*) setVariantCmd: ARRAY OF CHAR);
  (* Returns via reserved value definition 'variantSet' always TRUE *)
  PROCEDURE NoDataAssign (VAR (*In/Out*) datAssgCmd: ARRAY OF CHAR);
  (* Returns via reserved value definition 'dataAssigned' always TRUE *)
  PROCEDURE NoUpdate;



  (*******************************************************************

    (*--------------------------------------------------------*)
    (*=====   General Rules on Event Handling Routines   =====*)
    (*--------------------------------------------------------*)

      In summary, the event handling routines as installed by
      UseAsMasterSystem and UseAsSubSystem may be called directly or
      indirectly by the following routines:

        this module                   module SysStrctAux
        ------------------------      -------------------
        SetSysStructure               ConfigureSystem
        SetSubSysVariant              ChooseSubSysVariant
        AssignSystemsData
        AssignSubSysData              AssignDataToSubSysByDlg
        ExecuteEntirePreparation
        AUTOCONFIGURATION

      You can always learn where your handler is called from.  First
      observe that some routines may call the core routines
      SetSysStructure, SetSubSysVariant, and AssignSubSysData directly
      or indirectly.  The actual procedure chain is formed according
      to these calling relationships:

        Routine                     calls
        ---------------             ---------------
        AUTOCONFIGURATION *         SetSysStructure
        ExecuteEntirePreparation *  SetSysStructure
        ConfigureSystem             SetSysStructure

        SetSysStructure             SetSubSysVariant
        ChooseSubSysVariant         SetSubSysVariant

        SetSubSysVariant            AssignSubSysData
        AssignSystemsData           AssignSubSysData
        AssignDataToSubSysByDlg     AssignSubSysData

      Secondly, look at these reserved value definitions

        newStructure    only TRUE if SetSysStructure in procedure chain
        newVariant      only TRUE if SetSubSysVariant in procedure chain

      to learn by which way your handler has been called.  E.g.  if
      you call AssignSystemsData, both newStructure as well as
      newVariant are FALSE.  If you call SetSubSysVariant,
      newStructure is FALSE and newVariant is TRUE.  If you call
      SetSysStructure, both newStructure as well as newVariant are
      TRUE.

      -------------------
      * WhileConfiguringFromScratch  (this module) returns TRUE,
        otherwise FALSE

  ********************************************************************)


  PROCEDURE ForgetSystemUsage;
    (*
      Forgets at once the master system and all subsystems
      currently in use, allowing for another round of usage.
      Note, the actual existence of the involved systems as
      declared by routine DeclSystem or DeclChildSystem from
      SysModBase is not affected in any way by ForgetSystemUsage.
      Note also that data frames are neither affected, i.e.  the
      effect of the loading of the mainAnchor file (see routine
      UseAsMasterSystem) is not reverted; call DropAllDataFrames
      from DataFrames or DropDataFrame from DatFraAux to acchieve
      such an effect.
    *)



  (******************************************************************)
  (*#####   Controlling Actual System Structure & SubSystems   #####*)
  (******************************************************************)

  (*--------------------------------*)
  (*=====   System Structure   =====*)
  (*--------------------------------*)

   PROCEDURE DefineSysStructure ( syss: SystemStructure);
     (*
       Defines a default system structure as given by syss without
       actually affecting the system structure right away or
       triggering any events such as SetSysStructure does.  The
       passed system structure is only remembered and affects the
       current or next AUTOCONFIGURATION.  It is typically used
       during start-up of a system definition program to provide a
       configuration definition in case no data frame
       "SystemStructure" is available; the AUTOCONFIGURATION
       mechanism of ISIS may then use it (see also comment on
       routine AddPreparationRoutine this module, section
       AUTOCONFIGURATION).  RESTRICTION: This routine is without
       effect if called during a configuration such as an
       AUTOCONFIGURATION or a call to SetSysStructure, i.e.  by
       calling it from within defSysStructP (see UseAsMasterSystem).
     *)

  PROCEDURE SetSysStructure     (    syss: SystemStructure);
    (*
      Forces all installed subsystems to activate (or to
      deactivate, respectively), their dynamic models as given
      by the actual argument for syss.  Thus this function
      allows to configure the overall system structure under
      control of the callee.  Any given system structure can be
      described by a set, which lists an element for each
      subsystem to be activated (subsystems are referenced with
      the value returned in subSys when calling UseAsSubSystem).
      It is also possible to access this function via the
      standard user interface offered by module SysStrctAux,
      i.e.  routine ConfigureSystem.

      IMPORTANT NOTE: This routine will cause a whole chain of actions
      to take place.  In particular it will also call all routines
      installed by UseAsMasterSystem and for every subsystem those
      installed by UseAsSubSystem.  Consequently, this routine must be
      without any effect if called during an already running
      (re)configuration, e.g.  like that taking place during an
      AUTOCONFIGURATION.  Furthermore, if SetSysStructure can be
      called successfully, DefineSysStructure must have no effect at
      all.  In this context see please also the comments on routine
      DefineSysStructure and on AddPreparationRoutine, in particular
      the section AUTOCONFIGURATION, both from this module.
    *)

  PROCEDURE GetSysStructure     (VAR syss: SystemStructure);
    (*
      Returns the current system structure or overall system
      configuration in syss.
    *)

  PROCEDURE GetSysStructureFromDTF(VAR syss: SystemStructure);
    (*
      Returns the system structure as specified in the data frame
      "SystemStructure" (see module DataFrames for syntax and
      semantics of data frames). Ex.:

        DATAFRAME SystemStructure;
         KEYCOLUMN = SubSystem;
         REMARK = 'Structure of ForClim System';
         DATA:
        (*-------------------------*)
            SubSystem   Active      ;
        (*-------------------------*)
            C           TRUE        ;
            W           TRUE        ;
            E           TRUE        ;
            M           FALSE       ;
            T           TRUE        ;
            S           TRUE        ;
            D           FALSE       ;
            H           FALSE       ;
            I           FALSE       ;
            P           FALSE       ;
        (*-------------------------*)
        END SystemStructure;

      Column 'SubSystem' lists for every installed subsystem its
      subsysShortId (SSShortID) and the desired activation status in
      the column 'Active'.  The identifiers 'SystemStructure'
      and 'Active' are reserved. Of course the data frame
      SystemStructure may contain more columns than just the one
      shown here (cf.  routine GetSubSysVariantFromDTF).
    *)


  (*--------------------------------------*)
  (*=====   Variant of a Subsystem   =====*)
  (*--------------------------------------*)

  PROCEDURE SetSubSysVariant(subSys: SubSystem; vlist: ARRAY OF CHAR);
    (*
      Forces the subsystem denoted by subSys (value returned by
      UseAsSubSystem) to configure itself according to the
      combination of variants as specified in the actual argument
      variantlist.

      Variants are specified via an identifier (see also module
      SysVariants).  Since a subsystem can have several properties
      where it distinguishes variations or versions, a variantlist
      typically consists of several elements.  Each element
      represents a particular variant of a particular property.
      E.g.  ForClim-C may distinguish the following properties:

        - internal temporal resolution (TemporalResolution)
          recognized by equations and data (note, is independent
          from climate dynamics)

        - model variant of stochastic process to simulate temporal
          variability, such as interannual variability with an
          autoregressive model, or correlations among weather variables
          (StochasticProcess),

        - OutputTransformation,

        - the type of function used to compute climate changes
          (ClimChgFunction).

      A typical variantlist to be sent to ForClim-C may then look
      like:

        "monthly|crossCorr|outTransfA|noCC".

      Use variDelim from SysVariants to delimit individual variants.

      Note, it is also possible to access the functionality of
      SetSubSysVariant via the standard user interface offered by module
      SysStrctAux.  If you have installed it (see routines
      InstallSystemMenu or InstallSysMenuAndUtils from module
      SysStrctAux), each subsystem in use (see UseAsSubSystem) has its
      own special menu command in this menu while it is active.  It
      allows you to modify the current variants by dialogs with the same
      final effect as a call to SetSubSysVariant.

      IMPORTANT NOTE: vlist can optionally also be a SML command (see
      ISIS module SysMsgLingua).  This means that the actual argument
      for vlist may be a message which contains any SML value
      definitions; e.g.  the message string may be constructed via
      routine makeSetVariCmdP.  In all of these cases you have only to
      make sure, the variant to which you want to set the subsystem is
      published in the message string as the reserved value definition
      'variantList'.  Ex.:

         makeSetVariCmdP(subSys, msg);
         PublishStr(msg,'variantList',vlist);
         SetSubSysVariant(subSys,msg);

    *)

  PROCEDURE GetSubSysVariant(subSys: SubSystem; VAR vlist: ARRAY OF CHAR);
    (*
      Returns in vlist the current internal variant combination of
      the subsystem denoted by subSys (value returned by
      UseAsSubSystem).  See also routine SetSubSysVariant for
      further explanations on the meaning of vlist.
    *)

  PROCEDURE GetSubSysVariantFromDTF(subSys: SubSystem;
                                    VAR vlist: ARRAY OF CHAR);
    (*
      Returns in vlist the variant combination as specified in the
      data frame "SystemStructure" (see moduele DataFrames for
      syntax and semantics of data frames) for the subsystem denoted
      by subSys (value returned by UseAsSubSystem).  See also
      routine SetSubSysVariant for further explanations on the
      meaning of vlist.  Ex.:

        DATAFRAME SystemStructure; KEYCOLUMN = SubSys;
         REMARK = 'Configuration of ForClim System'; DATA:
        (*--------------------------------------------------------------*)
          SubSys Variant     ;
        (*--------------------------------------------------------------*)
          C      'monthly|phaseAvrgdAR1|outTransfE|transientCC';
          W      'phaseAvrgdAR1';
          E      'pet24|swb24|drStr24';
          M      '';
          T      'fct24';
          S      '';
          D      '';
          H      '';
          I      '';
          P      '';
        (*--------------------------------------------------------------*)
        END SystemStructure;

      Column 'SubSys' lists for every installed subsystem its
      subsysShortId (SSShortID) and the desired variant combination
      in the column 'Variant'.  The identifiers 'SystemStructure'
      and 'Active' are reserved.  Of course the data frame
      SystemStructure may contain more columns than just the one
      shown here (cf.  routine GetSysStructureFromDTF).
    *)

  PROCEDURE GetDefltSubSysVariant(subSys: SubSystem;
                                  VAR vlist: ARRAY OF CHAR);
    (*
      Returns in vlist the default variant combination for the
      subsystem denoted by subSys (value returned by
      UseAsSubSystem).  See also routine SetSubSysVariant for
      further explanations on the meaning of vlist.  The default
      variant combination is given by the first variant for each
      variant set maintained by the subsystem (see also module
      SysVariants).
    *)


  (*---------------------------------------------*)
  (*=====   Assigning Data to a Subsystem   =====*)
  (*---------------------------------------------*)

  PROCEDURE AssignSystemsData(VAR(*In/Out*) datAssgCmd: ARRAY OF CHAR);
    (*
      Asks all installed subsystems to assign their data to the models
      and model objects.  msg contains a SML (System Message Language)
      message (see ISIS module SysMsgLingua) which describes the data
      involved in the assignment.  E.g.  if the site changes the msg
      may be: "Site = 'Churchill'".  ISIS expects, that each subsystem
      publishes the reserved value definition 'dataAssigned' accordingly to its
      success in the parameter datAssgCmd it receives; otherwise ISIS
      will produce an error message.
    *)

  PROCEDURE AssignSubSysData( subSys: SubSystem; VAR(*In/Out*) datAssgCmd: ARRAY OF CHAR);
    (*
      Asks the subsystem denoted by subSys to assign its data to the
      models and model objects it owns.  msg contains a SML (System
      Message Language) message (see ISIS module SysMsgLingua) which
      describes the data involved in the assignment.  E.g.  if the site
      changes the msg may be: "Site = 'Churchill'".  datAssgCmd is an
      in/out parameter.  ISIS expects, that the subsystem publishes
      the reserved value definition 'dataAssigned' accordingly to its success.
    *)



  (**********************************************************)
  (*#####   Preparation of System Structure and Data   #####*)
  (**********************************************************)

  PROCEDURE AddPreparationRoutine(rp: PreparationRoutine);
  PROCEDURE VoidPreparationRoutine(rp: PreparationRoutine);
    (*
      A PreparationRoutine makes something ready for use, i.e.  it
      deals with some task which can only be executed if the
      entire system has been installed and needs some final
      preparation in order to be ready for simulation experiments.
      Such a routine is called automatically at the end of the
      starting up process of a System Definition Program (SDP)
      which installs a system.

      Typically you use this routine to process some data, e.g.  to
      load some data frames from files into memory (in addition to
      the mainAnchor file, see above routine UseAsMasterSystem).  This
      may serve to perform some global, initial computations needed
      at the begin of a complex simulation experiment (global means
      a task different from a model specific Initialize task, see
      module SysModBase, e.g.  routine DeclModel and formal
      parameter initialize).

      Preparation routines are called in the same order as they have
      been installed.

      AUTOCONFIGURATION: Note, there is a default preparation routine
      installed internally.  It is a routine which configures
      automatically the system structure as the last of all
      preparation routines.  Definitions of the system structure are
      recognized according to these priority rules:

        1) DefineSysStructure (called previously)
        2) GetSysStructureFromDTF
        3) defSysStructP (as installed via UseAsMasterSystem)

      If GetSysStructureFromDTF has success in retrieving valid
      data from the data frame "SystemStructure" the structure as
      previously defined by DefineSysStructure is ignored.  Typically
      the 'mainAnchor'-file (see above, routine UseAsMasterSystem)
      contains the reserved data frame 'SystemStructure'.  This
      will then automatically result in a system structure
      according to the specifications given in the data frame.

      Alternatively, you can ensure to overrule what is present in
      the data frames by routine defSysStructP, which you have
      installed while calling procedure UseAsMasterSystem.  This
      gives you a last word over the actual system structure
      resulting from the auto-configuration.  Note, if you never
      called DefineSysStructure, nor the data frame
      "SystemStructure" can be used successfully, nor defSysStructP
      defines a non-trivial system structre, the empty set is used
      and consequently no subsystems will be activated.

      For more details on exact sequence of events during an
      AUTOCONFIGURATION see comments on routine
      ExecuteEntirePreparation (this module).

      IMPLEMENTATION RESTRICTION: Preparation routines are a
      replacement for 'ModelWorks'' InstallDefSimEnv from module
      SimMaster, which you should no longer use or you defy all
      preparation routines.
    *)


  PROCEDURE ExecuteEntirePreparation;
    (*
      Executes an entire system preparation.  Note, the
      AUTOCONFIGURATION, which occurrs automatically when you enter
      the simulation environment by a call to RunSimEnvironment (from
      'ModelWorks' module SimMaster), does simply call
      ExecuteEntirePreparation.  ExecuteEntirePreparation calls
      routines you have installed in ISIS by UseAsMasterSystem and
      UseAsSubSystem in this sequence:

        1) FOR all installed subsystems which are active
           - deactivateSubSysP
        2) DataFrames.DropAllDataFrames
        3) DataFrames.LoadDataFrames('mainAnchor' (see UseAsMasterSystem)
        4) any client installed preparation routines in
           sequence of installation (see AddPreparationRoutine)
        5) defSysStructP (see UseAsMasterSystem)
        6) configInitP (see UseAsMasterSystem)
        7) FOR all installed subsystems
           - activateSubSysP (if to be activated, see UseAsSubSystem)
           or
           - deactivateSubSysP (if to be deactivated, see UseAsSubSystem)
        8) FOR all installed subsystems (if newly to be activated)
           - makeSetVariCmdP (see UseAsMasterSystem)
           - setVariantsP (see UseAsSubSystem)
           - makeDatAssgnCmdP (see UseAsMasterSystem)
           - assignDataP (see UseAsSubSystem)
           - linkInsP (see UseAsSubSystem)
        9) FOR all installed subsystems
           - updateSysP (see UseAsSubSystem)
       10) configTermP (see UseAsMasterSystem)

      Note, if you call SetSysStructure (this module) or
      ConfigureSystem (from module SysStrctAux), not the entire
      sequence listed above is executed.  Instead the steps 5 (if
      currently no subsystem active), 6,7,8, and 9 are executed only.
      Thus steps 1) to 5) can be considered to form the primary
      initialization, steps 6) to 9) the reconfiguration of a system
      structure.  During a configuration where all steps are executed,
      procedure WhileConfiguringFromScratch (this module) returns
      TRUE.  Finally note, subSysIsActiveP may be called anytime
      throughout the execution of ExecuteEntirePreparation.

      IMPORTANT NOTE: The effect of ExecuteEntirePreparation is the
      same as when you call the 'ModelWorks'' InstallDefSimEnv routine
      from module SimMaster, or by choosing any of the corresponding
      menu command(s) from within 'ModelWorks'' standard simulation
      environment (all preparations are done on all subprogram levels,
      i.e.  by every InstallDefSimEnv routine, given
      AddPreparationRoutine has been called on that subprogram level).

    *)



  PROCEDURE WhileConfiguringFromScratch(): BOOLEAN;
    (*
      Returns TRUE during any running configuration which involves
      all steps as described in the comment of routine
      ExecuteEntirePreparation, i.e.  an AUTOCONFIGURATION or a call
      to ExecuteEntirePreparation.  In particular it lets you know
      wether the running configuration has also reloaded the main
      anchor with all the consequences this may have on system
      structure, variants, and data usage.  This routine may be
      useful for you, since several routines you have installed in
      ISIS by UseAsMasterSystem and UseAsSubSystem can be called in
      many circumstances (e.g.  setVariantsP, linkInsP, assignDataP,
      updateSysP etc.).
    *)


  (***************************)
  (*#####   Utilities   #####*)
  (***************************)


  PROCEDURE ShowSubSysVariant(subSys: SubSystem; inAboutW: BOOLEAN);
    (*
      Documents the current configuration of the subsystem, i.e.  its
      variants.  If inAboutW = TRUE, the output is written into the
      about window (see enumeration type MWWindow, i.e.  element
      AboutMW, from module SimBase) of the 'ModelWorks' standard
      simulation environment, and only, if this window is currently
      already open.  If inAboutW = FALSE, any currently selected output
      window receives the documentation.  You can use this utility to
      implement an about procedure of a model which makes use of
      variants (see procedure DeclModel from ISIS module SysModBase).
      Note, if the subsystem is currently not dynamically active, then
      the window is only cleared and no visible documentation is
      generated.
    *)

  PROCEDURE CheckVariantList(subSys: SubSystem;
                             VAR(*speed-up*) vlist: ARRAY OF CHAR;
                             VAR listIsOk: BOOLEAN);
    (*
      Returns in listIsOk wether the combination of variants as given
      by vlist is well defined, i.e.  contains only variant elements
      which have been properly declared (see procedure AddVariant from
      SysVariants), belonging to a known variant set (see procedure
      CreateVariantSet from SysVariants), and define a combination
      which has not been forbidden as illegal (see procedure
      ForbidVCombination from SysVariants).  If any error is detected,
      the routine generates an error message using module Errors and
      the error constants as described at the begin of this definition.
      IMPORTANT NOTE: Normally, you don't need to call CheckVariantList
      in procedure setVariantsP (see routine UseAsSubSystem, this
      module) yourself.  This is already done by ISIS and your
      setVariantsP procedure is never called if an attempt has been
      made to pass an invalid vlist, e.g.  via data frames or by a call
      to SetSubSysVariant (this module).
    *)

  PROCEDURE VListToOrdTuple( subSys: SubSystem;
                             VAR(*speed-up*) vlist: ARRAY OF CHAR;
                             VAR ordTuple: ARRAY OF INTEGER);
    (*
      Returns in ordTuple the tuple of ordination numbers
      corresponding to the variant combination given by vlist for the
      subsystem subSys.  You call this routine typically from within
      setVariantsP (see routine UseAsSubSystem, this module); thus, no
      checking for the correctness of vlist is made (that's already
      done by ISIS when passing a vlist to setVariantsP).  In case an
      element in vlist has never been properly declared as a variant
      of a variant set owned by the subsystem (see procedures
      CreateVariantSet and AddVariant from SysVariants), the
      corresponding element in ordTuple will not be defined and a
      negative number will be returned instead (VListToOrdTuple calls
      internally procedure OrdInVS from SysVariants).  The same is
      true if any dimensions should mismatch, i.e. ordTuple is always
      filled up to its last element, i.e. HIGH(ordTuple), with
      undefined values if any of the input parameters does not
      sufficiently define all elements of ordTuple.
    *)

  PROCEDURE GetCurOrdTuple( subSys: SubSystem; VAR ordTuple: ARRAY OF INTEGER);
   (*
     Returns in ordTuple the tuple of ordination numbers corresponding
     to the current variant combination of the subsystem subSys.  You
     call this routine typically from within setVariantsP (see routine
     UseAsSubSystem, this module).  Note, should a particular variant
     combination not have been set yet, which is for instance the case
     the very first time ISIS calls setVariantsP or after activating
     the subsystem, ordTuple contains not valid, negative values, i.e.
     undefined ordination numbers, to signal that the current ones are
     not yet set (see also module SysVariants, in particular routines
     CreateVariantSet and AddVariant).  Any superfluous elements in
     ordTuple are again filled with undefined ordination numbers, i.e.
     negative values.
   *)

  PROCEDURE GetMainAnchor(VAR mainAnchor: ARRAY OF CHAR);
    (*
      Returns the main anchor file name (may contain a path) as
      declared by the last call to UseAsMasterSystem.
    *)

  PROCEDURE NoOfSubSystems(): INTEGER;
    (* Returns the number of subsystems which are currently in use *)

  PROCEDURE NoOfVSetsInSubSystem(subSys: SubSystem): INTEGER;
    (*
      Returns the number of variant sets the subsystem 'subSys'
      currently uses.
    *)

  PROCEDURE GetSSShortID(subSys: SubSystem; VAR ssshortid: ARRAY OF CHAR);
    (*
      Returns in ssshortid the short identifier which has been
      installed for subsystem subSys by a call to procedure
      UseAsSubSystem.  It returns the empty string in case the
      subystem denoted by subSys has never been installed, thus this
      routine can also be used to learn whether the subsystem is
      currently actually installed.
    *)

  PROCEDURE GetSubSysName(subSys: SubSystem; VAR subSysName: ARRAY OF CHAR);
    (*
      Returns in subSysName the name string which has been installed
      for subsystem subSys by a call to procedure UseAsSubSystem.  It
      returns the empty string in case the subystem denoted by subSys
      has never been installed.
    *)



END SysStructure.

  Contact RAMSES@env.ethz.ch Last updated: 25-Jul-2011 [Top of page]