From e7e71ea728c5cbb7c6e54c5572d8113b37247abd Mon Sep 17 00:00:00 2001 From: Parfenov Sergey Date: Sun, 27 Apr 2025 17:51:19 +0500 Subject: [PATCH 1/8] Support CDMS all species option; fix format for CDMS linelist reading; fix CDMS quantum numbers parsing 1) Adding support for CDMS queries with lines of all species 2) Fixing the CMDS lines list parsing Support CDMS all species option; fix format for CDMS linelist reading; fix CDMS quantum numbers parsing Adding test for a new functionality when all species are requested from CDMS --- astroquery/linelists/cdms/core.py | 60 +++++++++++++------ .../linelists/cdms/tests/test_cdms_remote.py | 18 ++++++ 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/astroquery/linelists/cdms/core.py b/astroquery/linelists/cdms/core.py index 95c739b304..9b7e73c060 100644 --- a/astroquery/linelists/cdms/core.py +++ b/astroquery/linelists/cdms/core.py @@ -54,7 +54,8 @@ def query_lines_async(self, min_frequency, max_frequency, *, min_strength : int, optional Minimum strength in catalog units, the default is -500 - molecule : list, string of regex if parse_name_locally=True, optional + molecule : list or string if parse_name_locally=False, + string of regex if parse_name_locally=True, optional Identifiers of the molecules to search for. If this parameter is not provided the search will match any species. Default is 'All'. As a first pass, the molecule will be searched for with a direct @@ -134,18 +135,21 @@ def query_lines_async(self, min_frequency, max_frequency, *, # changes interpretation of query self._last_query_temperature = temperature_for_intensity - if molecule is not None: - if parse_name_locally: - self.lookup_ids = build_lookup() - luts = self.lookup_ids.find(molecule, flags) - if len(luts) == 0: - raise InvalidQueryError('No matching species found. Please ' - 'refine your search or read the Docs ' - 'for pointers on how to search.') - payload['Molecules'] = tuple(f"{val:06d} {key}" - for key, val in luts.items())[0] - else: - payload['Molecules'] = molecule + if molecule == 'All': + payload['Moleculesgrp'] = 'all species' + else: + if molecule is not None: + if parse_name_locally: + self.lookup_ids = build_lookup() + luts = self.lookup_ids.find(molecule, flags) + if len(luts) == 0: + raise InvalidQueryError('No matching species found. Please ' + 'refine your search or read the Docs ' + 'for pointers on how to search.') + payload['Molecules'] = tuple(f"{val:06d} {key}" + for key, val in luts.items())[0] + else: + payload['Molecules'] = molecule if get_query_payload: return payload @@ -180,7 +184,7 @@ def query_lines_async(self, min_frequency, max_frequency, *, # accounts for three formats, e.g.: '058501' or 'H2C2S' or '058501 H2C2S' badlist = (self.MALFORMATTED_MOLECULE_LIST + # noqa [y for x in self.MALFORMATTED_MOLECULE_LIST for y in x.split()]) - if payload['Molecules'] in badlist: + if 'Moleculesgrp' not in payload.keys() and payload['Molecules'] in badlist: raise ValueError(f"Molecule {payload['Molecules']} is known not to comply with standard CDMS format. " f"Try get_molecule({payload['Molecules']}) instead.") @@ -233,13 +237,31 @@ def _parse_result(self, response, *, verbose=False): soup = BeautifulSoup(response.text, 'html.parser') text = soup.find('pre').text + need_to_filter_bad_molecules = False + for bad_molecule in self.MALFORMATTED_MOLECULE_LIST: + if text.find(bad_molecule.split()[1]) > -1: + need_to_filter_bad_molecules = True + break + if need_to_filter_bad_molecules: + text_new = '' + text = text.split('\n') + for line in text: + need_to_include_line = True + for bad_molecule in self.MALFORMATTED_MOLECULE_LIST: + if line.find(bad_molecule.split()[1]) > -1: + need_to_include_line = False + break + if need_to_include_line: + text_new = text_new + '\n' + line + text = text_new + starts = {'FREQ': 0, 'ERR': 14, 'LGINT': 25, 'DR': 36, 'ELO': 38, 'GUP': 47, - 'MOLWT': 51, + 'MOLWT': 50, 'TAG': 54, 'QNFMT': 58, 'Ju': 61, @@ -486,13 +508,13 @@ def parse_letternumber(st): From the CDMS docs: "Exactly two characters are available for each quantum number. Therefore, half integer quanta are rounded up ! In addition, capital letters are used to - indicate quantum numbers larger than 99. E. g. A0 is 100, Z9 is 359. Small - types are used to signal corresponding negative quantum numbers." + indicate quantum numbers larger than 99. E. g. A0 is 100, Z9 is 359. Lower case characters + are used similarly to signal negative quantum numbers smaller than –9. e. g., a0 is –10, b0 is –20, etc." """ asc = string.ascii_lowercase ASC = string.ascii_uppercase - newst = ''.join(['-' + str(asc.index(x)+10) if x in asc else - str(ASC.index(x)+10) if x in ASC else + newst = ''.join(['-' + str((asc.index(x)+1)) if x in asc else + str((ASC.index(x)+10)) if x in ASC else x for x in st]) return int(newst) diff --git a/astroquery/linelists/cdms/tests/test_cdms_remote.py b/astroquery/linelists/cdms/tests/test_cdms_remote.py index 5c2a2059fb..686e22848f 100644 --- a/astroquery/linelists/cdms/tests/test_cdms_remote.py +++ b/astroquery/linelists/cdms/tests/test_cdms_remote.py @@ -134,3 +134,21 @@ def test_regression_allcats(self, row): tag = f"{row['tag']:06d}" result = CDMS.get_molecule(tag) assert len(result) >= 1 + +@pytest.mark.remote_data +def test_remote_all_species(): + tbl = CDMS.query_lines(min_frequency=100.3 * u.GHz, + max_frequency=100.5 * u.GHz, + min_strength=-5) + assert isinstance(tbl, Table) + + AlS_is_in_table = False + Propanediol_is_in_table = False + for row in tbl: + if row['name'].strip() == 'AlS': + AlS_is_in_table = True + if row['name'].strip() == "aG'g-1,2-Propanediol": + Propanediol_is_in_table = True + + assert AlS_is_in_table + assert Propanediol_is_in_table From de4038bc1bb2b46e4027374b3ca4878754aa6dc9 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Sun, 27 Apr 2025 17:20:29 -0400 Subject: [PATCH 2/8] fix parse_letternumber test and rearrange and refactor new test --- astroquery/linelists/cdms/tests/test_cdms.py | 3 +- .../linelists/cdms/tests/test_cdms_remote.py | 34 ++++++++----------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/astroquery/linelists/cdms/tests/test_cdms.py b/astroquery/linelists/cdms/tests/test_cdms.py index 597311d715..4a030bee99 100644 --- a/astroquery/linelists/cdms/tests/test_cdms.py +++ b/astroquery/linelists/cdms/tests/test_cdms.py @@ -99,7 +99,8 @@ def test_parseletternumber(): assert parse_letternumber("Z9") == 359 # inferred? - assert parse_letternumber("z9") == -359 + assert parse_letternumber("a0") == -10 + assert parse_letternumber("b0") == -20 assert parse_letternumber("ZZ") == 3535 diff --git a/astroquery/linelists/cdms/tests/test_cdms_remote.py b/astroquery/linelists/cdms/tests/test_cdms_remote.py index 686e22848f..bd2c1cf505 100644 --- a/astroquery/linelists/cdms/tests/test_cdms_remote.py +++ b/astroquery/linelists/cdms/tests/test_cdms_remote.py @@ -121,6 +121,20 @@ def test_retrieve_species_table(): assert 'float' in species_table['lg(Q(1000))'].dtype.name +@pytest.mark.remote_data +def test_remote_all_species(): + tbl = CDMS.query_lines(min_frequency=100.3 * u.GHz, + max_frequency=100.5 * u.GHz, + min_strength=-5) + assert isinstance(tbl, Table) + + AlS_is_in_table = np.char.find(tbl['name'], 'AlS') != -1 + Propanediol_is_in_table = np.char.find(tbl['name'], "aG'g-1,2-Propanediol") != -1 + + assert AlS_is_in_table + assert Propanediol_is_in_table + + @pytest.mark.bigdata @pytest.mark.remote_data class TestRegressionAllCats: @@ -133,22 +147,4 @@ def test_regression_allcats(self, row): """ tag = f"{row['tag']:06d}" result = CDMS.get_molecule(tag) - assert len(result) >= 1 - -@pytest.mark.remote_data -def test_remote_all_species(): - tbl = CDMS.query_lines(min_frequency=100.3 * u.GHz, - max_frequency=100.5 * u.GHz, - min_strength=-5) - assert isinstance(tbl, Table) - - AlS_is_in_table = False - Propanediol_is_in_table = False - for row in tbl: - if row['name'].strip() == 'AlS': - AlS_is_in_table = True - if row['name'].strip() == "aG'g-1,2-Propanediol": - Propanediol_is_in_table = True - - assert AlS_is_in_table - assert Propanediol_is_in_table + assert len(result) >= 1 \ No newline at end of file From 34bd35b060927f6b9dd152067f9e21fd98149f2e Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Sun, 27 Apr 2025 18:25:57 -0400 Subject: [PATCH 3/8] expand test coverage and resolve some problems discovered as a result --- astroquery/linelists/cdms/core.py | 25 +++++++++++++------ astroquery/linelists/cdms/tests/test_cdms.py | 3 +++ .../linelists/cdms/tests/test_cdms_remote.py | 18 +++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/astroquery/linelists/cdms/core.py b/astroquery/linelists/cdms/core.py index 9b7e73c060..e592c4ac32 100644 --- a/astroquery/linelists/cdms/core.py +++ b/astroquery/linelists/cdms/core.py @@ -12,6 +12,7 @@ # import configurable items declared in __init__.py from astroquery.linelists.cdms import conf from astroquery.exceptions import InvalidQueryError, EmptyResponseError +from astroquery import log import re import string @@ -409,7 +410,7 @@ def tryfloat(x): return result - def get_molecule(self, molecule_id, *, cache=True): + def get_molecule(self, molecule_id, *, cache=True, return_response=False): """ Retrieve the whole molecule table for a given molecule id """ @@ -418,6 +419,8 @@ def get_molecule(self, molecule_id, *, cache=True): url = f'{self.CLASSIC_URL}/entries/c{molecule_id}.cat' response = self._request(method='GET', url=url, timeout=self.TIMEOUT, cache=cache) + if return_response: + return response result = self._parse_cat(response) species_table = self.get_species_table() @@ -449,7 +452,7 @@ def _parse_cat(self, response, *, verbose=False): 'GUP': 42, 'TAG': 44, 'QNFMT': 52, - 'Q1': 56, + 'Q1': 55, 'Q2': 58, 'Q3': 60, 'Q4': 62, @@ -472,7 +475,7 @@ def _parse_cat(self, response, *, verbose=False): format='fixed_width', fast_reader=False) # int truncates - which is what we want - result['MOLWT'] = [int(x/1e4) for x in result['TAG']] + result['MOLWT'] = [int(x/1e3) for x in result['TAG']] result['FREQ'].unit = u.MHz result['ERR'].unit = u.MHz @@ -482,15 +485,18 @@ def _parse_cat(self, response, *, verbose=False): result['MOLWT'].unit = u.Da fix_keys = ['GUP'] - for suf in '': - for qn in (f'Q{ii}' for ii in range(1, 15)): - qnind = qn+suf - fix_keys.append(qnind) + for qn in (f'Q{ii}' for ii in range(1, 15)): + fix_keys.append(qn) + log.debug(f"fix_keys: {fix_keys} should include Q1, Q2, ..., Q14 and GUP") for key in fix_keys: if not np.issubdtype(result[key].dtype, np.integer): intcol = np.array(list(map(parse_letternumber, result[key])), dtype=int) + if any(intcol == -999999): + intcol = np.ma.masked_where(intcol == -999999, intcol) result[key] = intcol + if not np.issubdtype(result[key].dtype, np.integer): + raise ValueError(f"Failed to parse {key} as integer") result['LGINT'].unit = u.nm**2 * u.MHz result['ELO'].unit = u.cm**(-1) @@ -508,9 +514,12 @@ def parse_letternumber(st): From the CDMS docs: "Exactly two characters are available for each quantum number. Therefore, half integer quanta are rounded up ! In addition, capital letters are used to - indicate quantum numbers larger than 99. E. g. A0 is 100, Z9 is 359. Lower case characters + indicate quantum numbers larger than 99. E. g. A0 is 100, Z9 is 359. Lower case characters are used similarly to signal negative quantum numbers smaller than –9. e. g., a0 is –10, b0 is –20, etc." """ + if np.ma.is_masked(st): + return -999999 + asc = string.ascii_lowercase ASC = string.ascii_uppercase newst = ''.join(['-' + str((asc.index(x)+1)) if x in asc else diff --git a/astroquery/linelists/cdms/tests/test_cdms.py b/astroquery/linelists/cdms/tests/test_cdms.py index 4a030bee99..0b8059105f 100644 --- a/astroquery/linelists/cdms/tests/test_cdms.py +++ b/astroquery/linelists/cdms/tests/test_cdms.py @@ -83,6 +83,7 @@ def test_query(patch_post): assert tbl['LGINT'][0] == -7.1425 assert tbl['GUP'][0] == 3 assert tbl['GUP'][7] == 17 + assert tbl['MOLWT'][0] == 28 def test_parseletternumber(): @@ -103,6 +104,8 @@ def test_parseletternumber(): assert parse_letternumber("b0") == -20 assert parse_letternumber("ZZ") == 3535 + assert parse_letternumber(np.ma.masked) == -999999 + def test_hc7s(patch_post): """ diff --git a/astroquery/linelists/cdms/tests/test_cdms_remote.py b/astroquery/linelists/cdms/tests/test_cdms_remote.py index bd2c1cf505..c778b0563a 100644 --- a/astroquery/linelists/cdms/tests/test_cdms_remote.py +++ b/astroquery/linelists/cdms/tests/test_cdms_remote.py @@ -38,6 +38,24 @@ def test_remote_300K(): assert tbl['FREQ'][0] == 505366.7875 assert tbl['ERR'][0] == 49.13 assert tbl['LGINT'][0] == -4.2182 + assert tbl['MOLWT'][0] == 18 + + +@pytest.mark.remote_data +def test_propanediol(): + tbl1 = CDMS.get_molecule('076513') + assert 'int' in tbl1['Q2'].dtype.name + + tbl = CDMS.query_lines(min_frequency=100.3 * u.GHz, + max_frequency=100.5 * u.GHz, + molecule='076513', + ) + assert isinstance(tbl, Table) + assert len(tbl) >= 1 + assert 'aG\'g-1,2-Propanediol' in tbl['name'] + # check that the parser worked - this will be string or obj otherwise + assert 'int' in tbl['Ku'].dtype.name + assert tbl['MOLWT'][0] == 76 @pytest.mark.remote_data From dbba11aa01f67e902d3642c6aaee92b20ea6a873 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Sun, 27 Apr 2025 18:30:59 -0400 Subject: [PATCH 4/8] propagate column change down trivial formatting fix my refactor; it was incorrect oops, fix to last one (yes, this needs to be squashed; pushing fast to skip tests... and spam my inbox...) --- astroquery/linelists/cdms/core.py | 28 +++++++++---------- .../linelists/cdms/tests/test_cdms_remote.py | 19 +++++++++---- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/astroquery/linelists/cdms/core.py b/astroquery/linelists/cdms/core.py index e592c4ac32..a2c714c4ef 100644 --- a/astroquery/linelists/cdms/core.py +++ b/astroquery/linelists/cdms/core.py @@ -148,7 +148,7 @@ def query_lines_async(self, min_frequency, max_frequency, *, 'refine your search or read the Docs ' 'for pointers on how to search.') payload['Molecules'] = tuple(f"{val:06d} {key}" - for key, val in luts.items())[0] + for key, val in luts.items())[0] else: payload['Molecules'] = molecule @@ -453,19 +453,19 @@ def _parse_cat(self, response, *, verbose=False): 'TAG': 44, 'QNFMT': 52, 'Q1': 55, - 'Q2': 58, - 'Q3': 60, - 'Q4': 62, - 'Q5': 64, - 'Q6': 66, - 'Q7': 68, - 'Q8': 70, - 'Q9': 72, - 'Q10': 74, - 'Q11': 76, - 'Q12': 78, - 'Q13': 80, - 'Q14': 82, + 'Q2': 57, + 'Q3': 59, + 'Q4': 61, + 'Q5': 63, + 'Q6': 65, + 'Q7': 67, + 'Q8': 69, + 'Q9': 71, + 'Q10': 73, + 'Q11': 75, + 'Q12': 77, + 'Q13': 79, + 'Q14': 81, } result = ascii.read(text, header_start=None, data_start=0, diff --git a/astroquery/linelists/cdms/tests/test_cdms_remote.py b/astroquery/linelists/cdms/tests/test_cdms_remote.py index c778b0563a..4149145ca1 100644 --- a/astroquery/linelists/cdms/tests/test_cdms_remote.py +++ b/astroquery/linelists/cdms/tests/test_cdms_remote.py @@ -41,6 +41,16 @@ def test_remote_300K(): assert tbl['MOLWT'][0] == 18 +@pytest.mark.remote_data +def test_co_basics(): + tbl = CDMS.get_molecule('028503') + assert tbl['Q1'][0] == 1 + assert tbl['Q7'][0] == 0 + assert tbl['Q1'][10] == 11 + assert tbl['Q7'][10] == 10 + assert tbl['MOLWT'][0] == 28 + + @pytest.mark.remote_data def test_propanediol(): tbl1 = CDMS.get_molecule('076513') @@ -48,8 +58,7 @@ def test_propanediol(): tbl = CDMS.query_lines(min_frequency=100.3 * u.GHz, max_frequency=100.5 * u.GHz, - molecule='076513', - ) + molecule='076513') assert isinstance(tbl, Table) assert len(tbl) >= 1 assert 'aG\'g-1,2-Propanediol' in tbl['name'] @@ -146,8 +155,8 @@ def test_remote_all_species(): min_strength=-5) assert isinstance(tbl, Table) - AlS_is_in_table = np.char.find(tbl['name'], 'AlS') != -1 - Propanediol_is_in_table = np.char.find(tbl['name'], "aG'g-1,2-Propanediol") != -1 + AlS_is_in_table = (tbl['name'] == 'AlS').sum() > 0 + Propanediol_is_in_table = (tbl['name'] == "aG'g-1,2-Propanediol").sum() > 0 assert AlS_is_in_table assert Propanediol_is_in_table @@ -165,4 +174,4 @@ def test_regression_allcats(self, row): """ tag = f"{row['tag']:06d}" result = CDMS.get_molecule(tag) - assert len(result) >= 1 \ No newline at end of file + assert len(result) >= 1 From ebda867a164b4cae3d52bb6e664676e301141190 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Mon, 28 Apr 2025 11:32:35 -0400 Subject: [PATCH 5/8] add ch3cn test and shift QNFMT by one --- astroquery/linelists/cdms/core.py | 2 +- astroquery/linelists/cdms/tests/test_cdms_remote.py | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/astroquery/linelists/cdms/core.py b/astroquery/linelists/cdms/core.py index a2c714c4ef..9d99130563 100644 --- a/astroquery/linelists/cdms/core.py +++ b/astroquery/linelists/cdms/core.py @@ -451,7 +451,7 @@ def _parse_cat(self, response, *, verbose=False): 'ELO': 32, 'GUP': 42, 'TAG': 44, - 'QNFMT': 52, + 'QNFMT': 51, 'Q1': 55, 'Q2': 57, 'Q3': 59, diff --git a/astroquery/linelists/cdms/tests/test_cdms_remote.py b/astroquery/linelists/cdms/tests/test_cdms_remote.py index 4149145ca1..29788f30a8 100644 --- a/astroquery/linelists/cdms/tests/test_cdms_remote.py +++ b/astroquery/linelists/cdms/tests/test_cdms_remote.py @@ -39,7 +39,7 @@ def test_remote_300K(): assert tbl['ERR'][0] == 49.13 assert tbl['LGINT'][0] == -4.2182 assert tbl['MOLWT'][0] == 18 - + assert tbl['TAG'][0] == 18505 @pytest.mark.remote_data def test_co_basics(): @@ -49,6 +49,15 @@ def test_co_basics(): assert tbl['Q1'][10] == 11 assert tbl['Q7'][10] == 10 assert tbl['MOLWT'][0] == 28 + assert tbl['TAG'][0] == 28503 + + +@pytest.mark.remote_data +def test_ch3cn_negqn(): + tbl = CDMS.get_molecule('041501') + fourtominusthree = tbl[(tbl['Q1'] == 4) & (tbl['Q2'] == -3)] + assert len(fourtominusthree) >= 1 + assert tbl['TAG'][0] == 41501 @pytest.mark.remote_data @@ -65,6 +74,7 @@ def test_propanediol(): # check that the parser worked - this will be string or obj otherwise assert 'int' in tbl['Ku'].dtype.name assert tbl['MOLWT'][0] == 76 + assert tbl['TAG'][0] == 76513 @pytest.mark.remote_data From 361e73b68635a008be3c0c6b7c64bdd00bee4d38 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Mon, 28 Apr 2025 11:39:01 -0400 Subject: [PATCH 6/8] cleanup molwt/tag parsing shift tag back one spot. Fix tests to accommodate more complete "tag" name add the b1 = -21 test whitespace --- astroquery/linelists/cdms/core.py | 6 +++--- .../linelists/cdms/tests/test_cdms_remote.py | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/astroquery/linelists/cdms/core.py b/astroquery/linelists/cdms/core.py index 9d99130563..8fe26164b5 100644 --- a/astroquery/linelists/cdms/core.py +++ b/astroquery/linelists/cdms/core.py @@ -262,9 +262,8 @@ def _parse_result(self, response, *, verbose=False): 'DR': 36, 'ELO': 38, 'GUP': 47, - 'MOLWT': 50, - 'TAG': 54, - 'QNFMT': 58, + 'TAG': 50, + 'QNFMT': 57, 'Ju': 61, 'Ku': 63, 'vu': 65, @@ -288,6 +287,7 @@ def _parse_result(self, response, *, verbose=False): result['FREQ'].unit = u.MHz result['ERR'].unit = u.MHz + result['MOLWT'] = [int(x/1e3) for x in result['TAG']] result['Lab'] = result['MOLWT'] < 0 result['MOLWT'] = np.abs(result['MOLWT']) result['MOLWT'].unit = u.Da diff --git a/astroquery/linelists/cdms/tests/test_cdms_remote.py b/astroquery/linelists/cdms/tests/test_cdms_remote.py index 29788f30a8..80576e9102 100644 --- a/astroquery/linelists/cdms/tests/test_cdms_remote.py +++ b/astroquery/linelists/cdms/tests/test_cdms_remote.py @@ -41,6 +41,7 @@ def test_remote_300K(): assert tbl['MOLWT'][0] == 18 assert tbl['TAG'][0] == 18505 + @pytest.mark.remote_data def test_co_basics(): tbl = CDMS.get_molecule('028503') @@ -49,7 +50,7 @@ def test_co_basics(): assert tbl['Q1'][10] == 11 assert tbl['Q7'][10] == 10 assert tbl['MOLWT'][0] == 28 - assert tbl['TAG'][0] == 28503 + assert tbl['TAG'][0] == -28503 @pytest.mark.remote_data @@ -57,7 +58,12 @@ def test_ch3cn_negqn(): tbl = CDMS.get_molecule('041501') fourtominusthree = tbl[(tbl['Q1'] == 4) & (tbl['Q2'] == -3)] assert len(fourtominusthree) >= 1 - assert tbl['TAG'][0] == 41501 + + # check specifically for -21, which is encoded as `b1` + twentytwominustwentyone = tbl[(tbl['Q1'] == 22) & (tbl['Q2'] == -21)] + assert len(twentytwominustwentyone) >= 1 + + assert tbl['TAG'][0] == -41501 @pytest.mark.remote_data @@ -103,16 +109,16 @@ def test_molecule_with_parens(): MC = np.ma.core.MaskedConstant() - for col, val in zip(tbl[0].colnames, (232588.7246, 0.2828, -4.1005, 3, 293.8540, 445, 66, - 506, 303, 44, 14, 30, MC, MC, MC, 45, 13, 33, MC, MC, MC, 'H2C(CN)2', False)): + for col, val in zip(tbl[0].colnames, (232588.7246, 0.2828, -4.1005, 3, 293.8540, 445, 66506, + 303, 44, 14, 30, MC, MC, MC, 45, 13, 33, MC, MC, MC, 'H2C(CN)2', 66, False)): if val is MC: assert tbl[0][col].mask else: assert tbl[0][col] == val # this test row includes degeneracy = 1225, which covers one of the weird letter-is-number parser cases - for col, val in zip(tbl[16].colnames, (233373.369, 10.26, -4.8704, 3, 1229.0674, 1125, 66, - 506, 303, 112, 10, 102, MC, MC, MC, 112, 9, 103, MC, MC, MC, 'H2C(CN)2', False),): + for col, val in zip(tbl[16].colnames, (233373.369, 10.26, -4.8704, 3, 1229.0674, 1125, 66506, + 303, 112, 10, 102, MC, MC, MC, 112, 9, 103, MC, MC, MC, 'H2C(CN)2', 66, False),): if val is MC: assert tbl[16][col].mask else: From a912cf2830b797f12dc2a47eb64ca31e99e3d24d Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Wed, 21 May 2025 18:33:30 -0400 Subject: [PATCH 7/8] fix ch3cn test; it had decayed into ch3ccd which has different QNs --- astroquery/linelists/cdms/tests/test_cdms_remote.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/astroquery/linelists/cdms/tests/test_cdms_remote.py b/astroquery/linelists/cdms/tests/test_cdms_remote.py index 80576e9102..96b5ee96ec 100644 --- a/astroquery/linelists/cdms/tests/test_cdms_remote.py +++ b/astroquery/linelists/cdms/tests/test_cdms_remote.py @@ -55,7 +55,9 @@ def test_co_basics(): @pytest.mark.remote_data def test_ch3cn_negqn(): - tbl = CDMS.get_molecule('041501') + # 041505 = CH3CN on 2025-05-21 + tbl = CDMS.get_molecule('041505') + assert tbl.meta['molecule'] == 'CH3CN, v=0' fourtominusthree = tbl[(tbl['Q1'] == 4) & (tbl['Q2'] == -3)] assert len(fourtominusthree) >= 1 @@ -63,7 +65,11 @@ def test_ch3cn_negqn(): twentytwominustwentyone = tbl[(tbl['Q1'] == 22) & (tbl['Q2'] == -21)] assert len(twentytwominustwentyone) >= 1 - assert tbl['TAG'][0] == -41501 + assert tbl['TAG'][0] == 41505 + + twentythreeminustwentyone = tbl[(tbl['Q1'] == 23) & (tbl['Q2'] == -21)] + assert len(twentythreeminustwentyone) >= 1 + assert twentythreeminustwentyone['TAG'][0] == -41505 @pytest.mark.remote_data From c94ad8d445be3bede3af86b20f44e7dd9e1bbf14 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Wed, 21 May 2025 19:19:09 -0400 Subject: [PATCH 8/8] add changelog --- CHANGES.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index b0d7964ee2..67d3b7ed77 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -27,6 +27,7 @@ linelists.cdms ^^^^^^^^^^^^^^ - Add a keyword to control writing of new species cache files. This is needed to prevent tests from overwriting those files. [#3297] +- Add more complete support for CDMS quantum number and other value parsing. [#3302] heasarc ^^^^^^^ @@ -76,10 +77,10 @@ mast - Fix bug in ``utils.remove_duplicate_products`` that does not retain the order of the products in an input table. [#3314] -- Added ``return_uri_map`` parameter to ``Observations.get_cloud_uris`` to return a mapping of the input data product URIs +- Added ``return_uri_map`` parameter to ``Observations.get_cloud_uris`` to return a mapping of the input data product URIs to the returned cloud URIs. [#3314] -- Added ``verbose`` parameter to ``Observations.get_cloud_uris`` to control whether warnings are logged when a product cannot +- Added ``verbose`` parameter to ``Observations.get_cloud_uris`` to control whether warnings are logged when a product cannot be found in the cloud. [#3314]