示例#1
0
 def read(self, filename, hdu=None):
     self.filename = filename
     self.name = self.name or os.path.basename(filename)
     # read FITS file
     if not hdu:
         dprint(3, "opening", filename)
         hdu = pyfits.open(filename)[0]
         hdu.verify('silentfix')
     hdr = self.fits_header = hdu.header
     dprint(3, "reading data")
     data = hdu.data
     # NB: all-data operations (such as getting global min/max or computing of histograms) are much faster
     # (almost x2) when data is iterated
     # over in the proper order. After a transpose(), data is in fortran order. Tell this to setData().
     data = numpy.transpose(data)
     # .copy()
     dprint(3, "setting data")
     self.setData(data, fortran_order=True)
     dprint(3, "reading header")
     ndim = hdr['NAXIS']
     if ndim < 2:
         raise ValueError, "Cannot load a one-dimensional FITS file"
     # setup projection
     # (strip out history from header, as big histories really slow down FITSWCS)
     hdr1 = pyfits.Header(
         filter(lambda x: not str(x).startswith('HISTORY'), hdr.cards))
     proj = Projection.FITSWCS(hdr1)
     nx = ny = None
     # find X and Y axes
     for iaxis in range(ndim):
         axs = str(iaxis + 1)
         npix = hdr['NAXIS' + axs]
         name = hdr.get('CTYPE' + axs, axs).strip().upper()
         # have we found the coordinate axes?
         if FITSHeaders.isAxisTypeX(name):
             nx = npix
             iaxis_ra = iaxis
         elif FITSHeaders.isAxisTypeY(name):
             ny = npix
             iaxis_dec = iaxis
     # check that we have them
     if nx is None or ny is None:
         iaxis_ra, iaxis_dec = 0, 1
         nx, ny = hdr.get('NAXIS1'), hdr.get('NAXIS2')
     for iaxis in range(ndim):
         axs = str(iaxis + 1)
         # get axis description
         npix = hdr['NAXIS' + axs]
         crval = hdr.get('CRVAL' + axs, 0)
         cdelt = hdr.get('CDELT' + axs, 1)
         crpix = hdr.get('CRPIX' + axs, 1) - 1
         name = hdr.get('CTYPE' + axs, axs).strip().upper()
         unit = hdr.get('CUNIT' + axs)
         # if this is not an X/Y axis, add it to the slicers
         if iaxis not in (iaxis_ra, iaxis_dec):
             # values becomes a list of axis values
             values = list(crval + (numpy.arange(npix) - crpix) * cdelt)
             unit = unit and unit.lower().capitalize()
             # FITS knows of two enumerable axes: STOKES and COMPLEX. For these two, replace values with proper names
             if name == "STOKES":
                 labels = [(self.StokesNames[int(i)] if i > 0
                            and i < len(self.StokesNames) else "%d" % i)
                           for i in values]
             elif name == "COMPLEX":
                 labels = [(self.ComplexNames[int(i)] if i > 0
                            and i < len(self.ComplexNames) else "%d" % i)
                           for i in values]
             else:
                 name = name.split("-")[0]
                 # if values are a simple sequence startying at 0 or 1, make simple labels
                 if cdelt == 1 and values[0] in (0., 1.):
                     labels = ["%d%s" % (val, unit) for val in values]
                 # else set labels to None: setExtraAxis() will figure it out
                 else:
                     labels = None
             self.setExtraAxis(iaxis, name or ("axis " + axs), labels,
                               values, unit)
     # check for beam parameters
     psf = [hdr.get(x, None) for x in 'BMAJ', 'BMIN', 'BPA']
     if all([x is not None for x in psf]):
         self.setPsfSize(*[p / 180 * math.pi for p in psf])
     self.setSkyAxis(0, iaxis_ra, nx, proj.ra0, -proj.xscale, proj.xpix0)
     self.setSkyAxis(1, iaxis_dec, ny, proj.dec0, proj.yscale, proj.ypix0)
     self.setDefaultProjection(proj)
     dprint(3, "setting initial slice")
     self._setupSlice()
