commit a6a4e2fb795b1bfd39fac462c298cae60a30e819
parent a358fc2b83f1115474dc19add03ef494542d4d73
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 9 Dec 2022 16:11:34 +0100
planeto: add the htrdr_planeto_source_get_spectrum function
Diffstat:
2 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/src/planeto/htrdr_planeto_source.c b/src/planeto/htrdr_planeto_source.c
@@ -378,3 +378,72 @@ htrdr_planeto_source_does_radiance_vary_spectrally
ASSERT(source);
return source->per_wlen_radiances != NULL;
}
+
+res_T
+htrdr_planeto_source_get_spectrum
+ (const struct htrdr_planeto_source* source,
+ const double range[2], /* In nm. Limits are inclusive */
+ struct htrdr_planeto_source_spectrum* source_spectrum)
+{
+ double full_range[2];
+ res_T res = RES_OK;
+ ASSERT(source && range && source_spectrum && range[0] <= range[1]);
+
+ if(!htrdr_planeto_source_does_radiance_vary_spectrally(source)) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = htrdr_planeto_source_get_spectral_range(source, full_range);
+ if(res != RES_OK) goto error;
+
+ if(range[0] < full_range[0] || full_range[1] < range[1]) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ source_spectrum->range[0] = range[0];
+ source_spectrum->range[1] = range[1];
+
+ if(range[0] == range[1]) {
+ /* Degenerated spectral range */
+ source_spectrum->size = 1;
+ source_spectrum->buffer = NULL;
+
+ } else {
+ const source_radiance_T* spectrum;
+ const source_radiance_T* low;
+ const source_radiance_T* upp;
+ struct sbuf_desc desc;
+
+ res = sbuf_get_desc(source->per_wlen_radiances, &desc);
+ if(res != RES_OK) goto error;
+
+ spectrum = desc.buffer;
+ low = search_lower_bound(&range[0], spectrum, desc.size, desc.pitch, cmp_wlen);
+ upp = search_lower_bound(&range[1], spectrum, desc.size, desc.pitch, cmp_wlen);
+ ASSERT(low && upp);
+
+ if(low == upp) {
+ /* The range is fully included in a band */
+ ASSERT(low->radiance > range[0] && upp->radiance >= range[1]);
+ source_spectrum->size = 2;
+ source_spectrum->buffer = NULL;
+
+ } else {
+ source_spectrum->size =
+ 2/* Boundaries */ + (size_t)(upp - low)/*discrete items*/;
+
+ if(low->wavelength == range[0]) {
+ /* The lower limit coincide with a discrete element.
+ * Remove the discrete element */
+ source_spectrum->size -= 1;
+ }
+ }
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/planeto/htrdr_planeto_source.h b/src/planeto/htrdr_planeto_source.h
@@ -26,6 +26,13 @@ struct htrdr_planeto_source;
struct htrdr_planeto_source_args;
struct ssp_rng;
+struct htrdr_planeto_source_spectrum {
+ struct htrdr_planeto_source* source;
+ double range[2]; /* In nm. Limits are inclusive */
+ size_t size; /* Number of elements representing the spectrum */
+ void* buffer; /* Pointer toward the spectrum data */
+};
+
extern LOCAL_SYM res_T
htrdr_planeto_source_create
(struct htrdr_planeto* cmd,
@@ -76,4 +83,15 @@ extern LOCAL_SYM int
htrdr_planeto_source_does_radiance_vary_spectrally
(const struct htrdr_planeto_source* source);
+/* Get discrete spectrum data for a given range. If the boundaries of the
+ * spectral range do not coincide with a discrete element, their radiance is
+ * recovered from the htrdr_planeto_source_get_radiance function. Note that
+ * this function returns an error if the radiance from the source does not vary
+ * spectrally, that is, its radiance is recovered from a constant temperature */
+extern LOCAL_SYM res_T
+htrdr_planeto_source_get_spectrum
+ (const struct htrdr_planeto_source* source,
+ const double range[2], /* In nm. Limits are inclusive */
+ struct htrdr_planeto_source_spectrum* spectrum);
+
#endif /* HTRDR_PLANETO_SOURCE_H */