def test_merging_hsc(self): files = ("fitsheader-hsc-HSCA04090107.yaml", "fitsheader-hsc.yaml") headers = [read_test_file(f, dir=self.datadir) for f in files] merged = merge_headers(headers, mode="first", sort=False) # The MJD-STR should come from the first file self.assertAlmostEqual(merged["MJD-STR"], 57305.34729859) # If we sort then MJD-STR should come from the oldest file merged = merge_headers(headers, mode="first", sort=True) self.assertAlmostEqual(merged["MJD-STR"], 56598.26106374757) # Drop headers that differ, MJD-STR should not appear merged = merge_headers(headers, mode="drop", sort=True) self.assertNotIn("MJD-STR", merged) # Drop but retain first MJD-STR without sorting merged = merge_headers(headers, mode="drop", sort=False, first=["MJD-STR", "UT-STR"]) self.assertAlmostEqual(merged["MJD-STR"], 57305.34729859) self.assertEqual(merged["UT-STR"], "08:20:06.598") # Drop but retain first MJD-STR merged = merge_headers(headers, mode="drop", sort=True, first=["MJD-STR", "UT-STR"]) self.assertAlmostEqual(merged["MJD-STR"], 56598.26106374757) self.assertEqual(merged["UT-STR"], "06:15:55.908")
def test_checker(self): filename = "latiss-future.yaml" from astro_metadata_translator.tests import read_test_file from astro_metadata_translator import ObservationInfo header = read_test_file(filename, self.datadir) obsInfo = ObservationInfo(header, pedantic=True) self.assertTrue(obsInfo)
def test_megaprime_stripping(self): header = read_test_file("fitsheader-megaprime.yaml", dir=self.datadir) v1 = ObservationInfo(header) # Check that headers have been removed new_hdr = v1.stripped_header() self.assertNotIn("INSTRUME", new_hdr) self.assertNotIn("TELESCOP", new_hdr) self.assertIn("CCD", new_hdr)
def test_translator_fix_header(self): """Check that translator classes can fix headers.""" # Read in a known header header = read_test_file("fitsheader-decam-0160496.yaml", dir=os.path.join(TESTDIR, "data")) self.assertEqual(header["DTSITE"], "ct") fixed = fix_header(header, translator_class=NotDecamTranslator) self.assertTrue(fixed) self.assertEqual(header["DTSITE"], "hi") header["DTSITE"] = "reset" with self.assertLogs("astro_metadata_translator", level="FATAL"): fixed = fix_header(header, translator_class=AlsoNotDecamTranslator) self.assertFalse(fixed) self.assertEqual(header["DTSITE"], "reset")
def test_fix_header(self): from astro_metadata_translator import fix_header from astro_metadata_translator.tests import read_test_file # Test that header fix up is working # Not all headers are used in metadata translation test_data = ( ("latiss-AT_O_20210212_000006.yaml", dict(RASTART=260.024385071917)), ("latiss-AT_O_20210210_000011.yaml", dict(RASTART=355.41750341182313)), ) for filename, expected in test_data: with self.subTest(f"Testing {filename}"): header = read_test_file(filename, dir=self.datadir) modified = fix_header(header) self.assertTrue(modified) for k, v in expected.items(): self.assertEqual(header[k], v, f"Testing {k} in {filename}")
def test_basic_fix_header(self): """Test that a header can be fixed if we specify a local path. """ header = read_test_file("fitsheader-decam-0160496.yaml", dir=os.path.join(TESTDIR, "data")) self.assertEqual(header["DETECTOR"], "S3-111_107419-8-3") # First fix header but using no search path (should work as no-op) fixed = fix_header(header) self.assertFalse(fixed) # Now using the test corrections directory fixed = fix_header(header, search_path=os.path.join(TESTDIR, "data", "corrections")) self.assertTrue(fixed) self.assertEqual(header["DETECTOR"], "NEW-ID") # Test that fix_header of unknown header is allowed header = {"SOMETHING": "UNKNOWN"} fixed = fix_header(header) self.assertFalse(fixed)
def read_file(file, hdrnum, print_trace, outstream=sys.stdout, errstream=sys.stderr, output_mode="verbose", write_heading=False): """Read the specified file and process it. Parameters ---------- file : `str` The file from which the header is to be read. hdrnum : `int` The HDU number to read. The primary header is always read and merged with the header from this HDU. print_trace : `bool` If there is an error reading the file and this parameter is `True`, a full traceback of the exception will be reported. If `False` prints a one line summary of the error condition. outstream : `io.StringIO`, optional Output stream to use for standard messages. Defaults to `sys.stdout`. errstream : `io.StringIO`, optional Stream to send messages that would normally be sent to standard error. Defaults to `sys.stderr`. output_mode : `str`, optional Output mode to use. Must be one of "verbose", "none", "table", "yaml", or "fixed". "yaml" and "fixed" can be modified with a "native" suffix to indicate that the output should be a representation of the native object type representing the header (which can be PropertyList or an Astropy header). Without this modify headers will be dumped as simple `dict` form. "auto" is not allowed by this point. write_heading: `bool`, optional If `True` and in table mode, write a table heading out before writing the content. Returns ------- success : `bool` `True` if the file was handled successfully, `False` if the file could not be processed. """ if output_mode not in OUTPUT_MODES: raise ValueError(f"Output mode of '{output_mode}' is not understood.") if output_mode == "auto": raise ValueError("Output mode can not be 'auto' here.") # This gets in the way in tabular mode if output_mode != "table": print(f"Analyzing {file}...", file=errstream) try: if file.endswith(".yaml"): md = read_test_file(file, ) if hdrnum != 0: # YAML can't have HDUs hdrnum = 0 else: md = read_metadata(file, 0) if md is None: print(f"Unable to open file {file}", file=errstream) return False if hdrnum != 0: mdn = read_metadata(file, int(hdrnum)) # Astropy does not allow append mode since it does not # convert lists to multiple cards. Overwrite for now if mdn is not None: md = merge_headers([md, mdn], mode="overwrite") else: print(f"HDU {hdrnum} was not found. Ignoring request.", file=errstream) if output_mode.endswith("native"): # Strip native and don't change type of md output_mode = output_mode[:-len("native")] else: # Rewrite md as simple dict for output md = {k: v for k, v in md.items()} if output_mode in ("yaml", "fixed"): if output_mode == "fixed": fix_header(md, filename=file) # The header should be written out in the insertion order print(yaml.dump(md, sort_keys=False), file=outstream) return True obs_info = ObservationInfo(md, pedantic=True, filename=file) if output_mode == "table": columns = [ "{:{fmt}}".format(getattr(obs_info, c["attr"]), fmt=c["format"]) for c in TABLE_COLUMNS ] if write_heading: # Construct headings of the same width as the items # we have calculated. Doing this means we don't have to # work out for ourselves how many characters will be used # for non-strings (especially Quantity) headings = [] separators = [] for thiscol, defn in zip(columns, TABLE_COLUMNS): width = len(thiscol) headings.append("{:{w}.{w}}".format(defn["label"], w=width)) separators.append("-" * width) print(" ".join(headings), file=outstream) print(" ".join(separators), file=outstream) row = " ".join(columns) print(row, file=outstream) elif output_mode == "verbose": print(f"{obs_info}", file=outstream) elif output_mode == "none": pass else: raise RuntimeError( f"Output mode of '{output_mode}' not recognized but should be known." ) except Exception as e: if print_trace: traceback.print_exc(file=outstream) else: print(repr(e), file=outstream) return False return True
def _files_to_headers(self, files): return [read_test_file(os.path.join(self.datadir, f)) for f in files]