def save_best_2comp_fit(reg): # should be renamed to determine_best_2comp_fit or something along that line # currently use np.nan for pixels with no models ncomp = [1, 2] # ideally, a copy function should be in place of reloading # a new Region object is created start fresh on some of the functions (e.g., aic comparison) reg_final = Region(reg.cubePath, reg.paraNameRoot, reg.paraDir) # start out clean, especially since the deepcopy function doesn't work well for pyspeckit cubes # load the file based on the passed in reg, rather than the default for nc in ncomp: if not str(nc) in reg.ucube.pcubes: reg_final.load_fits(ncomp=[nc]) else: # load files using paths from reg if they exist print("loading model from: {}".format(reg.ucube.paraPaths[str(nc)])) reg_final.ucube.load_model_fit(filename=reg.ucube.paraPaths[str(nc)], ncomp=nc) pcube_final = reg_final.ucube.pcubes['2'].copy('deep') # make the 2-comp para maps with the best fit model lnk21 = reg_final.ucube.get_AICc_likelihood(2, 1) mask = lnk21 > 5 print("2comp pix: {}".format(np.sum(mask))) pcube_final.parcube[:4, ~mask] = reg_final.ucube.pcubes['1'].parcube[:4, ~mask].copy() pcube_final.errcube[:4, ~mask] = reg_final.ucube.pcubes['1'].errcube[:4, ~mask].copy() pcube_final.parcube[4:8, ~mask] = np.nan pcube_final.errcube[4:8, ~mask] = np.nan lnk10 = reg_final.ucube.get_AICc_likelihood(1, 0) mask = lnk10 > 5 pcube_final.parcube[:, ~mask] = np.nan pcube_final.errcube[:, ~mask] = np.nan # use the default file formate to save the finals nc = 2 if not str(nc) in reg_final.ucube.paraPaths: reg_final.ucube.paraPaths[str(nc)] = '{}/{}_{}vcomp.fits'.format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot, nc) savename = "{}_final.fits".format(os.path.splitext(reg_final.ucube.paraPaths['2'])[0]) UCube.save_fit(pcube_final, savename=savename, ncomp=2) hdr2D =reg.ucube.cube.wcs.celestial.to_header() # save the lnk21 map savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para","lnk21")) save_map(lnk21, hdr2D, savename) # save the lnk10 map savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para","lnk10")) save_map(lnk10, hdr2D, savename) # create and save the lnk20 map for reference: lnk20 = reg_final.ucube.get_AICc_likelihood(2, 0) savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para","lnk20")) save_map(lnk20, hdr2D, savename) # save the SNR map snr_map = get_best_2comp_snr_mod(reg_final) savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para","SNR")) save_map(snr_map, hdr2D, savename) # create moment0 map modbest = get_best_2comp_model(reg_final) cube_mod = SpectralCube(data=modbest, wcs=reg_final.ucube.pcubes['2'].wcs.copy(), header=reg_final.ucube.pcubes['2'].header.copy()) # make sure the spectral unit is in km/s before making moment maps cube_mod = cube_mod.with_spectral_unit('km/s', velocity_convention='radio') mom0_mod = cube_mod.moment0() savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para", "model_mom0")) mom0_mod.write(savename, overwrite=True) # created masked mom0 map with model as the mask mom0 = UCube.get_masked_moment(cube=reg_final.ucube.cube, model=modbest, order=0, expand=20, mask=None) savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para", "mom0")) mom0.write(savename, overwrite=True) # save reduced chi-squred maps # would be useful to check if 3rd component is needed savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para", "chi2red_final")) chi_map = UCube.get_chisq(cube=reg_final.ucube.cube, model=modbest, expand=20, reduced=True, usemask=True, mask=None) save_map(chi_map, hdr2D, savename) # save reduced chi-squred maps for 1 comp and 2 comp individually chiRed_1c = reg_final.ucube.get_reduced_chisq(1) chiRed_2c = reg_final.ucube.get_reduced_chisq(2) savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para", "chi2red_1c")) save_map(chiRed_1c, hdr2D, savename) savename = "{}/{}.fits".format(reg_final.ucube.paraDir, reg_final.ucube.paraNameRoot.replace("para", "chi2red_2c")) save_map(chiRed_2c, hdr2D, savename) return reg
p.subplot(122) p.imshow(pv.data, cmap="binary", origin="lower") p.colorbar() p.show() hdu.close() # Now examine a subsection of the region that overlaps with the edge of # NGC-1333. I'm not sure the instrument that took the data, but it maps # 13CO(1-0) too. sc = SpectralCube.read("/srv/astro/surveys/classy/N1333.13co.fits") sc = sc[150:300, :, :] ends = [(57, 72), (73, 83), (105, 85)] xy = Path(ends, width=10) pv = extract_pv_slice(sc, xy) p.subplot(121) p.imshow(sc.moment0().value, cmap="binary", origin="lower") p.plot([i for i, j in ends], [j for i, j in ends], 'b-') p.subplot(122) p.imshow(pv.data, cmap="binary", origin="lower") p.colorbar() p.show()
class ObsCube(object): """ A wrapping class of SpectralCube which prepares observational data cubes to be compared to any other data cube. Parameters ---------- cube : str Path to file. mask : numpy.ndarray, any mask class from spectral_cube, optional Mask to be applied to the cube. algorithm : {NAME HERE}, optional Name of the cleaning algorithm to use. Example ------- ``` from turbustat.cube_tools import ObsCube cube = ObsCube("data.fits") cube.apply_cleaning(algorithm="SUPERAWESOMECLEANING") ``` """ def __init__(self, cube, mask=None, algorithm=None, beam=None): raise NotImplementedError("ObsCube is not yet implemented for " "general use.") super(ObsCube, self).__init__() self.cube = SpectralCube.read(cube) self.algorithm = algorithm # Make sure mask is an accepted type if mask is not None: _check_mask(mask) self.mask = mask if beam is not None: _check_beam(beam) self.noise = Noise(self.cube, beam=beam) def clean_cube(self, algorithm=None): raise NotImplementedError("") def apply_mask(self, mask=None): ''' Check if the given mask is acceptable abd apply to SpectralCube. ''' # Update mask if mask is not None: _check_mask(mask) self.mask = mask # Create the mask, auto masking nan values default_mask = np.isfinite(self.cube.filled_data[:]) if self.mask is not None: self.mask = CompositeMask(default_mask, self.mask) else: self.mask = default_mask # Apply mask to spectral cube object self.cube = self.cube.with_mask(mask) return self def _update(self, data=None, wcs=None, beam=None, method="MAD"): ''' Helper function to update classes. ''' # Check if we need a new SpectralCube if data is None and wcs is None: pass else: if data is None: data = self.cube.unmasked_data[:] if wcs is None: wcs = self.cube.wcs # Make new SpectralCube object self.cube = SpectralCube(data=data, wcs=wcs) if beam is not None: _check_beam(beam) self.noise = Noise(self.cube, beam=beam, method=method) def compute_properties(self): ''' Use SpectralCube to compute the moments. Also compute the integrated intensity based on the noise properties from Noise. ''' self._moment0 = self.cube.moment0().value self._moment1 = self.cube.moment1().value self._moment2 = self.cube.moment2().value _get_int_intensity(self) return self @property def moment0(self): return self._moment0 @property def moment1(self): return self._moment1 @property def moment2(self): return self._moment2 @property def intint(self): return self._intint def prep(self, mask=None, algorithm=None): ''' Prepares the cube to be compared to another cube. ''' if not mask is None: self.apply_mask() self.clean_cube() self.compute_properties() return self
class SimCube(object): ''' A wrapping class to prepare a simulated spectral data cube for comparison with another cube. ''' def __init__(self, cube, beam=None, mask=None, method="MAD", compute=True): # Initialize cube object self.cube = SpectralCube.read(cube) if mask is not None: _check_mask(mask) self.mask = mask if beam is not None: _check_beam(mask) # Initialize noise object self.noise = Noise(self.cube, beam=beam, method=method) def add_noise(self): ''' Use Noise to add synthetic noise to the data. Then update SpectralCube. ''' # Create the noisy cube self.noise.get_noise_cube() noise_data = self.noise.noise_cube +\ self.cube.filled_data[:] # Update SpectralCube object self._update(data=noise_data) return self def clean_cube(self, algorithm=None): raise NotImplementedError("") def apply_mask(self, mask=None): ''' Check if the given mask is acceptable abd apply to SpectralCube. ''' # Update mask if mask is not None: _check_mask(mask) self.mask = mask # Create the mask, auto masking nan values default_mask = np.isfinite(self.cube.filled_data[:]) if self.mask is not None: self.mask = CompositeMask(default_mask, self.mask) else: self.mask = default_mask # Apply mask to spectral cube object self.cube = self.cube.with_mask(mask) return self def _update(self, data=None, wcs=None, beam=None, method="MAD"): ''' Helper function to update classes. ''' # Check if we need a new SpectralCube if data is None and wcs is None: pass else: if data is None: data = self.cube.unmasked_data[:] if wcs is None: wcs = self.cube.wcs # Make new SpectralCube object self.cube = SpectralCube(data=data, wcs=wcs) if beam is not None: _check_beam(beam) self.noise = Noise(self.cube, beam=beam, method=method) def compute_properties(self): ''' Use SpectralCube to compute the moments. Also compute the integrated intensity based on the noise properties from Noise. ''' self._moment0 = self.cube.moment0().value self._moment1 = self.cube.moment1().value self._moment2 = self.cube.moment2().value _get_int_intensity(self) return self @property def moment0(self): return self._moment0 @property def moment1(self): return self._moment1 @property def moment2(self): return self._moment2 @property def intint(self): return self._intint def sim_prep(self, mask=None): ''' Prepares the cube when being compared to another simulation. This entails: * Optionally applying a mask to the data. * Computing the cube's property arrays ''' if not mask is None: self.apply_mask() self.compute_properties() return self def obs_prep(self, mask=None): ''' Prepares the cube when being compared to observational data. This entails: * Optionally applying a mask to the data. * Add synthetic noise based on the cube's properties. * Computing the cube's property arrays ''' if not mask is None: self.apply_mask() self.add_noise() self.compute_properties() return self
class ObsCube(object): """ A wrapping class of SpectralCube which prepares observational data cubes to be compared to any other data cube. Parameters ---------- cube : str Path to file. mask : numpy.ndarray, any mask class from spectral_cube, optional Mask to be applied to the cube. algorithm : {NAME HERE}, optional Name of the cleaning algorithm to use. Example ------- ``` from turbustat.cube_tools import ObsCube cube = ObsCube("data.fits") cube.apply_cleaning(algorithm="SUPERAWESOMECLEANING") ``` """ def __init__(self, cube, mask=None, algorithm=None, beam=None): super(ObsCube, self).__init__() self.cube = sc.SpectralCube.read(cube) self.algorithm = algorithm # Make sure mask is an accepted type if mask is not None: _check_mask(mask) self.mask = mask if beam is not None: _check_beam(beam) self.noise = Noise(self.cube, beam=beam) def clean_cube(self, algorithm=None): raise NotImplementedError("") def apply_mask(self, mask=None): ''' Check if the given mask is acceptable abd apply to SpectralCube. ''' # Update mask if mask is not None: _check_mask(mask) self.mask = mask # Create the mask, auto masking nan values default_mask = np.isfinite(self.cube.filled_data[:]) if self.mask is not None: self.mask = CompositeMask(default_mask, self.mask) else: self.mask = default_mask # Apply mask to spectral cube object self.cube = self.cube.with_mask(mask) return self def _update(self, data=None, wcs=None, beam=None, method="MAD"): ''' Helper function to update classes. ''' # Check if we need a new SpectralCube if data is None and wcs is None: pass else: if data is None: data = self.cube.unmasked_data[:] if wcs is None: wcs = self.cube.wcs # Make new SpectralCube object self.cube = SpectralCube(data=data, wcs=wcs) if beam is not None: _check_beam(beam) self.noise = Noise(self.cube, beam=beam, method=method) def compute_properties(self): ''' Use SpectralCube to compute the moments. Also compute the integrated intensity based on the noise properties from Noise. ''' self._moment0 = self.cube.moment0().value self._moment1 = self.cube.moment1().value self._moment2 = self.cube.moment2().value _get_int_intensity(self) return self @property def moment0(self): return self._moment0 @property def moment1(self): return self._moment1 @property def moment2(self): return self._moment2 @property def intint(self): return self._intint def prep(self, mask=None, algorithm=None): ''' Prepares the cube to be compared to another cube. ''' if not mask is None: self.apply_mask() self.clean_cube() self.compute_properties() return self