def _verify_blank(self): # Probably not the best place for this (it should probably happen # in _verify as well) but I want to be able to raise this warning # both when the HDU is created and when written if self._blank is None: return messages = [] # TODO: Once the FITSSchema framewhere is merged these warnings # should be handled by the schema if not _is_int(self._blank): messages.append( "Invalid value for 'BLANK' keyword in header: {0!r} " "The 'BLANK' keyword must be an integer. It will be " "ignored in the meantime.".format(self._blank)) self._blank = None if not self._bitpix > 0: messages.append( "Invalid 'BLANK' keyword in header. The 'BLANK' keyword " "is only applicable to integer data, and will be ignored " "in this HDU.") self._blank = None for msg in messages: warnings.warn(msg, VerifyWarning)
def setpar(self, parname, value): """ Set the group parameter value. """ # TODO: It would be nice if, instead of requiring a multi-part value to # be an array, there were an *option* to automatically split the value # into multiple columns if it doesn't already fit in the array data # type. if _is_int(parname): self.array[self.row][parname] = value else: indx = self._unique[parname.upper()] if len(indx) == 1: self.array[self.row][indx[0]] = value # if more than one group parameter have the same name, the # value must be a list (or tuple) containing arrays else: if isinstance(value, (list, tuple)) and \ len(indx) == len(value): for i in range(len(indx)): self.array[self.row][indx[i]] = value[i] else: raise ValueError('Parameter value must be a sequence with ' '{} arrays/numbers.'.format(len(indx)))
def _verify_blank(self): # Probably not the best place for this (it should probably happen # in _verify as well) but I want to be able to raise this warning # both when the HDU is created and when written if self._blank is None: return messages = [] # TODO: Once the FITSSchema framewhere is merged these warnings # should be handled by the schema if not _is_int(self._blank): messages.append( "Invalid value for 'BLANK' keyword in header: {!r} " "The 'BLANK' keyword must be an integer. It will be " "ignored in the meantime.".format(self._blank)) self._blank = None if not self._bitpix > 0: messages.append( "Invalid 'BLANK' keyword in header. The 'BLANK' keyword " "is only applicable to integer data, and will be ignored " "in this HDU.") self._blank = None for msg in messages: warnings.warn(msg, VerifyWarning)
def _verify(self, option='warn'): errs = super()._verify(option=option) # Verify locations and values of mandatory keywords. self.req_cards('NAXIS', 2, lambda v: (_is_int(v) and 1 <= v <= 999), 1, option, errs) self.req_cards('NAXIS1', 3, lambda v: (_is_int(v) and v == 0), 0, option, errs) after = self._header['NAXIS'] + 3 pos = lambda x: x >= after self.req_cards('GCOUNT', pos, _is_int, 1, option, errs) self.req_cards('PCOUNT', pos, _is_int, 0, option, errs) self.req_cards('GROUPS', pos, lambda v: (v is True), True, option, errs) return errs
def _verify(self, option='warn'): errs = super()._verify(option=option) # Verify locations and values of mandatory keywords. self.req_cards('NAXIS', 2, lambda v: (_is_int(v) and 1 <= v <= 999), 1, option, errs) self.req_cards('NAXIS1', 3, lambda v: (_is_int(v) and v == 0), 0, option, errs) after = self._header['NAXIS'] + 3 pos = lambda x: x >= after self.req_cards('GCOUNT', pos, _is_int, 1, option, errs) self.req_cards('PCOUNT', pos, _is_int, 0, option, errs) self.req_cards('GROUPS', pos, lambda v: (v is True), True, option, errs) return errs
def __getitem__(self, key): if not isinstance(key, tuple): key = (key, ) naxis = len(self.hdu.shape) return_scalar = (all(isinstance(k, (int, np.integer)) for k in key) and len(key) == naxis) if not any(k is Ellipsis for k in key): # We can always add a ... at the end, after making note of whether # to return a scalar. key += Ellipsis, ellipsis_count = len([k for k in key if k is Ellipsis]) if len(key) - ellipsis_count > naxis or ellipsis_count > 1: raise IndexError('too many indices for array') # Insert extra dimensions as needed. idx = next(i for i, k in enumerate(key + (Ellipsis, )) if k is Ellipsis) key = key[:idx] + (slice(None), ) * (naxis - len(key) + 1) + key[idx + 1:] return_0dim = (all(isinstance(k, (int, np.integer)) for k in key) and len(key) == naxis) dims = [] offset = 0 # Find all leading axes for which a single point is used. for idx in range(naxis): axis = self.hdu.shape[idx] indx = _IndexInfo(key[idx], axis) offset = offset * axis + indx.offset if not _is_int(key[idx]): dims.append(indx.npts) break is_contiguous = indx.contiguous for jdx in range(idx + 1, naxis): axis = self.hdu.shape[jdx] indx = _IndexInfo(key[jdx], axis) dims.append(indx.npts) if indx.npts == axis and indx.contiguous: # The offset needs to multiply the length of all remaining axes offset *= axis else: is_contiguous = False if is_contiguous: dims = tuple(dims) or (1, ) bitpix = self.hdu._orig_bitpix offset = self.hdu._data_offset + offset * abs(bitpix) // 8 data = self.hdu._get_scaled_image_data(offset, dims) else: data = self._getdata(key) if return_scalar: data = data.item() elif return_0dim: data = data.squeeze() return data
def __init__(self, ixmin, ixmax, iymin, iymax): if not _is_int(ixmin): raise TypeError('ixmin must be an integer') if not _is_int(ixmax): raise TypeError('ixmax must be an integer') if not _is_int(iymin): raise TypeError('iymin must be an integer') if not _is_int(iymax): raise TypeError('iymax must be an integer') if ixmin > ixmax: raise ValueError('ixmin must be <= ixmax') if iymin > iymax: raise ValueError('iymin must be <= iymax') self.ixmin = ixmin self.ixmax = ixmax self.iymin = iymin self.iymax = iymax
def __init__(self, ixmin, ixmax, iymin, iymax): if not _is_int(ixmin): raise TypeError('ixmin must be an integer') if not _is_int(ixmax): raise TypeError('ixmax must be an integer') if not _is_int(iymin): raise TypeError('iymin must be an integer') if not _is_int(iymax): raise TypeError('iymax must be an integer') if ixmin > ixmax: raise ValueError('ixmin must be <= ixmax') if iymin > iymax: raise ValueError('iymin must be <= iymax') self.ixmin = ixmin self.ixmax = ixmax self.iymin = iymin self.iymax = iymax
def match_header(cls, header): """A constant value HDU will only be recognized as such if the header contains a valid PIXVALUE and NAXIS == 0. """ pixvalue = header.get('PIXVALUE') naxis = header.get('NAXIS', 0) return (super(_ConstantValueImageBaseHDU, cls).match_header(header) and (isinstance(pixvalue, float) or _is_int(pixvalue)) and naxis == 0)
def __getitem__(self, key): if not isinstance(key, tuple): key = (key,) naxis = len(self.hdu.shape) return_scalar = (all(isinstance(k, (int, np.integer)) for k in key) and len(key) == naxis) if not any(k is Ellipsis for k in key): # We can always add a ... at the end, after making note of whether # to return a scalar. key += Ellipsis, ellipsis_count = len([k for k in key if k is Ellipsis]) if len(key) - ellipsis_count > naxis or ellipsis_count > 1: raise IndexError('too many indices for array') # Insert extra dimensions as needed. idx = next(i for i, k in enumerate(key + (Ellipsis,)) if k is Ellipsis) key = key[:idx] + (slice(None),) * (naxis - len(key) + 1) + key[idx+1:] return_0dim = (all(isinstance(k, (int, np.integer)) for k in key) and len(key) == naxis) dims = [] offset = 0 # Find all leading axes for which a single point is used. for idx in range(naxis): axis = self.hdu.shape[idx] indx = _IndexInfo(key[idx], axis) offset = offset * axis + indx.offset if not _is_int(key[idx]): dims.append(indx.npts) break is_contiguous = indx.contiguous for jdx in range(idx + 1, naxis): axis = self.hdu.shape[jdx] indx = _IndexInfo(key[jdx], axis) dims.append(indx.npts) if indx.npts == axis and indx.contiguous: # The offset needs to multiply the length of all remaining axes offset *= axis else: is_contiguous = False if is_contiguous: dims = tuple(dims) or (1,) bitpix = self.hdu._orig_bitpix offset = self.hdu._data_offset + offset * abs(bitpix) // 8 data = self.hdu._get_scaled_image_data(offset, dims) else: data = self._getdata(key) if return_scalar: data = data.item() elif return_0dim: data = data.squeeze() return data
def match_header(cls, header): """A constant value HDU will only be recognized as such if the header contains a valid PIXVALUE and NAXIS == 0. """ pixvalue = header.get('PIXVALUE') naxis = header.get('NAXIS', 0) return (super(_ConstantValueImageBaseHDU, cls).match_header(header) and (isinstance(pixvalue, float) or _is_int(pixvalue)) and naxis == 0)
def _verify(self, option='warn'): """ ImageHDU verify method. """ errs = super()._verify(option=option) naxis = self._header.get('NAXIS', 0) # PCOUNT must == 0, GCOUNT must == 1; the former is verified in # ExtensionHDU._verify, however ExtensionHDU._verify allows PCOUNT # to be >= 0, so we need to check it here self.req_cards('PCOUNT', naxis + 3, lambda v: (_is_int(v) and v == 0), 0, option, errs) return errs
def _verify(self, option='warn'): """ ImageHDU verify method. """ errs = super()._verify(option=option) naxis = self._header.get('NAXIS', 0) # PCOUNT must == 0, GCOUNT must == 1; the former is verified in # ExtensionHDU._verify, however ExtensionHDU._verify allows PCOUNT # to be >= 0, so we need to check it here self.req_cards('PCOUNT', naxis + 3, lambda v: (_is_int(v) and v == 0), 0, option, errs) return errs
def __init__(self, indx, naxis): if _is_int(indx): if 0 <= indx < naxis: self.npts = 1 self.offset = indx self.contiguous = True else: raise IndexError('Index {} out of range.'.format(indx)) elif isinstance(indx, slice): start, stop, step = indx.indices(naxis) self.npts = (stop - start) // step self.offset = start self.contiguous = step == 1 elif isiterable(indx): self.npts = len(indx) self.offset = 0 self.contiguous = False else: raise IndexError('Illegal index {}'.format(indx))
def par(self, parname): """ Get the group parameter value. """ if _is_int(parname): result = self.array[self.row][parname] else: indx = self._unique[parname.upper()] if len(indx) == 1: result = self.array[self.row][indx[0]] # if more than one group parameter have the same name else: result = self.array[self.row][indx[0]].astype('f8') for i in indx[1:]: result += self.array[self.row][i] return result
def par(self, parname): """ Get the group parameter values. """ if _is_int(parname): result = self.field(parname) else: indx = self._unique[parname.upper()] if len(indx) == 1: result = self.field(indx[0]) # if more than one group parameter have the same name else: result = self.field(indx[0]).astype('f8') for i in indx[1:]: result += self.field(i) return result
def __init__(self, indx, naxis): if _is_int(indx): if 0 <= indx < naxis: self.npts = 1 self.offset = indx self.contiguous = True else: raise IndexError(f'Index {indx} out of range.') elif isinstance(indx, slice): start, stop, step = indx.indices(naxis) self.npts = (stop - start) // step self.offset = start self.contiguous = step == 1 elif isiterable(indx): self.npts = len(indx) self.offset = 0 self.contiguous = False else: raise IndexError(f'Illegal index {indx}')