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

Last change on this file since 1282 was 1282, checked in by oabramkina, 7 years ago

Fixing a bug in case if freq_op is defined in months.

File size: 4.8 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, double missingValue, 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*/, double missingValue /*= 0.0*/)
12    : CFilter(gc, 1, this)
13    , functor(createFunctor(opId, ignoreMissingValue, missingValue, 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    , isFirstOperation(true)
25    , nextSamplingDate(initDate + initDate.getRelCalendar().getTimeStep() + this->samplingOffset)
26    , nextOperationDate(initDate + opFreq + this->samplingOffset)
27//    , nextOperationDate(initDate + opFreq + this->offsetMonth + this->offsetAllButMonth)
28    , nbSamplingDates(0)
29  {
30    if (offsetMonth != NoneDu && offsetAllButMonth != NoneDu)
31    {
32      nextOperationDate = initDate + opFreq + this->offsetMonth;
33//      nextSamplingDate = initDate + initDate.getRelCalendar().getTimeStep() + this->samplingOffset;
34      nextSamplingDate = initDate + this->offsetMonth + this->offsetAllButMonth;
35    }
36  }
37
38  CDataPacketPtr CTemporalFilter::apply(std::vector<CDataPacketPtr> data)
39  {
40    CDataPacketPtr packet;
41
42    if (data[0]->status != CDataPacket::END_OF_STREAM)
43    {
44      bool usePacket, outputResult, copyLess;
45      if (isOnceOperation)
46        usePacket = outputResult = copyLess = isFirstOperation;
47      else
48      {
49        usePacket = (data[0]->date >= nextSamplingDate);
50        outputResult = ((offsetMonth != NoneDu && offsetAllButMonth != NoneDu)
51                       ? (data[0]->date - offsetAllButMonth > nextOperationDate - samplingFreq)
52                       : (data[0]->date + samplingFreq > nextOperationDate));
53//        outputResult = (data[0]->date  > nextOperationDate - samplingFreq);
54        copyLess = (isInstantOperation && usePacket && outputResult);
55      }
56
57      if (usePacket)
58      {
59        if (!copyLess)
60        {
61          if (!tmpData.numElements())
62            tmpData.resize(data[0]->data.numElements());
63
64          (*functor)(data[0]->data);
65        }
66
67        if (offsetMonth != NoneDu && offsetAllButMonth != NoneDu)
68        {
69          nextSamplingDate = initDate + samplingFreq;
70          for (int i=0; i<(nbSamplingDates+1); i++)
71          {
72            nextSamplingDate = nextSamplingDate + samplingFreq;
73          }
74          nextSamplingDate = nextSamplingDate + offsetAllButMonth;
75        }
76        else
77          nextSamplingDate = nextSamplingDate + samplingFreq;
78
79        nbSamplingDates++;
80
81      }
82
83      if (outputResult)
84      {
85        if (!copyLess)
86        {
87          functor->final();
88
89          packet = CDataPacketPtr(new CDataPacket);
90          packet->date = data[0]->date;
91          packet->timestamp = data[0]->timestamp;
92          packet->status = data[0]->status;
93          packet->data.resize(tmpData.numElements());
94          packet->data = tmpData;
95        }
96        else
97          packet = data[0];
98
99        nextOperationDate = nextOperationDate + samplingFreq + opFreq - samplingFreq;
100        isFirstOperation = false;
101      }
102    }
103
104    return packet;
105  }
106
107  bool CTemporalFilter::isDataExpected(const CDate& date) const
108  {
109    return isOnceOperation ? isFirstOperation : (date >= nextSamplingDate || date + samplingFreq > nextOperationDate);
110  }
111
112  static func::CFunctor* createFunctor(const std::string& opId, bool ignoreMissingValue, double missingValue, CArray<double, 1>& tmpData)
113  {
114    func::CFunctor* functor = NULL;
115
116    double defaultValue = ignoreMissingValue ? std::numeric_limits<double>::quiet_NaN() : missingValue;
117
118#define DECLARE_FUNCTOR(MType, mtype) \
119    if (opId.compare(#mtype) == 0) \
120    { \
121      if (ignoreMissingValue) \
122      { \
123        functor = new func::C##MType(tmpData, defaultValue); \
124      } \
125      else \
126      { \
127        functor = new func::C##MType(tmpData); \
128      } \
129    }
130
131#include "functor_type.conf"
132
133    if (!functor)
134      ERROR("createFunctor(const std::string& opId, ...)",
135            << "\"" << opId << "\" is not a valid operation.");
136
137    return functor;
138  }
139} // namespace xios
Note: See TracBrowser for help on using the repository browser.