source: XIOS/trunk/src/filter/temporal_filter.cpp @ 1286

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

Backporting r1280 to trunk: adding a check on the field attributes freq_op and freq_offset and changing their default values.

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