def test_solver_factory(self): """ Test that the solver factory produces the correct types """ slvr_cfg = montblanc.rime_solver_cfg( data_source=Options.DATA_SOURCE_DEFAULT, version=Options.VERSION_TWO) with montblanc.factory.rime_solver(slvr_cfg) as slvr: self.assertTrue(type(slvr) == montblanc.impl.rime.v2.RimeSolver.RimeSolver) slvr_cfg = montblanc.rime_solver_cfg( data_source=Options.DATA_SOURCE_TEST, version=Options.VERSION_TWO) with montblanc.factory.rime_solver(slvr_cfg) as slvr: self.assertTrue(type(slvr) == montblanc.impl.rime.v2.RimeSolver.RimeSolver)
def src_perms(slvr_cfg, permute_weights=False): """ Permute the source types and return a SolverConfiguration suitable for use as input to the solver function/factory. Parameters: slvr_cfg : RimeSolverConfiguration Configuration containing other sensible defaults to include in the returned permutation. e.g. {'na': 14, 'ntime': 20, 'nchan': 48} { 'point': 0, 'gaussian': 00, 'sersic': 20 } { 'point': 0, 'gaussian': 20, 'sersic': 0 } { 'point': 20, 'gaussian': 0, 'sersic': 0 } { 'point': 0, 'gaussian': 20, 'sersic': 20 } { 'point': 20, 'gaussian': 20, 'sersic': 0 } { 'point': 20, 'gaussian': 0, 'sersic': 20 } { 'point': 20, 'gaussian': 20, 'sersic': 20 } >>> slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=20, nchan=48) >>> for p_slvr_cfg in src_perms(slvr_cfg, True) >>> with solver(p_slvr_cfg) as slvr: >>> slvr.solve() """ if slvr_cfg is None: slvr_cfg = montblanc.rime_solver_cfg() from montblanc.src_types import SOURCE_VAR_TYPES src_types = SOURCE_VAR_TYPES.keys() count = 0 weight_vector = [True, False] if permute_weights is True else [False] for wv in weight_vector: count = 0 for p in itertools.product([0, 20], repeat=len(src_types)): # Nasty, but works to avoid the (0,0,0) case count += 1 if count == 1: continue params = montblanc.rime_solver_cfg(**slvr_cfg) params[Options.WEIGHT_VECTOR] = wv src_dict = {s: p[i] for i, s in enumerate(src_types)} params[Options.SOURCES] = montblanc.sources(**src_dict) yield params
def src_perms(slvr_cfg, permute_weights=False): """ Permute the source types and return a SolverConfiguration suitable for use as input to the solver function/factory. Parameters: slvr_cfg : RimeSolverConfiguration Configuration containing other sensible defaults to include in the returned permutation. e.g. {'na': 14, 'ntime': 20, 'nchan': 48} { 'point': 0, 'gaussian': 00, 'sersic': 20 } { 'point': 0, 'gaussian': 20, 'sersic': 0 } { 'point': 20, 'gaussian': 0, 'sersic': 0 } { 'point': 0, 'gaussian': 20, 'sersic': 20 } { 'point': 20, 'gaussian': 20, 'sersic': 0 } { 'point': 20, 'gaussian': 0, 'sersic': 20 } { 'point': 20, 'gaussian': 20, 'sersic': 20 } >>> slvr_cfg = RimeSolverConfiguration(na=14, ntime=20, nchan=48) >>> for p_slvr_cfg in src_perms(slvr_cfg, True) >>> with solver(p_slvr_cfg) as slvr: >>> slvr.solve() """ if slvr_cfg is None: slvr_cfg = montblanc.rime_solver_cfg() from montblanc.src_types import SOURCE_VAR_TYPES src_types = SOURCE_VAR_TYPES.keys() count = 0 weight_vector = [True, False] if permute_weights is True else [False] for wv in weight_vector: count = 0 for p in itertools.product([0, 20], repeat=len(src_types)): # Nasty, but works to avoid the (0,0,0) case count += 1 if count == 1: continue params = montblanc.rime_solver_cfg(**slvr_cfg) params[Options.WEIGHT_VECTOR] = wv src_dict = {s: p[i] for i,s in enumerate(src_types)} params[Options.SOURCES] = montblanc.sources(**src_dict) yield params
def E_beam_test_helper(self, beam_lw, beam_mh, beam_nud, dtype, cmp=None): if cmp is None: cmp = {} slvr_cfg = montblanc.rime_solver_cfg(na=32, ntime=50, nchan=64, sources=montblanc.sources( point=10, gaussian=10), beam_lw=beam_lw, beam_mh=beam_mh, beam_nud=beam_nud, dtype=dtype, pipeline=Pipeline([RimeEBeam()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: # Check that the beam cube dimensions are # correctly configured self.assertTrue(cpu_slvr.E_beam.shape == (beam_lw, beam_mh, beam_nud, 4)) self.E_beam_test_impl(gpu_slvr, cpu_slvr, cmp=cmp)
def __init__(self, GD, npix, cell_size_rad): self._slvr_cfg = slvr_cfg = montblanc.rime_solver_cfg( data_source=Options.DATA_SOURCE_DEFAULT, tf_server_target=GD["Montblanc"]["TensorflowServerTarget"], mem_budget=2 * 1024 * 1024 * 1024, dtype='double', auto_correlations=False, version='tf') self._solver = montblanc.rime_solver(slvr_cfg) self._cell_size_rad = cell_size_rad self._npix = npix self._mgr = DataDictionaryManager() # Configure the Beam upfront if GD["Beam"]["Model"] == "FITS": fits_file_spec = GD["Beam"]["FITSFile"] l_axis = GD["Beam"]["FITSLAxis"] m_axis = GD["Beam"]["FITSMAxis"] self._beam_prov = FitsBeamSourceProvider(fits_file_spec, l_axis=l_axis, m_axis=m_axis) else: self._beam_prov = None
def test_solver_factory(self): """ Test that the solver factory produces the correct types """ slvr_cfg = montblanc.rime_solver_cfg( data_source=Options.DATA_SOURCE_DEFAULT, version=Options.VERSION_TWO) with montblanc.factory.rime_solver(slvr_cfg) as slvr: self.assertTrue( type(slvr) == montblanc.impl.rime.v2.RimeSolver.RimeSolver) slvr_cfg = montblanc.rime_solver_cfg( data_source=Options.DATA_SOURCE_TEST, version=Options.VERSION_TWO) with montblanc.factory.rime_solver(slvr_cfg) as slvr: self.assertTrue( type(slvr) == montblanc.impl.rime.v2.RimeSolver.RimeSolver)
def test_config_file(self): """ Test config file """ import tempfile key, value = 'frobulate', 'laksfjdsflk' cfg_file_contents = ( "[montblanc]\n" "na = 10\n" "nchan = 64\n" "{k} = {v}\n".format(k=key, v=value)) with tempfile.NamedTemporaryFile('w') as f: f.write(cfg_file_contents) f.flush() # Create some keyword arguments used for # generating the RIME solver configuration. # We provide a configuration file that will # provide some defaults which should be overwridden # by these keyword arguments. D = { Options.CFG_FILE: f.name, Options.DATA_SOURCE: Options.DATA_SOURCE_DEFAULT, Options.VERSION: Options.VERSION_FOUR, Options.NA: 14 } slvr_cfg = montblanc.rime_solver_cfg(**D) assert slvr_cfg[Options.NA] == 14 assert slvr_cfg[Options.NCHAN] == 64 assert slvr_cfg[Options.VERSION] == Options.VERSION_FOUR assert slvr_cfg[key] == value
def test_transpose(self): slvr_cfg = montblanc.rime_solver_cfg( na=14, ntime=10, nchan=16, sources=montblanc.sources(point=10, gaussian=10), weight_vector=True, pipeline=Pipeline([MatrixTranspose()]), data_source=Options.DATA_SOURCE_TEST, version=Options.VERSION_FOUR) with montblanc.factory.rime_solver(slvr_cfg) as gpu_slvr: nsrc, nchan = gpu_slvr.dim_global_size('nsrc', 'nchan') gpu_slvr.register_array(name='matrix_in', shape=('nsrc', 'nchan'), dtype='ft') gpu_slvr.register_array(name='matrix_out', shape=('nchan', 'nsrc'), dtype='ft') # Recreates existing arrays, but OK for testing purposes! gpu_slvr.create_arrays() matrix = np.random.random(size=(nsrc, nchan)).astype(gpu_slvr.ft) gpu_slvr.transfer_matrix_in(matrix) gpu_slvr.solve() transposed_matrix = gpu_slvr.retrieve_matrix_out() assert np.all(matrix == transposed_matrix.T)
def test_transpose(self): slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=10, nchan=16, sources=montblanc.sources(point=10, gaussian=10), weight_vector=True, pipeline=Pipeline([MatrixTranspose()]), data_source=Options.DATA_SOURCE_TEST, version=Options.VERSION_FOUR) with montblanc.factory.rime_solver(slvr_cfg) as gpu_slvr: nsrc, nchan = gpu_slvr.dim_global_size('nsrc', 'nchan') gpu_slvr.register_array( name='matrix_in', shape=('nsrc', 'nchan'), dtype='ft') gpu_slvr.register_array( name='matrix_out', shape=('nchan', 'nsrc'), dtype='ft') # Recreates existing arrays, but OK for testing purposes! gpu_slvr.create_arrays() matrix = np.random.random( size=(nsrc, nchan)).astype(gpu_slvr.ft) gpu_slvr.transfer_matrix_in(matrix) gpu_slvr.solve() transposed_matrix = gpu_slvr.retrieve_matrix_out() assert np.all(matrix == transposed_matrix.T)
def simulate(src_provs, snk_provs, opts): """ Convenience function which creates and executes a Montblanc solver for the given source and sink providers. Args: src_provs (list): List of :obj:`~montblanc.impl.rime.tensorflow.sources.SourceProvider` objects. See Montblanc's documentation. snk_provs (list): List of :obj:`~montblanc.impl.rime.tensorflow.sinks.SinkProvider` objects. See Montblanc's documentation. opts (dict): Montblanc simulation options (see [montblanc] section in DefaultParset.cfg). """ global _mb_slvr if _mb_slvr is None: slvr_cfg = montblanc.rime_solver_cfg( mem_budget=opts["mem-budget"] * 1024 * 1024, dtype=opts["dtype"], polarisation_type=opts["feed-type"], device_type=opts["device-type"]) _mb_slvr = montblanc.rime_solver(slvr_cfg) _mb_slvr.solve(source_providers=src_provs, sink_providers=snk_provs)
def test_B_sum_float(self): """ Test the B sum float kernel """ slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=20, nchan=48, dtype=Options.DTYPE_FLOAT) for p_slvr_cfg in src_perms(slvr_cfg, permute_weights=True): wv = p_slvr_cfg[Options.WEIGHT_VECTOR] gpu_slvr, cpu_slvr = solvers(p_slvr_cfg) with gpu_slvr, cpu_slvr: self.B_sum_test_impl(gpu_slvr, cpu_slvr, wv, {'rtol': 1e-2})
def test_B_sum_double(self): """ Test the B sum double kernel """ slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=20, nchan=48, dtype=Options.DTYPE_DOUBLE) for p_slvr_cfg in src_perms(slvr_cfg, permute_weights=True): wv = p_slvr_cfg[Options.WEIGHT_VECTOR] gpu_slvr, cpu_slvr = solvers(p_slvr_cfg) with gpu_slvr, cpu_slvr: self.B_sum_test_impl(gpu_slvr, cpu_slvr, wv)
def test_EK_double(self): """ Double precision EK test """ slvr_cfg = montblanc.rime_solver_cfg(na=64, ntime=10, nchan=64, sources=montblanc.sources(point=10, gaussian=10, sersic=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([RimeEK()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: self.EK_test_impl(gpu_slvr, cpu_slvr)
def test_B_sqrt_double(self): """ Test the B sqrt double kernel """ slvr_cfg = montblanc.rime_solver_cfg(na=7, ntime=200, nchan=320, sources=montblanc.sources(point=10, gaussian=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([RimeBSqrt()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: self.B_sqrt_test_impl(gpu_slvr, cpu_slvr)
def test_sum_coherencies_residuals_double(self): """ Test computation of double residuals """ slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=20, nchan=48, sources=montblanc.sources(point=10, gaussian=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([RimeSumCoherencies()]), vis_output=Options.VISIBILITY_OUTPUT_RESIDUALS) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: self.sum_coherencies_test_impl(gpu_slvr, cpu_slvr)
def test_EKBSqrt_double(self): """ Double precision EKBSqrt test """ slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=20, nchan=64, sources=montblanc.sources(point=10, gaussian=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([RimeEBeam(), RimeBSqrt(), RimeEKBSqrt()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: self.EKBSqrt_test_impl(gpu_slvr, cpu_slvr, cmp={'rtol': 1e-4})
def test_B_sqrt_float(self): """ Test the B sqrt float kernel """ slvr_cfg = montblanc.rime_solver_cfg(na=7, ntime=200, nchan=320, sources=montblanc.sources(point=10, gaussian=10), dtype=Options.DTYPE_FLOAT, pipeline=Pipeline([RimeBSqrt()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: # This fails more often with an rtol of 1e-4 self.B_sqrt_test_impl(gpu_slvr, cpu_slvr, cmp={'rtol': 1e-3})
def test_sum_coherencies_double(self): """ Test the coherency sum double kernel """ slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=20, nchan=48, dtype=Options.DTYPE_DOUBLE) for p_slvr_cfg in src_perms(slvr_cfg, permute_weights=True): wv = p_slvr_cfg[Options.WEIGHT_VECTOR] p_slvr_cfg['pipeline'] = Pipeline([RimeSumCoherencies()]) gpu_slvr, cpu_slvr = solvers(p_slvr_cfg) with gpu_slvr, cpu_slvr: self.sum_coherencies_test_impl(gpu_slvr, cpu_slvr)
def test_sum_coherencies_float(self): """ Test the coherency sum float kernel """ slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=20, nchan=48, dtype=Options.DTYPE_FLOAT) for p_slvr_cfg in src_perms(slvr_cfg, permute_weights=True): p_slvr_cfg['pipeline'] = Pipeline([RimeSumCoherencies()]) gpu_slvr, cpu_slvr = solvers(p_slvr_cfg) with gpu_slvr, cpu_slvr: self.sum_coherencies_test_impl(gpu_slvr, cpu_slvr, cmp={'rtol': 1e-3})
def __init__(self, GD, npix, cell_size_rad, MS, pointing_sols): shndlrs = filter(lambda x: isinstance(x, logging.StreamHandler), montblanc.log.handlers) montblanc.log.propagate = False log_levels = { "NOTSET": logging.NOTSET, "DEBUG": logging.DEBUG, "INFO": logging.INFO, "WARNING": logging.WARNING, "ERROR": logging.ERROR, "CRITICAL": logging.CRITICAL } for s in shndlrs: s.level = log_levels.get(GD["Montblanc"]["LogLevel"], logging.WARNING) apnd = "a" if GD["Log"]["Append"] else "w" lgname = GD["Output"]["Name"] + ".montblanc.log" \ if GD["Montblanc"]["LogFile"] is None else GD["Montblanc"]["LogFile"] fhndlr = logging.FileHandler(lgname, mode=apnd) fhndlr.level = logging.DEBUG montblanc.log.addHandler(fhndlr) # configure solver self._mgr = DataDictionaryManager(MS, pointing_sols) self._slvr_cfg = slvr_cfg = montblanc.rime_solver_cfg( data_source="default", polarisation_type=self._mgr._solver_polarization_type, mem_budget=int( np.ceil(GD["Montblanc"]["MemoryBudget"] * 1024 * 1024 * 1024)), dtype=GD["Montblanc"]["SolverDType"], auto_correlations=True, version=GD["Montblanc"]["DriverVersion"]) self._solver = montblanc.rime_solver(slvr_cfg) self._cell_size_rad = cell_size_rad self._npix = npix # Configure the Beam upfront if GD["Beam"]["Model"] == "FITS": fits_file_spec = GD["Beam"]["FITSFile"] l_axis = GD["Beam"]["FITSLAxis"] m_axis = GD["Beam"]["FITSMAxis"] self._beam_prov = FitsBeamSourceProvider(fits_file_spec, l_axis=l_axis, m_axis=m_axis) else: self._beam_prov = None
def test_B_sqrt_double(self): """ Test the B sqrt double kernel """ slvr_cfg = montblanc.rime_solver_cfg(na=7, ntime=200, nchan=320, sources=montblanc.sources( point=10, gaussian=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([RimeBSqrt()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: self.B_sqrt_test_impl(gpu_slvr, cpu_slvr)
def test_sum_coherencies_residuals_double(self): """ Test computation of double residuals """ slvr_cfg = montblanc.rime_solver_cfg( na=14, ntime=20, nchan=48, sources=montblanc.sources(point=10, gaussian=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([RimeSumCoherencies()]), vis_output=Options.VISIBILITY_OUTPUT_RESIDUALS) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: self.sum_coherencies_test_impl(gpu_slvr, cpu_slvr)
def test_EK_double(self): """ Double precision EK test """ slvr_cfg = montblanc.rime_solver_cfg(na=64, ntime=10, nchan=64, sources=montblanc.sources( point=10, gaussian=10, sersic=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([RimeEK()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: self.EK_test_impl(gpu_slvr, cpu_slvr)
def test_B_sqrt_float(self): """ Test the B sqrt float kernel """ slvr_cfg = montblanc.rime_solver_cfg(na=7, ntime=200, nchan=320, sources=montblanc.sources( point=10, gaussian=10), dtype=Options.DTYPE_FLOAT, pipeline=Pipeline([RimeBSqrt()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: # This fails more often with an rtol of 1e-4 self.B_sqrt_test_impl(gpu_slvr, cpu_slvr, cmp={'rtol': 1e-3})
def test_EKBSqrt_double(self): """ Double precision EKBSqrt test """ slvr_cfg = montblanc.rime_solver_cfg( na=14, ntime=20, nchan=64, sources=montblanc.sources(point=10, gaussian=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([RimeEBeam(), RimeBSqrt(), RimeEKBSqrt()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: self.EKBSqrt_test_impl(gpu_slvr, cpu_slvr, cmp={'rtol': 1e-4})
def E_beam_test_helper(self, beam_lw, beam_mh, beam_nud, dtype, cmp=None): if cmp is None: cmp = {} slvr_cfg = montblanc.rime_solver_cfg(na=32, ntime=50, nchan=64, sources=montblanc.sources(point=10, gaussian=10), beam_lw=beam_lw, beam_mh=beam_mh, beam_nud=beam_nud, dtype=dtype, pipeline=Pipeline([RimeEBeam()])) gpu_slvr, cpu_slvr = solvers(slvr_cfg) with gpu_slvr, cpu_slvr: # Check that the beam cube dimensions are # correctly configured self.assertTrue(cpu_slvr.E_beam.shape == (beam_lw, beam_mh, beam_nud, 4)) self.E_beam_test_impl(gpu_slvr, cpu_slvr, cmp=cmp)
def test_cmp_visibilities(self): """ Test visibilities produced by montblanc and meqtrees """ if not os.path.exists(msfile): raise unittest.SkipTest("MeasurementSet '{ms}' required " "for this test is not present".format(ms=msfile)) slvr_cfg = montblanc.rime_solver_cfg( msfile=msfile, sources=montblanc.sources(point=1, gaussian=0, sersic=0), dtype='double', version=Options.VERSION_FOUR, mem_budget=2*1024*1024*1024) # Test the v4 and v5 residuals agree v4_chi, v4_vis = self.get_v4_output(slvr_cfg, vis_output=Options.VISIBILITY_OUTPUT_RESIDUALS) v5_chi, v5_vis = self.get_v5_output(slvr_cfg, vis_output=Options.VISIBILITY_OUTPUT_RESIDUALS) self.assertTrue(np.allclose(v4_vis, v5_vis)) self.assertTrue(np.allclose(v4_chi, v5_chi)) v4_chi, v4_vis = self.get_v4_output(slvr_cfg) v5_chi, v5_vis = self.get_v5_output(slvr_cfg) # Test that v4 and v5 model visibilities agree self.assertTrue(np.allclose(v4_vis, v5_vis)) self.assertTrue(np.allclose(v4_chi, v5_chi)) # Test that meqtrees agrees with v5 try: meq_vis = self.get_meq_vis(slvr_cfg[Options.MS_FILE]) self.assertTrue(np.allclose(v5_vis, meq_vis)) except Exception as e: montblanc.log.exception("Unable to run MeqTrees for " "purposes of comparing model visibilities. " "This will not be treated as a test failure")
def run_test(msfile, pol_type, **kwargs): """ Parameters ---------- msfile : str Name of the Measurement Set pol_type : str 'linear' or 'circular' beam_file_schema (optional) : str Beam filename schema. Defaults to 'test_beam_$(corr)_$(reim).fits' overwrite_beams (optional) : bool If ``True`` create new beams using the cos**3 beam """ #========================================= # Directory and Script Configuration #========================================= # Directory in which we expect our measurement set to be located meq_vis_column = 'MODEL_DATA' mb_vis_column = 'CORRECTED_DATA' # Directory in which meqtree-related files are read/written meq_dir = 'meqtrees' # Scripts meqpipe = 'meqtree-pipeliner.py' # Meqtree profile and script cfg_file = os.path.join(meq_dir, 'tdlconf.profiles') sim_script = os.path.join(meq_dir, 'turbo-sim.py') tigger_sky_file = os.path.join(meq_dir, 'sky_model.txt') # Is the beam enabled beam_on = kwargs.get('beam_on', True) beam_on = 1 if beam_on is True else 0 # Directory in which we expect our beams to be located beam_file_schema = 'test_beam_$(corr)_$(reim).fits' # Beam file pattern beam_file_schema = kwargs.get("beam_file_schema", beam_file_schema) l_axis = kwargs.get('l_axis', '-X') m_axis = kwargs.get('m_axis', 'Y') # Find the location of the meqtree pipeliner script meqpipe_actual = subprocess.check_output(['which', meqpipe]).strip() cfg_section = '-'.join(('montblanc', 'compare', pol_type)) #====================================================== # Configure the beam files with frequencies from the MS #====================================================== from montblanc.impl.rime.tensorflow.sources.fits_beam_source_provider import ( _create_filenames, _open_fits_files) # Zero the visibility data with pt.table(msfile, ack=False, readonly=False) as T: data_desc = T.getcoldesc('DATA') try: shape = data_desc['shape'].tolist() except KeyError: shape = list(T.getcol('DATA', startrow=0, nrow=1).shape[1:]) shape = [T.nrows()] + shape T.putcol(mb_vis_column, np.zeros(shape, dtype=np.complex64)) T.putcol(meq_vis_column, np.zeros(shape, dtype=np.complex64)) # Extract frequencies from the MS with pt.table(msfile + '::SPECTRAL_WINDOW', ack=False) as SW: frequency = SW.getcol('CHAN_FREQ')[0] bandwidth = frequency[-1] - frequency[0] overwrite_beams = kwargs.get('overwrite_beams', False) # Get filenames from pattern and open the files filenames = beam_factory(polarisation_type=pol_type, frequency=frequency, schema=beam_file_schema, overwrite=overwrite_beams) #========================================= # Source Configuration #========================================= np.random.seed(0) dtype = np.float64 ctype = np.complex128 if dtype == np.float64 else np.complex64 def get_point_sources(nsrc): source_coords = np.empty(shape=(nsrc, 2), dtype=dtype) stokes = np.empty(shape=(nsrc, 4), dtype=dtype) I, Q, U, V = stokes[:,0], stokes[:,1], stokes[:,2], stokes[:,3] alphas = np.empty(shape=(nsrc,), dtype=dtype) ref_freq = np.empty(shape=(nsrc,), dtype=dtype) # Source coordinates between -45 and 45 degrees source_coords[:] = (rf(size=source_coords.shape) - 0.5)*90.0 Q[:] = rf(size=Q.shape)*0.1 U[:] = rf(size=U.shape)*0.1 V[:] = rf(size=V.shape)*0.1 I[:] = np.sqrt(Q**2 + U**2 + V**2)*1.5 + rf(size=I.shape)*0.1 # Zero and invert selected stokes parameters if nsrc > 0: zero_srcs = np.random.randint(nsrc, size=(2,)) source_coords[zero_srcs,:] = 0 # Create sources with both positive and negative flux sign = 2*np.random.randint(2, size=I.shape) - 1 I[:] *= sign alphas[:] = 2*(np.random.random(size=alphas.size) - 0.5) ref_freq[:] = 1.3e9 + np.random.random(ref_freq.size)*0.2e9 return (np.deg2rad(source_coords), np.asarray(stokes), np.asarray(alphas), np.asarray(ref_freq)) def get_gaussian_sources(nsrc): c, s, a, r= get_point_sources(nsrc) gauss_shape = np.empty(shape=(3, nsrc), dtype=np.float64) gauss_shape[:] = rf(size=gauss_shape.shape) return c, s, a, r, gauss_shape npsrc, ngsrc = 10, 10 pt_lm, pt_stokes, pt_alpha, pt_ref_freq = get_point_sources(npsrc) assert pt_lm.shape == (npsrc, 2), pt_lm.shape assert pt_stokes.shape == (npsrc, 4), pt_stokes.shape assert pt_alpha.shape == (npsrc,), pt_alpha.shape assert pt_ref_freq.shape == (npsrc,), pt_ref_freq.shape g_lm, g_stokes, g_alpha, g_ref_freq, g_shape = get_gaussian_sources(ngsrc) #========================================= # Create Tigger ASCII sky model #========================================= from Tigger.Models.Formats.AIPSCCFITS import lm_to_radec # Need the phase centre for lm_to_radec with pt.table(msfile + '::FIELD', ack=False, readonly=True) as F: ra0, dec0 = F.getcol('PHASE_DIR')[0][0] # Create the tigger sky model with open(tigger_sky_file, 'w') as f: f.write('#format: ra_d dec_d i q u v spi freq0 emaj_s emin_s pa_d\n') it = enumerate(itertools.izip(pt_lm, pt_stokes, pt_alpha, pt_ref_freq)) for i, ((l, m), (I, Q, U, V), alpha, ref_freq) in it: ra, dec = lm_to_radec(l, m, ra0, dec0) l, m = np.rad2deg([ra,dec]) f.write('{l:.20f} {m:.20f} {i} {q} {u} {v} {spi} {rf:.20f}\n'.format( l=l, m=m, i=I, q=Q, u=U, v=V, spi=alpha, rf=ref_freq)) it = enumerate(itertools.izip(g_lm, g_stokes, g_alpha, g_ref_freq, g_shape.T)) for i, ((l, m), (I, Q, U, V), alpha, ref_freq, (emaj, emin, pa)) in it: ra, dec = lm_to_radec(l, m, ra0, dec0) l, m = np.rad2deg([ra,dec]) # Convert to seconds emaj, emin = np.asarray([emaj, emin])*648000./np.pi # Convert to degrees pa *= 180.0/np.pi f.write('{l:.20f} {m:.20f} {i} {q} {u} {v} {spi} {rf:.20f} ' '{emaj} {emin} {pa}\n'.format( l=l, m=m, i=I, q=Q, u=U, v=V, spi=alpha, rf=ref_freq, emaj=emaj, emin=emin, pa=pa)) #========================================= # Call MeqTrees #========================================= cmd_list = ['python', # Meqtree Pipeline script meqpipe_actual, # Configuration File '-c', cfg_file, # Configuration section '[{section}]'.format(section=cfg_section), # Enable the beam? 'me.e_enable = {e}'.format(e=beam_on), # Measurement Set 'ms_sel.msname={ms}'.format(ms=msfile), # Tigger sky file 'tiggerlsm.filename={sm}'.format(sm=tigger_sky_file), # Output column 'ms_sel.output_column={c}'.format(c=meq_vis_column), # Imaging Column 'img_sel.imaging_column={c}'.format(c=meq_vis_column), # Beam FITS file pattern 'pybeams_fits.filename_pattern={p}'.format(p=beam_file_schema), # FITS L and M AXIS 'pybeams_fits.l_axis={l}'.format(l=l_axis), 'pybeams_fits.m_axis={m}'.format(m=m_axis), sim_script, '=simulate' ] import montblanc from montblanc.impl.rime.tensorflow.ms import MeasurementSetManager from montblanc.impl.rime.tensorflow.sources import (SourceProvider, MSSourceProvider, FitsBeamSourceProvider, CachedSourceProvider) from montblanc.impl.rime.tensorflow.sinks import MSSinkProvider class RadioSourceProvider(SourceProvider): def name(self): return "RadioSourceProvider" def point_lm(self, context): lp, up = context.dim_extents('npsrc') return pt_lm[lp:up, :] def point_stokes(self, context): (lp, up), (lt, ut) = context.dim_extents('npsrc', 'ntime') return np.tile(pt_stokes[lp:up, np.newaxis, :], [1, ut-lt, 1]) def point_alpha(self, context): (lp, up), (lt, ut) = context.dim_extents('npsrc', 'ntime') return np.tile(pt_alpha[lp:up, np.newaxis], [1, ut-lt]) def point_ref_freq(self, context): (lp, up) = context.dim_extents('npsrc') return pt_ref_freq[lp:up] def gaussian_lm(self, context): lg, ug = context.dim_extents('ngsrc') return g_lm[lg:ug, :] def gaussian_stokes(self, context): (lg, ug), (lt, ut) = context.dim_extents('ngsrc', 'ntime') return np.tile(g_stokes[lg:ug, np.newaxis, :], [1, ut-lt, 1]) def gaussian_alpha(self, context): (lg, ug), (lt, ut) = context.dim_extents('ngsrc', 'ntime') return np.tile(g_alpha[lg:ug, np.newaxis], [1, ut-lt]) def gaussian_ref_freq(self, context): (lg, ug) = context.dim_extents('ngsrc') return g_ref_freq[lg:ug] def gaussian_shape(self, context): (lg, ug) = context.dim_extents('ngsrc') gauss_shape = g_shape[:,lg:ug] emaj = gauss_shape[0] emin = gauss_shape[1] pa = gauss_shape[2] gauss = np.empty(context.shape, dtype=context.dtype) gauss[0,:] = emaj * np.sin(pa) gauss[1,:] = emaj * np.cos(pa) emaj[emaj == 0.0] = 1.0 gauss[2,:] = emin / emaj return gauss def updated_dimensions(self): return [('npsrc', pt_lm.shape[0]), ('ngsrc', g_lm.shape[0])] slvr_cfg = montblanc.rime_solver_cfg( mem_budget=1024*1024*1024, data_source='default', dtype='double' if dtype == np.float64 else 'float', polarisation_type=pol_type, auto_correlations=False, version='tf') slvr = montblanc.rime_solver(slvr_cfg) ms_mgr = MeasurementSetManager(msfile, slvr_cfg) source_providers = [] source_providers.append(MSSourceProvider(ms_mgr)) if beam_on == 1: beam_prov = FitsBeamSourceProvider(beam_file_schema, l_axis=l_axis, m_axis=m_axis) source_providers.append(beam_prov) source_providers.append(RadioSourceProvider()) cache_prov = CachedSourceProvider(source_providers) source_providers = [cache_prov] sink_providers = [MSSinkProvider(ms_mgr, mb_vis_column)] slvr.solve(source_providers=source_providers, sink_providers=sink_providers) import time time.sleep(1) for obj in source_providers + sink_providers + [ms_mgr]: obj.close() # Call the meqtrees simulation script, dumping visibilities into MODEL_DATA subprocess.call(cmd_list) # Compare MeqTree and Montblanc visibilities with pt.table(msfile, ack=False, readonly=True) as MS: ntime, nbl, nchan = slvr.hypercube.dim_global_size('ntime', 'nbl', 'nchan') shape = (ntime, nbl, nchan, 4) meq_vis = MS.getcol(meq_vis_column).reshape(shape) mb_vis = MS.getcol(mb_vis_column).reshape(shape) # Compare close = np.isclose(meq_vis, mb_vis) not_close = np.invert(close) problems = np.nonzero(not_close) # Everything agrees, exit if problems[0].size == 0: print 'Montblanc and MeqTree visibilities agree' sys.exit(1) bad_vis_file = 'bad_visibilities.txt' # Some visibilities differ, do some analysis print ("Montblanc differs from MeqTrees by {nc}/{t} visibilities. " "Writing them out to '{bvf}'").format( nc=problems[0].size, t=not_close.size, bvf=bad_vis_file) abs_diff = np.abs(meq_vis - mb_vis) rmsd = np.sqrt(np.sum(abs_diff**2)/abs_diff.size) nrmsd = rmsd / (np.max(abs_diff) - np.min(abs_diff)) print 'RMSD {rmsd} NRMSD {nrmsd}'.format(rmsd=rmsd, nrmsd=nrmsd) # Plot a histogram of the difference try: import matplotlib matplotlib.use('pdf') import matplotlib.pyplot as plt except: print "Exception importing matplotlib %s" % sys.exc_info()[2] else: try: nr_of_bins = 100 n, bins, patches = plt.hist(abs_diff.flatten(), bins=np.logspace(np.log10(1e-10), np.log10(1.0), nr_of_bins)) plt.gca().set_xscale("log") plt.xlabel('Magnitude Difference') plt.ylabel('Counts') plt.grid(True) plt.savefig('histogram.pdf') except: print "Error plotting histogram %s" % sys.exc_info()[2] mb_problems = mb_vis[problems] meq_problems = meq_vis[problems] difference = mb_problems - meq_problems amplitude = np.abs(difference) # Create an iterator over the first 100 problematic visibilities t = (np.asarray(problems).T, mb_problems, meq_problems, difference, amplitude) it = enumerate(itertools.izip(*t)) it = itertools.islice(it, 0, 1000, 1) # Write out the problematic visibilities to file with open(bad_vis_file, 'w') as f: for i, (p, mb, meq, d, amp) in it: f.write("{i} {t} Montblanc: {mb} MeqTrees: {meq} " "Difference {d} Absolute Difference {ad} \n".format( i=i, t=p, mb=mb, meq=meq, d=d, ad=amp))
dest='version', type=str, default=Options.VERSION_FIVE, choices=[Options.VERSION_FIVE], help='RIME Pipeline Version.') args = parser.parse_args(sys.argv[1:]) # Set the logging level montblanc.log.setLevel(logging.INFO) slvr_cfg = montblanc.rime_solver_cfg( msfile=args.msfile, sources=montblanc.sources(point=args.npsrc, gaussian=args.ngsrc, sersic=args.nssrc), init_weights='weight', weight_vector=False, dtype='float', auto_correlations=args.auto_correlations, version=args.version) with montblanc.rime_solver(slvr_cfg) as slvr: # Random point source coordinates in the l,m,n (brightness image) domain slvr.lm[:] = mbu.random_like(slvr.lm) * 0.1 # Need a positive semi-definite brightness matrix I, Q, U, V = slvr.stokes[:, :, 0], slvr.stokes[:, :, 1], slvr.stokes[:, :, 2], slvr.stokes[:, :, 3]
# nssrc : number of sersic sources # init_weights : (1) None (2) 'sigma' or (3) 'weight'. Either # (1) do not initialise the weight vector, or # (2) initialise from the MS 'SIGMA' tables, or # (3) initialise from the MS 'WEIGHT' tables. # weight_vector : indicates whether a weight vector should be used to # compute the chi squared or a single sigma squared value # nparams : number of sersic parameters with respect which to # compute the chi_squared gradient # store_cpu : indicates whether copies of the data passed into the # solver transfer_* methods should be stored on the solver object global slvr slvr_cfg = montblanc.rime_solver_cfg(msfile=args.msfile, sources=montblanc.sources(point=0, gaussian=0, sersic=args.nssrc), init_weights=None, weight_vector=False,# mem_budget=1024*1024*1024, sersic_gradient=True, dtype='double', version='v5') with montblanc.rime_solver(slvr_cfg) as slvr: nsrc, nssrc, ntime, nchan = slvr.dim_local_size('nsrc', 'nssrc', 'ntime', 'nchan') true_values = np.empty((nssrc,6)) # position, flux, scalelength, ellipticity # Read from catalog file, sources position, flux, scalelength and ellipticity catalog = np.loadtxt('catalog1000.txt')[:nsrc,:] # Source coordinates in the l,m (brightness image) domain l = catalog[:,0] m = catalog[:,1] lm = mbu.shape_list([l,m], shape=slvr.lm.shape, dtype=slvr.lm.dtype) slvr.lm[:] = lm
help='RIME Pipeline Version.') args = parser.parse_args(sys.argv[1:]) # Set the logging level montblanc.log.setLevel(logging.WARN) # Parse the sky model file sky_parse = mbu.parse_sky_model(args.sky_file) sources = montblanc.sources(point=sky_parse.src_counts.get('npsrc', 0), gaussian=sky_parse.src_counts.get('ngsrc', 0), sersic=sky_parse.src_counts.get('nssrc', 0)) slvr_cfg = montblanc.rime_solver_cfg(msfile=args.msfile, sources=sources, init_weights=None, weight_vector=False, version=args.version) with montblanc.rime_solver(slvr_cfg) as slvr: # Get the lm coordinates lm = sky_parse.shape_arrays(['l','m'], slvr.lm.shape, slvr.lm.dtype) # Get the stokes and alpha parameters stokes, alpha = repeat_brightness_over_time(slvr, sky_parse) # If there are gaussian sources, create their # shape matrix and transfer it. if slvr.dim_global_size('ngsrc') > 0: gauss.shape = sky_parse.shape_arrays(['el','em','eR'], slvr.gauss.shape.shape, slvr.gauss.shape.dtype)
threshold = float(args.threshold) print "Threshold: ", threshold #Set visibility noise variance (muJy) time_acc = 60 efficiency = 0.9 channel_bandwidth_hz = 240e6 SEFD = 400e6 sigma = (SEFD * SEFD) / (2. * time_acc * channel_bandwidth_hz * efficiency * efficiency) # Get the RIME solver slvr_cfg = montblanc.rime_solver_cfg(msfile=args.msfile, sources=montblanc.sources(point=0, gaussian=0, sersic=1), init_weights=None, weight_vector=False, dtype='double', version='v4') with montblanc.rime_solver(slvr_cfg) as slvr: nsrc, nssrc, ntime, nbl, nchan = slvr.dim_local_size( 'nsrc', 'nssrc', 'ntime', 'nbl', 'nchan') # Read from modes file, sources flux, scalelength and ellipticity data = np.loadtxt('best_modes.txt') modes = [] modes_SNR = [] lm = np.empty([1, 2])
import sys import argparse parser = argparse.ArgumentParser(description='RIME MS test script') parser.add_argument('msfile', help='Measurement Set File') parser.add_argument('-np','--npsrc',dest='npsrc', type=int, default=1, help='Number of Point Sources') parser.add_argument('-ng','--ngsrc',dest='ngsrc', type=int, default=0, help='Number of Gaussian Sources') parser.add_argument('-ns','--nssrc',dest='nssrc', type=int, default=0, help='Number of Gaussian Sources') parser.add_argument('-c','--count',dest='count', type=int, default=10, help='Number of Iterations') parser.add_argument('-v','--version',dest='version', type=str, default=Options.VERSION_FOUR, choices=Options.VALID_VERSIONS, help='version') args = parser.parse_args(sys.argv[1:]) slvr_cfg = montblanc.rime_solver_cfg(msfile=args.msfile, sources=montblanc.sources(point=args.npsrc, gaussian=args.ngsrc, sersic=args.nssrc), dtype='double', version=args.version) # Get the solver. with montblanc.rime_solver(slvr_cfg) as slvr: nsrc = slvr.dim_global_size('nsrc') # Create 1Jy point sources if args.version == Options.VERSION_TWO: lm = np.empty(shape=slvr.lm.shape, dtype=slvr.lm.dtype) lm[0,:] = 0 # Set all l = 0 lm[1,:] = 0 # Set all m = 0 slvr.transfer_lm(lm) brightness = np.empty(shape=slvr.brightness.shape, dtype=slvr.brightness.dtype) brightness[0,:,:] = 1
if __name__ == '__main__': import sys import argparse parser = argparse.ArgumentParser(description='RIME MS test script') parser.add_argument('msfile', help='Measurement Set File') parser.add_argument('-v','--version',dest='version', type=str, default=Options.VERSION_FOUR, choices=Options.VALID_VERSIONS, help='RIME Pipeline Version.') args = parser.parse_args(sys.argv[1:]) # Get the solver. slvr_cfg = montblanc.rime_solver_cfg(msfile=args.msfile, sources=montblanc.sources(point=1, gaussian=0, sersic=0), dtype='double', version=args.version) with montblanc.rime_solver(slvr_cfg) as slvr: if args.version in [Options.VERSION_TWO]: lm = np.empty(shape=slvr.lm.shape, dtype=slvr.lm.dtype) l, m = lm[0,:], lm[1,:] l[:] = 0.1 m[:] = 0.25 slvr.transfer_lm(lm) B = np.empty(shape=slvr.brightness.shape, dtype=slvr.brightness.dtype) I, Q, U, V, alpha = B[0,:,:], B[1,:,:], B[2,:,:], B[3,:,:], B[4,:,:] I[:] = 2 Q[:] = 1
parser.add_argument('-np','--npsrc',dest='npsrc', type=int, default=10, help='Number of Point Sources') parser.add_argument('-ac','--auto-correlations',dest='auto_correlations', type=lambda v: v.lower() in ("yes", "true", "t", "1"), choices=[True, False], default=False, help='Handle auto-correlations') args = parser.parse_args(sys.argv[1:]) # Set the logging level montblanc.log.setLevel(logging.DEBUG) [h.setLevel(logging.DEBUG) for h in montblanc.log.handlers] slvr_cfg = montblanc.rime_solver_cfg( mem_budget=1024*1024*1024, data_source='default', dtype='double', auto_correlations=args.auto_correlations) with montblanc.rime_solver(slvr_cfg) as slvr: # Manages measurement sets ms_mgr = MeasurementSetManager(args.msfile, slvr_cfg) source_provs = [] # Read problem info from the MS, taking observed visibilities from MODEL_DAT source_provs.append(MSSourceProvider(ms_mgr, 'MODEL_DATA')) # Add a beam when you're ready #source_provs.append(FitsBeamSourceProvider('beam_$(corr)_$(reim).fits')) source_provs.append(RadioSourceProvider(args.npsrc)) sink_provs = []
def test_sqrt_multiply(self): """ Confirm that multiplying the square root of the brightness matrix into the per antenna jones terms results in the same jones matrices as multiplying the brightness matrix into the per baseline jones matrices. """ slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=10, nchan=16, sources=montblanc.sources( point=10, gaussian=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([])) with CPUSolver(slvr_cfg) as cpu_slvr: nsrc, ntime, na, nbl, nchan = cpu_slvr.dim_global_size( 'nsrc', 'ntime', 'na', 'nbl', 'nchan') # Calculate per baseline antenna pair indexes ant0, ant1 = cpu_slvr.ap_idx(src=True, chan=True) # Get the brightness matrix B = cpu_slvr.compute_b_jones() # Fill in the jones matrix with random values cpu_slvr.jones[:] = np.random.random( size=cpu_slvr.jones.shape).astype(cpu_slvr.jones.dtype) + \ np.random.random( size=cpu_slvr.jones.shape).astype(cpu_slvr.jones.dtype) # Superfluous really, but makes below readable assert cpu_slvr.jones.shape == (nsrc, ntime, na, nchan, 4) # Get per baseline jones matrices from # the per antenna jones matrices J2, J1 = cpu_slvr.jones[ant0], cpu_slvr.jones[ant1] assert J1.shape == (nsrc, ntime, nbl, nchan, 4) assert J2.shape == (nsrc, ntime, nbl, nchan, 4) # Tile the brightness term over the baseline dimension # and transpose so that polarisations are last JB = np.tile(B[:, :, np.newaxis, :, :], (1, 1, nbl, 1, 1)) assert JB.shape == (nsrc, ntime, nbl, nchan, 4) # Calculate the first result using the classic equation # J2.B.J1^H res_one = cpu_slvr.jones_multiply(J2, JB) res_one = cpu_slvr.jones_multiply(res_one, J1, hermitian=True) # Compute the square root of the # brightness matrix B_sqrt = cpu_slvr.compute_b_sqrt_jones(B) # Tile the brightness square root term over # the antenna dimension and transpose so that # polarisations are last JBsqrt = np.tile(B_sqrt[:, :, np.newaxis, :, :], (1, 1, na, 1, 1)) assert JBsqrt.shape == (nsrc, ntime, na, nchan, 4) # Multiply the square root of the brightness matrix # into the per antenna jones terms J = (cpu_slvr.jones_multiply(cpu_slvr.jones, JBsqrt).reshape( nsrc, ntime, na, nchan, 4)) # Get per baseline jones matrices from # the per antenna jones matrices J2, J1 = J[ant0], J[ant1] assert J2.shape == (nsrc, ntime, nbl, nchan, 4) assert J1.shape == (nsrc, ntime, nbl, nchan, 4) # Calculate the first result using the optimised version # (J2.sqrt(B)).(J1.sqrt(B))^H == J2.sqrt(B).sqrt(B)^H.J1^H # == J2.sqrt(B).sqrt(B).J1^H # == J2.B.J1^H res_two = cpu_slvr.jones_multiply(J2, J1, hermitian=True) # Results from two different methods should be the same self.assertTrue(np.allclose(res_one, res_two))
default=10, help='Number of Iterations') parser.add_argument('-v', '--version', dest='version', type=str, default=Options.VERSION_FOUR, choices=Options.VALID_VERSIONS, help='version') args = parser.parse_args(sys.argv[1:]) slvr_cfg = montblanc.rime_solver_cfg(msfile=args.msfile, sources=montblanc.sources( point=args.npsrc, gaussian=args.ngsrc, sersic=args.nssrc), dtype='double', version=args.version) # Get the solver. with montblanc.rime_solver(slvr_cfg) as slvr: nsrc = slvr.dim_global_size('nsrc') # Create 1Jy point sources if args.version == Options.VERSION_TWO: lm = np.empty(shape=slvr.lm.shape, dtype=slvr.lm.dtype) lm[0, :] = 0 # Set all l = 0 lm[1, :] = 0 # Set all m = 0 slvr.transfer_lm(lm)
def test_sqrt_multiply(self): """ Confirm that multiplying the square root of the brightness matrix into the per antenna jones terms results in the same jones matrices as multiplying the brightness matrix into the per baseline jones matrices. """ slvr_cfg = montblanc.rime_solver_cfg(na=14, ntime=10, nchan=16, sources=montblanc.sources(point=10, gaussian=10), dtype=Options.DTYPE_DOUBLE, pipeline=Pipeline([])) with CPUSolver(slvr_cfg) as cpu_slvr: nsrc, ntime, na, nbl, nchan = cpu_slvr.dim_global_size( 'nsrc', 'ntime', 'na', 'nbl', 'nchan') # Calculate per baseline antenna pair indexes ant0, ant1 = cpu_slvr.ap_idx(src=True, chan=True) # Get the brightness matrix B = cpu_slvr.compute_b_jones() # Fill in the jones matrix with random values cpu_slvr.jones[:] = np.random.random( size=cpu_slvr.jones.shape).astype(cpu_slvr.jones.dtype) + \ np.random.random( size=cpu_slvr.jones.shape).astype(cpu_slvr.jones.dtype) # Superfluous really, but makes below readable assert cpu_slvr.jones.shape == (nsrc, ntime, na, nchan, 4) # Get per baseline jones matrices from # the per antenna jones matrices J2, J1 = cpu_slvr.jones[ant0], cpu_slvr.jones[ant1] assert J1.shape == (nsrc, ntime, nbl, nchan, 4) assert J2.shape == (nsrc, ntime, nbl, nchan, 4) # Tile the brightness term over the baseline dimension # and transpose so that polarisations are last JB = np.tile(B[:,:,np.newaxis,:,:], (1,1,nbl,1,1)) assert JB.shape == (nsrc, ntime, nbl, nchan, 4) # Calculate the first result using the classic equation # J2.B.J1^H res_one = cpu_slvr.jones_multiply(J2, JB) res_one = cpu_slvr.jones_multiply(res_one, J1, hermitian=True) # Compute the square root of the # brightness matrix B_sqrt = cpu_slvr.compute_b_sqrt_jones(B) # Tile the brightness square root term over # the antenna dimension and transpose so that # polarisations are last JBsqrt = np.tile(B_sqrt[:,:,np.newaxis,:,:], (1,1,na,1,1)) assert JBsqrt.shape == (nsrc, ntime, na, nchan, 4) # Multiply the square root of the brightness matrix # into the per antenna jones terms J = (cpu_slvr.jones_multiply(cpu_slvr.jones, JBsqrt) .reshape(nsrc, ntime, na, nchan, 4)) # Get per baseline jones matrices from # the per antenna jones matrices J2, J1 = J[ant0], J[ant1] assert J2.shape == (nsrc, ntime, nbl, nchan, 4) assert J1.shape == (nsrc, ntime, nbl, nchan, 4) # Calculate the first result using the optimised version # (J2.sqrt(B)).(J1.sqrt(B))^H == J2.sqrt(B).sqrt(B)^H.J1^H # == J2.sqrt(B).sqrt(B).J1^H # == J2.B.J1^H res_two = cpu_slvr.jones_multiply(J2, J1, hermitian=True) # Results from two different methods should be the same self.assertTrue(np.allclose(res_one, res_two))
Receives data from montblanc via data sink methods, which have the following signature .. code-block:: python def model_vis(self, context): print context. data """ def name(self): """ Name of the Sink Provider """ return self.__class__.__name__ def model_vis(self, context): """ Receive model visibilities from Montblanc in `context.data` """ print context.data # Configure montblanc solver with a memory budget of 2GB # and set it to double precision floating point accuracy slvr_cfg = montblanc.rime_solver_cfg( mem_budget=2*1024*1024*1024, dtype='double') # Create montblanc solver with montblanc.rime_solver(slvr_cfg) as slvr: # Create Customer Source and Sink Providers source_provs = [CustomSourceProvider()] sink_provs = [CustomSinkProvider()] # Call solver, supplying source and sink providers slvr.solve(source_providers=source_provs, sink_providers=sink_provs)
parser.add_argument('-ac','--auto-correlations',dest='auto_correlations', type=lambda v: v.lower() in ("yes", "true", "t", "1"), choices=[True, False], default=False, help='Handle auto-correlations') parser.add_argument('-v','--version',dest='version', type=str, default=Options.VERSION_FIVE, choices=[Options.VERSION_FIVE], help='RIME Pipeline Version.') args = parser.parse_args(sys.argv[1:]) # Set the logging level montblanc.log.setLevel(logging.INFO) slvr_cfg = montblanc.rime_solver_cfg(msfile=args.msfile, sources=montblanc.sources(point=args.npsrc, gaussian=args.ngsrc, sersic=args.nssrc), init_weights='weight', weight_vector=False, dtype='float', auto_correlations=args.auto_correlations, version=args.version) with montblanc.rime_solver(slvr_cfg) as slvr: # Random point source coordinates in the l,m,n (brightness image) domain slvr.lm[:] = mbu.random_like(slvr.lm)*0.1 # Need a positive semi-definite brightness matrix I, Q, U, V = slvr.stokes[:,:,0], slvr.stokes[:,:,1], slvr.stokes[:,:,2], slvr.stokes[:,:,3] Q[:] = np.random.random(size=Q.shape)-0.5 U[:] = np.random.random(size=U.shape)-0.5 V[:] = np.random.random(size=V.shape)-0.5 noise = np.random.random(size=(Q.shape))*0.1 # Determinant of a brightness matrix # is I^2 - Q^2 - U^2 - V^2, noise ensures