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.