SatDump 2.0.0-alpha-520736c72
Loading...
Searching...
No Matches
generic_xrit_calibrator.h
1#pragma once
2
3#include "common/calibration.h"
4#include "nlohmann/json.hpp"
5#include "products/image/image_calibrator.h"
6#include "projection/thinplatespline.h"
7
8#include "logger.h"
9#include <utility>
10#include <vector>
11
12namespace satdump
13{
14 namespace xrit
15 {
16 class GenericxRITCalibrator : public satdump::products::ImageCalibrator
17 {
18 private:
19 nlohmann::json calib_cfg;
20 std::unordered_map<int, double> wavenumbers;
21 std::unordered_map<int, bool> calib_type_map;
22 std::unordered_map<int, int> new_max_val;
23 std::unordered_map<int, int> product_bit_depth;
24
25 std::unordered_map<int, std::pair<std::shared_ptr<satdump::projection::VizGeorefSpline2D>, std::unordered_map<int, float>>> lut_for_channels;
26
27 public:
28 GenericxRITCalibrator(satdump::products::ImageProduct *p, nlohmann::json c) : satdump::products::ImageCalibrator(p, c)
29 {
30 calib_cfg = d_cfg;
31 for (size_t i = 0; i < d_pro->images.size(); i++)
32 {
33 wavenumbers.emplace(d_pro->images[i].abs_index, d_pro->images[i].wavenumber);
34 calib_type_map.emplace(d_pro->images[i].abs_index, d_pro->images[i].calibration_type == CALIBRATION_ID_EMISSIVE_RADIANCE);
35
36 product_bit_depth.emplace(d_pro->images[i].abs_index, pow(2, d_pro->images[i].bit_depth) - 1);
37 if (!calib_cfg["bits_for_calib"][d_pro->images[i].channel_name].is_null())
38 new_max_val.emplace(d_pro->images[i].abs_index, pow(2, calib_cfg["bits_for_calib"][d_pro->images[i].channel_name].get<int>()) - 1);
39 else
40 new_max_val.emplace(d_pro->images[i].abs_index, product_bit_depth[d_pro->images[i].abs_index]);
41 }
42
43 for (size_t i = 0; i < d_pro->images.size(); i++)
44 {
45 try
46 {
47 if (calib_cfg.contains("to_complete") && calib_cfg["to_complete"].get<bool>())
48 {
49 std::vector<std::pair<int, float>> llut = calib_cfg[d_pro->images[i].channel_name];
50 std::shared_ptr<satdump::projection::VizGeorefSpline2D> spline = std::make_shared<satdump::projection::VizGeorefSpline2D>(1);
51 bool is_first = true;
52 for (auto &v : llut)
53 {
54 if (v.second != 0 || is_first)
55 {
56 double rp_v[1] = {v.second};
57 spline->add_point(v.first, v.first, rp_v);
58 is_first = false;
59 // logger->info("Point %d %f", v.first, v.second);
60 }
61 }
62
63 int s = spline->solve();
64 if (s != 3)
65 lut_for_channels.emplace(d_pro->images[i].abs_index,
66 std::pair<std::shared_ptr<satdump::projection::VizGeorefSpline2D>, std::unordered_map<int, float>>{nullptr, std::unordered_map<int, float>()});
67 else
68 lut_for_channels.emplace(d_pro->images[i].abs_index,
69 std::pair<std::shared_ptr<satdump::projection::VizGeorefSpline2D>, std::unordered_map<int, float>>{spline, std::unordered_map<int, float>()});
70 }
71 else
72 {
73 std::vector<std::pair<int, float>> llut = calib_cfg[d_pro->images[i].channel_name];
74 std::unordered_map<int, float> flut;
75 for (auto &v : llut)
76 flut.emplace(v.first, v.second);
77 lut_for_channels.emplace(d_pro->images[i].abs_index, std::pair<std::shared_ptr<satdump::projection::VizGeorefSpline2D>, std::unordered_map<int, float>>{nullptr, flut});
78 }
79 }
80 catch (std::exception &)
81 {
82 lut_for_channels.emplace(d_pro->images[i].abs_index,
83 std::pair<std::shared_ptr<satdump::projection::VizGeorefSpline2D>, std::unordered_map<int, float>>{nullptr, std::unordered_map<int, float>()});
84 }
85 }
86 }
87
88 double compute(int channel, int /*pos_x*/, int /*pos_y*/, uint32_t px_val)
89 {
90 if (new_max_val[channel] != product_bit_depth[channel])
91 px_val = double(px_val / (double)product_bit_depth[channel]) * new_max_val[channel];
92
93 try
94 {
95 if (calib_type_map[channel] == 0)
96 {
97 if (px_val == product_bit_depth[channel])
98 return CALIBRATION_INVALID_VALUE;
99 else if (lut_for_channels[channel].second.count(px_val))
100 return lut_for_channels[channel].second[px_val];
101 else if (lut_for_channels[channel].first)
102 {
103 double point = 0;
104 lut_for_channels[channel].first->get_point(px_val, px_val, &point);
105 return point;
106 }
107 else
108 return CALIBRATION_INVALID_VALUE;
109 }
110 else if (calib_type_map[channel]) // TODOREWORK? More calib types?
111 {
112 if (px_val == 0)
113 return CALIBRATION_INVALID_VALUE;
114 else if (lut_for_channels[channel].second.count(px_val))
115 return temperature_to_radiance(lut_for_channels[channel].second[px_val], wavenumbers[channel]);
116 else if (lut_for_channels[channel].first)
117 {
118 double point = 0;
119 lut_for_channels[channel].first->get_point(px_val, px_val, &point);
120 return temperature_to_radiance(point, wavenumbers[channel]);
121 }
122 else
123 return CALIBRATION_INVALID_VALUE;
124 }
125 else
126 return CALIBRATION_INVALID_VALUE;
127 }
128 catch (std::exception &)
129 {
130 return CALIBRATION_INVALID_VALUE;
131 }
132 }
133 };
134 } // namespace xrit
135} // namespace satdump
Definition image_calibrator.h:12
SatDump image product class.
Definition image_product.h:43