示例#2
0
def getImageCube (fitshdu,filename="",extra_axes=None):
  """Converts a FITS HDU (consisting of a header and data) into a 4+-dim numpy array where the
  first two axes are x and y, the third is Stokes (possibly of length 1, if missing in the
  original image), and the rest are either as found in the FITS header (if extra_axes=None),
  or in the order specified by CTYPE in extra_axes (if present, else a dummy axis of size 1 is inserted),
  with axes not present in extra_axes removed by taking the 0-th plane along each.
  Returns tuple of
    array,stokes_list,extra_axes_ctype_list,removed_axes_ctype_list
  e.g. array,("I","Q"),("FREQ--FOO","TIME--BAR")
  """
  hdr = fitshdu.header;
  data = fitshdu.data;
  # recognized axes
  ix = iy = istokes = None;
  naxis = len(data.shape);
  # other axes which will be returned
  other_axes = [];
  other_axes_ctype = [];
  remove_axes = [];
  remove_axes_ctype = [];
  # match axis ctype
  # this makes FREQ equivalent to FELO*
  def match_ctype (ctype,ctype_list):
    for i,ct in enumerate(ctype_list):
      if ct == ctype or ( ct == "FREQ" and ctype.startswith("FELO") ) or ( ctype == "FREQ" and ct.startswith("FELO") ):
        return i;
    return None;
  # identify X, Y and stokes axes
  for n in range(naxis):
    iax = naxis-1-n;
    axs = str(n+1);
    ctype = hdr.get('CTYPE'+axs).strip().upper();
    if ix is None and FITSHeaders.isAxisTypeX(ctype):
      ix = iax; # in numpy order, axes are reversed
    elif iy is None and FITSHeaders.isAxisTypeY(ctype):
      iy = iax;
    elif ctype == 'STOKES':
      if istokes is not None:
        raise ValueError,"duplicate STOKES axis in FITS file %s"%filename;
      istokes = iax;
      crval = hdr.get('CRVAL'+axs,0);
      cdelt = hdr.get('CDELT'+axs,1);
      crpix = hdr.get('CRPIX'+axs,1)-1;
      values = map(int,list(crval + (numpy.arange(data.shape[iax]) - crpix)*cdelt));
      stokes_names = [ (FITSHeaders.StokesNames[i]
                        if i>0 and i<len(FITSHeaders.StokesNames) else "%d"%i) for i in values ];
    else:
      other_axes.append(iax);
      other_axes_ctype.append(ctype);
  # not found?
  if ix is None or iy is None:
    raise ValueError,"FITS file %s does not appear to contain an X and/or Y axis"%filename;
  # form up shape of resulting image, and order of axes for transpose
  shape = [data.shape[ix],data.shape[iy]];
  axes = [ix,iy];
  # add stokes axis
  if istokes is None:
    shape.append(1);
    stokes_labels = ("I",);
  else:
    shape.append(data.shape[istokes]);
    axes.append(istokes);
  if extra_axes:
    # if a fixed order for the extra axes is specified, add the ones we found
    for ctype in extra_axes:
      i = match_ctype(ctype,other_axes_ctype);
      if i is not None:
        iax = other_axes[i];
        axes.append(iax);
        shape.append(data.shape[iax]);
      else:
        shape.append(1);
    # add the ones that were not found into the remove list
    for iaxis,ctype in zip(other_axes,other_axes_ctype):
      if match_ctype(ctype,extra_axes) is None:
        axes.append(iaxis);
        remove_axes.append(iaxis);
        remove_axes_ctype.append(ctype);
  # return all extra axes found in header
  else:
    shape += [ data.shape[i] for i in other_axes ];
    axes += other_axes;
    extra_axes = other_axes_ctype;
  # tranpose
  data = data.transpose(axes);
  # trim off axes which are to be removed, if we have any
  if remove_axes:
    data = data[[Ellipsis]+[0]*len(remove_axes)];
  # reshape and return
  return data.reshape(shape),stokes_names,extra_axes,remove_axes_ctype;
