示例#1
0
double guess_EBV_max(TImgStack &img_stack) {
	cv::Mat stack, row_avg, col_avg;
	
	// Stack images
	img_stack.stack(stack);
	
	// Normalize at each distance
	/*cv::reduce(stack, col_avg, 1, CV_REDUCE_MAX);
	double tmp;
	for(size_t i=0; i<col_avg.rows; i++) {
		tmp = col_avg.at<double>(i, 0);
		if(tmp > 0) { stack.row(i) /= tmp; }
	}*/
	
	// Sum across each EBV
	cv::reduce(stack, row_avg, 0, CV_REDUCE_AVG);
	double max_sum = *std::max_element(row_avg.begin<double>(), row_avg.end<double>());
	int max = 1;
	/*for(int i = row_avg.cols - 1; i >= 0; i--) {
		std::cout << i << "\t" << row_avg.at<double>(0, i) << std::endl;
	}*/
	//std::cout << std::endl;
	for(int i = row_avg.cols - 1; i > 0; i--) {
		//std::cout << i << "\t" << row_avg.at<double>(0, i) << std::endl;
		if(row_avg.at<double>(0, i) > 0.001 * max_sum) {
			max = i;
			break;
		}
	}
	
	// Convert bin index to E(B-V)
	return max * img_stack.rect->dx[1] + img_stack.rect->min[1];
}
// Guess upper limit for E(B-V) based on stacked probability surfaces
double guess_EBV_max(TImgStack &img_stack) {
	cv::Mat stack, row_avg, col_avg;
	
	// Stack images
	img_stack.stack(stack);
	
	// Sum across each EBV
	cv::reduce(stack, row_avg, 0, CV_REDUCE_AVG);
	double max_sum = *std::max_element(row_avg.begin<double>(), row_avg.end<double>());
	int max = 1;
	for(int i = row_avg.cols - 1; i > 0; i--) {
		if(row_avg.at<double>(0, i) > 0.001 * max_sum) {
			max = i;
			break;
		}
	}
	
	// Convert bin index to E(B-V)
	return max * img_stack.rect->dx[1] + img_stack.rect->min[1];
}
示例#3
0
void sample_indiv_emp(std::string &out_fname, TMCMCOptions &options, TGalacticLOSModel& galactic_model,
                      TStellarModel& stellar_model, TExtinctionModel& extinction_model, TStellarData& stellar_data,
                      TImgStack& img_stack, std::vector<bool> &conv, std::vector<double> &lnZ,
                      double RV_sigma, bool saveSurfs) {
	unsigned int N_DM = 20;
	double DM_min = 5.;
	double DM_max = 20.;
	TMCMCParams params(&galactic_model, NULL, &stellar_model, &extinction_model, &stellar_data, N_DM, DM_min, DM_max);
	
	if(RV_sigma > 0.) {
		params.vary_RV = true;
		params.RV_variance = RV_sigma*RV_sigma;
	}
	
	std::string dim_name[5] = {"E(B-V)", "DM", "Mr", "FeH", "R_V"};
	
	double min[2] = {5., 0.};
	double max[2] = {20., 5.};
	unsigned int N_bins[2] = {120, 500};
	TRect rect(min, max, N_bins);
	
	img_stack.resize(params.N_stars);
	img_stack.set_rect(rect);
	TImgWriteBuffer *imgBuffer = NULL;
	if(saveSurfs) { imgBuffer = new TImgWriteBuffer(rect, params.N_stars); }
	
	unsigned int max_attempts = 3;
	unsigned int N_steps = options.steps;
	unsigned int N_samplers = options.samplers;
	unsigned int N_threads = options.N_threads;
	unsigned int ndim;
	
	if(params.vary_RV) { ndim = 5; } else { ndim = 4; }
	
	double *GR = new double[ndim];
	double GR_threshold = 1.1;
	
	TNullLogger logger;
	TAffineSampler<TMCMCParams, TNullLogger>::pdf_t f_pdf = &logP_indiv_simple_emp;
	TAffineSampler<TMCMCParams, TNullLogger>::rand_state_t f_rand_state = &gen_rand_state_indiv_emp;
	
	timespec t_start, t_write, t_end;
	
	std::cerr << std::endl;
	unsigned int N_nonconv = 0;
	
	TChainWriteBuffer chainBuffer(ndim, 100, params.N_stars);
	std::stringstream group_name;
	group_name << "/pixel " << stellar_data.healpix_index;
	
	for(size_t n=0; n<params.N_stars; n++) {
		params.idx_star = n;
		
		clock_gettime(CLOCK_MONOTONIC, &t_start);
		
		std::cout << "Star #" << n+1 << " of " << params.N_stars << std::endl;
		std::cout << "====================================" << std::endl;
		
		std::cout << "mags = ";
		for(unsigned int i=0; i<NBANDS; i++) {
			std::cout << std::setprecision(4) << params.data->star[n].m[i] << " ";
		}
		std::cout << std::endl;
		std::cout << "errs = ";
		for(unsigned int i=0; i<NBANDS; i++) {
			std::cout << std::setprecision(3) << params.data->star[n].err[i] << " ";
		}
		std::cout << std::endl;
		std::cout << "maglimit = ";
		for(unsigned int i=0; i<NBANDS; i++) {
			std::cout << std::setprecision(3) << params.data->star[n].maglimit[i] << " ";
		}
		std::cout << std::endl << std::endl;
		
		
		//std::cerr << "# Setting up sampler" << std::endl;
		TParallelAffineSampler<TMCMCParams, TNullLogger> sampler(f_pdf, f_rand_state, ndim, N_samplers*ndim, params, logger, N_threads);
		sampler.set_scale(1.5);
		sampler.set_replacement_bandwidth(0.2);
		
		//std::cerr << "# Burn-in" << std::endl;
		sampler.step(N_steps, false, 0., options.p_replacement, 0.);
		sampler.clear();
		
		//std::cerr << "# Main run" << std::endl;
		bool converged = false;
		size_t attempt;
		for(attempt = 0; (attempt < max_attempts) && (!converged); attempt++) {
			sampler.step((1<<attempt)*N_steps, true, 0., options.p_replacement, 0.);
			
			converged = true;
			sampler.get_GR_diagnostic(GR);
			for(size_t i=0; i<ndim; i++) {
				if(GR[i] > GR_threshold) {
					converged = false;
					if(attempt != max_attempts-1) {
						sampler.clear();
						//logger.clear();
					}
					break;
				}
			}
		}
		
		clock_gettime(CLOCK_MONOTONIC, &t_write);
		
		// Compute evidence
		TChain chain = sampler.get_chain();
		double lnZ_tmp = chain.get_ln_Z_harmonic(true, 10., 0.25, 0.05);
		if(isinf(lnZ_tmp)) { lnZ_tmp = -std::numeric_limits<double>::infinity(); }
		
		// Save thinned chain
		chainBuffer.add(chain, converged, lnZ_tmp);
		
		// Save binned p(DM, EBV) surface
		chain.get_image(*(img_stack.img[n]), rect, 1, 0, true, 0.1, 0.025, 500.);
		if(saveSurfs) { imgBuffer->add(*(img_stack.img[n])); }
		
		lnZ.push_back(lnZ_tmp);
		conv.push_back(converged);
		
		clock_gettime(CLOCK_MONOTONIC, &t_end);
		
		sampler.print_stats();
		std::cout << std::endl;
		
		if(!converged) {
			N_nonconv++;
			std::cerr << "# Failed to converge." << std::endl;
		}
		std::cerr << "# Number of steps: " << (1<<(attempt-1))*N_steps << std::endl;
		std::cerr << "# ln Z: " << lnZ.back() << std::endl;
		std::cerr << "# Time elapsed: " << std::setprecision(2) << (t_end.tv_sec - t_start.tv_sec) + 1.e-9*(t_end.tv_nsec - t_start.tv_nsec) << " s" << std::endl;
		std::cerr << "# Sample time: " << std::setprecision(2) << (t_write.tv_sec - t_start.tv_sec) + 1.e-9*(t_write.tv_nsec - t_start.tv_nsec) << " s" << std::endl;
		std::cerr << "# Write time: " << std::setprecision(2) << (t_end.tv_sec - t_write.tv_sec) + 1.e-9*(t_end.tv_nsec - t_write.tv_nsec) << " s" << std::endl << std::endl;
	}
	
	chainBuffer.write(out_fname, group_name.str(), "stellar chains");
	if(saveSurfs) { imgBuffer->write(out_fname, group_name.str(), "stellar pdfs"); }
	
	std::cerr << "====================================" << std::endl;
	std::cerr << std::endl;
	std::cerr << "# Failed to converge " << N_nonconv << " of " << params.N_stars << " times (" << std::setprecision(2) << 100.*(double)N_nonconv/(double)(params.N_stars) << " %)." << std::endl;
	std::cerr << std::endl;
	std::cerr << "====================================" << std::endl;
	
	if(imgBuffer != NULL) { delete imgBuffer; }
	delete[] GR;
}
void monotonic_guess(TImgStack &img_stack, unsigned int N_regions, std::vector<double>& Delta_EBV, TMCMCOptions& options) {
	std::cout << "stacking images" << std::endl;
	// Stack images
	cv::Mat stack;
	img_stack.stack(stack);
	
	std::cout << "calculating weighted mean at each distance" << std::endl;
	// Weighted mean of each distance
	double * dist_y_sum = new double[stack.rows];
	double * dist_y2_sum = new double[stack.rows];
	double * dist_sum = new double[stack.rows];
	for(int k = 0; k < stack.rows; k++) {
		dist_y_sum[k] = 0.;
		dist_y2_sum[k] = 0.;
		dist_sum[k] = 0.;
	}
	double y = 0.5;
	for(int j = 0; j < stack.cols; j++, y += 1.) {
		for(int k = 0; k < stack.rows; k++) {
			dist_y_sum[k] += y * stack.at<double>(k,j);
			dist_y2_sum[k] += y*y * stack.at<double>(k,j);
			dist_sum[k] += stack.at<double>(k,j);
		}
	}
	
	for(int k = 0; k < stack.rows; k++) {
		std::cout << k << "\t" << dist_y_sum[k]/dist_sum[k] << "\t" << sqrt(dist_y2_sum[k]/dist_sum[k]) << "\t" << dist_sum[k] << std::endl;
	}
	
	std::cout << "calculating weighted mean about each anchor" << std::endl;
	// Weighted mean in region of each anchor point
	std::vector<double> y_sum(N_regions+1, 0.);
	std::vector<double> y2_sum(N_regions+1, 0.);
	std::vector<double> w_sum(N_regions+1, 0.);
	int kStart = 0;
	int kEnd;
	double width = (double)(stack.rows) / (double)(N_regions);
	for(int n = 0; n < N_regions+1; n++) {
		std::cout << "n = " << n << std::endl;
		if(n == N_regions) {
			kEnd = stack.rows;
		} else {
			kEnd = ceil(((double)n + 0.5) * width);
		}
		for(int k = kStart; k < kEnd; k++) {
			y_sum[n] += dist_y_sum[k];
			y2_sum[n] += dist_y2_sum[k];
			w_sum[n] += dist_sum[k];
		}
		kStart = kEnd + 1;
	}
	
	delete[] dist_sum;
	delete[] dist_y_sum;
	delete[] dist_y2_sum;
	
	std::cout << "Covert to EBV and sigma_EBV" << std::endl;
	// Create non-monotonic guess
	Delta_EBV.resize(N_regions+1);
	std::vector<double> sigma_EBV(N_regions+1, 0.);
	for(int i=0; i<N_regions+1; i++) { Delta_EBV[i] = 0; }
	for(int n = 0; n < N_regions+1; n++) {
		Delta_EBV[n] = img_stack.rect->min[1] + img_stack.rect->dx[1] * y_sum[n] / w_sum[n];
		sigma_EBV[n] = img_stack.rect->dx[1] * sqrt( (y2_sum[n] - (y_sum[n] * y_sum[n] / w_sum[n])) / w_sum[n] );
		std::cout << n << "\t" << Delta_EBV[n] << "\t+-" << sigma_EBV[n] << std::endl;
	}
	
	// Fit monotonic guess
	unsigned int N_steps = 100;
	unsigned int N_samplers = 2 * N_regions;
	unsigned int N_threads = options.N_threads;
	unsigned int ndim = N_regions + 1;
	
	std::cout << "Setting up params" << std::endl;
	TEBVGuessParams params(Delta_EBV, sigma_EBV, w_sum, img_stack.rect->max[1]);
	TNullLogger logger;
	
	TAffineSampler<TEBVGuessParams, TNullLogger>::pdf_t f_pdf = &lnp_monotonic_guess;
	TAffineSampler<TEBVGuessParams, TNullLogger>::rand_state_t f_rand_state = &gen_rand_monotonic;
	
	std::cout << "Setting up sampler" << std::endl;
	TParallelAffineSampler<TEBVGuessParams, TNullLogger> sampler(f_pdf, f_rand_state, ndim, N_samplers*ndim, params, logger, N_threads);
	sampler.set_scale(1.1);
	sampler.set_replacement_bandwidth(0.75);
	
	std::cout << "Stepping" << std::endl;
	sampler.step(int(N_steps*40./100.), true, 0., 0.5, 0.);
	sampler.step(int(N_steps*10./100), true, 0., 1., 0.);
	sampler.step(int(N_steps*40./100.), true, 0., 0.5, 0.);
	sampler.step(int(N_steps*10./100), true, 0., 1., 0., true);
	
	sampler.print_stats();
	
	std::cout << "Getting best value" << std::endl;
	Delta_EBV.clear();
	sampler.get_chain().get_best(Delta_EBV);
	
	std::cout << "Monotonic guess" << std::endl;
	double EBV_sum = 0.;
	for(size_t i=0; i<Delta_EBV.size(); i++) {
		EBV_sum += Delta_EBV[i];
		std::cout << EBV_sum << std::endl;
		Delta_EBV[i] = log(Delta_EBV[i]);
	}
	std::cout << std::endl;
}