|
| 1 | +from astropy.table import Table |
| 2 | +from astropy import units as u |
| 3 | + |
| 4 | +from ..query import BaseQuery |
| 5 | +from ..utils import async_to_sync, prepend_docstr_nosections |
| 6 | +from . import conf |
| 7 | +from .utils import parse_readme |
| 8 | + |
| 9 | +__all__ = ['Hitran', 'HitranClass'] |
| 10 | + |
| 11 | + |
| 12 | +@async_to_sync |
| 13 | +class HitranClass(BaseQuery): |
| 14 | + |
| 15 | + QUERY_URL = conf.query_url |
| 16 | + TIMEOUT = conf.timeout |
| 17 | + FORMATFILE = conf.formatfile |
| 18 | + ISO_INDEX = {'id': 0, 'iso_name': 1, 'abundance': 2, 'mass': 3, |
| 19 | + 'mol_name': 4} |
| 20 | + |
| 21 | +# Copied from the hapi.py code (Academic Free License) |
| 22 | +# http://hitran.org/static/hapi/hapi.py |
| 23 | +# M I id iso_name abundance mass mol_name |
| 24 | + ISO = { |
| 25 | + (1, 1): [1, 'H2(16O)', 0.997317, 18.010565, 'H2O'], |
| 26 | + (1, 2): [2, 'H2(18O)', 0.00199983, 20.014811, 'H2O'], |
| 27 | + (1, 3): [3, 'H2(17O)', 0.000372, 19.01478, 'H2O'], |
| 28 | + (1, 4): [4, 'HD(16O)', 0.00031069, 19.01674, 'H2O'], |
| 29 | + (1, 5): [5, 'HD(18O)', 0.000000623, 21.020985, 'H2O'], |
| 30 | + (1, 6): [6, 'HD(17O)', 0.000000116, 20.020956, 'H2O'], |
| 31 | + (2, 1): [7, '(12C)(16O)2', 0.9842, 43.98983, 'CO2'], |
| 32 | + (2, 2): [8, '(13C)(16O)2', 0.01106, 44.993185, 'CO2'], |
| 33 | + (2, 3): [9, '(16O)(12C)(18O)', 0.0039471, 45.994076, 'CO2'], |
| 34 | + (2, 4): [10, '(16O)(12C)(17O)', 0.000734, 44.994045, 'CO2'], |
| 35 | + (2, 5): [11, '(16O)(13C)(18O)', 0.00004434, 46.997431, 'CO2'], |
| 36 | + (2, 6): [12, '(16O)(13C)(17O)', 0.00000825, 45.9974, 'CO2'], |
| 37 | + (2, 7): [13, '(12C)(18O)2', 0.0000039573, 47.998322, 'CO2'], |
| 38 | + (2, 8): [14, '(17O)(12C)(18O)', 0.00000147, 46.998291, 'CO2'], |
| 39 | + (2, 0): [15, '(13C)(18O)2', 0.000000044967, 49.001675, 'CO2'], |
| 40 | + (2, 11): [120, '(18O)(13C)(17O)', 0.00000001654, 48.00165, 'CO2'], |
| 41 | + (2, 9): [121, '(12C)(17O)2', 0.0000001368, 45.998262, 'CO2'], |
| 42 | + (3, 1): [16, '(16O)3', 0.992901, 47.984745, 'O3'], |
| 43 | + (3, 2): [17, '(16O)(16O)(18O)', 0.00398194, 49.988991, 'O3'], |
| 44 | + (3, 3): [18, '(16O)(18O)(16O)', 0.00199097, 49.988991, 'O3'], |
| 45 | + (3, 4): [19, '(16O)(16O)(17O)', 0.00074, 48.98896, 'O3'], |
| 46 | + (3, 5): [20, '(16O)(17O)(16O)', 0.00037, 48.98896, 'O3'], |
| 47 | + (4, 1): [21, '(14N)2(16O)', 0.990333, 44.001062, 'N2O'], |
| 48 | + (4, 2): [22, '(14N)(15N)(16O)', 0.0036409, 44.998096, 'N2O'], |
| 49 | + (4, 3): [23, '(15N)(14N)(16O)', 0.0036409, 44.998096, 'N2O'], |
| 50 | + (4, 4): [24, '(14N)2(18O)', 0.00198582, 46.005308, 'N2O'], |
| 51 | + (4, 5): [25, '(14N)2(17O)', 0.000369, 45.005278, 'N2O'], |
| 52 | + (5, 1): [26, '(12C)(16O)', 0.98654, 27.994915, 'CO'], |
| 53 | + (5, 2): [27, '(13C)(16O)', 0.01108, 28.99827, 'CO'], |
| 54 | + (5, 3): [28, '(12C)(18O)', 0.0019782, 29.999161, 'CO'], |
| 55 | + (5, 4): [29, '(12C)(17O)', 0.000368, 28.99913, 'CO'], |
| 56 | + (5, 5): [30, '(13C)(18O)', 0.00002222, 31.002516, 'CO'], |
| 57 | + (5, 6): [31, '(13C)(17O)', 0.00000413, 30.002485, 'CO'], |
| 58 | + (6, 1): [32, '(12C)H4', 0.98827, 16.0313, 'CH4'], |
| 59 | + (6, 2): [33, '(13C)H4', 0.0111, 17.034655, 'CH4'], |
| 60 | + (6, 3): [34, '(12C)H3D', 0.00061575, 17.037475, 'CH4'], |
| 61 | + (6, 4): [35, '(13C)H3D', 0.0000049203, 18.04083, 'CH4'], |
| 62 | + (7, 1): [36, '(16O)2', 0.995262, 31.98983, 'O2'], |
| 63 | + (7, 2): [37, '(16O)(18O)', 0.00399141, 33.994076, 'O2'], |
| 64 | + (7, 3): [38, '(16O)(17O)', 0.000742, 32.994045, 'O2'], |
| 65 | + (8, 1): [39, '(14N)(16O)', 0.993974, 29.997989, 'NO'], |
| 66 | + (8, 2): [40, '(15N)(16O)', 0.0036543, 30.995023, 'NO'], |
| 67 | + (8, 3): [41, '(14N)(18O)', 0.00199312, 32.002234, 'NO'], |
| 68 | + (9, 1): [42, '(32S)(16O)2', 0.94568, 63.961901, 'SO2'], |
| 69 | + (9, 2): [43, '(34S)(16O)2', 0.04195, 65.957695, 'SO2'], |
| 70 | + (10, 1): [44, '(14N)(16O)2', 0.991616, 45.992904, 'NO2'], |
| 71 | + (11, 1): [45, '(14N)H3', 0.9958715, 17.026549, 'NH3'], |
| 72 | + (11, 2): [46, '(15N)H3', 0.0036613, 18.023583, 'NH3'], |
| 73 | + (12, 1): [47, 'H(14N)(16O)3', 0.98911, 62.995644, 'HNO3'], |
| 74 | + (12, 2): [117, 'H(15N)(16O)3', 0.003636, 63.99268, 'HNO3'], |
| 75 | + (13, 1): [48, '(16O)H', 0.997473, 17.00274, 'OH'], |
| 76 | + (13, 2): [49, '(18O)H', 0.00200014, 19.006986, 'OH'], |
| 77 | + (13, 3): [50, '(16O)D', 0.00015537, 18.008915, 'OH'], |
| 78 | + (14, 1): [51, 'H(19F)', 0.99984425, 20.006229, 'HF'], |
| 79 | + (14, 2): [110, 'D(19F)', 0.000115, 21.0125049978, 'HF'], |
| 80 | + (15, 1): [52, 'H(35Cl)', 0.757587, 35.976678, 'HCl'], |
| 81 | + (15, 2): [53, 'H(37Cl)', 0.242257, 37.973729, 'HCl'], |
| 82 | + (15, 3): [107, 'D(35Cl)', 0.000118005, 36.9829544578, 'HCl'], |
| 83 | + (15, 4): [108, 'D(37Cl)', 0.000037735, 38.9800043678, 'HCl'], |
| 84 | + (16, 1): [54, 'H(79Br)', 0.50678, 79.92616, 'HBr'], |
| 85 | + (16, 2): [55, 'H(81Br)', 0.49306, 81.924115, 'HBr'], |
| 86 | + (16, 3): [111, 'D(79Br)', 0.0000582935, 80.9324388778, 'HBr'], |
| 87 | + (16, 4): [112, 'D(81Br)', 0.0000567065, 82.9303923778, 'HBr'], |
| 88 | + (17, 1): [56, 'H(127I)', 0.99984425, 127.912297, 'HI'], |
| 89 | + (17, 2): [113, 'D(127I)', 0.000115, 128.918574778, 'HI'], |
| 90 | + (18, 1): [57, '(35Cl)(16O)', 0.75591, 50.963768, 'ClO'], |
| 91 | + (18, 2): [58, '(37Cl)(16O)', 0.24172, 52.960819, 'ClO'], |
| 92 | + (19, 1): [59, '(16O)(12C)(32S)', 0.93739, 59.966986, 'OCS'], |
| 93 | + (19, 2): [60, '(16O)(12C)(34S)', 0.04158, 61.96278, 'OCS'], |
| 94 | + (19, 3): [61, '(16O)(13C)(32S)', 0.01053, 60.970341, 'OCS'], |
| 95 | + (19, 4): [62, '(16O)(12C)(33S)', 0.01053, 60.966371, 'OCS'], |
| 96 | + (19, 5): [63, '(18O)(12C)(32S)', 0.00188, 61.971231, 'OCS'], |
| 97 | + (20, 1): [64, 'H2(12C)(16O)', 0.98624, 30.010565, 'H2CO'], |
| 98 | + (20, 2): [65, 'H2(13C)(16O)', 0.01108, 31.01392, 'H2CO'], |
| 99 | + (20, 3): [66, 'H2(12C)(18O)', 0.0019776, 32.014811, 'H2CO'], |
| 100 | + (21, 1): [67, 'H(16O)(35Cl)', 0.75579, 51.971593, 'HOCl'], |
| 101 | + (21, 2): [68, 'H(16O)(37Cl)', 0.24168, 53.968644, 'HOCl'], |
| 102 | + (22, 1): [69, '(14N)2', 0.9926874, 28.006147, 'N2'], |
| 103 | + (22, 2): [118, '(14N)(15N)', 0.0072535, 29.997989, 'N2'], |
| 104 | + (23, 1): [70, 'H(12C)(14N)', 0.98511, 27.010899, 'HCN'], |
| 105 | + (23, 2): [71, 'H(13C)(14N)', 0.01107, 28.014254, 'HCN'], |
| 106 | + (23, 3): [72, 'H(12C)(15N)', 0.0036217, 28.007933, 'HCN'], |
| 107 | + (24, 1): [73, '(12C)H3(35Cl)', 0.74894, 49.992328, 'CH3Cl'], |
| 108 | + (24, 2): [74, '(12C)H3(37Cl)', 0.23949, 51.989379, 'CH3Cl'], |
| 109 | + (25, 1): [75, 'H2(16O)2', 0.994952, 34.00548, 'H2O2'], |
| 110 | + (26, 1): [76, '(12C)2H2', 0.9776, 26.01565, 'C2H2'], |
| 111 | + (26, 2): [77, '(12C)(13C)H2', 0.02197, 27.019005, 'C2H2'], |
| 112 | + (26, 3): [105, '(12C)2HD', 0.00030455, 27.021825, 'C2H2'], |
| 113 | + (27, 1): [78, '(12C)2H6', 0.97699, 30.04695, 'C2H6'], |
| 114 | + (27, 2): [106, '(12C)H3(13C)H3', 0.021952611, 31.050305, 'C2H6'], |
| 115 | + (28, 1): [79, '(31P)H3', 0.99953283, 33.997238, 'PH3'], |
| 116 | + (29, 1): [80, '(12C)(16O)(19F)2', 0.98654, 65.991722, 'COF2'], |
| 117 | + (29, 2): [119, '(13C)(16O)(19F)2', 0.0110834, 66.995083, 'COF2'], |
| 118 | + (31, 1): [81, 'H2(32S)', 0.94988, 33.987721, 'H2S'], |
| 119 | + (31, 2): [82, 'H2(34S)', 0.04214, 35.983515, 'H2S'], |
| 120 | + (31, 3): [83, 'H2(33S)', 0.007498, 34.987105, 'H2S'], |
| 121 | + (32, 1): [84, 'H(12C)(16O)(16O)H', 0.983898, 46.00548, 'HCOOH'], |
| 122 | + (33, 1): [85, 'H(16O)2', 0.995107, 32.997655, 'HO2'], |
| 123 | + (34, 1): [86, '(16O)', 0.997628, 15.994915, 'O'], |
| 124 | + (36, 1): [87, '(14N)(16O)+', 0.993974, 29.997989, 'NOp'], |
| 125 | + (37, 1): [88, 'H(16O)(79Br)', 0.5056, 95.921076, 'HOBr'], |
| 126 | + (37, 2): [89, 'H(16O)(81Br)', 0.4919, 97.919027, 'HOBr'], |
| 127 | + (38, 1): [90, '(12C)2H4', 0.9773, 28.0313, 'C2H4'], |
| 128 | + (38, 2): [91, '(12C)H2(13C)H2', 0.02196, 29.034655, 'C2H4'], |
| 129 | + (39, 1): [92, '(12C)H3(16O)H', 0.98593, 32.026215, 'CH3OH'], |
| 130 | + (40, 1): [93, '(12C)H3(79Br)', 0.5013, 93.941811, 'CH3Br'], |
| 131 | + (40, 2): [94, '(12C)H3(81Br)', 0.48766, 95.939764, 'CH3Br'], |
| 132 | + (41, 1): [95, '(12C)H3(12C)(14N)', 0.97482, 41.026549, 'CH3CN'], |
| 133 | + (42, 1): [96, '(12C)(19F)4', 0.9893, 87.993616, 'CF4'], |
| 134 | + (43, 1): [116, '(12C)4H2', 0.955998, 50.01565, 'C4H2'], |
| 135 | + (44, 1): [109, 'H(12C)3(14N)', 0.9646069, 51.01089903687, 'HC3N'], |
| 136 | + (45, 1): [103, 'H2', 0.999688, 2.01565, 'H2'], |
| 137 | + (45, 2): [115, 'HD', 0.00022997, 3.021825, 'H2'], |
| 138 | + (46, 1): [97, '(12C)(32S)', 0.939624, 43.971036, 'CS'], |
| 139 | + (46, 2): [98, '(12C)(34S)', 0.0416817, 45.966787, 'CS'], |
| 140 | + (46, 3): [99, '(13C)(32S)', 0.0105565, 44.974368, 'CS'], |
| 141 | + (46, 4): [100, '(12C)(33S)', 0.00741668, 44.970399, 'CS'], |
| 142 | + (47, 1): [114, '(32S)(16O)3', 0.9423964, 79.95682, 'SO3'], |
| 143 | + (1001, 1): [101, 'H', None, None, 'H'], |
| 144 | + (1002, 1): [102, 'He', None, None, 'He'], |
| 145 | + (1018, 1): [104, 'Ar', None, None, 'Ar'], |
| 146 | + } |
| 147 | + |
| 148 | + def __init__(self, **kwargs): |
| 149 | + """ |
| 150 | + Initialize a Hitran query class. |
| 151 | + """ |
| 152 | + super(HitranClass, self).__init__() |
| 153 | + |
| 154 | + def _args_to_payload(self, molecule_number=1, isotopologue_number=1, |
| 155 | + min_frequency=None, max_frequency=None): |
| 156 | + """ |
| 157 | + Code to parse input and construct the payload dicttionary. |
| 158 | +
|
| 159 | + Parameters |
| 160 | + ---------- |
| 161 | + molecule_number : int |
| 162 | + HITRAN molecule number |
| 163 | + isotopologue_number : int |
| 164 | + HITRAN isotopologue number |
| 165 | + min_frequency : `astropy.units` |
| 166 | + Minimum frequency (or any spectral() equivalent) |
| 167 | + max_frequency : `astropy.units` |
| 168 | + Maximum frequency (or any spectral() equivalent) |
| 169 | +
|
| 170 | + Returns |
| 171 | + ------- |
| 172 | + payload : dict |
| 173 | + Dictionary of the parameters to send to the SPLAT page |
| 174 | +
|
| 175 | + """ |
| 176 | + |
| 177 | + payload = dict() |
| 178 | + |
| 179 | + iso_id = str(self.ISO[(molecule_number, |
| 180 | + isotopologue_number)][self.ISO_INDEX['id']]) |
| 181 | + # mol_name = self.ISO[(molecule_number, |
| 182 | + # isotopologue_number)][self.ISO_INDEX['mol_name']] |
| 183 | + |
| 184 | + payload['iso_ids_list'] = iso_id |
| 185 | + |
| 186 | + if min_frequency is not None: |
| 187 | + min_frequency = min_frequency.to(u.cm**-1, u.spectral()) |
| 188 | + |
| 189 | + if max_frequency is not None: |
| 190 | + max_frequency = max_frequency.to(u.cm**-1, u.spectral()) |
| 191 | + |
| 192 | + if min_frequency is not None and max_frequency is not None: |
| 193 | + if min_frequency > max_frequency: |
| 194 | + min_frequency, max_frequency = max_frequency, min_frequency |
| 195 | + |
| 196 | + payload['numin'] = min_frequency.value |
| 197 | + payload['numax'] = max_frequency.value |
| 198 | + |
| 199 | + return payload |
| 200 | + |
| 201 | + @prepend_docstr_nosections("\n" + _args_to_payload.__doc__) |
| 202 | + def query_lines_async(self, get_query_payload=False, cache=True, **kwargs): |
| 203 | + """ |
| 204 | + Queries Hitran class for a particular molecule with default arguments |
| 205 | + set. Based on fetch function from hapi.py. |
| 206 | +
|
| 207 | + Returns |
| 208 | + ------- |
| 209 | + response : `requests.Response` |
| 210 | + The response of the HTTP request. |
| 211 | + """ |
| 212 | + |
| 213 | + params = self._args_to_payload(**kwargs) |
| 214 | + |
| 215 | + if get_query_payload: |
| 216 | + return params |
| 217 | + |
| 218 | + response = self._request(method='GET', |
| 219 | + url=self.QUERY_URL, |
| 220 | + params=params, |
| 221 | + timeout=self.TIMEOUT, |
| 222 | + cache=cache) |
| 223 | + |
| 224 | + return response |
| 225 | + |
| 226 | + def _parse_result(self, response, verbose=False): |
| 227 | + """ |
| 228 | + Parse a response into an `~astropy.table.Table` |
| 229 | + """ |
| 230 | + formats = parse_readme(self.FORMATFILE) |
| 231 | + |
| 232 | + dtypes = [entry['dtype'] for entry in formats.values()] |
| 233 | + |
| 234 | + rows = [] |
| 235 | + for line in response.text.split('\n'): |
| 236 | + if line.strip(): |
| 237 | + row = [] |
| 238 | + start = 0 |
| 239 | + for key, entry in formats.items(): |
| 240 | + formatter = entry['formatter'] |
| 241 | + length = entry['length'] |
| 242 | + value = formatter(line[start:start+length]) |
| 243 | + row.append(value) |
| 244 | + start = start + length |
| 245 | + rows.append(row) |
| 246 | + |
| 247 | + result = Table(rows=rows, names=formats.keys(), dtype=dtypes) |
| 248 | + |
| 249 | + return result |
| 250 | + |
| 251 | + |
| 252 | +Hitran = HitranClass() |
0 commit comments