def test_different_keyword_values(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() hb['C'] = 4 diff = HeaderDiff(ha, hb) assert not diff.identical assert diff.diff_keyword_values == {'C': [(3, 4)]}
def test_ignore_blank_cards(self): """Test for #152--ignore blank cards.""" ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = Header([('A', 1), ('', ''), ('B', 2), ('', ''), ('C', 3)]) hc = ha.copy() hc.append() hc.append() # We now have a header with interleaved blanks, and a header with end # blanks, both of which should ignore the blanks assert_true(HeaderDiff(ha, hb).identical) assert_true(HeaderDiff(ha, hc).identical) assert_true(HeaderDiff(hb, hc).identical) assert_false(HeaderDiff(ha, hb, ignore_blank_cards=False).identical) assert_false(HeaderDiff(ha, hc, ignore_blank_cards=False).identical) # Both hb and hc have the same number of blank cards; since order is # currently ignored, these should still be identical even if blank # cards are not ignored assert_true(HeaderDiff(hb, hc, ignore_blank_cards=False).identical) hc.append() # But now there are different numbers of blanks, so they should not be # ignored: assert_false(HeaderDiff(hb, hc, ignore_blank_cards=False).identical)
def test_different_keyword_values(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() hb['C'] = 4 diff = HeaderDiff(ha, hb) assert_false(diff.identical) assert_equal(diff.diff_keyword_values, {'C': [(3, 4)]})
def test_different_keyword_comments(self): ha = Header([('A', 1), ('B', 2), ('C', 3, 'comment 1')]) hb = ha.copy() hb.comments['C'] = 'comment 2' diff = HeaderDiff(ha, hb) assert_false(diff.identical) assert_equal(diff.diff_keyword_comments, {'C': [('comment 1', 'comment 2')]})
def test_different_keyword_values_with_duplicate(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() ha.append(('C', 4)) hb.append(('C', 5)) diff = HeaderDiff(ha, hb) assert_false(diff.identical) assert_equal(diff.diff_keyword_values, {'C': [None, (4, 5)]})
def test_different_keywords(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() hb['C'] = 4 hb['D'] = (5, 'Comment') ha['E'] = (6, 'Comment') ha['F'] = (7, 'Comment') diff = HeaderDiff(ha, hb) assert_false(diff.identical) assert_equal(diff.diff_keywords, (['E', 'F'], ['D']))
def test_different_keyword_count(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() del hb['B'] diff = HeaderDiff(ha, hb) assert_false(diff.identical) assert_equal(diff.diff_keyword_count, (3, 2)) # But make sure the common keywords are at least correct assert_equal(diff.common_keywords, ['A', 'C'])
def test_different_keyword_count(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() del hb['B'] diff = HeaderDiff(ha, hb) assert not diff.identical assert diff.diff_keyword_count == (3, 2) # But make sure the common keywords are at least correct assert diff.common_keywords == ['A', 'C']
def test_floating_point_tolerance(self): ha = Header([('A', 1), ('B', 2.00001), ('C', 3.000001)]) hb = ha.copy() hb['B'] = 2.00002 hb['C'] = 3.000002 diff = HeaderDiff(ha, hb) assert_false(diff.identical) assert_equal(diff.diff_keyword_values, {'B': [(2.00001, 2.00002)], 'C': [(3.000001, 3.000002)]}) diff = HeaderDiff(ha, hb, tolerance=1e-6) assert_false(diff.identical) assert_equal(diff.diff_keyword_values, {'B': [(2.00001, 2.00002)]})
def test_asymmetric_duplicate_keywords(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() ha.append(('A', 2, 'comment 1')) ha.append(('A', 3, 'comment 2')) hb.append(('B', 4, 'comment 3')) hb.append(('C', 5, 'comment 4')) diff = HeaderDiff(ha, hb) assert_false(diff.identical) assert_equal(diff.diff_keyword_values, {}) assert_equal(diff.diff_duplicate_keywords, {'A': (3, 1), 'B': (1, 2), 'C': (1, 2)})
def test_ignore_keyword_values(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() hb['B'] = 4 hb['C'] = 5 diff = HeaderDiff(ha, hb, ignore_keywords=['*']) assert diff.identical diff = HeaderDiff(ha, hb, ignore_keywords=['B']) assert not diff.identical assert diff.diff_keyword_values == {'C': [(3, 5)]} report = diff.report() assert 'Keyword B has different values' not in report assert 'Keyword C has different values' in report # Test case-insensitivity diff = HeaderDiff(ha, hb, ignore_keywords=['b']) assert not diff.identical assert diff.diff_keyword_values == {'C': [(3, 5)]}
def test_ignore_keyword_values(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() hb['B'] = 4 hb['C'] = 5 diff = HeaderDiff(ha, hb, ignore_keywords=['*']) assert_true(diff.identical) diff = HeaderDiff(ha, hb, ignore_keywords=['B']) assert_false(diff.identical) assert_equal(diff.diff_keyword_values, {'C': [(3, 5)]}) report = diff.report() assert_true('Keyword B has different values' not in report) assert_true('Keyword C has different values' in report) # Test case-insensitivity diff = HeaderDiff(ha, hb, ignore_keywords=['b']) assert_false(diff.identical) assert_equal(diff.diff_keyword_values, {'C': [(3, 5)]})
def test_ignore_blanks(self): pyfits.STRIP_HEADER_WHITESPACE = False try: ha = Header([('A', 1), ('B', 2), ('C', 'A ')]) hb = ha.copy() hb['C'] = 'A' assert_not_equal(ha['C'], hb['C']) diff = HeaderDiff(ha, hb) # Trailing blanks are ignored by default assert_true(diff.identical) assert_equal(diff.diff_keyword_values, {}) # Don't ignore blanks diff = HeaderDiff(ha, hb, ignore_blanks=False) assert_false(diff.identical) assert_equal(diff.diff_keyword_values, {'C': [('A ', 'A')]}) finally: pyfits.STRIP_HEADER_WHITESPACE = True
def test_ignore_keyword_comments(self): ha = Header([('A', 1, 'A'), ('B', 2, 'B'), ('C', 3, 'C')]) hb = ha.copy() hb.comments['B'] = 'D' hb.comments['C'] = 'E' diff = HeaderDiff(ha, hb, ignore_comments=['*']) assert diff.identical diff = HeaderDiff(ha, hb, ignore_comments=['B']) assert not diff.identical assert diff.diff_keyword_comments == {'C': [('C', 'E')]} report = diff.report() assert 'Keyword B has different comments' not in report assert 'Keyword C has different comments' in report # Test case-insensitivity diff = HeaderDiff(ha, hb, ignore_comments=['b']) assert not diff.identical assert diff.diff_keyword_comments == {'C': [('C', 'E')]}
def test_ignore_keyword_comments(self): ha = Header([('A', 1, 'A'), ('B', 2, 'B'), ('C', 3, 'C')]) hb = ha.copy() hb.comments['B'] = 'D' hb.comments['C'] = 'E' diff = HeaderDiff(ha, hb, ignore_comments=['*']) assert_true(diff.identical) diff = HeaderDiff(ha, hb, ignore_comments=['B']) assert_false(diff.identical) assert_equal(diff.diff_keyword_comments, {'C': [('C', 'E')]}) report = diff.report() assert_true('Keyword B has different comments' not in report) assert_true('Keyword C has different comments' in report) # Test case-insensitivity diff = HeaderDiff(ha, hb, ignore_comments=['b']) assert_false(diff.identical) assert_equal(diff.diff_keyword_comments, {'C': [('C', 'E')]})
def test_ignore_blanks(self): fits.STRIP_HEADER_WHITESPACE = False try: ha = Header([('A', 1), ('B', 2), ('C', 'A ')]) hb = ha.copy() hb['C'] = 'A' assert ha['C'] != hb['C'] diff = HeaderDiff(ha, hb) # Trailing blanks are ignored by default assert diff.identical assert diff.diff_keyword_values == {} # Don't ignore blanks diff = HeaderDiff(ha, hb, ignore_blanks=False) assert not diff.identical assert diff.diff_keyword_values == {'C': [('A ', 'A')]} finally: fits.STRIP_HEADER_WHITESPACE = True
def test_identical_headers(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() assert_true(HeaderDiff(ha, hb).identical)
def load(cls, datafile, cdfile=None, hfile=None, replace=False, header=None): """ Create a table from the input ASCII files. The input is from up to three separate files, one containing column definitions, one containing header parameters, and one containing column data. The column definition and header parameters files are not required. When absent the column definitions and/or header parameters are taken from the header object given in the header argument; otherwise sensible defaults are inferred (though this mode is not recommended). Parameters ---------- datafile : file path, file object or file-like object Input data file containing the table data in ASCII format. cdfile : file path, file object, file-like object, optional Input column definition file containing the names, formats, display formats, physical units, multidimensional array dimensions, undefined values, scale factors, and offsets associated with the columns in the table. If `None`, the column definitions are taken from the current values in this object. hfile : file path, file object, file-like object, optional Input parameter definition file containing the header parameter definitions to be associated with the table. If `None`, the header parameter definitions are taken from the current values in this objects header. replace : bool When `True`, indicates that the entire header should be replaced with the contents of the ASCII file instead of just updating the current header. header : Header object When the cdfile and hfile are missing, use this Header object in the creation of the new table and HDU. Otherwise this Header supercedes the keywords from hfile, which is only used to update values not present in this Header, unless replace=True in which this Header's values are completely replaced with the values from hfile. Notes ----- The primary use for the `load` method is to allow the input of ASCII data that was edited in a standard text editor of the table data and parameters. The `dump` method can be used to create the initial ASCII files. """ # Process the parameter file if header is None: header = Header() if hfile: if replace: header = Header.fromtextfile(hfile) else: header.extend(Header.fromtextfile(hfile), update=True, update_first=True) coldefs = None # Process the column definitions file if cdfile: coldefs = cls._load_coldefs(cdfile) # Process the data file data = cls._load_data(datafile, coldefs) if coldefs is None: coldefs = ColDefs(data) # Create a new HDU using the supplied header and data hdu = cls(data=data, header=header) hdu.columns = coldefs return hdu
def __init__(self, a, b, ignore_keywords=[], ignore_comments=[], tolerance=0.0, ignore_blanks=True, ignore_blank_cards=True): """ See `FITSDiff` for explanations of the initialization parameters. """ self.ignore_keywords = set(k.upper() for k in ignore_keywords) self.ignore_comments = set(k.upper() for k in ignore_comments) self.tolerance = tolerance self.ignore_blanks = ignore_blanks self.ignore_blank_cards = ignore_blank_cards self.ignore_keyword_patterns = set() self.ignore_comment_patterns = set() for keyword in list(self.ignore_keywords): keyword = keyword.upper() if keyword != '*' and glob.has_magic(keyword): self.ignore_keywords.remove(keyword) self.ignore_keyword_patterns.add(keyword) for keyword in list(self.ignore_comments): keyword = keyword.upper() if keyword != '*' and glob.has_magic(keyword): self.ignore_comments.remove(keyword) self.ignore_comment_patterns.add(keyword) # Keywords appearing in each header self.common_keywords = [] # Set to the number of keywords in each header if the counts differ self.diff_keyword_count = () # Set if the keywords common to each header (excluding ignore_keywords) # appear in different positions within the header # TODO: Implement this self.diff_keyword_positions = () # Keywords unique to each header (excluding keywords in # ignore_keywords) self.diff_keywords = () # Keywords that have different numbers of duplicates in each header # (excluding keywords in ignore_keywords) self.diff_duplicate_keywords = {} # Keywords common to each header but having different values (excluding # keywords in ignore_keywords) self.diff_keyword_values = defaultdict(lambda: []) # Keywords common to each header but having different comments # (excluding keywords in ignore_keywords or in ignore_comments) self.diff_keyword_comments = defaultdict(lambda: []) if isinstance(a, basestring): a = Header.fromstring(a) if isinstance(b, basestring): b = Header.fromstring(b) if not (isinstance(a, Header) and isinstance(b, Header)): raise TypeError('HeaderDiff can only diff pyfits.Header objects ' 'or strings containing FITS headers.') super(HeaderDiff, self).__init__(a, b)
def test_slightly_different_headers(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() hb['C'] = 4 assert_false(HeaderDiff(ha, hb).identical)
def __init__(self, data=None, header=None, do_not_scale_image_data=False, uint=False, scale_back=False, **kwargs): from pyfits.hdu.groups import GroupsHDU super(_ImageBaseHDU, self).__init__(data=data, header=header) if header is not None: if not isinstance(header, Header): # TODO: Instead maybe try initializing a new Header object from # whatever is passed in as the header--there are various types # of objects that could work for this... raise ValueError('header must be a Header object') if data is DELAYED: # Presumably if data is DELAYED then this HDU is coming from an # open file, and was not created in memory if header is None: # this should never happen raise ValueError('No header to setup HDU.') # if the file is read the first time, no need to copy, and keep it # unchanged else: self._header = header else: # TODO: Some of this card manipulation should go into the # PrimaryHDU and GroupsHDU subclasses # construct a list of cards of minimal header if isinstance(self, ExtensionHDU): c0 = ('XTENSION', 'IMAGE', self.standard_keyword_comments['XTENSION']) else: c0 = ('SIMPLE', True, self.standard_keyword_comments['SIMPLE']) cards = [ c0, ('BITPIX', 8, self.standard_keyword_comments['BITPIX']), ('NAXIS', 0, self.standard_keyword_comments['NAXIS'])] if isinstance(self, GroupsHDU): cards.append(('GROUPS', True, self.standard_keyword_comments['GROUPS'])) if isinstance(self, (ExtensionHDU, GroupsHDU)): cards.append(('PCOUNT', 0, self.standard_keyword_comments['PCOUNT'])) cards.append(('GCOUNT', 1, self.standard_keyword_comments['GCOUNT'])) if header is not None: orig = header.copy() header = Header(cards) header.extend(orig, strip=True, update=True, end=True) else: header = Header(cards) self._header = header self._do_not_scale_image_data = do_not_scale_image_data self._uint = uint self._scale_back = scale_back if do_not_scale_image_data: self._bzero = 0 self._bscale = 1 else: self._bzero = self._header.get('BZERO', 0) self._bscale = self._header.get('BSCALE', 1) # Save off other important values from the header needed to interpret # the image data self._axes = [self._header.get('NAXIS' + str(axis + 1), 0) for axis in xrange(self._header.get('NAXIS', 0))] self._bitpix = self._header.get('BITPIX', 8) self._gcount = self._header.get('GCOUNT', 1) self._pcount = self._header.get('PCOUNT', 0) self._blank = self._header.get('BLANK') self._orig_bitpix = self._bitpix self._orig_bzero = self._bzero self._orig_bscale = self._bscale # Set the name attribute if it was provided (if this is an ImageHDU # this will result in setting the EXTNAME keyword of the header as # well) if 'name' in kwargs and kwargs['name']: self.name = kwargs['name'] # Set to True if the data or header is replaced, indicating that # update_header should be called self._modified = False if data is DELAYED: return else: self.data = data self.update_header()
def test_common_keywords(self): ha = Header([('A', 1), ('B', 2), ('C', 3)]) hb = ha.copy() hb['C'] = 4 hb['D'] = (5, 'Comment') assert_equal(HeaderDiff(ha, hb).common_keywords, ['A', 'B', 'C'])