示例#3
0
def getImageCube(fitshdu, filename="", extra_axes=None):
    """Converts a FITS HDU (consisting of a header and data) into a 4+-dim numpy array where the
  first two axes are x and y, the third is Stokes (possibly of length 1, if missing in the
  original image), and the rest are either as found in the FITS header (if extra_axes=None),
  or in the order specified by CTYPE in extra_axes (if present, else a dummy axis of size 1 is inserted),
  with axes not present in extra_axes removed by taking the 0-th plane along each.
  Returns tuple of
    array,stokes_list,extra_axes_ctype_list,removed_axes_ctype_list
  e.g. array,("I","Q"),("FREQ--FOO","TIME--BAR")
  """
    hdr = fitshdu.header
    data = fitshdu.data
    # recognized axes
    ix = iy = istokes = None
    naxis = len(data.shape)
    # other axes which will be returned
    other_axes = []
    other_axes_ctype = []
    remove_axes = []
    remove_axes_ctype = []

    # match axis ctype
    # this makes FREQ equivalent to FELO*
    def match_ctype(ctype, ctype_list):
        for i, ct in enumerate(ctype_list):
            if ct == ctype or (ct == "FREQ" and ctype.startswith("FELO")) or (
                    ctype == "FREQ" and ct.startswith("FELO")):
                return i
        return None

    # identify X, Y and stokes axes
    for n in range(naxis):
        iax = naxis - 1 - n
        axs = str(n + 1)
        ctype = hdr.get('CTYPE' + axs).strip().upper()
        if ix is None and FITSHeaders.isAxisTypeX(ctype):
            ix = iax
            # in numpy order, axes are reversed
        elif iy is None and FITSHeaders.isAxisTypeY(ctype):
            iy = iax
        elif ctype == 'STOKES':
            if istokes is not None:
                raise ValueError, "duplicate STOKES axis in FITS file %s" % filename
            istokes = iax
            crval = hdr.get('CRVAL' + axs, 0)
            cdelt = hdr.get('CDELT' + axs, 1)
            crpix = hdr.get('CRPIX' + axs, 1) - 1
            values = map(
                int,
                list(crval + (numpy.arange(data.shape[iax]) - crpix) * cdelt))
            stokes_names = [
                (FITSHeaders.StokesNames[i]
                 if i > 0 and i < len(FITSHeaders.StokesNames) else "%d" % i)
                for i in values
            ]
        else:
            other_axes.append(iax)
            other_axes_ctype.append(ctype)
    # not found?
    if ix is None or iy is None:
        raise ValueError, "FITS file %s does not appear to contain an X and/or Y axis" % filename
    # form up shape of resulting image, and order of axes for transpose
    shape = [data.shape[ix], data.shape[iy]]
    axes = [ix, iy]
    # add stokes axis
    if istokes is None:
        shape.append(1)
        stokes_names = ("I", )
    else:
        shape.append(data.shape[istokes])
        axes.append(istokes)
    if extra_axes:
        # if a fixed order for the extra axes is specified, add the ones we found
        for ctype in extra_axes:
            i = match_ctype(ctype, other_axes_ctype)
            if i is not None:
                iax = other_axes[i]
                axes.append(iax)
                shape.append(data.shape[iax])
            else:
                shape.append(1)
        # add the ones that were not found into the remove list
        for iaxis, ctype in zip(other_axes, other_axes_ctype):
            if match_ctype(ctype, extra_axes) is None:
                axes.append(iaxis)
                remove_axes.append(iaxis)
                remove_axes_ctype.append(ctype)
    # return all extra axes found in header
    else:
        shape += [data.shape[i] for i in other_axes]
        axes += other_axes
        extra_axes = other_axes_ctype
    # tranpose
    data = data.transpose(axes)
    # trim off axes which are to be removed, if we have any
    if remove_axes:
        data = data[[Ellipsis] + [0] * len(remove_axes)]
    # reshape and return
    return data.reshape(shape), stokes_names, extra_axes, remove_axes_ctype
