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

Last change on this file since 1123 was 1123, checked in by rlacroix, 7 years ago

Instant filter: Optimize the sampling when it is easy to do so.

This way the "xios_field_is_active" function can provide more useful information for the current timestamp even if the user did not specify "freq_op" and "freq_offset".

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    // If we can optimize the sampling when dealing with an instant functor we do it
15    , samplingFreq((functor->timeType() == func::CFunctor::instant && samplingFreq == TimeStep && samplingOffset == NoneDu) ? opFreq : samplingFreq)
16    , samplingOffset((functor->timeType() == func::CFunctor::instant && samplingFreq == TimeStep && samplingOffset == NoneDu) ? opFreq - initDate.getRelCalendar().getTimeStep() : samplingOffset)
17    , opFreq(opFreq)
18    , nextSamplingDate(initDate + this->samplingOffset + initDate.getRelCalendar().getTimeStep())
19    , nextOperationDate(initDate + this->samplingOffset + opFreq)
20    , isFirstOperation(true)
21    , isOnceOperation(functor->timeType() == func::CFunctor::once)
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      const bool usePacket = isOnceOperation ? isFirstOperation : (data[0]->date >= nextSamplingDate);
32      if (usePacket)
33      {
34        if (!tmpData.numElements())
35          tmpData.resize(data[0]->data.numElements());
36
37        (*functor)(data[0]->data);
38
39        nextSamplingDate = nextSamplingDate + samplingFreq;
40      }
41
42      const bool outputResult = isOnceOperation ? isFirstOperation : (data[0]->date + samplingFreq > nextOperationDate);
43      if (outputResult)
44      {
45        functor->final();
46
47        packet = CDataPacketPtr(new CDataPacket);
48        packet->date = data[0]->date;
49        packet->timestamp = data[0]->timestamp;
50        packet->status = data[0]->status;
51        packet->data.resize(tmpData.numElements());
52        packet->data = tmpData;
53
54        isFirstOperation = false;
55        nextOperationDate = nextOperationDate + samplingFreq + opFreq - samplingFreq;
56      }
57    }
58
59    return packet;
60  }
61
62  bool CTemporalFilter::isDataExpected(const CDate& date) const
63  {
64    return isOnceOperation ? isFirstOperation : (date >= nextSamplingDate || date + samplingFreq > nextOperationDate);
65  }
66
67  static func::CFunctor* createFunctor(const std::string& opId, bool ignoreMissingValue, double missingValue, CArray<double, 1>& tmpData)
68  {
69    func::CFunctor* functor = NULL;
70
71    double defaultValue = ignoreMissingValue ? std::numeric_limits<double>::quiet_NaN() : missingValue;
72
73#define DECLARE_FUNCTOR(MType, mtype) \
74    if (opId.compare(#mtype) == 0) \
75    { \
76      if (ignoreMissingValue) \
77      { \
78        functor = new func::C##MType(tmpData, defaultValue); \
79      } \
80      else \
81      { \
82        functor = new func::C##MType(tmpData); \
83      } \
84    }
85
86#include "functor_type.conf"
87
88    if (!functor)
89      ERROR("createFunctor(const std::string& opId, ...)",
90            << "\"" << opId << "\" is not a valid operation.");
91
92    return functor;
93  }
94} // namespace xios
Note: See TracBrowser for help on using the repository browser.