Tutorials

Under construction

Creating a new bias-corrector

A bias-correction scheme adjusts forecasts. The adjustment model has parameters that are estimated based on past data. The developer must write two functions: correct and updateParameters
 1 class Corrector : public Component {
 2    public:
 3       Corrector(const Options& iOptions, const Data& iData);
 4 
 5       void correct(const Parameters& iParameters, Ensemble& iEnsemble) const;
 6       void updateParameters(const std::vector<Ensemble>& iUnCorrected,
 7             const std::vector<Obs>& iObs,
 8             Parameters& iParameters) const;
 9       void getDefaultParameters(Parameters& iParameters) const;
10 
11       static Corrector* getScheme(const Options& rOptions, const Data& iData);
12       static Corrector* getScheme(const std::string& iTag, const Data& iData);
13       virtual bool isMemberSpecific() const;
14       //! Does this method need the input ensemble to be the same size everytime?
15       //! E.g. for parameter estimation
16       bool needsConstantEnsembleSize() const;
17    protected:
18       virtual void correctCore(const Parameters& iParameters, Ensemble& iEnsemble) const = 0;
19       virtual void getDefaultParametersCore(Parameters& iParameters) const {};
20       //! Default: Don't update
21       //! Guarantee: Number of ensembles and obs are the same
22       virtual void updateParametersCore(const std::vector<Ensemble>& iUnCorrected,
23             const std::vector<Obs>& iObs,
24             Parameters& iParameters) const {};
25       bool mMemberSpecific; ///< Does correction apply to each ensemble member separately?
26       bool mPoolParameters; ///< Are the same parameters used on different members?
27       bool mEnforceLimits;    ///< Should corrected value be forced to be within variables limits?
28    private:
29       void enforceLimits(Ensemble& iEnsemble) const;
30 }
The header file $COMPS/src/Correctors/New.h will contain:
 1 class CorrectorNew : public Corrector {
 2    public:
 3       CorrectorNew(const Options& iOptions, const Data& iData);
 4       bool isMemberSpecific() const;
 5    protected:
 6       void correctCore(const Parameters& iParameters, Ensemble& iEnsemble) const;
 7       void getDefaultParametersCore(Parameters& iParameters) const;
 8       void updateParametersCore(const std::vector<Ensemble>& iUnCorrected,
 9             const std::vector<Obs>& iObs,
10             Parameters& iParameters) const;
11 }
The implementation file $COMPS/src/Correctors/New.cpp will contain:
 1 // Specifies how to correct an ensemble given a set of parameters
 2 void CorrectorNew::correctCore(const Parameters& iParameters, Ensemble& iEnsemble) const {
 3    float correction = iParameters[0];
 4 
 5    // Correct each ensemble member
 6    for(int i = 0; i < iEnsemble.size(); i++) {
 7       // ... but only if the member is not missing
 8       if(Global::isValid(iEnsemble[i])) {
 9          iEnsemble[i] = iEnsemble[i] + correction;
10       }
11    }
12 }
13 
14 // Specifies how old parameters should be updated based on new information
15 void CorrectorNew::updateParametersCore(const Ensemble& iUnCorrected, const std::vector<Obs>& iObs,
16                                         Parameters& iParameters) const {
17    float ensMean = iUnCorrected.getMoment(1);
18    float error = iObs.getValue() - ensMean;
19    // Weighted average of the old parameter with the new evidence
20    iParameters[0] = combine(iParameters[0], error);
21 }