示例#4
0
 def read (self,filename,hdu=None):
   self.filename = filename;
   self.name = self.name or os.path.basename(filename);
   # read FITS file
   if not hdu:
     dprint(3,"opening",filename);
     hdu = pyfits.open(filename)[0];
     hdu.verify('silentfix');
   hdr = self.fits_header = hdu.header;
   dprint(3,"reading data");
   data = hdu.data;
   # NB: all-data operations (such as getting global min/max or computing of histograms) are much faster
   # (almost x2) when data is iterated
   # over in the proper order. After a transpose(), data is in fortran order. Tell this to setData().
   data = numpy.transpose(data);  # .copy()
   dprint(3,"setting data");
   self.setData(data,fortran_order=True);
   dprint(3,"reading header");
   ndim = hdr['NAXIS'];
   if ndim < 2:
     raise ValueError,"Cannot load a one-dimensional FITS file";
   # setup projection
   # (strip out history from header, as big histories really slow down FITSWCS)
   hdr1 = pyfits.Header(filter(lambda x:not str(x).startswith('HISTORY'),hdr.cards));
   proj = Projection.FITSWCS(hdr1);
   nx = ny = None;
   # find X and Y axes
   for iaxis in range(ndim):
     axs = str(iaxis+1);
     npix = hdr['NAXIS'+axs];
     name = hdr.get('CTYPE'+axs,axs).strip().upper();
     # have we found the coordinate axes?
     if FITSHeaders.isAxisTypeX(name):
       nx = npix;
       iaxis_ra = iaxis;
     elif FITSHeaders.isAxisTypeY(name):
       ny = npix;
       iaxis_dec = iaxis;
   # check that we have them
   if nx is None or ny is None:
     iaxis_ra,iaxis_dec = 0,1;
     nx,ny = hdr.get('NAXIS1'),hdr.get('NAXIS2');
   for iaxis in range(ndim):
     axs = str(iaxis+1);
     # get axis description
     npix = hdr['NAXIS'+axs];
     crval = hdr.get('CRVAL'+axs,0 );
     cdelt = hdr.get('CDELT'+axs,1) ;
     crpix = hdr.get('CRPIX'+axs,1) -1;
     name = hdr.get('CTYPE'+axs,axs).strip().upper();
     unit = hdr.get('CUNIT'+axs);
     # if this is not an X/Y axis, add it to the slicers
     if iaxis not in (iaxis_ra,iaxis_dec):
       # values becomes a list of axis values
       values = list(crval + (numpy.arange(npix) - crpix)*cdelt);
       unit = unit and unit.lower().capitalize();
       # FITS knows of two enumerable axes: STOKES and COMPLEX. For these two, replace values with proper names
       if name == "STOKES":
         labels = [ (self.StokesNames[int(i)] if i>0 and i<len(self.StokesNames) else "%d"%i) for i in values ];
       elif name == "COMPLEX":
         labels = [ (self.ComplexNames[int(i)] if i>0 and i<len(self.ComplexNames) else "%d"%i) for i in values ];
       else:
         name = name.split("-")[0];
         # if values are a simple sequence startying at 0 or 1, make simple labels
         if cdelt == 1 and values[0] in (0.,1.):
           labels = [ "%d%s"%(val,unit) for val in values ];
         # else set labels to None: setExtraAxis() will figure it out
         else:
           labels = None;
       self.setExtraAxis(iaxis,name or ("axis "+axs),labels,values,unit);
   # check for beam parameters
   psf = [ hdr.get(x,None) for x in 'BMAJ','BMIN','BPA' ];
   if all([x is not None for x in psf]):
     self.setPsfSize(*[ p/180*math.pi for p in psf ]);
   self.setSkyAxis(0,iaxis_ra,nx,proj.ra0,-proj.xscale,proj.xpix0);
   self.setSkyAxis(1,iaxis_dec,ny,proj.dec0,proj.yscale,proj.ypix0);
   self.setDefaultProjection(proj);
   dprint(3,"setting initial slice");
   self._setupSlice();