SatDump 2.0.0-alpha-520736c72
Loading...
Searching...
No Matches
calib.h
Go to the documentation of this file.
1#pragma once
2
7
8#include "logger.h"
10#include "utils/string.h"
11#include "xrit/xrit_file.h"
12
13namespace satdump
14{
15 namespace xrit
16 {
29 inline void addCalibrationInfoFunc(satdump::products::ImageProduct &pro, ImageDataFunctionRecord *image_data_function_record, std::string channel, std::string instrument_id)
30 {
31 if (image_data_function_record)
32 {
33 if (instrument_id == "goesn_imager" && std::stoi(channel) > 0 && std::stoi(channel) <= 5)
34 {
35 const float goesn_imager_wavelength_table[5] = {
36 630, 3900, 6480, 10700, 13300,
37 };
38
39 pro.set_channel_wavenumber(pro.images.size() - 1, 1e7 / goesn_imager_wavelength_table[std::stoi(channel) - 1]);
40 }
41 else if (instrument_id == "abi" && channel.find_first_not_of("0123456789") == std::string::npos && std::stoi(channel) > 0 && std::stoi(channel) <= 16)
42 {
43 const float goes_abi_wavelength_table[16] = {
44 470, 640, 860, 1380, 1610, 2260, 3900, 6190, 6950, 7340, 8500, 9610, 10350, 11200, 12300, 13300,
45 };
46
47 pro.set_channel_wavenumber(pro.images.size() - 1, 1e7 / goes_abi_wavelength_table[std::stoi(channel) - 1]);
48 }
49 else if (instrument_id == "ahi" && std::stoi(channel) > 0 && std::stoi(channel) <= 16)
50 {
51 const float hima_ahi_wavelength_table[16] = {
52 470, 510, 640, 860, 1600, 2300, 3900, 6200, 6900, 7300, 8600, 9600, 10400, 11200, 12400, 13300,
53 };
54
55 pro.set_channel_wavenumber(pro.images.size() - 1, 1e7 / hima_ahi_wavelength_table[std::stoi(channel) - 1]);
56 }
57 else if (instrument_id == "ami")
58 {
59 double wavelength_nm = std::stod(channel.substr(2, channel.size() - 1)) * 100;
60 pro.set_channel_wavenumber(pro.images.size() - 1, 1e7 / wavelength_nm);
61 }
62 else
63 pro.set_channel_wavenumber(pro.images.size() - 1, -1);
64
65 // if (instrument_id == "ahi")
66 // printf("Channel %s\n%s\n", channel.c_str(), image_data_function_record->datas.c_str());
67
68 auto lines = splitString(image_data_function_record->datas, '\n');
69 if (lines.size() < 4)
70 {
71 lines = splitString(image_data_function_record->datas, '\r');
72 if (lines.size() < 4)
73 {
74 logger->error("Error parsing calibration info into lines!");
75 return;
76 }
77 }
78
79 // for (int i = 0; i < lines.size(); i++)
80 // logger->critical("%d => %s", i, lines[i].c_str());
81
82 if (lines[0].find("HALFTONE:=") != std::string::npos)
83 {
84 // GOES xRIT modes
85 if (instrument_id == "goesn_imager" || instrument_id == "abi")
86 {
87 if (lines[1] == "_NAME:=toa_lambertian_equivalent_albedo_multiplied_by_cosine_solar_zenith_angle")
88 {
89 std::vector<std::pair<int, float>> lut;
90 for (size_t i = 3; i < lines.size(); i++)
91 {
92 int val;
93 float valo;
94 if (sscanf(lines[i].c_str(), "%d:=%f", &val, &valo) == 2)
95 lut.push_back({val, valo});
96 }
97
98 nlohmann::json calib_cfg = pro.get_calibration_raw();
99
100 calib_cfg[channel] = lut;
101 pro.set_calibration("generic_xrit", calib_cfg);
102 pro.set_channel_unit(pro.images.size() - 1, CALIBRATION_ID_ALBEDO);
103 }
104 else if (lines[1] == "_NAME:=toa_brightness_temperature")
105 {
106 std::vector<std::pair<int, float>> lut;
107 for (size_t i = 3; i < lines.size(); i++)
108 {
109 int val;
110 float valo;
111 if (sscanf(lines[i].c_str(), "%d:=%f", &val, &valo) == 2)
112 lut.push_back({val, valo});
113 }
114
115 nlohmann::json calib_cfg = pro.get_calibration_raw();
116
117 calib_cfg[channel] = lut;
118 pro.set_calibration("generic_xrit", calib_cfg);
119 pro.set_channel_unit(pro.images.size() - 1, CALIBRATION_ID_EMISSIVE_RADIANCE);
120 }
121 }
122
123 // GK-2A xRIT modes
124 if (instrument_id == "ami")
125 {
126 int bits_for_calib = 8;
127 if (lines[0].find("HALFTONE:=9") != std::string::npos)
128 bits_for_calib = 9;
129 else if (lines[0].find("HALFTONE:=10") != std::string::npos)
130 bits_for_calib = 10;
131 else if (lines[0].find("HALFTONE:=11") != std::string::npos)
132 bits_for_calib = 11;
133 else if (lines[0].find("HALFTONE:=12") != std::string::npos)
134 bits_for_calib = 12;
135 else if (lines[0].find("HALFTONE:=13") != std::string::npos)
136 bits_for_calib = 13;
137 else if (lines[0].find("HALFTONE:=14") != std::string::npos)
138 bits_for_calib = 14;
139
140 if (lines[2] == "_UNIT:=ALBEDO(%)")
141 {
142 std::vector<std::pair<int, float>> lut;
143 for (size_t i = 3; i < lines.size(); i++)
144 {
145 int val;
146 float valo;
147 if (sscanf(lines[i].c_str(), "%d:=%f", &val, &valo) == 2)
148 lut.push_back({val, valo / 100.0});
149 }
150
151 nlohmann::json calib_cfg = pro.get_calibration_raw();
152
153 calib_cfg["bits_for_calib"][channel] = bits_for_calib;
154 calib_cfg["to_complete"] = true;
155
156 calib_cfg[channel] = lut;
157 pro.set_calibration("generic_xrit", calib_cfg);
158 pro.set_channel_unit(pro.images.size() - 1, CALIBRATION_ID_ALBEDO);
159 }
160 else if (lines[2] == "_UNIT:=KELVIN")
161 {
162 std::vector<std::pair<int, float>> lut;
163 for (size_t i = 3; i < lines.size(); i++)
164 {
165 int val;
166 float valo;
167 if (sscanf(lines[i].c_str(), "%d:=%f", &val, &valo) == 2)
168 lut.push_back({val, valo});
169 }
170
171 nlohmann::json calib_cfg = pro.get_calibration_raw();
172
173 calib_cfg["bits_for_calib"][channel] = bits_for_calib;
174 calib_cfg["to_complete"] = true;
175
176 calib_cfg[channel] = lut;
177 pro.set_calibration("generic_xrit", calib_cfg);
178 pro.set_channel_unit(pro.images.size() - 1, CALIBRATION_ID_EMISSIVE_RADIANCE);
179 }
180 }
181
182 // Himawari xRIT modes
183 if (instrument_id == "ahi")
184 {
185 int bits_for_calib = 8;
186 bool lut_has_1023 = false, lut_has_4095 = false, lut_has_16383 = false;
187 if (lines[2].find("_UNIT:=PERCENT") != std::string::npos || lines[2].find("_UNIT:=ALBEDO(%)") != std::string::npos)
188 {
189 std::vector<std::pair<int, float>> lut;
190 for (size_t i = 3; i < lines.size(); i++)
191 {
192 int val;
193 float valo;
194 if (sscanf(lines[i].c_str(), "%d:=%f", &val, &valo) == 2)
195 {
196 lut.push_back({val, valo / 100.0});
197 lut_has_1023 |= (val == 1023);
198 lut_has_4095 |= (val == 4095);
199 lut_has_16383 |= (val == 16383);
200 }
201 }
202
203 if (lut_has_1023)
204 bits_for_calib = 10;
205 if (lut_has_4095)
206 bits_for_calib = 12;
207 if (lut_has_16383)
208 bits_for_calib = 14;
209
210 nlohmann::json calib_cfg = pro.get_calibration_raw();
211
212 calib_cfg["bits_for_calib"][channel] = bits_for_calib;
213 calib_cfg["to_complete"] = true;
214
215 calib_cfg[channel] = lut;
216 pro.set_calibration("generic_xrit", calib_cfg);
217 pro.set_channel_unit(pro.images.size() - 1, CALIBRATION_ID_ALBEDO);
218 }
219 else if (lines[2].find("_UNIT:=KELVIN") != std::string::npos)
220 {
221 std::vector<std::pair<int, float>> lut;
222 for (size_t i = 3; i < lines.size(); i++)
223 {
224 int val;
225 float valo;
226 if (sscanf(lines[i].c_str(), "%d:=%f", &val, &valo) == 2)
227 {
228 lut.push_back({val, valo});
229 lut_has_1023 |= (val == 1023);
230 lut_has_4095 |= (val == 4095);
231 lut_has_16383 |= (val == 16383);
232 }
233 }
234
235 if (lut_has_1023)
236 bits_for_calib = 10;
237 if (lut_has_4095)
238 bits_for_calib = 12;
239 if (lut_has_16383)
240 bits_for_calib = 14;
241
242 nlohmann::json calib_cfg = pro.get_calibration_raw();
243
244 calib_cfg["bits_for_calib"][channel] = bits_for_calib;
245 calib_cfg["to_complete"] = true;
246
247 calib_cfg[channel] = lut;
248 pro.set_calibration("generic_xrit", calib_cfg);
249 pro.set_channel_unit(pro.images.size() - 1, CALIBRATION_ID_EMISSIVE_RADIANCE);
250 }
251 }
252 }
253 }
254 }
255 } // namespace xrit
256} // namespace satdump
void addCalibrationInfoFunc(satdump::products::ImageProduct &pro, ImageDataFunctionRecord *image_data_function_record, std::string channel, std::string instrument_id)
Most xRIT missions use the standard calibration header. This function parses it to insert calibration...
Definition calib.h:29
SatDump image product class.
Definition image_product.h:43
void set_channel_unit(int index, std::string type_or_unit)
Set channel calibration unit.
Definition image_product.h:444
void set_channel_wavenumber(int index, double wavenumber)
Set channel wavenumber.
Definition image_product.h:340
ImageProduct implementation.
A collection of string-related utility functions.