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

Last change on this file since 1358 was 1358, checked in by rlacroix, 6 years ago

Support reentrant workflows and workflows with temporal integration for fields read from files.

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