def test_spatial_integration(): # ------------- # |12|13|14|15| # |--+--+--+--+ # | 8| 9|10|11| # |--+--+--+--+ # | 4| 5| 6| 7| # |--+--+--+--+ # | 0| 1| 2| 3| # ------------- # The plane center has world coordinates (0, 0) plane_shape = (4, 4) pixsize = 1 # um header = create_fitsheader(plane_shape, ctype=['X---CAR', 'Y---CAR'], cdelt=[pixsize, pixsize], crval=(0, 0), cunit=['um', 'um']) plane = SceneGrid.fromfits(header) def func(center, ncolmax, itype, ftype, expected): detectors = create_grid_squares((2, 2), Quantity(pixsize, 'um'), center=center) proj = plane.get_integration_operator(plane.topixel(detectors), ncolmax=ncolmax, dtype=ftype, dtype_index=itype) x = np.arange(len(plane)).reshape(plane_shape) y = proj(x) assert_equal(proj.matrix.dtype, ftype) assert_equal(proj.matrix.data.index.dtype, itype) assert_equal(proj.shapein, plane.shape) assert_equal(proj.shapeout, detectors.shape[:-2]) assert_equal(proj.matrix.shape, (4, len(plane))) expected_min_ncolmax = 1 if center == (0, 0) else 4 assert_equal(proj.matrix.data.shape, (4, max(expected_min_ncolmax, ncolmax))) assert_equal(proj.min_ncolmax, expected_min_ncolmax) assert_same(y, expected) centers = [(0, 0), (-0.5, 0.5)] ncolmaxs = (0, 1, 4, 5) expecteds = [[[9, 10], [5, 6]], [[0.25 * (8 + 9 + 12 + 13), 0.25 * (9 + 10 + 13 + 14)], [0.25 * (4 + 5 + 8 + 9), 0.25 * (5 + 6 + 9 + 10)]]] for center, expected in zip(centers, expecteds): for ncolmax in ncolmaxs: for itype in itypes: for ftype in ftypes: yield func, center, ncolmax, itype, ftype, expected
def test1(): # creation of the sky map msize = 50 mymap = gaussian(2*(msize*2+1,), 10, unit='Jy/pixel') cd = np.array([[-1., 0.],[0., 1.]]) / 3600. header = create_fitsheader(fromdata=mymap, crval=[53.,27.], cd=cd) mymap.header = header # creation of the simulation scan = PacsObservation.create_scan((header['CRVAL1'], header['CRVAL2']), instrument_angle=0., length=60, nlegs=1, angle=20.) simul = PacsSimulation(scan, 'red', policy_bad_detector='keep', policy_other='keep') # build the acquisition model model = CompressionAverageOperator(simul.slice.compression_factor) * \ simul.get_projection_operator(header=header, npixels_per_sample=49) # get the noiseless tod tod = model(mymap) filename = 'simul-'+str(uuid1())+'.fits' try: simul.save(filename, tod) simul2 = PacsObservation(filename, policy_bad_detector='keep', policy_other='keep') status2 = simul2.status tod2 = simul2.get_tod() finally: try: os.remove(filename) except: pass for field in simul.status.dtype.names: if field == 'BAND': continue assert_eq(simul.status[field], status2[field]) assert_eq(tod, tod2) fields = [x for x in simul.slice.dtype.names if x not in ('filename','unit')] for field in fields: if getattr(simul.slice[0], field) != getattr(simul2.slice[0], field): msg = "Field '" + field + "'" if field == 'scan_step': print(msg + ' not implemented.') else: assert False
def test_spatial_integration(): # ------------- # |12|13|14|15| # |--+--+--+--+ # | 8| 9|10|11| # |--+--+--+--+ # | 4| 5| 6| 7| # |--+--+--+--+ # | 0| 1| 2| 3| # ------------- # The plane center has world coordinates (0, 0) plane_shape = (4, 4) pixsize = 1 # um header = create_fitsheader( plane_shape, ctype=["X---CAR", "Y---CAR"], cdelt=[pixsize, pixsize], crval=(0, 0), cunit=["um", "um"] ) plane = SceneGrid.fromfits(header) def func(center, ncolmax, itype, ftype, expected): detectors = create_grid_squares((2, 2), Quantity(pixsize, "um"), center=center) proj = plane.get_integration_operator(plane.topixel(detectors), ncolmax=ncolmax, dtype=ftype, dtype_index=itype) x = np.arange(len(plane)).reshape(plane_shape) y = proj(x) assert_equal(proj.matrix.dtype, ftype) assert_equal(proj.matrix.data.index.dtype, itype) assert_equal(proj.shapein, plane.shape) assert_equal(proj.shapeout, detectors.shape[:-2]) assert_equal(proj.matrix.shape, (4, len(plane))) expected_min_ncolmax = 1 if center == (0, 0) else 4 assert_equal(proj.matrix.data.shape, (4, max(expected_min_ncolmax, ncolmax))) assert_equal(proj.min_ncolmax, expected_min_ncolmax) assert_same(y, expected) centers = [(0, 0), (-0.5, 0.5)] ncolmaxs = (0, 1, 4, 5) expecteds = [ [[9, 10], [5, 6]], [[0.25 * (8 + 9 + 12 + 13), 0.25 * (9 + 10 + 13 + 14)], [0.25 * (4 + 5 + 8 + 9), 0.25 * (5 + 6 + 9 + 10)]], ] for center, expected in zip(centers, expecteds): for ncolmax in ncolmaxs: for itype in itypes: for ftype in ftypes: yield func, center, ncolmax, itype, ftype, expected
def get_fpimage(qubic,SOURCE_POWER=1., SOURCE_THETA=np.radians(0), SOURCE_PHI=np.radians(45), NU=150e9,DELTANU_NU=0.25,npts=512,HORN_OPEN=None,display=True,background=True,saturation=True): bg=0 ### background power is 6 pW if background: bg=5.95e-12 ## power in watts at the location of the entry horns ## that and phi in radians LAMBDA = c / NU # [m] DELTANU = DELTANU_NU * NU # [Hz] FOCAL_LENGTH = 0.3 # [m] PRIMARY_BEAM_FWHM = 14 # [degrees] SECONDARY_BEAM_FWHM = 14 # [degrees] DETECTOR_OFFSET = [0, 0] # [m] SAT_POWER = 20e-12 # [W] NPOINT_DETECTOR_PLANE = npts**2 # number of detector plane sampling points DETECTOR_PLANE_LIMITS = (np.nanmin(qubic.detector.vertex[..., 0]), np.nanmax(qubic.detector.vertex[..., 0])) # [m] if HORN_OPEN is None: HORN_OPEN = ~qubic.horn.removed #all open ######## # BEAMS ######## primary_beam = GaussianBeam(PRIMARY_BEAM_FWHM) secondary_beam = GaussianBeam(SECONDARY_BEAM_FWHM, backward=True) ######## # HORNS ######## nhorn_open = np.sum(HORN_OPEN) horn_vec = np.column_stack([qubic.horn.center[HORN_OPEN], np.zeros(nhorn_open)]) ################# # DETECTOR PLANE ################# ndet_x = int(np.sqrt(NPOINT_DETECTOR_PLANE)) a = np.r_[DETECTOR_PLANE_LIMITS[0]:DETECTOR_PLANE_LIMITS[1]:ndet_x*1j] det_x, det_y = np.meshgrid(a, a) det_spacing = (DETECTOR_PLANE_LIMITS[1] - DETECTOR_PLANE_LIMITS[0]) / ndet_x det_vec = np.dstack([det_x, det_y, np.zeros_like(det_x) - FOCAL_LENGTH]) det_uvec = norm(det_vec) det_theta = np.arccos(det_uvec[..., 2]) # solid angle of a detector plane pixel (gnomonic projection) central_pixel_sr = np.arctan(det_spacing / FOCAL_LENGTH)**2 detector_plane_pixel_sr = -central_pixel_sr * np.cos(det_theta)**3 ############ # DETECTORS ############ qubic.detector.vertex += DETECTOR_OFFSET header = create_fitsheader((ndet_x, ndet_x), cdelt=det_spacing, crval=(0, 0), ctype=['X---CAR', 'Y---CAR'], cunit=['m', 'm']) detector_plane = DiscreteSurface.fromfits(header) integ = MaskOperator(qubic.detector.removed) * \ detector_plane.get_integration_operator(qubic.detector.vertex) ############### # COMPUTATIONS ############### """ Phase and transmission from the switches to the focal plane. """ transmission = np.sqrt(secondary_beam(det_theta) / secondary_beam.sr * detector_plane_pixel_sr)[..., None] const = 2j * pi / LAMBDA product = np.dot(det_uvec, horn_vec.T) modelA = ne.evaluate('transmission * exp(const * product)') """ Phase and transmission from the source to the switches. """ source_uvec = ang2vec(SOURCE_THETA, SOURCE_PHI) source_E = np.sqrt(SOURCE_POWER) * np.sqrt(primary_beam(SOURCE_THETA)) const = 2j * pi / LAMBDA product = np.dot(horn_vec, source_uvec) modelB = ne.evaluate('source_E * exp(const * product)') E = np.sum(modelA * modelB, axis=-1) I = np.abs(E)**2 D = integ(I) ########## # Adding Background power ########## nobol = D == 0 D[~nobol]+=bg ########## # NOISE ########## hplanck=6.62606957e-34 # [M2.kg/s] NEPbol = 4e-17 #[W/sqrt(hz)] N = np.sqrt(2*hplanck*NU*D + 2*D**2/DELTANU + NEPbol**2) N[nobol]=0 ########## # SATURATION ########## if saturation: saturated = D >= SAT_POWER D[saturated]=0 N[saturated]=0 ########## # DISPLAY ########## if display: mp.figure() mp.imshow(np.log10(I), interpolation='nearest', origin='lower') mp.autoscale(False) qubic.detector.plot(transform=detector_plane.topixel) mp.figure() mp.imshow(D, interpolation='nearest') mp.gca().format_coord = lambda x,y: 'x={} y={} z={}'.format(x, y, D[x,y]) mp.show() print('Given {} horns, we get {} W in the detector plane and {} W in the detec' 'tors.'.format(nhorn_open, np.sum(I), np.sum(D))) return(D,N)
################# # FOCAL PLANE ################# nfp_x = int(np.sqrt(NPOINT_FOCAL_PLANE)) a = np.r_[FOCAL_PLANE_LIMITS[0]:FOCAL_PLANE_LIMITS[1]:nfp_x * 1j] fp_x, fp_y = np.meshgrid(a, a) fp = np.dstack([fp_x, fp_y, np.full_like(fp_x, -qubic.optics.focal_length)]) fp_spacing = (FOCAL_PLANE_LIMITS[1] - FOCAL_PLANE_LIMITS[0]) / nfp_x ############ # DETECTORS ############ header = create_fitsheader((nfp_x, nfp_x), cdelt=fp_spacing, crval=(0, 0), ctype=['X---CAR', 'Y---CAR'], cunit=['m', 'm']) focal_plane = SceneGrid.fromfits(header) integ = MaskOperator(qubic.detector.all.removed) * \ focal_plane.get_integration_operator( focal_plane.topixel(qubic.detector.all.vertex[..., :2])) ############### # COMPUTATIONS ############### E = qubic._get_response(SOURCE_THETA, SOURCE_PHI, SOURCE_POWER, fp, fp_spacing**2, qubic.filter.nu, qubic.horn, qubic.primary_beam, qubic.secondary_beam) I = np.abs(E)**2 D = integ(I)
det_spacing = (DETECTOR_PLANE_LIMITS[1] - DETECTOR_PLANE_LIMITS[0]) / ndet_x det_vec = np.dstack([det_x, det_y, np.zeros_like(det_x) - FOCAL_LENGTH]) det_uvec = norm(det_vec) det_theta = np.arccos(det_uvec[..., 2]) # solid angle of a detector plane pixel (gnomonic projection) central_pixel_sr = np.arctan(det_spacing / FOCAL_LENGTH) ** 2 detector_plane_pixel_sr = -central_pixel_sr * np.cos(det_theta) ** 3 ############ # DETECTORS ############ qubic.detector.vertex += DETECTOR_OFFSET header = create_fitsheader( (ndet_x, ndet_x), cdelt=det_spacing, crval=(0, 0), ctype=["X---CAR", "Y---CAR"], cunit=["m", "m"] ) detector_plane = DiscreteSurface.fromfits(header) integ = MaskOperator(qubic.detector.removed) * detector_plane.get_integration_operator(qubic.detector.vertex) ######## # MODEL ######## def get_model_A(): """ Phase and transmission from the switches to the focal plane. """ transmission = np.sqrt(secondary_beam(det_theta) / secondary_beam.sr * detector_plane_pixel_sr)[..., None] const = 2j * pi / LAMBDA product = np.dot(det_uvec, horn_vec.T) return ne.evaluate("transmission * exp(const * product)")
def mapper_nl(tod, model, unpacking=None, priors=[], hypers=[], norms=[], comms=[], x0=None, tol=1.e-6, maxiter=300, solver=None, linesearch=None, descent_method='pr', M=None, verbose=True, callback=None, profile=None): comm_map = model.commin or MPI.COMM_WORLD comm_tod = model.commout or comm_map tod = _validate_tod(tod) if len(priors) == 0 and len(hypers) != 0: npriors = len(model.shapein) priors = [ DiscreteDifferenceOperator(axis=axis, shapein=model.shapein, commin=comm_map) for axis in range(npriors) ] else: npriors = len(priors) if np.isscalar(hypers): hypers = npriors * [hypers] elif npriors != len(hypers): raise ValueError('There should be one hyperparameter per prior.') if len(norms) == 0: norms = (npriors + 1) * [norm2] if len(comms) == 0: comms = [comm_tod] + npriors * [comm_map] if isinstance(M, DiagonalOperator): filter_nonfinite(M.data, out=M.data) hypers = np.asarray(hypers, dtype=var.FLOAT_DTYPE) ntods = int(np.sum(~tod.mask)) if getattr(tod, 'mask', None) is not None \ else tod.size ntods = comm_tod.allreduce(ntods) nmaps = comm_map.allreduce(model.shape[1]) hypers /= nmaps hypers = np.hstack([1 / ntods, hypers]) y = tod.view(np.ndarray).ravel() class ObjectiveFunction(Function): def __init__(self): pass def __call__(self, x, inwork=None, outwork=None, out=None): outwork = self.set_outwork(outwork, self.get_work(x)) return self.set_out(out, [ h * n(r,comm=c) for h, n, r, c in \ zip(hypers, norms, outwork, comms) ]) def D(self, x, inwork=None, outwork=None, out=None): inwork = self.get_work(x, inwork) return self.set_out( out, sum([ h * M.T * n.D(r, comm=c) for h, M, n, r, c in zip(hypers, [model] + priors, norms, inwork, comms) ])) def get_work(self, x, work=None): if work is not None: return work if unpacking is not None: x = unpacking.matvec(x) return [model * x - y] + [p * x for p in priors] objfunc = ObjectiveFunction() if linesearch is None: linesearch = QuadraticStep(hypers, norms, [model] + priors, comms, unpacking, comm_map) if callback is None: callback = CgCallback(verbose=verbose) time0 = time.time() solution = nlcg(objfunc, model.shape[1], M=M, maxiter=maxiter, tol=tol, descent_method=descent_method, linesearch=linesearch, callback=callback, comm=comm_map) time0 = time.time() - time0 Js = objfunc(solution) solution = unpacking(solution) tod[...] = 1 coverage = model.T(tod) header = getattr(coverage, 'header', None) if header is None: header = create_fitsheader(fromdata=coverage) unit = getattr(coverage, 'unit', None) derived_units = getattr(coverage, 'derived_units', None) coverage = Map(coverage.magnitude, header=header, copy=False) header.update('likeliho', Js[0]) header.update('criter', sum(Js)) header.update('hyper', str(hypers)) header.update('nsamples', ntods) header.update('npixels', nmaps) header.update('time', time0) if hasattr(callback, 'niterations'): header.update('niter', callback.niterations) header.update('maxiter', maxiter) if hasattr(callback, 'residual'): header.update('residual', callback.residual) header.update('tol', tol) header.update('solver', 'nlcg') output = Map(solution.reshape(model.shapein), header=header, coverage=coverage, unit=unit, derived_units=derived_units, copy=False) return output
def mapper_rls(y, H, invntt=None, unpacking=None, hyper=1.0, x0=None, tol=1.e-5, maxiter=300, M=None, solver=None, verbose=True, callback=None, criterion=True, profile=None): """ Solve the linear equation y = H(x) where H is an Operator representing the acquisition, and y is the observed time series. x is the regularised least square solution as given by: x = argmin (Hx-y)^T N^-1 (Hx-y) + h ||D(x)||^2 or: x = (H^T N^-1 H + h D1^T D1 + h D2^T D2)^-1 H^T N^-1 y """ comm_map = H.commin or MPI.COMM_WORLD comm_tod = H.commout or comm_map if solver is None: solver = cg new_solver = solver in (pcg, ) tod = _validate_tod(y) ntods_ = int(np.sum(~tod.mask)) if getattr(tod, 'mask', None) is not None \ else tod.size nmaps_ = unpacking.shape[1] if unpacking is not None else None if nmaps_ is None: nmaps_ = H.shape[1] if nmaps_ is None: raise ValueError('The model H has not an explicit input shape.') ntods = comm_tod.allreduce(ntods_) nmaps = comm_map.allreduce(nmaps_) # get A if invntt is None: invntt = IdentityOperator() A = H.T * invntt * H npriors = len(H.shapein) priors = [ DiscreteDifferenceOperator(axis=axis, shapein=H.shapein, commin=comm_map) for axis in range(npriors) ] if comm_map.rank == 0 or comm_map.size > 1: A += sum((hyper * ntods / nmaps) * p.T * p for p in priors) # get b b = (H.T * invntt)(tod) if not np.all(np.isfinite(b)): raise ValueError('RHS contains non-finite values.') if b.shape != A.shapein: raise ValueError("Incompatible size for RHS: '" + str(b.size) + "' instead of '" + str(A.shape[1]) + "'.") if np.min(b) == np.max(b) == 0: print('Warning: in equation Ax=b, b is zero.') # unpack input if unpacking is None: unpacking = IdentityOperator() A = unpacking.T * A * unpacking b = unpacking.T(b) if x0 is not None: x0 = unpacking.T(x0) if not new_solver and solver is not cg: b = b.ravel() if x0 is not None: x0 = x0.ravel() if M is not None: if isinstance(M, DiagonalOperator): filter_nonfinite(M.data, out=M.data) M = unpacking.T * M * unpacking H_ = H * unpacking priors = [p * unpacking for p in priors] # criterion if hyper != 0: hc = np.hstack([1, npriors * [hyper]]) / ntods else: hc = [1 / ntods] norms = [norm2_ellipsoid(invntt)] + npriors * [norm2] comms = [comm_tod] + npriors * [comm_map] def criter(x): rs = [H_.matvec(x) - tod.view(np.ndarray).ravel() ] + [p.matvec(x) for p in priors] Js = [h * n(r, comm=c) for h, n, r, c in zip(hc, norms, rs, comms)] return Js if callback is None: if new_solver: callback = NewCgCallback(disp=verbose, comm=comm_map) else: callback = CgCallback(verbose=verbose, objfunc=criter if criterion else None) if (verbose or profile) and comm_map.rank == 0: print('') print('H.T * N^-1 * H:') print(repr(A)) if M is not None: print('Preconditioner:') print(M) time0 = time.time() if profile is not None: def run(): result = solver(A, b, x0=x0, M=M, tol=tol, maxiter=maxiter) if new_solver: solution = result['x'] if not result['success']: print('Solver failure: ' + result['message']) else: solution, info = result if info != 0: print('Solver failure: info=' + str(info)) cProfile.runctx('run()', globals(), locals(), profile + '.prof') print('Profile time: ' + str(time.time() - time0)) os.system('python -m gprof2dot -f pstats -o ' + profile + '.dot ' + profile + '.prof') os.system('dot -Tpng ' + profile + '.dot > ' + profile) os.system('rm -f ' + profile + '.prof' + ' ' + profile + '.dot') return None result = solver(A, b, x0=x0, M=M, tol=tol, maxiter=maxiter, callback=callback) time0 = time.time() - time0 if new_solver: solution = result['x'] if not result['success']: print('Solver failure: ' + result['message']) niterations = result['niterations'] error = result['error'] else: solution, info = result if info < 0: raise RuntimeError('Solver failure (code=' + str(info) + ' after ' + str(callback.niterations) + ' iterations).') if info > 0 and comm_map.rank == 0: print( 'Warning: Solver reached maximum number of iterations without' ' reaching specified tolerance.') niterations = getattr(callback, 'niterations', None) error = getattr(callback, 'residual', None) Js = criter(solution) if isinstance(unpacking, IdentityOperator): solution = solution.reshape(H.shapein) else: solution = unpacking(solution) tod[...] = 1 coverage = H.T(tod) unit = getattr(coverage, 'unit', None) derived_units = getattr(coverage, 'derived_units', None) coverage = coverage.view(Map) header = getattr(coverage, 'header', None) if header is None: header = create_fitsheader(fromdata=coverage) header.update('likeliho', Js[0]) header.update('criter', sum(Js)) header.update('hyper', hyper) header.update('nsamples', ntods) header.update('npixels', nmaps) header.update('time', time0) if niterations is not None: header.update('niter', niterations) header.update('maxiter', maxiter) if error is not None: header.update('error', error) header.update('tol', tol) header.update('solver', solver.__name__) output = Map(solution, header=header, coverage=coverage, unit=unit, derived_units=derived_units, copy=False) return output
################# # FOCAL PLANE ################# nfp_x = int(np.sqrt(NPOINT_FOCAL_PLANE)) a = np.r_[FOCAL_PLANE_LIMITS[0]:FOCAL_PLANE_LIMITS[1]:nfp_x*1j] fp_x, fp_y = np.meshgrid(a, a) fp = np.dstack([fp_x, fp_y, np.full_like(fp_x, -qubic.optics.focal_length)]) fp_spacing = (FOCAL_PLANE_LIMITS[1] - FOCAL_PLANE_LIMITS[0]) / nfp_x ############ # DETECTORS ############ header = create_fitsheader((nfp_x, nfp_x), cdelt=fp_spacing, crval=(0, 0), ctype=['X---CAR', 'Y---CAR'], cunit=['m', 'm']) focal_plane = SceneGrid.fromfits(header) integ = MaskOperator(qubic.detector.all.removed) * \ focal_plane.get_integration_operator( focal_plane.topixel(qubic.detector.all.vertex[..., :2])) ############### # COMPUTATIONS ############### # we make sure that exacty 1 W goes through the open horns SOURCE_POWER = 1 / (np.sum(qubic.horn.open) * np.pi * qubic.horn.radius**2) E = qubic._get_response(SOURCE_THETA, SOURCE_PHI, SOURCE_POWER, fp, fp_spacing**2, qubic.filter.nu, qubic.horn, qubic.primary_beam, qubic.secondary_beam)
def mapper_nl(tod, model, unpacking=None, priors=[], hypers=[], norms=[], comms=[], x0=None, tol=1.e-6, maxiter=300, solver=None, linesearch=None, descent_method='pr', M=None, verbose=True, callback=None, profile=None): comm_map = model.commin or MPI.COMM_WORLD comm_tod = model.commout or comm_map tod = _validate_tod(tod) if len(priors) == 0 and len(hypers) != 0: npriors = len(model.shapein) priors = [ DiscreteDifferenceOperator(axis=axis, shapein=model.shapein, commin=comm_map) for axis in range(npriors) ] else: npriors = len(priors) if np.isscalar(hypers): hypers = npriors * [hypers] elif npriors != len(hypers): raise ValueError('There should be one hyperparameter per prior.') if len(norms) == 0: norms = (npriors+1) * [norm2] if len(comms) == 0: comms = [comm_tod] + npriors * [comm_map] if isinstance(M, DiagonalOperator): filter_nonfinite(M.data, out=M.data) hypers = np.asarray(hypers, dtype=var.FLOAT_DTYPE) ntods = int(np.sum(~tod.mask)) if getattr(tod, 'mask', None) is not None \ else tod.size ntods = comm_tod.allreduce(ntods) nmaps = comm_map.allreduce(model.shape[1]) hypers /= nmaps hypers = np.hstack([1/ntods, hypers]) y = tod.view(np.ndarray).ravel() class ObjectiveFunction(Function): def __init__(self): pass def __call__(self, x, inwork=None, outwork=None, out=None): outwork = self.set_outwork(outwork, self.get_work(x)) return self.set_out(out, [ h * n(r,comm=c) for h, n, r, c in \ zip(hypers, norms, outwork, comms) ]) def D(self, x, inwork=None, outwork=None, out=None): inwork = self.get_work(x, inwork) return self.set_out(out, sum([h * M.T * n.D(r,comm=c) for h, M, n, r, c in zip(hypers, [model] + priors, norms, inwork, comms)])) def get_work(self, x, work=None): if work is not None: return work if unpacking is not None: x = unpacking.matvec(x) return [ model * x - y] + [p * x for p in priors ] objfunc = ObjectiveFunction() if linesearch is None: linesearch = QuadraticStep(hypers, norms, [model] + priors, comms, unpacking, comm_map) if callback is None: callback = CgCallback(verbose=verbose) time0 = time.time() solution = nlcg(objfunc, model.shape[1], M=M, maxiter=maxiter, tol=tol, descent_method=descent_method, linesearch=linesearch, callback=callback, comm=comm_map) time0 = time.time() - time0 Js = objfunc(solution) solution = unpacking(solution) tod[...] = 1 coverage = model.T(tod) header = getattr(coverage, 'header', None) if header is None: header = create_fitsheader(fromdata=coverage) unit = getattr(coverage, 'unit', None) derived_units = getattr(coverage, 'derived_units', None) coverage = Map(coverage.magnitude, header=header, copy=False) header.update('likeliho', Js[0]) header.update('criter', sum(Js)) header.update('hyper', str(hypers)) header.update('nsamples', ntods) header.update('npixels', nmaps) header.update('time', time0) if hasattr(callback, 'niterations'): header.update('niter', callback.niterations) header.update('maxiter', maxiter) if hasattr(callback, 'residual'): header.update('residual', callback.residual) header.update('tol', tol) header.update('solver', 'nlcg') output = Map(solution.reshape(model.shapein), header=header, coverage=coverage, unit=unit, derived_units=derived_units, copy=False) return output
def mapper_rls(y, H, invntt=None, unpacking=None, hyper=1.0, x0=None, tol=1.e-5, maxiter=300, M=None, solver=None, verbose=True, callback=None, criterion=True, profile=None): """ Solve the linear equation y = H(x) where H is an Operator representing the acquisition, and y is the observed time series. x is the regularised least square solution as given by: x = argmin (Hx-y)^T N^-1 (Hx-y) + h ||D(x)||^2 or: x = (H^T N^-1 H + h D1^T D1 + h D2^T D2)^-1 H^T N^-1 y """ comm_map = H.commin or MPI.COMM_WORLD comm_tod = H.commout or comm_map if solver is None: solver = cg new_solver = solver in (pcg,) tod = _validate_tod(y) ntods_ = int(np.sum(~tod.mask)) if getattr(tod, 'mask', None) is not None \ else tod.size nmaps_ = unpacking.shape[1] if unpacking is not None else None if nmaps_ is None: nmaps_ = H.shape[1] if nmaps_ is None: raise ValueError('The model H has not an explicit input shape.') ntods = comm_tod.allreduce(ntods_) nmaps = comm_map.allreduce(nmaps_) # get A if invntt is None: invntt = IdentityOperator() A = H.T * invntt * H npriors = len(H.shapein) priors = [DiscreteDifferenceOperator(axis=axis, shapein=H.shapein, commin=comm_map) for axis in range(npriors)] if comm_map.rank == 0 or comm_map.size > 1: A += sum((hyper * ntods / nmaps) * p.T * p for p in priors) # get b b = (H.T * invntt)(tod) if not np.all(np.isfinite(b)): raise ValueError('RHS contains non-finite values.') if b.shape != A.shapein: raise ValueError("Incompatible size for RHS: '" + str(b.size) + "' instead of '" + str(A.shape[1]) + "'.") if np.min(b) == np.max(b) == 0: print('Warning: in equation Ax=b, b is zero.') # unpack input if unpacking is None: unpacking = IdentityOperator() A = unpacking.T * A * unpacking b = unpacking.T(b) if x0 is not None: x0 = unpacking.T(x0) if not new_solver and solver is not cg: b = b.ravel() if x0 is not None: x0 = x0.ravel() if M is not None: if isinstance(M, DiagonalOperator): filter_nonfinite(M.data, out=M.data) M = unpacking.T * M * unpacking H_ = H * unpacking priors = [p * unpacking for p in priors] # criterion if hyper != 0: hc = np.hstack([1, npriors * [hyper]]) / ntods else: hc = [ 1 / ntods ] norms = [norm2_ellipsoid(invntt)] + npriors * [norm2] comms = [comm_tod] + npriors * [comm_map] def criter(x): rs = [H_.matvec(x) - tod.view(np.ndarray).ravel()] + [p.matvec(x) for p in priors] Js = [h * n(r,comm=c) for h, n, r, c in zip(hc, norms, rs, comms)] return Js if callback is None: if new_solver: callback = NewCgCallback(disp=verbose, comm=comm_map) else: callback = CgCallback(verbose=verbose, objfunc=criter if criterion else None) if (verbose or profile) and comm_map.rank == 0: print('') print('H.T * N^-1 * H:') print(repr(A)) if M is not None: print('Preconditioner:') print(M) time0 = time.time() if profile is not None: def run(): result = solver(A, b, x0=x0, M=M, tol=tol, maxiter=maxiter) if new_solver: solution = result['x'] if not result['success']: print('Solver failure: ' + result['message']) else: solution, info = result if info != 0: print('Solver failure: info='+str(info)) cProfile.runctx('run()', globals(), locals(), profile+'.prof') print('Profile time: '+str(time.time()-time0)) os.system('python -m gprof2dot -f pstats -o ' + profile +'.dot ' + profile + '.prof') os.system('dot -Tpng ' + profile + '.dot > ' + profile) os.system('rm -f ' + profile + '.prof' + ' ' + profile + '.dot') return None result = solver(A, b, x0=x0, M=M, tol=tol, maxiter=maxiter, callback=callback) time0 = time.time() - time0 if new_solver: solution = result['x'] if not result['success']: print('Solver failure: ' + result['message']) niterations = result['niterations'] error = result['error'] else: solution, info = result if info < 0: raise RuntimeError('Solver failure (code=' + str(info) + ' after ' + str(callback.niterations) + ' iterations).') if info > 0 and comm_map.rank == 0: print('Warning: Solver reached maximum number of iterations without' ' reaching specified tolerance.') niterations = getattr(callback, 'niterations', None) error = getattr(callback, 'residual', None) Js = criter(solution) if isinstance(unpacking, IdentityOperator): solution = solution.reshape(H.shapein) else: solution = unpacking(solution) tod[...] = 1 coverage = H.T(tod) unit = getattr(coverage, 'unit', None) derived_units = getattr(coverage, 'derived_units', None) coverage = coverage.view(Map) header = getattr(coverage, 'header', None) if header is None: header = create_fitsheader(fromdata=coverage) header.update('likeliho', Js[0]) header.update('criter', sum(Js)) header.update('hyper', hyper) header.update('nsamples', ntods) header.update('npixels', nmaps) header.update('time', time0) if niterations is not None: header.update('niter', niterations) header.update('maxiter', maxiter) if error is not None: header.update('error', error) header.update('tol', tol) header.update('solver', solver.__name__) output = Map(solution, header=header, coverage=coverage, unit=unit, derived_units=derived_units, copy=False) return output
keywords_m = keywords_f.copy() keywords_m.update({'coverage': 8, 'error': 1., 'origin': 'upper'}) keywords_t = keywords_f.copy() keywords_t.update({'mask': True}) keywords_types = (keywords_q, keywords_f, keywords_m, keywords_t) dtypes = (bool, int, np.float32, np.float64, np.complex64, np.complex128) def teardown(): for file in glob.glob(filename+'*'): os.remove(file) a = np.ones((4, 3)) a[1, 2] = 4 q = Quantity(a, unit='myunit', derived_units={'myunit': Quantity(2., 'Jy')}) header = create_fitsheader(fromdata=q, cdelt=0.5, crval=(4., 8.)) header['BUNIT'] = 'myunit' f = FitsArray(q, header=header) m = Map(f, origin='upper', error=a*2, coverage=a*3) mask = np.zeros((4, 3), np.bool8) mask[0, 2] = True t = Tod(f, mask=mask) del mask def test_copy_false_subok_true(): def func(obj1, t): obj2 = t(obj1, copy=False, subok=True) if isinstance(obj, t): assert obj1 is obj2 else:
keywords_m.update({'coverage': 8, 'error': 1., 'origin': 'upper'}) keywords_t = keywords_f.copy() keywords_t.update({'mask': True}) keywords_types = (keywords_q, keywords_f, keywords_m, keywords_t) dtypes = (bool, int, np.float32, np.float64, np.complex64, np.complex128) def teardown(): for file in glob.glob(filename + '*'): os.remove(file) a = np.ones((4, 3)) a[1, 2] = 4 q = Quantity(a, unit='myunit', derived_units={'myunit': Quantity(2., 'Jy')}) header = create_fitsheader(fromdata=q, cdelt=0.5, crval=(4., 8.)) header['BUNIT'] = 'myunit' f = FitsArray(q, header=header) m = Map(f, origin='upper', error=a * 2, coverage=a * 3) mask = np.zeros((4, 3), np.bool8) mask[0, 2] = True t = Tod(f, mask=mask) del mask def test_copy_false_subok_true(): def func(obj1, t): obj2 = t(obj1, copy=False, subok=True) if isinstance(obj, t): assert obj1 is obj2 else: