All error message of pcrcalc have the format:
scriptFileName:lineNr:colNr:ERROR: A descriptive message
The message is a list of positions separated by the symbol :
In most cases, pcrcalc will point to the exact position where the error is present. There are a few occasions that the actual (syntax) error is before the position that pcrcalc reports. One of these occasions is the generic syntax error like:
example.mod:5:36:ERROR: Syntax error at symbol ';'
In this example, the symbol ”;” at line 5, character position 36 is not expected. This may be caused by earlier symbols in the script.
Conditional iteration (looping) allows to perform model code a conditional number of times. The syntax is:
repeat {
Statements
} until BooleanCondition ;
The Statements are executed repeatedly until the BooleanCondition is true. For example:
nrLoopsExecuted=0;
repeat {
nrLoopsExecuted=nrLoopsExecuted+1;
} until nrLoopsExecuted eq 4;
The statement nrLoopsExecuted=nrLoopsExecuted+1 is executed 4 times.
If the BooleanCondition is spatial (it evaluates to a map) then the Statements are executed until no cells in BooleanCondition are false(0). In other words execution of the loop is stopped if all cells are true(1) or missing value. Note that the execution is not stopped at a per cell base, but when ALL cells meet the specified condition. In theory, stopping at a per cell base might decrease execution time, but the additonal bookkeeping of which cells needs one iteration more at each loop will neutralise this gain. A more realistic example is an iteration to fit a certain function, with a series of succesive estimates that will stop if the next estimate only differs a certain small epsilon value.
prevEst= ...initial estimate ... ;
repeat {
nextEst= ... estimate ... ;
difference = abs(nextEst-prevEst);
prevEst=nextEst;
} until difference < 0.00001;
If the result of nextEst is a map, then this loop will continue until each cell in difference has a value smaller than 0.000001.
In scripts one can define at which timesteps a map must be written to the permanent database (in other words your harddisk).
This feature consists of the following extensions to the modelling language:
To explain this feature, we use the following minimal script
timer 1 1000 1;
initial
dynamic
report stack1_ = input.map;
report stack2_ = input.map;
The script simply copies the input.map to 2000 maps named stack1_0.001, stack2_0.002 up to stack1_1.000 and stack2_0.001 up to stack2_1.000.
Now suppose we want to write to stack stack1_ only at step 1, 10, 900, 1000 and stack2_ at every fifth step. We then define and use two report moment definitions in the timer sections and apply them to the reports:
timer 1 1000 1;
rep1 = 1,10,900,endtime;
rep2 = 5+5..endtime;
initial
dynamic
report(rep1) stack1_ = input.map;
report(rep2) stack2_ = input.map;
Different moments in a report moment definition are seperated by ‘,’ as in 1,10,900,endtime that defines 4 moments. A range of moments can be given by the syntax start+step..end. Step increases the moments up and including end. In the example above stack2_ will be reported at timestep 5,10,15,25, etc. until 1000. If the + is omitted a step value of 1 is assumed. In other words 5..10 and 5+1..10 will both result in 5,6,7,8,9,10.
A report moment definition can also be placed within the report statements:
timer 1 1000 1;
initial
dynamic
report(endtime) stack1_ = input.map;
report(1,5+3..12) stack2_ = input.map;
In the example above stack1_ is only reported at the last step and stack2_ at 1,5,8,11.
A special report definition is reportdefault. Defining this one in the timer section causes all stack reports without explicit moments to report only at particular moments:
timer 1 1000 1;
reportdefault = 900+5..endtime;
initial
dynamic
report stack1_ = input.map;
report stack2_ = input.map;
Both stack1_ and stack2_ are reported at steps 900,905,910..1000.
In both command line expressions and model scripts, parts of the model can be substituted from shell-like arguments. For example when sum_2.mod contains:
Then calling
pcrcalc -f sum_2.mod sum_2.map add_1.map add_2.map
Will yield execution of:
sum_2.map = add_1.map + add_2.map;
On the command line, the model and the arguments need to be separated by ;; . For example:
pcrcalc "$1 = $2 + $3 ;;" sum_2.map add_1.map add_2.map
Basic substitution rules:
Advanced substitution rules:
- A range of parameters can be given in the ${from,to} construct. For example: $1 = max(${2,3}) ;; max.map in1.map in2.map becomes max.map = max(in1.map,in2.map)
- n in the first or second arguments denotes the number of arguments: $1 = max(${2,n}) ;; max.map in1.map in2.map in3.map becomes max.map = max(in1.map,in2.map,in3.map)
- The ${from,to} construct prints an ‘,’ between every argument. Another argument separator can be given explicitly: $1 = ${2,n,+} ;; sum.map in1.map in2.map in3.map becomes sum.map = in1.map+in2.map+in3.map
- A wrapper around each arguments can be given: $1 = ${2,n,+,sqrt($)} ;; sumsqrt.map in1.map in2.map in3.map becomes sumsqrt.map = sqrt(in1.map)+sqrt(in2.map)+sqrt(in3.map)
- In the 4th argument, the wrapper, a $ is given for where the argument should be inserted. That $-sign is optional, allowing the following construct: $1 = (${2,n,+}) / (${2,n,+,1});; av.map in1.map in2.map in3.map becomes av.map = (in1.map+in2.map+in3.map) / (1+1+1)
- white space in argument 3 and 4 is kept in the substitution: $1 = ${2,n,and,not $} ;; andnot.map in1.map in2.map in3.map becomes andnot.map = not in1.mapandnot in2.mapandnot in3.map while $1 = ${2,n, and ,not $} ;; andnot.map in1.map in2.map in3.map becomes the correct andnot.map = not in1.map and not in2.map and not in3.map
Additional notes:
- comments (#) are not allowed within a substitution
- Note that ${n} denotes the last argument, while $n means an environment variable named n.
- Note that is an extra substitution level, so one needs to give $$1 in an UNIX shell, if the command line expression is enclosed in “-symbols. This is not neccessary if it is enclosed in ‘-symbols.
- If you are trying $-constructs and you get the message: ERROR: parse error near line ‘?’ near symbol ‘?’ Then two errors are frequent:
- you forgot the delimit the expression and the arguments by ;;
- the substitution went wrong. First try -t, to see what the result of the substitution is. As said before, the substitution mechanism silently ignores most errors, and returns blanks. So be warned.