star-hitran

Load line-by-line data from the HITRAN database
git clone git://git.meso-star.com/star-hitran.git
Log | Files | Refs | README | LICENSE

shtr.h (13658B)


      1 /* Copyright (C) 2022, 2025, 2026 |Méso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2025, 2026 Université de Lorraine
      3  * Copyright (C) 2022 Centre National de la Recherche Scientifique
      4  * Copyright (C) 2022 Université Paul Sabatier
      5  *
      6  * This program is free software: you can redistribute it and/or modify
      7  * it under the terms of the GNU General Public License as published by
      8  * the Free Software Foundation, either version 3 of the License, or
      9  * (at your option) any later version.
     10  *
     11  * This program is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     14  * GNU General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU General Public License
     17  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     18 
     19 #ifndef SHTR_H
     20 #define SHTR_H
     21 
     22 #include <rsys/hash.h>
     23 #include <rsys/rsys.h>
     24 
     25 #include <float.h>
     26 #include <limits.h>
     27 
     28 /* Library symbol management */
     29 #if defined(SHTR_SHARED_BUILD)  /* Build shared library */
     30   #define SHTR_API extern EXPORT_SYM
     31 #elif defined(SHTR_STATIC)  /* Use/build static library */
     32   #define SHTR_API extern LOCAL_SYM
     33 #else
     34   #define SHTR_API extern IMPORT_SYM
     35 #endif
     36 
     37 /* Helper macro that asserts if the invocation of the shtr function `Func'
     38  * returns an error. One should use this macro on shtr function calls for which
     39  * no explicit error checking is performed */
     40 #ifndef NDEBUG
     41   #define SHTR(Func) ASSERT(shtr_ ## Func == RES_OK)
     42 #else
     43   #define SHTR(Func) shtr_ ## Func
     44 #endif
     45 
     46 #define SHTR_MAX_ISOTOPE_COUNT 16
     47 
     48 /* List of HITRAN species. They are classified as in the HITRAN database, i.e.
     49  * their value corresponds to that of HITRAN. Note that they start at 1 rather
     50  * than zero and therefore do not strictly correspond to a C array index */
     51 enum shtr_molecule_id {
     52   SHTR_MOLECULE_ID_NULL = 0,
     53 
     54   SHTR_H2O,    SHTR_CO2,    SHTR_O3,     SHTR_N2O,    SHTR_CO,     SHTR_CH4,
     55   SHTR_O2,     SHTR_NO,     SHTR_SO2,    SHTR_NO2,    SHTR_NH3,    SHTR_HNO3,
     56   SHTR_OH,     SHTR_HF,     SHTR_HCl,    SHTR_HBr,    SHTR_HI,     SHTR_ClO,
     57   SHTR_OCS,    SHTR_H2CO,   SHTR_HOCl,   SHTR_N2,     SHTR_HCN,    SHTR_CH3Cl,
     58   SHTR_H2O2,   SHTR_C2H2,   SHTR_C2H6,   SHTR_PH3,    SHTR_COF2,   SHTR_SF6,
     59   SHTR_H2S,    SHTR_HCOOH,  SHTR_HO2,    SHTR_O,      SHTR_ClONO2, SHTR_NOplus,
     60   SHTR_HOBr,   SHTR_C2H4,   SHTR_CH3OH,  SHTR_CH3Br,  SHTR_CH3CN,  SHTR_CF4,
     61   SHTR_C4H2,   SHTR_HC3N,   SHTR_H2,     SHTR_CS,     SHTR_SO3,    SHTR_C2N2,
     62   SHTR_COCl2,  SHTR_SO,     SHTR_CH3F,   SHTR_GeH4,   SHTR_CS2,    SHTR_CH3I,
     63   SHTR_NF3,    SHTR_H3plus, SHTR_CH3,    SHTR_S2,     SHTR_COFCl,  SHTR_HONO,
     64   SHTR_ClNO2,
     65 
     66   SHTR_MAX_MOLECULE_COUNT
     67 };
     68 
     69 /* Table that associates the molecule ID with its name */
     70 static const char* SHTR_MOLECULE_CSTR__[SHTR_MAX_MOLECULE_COUNT] = {
     71   NULL, /* SHTR_MOLECULE_ID_NULL__ */
     72 
     73   "H2O",    "CO2",    "O3",     "N2O",    "CO",     "CH4",
     74   "O2",     "NO",     "SO2",    "NO2",    "NH3",    "HNO3",
     75   "OH",     "HF",     "HCl",    "HBr",    "HI",     "ClO",
     76   "OCS",    "H2CO",   "HOCl",   "N2",     "HCN",    "CH3Cl",
     77   "H2O2",   "C2H2",   "C2H6",   "PH3",    "COF2",   "SF6",
     78   "H2S",    "HCOOH",  "HO2",    "O",      "ClONO2", "NO+",
     79   "HOBr",   "C2H4",   "CH3OH",  "CH3Br",  "CH3CN",  "CF4",
     80   "C4H2",   "HC3N",   "H2",     "CS",     "SO3",    "C2N2",
     81   "COCl2",  "SO",     "CH3F",   "GeH4",   "CS2",    "CH3I",
     82   "NF3",    "H3+",    "CH3",    "S2",     "COFCl",  "HONO",
     83   "ClNO2"
     84 };
     85 
     86 static INLINE const char*
     87 shtr_molecule_cstr(const enum shtr_molecule_id id)
     88 {
     89   ASSERT(id < SHTR_MAX_MOLECULE_COUNT);
     90   return SHTR_MOLECULE_CSTR__[id];
     91 }
     92 
     93 struct shtr_isotope {
     94   double abundance; /* in ]0, 1] */
     95   double Q296K; /* Partition function at Tref = 296K */
     96   double molar_mass; /* In g.mol^-1 */
     97 
     98   /* Local idx of the molecule to which the isotope belongs */
     99   size_t molecule_id_local;
    100 
    101   int gj; /* State independent degeneracy factor */
    102   int id; /* Identifier of the isotope <=> Global index */
    103 };
    104 #define SHTR_ISOTOPE_NULL__ {0,0,0,0,0,-1}
    105 static const struct shtr_isotope SHTR_ISOTOPE_NULL =
    106   SHTR_ISOTOPE_NULL__;
    107 
    108 struct shtr_molecule {
    109   const char* name;
    110   size_t nisotopes; /* Number of isotopes */
    111   const struct shtr_isotope* isotopes;
    112   enum shtr_molecule_id id; /* Unique identifier */
    113 };
    114 #define SHTR_MOLECULE_NULL__ {NULL, 0, NULL, SHTR_MOLECULE_ID_NULL}
    115 static const struct shtr_molecule SHTR_MOLECULE_NULL =
    116   SHTR_MOLECULE_NULL__;
    117 
    118 #define SHTR_MOLECULE_IS_NULL(Molecule) \
    119   ((Molecule)->id == SHTR_MOLECULE_NULL.id)
    120 
    121 struct shtr_line {
    122   double wavenumber; /* Central wavenumber in vacuum [cm^-1] */
    123   double intensity; /* Reference intensity [cm^-1/(molec.cm^2)] */
    124   double gamma_air; /* Air broadening half-width [cm^-1.atm^-1] */
    125   double gamma_self; /* Self broadening half-width [cm^-1.atm^-1] */
    126   double lower_state_energy; /* [cm^-1] */
    127   double n_air; /* Temperature-dependant exponent */
    128   double delta_air; /* Air-pressure wavenumber shift [cm^-1.atm^-1] */
    129 
    130   enum shtr_molecule_id molecule_id;
    131 
    132   /* The value of the following isotopic index is _not_ the value of the
    133    * isotopic index read from the HITRAN file. The original value is in [0, 9]
    134    * with 0 actually meaning 10. Thus, once decoded, the index is located in
    135    * [1, 10]. The next member variable simply stores this index but decremented
    136    * by one in order to make it compatible with C indexing. As a result, it
    137    * can be used directly to index the 'isotopes' array of a 'shtr_molecule'
    138    * data structure loaded from an isotope metadata file */
    139   int32_t isotope_id_local;
    140 };
    141 #define SHTR_LINE_NULL__ {0,0,0,0,0,0,0,-1,-1}
    142 static const struct shtr_line SHTR_LINE_NULL = SHTR_LINE_NULL__;
    143 
    144 static INLINE int
    145 shtr_line_eq(const struct shtr_line* line0, const struct shtr_line* line1)
    146 {
    147   ASSERT(line0 && line1);
    148   return line0->wavenumber == line1->wavenumber
    149       && line0->intensity == line1->intensity
    150       && line0->gamma_air == line1->gamma_air
    151       && line0->gamma_self == line1->gamma_self
    152       && line0->lower_state_energy == line1->lower_state_energy
    153       && line0->n_air == line1->n_air
    154       && line0->delta_air == line1->delta_air
    155       && line0->molecule_id == line1->molecule_id
    156       && line0->isotope_id_local == line1->isotope_id_local;
    157 }
    158 
    159 struct shtr_line_param_info {
    160   double range[2];
    161   double err; /* Encoding error */
    162 };
    163 #define SHTR_LINE_PARAM_INFO_NULL__ {{DBL_MAX,-DBL_MAX}, 0}
    164 static const struct shtr_line_param_info SHTR_LINE_PARAM_INFO_NULL =
    165   SHTR_LINE_PARAM_INFO_NULL__;
    166 
    167 /* Information on a list of lines */
    168 struct shtr_line_list_info {
    169   struct shtr_line_param_info wavenumber;
    170   struct shtr_line_param_info intensity;
    171   struct shtr_line_param_info gamma_air;
    172   struct shtr_line_param_info gamma_self;
    173   struct shtr_line_param_info lower_state_energy;
    174   struct shtr_line_param_info n_air;
    175   struct shtr_line_param_info delta_air;
    176 };
    177 #define SHTR_LINE_LIST_INFO_NULL__ { \
    178   SHTR_LINE_PARAM_INFO_NULL__, \
    179   SHTR_LINE_PARAM_INFO_NULL__, \
    180   SHTR_LINE_PARAM_INFO_NULL__, \
    181   SHTR_LINE_PARAM_INFO_NULL__, \
    182   SHTR_LINE_PARAM_INFO_NULL__, \
    183   SHTR_LINE_PARAM_INFO_NULL__, \
    184   SHTR_LINE_PARAM_INFO_NULL__, \
    185 }
    186 static const struct shtr_line_list_info SHTR_LINE_LIST_INFO_NULL =
    187   SHTR_LINE_LIST_INFO_NULL__;
    188 
    189 /* Forward declarations of opaque data structures */
    190 struct shtr;
    191 struct shtr_isotope_metadata;
    192 struct shtr_line_list;
    193 struct shtr_line_view;
    194 
    195 /*******************************************************************************
    196  * Input arguments for API functions
    197  ******************************************************************************/
    198 struct shtr_create_args {
    199   struct logger* logger; /* May be NULL <=> default logger */
    200   struct mem_allocator* allocator; /* NULL <=> use default allocator */
    201   int verbose; /* Verbosity level */
    202 };
    203 #define SHTR_CREATE_ARGS_DEFAULT__ {NULL, NULL, 0}
    204 static const struct shtr_create_args SHTR_CREATE_ARGS_DEFAULT =
    205   SHTR_CREATE_ARGS_DEFAULT__;
    206 
    207 /* Load lines saved in HITRAN format */
    208 struct shtr_line_list_load_args {
    209   /* Name of the file to load or of the provided stream.
    210    * NULL <=> uses a default name for the stream to be loaded, which must
    211    * therefore be defined. */
    212   const char* filename;
    213 
    214   /* Stream from where data are loaded.
    215    * NULL <=> loading from the file name, which must therefore be defined */
    216   FILE* file;
    217 };
    218 #define SHTR_LINE_LIST_LOAD_ARGS_NULL__ {NULL, NULL}
    219 static const struct shtr_line_list_load_args SHTR_LINE_LIST_LOAD_ARGS_NULL =
    220   SHTR_LINE_LIST_LOAD_ARGS_NULL__;
    221 
    222 /* Read the lines stored in the internal format of the shtr library, i.e., as
    223  * they were written by the shtr_line_list_write function */
    224 struct shtr_line_list_read_args {
    225   /* Name of the file to read or of the provided stream.
    226    * NULL <=> uses a default name for the stream to be read, which must
    227    * therefore be defined. */
    228   const char* filename; /* Name of the file to read */
    229   FILE* file; /* Stream from where data are read. NULL <=> read from file */
    230 
    231   /* Range of line indices to read. The limits are included.
    232    * If the lower limit is greater than or equal to the number of lines to read,
    233    * no lines are read.
    234    * If the upper limit is greater than or equal to the number of lines to read,
    235    * all lines from the lower limit are read.
    236    * If the range is degenerate, an error is returned. */
    237   size_t range[2];
    238 };
    239 #define SHTR_LINE_LIST_READ_ARGS_NULL__ {NULL, NULL, {0,SIZE_MAX}}
    240 static const struct shtr_line_list_read_args SHTR_LINE_LIST_READ_ARGS_NULL =
    241   SHTR_LINE_LIST_READ_ARGS_NULL__;
    242 
    243 struct shtr_line_list_write_args {
    244   /* Name of the file in which the list of lines is serialized.
    245    * NULL <=> uses a default name for the stream to be written, which must
    246    * therefore be defined. */
    247   const char* filename; /* Name of the file to read */
    248 
    249   /* Stream where data is written.
    250    * NULL <=> write to the file defined by "filename" */
    251   FILE* file;
    252 };
    253 #define SHTR_LINE_LIST_WRITE_ARGS_NULL__ {NULL, NULL}
    254 static const struct shtr_line_list_write_args SHTR_LINE_LIST_WRITE_ARGS_NULL =
    255   SHTR_LINE_LIST_WRITE_ARGS_NULL__;
    256 
    257 BEGIN_DECLS
    258 
    259 /*******************************************************************************
    260  * Device API
    261  ******************************************************************************/
    262 SHTR_API res_T
    263 shtr_create
    264   (const struct shtr_create_args* args,
    265    struct shtr** shtr);
    266 
    267 SHTR_API res_T
    268 shtr_ref_get
    269   (struct shtr* shtr);
    270 
    271 SHTR_API res_T
    272 shtr_ref_put
    273   (struct shtr* shtr);
    274 
    275 /*******************************************************************************
    276  * Isotope metadata API
    277  ******************************************************************************/
    278 SHTR_API res_T
    279 shtr_isotope_metadata_load
    280   (struct shtr* shtr,
    281    const char* path,
    282    struct shtr_isotope_metadata** metadata);
    283 
    284 SHTR_API res_T
    285 shtr_isotope_metadata_load_stream
    286   (struct shtr* shtr,
    287    FILE* stream,
    288    const char* stream_name, /* NULL <=> use default stream name */
    289    struct shtr_isotope_metadata** metadata);
    290 
    291 /* Load the isotope metadata serialized with the "shtr_isotope_metadata_write"
    292  * function */
    293 SHTR_API res_T
    294 shtr_isotope_metadata_create_from_stream
    295   (struct shtr* shtr,
    296    FILE* stream,
    297    struct shtr_isotope_metadata** metadata);
    298 
    299 SHTR_API res_T
    300 shtr_isotope_metadata_ref_get
    301   (struct shtr_isotope_metadata* metadata);
    302 
    303 SHTR_API res_T
    304 shtr_isotope_metadata_ref_put
    305   (struct shtr_isotope_metadata* metadata);
    306 
    307 SHTR_API res_T
    308 shtr_isotope_metadata_get_molecules_count
    309   (const struct shtr_isotope_metadata* metadata,
    310    size_t* nmolecules);
    311 
    312 SHTR_API res_T
    313 shtr_isotope_metadata_get_isotopes_count
    314   (const struct shtr_isotope_metadata* metadata,
    315    size_t* nisotopes);
    316 
    317 SHTR_API res_T
    318 shtr_isotope_metadata_get_molecule
    319   (const struct shtr_isotope_metadata* metadata,
    320    const size_t imolecule, /* Local index of the molecule in [0, molecules_count[ */
    321    struct shtr_molecule* molecule);
    322 
    323 /* `molecule' is set to SHTR_MOLECULE_NULL if `molecule_id' is not found */
    324 SHTR_API res_T
    325 shtr_isotope_metadata_find_molecule
    326   (struct shtr_isotope_metadata* metadata,
    327    const int molecule_id, /* Unique identifier of the molecule <=> Global index */
    328    struct shtr_molecule* molecule);
    329 
    330 SHTR_API res_T
    331 shtr_isotope_metadata_write
    332   (const struct shtr_isotope_metadata* metadata,
    333    FILE* stream);
    334 
    335 SHTR_API res_T
    336 shtr_isotope_metadata_hash
    337   (const struct shtr_isotope_metadata* metadata,
    338    hash256_T hash);
    339 
    340 /*******************************************************************************
    341  * Lines API
    342  ******************************************************************************/
    343 SHTR_API res_T
    344 shtr_line_list_load
    345   (struct shtr* shtr,
    346    const struct shtr_line_list_load_args* args,
    347    struct shtr_line_list** list);
    348 
    349 /* Load the line list serialized with the "shtr_line_list_write" function */
    350 SHTR_API res_T
    351 shtr_line_list_read
    352   (struct shtr* shtr,
    353    const struct shtr_line_list_read_args* args,
    354    struct shtr_line_list** list);
    355 
    356 SHTR_API res_T
    357 shtr_line_list_ref_get
    358    (struct shtr_line_list* list);
    359 
    360 SHTR_API res_T
    361 shtr_line_list_ref_put
    362    (struct shtr_line_list* list);
    363 
    364 SHTR_API res_T
    365 shtr_line_list_get_size
    366   (const struct shtr_line_list* list,
    367    size_t* nlines);
    368 
    369 SHTR_API res_T
    370 shtr_line_list_at
    371   (struct shtr_line_list* list,
    372    const size_t i,
    373    struct shtr_line* line);
    374 
    375 SHTR_API res_T
    376 shtr_line_list_write
    377   (const struct shtr_line_list* list,
    378    const struct shtr_line_list_write_args* args);
    379 
    380 SHTR_API res_T
    381 shtr_line_list_get_info
    382   (const struct shtr_line_list* list,
    383    struct shtr_line_list_info* info);
    384 
    385 SHTR_API res_T
    386 shtr_line_list_hash
    387   (const struct shtr_line_list* list,
    388    hash256_T hash);
    389 
    390 END_DECLS
    391 
    392 #endif /* SHTR_H */