def mask_object(cube, decimate=False, remove_nan=False, **kwargs): obj_rmin = kwargs.get('obj_rmin', None) obj_rmax = kwargs.get('obj_rmax', None) if obj_rmin is not None or obj_rmax is not None: obj_mask = solar.define_map_mask(cube, **kwargs) # decimate is mandatory to remove nan because NaN * 0 = NaN if decimate or remove_nan: Mo = lo.decimate(obj_mask, dtype=cube.dtype) else: Mo = lo.ndmask(obj_mask, dtype=cube.dtype) return Mo, obj_mask
def stsrt(data, cube, **kwargs): """ Smooth Temporal Solar Rotational Tomography. Assumes data is sorted by observation time 'DATE_OBS'. Returns ------- P : The projector with masking D : Smoothness priors obj_mask : object mask array data_mask : data mask array """ # Parse kwargs. obj_rmin = kwargs.get('obj_rmin', None) obj_rmax = kwargs.get('obj_rmax', None) # mask data data_mask = solar.define_data_mask(data, **kwargs) # define temporal groups times = [solar.convert_time(h['DATE_OBS']) for h in data.header] ## if no interval is given separate every image dt_min = kwargs.get('dt_min', np.max(np.diff(times)) + 1) #groups = solar.temporal_groups(data, dt_min) ind = solar.temporal_groups_indexes(data, dt_min) n = len(ind) # define new 4D cube cube4 = cube[..., np.newaxis].repeat(n, axis=-1) cube4.header = copy.copy(cube.header) cube4.header['NAXIS'] = 4 cube4.header['NAXIS4'] = cube4.shape[3] # define 4d model # XXX assumes all groups have same number of elements ng = data.shape[-1] / n P = siddon4d_lo(data.header, cube4.header, ng=ng, mask=data_mask, obstacle="sun") # priors D = smoothness_prior(cube4, kwargs.get("height_prior", False)) # mask object if obj_rmin is not None or obj_rmax is not None: Mo, obj_mask = mask_object(cube, **kwargs) obj_mask = obj_mask[..., np.newaxis].repeat(n, axis=-1) if kwargs.get("decimate", False) or kwargs.get("remove_nan", False): Mo = lo.decimate(obj_mask) else: Mo = lo.ndmask(obj_mask) P = P * Mo.T D = [Di * Mo.T for Di in D] else: obj_mask = None return P, D, obj_mask, data_mask
def check_model(model, im_h, obj_h): obj = siddon.simu.object_from_header(obj_h) obj = siddon.fa.InfoArray(data=obj, header=dict(obj.header)) obj[:] = 1. im_h['n_images'] = 100 im_h['max_lon'] = 3 * np.pi data = siddon.simu.circular_trajectory_data(**im_h) if obj.dtype == data.dtype: P, D, obj_mask, data_mask = model(data, obj, obj_rmin=1., decimate=True) Mo = lo.decimate(obj_mask) w = (Mo.T * (P.T * np.ones(data.size))).reshape(obj_mask.shape) is_seen = (w != 0) new_obj = fa.FitsArray(obj_mask.shape) new_obj = 1. new_obj *= (1 - obj_mask) data[:] = (P * Mo * new_obj.ravel()).reshape(data.shape) hypers = new_obj.ndim * (1e-10, ) sol = lo.acg(P, data.ravel(), D, hypers=hypers, tol=1e-20) sol = fa.asfitsarray((Mo.T * sol).reshape(obj_mask.shape), header=obj.header) assert_almost_equal(sol[is_seen], new_obj[is_seen], decimal=1)
# define masking of coefficients # ------------------------------ # number of coefficients to keep factor = 8. nk = P.shape[0] / factor # coverage map w = P.T * np.ones(P.shape[0]) # sort coverage map coefficients ws = np.sort(w) # find the nk largest coverage elements threshold = ws[-nk] mask = w < threshold # define decimation Linear Operator according to coverage map coef # selection. M = lo.decimate(mask) # model is projection matrix time decimation matrix H = P * M.T # Store model matrix on hard-drive as FITS # --------------------------------------------- # convert LinearOperator to dense matrix (ndarray) Hd = H.todense() Hd = np.asmatrix(Hd) # convert into my FitsArray : Hd_fits = fa.FitsArray(data=Hd) # save the model to defined filename filename = os.path.join(os.getenv("HOME"), "data", "pacs", "mmc_model_cam_angle_0_scan_angle_0_speed60.fits") Hd_fits.tofits(filename)