/* Fitting the surface brightness profile with an NFW-based surface brightness model Author: Junhua Gu Last modification 20120721 The temperature is assumed to be an allen model with a minimum temperature assumed */ #include #include #include "vchisq.hpp" #include "nfw_ne.hpp" #include #include #include #include #include "spline.hpp" using namespace std; using namespace opt_utilities; //double s=5.63136645E20; const double M_sun=1.988E33;//solar mass in g const double kpc=3.086E21;//kpc in cm //A class enclosing the spline interpolation method class spline_func_obj :public func_obj { //has an spline object spline spl; public: //This function is used to calculate the intepolated value double do_eval(const double& x) { /* if(x<=spl.x_list[0]) { return spl.y_list[0]; } if(x>=spl.x_list.back()) { return spl.y_list.back(); } */ return spl.get_value(x); } //we need this function, when this object is performing a clone of itself spline_func_obj* do_clone()const { return new spline_func_obj(*this); } public: //add points to the spline object, after which the spline will be initialized void add_point(double x,double y) { spl.push_point(x,y); } //before getting the intepolated value, the spline should be initialzied by calling this function void gen_spline() { spl.gen_spline(0,0); } }; //Allen temperature model int main(int argc,char* argv[]) { if(argc!=2) { cerr<"< arg_map; //open the configuration file ifstream cfg_file(argv[1]); assert(cfg_file.is_open()); for(;;) { std::string key; std::string value; cfg_file>>key>>value; if(!cfg_file.good()) { cfg_file.close(); break; } arg_map[key]=value; } //check whether following parameters are defined in the configuration file assert(arg_map.find("radius_file")!=arg_map.end()); assert(arg_map.find("sbp_file")!=arg_map.end()); assert(arg_map.find("cfunc_file")!=arg_map.end()); assert(arg_map.find("T_file")!=arg_map.end()); assert(arg_map.find("z")!=arg_map.end()); const double z=atof(arg_map["z"].c_str()); double r_min=0; if(arg_map.find("r_min")!=arg_map.end()) { r_min=atof(arg_map["r_min"].c_str()); cerr<<"r_min presents and its value is "< radii;//to store radius std::vector sbps;//to store the surface brightness value std::vector sbpe;//to store the sbp error //read in radius file /* About the format of the radius file: the radius file contains only radius, separated by space or line feed (i.e., the key). the unit should be pixel The number of radius can be larger than the number of annuli+1, the exceeded radius can be used to calculate the influence of outer shells. */ int ncut=0; for(ifstream ifs(arg_map["radius_file"].c_str());;) { assert(ifs.is_open()); double x; ifs>>x; if(!ifs.good()) { break; } if(x>x>>xe; if(!ifs.good()) { break; } if(ncut) { --ncut; continue; } cerr<>x>>y; if(!ifs.good()) { break; } cerr<,std::vector > ds; ds.add_data(data,std::vector >(radii,sbps,sbpe,sbpe,radii,radii)); //initial a fitter object fitter,vector,vector,double> f; //load the data set into the fitter object f.load_data(ds); //define a projector object //see projector for more detailed information projector a; //define the nfw surface brightness profofile model nfw_ne nfw; //attach the cooling function into the projector a.attach_cfunc(cf); assert(arg_map.find("cm_per_pixel")!=arg_map.end()); //set the cm to pixel ratio double cm_per_pixel=atof(arg_map["cm_per_pixel"].c_str()); a.set_cm_per_pixel(cm_per_pixel); nfw.set_cm_per_pixel(cm_per_pixel); //define the temperature profile model spline_func_obj tf; for(ifstream ifs_tfunc(arg_map["T_file"].c_str());;) { assert(ifs_tfunc.is_open()); double x,y; ifs_tfunc>>x>>y; if(!ifs_tfunc.good()) { break; } if(x c; c.verbose(true); f.set_statistic(c); //set the optimization method, here we use powell method f.set_opt_method(powell_method >()); //set the initial values double n0=atof(arg_map["n0"].c_str()); double rho0=atof(arg_map["rho0"].c_str()); double rs=atof(arg_map["rs"].c_str()); double bkg=atof(arg_map["bkg"].c_str()); f.set_param_value("n0",n0); f.set_param_value("rho0",rho0); f.set_param_value("rs",rs); f.set_param_value("bkg",bkg); cout< p=f.get_all_params(); f.clear_param_modifier(); std::vector mv=f.eval_model(radii,p); cerr< radius_list; std::vector delta_list; cerr<<"delta\tr_delta (kpc)\tr_delta (pixel)\tmass_delta (solar mass)\n"; for(double r=kpc;r<6000*kpc;r+=kpc) { double delta=nfw_average_density(r,abs(rho0),abs(rs))/calc_critical_density(z); radius_list.push_back(r); delta_list.push_back(delta); /* if(delta<=200&&!hit_200) { hit_200=true; cerr<<200<<"\t"<=200&&delta_list[i+1]<200) { cerr<<200<<"\t"<=500&&delta_list[i+1]<500) { cerr<<500<<"\t"<=1500&&delta_list[i+1]<1500) { cerr<<1500<<"\t"<=2500&&delta_list[i+1]<2500) { cerr<<2500<<"\t"<