data_observations_filter_writing (08/31/04)

CRHM Platform

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.