File: timetickset.h

package info (click to toggle)
aoflagger 3.5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,000 kB
  • sloc: cpp: 67,891; python: 497; sh: 242; makefile: 22
file content (137 lines) | stat: -rw-r--r-- 4,209 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef TIME_TICK_SET_H
#define TIME_TICK_SET_H

#include "tickset.h"

#include "../../structures/date.h"

class TimeTickSet final : public TickSet {
 public:
  TimeTickSet(double minTime, double maxTime, unsigned sizeRequest)
      : _min(minTime), _max(maxTime), _sizeRequest(sizeRequest) {
    if (!std::isfinite(minTime) || !std::isfinite(maxTime))
      throw std::runtime_error("Invalid (non-finite) range in TimeTickSet");
    set(sizeRequest);
  }

  std::unique_ptr<TickSet> Clone() const override {
    return std::unique_ptr<TickSet>(new TimeTickSet(*this));
  }

  size_t Size() const override { return _ticks.size(); }

  Tick GetTick(size_t i) const override {
    double val = _ticks[i];
    return Tick((val - _min) / (_max - _min), Date::AipsMJDToTimeString(val));
  }

  void Reset() override {
    _ticks.clear();
    set(_sizeRequest);
  }

  void Set(size_t maxSize) override {
    _ticks.clear();
    set(maxSize);
  }
  double UnitToAxis(double unitValue) const override {
    return (unitValue - _min) / (_max - _min);
  }
  double AxisToUnit(double axisValue) const override {
    return axisValue * (_max - _min) + _min;
  }

 private:
  void set(size_t sizeRequest) {
    if (_max == _min) {
      _ticks.push_back(_min);
    } else {
      if (sizeRequest == 0) return;
      double tickWidth =
          calculateTickWidth((_max - _min) / (double)sizeRequest);
      if (tickWidth == 0.0 || !std::isfinite(tickWidth)) tickWidth = 1.0;
      double pos = roundUpToNiceNumber(_min, tickWidth);
      while (pos < _max) {
        _ticks.push_back(pos);
        pos += tickWidth;
      }
      while (_ticks.size() > sizeRequest) _ticks.pop_back();
    }
  }

  double calculateTickWidth(double lowerLimit) const {
    if (!std::isfinite(lowerLimit)) return lowerLimit;

    // number is in units of seconds

    if (lowerLimit >= 60.0 * 60.0 * 24.0) {  // In days?
      double width = 60.0 * 60.0 * 24.0;
      while (width < lowerLimit) width *= 2.0;
      return width;
    } else if (lowerLimit > 60.0 * 30.0) {  // in hours?
      if (lowerLimit <= 60.0 * 60.0) {
        return 60.0 * 60.0;  // hours
      } else if (lowerLimit <= 60.0 * 60.0 * 2.0) {
        return 60.0 * 60.0 * 2.0;  // two hours
      } else if (lowerLimit <= 60.0 * 60.0 * 3.0) {
        return 60.0 * 60.0 * 3.0;  // three hours
      } else if (lowerLimit <= 60.0 * 60.0 * 4.0) {
        return 60.0 * 60.0 * 4.0;  // four hours
      } else if (lowerLimit <= 60.0 * 60.0 * 6.0) {
        return 60.0 * 60.0 * 6.0;  // six hours
      } else {
        return 60.0 * 60.0 * 12.0;  // twelve hours
      }
    } else if (lowerLimit > 30.0) {  // in minutes?
      if (lowerLimit <= 60.0)
        return 60.0;  // in minutes
      else if (lowerLimit <= 60.0 * 2.0)
        return 60.0 * 2.0;  // two minutes
      else if (lowerLimit <= 60.0 * 5.0)
        return 60.0 * 5.0;  // five minutes
      else if (lowerLimit <= 60.0 * 10.0)
        return 60.0 * 10.0;  // ten minutes
      else if (lowerLimit <= 60.0 * 15.0)
        return 60.0 * 15.0;  // quarter hours
      else
        return 60.0 * 30.0;         // half hours
    } else if (lowerLimit > 0.5) {  // in seconds?
      if (lowerLimit <= 1.0)
        return 1.0;  // in seconds
      else if (lowerLimit <= 2.0)
        return 2.0;  // two seconds
      else if (lowerLimit <= 5.0)
        return 5.0;  // five seconds
      else if (lowerLimit <= 10.0)
        return 10.0;  // ten seconds
      else if (lowerLimit <= 15.0)
        return 15.0;  // quarter minute
      else
        return 30.0;  // half a minute
    } else if (lowerLimit == 0.0) {
      return 0.0;
    } else {  // in 10th of seconds or lower?
      double factor = 1.0;
      while (lowerLimit <= 0.1 && std::isfinite(lowerLimit)) {
        factor *= 0.1;
        lowerLimit *= 10.0;
      }
      if (lowerLimit <= 0.2)
        return 0.2 * factor;
      else if (lowerLimit <= 0.5)
        return 0.5 * factor;
      else
        return factor;
    }
  }

  double roundUpToNiceNumber(double number, double roundUnit) {
    return roundUnit * std::ceil(number / roundUnit);
  }

  double _min, _max;
  size_t _sizeRequest;
  std::vector<double> _ticks;
};

#endif