SatDump 2.0.0-alpha-520736c72
Loading...
Searching...
No Matches
image_product.h
Go to the documentation of this file.
1#pragma once
2
7
9#include "image/image.h"
10#include "product.h"
11#include "utils/stats.h"
12
13#include "common/physics_constants.h"
14#include "image/calibration_units.h" // TODOREWORK MOVE!!!! + Conversion
15
16// TODOREWORK MOVE
17#include "common/calibration.h"
18#include "utils/string.h"
19#include "utils/unit_parser.h"
20#include <string>
21
22namespace satdump
23{
24 namespace products
25 {
42 class ImageProduct : public Product
43 {
44 public:
45 enum channel_polarization_t
46 {
47 POL_NONE = 0,
48 POL_HORIZONTAL = 1,
49 POL_VERTICAL = 2,
50 POL_RHCP = 3,
51 POL_LHCP = 4,
52 POL_ANY = 99,
53 };
54
72 {
73 int abs_index = -1;
74 std::string filename;
75 std::string channel_name;
76 image::Image image;
77 int bit_depth = 16;
79 double wavenumber = -1;
80 channel_polarization_t polarization = POL_NONE;
81 double bandwidth = -1;
82 std::string calibration_type = "";
83 };
84
85 std::vector<ImageHolder> images;
86
87 bool save_as_matrix = false;
88
89 public:
94 void set_proj_cfg(nlohmann::json cfg)
95 {
96 contents["projection_cfg"] = cfg;
97 if (cfg.contains("tle") && cfg["tle"].contains("name"))
98 if (!has_product_source())
99 set_product_source(cfg["tle"]["name"]);
100 if (cfg.contains("timestamps") && !has_product_timestamp())
101 set_product_timestamp(get_median(cfg["timestamps"].get<std::vector<double>>()));
102 }
103
110 void set_proj_cfg_tle_timestamps(nlohmann::json cfg, nlohmann::json tle, nlohmann::json timestamps)
111 {
112 cfg["tle"] = tle;
113 cfg["timestamps"] = timestamps;
114 set_proj_cfg(cfg);
115 }
116
122 nlohmann::json get_proj_cfg(int channel)
123 {
124 // TODO CHANNEL SPECIFICS
125 auto cfg = contents["projection_cfg"];
126 if (channel != -1)
127 {
128 cfg["transform"] = get_channel_image(channel).ch_transform;
129 cfg["width"] = get_channel_image(channel).image.width();
130 cfg["height"] = get_channel_image(channel).image.height();
131 }
133 cfg["proj_timestamp"] = get_product_timestamp();
134 return cfg;
135 }
136
141 bool has_proj_cfg() { return contents.contains("projection_cfg"); }
142
143 public:
144 void set_calibration(std::string calibrator, nlohmann::json cfg)
145 {
146 contents["calibration"] = cfg;
147 contents["calibration"]["calibrator"] = calibrator;
148 }
149
150 std::pair<std::string, nlohmann::json> get_calibration() { return {contents["calibration"]["calibrator"], contents["calibration"]}; }
151
156 bool has_calibration() { return contents.contains("calibration"); }
157
158 // TODOREWORK DOCUMENT
159 nlohmann::json get_calibration_raw() { return contents.contains("calibration") ? contents["calibration"] : nlohmann::json(); }
160
161 public:
168 {
169 for (auto &img : images)
170 if (img.abs_index == index)
171 return img;
172 throw satdump_exception("Product Channel Index " + std::to_string(index) + " is not present!");
173 }
174
181 {
182 for (auto &img : images)
183 if (img.channel_name == name)
184 return img;
185 throw satdump_exception("Product Channel Name " + name + " is not present!");
186 }
187
198 channel_polarization_t polarization = POL_ANY, //
199 double bandwidth = -1, //
200 double freq_tolerance_percent = 5, //
201 double bw_tolerance_percent = 20)
202 {
203 double fbest = 1e40;
204 double fvalid_min = wavenumber * ((100. - freq_tolerance_percent) / 100.);
205 double fvalid_max = wavenumber * ((100. + freq_tolerance_percent) / 100.);
206
207 double bbest = 1e40;
208 double bvalid_min = bandwidth * ((100. - bw_tolerance_percent) / 100.);
209 double bvalid_max = bandwidth * ((100. + bw_tolerance_percent) / 100.);
210
211 ImageHolder *out = nullptr;
212 for (auto &img : images)
213 {
214 // Check pol
215 if (polarization != POL_ANY)
216 if (img.polarization != polarization)
217 continue;
218
219 // Check center freq and bandwidth
220 if (img.wavenumber != -1 && //
221 fbest > abs(img.wavenumber - wavenumber) && //
222 fvalid_min <= img.wavenumber && //
223 img.wavenumber <= fvalid_max && //
224 (bandwidth == -1 || //
225 (bbest > abs(img.bandwidth - bandwidth) && //
226 bvalid_min <= img.bandwidth && //
227 img.bandwidth <= bvalid_max)))
228 {
229 out = &img;
230 fbest = abs(img.wavenumber - wavenumber);
231 bbest = abs(img.bandwidth - bandwidth);
232 }
233 }
234 if (out == nullptr)
235 throw satdump_exception("Product Channel Close to Wavelength " + std::to_string(wavenumber) + " is not present!");
236 return *out;
237 }
238
246 {
247 double freq = 0;
248 channel_polarization_t polarization = POL_ANY;
249 double bw = -1;
250 double freq_tolerance_percent = 5;
251 double bw_tolerance_percent = 20;
252
253 // Parse the token
254 auto parts = splitString(str, ',');
255 if (parts.size() == 0)
256 parts = {str};
257
259 // Format is : {Freq,Pol,Bandwidth,FreqTol,BwTol}
261
262 if (parseUnitFromString(parts[0], freq, UNIT_METER))
263 freq = freq_to_wavenumber(SPEED_OF_LIGHT_M_S / freq);
264 else if (parseUnitFromString(parts[0], freq, UNIT_HERTZ))
265 freq = freq_to_wavenumber(freq);
266 else
267 throw satdump_exception("Couldn't parse frequency unit and value from " + str);
268
269 if (parts.size() >= 2)
270 {
271 if (parts[1] == "N")
272 polarization = ImageProduct::POL_NONE;
273 else if (parts[1] == "H")
274 polarization = ImageProduct::POL_HORIZONTAL;
275 else if (parts[1] == "V")
276 polarization = ImageProduct::POL_VERTICAL;
277 else if (parts[1] == "R")
278 polarization = ImageProduct::POL_RHCP;
279 else if (parts[1] == "L")
280 polarization = ImageProduct::POL_LHCP;
281 else if (parts[1] == "*")
282 polarization = ImageProduct::POL_ANY;
283 else
284 throw satdump_exception("Invalid polarization " + parts[1] + " in token \"" + str + "\"");
285 }
286
287 if (parts.size() >= 3)
288 {
289 if (parseUnitFromString(parts[2], bw, UNIT_METER))
290 bw = SPEED_OF_LIGHT_M_S / bw;
291 else if (parseUnitFromString(parts[2], bw, UNIT_HERTZ))
292 ;
293 else
294 throw satdump_exception("Couldn't parse bandwidth unit and value from " + str);
295 }
296
297 if (parts.size() >= 4)
298 freq_tolerance_percent = std::stod(parts[3]);
299
300 if (parts.size() >= 5)
301 bw_tolerance_percent = std::stod(parts[4]);
302
303 return get_channel_image_by_specifications(freq, polarization, bw, freq_tolerance_percent, bw_tolerance_percent);
304 }
305
311 int get_channel_image_idx(std::string name)
312 {
313 for (int i = 0; i < (int)images.size(); i++)
314 if (images[i].channel_name == name)
315 return i;
316 throw satdump_exception("Product Channel Name " + name + " is not present!");
317 }
318
325 inline int get_raw_channel_val(int idx, int x, int y)
326 {
327 auto &i = images[idx];
328 int depth_diff = i.bit_depth - i.image.depth();
329 if (depth_diff > 0)
330 return i.image.get(0, x, y) << depth_diff;
331 else
332 return i.image.get(0, x, y) >> -depth_diff;
333 }
334
340 void set_channel_wavenumber(int index, double wavenumber)
341 {
342 for (auto &img : images)
343 if (img.abs_index == index)
344 {
345 img.wavenumber = wavenumber;
346 return;
347 }
348 throw satdump_exception("Product Channel Index " + std::to_string(index) + " is not present!");
349 }
350
356 void set_channel_frequency(int index, double frequency) { set_channel_wavenumber(index, freq_to_wavenumber(frequency)); }
357
363 double get_channel_wavenumber(int index)
364 {
365 for (auto &img : images)
366 if (img.abs_index == index)
367 return img.wavenumber;
368 throw satdump_exception("Product Channel Index " + std::to_string(index) + " is not present!");
369 }
370
376 double get_channel_frequency(int index) { return wavenumber_to_freq(get_channel_wavenumber(index)); }
377
383 void set_channel_polarization(int index, channel_polarization_t polarization)
384 {
385 for (auto &img : images)
386 if (img.abs_index == index)
387 {
388 img.polarization = polarization;
389 return;
390 }
391 throw satdump_exception("Product Channel Index " + std::to_string(index) + " is not present!");
392 }
393
399 double get_channel_polarization(int index)
400 {
401 for (auto &img : images)
402 if (img.abs_index == index)
403 return img.polarization;
404 throw satdump_exception("Product Channel Index " + std::to_string(index) + " is not present!");
405 }
406
414 void set_channel_bandwidth(int index, double bandwidth)
415 {
416 for (auto &img : images)
417 if (img.abs_index == index)
418 {
419 img.bandwidth = bandwidth;
420 return;
421 }
422 throw satdump_exception("Product Channel Index " + std::to_string(index) + " is not present!");
423 }
424
430 double get_channel_bandwidth(int index)
431 {
432 for (auto &img : images)
433 if (img.abs_index == index)
434 return img.bandwidth;
435 throw satdump_exception("Product Channel Index " + std::to_string(index) + " is not present!");
436 }
437
444 void set_channel_unit(int index, std::string type_or_unit)
445 {
446 // TODOREWORK, may want to enforce unit automatically?
447 for (auto &img : images)
448 if (img.abs_index == index)
449 {
450 img.calibration_type = type_or_unit;
451 return;
452 }
453 throw satdump_exception("Product Channel Index " + std::to_string(index) + " is not present!");
454 }
455
456 public:
457 bool d_no_not_save_images = false;
458 bool d_no_not_load_images = false;
459
460 public:
461 virtual void save(std::string directory);
462 virtual void load(std::string file);
463
464 ImageProduct() { type = "image"; }
465 virtual ~ImageProduct();
466 };
467 } // namespace products
468} // namespace satdump
Class handling 2D transforms, mainly intended for image channels. This covers a simple but pretty imp...
Definition channel_transform.h:39
ChannelTransform & init_none()
Initialize a NONE transform.
Definition channel_transform.cpp:10
Definition image.h:17
size_t height() const
Returns image height.
Definition image.h:216
size_t width() const
Returns image width.
Definition image.h:210
SatDump image product class.
Definition image_product.h:43
double get_channel_wavenumber(int index)
Get channel wavenumber.
Definition image_product.h:363
void set_channel_polarization(int index, channel_polarization_t polarization)
Set channel polarization.
Definition image_product.h:383
void set_channel_unit(int index, std::string type_or_unit)
Set channel calibration unit.
Definition image_product.h:444
bool has_calibration()
Check if calibration info is present.
Definition image_product.h:156
void set_channel_bandwidth(int index, double bandwidth)
Set channel bandwidth in Hz. Can also represent a visible interval (eg, 0.55 um to 0....
Definition image_product.h:414
ImageHolder & get_channel_image_by_unitstr(std::string str)
Get image channel by unit string. Returns the closest one See documentation page "Image Product Expre...
Definition image_product.h:245
virtual void load(std::string file)
Load the product. This should refer to the product.cbor file.
Definition image_product.cpp:83
void set_channel_wavenumber(int index, double wavenumber)
Set channel wavenumber.
Definition image_product.h:340
int get_raw_channel_val(int idx, int x, int y)
Get raw channel count.
Definition image_product.h:325
double get_channel_frequency(int index)
Get channel frequency.
Definition image_product.h:376
bool has_proj_cfg()
Check if geo projection info is present.
Definition image_product.h:141
double get_channel_bandwidth(int index)
Get channel bandwidth in Hz.
Definition image_product.h:430
void set_channel_frequency(int index, double frequency)
Set channel frequency (internally, wavenumber)
Definition image_product.h:356
int get_channel_image_idx(std::string name)
Get image channel raw ID by name.
Definition image_product.h:311
double get_channel_polarization(int index)
Get channel polarization.
Definition image_product.h:399
ImageHolder & get_channel_image_by_specifications(double wavenumber, channel_polarization_t polarization=POL_ANY, double bandwidth=-1, double freq_tolerance_percent=5, double bw_tolerance_percent=20)
Get image channel by specifications. Returns the closest one.
Definition image_product.h:197
ImageHolder & get_channel_image(std::string name)
Get image channel by name.
Definition image_product.h:180
void set_proj_cfg_tle_timestamps(nlohmann::json cfg, nlohmann::json tle, nlohmann::json timestamps)
Set geo projection config in the product, with a TLE and timestamps.
Definition image_product.h:110
ImageHolder & get_channel_image(int index)
Get image channel by absolute ID.
Definition image_product.h:167
virtual void save(std::string directory)
Save the product. Depending on the type this will save a product.cbor and other files in the same dir...
Definition image_product.cpp:18
nlohmann::json get_proj_cfg(int channel)
Get geo projection config in the product, if present.
Definition image_product.h:122
void set_proj_cfg(nlohmann::json cfg)
Set geo projection config in the product.
Definition image_product.h:94
double get_product_timestamp()
Get the product timestamp.
Definition product.h:64
void set_product_source(std::string source)
Set product source, optional. This is meant to contextualize where this product is from,...
Definition product.h:70
void set_product_timestamp(double timestamp)
Set product timestamp, optional. This is usually the rough creation time / acquisition time.
Definition product.h:52
bool has_product_source()
Check if a product source is present.
Definition product.h:76
bool has_product_timestamp()
Check if a product timestamp is present.
Definition product.h:58
Core Image class.
Core Product implementation.
Math/Statistics functions.
A collection of string-related utility functions.
Struct holding both the image and some metadata.
Definition image_product.h:72
Utilities to help parse physical units.
const std::vector< UnitInfo > UNIT_METER
Unit declaration (to be used in parseUnitFromString) for Meters.
Definition unit_parser.h:28
const std::vector< UnitInfo > UNIT_HERTZ
Unit declaration (to be used in parseUnitFromString) for Hertz.
Definition unit_parser.h:48