def compute_3pt_pix(self): kkk = treecorr.KKKCorrelation(config=self.config_3pt) toc = time.time() kkk.process(self.cat) tic = time.time() print '3PCF took', tic - toc stdout.flush() self.kkk = kkk
def test_constant(): # A fairly trivial test is to use a constant value of kappa everywhere. ngal = 500 A = 0.05 L = 100. rng = np.random.RandomState(8675309) x = (rng.random_sample(ngal) - 0.5) * L y = (rng.random_sample(ngal) - 0.5) * L kappa = A * np.ones(ngal) cat = treecorr.Catalog(x=x, y=y, k=kappa, x_units='arcmin', y_units='arcmin') min_sep = 10. max_sep = 25. nbins = 5 min_u = 0.6 max_u = 0.9 nubins = 3 min_v = 0.5 max_v = 0.9 nvbins = 5 kkk = treecorr.KKKCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, min_v=min_v, max_v=max_v, nubins=nubins, nvbins=nvbins, sep_units='arcmin', verbose=1) kkk.process(cat) print('kkk.zeta = ', kkk.zeta.flatten()) np.testing.assert_allclose(kkk.zeta, A**3, rtol=1.e-5) # Should also work as a cross-correlation kkk.process(cat, cat, cat) print('as cross-correlation: kkk.zeta = ', kkk.zeta.flatten()) np.testing.assert_allclose(kkk.zeta, A**3, rtol=1.e-5) # Now add some noise to the values. It should still work, but at slightly lower accuracy. kappa += 0.001 * (rng.random_sample(ngal) - 0.5) cat = treecorr.Catalog(x=x, y=y, k=kappa, x_units='arcmin', y_units='arcmin') kkk.process(cat) print('with noise: kkk.zeta = ', kkk.zeta.flatten()) np.testing.assert_allclose(kkk.zeta, A**3, rtol=3.e-3)
def __init__(self, dataname, runname, sample_type, n_jackknife): self.sample_type = sample_type #redmagicHD, dark_matter self.dataname = dataname self.runname = runname config_fname = output_path + self.runname + '.config' try: with open(config_fname) as f: self.configdict = yaml.load(f.read()) except IOError: print 'config file ' + config_fname + ' not found.' raise self.kk = treecorr.KKCorrelation(config=self.configdict['2PCF']) self.kkk = treecorr.KKKCorrelation(config=self.configdict['3PCF']) self.n_jackknife = n_jackknife self.zetas = [] self.weights = [] self.xis = []
def corr3(config, logger=None): """Run the full three-point correlation function code based on the parameters in the given config dict. The function print_corr3_params() will output information about the valid parameters that are expected to be in the config dict. Optionally a logger parameter maybe given, in which case it is used for logging. If not given, the logging will be based on the verbose and log_file parameters. :param config: The configuration dict which defines what to do. :param logger: If desired, a logger object for logging. (default: None, in which case one will be built according to the config dict's verbose level.) """ # Setup logger based on config verbose value if logger is None: logger = treecorr.config.setup_logger( treecorr.config.get(config, 'verbose', int, 1), config.get('log_file', None)) # Check that config doesn't have any extra parameters. # (Such values are probably typos.) # Also convert the given parameters to the correct type, etc. config = treecorr.config.check_config(config, corr3_valid_params, corr3_aliases, logger) import pprint logger.debug('Using configuration dict:\n%s', pprint.pformat(config)) if ('output_dots' not in config and config.get('log_file', None) is None and config['verbose'] >= 2): config['output_dots'] = True # Set the number of threads num_threads = config.get('num_threads', None) logger.debug('From config dict, num_threads = %s', num_threads) treecorr.set_omp_threads(num_threads, logger) # Read in the input files. Each of these is a list. cat1 = treecorr.read_catalogs(config, 'file_name', 'file_list', 0, logger) if len(cat1) == 0: raise AttributeError("Either file_name or file_list is required") cat2 = treecorr.read_catalogs(config, 'file_name2', 'rand_file_list2', 1, logger) cat3 = treecorr.read_catalogs(config, 'file_name3', 'rand_file_list3', 1, logger) rand1 = treecorr.read_catalogs(config, 'rand_file_name', 'rand_file_list', 0, logger) rand2 = treecorr.read_catalogs(config, 'rand_file_name2', 'rand_file_list2', 1, logger) rand3 = treecorr.read_catalogs(config, 'rand_file_name3', 'rand_file_list3', 1, logger) if len(cat2) == 0 and len(rand2) > 0: raise AttributeError("rand_file_name2 is invalid without file_name2") if len(cat3) == 0 and len(rand3) > 0: raise AttributeError("rand_file_name3 is invalid without file_name3") logger.info("Done reading input catalogs") # Do GGG correlation function if necessary if 'ggg_file_name' in config: #or 'm3_file_name' in config: logger.info("Start GGG calculations...") ggg = treecorr.GGGCorrelation(config, logger) ggg.process(cat1, cat2, cat3) logger.info("Done GGG calculations.") if 'ggg_file_name' in config: ggg.write(config['ggg_file_name']) if 'm3_file_name' in config: ggg.writeMapSq(config['m3_file_name']) # Do NNN correlation function if necessary if 'nnn_file_name' in config: if len(rand1) == 0: raise AttributeError( "rand_file_name is required for NNN correlation") if len(cat2) > 0 and len(rand2) == 0: raise AttributeError( "rand_file_name2 is required for NNN cross-correlation") if len(cat3) > 0 and len(rand3) == 0: raise AttributeError( "rand_file_name3 is required for NNN cross-correlation") if (len(cat2) > 0) != (len(cat3) > 0): raise NotImplementedError( "Cannot yet handle 3-point corrleations with only two catalogs. " + "Need both cat2 and cat3.") logger.info("Start DDD calculations...") ddd = treecorr.NNNCorrelation(config, logger) ddd.process(cat1, cat2, cat3) logger.info("Done DDD calculations.") if len(cat2) == 0: rrr = treecorr.NNNCorrelation(config, logger) rrr.process(rand1) logger.info("Done RRR calculations.") # For the next step, just make cat2 = cat3 = cat1 and rand2 = rand3 = rand1. cat2 = cat3 = cat1 rand2 = rand3 = rand1 else: rrr = treecorr.NNNCorrelation(config, logger) rrr.process(rand1, rand2, rand3) logger.info("Done RRR calculations.") if config['nnn_statistic'] == 'compensated': drr = treecorr.NNNCorrelation(config, logger) drr.process(cat1, rand2, rand3) logger.info("Done DRR calculations.") ddr = treecorr.NNNCorrelation(config, logger) ddr.process(cat1, cat2, rand3) logger.info("Done DDR calculations.") rdr = treecorr.NNNCorrelation(config, logger) rdr.process(rand1, cat2, rand3) logger.info("Done RDR calculations.") rrd = treecorr.NNNCorrelation(config, logger) rrd.process(rand1, rand2, cat3) logger.info("Done RRD calculations.") drd = treecorr.NNNCorrelation(config, logger) drd.process(cat1, rand2, cat3) logger.info("Done DRD calculations.") rdd = treecorr.NNNCorrelation(config, logger) rdd.process(rand1, cat2, cat3) logger.info("Done RDD calculations.") ddd.write(config['nnn_file_name'], rrr, drr, rdr, rrd, ddr, drd, rdd) else: ddd.write(config['nnn_file_name'], rrr) # Do KKK correlation function if necessary if 'kkk_file_name' in config: logger.info("Start KKK calculations...") kkk = treecorr.KKKCorrelation(config, logger) kkk.process(cat1, cat2, cat3) logger.info("Done KKK calculations.") kkk.write(config['kkk_file_name']) # Do NNG correlation function if necessary if False: #if 'nng_file_name' in config or 'nnm_file_name' in config: if len(cat3) == 0: raise AttributeError("file_name3 is required for nng correlation") logger.info("Start NNG calculations...") nng = treecorr.NNGCorrelation(config, logger) nng.process(cat1, cat2, cat3) logger.info("Done NNG calculation.") # The default ng_statistic is compensated _iff_ rand files are given. rrg = None if len(rand1) == 0: if config.get('nng_statistic', None) == 'compensated': raise AttributeError( "rand_files is required for nng_statistic = compensated") elif config.get('nng_statistic', 'compensated') == 'compensated': rrg = treecorr.NNGCorrelation(config, logger) rrg.process(rand1, rand1, cat2) logger.info("Done RRG calculation.") if 'nng_file_name' in config: nng.write(config['nng_file_name'], rrg) if 'nnm_file_name' in config: nng.writeNNMap(config['nnm_file_name'], rrg) # Do NNK correlation function if necessary if False: #if 'nnk_file_name' in config: if len(cat3) == 0: raise AttributeError("file_name3 is required for nnk correlation") logger.info("Start NNK calculations...") nnk = treecorr.NNKCorrelation(config, logger) nnk.process(cat1, cat2, cat3) logger.info("Done NNK calculation.") rrk = None if len(rand1) == 0: if config.get('nnk_statistic', None) == 'compensated': raise AttributeError( "rand_files is required for nnk_statistic = compensated") elif config.get('nnk_statistic', 'compensated') == 'compensated': rrk = treecorr.NNKCorrelation(config, logger) rrk.process(rand1, rand1, cat2) logger.info("Done RRK calculation.") nnk.write(config['nnk_file_name'], rrk) # Do KKG correlation function if necessary if False: #if 'kkg_file_name' in config: if len(cat3) == 0: raise AttributeError("file_name3 is required for kkg correlation") logger.info("Start KKG calculations...") kkg = treecorr.KKGCorrelation(config, logger) kkg.process(cat1, cat2, cat3) logger.info("Done KKG calculation.") kkg.write(config['kkg_file_name'])
def test_kkk(): # Use kappa(r) = A exp(-r^2/2s^2) # # The Fourier transform is: kappa~(k) = 2 pi A s^2 exp(-s^2 k^2/2) / L^2 # # B(k1,k2) = <k~(k1) k~(k2) k~(-k1-k2)> # = (2 pi A (s/L)^2)^3 exp(-s^2 (|k1|^2 + |k2|^2 - k1.k2)) # = (2 pi A (s/L)^2)^3 exp(-s^2 (|k1|^2 + |k2|^2 + |k3|^2)/2) # # zeta(r1,r2) = (1/2pi)^4 int(d^2k1 int(d^2k2 exp(ik1.x1) exp(ik2.x2) B(k1,k2) )) # = 2/3 pi A^3 (s/L)^2 exp(-(x1^2 + y1^2 + x2^2 + y2^2 - x1x2 - y1y2)/3s^2) # = 2/3 pi A^3 (s/L)^2 exp(-(d1^2 + d2^2 + d3^2)/6s^2) A = 0.05 s = 10. if __name__ == '__main__': ngal = 200000 L = 30. * s # Not infinity, so this introduces some error. Our integrals were to infinity. tol_factor = 1 else: # Looser tests from nosetests that don't take so long to run. ngal = 10000 L = 20. * s tol_factor = 5 rng = np.random.RandomState(8675309) x = (rng.random_sample(ngal) - 0.5) * L y = (rng.random_sample(ngal) - 0.5) * L r2 = (x**2 + y**2) / s**2 kappa = A * np.exp(-r2 / 2.) min_sep = 11. max_sep = 15. nbins = 3 min_u = 0.7 max_u = 1.0 nubins = 3 min_v = 0.1 max_v = 0.3 nvbins = 2 cat = treecorr.Catalog(x=x, y=y, k=kappa, x_units='arcmin', y_units='arcmin') kkk = treecorr.KKKCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, min_v=min_v, max_v=max_v, nubins=nubins, nvbins=nvbins, sep_units='arcmin', verbose=1) kkk.process(cat) # log(<d>) != <logd>, but it should be close: print('meanlogd1 - log(meand1) = ', kkk.meanlogd1 - np.log(kkk.meand1)) print('meanlogd2 - log(meand2) = ', kkk.meanlogd2 - np.log(kkk.meand2)) print('meanlogd3 - log(meand3) = ', kkk.meanlogd3 - np.log(kkk.meand3)) print('meand3 / meand2 = ', kkk.meand3 / kkk.meand2) print('meanu = ', kkk.meanu) print('max diff = ', np.max(np.abs(kkk.meand3 / kkk.meand2 - kkk.meanu))) print('max rel diff = ', np.max(np.abs((kkk.meand3 / kkk.meand2 - kkk.meanu) / kkk.meanu))) print('(meand1 - meand2)/meand3 = ', (kkk.meand1 - kkk.meand2) / kkk.meand3) print('meanv = ', kkk.meanv) print( 'max diff = ', np.max( np.abs((kkk.meand1 - kkk.meand2) / kkk.meand3 - np.abs(kkk.meanv)))) print( 'max rel diff = ', np.max( np.abs( ((kkk.meand1 - kkk.meand2) / kkk.meand3 - np.abs(kkk.meanv)) / kkk.meanv))) np.testing.assert_allclose(kkk.meanlogd1, np.log(kkk.meand1), rtol=1.e-3) np.testing.assert_allclose(kkk.meanlogd2, np.log(kkk.meand2), rtol=1.e-3) np.testing.assert_allclose(kkk.meanlogd3, np.log(kkk.meand3), rtol=1.e-3) np.testing.assert_allclose(kkk.meand3 / kkk.meand2, kkk.meanu, rtol=1.e-5 * tol_factor) np.testing.assert_allclose(np.abs(kkk.meand1 - kkk.meand2) / kkk.meand3, np.abs(kkk.meanv), rtol=1.e-5 * tol_factor, atol=1.e-5 * tol_factor) np.testing.assert_allclose(kkk.meanlogd3 - kkk.meanlogd2, np.log(kkk.meanu), atol=1.e-3 * tol_factor) np.testing.assert_allclose(np.log(np.abs(kkk.meand1 - kkk.meand2)) - kkk.meanlogd3, np.log(np.abs(kkk.meanv)), atol=2.e-3 * tol_factor) d1 = kkk.meand1 d2 = kkk.meand2 d3 = kkk.meand3 #print('rnom = ',np.exp(kkk.logr)) #print('unom = ',kkk.u) #print('vnom = ',kkk.v) #print('d1 = ',d1) #print('d2 = ',d2) #print('d3 = ',d3) # The L^2 term in the denominator of true_zeta is the area over which the integral is done. # Since the centers of the triangles don't go to the edge of the box, we approximate the # correct area by subtracting off 2d2 from L, which should give a slightly better estimate # of the correct area to use here. L = L - 2. * d2 true_zeta = (2. * np.pi / 3) * A**3 * (s / L)**2 * np.exp( -(d1**2 + d2**2 + d3**2) / (6. * s**2)) #print('ntri = ',kkk.ntri) print('zeta = ', kkk.zeta) print('true_zeta = ', true_zeta) #print('ratio = ',kkk.zeta / true_zeta) #print('diff = ',kkk.zeta - true_zeta) print('max rel diff = ', np.max(np.abs( (kkk.zeta - true_zeta) / true_zeta))) np.testing.assert_allclose(kkk.zeta, true_zeta, rtol=0.1 * tol_factor) np.testing.assert_allclose(np.log(np.abs(kkk.zeta)), np.log(np.abs(true_zeta)), atol=0.1 * tol_factor) # Check that we get the same result using the corr3 functin: cat.write(os.path.join('data', 'kkk_data.dat')) config = treecorr.config.read_config('configs/kkk.yaml') config['verbose'] = 0 treecorr.corr3(config) corr3_output = np.genfromtxt(os.path.join('output', 'kkk.out'), names=True, skip_header=1) np.testing.assert_almost_equal(corr3_output['zeta'], kkk.zeta.flatten()) try: import fitsio except ImportError: print('Skipping FITS tests, since fitsio is not installed') return # Check the fits write option out_file_name = os.path.join('output', 'kkk_out.fits') kkk.write(out_file_name) data = fitsio.read(out_file_name) np.testing.assert_almost_equal(data['r_nom'], np.exp(kkk.logr).flatten()) np.testing.assert_almost_equal(data['u_nom'], kkk.u.flatten()) np.testing.assert_almost_equal(data['v_nom'], kkk.v.flatten()) np.testing.assert_almost_equal(data['meand1'], kkk.meand1.flatten()) np.testing.assert_almost_equal(data['meanlogd1'], kkk.meanlogd1.flatten()) np.testing.assert_almost_equal(data['meand2'], kkk.meand2.flatten()) np.testing.assert_almost_equal(data['meanlogd2'], kkk.meanlogd2.flatten()) np.testing.assert_almost_equal(data['meand3'], kkk.meand3.flatten()) np.testing.assert_almost_equal(data['meanlogd3'], kkk.meanlogd3.flatten()) np.testing.assert_almost_equal(data['meanu'], kkk.meanu.flatten()) np.testing.assert_almost_equal(data['meanv'], kkk.meanv.flatten()) np.testing.assert_almost_equal(data['zeta'], kkk.zeta.flatten()) np.testing.assert_almost_equal(data['sigma_zeta'], np.sqrt(kkk.varzeta.flatten())) np.testing.assert_almost_equal(data['weight'], kkk.weight.flatten()) np.testing.assert_almost_equal(data['ntri'], kkk.ntri.flatten()) # Check the read function # Note: These don't need the flatten. The read function should reshape them to the right shape. kkk2 = treecorr.KKKCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, min_v=min_v, max_v=max_v, nubins=nubins, nvbins=nvbins, sep_units='arcmin', verbose=1) kkk2.read(out_file_name) np.testing.assert_almost_equal(kkk2.logr, kkk.logr) np.testing.assert_almost_equal(kkk2.u, kkk.u) np.testing.assert_almost_equal(kkk2.v, kkk.v) np.testing.assert_almost_equal(kkk2.meand1, kkk.meand1) np.testing.assert_almost_equal(kkk2.meanlogd1, kkk.meanlogd1) np.testing.assert_almost_equal(kkk2.meand2, kkk.meand2) np.testing.assert_almost_equal(kkk2.meanlogd2, kkk.meanlogd2) np.testing.assert_almost_equal(kkk2.meand3, kkk.meand3) np.testing.assert_almost_equal(kkk2.meanlogd3, kkk.meanlogd3) np.testing.assert_almost_equal(kkk2.meanu, kkk.meanu) np.testing.assert_almost_equal(kkk2.meanv, kkk.meanv) np.testing.assert_almost_equal(kkk2.zeta, kkk.zeta) np.testing.assert_almost_equal(kkk2.varzeta, kkk.varzeta) np.testing.assert_almost_equal(kkk2.weight, kkk.weight) np.testing.assert_almost_equal(kkk2.ntri, kkk.ntri) assert kkk2.coords == kkk.coords assert kkk2.metric == kkk.metric assert kkk2.sep_units == kkk.sep_units assert kkk2.bin_type == kkk.bin_type
def test_direct_spherical(): # Repeat in spherical coords ngal = 50 s = 10. rng = np.random.RandomState(8675309) x = rng.normal(0, s, (ngal, )) y = rng.normal( 0, s, (ngal, )) + 200 # Put everything at large y, so small angle on sky z = rng.normal(0, s, (ngal, )) w = rng.random_sample(ngal) kap = rng.normal(0, 3, (ngal, )) w = np.ones_like(w) ra, dec = coord.CelestialCoord.xyz_to_radec(x, y, z) cat = treecorr.Catalog(ra=ra, dec=dec, ra_units='rad', dec_units='rad', w=w, k=kap) min_sep = 1. bin_size = 0.2 nrbins = 10 nubins = 5 nvbins = 5 max_sep = min_sep * np.exp(nrbins * bin_size) kkk = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, sep_units='deg', brute=True) kkk.process(cat) r = np.sqrt(x**2 + y**2 + z**2) x /= r y /= r z /= r north_pole = coord.CelestialCoord(0 * coord.radians, 90 * coord.degrees) true_ntri = np.zeros((nrbins, nubins, 2 * nvbins), dtype=int) true_weight = np.zeros((nrbins, nubins, 2 * nvbins), dtype=float) true_zeta = np.zeros((nrbins, nubins, 2 * nvbins), dtype=float) rad_min_sep = min_sep * coord.degrees / coord.radians rad_max_sep = max_sep * coord.degrees / coord.radians c = [ coord.CelestialCoord(r * coord.radians, d * coord.radians) for (r, d) in zip(ra, dec) ] for i in range(ngal): for j in range(i + 1, ngal): for k in range(j + 1, ngal): d12 = np.sqrt((x[i] - x[j])**2 + (y[i] - y[j])**2 + (z[i] - z[j])**2) d23 = np.sqrt((x[j] - x[k])**2 + (y[j] - y[k])**2 + (z[j] - z[k])**2) d31 = np.sqrt((x[k] - x[i])**2 + (y[k] - y[i])**2 + (z[k] - z[i])**2) d3, d2, d1 = sorted([d12, d23, d31]) rindex = np.floor(np.log(d2 / rad_min_sep) / bin_size).astype(int) if rindex < 0 or rindex >= nrbins: continue if [d1, d2, d3] == [d23, d31, d12]: ii, jj, kk = i, j, k elif [d1, d2, d3] == [d23, d12, d31]: ii, jj, kk = i, k, j elif [d1, d2, d3] == [d31, d12, d23]: ii, jj, kk = j, k, i elif [d1, d2, d3] == [d31, d23, d12]: ii, jj, kk = j, i, k elif [d1, d2, d3] == [d12, d23, d31]: ii, jj, kk = k, i, j elif [d1, d2, d3] == [d12, d31, d23]: ii, jj, kk = k, j, i else: assert False # Now use ii, jj, kk rather than i,j,k, to get the indices # that correspond to the points in the right order. u = d3 / d2 v = (d1 - d2) / d3 if (((x[jj] - x[ii]) * (y[kk] - y[ii]) - (x[kk] - x[ii]) * (y[jj] - y[ii])) * z[ii] + ((y[jj] - y[ii]) * (z[kk] - z[ii]) - (y[kk] - y[ii]) * (z[jj] - z[ii])) * x[ii] + ((z[jj] - z[ii]) * (x[kk] - x[ii]) - (z[kk] - z[ii]) * (x[jj] - x[ii])) * y[ii]) > 0: v = -v uindex = np.floor(u / bin_size).astype(int) assert 0 <= uindex < nubins vindex = np.floor((v + 1) / bin_size).astype(int) assert 0 <= vindex < 2 * nvbins www = w[i] * w[j] * w[k] zeta = www * kap[i] * kap[j] * kap[k] true_ntri[rindex, uindex, vindex] += 1 true_weight[rindex, uindex, vindex] += www true_zeta[rindex, uindex, vindex] += zeta pos = true_weight > 0 true_zeta[pos] /= true_weight[pos] np.testing.assert_array_equal(kkk.ntri, true_ntri) np.testing.assert_allclose(kkk.weight, true_weight, rtol=1.e-5, atol=1.e-8) np.testing.assert_allclose(kkk.zeta, true_zeta, rtol=1.e-4, atol=1.e-6) try: import fitsio except ImportError: print('Skipping FITS tests, since fitsio is not installed') return # Check that running via the corr3 script works correctly. config = treecorr.config.read_config('configs/kkk_direct_spherical.yaml') cat.write(config['file_name']) treecorr.corr3(config) data = fitsio.read(config['kkk_file_name']) np.testing.assert_allclose(data['r_nom'], kkk.rnom.flatten()) np.testing.assert_allclose(data['u_nom'], kkk.u.flatten()) np.testing.assert_allclose(data['v_nom'], kkk.v.flatten()) np.testing.assert_allclose(data['ntri'], kkk.ntri.flatten()) np.testing.assert_allclose(data['weight'], kkk.weight.flatten()) np.testing.assert_allclose(data['zeta'], kkk.zeta.flatten(), rtol=1.e-3) # Repeat with binslop = 0 # And don't do any top-level recursion so we actually test not going to the leaves. kkk = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, sep_units='deg', bin_slop=0, max_top=0) kkk.process(cat) np.testing.assert_array_equal(kkk.ntri, true_ntri) np.testing.assert_allclose(kkk.weight, true_weight, rtol=1.e-5, atol=1.e-8) np.testing.assert_allclose(kkk.zeta, true_zeta, rtol=1.e-4, atol=1.e-6)
def test_direct(): # If the catalogs are small enough, we can do a direct calculation to see if comes out right. # This should exactly match the treecorr result if brute=True. ngal = 100 s = 10. rng = np.random.RandomState(8675309) x = rng.normal(0, s, (ngal, )) y = rng.normal(0, s, (ngal, )) w = rng.random_sample(ngal) kap = rng.normal(0, 3, (ngal, )) cat = treecorr.Catalog(x=x, y=y, w=w, k=kap) min_sep = 1. bin_size = 0.2 nrbins = 10 nubins = 5 nvbins = 5 max_sep = min_sep * np.exp(nrbins * bin_size) kkk = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, brute=True) kkk.process(cat, num_threads=2) true_ntri = np.zeros((nrbins, nubins, 2 * nvbins), dtype=int) true_weight = np.zeros((nrbins, nubins, 2 * nvbins), dtype=float) true_zeta = np.zeros((nrbins, nubins, 2 * nvbins), dtype=float) for i in range(ngal): for j in range(i + 1, ngal): for k in range(j + 1, ngal): d12 = np.sqrt((x[i] - x[j])**2 + (y[i] - y[j])**2) d23 = np.sqrt((x[j] - x[k])**2 + (y[j] - y[k])**2) d31 = np.sqrt((x[k] - x[i])**2 + (y[k] - y[i])**2) d3, d2, d1 = sorted([d12, d23, d31]) rindex = np.floor(np.log(d2 / min_sep) / bin_size).astype(int) if rindex < 0 or rindex >= nrbins: continue if [d1, d2, d3] == [d23, d31, d12]: ii, jj, kk = i, j, k elif [d1, d2, d3] == [d23, d12, d31]: ii, jj, kk = i, k, j elif [d1, d2, d3] == [d31, d12, d23]: ii, jj, kk = j, k, i elif [d1, d2, d3] == [d31, d23, d12]: ii, jj, kk = j, i, k elif [d1, d2, d3] == [d12, d23, d31]: ii, jj, kk = k, i, j elif [d1, d2, d3] == [d12, d31, d23]: ii, jj, kk = k, j, i else: assert False # Now use ii, jj, kk rather than i,j,k, to get the indices # that correspond to the points in the right order. u = d3 / d2 v = (d1 - d2) / d3 if (x[jj] - x[ii]) * (y[kk] - y[ii]) < (x[kk] - x[ii]) * ( y[jj] - y[ii]): v = -v uindex = np.floor(u / bin_size).astype(int) assert 0 <= uindex < nubins vindex = np.floor((v + 1) / bin_size).astype(int) assert 0 <= vindex < 2 * nvbins www = w[i] * w[j] * w[k] zeta = www * kap[i] * kap[j] * kap[k] true_ntri[rindex, uindex, vindex] += 1 true_weight[rindex, uindex, vindex] += www true_zeta[rindex, uindex, vindex] += zeta pos = true_weight > 0 true_zeta[pos] /= true_weight[pos] np.testing.assert_array_equal(kkk.ntri, true_ntri) np.testing.assert_allclose(kkk.weight, true_weight, rtol=1.e-5, atol=1.e-8) np.testing.assert_allclose(kkk.zeta, true_zeta, rtol=1.e-5, atol=1.e-8) try: import fitsio except ImportError: print('Skipping FITS tests, since fitsio is not installed') return # Check that running via the corr3 script works correctly. config = treecorr.config.read_config('configs/kkk_direct.yaml') cat.write(config['file_name']) treecorr.corr3(config) data = fitsio.read(config['kkk_file_name']) np.testing.assert_allclose(data['r_nom'], kkk.rnom.flatten()) np.testing.assert_allclose(data['u_nom'], kkk.u.flatten()) np.testing.assert_allclose(data['v_nom'], kkk.v.flatten()) np.testing.assert_allclose(data['ntri'], kkk.ntri.flatten()) np.testing.assert_allclose(data['weight'], kkk.weight.flatten()) np.testing.assert_allclose(data['zeta'], kkk.zeta.flatten(), rtol=1.e-3) # Also check the "cross" calculation. (Real cross doesn't work, but this should.) kkk = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, brute=True) kkk.process(cat, cat, cat, num_threads=2) np.testing.assert_array_equal(kkk.ntri, true_ntri) np.testing.assert_allclose(kkk.weight, true_weight, rtol=1.e-5, atol=1.e-8) np.testing.assert_allclose(kkk.zeta, true_zeta, rtol=1.e-5, atol=1.e-8) config['file_name2'] = config['file_name'] config['file_name3'] = config['file_name'] treecorr.corr3(config) data = fitsio.read(config['kkk_file_name']) np.testing.assert_allclose(data['r_nom'], kkk.rnom.flatten()) np.testing.assert_allclose(data['u_nom'], kkk.u.flatten()) np.testing.assert_allclose(data['v_nom'], kkk.v.flatten()) np.testing.assert_allclose(data['ntri'], kkk.ntri.flatten()) np.testing.assert_allclose(data['weight'], kkk.weight.flatten()) np.testing.assert_allclose(data['zeta'], kkk.zeta.flatten(), rtol=1.e-3) # Repeat with binslop = 0 # And don't do any top-level recursion so we actually test not going to the leaves. kkk = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, bin_slop=0, max_top=0) kkk.process(cat) np.testing.assert_array_equal(kkk.ntri, true_ntri) np.testing.assert_allclose(kkk.weight, true_weight, rtol=1.e-5, atol=1.e-8) np.testing.assert_allclose(kkk.zeta, true_zeta, rtol=1.e-5, atol=1.e-8) # Check a few basic operations with a GGCorrelation object. do_pickle(kkk) kkk2 = kkk.copy() kkk2 += kkk np.testing.assert_allclose(kkk2.ntri, 2 * kkk.ntri) np.testing.assert_allclose(kkk2.weight, 2 * kkk.weight) np.testing.assert_allclose(kkk2.meand1, 2 * kkk.meand1) np.testing.assert_allclose(kkk2.meand2, 2 * kkk.meand2) np.testing.assert_allclose(kkk2.meand3, 2 * kkk.meand3) np.testing.assert_allclose(kkk2.meanlogd1, 2 * kkk.meanlogd1) np.testing.assert_allclose(kkk2.meanlogd2, 2 * kkk.meanlogd2) np.testing.assert_allclose(kkk2.meanlogd3, 2 * kkk.meanlogd3) np.testing.assert_allclose(kkk2.meanu, 2 * kkk.meanu) np.testing.assert_allclose(kkk2.meanv, 2 * kkk.meanv) np.testing.assert_allclose(kkk2.zeta, 2 * kkk.zeta) kkk2.clear() kkk2 += kkk np.testing.assert_allclose(kkk2.ntri, kkk.ntri) np.testing.assert_allclose(kkk2.weight, kkk.weight) np.testing.assert_allclose(kkk2.meand1, kkk.meand1) np.testing.assert_allclose(kkk2.meand2, kkk.meand2) np.testing.assert_allclose(kkk2.meand3, kkk.meand3) np.testing.assert_allclose(kkk2.meanlogd1, kkk.meanlogd1) np.testing.assert_allclose(kkk2.meanlogd2, kkk.meanlogd2) np.testing.assert_allclose(kkk2.meanlogd3, kkk.meanlogd3) np.testing.assert_allclose(kkk2.meanu, kkk.meanu) np.testing.assert_allclose(kkk2.meanv, kkk.meanv) np.testing.assert_allclose(kkk2.zeta, kkk.zeta) ascii_name = 'output/kkk_ascii.txt' kkk.write(ascii_name, precision=16) kkk3 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins) kkk3.read(ascii_name) np.testing.assert_allclose(kkk3.ntri, kkk.ntri) np.testing.assert_allclose(kkk3.weight, kkk.weight) np.testing.assert_allclose(kkk3.meand1, kkk.meand1) np.testing.assert_allclose(kkk3.meand2, kkk.meand2) np.testing.assert_allclose(kkk3.meand3, kkk.meand3) np.testing.assert_allclose(kkk3.meanlogd1, kkk.meanlogd1) np.testing.assert_allclose(kkk3.meanlogd2, kkk.meanlogd2) np.testing.assert_allclose(kkk3.meanlogd3, kkk.meanlogd3) np.testing.assert_allclose(kkk3.meanu, kkk.meanu) np.testing.assert_allclose(kkk3.meanv, kkk.meanv) np.testing.assert_allclose(kkk3.zeta, kkk.zeta) fits_name = 'output/kkk_fits.fits' kkk.write(fits_name) kkk4 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins) kkk4.read(fits_name) np.testing.assert_allclose(kkk4.ntri, kkk.ntri) np.testing.assert_allclose(kkk4.weight, kkk.weight) np.testing.assert_allclose(kkk4.meand1, kkk.meand1) np.testing.assert_allclose(kkk4.meand2, kkk.meand2) np.testing.assert_allclose(kkk4.meand3, kkk.meand3) np.testing.assert_allclose(kkk4.meanlogd1, kkk.meanlogd1) np.testing.assert_allclose(kkk4.meanlogd2, kkk.meanlogd2) np.testing.assert_allclose(kkk4.meanlogd3, kkk.meanlogd3) np.testing.assert_allclose(kkk4.meanu, kkk.meanu) np.testing.assert_allclose(kkk4.meanv, kkk.meanv) np.testing.assert_allclose(kkk4.zeta, kkk.zeta) with assert_raises(TypeError): kkk2 += config kkk5 = treecorr.KKKCorrelation(min_sep=min_sep / 2, bin_size=bin_size, nbins=nrbins) with assert_raises(ValueError): kkk2 += kkk5 kkk6 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size / 2, nbins=nrbins) with assert_raises(ValueError): kkk2 += kkk6 kkk7 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins * 2) with assert_raises(ValueError): kkk2 += kkk7 kkk8 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, min_u=0.1) with assert_raises(ValueError): kkk2 += kkk8 kkk0 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, max_u=0.1) with assert_raises(ValueError): kkk2 += kkk0 kkk10 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, nubins=nrbins * 2) with assert_raises(ValueError): kkk2 += kkk10 kkk11 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, min_v=0.1) with assert_raises(ValueError): kkk2 += kkk11 kkk12 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, max_v=0.1) with assert_raises(ValueError): kkk2 += kkk12 kkk13 = treecorr.KKKCorrelation(min_sep=min_sep, bin_size=bin_size, nbins=nrbins, nvbins=nrbins * 2) with assert_raises(ValueError): kkk2 += kkk13 # Currently not implemented to only have cat2 or cat3 with assert_raises(NotImplementedError): kkk.process(cat, cat2=cat) with assert_raises(NotImplementedError): kkk.process(cat, cat3=cat) with assert_raises(NotImplementedError): kkk.process_cross21(cat, cat)
def corr3(config, logger=None): """Run the full three-point correlation function code based on the parameters in the given config dict. The function `print_corr3_params` will output information about the valid parameters that are expected to be in the config dict. Optionally a logger parameter maybe given, in which case it is used for logging. If not given, the logging will be based on the verbose and log_file parameters. :param config: The configuration dict which defines what to do. :param logger: If desired, a logger object for logging. (default: None, in which case one will be built according to the config dict's verbose level.) """ # Setup logger based on config verbose value if logger is None: logger = treecorr.config.setup_logger( treecorr.config.get(config, 'verbose', int, 1), config.get('log_file', None)) # Check that config doesn't have any extra parameters. # (Such values are probably typos.) # Also convert the given parameters to the correct type, etc. config = treecorr.config.check_config(config, corr3_valid_params, corr3_aliases, logger) import pprint logger.debug('Using configuration dict:\n%s', pprint.pformat(config)) if ('output_dots' not in config and config.get('log_file', None) is None and config['verbose'] >= 2): config['output_dots'] = True # Set the number of threads num_threads = config.get('num_threads', None) logger.debug('From config dict, num_threads = %s', num_threads) treecorr.set_omp_threads(num_threads, logger) # Read in the input files. Each of these is a list. cat1 = treecorr.read_catalogs(config, 'file_name', 'file_list', 0, logger) cat2 = treecorr.read_catalogs(config, 'file_name2', 'rand_file_list2', 1, logger) cat3 = treecorr.read_catalogs(config, 'file_name3', 'rand_file_list3', 1, logger) rand1 = treecorr.read_catalogs(config, 'rand_file_name', 'rand_file_list', 0, logger) rand2 = treecorr.read_catalogs(config, 'rand_file_name2', 'rand_file_list2', 1, logger) rand3 = treecorr.read_catalogs(config, 'rand_file_name3', 'rand_file_list3', 1, logger) if len(cat1) == 0: raise TypeError("Either file_name or file_list is required") if len(cat2) == 0: cat2 = None if len(cat3) == 0: cat3 = None if len(rand1) == 0: rand1 = None if len(rand2) == 0: rand2 = None if len(rand3) == 0: rand3 = None if cat2 is None and rand2 is not None: raise TypeError("rand_file_name2 is invalid without file_name2") if cat3 is None and rand3 is not None: raise TypeError("rand_file_name3 is invalid without file_name3") if (cat2 is None) != (cat3 is None): raise NotImplementedError( "Cannot yet handle 3-point corrleations with only two catalogs. " + "Need both cat2 and cat3.") logger.info("Done reading input catalogs") # Do GGG correlation function if necessary if 'ggg_file_name' in config or 'm3_file_name' in config: logger.warning("Performing GGG calculations...") ggg = treecorr.GGGCorrelation(config, logger) ggg.process(cat1, cat2, cat3) logger.info("Done GGG calculations.") if 'ggg_file_name' in config: ggg.write(config['ggg_file_name']) logger.warning("Wrote GGG correlation to %s", config['ggg_file_name']) if 'm3_file_name' in config: ggg.writeMap3(config['m3_file_name']) logger.warning("Wrote Map3 values to %s", config['m3_file_name']) # Do NNN correlation function if necessary if 'nnn_file_name' in config: logger.warning("Performing DDD calculations...") ddd = treecorr.NNNCorrelation(config, logger) ddd.process(cat1, cat2, cat3) logger.info("Done DDD calculations.") drr = None rdr = None rrd = None ddr = None drd = None rdd = None if rand1 is None: if rand2 is not None or rand3 is not None: raise TypeError( "rand_file_name is required if rand2 or rand3 is given") logger.warning( "No random catalogs given. Only doing ntri calculation.") rrr = None elif cat2 is None: logger.warning("Performing RRR calculations...") rrr = treecorr.NNNCorrelation(config, logger) rrr.process(rand1) logger.info("Done RRR calculations.") # For the next step, just make cat2 = cat3 = cat1 and rand2 = rand3 = rand1. cat2 = cat3 = cat1 rand2 = rand3 = rand1 else: if rand2 is None: raise TypeError( "rand_file_name2 is required when file_name2 is given") if cat3 is not None and rand3 is None: raise TypeError( "rand_file_name3 is required when file_name3 is given") logger.warning("Performing RRR calculations...") rrr = treecorr.NNNCorrelation(config, logger) rrr.process(rand1, rand2, rand3) logger.info("Done RRR calculations.") if rrr is not None and config['nnn_statistic'] == 'compensated': logger.warning("Performing DRR calculations...") drr = treecorr.NNNCorrelation(config, logger) drr.process(cat1, rand2, rand3) logger.info("Done DRR calculations.") logger.warning("Performing DDR calculations...") ddr = treecorr.NNNCorrelation(config, logger) ddr.process(cat1, cat2, rand3) logger.info("Done DDR calculations.") logger.warning("Performing RDR calculations...") rdr = treecorr.NNNCorrelation(config, logger) rdr.process(rand1, cat2, rand3) logger.info("Done RDR calculations.") logger.warning("Performing RRD calculations...") rrd = treecorr.NNNCorrelation(config, logger) rrd.process(rand1, rand2, cat3) logger.info("Done RRD calculations.") logger.warning("Performing DRD calculations...") drd = treecorr.NNNCorrelation(config, logger) drd.process(cat1, rand2, cat3) logger.info("Done DRD calculations.") logger.warning("Performing RDD calculations...") rdd = treecorr.NNNCorrelation(config, logger) rdd.process(rand1, cat2, cat3) logger.info("Done RDD calculations.") ddd.write(config['nnn_file_name'], rrr, drr, rdr, rrd, ddr, drd, rdd) logger.warning("Wrote NNN correlation to %s", config['nnn_file_name']) # Do KKK correlation function if necessary if 'kkk_file_name' in config: logger.warning("Performing KKK calculations...") kkk = treecorr.KKKCorrelation(config, logger) kkk.process(cat1, cat2, cat3) logger.info("Done KKK calculations.") kkk.write(config['kkk_file_name']) logger.warning("Wrote KKK correlation to %s", config['kkk_file_name'])
def test_kkk(): # Use kappa(r) = A exp(-r^2/2s^2) # # The Fourier transform is: kappa~(k) = 2 pi A s^2 exp(-s^2 k^2/2) / L^2 # # B(k1,k2) = <k~(k1) k~(k2) k~(-k1-k2)> # = (2 pi A (s/L)^2)^3 exp(-s^2 (|k1|^2 + |k2|^2 - k1.k2)) # = (2 pi A (s/L)^2)^3 exp(-s^2 (|k1|^2 + |k2|^2 + |k3|^2)/2) # # zeta(r1,r2) = (1/2pi)^4 int(d^2k1 int(d^2k2 exp(ik1.x1) exp(ik2.x2) B(k1,k2) )) # = 2/3 pi A^3 (s/L)^2 exp(-(x1^2 + y1^2 + x2^2 + y2^2 - x1x2 - y1y2)/3s^2) # = 2/3 pi A^3 (s/L)^2 exp(-(d1^2 + d2^2 + d3^2)/6s^2) A = 0.05 s = 10. if __name__ == '__main__': ngal = 200000 L = 30. * s # Not infinity, so this introduces some error. Our integrals were to infinity. req_factor = 1 else: # Looser tests from nosetests that don't take so long to run. ngal = 5000 L = 10. * s req_factor = 5 numpy.random.seed(8675309) x = (numpy.random.random_sample(ngal) - 0.5) * L y = (numpy.random.random_sample(ngal) - 0.5) * L r2 = (x**2 + y**2) / s**2 kappa = A * numpy.exp(-r2 / 2.) min_sep = 11. max_sep = 15. nbins = 3 min_u = 0.7 max_u = 1.0 nubins = 3 min_v = -0.1 max_v = 0.3 nvbins = 4 cat = treecorr.Catalog(x=x, y=y, k=kappa, x_units='arcmin', y_units='arcmin') kkk = treecorr.KKKCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, min_v=min_v, max_v=max_v, nubins=nubins, nvbins=nvbins, sep_units='arcmin', verbose=1) kkk.process(cat) # log(<d>) != <logd>, but it should be close: #print('meanlogd1 - log(meand1) = ',kkk.meanlogd1 - numpy.log(kkk.meand1)) #print('meanlogd2 - log(meand2) = ',kkk.meanlogd2 - numpy.log(kkk.meand2)) #print('meanlogd3 - log(meand3) = ',kkk.meanlogd3 - numpy.log(kkk.meand3)) #print('meanlogd3 - meanlogd2 - log(meanu) = ',kkk.meanlogd3 - kkk.meanlogd2 - numpy.log(kkk.meanu)) #print('log(meand1-meand2) - meanlogd3 - log(meanv) = ',numpy.log(kkk.meand1-kkk.meand2) - kkk.meanlogd3 - numpy.log(numpy.abs(kkk.meanv))) numpy.testing.assert_almost_equal(kkk.meanlogd1, numpy.log(kkk.meand1), decimal=3) numpy.testing.assert_almost_equal(kkk.meanlogd2, numpy.log(kkk.meand2), decimal=3) numpy.testing.assert_almost_equal(kkk.meanlogd3, numpy.log(kkk.meand3), decimal=3) numpy.testing.assert_almost_equal(kkk.meanlogd3 - kkk.meanlogd2, numpy.log(kkk.meanu), decimal=3) numpy.testing.assert_almost_equal(numpy.log(kkk.meand1 - kkk.meand2) - kkk.meanlogd3, numpy.log(numpy.abs(kkk.meanv)), decimal=3) d1 = kkk.meand1 d2 = kkk.meand2 d3 = kkk.meand3 #print('rnom = ',numpy.exp(kkk.logr)) #print('unom = ',kkk.u) #print('vnom = ',kkk.v) #print('d1 = ',d1) #print('d2 = ',d2) #print('d3 = ',d3) # The L^2 term in the denominator of true_zeta is the area over which the integral is done. # Since the centers of the triangles don't go to the edge of the box, we approximate the # correct area by subtracting off 2d2 from L, which should give a slightly better estimate # of the correct area to use here. L = L - 2. * d2 true_zeta = (2. * numpy.pi / 3) * A**3 * (s / L)**2 * numpy.exp( -(d1**2 + d2**2 + d3**2) / (6. * s**2)) #print('ntri = ',kkk.ntri) print('zeta = ', kkk.zeta) print('true_zeta = ', true_zeta) #print('ratio = ',kkk.zeta / true_zeta) #print('diff = ',kkk.zeta - true_zeta) print('max rel diff = ', numpy.max(numpy.abs((kkk.zeta - true_zeta) / true_zeta))) assert numpy.max(numpy.abs( (kkk.zeta - true_zeta) / true_zeta)) / req_factor < 0.1 numpy.testing.assert_almost_equal( numpy.log(numpy.abs(kkk.zeta)) / req_factor, numpy.log(numpy.abs(true_zeta)) / req_factor, decimal=1) # Check that we get the same result using the corr3 executable: if __name__ == '__main__': cat.write(os.path.join('data', 'kkk_data.dat')) import subprocess corr3_exe = get_script_name('corr3') p = subprocess.Popen([corr3_exe, "kkk.yaml"]) p.communicate() corr3_output = numpy.genfromtxt(os.path.join('output', 'kkk.out'), names=True) #print('zeta = ',kkk.zeta) #print('from corr3 output = ',corr3_output['zeta']) #print('ratio = ',corr3_output['zeta']/kkk.zeta.flatten()) #print('diff = ',corr3_output['zeta']-kkk.zeta.flatten()) numpy.testing.assert_almost_equal(corr3_output['zeta'] / kkk.zeta.flatten(), 1., decimal=3) # Check the fits write option out_file_name = os.path.join('output', 'kkk_out.fits') kkk.write(out_file_name) data = fitsio.read(out_file_name) numpy.testing.assert_almost_equal(data['R_nom'], numpy.exp(kkk.logr).flatten()) numpy.testing.assert_almost_equal(data['u_nom'], kkk.u.flatten()) numpy.testing.assert_almost_equal(data['v_nom'], kkk.v.flatten()) numpy.testing.assert_almost_equal(data['meand1'], kkk.meand1.flatten()) numpy.testing.assert_almost_equal(data['meanlogd1'], kkk.meanlogd1.flatten()) numpy.testing.assert_almost_equal(data['meand2'], kkk.meand2.flatten()) numpy.testing.assert_almost_equal(data['meanlogd2'], kkk.meanlogd2.flatten()) numpy.testing.assert_almost_equal(data['meand3'], kkk.meand3.flatten()) numpy.testing.assert_almost_equal(data['meanlogd3'], kkk.meanlogd3.flatten()) numpy.testing.assert_almost_equal(data['meanu'], kkk.meanu.flatten()) numpy.testing.assert_almost_equal(data['meanv'], kkk.meanv.flatten()) numpy.testing.assert_almost_equal(data['zeta'], kkk.zeta.flatten()) numpy.testing.assert_almost_equal(data['sigma_zeta'], numpy.sqrt(kkk.varzeta.flatten())) numpy.testing.assert_almost_equal(data['weight'], kkk.weight.flatten()) numpy.testing.assert_almost_equal(data['ntri'], kkk.ntri.flatten()) # Check the read function # Note: These don't need the flatten. The read function should reshape them to the right shape. kkk2 = treecorr.KKKCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, min_v=min_v, max_v=max_v, nubins=nubins, nvbins=nvbins, sep_units='arcmin', verbose=1) kkk2.read(out_file_name) numpy.testing.assert_almost_equal(kkk2.logr, kkk.logr) numpy.testing.assert_almost_equal(kkk2.u, kkk.u) numpy.testing.assert_almost_equal(kkk2.v, kkk.v) numpy.testing.assert_almost_equal(kkk2.meand1, kkk.meand1) numpy.testing.assert_almost_equal(kkk2.meanlogd1, kkk.meanlogd1) numpy.testing.assert_almost_equal(kkk2.meand2, kkk.meand2) numpy.testing.assert_almost_equal(kkk2.meanlogd2, kkk.meanlogd2) numpy.testing.assert_almost_equal(kkk2.meand3, kkk.meand3) numpy.testing.assert_almost_equal(kkk2.meanlogd3, kkk.meanlogd3) numpy.testing.assert_almost_equal(kkk2.meanu, kkk.meanu) numpy.testing.assert_almost_equal(kkk2.meanv, kkk.meanv) numpy.testing.assert_almost_equal(kkk2.zeta, kkk.zeta) numpy.testing.assert_almost_equal(kkk2.varzeta, kkk.varzeta) numpy.testing.assert_almost_equal(kkk2.weight, kkk.weight) numpy.testing.assert_almost_equal(kkk2.ntri, kkk.ntri)