def test_ccd_process_gain_corrected(): # test the through ccd_process with gain_corrected as False ccd_data = CCDData(10.0 * np.ones((100, 100)), unit=u.adu) ccd_data.data[:, -10:] = 2 ccd_data.meta['testkw'] = 100 mask = np.zeros((100, 90)) masterbias = CCDData(4.0 * np.ones((100, 90)), unit=u.adu) masterbias.uncertainty = StdDevUncertainty(np.zeros((100, 90))) dark_frame = CCDData(0.0 * np.ones((100, 90)), unit=u.adu) dark_frame.uncertainty = StdDevUncertainty(np.zeros((100, 90))) masterflat = CCDData(5.0 * np.ones((100, 90)), unit=u.adu) masterflat.uncertainty = StdDevUncertainty(np.zeros((100, 90))) occd = ccd_process(ccd_data, oscan=ccd_data[:, -10:], trim='[1:90,1:100]', error=True, master_bias=masterbias, master_flat=masterflat, dark_frame=dark_frame, bad_pixel_mask=mask, gain=0.5 * u.electron/u.adu, readnoise=5**0.5 * u.electron, oscan_median=True, dark_scale=False, dark_exposure=1.*u.s, data_exposure=1.*u.s, gain_corrected=False) # final results should be (10 - 2) / 2.0 - 2 = 2 # error should be (4 + 5)**0.5 / 0.5 = 3.0 np.testing.assert_array_equal(2.0 * np.ones((100, 90)), occd.data) np.testing.assert_almost_equal(3.0 * np.ones((100, 90)), occd.uncertainty.array) np.testing.assert_array_equal(mask, occd.mask) assert(occd.unit == u.electron) # Make sure the original keyword is still present. Regression test for #401 assert occd.meta['testkw'] == 100
def test_3d_combiner_with_scaling(): ccd_data = ccd_data_func() # The factors below are not particularly important; just avoid anything # whose average is 1. ccd_data = CCDData(np.ones((5, 5, 5)), unit=u.adu) ccd_data_lower = CCDData(3 * np.ones((5, 5, 5)), unit=u.adu) ccd_data_higher = CCDData(0.9 * np.ones((5, 5, 5)), unit=u.adu) combiner = Combiner([ccd_data, ccd_data_higher, ccd_data_lower]) # scale each array to the mean of the first image scale_by_mean = lambda x: ccd_data.data.mean() / np.ma.average(x) combiner.scaling = scale_by_mean avg_ccd = combiner.average_combine() # Does the mean of the scaled arrays match the value to which it was # scaled? np.testing.assert_almost_equal(avg_ccd.data.mean(), ccd_data.data.mean()) assert avg_ccd.shape == ccd_data.shape median_ccd = combiner.median_combine() # Does median also scale to the correct value? np.testing.assert_almost_equal(np.median(median_ccd.data), np.median(ccd_data.data)) # Set the scaling manually... combiner.scaling = [scale_by_mean(combiner.data_arr[i]) for i in range(3)] avg_ccd = combiner.average_combine() np.testing.assert_almost_equal(avg_ccd.data.mean(), ccd_data.data.mean()) assert avg_ccd.shape == ccd_data.shape
def process_science(sci_list,fil,red_path,mbias=None,mflat=None,proc=None,log=None): masks = [] processed = [] for sci in sci_list: log.info('Loading file: '+sci) log.info('Applying gain correction and flat correction.') with fits.open(sci) as hdr: header = hdr[0].header data = hdr[0].data data[np.isnan(data)] = np.nanmedian(data) raw = CCDData(data,meta=header,unit=u.adu) red = ccdproc.ccd_process(raw, gain=raw.header['SYSGAIN']*u.electron/u.adu, readnoise=rdnoise(raw.header)*u.electron) log.info('Exposure time of science image is '+str(red.header['TRUITIME']*red.header['COADDONE'])) flat = np.array(ccdproc.flat_correct(red, mflat)) flat[np.isnan(flat)] = np.nanmedian(flat) processed_data = CCDData(flat,unit=u.electron,header=red.header,wcs=red.wcs) log.info('File proccessed.') log.info('Cleaning cosmic rays and creating mask.') mask = make_source_mask(processed_data, nsigma=3, npixels=5) masks.append(mask) clean, com_mask = create_mask.create_mask(sci.replace('.gz',''),processed_data,'_mask.fits',static_mask(proc)[0],mask,saturation(red.header),binning(),rdnoise(raw.header),cr_clean_sigclip(),cr_clean_sigcfrac(),cr_clean_objlim(),log) processed_data.data = clean log.info('Calculating 2D background.') bkg = Background2D(processed_data, (128, 128), filter_size=(3, 3),sigma_clip=SigmaClip(sigma=3), bkg_estimator=MeanBackground(), mask=mask, exclude_percentile=80) log.info('Median background: '+str(np.median(bkg.background))) fits.writeto(sci.replace('/raw/','/red/').replace('.fits','_bkg.fits').replace('.gz',''),bkg.background,overwrite=True) final = processed_data.subtract(CCDData(bkg.background,unit=u.electron),propagate_uncertainties=True,handle_meta='first_found').divide(red.header['TRUITIME']*red.header['COADDONE']*u.second,propagate_uncertainties=True,handle_meta='first_found') log.info('Background subtracted and image divided by exposure time.') final.write(sci.replace('/raw/','/red/').replace('.gz',''),overwrite=True) processed.append(final) return processed, masks
def test_combiner_minmax_min(): ccd_list = [CCDData(np.zeros((10, 10)), unit=u.adu), CCDData(np.zeros((10, 10)) - 1000, unit=u.adu), CCDData(np.zeros((10, 10)) + 1000, unit=u.adu)] c = Combiner(ccd_list) c.minmax_clipping(min_clip=-500, max_clip=None) assert c.data_arr[1].mask.all()
def test_1Dweights(): ccd_list = [CCDData(np.zeros((10, 10)), unit=u.adu), CCDData(np.zeros((10, 10)) - 1000, unit=u.adu), CCDData(np.zeros((10, 10)) + 1000, unit=u.adu)] c = Combiner(ccd_list) c.weights = np.array([1, 5, 10]) ccd = c.average_combine() np.testing.assert_almost_equal(ccd.data, 312.5)
def test_combiner_minmax(): ccd_list = [CCDData(np.zeros((10, 10)), unit=u.adu), CCDData(np.zeros((10, 10)) - 1000, unit=u.adu), CCDData(np.zeros((10, 10)) + 1000, unit=u.adu)] c = Combiner(ccd_list) c.minmax_clipping(min_clip=-500, max_clip=500) ccd = c.median_combine() assert ccd.data.mean() == 0
def test_subtract_bias_fails(ccd_data): # Should fail if shapes don't match bias = CCDData(np.array([200, 200]), unit=u.adu) with pytest.raises(ValueError): subtract_bias(ccd_data, bias) # should fail because units don't match bias = CCDData(np.zeros_like(ccd_data), unit=u.meter) with pytest.raises(u.UnitsError): subtract_bias(ccd_data, bias)
def test_flat_correct_data_uncertainty(): # Regression test for #345 dat = CCDData(np.ones([100, 100]), unit='adu', uncertainty=np.ones([100, 100])) # Note flat is set to 10, error, if present, is set to one. flat = CCDData(10 * np.ones([100, 100]), unit='adu') res = flat_correct(dat, flat) assert (res.data == dat.data).all() assert (res.uncertainty.array == dat.uncertainty.array).all()
def test_combiner_uncertainty_average(): ccd_list = [CCDData(np.ones((10, 10)), unit=u.adu), CCDData(np.ones((10, 10)) * 2, unit=u.adu)] c = Combiner(ccd_list) ccd = c.average_combine() # Just the standard deviation of ccd data. ref_uncertainty = np.ones((10, 10)) / 2 # Correction because we combined two images. ref_uncertainty /= np.sqrt(2) np.testing.assert_array_almost_equal(ccd.uncertainty.array, ref_uncertainty)
def test_subtract_dark_fails(): ccd_data = ccd_data_func() # None of these tests check a result so the content of the master # can be anything. ccd_data.header['exptime'] = 30.0 master = ccd_data.copy() # Do we fail if we give one of dark_exposure, data_exposure but not both? with pytest.raises(TypeError): subtract_dark(ccd_data, master, dark_exposure=30 * u.second) with pytest.raises(TypeError): subtract_dark(ccd_data, master, data_exposure=30 * u.second) # Do we fail if we supply dark_exposure and data_exposure and exposure_time with pytest.raises(TypeError): subtract_dark(ccd_data, master, dark_exposure=10 * u.second, data_exposure=10 * u.second, exposure_time='exptime') # Fail if we supply none of the exposure-related arguments? with pytest.raises(TypeError): subtract_dark(ccd_data, master) # Fail if we supply exposure time but not a unit? with pytest.raises(TypeError): subtract_dark(ccd_data, master, exposure_time='exptime') # Fail if ccd_data or master are not CCDData objects? with pytest.raises(TypeError): subtract_dark(ccd_data.data, master, exposure_time='exptime') with pytest.raises(TypeError): subtract_dark(ccd_data, master.data, exposure_time='exptime') # Fail if units do not match... # ...when there is no scaling? master = CCDData(ccd_data) master.unit = u.meter with pytest.raises(u.UnitsError) as e: subtract_dark(ccd_data, master, exposure_time='exptime', exposure_unit=u.second) assert "uncalibrated image" in str(e.value) # Fail when the arrays are not the same size with pytest.raises(ValueError): small_master = CCDData(ccd_data) small_master.data = np.zeros((1, 1)) subtract_dark(ccd_data, small_master)
def test_ccdmask_not_2d(): # Fails when a CCDData has less than 2 dimensions with pytest.raises(ValueError): ccdmask(CCDData(np.ones(3), unit='adu')) # Fails when scalar with pytest.raises(ValueError): ccdmask(CCDData(np.array(10), unit='adu')) # Fails when more than 2d with pytest.raises(ValueError): ccdmask(CCDData(np.ones((3, 3, 3)), unit='adu'))
def preproc(fnames, mbias, mflat, min_value=0, crrej=False): if not isinstance(mbias, CCDData): master_bias = CCDData(data=mbias, unit='adu') else: master_bias = mbias.copy() if not isinstance(mflat, CCDData): master_flat = CCDData(data=mflat, unit='adu') else: master_flat = mflat.copy() processed_ccds = [] for fname in fnames: print('Preprocessing started for {:s}'.format(fname)) obj_p = CCDData(fits.getdata(fname), meta=fits.getheader(fname), unit='adu') gain = obj_p.header['gain'] xbin = obj_p.header['bin-fct1'] chip = obj_p.header['det-id'] # TODO: change ccd.data to just ccd (after ccdproc ver>1.3 release) # TODO: gain value differs from ch to ch. if crrej: ronoise = 4.0 import astroscrappy # TODO: implement spec crrej m, obj_p.data = astroscrappy.detect_cosmics(obj_p.data, satlevel=np.inf, sepmed=False, cleantype='medmask', fsmode='median', gain=gain, readnoise=ronoise) # TODO: Use ccdproc when ccdproc 1.3 is released # obj_p = subtract_bias(obj_p, master_bias) # obj_p = flat_correct(obj_p, master_flat, min_value=min_value) # obj_p = gain_correct(obj_p, gain=gain, gain_unit=u.electron/u.adu) obj_p = (obj_p.data - master_bias) obj_p = suboverscan(data=obj_p, xbin=xbin, chip=chip, ybox=5) obj_p = obj_p / master_flat * np.mean(master_flat) obj_p = obj_p * gain obj_p.astype(np.float32) processed_ccds.append(obj_p) print('\tDone') return processed_ccds
def test_combiner_3d(): data1 = CCDData(3 * np.ones((5, 5, 5)), unit=u.adu) data2 = CCDData(2 * np.ones((5, 5, 5)), unit=u.adu) data3 = CCDData(4 * np.ones((5, 5, 5)), unit=u.adu) ccd_list = [data1, data2, data3] c = Combiner(ccd_list) assert c.data_arr.shape == (3, 5, 5, 5) assert c.data_arr.mask.shape == (3, 5, 5, 5) ccd = c.average_combine() assert ccd.shape == (5, 5, 5) np.testing.assert_array_almost_equal(ccd.data, data1, decimal=4)
def test_combiner_uncertainty_sum_mask(): mask = np.zeros((10, 10), dtype=np.bool_) mask[5, 5] = True ccd_with_mask = CCDData(np.ones((10, 10)), unit=u.adu, mask=mask) ccd_list = [ccd_with_mask, CCDData(np.ones((10, 10)) * 2, unit=u.adu), CCDData(np.ones((10, 10)) * 3, unit=u.adu)] c = Combiner(ccd_list) ccd = c.sum_combine() # Just the standard deviation of ccd data. ref_uncertainty = np.ones((10, 10)) * np.std([1, 2, 3]) ref_uncertainty *= np.sqrt(3) ref_uncertainty[5, 5] = np.std([2, 3]) * np.sqrt(2) np.testing.assert_array_almost_equal(ccd.uncertainty.array, ref_uncertainty)
def create_flat(flat_list,fil,red_path,mbias=None,log=None): log.info('Processing files for filter: '+fil) log.info(str(len(flat_list))+' files found.') flats = [] masks = [] flat_scale = [] for flat in flat_list: log.info('Loading file: '+flat) raw = CCDData.read(flat,unit=u.adu) red = ccdproc.ccd_process(raw, gain=raw.header['SYSGAIN']*u.electron/u.adu, readnoise=rdnoise(raw.header)*u.electron) log.info('Exposure time of image is '+str(red.header['TRUITIME']*red.header['COADDONE'])) mask = make_source_mask(red, nsigma=3, npixels=5) bkg = Background2D(red, (20, 20), filter_size=(3, 3),sigma_clip=SigmaClip(sigma=3), bkg_estimator=MeanBackground(), mask=mask, exclude_percentile=80) masked = np.array(red) masked[mask] = bkg.background[mask] log.info('Median flat level: '+str(np.median(masked))) norm = 1/np.median(masked[224:1824,224:1824]) log.info('Flat normalization: '+str(norm)) flat_scale.append(norm) flats.append(CCDData(masked,meta=red.header,unit=u.electron)) mflat = ccdproc.combine(flats,method='median',scale=flat_scale,sigma_clip=True) log.info('Created master flat for filter: '+fil) mflat.write(red_path+'mflat_'+fil+'.fits',overwrite=True) log.info('Master flat written to mflat_'+fil+'.fits') return
def vue_calculate_moment(self, event): #Retrieve the data cube and slice out desired region, if specified cube = self._selected_data.get_object(cls=SpectralCube) spec_min = float(self.spectral_min) * u.Unit(self.spectral_unit) spec_max = float(self.spectral_max) * u.Unit(self.spectral_unit) slab = cube.spectral_slab(spec_min, spec_max) # Calculate the moment and convert to CCDData to add to the viewers try: n_moment = int(self.n_moment) if n_moment < 0: raise ValueError("Moment must be a positive integer") except ValueError: raise ValueError("Moment must be a positive integer") self.moment = slab.moment(n_moment) moment_ccd = CCDData(self.moment.array, wcs=self.moment.wcs, unit=self.moment.unit) label = "Moment {}: {}".format(n_moment, self._selected_data.label) fname_label = self._selected_data.label.replace("[", "_").replace("]", "_") self.filename = "moment{}_{}.fits".format(n_moment, fname_label) self.data_collection[label] = moment_ccd self.moment_available = True msg = SnackbarMessage("{} added to data collection".format(label), sender=self, color="success") self.hub.broadcast(msg)
def test_medianfilter_correct(): ccd = CCDData([[2, 6, 6, 1, 7, 2, 4, 5, 9, 1], [10, 10, 9, 0, 2, 10, 8, 3, 9, 7], [2, 4, 0, 4, 4, 10, 0, 5, 6, 5], [7, 10, 8, 7, 7, 0, 5, 3, 5, 9], [9, 6, 3, 8, 6, 9, 2, 8, 10, 10], [6, 5, 1, 7, 8, 0, 8, 2, 9, 3], [0, 6, 0, 6, 3, 10, 8, 9, 7, 8], [5, 8, 3, 2, 3, 0, 2, 0, 3, 5], [9, 6, 3, 7, 1, 0, 5, 4, 8, 3], [5, 6, 9, 9, 0, 4, 9, 1, 7, 8]], unit='adu') result = core.median_filter(ccd, 3) assert isinstance(result, CCDData) assert np.all(result.data == [[6, 6, 6, 6, 2, 4, 4, 5, 5, 7], [4, 6, 4, 4, 4, 4, 5, 5, 5, 6], [7, 8, 7, 4, 4, 5, 5, 5, 5, 7], [7, 6, 6, 6, 7, 5, 5, 5, 6, 9], [7, 6, 7, 7, 7, 6, 3, 5, 8, 9], [6, 5, 6, 6, 7, 8, 8, 8, 8, 8], [5, 5, 5, 3, 3, 3, 2, 7, 5, 5], [6, 5, 6, 3, 3, 3, 4, 5, 5, 5], [6, 6, 6, 3, 2, 2, 2, 4, 4, 5], [6, 6, 7, 7, 4, 4, 4, 7, 7, 8]]) assert result.unit == 'adu' assert all(getattr(result, attr) is None for attr in ['mask', 'uncertainty', 'wcs', 'flags']) # The following test could be deleted if log_to_metadata is also applied. assert not result.meta
def ccd_data(request): """ Return a CCDData object with units of ADU. The size of the data array is 100x100 but can be changed using the marker @pytest.mark.data_size(N) on the test function, where N should be the desired dimension. Data values are initialized to random numbers drawn from a normal distribution with mean of 0 and scale 1. The scale can be changed with the marker @pytest.marker.scale(s) on the test function, where s is the desired scale. The mean can be changed with the marker @pytest.marker.scale(m) on the test function, where m is the desired mean. """ size = value_from_markers('data_size', request) scale = value_from_markers('data_scale', request) mean = value_from_markers('data_mean', request) with NumpyRNGContext(DEFAULTS['seed']): data = np.random.normal(loc=mean, size=[size, size], scale=scale) fake_meta = {'my_key': 42, 'your_key': 'not 42'} ccd = CCDData(data, unit=u.adu) ccd.header = fake_meta return ccd
def download_ps1_image(filename, saveas=None): """ Download image from PS1 and correct luptitudes back to a linear scale. Parameters --------------- filename : PS1 image filename (from `get_ps1_filename`) saveas : Path to save template file (default: do not save) Output --------------- ccddata : CCDData format of data with WCS """ res = requests.get('http://ps1images.stsci.edu' + filename) hdulist = fits.open(BytesIO(res.content)) # Linearize from luptitudes boffset = hdulist[1].header['boffset'] bsoften = hdulist[1].header['bsoften'] data_linear = boffset + bsoften * 2 * np.sinh(hdulist[1].data * np.log(10.) / 2.5) warnings.simplefilter('ignore') # ignore warnings from nonstandard PS1 header keywords ccddata = CCDData(data_linear, wcs=WCS(hdulist[1].header), unit='adu') # Save the template to file if saveas is not None: ccddata.write(saveas, overwrite=True) return ccddata
def test_flat_correct_does_not_change_input(): ccd_data = ccd_data_func() original = ccd_data.copy() flat = CCDData(np.zeros_like(ccd_data), unit=ccd_data.unit) ccd = flat_correct(ccd_data, flat=flat) np.testing.assert_array_equal(original.data, ccd_data.data) assert original.unit == ccd_data.unit
def sum_combine(self, sum_func=ma.sum, scale_to=None, uncertainty_func=ma.std): """ Sum combine together a set of arrays. A `~astropy.nddata.CCDData` object is returned with the data property set to the sum of the arrays. If the data was masked or any data have been rejected, those pixels will not be included in the sum. A mask will be returned, and if a pixel has been rejected in all images, it will be masked. The uncertainty of the combined image is set by the multiplication of summation of standard deviation of the input by square root of number of images. Because sum_combine returns 'pure sum' with masked pixels ignored, if re-scaled sum is needed, average_combine have to be used with multiplication by number of images combined. Parameters ---------- sum_func : function, optional Function to calculate the sum. Defaults to `numpy.ma.sum`. scale_to : float or None, optional Scaling factor used in the sum combined image. If given, it overrides `scaling`. Defaults to ``None``. uncertainty_func : function, optional Function to calculate uncertainty. Defaults to `numpy.ma.std`. Returns ------- combined_image: `~astropy.nddata.CCDData` CCDData object based on the combined input of CCDData objects. """ # set up the data data = sum_func(self._get_scaled_data(scale_to), axis=0) # set up the mask masked_values = self.data_arr.mask.sum(axis=0) mask = (masked_values == len(self.data_arr)) # set up the deviation uncertainty = uncertainty_func(self.data_arr, axis=0) # Divide uncertainty by the number of pixel (#309) uncertainty /= np.sqrt(len(self.data_arr) - masked_values) # Convert uncertainty to plain numpy array (#351) uncertainty = np.asarray(uncertainty) # Multiply uncertainty by square root of the number of images uncertainty *= len(self.data_arr) - masked_values # create the combined image with a dtype that matches the combiner combined_image = CCDData(np.asarray(data.data, dtype=self.dtype), mask=mask, unit=self.unit, uncertainty=StdDevUncertainty(uncertainty)) # update the meta data combined_image.meta['NCOMBINE'] = len(self.data_arr) # return the combined image return combined_image
def test_adding_markers_as_world_recovers_with_get_markers(): """ Make sure that our internal conversion from world to pixel coordinates doesn't mess anything up. """ npix_side = 100 fake_image = np.random.randn(npix_side, npix_side) wcs = WCS(naxis=2) wcs.wcs.crpix = (fake_image.shape[0] / 2, fake_image.shape[1] / 2) wcs.wcs.ctype = ('RA---TAN', 'DEC--TAN') wcs.wcs.crval = (314.275419158, 31.6662781301) wcs.wcs.pc = [[0.000153051015113, -3.20700931602e-05], [3.20704370872e-05, 0.000153072382405]] fake_ccd = CCDData(data=fake_image, wcs=wcs, unit='adu') iw = ImageWidget(pixel_coords_offset=0) iw.load_nddata(fake_ccd) # Get me 100 positions please, not right at the edge marker_locs = np.random.randint(10, high=npix_side - 10, size=(100, 2)) marks_pix = Table(data=marker_locs, names=['x', 'y']) marks_world = wcs.all_pix2world(marker_locs, 0) marks_coords = SkyCoord(marks_world, unit='degree') mark_coord_table = Table(data=[marks_coords], names=['coord']) iw.add_markers(mark_coord_table, use_skycoord=True) result = iw.get_markers() # Check the x, y positions as long as we are testing things... np.testing.assert_allclose(result['x'], marks_pix['x']) np.testing.assert_allclose(result['y'], marks_pix['y']) np.testing.assert_allclose(result['coord'].ra.deg, mark_coord_table['coord'].ra.deg) np.testing.assert_allclose(result['coord'].dec.deg, mark_coord_table['coord'].dec.deg)
def test_meta_round_trip(): wcs = WCS(naxis=2) wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] meta = {'BUNIT': 'Jy/beam', 'some_variable': 10} spec = CCDData([[2, 3], [4, 5]] * u.Jy, wcs=wcs, meta=meta) data_collection = DataCollection() data_collection['image'] = spec data = data_collection['image'] assert isinstance(data, Data) assert len(data.meta) == 2 assert data.meta['BUNIT'] == 'Jy/beam' assert data.meta['some_variable'] == 10 # Check round-tripping image_new = data.get_object(attribute='data') assert isinstance(image_new, CCDData) assert len(image_new.meta) == 2 assert image_new.meta['BUNIT'] == 'Jy/beam' assert image_new.meta['some_variable'] == 10
def test_flat_correct_min_value(ccd_data): size = ccd_data.shape[0] # create the flat data = 2 * np.random.normal(loc=1.0, scale=0.05, size=(size, size)) flat = CCDData(data, meta=fits.header.Header(), unit=ccd_data.unit) flat_orig_data = flat.data.copy() min_value = 2.1 # should replace some, but not all, values flat_corrected_data = flat_correct(ccd_data, flat, min_value=min_value) flat_with_min = flat.copy() flat_with_min.data[flat_with_min.data < min_value] = min_value # Check that the flat was normalized. The asserts below, which look a # little odd, are correctly testing that # flat_corrected_data = ccd_data / (flat_with_min / mean(flat_with_min)) np.testing.assert_almost_equal( (flat_corrected_data.data * flat_with_min.data).mean(), (ccd_data.data * flat_with_min.data.mean()).mean() ) np.testing.assert_allclose(ccd_data.data / flat_corrected_data.data, flat_with_min.data / flat_with_min.data.mean()) # Test that flat is not modified. assert (flat_orig_data == flat.data).all() assert flat_orig_data is not flat.data
def extract2d(self, hd, rows=None, plot=None): """ Extract 2D spectrum given trace(s) Assumes all requests row uses same trace, just offset, not a 2D model for traces """ nrows = hd.data.shape[0] ncols = hd.data.shape[-1] out = [] if plot is not None: plot.clear() plot.tv(hd) for model in self.model: if plot is not None: plot.ax.plot([0, ncols], [self.rows[0], self.rows[0]], color='g') plot.ax.plot([0, ncols], [self.rows[1], self.rows[1]], color='g') plt.draw() outrows = np.arange(self.rows[0], self.rows[1]) noutrows = len(range(self.rows[0], self.rows[1])) spec = np.zeros([noutrows, ncols]) sig = np.zeros([noutrows, ncols]) cr = model(np.arange(ncols)) cr -= cr[self.sc0] for col in range(ncols): spec[:, col] = np.interp(outrows + cr[col], np.arange(nrows), hd.data[:, col]) sig[:, col] = np.sqrt( np.interp(outrows + cr[col], np.arange(nrows), hd.uncertainty.array[:, col]**2)) out.append(CCDData(spec, StdDevUncertainty(sig), unit='adu')) if plot is not None: input(' enter something to continue....') if len(out) == 1: return out[0] else: return out
def test_block_replicate(): ccd = CCDData(np.ones((4, 4)), unit='adu', meta={'testkw': 1}, mask=np.zeros((4, 4), dtype=bool), uncertainty=StdDevUncertainty(np.ones((4, 4))), wcs=np.zeros((4, 4))) with catch_warnings(AstropyUserWarning) as w: ccd_repl = block_replicate(ccd, (2, 2)) assert len(w) == 1 assert 'following attributes were set' in str(w[0].message) assert isinstance(ccd_repl, CCDData) assert np.all(ccd_repl.data == 0.25) assert ccd_repl.data.shape == (8, 8) assert ccd_repl.unit == u.adu # Other attributes are set to None. In case the function is modified to # work on these attributes correctly those tests need to be updated! assert ccd_repl.meta == {'testkw': 1} assert ccd_repl.mask is None assert ccd_repl.wcs is None assert ccd_repl.uncertainty is None # Make sure meta is copied ccd_repl.meta['testkw2'] = 10 assert 'testkw2' not in ccd.meta
def to_object(self, data_or_subset, attribute=None): """ Convert a glue Data object to a CCDData object. Parameters ---------- data_or_subset : `glue.core.data.Data` or `glue.core.subset.Subset` The data to convert to a Spectrum1D object attribute : `glue.core.component_id.ComponentID` The attribute to use for the Spectrum1D data """ if isinstance(data_or_subset, Subset): data = data_or_subset.data subset_state = data_or_subset.subset_state else: data = data_or_subset subset_state = None if isinstance(data.coords, WCS): wcs = data.coords elif type(data.coords) is Coordinates or data.coords is None: wcs = None else: raise TypeError( 'data.coords should be an instance of Coordinates or WCS') if isinstance(attribute, str): attribute = data.id[attribute] elif len(data.main_components) == 0: raise ValueError('Data object has no attributes.') elif attribute is None: if len(data.main_components) == 1: attribute = data.main_components[0] else: raise ValueError( "Data object has more than one attribute, so " "you will need to specify which one to use as " "the flux for the spectrum using the " "attribute= keyword argument.") component = data.get_component(attribute) if data.ndim != 2: raise ValueError( "Only 2-dimensional datasets can be converted to CCDData") values = data.get_data(attribute) if subset_state is None: mask = None else: mask = data.get_mask(subset_state=subset_state) values = values.copy() # Flip mask to match astropy.ndddata formalism mask = ~mask values = values * u.Unit(component.units) return CCDData(values, mask=mask, wcs=wcs, meta=data.meta)
def sum(self,ims, return_list=False, **kwargs) : """ Coadd input images """ allcube = self.getcube(ims, **kwargs) nframe = len(allcube) out=[] for chip in range(self.nchip) : datacube = [] varcube = [] maskcube = [] for im in range(nframe) : datacube.append(allcube[im][chip].data) varcube.append(allcube[im][chip].uncertainty.array**2) maskcube.append(allcube[im][chip].mask) sum = np.sum(np.array(datacube),axis=0) sig = np.sqrt(np.sum(np.array(varcube),axis=0)) mask = np.any(maskcube,axis=0) out.append(CCDData(sum,uncertainty=StdDevUncertainty(sig),mask=mask,unit='adu')) # return the frame if len(out) == 1 : if return_list : return [out[0]] else : return out[0] else : return out
def read_ss_image(self, filepath): ''' read sky subtracted image from "filepath" ''' hdu = fits.open(filepath) self.ss_data = CCDData(hdu[0].data, unit=self.data.unit) self.ss_data.mask = self.data.mask.copy()
def test_subtract_bias_does_not_change_input(): ccd_data = ccd_data_func() original = ccd_data.copy() master_frame = CCDData(np.zeros_like(ccd_data), unit=ccd_data.unit) ccd = subtract_bias(ccd_data, master=master_frame) np.testing.assert_array_equal(original.data, ccd_data.data) assert original.unit == ccd_data.unit