htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

commit 7f12e284a09db782df8ef36a4ffeeb11e53df8c8
parent e125e6b9d0e6d649e8abdd74892047d2b3972e9a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  6 Nov 2024 12:37:05 +0100

Merge branch 'release_0.11'

Diffstat:
M.gitignore | 22+++++++++++-----------
MMakefile | 375+++++++++++++++++++++++++++++++++----------------------------------------------
MREADME.md | 32+++++++++++++++++++-------------
Mconfig.mk | 153++++++++++++++++---------------------------------------------------------------
Mdoc/htrdr-atmosphere.1.in | 38+++++++++++++++++++-------------------
Mdoc/htrdr-combustion.1.in | 52++++++++++++++++++++++++++--------------------------
Mdoc/htrdr-image.5 | 16++++++++--------
Mdoc/htrdr-materials.5 | 16++++++++--------
Mdoc/htrdr-obj.5 | 16++++++++--------
Ddoc/htrdr-planeto.1.in | 610------------------------------------------------------------------------------
Adoc/htrdr-planets.1.in | 648+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/htrdr.1 | 16++++++++--------
Mdoc/rnrl.5 | 16++++++++--------
Dhtrdr-planeto.pc.in | 18------------------
Ahtrdr-planets.pc.in | 18++++++++++++++++++
Ainstall.sh | 44++++++++++++++++++++++++++++++++++++++++++++
Dmake.sh | 47-----------------------------------------------
Msrc/atmosphere/htrdr_atmosphere.c | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere.h | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_args.c | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_args.h.in | 12++++++------
Msrc/atmosphere/htrdr_atmosphere_c.h | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_compute_radiance_lw.c | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_compute_radiance_sw.c | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_draw_map.c | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_ground.c | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_ground.h | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_main.c | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_sun.c | 16++++++++--------
Msrc/atmosphere/htrdr_atmosphere_sun.h | 16++++++++--------
Msrc/combustion/htrdr_combustion.c | 16++++++++--------
Msrc/combustion/htrdr_combustion.h | 16++++++++--------
Msrc/combustion/htrdr_combustion_args.c | 16++++++++--------
Msrc/combustion/htrdr_combustion_args.h.in | 12++++++------
Msrc/combustion/htrdr_combustion_c.h | 16++++++++--------
Msrc/combustion/htrdr_combustion_compute_radiance_sw.c | 16++++++++--------
Msrc/combustion/htrdr_combustion_draw_map.c | 16++++++++--------
Msrc/combustion/htrdr_combustion_geometry_ray_filter.c | 16++++++++--------
Msrc/combustion/htrdr_combustion_geometry_ray_filter.h | 16++++++++--------
Msrc/combustion/htrdr_combustion_laser.c | 16++++++++--------
Msrc/combustion/htrdr_combustion_laser.h | 16++++++++--------
Msrc/combustion/htrdr_combustion_main.c | 16++++++++--------
Msrc/combustion/htrdr_combustion_phase_func.c | 16++++++++--------
Msrc/combustion/test_htrdr_combustion_laser.c | 16++++++++--------
Msrc/commands/htrdr_atmosphere_cmd.c | 16++++++++--------
Msrc/commands/htrdr_cmd.c | 28++++++++++++++--------------
Msrc/commands/htrdr_combustion_cmd.c | 16++++++++--------
Dsrc/commands/htrdr_planeto_cmd.c | 41-----------------------------------------
Asrc/commands/htrdr_planets_cmd.c | 41+++++++++++++++++++++++++++++++++++++++++
Msrc/core/htrdr.c | 16++++++++--------
Msrc/core/htrdr.h | 28++++++++++++++--------------
Msrc/core/htrdr_accum.h | 16++++++++--------
Msrc/core/htrdr_args.c | 20+++++++++++---------
Msrc/core/htrdr_args.h.in | 12++++++------
Msrc/core/htrdr_buffer.c | 16++++++++--------
Msrc/core/htrdr_buffer.h | 16++++++++--------
Msrc/core/htrdr_c.h | 16++++++++--------
Msrc/core/htrdr_draw_map.c | 16++++++++--------
Msrc/core/htrdr_draw_map.h | 16++++++++--------
Msrc/core/htrdr_geometry.c | 16++++++++--------
Msrc/core/htrdr_geometry.h | 16++++++++--------
Msrc/core/htrdr_interface.h | 16++++++++--------
Msrc/core/htrdr_log.c | 16++++++++--------
Msrc/core/htrdr_log.h | 16++++++++--------
Msrc/core/htrdr_materials.c | 16++++++++--------
Msrc/core/htrdr_materials.h | 16++++++++--------
Msrc/core/htrdr_ran_wlen_cie_xyz.c | 16++++++++--------
Msrc/core/htrdr_ran_wlen_cie_xyz.h | 16++++++++--------
Msrc/core/htrdr_ran_wlen_discrete.c | 16++++++++--------
Msrc/core/htrdr_ran_wlen_discrete.h | 16++++++++--------
Msrc/core/htrdr_ran_wlen_planck.c | 16++++++++--------
Msrc/core/htrdr_ran_wlen_planck.h | 16++++++++--------
Msrc/core/htrdr_rectangle.c | 16++++++++--------
Msrc/core/htrdr_rectangle.h | 16++++++++--------
Msrc/core/htrdr_sensor.h | 16++++++++--------
Msrc/core/htrdr_slab.c | 16++++++++--------
Msrc/core/htrdr_slab.h | 16++++++++--------
Msrc/core/htrdr_spectral.c | 16++++++++--------
Msrc/core/htrdr_spectral.h | 16++++++++--------
Msrc/core/htrdr_version.h.in | 12++++++------
Dsrc/planeto/htrdr_planeto.c | 595-------------------------------------------------------------------------------
Dsrc/planeto/htrdr_planeto.h | 61-------------------------------------------------------------
Dsrc/planeto/htrdr_planeto_args.c | 734-------------------------------------------------------------------------------
Dsrc/planeto/htrdr_planeto_args.h.in | 148-------------------------------------------------------------------------------
Dsrc/planeto/htrdr_planeto_c.h | 127-------------------------------------------------------------------------------
Dsrc/planeto/htrdr_planeto_compute_radiance.c | 671-------------------------------------------------------------------------------
Dsrc/planeto/htrdr_planeto_draw_map.c | 457-------------------------------------------------------------------------------
Dsrc/planeto/htrdr_planeto_main.c | 91-------------------------------------------------------------------------------
Dsrc/planeto/htrdr_planeto_source.c | 491-------------------------------------------------------------------------------
Dsrc/planeto/htrdr_planeto_source.h | 116-------------------------------------------------------------------------------
Dsrc/planeto/test_htrdr_planeto_source.c | 302------------------------------------------------------------------------------
Asrc/planets/htrdr_planets.c | 595+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets.h | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets_args.c | 734+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets_args.h.in | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets_c.h | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets_compute_radiance.c | 671+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets_draw_map.c | 457+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets_main.c | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets_source.c | 491+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/htrdr_planets_source.h | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/planets/test_htrdr_planets_source.c | 302++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
102 files changed, 5340 insertions(+), 5453 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,18 +1,18 @@ -.gitignore -[Bb]uild* -*.sw[po] -*.[aod] -*.so *~ +*.[aod] +[Bb]uild* .config* -tags -*.pc -htrdr_*args.h -htrdr_version.h +.gitignore htrdr +htrdr_*args.h htrdr-atmosphere htrdr-atmosphere.1 htrdr-combustion htrdr-combustion.1 -htrdr-planeto -htrdr-planeto.1 +htrdr-planets +htrdr-planets.1 +htrdr_version.h +*.pc +*.so +*.sw[po] +tags diff --git a/Makefile b/Makefile @@ -1,12 +1,12 @@ -# Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +# Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique # Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -# Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -# Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -# Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -# Copyright (C) 2022-2023 Observatoire de Paris -# Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -# Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -# Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier +# Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +# Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +# Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +# Copyright (C) 2022-2024 Observatoire de Paris +# Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +# Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +# Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ include config.mk ATMOSPHERE_LIBNAME = libhtrdr-atmosphere.a COMBUSTION_LIBNAME = libhtrdr-combustion.a -PLANETO_LIBNAME = libhtrdr-planeto.a +PLANETS_LIBNAME = libhtrdr-planets.a PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./:$${PKG_CONFIG_PATH}" $(PKG_CONFIG) @@ -46,26 +46,25 @@ COMBUSTION_BUILD_LIB_ENABLE = build_combustion COMBUSTION_BUILD_CMD_ENABLE = build_htrdr_combustion COMBUSTION_LIBNAME_ENABLE = $(COMBUSTION_LIBNAME) -# Define macros when PLANETO is set to ENABLE -PLANETO_CFLAGS_ENABLE = $$($(PKG_CONFIG_LOCAL) --static --cflags htrdr-planeto) -PLANETO_LIBS_ENABLE = $$($(PKG_CONFIG_LOCAL) --static --libs htrdr-planeto) -PLANETO_BUILD_LIB_ENABLE = build_planeto -PLANETO_BUILD_CMD_ENABLE = build_htrdr_planeto -PLANETO_LIBNAME_ENABLE = $(PLANETO_LIBNAME) +# Define macros when PLANETS is set to ENABLE +PLANETS_CFLAGS_ENABLE = $$($(PKG_CONFIG_LOCAL) --static --cflags htrdr-planets) +PLANETS_LIBS_ENABLE = $$($(PKG_CONFIG_LOCAL) --static --libs htrdr-planets) +PLANETS_BUILD_LIB_ENABLE = build_planets +PLANETS_BUILD_CMD_ENABLE = build_htrdr_planets +PLANETS_LIBNAME_ENABLE = $(PLANETS_LIBNAME) # Default target all:\ build_htrdr\ build_htrdr_atmosphere\ build_htrdr_combustion\ - build_htrdr_planeto\ + build_htrdr_planets\ man # Check commands dependencies .config_commands: config.mk - @if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \ - echo "rsys $(RSYS_VERSION) not found" >&2; exit 1; fi - @echo "config done" > $@ + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + echo 'config done' > $@ # Inference rules for command build .SUFFIXES: .c .d .o @@ -87,27 +86,27 @@ HTRDR_DPDC_CFLAGS =\ $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags htrdr-core)\ $(ATMOSPHERE_CFLAGS_$(ATMOSPHERE))\ $(COMBUSTION_CFLAGS_$(COMBUSTION))\ - $(PLANETO_CFLAGS_$(PLANETO))\ + $(PLANETS_CFLAGS_$(PLANETS))\ $(RSYS_CFLAGS) HTRDR_DPDC_LIBS =\ $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs htrdr-core)\ $(ATMOSPHERE_LIBS_$(ATMOSPHERE))\ $(COMBUSTION_LIBS_$(COMBUSTION))\ - $(PLANETO_LIBS_$(PLANETO))\ + $(PLANETS_LIBS_$(PLANETS))\ $(RSYS_LIBS) HTRDR_DPDC_BUILD =\ build_core\ $(ATMOSPHERE_BUILD_LIB_$(ATMOSPHERE))\ $(COMBUSTION_BUILD_LIB_$(COMBUSTION))\ - $(PLANETO_BUILD_LIB_$(PLANETO)) + $(PLANETS_BUILD_LIB_$(PLANETS)) HTRDR_DPDC_PREREQ =\ $(CORE_LIBNAME)\ $(ATMOSPHERE_LIBNAME_$(ATMOSPHERE))\ $(COMBUSTION_LIBNAME_$(COMBUSTION))\ - $(PLANETO_LIBNAME_$(PLANETO)) + $(PLANETS_LIBNAME_$(PLANETS)) build_htrdr: .config_commands $(HTRDR_DPDC_BUILD) $(HTRDR_DEP) @$(MAKE) -fMakefile -f $(HTRDR_DEP) htrdr @@ -119,10 +118,8 @@ htrdr: config.mk $(HTRDR_OBJ) $(HTRDR_DPDC_PREREQ) $(HTRDR_OBJ) $(HTRDR_DEP): config.mk clean_htrdr: - rm -f $(HTRDR_OBJ) htrdr .config_commands - -distclean_htrdr: clean_htrdr - rm -f $(HTRDR_DEP) + rm -f htrdr $(HTRDR_OBJ) $(HTRDR_DEP) + rm -f .config_commands ################################################################################ # Build the htrdr-atmosphere command @@ -148,10 +145,8 @@ htrdr-atmosphere: config.mk $(HTRDR_ATMOSPHERE_OBJ) $(HTRDR_ATMOSPHERE_DPDC_PRER $(HTRDR_ATMOSPHERE_OBJ) $(HTRDR_ATMOSPHERE_DEP): config.mk clean_htrdr-atmosphere: - rm -f $(HTRDR_ATMOSPHERE_OBJ) htrdr-atmosphere - -distclean_htrdr-atmosphere: clean_htrdr-atmosphere - rm -f $(HTRDR_ATMOSPHERE_DEP) .config_commands + rm -f htrdr-atmosphere $(HTRDR_ATMOSPHERE_OBJ) $(HTRDR_ATMOSPHERE_DEP) + rm -f .config_commands ################################################################################ # Build the htrdr-combustion command @@ -177,39 +172,35 @@ htrdr-combustion: config.mk $(HTRDR_COMBUSTION_OBJ) $(HTRDR_COMBUSTION_DPDC_PRER $(HTRDR_COMBUSTION_OBJ) $(HTRDR_COMBUSTION_DEP): config.mk clean_htrdr-combustion: - rm -f $(HTRDR_COMBUSTION_OBJ) htrdr-combustion - -distclean_htrdr-combustion: clean_htrdr-combustion - rm -f $(HTRDR_COMBUSTION_DEP) .config_commands + rm -f htrdr-combustion $(HTRDR_COMBUSTION_OBJ) $(HTRDR_COMBUSTION_DEP) + rm -f .config_commands ################################################################################ -# Build the htrdr-planeto command +# Build the htrdr-planets command ################################################################################ -HTRDR_PLANETO_SRC = src/commands/htrdr_planeto_cmd.c -HTRDR_PLANETO_OBJ = $(HTRDR_PLANETO_SRC:.c=.o) -HTRDR_PLANETO_DEP = $(HTRDR_PLANETO_SRC:.c=.d) +HTRDR_PLANETS_SRC = src/commands/htrdr_planets_cmd.c +HTRDR_PLANETS_OBJ = $(HTRDR_PLANETS_SRC:.c=.o) +HTRDR_PLANETS_DEP = $(HTRDR_PLANETS_SRC:.c=.d) -HTRDR_PLANETO_DPDC_LIBS = $(PLANETO_LIBS_$(PLANETO)) -HTRDR_PLANETO_DPDC_BUILD = build_core $(PLANETO_BUILD_LIB_$(PLANETO)) -HTRDR_PLANETO_DPDC_PREREQ = $(CORE_LIBNAME) $(PLANETO_LIBNAME_$(PLANETO)) +HTRDR_PLANETS_DPDC_LIBS = $(PLANETS_LIBS_$(PLANETS)) +HTRDR_PLANETS_DPDC_BUILD = build_core $(PLANETS_BUILD_LIB_$(PLANETS)) +HTRDR_PLANETS_DPDC_PREREQ = $(CORE_LIBNAME) $(PLANETS_LIBNAME_$(PLANETS)) -build_htrdr_planeto:\ +build_htrdr_planets:\ .config_commands\ - $(HTRDR_PLANETO_DPDC_BUILD)\ - $(HTRDR_PLANETO_DEP) - @$(MAKE) -fMakefile -f $(HTRDR_PLANETO_DEP) htrdr-planeto + $(HTRDR_PLANETS_DPDC_BUILD)\ + $(HTRDR_PLANETS_DEP) + @$(MAKE) -fMakefile -f $(HTRDR_PLANETS_DEP) htrdr-planets -htrdr-planeto: config.mk $(HTRDR_PLANETO_OBJ) $(HTRDR_PLANETO_DPDC_PREREQ) +htrdr-planets: config.mk $(HTRDR_PLANETS_OBJ) $(HTRDR_PLANETS_DPDC_PREREQ) $(CC) $(CFLAGS_EXE) $(HTRDR_DPDC_CFLAGS) -o $@ \ - $(HTRDR_PLANETO_OBJ) $(LDFLAGS_EXE) $(HTRDR_PLANETO_DPDC_LIBS) + $(HTRDR_PLANETS_OBJ) $(LDFLAGS_EXE) $(HTRDR_PLANETS_DPDC_LIBS) -$(HTRDR_PLANETO_OBJ) $(HTRDR_PLANETO_DEP): config.mk +$(HTRDR_PLANETS_OBJ) $(HTRDR_PLANETS_DEP): config.mk -clean_htrdr-planeto: - rm -f $(HTRDR_PLANETO_OBJ) htrdr-planeto - -distclean_htrdr-planeto: clean_htrdr-planeto - rm -f $(HTRDR_PLANETO_DEP) .config_commands +clean_htrdr-planets: + rm -f htrdr-planets $(HTRDR_PLANETS_OBJ) $(HTRDR_PLANETS_DEP) + rm -f .config_commands ################################################################################ # Building the core @@ -257,23 +248,15 @@ libhtrdr-core.o: $(CORE_OBJ) $(OBJCOPY) $(OCPFLAGS) $@ .config_core: config.mk - @if ! $(PKG_CONFIG) --atleast-version $(AW_VERSION) aw; then \ - echo "aw $(AW_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(MPI_VERSION) $(MPI_PC); then \ - echo "$(MPI_PC) $(MPI_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(MRUMTL_VERSION) mrumtl; then \ - echo "mrumtl $(MRUMTL_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \ - echo "rsys $(RSYS_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d; then \ - echo "s3d $(S3D_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SCAM_VERSION) scam; then \ - echo "scam $(SCAM_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SSF_VERSION) ssf; then \ - echo "ssf $(SSF_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp; then \ - echo "star-sp $(SSP_VERSION) not found" >&2; exit 1; fi - @echo "config done" > $@ + $(PKG_CONFIG) --atleast-version $(AW_VERSION) aw + $(PKG_CONFIG) --atleast-version $(MPI_VERSION) $(MPI_PC) + $(PKG_CONFIG) --atleast-version $(MRUMTL_VERSION) mrumtl + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d + $(PKG_CONFIG) --atleast-version $(SCAM_VERSION) scam + $(PKG_CONFIG) --atleast-version $(SSF_VERSION) ssf + $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp + echo 'config done' > $@ src/core/htrdr_args.h: config.mk src/core/htrdr_args.h.in sed -e 's/@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN@/$(HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN)/g' \ @@ -320,13 +303,10 @@ htrdr-core.pc: config.mk htrdr-core.pc.in $@.in > $@ clean_core: - rm -f $(CORE_OBJ) $(CORE_LIBNAME) libhtrdr-core.o - rm -f .config_core mobhtrdr-core.o htrdr-core.pc + rm -f $(CORE_LIBNAME) $(CORE_OBJ) $(CORE_DEP) + rm -f libhtrdr-core.o .config_core htrdr-core.pc rm -f src/core/htrdr_args.h src/core/htrdr_version.h -distclean_core: clean_core - rm -f $(CORE_DEP) - ################################################################################ # Building the atmosphere library ################################################################################ @@ -357,21 +337,14 @@ libhtrdr-atmosphere.o: $(ATMOSPHERE_OBJ) $(OBJCOPY) $(OCPFLAGS) $@ .config_atmosphere: config.mk - @if ! $(PKG_CONFIG) --atleast-version $(HTSKY_VERSION) htsky; then \ - echo "htsky $(HTSKY_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \ - echo "rsys $(RSYS_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d; then \ - echo "s3d $(S3D_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SCAM_VERSION) scam; then \ - echo "scam $(SCAM_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SSF_VERSION) ssf; then \ - echo "ssf $(SSF_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp; then \ - echo "star-sp $(SSP_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SVX_VERSION) svx; then \ - echo "svx $(SVX_VERSION) not found" >&2; exit 1; fi - @echo "config done" > $@ + $(PKG_CONFIG) --atleast-version $(HTSKY_VERSION) htsky + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d + $(PKG_CONFIG) --atleast-version $(SCAM_VERSION) scam + $(PKG_CONFIG) --atleast-version $(SSF_VERSION) ssf + $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp + $(PKG_CONFIG) --atleast-version $(SVX_VERSION) svx + echo 'config done' > $@ src/atmosphere/htrdr_atmosphere_args.h: config.mk src/atmosphere/htrdr_atmosphere_args.h.in sed -e 's/@HTRDR_ATMOSPHERE_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@/$(HTRDR_ATMOSPHERE_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD)/g' \ @@ -396,13 +369,10 @@ htrdr-atmosphere.pc: config.mk htrdr-atmosphere.pc.in $@.in > $@ clean_atmosphere: - rm -f $(ATMOSPHERE_OBJ) $(ATMOSPHERE_LIBNAME) + rm -f $(ATMOSPHERE_LIBNAME) $(ATMOSPHERE_OBJ) $(ATMOSPHERE_DEP) rm -f .config_atmosphere libhtrdr-atmosphere.o htrdr-atmosphere.pc rm -f src/atmosphere/htrdr_atmosphere_args.h -distclean_atmosphere: clean_atmosphere - rm -f $(ATMOSPHERE_DEP) - ################################################################################ # Building the combustion library ################################################################################ @@ -433,21 +403,14 @@ libhtrdr-combustion.o: $(COMBUSTION_OBJ) $(OBJCOPY) $(OCPFLAGS) $@ .config_combustion: config.mk - @if ! $(PKG_CONFIG) --atleast-version $(ATRSTM_VERSION) atrstm; then \ - echo "atrstm $(ATRSTM_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \ - echo "rsys $(RSYS_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d; then \ - echo "s3d $(S3D_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SCAM_VERSION) scam; then \ - echo "scam $(SCAM_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SSF_VERSION) ssf; then \ - echo "ssf $(SSF_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp; then \ - echo "star-sp $(SSP_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SVX_VERSION) svx; then \ - echo "svx $(SVX_VERSION) not found" >&2; exit 1; fi - @echo "config done" > $@ + $(PKG_CONFIG) --atleast-version $(ATRSTM_VERSION) atrstm + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d + $(PKG_CONFIG) --atleast-version $(SCAM_VERSION) scam + $(PKG_CONFIG) --atleast-version $(SSF_VERSION) ssf + $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp + $(PKG_CONFIG) --atleast-version $(SVX_VERSION) svx + echo 'config done' > $@ src/combustion/htrdr_combustion_args.h: config.mk src/combustion/htrdr_combustion_args.h.in sed -e 's/@HTRDR_COMBUSTION_ARGS_DEFAULT_LASER_FLUX_DENSITY@/$(HTRDR_COMBUSTION_ARGS_DEFAULT_LASER_FLUX_DENSITY)/g' \ @@ -476,75 +439,63 @@ htrdr-combustion.pc: config.mk htrdr-combustion.pc.in $@.in > $@ clean_combustion: - rm -f $(COMBUSTION_OBJ) $(COMBUSTION_LIBNAME) + rm -f $(COMBUSTION_LIBNAME) $(COMBUSTION_OBJ) $(COMBUSTION_DEP) rm -f .config_combustion libhtrdr-combustion.o htrdr-combustion.pc rm -f src/combustion/htrdr_combustion_args.h -distclean_combustion: clean_combustion - rm -f $(COMBUSTION_DEP) - ################################################################################ -# Building the planeto library +# Building the planets library ################################################################################ -PLANETO_LIBNAME = libhtrdr-planeto.a +PLANETS_LIBNAME = libhtrdr-planets.a -PLANETO_SRC =\ - src/planeto/htrdr_planeto.c\ - src/planeto/htrdr_planeto_args.c\ - src/planeto/htrdr_planeto_compute_radiance.c\ - src/planeto/htrdr_planeto_draw_map.c\ - src/planeto/htrdr_planeto_main.c\ - src/planeto/htrdr_planeto_source.c -PLANETO_OBJ = $(PLANETO_SRC:.c=.o) -PLANETO_DEP = $(PLANETO_SRC:.c=.d) +PLANETS_SRC =\ + src/planets/htrdr_planets.c\ + src/planets/htrdr_planets_args.c\ + src/planets/htrdr_planets_compute_radiance.c\ + src/planets/htrdr_planets_draw_map.c\ + src/planets/htrdr_planets_main.c\ + src/planets/htrdr_planets_source.c +PLANETS_OBJ = $(PLANETS_SRC:.c=.o) +PLANETS_DEP = $(PLANETS_SRC:.c=.d) -build_planeto: build_core .config_planeto htrdr-planeto.pc $(PLANETO_DEP) - @$(MAKE) -fMakefile $$(for i in $(PLANETO_DEP); do echo -f $${i}; done) \ - $(PLANETO_LIBNAME) +build_planets: build_core .config_planets htrdr-planets.pc $(PLANETS_DEP) + @$(MAKE) -fMakefile $$(for i in $(PLANETS_DEP); do echo -f $${i}; done) \ + $(PLANETS_LIBNAME) -$(PLANETO_DEP) $(PLANETO_OBJ): config.mk src/planeto/htrdr_planeto_args.h +$(PLANETS_DEP) $(PLANETS_OBJ): config.mk src/planets/htrdr_planets_args.h -$(PLANETO_LIBNAME): libhtrdr-planeto.o +$(PLANETS_LIBNAME): libhtrdr-planets.o $(AR) -rc $@ $? $(RANLIB) $@ -libhtrdr-planeto.o: $(PLANETO_OBJ) - $(LD) -r $(PLANETO_OBJ) -o $@ +libhtrdr-planets.o: $(PLANETS_OBJ) + $(LD) -r $(PLANETS_OBJ) -o $@ $(OBJCOPY) $(OCPFLAGS) $@ -.config_planeto: config.mk - @if ! $(PKG_CONFIG) --atleast-version $(RNATM_VERSION) rnatm; then \ - echo "rnatm $(RNATM_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(RNGRD_VERSION) rngrd; then \ - echo "rngrd $(RNGRD_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \ - echo "rsys $(RSYS_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d; then \ - echo "s3d $(S3D_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SBUF_VERSION) sbuf; then \ - echo "sbuf $(SBUF_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SCAM_VERSION) scam; then \ - echo "scam $(SCAM_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SSF_VERSION) ssf; then \ - echo "ssf $(SSF_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp; then \ - echo "star-sp $(SSP_VERSION) not found" >&2; exit 1; fi - @if ! $(PKG_CONFIG) --atleast-version $(SVX_VERSION) svx; then \ - echo "svx $(SVX_VERSION) not found" >&2; exit 1; fi - @echo "config done" > $@ - -src/planeto/htrdr_planeto_args.h: config.mk src/planeto/htrdr_planeto_args.h.in - sed -e 's/@HTRDR_PLANETO_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@/$(HTRDR_PLANETO_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD)/g' \ - -e 's/@HTRDR_PLANETO_ARGS_DEFAULT_GRID_DEFINITION_HINT@/$(HTRDR_PLANETO_ARGS_DEFAULT_GRID_DEFINITION_HINT)/g' \ +.config_planets: config.mk + $(PKG_CONFIG) --atleast-version $(RNATM_VERSION) rnatm + $(PKG_CONFIG) --atleast-version $(RNGRD_VERSION) rngrd + $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys + $(PKG_CONFIG) --atleast-version $(S3D_VERSION) s3d + $(PKG_CONFIG) --atleast-version $(SBUF_VERSION) sbuf + $(PKG_CONFIG) --atleast-version $(SCAM_VERSION) scam + $(PKG_CONFIG) --atleast-version $(SSF_VERSION) ssf + $(PKG_CONFIG) --atleast-version $(SSP_VERSION) star-sp + $(PKG_CONFIG) --atleast-version $(SVX_VERSION) svx + echo 'config done' > $@ + +src/planets/htrdr_planets_args.h: config.mk src/planets/htrdr_planets_args.h.in + sed -e 's/@HTRDR_PLANETS_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@/$(HTRDR_PLANETS_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD)/g' \ + -e 's/@HTRDR_PLANETS_ARGS_DEFAULT_GRID_DEFINITION_HINT@/$(HTRDR_PLANETS_ARGS_DEFAULT_GRID_DEFINITION_HINT)/g' \ $@.in > $@ -$(PLANETO_DEP): - @$(CC) $(CFLAGS_SO) $(PLANETO_DPDC_CFLAGS) -Isrc -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ +$(PLANETS_DEP): + @$(CC) $(CFLAGS_SO) $(PLANETS_DPDC_CFLAGS) -Isrc -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ -$(PLANETO_OBJ): - $(CC) $(CFLAGS_SO) $(PLANETO_DPDC_CFLAGS) -Isrc -DHTRDR_SHARED_BUILD -c $(@:.o=.c) -o $@ +$(PLANETS_OBJ): + $(CC) $(CFLAGS_SO) $(PLANETS_DPDC_CFLAGS) -Isrc -DHTRDR_SHARED_BUILD -c $(@:.o=.c) -o $@ -htrdr-planeto.pc: config.mk htrdr-planeto.pc.in +htrdr-planets.pc: config.mk htrdr-planets.pc.in sed -e 's/@VERSION@/$(VERSION)/g' \ -e 's/@RNATM_VERSION@/$(RNATM_VERSION)/g' \ -e 's/@RNGRD_VERSION@/$(RNGRD_VERSION)/g' \ @@ -557,18 +508,15 @@ htrdr-planeto.pc: config.mk htrdr-planeto.pc.in -e 's/@SVX_VERSION@/$(SVX_VERSION)/g' \ $@.in > $@ -clean_planeto: - rm -f $(PLANETO_OBJ) $(PLANETO_LIBNAME) - rm -f .config_planeto libhtrdr-planeto.o htrdr-planeto.pc - rm -f src/planeto/htrdr_planeto_args.h - -distclean_planeto: clean_planeto - rm -f $(PLANETO_DEP) +clean_planets: + rm -f $(PLANETS_LIBNAME) $(PLANETS_OBJ) $(PLANETS_DEP) + rm -f .config_planets libhtrdr-planets.o htrdr-planets.pc + rm -f src/planets/htrdr_planets_args.h ################################################################################ # Man pages ################################################################################ -man: doc/htrdr-atmosphere.1 doc/htrdr-combustion.1 doc/htrdr-planeto.1 +man: doc/htrdr-atmosphere.1 doc/htrdr-combustion.1 doc/htrdr-planets.1 doc/htrdr-atmosphere.1: doc/htrdr-atmosphere.1.in sed -e 's/@HTRDR_ATMOSPHERE_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@/$(HTRDR_ATMOSPHERE_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD)/g' \ @@ -614,7 +562,7 @@ doc/htrdr-combustion.1: doc/htrdr-combustion.1.in -e 's/@HTRDR_ARGS_DEFAULT_RECTANGLE_SZ@/$(HTRDR_ARGS_DEFAULT_RECTANGLE_SZ)/g'\ $@.in > $@ -doc/htrdr-planeto.1: doc/htrdr-planeto.1.in +doc/htrdr-planets.1: doc/htrdr-planets.1.in sed -e 's/@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN@/$(HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN)/g' \ -e 's/@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX@/$(HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX)/g' \ -e 's/@HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOCAL_DST@/$(HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOCAL_DST)/g' \ @@ -626,52 +574,52 @@ doc/htrdr-planeto.1: doc/htrdr-planeto.1.in -e 's/@HTRDR_ARGS_DEFAULT_IMG_WIDTH@/$(HTRDR_ARGS_DEFAULT_IMG_WIDTH)/g' \ -e 's/@HTRDR_ARGS_DEFAULT_IMG_HEIGHT@/$(HTRDR_ARGS_DEFAULT_IMG_HEIGHT)/g' \ -e 's/@HTRDR_ARGS_DEFAULT_IMG_SPP@/$(HTRDR_ARGS_DEFAULT_IMG_SPP)/g' \ - -e 's/@HTRDR_PLANETO_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@/$(HTRDR_PLANETO_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD)/g' \ - -e 's/@HTRDR_PLANETO_ARGS_DEFAULT_GRID_DEFINITION_HINT@/$(HTRDR_PLANETO_ARGS_DEFAULT_GRID_DEFINITION_HINT)/g' \ + -e 's/@HTRDR_PLANETS_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@/$(HTRDR_PLANETS_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD)/g' \ + -e 's/@HTRDR_PLANETS_ARGS_DEFAULT_GRID_DEFINITION_HINT@/$(HTRDR_PLANETS_ARGS_DEFAULT_GRID_DEFINITION_HINT)/g' \ $@.in > $@ clean_man: - rm -f doc/htrdr-atmosphere.1 doc/htrdr-combustion.1 doc/htrdr-planeto.1 + rm -f doc/htrdr-atmosphere.1 doc/htrdr-combustion.1 doc/htrdr-planets.1 ################################################################################ # Installation ################################################################################ install: all - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/bin" htrdr - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/bin" htrdr-atmosphere - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/bin" htrdr-combustion - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/bin" htrdr-planeto + @$(SHELL) install.sh 755 "$(DESTDIR)$(BINPREFIX)" htrdr + @$(SHELL) install.sh 755 "$(DESTDIR)$(BINPREFIX)" htrdr-atmosphere + @$(SHELL) install.sh 755 "$(DESTDIR)$(BINPREFIX)" htrdr-combustion + @$(SHELL) install.sh 755 "$(DESTDIR)$(BINPREFIX)" htrdr-planets @if [ "$(LIB_TYPE)" = "SHARED" ]; then \ - $(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib" $(CORE_LIBNAME_SHARED); fi - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/doc/htrdr" COPYING README.md - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man1" doc/htrdr.1 + $(SHELL) install.sh 755 "$(DESTDIR)$(LIBPREFIX)" $(CORE_LIBNAME_SHARED); fi + @$(SHELL) install.sh 644 "$(DESTDIR)$(DOCPREFIX)/htrdr" COPYING README.md + @$(SHELL) install.sh 644 "$(DESTDIR)$(MANPREFIX)/man1" doc/htrdr.1 @if [ "$(ATMOSPHERE)" = "ENABLE" ]; then \ - $(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man1" doc/htrdr-atmosphere.1; fi + $(SHELL) install.sh 644 "$(DESTDIR)$(MANPREFIX)/man1" doc/htrdr-atmosphere.1; fi @if [ "$(COMBUSTION)" = "ENABLE" ]; then \ - $(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man1" doc/htrdr-combustion.1; fi - @if [ "$(PLANETO)" = "ENABLE" ]; then \ - $(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man1" doc/htrdr-planeto.1; fi - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man5" doc/htrdr-image.5 - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man5" doc/htrdr-materials.5 - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man5" doc/htrdr-obj.5 - @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man5" doc/rnrl.5 + $(SHELL) install.sh 644 "$(DESTDIR)$(MANPREFIX)/man1" doc/htrdr-combustion.1; fi + @if [ "$(PLANETS)" = "ENABLE" ]; then \ + $(SHELL) install.sh 644 "$(DESTDIR)$(MANPREFIX)/man1" doc/htrdr-planets.1; fi + @$(SHELL) install.sh 644 "$(DESTDIR)$(MANPREFIX)/man5" doc/htrdr-image.5 + @$(SHELL) install.sh 644 "$(DESTDIR)$(MANPREFIX)/man5" doc/htrdr-materials.5 + @$(SHELL) install.sh 644 "$(DESTDIR)$(MANPREFIX)/man5" doc/htrdr-obj.5 + @$(SHELL) install.sh 644 "$(DESTDIR)$(MANPREFIX)/man5" doc/rnrl.5 uninstall: - rm -f "$(DESTDIR)$(PREFIX)/bin/htrdr" - rm -f "$(DESTDIR)$(PREFIX)/bin/htrdr-atmosphere" - rm -f "$(DESTDIR)$(PREFIX)/bin/htrdr-combustion" - rm -f "$(DESTDIR)$(PREFIX)/bin/htrdr-planeto" - rm -f "$(DESTDIR)$(PREFIX)/lib/$(CORE_LIBNAME_SHARED)" - rm -f "$(DESTDIR)$(PREFIX)/share/doc/htrdr/COPYING" - rm -f "$(DESTDIR)$(PREFIX)/share/doc/htrdr/README.md" - rm -f "$(DESTDIR)$(PREFIX)/share/man/man1/htrdr.1" - rm -f "$(DESTDIR)$(PREFIX)/share/man/man1/htrdr-atmosphere.1" - rm -f "$(DESTDIR)$(PREFIX)/share/man/man1/htrdr-combustion.1" - rm -f "$(DESTDIR)$(PREFIX)/share/man/man1/htrdr-planeto.1" - rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/htrdr-image.5" - rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/htrdr-materials.5" - rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/htrdr-obj.5" - rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/rnrl.5" + rm -f "$(DESTDIR)$(BINPREFIX)/htrdr" + rm -f "$(DESTDIR)$(BINPREFIX)/htrdr-atmosphere" + rm -f "$(DESTDIR)$(BINPREFIX)/htrdr-combustion" + rm -f "$(DESTDIR)$(BINPREFIX)/htrdr-planets" + rm -f "$(DESTDIR)$(LIBPREFIX)/$(CORE_LIBNAME_SHARED)" + rm -f "$(DESTDIR)$(DOCPREFIX)/htrdr/COPYING" + rm -f "$(DESTDIR)$(DOCPREFIX)/htrdr/README.md" + rm -f "$(DESTDIR)$(MANPREFIX)/man1/htrdr.1" + rm -f "$(DESTDIR)$(MANPREFIX)/man1/htrdr-atmosphere.1" + rm -f "$(DESTDIR)$(MANPREFIX)/man1/htrdr-combustion.1" + rm -f "$(DESTDIR)$(MANPREFIX)/man1/htrdr-planets.1" + rm -f "$(DESTDIR)$(MANPREFIX)/man5/htrdr-image.5" + rm -f "$(DESTDIR)$(MANPREFIX)/man5/htrdr-materials.5" + rm -f "$(DESTDIR)$(MANPREFIX)/man5/htrdr-obj.5" + rm -f "$(DESTDIR)$(MANPREFIX)/man5/rnrl.5" ################################################################################ # Miscellaneous targets @@ -680,30 +628,19 @@ clean:\ clean_htrdr\ clean_htrdr-atmosphere\ clean_htrdr-combustion\ - clean_htrdr-planeto\ + clean_htrdr-planets\ clean_atmosphere\ clean_combustion\ - clean_planeto\ + clean_planets\ clean_core\ clean_man -distclean:\ - distclean_htrdr\ - distclean_htrdr-atmosphere\ - distclean_htrdr-combustion\ - distclean_htrdr-planeto\ - distclean_atmosphere\ - distclean_combustion\ - distclean_planeto\ - distclean_core\ - clean_man - -lint: doc/htrdr-atmosphere.1 doc/htrdr-combustion.1 doc/htrdr-planeto.1 - shellcheck -o all make.sh +lint: doc/htrdr-atmosphere.1 doc/htrdr-combustion.1 doc/htrdr-planets.1 + shellcheck -o all install.sh mandoc -Tlint -Wall doc/htrdr.1 || [ $$? -le 1 ] mandoc -Tlint -Wall doc/htrdr-atmosphere.1 || [ $$? -le 1 ] mandoc -Tlint -Wall doc/htrdr-combustion.1 || [ $$? -le 1 ] - mandoc -Tlint -Wall doc/htrdr-planeto.1 || [ $$? -le 1 ] + mandoc -Tlint -Wall doc/htrdr-planets.1 || [ $$? -le 1 ] mandoc -Tlint -Wall doc/htrdr-image.5 || [ $$? -le 1 ] mandoc -Tlint -Wall doc/htrdr-materials.5 || [ $$? -le 1 ] mandoc -Tlint -Wall doc/htrdr-obj.5 || [ $$? -le 1 ] diff --git a/README.md b/README.md @@ -30,7 +30,7 @@ fields: external: a monochromatic laser sheet illuminates the inside of the combustion chamber for diagnostic purposes. -3. *Planetology*: takes into account the geometry of a "ground" of +3. *Planetary science*: takes into account the geometry of a "ground" of arbitrary shape, described by a triangular mesh, with the possibility of using an arbitrary number of materials. The radiative properties of a gas mixture must be provided on a tetrahedral mesh, using the @@ -75,13 +75,13 @@ that calculate the radiance are used for computing various quantities: (optional; required by ATMOSHPERE) - [ModRadUrb: MaTeriaL](https://gitlab.com/meso-star/mrumtl) - [Rad-Net ATMopshere](https://gitlab.com/meso-star/rnatm) - (optional; required by PLANETO) + (optional; required by PLANETS) - [Rad-Net GRounD](https://gitlab.com/meso-star/rngrd) - (optional; required by PLANETO) + (optional; required by PLANETS) - [RSys](https://gitlab.com/vaplv/rsys) - [Star 3D](https://gitlab.com/meso-star/star-3d) - [Star Buffer](https://gitlab.com/meso-star/star-buffer) - (optional; required by PLANETO) + (optional; required by PLANETS) - [Star Camera](https://gitlab.com/meso-star/star-camera) - [Star Scattering Functions](https://gitlab.com/meso-star/star-sf) - [Star SamPling](https://gitlab.com/meso-star/star-sp) @@ -95,6 +95,13 @@ Edit config.mk as needed, then run: ## Release notes +### Version 0.11 + +- Renamed `planeto` sub-command to `planets`. +- Fix typos in manual pages and formatting problems. +- Ensure correct default value for a camera. +- Correct error handling when parsing planeto input arguments. + ### Version 0.10 #### Use POSIX make as a build system @@ -376,19 +383,18 @@ CIE XYZ (i.e. regular image rendering), longwave or shortwave. ## Copyright notice -Copyright © 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +Copyright © 2018-2019, 2022-2024 Centre National de la Recherche Scientifique Copyright © 2020-2022 Institut Mines Télécom Albi-Carmaux -Copyright © 2022-2023 Institut Pierre-Simon Laplace -Copyright © 2022-2023 Institut de Physique du Globe de Paris -Copyright © 2018-2023 [|Méso|Star>](http://www.meso-star.com) (<contact@meso-star.com>) -Copyright © 2022-2023 Observatoire de Paris -Copyright © 2022-2023 Université de Reims Champagne-Ardenne -Copyright © 2022-2023 Université de Versaille Saint-Quentin -Copyright © 2018-2019, 2022-2023 Université Paul Sabatier +Copyright © 2022-2024 Institut Pierre-Simon Laplace +Copyright © 2022-2024 Institut de Physique du Globe de Paris +Copyright © 2018-2024 [|Méso|Star>](http://www.meso-star.com) (contact@meso-star.com) +Copyright © 2022-2024 Observatoire de Paris +Copyright © 2022-2024 Université de Reims Champagne-Ardenne +Copyright © 2022-2024 Université de Versaille Saint-Quentin +Copyright © 2018-2019, 2022-2024 Université Paul Sabatier ## License `htrdr` is free software released under the GPL v3+ license: GNU GPL version 3 or later. You are welcome to redistribute it under certain conditions; refer to the COPYING file for details. - diff --git a/config.mk b/config.mk @@ -1,9 +1,22 @@ VERSION_MAJOR = 0 -VERSION_MINOR = 10 +VERSION_MINOR = 11 VERSION_PATCH = 0 VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) + PREFIX = /usr/local +BINPREFIX = $(PREFIX)/bin +DOCPREFIX = $(PREFIX)/share/doc +INCPREFIX = $(PREFIX)/include +LIBPREFIX = $(PREFIX)/lib +MANPREFIX = $(PREFIX)/share/man + +# Define the features supported, i.e. the htrdr commands to be built. +# Any value other than ENABLE disables the corresponding functionality. +# So, simply comment on a feature to deactivate it. +ATMOSPHERE = ENABLE +COMBUSTION = ENABLE +PLANETS = ENABLE LIB_TYPE = SHARED #LIB_TYPE = STATIC @@ -14,13 +27,6 @@ BUILD_TYPE = RELEASE # MPI pkg-config file MPI_PC = ompi -# Define the features supported, i.e. the htrdr commands to be built. -# Any value other than ENABLE disables the corresponding functionality. -# So, simply comment on a feature to deactivate it. -ATMOSPHERE = ENABLE -COMBUSTION = ENABLE -PLANETO = ENABLE - ################################################################################ # Default argument values ################################################################################ @@ -54,9 +60,9 @@ HTRDR_COMBUSTION_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD = 1.0 HTRDR_COMBUSTION_ARGS_DEFAULT_GRID_DEFINITION_HINT = 256 HTRDR_COMBUSTION_ARGS_DEFAULT_WAVELENGTH = 532 -# Planeto -HTRDR_PLANETO_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD = 1 -HTRDR_PLANETO_ARGS_DEFAULT_GRID_DEFINITION_HINT = 512 +# Planets +HTRDR_PLANETS_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD = 1 +HTRDR_PLANETS_ARGS_DEFAULT_GRID_DEFINITION_HINT = 512 ################################################################################ # Tools @@ -76,144 +82,45 @@ PCFLAGS_STATIC = --static PCFLAGS = $(PCFLAGS_$(LIB_TYPE)) AW_VERSION = 2.1 -AW_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags aw) -AW_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs aw) - ATRSTM_VERSION = 0.1 -ATRSTM_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags atrstm) -ATRSTM_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs atrstm) - HTSKY_VERSION = 0.3 -HTSKY_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags htsky) -HTSKY_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs htsky) - MPI_VERSION = 2 -MPI_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags $(MPI_PC)) -MPI_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs $(MPI_PC)) - MRUMTL_VERSION = 0.2 -MRUMTL_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags mrumtl) -MRUMTL_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs mrumtl) - RNATM_VERSION = 0.1 -RNATM_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rnatm) -RNATM_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rnatm) - RNGRD_VERSION = 0.1 -RNGRD_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rngrd) -RNGRD_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rngrd) - RSYS_VERSION = 0.14 -RSYS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rsys) -RSYS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rsys) - S3D_VERSION = 0.10 -S3D_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags s3d) -S3D_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs s3d) - SBUF_VERSION = 0.1 -SBUF_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags sbuf) -SBUF_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs sbuf) - SCAM_VERSION = 0.2 -SCAM_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags scam) -SCAM_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs scam) - SSF_VERSION = 0.9 -SSF_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags ssf) -SSF_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs ssf) - SSP_VERSION = 0.14 -SSP_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags star-sp) -SSP_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs star-sp) - SVX_VERSION = 0.3 -SVX_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags svx) -SVX_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs svx) # Atmosphere ATMOSPHERE_DPDC_CFLAGS =\ - $(HTSKY_CFLAGS)\ - $(RSYS_CFLAGS)\ - $(S3D_CFLAGS)\ - $(SCAM_CFLAGS)\ - $(SSF_CFLAGS)\ - $(SSP_CFLAGS)\ - $(SVX_CFLAGS) + $$($(PKG_CONFIG) $(PCFLAGS) --cflags htsky rsys s3d scam ssf star-sp svx) ATMOSPHERE_DPDC_LIBS =\ - $(HTSKY_LIBS)\ - $(RSYS_LIBS)\ - $(S3D_LIBS)\ - $(SCAM_LIBS)\ - $(SSF_LIBS)\ - $(SSP_LIBS)\ - $(SVX_LIBS)\ - -lm + $$($(PKG_CONFIG) $(PCFLAGS) --libs htsky rsys s3d scam ssf star-sp svx) -lm # Combustion COMBUSTION_DPDC_CFLAGS =\ - $(ATRSTM_CFLAGS)\ - $(RSYS_CFLAGS)\ - $(S3D_CFLAGS)\ - $(SCAM_CFLAGS)\ - $(SSF_CFLAGS)\ - $(SSP_CFLAGS)\ - $(SVX_CFLAGS) + $$($(PKG_CONFIG) $(PCFLAGS) --cflags atrstm rsys s3d scam ssf star-sp svx) COMBUSTION_DPDC_LIBS =\ - $(ATRSTM_LIBS)\ - $(RSYS_LIBS)\ - $(S3D_LIBS)\ - $(SCAM_LIBS)\ - $(SSF_LIBS)\ - $(SSP_LIBS)\ - $(SVX_LIBS)\ - -lm + $$($(PKG_CONFIG) $(PCFLAGS) --libs atrstm rsys s3d scam ssf star-sp svx) -lm # Core CORE_DPDC_CFLAGS =\ - $(AW_CFLAGS)\ - $(MPI_CFLAGS)\ - $(MRUMTL_CFLAGS)\ - $(RSYS_CFLAGS)\ - $(S3D_CFLAGS)\ - $(SCAM_CFLAGS)\ - $(SSF_CFLAGS)\ - $(SSP_CFLAGS)\ + $$($(PKG_CONFIG) $(PCFLAGS) --cflags aw $(MPI_PC) mrumtl rsys s3d scam ssf star-sp)\ -fopenmp CORE_DPDC_LIBS =\ - $(AW_LIBS)\ - $(MPI_LIBS)\ - $(MRUMTL_LIBS)\ - $(RSYS_LIBS)\ - $(S3D_LIBS)\ - $(SCAM_LIBS)\ - $(SSF_LIBS)\ - $(SSP_LIBS)\ - -fopenmp\ - -lm - -# Planeto -PLANETO_DPDC_CFLAGS=\ - $(RNATM_CFLAGS)\ - $(RNGRD_CFLAGS)\ - $(RSYS_CFLAGS)\ - $(S3D_CFLAGS)\ - $(SBUF_CFLAGS)\ - $(SCAM_CFLAGS)\ - $(SSF_CFLAGS)\ - $(SSP_CFLAGS)\ - $(SVX_CFLAGS) -PLANETO_DPDC_LIBS=\ - $(RNATM_LIBS)\ - $(RNGRD_LIBS)\ - $(RSYS_LIBS)\ - $(S3D_LIBS)\ - $(SBUF_LIBS)\ - $(SCAM_LIBS)\ - $(SSF_LIBS)\ - $(SSP_LIBS)\ - $(SVX_LIBS)\ --lm + $$($(PKG_CONFIG) $(PCFLAGS) --libs aw $(MPI_PC) mrumtl rsys s3d scam ssf star-sp)\ + -fopenmp -lm + +# Planets +PLANETS_DPDC_CFLAGS=\ + $$($(PKG_CONFIG) $(PCFLAGS) --cflags rnatm rngrd rsys s3d sbuf scam ssf star-sp svx) +PLANETS_DPDC_LIBS=\ + $$($(PKG_CONFIG) $(PCFLAGS) --libs rnatm rngrd rsys s3d sbuf scam ssf star-sp svx) -lm ################################################################################ # Compilation options diff --git a/doc/htrdr-atmosphere.1.in b/doc/htrdr-atmosphere.1.in @@ -1,12 +1,12 @@ -.\" Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +.\" Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique .\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -.\" Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -.\" Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -.\" Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -.\" Copyright (C) 2022-2023 Observatoire de Paris -.\" Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -.\" Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -.\" Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier +.\" Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +.\" Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2022-2024 Observatoire de Paris +.\" Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +.\" Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +.\" Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier .\" .\" This program is free software: you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by @@ -20,7 +20,7 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. -.Dd October 4, 2023 +.Dd January 24, 2024 .Dt HTRDR-ATMOSPHERE 1 .Os .Sh NAME @@ -30,18 +30,18 @@ .Nm .Op Fl dfhRrv .Op Fl c Pa clouds -.Op Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt ... +.Op Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt No ... .Op Fl D Ar sun_azimuth , Ns Ar sun_elevation .Op Fl g Pa ground -.Op Fl i Ar image_opt Ns Op : Ns Ar image_opt ... +.Op Fl i Ar image_opt Ns Op : Ns Ar image_opt No ... .Op Fl M Pa materials .Op Fl m Pa mie .Op Fl n Ar sky_mtl .Op Fl O Pa cache .Op Fl o Pa output -.Op Fl P Ar ortho_camera_opt Ns Op : Ns Ar ortho_camera_opt ... -.Op Fl p Ar flux_sensor_opt Ns Op : Ns Ar flux_sensor_opt ... -.Op Fl s Ar spectral_opt Ns Op : Ns Ar spectral_opt ... +.Op Fl P Ar ortho_camera_opt Ns Op : Ns Ar ortho_camera_opt No ... +.Op Fl p Ar flux_sensor_opt Ns Op : Ns Ar flux_sensor_opt No ... +.Op Fl s Ar spectral_opt Ns Op : Ns Ar spectral_opt No ... .Op Fl T Ar optical_thickness .Op Fl t Ar threads_count .Op Fl V Ar x , Ns Ar y , Ns Ar z @@ -147,7 +147,7 @@ Optical properties of atmospheric gases saved in htgop format. Cloud properties saved in .Xr htcp 5 format. -.It Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt ... +.It Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt No ... Set up a pinhole or thin-lens perspective camera. .Pp The options for a perspective camera are as follows: @@ -239,7 +239,7 @@ Ground geometry saved in format. .It Fl h Display short help and exit. -.It Fl i Ar image_opt Ns Op : Ns Ar image_opt ... +.It Fl i Ar image_opt Ns Op : Ns Ar image_opt No ... Configure sensor image. .Pp The image options are as follows: @@ -310,7 +310,7 @@ ignores the options used to build acceleration structures .It Fl o Pa output Output file. If not defined, data is written to standard output. -.It Fl P Ar ortho_camera_opt Ns Op : Ns Ar ortho_camera_opt ... +.It Fl P Ar ortho_camera_opt Ns Op : Ns Ar ortho_camera_opt No ... Set up an orthographic camera. .Pp The options for an orthographic camera are as follows: @@ -330,7 +330,7 @@ Default is @HTRDR_ARGS_DEFAULT_CAMERA_TGT@. Upward vector that the top of the camera is pointing towards. Default is @HTRDR_ARGS_DEFAULT_CAMERA_UP@. .El -.It Fl p Ar flux_sensor_opt Ns Op : Ns Ar flux_sensor_opt ... +.It Fl p Ar flux_sensor_opt Ns Op : Ns Ar flux_sensor_opt No ... Set up a flux sensor. The flux is computed for the part of the sensor that is outside any geometry. @@ -350,7 +350,7 @@ Default is @HTRDR_ARGS_DEFAULT_RECTANGLE_UP@. Sensor size in meters. Default is @HTRDR_ARGS_DEFAULT_RECTANGLE_SZ@. .El -.It Fl s Ar spectral_opt Ns Op : Ns Ar spectral_opt ... +.It Fl s Ar spectral_opt Ns Op : Ns Ar spectral_opt No ... Configure spectral integration. .Pp The spectral integration options are as follows: diff --git a/doc/htrdr-combustion.1.in b/doc/htrdr-combustion.1.in @@ -1,12 +1,12 @@ -.\" Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +.\" Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique .\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -.\" Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -.\" Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -.\" Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -.\" Copyright (C) 2022-2023 Observatoire de Paris -.\" Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -.\" Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -.\" Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier +.\" Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +.\" Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2022-2024 Observatoire de Paris +.\" Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +.\" Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +.\" Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier .\" .\" This program is free software: you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by @@ -20,7 +20,7 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. -.Dd October 4, 2023 +.Dd January 24, 2024 .Dt HTRDR-COMBUSTION 1 .Os .Sh NAME @@ -29,17 +29,17 @@ .Sh SYNOPSIS .Nm .Op Fl fhINsv -.Op Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt ... +.Op Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt No ... .Op Fl D Ar laser_flux_density .Op Fl d Ar dump_type -.Op Fl F Ar rdgfa_opt Ns Op : Ns Ar rdgfa_opt ... -.Op Fl g Ar combustion_chamber_opt Ns Op : Ns Ar combustion_chamber_opt... -.Op Fl i Ar image_opt Ns Op : Ns Ar image_opt ... -.Op Fl l Ar laser_opt Ns Op : Ns Ar laser_opt ... +.Op Fl F Ar rdgfa_opt Ns Op : Ns Ar rdgfa_opt No ... +.Op Fl g Ar combustion_chamber_opt Ns Op : Ns Ar combustion_chamber_opt No ... +.Op Fl i Ar image_opt Ns Op : Ns Ar image_opt No ... +.Op Fl l Ar laser_opt Ns Op : Ns Ar laser_opt No ... .Op Fl O Pa cache .Op Fl o Pa output -.Op Fl P Ar ortho_camera_opt Ns Op : Ns Ar ortho_camera_opt ... -.Op Fl R Ar flux_sensor_opt Ns Op : Ns Ar flux_sensor_opt ... +.Op Fl P Ar ortho_camera_opt Ns Op : Ns Ar ortho_camera_opt No ... +.Op Fl R Ar flux_sensor_opt Ns Op : Ns Ar flux_sensor_opt No ... .Op Fl T Ar optical_thickness .Op Fl t Ar threads_count .Op Fl V Ar accel_struct_definition @@ -109,7 +109,7 @@ to distribute the calculation on several computers. .Pp The options are as follows: .Bl -tag -width Ds -.It Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt ... +.It Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt No ... Set up a pinhole or thin-lens perspective camera. .Pp The options for a perspective camera are as follows: @@ -171,7 +171,7 @@ Each leaf stores the minimum and maximum extinction coefficients of the tetrahedra it covers. Data are written in legacy VTK format. .El -.It Fl F Ar rdgfa_opt Ns Op : Ns Ar rdgfa_opt ... +.It Fl F Ar rdgfa_opt Ns Op : Ns Ar rdgfa_opt No ... RDG-FA phase function parameters. .Pp The parameters of the RDG-FA phase function are as follows: @@ -187,7 +187,7 @@ Default is @HTRDR_COMBUSTION_ARGS_DEFAULT_FRACTAL_PREFACTOR@. Force overwriting of .Pa output file. -.It Fl g Ar combustion_chamber_opt Ns Op : Ns Ar combustion_chamber_opt... +.It Fl g Ar combustion_chamber_opt Ns Op : Ns Ar combustion_chamber_opt No ... Define the combustion chamber. .Pp Note that the combustion chamber does not prevent the camera from seeing @@ -230,7 +230,7 @@ Display short help and exit. .It Fl I Use an isotropic phase function rather than the RDG-FA phase function .Pq option Fl F . -.It Fl i Ar image_opt Ns Op : Ns Ar image_opt ... +.It Fl i Ar image_opt Ns Op : Ns Ar image_opt No ... Configure sensor image. .Pp The image options are as follows: @@ -243,7 +243,7 @@ Default is Number of samples to solve the Monte Carlo estimation of each pixel. Default is @HTRDR_ARGS_DEFAULT_IMG_SPP@. .El -.It Fl l Ar laser_opt Ns Op : Ns Ar laser_opt ... +.It Fl l Ar laser_opt Ns Op : Ns Ar laser_opt No ... Laser emission surface. .Pp The laser options are as follows: @@ -298,7 +298,7 @@ avoiding the use of bad cached data. .It Fl o Pa output Output file. If not defined, data is written to standard output. -.It Fl P Ar ortho_camera_opt Ns Op : Ns Ar ortho_camera_opt ... +.It Fl P Ar ortho_camera_opt Ns Op : Ns Ar ortho_camera_opt No ... Set up an orthographic camera. .Pp The options for an orthographic camera are as follows: @@ -322,7 +322,7 @@ Default is @HTRDR_ARGS_DEFAULT_CAMERA_UP@. Thermodynamic properties of the combustion medium saved in .Xr atrtp 5 format. -.It Fl R Ar flux_sensor_opt Ns Op : Ns Ar flux_sensor_opt ... +.It Fl R Ar flux_sensor_opt Ns Op : Ns Ar flux_sensor_opt No ... Set up a flux sensor. .Pp The flux sensor options are as follow: @@ -451,7 +451,7 @@ htrdr-combustion -v \\ -r refract_ids.atrri \\ -l pos=0,0,0:tgt=0,1,0:up=0,0,1:sz=0.001,0.2 \\ -w 500 \\ - -C pos=0.06,0,0.01:tgt=0.05,0,0.01:up=0,0,1:fov=30 \\ + -C pos=0.6,0,0.1:tgt=0.5,0,0.1:up=0,0,1:fov=30 \\ -i def=800x600:spp=64 \\ -o output .Ed @@ -491,7 +491,7 @@ htrdr-combustion -v \\ -g obj=chamber.obj:mats=materials.mtls \\ -l pos=0,0,0:tgt=0,1,0:up=0,0,1:sz=0.001,0.2 \\ -w 500 \\ - -C pos=0.06,0,0.01:tgt=0.05,0,0.01:up=0,0,1:fov=30 \\ + -C pos=0.6,0,0.1:tgt=0.5,0,0.1:up=0,0,1:fov=30 \\ -i def=800x600:spp=64 \\ -O octree.cache \\ -V 1000 \\ @@ -552,7 +552,7 @@ htrdr-combustion -v \\ .Xr smsh 5 .Rs .%A Morgan Sans -.%A Mouna El Hafi +.%A Mouna El\ Hafi .%A Vincent Eymet .%A Vincent Forest .%A Richard Fournier diff --git a/doc/htrdr-image.5 b/doc/htrdr-image.5 @@ -1,12 +1,12 @@ -.\" Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +.\" Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique .\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -.\" Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -.\" Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -.\" Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -.\" Copyright (C) 2022-2023 Observatoire de Paris -.\" Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -.\" Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -.\" Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier +.\" Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +.\" Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2022-2024 Observatoire de Paris +.\" Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +.\" Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +.\" Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier .\" .\" This program is free software: you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by diff --git a/doc/htrdr-materials.5 b/doc/htrdr-materials.5 @@ -1,12 +1,12 @@ -.\" Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +.\" Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique .\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -.\" Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -.\" Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -.\" Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -.\" Copyright (C) 2022-2023 Observatoire de Paris -.\" Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -.\" Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -.\" Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier +.\" Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +.\" Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2022-2024 Observatoire de Paris +.\" Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +.\" Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +.\" Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier .\" .\" This program is free software: you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by diff --git a/doc/htrdr-obj.5 b/doc/htrdr-obj.5 @@ -1,12 +1,12 @@ -.\" Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +.\" Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique .\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -.\" Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -.\" Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -.\" Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -.\" Copyright (C) 2022-2023 Observatoire de Paris -.\" Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -.\" Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -.\" Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier +.\" Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +.\" Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2022-2024 Observatoire de Paris +.\" Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +.\" Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +.\" Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier .\" .\" This program is free software: you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by diff --git a/doc/htrdr-planeto.1.in b/doc/htrdr-planeto.1.in @@ -1,610 +0,0 @@ -.\" Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique -.\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -.\" Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -.\" Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -.\" Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -.\" Copyright (C) 2022-2023 Observatoire de Paris -.\" Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -.\" Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -.\" Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier -.\" -.\" This program is free software: you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation, either version 3 of the License, or -.\" (at your option) any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program. If not, see <http://www.gnu.org/licenses/>. -.Dd October 4, 2023 -.Dt HTRDR-PLANETO 1 -.Os -.Sh NAME -.Nm htrdr-planeto -.Nd simulate radiative transfer in 3D planetary atmosphere -.Sh SYNOPSIS -.Nm -.Op Fl dfhNv -.Op Fl a Ar aerosol_opt Ns Op : Ns Ar aerosol_opt ... -.Op Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt ... -.Op Fl G Ar ground_opt Ns Op : Ns Ar ground_opt ... -.Op Fl i Ar image_opt Ns Op : Ns Ar image_opt ... -.Op Fl O Pa accel_struct_storage -.Op Fl o Pa output -.Op Fl S Ar source_opt Ns Op : Ns Ar source_opt ... -.Op Fl s Ar spectral_opt Ns Op : Ns Ar spectral_opt ... -.Op Fl T Ar optical_thickness -.Op Fl t Ar threads_count -.Op Fl V Ar accel_struct_definition -.Fl g Ar gas_opt Ns Op : Ns Ar gas_opt ... -.Sh DESCRIPTION -.Nm -simulates the radiative transfer of a terrestrial planet in the visible -or the infrared part of the spectrum. -The planet's ground -.Pq option Fl G -can be any set of triangles with BRDFs and temperatures defined per triangle. -The atmosphere is composed of a gas mixture -.Pq option Fl g -and a potentially empty set of aerosols -.Pq option Fl a . -Both can have arbitrary tetrahedral meshes with per-node radiative -properties. -Rayleigh is used as a gas phase function. -The temperature of the gas is defined on the mesh nodes. -Aerosol phase functions -.Pq Henyey and Greenstein or user defined -are also defined per node. -.Pp -.Nm -is mainly a renderer that calculates an image -.Pq option Fl i -for a given observation position -.Pq option Fl C . -Its internal rendering algorithm is based on Monte Carlo integration, -which consists for each pixel of simulating a given number of optical -paths from the sensor, taking into account the phenomena of light -absorption and scattering. -.Pp -.Nm -offers three ways to perform spectral integration -.Pq option Fl s . -By default, it calculates an image for the visible part of the spectrum between -380 and 780 nanometers, for the three components of the CIE 1931 XYZ color space -which are then recombined to obtain the final color for each pixel. -The other two methods are to explicitly define the longwave or shortwave -spectral range to be integrated and continuously sample a wavelength in -this range. -In fact, longwave and shortwave are keywords that mean that the source -of radiation is either internal or external to the medium, respectively. -In shortwave, only radiance is evaluated and stored in the output image. -For longwave rendering, this estimated radiance is then converted to -brightness temperature and both are recorded in the image. -.Pp -In -.Nm , -the spatial unit 1.0 corresponds to one meter and temperatures are -expressed in Kelvin. -The estimated radiances are given in W/sr/m^2, except for monochromatic -calculations where the calculated spectral radiance is defined in -W/sr/m^2/nm. -.Pp -.Nm -implements mixed parallelism. -On a single computer -.Pq that is, a node , -it uses shared memory parallelism while it relies on Message Passing -Interface (MPI) to parallelize calculations between multiple nodes. -.Nm -can therefore be launched either directly or via a process -launcher such as -.Xr mpirun 1 -to distribute the rendering on several computers. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl a Ar aerosol_opt Ns Op : Ns Ar aerosol_opt ... -Define an aerosol. -Use this option once per aerosol, and duplicate it as many times as -necessary. -.Pp -The aerosol options are as follows: -.Bl -tag -width Ds -.It Cm mesh= Ns Pa volumetric_mesh -Aerosol tetrahedral mesh saved in -.Xr smsh 5 -format. -.It Cm name= Ns Ar string -Name assined to the aerosol. -.It Cm radprop= Ns Pa radiative_properties -Radiatve properties of the aerosol saved in -.Xr sars 5 -format. -Radiative properties are defined per volumetric mesh node. -This file and the tetrahedral mesh -.Pq option Cm mesh -must therefore be consistent with each other, i.e. the nodes must be -listed in the same order. -.It Cm phasefn= Ns Pa phase_functions_list -List in -.Xr rnsl 5 -format of phase functions to be loaded. -Each phase function is saved in -.Xr rnsf 5 -format. -The correspondence between these phase functions and the nodes of the -volumetric mesh is defined in another file -.Pq option Cm phaseids . -.It Cm phaseids= Ns Pa per_node_phase_function -Path to the -.Xr rnpfi 5 -file that stores the index of the phase function to be used per -volumetric mesh node. -The list of phase function is defined in another file -.Pq option Cm phasefn . -Note that this file and the tetrahedral mesh -.Pq option Cm mesh -must be consistent with each other, i.e. the nodes must be -listed in the same order. -.El -.It Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt ... -Set up a pinhole or thin-lens perspective camera. -.Pp -The options for a perspective camera are as follows: -.Bl -tag -width Ds -.It Cm focal-dst= Ns Ar distance -Distance to focus on with a thin lens camera, that is, a camera whose -.Cm lens-radius -is not zero. -The default focal distance is -@HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOCAL_DST@ meters. -.It Cm focal-length= Ns Ar length -Focal length of a camera lens. -It is another way to control the field of view of a thin lens camera. -By default, the field of view is set through the -.Cm fov -parameter. -.It Cm fov= Ns Ar angle -Vertical field of view of the camera in -]@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN@, -@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX@[ degrees. -The default field of view is -@HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOV@ degrees. -.It Cm lens-radius= Ar radius -Radius of the camera lens. -A non-zero radius means that the camera is a thin lens camera while a -zero radius defines a pinhole camera. -The default lens radius is -@HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_LENS_RADIUS@. -.It Cm pos= Ns Ar x , Ns Ar y , Ns Ar z -Camera position. -Default is @HTRDR_ARGS_DEFAULT_CAMERA_POS@. -.It Cm tgt= Ns Ar x , Ns Ar y , Ns Ar z -Targeted position -Default is @HTRDR_ARGS_DEFAULT_CAMERA_TGT@. -.It Cm up= Ns Ar x , Ns Ar y , Ns Ar z -Upward vector that the top of the camera is pointing towards. -Default is @HTRDR_ARGS_DEFAULT_CAMERA_UP@. -.El -.It Fl d -Write atmospheric acceleration structures to -.Pa output . -Each structure is saved in legacy VTK format. -To divide the resulting output into N files -.Pq N > 1 , -each storing an acceleration structure, one can use the -.Xr csplit 1 -command as below: -.Bd -literal -offset Ds -csplit -f octree -k output %^#\\ vtk% /^#\\ vtk/ \\ - {$(($(grep -ce "^# vtk" output)-2))} -.Ed -.It Fl f -Force overwriting of -.Pa output -file. -.It Fl G Ar ground_opt Ns Op : Ns Ar ground_opt ... -The planet's ground. -.Pp -The ground options are as follows: -.Bl -tag -width Ds -.It Cm brdf= Ns Pa brdfs_list -List in -.Xr rnsl 5 -format of the BRDFs to be loaded. -Each BRDF is saved in -.Xr mrumtl 5 -format. -The correspondence between these BRDFs and the triangles of the surface -mesh is defined in another file -.Pq option Cm prop . -.It Cm mesh= Ns Pa surface_mesh -Ground triangular mesh saved in -.Xr smsh 5 -format. -.It Cm name= Ns Ar string -Name assigned to the ground. -.It Cm prop= Ns Ar surface_properties -Ground surface properties, i.e. BRDF index and temperature, both defined -by triangle. -The list of BRDF is defined in another file -.Pq option Cm brdf . -Note that this file and the surface mesh must be consistent -.Pq option Cm mesh , -i.e. the triangles must be listed in the same order. -.El -.It Fl g Ar gas_opt Ns Op : Ns Ar gas_opt ... -Gas mixture. -.Pp -The gas options are as follows: -.Bl -tag -width Ds -.It Cm mesh= Ns Pa volumetric_mesh -Gas tetrahedral mesh saved in -.Xr smsh 5 -format. -.It Cm ck= Ns Pa correlated_k -Correlated K fof the gas saved in -.Xr sck 5 -format. -The correlated K are defined per volumetric mesh node. -This file and the tetrahedral mesh -.Pq option Cm mesh -must therefore be consistent with each other, i.e. the nodes must be -listed in the same order. -.It Cm temp= Ns Pa temperature -Gas temperatures saved in -.Xr rngt 5 -format. -The temperature is defined per volumetric mesh node. -This file and the tetrahedral mesh -.Pq option Cm mesh -must therefore be consistent with each other, i.e. the nodes must be -listed in the same order. -.El -.It Fl h -Display short help and exit. -.It Fl i Ar image_opt Ns Op : Ns Ar image_opt ... -Configure sensor image. -.Pp -The image options are as follows: -.Bl -tag -width Ds -.It Cm def= Ns Ar width Ns x Ns Ar height -Image definition. -Default is -@HTRDR_ARGS_DEFAULT_IMG_WIDTH@x@HTRDR_ARGS_DEFAULT_IMG_HEIGHT@. -.It Cm spp= Ns Ar samples_per_pixel -Number of samples to solve the Monte Carlo estimation of each pixel. -Default is @HTRDR_ARGS_DEFAULT_IMG_SPP@. -.El -.It Fl N -Precalculate tetrahedron normals. -This speeds up runtime performance by calculating normals once and for -all rather than re-evaluating them every time a tetrahedron is queried -at a given position. -In return, the memory space used to store normals increases the memory -footprint. -.It Fl O Pa accel_struct_storage -File where atmospheric acceleration structures are stored/loaded. -.Pp -If -.Pa accel_struct_storage -does not exist, it is created and is used to store the built -acceleration structures. -.Pp -If -.Pa accel_struct_storage -exists, acceleration structures are loaded from it rather than built -from scratch, resulting in significant acceleration of the preprocessing -step. -Note that if the data structures stored in -.Pa accel_struct_storage -are not as expected (that is, the input atmospheric data or construction -parameters are different), an error is notified and execution is -stopped, thus avoiding the use of incorrect acceleration structures. -.It Fl o Pa output -Output file. -If not defined, data is written to standard output. -.It Fl S Ar source_opt Ns Op : Ns Ar source_opt ... -Define the external source. -.Pp -The source options are as follows: -.Bl -tag -width Ds -.It Cm lat= Ns Ar latitude -The latitude of the source, i.e. its angle between -.Bq -90, 90 -degrees about the Y axis. -The default latitude of 0 is that of the X axis. -.It Cm lon= Ns Ar longitude -The longitude of the source, i.e. its angle between [-180, 180] degrees -about the Z axis. -The default longitude of 0 is that of the X axis. -.It Cm dst= Ns Ar distance -Distance in kilometers from source to origin. -Default is 0. -.It Cm rad= Ns Ar radiance_distribution -Source radiance distribution saved in -.Xr rnrl 5 -format. -This option is not compatible with the temperature setting of the source -.Pq option Cm temp -which also defines its radiance distribution. -.It Cm radius= Ns Ar real -Source radius in kilometers. -.It Cm temp= Ns Ar temperature -Source temperature in Kelvin. -When this option is set, the radiance distribution of the source is -Planck, at the specified temperature. -This option is not compatible with the -.Cm rad -option that explicitly defines the source radiance distribution. -.El -.It Fl s Ar spectral_opt Ns Op : Ns Ar spectral_opt ... -Configure spectral integration. -.Pp -The spectral integration options are as follows: -.Bl -tag -width Ds -.It Cm cie_xyz -Calculate the radiance for the visible part of the spectrum between -.Bq 380, 780 -nanometers using the XYZ CIE 1931 color matching functions. -This is the default behavior. -.It Cm lw= Ns Ar wlen_min , Ns Ar wlen_max -Calculate the radiance using the internal source of radiation, i.e. the -radiance emitted by the medium and its boundaries (ground and space). -.Pp -Calculations are performed between -.Bq Ar wlen_min , Ar wlen_max -nanometers according to Planck's function for a reference temperature -defined as the maximum ground temperature. -.Pp -If -.Ar wlen_min -and -.Ar wlen_max -are equal, the calculation is monochromatic. -.It Cm sw= Ns Ar wlen_min , Ns Ar wlen_max -Calculate the radiance using the external source of radiance -.Pq option Fl S . -.Pp -Calculations are performed between -.Bq Ar wlen_min , Ar wlen_max -nanometers according to the radiance distribution of the external -source -.Pq see Fl S No option -.Pp -If -.Ar wlen_min -and -.Ar wlen_max -are equal, the calculation is monochromatic. -.El -.It Fl T Ar optical_thickness -Optical thickness used as threshold criterion for building the acceleration -structures. -Default is @HTRDR_PLANETO_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@. -.It Fl t -Advice on the number of threads to use. -By default, -.Nm -uses many threads as processor cores. -.It Fl V Ar accel_struct_definition -Advice on the definition of the atmospheric acceleration structures. -Default is @HTRDR_PLANETO_ARGS_DEFAULT_GRID_DEFINITION_HINT@. -.It Fl v -Make -.Nm -verbose. -.El -.Sh OUTPUT IMAGE -Images calculated by -.Nm -are saved in -.Xr htrdr-image 5 -format. -This section describes the nature and arrangement of image data -depending on the type of calculation performed. -.Ss XYZ image -For an image rendering in the visible part of the spectrum -.Pq default behavior or option Fl s Cm cie_xyz , -the pixel components store 4 estimates. -The first, second, and third pairs of floating point values encode the -estimated integrated radiance in W/sr/m^2 for the X, Y, and Z components -of the CIE 1931 XYZ color space. -The first value of each pair is the expected value of the -average radiance of the pixel. -The second value is its associated standard deviation. -The fourth and final pair records the microsecond estimate of the -computation time per radiative path and its standard error. -.Ss Longwave image -For infrared calculations -.Pq option Fl s Cm lw= Ns Ar wlen_min , Ns Ar wlen_max -the first and second pixel components store the expected value and the -standard error of the estimated brightness temperature (in K), -respectively. -The third and fourth components record the expected value and the -standard deviation of the pixel radiance which is either an integrated -radiance in W/sr/m^2 or a spectral radiance in W/sr/m^2/nm depending on -whether this radiance was calculated for a spectral range or at a single -wavelength. -The fifth and sixth pixel components are not used. -Finally, the last 2 components of the pixel record the estimate in -microseconds of the computation time per radiative path and its standard -error. -.Ss Shortwave image -For shortwave calculations -.Pq option Fl s Cm sw= Ns Ar wlen_min , Ns Ar wlen_max -the output image is formatted as for a longwave image except that the -first and second components of the pixels are not used, as no brightness -temperature has been evaluated. -That is, the third and fourth values record the estimated radiance per -pixel and the seventh and eighth values store the estimate of the -calculation time by radiative path. -The other values are set to 0. -.Sh EXIT STATUS -.Ex -std -.Sh EXAMPLES -The following command line runs -.Nm -in a verbose way -.Pq option Fl v -to calculate an -.Ar 800 No by Ar 600 -pixel image by sampling -.Ar 64 -radiative paths per pixel -.Pq option Fl i -for the 3 components of the CIE 1931 XYZ color -space -.Pq option Fl s . -The external source is positioned at -.Ar -45 -degrees longitude and -.Ar 50 -degrees latitude relative to the absolute referential -.Pq option Fl S . -The camera -.Pq option Fl C -looks at the origin -.Pq Cm tgt= Ns Ar 0 , Ns Ar 0 , Ns Ar 0 -and is positioned at -.Ar 1.5e7 -meters along the Y axis with an image plane aligned along the Z axis -.Pq Cm up= Ns Ar 0 , Ns Ar 0 , Ns Ar 1 . -Its vertical field of view is -.Ar 70 -degrees. -The gas of the planetary atmosphere is described by the tetrahedral mesh -recorded in the -.Pa gas.smsh -file, while its spectral data and temperature are given by the files -.Pa gas.sck -and -.Pa gas.rngt , -respectively. -Two aerosols complete the planetary atmosphere: one for -.Ar clouds -and one for -.Ar haze . -Their respective meshes are stored in the -.Pa a.smsh No and Pa b.smsh -files while their radiative properties are given by the -.Pa a.sars No and Pa b.sars -files. -Finally, their phase functions are described by a set of 2 files: the -.Pa a.rnsf No and Pa b.rnsf -files which list the aerosol phase functions, -and the -.Pa a.rnpfi No and Pa b.rnpfi -files which reference them by volumetric mesh node. -To speed up rendering time, the normals of the tetrahedral meshes of -the gas and aerosols are precalculated once and for all -.Pq option Fl N . -The ground geometry is stored in the -.Pa ground.smsh -file with its triangle properties -.Pq temperature and BRDF -defined in the -.Pa ground.rnsp -file. -The referenced BRDFs are listed in the -.Pa ground.rnsl -file. -The definition of acceleration structures -cannot exceed -.Ar 512^3 -and its voxels can be merged until their optical thickness -is greater than -.Ar 10 . -These structures are either reloaded from -.Pa storage_cie.bin -or built from scratch and stored in -.Pa storage_cie.bin -depending on whether that file exists or not. -Finally, the calculated images are -stored in the -.Pa image_CIE_XYZ.ht -file even if the file already exists -.Pq options Fl fo : -.Bd -literal -offset Ds -htrdr-planeto -v -N \\ --i def=800x600:spp=64 \\ --s cie_xyz \\ --S lon=-45:lat=50:dst=1.5e8:radius=6.9e5:temp=5778 \\ --C pos=0,1.5e7,0:tgt=0,0,0:up=0,0,1:fov=70 \\ --g mesh=gas.smsh:ck=gas.sck:temp=gas.rngt \\ --a mesh=a.smsh:radprop=a.sars:phasefn=a.rnsf:phaseids=a.rnpfi:name=clouds \\ --a mesh=b.smsh:radprop=b.sars:phasefn=b.rnsf:phaseids=b.rnpfi:name=haze \\ --G mesh=ground.smsh:prop=ground.rnsp:brdf=ground.rnsl:name=namek \\ --V 512 -T 10 -O storage_cie.bin \\ --fo image_CIE_XYZ.ht -.Ed -.Pp -The next command line is the same as the previous one, except that it calculates -an infrared image between -.Ar 10,000 -nm and -.Ar 20,000 -nm -.Pq option Fl s . -Note that the acceleration structure storage file is no longer the same -.Pq Pa storage_lw.bin No rather than Pa storage_cie.bin . -Indeed, the previous one records the acceleration structures for the -spectral range of the CIE 1931 XYZ color space -.Pq i.e. between Bo 380, 780 Bc nm , -while one wants to store/reload the acceleration structures for a -spectral range between 10 and 20 microns. -In any case, if the previous storage had been submitted, the command -would have stopped with an error message, thus avoiding the use of the -wrong acceleration structures -.Pq see Fl O No option . -.Bd -literal -offset Ds -htrdr-planeto -v -N \\ --i def=800x600:spp=64 \\ --s lw=10000,20000 \\ --C pos=0,1.5e7,0:tgt=0,0,0:up=0,0,1:fov=70 \\ --g mesh=gas.smsh:ck=gas.sck:temp=gas.rngt \\ --a mesh=a.smsh:radprop=a.sars:phasefn=a.rnsf:phaseids=a.rnpfi:name=clouds \\ --a mesh=b.smsh:radprop=b.sars:phasefn=b.rnsf:phaseids=b.rnpfi:name=haze \\ --G mesh=ground.smsh:prop=ground.rnsp:brdf=ground.rnsl:name=namek \\ --V 512 -T 10 -O storage_lw.bin \\ --fo image_infrared.ht -.Ed -.Sh SEE ALSO -.Xr htrdr-image 5 , -.Xr mrumtl 5 , -.Xr rngt 5 , -.Xr rnpfi 5 , -.Xr rnrl 5 , -.Xr rnsf 5 , -.Xr sars 5 , -.Xr sck 5 , -.Xr smsh 5 -.Sh STANDARDS -.Rs -.%A International Organization for Standardization / CIE -.%R ISO/CIE 11664-1:2019 -.%D June 2019 -.%T Colorimetry - Part 1: CIE standard colorimetric observers -.Re -.Pp -.Rs -.%A OpenMP Architecture Review Board -.%D March 2002 -.%T OpenMP C and C++ Application Interface -.%O version 2.0 -.Re -.Pp -.Rs -.%A Message Passing Interface Forum -.%D July 1997 -.%T MPI-2: Extensions to The Message-Passing Interface -.Re -.Sh HISTORY -.Nm -has been developed as part of -.Li ANR-21-CE49-0020 -RaD-net project. diff --git a/doc/htrdr-planets.1.in b/doc/htrdr-planets.1.in @@ -0,0 +1,648 @@ +.\" Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique +.\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux +.\" Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +.\" Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2022-2024 Observatoire de Paris +.\" Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +.\" Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +.\" Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.Dd November 6, 2024 +.Dt HTRDR-PLANETS 1 +.Os +.Sh NAME +.Nm htrdr-planets +.Nd simulate radiative transfer in 3D planetary atmosphere +.Sh SYNOPSIS +.Nm +.Op Fl dfhNv +.Op Fl a Ar aerosol_opt Ns Op : Ns Ar aerosol_opt No ... +.Op Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt No ... +.Op Fl G Ar ground_opt Ns Op : Ns Ar ground_opt No ... +.Op Fl i Ar image_opt Ns Op : Ns Ar image_opt No ... +.Op Fl O Pa accel_struct_storage +.Op Fl o Pa output +.Op Fl S Ar source_opt Ns Op : Ns Ar source_opt No ... +.Op Fl s Ar spectral_opt Ns Op : Ns Ar spectral_opt No ... +.Op Fl T Ar optical_thickness +.Op Fl t Ar threads_count +.Op Fl V Ar accel_struct_definition +.Fl g Ar gas_opt Ns Op : Ns Ar gas_opt No ... +.Sh DESCRIPTION +.Nm +simulates the radiative transfer of a terrestrial planet in the visible +or the infrared part of the spectrum. +The planet's ground +.Pq option Fl G +can be any set of triangles with BRDFs and temperatures defined per triangle. +The atmosphere is composed of a gas mixture +.Pq option Fl g +and a potentially empty set of aerosols +.Pq option Fl a . +Both can have arbitrary tetrahedral meshes with per-node radiative +properties. +Rayleigh is used as a gas phase function. +The temperature of the gas is defined on the mesh nodes. +Aerosol phase functions +.Pq Henyey and Greenstein or user defined +are also defined per node. +.Pp +.Nm +is mainly a renderer that calculates an image +.Pq option Fl i +for a given observation position +.Pq option Fl C . +Its internal rendering algorithm is based on Monte Carlo integration, +which consists for each pixel of simulating a given number of optical +paths from the sensor, taking into account the phenomena of light +absorption and scattering. +.Pp +.Nm +offers three ways to perform spectral integration +.Pq option Fl s . +By default, it calculates an image for the visible part of the spectrum between +380 and 780 nanometers, for the three components of the CIE 1931 XYZ color space +which are then recombined to obtain the final color for each pixel. +The other two methods are to explicitly define the longwave or shortwave +spectral range to be integrated and continuously sample a wavelength in +this range. +In fact, longwave and shortwave are keywords that mean that the source +of radiation is either internal or external to the medium, respectively. +In shortwave, only radiance is evaluated and stored in the output image. +For longwave rendering, this estimated radiance is then converted to +brightness temperature and both are recorded in the image. +.Pp +In +.Nm , +the spatial unit 1.0 corresponds to one meter and temperatures are +expressed in Kelvin. +The estimated radiances are given in W/sr/m^2, except for monochromatic +calculations where the calculated spectral radiance is defined in +W/sr/m^2/nm. +.Pp +.Nm +implements mixed parallelism. +On a single computer +.Pq that is, a node , +it uses shared memory parallelism while it relies on Message Passing +Interface (MPI) to parallelize calculations between multiple nodes. +.Nm +can therefore be launched either directly or via a process +launcher such as +.Xr mpirun 1 +to distribute the rendering on several computers. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl a Ar aerosol_opt Ns Op : Ns Ar aerosol_opt No ... +Define an aerosol. +Use this option once per aerosol, and duplicate it as many times as +necessary. +.Pp +The aerosol options are as follows: +.Bl -tag -width Ds +.It Cm mesh= Ns Pa volumetric_mesh +Aerosol tetrahedral mesh saved in +.Xr smsh 5 +format. +.It Cm name= Ns Ar string +Name assigned to the aerosol. +.It Cm radprop= Ns Pa radiative_properties +Radiatve properties of the aerosol saved in +.Xr sars 5 +format. +Radiative properties are defined per volumetric mesh node. +This file and the tetrahedral mesh +.Pq option Cm mesh +must therefore be consistent with each other, i.e. the nodes must be +listed in the same order. +.It Cm phasefn= Ns Pa phase_functions_list +List in +.Xr rnsl 5 +format of phase functions to be loaded. +Each phase function is saved in +.Xr rnsf 5 +format. +The correspondence between these phase functions and the nodes of the +volumetric mesh is defined in another file +.Pq option Cm phaseids . +.It Cm phaseids= Ns Pa per_node_phase_function +Path to the +.Xr rnpfi 5 +file that stores the index of the phase function to be used per +volumetric mesh node. +The list of phase function is defined in another file +.Pq option Cm phasefn . +Note that this file and the tetrahedral mesh +.Pq option Cm mesh +must be consistent with each other, i.e. the nodes must be +listed in the same order. +.El +.It Fl C Ar persp_camera_opt Ns Op : Ns Ar persp_camera_opt No ... +Set up a pinhole or thin-lens perspective camera. +.Pp +The options for a perspective camera are as follows: +.Bl -tag -width Ds +.It Cm focal-dst= Ns Ar distance +Distance to focus on with a thin lens camera, that is, a camera whose +.Cm lens-radius +is not zero. +The default focal distance is +@HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOCAL_DST@ meters. +.It Cm focal-length= Ns Ar length +Focal length of a camera lens. +It is another way to control the field of view of a thin lens camera. +By default, the field of view is set through the +.Cm fov +parameter. +.It Cm fov= Ns Ar angle +Vertical field of view of the camera in +]@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN@, +@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX@[ degrees. +The default field of view is +@HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOV@ degrees. +.It Cm lens-radius= Ns Ar radius +Radius of the camera lens. +A non-zero radius means that the camera is a thin lens camera while a +zero radius defines a pinhole camera. +The default lens radius is +@HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_LENS_RADIUS@. +.It Cm pos= Ns Ar x , Ns Ar y , Ns Ar z +Camera position. +Default is @HTRDR_ARGS_DEFAULT_CAMERA_POS@. +.It Cm tgt= Ns Ar x , Ns Ar y , Ns Ar z +Targeted position +Default is @HTRDR_ARGS_DEFAULT_CAMERA_TGT@. +.It Cm up= Ns Ar x , Ns Ar y , Ns Ar z +Upward vector that the top of the camera is pointing towards. +Default is @HTRDR_ARGS_DEFAULT_CAMERA_UP@. +.El +.It Fl d +Write atmospheric acceleration structures to +.Pa output . +Each structure is saved in legacy VTK format. +To divide the resulting output into N files +.Pq N > 1 , +each storing an acceleration structure, one can use the +.Xr csplit 1 +command as below: +.Bd -literal -offset Ds +csplit -f octree -k output %^#\\ vtk% /^#\\ vtk/ \\ + {$(($(grep -ce "^# vtk" output)-2))} +.Ed +.It Fl f +Force overwriting of +.Pa output +file. +.It Fl G Ar ground_opt Ns Op : Ns Ar ground_opt No ... +The planet's ground. +.Pp +The ground options are as follows: +.Bl -tag -width Ds +.It Cm brdf= Ns Pa brdfs_list +List in +.Xr rnsl 5 +format of the BRDFs to be loaded. +Each BRDF is saved in +.Xr mrumtl 5 +format. +The correspondence between these BRDFs and the triangles of the surface +mesh is defined in another file +.Pq option Cm prop . +.It Cm mesh= Ns Pa surface_mesh +Ground triangular mesh saved in +.Xr smsh 5 +format. +.It Cm name= Ns Ar string +Name assigned to the ground. +.It Cm prop= Ns Ar surface_properties +Ground surface properties, i.e. BRDF index and temperature, both defined +by triangle. +The list of BRDF is defined in another file +.Pq option Cm brdf . +Note that this file and the surface mesh must be consistent +.Pq option Cm mesh , +i.e. the triangles must be listed in the same order. +.El +.It Fl g Ar gas_opt Ns Op : Ns Ar gas_opt No ... +Gas mixture. +.Pp +The gas options are as follows: +.Bl -tag -width Ds +.It Cm mesh= Ns Pa volumetric_mesh +Gas tetrahedral mesh saved in +.Xr smsh 5 +format. +.It Cm ck= Ns Pa correlated_k +Correlated K fof the gas saved in +.Xr sck 5 +format. +The correlated K are defined per volumetric mesh node. +This file and the tetrahedral mesh +.Pq option Cm mesh +must therefore be consistent with each other, i.e. the nodes must be +listed in the same order. +.It Cm temp= Ns Pa temperature +Gas temperatures saved in +.Xr rngt 5 +format. +The temperature is defined per volumetric mesh node. +This file and the tetrahedral mesh +.Pq option Cm mesh +must therefore be consistent with each other, i.e. the nodes must be +listed in the same order. +.El +.It Fl h +Display short help and exit. +.It Fl i Ar image_opt Ns Op : Ns Ar image_opt No ... +Configure sensor image. +.Pp +The image options are as follows: +.Bl -tag -width Ds +.It Cm def= Ns Ar width Ns x Ns Ar height +Image definition. +Default is +@HTRDR_ARGS_DEFAULT_IMG_WIDTH@x@HTRDR_ARGS_DEFAULT_IMG_HEIGHT@. +.It Cm spp= Ns Ar samples_per_pixel +Number of samples to solve the Monte Carlo estimation of each pixel. +Default is @HTRDR_ARGS_DEFAULT_IMG_SPP@. +.El +.It Fl N +Precalculate tetrahedron normals. +This speeds up runtime performance by calculating normals once and for +all rather than re-evaluating them every time a tetrahedron is queried +at a given position. +In return, the memory space used to store normals increases the memory +footprint. +.It Fl O Pa accel_struct_storage +File where atmospheric acceleration structures are stored/loaded. +.Pp +If +.Pa accel_struct_storage +does not exist, it is created and is used to store the built +acceleration structures. +.Pp +If +.Pa accel_struct_storage +exists, acceleration structures are loaded from it rather than built +from scratch, resulting in significant acceleration of the preprocessing +step. +Note that if the data structures stored in +.Pa accel_struct_storage +are not as expected (that is, the input atmospheric data or construction +parameters are different), an error is notified and execution is +stopped, thus avoiding the use of incorrect acceleration structures. +.It Fl o Pa output +Output file. +If not defined, data is written to standard output. +.It Fl S Ar source_opt Ns Op : Ns Ar source_opt No ... +Define the external source. +.Pp +The source options are as follows: +.Bl -tag -width Ds +.It Cm lat= Ns Ar latitude +The latitude of the source, i.e. its angle between +.Bq -90, 90 +degrees about the Y axis. +The default latitude of 0 is that of the X axis. +.It Cm lon= Ns Ar longitude +The longitude of the source, i.e. its angle between [-180, 180] degrees +about the Z axis. +The default longitude of 0 is that of the X axis. +.It Cm dst= Ns Ar distance +Distance in kilometers from source to origin. +Default is 0. +.It Cm rad= Ns Ar radiance_distribution +Source radiance distribution saved in +.Xr rnrl 5 +format. +This option is not compatible with the temperature setting of the source +.Pq option Cm temp +which also defines its radiance distribution. +.It Cm radius= Ns Ar real +Source radius in kilometers. +.It Cm temp= Ns Ar temperature +Source temperature in Kelvin. +When this option is set, the radiance distribution of the source is +Planck, at the specified temperature. +This option is not compatible with the +.Cm rad +option that explicitly defines the source radiance distribution. +.El +.It Fl s Ar spectral_opt Ns Op : Ns Ar spectral_opt No ... +Configure spectral integration. +.Pp +The spectral integration options are as follows: +.Bl -tag -width Ds +.It Cm cie_xyz +Calculate the radiance for the visible part of the spectrum between +.Bq 380, 780 +nanometers using the XYZ CIE 1931 color matching functions. +This is the default behavior. +.It Cm lw= Ns Ar wlen_min , Ns Ar wlen_max +Calculate the radiance using the internal source of radiation, i.e. the +radiance emitted by the medium and its boundaries (ground and space). +.Pp +Calculations are performed between +.Bq Ar wlen_min , Ar wlen_max +nanometers according to Planck's function for a reference temperature +defined as the maximum ground temperature. +.Pp +If +.Ar wlen_min +and +.Ar wlen_max +are equal, the calculation is monochromatic. +.It Cm sw= Ns Ar wlen_min , Ns Ar wlen_max +Calculate the radiance using the external source of radiance +.Pq option Fl S . +.Pp +Calculations are performed between +.Bq Ar wlen_min , Ar wlen_max +nanometers according to the radiance distribution of the external +source +.Pq see Fl S No option +.Pp +If +.Ar wlen_min +and +.Ar wlen_max +are equal, the calculation is monochromatic. +.El +.It Fl T Ar optical_thickness +Optical thickness used as threshold criterion for building the acceleration +structures. +Default is @HTRDR_PLANETS_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@. +.It Fl t +Advice on the number of threads to use. +By default, +.Nm +uses many threads as processor cores. +.It Fl V Ar accel_struct_definition +Advice on the definition of the atmospheric acceleration structures. +Default is @HTRDR_PLANETS_ARGS_DEFAULT_GRID_DEFINITION_HINT@. +.It Fl v +Make +.Nm +verbose. +.El +.Sh OUTPUT IMAGE +Images calculated by +.Nm +are saved in +.Xr htrdr-image 5 +format. +This section describes the nature and arrangement of image data +depending on the type of calculation performed. +.Ss XYZ image +For an image rendering in the visible part of the spectrum +.Pq default behavior or option Fl s Cm cie_xyz , +the pixel components store 4 estimates. +The first, second, and third pairs of floating point values encode the +estimated integrated radiance in W/sr/m^2 for the X, Y, and Z components +of the CIE 1931 XYZ color space. +The first value of each pair is the expected value of the +average radiance of the pixel. +The second value is its associated standard deviation. +The fourth and final pair records the microsecond estimate of the +computation time per radiative path and its standard error. +.Ss Longwave image +For infrared calculations +.Pq option Fl s Cm lw= Ns Ar wlen_min , Ns Ar wlen_max +the first and second pixel components store the expected value and the +standard error of the estimated brightness temperature (in K), +respectively. +The third and fourth components record the expected value and the +standard deviation of the pixel radiance which is either an integrated +radiance in W/sr/m^2 or a spectral radiance in W/sr/m^2/nm depending on +whether this radiance was calculated for a spectral range or at a single +wavelength. +The fifth and sixth pixel components are not used. +Finally, the last 2 components of the pixel record the estimate in +microseconds of the computation time per radiative path and its standard +error. +.Ss Shortwave image +For shortwave calculations +.Pq option Fl s Cm sw= Ns Ar wlen_min , Ns Ar wlen_max +the output image is formatted as for a longwave image except that the +first and second components of the pixels are not used, as no brightness +temperature has been evaluated. +That is, the third and fourth values record the estimated radiance per +pixel and the seventh and eighth values store the estimate of the +calculation time by radiative path. +The other values are set to 0. +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +An +.Nm +command line can be lengthy due to the options required to describe the +system to be simulated. +For editing reasons, the command lines given as examples in this section +will take up several lines by using the backslash character +.Pq Li \e . +While there's nothing original about this practice, we'd like to +emphasize the importance of spaces or their absence before the backslash +character, particularly for options defining aerosols +.Pq option Fl a +or ground +.Pq option Fl G : +their argument must be a single character string with no spaces other +than those that may be required for file names. +.Pp +The following command line runs +.Nm +in a verbose way +.Pq option Fl v +to calculate an +.Ar 800 No by Ar 600 +pixel image by sampling +.Ar 64 +radiative paths per pixel +.Pq option Fl i +for the 3 components of the CIE 1931 XYZ color +space +.Pq option Fl s . +The external source is positioned at +.Ar -45 +degrees longitude and +.Ar 50 +degrees latitude relative to the absolute referential +.Pq option Fl S . +The camera +.Pq option Fl C +looks at the origin +.Pq Cm tgt= Ns Ar 0 , Ns Ar 0 , Ns Ar 0 +and is positioned at +.Ar 1.5e7 +meters along the Y axis with an image plane aligned along the Z axis +.Pq Cm up= Ns Ar 0 , Ns Ar 0 , Ns Ar 1 . +Its vertical field of view is +.Ar 70 +degrees. +The gas of the planetary atmosphere is described by the tetrahedral mesh +recorded in the +.Pa gas.smsh +file, while its spectral data and temperature are given by the files +.Pa gas.sck +and +.Pa gas.rngt , +respectively. +Two aerosols complete the planetary atmosphere: one for +.Ar clouds +and one for +.Ar haze . +Their respective meshes are stored in the +.Pa clouds_tetrahedra.smsh No and Pa haze_tetrahedra.smsh +files while their radiative properties are given by the +.Pa clouds_properties.sars No and Pa haze_properties.sars +files. +Finally, their phase functions are described by a set of 2 files: the +.Pa clouds_phase_functions.rnsf No and Pa haze_phase_functions.rnsf +files which list the aerosol phase functions, +and the +.Pa clouds_phase_function_ids.rnpfi No and Pa haze_phase_function_ids.rnpfi +files which reference them by volumetric mesh node. +To speed up rendering time, the normals of the tetrahedral meshes of +the gas and aerosols are precalculated once and for all +.Pq option Fl N . +The ground geometry is stored in the +.Pa ground_triangles.smsh +file with its triangle properties +.Pq temperature and BRDF +defined in the +.Pa ground_properties.rnsp +file. +The referenced BRDFs are listed in the +.Pa ground_brdfs.rnsl +file. +The definition of acceleration structures +cannot exceed +.Ar 512^3 +and its voxels can be merged until their optical thickness +is greater than +.Ar 10 . +These structures are either reloaded from +.Pa storage_cie.bin +or built from scratch and stored in +.Pa storage_cie.bin +depending on whether that file exists or not. +Finally, the calculated images are +stored in the +.Pa image_CIE_XYZ.ht +file even if the file already exists +.Pq options Fl fo : +.Bd -literal -offset Ds +htrdr-planets -v -N \\ + -i def=800x600:spp=64 \\ + -s cie_xyz \\ + -S lon=-45:lat=50:dst=1.5e8:radius=6.9e5:temp=5778 \\ + -C pos=0,1.5e7,0:tgt=0,0,0:up=0,0,1:fov=70 \\ + -g mesh=gas.smsh:ck=gas.sck:temp=gas.rngt \\ + -a name=clouds\\ +:mesh=clouds_tetrahedra.smsh\\ +:radprop=clouds_properties.sars\\ +:phasefn=clouds_phase_functions.rnsf\\ +:phaseids=clouds_phase_function_ids.rnpfi \\ + -a name=haze\\ +:mesh=haze_tetrahedra.smsh\\ +:radprop=haze_properties.sars\\ +:phasefn=haze_phase_functions.rnsf\\ +:phaseids=haze_phase_function_ids.rnpfi \\ + -G name=namek\\ +:mesh=ground_triangles.smsh\\ +:prop=ground_properties.rnsp\\ +:brdf=ground_brdfs.rnsl \\ + -V 512 -T 10 -O storage_cie.bin \\ + -fo image_CIE_XYZ.ht +.Ed +.Pp +The next command line is the same as the previous one, except that it calculates +an infrared image between +.Ar 10,000 +nm and +.Ar 20,000 +nm +.Pq option Fl s . +Note that the acceleration structure storage file is no longer the same +.Pq Pa storage_lw.bin No rather than Pa storage_cie.bin . +Indeed, the previous one records the acceleration structures for the +spectral range of the CIE 1931 XYZ color space +.Pq i.e. between Bo 380, 780 Bc nm , +while one wants to store/reload the acceleration structures for a +spectral range between 10 and 20 microns. +In any case, if the previous storage had been submitted, the command +would have stopped with an error message, thus avoiding the use of the +wrong acceleration structures +.Pq see Fl O No option . +.Bd -literal -offset Ds +htrdr-planets -v -N \\ + -i def=800x600:spp=64 \\ + -s lw=10000,20000 \\ + -C pos=0,1.5e7,0:tgt=0,0,0:up=0,0,1:fov=70 \\ + -g mesh=gas.smsh:ck=gas.sck:temp=gas.rngt \\ + -a name=clouds\\ +:mesh=clouds_tetrahedra.smsh\\ +:radprop=clouds_properties.sars\\ +:phasefn=clouds_phase_functions.rnsf\\ +:phaseids=clouds_phase_function_ids.rnpfi \\ + -a name=haze\\ +:mesh=haze_tetrahedra.smsh\\ +:radprop=haze_properties.sars\\ +:phasefn=haze_phase_functions.rnsf\\ +:phaseids=haze_phase_function_ids.rnpfi \\ + -G name=namek\\ +:mesh=ground_triangles.smsh\\ +:prop=ground_properties.rnsp\\ +:brdf=ground_brdfs.rnsl \\ + -V 512 -T 10 -O storage_lw.bin \\ + -fo image_infrared.ht +.Ed +.Sh SEE ALSO +.Xr htrdr-image 5 , +.Xr mrumtl 5 , +.Xr rngt 5 , +.Xr rnpfi 5 , +.Xr rnrl 5 , +.Xr rnsf 5 , +.Xr sars 5 , +.Xr sck 5 , +.Xr smsh 5 +.Sh STANDARDS +.Rs +.%A International Organization for Standardization / CIE +.%R ISO/CIE 11664-1:2019 +.%D June 2019 +.%T Colorimetry - Part 1: CIE standard colorimetric observers +.Re +.Pp +.Rs +.%A OpenMP Architecture Review Board +.%D March 2002 +.%T OpenMP C and C++ Application Interface +.%O version 2.0 +.Re +.Pp +.Rs +.%A Message Passing Interface Forum +.%D July 1997 +.%T MPI-2: Extensions to The Message-Passing Interface +.Re +.Sh HISTORY +.Nm +has been developed as part of +.Li ANR-21-CE49-0020 +RaD-net project. diff --git a/doc/htrdr.1 b/doc/htrdr.1 @@ -1,12 +1,12 @@ -.\" Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +.\" Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique .\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -.\" Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -.\" Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -.\" Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -.\" Copyright (C) 2022-2023 Observatoire de Paris -.\" Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -.\" Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -.\" Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier +.\" Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +.\" Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2022-2024 Observatoire de Paris +.\" Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +.\" Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +.\" Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier .\" .\" This program is free software: you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by diff --git a/doc/rnrl.5 b/doc/rnrl.5 @@ -1,12 +1,12 @@ -.\" Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +.\" Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique .\" Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -.\" Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -.\" Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -.\" Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -.\" Copyright (C) 2022-2023 Observatoire de Paris -.\" Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -.\" Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -.\" Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier +.\" Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +.\" Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +.\" Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +.\" Copyright (C) 2022-2024 Observatoire de Paris +.\" Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +.\" Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +.\" Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier .\" .\" This program is free software: you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by diff --git a/htrdr-planeto.pc.in b/htrdr-planeto.pc.in @@ -1,18 +0,0 @@ -# Used for local building only -Requires: rsys >= @RSYS_VERSION@ -Requires.private:\ - htrdr-core >= @VERSION@,\ - rnatm > @RNATM_VERSION@,\ - rngrd > @RNGRD_VERSION@,\ - s3d >= @S3D_VERSION@,\ - sbuf >= @SBUF_VERSION@,\ - scam >= @SCAM_VERSION@,\ - ssf >= @SSF_VERSION@,\ - star-sp >= @SSP_VERSION@,\ - svx >= @SVX_VERSION@ -Name: htrdr-planeto -Description: htrdr Planeto -Version: @VERSION@ -Libs: -L. -lhtrdr-planeto -Libs.private: -lm -CFlags: -DHTRDR_BUILD_PLANETO -Isrc diff --git a/htrdr-planets.pc.in b/htrdr-planets.pc.in @@ -0,0 +1,18 @@ +# Used for local building only +Requires: rsys >= @RSYS_VERSION@ +Requires.private:\ + htrdr-core >= @VERSION@,\ + rnatm > @RNATM_VERSION@,\ + rngrd > @RNGRD_VERSION@,\ + s3d >= @S3D_VERSION@,\ + sbuf >= @SBUF_VERSION@,\ + scam >= @SCAM_VERSION@,\ + ssf >= @SSF_VERSION@,\ + star-sp >= @SSP_VERSION@,\ + svx >= @SVX_VERSION@ +Name: htrdr-planets +Description: htrdr Planets +Version: @VERSION@ +Libs: -L. -lhtrdr-planets +Libs.private: -lm +CFlags: -DHTRDR_BUILD_PLANETS -Isrc diff --git a/install.sh b/install.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique +# Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux +# Copyright (C) 2022-2024 Institut Pierre-Simon Laplace +# Copyright (C) 2022-2024 Institut de Physique du Globe de Paris +# Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) +# Copyright (C) 2022-2024 Observatoire de Paris +# Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne +# Copyright (C) 2022-2024 Université de Versaille Saint-Quentin +# Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +set -e + +mode=$1 +prefix=$2 +shift 2 + +mkdir -p "${prefix}" + +for i in "$@"; do + dst="${prefix}/${i##*/}" + + if cmp -s "${i}" "${dst}"; then + printf 'Up to date %s\n' "${dst}" + else + printf 'Installing %s\n' "${dst}" + cp "${i}" "${prefix}" + chmod "${mode}" "${prefix}/$(basename "${i}")" + fi +done diff --git a/make.sh b/make.sh @@ -1,47 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique -# Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux -# Copyright (C) 2022-2023 Institut Pierre-Simon Laplace -# Copyright (C) 2022-2023 Institut de Physique du Globe de Paris -# Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) -# Copyright (C) 2022-2023 Observatoire de Paris -# Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne -# Copyright (C) 2022-2023 Université de Versaille Saint-Quentin -# Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -set -e - -install() -{ - prefix=$1 - shift 1 - - mkdir -p "${prefix}" - - for i in "$@"; do - dst="${prefix}/${i##*/}" - - if cmp -s "${i}" "${dst}"; then - printf "Up to date %s\n" "${dst}" - else - printf "Installing %s\n" "${dst}" - cp "${i}" "${prefix}" - fi - done -} - -"$@" diff --git a/src/atmosphere/htrdr_atmosphere.c b/src/atmosphere/htrdr_atmosphere.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere.h b/src/atmosphere/htrdr_atmosphere.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_args.c b/src/atmosphere/htrdr_atmosphere_args.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_args.h.in b/src/atmosphere/htrdr_atmosphere_args.h.in @@ -1,10 +1,10 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_c.h b/src/atmosphere/htrdr_atmosphere_c.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_compute_radiance_lw.c b/src/atmosphere/htrdr_atmosphere_compute_radiance_lw.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_compute_radiance_sw.c b/src/atmosphere/htrdr_atmosphere_compute_radiance_sw.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_draw_map.c b/src/atmosphere/htrdr_atmosphere_draw_map.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_ground.c b/src/atmosphere/htrdr_atmosphere_ground.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_ground.h b/src/atmosphere/htrdr_atmosphere_ground.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_main.c b/src/atmosphere/htrdr_atmosphere_main.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_sun.c b/src/atmosphere/htrdr_atmosphere_sun.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/atmosphere/htrdr_atmosphere_sun.h b/src/atmosphere/htrdr_atmosphere_sun.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion.c b/src/combustion/htrdr_combustion.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion.h b/src/combustion/htrdr_combustion.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_args.c b/src/combustion/htrdr_combustion_args.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_args.h.in b/src/combustion/htrdr_combustion_args.h.in @@ -1,10 +1,10 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_c.h b/src/combustion/htrdr_combustion_c.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_compute_radiance_sw.c b/src/combustion/htrdr_combustion_compute_radiance_sw.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_draw_map.c b/src/combustion/htrdr_combustion_draw_map.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_geometry_ray_filter.c b/src/combustion/htrdr_combustion_geometry_ray_filter.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_geometry_ray_filter.h b/src/combustion/htrdr_combustion_geometry_ray_filter.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_laser.c b/src/combustion/htrdr_combustion_laser.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_laser.h b/src/combustion/htrdr_combustion_laser.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_main.c b/src/combustion/htrdr_combustion_main.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/htrdr_combustion_phase_func.c b/src/combustion/htrdr_combustion_phase_func.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/combustion/test_htrdr_combustion_laser.c b/src/combustion/test_htrdr_combustion_laser.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/commands/htrdr_atmosphere_cmd.c b/src/commands/htrdr_atmosphere_cmd.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/commands/htrdr_cmd.c b/src/commands/htrdr_cmd.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,8 +27,8 @@ #ifdef HTRDR_BUILD_COMBUSTION #include "combustion/htrdr_combustion.h" #endif -#ifdef HTRDR_BUILD_PLANETO - #include "planeto/htrdr_planeto.h" +#ifdef HTRDR_BUILD_PLANETS + #include "planets/htrdr_planets.h" #endif #include "core/htrdr_log.h" @@ -85,13 +85,13 @@ main(int argc, char** argv) #endif /* Planeto mode */ - } else if(!strcmp(argv[1], "planeto")) { -#ifdef HTRDR_BUILD_PLANETO - err = htrdr_planeto_main(argc-1, argv+1); + } else if(!strcmp(argv[1], "planets")) { +#ifdef HTRDR_BUILD_PLANETS + err = htrdr_planets_main(argc-1, argv+1); if(err) goto error; #else fprintf(stderr, - "The planeto mode is not available in this htrdr build.\n"); + "The planets mode is not available in this htrdr build.\n"); err = 1; goto error; #endif diff --git a/src/commands/htrdr_combustion_cmd.c b/src/commands/htrdr_combustion_cmd.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/commands/htrdr_planeto_cmd.c b/src/commands/htrdr_planeto_cmd.c @@ -1,41 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HTRDR_BUILD_PLANETO - #include "planeto/htrdr_planeto.h" -#else - #include <stdio.h> -#endif - -int -main(int argc, char** argv) -{ -#ifdef HTRDR_BUILD_PLANETO - return htrdr_planeto_main(argc, argv); -#else - (void)argc, (void)argv; - fprintf(stderr, - "The htrdr-planeto command is not available in this htrdr build.\n"); - return 1; -#endif -} diff --git a/src/commands/htrdr_planets_cmd.c b/src/commands/htrdr_planets_cmd.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HTRDR_BUILD_PLANETS + #include "planets/htrdr_planets.h" +#else + #include <stdio.h> +#endif + +int +main(int argc, char** argv) +{ +#ifdef HTRDR_BUILD_PLANETS + return htrdr_planets_main(argc, argv); +#else + (void)argc, (void)argv; + fprintf(stderr, + "The htrdr-planets command is not available in this htrdr build.\n"); + return 1; +#endif +} diff --git a/src/core/htrdr.c b/src/core/htrdr.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr.h b/src/core/htrdr.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,13 +64,13 @@ htrdr_fprint_copyright(const char* cmd, FILE* stream) { (void)cmd; fprintf(stream, -"Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique\n" +"Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique\n" "Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux\n" -"Copyright (C) 2022-2023 Institut de Physique du Globe de Paris\n" -"Copyright (C) 2018-2023 |Méso|Star> <contact@meso-star.com>\n" -"Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne\n" -"Copyright (C) 2022-2023 Université de Versaille Saint-Quentin\n" -"Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier\n"); +"Copyright (C) 2022-2024 Institut de Physique du Globe de Paris\n" +"Copyright (C) 2018-2024 |Méso|Star> <contact@meso-star.com>\n" +"Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne\n" +"Copyright (C) 2022-2024 Université de Versaille Saint-Quentin\n" +"Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier\n"); } static INLINE void diff --git a/src/core/htrdr_accum.h b/src/core/htrdr_accum.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_args.c b/src/core/htrdr_args.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -215,7 +215,7 @@ parse_image_parameter(const char* str, void* args) #undef PARSE if(!img->definition[0] || !img->definition[1]) { - fprintf(stderr, "The image definition cannot be null.n"); + fprintf(stderr, "The image definition cannot be null.\n"); res = RES_BAD_ARG; goto error; } @@ -561,6 +561,8 @@ htrdr_args_camera_perspective_parse goto error; } + *cam = HTRDR_ARGS_CAMERA_PERSPECTIVE_DEFAULT; + res = cstr_parse_list(str, ':', parse_camera_perspective_parameter, cam); if(res != RES_OK) goto error; diff --git a/src/core/htrdr_args.h.in b/src/core/htrdr_args.h.in @@ -1,10 +1,10 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_buffer.c b/src/core/htrdr_buffer.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_buffer.h b/src/core/htrdr_buffer.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_c.h b/src/core/htrdr_c.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_draw_map.c b/src/core/htrdr_draw_map.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_draw_map.h b/src/core/htrdr_draw_map.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_geometry.c b/src/core/htrdr_geometry.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_geometry.h b/src/core/htrdr_geometry.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_interface.h b/src/core/htrdr_interface.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_log.c b/src/core/htrdr_log.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_log.h b/src/core/htrdr_log.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_materials.c b/src/core/htrdr_materials.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_materials.h b/src/core/htrdr_materials.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_ran_wlen_cie_xyz.c b/src/core/htrdr_ran_wlen_cie_xyz.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_ran_wlen_cie_xyz.h b/src/core/htrdr_ran_wlen_cie_xyz.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_ran_wlen_discrete.c b/src/core/htrdr_ran_wlen_discrete.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_ran_wlen_discrete.h b/src/core/htrdr_ran_wlen_discrete.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_ran_wlen_planck.c b/src/core/htrdr_ran_wlen_planck.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_ran_wlen_planck.h b/src/core/htrdr_ran_wlen_planck.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_rectangle.c b/src/core/htrdr_rectangle.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_rectangle.h b/src/core/htrdr_rectangle.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_sensor.h b/src/core/htrdr_sensor.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_slab.c b/src/core/htrdr_slab.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_slab.h b/src/core/htrdr_slab.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_spectral.c b/src/core/htrdr_spectral.c @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_spectral.h b/src/core/htrdr_spectral.h @@ -1,12 +1,12 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/htrdr_version.h.in b/src/core/htrdr_version.h.in @@ -1,10 +1,10 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/planeto/htrdr_planeto.c b/src/planeto/htrdr_planeto.c @@ -1,595 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#define _POSIX_C_SOURCE 200112L /* fdopen, nextafter, rint */ - -#include "core/htrdr.h" -#include "core/htrdr_ran_wlen_cie_xyz.h" -#include "core/htrdr_ran_wlen_discrete.h" -#include "core/htrdr_ran_wlen_planck.h" -#include "core/htrdr_log.h" - -#include "planeto/htrdr_planeto.h" -#include "planeto/htrdr_planeto_args.h" -#include "planeto/htrdr_planeto_c.h" -#include "planeto/htrdr_planeto_source.h" - -#include <rad-net/rnatm.h> -#include <rad-net/rngrd.h> - -#include <star/scam.h> - -#include <rsys/cstr.h> -#include <rsys/double3.h> -#include <rsys/mem_allocator.h> - -#include <fcntl.h> /* open */ -#include <math.h> /* nextafter, rint */ -#include <unistd.h> /* close */ -#include <sys/stat.h> - -/******************************************************************************* - * Helper function - ******************************************************************************/ -/* Calculate the number of fixed size spectral intervals to use for the - * cumulative */ -static size_t -compute_nintervals_for_spectral_cdf(const struct htrdr_planeto* cmd) -{ - double range_size; - size_t nintervals; - ASSERT(cmd); - - range_size = - cmd->spectral_domain.wlen_range[1] - - cmd->spectral_domain.wlen_range[0]; - - /* Initially assume ~one interval per nanometer */ - nintervals = (size_t)rint(range_size); - - return nintervals; -} - -static res_T -setup_octree_storage - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args, - struct rnatm_create_args* rnatm_args) -{ - struct stat file_stat; - int fd = -1; - int err = 0; - res_T res = RES_OK; - ASSERT(cmd && args && rnatm_args); - - rnatm_args->octrees_storage = NULL; - rnatm_args->load_octrees_from_storage = 0; - - if(!args->octrees_storage) goto exit; - - fd = open(args->octrees_storage, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); - if(fd < 0) { res = RES_IO_ERR; goto error; } - - rnatm_args->octrees_storage = fdopen(fd, "w+"); - if(!rnatm_args->octrees_storage) { res = RES_IO_ERR; goto error; } - - /* From now on, manage the opened file from its pointer and not from its - * descriptor */ - fd = -1; - - err = stat(args->octrees_storage, &file_stat); - if(err < 0) { res = RES_IO_ERR; goto error; } - - if(file_stat.st_size != 0) { - /* The file is not empty and therefore must contain valid octrees */ - rnatm_args->load_octrees_from_storage = 1; - } - -exit: - cmd->octrees_storage = rnatm_args->octrees_storage; - return res; -error: - htrdr_log_err(cmd->htrdr, "error opening the octree storage `%s' -- %s\n", - args->octrees_storage, res_to_cstr(res)); - - if(fd >= 0) CHK(close(fd) == 0); - if(rnatm_args->octrees_storage) CHK(fclose(rnatm_args->octrees_storage) == 0); - rnatm_args->octrees_storage = NULL; - rnatm_args->load_octrees_from_storage = 1; - goto exit; -} - -static res_T -setup_atmosphere - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args) -{ - struct rnatm_create_args rnatm_args = RNATM_CREATE_ARGS_DEFAULT; - res_T res = RES_OK; - ASSERT(cmd && args); - - rnatm_args.gas = args->gas; - rnatm_args.aerosols = args->aerosols; - rnatm_args.naerosols = args->naerosols; - rnatm_args.name = "atmosphere"; - rnatm_args.spectral_range[0] = args->spectral_domain.wlen_range[0]; - rnatm_args.spectral_range[1] = args->spectral_domain.wlen_range[1]; - rnatm_args.optical_thickness = args->optical_thickness; - rnatm_args.grid_definition_hint = args->octree_definition_hint; - rnatm_args.precompute_normals = args->precompute_normals; - rnatm_args.logger = htrdr_get_logger(cmd->htrdr); - rnatm_args.allocator = htrdr_get_allocator(cmd->htrdr); - rnatm_args.nthreads = args->nthreads; - rnatm_args.verbose = args->verbose; - - res = setup_octree_storage(cmd, args, &rnatm_args); - if(res != RES_OK) goto error; - - res = rnatm_create(&rnatm_args, &cmd->atmosphere); - if(res != RES_OK) goto error; - -exit: - return res; -error: - if(cmd->atmosphere) { - RNATM(ref_put(cmd->atmosphere)); - cmd->atmosphere = NULL; - } - goto exit; -} - -static res_T -setup_ground - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args) -{ - struct rngrd_create_args rngrd_args = RNGRD_CREATE_ARGS_DEFAULT; - res_T res = RES_OK; - ASSERT(cmd && args); - - if(cmd->output_type == HTRDR_PLANETO_ARGS_OUTPUT_OCTREES) - goto exit; - - rngrd_args.smsh_filename = args->ground.smsh_filename; - rngrd_args.props_filename = args->ground.props_filename; - rngrd_args.mtllst_filename = args->ground.mtllst_filename; - rngrd_args.name = args->ground.name; - rngrd_args.logger = htrdr_get_logger(cmd->htrdr); - rngrd_args.allocator = htrdr_get_allocator(cmd->htrdr); - rngrd_args.verbose = args->verbose; - - res = rngrd_create(&rngrd_args, &cmd->ground); - if(res != RES_OK) goto error; - -exit: - return res; -error: - if(cmd->ground) { - RNGRD(ref_put(cmd->ground)); - cmd->ground = NULL; - } - goto exit; -} - -static res_T -setup_spectral_domain_sw - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args) -{ - res_T res = RES_OK; - ASSERT(cmd && args); - ASSERT(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW); - - /* Discrete distribution */ - if(args->source.rnrl_filename) { - struct htrdr_planeto_source_spectrum spectrum; - struct htrdr_ran_wlen_discrete_create_args discrete_args; - - res = htrdr_planeto_source_get_spectrum - (cmd->source, cmd->spectral_domain.wlen_range, &spectrum); - if(res != RES_OK) goto error; - - discrete_args.get = htrdr_planeto_source_spectrum_at; - discrete_args.nwavelengths = spectrum.size; - discrete_args.context = &spectrum; - res = htrdr_ran_wlen_discrete_create - (cmd->htrdr, &discrete_args, &cmd->discrete); - if(res != RES_OK) goto error; - - /* Planck distribution */ - } else { - const size_t nintervals = compute_nintervals_for_spectral_cdf(cmd); - - /* Use the source temperature as the reference temperature of the Planck - * distribution */ - res = htrdr_ran_wlen_planck_create(cmd->htrdr, - cmd->spectral_domain.wlen_range, nintervals, args->source.temperature, - &cmd->planck); - if(res != RES_OK) goto error; - } - -exit: - return res; -error: - goto exit; -} - -static INLINE res_T -setup_spectral_domain - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args) -{ - double ground_T_range[2]; - size_t nintervals; - res_T res = RES_OK; - ASSERT(cmd && args); - - cmd->spectral_domain = args->spectral_domain; - - /* Configure the spectral distribution */ - switch(cmd->spectral_domain.type) { - - case HTRDR_SPECTRAL_LW: - res = rngrd_get_temperature_range(cmd->ground, ground_T_range); - if(res != RES_OK) goto error; - - /* Use as the reference temperature of the Planck distribution the - * maximum scene temperature which, in fact, should be the maximum ground - * temperature */ - nintervals = compute_nintervals_for_spectral_cdf(cmd); - res = htrdr_ran_wlen_planck_create(cmd->htrdr, - cmd->spectral_domain.wlen_range, nintervals, ground_T_range[1], - &cmd->planck); - if(res != RES_OK) goto error; - break; - - case HTRDR_SPECTRAL_SW: - res = setup_spectral_domain_sw(cmd, args); - if(res != RES_OK) goto error; - break; - - case HTRDR_SPECTRAL_SW_CIE_XYZ: - /* CIE XYZ distribution */ - nintervals = compute_nintervals_for_spectral_cdf(cmd); - res = htrdr_ran_wlen_cie_xyz_create(cmd->htrdr, - cmd->spectral_domain.wlen_range, nintervals, &cmd->cie); - if(res != RES_OK) goto error; - break; - - default: FATAL("Unreachable code\n"); break; - } - -exit: - return res; -error: - goto exit; -} - -static res_T -setup_output - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args) -{ - const char* output_name = NULL; - res_T res = RES_OK; - ASSERT(cmd && args); - - /* No output stream on non master processes */ - if(htrdr_get_mpi_rank(cmd->htrdr) != 0) { - cmd->output = NULL; - output_name = "<null>"; - - /* Write results on stdout */ - } else if(!args->output) { - cmd->output = stdout; - output_name = "<stdout>"; - - /* Open the output stream */ - } else { - res = htrdr_open_output_stream(cmd->htrdr, args->output, 0/*read*/, - args->force_output_overwrite, &cmd->output); - if(res != RES_OK) goto error; - output_name = args->output; - } - - res = str_set(&cmd->output_name, output_name); - if(res != RES_OK) { - htrdr_log_err(cmd->htrdr, "error storing output stream name `%s' -- %s\n", - output_name, res_to_cstr(res)); - goto error; - } - - cmd->output_type = args->output_type; - -exit: - return res; -error: - str_clear(&cmd->output_name); - if(cmd->output && cmd->output != stdout) { - CHK(fclose(cmd->output) == 0); - cmd->output = NULL; - } - goto exit; -} - -static INLINE res_T -setup_source - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args) -{ - res_T res = RES_OK; - ASSERT(cmd && args); - - if(cmd->output_type == HTRDR_PLANETO_ARGS_OUTPUT_OCTREES) - goto exit; - - res = htrdr_planeto_source_create(cmd->htrdr, &args->source, &cmd->source); - if(res != RES_OK) goto error; - -exit: - return res; -error: - goto exit; -} - -static res_T -setup_camera - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args) -{ - struct scam_perspective_args cam_args = SCAM_PERSPECTIVE_ARGS_DEFAULT; - res_T res = RES_OK; - ASSERT(cmd && args); - - if(cmd->output_type != HTRDR_PLANETO_ARGS_OUTPUT_IMAGE) - goto exit; - - ASSERT(htrdr_args_camera_perspective_check(&args->cam_persp) == RES_OK); - ASSERT(htrdr_args_image_check(&args->image) == RES_OK); - - d3_set(cam_args.position, args->cam_persp.position); - d3_set(cam_args.target, args->cam_persp.target); - d3_set(cam_args.up, args->cam_persp.up); - cam_args.field_of_view = MDEG2RAD(args->cam_persp.fov_y); - cam_args.lens_radius = args->cam_persp.lens_radius; - cam_args.focal_distance = args->cam_persp.focal_dst; - cam_args.aspect_ratio = - (double)args->image.definition[0] - / (double)args->image.definition[1]; - - res = scam_create_perspective - (htrdr_get_logger(cmd->htrdr), - htrdr_get_allocator(cmd->htrdr), - htrdr_get_verbosity_level(cmd->htrdr), - &cam_args, - &cmd->camera); - if(res != RES_OK) goto error; - -exit: - return res; -error: - goto exit; -} - -static res_T -setup_buffer - (struct htrdr_planeto* cmd, - const struct htrdr_planeto_args* args) -{ - struct htrdr_pixel_format pixfmt = HTRDR_PIXEL_FORMAT_NULL; - res_T res = RES_OK; - ASSERT(cmd && args); - - if(cmd->output_type != HTRDR_PLANETO_ARGS_OUTPUT_IMAGE) - goto exit; - - planeto_get_pixel_format(cmd, &pixfmt); - - /* Setup buffer layout */ - cmd->buf_layout.width = args->image.definition[0]; - cmd->buf_layout.height = args->image.definition[1]; - cmd->buf_layout.pitch = args->image.definition[0] * pixfmt.size; - cmd->buf_layout.elmt_size = pixfmt.size; - cmd->buf_layout.alignment = pixfmt.alignment; - - /* Save the number of samples per pixel */ - cmd->spp = args->image.spp; - - /* Create the image buffer only on the master process; Image parts rendered - * by other processes are collected there */ - if(htrdr_get_mpi_rank(cmd->htrdr) != 0) goto exit; - - res = htrdr_buffer_create(cmd->htrdr, &cmd->buf_layout, &cmd->buf); - if(res != RES_OK) goto error; - -exit: - return res; -error: - if(cmd->buf) { htrdr_buffer_ref_put(cmd->buf); cmd->buf = NULL; } - goto exit; -} - -static INLINE res_T -write_vtk_octrees(const struct htrdr_planeto* cmd) -{ - size_t octrees_range[2]; - res_T res = RES_OK; - ASSERT(cmd); - - /* Nothing to do on non master process */ - if(htrdr_get_mpi_rank(cmd->htrdr) != 0) goto exit; - - octrees_range[0] = 0; - octrees_range[1] = rnatm_get_spectral_items_count(cmd->atmosphere) - 1; - - res = rnatm_write_vtk_octrees(cmd->atmosphere, octrees_range, cmd->output); - if(res != RES_OK) goto error; - -exit: - return res; -error: - goto exit; -} - -static void -planeto_release(ref_T* ref) -{ - struct htrdr_planeto* cmd = CONTAINER_OF(ref, struct htrdr_planeto, ref); - struct htrdr* htrdr = NULL; - ASSERT(ref); - - if(cmd->atmosphere) RNATM(ref_put(cmd->atmosphere)); - if(cmd->ground) RNGRD(ref_put(cmd->ground)); - if(cmd->source) htrdr_planeto_source_ref_put(cmd->source); - if(cmd->cie) htrdr_ran_wlen_cie_xyz_ref_put(cmd->cie); - if(cmd->discrete) htrdr_ran_wlen_discrete_ref_put(cmd->discrete); - if(cmd->planck) htrdr_ran_wlen_planck_ref_put(cmd->planck); - if(cmd->octrees_storage) CHK(fclose(cmd->octrees_storage) == 0); - if(cmd->output && cmd->output != stdout) CHK(fclose(cmd->output) == 0); - if(cmd->buf) htrdr_buffer_ref_put(cmd->buf); - if(cmd->camera) SCAM(ref_put(cmd->camera)); - str_release(&cmd->output_name); - - htrdr = cmd->htrdr; - MEM_RM(htrdr_get_allocator(htrdr), cmd); - htrdr_ref_put(htrdr); -} - -/******************************************************************************* - * Exported functions - ******************************************************************************/ -res_T -htrdr_planeto_create - (struct htrdr* htrdr, - const struct htrdr_planeto_args* args, - struct htrdr_planeto** out_cmd) -{ - struct htrdr_planeto* cmd = NULL; - res_T res = RES_OK; - ASSERT(htrdr && out_cmd); - - res = htrdr_planeto_args_check(args); - if(res != RES_OK) { - htrdr_log_err(htrdr, "Invalid htrdr_planeto arguments -- %s\n", - res_to_cstr(res)); - goto error; - } - - cmd = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*cmd)); - if(!cmd) { - htrdr_log_err(htrdr, "Error allocating htrdr_planeto command\n"); - res = RES_MEM_ERR; - goto error; - } - ref_init(&cmd->ref); - htrdr_ref_get(htrdr); - cmd->htrdr = htrdr; - str_init(htrdr_get_allocator(htrdr), &cmd->output_name); - - res = setup_output(cmd, args); - if(res != RES_OK) goto error; - res = setup_source(cmd, args); - if(res != RES_OK) goto error; - res = setup_camera(cmd, args); - if(res != RES_OK) goto error; - res = setup_ground(cmd, args); - if(res != RES_OK) goto error; - res = setup_atmosphere(cmd, args); - if(res != RES_OK) goto error; - res = setup_spectral_domain(cmd, args); - if(res != RES_OK) goto error; - res = setup_buffer(cmd, args); - if(res != RES_OK) goto error; - -exit: - *out_cmd = cmd; - return res; -error: - if(cmd) { - htrdr_planeto_ref_put(cmd); - cmd = NULL; - } - goto exit; -} - -void -htrdr_planeto_ref_get(struct htrdr_planeto* cmd) -{ - ASSERT(cmd); - ref_get(&cmd->ref); -} - -void -htrdr_planeto_ref_put(struct htrdr_planeto* cmd) -{ - ASSERT(cmd); - ref_put(&cmd->ref, planeto_release); -} - -res_T -htrdr_planeto_run(struct htrdr_planeto* cmd) -{ - res_T res = RES_OK; - ASSERT(cmd); - - switch(cmd->output_type) { - case HTRDR_PLANETO_ARGS_OUTPUT_IMAGE: - res = planeto_draw_map(cmd); - break; - case HTRDR_PLANETO_ARGS_OUTPUT_OCTREES: - res = write_vtk_octrees(cmd); - break; - default: FATAL("Unreachable code\n"); break; - } - if(res != RES_OK) goto error; - -exit: - return res; -error: - goto exit; -} - -/******************************************************************************* - * Local function - ******************************************************************************/ -void -planeto_get_pixel_format - (const struct htrdr_planeto* cmd, - struct htrdr_pixel_format* fmt) -{ - ASSERT(cmd && fmt && cmd->output_type == HTRDR_PLANETO_ARGS_OUTPUT_IMAGE); - (void)cmd; - - switch(cmd->spectral_domain.type) { - case HTRDR_SPECTRAL_LW: - case HTRDR_SPECTRAL_SW: - fmt->size = sizeof(struct planeto_pixel_xwave); - fmt->alignment = ALIGNOF(struct planeto_pixel_xwave); - break; - case HTRDR_SPECTRAL_SW_CIE_XYZ: - fmt->size = sizeof(struct planeto_pixel_image); - fmt->alignment = ALIGNOF(struct planeto_pixel_image); - break; - default: FATAL("Unreachable code\n"); break; - } -} diff --git a/src/planeto/htrdr_planeto.h b/src/planeto/htrdr_planeto.h @@ -1,61 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef HTRDR_PLANETO_H -#define HTRDR_PLANETO_H - -#include "core/htrdr.h" -#include <rsys/rsys.h> - -struct htrdr; -struct htrdr_planeto; -struct htrdr_planeto_args; - -BEGIN_DECLS - -HTRDR_API res_T -htrdr_planeto_create - (struct htrdr* htrdr, - const struct htrdr_planeto_args* args, - struct htrdr_planeto** cmd); - -HTRDR_API void -htrdr_planeto_ref_get - (struct htrdr_planeto* cmd); - -HTRDR_API void -htrdr_planeto_ref_put - (struct htrdr_planeto* cmd); - -HTRDR_API res_T -htrdr_planeto_run - (struct htrdr_planeto* cmd); - -HTRDR_API int -htrdr_planeto_main - (int argc, - char** argv); - -END_DECLS - -#endif /* HTRDR_PLANETO_H */ diff --git a/src/planeto/htrdr_planeto_args.c b/src/planeto/htrdr_planeto_args.c @@ -1,734 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#define _POSIX_C_SOURCE 200112L /* strtok_r support */ - -#include "planeto/htrdr_planeto_args.h" - -#include <rsys/cstr.h> -#include <rsys/stretchy_array.h> -#include <rsys/mem_allocator.h> - -#include <getopt.h> -#include <string.h> - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static INLINE res_T -check_gas_args(const struct rnatm_gas_args* args) -{ - if(!args) return RES_BAD_ARG; - - /* Filenames cannot be NULL */ - if(!args->smsh_filename - || !args->sck_filename - || !args->temperatures_filename) - return RES_BAD_ARG; - - return RES_OK; -} - -static INLINE res_T -check_aerosol_args(const struct rnatm_aerosol_args* args) -{ - if(!args) return RES_BAD_ARG; - - /* Filenames cannot be NULL */ - if(!args->smsh_filename - || !args->sars_filename - || !args->phase_fn_ids_filename - || !args->phase_fn_lst_filename) - return RES_BAD_ARG; - - return RES_OK; -} - -static INLINE res_T -check_ground_args(const struct htrdr_planeto_ground_args* args) -{ - if(!args) return RES_BAD_ARG; - - /* Filenames cannot be NULL */ - if(!args->smsh_filename - || !args->props_filename - || !args->mtllst_filename) - return RES_BAD_ARG; - - return RES_OK; -} - -static INLINE res_T -check_spectral_args(const struct htrdr_planeto_spectral_args* args) -{ - if(!args) return RES_BAD_ARG; - - /* Invalid type */ - switch(args->type) { - case HTRDR_SPECTRAL_LW: - case HTRDR_SPECTRAL_SW: - case HTRDR_SPECTRAL_SW_CIE_XYZ: - /* Nothing to be done */ - break; - default: - return RES_BAD_ARG; - } - - /* Invalid spectral range */ - if(args->wlen_range[0] < 0 - || args->wlen_range[1] < 0 - || args->wlen_range[0] > args->wlen_range[1]) - return RES_BAD_ARG; - - return RES_OK; -} -static void -usage(void) -{ - printf("usage: htrdr-planeto [-dfhNv] [-a aerosol_opt[:aerosol_opt ...]]\n"); - printf(" [-C persp_camera_opt[:persp_camera_opt ...]]\n"); - printf(" [-G ground_opt[:ground_opt ...]]\n"); - printf(" [-i image_opt[:image_opt ...]] [-O accel_struct_storage]\n"); - printf(" [-o output] [-S source_opt[:source_opt ...]]\n"); - printf(" [-s spectral_opt[:spectral_opt ...]] [-T optical_thickness]\n"); - printf(" [-t threads_count] [-V accel_struct_definition]\n"); - printf(" -g gas_opt[:gas_opt ...] \n"); -} - -static INLINE char* -str_dup(const char* str) -{ - size_t len = 0; - char* dup = NULL; - ASSERT(str); - len = strlen(str) + 1/*NULL char*/; - dup = mem_alloc(len); - if(!dup) { - return NULL; - } else { - return memcpy(dup, str, len); - } -} - -static res_T -parse_aerosol_parameters(const char* str, void* ptr) -{ - enum { MESH, NAME, RADPROP, PHASEFN, PHASEIDS } iparam; - struct rnatm_aerosol_args* aerosol = NULL; - char buf[BUFSIZ]; - struct htrdr_planeto_args* args = ptr; - char* key; - char* val; - char* tk_ctx; - res_T res = RES_OK; - ASSERT(args && str); - - if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { - fprintf(stderr, "Could not duplicate the aerosol parameter `%s'\n", str); - res = RES_MEM_ERR; - goto error; - } - strncpy(buf, str, sizeof(buf)); - - key = strtok_r(buf, "=", &tk_ctx); - val = strtok_r(NULL, "", &tk_ctx); - - if(!strcmp(key, "mesh")) iparam = MESH; - else if(!strcmp(key, "name")) iparam = NAME; - else if(!strcmp(key, "radprop")) iparam = RADPROP; - else if(!strcmp(key, "phasefn")) iparam = PHASEFN; - else if(!strcmp(key, "phaseids")) iparam = PHASEIDS; - else { - fprintf(stderr, "Invalid aerosol parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - if(!val) { - fprintf(stderr, "Invalid null value for aerosol parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - ASSERT(args->naerosols); - aerosol = args->aerosols + (args->naerosols - 1); - - #define SET_STR(Dst) { \ - if(Dst) mem_rm(Dst); \ - if(!((Dst) = str_dup(val))) res = RES_MEM_ERR; \ - } (void)0 - switch(iparam) { - case MESH: SET_STR(aerosol->smsh_filename); break; - case NAME: SET_STR(aerosol->name); break; - case RADPROP: SET_STR(aerosol->sars_filename); break; - case PHASEFN: SET_STR(aerosol->phase_fn_lst_filename); break; - case PHASEIDS: SET_STR(aerosol->phase_fn_ids_filename); break; - default: FATAL("Unreachable code\n"); break; - } - #undef SET_STR - if(res != RES_OK) { - fprintf(stderr, "Unable to parse the aerosol parameter `%s' -- %s\n", - str, res_to_cstr(res)); - goto error; - } - -exit: - return res; -error: - goto exit; -} - -static res_T -parse_ground_parameters(const char* str, void* ptr) -{ - enum { BRDF, MESH, NAME, PROP } iparam; - char buf[BUFSIZ]; - struct htrdr_planeto_args* args = ptr; - char* key; - char* val; - char* tk_ctx; - res_T res = RES_OK; - ASSERT(args && str); - - if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { - fprintf(stderr, "Could not duplicate the ground parameter `%s'\n", str); - res = RES_MEM_ERR; - goto error; - } - strncpy(buf, str, sizeof(buf)); - - key = strtok_r(buf, "=", &tk_ctx); - val = strtok_r(NULL, "", &tk_ctx); - - if(!strcmp(key, "brdf")) iparam = BRDF; - else if(!strcmp(key, "mesh")) iparam = MESH; - else if(!strcmp(key, "name")) iparam = NAME; - else if(!strcmp(key, "prop")) iparam = PROP; - else { - fprintf(stderr, "Invalid ground parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - if(!val) { - fprintf(stderr, "Invalid null value for ground parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - #define SET_STR(Dst) { \ - if(Dst) mem_rm(Dst); \ - if(!((Dst) = str_dup(val))) res = RES_MEM_ERR; \ - } (void)0 - switch(iparam) { - case BRDF: SET_STR(args->ground.mtllst_filename); break; - case MESH: SET_STR(args->ground.smsh_filename); break; - case NAME: SET_STR(args->ground.name); break; - case PROP: SET_STR(args->ground.props_filename); break; - default: FATAL("Unreachable code\n"); break; - } - #undef SET_STR - if(res != RES_OK) { - fprintf(stderr, "Unable to parse the ground parameter `%s' -- %s\n", - str, res_to_cstr(res)); - goto error; - } - -exit: - return res; -error: - goto exit; -} - -static res_T -parse_gas_parameters(const char* str, void* ptr) -{ - enum { MESH, CK, TEMP } iparam; - char buf[BUFSIZ]; - struct htrdr_planeto_args* args = ptr; - char* key; - char* val; - char* tk_ctx; - res_T res = RES_OK; - ASSERT(args && str); - - if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { - fprintf(stderr, "Could not duplicate the gas parameter `%s'\n", str); - res = RES_MEM_ERR; - goto error; - } - strncpy(buf, str, sizeof(buf)); - - key = strtok_r(buf, "=", &tk_ctx); - val = strtok_r(NULL, "", &tk_ctx); - - if(!strcmp(key, "mesh")) iparam = MESH; - else if(!strcmp(key, "ck")) iparam = CK; - else if(!strcmp(key, "temp")) iparam = TEMP; - else { - fprintf(stderr, "Invalid gas parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - if(!val) { - fprintf(stderr, "Invalid null value for gas parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - #define SET_STR(Dst) { \ - if(Dst) mem_rm(Dst); \ - if(!((Dst) = str_dup(val))) res = RES_MEM_ERR; \ - } (void)0 - switch(iparam) { - case MESH: SET_STR(args->gas.smsh_filename); break; - case CK: SET_STR(args->gas.sck_filename); break; - case TEMP: SET_STR(args->gas.temperatures_filename); break; - default: FATAL("Unreachable code\n"); break; - } - #undef SET_STR - if(res != RES_OK) { - fprintf(stderr, "Unable to parse the gas parameter `%s' -- %s\n", - str, res_to_cstr(res)); - goto error; - } - -exit: - return res; -error: - goto exit; -} - -static res_T -parse_source_parameters(const char* str, void* ptr) -{ - enum {LAT, LON, DST, RADIUS, TEMP, RAD} iparam; - char buf[BUFSIZ]; - struct htrdr_planeto_args* args = ptr; - struct htrdr_planeto_source_args* src = NULL; - char* key; - char* val; - char* tk_ctx; - res_T res = RES_OK; - ASSERT(str && ptr); - - src = &args->source; - - if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { - fprintf(stderr, "Could not duplicate the source parameter `%s'\n", str); - res = RES_MEM_ERR; - goto error; - } - strncpy(buf, str, sizeof(buf)); - - key = strtok_r(buf, "=", &tk_ctx); - val = strtok_r(NULL, "", &tk_ctx); - - if(!strcmp(key, "lat")) iparam = LAT; - else if(!strcmp(key, "lon")) iparam = LON; - else if(!strcmp(key, "dst")) iparam = DST; - else if(!strcmp(key, "rad")) iparam = RAD; - else if(!strcmp(key, "radius")) iparam = RADIUS; - else if(!strcmp(key, "temp")) iparam = TEMP; - else { - fprintf(stderr, "Invalid source parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - if(!val) { - fprintf(stderr, "Invalid null value for the source parameter`%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - switch(iparam) { - case LAT: - res = cstr_to_double(val, &src->latitude); - if(res == RES_OK && (src->latitude < -90 || src->latitude > 90)) { - res = RES_BAD_ARG; - } - break; - case LON: - res = cstr_to_double(val, &src->longitude); - if(res == RES_OK && (src->longitude < -180 || src->longitude > 180)) { - res = RES_BAD_ARG; - } - break; - case DST: - res = cstr_to_double(val, &src->distance); - if(res == RES_OK && src->distance < 0) res = RES_BAD_ARG; - break; - case RAD: - /* Use a per wavelength radiance rather than a constant temperature */ - src->temperature = -1; - if(src->rnrl_filename) mem_rm(src->rnrl_filename); - src->rnrl_filename = str_dup(val); - if(!src->rnrl_filename) res = RES_MEM_ERR; - break; - case RADIUS: - res = cstr_to_double(val, &src->radius); - if(res == RES_OK && src->radius < 0) res = RES_BAD_ARG; - break; - case TEMP: - /* Use a constant temperature rather than a per wavelength radiance */ - if(src->rnrl_filename) { - mem_rm(src->rnrl_filename); - src->rnrl_filename = NULL; - } - res = cstr_to_double(val, &src->temperature); - if(res == RES_OK && src->temperature < 0) res = RES_BAD_ARG; - break; - default: FATAL("Unreachable code\n"); break; - } - if(res != RES_OK) { - fprintf(stderr, "Unable to parse the source parameter `%s' -- %s\n", - str, res_to_cstr(res)); - goto error; - } - -exit: - return res; -error: - goto exit; -} - -static INLINE res_T -parse_spectral_range(const char* str, double wlen_range[2]) -{ - double range[2]; - size_t len; - res_T res = RES_OK; - ASSERT(wlen_range && str); - - res = cstr_to_list_double(str, ',', range, &len, 2); - if(res == RES_OK && len != 2) res = RES_BAD_ARG; - if(res == RES_OK && range[0] > range[1]) res = RES_BAD_ARG; - if(res == RES_OK && (range[0] < 0 || range[1] < 0)) res = RES_BAD_ARG; - if(res != RES_OK) goto error; - - wlen_range[0] = range[0]; - wlen_range[1] = range[1]; - -exit: - return res; -error: - goto exit; -} - -static res_T -parse_spectral_parameters(const char* str, void* ptr) -{ - enum {CIE_XYZ, LW, SW} iparam; - char buf[BUFSIZ]; - struct htrdr_planeto_args* args = ptr; - struct htrdr_planeto_spectral_args* spectral = NULL; - char* key; - char* val; - char* tk_ctx; - res_T res = RES_OK; - ASSERT(str && ptr); - - spectral = &args->spectral_domain; - - if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { - fprintf(stderr, "Could not duplicate the spectral parameter `%s'\n", str); - res = RES_MEM_ERR; - goto error; - } - strncpy(buf, str, sizeof(buf)); - - key = strtok_r(buf, "=", &tk_ctx); - val = strtok_r(NULL, "", &tk_ctx); - - if(!strcmp(key, "cie_xyz")) iparam = CIE_XYZ; - else if(!strcmp(key, "lw")) iparam = LW; - else if(!strcmp(key, "sw")) iparam = SW; - else { - fprintf(stderr, "Invalid spectral parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - if((iparam == LW || iparam == SW) && !val) { - fprintf(stderr, - "Invalid null value for the spectral parameter `%s'\n", key); - res = RES_BAD_ARG; - goto error; - } - - switch(iparam) { - case CIE_XYZ: - spectral->type = HTRDR_SPECTRAL_SW_CIE_XYZ; - spectral->wlen_range[0] = HTRDR_RAN_WLEN_CIE_XYZ_RANGE_DEFAULT[0]; - spectral->wlen_range[1] = HTRDR_RAN_WLEN_CIE_XYZ_RANGE_DEFAULT[1]; - break; - case LW: - spectral->type = HTRDR_SPECTRAL_LW; - res = parse_spectral_range(val, spectral->wlen_range); - break; - case SW: - spectral->type = HTRDR_SPECTRAL_SW; - res = parse_spectral_range(val, spectral->wlen_range); - break; - default: FATAL("Unreachable code\n"); break; - } - if(res != RES_OK) { - fprintf(stderr, "Unable to parse the spectral parameter `%s' -- %s\n", - str, res_to_cstr(res)); - goto error; - } - -exit: - return res; -error: - goto exit; -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -htrdr_planeto_args_init(struct htrdr_planeto_args* args, int argc, char** argv) -{ - int opt; - res_T res = RES_OK; - ASSERT(args && argc && argv); - - *args = HTRDR_PLANETO_ARGS_DEFAULT; - - while((opt = getopt(argc, argv, "a:C:dfG:g:hi:NO:o:S:s:T:t:V:v")) != -1) { - switch(opt) { - case 'a': - (void)sa_add(args->aerosols, 1); - args->aerosols[args->naerosols] = RNATM_AEROSOL_ARGS_NULL; - args->naerosols += 1; - res = cstr_parse_list(optarg, ':', parse_aerosol_parameters, args); - if(res == RES_OK) { - res = check_aerosol_args(args->aerosols+args->naerosols-1); - } - break; - case 'C': - res = htrdr_args_camera_perspective_parse(&args->cam_persp, optarg); - args->output_type = HTRDR_PLANETO_ARGS_OUTPUT_IMAGE; - break; - case 'd': - args->output_type = HTRDR_PLANETO_ARGS_OUTPUT_OCTREES; - break; - case 'f': - args->force_output_overwrite = 1; - break; - case 'G': - res = cstr_parse_list(optarg, ':', parse_ground_parameters, args); - if(res == RES_OK) { - res = check_ground_args(&args->ground); - } - break; - case 'g': - res = cstr_parse_list(optarg, ':', parse_gas_parameters, args); - if(res == RES_OK) { - res = check_gas_args(&args->gas); - } - break; - case 'h': - usage(); - htrdr_planeto_args_release(args); - args->quit = 1; - goto exit; - case 'i': - res = htrdr_args_image_parse(&args->image, optarg); - break; - case 'N': args->precompute_normals = 1; break; - case 'O': args->octrees_storage = optarg; break; - case 'o': args->output = optarg; break; - case 'S': - res = cstr_parse_list(optarg, ':', parse_source_parameters, args); - break; - case 's': - res = cstr_parse_list(optarg, ':', parse_spectral_parameters, args); - break; - case 'T': - res = cstr_to_double(optarg, &args->optical_thickness); - if(res != RES_OK && args->optical_thickness < 0) res = RES_BAD_ARG; - break; - case 't': - res = cstr_to_uint(optarg, &args->nthreads); - if(res != RES_OK && !args->nthreads) res = RES_BAD_ARG; - break; - case 'V': - res = cstr_to_uint(optarg, &args->octree_definition_hint); - if(res != RES_OK && !args->octree_definition_hint) res = RES_BAD_ARG; - break; - case 'v': args->verbose = 1; break; - default: res = RES_BAD_ARG; break; - } - if(res != RES_OK) { - if(optarg) { - fprintf(stderr, "%s: invalid option argument '%s' -- '%c'\n", - argv[0], optarg, opt); - } - goto error; - } - } - - res = check_gas_args(&args->gas); - if(res != RES_OK) { - fprintf(stderr, "missing gas definition -- option '-g'\n"); - goto error; - } - - if(args->output_type != HTRDR_PLANETO_ARGS_OUTPUT_OCTREES) { - res = check_ground_args(&args->ground); - if(res != RES_OK) { - fprintf(stderr, "missing ground definition -- option '-G'\n"); - goto error; - } - - /* Check the source */ - if(args->spectral_domain.type == HTRDR_SPECTRAL_SW - || args->spectral_domain.type == HTRDR_SPECTRAL_SW_CIE_XYZ) { - res = htrdr_planeto_source_args_check(&args->source); - if(res != RES_OK) { - fprintf(stderr, "missing source definition -- option '-S'\n"); - goto error; - } - } - } - -exit: - return res; -error: - usage(); - htrdr_planeto_args_release(args); - goto exit; -} - -void -htrdr_planeto_args_release(struct htrdr_planeto_args* args) -{ - size_t i; - ASSERT(args); - - if(args->gas.smsh_filename) mem_rm(args->gas.smsh_filename); - if(args->gas.sck_filename) mem_rm(args->gas.sck_filename); - if(args->gas.temperatures_filename) mem_rm(args->gas.temperatures_filename); - if(args->ground.smsh_filename) mem_rm(args->ground.smsh_filename); - if(args->ground.props_filename) mem_rm(args->ground.props_filename); - if(args->ground.mtllst_filename) mem_rm(args->ground.mtllst_filename); - if(args->ground.name) mem_rm(args->ground.name); - if(args->source.rnrl_filename) mem_rm(args->source.rnrl_filename); - - FOR_EACH(i, 0, args->naerosols) { - struct rnatm_aerosol_args* aerosol = args->aerosols + i; - if(aerosol->name) mem_rm(aerosol->name); - if(aerosol->smsh_filename) mem_rm(aerosol->smsh_filename); - if(aerosol->sars_filename) mem_rm(aerosol->sars_filename); - if(aerosol->phase_fn_ids_filename) mem_rm(aerosol->phase_fn_ids_filename); - if(aerosol->phase_fn_lst_filename) mem_rm(aerosol->phase_fn_lst_filename); - } - sa_release(args->aerosols); - - *args = HTRDR_PLANETO_ARGS_DEFAULT; -} - -res_T -htrdr_planeto_args_check(const struct htrdr_planeto_args* args) -{ - size_t i; - res_T res = RES_OK; - - if(!args) return RES_BAD_ARG; - - /* Check the gas */ - res = check_gas_args(&args->gas); - if(res != RES_OK) return res; - - /* Check the aerosols */ - FOR_EACH(i, 0, args->naerosols) { - res = check_aerosol_args(args->aerosols+i); - if(res != RES_OK) return res; - } - - /* Check the octree parameters */ - if(args->octree_definition_hint == 0 - || args->optical_thickness < 0) - return RES_BAD_ARG; - - /* Check the spectral domain */ - res = check_spectral_args(&args->spectral_domain); - if(res != RES_OK) return res; - - if(args->output_type != HTRDR_PLANETO_ARGS_OUTPUT_OCTREES) { - /* Check the ground */ - res = check_ground_args(&args->ground); - if(res != RES_OK) return res; - - /* Check the source */ - if(args->spectral_domain.type == HTRDR_SPECTRAL_SW - || args->spectral_domain.type == HTRDR_SPECTRAL_SW_CIE_XYZ) { - res = htrdr_planeto_source_args_check(&args->source); - if(res != RES_OK) return res; - } - } - - if(args->output_type != HTRDR_PLANETO_ARGS_OUTPUT_IMAGE) { - res = htrdr_args_camera_perspective_check(&args->cam_persp); - if(res != RES_OK) return res; - - res = htrdr_args_image_check(&args->image); - if(res != RES_OK) return res; - } - - /* Check miscalleneous parameters */ - if(args->nthreads == 0 - || (unsigned)args->output_type >= HTRDR_PLANETO_ARGS_OUTPUT_TYPES_COUNT__) - return RES_BAD_ARG; - - return RES_OK; -} - -res_T -htrdr_planeto_source_args_check(const struct htrdr_planeto_source_args* args) -{ - if(!args) return RES_BAD_ARG; - - /* Invalid position */ - if(args->latitude <-90 - || args->latitude > 90 - || args->longitude <-180 - || args->longitude > 180 - || args->distance < 0) - return RES_BAD_ARG; - - /* Invalid radius */ - if(args->radius < 0) - return RES_BAD_ARG; - - /* Invalid radiance */ - if((args->temperature < 0 && !args->rnrl_filename) /* Both are invalids */ - || (args->temperature >=0 && args->rnrl_filename)) /* Both are valids */ - return RES_BAD_ARG; - - return RES_OK; -} diff --git a/src/planeto/htrdr_planeto_args.h.in b/src/planeto/htrdr_planeto_args.h.in @@ -1,148 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef HTRDR_PLANETO_ARGS_H -#define HTRDR_PLANETO_ARGS_H - -#include "core/htrdr_args.h" - -#include <rad-net/rnatm.h> -#include <rsys/rsys.h> - -#include <limits.h> /* UINT_MAX */ - -enum htrdr_planeto_args_output_type { - HTRDR_PLANETO_ARGS_OUTPUT_IMAGE, - HTRDR_PLANETO_ARGS_OUTPUT_OCTREES, - HTRDR_PLANETO_ARGS_OUTPUT_TYPES_COUNT__ -}; - -struct htrdr_planeto_spectral_args { - double wlen_range[2]; /* Spectral range in nm */ - enum htrdr_spectral_type type; -}; -#define HTRDR_PLANETO_SPECTRAL_ARGS_DEFAULT__ { \ - HTRDR_RAN_WLEN_CIE_XYZ_RANGE_DEFAULT__, /* Spectral range */ \ - HTRDR_SPECTRAL_SW_CIE_XYZ, /* Spectral type */ \ -} -static const struct htrdr_planeto_spectral_args -HTRDR_PLANETO_SPECTRAL_ARGS_DEFAULT = HTRDR_PLANETO_SPECTRAL_ARGS_DEFAULT__; - -struct htrdr_planeto_source_args { - /* Radiance of the source per wavelength. May be NULL */ - char* rnrl_filename; - - double longitude; /* In [-180, 180] degrees */ - double latitude; /* In [-90, 90] degrees */ - double distance; /* In km */ - double radius; /* In km */ - double temperature; /* In Kelvin */ -}; -#define HTRDR_PLANETO_SOURCE_ARGS_NULL__ {NULL,0,0,0,-1,-1} -static const struct htrdr_planeto_source_args HTRDR_PLANETO_SOURCE_ARGS_NULL = - HTRDR_PLANETO_SOURCE_ARGS_NULL__; - -struct htrdr_planeto_ground_args { - char* smsh_filename; /* The Star-Mesh geometry */ - char* props_filename; /* Per triangle physical properties */ - char* mtllst_filename; /* List of used materials */ - char* name; -}; -#define HTRDR_PLANETO_GROUND_ARGS_NULL__ {NULL,NULL,NULL,NULL} -static const struct htrdr_planeto_ground_args HTRDR_PLANETO_GROUND_ARGS_NULL = - HTRDR_PLANETO_GROUND_ARGS_NULL__; - -struct htrdr_planeto_args { - /* System data */ - struct rnatm_gas_args gas; - struct rnatm_aerosol_args* aerosols; - size_t naerosols; - struct htrdr_planeto_ground_args ground; - - /* Read/Write file where octrees are stored. May be NULL => octres are built - * at runtime and kept in memory */ - char* octrees_storage; - - unsigned octree_definition_hint; /* Hint on octree definition */ - double optical_thickness; /* Threshold used during octree building */ - - char* output; /* File where the result is written */ - struct htrdr_planeto_spectral_args spectral_domain; /* Integration spectral domain */ - struct htrdr_planeto_source_args source; - struct htrdr_args_image image; - - struct htrdr_args_camera_perspective cam_persp; /* Perspective camera */ - - /* Miscellaneous arguments */ - unsigned nthreads; /* Hint on the nimber of threads to use */ - enum htrdr_planeto_args_output_type output_type; - int precompute_normals; /* Pre-compute tetrahedron normals */ - int force_output_overwrite; /* Replace output if it exists */ - int verbose; /* Verbose level */ - int quit; /* Stop the command */ -}; -#define HTRDR_PLANETO_ARGS_DEFAULT__ { \ - RNATM_GAS_ARGS_NULL__, /* Gas */ \ - NULL, /* List of aerosols */ \ - 0, /* Number of aerosols */ \ - HTRDR_PLANETO_GROUND_ARGS_NULL__, /* Ground */ \ - \ - NULL, /* File where to dump octrees */ \ - \ - @HTRDR_PLANETO_ARGS_DEFAULT_GRID_DEFINITION_HINT@, /* octree definition */ \ - @HTRDR_PLANETO_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@, \ - \ - NULL, /* Ouput file */ \ - HTRDR_PLANETO_SPECTRAL_ARGS_DEFAULT__, /* Spectral domain */ \ - HTRDR_PLANETO_SOURCE_ARGS_NULL__, /* Source */ \ - HTRDR_ARGS_IMAGE_DEFAULT__, /* Image */ \ - \ - HTRDR_ARGS_CAMERA_PERSPECTIVE_DEFAULT__, /* Perspective camera */ \ - \ - UINT_MAX, /* Number of threads */ \ - HTRDR_PLANETO_ARGS_OUTPUT_IMAGE, \ - 0, /* Force output overwrite */ \ - 0, /* Precompute normals */ \ - 0, /* Verbosity level */ \ - 0 /* Stop the command */ \ -} -static const struct htrdr_planeto_args HTRDR_PLANETO_ARGS_DEFAULT = - HTRDR_PLANETO_ARGS_DEFAULT__; - -extern LOCAL_SYM res_T -htrdr_planeto_args_init - (struct htrdr_planeto_args* args, - int argc, - char** argv); - -extern LOCAL_SYM void -htrdr_planeto_args_release - (struct htrdr_planeto_args* args); - -extern LOCAL_SYM res_T -htrdr_planeto_args_check - (const struct htrdr_planeto_args* args); - -extern LOCAL_SYM res_T -htrdr_planeto_source_args_check - (const struct htrdr_planeto_source_args* args); - -#endif /* HTRDR_PLANETO_ARGS_H */ diff --git a/src/planeto/htrdr_planeto_c.h b/src/planeto/htrdr_planeto_c.h @@ -1,127 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef HTRDR_PLANETO_C_H -#define HTRDR_PLANETO_C_H - -#include "planeto/htrdr_planeto_args.h" - -#include "core/htrdr_accum.h" -#include "core/htrdr_args.h" -#include "core/htrdr_buffer.h" - -#include <rsys/ref_count.h> -#include <rsys/str.h> - -/* Forward declarations */ -struct htrdr; -struct htrdr_pixel_format; -struct htrdr_ran_wlen_cie_xyz; -struct htrdr_ran_wlen_planck; -struct rnatm; -struct rngrd; -struct scam; - -struct planeto_pixel_xwave { - struct htrdr_accum radiance; /* In W/m²/sr */ - struct htrdr_accum time; /* In µs */ - struct htrdr_estimate radiance_temperature; /* In W/m²/sr */ -}; -#define PLANETO_PIXEL_XWAVE_NULL__ { \ - HTRDR_ACCUM_NULL__, \ - HTRDR_ACCUM_NULL__, \ - HTRDR_ESTIMATE_NULL__ \ -} -static const struct planeto_pixel_xwave PLANETO_PIXEL_XWAVE_NULL = - PLANETO_PIXEL_XWAVE_NULL__; - -struct planeto_pixel_image { - struct htrdr_estimate X; /* In W/m²/sr */ - struct htrdr_estimate Y; /* In W/m²/sr */ - struct htrdr_estimate Z; /* In W/m²/sr */ - struct htrdr_accum time; /* In µs */ -}; -#define PLANETO_PIXEL_IMAGE_NULL__ { \ - HTRDR_ESTIMATE_NULL__, \ - HTRDR_ESTIMATE_NULL__, \ - HTRDR_ESTIMATE_NULL__, \ - HTRDR_ACCUM_NULL__ \ -} - -struct planeto_compute_radiance_args { - struct ssp_rng* rng; - size_t ithread; /* Index of the thread executing the function */ - - double path_org[3]; /* Origin of the path to trace */ - double path_dir[3]; /* Initial direction of the path to trace */ - - double wlen; /* In nm */ - size_t iband; /* Spectral band index */ - size_t iquad; /* Quadrature point */ -}; -#define PLANETO_COMPUTE_RADIANCE_ARGS_NULL__ {NULL, 0, {0,0,0}, {0,0,0}, 0, 0, 0} -static const struct planeto_compute_radiance_args -PLANETO_COMPUTE_RADIANCE_ARGS_NULL = PLANETO_COMPUTE_RADIANCE_ARGS_NULL__; - -struct htrdr_planeto { - struct rnatm* atmosphere; - struct rngrd* ground; - struct htrdr_planeto_source* source; - - struct htrdr_planeto_spectral_args spectral_domain; - struct htrdr_ran_wlen_cie_xyz* cie; /* HTRDR_SPECTRAL_SW_CIE_XYZ */ - struct htrdr_ran_wlen_planck* planck; /* HTRDR_SPECTRAL_<LW|SW> */ - struct htrdr_ran_wlen_discrete* discrete; /* HTRDR_SPECTRAL_SW */ - - FILE* octrees_storage; - - FILE* output; - struct str output_name; - enum htrdr_planeto_args_output_type output_type; - - struct scam* camera; - - struct htrdr_buffer_layout buf_layout; - struct htrdr_buffer* buf; /* NULL on non master processes */ - size_t spp; /* Samples per pixel */ - - ref_T ref; - struct htrdr* htrdr; -}; - -extern LOCAL_SYM res_T -planeto_draw_map - (struct htrdr_planeto* cmd); - -extern LOCAL_SYM void -planeto_get_pixel_format - (const struct htrdr_planeto* cmd, - struct htrdr_pixel_format* fmt); - -/* Return the radiance in W/m²/sr/m */ -extern LOCAL_SYM double -planeto_compute_radiance - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args); - -#endif /* HTRDR_PLANETO_C_H */ diff --git a/src/planeto/htrdr_planeto_compute_radiance.c b/src/planeto/htrdr_planeto_compute_radiance.c @@ -1,671 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "planeto/htrdr_planeto_c.h" -#include "planeto/htrdr_planeto_source.h" - -#include <rad-net/rnatm.h> -#include <rad-net/rngrd.h> - -#include <star/s3d.h> -#include <star/ssf.h> -#include <star/ssp.h> -#include <star/suvm.h> -#include <star/svx.h> - -#include <rsys/double2.h> -#include <rsys/double3.h> - -/* Syntactic sugar */ -#define DISTANCE_NONE(Dst) ((Dst) >= FLT_MAX) -#define SURFACE_EVENT(Event) (!S3D_HIT_NONE(&(Event)->hit)) - -struct event { - /* Set to S3D_HIT_NULL if the event occurs in volume.*/ - struct s3d_hit hit; - - /* The surface normal is defined only if event is on the surface. It is - * normalized and looks towards the incoming direction */ - double normal[3]; - - /* Cells in which the event position is located. It makes sense only for an - * event in volume */ - struct rnatm_cell_pos cells[RNATM_MAX_COMPONENTS_COUNT]; - - double distance; /* Distance from ray origin to scattering position */ -}; -#define EVENT_NULL__ { \ - S3D_HIT_NULL__, {0,0,0}, {RNATM_CELL_POS_NULL__}, DBL_MAX \ -} -static const struct event EVENT_NULL = EVENT_NULL__; - -/* Arguments of the filtering function used to sample a position */ -struct sample_distance_context { - struct ssp_rng* rng; - struct rnatm* atmosphere; - size_t iband; - size_t iquad; - double wavelength; /* In nm */ - enum rnatm_radcoef radcoef; - double Ts; /* Sample optical thickness */ - - /* Output data */ - struct rnatm_cell_pos* cells; - double distance; -}; -#define SAMPLE_DISTANCE_CONTEXT_NULL__ { \ - NULL, NULL, 0, 0, 0, RNATM_RADCOEFS_COUNT__, 0, NULL, DBL_MAX \ -} -static const struct sample_distance_context SAMPLE_DISTANCE_CONTEXT_NULL = - SAMPLE_DISTANCE_CONTEXT_NULL__; - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static INLINE res_T -check_planeto_compute_radiance_args - (const struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args) -{ - struct rnatm_band_desc band = RNATM_BAND_DESC_NULL; - res_T res = RES_OK; - - if(!args || !args->rng) - return RES_BAD_ARG; - - /* Invalid thread index */ - if(args->ithread >= htrdr_get_threads_count(cmd->htrdr)) - return RES_BAD_ARG; - - /* Invalid input direction */ - if(!d3_is_normalized(args->path_dir)) - return RES_BAD_ARG; - - /* Invalid wavelength */ - if(args->wlen < cmd->spectral_domain.wlen_range[0] - || args->wlen > cmd->spectral_domain.wlen_range[1]) - return RES_BAD_ARG; - - res = rnatm_band_get_desc(cmd->atmosphere, args->iband, &band); - if(res != RES_OK) return res; - - /* Inconsistent spectral dimension */ - if(args->wlen < band.lower - || args->wlen >= band.upper /* Exclusive */ - || args->iquad >= band.quad_pts_count) - return RES_BAD_ARG; - - return RES_OK; -} - -static int -sample_position_hit_filter - (const struct svx_hit* hit, - const double org[3], - const double dir[3], - const double range[2], - void* context) -{ - struct rnatm_get_radcoef_args get_k_args = RNATM_GET_RADCOEF_ARGS_NULL; - struct sample_distance_context* ctx = context; - double k_min = 0; - double k_max = 0; - double dst_travelled = 0; - int pursue_traversal = 1; - ASSERT(hit && org && range && context); - (void)range; - - dst_travelled = hit->distance[0]; - - /* Get the k_min, k_max of the voxel */ - k_min = rnatm_get_k_svx_voxel - (ctx->atmosphere, &hit->voxel, ctx->radcoef, RNATM_SVX_OP_MIN); - k_max = rnatm_get_k_svx_voxel - (ctx->atmosphere, &hit->voxel, ctx->radcoef, RNATM_SVX_OP_MAX); - - /* Configure the common input arguments to retrieve the radiative coefficient - * of a given position */ - get_k_args.cells = ctx->cells; - get_k_args.iband = ctx->iband; - get_k_args.iquad = ctx->iquad; - get_k_args.radcoef = ctx->radcoef; - get_k_args.k_min = k_min; - get_k_args.k_max = k_max; - - for(;;) { - /* Compute the optical thickness of the voxel */ - const double vox_dst = hit->distance[1] - dst_travelled; - const double T = vox_dst * k_max; - - /* A collision occurs behind the voxel */ - if(ctx->Ts > T) { - ctx->Ts -= T; - pursue_traversal = 1; - break; - - /* A collision occurs in the voxel */ - } else { - const double vox_dst_collision = ctx->Ts / k_max; - double pos[3]; - double k, r; - - /* Calculate the distance travelled to the collision to be queried */ - dst_travelled += vox_dst_collision; - - /* Retrieve the radiative coefficient at the collision position */ - pos[0] = org[0] + dst_travelled * dir[0]; - pos[1] = org[1] + dst_travelled * dir[1]; - pos[2] = org[2] + dst_travelled * dir[2]; - RNATM(fetch_cell_list(ctx->atmosphere, pos, get_k_args.cells, NULL)); - RNATM(get_radcoef(ctx->atmosphere, &get_k_args, &k)); - - r = ssp_rng_canonical(ctx->rng); - - /* Null collision */ - if(r > k/k_max) { - ctx->Ts = ssp_ran_exp(ctx->rng, 1); - - /* Real collision */ - } else { - ctx->distance = dst_travelled; - pursue_traversal = 0; - break; - } - } - } - - return pursue_traversal; -} - -static double -sample_distance - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - struct rnatm_cell_pos* cells, - const enum rnatm_radcoef radcoef, - const double pos[3], - const double dir[3], - const double range[2]) -{ - struct rnatm_trace_ray_args rt = RNATM_TRACE_RAY_ARGS_NULL; - struct sample_distance_context ctx = SAMPLE_DISTANCE_CONTEXT_NULL; - struct svx_hit hit; - ASSERT(cmd && args && cells && pos && dir && d3_is_normalized(dir) && range); - ASSERT((unsigned)radcoef < RNATM_RADCOEFS_COUNT__); - ASSERT(range[0] < range[1]); - - /* Sample an optical thickness */ - ctx.Ts = ssp_ran_exp(args->rng, 1); - - /* Setup the remaining arguments of the RT context */ - ctx.rng = args->rng; - ctx.atmosphere = cmd->atmosphere; - ctx.iband = args->iband; - ctx.iquad = args->iquad; - ctx.wavelength = args->wlen; - ctx.radcoef = radcoef; - ctx.cells = cells; - - /* Trace the ray into the atmosphere */ - d3_set(rt.ray_org, pos); - d3_set(rt.ray_dir, dir); - rt.ray_range[0] = range[0]; - rt.ray_range[1] = range[1]; - rt.filter = sample_position_hit_filter; - rt.context = &ctx; - rt.iband = args->iband; - rt.iquad = args->iquad; - RNATM(trace_ray(cmd->atmosphere, &rt, &hit)); - - if(SVX_HIT_NONE(&hit)) { /* No collision found */ - return INF; - } else { /* A (real) collision occured */ - return ctx.distance; - } -} - -static INLINE double -transmissivity - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - const enum rnatm_radcoef radcoef, - const double pos[3], - const double dir[3], - const double range_max) -{ - struct rnatm_cell_pos cells[RNATM_MAX_COMPONENTS_COUNT]; - double range[2]; - double dst = 0; - ASSERT(range_max >= 0); - - range[0] = 0; - range[1] = range_max; - dst = sample_distance(cmd, args, cells, radcoef, pos, dir, range); - - if(DISTANCE_NONE(dst)) { - return 1.0; /* No collision in the medium */ - } else { - return 0.0; /* A (real) collision occurs */ - } -} - -static double -direct_contribution - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - const double pos[3], - const double dir[3], - const struct s3d_hit* hit_from) -{ - struct rngrd_trace_ray_args rt = RNGRD_TRACE_RAY_ARGS_DEFAULT; - struct s3d_hit hit; - double Tr; - double Ld; - double src_dst; - ASSERT(cmd && args && pos && dir); - - /* Is the source hidden? */ - d3_set(rt.ray_org, pos); - d3_set(rt.ray_dir, dir); - if(hit_from) rt.hit_from = *hit_from; - RNGRD(trace_ray(cmd->ground, &rt, &hit)); - if(!S3D_HIT_NONE(&hit)) return 0; - - /* Calculate the distance between the source and `pos' */ - src_dst = htrdr_planeto_source_distance_to(cmd->source, pos); - ASSERT(src_dst >= 0); - - Tr = transmissivity(cmd, args, RNATM_RADCOEF_Kext, pos, dir, src_dst); - Ld = htrdr_planeto_source_get_radiance(cmd->source, args->wlen); - return Ld * Tr; -} - -static void -find_event - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - const enum rnatm_radcoef radcoef, - const double pos[3], - const double dir[3], - const struct s3d_hit* hit_from, - struct event* evt) -{ - struct rngrd_trace_ray_args rt = RNGRD_TRACE_RAY_ARGS_DEFAULT; - struct s3d_hit hit; - double range[2]; - double dst; - ASSERT(cmd && args && pos && dir && hit_from && evt); - - *evt = EVENT_NULL; - - /* Look for a surface intersection */ - d3_set(rt.ray_org, pos); - d3_set(rt.ray_dir, dir); - d2(rt.ray_range, 0, INF); - rt.hit_from = *hit_from; - RNGRD(trace_ray(cmd->ground, &rt, &hit)); - - /* Look for an atmospheric collision */ - range[0] = 0; - range[1] = hit.distance; - dst = sample_distance(cmd, args, evt->cells, radcoef, pos, dir, range); - - /* Event occurs in volume */ - if(!DISTANCE_NONE(dst)) { - evt->distance = dst; - evt->hit = S3D_HIT_NULL; - - /* Event is on surface */ - } else if(!S3D_HIT_NONE(&hit)) { - /* Normalize the normal and ensure that it points to `dir' */ - d3_normalize(evt->normal, d3_set_f3(evt->normal, hit.normal)); - if(d3_dot(evt->normal, dir) > 0) d3_minus(evt->normal, evt->normal); - - evt->distance = hit.distance; - evt->hit = hit; - - /* No event */ - } else { - evt->distance = INF; - evt->hit = S3D_HIT_NULL; - } -} - -static INLINE struct ssf_bsdf* -create_bsdf - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - const struct s3d_hit* hit) -{ - struct rngrd_create_bsdf_args bsdf_args = RNGRD_CREATE_BSDF_ARGS_NULL; - struct ssf_bsdf* bsdf = NULL; - ASSERT(!S3D_HIT_NONE(hit)); - - /* Retrieve the BSDF at the intersected surface position */ - bsdf_args.prim = hit->prim; - bsdf_args.barycentric_coords[0] = hit->uv[0]; - bsdf_args.barycentric_coords[1] = hit->uv[1]; - bsdf_args.barycentric_coords[2] = 1 - hit->uv[0] - hit->uv[1]; - bsdf_args.wavelength = args->wlen; - bsdf_args.r = ssp_rng_canonical(args->rng); - RNGRD(create_bsdf(cmd->ground, &bsdf_args, &bsdf)); - - return bsdf; -} - -static INLINE struct ssf_phase* -create_phase_fn - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - const struct rnatm_cell_pos* cells) /* Cells in which scattering occurs */ -{ - struct rnatm_sample_component_args sample_args = - RNATM_SAMPLE_COMPONENT_ARGS_NULL; - struct rnatm_cell_create_phase_fn_args phase_fn_args = - RNATM_CELL_CREATE_PHASE_FN_ARGS_NULL; - struct ssf_phase* phase = NULL; - size_t cpnt; - ASSERT(cmd && args && cells); - - /* Sample the atmospheric scattering component */ - sample_args.cells = cells; - sample_args.iband = args->iband; - sample_args.iquad = args->iquad; - sample_args.radcoef = RNATM_RADCOEF_Ks; - sample_args.r = ssp_rng_canonical(args->rng); - RNATM(sample_component(cmd->atmosphere, &sample_args, &cpnt)); - - /* Retrieve the component cell in which the scattering position is located */ - phase_fn_args.cell = RNATM_GET_COMPONENT_CELL(cells, cpnt); - ASSERT(!SUVM_PRIMITIVE_NONE(&phase_fn_args.cell.prim)); - - /* Retrieve the component phase function */ - phase_fn_args.wavelength = args->wlen; - phase_fn_args.r[0] = ssp_rng_canonical(args->rng); - phase_fn_args.r[1] = ssp_rng_canonical(args->rng); - RNATM(cell_create_phase_fn(cmd->atmosphere, &phase_fn_args, &phase)); - - return phase; -} - -/* In shortwave, return the contribution of the external source at the bounce - * position. In longwave, simply return 0 */ -static double -surface_bounce - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - const struct event* sc, - const double sc_pos[3], /* Scattering position */ - const double in_dir[3], /* Incident direction */ - double sc_dir[3], /* Sampled scattering direction */ - double *out_refl) /* Surface reflectivity */ -{ - struct ssf_bsdf* bsdf = NULL; - const double* N = NULL; - double wo[3] = {0,0,0}; - double reflectivity = 0; /* Surface reflectivity */ - double L = 0; - int mask = 0; - ASSERT(cmd && args && sc && sc_pos && in_dir && sc_dir && out_refl); - ASSERT(d3_dot(sc->normal, in_dir) < 0 && d3_is_normalized(sc->normal)); - - bsdf = create_bsdf(cmd, args, &sc->hit); - N = sc->normal; - d3_minus(wo, in_dir); /* Match StarSF convention */ - ASSERT(d3_dot(wo, N) > 0); - - /* Sample the scattering direction */ - reflectivity = ssf_bsdf_sample(bsdf, args->rng, wo, N, sc_dir, &mask, NULL); - - /* Fully absorbs transmissions */ - if(mask & SSF_TRANSMISSION) reflectivity = 0; - - /* No external source in longwave */ - if(cmd->spectral_domain.type == HTRDR_SPECTRAL_LW) - goto exit; - - /* Calculate direct contribution for specular reflection */ - if((mask & SSF_SPECULAR) - && (mask & SSF_REFLECTION) - && htrdr_planeto_source_is_targeted(cmd->source, sc_pos, sc_dir)) { - const double Ld = direct_contribution(cmd, args, sc_pos, sc_dir, &sc->hit); - L = Ld * reflectivity; - - /* Calculate direct contribution in general case */ - } else if(!(mask & SSF_SPECULAR)) { - double wi[3], pdf; - - /* Sample a direction toward the source */ - pdf = htrdr_planeto_source_sample_direction(cmd->source, args->rng, sc_pos, wi); - - /* The source is behind the surface */ - if(d3_dot(wi, N) <= 0) { - L = 0; - - /* The source is above the surface */ - } else { - const double Ld = direct_contribution(cmd, args, sc_pos, wi, &sc->hit); - const double rho = ssf_bsdf_eval(bsdf, wo, N, wi); - const double cos_N_wi = d3_dot(N, wi); - ASSERT(cos_N_wi > 0); - - L = Ld * rho * cos_N_wi / pdf; - } - } - -exit: - SSF(bsdf_ref_put(bsdf)); - *out_refl = reflectivity; - return L; -} - -/* In shortwave, return the contribution at the scattering position of the - * external source. Returns 0 in long wave */ -static INLINE double -volume_scattering - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - const struct event* sc, - const double sc_pos[3], /* Scattering position */ - const double in_dir[3], /* Incident direction */ - double sc_dir[3]) /* Sampled scattering direction */ -{ - struct ssf_phase* phase = NULL; - double wo[3] = {0,0,0}; - double wi[3] = {0,0,0}; - double L = 0; - double pdf = 0; - double rho = 0; - double Ld = 0; - ASSERT(cmd && args && sc && sc_pos && in_dir && sc_dir); - - phase = create_phase_fn(cmd, args, sc->cells); - d3_minus(wo, in_dir); /* Match StarSF convention */ - - ssf_phase_sample(phase, args->rng, wo, sc_dir, NULL); - - /* Sample a direction toward the source */ - pdf = htrdr_planeto_source_sample_direction(cmd->source, args->rng, sc_pos, wi); - - /* In short wave, manage the contribution of the external source */ - switch(cmd->spectral_domain.type) { - case HTRDR_SPECTRAL_LW: - /* Nothing to be done */ - break; - - case HTRDR_SPECTRAL_SW: - case HTRDR_SPECTRAL_SW_CIE_XYZ: - /* Calculate the direct contribution at the scattering position */ - Ld = direct_contribution(cmd, args, sc_pos, wi, NULL); - rho = ssf_phase_eval(phase, wo, wi); - L = Ld * rho / pdf; - break; - - default: FATAL("Unreachable code.\n"); break; - } - - SSF(phase_ref_put(phase)); - return L; -} - -static INLINE enum rnatm_radcoef -sample_volume_event_type - (const struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args, - struct event* evt) -{ - struct rnatm_get_radcoef_args get_k_args = RNATM_GET_RADCOEF_ARGS_NULL; - double ka, kext; - double r; - ASSERT(cmd && args && evt); - - get_k_args.cells = evt->cells; - get_k_args.iband = args->iband; - get_k_args.iquad = args->iquad; - - /* Retrieve the absorption coefficient */ - get_k_args.radcoef = RNATM_RADCOEF_Ka; - RNATM(get_radcoef(cmd->atmosphere, &get_k_args, &ka)); - - /* Retrieve the extinction coefficient */ - get_k_args.radcoef = RNATM_RADCOEF_Kext; - RNATM(get_radcoef(cmd->atmosphere, &get_k_args, &kext)); - - r = ssp_rng_canonical(args->rng); - if(r < ka / kext) { - return RNATM_RADCOEF_Ka; /* Absorption */ - } else { - return RNATM_RADCOEF_Ks; /* Scattering */ - } -} - -static INLINE double -get_temperature - (const struct htrdr_planeto* cmd, - const struct event* evt) -{ - double T = 0; - ASSERT(cmd && evt); - - if(!SURFACE_EVENT(evt)) { - const struct rnatm_cell_pos* cell = NULL; - - /* Get gas temperature */ - cell = &RNATM_GET_COMPONENT_CELL(evt->cells, RNATM_GAS); - RNATM(cell_get_gas_temperature(cmd->atmosphere, cell, &T)); - - } else { - struct rngrd_get_temperature_args temp_args = RNGRD_GET_TEMPERATURE_ARGS_NULL; - - /* Get ground temperature */ - temp_args.prim = evt->hit.prim; - temp_args.barycentric_coords[0] = evt->hit.uv[0]; - temp_args.barycentric_coords[1] = evt->hit.uv[1]; - temp_args.barycentric_coords[2] = 1 - evt->hit.uv[0] - evt->hit.uv[1]; - RNGRD(get_temperature(cmd->ground, &temp_args, &T)); - - } - return T; -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -double /* Radiance in W/m²/sr/m */ -planeto_compute_radiance - (struct htrdr_planeto* cmd, - const struct planeto_compute_radiance_args* args) -{ - struct s3d_hit hit_from = S3D_HIT_NULL; - struct event ev; - double pos[3]; - double dir[3]; - double L = 0; /* Radiance in W/m²/sr/m */ - size_t nsc = 0; /* Number of surface or volume scatterings (for debug) */ - int longwave = 0; - ASSERT(cmd && check_planeto_compute_radiance_args(cmd, args) == RES_OK); - - d3_set(pos, args->path_org); - d3_set(dir, args->path_dir); - longwave = cmd->spectral_domain.type == HTRDR_SPECTRAL_LW; - - if(!longwave && htrdr_planeto_source_is_targeted(cmd->source, pos, dir)) { - L = direct_contribution(cmd, args, pos, dir, NULL); /* In W/m²/sr/m */ - } - - for(;;) { - double ev_pos[3]; - double sc_dir[3]; - - find_event(cmd, args, RNATM_RADCOEF_Kext, pos, dir, &hit_from, &ev); - - /* No event on surface or in volume. Stop the path */ - if(DISTANCE_NONE(ev.distance)) break; - - /* Compute the event position */ - ev_pos[0] = pos[0] + dir[0] * ev.distance; - ev_pos[1] = pos[1] + dir[1] * ev.distance; - ev_pos[2] = pos[2] + dir[2] * ev.distance; - - /* The event occurs on the surface */ - if(SURFACE_EVENT(&ev)) { - double refl; /* Surface reflectivity */ - L += surface_bounce(cmd, args, &ev, ev_pos, dir, sc_dir, &refl); - - /* Check the absorption of the surface with a Russian roulette against - * the reflectivity of the surface */ - if(ssp_rng_canonical(args->rng) >= refl) break; - - /* Save current intersected surface to avoid self-intersection when - * sampling next event */ - hit_from = ev.hit; - - /* The event occurs in the volume */ - } else { - enum rnatm_radcoef ev_type = sample_volume_event_type(cmd, args, &ev); - ASSERT(ev_type == RNATM_RADCOEF_Ka || ev_type == RNATM_RADCOEF_Ks); - - /* Absorption. Stop the path */ - if(ev_type == RNATM_RADCOEF_Ka) break; - - L += volume_scattering(cmd, args, &ev, ev_pos, dir, sc_dir); - hit_from = S3D_HIT_NULL; /* Reset surface intersection */ - } - - d3_set(pos, ev_pos); - d3_set(dir, sc_dir); - - ++nsc; - } - - /* From there, a valid event means that the path has stopped in surface or - * volume absorption. In longwave, add the contribution of the internal - * source */ - if(longwave && !DISTANCE_NONE(ev.distance)) { - const double wlen_m = args->wlen * 1.e-9; /* wavelength in meters */ - const double temperature = get_temperature(cmd, &ev); /* In K */ - L += htrdr_planck_monochromatic(wlen_m, temperature); - } - - return L; /* In W/m²/sr/m */ -} diff --git a/src/planeto/htrdr_planeto_draw_map.c b/src/planeto/htrdr_planeto_draw_map.c @@ -1,457 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "planeto/htrdr_planeto_c.h" -#include "planeto/htrdr_planeto_source.h" - -#include "core/htrdr.h" -#include "core/htrdr_accum.h" -#include "core/htrdr_buffer.h" -#include "core/htrdr_draw_map.h" -#include "core/htrdr_log.h" -#include "core/htrdr_ran_wlen_cie_xyz.h" -#include "core/htrdr_ran_wlen_discrete.h" -#include "core/htrdr_ran_wlen_planck.h" - -#include <rad-net/rnatm.h> -#include <star/scam.h> -#include <star/ssp.h> - -#include <rsys/clock_time.h> - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static void -draw_pixel_xwave - (struct htrdr* htrdr, - const struct htrdr_draw_pixel_args* args, - void* data) -{ - struct planeto_compute_radiance_args rad_args = - PLANETO_COMPUTE_RADIANCE_ARGS_NULL; - - struct htrdr_accum radiance; - struct htrdr_accum time; - struct htrdr_planeto* cmd; - struct planeto_pixel_xwave* pixel = data; - size_t isamp = 0; - ASSERT(htrdr && htrdr_draw_pixel_args_check(args) && data); - (void)htrdr; - - cmd = args->context; - ASSERT(cmd); - ASSERT(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW - || cmd->spectral_domain.type == HTRDR_SPECTRAL_LW); - ASSERT(cmd->output_type == HTRDR_PLANETO_ARGS_OUTPUT_IMAGE); - - /* Reset accumulators */ - radiance = HTRDR_ACCUM_NULL; - time = HTRDR_ACCUM_NULL; - - FOR_EACH(isamp, 0, args->spp) { - struct time t0, t1; - struct scam_sample sample = SCAM_SAMPLE_NULL; - struct scam_ray ray = SCAM_RAY_NULL; - double weight; - double r0, r1, r2; - double wlen[2]; /* Sampled wavelength */ - double pdf; - size_t iband[2]; - size_t iquad; - double usec; - - /* Begin the registration of the time spent to in the realisation */ - time_current(&t0); - - /* Sample a position into the pixel, in the normalized image plane */ - sample.film[0] = (double)args->pixel_coord[0]+ssp_rng_canonical(args->rng); - sample.film[1] = (double)args->pixel_coord[1]+ssp_rng_canonical(args->rng); - sample.film[0] *= args->pixel_normalized_size[0]; - sample.film[1] *= args->pixel_normalized_size[1]; - sample.lens[0] = ssp_rng_canonical(args->rng); - sample.lens[1] = ssp_rng_canonical(args->rng); - - /* Generate a camera ray */ - scam_generate_ray(cmd->camera, &sample, &ray); - - r0 = ssp_rng_canonical(args->rng); - r1 = ssp_rng_canonical(args->rng); - r2 = ssp_rng_canonical(args->rng); - - /* Sample a wavelength */ - switch(cmd->spectral_domain.type) { - case HTRDR_SPECTRAL_LW: - wlen[0] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf); - break; - case HTRDR_SPECTRAL_SW: - if(htrdr_planeto_source_does_radiance_vary_spectrally(cmd->source)) { - wlen[0] = htrdr_ran_wlen_discrete_sample(cmd->discrete, r0, r1, &pdf); - } else { - wlen[0] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf); - } - break; - default: FATAL("Unreachable code\n"); break; - - } - wlen[1] = wlen[0]; - pdf *= 1.e9; /* Transform the pdf from nm⁻¹ to m⁻¹ */ - - /* Find the band the wavelength belongs to and sample a quadrature point */ - RNATM(find_bands(cmd->atmosphere, wlen, iband)); - RNATM(band_sample_quad_pt(cmd->atmosphere, r2, iband[0], &iquad)); - ASSERT(iband[0] == iband[1]); - - /* Compute the radiance in W/m²/sr/m */ - d3_set(rad_args.path_org, ray.org); - d3_set(rad_args.path_dir, ray.dir); - rad_args.rng = args->rng; - rad_args.ithread = args->ithread; - rad_args.wlen = wlen[0]; - rad_args.iband = iband[0]; - rad_args.iquad = iquad; - weight = planeto_compute_radiance(cmd, &rad_args); - ASSERT(weight >= 0); - - weight /= pdf; /* In W/m²/sr */ - - /* End of time recording per realisation */ - time_sub(&t0, time_current(&t1), &t0); - usec = (double)time_val(&t0, TIME_NSEC) * 0.001; - - /* Update the radiance accumulator */ - radiance.sum_weights += weight; - radiance.sum_weights_sqr += weight*weight; - radiance.nweights += 1; - - /* Update the per realisation time accumulator */ - time.sum_weights += usec; - time.sum_weights_sqr += usec*usec; - time.nweights += 1; - } - - /* Flush pixel data */ - pixel->radiance = radiance; - pixel->time = time; - - if(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW) { - pixel->radiance_temperature.E = 0; - pixel->radiance_temperature.SE = 0; - } else { - struct htrdr_estimate L; - - /* Wavelength in meters */ - const double wmin_m = cmd->spectral_domain.wlen_range[0] * 1.e-9; - const double wmax_m = cmd->spectral_domain.wlen_range[1] * 1.e-9; - - /* Brightness temperatures in W/m²/sr */ - double T, Tmin, Tmax; - - htrdr_accum_get_estimation(&radiance, &L); - - T = htrdr_radiance_temperature(cmd->htrdr, wmin_m, wmax_m, L.E); - Tmin = htrdr_radiance_temperature(cmd->htrdr, wmin_m, wmax_m, L.E - L.SE); - Tmax = htrdr_radiance_temperature(cmd->htrdr, wmin_m, wmax_m, L.E + L.SE); - - pixel->radiance_temperature.E = T; - pixel->radiance_temperature.SE = Tmax - Tmin; - } -} - -static void -draw_pixel_image - (struct htrdr* htrdr, - const struct htrdr_draw_pixel_args* args, - void* data) -{ - struct planeto_compute_radiance_args rad_args = - PLANETO_COMPUTE_RADIANCE_ARGS_NULL; - - struct htrdr_accum XYZ[3]; /* X, Y, and Z */ - struct htrdr_accum time; - struct htrdr_planeto* cmd; - struct planeto_pixel_image* pixel = data; - size_t ichannel; - ASSERT(htrdr && htrdr_draw_pixel_args_check(args) && data); - (void)htrdr; - - cmd = args->context; - ASSERT(cmd); - ASSERT(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW_CIE_XYZ); - ASSERT(cmd->output_type == HTRDR_PLANETO_ARGS_OUTPUT_IMAGE); - - /* Reset accumulators */ - XYZ[0] = HTRDR_ACCUM_NULL; - XYZ[1] = HTRDR_ACCUM_NULL; - XYZ[2] = HTRDR_ACCUM_NULL; - time = HTRDR_ACCUM_NULL; - - FOR_EACH(ichannel, 0, 3) { - size_t isamp; - - FOR_EACH(isamp, 0, args->spp) { - struct time t0, t1; - struct scam_sample sample = SCAM_SAMPLE_NULL; - struct scam_ray ray = SCAM_RAY_NULL; - double weight; - double r0, r1, r2; - double wlen[2]; /* Sampled wavelength into the spectral band */ - double pdf; - size_t iband[2]; /* Sampled spectral band */ - size_t iquad; /* Sampled quadrature point into the spectral band */ - double usec; - - /* Begin the registration of the time spent to in the realisation */ - time_current(&t0); - - /* Sample a position into the pixel, in the normalized image plane */ - sample.film[0] = (double)args->pixel_coord[0]+ssp_rng_canonical(args->rng); - sample.film[1] = (double)args->pixel_coord[1]+ssp_rng_canonical(args->rng); - sample.film[0] *= args->pixel_normalized_size[0]; - sample.film[1] *= args->pixel_normalized_size[1]; - sample.lens[0] = ssp_rng_canonical(args->rng); - sample.lens[1] = ssp_rng_canonical(args->rng); - - /* Generate a camera ray */ - SCAM(generate_ray(cmd->camera, &sample, &ray)); - - r0 = ssp_rng_canonical(args->rng); - r1 = ssp_rng_canonical(args->rng); - r2 = ssp_rng_canonical(args->rng); - - /* Sample a wavelength according to the CIE XYZ color space */ - switch(ichannel) { - case 0: - wlen[0] = htrdr_ran_wlen_cie_xyz_sample_X(cmd->cie, r0, r1, &pdf); - break; - case 1: - wlen[0] = htrdr_ran_wlen_cie_xyz_sample_Y(cmd->cie, r0, r1, &pdf); - break; - case 2: - wlen[0] = htrdr_ran_wlen_cie_xyz_sample_Z(cmd->cie, r0, r1, &pdf); - break; - default: FATAL("Unreachable code.\n"); break; - } - pdf *= 1.e9; /* Transform the pdf from nm⁻¹ to m⁻¹ */ - - /* Find the band the wavelength belongs to and sample a quadrature point */ - wlen[1] = wlen[0]; - RNATM(find_bands(cmd->atmosphere, wlen, iband)); - RNATM(band_sample_quad_pt(cmd->atmosphere, r2, iband[0], &iquad)); - ASSERT(iband[0] == iband[1]); - - /* Compute the radiance in W/m²/sr/m */ - d3_set(rad_args.path_org, ray.org); - d3_set(rad_args.path_dir, ray.dir); - rad_args.rng = args->rng; - rad_args.ithread = args->ithread; - rad_args.wlen = wlen[0]; - rad_args.iband = iband[0]; - rad_args.iquad = iquad; - weight = planeto_compute_radiance(cmd, &rad_args); - ASSERT(weight >= 0); - - weight /= pdf; /* In W/m²/sr */ - - /* End of time recording per realisation */ - time_sub(&t0, time_current(&t1), &t0); - usec = (double)time_val(&t0, TIME_NSEC) * 0.001; - - /* Update pixel channel accumulators */ - XYZ[ichannel].sum_weights += weight; - XYZ[ichannel].sum_weights_sqr += weight*weight; - XYZ[ichannel].nweights += 1; - - /* Update the per realisation time accumulator */ - time.sum_weights += usec; - time.sum_weights_sqr += usec*usec; - time.nweights += 1; - } - } - - /* Flush pixel data */ - htrdr_accum_get_estimation(XYZ+0, &pixel->X); - htrdr_accum_get_estimation(XYZ+1, &pixel->Y); - htrdr_accum_get_estimation(XYZ+2, &pixel->Z); - pixel->time = time; -} - - -static INLINE void -write_accum - (const struct htrdr_accum* acc, /* Accum to dump */ - struct htrdr_accum* out_acc, /* May be NULL */ - FILE* stream) -{ - ASSERT(acc && stream); - - if(acc->nweights == 0) { - fprintf(stream, "0 0 "); - } else { - struct htrdr_estimate estimate = HTRDR_ESTIMATE_NULL; - - htrdr_accum_get_estimation(acc, &estimate); - fprintf(stream, "%g %g ", estimate.E, estimate.SE); - - if(out_acc) { - out_acc->sum_weights += acc->sum_weights; - out_acc->sum_weights_sqr += acc->sum_weights_sqr; - out_acc->nweights += acc->nweights; - } - } -} - -static INLINE void -write_pixel_image - (const struct planeto_pixel_image* pix, - struct htrdr_accum* time_acc, /* May be NULL */ - FILE* stream) -{ - ASSERT(pix && stream); - fprintf(stream, "%g %g ", pix->X.E, pix->X.SE); - fprintf(stream, "%g %g ", pix->Y.E, pix->Y.SE); - fprintf(stream, "%g %g ", pix->Z.E, pix->Z.SE); - write_accum(&pix->time, time_acc, stream); - fprintf(stream, "\n"); -} - -static INLINE void -write_pixel_xwave - (const struct planeto_pixel_xwave* pix, - struct htrdr_accum* radiance_acc, /* May be NULL */ - struct htrdr_accum* time_acc, /* May be NULL */ - FILE* stream) -{ - ASSERT(pix && stream); - fprintf(stream, "%g %g ", - pix->radiance_temperature.E, - pix->radiance_temperature.SE); - write_accum(&pix->radiance, radiance_acc, stream); - fprintf(stream, "0 0 "); - write_accum(&pix->time, time_acc, stream); - fprintf(stream, "\n"); -} - -static res_T -write_buffer - (struct htrdr_planeto* cmd, - struct htrdr_buffer* buf, - struct htrdr_accum* radiance_acc, /* May be NULL */ - struct htrdr_accum* time_acc, - FILE* stream) -{ - struct htrdr_pixel_format pixfmt; - struct htrdr_buffer_layout layout; - size_t x, y; - ASSERT(cmd && buf && time_acc && stream); - ASSERT(cmd->output_type == HTRDR_PLANETO_ARGS_OUTPUT_IMAGE); - - planeto_get_pixel_format(cmd, &pixfmt); - htrdr_buffer_get_layout(buf, &layout); - CHK(pixfmt.size == layout.elmt_size); - - fprintf(stream, "%lu %lu\n", layout.width, layout.height); - *time_acc = HTRDR_ACCUM_NULL; - - FOR_EACH(y, 0, layout.height) { - FOR_EACH(x, 0, layout.width) { - void* pix_raw = htrdr_buffer_at(buf, x, y); - ASSERT(IS_ALIGNED(pix_raw, pixfmt.alignment)); - - switch(cmd->spectral_domain.type) { - case HTRDR_SPECTRAL_LW: - case HTRDR_SPECTRAL_SW: - write_pixel_xwave(pix_raw, radiance_acc, time_acc, stream); - break; - case HTRDR_SPECTRAL_SW_CIE_XYZ: - write_pixel_image(pix_raw, time_acc, stream); - break; - default: FATAL("Unreachable code\n"); break; - } - } - } - return RES_OK; -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -planeto_draw_map(struct htrdr_planeto* cmd) -{ - struct htrdr_draw_map_args args = HTRDR_DRAW_MAP_ARGS_NULL; - struct htrdr_estimate path_time = HTRDR_ESTIMATE_NULL; - struct htrdr_accum path_time_acc = HTRDR_ACCUM_NULL; - struct htrdr_accum radiance_acc = HTRDR_ACCUM_NULL; - res_T res = RES_OK; - ASSERT(cmd && cmd->output_type == HTRDR_PLANETO_ARGS_OUTPUT_IMAGE); - - args.buffer_layout = cmd->buf_layout; - args.spp = cmd->spp; - args.context = cmd; - switch(cmd->spectral_domain.type) { - case HTRDR_SPECTRAL_LW: - case HTRDR_SPECTRAL_SW: - args.draw_pixel = draw_pixel_xwave; - break; - case HTRDR_SPECTRAL_SW_CIE_XYZ: - args.draw_pixel = draw_pixel_image; - break; - default: FATAL("Unreachable code\n"); break; - } - - res = htrdr_draw_map(cmd->htrdr, &args, cmd->buf); - if(res != RES_OK) goto error; - - /* Nothing more to do on non master processes */ - if(htrdr_get_mpi_rank(cmd->htrdr) != 0) goto exit; - - /* Write output image */ - res = write_buffer(cmd, cmd->buf, &radiance_acc, &path_time_acc, cmd->output); - if(res != RES_OK) goto error; - - CHK(fflush(cmd->output) == 0); - - /* Log time per realisation */ - htrdr_accum_get_estimation(&path_time_acc, &path_time); - htrdr_log(cmd->htrdr, "Time per radiative path (in µs): %g +/- %g\n", - path_time.E, path_time.SE); - - /* Log measured radiance on the whole image */ - if(cmd->spectral_domain.type == HTRDR_SPECTRAL_LW - || cmd->spectral_domain.type == HTRDR_SPECTRAL_SW) { - struct htrdr_estimate L; - double omega; /* Solid angle of the camera */ - - htrdr_accum_get_estimation(&radiance_acc, &L); - SCAM(perspective_get_solid_angle(cmd->camera, &omega)); - htrdr_log(cmd->htrdr, "Radiance in W/m²/sr: %g +/- %g\n", L.E, L.SE); - htrdr_log(cmd->htrdr, "Radiance in W/m² (solid angle = %g sr): %g +/- %g\n", - omega, L.E*omega, L.SE*omega); - } - -exit: - return res; -error: - goto exit; -} diff --git a/src/planeto/htrdr_planeto_main.c b/src/planeto/htrdr_planeto_main.c @@ -1,91 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "planeto/htrdr_planeto.h" -#include "planeto/htrdr_planeto_args.h" - -#include "core/htrdr_log.h" - -#include <rsys/mem_allocator.h> - -int -htrdr_planeto_main(int argc, char** argv) -{ - char cmd_name[] = "htrdr-planeto"; - struct htrdr_args htrdr_args = HTRDR_ARGS_DEFAULT; - struct htrdr_planeto_args cmd_args = HTRDR_PLANETO_ARGS_DEFAULT; - struct htrdr* htrdr = NULL; - struct htrdr_planeto* cmd = NULL; - const size_t memsz_begin = mem_allocated_size(); - size_t memsz_end; - int is_mpi_init = 0; - res_T res = RES_OK; - int err = 0; - - /* Overwrite command name */ - argv[0] = cmd_name; - - res = htrdr_mpi_init(argc, argv); - if(res != RES_OK) goto error; - is_mpi_init = 1; - - res = htrdr_planeto_args_init(&cmd_args, argc, argv); - if(res != RES_OK) goto error; - if(cmd_args.quit) goto exit; - - htrdr_args.nthreads = cmd_args.nthreads; - htrdr_args.verbose = cmd_args.verbose; - res = htrdr_create(&mem_default_allocator, &htrdr_args, &htrdr); - if(res != RES_OK) goto error; - - if(cmd_args.output_type == HTRDR_PLANETO_ARGS_OUTPUT_OCTREES - && htrdr_get_mpi_rank(htrdr) != 0) { - goto exit; /* Nothing to do except for the master process */ - } - - res = htrdr_planeto_create(htrdr, &cmd_args, &cmd); - if(res != RES_OK) goto error; - - res = htrdr_planeto_run(cmd); - if(res != RES_OK) goto error; - -exit: - htrdr_planeto_args_release(&cmd_args); - if(is_mpi_init) htrdr_mpi_finalize(); - if(htrdr) htrdr_ref_put(htrdr); - if(cmd) htrdr_planeto_ref_put(cmd); - - /* Check memory leaks */ - memsz_end = mem_allocated_size(); - if(memsz_begin != memsz_end) { - ASSERT(memsz_end >= memsz_begin); - fprintf(stderr, HTRDR_LOG_WARNING_PREFIX"Memory leaks: %lu Bytes\n", - (unsigned long)(memsz_end - memsz_begin)); - err = -1; - } - return err; -error: - err = -1; - goto exit; -} - diff --git a/src/planeto/htrdr_planeto_source.c b/src/planeto/htrdr_planeto_source.c @@ -1,491 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "planeto/htrdr_planeto_c.h" -#include "planeto/htrdr_planeto_source.h" - -#include "core/htrdr.h" -#include "core/htrdr_log.h" - -#include <star/sbuf.h> -#include <star/ssp.h> - -#include <rsys/algorithm.h> -#include <rsys/cstr.h> -#include <rsys/double3.h> -#include <rsys/ref_count.h> - -typedef struct ALIGN(16) { - double wavelength; /* in nm */ - double radiance; /* in W/m²/sr/m */ -} source_radiance_T; - -struct htrdr_planeto_source { - double position[3]; /* In m */ - - double radius; /* In m */ - - /* In Kelvin. Defined if the radiances by wavelength is no set */ - double temperature; - - struct sbuf* per_wlen_radiances; /* List of radiances by wavelength */ - - ref_T ref; - struct htrdr* htrdr; -}; - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static INLINE res_T -check_per_wlen_radiance_sbuf_desc - (const struct htrdr_planeto_source* src, - const struct sbuf_desc* desc) -{ - const source_radiance_T* spectrum = NULL; - size_t i; - ASSERT(src && desc); - - /* Invalid size */ - if(desc->size == 0) { - htrdr_log_err(src->htrdr, "invalid empty source spectrum\n"); - return RES_BAD_ARG; - } - - /* Invalid memory layout */ - if(desc->szitem != 16 || desc->alitem != 16 || desc->pitch != 16) { - htrdr_log_err(src->htrdr, "unexpected layout of source spectrum\n"); - return RES_BAD_ARG; - } - - /* Data must be sorted */ - spectrum = desc->buffer; - FOR_EACH(i, 1, desc->size) { - if(spectrum[i-1].wavelength >= spectrum[i].wavelength) { - htrdr_log_err(src->htrdr, - "the source spectrum is not sorted in ascending order " - "with respect to wavelengths\n"); - return RES_BAD_ARG; - } - } - - return RES_OK; -} - -static res_T -setup_per_wavelength_radiances - (struct htrdr_planeto_source* src, - const struct htrdr_planeto_source_args* args) -{ - struct sbuf_create_args sbuf_args; - struct sbuf_desc desc; - res_T res = RES_OK; - ASSERT(src && args && args->rnrl_filename && args->temperature < 0); - - sbuf_args.logger = htrdr_get_logger(src->htrdr); - sbuf_args.allocator = htrdr_get_allocator(src->htrdr); - sbuf_args.verbose = htrdr_get_verbosity_level(src->htrdr); - res = sbuf_create(&sbuf_args, &src->per_wlen_radiances); - if(res != RES_OK) goto error; - - res = sbuf_load(src->per_wlen_radiances, args->rnrl_filename); - if(res != RES_OK) goto error; - res = sbuf_get_desc(src->per_wlen_radiances, &desc); - if(res != RES_OK) goto error; - res = check_per_wlen_radiance_sbuf_desc(src, &desc); - if(res != RES_OK) goto error; - -exit: - return res; -error: - htrdr_log_err(src->htrdr, "error loading %s -- %s\n", - args->rnrl_filename, res_to_cstr(res)); - goto exit; -} - -static INLINE int -cmp_wlen(const void* a, const void* b) -{ - const double wlen = *((double*)a); - const source_radiance_T* src_rad1 = b; - ASSERT(a && b); - - if(wlen < src_rad1->wavelength) { - return -1; - } else if(wlen > src_rad1->wavelength) { - return +1; - } else { - return 0; - } -} - -static double -get_radiance - (const struct htrdr_planeto_source* src, - const double wlen) -{ - struct sbuf_desc desc; - const source_radiance_T* spectrum; - const source_radiance_T* find; - size_t id; - ASSERT(src && src->per_wlen_radiances); - - SBUF(get_desc(src->per_wlen_radiances, &desc)); - spectrum = desc.buffer; - - if(wlen < spectrum[0].wavelength) { - htrdr_log_warn(src->htrdr, - "The wavelength %g nm is before the spectrum of the source\n", wlen); - return spectrum[0].radiance; - } - if(wlen > spectrum[desc.size-1].wavelength) { - htrdr_log_warn(src->htrdr, - "The wavelength %g nm is above the spectrum of the source\n", wlen); - return spectrum[desc.size-1].radiance; - } - - /* Look for the first item whose wavelength is not less than 'wlen' */ - find = search_lower_bound(&wlen, spectrum, desc.size, desc.pitch, cmp_wlen); - ASSERT(find); - id = (size_t)(find - spectrum); - ASSERT(id < desc.size); - - if(id == 0) { - ASSERT(wlen == spectrum[0].wavelength); - return spectrum[0].radiance; - } else { - const double w0 = spectrum[id-1].wavelength; - const double w1 = spectrum[id-0].wavelength; - const double L0 = spectrum[id-1].radiance; - const double L1 = spectrum[id-0].radiance; - const double u = (wlen - w0) / (w1 - w0); - const double L = L0 + u*(L1 - L0); /* Linear interpolation */ - return L; - } -} - -static void -release_source(ref_T* ref) -{ - struct htrdr_planeto_source* source; - struct htrdr* htrdr; - ASSERT(ref); - - source = CONTAINER_OF(ref, struct htrdr_planeto_source, ref); - htrdr = source->htrdr; - if(source->per_wlen_radiances) SBUF(ref_put(source->per_wlen_radiances)); - MEM_RM(htrdr_get_allocator(htrdr), source); - htrdr_ref_put(htrdr); -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -htrdr_planeto_source_create - (struct htrdr* htrdr, - const struct htrdr_planeto_source_args* args, - struct htrdr_planeto_source** out_source) -{ - struct htrdr_planeto_source* src = NULL; - double dst; /* In m */ - double lat; /* In radians */ - double lon; /* In radians */ - res_T res = RES_OK; - ASSERT(htrdr && out_source); - ASSERT(htrdr_planeto_source_args_check(args) == RES_OK); - - src = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*src)); - if(!src) { - htrdr_log_err(htrdr, "error allocating source\n"); - res = RES_MEM_ERR; - goto error; - } - ref_init(&src->ref); - htrdr_ref_get(htrdr); - src->htrdr = htrdr; - src->radius = args->radius * 1e3/*From km to m*/; - - if(!args->rnrl_filename) { - src->temperature = args->temperature; - } else { - res = setup_per_wavelength_radiances(src, args); - if(res != RES_OK) goto error; - src->temperature = -1; /* Not used */ - } - - /* Convert latitude and longitude to radians and distance in m */ - lat = MDEG2RAD(args->latitude); - lon = MDEG2RAD(args->longitude); - dst = args->distance * 1e3/*From km to m*/; - - /* Compute the position of the source */ - src->position[0] = dst * cos(lat) * cos(lon); - src->position[1] = dst * cos(lat) * sin(lon); - src->position[2] = dst * sin(lat); - -exit: - *out_source = src; - return res; -error: - if(src) { htrdr_planeto_source_ref_put(src); src = NULL; } - goto exit; -} - -void -htrdr_planeto_source_ref_get(struct htrdr_planeto_source* source) -{ - ASSERT(source); - ref_get(&source->ref); -} - -void htrdr_planeto_source_ref_put(struct htrdr_planeto_source* source) -{ - ASSERT(source); - ref_put(&source->ref, release_source); -} - -double -htrdr_planeto_source_sample_direction - (const struct htrdr_planeto_source* source, - struct ssp_rng* rng, - const double pos[3], - double dir[3]) -{ - double main_dir[3]; - double half_angle; /* In radians */ - double cos_half_angle; - double dst; /* In m */ - double pdf; - ASSERT(source && rng && pos && dir); - - /* compute the direction of `pos' toward the center of the source */ - d3_sub(main_dir, source->position, pos); - - /* Normalize the direction and keep the distance from `pos' to the center of - * the source */ - dst = d3_normalize(main_dir, main_dir); - CHK(dst > source->radius); - - /* Sample the source according to its solid angle, - * i.e. 2*PI*(1 - cos(half_angle)) */ - half_angle = asin(source->radius/dst); - cos_half_angle = cos(half_angle); - ssp_ran_sphere_cap_uniform(rng, main_dir, cos_half_angle, dir, &pdf); - - return pdf; -} - -double /* In W/m²/sr/m */ -htrdr_planeto_source_get_radiance - (const struct htrdr_planeto_source* source, - const double wlen) -{ - if(source->per_wlen_radiances) { - return get_radiance(source, wlen); - } else { - return htrdr_planck_monochromatic - (wlen*1e-9/*From nm to m*/, source->temperature); - } -} - -double -htrdr_planeto_source_distance_to - (const struct htrdr_planeto_source* source, - const double pos[3]) -{ - double vec[3]; - double dst; - ASSERT(source && pos); - - d3_sub(vec, source->position, pos); - dst = d3_len(vec); - return dst - source->radius; -} - -int -htrdr_planeto_source_is_targeted - (const struct htrdr_planeto_source* source, - const double pos[3], - const double dir[3]) -{ - double main_dir[3]; - double half_angle; /* In radians */ - double dst; /* In m */ - ASSERT(source && dir && d3_is_normalized(dir)); - - /* compute the direction of `pos' toward the center of the source */ - d3_sub(main_dir, source->position, pos); - - /* Normalize the direction and keep the distance from `pos' to the center of - * the source */ - dst = d3_normalize(main_dir, main_dir); - CHK(dst > source->radius); - - /* Compute the the half angle of the source as seen from pos */ - half_angle = asin(source->radius/dst); - - return d3_dot(dir, main_dir) >= cos(half_angle); -} - -res_T -htrdr_planeto_source_get_spectral_range - (const struct htrdr_planeto_source* source, - double range[2]) -{ - res_T res = RES_OK; - ASSERT(source && range); - - if(!source->per_wlen_radiances) { - range[0] = 0; - range[1] = INF; - } else { - struct sbuf_desc desc = SBUF_DESC_NULL; - const source_radiance_T* spectrum = NULL; - - res = sbuf_get_desc(source->per_wlen_radiances, &desc); - if(res != RES_OK) goto error; - - spectrum = desc.buffer; - range[0] = spectrum[0].wavelength; - range[1] = spectrum[desc.size-1].wavelength; - } - -exit: - return res; -error: - goto exit; -} - -int -htrdr_planeto_source_does_radiance_vary_spectrally - (const struct htrdr_planeto_source* source) -{ - 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->source = source; - 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; - source_spectrum->buffer = low + 1; - } else { - source_spectrum->buffer = low; - } - - } - } - -exit: - return res; -error: - goto exit; -} - -void -htrdr_planeto_source_spectrum_at - (void* source_spectrum, - const size_t i, /* between [0, spectrum->size[ */ - double* wavelength, /* In nm */ - double* radiance) /* In W/m²/sr/m */ -{ - struct htrdr_planeto_source_spectrum* spectrum = source_spectrum; - ASSERT(spectrum && i < spectrum->size && wavelength && radiance); - - /* Lower limit */ - if(i == 0) { - *wavelength = spectrum->range[0]; - *radiance = htrdr_planeto_source_get_radiance - (spectrum->source, spectrum->range[0]); - - /* Upper limit */ - } else if(i == spectrum->size-1) { - *wavelength = spectrum->range[1]; - *radiance = htrdr_planeto_source_get_radiance - (spectrum->source, spectrum->range[1]); - - /* Discrete element */ - } else { - const source_radiance_T* item = - (const source_radiance_T*)spectrum->buffer + (i-1); - *wavelength = item->wavelength; - *radiance = item->radiance; - } -} diff --git a/src/planeto/htrdr_planeto_source.h b/src/planeto/htrdr_planeto_source.h @@ -1,116 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef HTRDR_PLANETO_SOURCE_H -#define HTRDR_PLANETO_SOURCE_H - -#include <rsys/rsys.h> - -/* Forward declarations */ -struct htrdr; -struct htrdr_planeto_source; -struct htrdr_planeto_source_args; -struct ssp_rng; - -struct htrdr_planeto_source_spectrum { - const struct htrdr_planeto_source* source; - double range[2]; /* In nm. Limits are inclusive */ - size_t size; /* Number of elements representing the spectrum */ - const void* buffer; /* Pointer toward the spectrum data */ -}; -#define HTRDR_PLANETO_SOURCE_SPECTRUM_NULL__ {NULL, {0,0}, 0, NULL} -static const struct htrdr_planeto_source_spectrum -HTRDR_PLANETO_SOURCE_SPECTRUM_NULL = HTRDR_PLANETO_SOURCE_SPECTRUM_NULL__; - -extern LOCAL_SYM res_T -htrdr_planeto_source_create - (struct htrdr* htrdr, - const struct htrdr_planeto_source_args* args, - struct htrdr_planeto_source** source); - -extern LOCAL_SYM void -htrdr_planeto_source_ref_get - (struct htrdr_planeto_source* source); - -extern LOCAL_SYM void -htrdr_planeto_source_ref_put - (struct htrdr_planeto_source* source); - -/* Return the pdf of the sampled direction */ -extern LOCAL_SYM double -htrdr_planeto_source_sample_direction - (const struct htrdr_planeto_source* source, - struct ssp_rng* rng, - const double pos[3], /* Position from which direction is sampled */ - double dir[3]); - -extern LOCAL_SYM double /* In W/m²/sr/m */ -htrdr_planeto_source_get_radiance - (const struct htrdr_planeto_source* source, - const double wlen); /* In nanometers */ - -/* Return the distance between the source surface and the input position. Can - * be negative if the position is in the source */ -extern LOCAL_SYM double /* In m */ -htrdr_planeto_source_distance_to - (const struct htrdr_planeto_source* source, - const double pos[3]); - -/* Return 1 if the source is targeted by the submitted ray and 0 otherwise */ -extern LOCAL_SYM int -htrdr_planeto_source_is_targeted - (const struct htrdr_planeto_source* source, - const double pos[3], /* Ray origin */ - const double dir[3]);/* Ray direction */ - -extern LOCAL_SYM res_T -htrdr_planeto_source_get_spectral_range - (const struct htrdr_planeto_source* source, - double range[2]); /* In nm. Limits are inclusive */ - -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); - -/* Note that the following function profile corresponds to the type expected by - * the discrete wavelength distribution - * (see htrdr_ran_wlen_discrete_create_args structure) */ -extern LOCAL_SYM void -htrdr_planeto_source_spectrum_at - (void* spectrum, - size_t i, /* between [0, spectrum->size[ */ - double* wavelength, /* In nm */ - double* radiance); /* In W/m²/sr/m */ - -#endif /* HTRDR_PLANETO_SOURCE_H */ diff --git a/src/planeto/test_htrdr_planeto_source.c b/src/planeto/test_htrdr_planeto_source.c @@ -1,302 +0,0 @@ -/* Copyright (C) 2018-2019, 2022-2023 Centre National de la Recherche Scientifique - * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2022-2023 Institut Pierre-Simon Laplace - * Copyright (C) 2022-2023 Institut de Physique du Globe de Paris - * Copyright (C) 2018-2023 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2022-2023 Observatoire de Paris - * Copyright (C) 2022-2023 Université de Reims Champagne-Ardenne - * Copyright (C) 2022-2023 Université de Versaille Saint-Quentin - * Copyright (C) 2018-2019, 2022-2023 Université Paul Sabatier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include "planeto/htrdr_planeto_args.h" -#include "planeto/htrdr_planeto_source.h" - -#include "core/htrdr.h" -#include "core/htrdr_ran_wlen_discrete.h" - -#include <rsys/math.h> -#include <rsys/mem_allocator.h> - -#include <stdio.h> - -static void -write_per_wlen_radiances - (FILE* fp, - const size_t pagesize, - const size_t size, - const size_t szelmt, - const size_t alelmt) -{ - const char byte = 0; - size_t i; - - CHK(fp); - - /* Header */ - CHK(fwrite(&pagesize, sizeof(pagesize), 1, fp) == 1); - CHK(fwrite(&size, sizeof(size), 1, fp) == 1); - CHK(fwrite(&szelmt, sizeof(szelmt), 1, fp) == 1); - CHK(fwrite(&alelmt, sizeof(alelmt), 1, fp) == 1); - - /* Padding */ - CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0); - - FOR_EACH(i, 0, size) { - const double w = (double)i; - const double L = (double)(100 + i); - - CHK(fwrite(&w, sizeof(w), 1, fp) == 1); - CHK(fwrite(&L, sizeof(L), 1, fp) == 1); - } - - /* Padding. Write one char to position the EOF indicator */ - CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize)-1, SEEK_SET) == 0); - CHK(fwrite(&byte, sizeof(byte), 1, fp) == 1); - - CHK(fflush(fp) == 0); -} - -static void -test_spectrum(struct htrdr* htrdr) -{ - struct htrdr_planeto_source_args source_args = HTRDR_PLANETO_SOURCE_ARGS_NULL; - struct htrdr_planeto_source_spectrum spectrum; - struct htrdr_planeto_source* source = NULL; - - FILE* fp = NULL; - char rnrl_filename[] = "rnrl.bin"; - double range[2]; - double w, L; - - CHK(fp = fopen(rnrl_filename, "w")); - write_per_wlen_radiances(fp, 4096, 10, 16, 16); - CHK(fclose(fp) == 0); - - source_args.rnrl_filename = rnrl_filename; - source_args.longitude = 0; - source_args.latitude = 0; - source_args.distance = 0; - source_args.radius = 1e8; - source_args.temperature = -1; - CHK(htrdr_planeto_source_create(htrdr, &source_args, &source) == RES_OK); - CHK(htrdr_planeto_source_does_radiance_vary_spectrally(source) == 1); - CHK(htrdr_planeto_source_get_spectral_range(source, range) == RES_OK); - CHK(range[0] == 0); - CHK(range[1] == 9); - - range[0] = 0; range[1] = 10; - CHK(htrdr_planeto_source_get_spectrum(source, range, &spectrum) == RES_BAD_ARG); - - range[0] = 1; range[1] = 3; - CHK(htrdr_planeto_source_get_spectrum(source, range, &spectrum) == RES_OK); - CHK(spectrum.source == source); - CHK(spectrum.range[0] == 1); - CHK(spectrum.range[1] == 3); - CHK(spectrum.size == 3); - - htrdr_planeto_source_spectrum_at(&spectrum, 0, &w, &L); - CHK(w == 1 && L == 101); - htrdr_planeto_source_spectrum_at(&spectrum, 1, &w, &L); - CHK(w == 2 && L == 102); - htrdr_planeto_source_spectrum_at(&spectrum, 2, &w, &L); - CHK(w == 3 && L == 103); - - range[0] = 1.7; range[1] = 1.95; - CHK(htrdr_planeto_source_get_spectrum(source, range, &spectrum) == RES_OK); - CHK(spectrum.source == source); - CHK(spectrum.range[0] = 1.7); - CHK(spectrum.range[1] = 1.95); - CHK(spectrum.size == 2); - htrdr_planeto_source_spectrum_at(&spectrum, 0, &w, &L); - CHK(w == 1.7 && eq_eps(L, 101.7, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 1, &w, &L); - CHK(w == 1.95 && eq_eps(L, 101.95, 1.e-6)); - - range[0] = 2; range[1] = 2.01; - CHK(htrdr_planeto_source_get_spectrum(source, range, &spectrum) == RES_OK); - CHK(spectrum.size == 2); - htrdr_planeto_source_spectrum_at(&spectrum, 0, &w, &L); - CHK(w == 2 && L == 102); - htrdr_planeto_source_spectrum_at(&spectrum, 1, &w, &L); - CHK(w == 2.01 && eq_eps(L, 102.01, 1.e-6)); - - range[0] = 5.1; range[1] = 6; - CHK(htrdr_planeto_source_get_spectrum(source, range, &spectrum) == RES_OK); - CHK(spectrum.size == 2); - htrdr_planeto_source_spectrum_at(&spectrum, 0, &w, &L); - CHK(w == 5.1 && eq_eps(L, 105.1, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 1, &w, &L); - CHK(w == 6 && L == 106); - - range[0] = 7.5; range[1] = 9; - CHK(htrdr_planeto_source_get_spectrum(source, range, &spectrum) == RES_OK); - CHK(spectrum.size == 3); - htrdr_planeto_source_spectrum_at(&spectrum, 0, &w, &L); - CHK(w == 7.5 && eq_eps(L, 107.5, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 1, &w, &L); - CHK(w == 8 && L == 108); - htrdr_planeto_source_spectrum_at(&spectrum, 2, &w, &L); - CHK(w == 9 && L == 109); - - range[0] = 0.9; range[1] = 7.456; - CHK(htrdr_planeto_source_get_spectrum(source, range, &spectrum) == RES_OK); - CHK(spectrum.size == 9); - htrdr_planeto_source_spectrum_at(&spectrum, 0, &w, &L); - CHK(w == 0.9 && eq_eps(L, 100.9, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 1, &w, &L); - CHK(w == 1 && eq_eps(L, 101, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 2, &w, &L); - CHK(w == 2 && eq_eps(L, 102, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 3, &w, &L); - CHK(w == 3 && eq_eps(L, 103, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 4, &w, &L); - CHK(w == 4 && eq_eps(L, 104, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 5, &w, &L); - CHK(w == 5 && eq_eps(L, 105, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 6, &w, &L); - CHK(w == 6 && eq_eps(L, 106, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 7, &w, &L); - CHK(w == 7 && eq_eps(L, 107, 1.e-6)); - htrdr_planeto_source_spectrum_at(&spectrum, 8, &w, &L); - CHK(w == 7.456 && eq_eps(L, 107.456, 1.e-6)); - - htrdr_planeto_source_ref_put(source); -} - -static void -test_spectrum_fail(struct htrdr* htrdr) -{ - struct htrdr_planeto_source_args source_args = HTRDR_PLANETO_SOURCE_ARGS_NULL; - struct htrdr_planeto_source* source = NULL; - FILE* fp = NULL; - char rnrl_filename[] = "rnrl.bin"; - double w, L; - - source_args.rnrl_filename = rnrl_filename; - source_args.longitude = 0; - source_args.latitude = 0; - source_args.distance = 0; - source_args.radius = 1e8; - source_args.temperature = -1; - - /* Wrong item size */ - CHK(fp = fopen(rnrl_filename, "w")); - write_per_wlen_radiances(fp, 4096, 10, 8, 16); - CHK(fclose(fp) == 0); - CHK(htrdr_planeto_source_create(htrdr, &source_args, &source) == RES_BAD_ARG); - - /* Wrong item alignment */ - CHK(fp = fopen(rnrl_filename, "w")); - write_per_wlen_radiances(fp, 4096, 10, 16, 32); - CHK(fclose(fp) == 0); - CHK(htrdr_planeto_source_create(htrdr, &source_args, &source) == RES_BAD_ARG); - - CHK(fp = fopen(rnrl_filename, "w")); - write_per_wlen_radiances(fp, 4096, 4, 16, 16); - - /* Overwrite sorted items by unsorted items */ - CHK(fseek(fp, 4096, SEEK_SET) == 0); - w = 10; L = 1; - CHK(fwrite(&w, sizeof(w), 1, fp) == 1); - CHK(fwrite(&L, sizeof(L), 1, fp) == 1); - w = 11; L = 2; - CHK(fwrite(&w, sizeof(w), 1, fp) == 1); - CHK(fwrite(&L, sizeof(L), 1, fp) == 1); - w = 9; L = 3; - CHK(fwrite(&w, sizeof(w), 1, fp) == 1); - CHK(fwrite(&L, sizeof(L), 1, fp) == 1); - w = 12; L = 4; - CHK(fwrite(&w, sizeof(w), 1, fp) == 1); - CHK(fwrite(&L, sizeof(L), 1, fp) == 1); - CHK(fclose(fp) == 0); - - /* Unsorted items */ - CHK(htrdr_planeto_source_create(htrdr, &source_args, &source) == RES_BAD_ARG); -} - -static void -test_spectrum_from_files(struct htrdr* htrdr, int argc, char** argv) -{ - struct htrdr_ran_wlen_discrete_create_args distrib_args = - HTRDR_RAN_WLEN_DISCRETE_CREATE_ARGS_NULL; - struct htrdr_ran_wlen_discrete* distrib = NULL; - - struct htrdr_planeto_source_args source_args = HTRDR_PLANETO_SOURCE_ARGS_NULL; - struct htrdr_planeto_source_spectrum spectrum = HTRDR_PLANETO_SOURCE_SPECTRUM_NULL; - struct htrdr_planeto_source* source = NULL; - size_t i; - - source_args.longitude = 0; - source_args.latitude = 0; - source_args.distance = 0; - source_args.radius = 1e8; - source_args.temperature = -1; - - FOR_EACH(i, 1, argc) { - double range[2]; - double lambda, pdf; - source_args.rnrl_filename = argv[i]; - - CHK(htrdr_planeto_source_create(htrdr, &source_args, &source) == RES_OK); - CHK(htrdr_planeto_source_does_radiance_vary_spectrally(source)); - CHK(htrdr_planeto_source_get_spectral_range(source, range) == RES_OK); - - range[0] = 250; - range[1] = 850; - CHK(htrdr_planeto_source_get_spectrum(source, range, &spectrum) == RES_OK); - - printf("`%s' stores %lu entries between [%g, %g] nm\n", - argv[i], spectrum.size, SPLIT2(range)); - - distrib_args.get = htrdr_planeto_source_spectrum_at; - distrib_args.nwavelengths = spectrum.size; - distrib_args.context = &spectrum; - CHK(htrdr_ran_wlen_discrete_create(htrdr, &distrib_args, &distrib) == RES_OK); - - lambda = htrdr_ran_wlen_discrete_sample(distrib, 0.3, 0.5, &pdf); - printf("lambda = %g nm; pdf = %f nm⁻¹\n", lambda, pdf); - - htrdr_planeto_source_ref_put(source); - htrdr_ran_wlen_discrete_ref_put(distrib); - } -} - -int -main(int argc, char** argv) -{ - struct htrdr_args args = HTRDR_ARGS_DEFAULT; - struct htrdr* htrdr = NULL; - size_t memsz = 0; - - args.verbose = 1; - htrdr_mpi_init(argc, argv); - CHK(htrdr_create(NULL, &args, &htrdr) == RES_OK); - - memsz = MEM_ALLOCATED_SIZE(htrdr_get_allocator(htrdr)); - - if(argc > 1) { - test_spectrum_from_files(htrdr, argc, argv); - } else { - test_spectrum(htrdr); - test_spectrum_fail(htrdr); - } - - CHK(MEM_ALLOCATED_SIZE(htrdr_get_allocator(htrdr)) == memsz); - - htrdr_ref_put(htrdr); - htrdr_mpi_finalize(); - return 0; -} diff --git a/src/planets/htrdr_planets.c b/src/planets/htrdr_planets.c @@ -0,0 +1,595 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#define _POSIX_C_SOURCE 200112L /* fdopen, nextafter, rint */ + +#include "core/htrdr.h" +#include "core/htrdr_ran_wlen_cie_xyz.h" +#include "core/htrdr_ran_wlen_discrete.h" +#include "core/htrdr_ran_wlen_planck.h" +#include "core/htrdr_log.h" + +#include "planets/htrdr_planets.h" +#include "planets/htrdr_planets_args.h" +#include "planets/htrdr_planets_c.h" +#include "planets/htrdr_planets_source.h" + +#include <rad-net/rnatm.h> +#include <rad-net/rngrd.h> + +#include <star/scam.h> + +#include <rsys/cstr.h> +#include <rsys/double3.h> +#include <rsys/mem_allocator.h> + +#include <fcntl.h> /* open */ +#include <math.h> /* nextafter, rint */ +#include <unistd.h> /* close */ +#include <sys/stat.h> + +/******************************************************************************* + * Helper function + ******************************************************************************/ +/* Calculate the number of fixed size spectral intervals to use for the + * cumulative */ +static size_t +compute_nintervals_for_spectral_cdf(const struct htrdr_planets* cmd) +{ + double range_size; + size_t nintervals; + ASSERT(cmd); + + range_size = + cmd->spectral_domain.wlen_range[1] + - cmd->spectral_domain.wlen_range[0]; + + /* Initially assume ~one interval per nanometer */ + nintervals = (size_t)rint(range_size); + + return nintervals; +} + +static res_T +setup_octree_storage + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args, + struct rnatm_create_args* rnatm_args) +{ + struct stat file_stat; + int fd = -1; + int err = 0; + res_T res = RES_OK; + ASSERT(cmd && args && rnatm_args); + + rnatm_args->octrees_storage = NULL; + rnatm_args->load_octrees_from_storage = 0; + + if(!args->octrees_storage) goto exit; + + fd = open(args->octrees_storage, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); + if(fd < 0) { res = RES_IO_ERR; goto error; } + + rnatm_args->octrees_storage = fdopen(fd, "w+"); + if(!rnatm_args->octrees_storage) { res = RES_IO_ERR; goto error; } + + /* From now on, manage the opened file from its pointer and not from its + * descriptor */ + fd = -1; + + err = stat(args->octrees_storage, &file_stat); + if(err < 0) { res = RES_IO_ERR; goto error; } + + if(file_stat.st_size != 0) { + /* The file is not empty and therefore must contain valid octrees */ + rnatm_args->load_octrees_from_storage = 1; + } + +exit: + cmd->octrees_storage = rnatm_args->octrees_storage; + return res; +error: + htrdr_log_err(cmd->htrdr, "error opening the octree storage `%s' -- %s\n", + args->octrees_storage, res_to_cstr(res)); + + if(fd >= 0) CHK(close(fd) == 0); + if(rnatm_args->octrees_storage) CHK(fclose(rnatm_args->octrees_storage) == 0); + rnatm_args->octrees_storage = NULL; + rnatm_args->load_octrees_from_storage = 1; + goto exit; +} + +static res_T +setup_atmosphere + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args) +{ + struct rnatm_create_args rnatm_args = RNATM_CREATE_ARGS_DEFAULT; + res_T res = RES_OK; + ASSERT(cmd && args); + + rnatm_args.gas = args->gas; + rnatm_args.aerosols = args->aerosols; + rnatm_args.naerosols = args->naerosols; + rnatm_args.name = "atmosphere"; + rnatm_args.spectral_range[0] = args->spectral_domain.wlen_range[0]; + rnatm_args.spectral_range[1] = args->spectral_domain.wlen_range[1]; + rnatm_args.optical_thickness = args->optical_thickness; + rnatm_args.grid_definition_hint = args->octree_definition_hint; + rnatm_args.precompute_normals = args->precompute_normals; + rnatm_args.logger = htrdr_get_logger(cmd->htrdr); + rnatm_args.allocator = htrdr_get_allocator(cmd->htrdr); + rnatm_args.nthreads = args->nthreads; + rnatm_args.verbose = args->verbose; + + res = setup_octree_storage(cmd, args, &rnatm_args); + if(res != RES_OK) goto error; + + res = rnatm_create(&rnatm_args, &cmd->atmosphere); + if(res != RES_OK) goto error; + +exit: + return res; +error: + if(cmd->atmosphere) { + RNATM(ref_put(cmd->atmosphere)); + cmd->atmosphere = NULL; + } + goto exit; +} + +static res_T +setup_ground + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args) +{ + struct rngrd_create_args rngrd_args = RNGRD_CREATE_ARGS_DEFAULT; + res_T res = RES_OK; + ASSERT(cmd && args); + + if(cmd->output_type == HTRDR_PLANETS_ARGS_OUTPUT_OCTREES) + goto exit; + + rngrd_args.smsh_filename = args->ground.smsh_filename; + rngrd_args.props_filename = args->ground.props_filename; + rngrd_args.mtllst_filename = args->ground.mtllst_filename; + rngrd_args.name = args->ground.name; + rngrd_args.logger = htrdr_get_logger(cmd->htrdr); + rngrd_args.allocator = htrdr_get_allocator(cmd->htrdr); + rngrd_args.verbose = args->verbose; + + res = rngrd_create(&rngrd_args, &cmd->ground); + if(res != RES_OK) goto error; + +exit: + return res; +error: + if(cmd->ground) { + RNGRD(ref_put(cmd->ground)); + cmd->ground = NULL; + } + goto exit; +} + +static res_T +setup_spectral_domain_sw + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args) +{ + res_T res = RES_OK; + ASSERT(cmd && args); + ASSERT(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW); + + /* Discrete distribution */ + if(args->source.rnrl_filename) { + struct htrdr_planets_source_spectrum spectrum; + struct htrdr_ran_wlen_discrete_create_args discrete_args; + + res = htrdr_planets_source_get_spectrum + (cmd->source, cmd->spectral_domain.wlen_range, &spectrum); + if(res != RES_OK) goto error; + + discrete_args.get = htrdr_planets_source_spectrum_at; + discrete_args.nwavelengths = spectrum.size; + discrete_args.context = &spectrum; + res = htrdr_ran_wlen_discrete_create + (cmd->htrdr, &discrete_args, &cmd->discrete); + if(res != RES_OK) goto error; + + /* Planck distribution */ + } else { + const size_t nintervals = compute_nintervals_for_spectral_cdf(cmd); + + /* Use the source temperature as the reference temperature of the Planck + * distribution */ + res = htrdr_ran_wlen_planck_create(cmd->htrdr, + cmd->spectral_domain.wlen_range, nintervals, args->source.temperature, + &cmd->planck); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} + +static INLINE res_T +setup_spectral_domain + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args) +{ + double ground_T_range[2]; + size_t nintervals; + res_T res = RES_OK; + ASSERT(cmd && args); + + cmd->spectral_domain = args->spectral_domain; + + /* Configure the spectral distribution */ + switch(cmd->spectral_domain.type) { + + case HTRDR_SPECTRAL_LW: + res = rngrd_get_temperature_range(cmd->ground, ground_T_range); + if(res != RES_OK) goto error; + + /* Use as the reference temperature of the Planck distribution the + * maximum scene temperature which, in fact, should be the maximum ground + * temperature */ + nintervals = compute_nintervals_for_spectral_cdf(cmd); + res = htrdr_ran_wlen_planck_create(cmd->htrdr, + cmd->spectral_domain.wlen_range, nintervals, ground_T_range[1], + &cmd->planck); + if(res != RES_OK) goto error; + break; + + case HTRDR_SPECTRAL_SW: + res = setup_spectral_domain_sw(cmd, args); + if(res != RES_OK) goto error; + break; + + case HTRDR_SPECTRAL_SW_CIE_XYZ: + /* CIE XYZ distribution */ + nintervals = compute_nintervals_for_spectral_cdf(cmd); + res = htrdr_ran_wlen_cie_xyz_create(cmd->htrdr, + cmd->spectral_domain.wlen_range, nintervals, &cmd->cie); + if(res != RES_OK) goto error; + break; + + default: FATAL("Unreachable code\n"); break; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +setup_output + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args) +{ + const char* output_name = NULL; + res_T res = RES_OK; + ASSERT(cmd && args); + + /* No output stream on non master processes */ + if(htrdr_get_mpi_rank(cmd->htrdr) != 0) { + cmd->output = NULL; + output_name = "<null>"; + + /* Write results on stdout */ + } else if(!args->output) { + cmd->output = stdout; + output_name = "<stdout>"; + + /* Open the output stream */ + } else { + res = htrdr_open_output_stream(cmd->htrdr, args->output, 0/*read*/, + args->force_output_overwrite, &cmd->output); + if(res != RES_OK) goto error; + output_name = args->output; + } + + res = str_set(&cmd->output_name, output_name); + if(res != RES_OK) { + htrdr_log_err(cmd->htrdr, "error storing output stream name `%s' -- %s\n", + output_name, res_to_cstr(res)); + goto error; + } + + cmd->output_type = args->output_type; + +exit: + return res; +error: + str_clear(&cmd->output_name); + if(cmd->output && cmd->output != stdout) { + CHK(fclose(cmd->output) == 0); + cmd->output = NULL; + } + goto exit; +} + +static INLINE res_T +setup_source + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args) +{ + res_T res = RES_OK; + ASSERT(cmd && args); + + if(cmd->output_type == HTRDR_PLANETS_ARGS_OUTPUT_OCTREES) + goto exit; + + res = htrdr_planets_source_create(cmd->htrdr, &args->source, &cmd->source); + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +} + +static res_T +setup_camera + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args) +{ + struct scam_perspective_args cam_args = SCAM_PERSPECTIVE_ARGS_DEFAULT; + res_T res = RES_OK; + ASSERT(cmd && args); + + if(cmd->output_type != HTRDR_PLANETS_ARGS_OUTPUT_IMAGE) + goto exit; + + ASSERT(htrdr_args_camera_perspective_check(&args->cam_persp) == RES_OK); + ASSERT(htrdr_args_image_check(&args->image) == RES_OK); + + d3_set(cam_args.position, args->cam_persp.position); + d3_set(cam_args.target, args->cam_persp.target); + d3_set(cam_args.up, args->cam_persp.up); + cam_args.field_of_view = MDEG2RAD(args->cam_persp.fov_y); + cam_args.lens_radius = args->cam_persp.lens_radius; + cam_args.focal_distance = args->cam_persp.focal_dst; + cam_args.aspect_ratio = + (double)args->image.definition[0] + / (double)args->image.definition[1]; + + res = scam_create_perspective + (htrdr_get_logger(cmd->htrdr), + htrdr_get_allocator(cmd->htrdr), + htrdr_get_verbosity_level(cmd->htrdr), + &cam_args, + &cmd->camera); + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +} + +static res_T +setup_buffer + (struct htrdr_planets* cmd, + const struct htrdr_planets_args* args) +{ + struct htrdr_pixel_format pixfmt = HTRDR_PIXEL_FORMAT_NULL; + res_T res = RES_OK; + ASSERT(cmd && args); + + if(cmd->output_type != HTRDR_PLANETS_ARGS_OUTPUT_IMAGE) + goto exit; + + planets_get_pixel_format(cmd, &pixfmt); + + /* Setup buffer layout */ + cmd->buf_layout.width = args->image.definition[0]; + cmd->buf_layout.height = args->image.definition[1]; + cmd->buf_layout.pitch = args->image.definition[0] * pixfmt.size; + cmd->buf_layout.elmt_size = pixfmt.size; + cmd->buf_layout.alignment = pixfmt.alignment; + + /* Save the number of samples per pixel */ + cmd->spp = args->image.spp; + + /* Create the image buffer only on the master process; Image parts rendered + * by other processes are collected there */ + if(htrdr_get_mpi_rank(cmd->htrdr) != 0) goto exit; + + res = htrdr_buffer_create(cmd->htrdr, &cmd->buf_layout, &cmd->buf); + if(res != RES_OK) goto error; + +exit: + return res; +error: + if(cmd->buf) { htrdr_buffer_ref_put(cmd->buf); cmd->buf = NULL; } + goto exit; +} + +static INLINE res_T +write_vtk_octrees(const struct htrdr_planets* cmd) +{ + size_t octrees_range[2]; + res_T res = RES_OK; + ASSERT(cmd); + + /* Nothing to do on non master process */ + if(htrdr_get_mpi_rank(cmd->htrdr) != 0) goto exit; + + octrees_range[0] = 0; + octrees_range[1] = rnatm_get_spectral_items_count(cmd->atmosphere) - 1; + + res = rnatm_write_vtk_octrees(cmd->atmosphere, octrees_range, cmd->output); + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +} + +static void +planets_release(ref_T* ref) +{ + struct htrdr_planets* cmd = CONTAINER_OF(ref, struct htrdr_planets, ref); + struct htrdr* htrdr = NULL; + ASSERT(ref); + + if(cmd->atmosphere) RNATM(ref_put(cmd->atmosphere)); + if(cmd->ground) RNGRD(ref_put(cmd->ground)); + if(cmd->source) htrdr_planets_source_ref_put(cmd->source); + if(cmd->cie) htrdr_ran_wlen_cie_xyz_ref_put(cmd->cie); + if(cmd->discrete) htrdr_ran_wlen_discrete_ref_put(cmd->discrete); + if(cmd->planck) htrdr_ran_wlen_planck_ref_put(cmd->planck); + if(cmd->octrees_storage) CHK(fclose(cmd->octrees_storage) == 0); + if(cmd->output && cmd->output != stdout) CHK(fclose(cmd->output) == 0); + if(cmd->buf) htrdr_buffer_ref_put(cmd->buf); + if(cmd->camera) SCAM(ref_put(cmd->camera)); + str_release(&cmd->output_name); + + htrdr = cmd->htrdr; + MEM_RM(htrdr_get_allocator(htrdr), cmd); + htrdr_ref_put(htrdr); +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +htrdr_planets_create + (struct htrdr* htrdr, + const struct htrdr_planets_args* args, + struct htrdr_planets** out_cmd) +{ + struct htrdr_planets* cmd = NULL; + res_T res = RES_OK; + ASSERT(htrdr && out_cmd); + + res = htrdr_planets_args_check(args); + if(res != RES_OK) { + htrdr_log_err(htrdr, "Invalid htrdr_planets arguments -- %s\n", + res_to_cstr(res)); + goto error; + } + + cmd = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*cmd)); + if(!cmd) { + htrdr_log_err(htrdr, "Error allocating htrdr_planets command\n"); + res = RES_MEM_ERR; + goto error; + } + ref_init(&cmd->ref); + htrdr_ref_get(htrdr); + cmd->htrdr = htrdr; + str_init(htrdr_get_allocator(htrdr), &cmd->output_name); + + res = setup_output(cmd, args); + if(res != RES_OK) goto error; + res = setup_source(cmd, args); + if(res != RES_OK) goto error; + res = setup_camera(cmd, args); + if(res != RES_OK) goto error; + res = setup_ground(cmd, args); + if(res != RES_OK) goto error; + res = setup_atmosphere(cmd, args); + if(res != RES_OK) goto error; + res = setup_spectral_domain(cmd, args); + if(res != RES_OK) goto error; + res = setup_buffer(cmd, args); + if(res != RES_OK) goto error; + +exit: + *out_cmd = cmd; + return res; +error: + if(cmd) { + htrdr_planets_ref_put(cmd); + cmd = NULL; + } + goto exit; +} + +void +htrdr_planets_ref_get(struct htrdr_planets* cmd) +{ + ASSERT(cmd); + ref_get(&cmd->ref); +} + +void +htrdr_planets_ref_put(struct htrdr_planets* cmd) +{ + ASSERT(cmd); + ref_put(&cmd->ref, planets_release); +} + +res_T +htrdr_planets_run(struct htrdr_planets* cmd) +{ + res_T res = RES_OK; + ASSERT(cmd); + + switch(cmd->output_type) { + case HTRDR_PLANETS_ARGS_OUTPUT_IMAGE: + res = planets_draw_map(cmd); + break; + case HTRDR_PLANETS_ARGS_OUTPUT_OCTREES: + res = write_vtk_octrees(cmd); + break; + default: FATAL("Unreachable code\n"); break; + } + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +} + +/******************************************************************************* + * Local function + ******************************************************************************/ +void +planets_get_pixel_format + (const struct htrdr_planets* cmd, + struct htrdr_pixel_format* fmt) +{ + ASSERT(cmd && fmt && cmd->output_type == HTRDR_PLANETS_ARGS_OUTPUT_IMAGE); + (void)cmd; + + switch(cmd->spectral_domain.type) { + case HTRDR_SPECTRAL_LW: + case HTRDR_SPECTRAL_SW: + fmt->size = sizeof(struct planets_pixel_xwave); + fmt->alignment = ALIGNOF(struct planets_pixel_xwave); + break; + case HTRDR_SPECTRAL_SW_CIE_XYZ: + fmt->size = sizeof(struct planets_pixel_image); + fmt->alignment = ALIGNOF(struct planets_pixel_image); + break; + default: FATAL("Unreachable code\n"); break; + } +} diff --git a/src/planets/htrdr_planets.h b/src/planets/htrdr_planets.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef HTRDR_PLANETS_H +#define HTRDR_PLANETS_H + +#include "core/htrdr.h" +#include <rsys/rsys.h> + +struct htrdr; +struct htrdr_planets; +struct htrdr_planets_args; + +BEGIN_DECLS + +HTRDR_API res_T +htrdr_planets_create + (struct htrdr* htrdr, + const struct htrdr_planets_args* args, + struct htrdr_planets** cmd); + +HTRDR_API void +htrdr_planets_ref_get + (struct htrdr_planets* cmd); + +HTRDR_API void +htrdr_planets_ref_put + (struct htrdr_planets* cmd); + +HTRDR_API res_T +htrdr_planets_run + (struct htrdr_planets* cmd); + +HTRDR_API int +htrdr_planets_main + (int argc, + char** argv); + +END_DECLS + +#endif /* HTRDR_PLANETS_H */ diff --git a/src/planets/htrdr_planets_args.c b/src/planets/htrdr_planets_args.c @@ -0,0 +1,734 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#define _POSIX_C_SOURCE 200112L /* strtok_r support */ + +#include "planets/htrdr_planets_args.h" + +#include <rsys/cstr.h> +#include <rsys/stretchy_array.h> +#include <rsys/mem_allocator.h> + +#include <getopt.h> +#include <string.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE res_T +check_gas_args(const struct rnatm_gas_args* args) +{ + if(!args) return RES_BAD_ARG; + + /* Filenames cannot be NULL */ + if(!args->smsh_filename + || !args->sck_filename + || !args->temperatures_filename) + return RES_BAD_ARG; + + return RES_OK; +} + +static INLINE res_T +check_aerosol_args(const struct rnatm_aerosol_args* args) +{ + if(!args) return RES_BAD_ARG; + + /* Filenames cannot be NULL */ + if(!args->smsh_filename + || !args->sars_filename + || !args->phase_fn_ids_filename + || !args->phase_fn_lst_filename) + return RES_BAD_ARG; + + return RES_OK; +} + +static INLINE res_T +check_ground_args(const struct htrdr_planets_ground_args* args) +{ + if(!args) return RES_BAD_ARG; + + /* Filenames cannot be NULL */ + if(!args->smsh_filename + || !args->props_filename + || !args->mtllst_filename) + return RES_BAD_ARG; + + return RES_OK; +} + +static INLINE res_T +check_spectral_args(const struct htrdr_planets_spectral_args* args) +{ + if(!args) return RES_BAD_ARG; + + /* Invalid type */ + switch(args->type) { + case HTRDR_SPECTRAL_LW: + case HTRDR_SPECTRAL_SW: + case HTRDR_SPECTRAL_SW_CIE_XYZ: + /* Nothing to be done */ + break; + default: + return RES_BAD_ARG; + } + + /* Invalid spectral range */ + if(args->wlen_range[0] < 0 + || args->wlen_range[1] < 0 + || args->wlen_range[0] > args->wlen_range[1]) + return RES_BAD_ARG; + + return RES_OK; +} +static void +usage(void) +{ + printf("usage: htrdr-planets [-dfhNv] [-a aerosol_opt[:aerosol_opt ...]]\n"); + printf(" [-C persp_camera_opt[:persp_camera_opt ...]]\n"); + printf(" [-G ground_opt[:ground_opt ...]]\n"); + printf(" [-i image_opt[:image_opt ...]] [-O accel_struct_storage]\n"); + printf(" [-o output] [-S source_opt[:source_opt ...]]\n"); + printf(" [-s spectral_opt[:spectral_opt ...]] [-T optical_thickness]\n"); + printf(" [-t threads_count] [-V accel_struct_definition]\n"); + printf(" -g gas_opt[:gas_opt ...] \n"); +} + +static INLINE char* +str_dup(const char* str) +{ + size_t len = 0; + char* dup = NULL; + ASSERT(str); + len = strlen(str) + 1/*NULL char*/; + dup = mem_alloc(len); + if(!dup) { + return NULL; + } else { + return memcpy(dup, str, len); + } +} + +static res_T +parse_aerosol_parameters(const char* str, void* ptr) +{ + enum { MESH, NAME, RADPROP, PHASEFN, PHASEIDS } iparam; + struct rnatm_aerosol_args* aerosol = NULL; + char buf[BUFSIZ]; + struct htrdr_planets_args* args = ptr; + char* key; + char* val; + char* tk_ctx; + res_T res = RES_OK; + ASSERT(args && str); + + if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the aerosol parameter `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &tk_ctx); + val = strtok_r(NULL, "", &tk_ctx); + + if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "name")) iparam = NAME; + else if(!strcmp(key, "radprop")) iparam = RADPROP; + else if(!strcmp(key, "phasefn")) iparam = PHASEFN; + else if(!strcmp(key, "phaseids")) iparam = PHASEIDS; + else { + fprintf(stderr, "Invalid aerosol parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!val) { + fprintf(stderr, "Invalid null value for aerosol parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + ASSERT(args->naerosols); + aerosol = args->aerosols + (args->naerosols - 1); + + #define SET_STR(Dst) { \ + if(Dst) mem_rm(Dst); \ + if(!((Dst) = str_dup(val))) res = RES_MEM_ERR; \ + } (void)0 + switch(iparam) { + case MESH: SET_STR(aerosol->smsh_filename); break; + case NAME: SET_STR(aerosol->name); break; + case RADPROP: SET_STR(aerosol->sars_filename); break; + case PHASEFN: SET_STR(aerosol->phase_fn_lst_filename); break; + case PHASEIDS: SET_STR(aerosol->phase_fn_ids_filename); break; + default: FATAL("Unreachable code\n"); break; + } + #undef SET_STR + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the aerosol parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_ground_parameters(const char* str, void* ptr) +{ + enum { BRDF, MESH, NAME, PROP } iparam; + char buf[BUFSIZ]; + struct htrdr_planets_args* args = ptr; + char* key; + char* val; + char* tk_ctx; + res_T res = RES_OK; + ASSERT(args && str); + + if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the ground parameter `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &tk_ctx); + val = strtok_r(NULL, "", &tk_ctx); + + if(!strcmp(key, "brdf")) iparam = BRDF; + else if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "name")) iparam = NAME; + else if(!strcmp(key, "prop")) iparam = PROP; + else { + fprintf(stderr, "Invalid ground parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!val) { + fprintf(stderr, "Invalid null value for ground parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + #define SET_STR(Dst) { \ + if(Dst) mem_rm(Dst); \ + if(!((Dst) = str_dup(val))) res = RES_MEM_ERR; \ + } (void)0 + switch(iparam) { + case BRDF: SET_STR(args->ground.mtllst_filename); break; + case MESH: SET_STR(args->ground.smsh_filename); break; + case NAME: SET_STR(args->ground.name); break; + case PROP: SET_STR(args->ground.props_filename); break; + default: FATAL("Unreachable code\n"); break; + } + #undef SET_STR + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the ground parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_gas_parameters(const char* str, void* ptr) +{ + enum { MESH, CK, TEMP } iparam; + char buf[BUFSIZ]; + struct htrdr_planets_args* args = ptr; + char* key; + char* val; + char* tk_ctx; + res_T res = RES_OK; + ASSERT(args && str); + + if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the gas parameter `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &tk_ctx); + val = strtok_r(NULL, "", &tk_ctx); + + if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "ck")) iparam = CK; + else if(!strcmp(key, "temp")) iparam = TEMP; + else { + fprintf(stderr, "Invalid gas parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!val) { + fprintf(stderr, "Invalid null value for gas parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + #define SET_STR(Dst) { \ + if(Dst) mem_rm(Dst); \ + if(!((Dst) = str_dup(val))) res = RES_MEM_ERR; \ + } (void)0 + switch(iparam) { + case MESH: SET_STR(args->gas.smsh_filename); break; + case CK: SET_STR(args->gas.sck_filename); break; + case TEMP: SET_STR(args->gas.temperatures_filename); break; + default: FATAL("Unreachable code\n"); break; + } + #undef SET_STR + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the gas parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_source_parameters(const char* str, void* ptr) +{ + enum {LAT, LON, DST, RADIUS, TEMP, RAD} iparam; + char buf[BUFSIZ]; + struct htrdr_planets_args* args = ptr; + struct htrdr_planets_source_args* src = NULL; + char* key; + char* val; + char* tk_ctx; + res_T res = RES_OK; + ASSERT(str && ptr); + + src = &args->source; + + if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the source parameter `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &tk_ctx); + val = strtok_r(NULL, "", &tk_ctx); + + if(!strcmp(key, "lat")) iparam = LAT; + else if(!strcmp(key, "lon")) iparam = LON; + else if(!strcmp(key, "dst")) iparam = DST; + else if(!strcmp(key, "rad")) iparam = RAD; + else if(!strcmp(key, "radius")) iparam = RADIUS; + else if(!strcmp(key, "temp")) iparam = TEMP; + else { + fprintf(stderr, "Invalid source parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!val) { + fprintf(stderr, "Invalid null value for the source parameter`%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + switch(iparam) { + case LAT: + res = cstr_to_double(val, &src->latitude); + if(res == RES_OK && (src->latitude < -90 || src->latitude > 90)) { + res = RES_BAD_ARG; + } + break; + case LON: + res = cstr_to_double(val, &src->longitude); + if(res == RES_OK && (src->longitude < -180 || src->longitude > 180)) { + res = RES_BAD_ARG; + } + break; + case DST: + res = cstr_to_double(val, &src->distance); + if(res == RES_OK && src->distance < 0) res = RES_BAD_ARG; + break; + case RAD: + /* Use a per wavelength radiance rather than a constant temperature */ + src->temperature = -1; + if(src->rnrl_filename) mem_rm(src->rnrl_filename); + src->rnrl_filename = str_dup(val); + if(!src->rnrl_filename) res = RES_MEM_ERR; + break; + case RADIUS: + res = cstr_to_double(val, &src->radius); + if(res == RES_OK && src->radius < 0) res = RES_BAD_ARG; + break; + case TEMP: + /* Use a constant temperature rather than a per wavelength radiance */ + if(src->rnrl_filename) { + mem_rm(src->rnrl_filename); + src->rnrl_filename = NULL; + } + res = cstr_to_double(val, &src->temperature); + if(res == RES_OK && src->temperature < 0) res = RES_BAD_ARG; + break; + default: FATAL("Unreachable code\n"); break; + } + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the source parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static INLINE res_T +parse_spectral_range(const char* str, double wlen_range[2]) +{ + double range[2]; + size_t len; + res_T res = RES_OK; + ASSERT(wlen_range && str); + + res = cstr_to_list_double(str, ',', range, &len, 2); + if(res == RES_OK && len != 2) res = RES_BAD_ARG; + if(res == RES_OK && range[0] > range[1]) res = RES_BAD_ARG; + if(res == RES_OK && (range[0] < 0 || range[1] < 0)) res = RES_BAD_ARG; + if(res != RES_OK) goto error; + + wlen_range[0] = range[0]; + wlen_range[1] = range[1]; + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_spectral_parameters(const char* str, void* ptr) +{ + enum {CIE_XYZ, LW, SW} iparam; + char buf[BUFSIZ]; + struct htrdr_planets_args* args = ptr; + struct htrdr_planets_spectral_args* spectral = NULL; + char* key; + char* val; + char* tk_ctx; + res_T res = RES_OK; + ASSERT(str && ptr); + + spectral = &args->spectral_domain; + + if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the spectral parameter `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &tk_ctx); + val = strtok_r(NULL, "", &tk_ctx); + + if(!strcmp(key, "cie_xyz")) iparam = CIE_XYZ; + else if(!strcmp(key, "lw")) iparam = LW; + else if(!strcmp(key, "sw")) iparam = SW; + else { + fprintf(stderr, "Invalid spectral parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if((iparam == LW || iparam == SW) && !val) { + fprintf(stderr, + "Invalid null value for the spectral parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + switch(iparam) { + case CIE_XYZ: + spectral->type = HTRDR_SPECTRAL_SW_CIE_XYZ; + spectral->wlen_range[0] = HTRDR_RAN_WLEN_CIE_XYZ_RANGE_DEFAULT[0]; + spectral->wlen_range[1] = HTRDR_RAN_WLEN_CIE_XYZ_RANGE_DEFAULT[1]; + break; + case LW: + spectral->type = HTRDR_SPECTRAL_LW; + res = parse_spectral_range(val, spectral->wlen_range); + break; + case SW: + spectral->type = HTRDR_SPECTRAL_SW; + res = parse_spectral_range(val, spectral->wlen_range); + break; + default: FATAL("Unreachable code\n"); break; + } + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the spectral parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +htrdr_planets_args_init(struct htrdr_planets_args* args, int argc, char** argv) +{ + int opt; + res_T res = RES_OK; + ASSERT(args && argc && argv); + + *args = HTRDR_PLANETS_ARGS_DEFAULT; + + while((opt = getopt(argc, argv, "a:C:dfG:g:hi:NO:o:S:s:T:t:V:v")) != -1) { + switch(opt) { + case 'a': + (void)sa_add(args->aerosols, 1); + args->aerosols[args->naerosols] = RNATM_AEROSOL_ARGS_NULL; + args->naerosols += 1; + res = cstr_parse_list(optarg, ':', parse_aerosol_parameters, args); + if(res == RES_OK) { + res = check_aerosol_args(args->aerosols+args->naerosols-1); + } + break; + case 'C': + res = htrdr_args_camera_perspective_parse(&args->cam_persp, optarg); + args->output_type = HTRDR_PLANETS_ARGS_OUTPUT_IMAGE; + break; + case 'd': + args->output_type = HTRDR_PLANETS_ARGS_OUTPUT_OCTREES; + break; + case 'f': + args->force_output_overwrite = 1; + break; + case 'G': + res = cstr_parse_list(optarg, ':', parse_ground_parameters, args); + if(res == RES_OK) { + res = check_ground_args(&args->ground); + } + break; + case 'g': + res = cstr_parse_list(optarg, ':', parse_gas_parameters, args); + if(res == RES_OK) { + res = check_gas_args(&args->gas); + } + break; + case 'h': + usage(); + htrdr_planets_args_release(args); + args->quit = 1; + goto exit; + case 'i': + res = htrdr_args_image_parse(&args->image, optarg); + break; + case 'N': args->precompute_normals = 1; break; + case 'O': args->octrees_storage = optarg; break; + case 'o': args->output = optarg; break; + case 'S': + res = cstr_parse_list(optarg, ':', parse_source_parameters, args); + break; + case 's': + res = cstr_parse_list(optarg, ':', parse_spectral_parameters, args); + break; + case 'T': + res = cstr_to_double(optarg, &args->optical_thickness); + if(res == RES_OK && args->optical_thickness < 0) res = RES_BAD_ARG; + break; + case 't': + res = cstr_to_uint(optarg, &args->nthreads); + if(res == RES_OK && !args->nthreads) res = RES_BAD_ARG; + break; + case 'V': + res = cstr_to_uint(optarg, &args->octree_definition_hint); + if(res == RES_OK && !args->octree_definition_hint) res = RES_BAD_ARG; + break; + case 'v': args->verbose = 1; break; + default: res = RES_BAD_ARG; break; + } + if(res != RES_OK) { + if(optarg) { + fprintf(stderr, "%s: invalid option argument '%s' -- '%c'\n", + argv[0], optarg, opt); + } + goto error; + } + } + + res = check_gas_args(&args->gas); + if(res != RES_OK) { + fprintf(stderr, "missing gas definition -- option '-g'\n"); + goto error; + } + + if(args->output_type != HTRDR_PLANETS_ARGS_OUTPUT_OCTREES) { + res = check_ground_args(&args->ground); + if(res != RES_OK) { + fprintf(stderr, "missing ground definition -- option '-G'\n"); + goto error; + } + + /* Check the source */ + if(args->spectral_domain.type == HTRDR_SPECTRAL_SW + || args->spectral_domain.type == HTRDR_SPECTRAL_SW_CIE_XYZ) { + res = htrdr_planets_source_args_check(&args->source); + if(res != RES_OK) { + fprintf(stderr, "missing source definition -- option '-S'\n"); + goto error; + } + } + } + +exit: + return res; +error: + usage(); + htrdr_planets_args_release(args); + goto exit; +} + +void +htrdr_planets_args_release(struct htrdr_planets_args* args) +{ + size_t i; + ASSERT(args); + + if(args->gas.smsh_filename) mem_rm(args->gas.smsh_filename); + if(args->gas.sck_filename) mem_rm(args->gas.sck_filename); + if(args->gas.temperatures_filename) mem_rm(args->gas.temperatures_filename); + if(args->ground.smsh_filename) mem_rm(args->ground.smsh_filename); + if(args->ground.props_filename) mem_rm(args->ground.props_filename); + if(args->ground.mtllst_filename) mem_rm(args->ground.mtllst_filename); + if(args->ground.name) mem_rm(args->ground.name); + if(args->source.rnrl_filename) mem_rm(args->source.rnrl_filename); + + FOR_EACH(i, 0, args->naerosols) { + struct rnatm_aerosol_args* aerosol = args->aerosols + i; + if(aerosol->name) mem_rm(aerosol->name); + if(aerosol->smsh_filename) mem_rm(aerosol->smsh_filename); + if(aerosol->sars_filename) mem_rm(aerosol->sars_filename); + if(aerosol->phase_fn_ids_filename) mem_rm(aerosol->phase_fn_ids_filename); + if(aerosol->phase_fn_lst_filename) mem_rm(aerosol->phase_fn_lst_filename); + } + sa_release(args->aerosols); + + *args = HTRDR_PLANETS_ARGS_DEFAULT; +} + +res_T +htrdr_planets_args_check(const struct htrdr_planets_args* args) +{ + size_t i; + res_T res = RES_OK; + + if(!args) return RES_BAD_ARG; + + /* Check the gas */ + res = check_gas_args(&args->gas); + if(res != RES_OK) return res; + + /* Check the aerosols */ + FOR_EACH(i, 0, args->naerosols) { + res = check_aerosol_args(args->aerosols+i); + if(res != RES_OK) return res; + } + + /* Check the octree parameters */ + if(args->octree_definition_hint == 0 + || args->optical_thickness < 0) + return RES_BAD_ARG; + + /* Check the spectral domain */ + res = check_spectral_args(&args->spectral_domain); + if(res != RES_OK) return res; + + if(args->output_type != HTRDR_PLANETS_ARGS_OUTPUT_OCTREES) { + /* Check the ground */ + res = check_ground_args(&args->ground); + if(res != RES_OK) return res; + + /* Check the source */ + if(args->spectral_domain.type == HTRDR_SPECTRAL_SW + || args->spectral_domain.type == HTRDR_SPECTRAL_SW_CIE_XYZ) { + res = htrdr_planets_source_args_check(&args->source); + if(res != RES_OK) return res; + } + } + + if(args->output_type != HTRDR_PLANETS_ARGS_OUTPUT_IMAGE) { + res = htrdr_args_camera_perspective_check(&args->cam_persp); + if(res != RES_OK) return res; + + res = htrdr_args_image_check(&args->image); + if(res != RES_OK) return res; + } + + /* Check miscalleneous parameters */ + if(args->nthreads == 0 + || (unsigned)args->output_type >= HTRDR_PLANETS_ARGS_OUTPUT_TYPES_COUNT__) + return RES_BAD_ARG; + + return RES_OK; +} + +res_T +htrdr_planets_source_args_check(const struct htrdr_planets_source_args* args) +{ + if(!args) return RES_BAD_ARG; + + /* Invalid position */ + if(args->latitude <-90 + || args->latitude > 90 + || args->longitude <-180 + || args->longitude > 180 + || args->distance < 0) + return RES_BAD_ARG; + + /* Invalid radius */ + if(args->radius < 0) + return RES_BAD_ARG; + + /* Invalid radiance */ + if((args->temperature < 0 && !args->rnrl_filename) /* Both are invalids */ + || (args->temperature >=0 && args->rnrl_filename)) /* Both are valids */ + return RES_BAD_ARG; + + return RES_OK; +} diff --git a/src/planets/htrdr_planets_args.h.in b/src/planets/htrdr_planets_args.h.in @@ -0,0 +1,148 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef HTRDR_PLANETS_ARGS_H +#define HTRDR_PLANETS_ARGS_H + +#include "core/htrdr_args.h" + +#include <rad-net/rnatm.h> +#include <rsys/rsys.h> + +#include <limits.h> /* UINT_MAX */ + +enum htrdr_planets_args_output_type { + HTRDR_PLANETS_ARGS_OUTPUT_IMAGE, + HTRDR_PLANETS_ARGS_OUTPUT_OCTREES, + HTRDR_PLANETS_ARGS_OUTPUT_TYPES_COUNT__ +}; + +struct htrdr_planets_spectral_args { + double wlen_range[2]; /* Spectral range in nm */ + enum htrdr_spectral_type type; +}; +#define HTRDR_PLANETS_SPECTRAL_ARGS_DEFAULT__ { \ + HTRDR_RAN_WLEN_CIE_XYZ_RANGE_DEFAULT__, /* Spectral range */ \ + HTRDR_SPECTRAL_SW_CIE_XYZ, /* Spectral type */ \ +} +static const struct htrdr_planets_spectral_args +HTRDR_PLANETS_SPECTRAL_ARGS_DEFAULT = HTRDR_PLANETS_SPECTRAL_ARGS_DEFAULT__; + +struct htrdr_planets_source_args { + /* Radiance of the source per wavelength. May be NULL */ + char* rnrl_filename; + + double longitude; /* In [-180, 180] degrees */ + double latitude; /* In [-90, 90] degrees */ + double distance; /* In km */ + double radius; /* In km */ + double temperature; /* In Kelvin */ +}; +#define HTRDR_PLANETS_SOURCE_ARGS_NULL__ {NULL,0,0,0,-1,-1} +static const struct htrdr_planets_source_args HTRDR_PLANETS_SOURCE_ARGS_NULL = + HTRDR_PLANETS_SOURCE_ARGS_NULL__; + +struct htrdr_planets_ground_args { + char* smsh_filename; /* The Star-Mesh geometry */ + char* props_filename; /* Per triangle physical properties */ + char* mtllst_filename; /* List of used materials */ + char* name; +}; +#define HTRDR_PLANETS_GROUND_ARGS_NULL__ {NULL,NULL,NULL,NULL} +static const struct htrdr_planets_ground_args HTRDR_PLANETS_GROUND_ARGS_NULL = + HTRDR_PLANETS_GROUND_ARGS_NULL__; + +struct htrdr_planets_args { + /* System data */ + struct rnatm_gas_args gas; + struct rnatm_aerosol_args* aerosols; + size_t naerosols; + struct htrdr_planets_ground_args ground; + + /* Read/Write file where octrees are stored. May be NULL => octres are built + * at runtime and kept in memory */ + char* octrees_storage; + + unsigned octree_definition_hint; /* Hint on octree definition */ + double optical_thickness; /* Threshold used during octree building */ + + char* output; /* File where the result is written */ + struct htrdr_planets_spectral_args spectral_domain; /* Integration spectral domain */ + struct htrdr_planets_source_args source; + struct htrdr_args_image image; + + struct htrdr_args_camera_perspective cam_persp; /* Perspective camera */ + + /* Miscellaneous arguments */ + unsigned nthreads; /* Hint on the nimber of threads to use */ + enum htrdr_planets_args_output_type output_type; + int precompute_normals; /* Pre-compute tetrahedron normals */ + int force_output_overwrite; /* Replace output if it exists */ + int verbose; /* Verbose level */ + int quit; /* Stop the command */ +}; +#define HTRDR_PLANETS_ARGS_DEFAULT__ { \ + RNATM_GAS_ARGS_NULL__, /* Gas */ \ + NULL, /* List of aerosols */ \ + 0, /* Number of aerosols */ \ + HTRDR_PLANETS_GROUND_ARGS_NULL__, /* Ground */ \ + \ + NULL, /* File where to dump octrees */ \ + \ + @HTRDR_PLANETS_ARGS_DEFAULT_GRID_DEFINITION_HINT@, /* octree definition */ \ + @HTRDR_PLANETS_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD@, \ + \ + NULL, /* Ouput file */ \ + HTRDR_PLANETS_SPECTRAL_ARGS_DEFAULT__, /* Spectral domain */ \ + HTRDR_PLANETS_SOURCE_ARGS_NULL__, /* Source */ \ + HTRDR_ARGS_IMAGE_DEFAULT__, /* Image */ \ + \ + HTRDR_ARGS_CAMERA_PERSPECTIVE_DEFAULT__, /* Perspective camera */ \ + \ + UINT_MAX, /* Number of threads */ \ + HTRDR_PLANETS_ARGS_OUTPUT_IMAGE, \ + 0, /* Force output overwrite */ \ + 0, /* Precompute normals */ \ + 0, /* Verbosity level */ \ + 0 /* Stop the command */ \ +} +static const struct htrdr_planets_args HTRDR_PLANETS_ARGS_DEFAULT = + HTRDR_PLANETS_ARGS_DEFAULT__; + +extern LOCAL_SYM res_T +htrdr_planets_args_init + (struct htrdr_planets_args* args, + int argc, + char** argv); + +extern LOCAL_SYM void +htrdr_planets_args_release + (struct htrdr_planets_args* args); + +extern LOCAL_SYM res_T +htrdr_planets_args_check + (const struct htrdr_planets_args* args); + +extern LOCAL_SYM res_T +htrdr_planets_source_args_check + (const struct htrdr_planets_source_args* args); + +#endif /* HTRDR_PLANETS_ARGS_H */ diff --git a/src/planets/htrdr_planets_c.h b/src/planets/htrdr_planets_c.h @@ -0,0 +1,127 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef HTRDR_PLANETS_C_H +#define HTRDR_PLANETS_C_H + +#include "planets/htrdr_planets_args.h" + +#include "core/htrdr_accum.h" +#include "core/htrdr_args.h" +#include "core/htrdr_buffer.h" + +#include <rsys/ref_count.h> +#include <rsys/str.h> + +/* Forward declarations */ +struct htrdr; +struct htrdr_pixel_format; +struct htrdr_ran_wlen_cie_xyz; +struct htrdr_ran_wlen_planck; +struct rnatm; +struct rngrd; +struct scam; + +struct planets_pixel_xwave { + struct htrdr_accum radiance; /* In W/m²/sr */ + struct htrdr_accum time; /* In µs */ + struct htrdr_estimate radiance_temperature; /* In W/m²/sr */ +}; +#define PLANETS_PIXEL_XWAVE_NULL__ { \ + HTRDR_ACCUM_NULL__, \ + HTRDR_ACCUM_NULL__, \ + HTRDR_ESTIMATE_NULL__ \ +} +static const struct planets_pixel_xwave PLANETS_PIXEL_XWAVE_NULL = + PLANETS_PIXEL_XWAVE_NULL__; + +struct planets_pixel_image { + struct htrdr_estimate X; /* In W/m²/sr */ + struct htrdr_estimate Y; /* In W/m²/sr */ + struct htrdr_estimate Z; /* In W/m²/sr */ + struct htrdr_accum time; /* In µs */ +}; +#define PLANETS_PIXEL_IMAGE_NULL__ { \ + HTRDR_ESTIMATE_NULL__, \ + HTRDR_ESTIMATE_NULL__, \ + HTRDR_ESTIMATE_NULL__, \ + HTRDR_ACCUM_NULL__ \ +} + +struct planets_compute_radiance_args { + struct ssp_rng* rng; + size_t ithread; /* Index of the thread executing the function */ + + double path_org[3]; /* Origin of the path to trace */ + double path_dir[3]; /* Initial direction of the path to trace */ + + double wlen; /* In nm */ + size_t iband; /* Spectral band index */ + size_t iquad; /* Quadrature point */ +}; +#define PLANETS_COMPUTE_RADIANCE_ARGS_NULL__ {NULL, 0, {0,0,0}, {0,0,0}, 0, 0, 0} +static const struct planets_compute_radiance_args +PLANETS_COMPUTE_RADIANCE_ARGS_NULL = PLANETS_COMPUTE_RADIANCE_ARGS_NULL__; + +struct htrdr_planets { + struct rnatm* atmosphere; + struct rngrd* ground; + struct htrdr_planets_source* source; + + struct htrdr_planets_spectral_args spectral_domain; + struct htrdr_ran_wlen_cie_xyz* cie; /* HTRDR_SPECTRAL_SW_CIE_XYZ */ + struct htrdr_ran_wlen_planck* planck; /* HTRDR_SPECTRAL_<LW|SW> */ + struct htrdr_ran_wlen_discrete* discrete; /* HTRDR_SPECTRAL_SW */ + + FILE* octrees_storage; + + FILE* output; + struct str output_name; + enum htrdr_planets_args_output_type output_type; + + struct scam* camera; + + struct htrdr_buffer_layout buf_layout; + struct htrdr_buffer* buf; /* NULL on non master processes */ + size_t spp; /* Samples per pixel */ + + ref_T ref; + struct htrdr* htrdr; +}; + +extern LOCAL_SYM res_T +planets_draw_map + (struct htrdr_planets* cmd); + +extern LOCAL_SYM void +planets_get_pixel_format + (const struct htrdr_planets* cmd, + struct htrdr_pixel_format* fmt); + +/* Return the radiance in W/m²/sr/m */ +extern LOCAL_SYM double +planets_compute_radiance + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args); + +#endif /* HTRDR_PLANETS_C_H */ diff --git a/src/planets/htrdr_planets_compute_radiance.c b/src/planets/htrdr_planets_compute_radiance.c @@ -0,0 +1,671 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "planets/htrdr_planets_c.h" +#include "planets/htrdr_planets_source.h" + +#include <rad-net/rnatm.h> +#include <rad-net/rngrd.h> + +#include <star/s3d.h> +#include <star/ssf.h> +#include <star/ssp.h> +#include <star/suvm.h> +#include <star/svx.h> + +#include <rsys/double2.h> +#include <rsys/double3.h> + +/* Syntactic sugar */ +#define DISTANCE_NONE(Dst) ((Dst) >= FLT_MAX) +#define SURFACE_EVENT(Event) (!S3D_HIT_NONE(&(Event)->hit)) + +struct event { + /* Set to S3D_HIT_NULL if the event occurs in volume.*/ + struct s3d_hit hit; + + /* The surface normal is defined only if event is on the surface. It is + * normalized and looks towards the incoming direction */ + double normal[3]; + + /* Cells in which the event position is located. It makes sense only for an + * event in volume */ + struct rnatm_cell_pos cells[RNATM_MAX_COMPONENTS_COUNT]; + + double distance; /* Distance from ray origin to scattering position */ +}; +#define EVENT_NULL__ { \ + S3D_HIT_NULL__, {0,0,0}, {RNATM_CELL_POS_NULL__}, DBL_MAX \ +} +static const struct event EVENT_NULL = EVENT_NULL__; + +/* Arguments of the filtering function used to sample a position */ +struct sample_distance_context { + struct ssp_rng* rng; + struct rnatm* atmosphere; + size_t iband; + size_t iquad; + double wavelength; /* In nm */ + enum rnatm_radcoef radcoef; + double Ts; /* Sample optical thickness */ + + /* Output data */ + struct rnatm_cell_pos* cells; + double distance; +}; +#define SAMPLE_DISTANCE_CONTEXT_NULL__ { \ + NULL, NULL, 0, 0, 0, RNATM_RADCOEFS_COUNT__, 0, NULL, DBL_MAX \ +} +static const struct sample_distance_context SAMPLE_DISTANCE_CONTEXT_NULL = + SAMPLE_DISTANCE_CONTEXT_NULL__; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE res_T +check_planets_compute_radiance_args + (const struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args) +{ + struct rnatm_band_desc band = RNATM_BAND_DESC_NULL; + res_T res = RES_OK; + + if(!args || !args->rng) + return RES_BAD_ARG; + + /* Invalid thread index */ + if(args->ithread >= htrdr_get_threads_count(cmd->htrdr)) + return RES_BAD_ARG; + + /* Invalid input direction */ + if(!d3_is_normalized(args->path_dir)) + return RES_BAD_ARG; + + /* Invalid wavelength */ + if(args->wlen < cmd->spectral_domain.wlen_range[0] + || args->wlen > cmd->spectral_domain.wlen_range[1]) + return RES_BAD_ARG; + + res = rnatm_band_get_desc(cmd->atmosphere, args->iband, &band); + if(res != RES_OK) return res; + + /* Inconsistent spectral dimension */ + if(args->wlen < band.lower + || args->wlen >= band.upper /* Exclusive */ + || args->iquad >= band.quad_pts_count) + return RES_BAD_ARG; + + return RES_OK; +} + +static int +sample_position_hit_filter + (const struct svx_hit* hit, + const double org[3], + const double dir[3], + const double range[2], + void* context) +{ + struct rnatm_get_radcoef_args get_k_args = RNATM_GET_RADCOEF_ARGS_NULL; + struct sample_distance_context* ctx = context; + double k_min = 0; + double k_max = 0; + double dst_travelled = 0; + int pursue_traversal = 1; + ASSERT(hit && org && range && context); + (void)range; + + dst_travelled = hit->distance[0]; + + /* Get the k_min, k_max of the voxel */ + k_min = rnatm_get_k_svx_voxel + (ctx->atmosphere, &hit->voxel, ctx->radcoef, RNATM_SVX_OP_MIN); + k_max = rnatm_get_k_svx_voxel + (ctx->atmosphere, &hit->voxel, ctx->radcoef, RNATM_SVX_OP_MAX); + + /* Configure the common input arguments to retrieve the radiative coefficient + * of a given position */ + get_k_args.cells = ctx->cells; + get_k_args.iband = ctx->iband; + get_k_args.iquad = ctx->iquad; + get_k_args.radcoef = ctx->radcoef; + get_k_args.k_min = k_min; + get_k_args.k_max = k_max; + + for(;;) { + /* Compute the optical thickness of the voxel */ + const double vox_dst = hit->distance[1] - dst_travelled; + const double T = vox_dst * k_max; + + /* A collision occurs behind the voxel */ + if(ctx->Ts > T) { + ctx->Ts -= T; + pursue_traversal = 1; + break; + + /* A collision occurs in the voxel */ + } else { + const double vox_dst_collision = ctx->Ts / k_max; + double pos[3]; + double k, r; + + /* Calculate the distance travelled to the collision to be queried */ + dst_travelled += vox_dst_collision; + + /* Retrieve the radiative coefficient at the collision position */ + pos[0] = org[0] + dst_travelled * dir[0]; + pos[1] = org[1] + dst_travelled * dir[1]; + pos[2] = org[2] + dst_travelled * dir[2]; + RNATM(fetch_cell_list(ctx->atmosphere, pos, get_k_args.cells, NULL)); + RNATM(get_radcoef(ctx->atmosphere, &get_k_args, &k)); + + r = ssp_rng_canonical(ctx->rng); + + /* Null collision */ + if(r > k/k_max) { + ctx->Ts = ssp_ran_exp(ctx->rng, 1); + + /* Real collision */ + } else { + ctx->distance = dst_travelled; + pursue_traversal = 0; + break; + } + } + } + + return pursue_traversal; +} + +static double +sample_distance + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + struct rnatm_cell_pos* cells, + const enum rnatm_radcoef radcoef, + const double pos[3], + const double dir[3], + const double range[2]) +{ + struct rnatm_trace_ray_args rt = RNATM_TRACE_RAY_ARGS_NULL; + struct sample_distance_context ctx = SAMPLE_DISTANCE_CONTEXT_NULL; + struct svx_hit hit; + ASSERT(cmd && args && cells && pos && dir && d3_is_normalized(dir) && range); + ASSERT((unsigned)radcoef < RNATM_RADCOEFS_COUNT__); + ASSERT(range[0] < range[1]); + + /* Sample an optical thickness */ + ctx.Ts = ssp_ran_exp(args->rng, 1); + + /* Setup the remaining arguments of the RT context */ + ctx.rng = args->rng; + ctx.atmosphere = cmd->atmosphere; + ctx.iband = args->iband; + ctx.iquad = args->iquad; + ctx.wavelength = args->wlen; + ctx.radcoef = radcoef; + ctx.cells = cells; + + /* Trace the ray into the atmosphere */ + d3_set(rt.ray_org, pos); + d3_set(rt.ray_dir, dir); + rt.ray_range[0] = range[0]; + rt.ray_range[1] = range[1]; + rt.filter = sample_position_hit_filter; + rt.context = &ctx; + rt.iband = args->iband; + rt.iquad = args->iquad; + RNATM(trace_ray(cmd->atmosphere, &rt, &hit)); + + if(SVX_HIT_NONE(&hit)) { /* No collision found */ + return INF; + } else { /* A (real) collision occured */ + return ctx.distance; + } +} + +static INLINE double +transmissivity + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + const enum rnatm_radcoef radcoef, + const double pos[3], + const double dir[3], + const double range_max) +{ + struct rnatm_cell_pos cells[RNATM_MAX_COMPONENTS_COUNT]; + double range[2]; + double dst = 0; + ASSERT(range_max >= 0); + + range[0] = 0; + range[1] = range_max; + dst = sample_distance(cmd, args, cells, radcoef, pos, dir, range); + + if(DISTANCE_NONE(dst)) { + return 1.0; /* No collision in the medium */ + } else { + return 0.0; /* A (real) collision occurs */ + } +} + +static double +direct_contribution + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + const double pos[3], + const double dir[3], + const struct s3d_hit* hit_from) +{ + struct rngrd_trace_ray_args rt = RNGRD_TRACE_RAY_ARGS_DEFAULT; + struct s3d_hit hit; + double Tr; + double Ld; + double src_dst; + ASSERT(cmd && args && pos && dir); + + /* Is the source hidden? */ + d3_set(rt.ray_org, pos); + d3_set(rt.ray_dir, dir); + if(hit_from) rt.hit_from = *hit_from; + RNGRD(trace_ray(cmd->ground, &rt, &hit)); + if(!S3D_HIT_NONE(&hit)) return 0; + + /* Calculate the distance between the source and `pos' */ + src_dst = htrdr_planets_source_distance_to(cmd->source, pos); + ASSERT(src_dst >= 0); + + Tr = transmissivity(cmd, args, RNATM_RADCOEF_Kext, pos, dir, src_dst); + Ld = htrdr_planets_source_get_radiance(cmd->source, args->wlen); + return Ld * Tr; +} + +static void +find_event + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + const enum rnatm_radcoef radcoef, + const double pos[3], + const double dir[3], + const struct s3d_hit* hit_from, + struct event* evt) +{ + struct rngrd_trace_ray_args rt = RNGRD_TRACE_RAY_ARGS_DEFAULT; + struct s3d_hit hit; + double range[2]; + double dst; + ASSERT(cmd && args && pos && dir && hit_from && evt); + + *evt = EVENT_NULL; + + /* Look for a surface intersection */ + d3_set(rt.ray_org, pos); + d3_set(rt.ray_dir, dir); + d2(rt.ray_range, 0, INF); + rt.hit_from = *hit_from; + RNGRD(trace_ray(cmd->ground, &rt, &hit)); + + /* Look for an atmospheric collision */ + range[0] = 0; + range[1] = hit.distance; + dst = sample_distance(cmd, args, evt->cells, radcoef, pos, dir, range); + + /* Event occurs in volume */ + if(!DISTANCE_NONE(dst)) { + evt->distance = dst; + evt->hit = S3D_HIT_NULL; + + /* Event is on surface */ + } else if(!S3D_HIT_NONE(&hit)) { + /* Normalize the normal and ensure that it points to `dir' */ + d3_normalize(evt->normal, d3_set_f3(evt->normal, hit.normal)); + if(d3_dot(evt->normal, dir) > 0) d3_minus(evt->normal, evt->normal); + + evt->distance = hit.distance; + evt->hit = hit; + + /* No event */ + } else { + evt->distance = INF; + evt->hit = S3D_HIT_NULL; + } +} + +static INLINE struct ssf_bsdf* +create_bsdf + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + const struct s3d_hit* hit) +{ + struct rngrd_create_bsdf_args bsdf_args = RNGRD_CREATE_BSDF_ARGS_NULL; + struct ssf_bsdf* bsdf = NULL; + ASSERT(!S3D_HIT_NONE(hit)); + + /* Retrieve the BSDF at the intersected surface position */ + bsdf_args.prim = hit->prim; + bsdf_args.barycentric_coords[0] = hit->uv[0]; + bsdf_args.barycentric_coords[1] = hit->uv[1]; + bsdf_args.barycentric_coords[2] = 1 - hit->uv[0] - hit->uv[1]; + bsdf_args.wavelength = args->wlen; + bsdf_args.r = ssp_rng_canonical(args->rng); + RNGRD(create_bsdf(cmd->ground, &bsdf_args, &bsdf)); + + return bsdf; +} + +static INLINE struct ssf_phase* +create_phase_fn + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + const struct rnatm_cell_pos* cells) /* Cells in which scattering occurs */ +{ + struct rnatm_sample_component_args sample_args = + RNATM_SAMPLE_COMPONENT_ARGS_NULL; + struct rnatm_cell_create_phase_fn_args phase_fn_args = + RNATM_CELL_CREATE_PHASE_FN_ARGS_NULL; + struct ssf_phase* phase = NULL; + size_t cpnt; + ASSERT(cmd && args && cells); + + /* Sample the atmospheric scattering component */ + sample_args.cells = cells; + sample_args.iband = args->iband; + sample_args.iquad = args->iquad; + sample_args.radcoef = RNATM_RADCOEF_Ks; + sample_args.r = ssp_rng_canonical(args->rng); + RNATM(sample_component(cmd->atmosphere, &sample_args, &cpnt)); + + /* Retrieve the component cell in which the scattering position is located */ + phase_fn_args.cell = RNATM_GET_COMPONENT_CELL(cells, cpnt); + ASSERT(!SUVM_PRIMITIVE_NONE(&phase_fn_args.cell.prim)); + + /* Retrieve the component phase function */ + phase_fn_args.wavelength = args->wlen; + phase_fn_args.r[0] = ssp_rng_canonical(args->rng); + phase_fn_args.r[1] = ssp_rng_canonical(args->rng); + RNATM(cell_create_phase_fn(cmd->atmosphere, &phase_fn_args, &phase)); + + return phase; +} + +/* In shortwave, return the contribution of the external source at the bounce + * position. In longwave, simply return 0 */ +static double +surface_bounce + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + const struct event* sc, + const double sc_pos[3], /* Scattering position */ + const double in_dir[3], /* Incident direction */ + double sc_dir[3], /* Sampled scattering direction */ + double *out_refl) /* Surface reflectivity */ +{ + struct ssf_bsdf* bsdf = NULL; + const double* N = NULL; + double wo[3] = {0,0,0}; + double reflectivity = 0; /* Surface reflectivity */ + double L = 0; + int mask = 0; + ASSERT(cmd && args && sc && sc_pos && in_dir && sc_dir && out_refl); + ASSERT(d3_dot(sc->normal, in_dir) < 0 && d3_is_normalized(sc->normal)); + + bsdf = create_bsdf(cmd, args, &sc->hit); + N = sc->normal; + d3_minus(wo, in_dir); /* Match StarSF convention */ + ASSERT(d3_dot(wo, N) > 0); + + /* Sample the scattering direction */ + reflectivity = ssf_bsdf_sample(bsdf, args->rng, wo, N, sc_dir, &mask, NULL); + + /* Fully absorbs transmissions */ + if(mask & SSF_TRANSMISSION) reflectivity = 0; + + /* No external source in longwave */ + if(cmd->spectral_domain.type == HTRDR_SPECTRAL_LW) + goto exit; + + /* Calculate direct contribution for specular reflection */ + if((mask & SSF_SPECULAR) + && (mask & SSF_REFLECTION) + && htrdr_planets_source_is_targeted(cmd->source, sc_pos, sc_dir)) { + const double Ld = direct_contribution(cmd, args, sc_pos, sc_dir, &sc->hit); + L = Ld * reflectivity; + + /* Calculate direct contribution in general case */ + } else if(!(mask & SSF_SPECULAR)) { + double wi[3], pdf; + + /* Sample a direction toward the source */ + pdf = htrdr_planets_source_sample_direction(cmd->source, args->rng, sc_pos, wi); + + /* The source is behind the surface */ + if(d3_dot(wi, N) <= 0) { + L = 0; + + /* The source is above the surface */ + } else { + const double Ld = direct_contribution(cmd, args, sc_pos, wi, &sc->hit); + const double rho = ssf_bsdf_eval(bsdf, wo, N, wi); + const double cos_N_wi = d3_dot(N, wi); + ASSERT(cos_N_wi > 0); + + L = Ld * rho * cos_N_wi / pdf; + } + } + +exit: + SSF(bsdf_ref_put(bsdf)); + *out_refl = reflectivity; + return L; +} + +/* In shortwave, return the contribution at the scattering position of the + * external source. Returns 0 in long wave */ +static INLINE double +volume_scattering + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + const struct event* sc, + const double sc_pos[3], /* Scattering position */ + const double in_dir[3], /* Incident direction */ + double sc_dir[3]) /* Sampled scattering direction */ +{ + struct ssf_phase* phase = NULL; + double wo[3] = {0,0,0}; + double wi[3] = {0,0,0}; + double L = 0; + double pdf = 0; + double rho = 0; + double Ld = 0; + ASSERT(cmd && args && sc && sc_pos && in_dir && sc_dir); + + phase = create_phase_fn(cmd, args, sc->cells); + d3_minus(wo, in_dir); /* Match StarSF convention */ + + ssf_phase_sample(phase, args->rng, wo, sc_dir, NULL); + + /* Sample a direction toward the source */ + pdf = htrdr_planets_source_sample_direction(cmd->source, args->rng, sc_pos, wi); + + /* In short wave, manage the contribution of the external source */ + switch(cmd->spectral_domain.type) { + case HTRDR_SPECTRAL_LW: + /* Nothing to be done */ + break; + + case HTRDR_SPECTRAL_SW: + case HTRDR_SPECTRAL_SW_CIE_XYZ: + /* Calculate the direct contribution at the scattering position */ + Ld = direct_contribution(cmd, args, sc_pos, wi, NULL); + rho = ssf_phase_eval(phase, wo, wi); + L = Ld * rho / pdf; + break; + + default: FATAL("Unreachable code.\n"); break; + } + + SSF(phase_ref_put(phase)); + return L; +} + +static INLINE enum rnatm_radcoef +sample_volume_event_type + (const struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args, + struct event* evt) +{ + struct rnatm_get_radcoef_args get_k_args = RNATM_GET_RADCOEF_ARGS_NULL; + double ka, kext; + double r; + ASSERT(cmd && args && evt); + + get_k_args.cells = evt->cells; + get_k_args.iband = args->iband; + get_k_args.iquad = args->iquad; + + /* Retrieve the absorption coefficient */ + get_k_args.radcoef = RNATM_RADCOEF_Ka; + RNATM(get_radcoef(cmd->atmosphere, &get_k_args, &ka)); + + /* Retrieve the extinction coefficient */ + get_k_args.radcoef = RNATM_RADCOEF_Kext; + RNATM(get_radcoef(cmd->atmosphere, &get_k_args, &kext)); + + r = ssp_rng_canonical(args->rng); + if(r < ka / kext) { + return RNATM_RADCOEF_Ka; /* Absorption */ + } else { + return RNATM_RADCOEF_Ks; /* Scattering */ + } +} + +static INLINE double +get_temperature + (const struct htrdr_planets* cmd, + const struct event* evt) +{ + double T = 0; + ASSERT(cmd && evt); + + if(!SURFACE_EVENT(evt)) { + const struct rnatm_cell_pos* cell = NULL; + + /* Get gas temperature */ + cell = &RNATM_GET_COMPONENT_CELL(evt->cells, RNATM_GAS); + RNATM(cell_get_gas_temperature(cmd->atmosphere, cell, &T)); + + } else { + struct rngrd_get_temperature_args temp_args = RNGRD_GET_TEMPERATURE_ARGS_NULL; + + /* Get ground temperature */ + temp_args.prim = evt->hit.prim; + temp_args.barycentric_coords[0] = evt->hit.uv[0]; + temp_args.barycentric_coords[1] = evt->hit.uv[1]; + temp_args.barycentric_coords[2] = 1 - evt->hit.uv[0] - evt->hit.uv[1]; + RNGRD(get_temperature(cmd->ground, &temp_args, &T)); + + } + return T; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +double /* Radiance in W/m²/sr/m */ +planets_compute_radiance + (struct htrdr_planets* cmd, + const struct planets_compute_radiance_args* args) +{ + struct s3d_hit hit_from = S3D_HIT_NULL; + struct event ev; + double pos[3]; + double dir[3]; + double L = 0; /* Radiance in W/m²/sr/m */ + size_t nsc = 0; /* Number of surface or volume scatterings (for debug) */ + int longwave = 0; + ASSERT(cmd && check_planets_compute_radiance_args(cmd, args) == RES_OK); + + d3_set(pos, args->path_org); + d3_set(dir, args->path_dir); + longwave = cmd->spectral_domain.type == HTRDR_SPECTRAL_LW; + + if(!longwave && htrdr_planets_source_is_targeted(cmd->source, pos, dir)) { + L = direct_contribution(cmd, args, pos, dir, NULL); /* In W/m²/sr/m */ + } + + for(;;) { + double ev_pos[3]; + double sc_dir[3]; + + find_event(cmd, args, RNATM_RADCOEF_Kext, pos, dir, &hit_from, &ev); + + /* No event on surface or in volume. Stop the path */ + if(DISTANCE_NONE(ev.distance)) break; + + /* Compute the event position */ + ev_pos[0] = pos[0] + dir[0] * ev.distance; + ev_pos[1] = pos[1] + dir[1] * ev.distance; + ev_pos[2] = pos[2] + dir[2] * ev.distance; + + /* The event occurs on the surface */ + if(SURFACE_EVENT(&ev)) { + double refl; /* Surface reflectivity */ + L += surface_bounce(cmd, args, &ev, ev_pos, dir, sc_dir, &refl); + + /* Check the absorption of the surface with a Russian roulette against + * the reflectivity of the surface */ + if(ssp_rng_canonical(args->rng) >= refl) break; + + /* Save current intersected surface to avoid self-intersection when + * sampling next event */ + hit_from = ev.hit; + + /* The event occurs in the volume */ + } else { + enum rnatm_radcoef ev_type = sample_volume_event_type(cmd, args, &ev); + ASSERT(ev_type == RNATM_RADCOEF_Ka || ev_type == RNATM_RADCOEF_Ks); + + /* Absorption. Stop the path */ + if(ev_type == RNATM_RADCOEF_Ka) break; + + L += volume_scattering(cmd, args, &ev, ev_pos, dir, sc_dir); + hit_from = S3D_HIT_NULL; /* Reset surface intersection */ + } + + d3_set(pos, ev_pos); + d3_set(dir, sc_dir); + + ++nsc; + } + + /* From there, a valid event means that the path has stopped in surface or + * volume absorption. In longwave, add the contribution of the internal + * source */ + if(longwave && !DISTANCE_NONE(ev.distance)) { + const double wlen_m = args->wlen * 1.e-9; /* wavelength in meters */ + const double temperature = get_temperature(cmd, &ev); /* In K */ + L += htrdr_planck_monochromatic(wlen_m, temperature); + } + + return L; /* In W/m²/sr/m */ +} diff --git a/src/planets/htrdr_planets_draw_map.c b/src/planets/htrdr_planets_draw_map.c @@ -0,0 +1,457 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "planets/htrdr_planets_c.h" +#include "planets/htrdr_planets_source.h" + +#include "core/htrdr.h" +#include "core/htrdr_accum.h" +#include "core/htrdr_buffer.h" +#include "core/htrdr_draw_map.h" +#include "core/htrdr_log.h" +#include "core/htrdr_ran_wlen_cie_xyz.h" +#include "core/htrdr_ran_wlen_discrete.h" +#include "core/htrdr_ran_wlen_planck.h" + +#include <rad-net/rnatm.h> +#include <star/scam.h> +#include <star/ssp.h> + +#include <rsys/clock_time.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +draw_pixel_xwave + (struct htrdr* htrdr, + const struct htrdr_draw_pixel_args* args, + void* data) +{ + struct planets_compute_radiance_args rad_args = + PLANETS_COMPUTE_RADIANCE_ARGS_NULL; + + struct htrdr_accum radiance; + struct htrdr_accum time; + struct htrdr_planets* cmd; + struct planets_pixel_xwave* pixel = data; + size_t isamp = 0; + ASSERT(htrdr && htrdr_draw_pixel_args_check(args) && data); + (void)htrdr; + + cmd = args->context; + ASSERT(cmd); + ASSERT(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW + || cmd->spectral_domain.type == HTRDR_SPECTRAL_LW); + ASSERT(cmd->output_type == HTRDR_PLANETS_ARGS_OUTPUT_IMAGE); + + /* Reset accumulators */ + radiance = HTRDR_ACCUM_NULL; + time = HTRDR_ACCUM_NULL; + + FOR_EACH(isamp, 0, args->spp) { + struct time t0, t1; + struct scam_sample sample = SCAM_SAMPLE_NULL; + struct scam_ray ray = SCAM_RAY_NULL; + double weight; + double r0, r1, r2; + double wlen[2]; /* Sampled wavelength */ + double pdf; + size_t iband[2]; + size_t iquad; + double usec; + + /* Begin the registration of the time spent to in the realisation */ + time_current(&t0); + + /* Sample a position into the pixel, in the normalized image plane */ + sample.film[0] = (double)args->pixel_coord[0]+ssp_rng_canonical(args->rng); + sample.film[1] = (double)args->pixel_coord[1]+ssp_rng_canonical(args->rng); + sample.film[0] *= args->pixel_normalized_size[0]; + sample.film[1] *= args->pixel_normalized_size[1]; + sample.lens[0] = ssp_rng_canonical(args->rng); + sample.lens[1] = ssp_rng_canonical(args->rng); + + /* Generate a camera ray */ + scam_generate_ray(cmd->camera, &sample, &ray); + + r0 = ssp_rng_canonical(args->rng); + r1 = ssp_rng_canonical(args->rng); + r2 = ssp_rng_canonical(args->rng); + + /* Sample a wavelength */ + switch(cmd->spectral_domain.type) { + case HTRDR_SPECTRAL_LW: + wlen[0] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf); + break; + case HTRDR_SPECTRAL_SW: + if(htrdr_planets_source_does_radiance_vary_spectrally(cmd->source)) { + wlen[0] = htrdr_ran_wlen_discrete_sample(cmd->discrete, r0, r1, &pdf); + } else { + wlen[0] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf); + } + break; + default: FATAL("Unreachable code\n"); break; + + } + wlen[1] = wlen[0]; + pdf *= 1.e9; /* Transform the pdf from nm⁻¹ to m⁻¹ */ + + /* Find the band the wavelength belongs to and sample a quadrature point */ + RNATM(find_bands(cmd->atmosphere, wlen, iband)); + RNATM(band_sample_quad_pt(cmd->atmosphere, r2, iband[0], &iquad)); + ASSERT(iband[0] == iband[1]); + + /* Compute the radiance in W/m²/sr/m */ + d3_set(rad_args.path_org, ray.org); + d3_set(rad_args.path_dir, ray.dir); + rad_args.rng = args->rng; + rad_args.ithread = args->ithread; + rad_args.wlen = wlen[0]; + rad_args.iband = iband[0]; + rad_args.iquad = iquad; + weight = planets_compute_radiance(cmd, &rad_args); + ASSERT(weight >= 0); + + weight /= pdf; /* In W/m²/sr */ + + /* End of time recording per realisation */ + time_sub(&t0, time_current(&t1), &t0); + usec = (double)time_val(&t0, TIME_NSEC) * 0.001; + + /* Update the radiance accumulator */ + radiance.sum_weights += weight; + radiance.sum_weights_sqr += weight*weight; + radiance.nweights += 1; + + /* Update the per realisation time accumulator */ + time.sum_weights += usec; + time.sum_weights_sqr += usec*usec; + time.nweights += 1; + } + + /* Flush pixel data */ + pixel->radiance = radiance; + pixel->time = time; + + if(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW) { + pixel->radiance_temperature.E = 0; + pixel->radiance_temperature.SE = 0; + } else { + struct htrdr_estimate L; + + /* Wavelength in meters */ + const double wmin_m = cmd->spectral_domain.wlen_range[0] * 1.e-9; + const double wmax_m = cmd->spectral_domain.wlen_range[1] * 1.e-9; + + /* Brightness temperatures in W/m²/sr */ + double T, Tmin, Tmax; + + htrdr_accum_get_estimation(&radiance, &L); + + T = htrdr_radiance_temperature(cmd->htrdr, wmin_m, wmax_m, L.E); + Tmin = htrdr_radiance_temperature(cmd->htrdr, wmin_m, wmax_m, L.E - L.SE); + Tmax = htrdr_radiance_temperature(cmd->htrdr, wmin_m, wmax_m, L.E + L.SE); + + pixel->radiance_temperature.E = T; + pixel->radiance_temperature.SE = Tmax - Tmin; + } +} + +static void +draw_pixel_image + (struct htrdr* htrdr, + const struct htrdr_draw_pixel_args* args, + void* data) +{ + struct planets_compute_radiance_args rad_args = + PLANETS_COMPUTE_RADIANCE_ARGS_NULL; + + struct htrdr_accum XYZ[3]; /* X, Y, and Z */ + struct htrdr_accum time; + struct htrdr_planets* cmd; + struct planets_pixel_image* pixel = data; + size_t ichannel; + ASSERT(htrdr && htrdr_draw_pixel_args_check(args) && data); + (void)htrdr; + + cmd = args->context; + ASSERT(cmd); + ASSERT(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW_CIE_XYZ); + ASSERT(cmd->output_type == HTRDR_PLANETS_ARGS_OUTPUT_IMAGE); + + /* Reset accumulators */ + XYZ[0] = HTRDR_ACCUM_NULL; + XYZ[1] = HTRDR_ACCUM_NULL; + XYZ[2] = HTRDR_ACCUM_NULL; + time = HTRDR_ACCUM_NULL; + + FOR_EACH(ichannel, 0, 3) { + size_t isamp; + + FOR_EACH(isamp, 0, args->spp) { + struct time t0, t1; + struct scam_sample sample = SCAM_SAMPLE_NULL; + struct scam_ray ray = SCAM_RAY_NULL; + double weight; + double r0, r1, r2; + double wlen[2]; /* Sampled wavelength into the spectral band */ + double pdf; + size_t iband[2]; /* Sampled spectral band */ + size_t iquad; /* Sampled quadrature point into the spectral band */ + double usec; + + /* Begin the registration of the time spent to in the realisation */ + time_current(&t0); + + /* Sample a position into the pixel, in the normalized image plane */ + sample.film[0] = (double)args->pixel_coord[0]+ssp_rng_canonical(args->rng); + sample.film[1] = (double)args->pixel_coord[1]+ssp_rng_canonical(args->rng); + sample.film[0] *= args->pixel_normalized_size[0]; + sample.film[1] *= args->pixel_normalized_size[1]; + sample.lens[0] = ssp_rng_canonical(args->rng); + sample.lens[1] = ssp_rng_canonical(args->rng); + + /* Generate a camera ray */ + SCAM(generate_ray(cmd->camera, &sample, &ray)); + + r0 = ssp_rng_canonical(args->rng); + r1 = ssp_rng_canonical(args->rng); + r2 = ssp_rng_canonical(args->rng); + + /* Sample a wavelength according to the CIE XYZ color space */ + switch(ichannel) { + case 0: + wlen[0] = htrdr_ran_wlen_cie_xyz_sample_X(cmd->cie, r0, r1, &pdf); + break; + case 1: + wlen[0] = htrdr_ran_wlen_cie_xyz_sample_Y(cmd->cie, r0, r1, &pdf); + break; + case 2: + wlen[0] = htrdr_ran_wlen_cie_xyz_sample_Z(cmd->cie, r0, r1, &pdf); + break; + default: FATAL("Unreachable code.\n"); break; + } + pdf *= 1.e9; /* Transform the pdf from nm⁻¹ to m⁻¹ */ + + /* Find the band the wavelength belongs to and sample a quadrature point */ + wlen[1] = wlen[0]; + RNATM(find_bands(cmd->atmosphere, wlen, iband)); + RNATM(band_sample_quad_pt(cmd->atmosphere, r2, iband[0], &iquad)); + ASSERT(iband[0] == iband[1]); + + /* Compute the radiance in W/m²/sr/m */ + d3_set(rad_args.path_org, ray.org); + d3_set(rad_args.path_dir, ray.dir); + rad_args.rng = args->rng; + rad_args.ithread = args->ithread; + rad_args.wlen = wlen[0]; + rad_args.iband = iband[0]; + rad_args.iquad = iquad; + weight = planets_compute_radiance(cmd, &rad_args); + ASSERT(weight >= 0); + + weight /= pdf; /* In W/m²/sr */ + + /* End of time recording per realisation */ + time_sub(&t0, time_current(&t1), &t0); + usec = (double)time_val(&t0, TIME_NSEC) * 0.001; + + /* Update pixel channel accumulators */ + XYZ[ichannel].sum_weights += weight; + XYZ[ichannel].sum_weights_sqr += weight*weight; + XYZ[ichannel].nweights += 1; + + /* Update the per realisation time accumulator */ + time.sum_weights += usec; + time.sum_weights_sqr += usec*usec; + time.nweights += 1; + } + } + + /* Flush pixel data */ + htrdr_accum_get_estimation(XYZ+0, &pixel->X); + htrdr_accum_get_estimation(XYZ+1, &pixel->Y); + htrdr_accum_get_estimation(XYZ+2, &pixel->Z); + pixel->time = time; +} + + +static INLINE void +write_accum + (const struct htrdr_accum* acc, /* Accum to dump */ + struct htrdr_accum* out_acc, /* May be NULL */ + FILE* stream) +{ + ASSERT(acc && stream); + + if(acc->nweights == 0) { + fprintf(stream, "0 0 "); + } else { + struct htrdr_estimate estimate = HTRDR_ESTIMATE_NULL; + + htrdr_accum_get_estimation(acc, &estimate); + fprintf(stream, "%g %g ", estimate.E, estimate.SE); + + if(out_acc) { + out_acc->sum_weights += acc->sum_weights; + out_acc->sum_weights_sqr += acc->sum_weights_sqr; + out_acc->nweights += acc->nweights; + } + } +} + +static INLINE void +write_pixel_image + (const struct planets_pixel_image* pix, + struct htrdr_accum* time_acc, /* May be NULL */ + FILE* stream) +{ + ASSERT(pix && stream); + fprintf(stream, "%g %g ", pix->X.E, pix->X.SE); + fprintf(stream, "%g %g ", pix->Y.E, pix->Y.SE); + fprintf(stream, "%g %g ", pix->Z.E, pix->Z.SE); + write_accum(&pix->time, time_acc, stream); + fprintf(stream, "\n"); +} + +static INLINE void +write_pixel_xwave + (const struct planets_pixel_xwave* pix, + struct htrdr_accum* radiance_acc, /* May be NULL */ + struct htrdr_accum* time_acc, /* May be NULL */ + FILE* stream) +{ + ASSERT(pix && stream); + fprintf(stream, "%g %g ", + pix->radiance_temperature.E, + pix->radiance_temperature.SE); + write_accum(&pix->radiance, radiance_acc, stream); + fprintf(stream, "0 0 "); + write_accum(&pix->time, time_acc, stream); + fprintf(stream, "\n"); +} + +static res_T +write_buffer + (struct htrdr_planets* cmd, + struct htrdr_buffer* buf, + struct htrdr_accum* radiance_acc, /* May be NULL */ + struct htrdr_accum* time_acc, + FILE* stream) +{ + struct htrdr_pixel_format pixfmt; + struct htrdr_buffer_layout layout; + size_t x, y; + ASSERT(cmd && buf && time_acc && stream); + ASSERT(cmd->output_type == HTRDR_PLANETS_ARGS_OUTPUT_IMAGE); + + planets_get_pixel_format(cmd, &pixfmt); + htrdr_buffer_get_layout(buf, &layout); + CHK(pixfmt.size == layout.elmt_size); + + fprintf(stream, "%lu %lu\n", layout.width, layout.height); + *time_acc = HTRDR_ACCUM_NULL; + + FOR_EACH(y, 0, layout.height) { + FOR_EACH(x, 0, layout.width) { + void* pix_raw = htrdr_buffer_at(buf, x, y); + ASSERT(IS_ALIGNED(pix_raw, pixfmt.alignment)); + + switch(cmd->spectral_domain.type) { + case HTRDR_SPECTRAL_LW: + case HTRDR_SPECTRAL_SW: + write_pixel_xwave(pix_raw, radiance_acc, time_acc, stream); + break; + case HTRDR_SPECTRAL_SW_CIE_XYZ: + write_pixel_image(pix_raw, time_acc, stream); + break; + default: FATAL("Unreachable code\n"); break; + } + } + } + return RES_OK; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +planets_draw_map(struct htrdr_planets* cmd) +{ + struct htrdr_draw_map_args args = HTRDR_DRAW_MAP_ARGS_NULL; + struct htrdr_estimate path_time = HTRDR_ESTIMATE_NULL; + struct htrdr_accum path_time_acc = HTRDR_ACCUM_NULL; + struct htrdr_accum radiance_acc = HTRDR_ACCUM_NULL; + res_T res = RES_OK; + ASSERT(cmd && cmd->output_type == HTRDR_PLANETS_ARGS_OUTPUT_IMAGE); + + args.buffer_layout = cmd->buf_layout; + args.spp = cmd->spp; + args.context = cmd; + switch(cmd->spectral_domain.type) { + case HTRDR_SPECTRAL_LW: + case HTRDR_SPECTRAL_SW: + args.draw_pixel = draw_pixel_xwave; + break; + case HTRDR_SPECTRAL_SW_CIE_XYZ: + args.draw_pixel = draw_pixel_image; + break; + default: FATAL("Unreachable code\n"); break; + } + + res = htrdr_draw_map(cmd->htrdr, &args, cmd->buf); + if(res != RES_OK) goto error; + + /* Nothing more to do on non master processes */ + if(htrdr_get_mpi_rank(cmd->htrdr) != 0) goto exit; + + /* Write output image */ + res = write_buffer(cmd, cmd->buf, &radiance_acc, &path_time_acc, cmd->output); + if(res != RES_OK) goto error; + + CHK(fflush(cmd->output) == 0); + + /* Log time per realisation */ + htrdr_accum_get_estimation(&path_time_acc, &path_time); + htrdr_log(cmd->htrdr, "Time per radiative path (in µs): %g +/- %g\n", + path_time.E, path_time.SE); + + /* Log measured radiance on the whole image */ + if(cmd->spectral_domain.type == HTRDR_SPECTRAL_LW + || cmd->spectral_domain.type == HTRDR_SPECTRAL_SW) { + struct htrdr_estimate L; + double omega; /* Solid angle of the camera */ + + htrdr_accum_get_estimation(&radiance_acc, &L); + SCAM(perspective_get_solid_angle(cmd->camera, &omega)); + htrdr_log(cmd->htrdr, "Radiance in W/m²/sr: %g +/- %g\n", L.E, L.SE); + htrdr_log(cmd->htrdr, "Radiance in W/m² (solid angle = %g sr): %g +/- %g\n", + omega, L.E*omega, L.SE*omega); + } + +exit: + return res; +error: + goto exit; +} diff --git a/src/planets/htrdr_planets_main.c b/src/planets/htrdr_planets_main.c @@ -0,0 +1,91 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "planets/htrdr_planets.h" +#include "planets/htrdr_planets_args.h" + +#include "core/htrdr_log.h" + +#include <rsys/mem_allocator.h> + +int +htrdr_planets_main(int argc, char** argv) +{ + char cmd_name[] = "htrdr-planets"; + struct htrdr_args htrdr_args = HTRDR_ARGS_DEFAULT; + struct htrdr_planets_args cmd_args = HTRDR_PLANETS_ARGS_DEFAULT; + struct htrdr* htrdr = NULL; + struct htrdr_planets* cmd = NULL; + const size_t memsz_begin = mem_allocated_size(); + size_t memsz_end; + int is_mpi_init = 0; + res_T res = RES_OK; + int err = 0; + + /* Overwrite command name */ + argv[0] = cmd_name; + + res = htrdr_mpi_init(argc, argv); + if(res != RES_OK) goto error; + is_mpi_init = 1; + + res = htrdr_planets_args_init(&cmd_args, argc, argv); + if(res != RES_OK) goto error; + if(cmd_args.quit) goto exit; + + htrdr_args.nthreads = cmd_args.nthreads; + htrdr_args.verbose = cmd_args.verbose; + res = htrdr_create(&mem_default_allocator, &htrdr_args, &htrdr); + if(res != RES_OK) goto error; + + if(cmd_args.output_type == HTRDR_PLANETS_ARGS_OUTPUT_OCTREES + && htrdr_get_mpi_rank(htrdr) != 0) { + goto exit; /* Nothing to do except for the master process */ + } + + res = htrdr_planets_create(htrdr, &cmd_args, &cmd); + if(res != RES_OK) goto error; + + res = htrdr_planets_run(cmd); + if(res != RES_OK) goto error; + +exit: + htrdr_planets_args_release(&cmd_args); + if(is_mpi_init) htrdr_mpi_finalize(); + if(htrdr) htrdr_ref_put(htrdr); + if(cmd) htrdr_planets_ref_put(cmd); + + /* Check memory leaks */ + memsz_end = mem_allocated_size(); + if(memsz_begin != memsz_end) { + ASSERT(memsz_end >= memsz_begin); + fprintf(stderr, HTRDR_LOG_WARNING_PREFIX"Memory leaks: %lu Bytes\n", + (unsigned long)(memsz_end - memsz_begin)); + err = -1; + } + return err; +error: + err = -1; + goto exit; +} + diff --git a/src/planets/htrdr_planets_source.c b/src/planets/htrdr_planets_source.c @@ -0,0 +1,491 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "planets/htrdr_planets_c.h" +#include "planets/htrdr_planets_source.h" + +#include "core/htrdr.h" +#include "core/htrdr_log.h" + +#include <star/sbuf.h> +#include <star/ssp.h> + +#include <rsys/algorithm.h> +#include <rsys/cstr.h> +#include <rsys/double3.h> +#include <rsys/ref_count.h> + +typedef struct ALIGN(16) { + double wavelength; /* in nm */ + double radiance; /* in W/m²/sr/m */ +} source_radiance_T; + +struct htrdr_planets_source { + double position[3]; /* In m */ + + double radius; /* In m */ + + /* In Kelvin. Defined if the radiances by wavelength is no set */ + double temperature; + + struct sbuf* per_wlen_radiances; /* List of radiances by wavelength */ + + ref_T ref; + struct htrdr* htrdr; +}; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE res_T +check_per_wlen_radiance_sbuf_desc + (const struct htrdr_planets_source* src, + const struct sbuf_desc* desc) +{ + const source_radiance_T* spectrum = NULL; + size_t i; + ASSERT(src && desc); + + /* Invalid size */ + if(desc->size == 0) { + htrdr_log_err(src->htrdr, "invalid empty source spectrum\n"); + return RES_BAD_ARG; + } + + /* Invalid memory layout */ + if(desc->szitem != 16 || desc->alitem != 16 || desc->pitch != 16) { + htrdr_log_err(src->htrdr, "unexpected layout of source spectrum\n"); + return RES_BAD_ARG; + } + + /* Data must be sorted */ + spectrum = desc->buffer; + FOR_EACH(i, 1, desc->size) { + if(spectrum[i-1].wavelength >= spectrum[i].wavelength) { + htrdr_log_err(src->htrdr, + "the source spectrum is not sorted in ascending order " + "with respect to wavelengths\n"); + return RES_BAD_ARG; + } + } + + return RES_OK; +} + +static res_T +setup_per_wavelength_radiances + (struct htrdr_planets_source* src, + const struct htrdr_planets_source_args* args) +{ + struct sbuf_create_args sbuf_args; + struct sbuf_desc desc; + res_T res = RES_OK; + ASSERT(src && args && args->rnrl_filename && args->temperature < 0); + + sbuf_args.logger = htrdr_get_logger(src->htrdr); + sbuf_args.allocator = htrdr_get_allocator(src->htrdr); + sbuf_args.verbose = htrdr_get_verbosity_level(src->htrdr); + res = sbuf_create(&sbuf_args, &src->per_wlen_radiances); + if(res != RES_OK) goto error; + + res = sbuf_load(src->per_wlen_radiances, args->rnrl_filename); + if(res != RES_OK) goto error; + res = sbuf_get_desc(src->per_wlen_radiances, &desc); + if(res != RES_OK) goto error; + res = check_per_wlen_radiance_sbuf_desc(src, &desc); + if(res != RES_OK) goto error; + +exit: + return res; +error: + htrdr_log_err(src->htrdr, "error loading %s -- %s\n", + args->rnrl_filename, res_to_cstr(res)); + goto exit; +} + +static INLINE int +cmp_wlen(const void* a, const void* b) +{ + const double wlen = *((double*)a); + const source_radiance_T* src_rad1 = b; + ASSERT(a && b); + + if(wlen < src_rad1->wavelength) { + return -1; + } else if(wlen > src_rad1->wavelength) { + return +1; + } else { + return 0; + } +} + +static double +get_radiance + (const struct htrdr_planets_source* src, + const double wlen) +{ + struct sbuf_desc desc; + const source_radiance_T* spectrum; + const source_radiance_T* find; + size_t id; + ASSERT(src && src->per_wlen_radiances); + + SBUF(get_desc(src->per_wlen_radiances, &desc)); + spectrum = desc.buffer; + + if(wlen < spectrum[0].wavelength) { + htrdr_log_warn(src->htrdr, + "The wavelength %g nm is before the spectrum of the source\n", wlen); + return spectrum[0].radiance; + } + if(wlen > spectrum[desc.size-1].wavelength) { + htrdr_log_warn(src->htrdr, + "The wavelength %g nm is above the spectrum of the source\n", wlen); + return spectrum[desc.size-1].radiance; + } + + /* Look for the first item whose wavelength is not less than 'wlen' */ + find = search_lower_bound(&wlen, spectrum, desc.size, desc.pitch, cmp_wlen); + ASSERT(find); + id = (size_t)(find - spectrum); + ASSERT(id < desc.size); + + if(id == 0) { + ASSERT(wlen == spectrum[0].wavelength); + return spectrum[0].radiance; + } else { + const double w0 = spectrum[id-1].wavelength; + const double w1 = spectrum[id-0].wavelength; + const double L0 = spectrum[id-1].radiance; + const double L1 = spectrum[id-0].radiance; + const double u = (wlen - w0) / (w1 - w0); + const double L = L0 + u*(L1 - L0); /* Linear interpolation */ + return L; + } +} + +static void +release_source(ref_T* ref) +{ + struct htrdr_planets_source* source; + struct htrdr* htrdr; + ASSERT(ref); + + source = CONTAINER_OF(ref, struct htrdr_planets_source, ref); + htrdr = source->htrdr; + if(source->per_wlen_radiances) SBUF(ref_put(source->per_wlen_radiances)); + MEM_RM(htrdr_get_allocator(htrdr), source); + htrdr_ref_put(htrdr); +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +htrdr_planets_source_create + (struct htrdr* htrdr, + const struct htrdr_planets_source_args* args, + struct htrdr_planets_source** out_source) +{ + struct htrdr_planets_source* src = NULL; + double dst; /* In m */ + double lat; /* In radians */ + double lon; /* In radians */ + res_T res = RES_OK; + ASSERT(htrdr && out_source); + ASSERT(htrdr_planets_source_args_check(args) == RES_OK); + + src = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*src)); + if(!src) { + htrdr_log_err(htrdr, "error allocating source\n"); + res = RES_MEM_ERR; + goto error; + } + ref_init(&src->ref); + htrdr_ref_get(htrdr); + src->htrdr = htrdr; + src->radius = args->radius * 1e3/*From km to m*/; + + if(!args->rnrl_filename) { + src->temperature = args->temperature; + } else { + res = setup_per_wavelength_radiances(src, args); + if(res != RES_OK) goto error; + src->temperature = -1; /* Not used */ + } + + /* Convert latitude and longitude to radians and distance in m */ + lat = MDEG2RAD(args->latitude); + lon = MDEG2RAD(args->longitude); + dst = args->distance * 1e3/*From km to m*/; + + /* Compute the position of the source */ + src->position[0] = dst * cos(lat) * cos(lon); + src->position[1] = dst * cos(lat) * sin(lon); + src->position[2] = dst * sin(lat); + +exit: + *out_source = src; + return res; +error: + if(src) { htrdr_planets_source_ref_put(src); src = NULL; } + goto exit; +} + +void +htrdr_planets_source_ref_get(struct htrdr_planets_source* source) +{ + ASSERT(source); + ref_get(&source->ref); +} + +void htrdr_planets_source_ref_put(struct htrdr_planets_source* source) +{ + ASSERT(source); + ref_put(&source->ref, release_source); +} + +double +htrdr_planets_source_sample_direction + (const struct htrdr_planets_source* source, + struct ssp_rng* rng, + const double pos[3], + double dir[3]) +{ + double main_dir[3]; + double half_angle; /* In radians */ + double cos_half_angle; + double dst; /* In m */ + double pdf; + ASSERT(source && rng && pos && dir); + + /* compute the direction of `pos' toward the center of the source */ + d3_sub(main_dir, source->position, pos); + + /* Normalize the direction and keep the distance from `pos' to the center of + * the source */ + dst = d3_normalize(main_dir, main_dir); + CHK(dst > source->radius); + + /* Sample the source according to its solid angle, + * i.e. 2*PI*(1 - cos(half_angle)) */ + half_angle = asin(source->radius/dst); + cos_half_angle = cos(half_angle); + ssp_ran_sphere_cap_uniform(rng, main_dir, cos_half_angle, dir, &pdf); + + return pdf; +} + +double /* In W/m²/sr/m */ +htrdr_planets_source_get_radiance + (const struct htrdr_planets_source* source, + const double wlen) +{ + if(source->per_wlen_radiances) { + return get_radiance(source, wlen); + } else { + return htrdr_planck_monochromatic + (wlen*1e-9/*From nm to m*/, source->temperature); + } +} + +double +htrdr_planets_source_distance_to + (const struct htrdr_planets_source* source, + const double pos[3]) +{ + double vec[3]; + double dst; + ASSERT(source && pos); + + d3_sub(vec, source->position, pos); + dst = d3_len(vec); + return dst - source->radius; +} + +int +htrdr_planets_source_is_targeted + (const struct htrdr_planets_source* source, + const double pos[3], + const double dir[3]) +{ + double main_dir[3]; + double half_angle; /* In radians */ + double dst; /* In m */ + ASSERT(source && dir && d3_is_normalized(dir)); + + /* compute the direction of `pos' toward the center of the source */ + d3_sub(main_dir, source->position, pos); + + /* Normalize the direction and keep the distance from `pos' to the center of + * the source */ + dst = d3_normalize(main_dir, main_dir); + CHK(dst > source->radius); + + /* Compute the the half angle of the source as seen from pos */ + half_angle = asin(source->radius/dst); + + return d3_dot(dir, main_dir) >= cos(half_angle); +} + +res_T +htrdr_planets_source_get_spectral_range + (const struct htrdr_planets_source* source, + double range[2]) +{ + res_T res = RES_OK; + ASSERT(source && range); + + if(!source->per_wlen_radiances) { + range[0] = 0; + range[1] = INF; + } else { + struct sbuf_desc desc = SBUF_DESC_NULL; + const source_radiance_T* spectrum = NULL; + + res = sbuf_get_desc(source->per_wlen_radiances, &desc); + if(res != RES_OK) goto error; + + spectrum = desc.buffer; + range[0] = spectrum[0].wavelength; + range[1] = spectrum[desc.size-1].wavelength; + } + +exit: + return res; +error: + goto exit; +} + +int +htrdr_planets_source_does_radiance_vary_spectrally + (const struct htrdr_planets_source* source) +{ + ASSERT(source); + return source->per_wlen_radiances != NULL; +} + +res_T +htrdr_planets_source_get_spectrum + (const struct htrdr_planets_source* source, + const double range[2], /* In nm. Limits are inclusive */ + struct htrdr_planets_source_spectrum* source_spectrum) +{ + double full_range[2]; + res_T res = RES_OK; + ASSERT(source && range && source_spectrum && range[0] <= range[1]); + + if(!htrdr_planets_source_does_radiance_vary_spectrally(source)) { + res = RES_BAD_ARG; + goto error; + } + + res = htrdr_planets_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->source = source; + 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; + source_spectrum->buffer = low + 1; + } else { + source_spectrum->buffer = low; + } + + } + } + +exit: + return res; +error: + goto exit; +} + +void +htrdr_planets_source_spectrum_at + (void* source_spectrum, + const size_t i, /* between [0, spectrum->size[ */ + double* wavelength, /* In nm */ + double* radiance) /* In W/m²/sr/m */ +{ + struct htrdr_planets_source_spectrum* spectrum = source_spectrum; + ASSERT(spectrum && i < spectrum->size && wavelength && radiance); + + /* Lower limit */ + if(i == 0) { + *wavelength = spectrum->range[0]; + *radiance = htrdr_planets_source_get_radiance + (spectrum->source, spectrum->range[0]); + + /* Upper limit */ + } else if(i == spectrum->size-1) { + *wavelength = spectrum->range[1]; + *radiance = htrdr_planets_source_get_radiance + (spectrum->source, spectrum->range[1]); + + /* Discrete element */ + } else { + const source_radiance_T* item = + (const source_radiance_T*)spectrum->buffer + (i-1); + *wavelength = item->wavelength; + *radiance = item->radiance; + } +} diff --git a/src/planets/htrdr_planets_source.h b/src/planets/htrdr_planets_source.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef HTRDR_PLANETS_SOURCE_H +#define HTRDR_PLANETS_SOURCE_H + +#include <rsys/rsys.h> + +/* Forward declarations */ +struct htrdr; +struct htrdr_planets_source; +struct htrdr_planets_source_args; +struct ssp_rng; + +struct htrdr_planets_source_spectrum { + const struct htrdr_planets_source* source; + double range[2]; /* In nm. Limits are inclusive */ + size_t size; /* Number of elements representing the spectrum */ + const void* buffer; /* Pointer toward the spectrum data */ +}; +#define HTRDR_PLANETS_SOURCE_SPECTRUM_NULL__ {NULL, {0,0}, 0, NULL} +static const struct htrdr_planets_source_spectrum +HTRDR_PLANETS_SOURCE_SPECTRUM_NULL = HTRDR_PLANETS_SOURCE_SPECTRUM_NULL__; + +extern LOCAL_SYM res_T +htrdr_planets_source_create + (struct htrdr* htrdr, + const struct htrdr_planets_source_args* args, + struct htrdr_planets_source** source); + +extern LOCAL_SYM void +htrdr_planets_source_ref_get + (struct htrdr_planets_source* source); + +extern LOCAL_SYM void +htrdr_planets_source_ref_put + (struct htrdr_planets_source* source); + +/* Return the pdf of the sampled direction */ +extern LOCAL_SYM double +htrdr_planets_source_sample_direction + (const struct htrdr_planets_source* source, + struct ssp_rng* rng, + const double pos[3], /* Position from which direction is sampled */ + double dir[3]); + +extern LOCAL_SYM double /* In W/m²/sr/m */ +htrdr_planets_source_get_radiance + (const struct htrdr_planets_source* source, + const double wlen); /* In nanometers */ + +/* Return the distance between the source surface and the input position. Can + * be negative if the position is in the source */ +extern LOCAL_SYM double /* In m */ +htrdr_planets_source_distance_to + (const struct htrdr_planets_source* source, + const double pos[3]); + +/* Return 1 if the source is targeted by the submitted ray and 0 otherwise */ +extern LOCAL_SYM int +htrdr_planets_source_is_targeted + (const struct htrdr_planets_source* source, + const double pos[3], /* Ray origin */ + const double dir[3]);/* Ray direction */ + +extern LOCAL_SYM res_T +htrdr_planets_source_get_spectral_range + (const struct htrdr_planets_source* source, + double range[2]); /* In nm. Limits are inclusive */ + +extern LOCAL_SYM int +htrdr_planets_source_does_radiance_vary_spectrally + (const struct htrdr_planets_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_planets_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_planets_source_get_spectrum + (const struct htrdr_planets_source* source, + const double range[2], /* In nm. Limits are inclusive */ + struct htrdr_planets_source_spectrum* spectrum); + +/* Note that the following function profile corresponds to the type expected by + * the discrete wavelength distribution + * (see htrdr_ran_wlen_discrete_create_args structure) */ +extern LOCAL_SYM void +htrdr_planets_source_spectrum_at + (void* spectrum, + size_t i, /* between [0, spectrum->size[ */ + double* wavelength, /* In nm */ + double* radiance); /* In W/m²/sr/m */ + +#endif /* HTRDR_PLANETS_SOURCE_H */ diff --git a/src/planets/test_htrdr_planets_source.c b/src/planets/test_htrdr_planets_source.c @@ -0,0 +1,302 @@ +/* Copyright (C) 2018-2019, 2022-2024 Centre National de la Recherche Scientifique + * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux + * Copyright (C) 2022-2024 Institut Pierre-Simon Laplace + * Copyright (C) 2022-2024 Institut de Physique du Globe de Paris + * Copyright (C) 2018-2024 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022-2024 Observatoire de Paris + * Copyright (C) 2022-2024 Université de Reims Champagne-Ardenne + * Copyright (C) 2022-2024 Université de Versaille Saint-Quentin + * Copyright (C) 2018-2019, 2022-2024 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "planets/htrdr_planets_args.h" +#include "planets/htrdr_planets_source.h" + +#include "core/htrdr.h" +#include "core/htrdr_ran_wlen_discrete.h" + +#include <rsys/math.h> +#include <rsys/mem_allocator.h> + +#include <stdio.h> + +static void +write_per_wlen_radiances + (FILE* fp, + const size_t pagesize, + const size_t size, + const size_t szelmt, + const size_t alelmt) +{ + const char byte = 0; + size_t i; + + CHK(fp); + + /* Header */ + CHK(fwrite(&pagesize, sizeof(pagesize), 1, fp) == 1); + CHK(fwrite(&size, sizeof(size), 1, fp) == 1); + CHK(fwrite(&szelmt, sizeof(szelmt), 1, fp) == 1); + CHK(fwrite(&alelmt, sizeof(alelmt), 1, fp) == 1); + + /* Padding */ + CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize), SEEK_SET) == 0); + + FOR_EACH(i, 0, size) { + const double w = (double)i; + const double L = (double)(100 + i); + + CHK(fwrite(&w, sizeof(w), 1, fp) == 1); + CHK(fwrite(&L, sizeof(L), 1, fp) == 1); + } + + /* Padding. Write one char to position the EOF indicator */ + CHK(fseek(fp, (long)ALIGN_SIZE((size_t)ftell(fp), pagesize)-1, SEEK_SET) == 0); + CHK(fwrite(&byte, sizeof(byte), 1, fp) == 1); + + CHK(fflush(fp) == 0); +} + +static void +test_spectrum(struct htrdr* htrdr) +{ + struct htrdr_planets_source_args source_args = HTRDR_PLANETS_SOURCE_ARGS_NULL; + struct htrdr_planets_source_spectrum spectrum; + struct htrdr_planets_source* source = NULL; + + FILE* fp = NULL; + char rnrl_filename[] = "rnrl.bin"; + double range[2]; + double w, L; + + CHK(fp = fopen(rnrl_filename, "w")); + write_per_wlen_radiances(fp, 4096, 10, 16, 16); + CHK(fclose(fp) == 0); + + source_args.rnrl_filename = rnrl_filename; + source_args.longitude = 0; + source_args.latitude = 0; + source_args.distance = 0; + source_args.radius = 1e8; + source_args.temperature = -1; + CHK(htrdr_planets_source_create(htrdr, &source_args, &source) == RES_OK); + CHK(htrdr_planets_source_does_radiance_vary_spectrally(source) == 1); + CHK(htrdr_planets_source_get_spectral_range(source, range) == RES_OK); + CHK(range[0] == 0); + CHK(range[1] == 9); + + range[0] = 0; range[1] = 10; + CHK(htrdr_planets_source_get_spectrum(source, range, &spectrum) == RES_BAD_ARG); + + range[0] = 1; range[1] = 3; + CHK(htrdr_planets_source_get_spectrum(source, range, &spectrum) == RES_OK); + CHK(spectrum.source == source); + CHK(spectrum.range[0] == 1); + CHK(spectrum.range[1] == 3); + CHK(spectrum.size == 3); + + htrdr_planets_source_spectrum_at(&spectrum, 0, &w, &L); + CHK(w == 1 && L == 101); + htrdr_planets_source_spectrum_at(&spectrum, 1, &w, &L); + CHK(w == 2 && L == 102); + htrdr_planets_source_spectrum_at(&spectrum, 2, &w, &L); + CHK(w == 3 && L == 103); + + range[0] = 1.7; range[1] = 1.95; + CHK(htrdr_planets_source_get_spectrum(source, range, &spectrum) == RES_OK); + CHK(spectrum.source == source); + CHK(spectrum.range[0] = 1.7); + CHK(spectrum.range[1] = 1.95); + CHK(spectrum.size == 2); + htrdr_planets_source_spectrum_at(&spectrum, 0, &w, &L); + CHK(w == 1.7 && eq_eps(L, 101.7, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 1, &w, &L); + CHK(w == 1.95 && eq_eps(L, 101.95, 1.e-6)); + + range[0] = 2; range[1] = 2.01; + CHK(htrdr_planets_source_get_spectrum(source, range, &spectrum) == RES_OK); + CHK(spectrum.size == 2); + htrdr_planets_source_spectrum_at(&spectrum, 0, &w, &L); + CHK(w == 2 && L == 102); + htrdr_planets_source_spectrum_at(&spectrum, 1, &w, &L); + CHK(w == 2.01 && eq_eps(L, 102.01, 1.e-6)); + + range[0] = 5.1; range[1] = 6; + CHK(htrdr_planets_source_get_spectrum(source, range, &spectrum) == RES_OK); + CHK(spectrum.size == 2); + htrdr_planets_source_spectrum_at(&spectrum, 0, &w, &L); + CHK(w == 5.1 && eq_eps(L, 105.1, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 1, &w, &L); + CHK(w == 6 && L == 106); + + range[0] = 7.5; range[1] = 9; + CHK(htrdr_planets_source_get_spectrum(source, range, &spectrum) == RES_OK); + CHK(spectrum.size == 3); + htrdr_planets_source_spectrum_at(&spectrum, 0, &w, &L); + CHK(w == 7.5 && eq_eps(L, 107.5, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 1, &w, &L); + CHK(w == 8 && L == 108); + htrdr_planets_source_spectrum_at(&spectrum, 2, &w, &L); + CHK(w == 9 && L == 109); + + range[0] = 0.9; range[1] = 7.456; + CHK(htrdr_planets_source_get_spectrum(source, range, &spectrum) == RES_OK); + CHK(spectrum.size == 9); + htrdr_planets_source_spectrum_at(&spectrum, 0, &w, &L); + CHK(w == 0.9 && eq_eps(L, 100.9, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 1, &w, &L); + CHK(w == 1 && eq_eps(L, 101, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 2, &w, &L); + CHK(w == 2 && eq_eps(L, 102, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 3, &w, &L); + CHK(w == 3 && eq_eps(L, 103, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 4, &w, &L); + CHK(w == 4 && eq_eps(L, 104, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 5, &w, &L); + CHK(w == 5 && eq_eps(L, 105, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 6, &w, &L); + CHK(w == 6 && eq_eps(L, 106, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 7, &w, &L); + CHK(w == 7 && eq_eps(L, 107, 1.e-6)); + htrdr_planets_source_spectrum_at(&spectrum, 8, &w, &L); + CHK(w == 7.456 && eq_eps(L, 107.456, 1.e-6)); + + htrdr_planets_source_ref_put(source); +} + +static void +test_spectrum_fail(struct htrdr* htrdr) +{ + struct htrdr_planets_source_args source_args = HTRDR_PLANETS_SOURCE_ARGS_NULL; + struct htrdr_planets_source* source = NULL; + FILE* fp = NULL; + char rnrl_filename[] = "rnrl.bin"; + double w, L; + + source_args.rnrl_filename = rnrl_filename; + source_args.longitude = 0; + source_args.latitude = 0; + source_args.distance = 0; + source_args.radius = 1e8; + source_args.temperature = -1; + + /* Wrong item size */ + CHK(fp = fopen(rnrl_filename, "w")); + write_per_wlen_radiances(fp, 4096, 10, 8, 16); + CHK(fclose(fp) == 0); + CHK(htrdr_planets_source_create(htrdr, &source_args, &source) == RES_BAD_ARG); + + /* Wrong item alignment */ + CHK(fp = fopen(rnrl_filename, "w")); + write_per_wlen_radiances(fp, 4096, 10, 16, 32); + CHK(fclose(fp) == 0); + CHK(htrdr_planets_source_create(htrdr, &source_args, &source) == RES_BAD_ARG); + + CHK(fp = fopen(rnrl_filename, "w")); + write_per_wlen_radiances(fp, 4096, 4, 16, 16); + + /* Overwrite sorted items by unsorted items */ + CHK(fseek(fp, 4096, SEEK_SET) == 0); + w = 10; L = 1; + CHK(fwrite(&w, sizeof(w), 1, fp) == 1); + CHK(fwrite(&L, sizeof(L), 1, fp) == 1); + w = 11; L = 2; + CHK(fwrite(&w, sizeof(w), 1, fp) == 1); + CHK(fwrite(&L, sizeof(L), 1, fp) == 1); + w = 9; L = 3; + CHK(fwrite(&w, sizeof(w), 1, fp) == 1); + CHK(fwrite(&L, sizeof(L), 1, fp) == 1); + w = 12; L = 4; + CHK(fwrite(&w, sizeof(w), 1, fp) == 1); + CHK(fwrite(&L, sizeof(L), 1, fp) == 1); + CHK(fclose(fp) == 0); + + /* Unsorted items */ + CHK(htrdr_planets_source_create(htrdr, &source_args, &source) == RES_BAD_ARG); +} + +static void +test_spectrum_from_files(struct htrdr* htrdr, int argc, char** argv) +{ + struct htrdr_ran_wlen_discrete_create_args distrib_args = + HTRDR_RAN_WLEN_DISCRETE_CREATE_ARGS_NULL; + struct htrdr_ran_wlen_discrete* distrib = NULL; + + struct htrdr_planets_source_args source_args = HTRDR_PLANETS_SOURCE_ARGS_NULL; + struct htrdr_planets_source_spectrum spectrum = HTRDR_PLANETS_SOURCE_SPECTRUM_NULL; + struct htrdr_planets_source* source = NULL; + size_t i; + + source_args.longitude = 0; + source_args.latitude = 0; + source_args.distance = 0; + source_args.radius = 1e8; + source_args.temperature = -1; + + FOR_EACH(i, 1, argc) { + double range[2]; + double lambda, pdf; + source_args.rnrl_filename = argv[i]; + + CHK(htrdr_planets_source_create(htrdr, &source_args, &source) == RES_OK); + CHK(htrdr_planets_source_does_radiance_vary_spectrally(source)); + CHK(htrdr_planets_source_get_spectral_range(source, range) == RES_OK); + + range[0] = 250; + range[1] = 850; + CHK(htrdr_planets_source_get_spectrum(source, range, &spectrum) == RES_OK); + + printf("`%s' stores %lu entries between [%g, %g] nm\n", + argv[i], spectrum.size, SPLIT2(range)); + + distrib_args.get = htrdr_planets_source_spectrum_at; + distrib_args.nwavelengths = spectrum.size; + distrib_args.context = &spectrum; + CHK(htrdr_ran_wlen_discrete_create(htrdr, &distrib_args, &distrib) == RES_OK); + + lambda = htrdr_ran_wlen_discrete_sample(distrib, 0.3, 0.5, &pdf); + printf("lambda = %g nm; pdf = %f nm⁻¹\n", lambda, pdf); + + htrdr_planets_source_ref_put(source); + htrdr_ran_wlen_discrete_ref_put(distrib); + } +} + +int +main(int argc, char** argv) +{ + struct htrdr_args args = HTRDR_ARGS_DEFAULT; + struct htrdr* htrdr = NULL; + size_t memsz = 0; + + args.verbose = 1; + htrdr_mpi_init(argc, argv); + CHK(htrdr_create(NULL, &args, &htrdr) == RES_OK); + + memsz = MEM_ALLOCATED_SIZE(htrdr_get_allocator(htrdr)); + + if(argc > 1) { + test_spectrum_from_files(htrdr, argc, argv); + } else { + test_spectrum(htrdr); + test_spectrum_fail(htrdr); + } + + CHK(MEM_ALLOCATED_SIZE(htrdr_get_allocator(htrdr)) == memsz); + + htrdr_ref_put(htrdr); + htrdr_mpi_finalize(); + return 0; +}