source: XIOS/dev/XIOS_DEV_CMIP6/src/filter/temporal_filter.cpp @ 1473

Last change on this file since 1473 was 1473, checked in by oabramkina, 3 years ago

DEV_CMIP6: bugfix for certain cases of monthly output and freq_offset such as 1mo-2ts.

File size: 4.2 KB
Line 
1#include "temporal_filter.hpp"
2#include "functor_type.hpp"
3#include "calendar_util.hpp"
4
5namespace xios
6{
7  static func::CFunctor* createFunctor(const std::string& opId, bool ignoreMissingValue, CArray<double, 1>& tmpData);
8
9  CTemporalFilter::CTemporalFilter(CGarbageCollector& gc, const std::string& opId,
10                                   const CDate& initDate, const CDuration samplingFreq, const CDuration samplingOffset, const CDuration opFreq,
11                                   bool ignoreMissingValue /*= false*/)
12    : CFilter(gc, 1, this)
13    , functor(createFunctor(opId, ignoreMissingValue, tmpData))
14    , isOnceOperation(functor->timeType() == func::CFunctor::once)
15    , isInstantOperation(functor->timeType() == func::CFunctor::instant)
16    , samplingFreq(samplingFreq)
17    , samplingOffset(samplingOffset)
18    , opFreq(opFreq)
19    , offsetMonth(0, this->samplingOffset.month, 0, 0, 0, 0, 0)
20    , offsetAllButMonth(this->samplingOffset.year, 0 , this->samplingOffset.day,
21                        this->samplingOffset.hour, this->samplingOffset.minute,
22                        this->samplingOffset.second, this->samplingOffset.timestep)
23    , initDate(initDate)
24    , nextSamplingDate(initDate + (this->samplingOffset + initDate.getRelCalendar().getTimeStep()))
25    , nbOperationDates(1)
26    , nbSamplingDates(0)
27//    , nextOperationDate(initDate + opFreq + this->samplingOffset)
28    , isFirstOperation(true)
29  {
30  }
31
32  CDataPacketPtr CTemporalFilter::apply(std::vector<CDataPacketPtr> data)
33  {
34    CDataPacketPtr packet;
35
36    if (data[0]->status != CDataPacket::END_OF_STREAM)
37    {
38      bool usePacket, outputResult, copyLess;
39      if (isOnceOperation)
40        usePacket = outputResult = copyLess = isFirstOperation;
41      else
42      {
43        usePacket = (data[0]->date >= nextSamplingDate);
44//        outputResult = (data[0]->date + samplingFreq > nextOperationDate);
45        outputResult = (data[0]->date  > initDate + nbOperationDates*opFreq - samplingFreq + offsetMonth + offsetAllButMonth);
46        copyLess = (isInstantOperation && usePacket && outputResult);
47      }
48
49      if (usePacket)
50      {
51        nbSamplingDates ++;
52        if (!copyLess)
53        {
54          if (!tmpData.numElements())
55            tmpData.resize(data[0]->data.numElements());
56
57          (*functor)(data[0]->data);
58        }
59
60        nextSamplingDate = ((initDate + offsetMonth) + nbSamplingDates * samplingFreq) + offsetAllButMonth + initDate.getRelCalendar().getTimeStep();
61      }
62
63      if (outputResult)
64      {
65        nbOperationDates ++;
66        if (!copyLess)
67        {
68          functor->final();
69
70          packet = CDataPacketPtr(new CDataPacket);
71          packet->date = data[0]->date;
72          packet->timestamp = data[0]->timestamp;
73          packet->status = data[0]->status;
74          packet->data.resize(tmpData.numElements());
75          packet->data = tmpData;
76        }
77        else
78          packet = data[0];
79
80        isFirstOperation = false;
81//        nextOperationDate = initDate + samplingFreq + nbOperationDates*opFreq - samplingFreq + offsetMonth + offsetAllButMonth;
82      }
83    }
84
85    return packet;
86  }
87
88  bool CTemporalFilter::mustAutoTrigger() const
89  {
90    return true;
91  }
92
93  bool CTemporalFilter::isDataExpected(const CDate& date) const
94  {
95//    return isOnceOperation ? isFirstOperation : (date >= nextSamplingDate || date + samplingFreq > nextOperationDate);
96    return isOnceOperation ? isFirstOperation : (date >= nextSamplingDate || date > initDate + nbOperationDates*opFreq - samplingFreq + offsetMonth + offsetAllButMonth);
97  }
98
99  static func::CFunctor* createFunctor(const std::string& opId, bool ignoreMissingValue, CArray<double, 1>& tmpData)
100  {
101    func::CFunctor* functor = NULL;
102
103    double defaultValue = std::numeric_limits<double>::quiet_NaN();
104
105#define DECLARE_FUNCTOR(MType, mtype) \
106    if (opId.compare(#mtype) == 0) \
107    { \
108      if (ignoreMissingValue) \
109      { \
110        functor = new func::C##MType(tmpData, defaultValue); \
111      } \
112      else \
113      { \
114        functor = new func::C##MType(tmpData); \
115      } \
116    }
117
118#include "functor_type.conf"
119
120    if (!functor)
121      ERROR("createFunctor(const std::string& opId, ...)",
122            << "\"" << opId << "\" is not a valid operation.");
123
124    return functor;
125  }
126} // namespace xios
Note: See TracBrowser for help on using the repository browser.