Filter writing
Filters are derived from the class called 'Classfilter'. Writing a filter is quite straightforward but does require some care to link properly to the parameter variables and constants. The code for the Classea will be used for illustration and its calling procedure and code follows. The capability to write filters is not presently available to CRHM user.
Call
$ea ea(t, rh) ea =desired vapour pressure fot t = temperature and rh (%) = the relative humidity.
C++ Header
class Classea : Classfilter {
public:
Classea(ClassData *MyObs, String ToVar, String args, String argtypes = "VV");
virtual void doFunc(long Line);
}
Header discussion
The class constructor always has the same number of arquments. The first 'MyObs' is the class describing the input data file. Next is the class describing the variable generated by the filter. The string 'args' holds the parameter string when the filter class is constructed and finally, a constant string describing the required parameters for the filter. In this case two variables consisting of 't' and 'rh'.
C++ Code
Classea::Classea(ClassData *MyObs, String ToVar, String args, String argtypes)
: Classfilter(MyObs, ToVar, args, argtypes) {
}
Constructor discussion
The only changes ever made to this section of the code is to the user selected class name.
void Classea::doFunc(long Obs, long Line){
Data[Vs-1][Obs][Line] = estar(Data[0][Obs][Line])* Data[1][Obs][Line]/100.0;
}
Function discussion
This part performs the filters work. The array 'Data' stores all the data read from the data input file plus any new variables generated by filters. The second index, 'Obs' indexes multiple observations for the interval. The third index, 'Line' is incremented every interval, i.e. for every data line read from the data file. The first index references the input filter parameter variables. Variables and constants are counted separately from zero beginning with the first parameter. For example for a filter class whose 'argtypes' is assigned 'VVCVC' the parameters would be accessed as myFilter(V0, V1, C0, V2, C1). A constant is accessed using Constants[0] etc. The filter output variable is always accessed using Data[Vs][Obs][Line]. It follows that this function implements:
$ea ea(t, rh) .
Wind height reference change
$u2 refwind(u, 2, 10, 1) this is a comment, where parameters are refwind(u, Z2, Zm, Ht)
Code
class Classrefwind : Classfilter {
public:
float Const; // result log((Z2 - d)/Z)/log((Zm - d)/Z)
Classrefwind(ClassData *MyObs, String ToVar, String args, String argtypes = "VCCC");
virtual void doFunc(long Line);
};
Classrefwind::Classrefwind(ClassData *MyObs, String ToVar, String args, String argtypes)
: Classfilter(MyObs, ToVar, args, argtypes) {
if(!Error) {
float d = Constants[2]*2.0/3.0; // zero plane
float Z = Constants[2]*0.123; // roughness
Const = log((Constants[1] - d)/Z)/log((Constants[0] - d)/Z);
}
}
void Classrefwind::doFunc(long Obs, long Line){
Data[Vs][Obs][Line] = Data[0][Obs][Line]* Const;
}
Comment
This example follows the pattern of the first example but has some extra features. Since the term log((Z2 - d)/Z)/log((Zm - d)/Z) is a constant and not dependent on the input data it needs only to be calculated once. It is calculated only once in the class constructor. The calculation of the constant is only made if the error checking boolean variable 'Error' is not true. This would be set if the end user had not assigned the filter parameters correctly and avoids divide by zero errors.