def calc_3pt(data, randoms, config_fname, zvar, random_zvar, ra_var='RA', dec_var='DEC', random_ra_var='RA', random_dec_var='DEC'): config_3pt = load_config(config_fname)['3PCF'] cat = treecorr.Catalog(ra=data[ra_var], dec=data[dec_var], dec_units='degrees', ra_units='degrees', r=datasets.buzzard_cosmo.comoving_distance(data[zvar]).value*datasets.buzzard_cosmo.h) random_cat = treecorr.Catalog(ra=randoms[random_ra_var], dec=randoms[random_dec_var], dec_units='degrees', ra_units='degrees', r=datasets.buzzard_cosmo.comoving_distance(randoms[random_zvar]).value*datasets.buzzard_cosmo.h) print config_3pt ddd = treecorr.NNNCorrelation(config=config_3pt) ddr = treecorr.NNNCorrelation(config=config_3pt) drd = treecorr.NNNCorrelation(config=config_3pt) rdd = treecorr.NNNCorrelation(config=config_3pt) rdr = treecorr.NNNCorrelation(config=config_3pt) rrd = treecorr.NNNCorrelation(config=config_3pt) drr = treecorr.NNNCorrelation(config=config_3pt) rrr = treecorr.NNNCorrelation(config=config_3pt) ddd.process(cat, metric=config_3pt['metric']) ddr.process(cat, cat, random_cat, metric=config_3pt['metric']) drd.process(cat, random_cat, cat, metric=config_3pt['metric']) rdd.process(random_cat, cat, cat, metric=config_3pt['metric']) rdr.process(random_cat, cat, random_cat, metric=config_3pt['metric']) rrd.process(random_cat, random_cat, cat, metric=config_3pt['metric']) drr.process(cat, random_cat, random_cat, metric=config_3pt['metric']) rrr.process(random_cat, random_cat, random_cat, metric=config_3pt['metric']) zeta, varzeta = ddd.calculateZeta( ddr=ddr, drd=drd, rdd=rdd, rrd=rrd, rdr=rdr, drr=drr, rrr=rrr) return zeta
def compute_3pt_raw(self): nnn = treecorr.NNNCorrelation(config=self.config_3pt) toc = time.time() setdict = {'d': self.cat, 'r': self.random_cat} nnn.process(setdict[self.set_str[0]], setdict[self.set_str[1]], setdict[self.set_str[2]], metric=self.config_3pt['metric']) tic = time.time() print '3PCF took', tic - toc stdout.flush() self.nnn = nnn
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 analyze_single_run(self, mode, **kwargs): template = treecorr.NNNCorrelation(config=self.config) if mode == 'angle': get_binned_stat = computeXvsAngle if mode == 'equi': get_binned_stat = compute_x_vs_side_length binned = {} binned['ddd'], bins = get_binned_stat(template, self.ddd, stat='sum', **kwargs) binned['ddr'], bins = get_binned_stat(template, self.ddr, stat='sum', **kwargs) binned['drd'], bins = get_binned_stat(template, self.drd, stat='sum', **kwargs) binned['rdd'], bins = get_binned_stat(template, self.rdd, stat='sum', **kwargs) binned['rrd'], bins = get_binned_stat(template, self.rrd, stat='sum', **kwargs) binned['drr'], bins = get_binned_stat(template, self.drr, stat='sum', **kwargs) binned['rdr'], bins = get_binned_stat(template, self.rdr, stat='sum', **kwargs) binned['rrr'], bins = get_binned_stat(template, self.rrr, stat='sum', **kwargs) binned['d1'], bins = get_binned_stat( template, template.u * np.abs(template.v) * np.exp(template.logr) + np.exp(template.logr), **kwargs) binned['d2'], bins = get_binned_stat(template, np.exp(template.logr), **kwargs) binned['d3'], bins = get_binned_stat( template, template.u * np.exp(template.logr), **kwargs) datatot = len(self.data) randtot = len(self.randoms) dddtot = float(datatot)**3 / 6 drrtot = float(datatot) * float(randtot)**2 / 6 rdrtot = float(datatot) * float(randtot)**2 / 6 rrdtot = float(datatot) * float(randtot)**2 / 6 ddrtot = float(datatot)**2 * float(randtot) / 6 drdtot = float(datatot)**2 * float(randtot) / 6 rddtot = float(datatot)**2 * float(randtot) / 6 rrrtot = float(randtot)**3 / 6 binned['zeta'] = (binned['ddd'] + dddtot * (-binned['ddr'] / ddrtot - binned['drd'] / drdtot - binned['rdd'] / rddtot + binned['rrd'] / rrdtot + binned['rdr'] / rdrtot + binned['drr'] / drrtot - binned['rrr'] / rrrtot)) / (binned['rrr'] * dddtot / rrrtot) binned['denom'] = self.get_two_point_expectation( binned['d1'], binned['d2'], binned['d3']) binned['q'] = binned['zeta'] / binned['denom'] return bins, binned
def test_3pt(): # Test a direct calculation of the 3pt function with the Periodic metric. from test_nnn import is_ccw ngal = 50 Lx = 250. Ly = 180. rng = np.random.RandomState(8675309) x = (rng.random_sample(ngal)-0.5) * Lx y = (rng.random_sample(ngal)-0.5) * Ly cat = treecorr.Catalog(x=x, y=y) min_sep = 1. max_sep = 40. # This only really makes sense if max_sep < L/4 for all L. nbins = 50 min_u = 0.13 max_u = 0.89 nubins = 10 min_v = 0.13 max_v = 0.59 nvbins = 10 ddd = treecorr.NNNCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, nubins=nubins, min_v=min_v, max_v=max_v, nvbins=nvbins, bin_slop=0, xperiod=Lx, yperiod=Ly, brute=True) ddd.process(cat, metric='Periodic', num_threads=1) #print('ddd.ntri = ',ddd.ntri) log_min_sep = np.log(min_sep) log_max_sep = np.log(max_sep) true_ntri = np.zeros( (nbins, nubins, 2*nvbins) ) bin_size = (log_max_sep - log_min_sep) / nbins ubin_size = (max_u-min_u) / nubins vbin_size = (max_v-min_v) / nvbins for i in range(ngal): for j in range(i+1,ngal): for k in range(j+1,ngal): xi = x[i] xj = x[j] xk = x[k] yi = y[i] yj = y[j] yk = y[k] #print(i,j,k,xi,yi,xj,yj,xk,yk) xi,xj = wrap(xi, xj, Lx, xk) #print(' ',xi,xj,xk) xi,xk = wrap(xi, xk, Lx, xj) #print(' ',xi,xj,xk) xj,xk = wrap(xj, xk, Lx, xi) #print(' ',xi,xj,xk) yi,yj = wrap(yi, yj, Ly, yk) #print(' ',yi,yj,yk) yi,yk = wrap(yi, yk, Ly, yj) #print(' ',yi,yj,yk) yj,yk = wrap(yj, yk, Ly, yi) #print(' ',yi,yj,yk) #print('->',xi,yi,xj,yj,xk,yk) dij = np.sqrt((xi-xj)**2 + (yi-yj)**2) dik = np.sqrt((xi-xk)**2 + (yi-yk)**2) djk = np.sqrt((xj-xk)**2 + (yj-yk)**2) if dij == 0.: continue if dik == 0.: continue if djk == 0.: continue ccw = True if dij < dik: if dik < djk: d3 = dij; d2 = dik; d1 = djk; ccw = is_ccw(xi,yi,xj,yj,xk,yk) elif dij < djk: d3 = dij; d2 = djk; d1 = dik; ccw = is_ccw(xj,yj,xi,yi,xk,yk) else: d3 = djk; d2 = dij; d1 = dik; ccw = is_ccw(xj,yj,xk,yk,xi,yi) else: if dij < djk: d3 = dik; d2 = dij; d1 = djk; ccw = is_ccw(xi,yi,xk,yk,xj,yj) elif dik < djk: d3 = dik; d2 = djk; d1 = dij; ccw = is_ccw(xk,yk,xi,yi,xj,yj) else: d3 = djk; d2 = dik; d1 = dij; ccw = is_ccw(xk,yk,xj,yj,xi,yi) #print('d1,d2,d3 = ',d1,d2,d3) r = d2 u = d3/d2 v = (d1-d2)/d3 if r < min_sep or r >= max_sep: continue if u < min_u or u >= max_u: continue if v < min_v or v >= max_v: continue if not ccw: v = -v #print('r,u,v = ',r,u,v) kr = int(np.floor( (np.log(r)-log_min_sep) / bin_size )) ku = int(np.floor( (u-min_u) / ubin_size )) if v > 0: kv = int(np.floor( (v-min_v) / vbin_size )) + nvbins else: kv = int(np.floor( (v-(-max_v)) / vbin_size )) #print('kr,ku,kv = ',kr,ku,kv) assert 0 <= kr < nbins assert 0 <= ku < nubins assert 0 <= kv < 2*nvbins true_ntri[kr,ku,kv] += 1 #print('good.', true_ntri[kr,ku,kv]) #print('true_ntri => ',true_ntri) #print('diff = ',ddd.ntri - true_ntri) mask = np.where(true_ntri > 0) #print('ddd.ntri[mask] = ',ddd.ntri[mask]) #print('true_ntri[mask] = ',true_ntri[mask]) #print('diff[mask] = ',(ddd.ntri - true_ntri)[mask]) mask2 = np.where(ddd.ntri > 0) #print('ddd.ntri[mask2] = ',ddd.ntri[mask2]) #print('true_ntri[mask2] = ',true_ntri[mask2]) #print('diff[mask2] = ',(ddd.ntri - true_ntri)[mask2]) np.testing.assert_array_equal(ddd.ntri, true_ntri) # If don't give a period, then an error. ddd = treecorr.NNNCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, nubins=nubins, min_v=min_v, max_v=max_v, nvbins=nvbins) with assert_raises(ValueError): ddd.process(cat, metric='Periodic') # Or if only give one kind of period ddd = treecorr.NNNCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, nubins=nubins, min_v=min_v, max_v=max_v, nvbins=nvbins, xperiod=3) with assert_raises(ValueError): ddd.process(cat, metric='Periodic') ddd = treecorr.NNNCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, nubins=nubins, min_v=min_v, max_v=max_v, nvbins=nvbins, yperiod=3) with assert_raises(ValueError): ddd.process(cat, metric='Periodic') # If give period, but then don't use Periodic metric, that's also an error. ddd = treecorr.NNNCorrelation(min_sep=min_sep, max_sep=max_sep, nbins=nbins, min_u=min_u, max_u=max_u, nubins=nubins, min_v=min_v, max_v=max_v, nvbins=nvbins, period=3) with assert_raises(ValueError): ddd.process(cat)
def load(self): [ddd, ddr, drd, rdd, drr, rdr, rrd, rrr] = 8 * [treecorr.NNNCorrelation(config=self.config)] for nnn in [ddd, ddr, drd, rdd, drr, rdr, rrd, rrr]: pass
var[np.where(isRightSize & isCollapsed)], bins=nbins, statistic='mean') full_var = np.concatenate((out2, out1)) #make edges centers bins1 += (bins1[1] - bins1[0]) / 2 bins2 += (bins2[1] - bins2[0]) / 2 full_bins = np.concatenate((bins2[:-1], bins1[:-1])) return full_var, full_bins #load data with open(output_dir + runname + '.config') as f: config = json.loads(f.read()) nnn = treecorr.NNNCorrelation(config=config) rrr = treecorr.NNNCorrelation(config=config) ddd.read(output_dir + runname + str(random_set_id) + '.out', file_type='FITS') drr.read(output_dir + runname + str(random_set_id) + '.out', file_type='FITS') data = fits.getdata(output_dir + 'redmagic_Y1_sims_data.fits') randoms = fits.getdata(output_dir + 'redmagic_Y1_sims_5x_randoms.fits') data = data[((data['ZREDMAGIC'] > config['min_z']) & (data['ZREDMAGIC'] < config['max_z']))] data = data[((data['RA'] > config['min_ra']) & (data['RA'] < config['max_ra']))] data = data[((data['DEC'] > config['min_dec']) & (data['DEC'] < config['max_dec']))]
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'])