simrisc
's man-pages
This manual covers the design and organization of simrisc
's software. Each
section (except for section main
) covers a class as encountered when
reading the sources starting at the main
function.
In total almost 30 classes were defined. Starting from main
only
Simulator
is required.
At the other side of the spectrum there are several classes or comparable elements which are used by many classes. These elements are defined in separate header files:
enums/enums.h
, containing enumeration values for errors and constant
values;
typedefs/typedefs.h
, defining short names for frequently used vectors
(like SizeVect
for std::vector<size_t>
)
globals/globals.h
, a struct defining several static functions handling
frquently encountered small computations (like isZero
to determine
whether a double
value has a value that's closer to zero than a
(compile time configurable) tolerance).
These files are not further covered in this manual: they contain definitions and trivial support functions, and the reader should refer for these files themselves for further details.
The outline of the organization of the outer levels of the program is shown in
Figure 1. main
uses a Simulator
, and for each separate
analysis the Simulator
creates an Analysis
object, which in turn
creates a Loop
object, doing all the hard work (hence the ellipsis in
Figure 1).
The configuration file defines elements that can be used in the analyses. Such
elements are, e.g., Screening
, containing screening parameters,
Densities
, containing parameters of breast densities, and Incidence
,
containing tumor incidence parameters. Objects of those classes are used by
Loop
.
It is quite possible that future versions of simrisc
also supports different types
of simulations. It's likely that Loop
itself then becomes a scenario
as defined by Gamma et al. (1995), and that analysis specification files also
select the requested scenario(s) by specifying the requested simulation
type(s).
enums/enums.h
file. These enumerations are:
Constants
, defining the number of bi-rad categories (N_BIRADS
= 4
) and the ending and maximum ages for simulated cases (END_AGE
= 101, MAX_AGE = END_AGE - 1
);
DistType
, defining the types of the distributions used when
generating random values. All classes using distributions (like
Distribution
and Random
) use this enumeration when referring
to statistical distributions.
GeneratorType
, defining the diffent ways the random number
generators can be initialized (cf. the generator:
parameter in the
configuration file);
ParamsSrc
, specifying whether parameters are defined in a
configuration file or in an analysis:
specification section.
typedefs/typedefs.h
contains type definitions of container types
that are used throughout the program. Because of the types that are
defined in typedefs.h
source files may assume that the headers cstdint,
vector, string, unordered_set
and enums.h
are also included.
When parameter specifications are retrieved these specifications are stored in
a dedicated struct LineInfo
:
struct LineInfo { ParamsSrc src; uint16_t lineNr; std::string txt; std::string tail; };
In addition the following type definitions of various containers are defined:
typedef std::unordered_set<std::string> StringSet; typedef std::vector<LineInfo> LineInfoVect; typedef std::vector<double> DoubleVect; typedef std::vector<DoubleVect> DoubleVect2; typedef std::vector<size_t> SizeVect; typedef std::vector<std::string> StringVect; typedef std::vector<uint16_t> Uint16Vect;
Globals
merely provides functions. These functions are all
static member functions. They are:
double findAge(DoubleVect const &cumProb, double prob)
prob
in
cumProb
, using the index of the first of that series of elements
as the begin index, and finds the first element in cumProb
exceeding prob
using that element's index as the end-index. It
then interpolates prob
in the half-open range
[cumProb[begin], cumProb[end])
returning the corresponding the (floating point) index;
bool isZero(double value)
value's
absolute value is smaller than 1e-8
;
bool isPositiveZero(double value)
value
is not negative and smaller than 1e-8
;
ostream &setPrecision(ostream &out, uint16_t nDigits)
out's
precision when inserting double
values to
nDigits
behind the decimal point;
int weakCompare(double lhs, double rhs)
1e-3
returns -1 if lhs < rhs
, 0 if lhs ==
rhs
, and 1 if lhs > rhs
.
Simrisc
, like many other programs, expects arguments when it is activated. As
described in the simrisc(1) man-page simrisc
's only argument is analyses
,
describing the analyses simrisc
performs. Other than that simrisc
expects options.
Options come as boolean options (like --help, --one-analysis,
and
--verbose
and as options requiring arguments (like --nCases
,
specifying the number of cases to simulate).
The class Options
inspects all options and stores their values. Since
Arg
, the class receiving the program arguments and options is a singleton
it is only natural for Options
to be a singleton class as well, allowing
all program components to access the options without having to pass an
Options
object as argument.
Most members simply return their option values (like string const &base()
,
returning the base directory where by default the results are written). But
some members (like fixedNaturalDeathAge
) (conditionally) assign values to
their parameters instead of returning a value.
Hier is an overview of Options'
public members. All members are const
members except alter
, which is used to modify option values as found in
the configuration file:
Err
. This class defines the
content of various error messages, some of which are plain messages, and some
require a onfiguration line information (LineInfo
, cf. section
1.1.2). The messages are selected using symbolic names defined in the
enum Msg
, nested under the class Err
. The following symbolic
names are defined:
All members of Err
are static. They are:
char const *src(ParamsSrc type)
type
(cf. section 1.1.1);
std::ostream &msg(Msg err)
std::ostream &msg(Msg err, LineInfo const &lineInfo)
:
'. A reference to the stream is
returned;
void specification(LineInfo const &line)
msg(SPEC_ERROR, line)
.
void multiplySpecified(LineInfoVect const &lines,
std::string const §ionList)
MULTIPLY_SPECIFIED
in specification
sectionList
, listing the info about the multiple specifications
provided in lines
.
VSD
(Value, Standard deviation, Distribution) stores the value,
standard deviation and distribution type of parameter values. Such parameters
are usually specified in the configuration file like this:
# value spread distr. parameterName: 72.9 .552 Normal
The parameter values are retrieved by accessor members. If the
Scenario's spread
parameter was configured as true
then the member
refresh
applies a random variation to the value parameter, which is then
returned by the value
accessor. If D
represents a random value from
the used distribution and orgValue
is the value that was originally read
from the configuration file then refresh
modifies value
as
value = orgValue + spread * D()which value is thereupon returned by its
value
accessor.
Note: if the VSD spread
parameter is not specified then the default value
0 is used. In those cases the VSD value
data member is not modified
when Scenario spread
is specified as true
.
AgeGroup
extracts age group specifications from the
configuration file. Age group specifications look like this:
0 - 40 40 - 50 50 - 60 60 - 70 70 - *which are half-open age ranges:
[begin, end+CHAR41
. The star
specifies the maximum possible age (MAX_AGE
as defined in enums.h
).
AgeGroup
objects have two accessors: beginAge
, returning the begin
age, and endAge
returning the ending age of the half open range.
When age groups are read then their ranges must connect. This is checked by the member
bool nextRange(std::vector<Type> const &vect, LineInfo const &lineInfo) const;returning
true
if the begin age read from lineInfo
equals the
end age in vect.back()
. This is used, e.g., when reading the age ranges of
the various breast densities (cf. densities/add.cc
).