diff options
author | Aaron LI <aaronly.me@gmail.com> | 2016-05-27 22:47:24 +0800 |
---|---|---|
committer | Aaron LI <aaronly.me@gmail.com> | 2016-05-27 22:47:24 +0800 |
commit | ffd178e0bd72562a3c2cff9747b6e656edc881dc (patch) | |
tree | 8800b7b5b2e8bc3df1a6760df5cd54eaaa686702 /mass_profile | |
parent | 5c35fad9240fb42c1371c721e0b2af7379bd9ea0 (diff) | |
download | chandra-acis-analysis-ffd178e0bd72562a3c2cff9747b6e656edc881dc.tar.bz2 |
Add mass_profile tools
* These tools are mainly use to calculate the total gravitational mass
profile, as well as the intermediate products (e.g., surface
brightness profile fitting, gas density profile, NFW fitting, etc.)
* There are additional tools for calculating the luminosity and flux.
* These tools mainly developed by Junhua GU, and contributed by
Weitian (Aaron) LI, and Zhenghao ZHU.
Diffstat (limited to 'mass_profile')
79 files changed, 11440 insertions, 0 deletions
diff --git a/mass_profile/.gitignore b/mass_profile/.gitignore new file mode 100644 index 0000000..4905ae4 --- /dev/null +++ b/mass_profile/.gitignore @@ -0,0 +1,24 @@ +# ignore built executables +calc_distance +calc_lx +calc_lx_beta +calc_lx_dbeta +cooling_time +cosmo_calc +fit_beta_sbp +fit_dbeta_sbp +fit_direct_beta +fit_lt_bpl +fit_lt_pl +fit_mt_bpl +fit_mt_pl +fit_nfw_mass +fit_nfw_sbp +fit_wang2012_model + +# building dependent libraries +libcpgplot.a +libpgplot.a + +# ignore the backup files +ly_mod/ diff --git a/mass_profile/Makefile b/mass_profile/Makefile new file mode 100644 index 0000000..21972a3 --- /dev/null +++ b/mass_profile/Makefile @@ -0,0 +1,57 @@ +targets=fit_nfw_sbp fit_dbeta_sbp fit_beta_sbp fit_direct_beta calc_distance fit_wang2012_model fit_nfw_mass calc_lx fit_mt_pl fit_lt_pl fit_mt_bpl fit_lt_bpl cooling_time calc_lx_dbeta calc_lx_beta +target:$(targets) py + +LIB_PGPLOT_PATH="`ls`" +LIB_PGPLOT=plot_reporter.cpp -lcpgplot -lpgplot -lX11 -lgfortran + +py: + chmod a+x *.py + +fit_nfw_sbp:fit_nfw_sbp.cpp nfw_ne.hpp projector.hpp spline.h vchisq.hpp plot_reporter.hpp plot_reporter.cpp + g++ $< -o $@ -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + +fit_dbeta_sbp:fit_dbeta_sbp.cpp beta_cfg.cpp beta_cfg.hpp constrained_dbeta.hpp projector.hpp spline.h vchisq.hpp plot_reporter.hpp plot_reporter.cpp report_error.hpp report_error.cpp + g++ -o $@ $< report_error.cpp beta_cfg.cpp -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + +fit_beta_sbp:fit_beta_sbp.cpp beta_cfg.cpp beta_cfg.hpp beta.hpp projector.hpp spline.h vchisq.hpp plot_reporter.hpp plot_reporter.cpp dump_fit_qdp.cpp dump_fit_qdp.hpp + g++ -o $@ $< dump_fit_qdp.cpp beta_cfg.cpp report_error.cpp -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + +fit_wang2012_model:fit_wang2012_model.cpp wang2012_model.hpp chisq.hpp plot_reporter.hpp plot_reporter.cpp + g++ $< -o $@ -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + +fit_nfw_mass:fit_nfw_mass.cpp nfw.hpp chisq.hpp plot_reporter.hpp plot_reporter.cpp + g++ $< -o $@ -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + + +fit_direct_beta:fit_direct_beta.cpp plot_reporter.hpp plot_reporter.cpp + g++ $< -o $@ -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + +calc_lx:calc_lx.cpp plot_reporter.hpp plot_reporter.cpp calc_distance.h calc_distance.cc + g++ -o $@ $< calc_distance.cc -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + +calc_lx_dbeta:calc_lx_dbeta.cpp beta_cfg.cpp beta_cfg.hpp constrained_dbeta.hpp projector.hpp spline.h vchisq.hpp plot_reporter.hpp plot_reporter.cpp report_error.hpp report_error.cpp + g++ -o $@ $< report_error.cpp beta_cfg.cpp -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + +calc_lx_beta:calc_lx_beta.cpp beta_cfg.cpp beta_cfg.hpp beta.hpp projector.hpp spline.h vchisq.hpp plot_reporter.hpp plot_reporter.cpp dump_fit_qdp.cpp dump_fit_qdp.hpp + g++ -o $@ $< dump_fit_qdp.cpp beta_cfg.cpp report_error.cpp -I ../opt_utilities -O3 `if [ -e pgplot_path.txt ]; then grep LIB pgplot_path.txt|awk '{print "-L" $$2}'; fi` `if [ -e pgplot_path.txt ]; then grep INC pgplot_path.txt|awk '{print "-I" $$2}'; fi` $(LIB_PGPLOT) + +calc_distance:call_calc_distance.cc calc_distance.cc calc_distance.h adapt_trapezoid.h + g++ call_calc_distance.cc calc_distance.cc -o $@ -O3 + +fit_mt_pl:fit_mt_pl.cpp + g++ $< -o $@ -O3 -I ../opt_utilities + +fit_lt_pl:fit_lt_pl.cpp + g++ $< -o $@ -O3 -I ../opt_utilities + +fit_mt_bpl:fit_mt_bpl.cpp + g++ $< -o $@ -O3 -I ../opt_utilities + +fit_lt_bpl:fit_lt_bpl.cpp + g++ $< -o $@ -O3 -I ../opt_utilities + +cooling_time:cooling_time.cpp + g++ $< -o $@ -O3 + +clean: + rm -f $(targets) diff --git a/mass_profile/adapt_trapezoid.h b/mass_profile/adapt_trapezoid.h new file mode 100644 index 0000000..35d22b4 --- /dev/null +++ b/mass_profile/adapt_trapezoid.h @@ -0,0 +1,124 @@ +#ifndef ADAPT_TRAPEZOID_H +#define ADAPT_TRAPEZOID_H +#include <list> +#include <utility> +#include <cassert> +//#include <iostream> + +//using namespace std; + +template<typename T1,typename T2,typename T3> +class triple +{ + public: + T1 first; + T2 second; + T3 third; + triple(T1 x1,T2 x2,T3 x3) + :first(x1),second(x2),third(x3) + { + } +}; + + +template<typename T1,typename T2,typename T3> +triple<T1,T2,T3> make_triple(T1 x1,T2 x2,T3 x3) +{ + return triple<T1,T2,T3>(x1,x2,x3); +} + +template <typename T> +T trapezoid(T (*fun)(T),T x1,T x2,T err_limit) +{ + int n=256; + T result; + const int max_division=24; + T old_value=0; + for(int i=1;i<max_division;i++) + { + result=0.; + n*=2; + T step=(x2-x1)/n; + for(int j=0;j<n;j++) + { + result+=(fun(x1+(j+1)*step)+fun(x1+j*step))*step/T(2.); + } + old_value-=result; + old_value=old_value<0?-old_value:old_value; + if(old_value<err_limit) + { + return result; + } + old_value=result; + } +} + + +template <typename T> +T adapt_trapezoid(T (*fun)(T),T x1,T x2,T err_limit) +{ + // const err_limit=.001; + typedef triple<T,T,bool> interval; + /*T for interval type, + bool for state trur for still to be updated, + false for do not need to be updated + */ + std::list<interval> interval_list; + T current_sum=((fun(x1)+fun(x2))/2.*(x2-x1)); + interval_list.push_back(make_triple(x1,current_sum,true)); + interval_list.push_back(make_triple(x2,(T)0.,true)); + bool int_state=1; + int n_intervals=1; + while(int_state) + { + //std::cout<<n_intervals<<std::endl; + int_state=0; + typename std::list<interval>::iterator i1=interval_list.begin(); + typename std::list<interval>::iterator i2=interval_list.begin(); + i2++; + for(;i2!=interval_list.end();i1++,i2=i1,i2++) + { + //cout<<i1->first<<"\t"<<i2->first<<endl; + //assert(i2->first>i1->first); + if(i1->third) + { + interval new_interval((i1->first+i2->first)/2,0,true); + + T sum1,sum2; + sum1=(fun(new_interval.first)+fun(i1->first))/2*(new_interval.first-i1->first); + sum2=(fun(new_interval.first)+fun(i2->first))/2*(i2->first-new_interval.first); + new_interval.second=sum2; + T err; + err=i1->second-sum1-sum2; + err=err<0?-err:err; + + if(err>err_limit/n_intervals) + { + i1->second=sum1; + interval_list.insert(i2,new_interval); + n_intervals++; + if(n_intervals>10e6) + { + + break; + } + } + else + { + i1->third=false; + } + int_state=1; + } + } + + } + T result=0; + for(typename std::list<interval>::iterator i=interval_list.begin();i!=interval_list.end();i++) + { + result+=i->second; + } + return result; +} + +#endif +//end of the file diff --git a/mass_profile/analyze_entropy_profile.py b/mass_profile/analyze_entropy_profile.py new file mode 100755 index 0000000..c123681 --- /dev/null +++ b/mass_profile/analyze_entropy_profile.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python + +import sys +import numpy +import scipy.interpolate + +center_entropy_file=open('entropy_center.qdp') +entropy_file=open('summary_entropy.qdp') +confidence_level=.68 +rout=float(sys.argv[1]) + +center_s=0 +for i in center_entropy_file: + r,s=i.split() + r=float(r) + s=float(s) + if r>rout: + center_s=s + break + +new_data=True + + +s_list=[] +for i in entropy_file: + if i[0]=='n': + new_data=True + continue + if new_data==False: + continue + r,s=i.split() + r=float(r) + s=float(s) + if r>rout: + new_data=False + s_list.append(s) + +s_idx=-1 + +s_list.sort() +for i in range(len(s_list)-1): + if (center_s-s_list[i])*(center_s-s_list[i+1])<=0: + m_idx=i + break + + +slidx=int(s_idx*(1-confidence_level)) +suidx=s_idx-1+int((len(s_list)-s_idx)*confidence_level) + + +serr1=s_list[slidx]-center_s +serr2=s_list[suidx]-center_s + +print("S=\t%e\t %e/+%e keV cm^2 (1 sigma)"%(center_s,serr1,serr2)) diff --git a/mass_profile/analyze_fx.py b/mass_profile/analyze_fx.py new file mode 100755 index 0000000..4f72f57 --- /dev/null +++ b/mass_profile/analyze_fx.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +import sys +import math +import numpy + +fx1_array=[] +fx2_array=[] +fx3_array=[] +for i in open('summary_fx.dat'): + x1,x2,x3=i.split() + x1=float(x1) + x2=float(x2) + x3=float(x3) + fx1_array.append(x1) + fx2_array.append(x2) + fx3_array.append(x3) + + +fx1_array=numpy.array(fx1_array) +fx2_array=numpy.array(fx2_array) +fx3_array=numpy.array(fx3_array) + + +f=open('fx_result.txt','w') +f.write("Fx(bolot)= %4.2E +/- %4.2E erg/s/cm^2\n"%(fx1_array[0],fx1_array.std())) +print("Fx(bolot)= %4.2E +/- %4.2E erg/s/cm^2"%(fx1_array[0],fx1_array.std())) +f.write("Fx(0.7-7)= %4.2E +/- %4.2E erg/s/cm^2\n"%(fx2_array[0],fx2_array.std())) +print("Fx(0.7-7)= %4.2E +/- %4.2E erg/s/cm^2"%(fx2_array[0],fx2_array.std())) +f.write("Fx(0.1-2.4)= %4.2E +/- %4.2E erg/s/cm^2\n"%(fx3_array[0],fx3_array.std())) +print("Fx(0.1-2.4)= %4.2E +/- %4.2E erg/s/cm^2"%(fx3_array[0],fx3_array.std())) + diff --git a/mass_profile/analyze_lx.py b/mass_profile/analyze_lx.py new file mode 100755 index 0000000..c3d4030 --- /dev/null +++ b/mass_profile/analyze_lx.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +import sys +import math +import numpy + +lx1_array=[] +lx2_array=[] +lx3_array=[] +for i in open('summary_lx.dat'): + x1,x2,x3=i.split() + x1=float(x1) + x2=float(x2) + x3=float(x3) + lx1_array.append(x1) + lx2_array.append(x2) + lx3_array.append(x3) + + +lx1_array=numpy.array(lx1_array) +lx2_array=numpy.array(lx2_array) +lx3_array=numpy.array(lx3_array) + + +f=open('lx_result.txt','w') +f.write("Lx(bolo)= %4.2E +/- %4.2E erg/s\n"%(lx1_array[0],lx1_array.std())) +print("Lx(bolo)= %4.2E +/- %4.2E erg/s"%(lx1_array[0],lx1_array.std())) +f.write("Lx(0.7-7)= %4.2E +/- %4.2E erg/s\n"%(lx2_array[0],lx2_array.std())) +print("Lx(0.7-7)= %4.2E +/- %4.2E erg/s"%(lx2_array[0],lx2_array.std())) +f.write("Lx(0.1-2.4)= %4.2E +/- %4.2E erg/s\n"%(lx3_array[0],lx3_array.std())) +print("Lx(0.1-2.4)= %4.2E +/- %4.2E erg/s"%(lx3_array[0],lx3_array.std())) + diff --git a/mass_profile/analyze_mass_profile.py b/mass_profile/analyze_mass_profile.py new file mode 100755 index 0000000..3ee128c --- /dev/null +++ b/mass_profile/analyze_mass_profile.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python + +import sys +import numpy +import scipy.interpolate + +confidence_level=.68 +def read_file(param): + delta=float(param[0]) + + file_mass_center=open("mass_int_center.qdp").readlines(); + file_delta_center=open("overdensity_center.qdp").readlines(); + + center_r=0 + center_m=0 + center_gm=0 + center_gf=0 + + + for i in range(0,len(file_mass_center)): + lm=file_mass_center[i].strip(); + ld=file_delta_center[i].strip(); + r,m=lm.split() + r,d=ld.split() + r=float(r) + d=float(d) + m=float(m) + if m<1e11: + continue + if d<delta: + center_r=r + center_m=m + for j in open("gas_mass_int_center.qdp"): + rgm,gm=j.strip().split() + rgm=float(rgm) + gm=float(gm) + if rgm>r: + + center_gm=gm + center_gf=gm/m + break + break + if len(param)>1 and param[1]=='c': + #print("%s(<r%d)=%E solar mass"%("mass",delta,center_m)) + #print("%s%d=%E kpc"%("r",delta,center_r)) + #print("%s(<r%d)=%E solar mass"%("gas mass",delta,center_gm)) + #print("%s(<r%d)=%E"%("gas fraction",delta,center_gf)) + return center_m,center_r,center_gm,center_gf,None,None,None,None + + +#print(center_gm,center_gf) + file_mass=open('summary_mass_profile.qdp').readlines() + file_delta=open('summary_overdensity.qdp').readlines() + file_gm=open('summary_gas_mass_profile.qdp') + + + flag=True + rlist=[] + mlist=[] + gmlist=[] + gflist=[] + old_m=0 + invalid_count=0 + for i in range(0,len(file_mass)): + lm=file_mass[i].strip() + ld=file_delta[i].strip() + if lm[0]=='n': + flag=True + old_m=0 + continue + if not flag: + continue + r,m=lm.split() + m=float(m) + if m<1e12: + continue + if m<old_m: + invalid_count+=1 + flag=False + continue + r,d=ld.split() + d=float(d) + r=float(r) + + if d<delta: + #print("%s %e"%(d,m)) + mlist.append(m) + rlist.append(r) + flag1=True + while True: + lgm=file_gm.readline().strip() + if lgm[0]=='n': + break + rgm,gm=lgm.split() + rgm=float(rgm) + gm=float(gm) + if rgm>r and flag1: + gmlist.append(gm) + + flag1=False + gflist.append(gm/mlist[-1]) + #print(gm,gflist[-1]) + flag=False + old_m=m + print("%d abnormal data dropped"%(invalid_count)) + + + return center_m,center_r,center_gm,center_gf,mlist,rlist,gmlist,gflist +#center_m=numpy.mean(mlist) +#center_r=numpy.mean(rlist) + +center_m,center_r,center_gm,center_gf,mlist,rlist,gmlist,gflist=read_file(sys.argv[1:]) +delta=float(sys.argv[1]) + +if len(sys.argv)>2 and sys.argv[2]=='c': + print("%s(<r%d)=%E solar mass"%("mass",delta,center_m)) + print("%s%d=%E kpc"%("r",delta,center_r)) + print("%s(<r%d)=%E solar mass"%("gas mass",delta,center_gm)) + print("%s(<r%d)=%E"%("gas fraction",delta,center_gf)) + sys.exit(0) + + +mlist.sort() +rlist.sort() +gflist.sort() +gmlist.sort() + +m_idx=-1 +r_idx=-1 +gm_idx=-1 +gf_idx=-1 +delta=float(sys.argv[1]) +for i in range(len(mlist)-1): + if (center_m-mlist[i])*(center_m-mlist[i+1])<=0: + m_idx=i + break + +for i in range(len(rlist)-1): + if (center_r-rlist[i])*(center_r-rlist[i+1])<=0: + r_idx=i + break + +for i in range(len(gmlist)-1): + if (center_gm-gmlist[i])*(center_gm-gmlist[i+1])<=0: + gm_idx=i + break + +for i in range(len(gflist)-1): + if (center_gf-gflist[i])*(center_gf-gflist[i+1])<=0: + gf_idx=i + break + + +if m_idx==-1 or r_idx==-1 or gf_idx==-1 or gm_idx==-1: + print("Error, the center value is not enclosed by the Monte-Carlo realizations, please check the result!") + print("m:%E %E %E"%(center_m,mlist[0],mlist[-1])) + print("gm:%E %E %E"%(center_gm,gmlist[0],gmlist[-1])) + print("gf:%E %E %E"%(center_gf,gflist[0],gflist[-1])) + print("r:%E %E %E"%(center_r,rlist[0],rlist[-1])) + sys.exit(1) + + +mlidx=int(m_idx*(1-confidence_level)) +muidx=m_idx-1+int((len(mlist)-m_idx)*confidence_level) + + +rlidx=int(r_idx*(1-confidence_level)) +ruidx=r_idx-1+int((len(rlist)-r_idx)*confidence_level) + +gmlidx=int(gm_idx*(1-confidence_level)) +gmuidx=gm_idx-1+int((len(gmlist)-gm_idx)*confidence_level) + +gflidx=int(gf_idx*(1-confidence_level)) +gfuidx=gf_idx-1+int((len(gflist)-gf_idx)*confidence_level) + + +merr1=mlist[mlidx]-center_m +merr2=mlist[muidx]-center_m + +rerr1=rlist[rlidx]-center_r +rerr2=rlist[ruidx]-center_r + +gmerr1=gmlist[gmlidx]-center_gm +gmerr2=gmlist[gmuidx]-center_gm + +gferr1=gflist[gflidx]-center_gf +gferr2=gflist[gfuidx]-center_gf + +#print("%d %d %d"%(mlidx,m_idx,muidx)) +#print("%d %d %d"%(rlidx,r_idx,ruidx)) + +print("m%d=\t%e\t %e/+%e solar mass (1 sigma)"%(delta,center_m,merr1,merr2)) +print("gas_m%d=\t%e\t %e/+%e solar mass (1 sigma)"%(delta,center_gm,gmerr1,gmerr2)) +print("gas_fraction%d=\t%e\t %e/+%e (1 sigma)"%(delta,center_gf,gferr1,gferr2)) +print("r%d=\t%d\t %d/+%d kpc (1 sigma)"%(delta,center_r,rerr1,rerr2)) diff --git a/mass_profile/beta.hpp b/mass_profile/beta.hpp new file mode 100644 index 0000000..4e6264c --- /dev/null +++ b/mass_profile/beta.hpp @@ -0,0 +1,45 @@ +#ifndef BETA +#define BETA +#include "projector.hpp" + +namespace opt_utilities +{ + template <typename T> + class beta + :public model<std::vector<T>,std::vector<T>,std::vector<T> > + { + public: + beta() + { + this->push_param_info(param_info<std::vector<T>,std::string>("n0",1,0,1E99)); + this->push_param_info(param_info<std::vector<T>,std::string>("beta",.66,0,1E99)); + this->push_param_info(param_info<std::vector<T>,std::string>("rc",100,0,1E99)); + } + + public: + beta<T>* do_clone()const + { + return new beta<T>(*this); + } + + std::vector<T> do_eval(const std::vector<T> & x, + const std::vector<T>& p) + { + T n0=std::abs(p[0]); + T beta=p[1]; + T rc=p[2]; + + std::vector<T> result(x.size()-1); + for(int i=1;i<x.size();++i) + { + T xi=(x[i]+x[i-1])/2; + T yi=0; + yi=n0*pow(1+xi*xi/rc/rc,-3./2.*beta); + result[i-1]=yi; + } + return result; + } + }; +} + +#endif diff --git a/mass_profile/beta_cfg.cpp b/mass_profile/beta_cfg.cpp new file mode 100644 index 0000000..408970f --- /dev/null +++ b/mass_profile/beta_cfg.cpp @@ -0,0 +1,91 @@ +#include "beta_cfg.hpp" +#include <sstream> +#include <cstdlib> +using namespace std; + +cfg_map parse_cfg_file(std::istream& is) +{ + cfg_map result; + result.rmin_pixel=-1; + result.rmin_kpc=-1; + for(;;) + { + std::string line; + getline(is,line); + line+="\n"; + if(!is.good()) + { + break; + } + string key; + istringstream iss(line); + iss>>key; + if(key=="radius_file") + { + string value; + iss>>value; + result.radius_file=value; + } + else if(key=="sbp_file") + { + string value; + iss>>value; + result.sbp_file=value; + } + else if(key=="cfunc_file") + { + string value; + iss>>value; + result.cfunc_file=value; + } + else if(key=="T_file") + { + string value; + iss>>value; + result.T_file=value; + } + else if(key=="z") + { + double z; + iss>>z; + result.z=z; + } + else if(key=="cm_per_pixel") + { + double cm_per_pixel; + iss>>cm_per_pixel; + result.cm_per_pixel=cm_per_pixel; + } + else if(key=="rmin_pixel") + { + double v; + iss>>v; + result.rmin_pixel=v; + } + else if(key=="rmin_kpc") + { + double v; + iss>>v; + result.rmin_kpc=v; + } + else + { + std::vector<double> value; + for(;;) + { + double v; + iss>>v; + if(!iss.good()) + { + break; + } + value.push_back(v); + } + if(!value.empty()) + { + result.param_map[key]=value; + } + } + } + return result; +} diff --git a/mass_profile/beta_cfg.hpp b/mass_profile/beta_cfg.hpp new file mode 100644 index 0000000..5dc9b2d --- /dev/null +++ b/mass_profile/beta_cfg.hpp @@ -0,0 +1,24 @@ +#ifndef BETA_CFG +#define BETA_CFG + +#include <map> +#include <vector> +#include <string> +#include <iostream> + +struct cfg_map +{ + std::string radius_file; + std::string sbp_file; + std::string cfunc_file; + std::string T_file; + double z; + double cm_per_pixel; + double rmin_kpc; + double rmin_pixel; + std::map<std::string,std::vector<double> > param_map; +}; + +cfg_map parse_cfg_file(std::istream& is); + +#endif diff --git a/mass_profile/calc_all_cooling_time.sh b/mass_profile/calc_all_cooling_time.sh new file mode 100755 index 0000000..2b0ac77 --- /dev/null +++ b/mass_profile/calc_all_cooling_time.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +if [ $# -eq 1 ] +then + : +else + echo "Usage: <global.cfg list file>" + exit +fi + +bdir=`pwd` +base_path=`dirname $0` +for i in `cat $1` +do + dname=`dirname $i` + #dname=`dirname $dname` + echo $dname + cd $dname ||continue + sbp_cfg=`grep sbp_cfg global.cfg|awk '{print $2}'` + if grep n01 $sbp_cfg >/dev/null + then + echo "dbeta" + $base_path/fit_dbeta_nfw_mass_profile.sh global.cfg c + else + echo "beta" + $base_path/fit_beta_nfw_mass_profile.sh global.cfg c + fi + + cd $bdir +done diff --git a/mass_profile/calc_all_entropy.sh b/mass_profile/calc_all_entropy.sh new file mode 100755 index 0000000..5506ab8 --- /dev/null +++ b/mass_profile/calc_all_entropy.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +if [ $# -eq 1 ] +then + : +else + echo "Usage: <global.cfg list file>" + exit +fi + +bdir=`pwd` + +for i in `cat $1` +do + dname=`dirname $i` + #dname=`dirname $dname` + echo $dname + cd $dname ||continue +# mkdir -p profile_entropy +# cp -rf profile/* profile_entropy/ +# cd profile/ + + [ -e result ] && r200file=result + [ -e result ] || r200file=result_checked + + r200=`grep r200 $r200file|awk -F = '{print $2}' |awk -F '-' '{print $1}'` + rout=`python -c "print($r200*.1)"` + echo $rout + if grep n01 source.cfg >/dev/null + then + echo "dbeta" + fit_dbeta_entropy.sh global.cfg $rout + else + echo "beta" + fit_beta_entropy.sh global.cfg $rout + fi + + cd $bdir +done diff --git a/mass_profile/calc_distance.cc b/mass_profile/calc_distance.cc new file mode 100644 index 0000000..1a637d3 --- /dev/null +++ b/mass_profile/calc_distance.cc @@ -0,0 +1,61 @@ +#include <iostream> +#include <cmath> +#include <cstdlib> +#include <cstddef> +#include <cassert> +#include "adapt_trapezoid.h" + +//calc_distance +//usage: +//calc_distance z + +using namespace std; + +static double cm=1; +static double s=1; +static double km=1000*100; +static double Mpc=3.08568e+24*cm; +static double kpc=3.08568e+21*cm; +static double yr=365.*24.*3600.; +static double Gyr=1e9*yr; +static double H=71.*km/s/Mpc; +static const double c=299792458.*100.*cm; +//const double c=3e8*100*cm; +static const double omega_m=0.27; +static const double omega_l=0.73; +static const double arcsec2arc_ratio=1./60/60/180*3.1415926; + + +double E(double z) +{ + double omega_k=1-omega_m-omega_l; + return sqrt(omega_m*(1+z)*(1+z)*(1+z)+omega_k*(1+z)*(1+z)+omega_l); +} + +double f_dist(double z) +{ + return 1/E(z); +} + +double f_age(double z) +{ + return f_dist(1/z)/(z*z); +} + + + +double calc_angular_distance(double z) +{ + //return c/H*integer(f_dist,0,z)/(1+z); + //return c/H*adapt_trapezoid(f_dist,0.,z,1e-4)/(1+z); + return adapt_trapezoid(f_dist,0.,z,1e-4)/(1+z); +} + +double calc_luminosity_distance(double z) +{ + //return c/H*integer(f_dist,0,z)/(1+z); + return c/H*adapt_trapezoid(f_dist,0.,z,1e-4)*(1+z); +} + + +//EOF diff --git a/mass_profile/calc_distance.h b/mass_profile/calc_distance.h new file mode 100644 index 0000000..ba01316 --- /dev/null +++ b/mass_profile/calc_distance.h @@ -0,0 +1,8 @@ +#ifndef CALC_DISTANCE_H +#define CALC_DISTANCE_H +extern double calc_angular_distance(double z); +extern double calc_luminosity_distance(double z); +extern double E(double z); +#endif + +//EOF diff --git a/mass_profile/calc_lx.cpp b/mass_profile/calc_lx.cpp new file mode 100644 index 0000000..e5cff62 --- /dev/null +++ b/mass_profile/calc_lx.cpp @@ -0,0 +1,218 @@ +#include "calc_distance.h" +#include "spline.h" +#include <iostream> +#include <string> +#include <vector> +#include <statistics/chisq.hpp> +#include <methods/powell/powell_method.hpp> +#include <data_sets/default_data_set.hpp> +#include <misc/data_loaders.hpp> +#include "methods/aga/aga.hpp" +#include <models/beta1d.hpp> +#include <cstdlib> +using namespace std; +using namespace opt_utilities; + + +static const double cm=1; +static const double s=1; +static const double km=1000*100; +static const double Mpc=3.08568e+24*cm; +static const double kpc=3.08568e+21*cm; +static const double yr=365.*24.*3600.; +static const double Gyr=1e9*yr; +static const double H=71.*km/s/Mpc; +static const double c=299792458.*100.*cm; +//const double c=3e8*100*cm; +static const double pi=4*atan(1); +static const double omega_m=0.27; +static const double omega_l=0.73; +static const double arcsec2arc_ratio=1./60/60/180*pi; + +double std_norm_rand() +{ + double u=0; + double v=0; + while(u<=0||v<=0) + { + u=rand()/(double)RAND_MAX; + rand(); + v=rand()/(double)RAND_MAX; + } + double x=std::sqrt(-log(u))*cos(2*pi*v); + return x; +} + + +int main(int argc,char* argv[]) +{ + srand(time(0)); + if(argc<5) + { + cerr<<"Usage:"<<argv[0]<<" <sbp data> <ratio file> <z> <r500 in kpc> [Tprofile.dat]"<<endl; + return -1; + } + double z=atof(argv[3]); + assert(z>0); + double d_a_cm=c/H*calc_angular_distance(z); + double d_l_cm=(1+z)*(1+z)*d_a_cm; + double cm_per_pixel=d_a_cm*.492*arcsec2arc_ratio; + ////////////////////////////// + //perform a 1-beta fitting//// + ////////////////////////////// + fitter<double,double,vector<double>,double,string> f; + + f.set_statistic(chisq<double,double,vector<double>,double,string>()); + f.set_opt_method(powell_method<double,vector<double> >()); + f.set_model(beta1d<double>()); + dl_x_xe_y_ye<double,double> dl; + ifstream ifs(argv[1]); + ifs>>dl; + f.load_data(dl.get_data_set()); + f.fit(); + double rmin=f.get_data_set().get_data(0).get_x(); + double rmax=f.get_data_set().get_data(f.get_data_set().size()-1).get_x(); + ofstream lx_fit_result("lx_fit_result.qdp"); + lx_fit_result<<"read terr 1 2\nskip single\n"; + for(int i=0;i<f.get_data_set().size();++i) + { + lx_fit_result<<f.get_data_set().get_data(i).get_x()<<"\t"<< + -abs(f.get_data_set().get_data(i).get_x_lower_err())<<"\t"<< + abs(f.get_data_set().get_data(i).get_x_upper_err())<<"\t"<< + f.get_data_set().get_data(i).get_y()<<"\t"<< + -abs(f.get_data_set().get_data(i).get_y_lower_err())<<"\t"<< + abs(f.get_data_set().get_data(i).get_y_upper_err())<<endl; + } + lx_fit_result<<"no no no\n"; + + for(double i=rmin;i<rmax;i+=1) + { + lx_fit_result<<i<<"\t0\t0\t"<<f.eval_model(i,f.get_all_params())<<"\t0\t0"<<endl; + } + + for(int i=0;i<f.get_num_params();++i) + { + cerr<<f.get_param_info(i).get_name()<<"="<< + f.get_param_info(i).get_value()<<endl; + } + + vector<double> p=f.get_all_params(); + + double r500kpc=atof(argv[4]); + assert(r500kpc>0); + double r500pixel=r500kpc*kpc/cm_per_pixel; + + const double dr=1; + double sum_cnt=0; + double sum_flux=0; + spline<double> spl; + ifstream ifs_ratio(argv[2]); + assert(ifs_ratio.is_open()); + for(;;) + { + double x,y; + ifs_ratio>>x>>y; + if(!ifs_ratio.good()) + { + break; + } + spl.push_point(x,y); + } + spl.gen_spline(0,0); + + for(double r=0;r<r500pixel;r+=dr) + { + double r1=r<.2*r500pixel?.2*r500pixel:r; + double sbp=f.eval_model_raw(r1,p); + double cnt=sbp*pi*(2*r+dr)*dr; + double ratio=spl.get_value(r); + //cerr<<sbp<<endl; + sum_cnt+=cnt; + sum_flux+=cnt*ratio; + } + double lx=sum_flux*4*pi*d_l_cm*d_l_cm; + + double l_mean=0; + double l2_mean=0; + double cnt=0; + for(int n=0;n<100;++n) + { + cerr<<"."; + opt_utilities::default_data_set<double,double> ds(dl.get_data_set()); + opt_utilities::default_data_set<double,double> ds1; + for(int i=0;i<ds.size();++i) + { + double yc=ds.get_data(i).get_y(); + double ye=(std::abs(ds.get_data(i).get_y_lower_err())+std::abs(ds.get_data(i).get_y_lower_err()))/2; + double xc=ds.get_data(i).get_x(); + double xe=(std::abs(ds.get_data(i).get_x_lower_err())+std::abs(ds.get_data(i).get_x_lower_err()))/2; + double newy=std_norm_rand()*ye+yc; + //cout<<yc<<"\t"<<newy<<endl; + ds1.add_data(data<double,double>(xc,newy,ye,ye,xe,xe)); + } + f.load_data(ds1); + chisq<double,double,vector<double>,double,string> c; + //c.verbose(true); + f.set_statistic(c); + f.fit(); + vector<double> p=f.get_all_params(); + //cout<<f.get_param_value("beta")<<endl; + double sum_cnt=0; + double sum_flux=0; + + for(double r=0;r<r500pixel;r+=dr) + { + double r1=r<.2*r500pixel?.2*r500pixel:r; + double sbp=f.eval_model_raw(r1,p); + double cnt=sbp*pi*(2*r+dr)*dr; + double ratio=spl.get_value(r); + sum_cnt+=cnt; + sum_flux+=cnt*ratio; + } + //cout<<sum_cnt<<endl; + double lx=sum_flux*4*pi*d_l_cm*d_l_cm; + l_mean+=lx; + l2_mean+=lx*lx; + cnt+=1; + //std::cerr<<lx<<endl; + //std::cerr<<f.get_param_value( + } + l_mean/=cnt; + l2_mean/=cnt; + cerr<<endl; + double std_l=std::sqrt(l2_mean-l_mean*l_mean); + + double std_l2=0; + if(argc==6) + { + ifstream ifs_tfile(argv[5]); + assert(ifs_tfile.is_open()); + double mean_T=0; + int cnt=0; + double mean_Te=0; + for(;;) + { + double r,re,t,te; + ifs_tfile>>r>>re>>t>>te; + if(!ifs_tfile.good()) + { + break; + } + cnt+=1; + mean_T+=t; + mean_Te+=te*te; + } + mean_T/=cnt; + mean_Te/=cnt; + mean_Te=std::sqrt(mean_Te); + if(mean_Te>mean_T) + { + mean_Te=mean_T; + } + std_l2=mean_Te/mean_T*lx; + //cout<<mean_Te<<"\t"<<mean_T<<endl; + } + std_l=std::sqrt(std_l*std_l+std_l2*std_l2); + std::cout<<"Lx(bol): "<<lx<<" +/- "<<std_l<<" erg/s #Lx(bol) within r500"<<std::endl; + //std::cout<<sum_cnt<<std::endl; +} diff --git a/mass_profile/calc_lx_beta.cpp b/mass_profile/calc_lx_beta.cpp new file mode 100644 index 0000000..5bb2570 --- /dev/null +++ b/mass_profile/calc_lx_beta.cpp @@ -0,0 +1,506 @@ +/* + Perform a double-beta density model fitting to the surface brightness data + Author: Junhua Gu + Last modified: 2011.01.01 + This code is distributed with no warrant +*/ + +#include <unistd.h> +#include <iostream> +#include <fstream> +#include <list> +#include <algorithm> +using namespace std; +#include "beta_cfg.hpp" +#include "dump_fit_qdp.hpp" +#include "report_error.hpp" +#include "vchisq.hpp" +#include "chisq.hpp" +#include "beta.hpp" +#include "models/beta1d.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <core/freeze_param.hpp> +#include <error_estimator/error_estimator.hpp> +#include "spline.h" +using namespace opt_utilities; +//double s=5.63136645E20; +const double kpc=3.086E21;//kpc in cm +const double Mpc=kpc*1000; +double beta_func(double r, + double n0,double rc,double beta) +{ + + return abs(n0)*pow(1+r*r/rc/rc,-3./2.*abs(beta)); +} + + + //calculate critical density from z, under following cosmological constants +static double calc_critical_density(double z, + const double H0=2.3E-18, + const double Omega_m=.27) +{ + const double G=6.673E-8;//cm^3 g^-1 s^2 + const double E=std::sqrt(Omega_m*(1+z)*(1+z)*(1+z)+1-Omega_m); + const double H=H0*E; + return 3*H*H/8/pi/G; +} + + +//A class enclosing the spline interpolation method of cooling function +//check spline.h for more detailed information +//this class is a thin wrapper for the spline class defined in spline.h +class spline_func_obj + :public func_obj<double,double> +{ + //has an spline object + spline<double> spl; +public: + //This function is used to calculate the intepolated value + double do_eval(const double& x) + { + 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); + } +}; + +int main(int argc,char* argv[]) +{ + if(argc<4) + { + cerr<<argv[0]<<" <configure file> <rout in kpc> <bolo erg cfunc file>"<<endl; + return -1; + } + //initialize the parameters list + ifstream cfg_file(argv[1]); + assert(cfg_file.is_open()); + cfg_map cfg=parse_cfg_file(cfg_file); + + //check the existence of following parameters + + const double z=cfg.z; + + //initialize the radius list, sbp list and sbp error list + std::vector<double> radii; + std::vector<double> sbps; + std::vector<double> sbpe; + std::vector<double> radii_all; + std::vector<double> sbps_all; + std::vector<double> sbpe_all; + //read sbp and sbp error data + for(ifstream ifs(cfg.sbp_file.c_str());;) + { + assert(ifs.is_open()); + double x,xe; + ifs>>x>>xe; + if(!ifs.good()) + { + break; + } + if(x/xe<2) + { + break; + } + cerr<<x<<"\t"<<xe<<endl; + sbps.push_back(x); + sbpe.push_back(xe); + sbps_all.push_back(x); + sbpe_all.push_back(xe); + } + + //read radius data + for(ifstream ifs(cfg.radius_file.c_str());;) + { + assert(ifs.is_open()); + double x; + ifs>>x; + if(!ifs.good()) + { + break; + } + cerr<<x<<endl; + radii.push_back(x); + radii_all.push_back(x); + } + //initialize the cm/pixel value + double cm_per_pixel=cfg.cm_per_pixel; + double rmin=5*kpc/cm_per_pixel; + if(cfg.rmin_pixel>0) + { + rmin=cfg.rmin_pixel; + } + else + { + rmin=cfg.rmin_kpc*kpc/cm_per_pixel; + } + + cerr<<"rmin="<<rmin<<endl; + std::list<double> radii_tmp,sbps_tmp,sbpe_tmp; + radii_tmp.resize(radii.size()); + sbps_tmp.resize(sbps.size()); + sbpe_tmp.resize(sbpe.size()); + copy(radii.begin(),radii.end(),radii_tmp.begin()); + copy(sbps.begin(),sbps.end(),sbps_tmp.begin()); + copy(sbpe.begin(),sbpe.end(),sbpe_tmp.begin()); + for(list<double>::iterator i=radii_tmp.begin();i!=radii_tmp.end();) + { + if(*i<rmin) + { + radii_tmp.pop_front(); + sbps_tmp.pop_front(); + sbpe_tmp.pop_front(); + i=radii_tmp.begin(); + continue; + } + ++i; + } + radii.resize(radii_tmp.size()); + sbps.resize(sbps_tmp.size()); + sbpe.resize(sbpe_tmp.size()); + copy(radii_tmp.begin(),radii_tmp.end(),radii.begin()); + copy(sbps_tmp.begin(),sbps_tmp.end(),sbps.begin()); + copy(sbpe_tmp.begin(),sbpe_tmp.end(),sbpe.begin()); + + //read cooling function data + spline_func_obj cf; + for(ifstream ifs(cfg.cfunc_file.c_str());;) + { + assert(ifs.is_open()); + double x,y,y1,y2; + ifs>>x>>y; + if(!ifs.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; + if(x>radii.back()) + { + break; + } + //cf.add_point(x,y*2.1249719395939022e-68);//change with source + cf.add_point(x,y);//change with source + } + cf.gen_spline(); + + //read temperature profile data + spline_func_obj Tprof; + int tcnt=0; + for(ifstream ifs1(cfg.T_file.c_str());;++tcnt) + { + assert(ifs1.is_open()); + double x,y; + ifs1>>x>>y; + if(!ifs1.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; +#if 0 + if(tcnt==0) + { + Tprof.add_point(0,y); + } +#endif + Tprof.add_point(x,y); + } + + + Tprof.gen_spline(); + + default_data_set<std::vector<double>,std::vector<double> > ds; + ds.add_data(data<std::vector<double>,std::vector<double> >(radii,sbps,sbpe,sbpe,radii,radii)); + + //initial fitter + fitter<vector<double>,vector<double>,vector<double>,double> f; + f.load_data(ds); + //initial the object, which is used to calculate projection effect + projector<double> a; + beta<double> betao; + //attach the cooling function + a.attach_cfunc(cf); + a.set_cm_per_pixel(cm_per_pixel); + a.attach_model(betao); + f.set_model(a); + //chi^2 statistic + vchisq<double> c; + c.verbose(true); + c.set_limit(); + f.set_statistic(c); + //optimization method + f.set_opt_method(powell_method<double,std::vector<double> >()); + //initialize the initial values + double n0=0; + //double beta=atof(arg_map["beta"].c_str()); + double beta=0; + double rc=0; + double bkg=0; + + for(std::map<std::string,std::vector<double> >::iterator i=cfg.param_map.begin(); + i!=cfg.param_map.end();++i) + { + std::string pname=i->first; + f.set_param_value(pname,i->second.at(0)); + if(i->second.size()==3) + { + double a1=i->second[1]; + double a2=i->second[2]; + double u=std::max(a1,a2); + double l=std::min(a1,a2); + f.set_param_upper_limit(pname,u); + f.set_param_lower_limit(pname,l); + } + else + { + if(pname=="beta") + { + f.set_param_lower_limit(pname,.3); + f.set_param_upper_limit(pname,1.4); + } + } + } + + f.fit(); + f.fit(); + std::vector<double> p=f.get_all_params(); + n0=f.get_param_value("n0"); + rc=f.get_param_value("rc"); + beta=f.get_param_value("beta"); + //output the datasets and fitting results + ofstream param_output("lx_beta_param.txt"); + for(int i=0;i<f.get_num_params();++i) + { + if(f.get_param_info(i).get_name()=="rc") + { + cerr<<"rc_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + param_output<<"rc_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + } + cerr<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + param_output<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + } + cerr<<"chi square="<<f.get_statistic_value()/(radii.size()-f.get_model().get_num_free_params())<<endl; + param_output<<"chi square="<<f.get_statistic_value()/(radii.size()-f.get_model().get_num_free_params())<<endl; + + std::vector<double> mv=f.eval_model_raw(radii_all,p); + int sbps_inner_cut_size=int(sbps_all.size()-sbps.size()); + ofstream ofs_sbp("lx_sbp_fit.qdp"); + ofs_sbp<<"read serr 2"<<endl; + ofs_sbp<<"skip single"<<endl; + ofs_sbp<<"line off "<<endl; + if(sbps_inner_cut_size>=1) + { + ofs_sbp<<"line on 2"<<endl; + ofs_sbp<<"line on 3"<<endl; + ofs_sbp<<"line on 4"<<endl; + ofs_sbp<<"line on 5"<<endl; + ofs_sbp<<"ls 2 on 2"<<endl; + ofs_sbp<<"ls 2 on 4"<<endl; + ofs_sbp<<"ls 2 on 5"<<endl; + ofs_sbp<<"line on 7"<<endl; + ofs_sbp<<"ls 2 on 7"<<endl; + + ofs_sbp<<"ma 1 on 2"<<endl; + ofs_sbp<<"color 1 on 1"<<endl; + ofs_sbp<<"color 2 on 2"<<endl; + ofs_sbp<<"color 3 on 3"<<endl; + ofs_sbp<<"color 4 on 4"<<endl; + ofs_sbp<<"color 5 on 5"<<endl; + + ofs_sbp<<"win 1"<<endl; + ofs_sbp<<"yplot 1 2 3 4 5"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .4 .9 .9"<<endl; + ofs_sbp<<"la y cnt/s/pixel/cm^2"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[sbps.size()-2]+radii[sbps.size()-1])/2*cm_per_pixel/kpc<<endl; + ofs_sbp<<"win 2"<<endl; + ofs_sbp<<"yplot 6 7"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .1 .9 .4"<<endl; + ofs_sbp<<"la x radius (kpc)"<<endl; + ofs_sbp<<"la y chi"<<endl; + ofs_sbp<<"log y off"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[sbps.size()-2]+radii[sbps.size()-1])/2*cm_per_pixel/kpc<<endl; + } + else + { + ofs_sbp<<"line on 2"<<endl; + ofs_sbp<<"line on 3"<<endl; + ofs_sbp<<"line on 4"<<endl; + ofs_sbp<<"ls 2 on 3"<<endl; + ofs_sbp<<"ls 2 on 4"<<endl; + ofs_sbp<<"line on 6"<<endl; + ofs_sbp<<"ls 2 on 6"<<endl; + + ofs_sbp<<"color 1 on 1"<<endl; + ofs_sbp<<"color 3 on 2"<<endl; + ofs_sbp<<"color 4 on 3"<<endl; + ofs_sbp<<"color 5 on 4"<<endl; + //ofs_sbp<<"ma 1 on 2"<<endl; + + ofs_sbp<<"win 1"<<endl; + ofs_sbp<<"yplot 1 2 3 4"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .4 .9 .9"<<endl; + ofs_sbp<<"la y cnt/s/pixel/cm^2"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[radii.size()-2]+radii[radii.size()-1])/2*cm_per_pixel/kpc<<endl; + ofs_sbp<<"win 2"<<endl; + ofs_sbp<<"yplot 5 6"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .1 .9 .4"<<endl; + ofs_sbp<<"la x radius (kpc)"<<endl; + ofs_sbp<<"la y chi"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y off"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[radii.size()-2]+radii[radii.size()-1])/2*cm_per_pixel/kpc<<endl; + + } + // cout<<sbps_all.size()<<"\t"<<sbps.size()<<"\t"<<sbps_inner_cut_size<<endl; + for(int i=1;i<sbps_all.size();++i) + { + double x=(radii_all[i]+radii_all[i-1])/2; + double y=sbps_all[i-1]; + double ye=sbpe_all[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<y<<"\t"<<ye<<endl; + } + if(sbps_inner_cut_size>=1) + { + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps_inner_cut_size+1;++i) + { + double x=(radii_all[i]+radii_all[i-1])/2; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<ym<<"\t"<<"0"<<endl; + } + } + ofs_sbp<<"no no no"<<endl; + for(int i=sbps_inner_cut_size;i<sbps_all.size();++i) + { + double x=(radii_all[i]+radii_all[i-1])/2; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<ym<<"\t"<<"0"<<endl; + } + ofs_sbp<<"no no no"<<endl; + //bkg level + double bkg_level=abs(f.get_param_value("bkg")); + for(int i=0;i<sbps_all.size();++i) + { + double x=(radii_all[i]+radii_all[i-1])/2; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<bkg_level<<"\t0"<<endl; + } + ofs_sbp<<"no no no"<<endl; + //rc + double rc_kpc=abs(f.get_param_value("rc")*cm_per_pixel/kpc); + double max_sbp=*max_element(sbps_all.begin(),sbps_all.end()); + double min_sbp=*min_element(sbps_all.begin(),sbps_all.end()); + for(double x=min_sbp;x<=max_sbp;x+=(max_sbp-min_sbp)/100) + { + ofs_sbp<<rc_kpc<<"\t"<<x<<"\t"<<"0"<<endl; + } + //resid + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<(ym-sbps[i-1])/sbpe[i-1]<<"\t"<<1<<endl; + } + + //zero level of resid + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<0<<"\t"<<0<<endl; + } + + mv=betao.eval(radii,p); + ofstream ofs_rho("lx_rho_fit.qdp"); + ofstream ofs_rho_data("lx_rho_fit.dat"); + + ofs_rho<<"la x radius (kpc)"<<endl; + ofs_rho<<"la y density (cm\\u-3\\d)"<<endl; + /* + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double ym=mv[i-1]; + ofs_rho<<x*cm_per_pixel/kpc<<"\t"<<ym<<endl; + } + */ + p.back()=0; + radii.clear(); + double rout=atof(argv[2])*kpc; + + for(double r=0;r<rout;r+=1*kpc)//step size=1kpc + { + double r_pix=r/cm_per_pixel; + radii.push_back(r_pix); + } + + double Da=cm_per_pixel/(.492/3600./180.*pi); + double Dl=Da*(1+z)*(1+z); + cout<<"dl="<<Dl/kpc<<endl; + + for(int n=3;n<argc;++n) + { + spline_func_obj cf_bolo_erg; + for(ifstream ifs(argv[n]);;) + { + assert(ifs.is_open()); + double x,y; + ifs>>x>>y; + if(!ifs.good()) + { + break; + } + //cerr<<x<<"\t"<<y<<endl; + + cf_bolo_erg.add_point(x,y);//change with source + } + cf_bolo_erg.gen_spline(); + + projector<double>& pj=dynamic_cast<projector<double>&>(f.get_model()); + pj.attach_cfunc(cf_bolo_erg); + + + + mv=f.eval_model_raw(radii,p); + double flux_erg=0; + for(int i=0;i<radii.size()-1;++i) + { + double S=pi*(radii[i+1]+radii[i])*(radii[i+1]-radii[i]); + flux_erg+=S*mv[i]; + } + cout<<flux_erg*4*pi*Dl*Dl<<endl; + cout<<flux_erg<<endl; + param_output<<"Lx"<<n-2<<"\t"<<flux_erg*4*pi*Dl*Dl<<endl; + param_output<<"Fx"<<n-2<<"\t"<<flux_erg<<endl; + } +} diff --git a/mass_profile/calc_lx_beta.sh b/mass_profile/calc_lx_beta.sh new file mode 100755 index 0000000..b007b4f --- /dev/null +++ b/mass_profile/calc_lx_beta.sh @@ -0,0 +1,161 @@ +#!/bin/sh + +echo "### \$#: $#" +echo "### `pwd -P`" +if [ $# -gt 1 ] +then + : +else + echo "Usage:$0 <cfg file> <rout in kpc> [c]" + echo "If central value only, append a \"c\"" + exit +fi +export PATH="/usr/local/bin:/usr/bin:/bin:$PATH" +export PGPLOT_FONT="${HEADAS}/lib/grfont.dat" + +# blist file +# (energy bands to calc cooling function data) +BLIST="blist.txt" +[ -e "${BLIST}" ] && mv -f ${BLIST} ${BLIST}_bak +cat > ${BLIST} << _EOF_ +bolo +0.7 7 +0.1 2.4 +_EOF_ + +cfg_file=$1 +rout=$2 +base_path=`dirname $0` +echo $base_path +#initialize sbp config file +sbp_cfg=`grep '^sbp_cfg' $cfg_file|awk '{print $2}'` +#initialize profile type name +t_profile_type=`grep '^t_profile' $cfg_file|awk '{print $2}'` +#initialize data file name +t_data_file=`grep '^t_data_file' $cfg_file|awk '{print $2}'` +#initialize sbp data file +sbp_data_file=`grep '^sbp_file' $sbp_cfg | awk '{ print $2 }'` +#initialize the temperature profile file +T_file=`grep '^T_file' $sbp_cfg|awk '{print $2}'` +#initialize the rmin_kpc for nfw mass profile fitting +nfw_rmin_kpc=`grep '^nfw_rmin_kpc' $cfg_file|awk '{print $2}'` +#echo $t_profile_type +cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` +da=`python -c "print($cm_per_pixel/(.492/3600/180*3.1415926))"` + +#determine which temperature profile to be used, and fit the T profile +if [ "$t_profile_type" = "wang2012" ]; then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel 2> /dev/null + mv -f wang2012_dump.qdp ${T_file} +else + echo temperature profile name invalid! + exit +fi + +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{print $2}'` +z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` +dl=`python -c "print($da*(1+$z)**2)"` +abund=`grep '^abund' ${cfg_file} |awk '{print $2}'` +nh=`grep '^nh' ${cfg_file} |awk '{print $2}'` +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file +#$base_path/coolfunc_calc_bolo.sh ${T_file} $abund $nh $z cfunc_bolo.dat +#$base_path/coolfunc_calc_0.7-7.sh ${T_file} $abund $nh $z cfunc_0.7-7.dat +#$base_path/coolfunc_calc_0.1-2.4.sh ${T_file} $abund $nh $z cfunc_0.1-2.4.dat +$base_path/coolfunc_calc_erg.sh ${T_file} $abund $nh $z "cfunc_" ${BLIST} +mv flux_cnt_ratio.txt flux_cnt_ratio_center.txt +#fit sbp +prog="calc_lx_beta" +lx_res="lx_beta_param.txt" +$base_path/${prog} $sbp_cfg $rout cfunc_bolo.dat cfunc_0.7-7.dat cfunc_0.1-2.4.dat 2> /dev/null +LX1=`grep 'Lx1' $lx_res |awk '{print $2}'` +LX2=`grep 'Lx2' $lx_res |awk '{print $2}'` +LX3=`grep 'Lx3' $lx_res |awk '{print $2}'` +FX1=`grep 'Fx1' $lx_res |awk '{print $2}'` +FX2=`grep 'Fx2' $lx_res |awk '{print $2}'` +FX3=`grep 'Fx3' $lx_res |awk '{print $2}'` + +echo $LX1 $LX2 $LX3 >summary_lx.dat +echo $FX1 $FX2 $FX3 >summary_fx.dat +echo $cfunc_file +#exit + +#store central value +mv ${lx_res} ${lx_res%.txt}_center.txt +mv lx_sbp_fit.qdp lx_sbp_fit_center.qdp +mv lx_rho_fit.dat lx_rho_fit_center.dat + +#rm -f summary_lx.dat +#calculate cooling time +#echo $dl + +## calculate center values +if [ $# -eq 3 ]; then + $base_path/analyze_lx.py + $base_path/analyze_fx.py + exit 0 +fi + + +########################################################### +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +for i in `seq 1 100`; do + echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + #t_data_file=temp_shuffled_t.dat + #exit + + if [ "$t_profile_type" = "wang2012" ]; then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel 2> /dev/null + mv -f wang2012_dump.qdp ${T_file} + else + echo temperature profile name invalid! + exit + fi + + echo >temp_sbp.cfg + + cat $sbp_cfg | while read l; do + if echo $l|grep sbp_file >/dev/null + then + echo sbp_file temp_shuffled_sbp.dat >>temp_sbp.cfg + elif echo $l|grep T_file >/dev/null + then + echo T_file ${T_file} >>temp_sbp.cfg + else + echo $l >>temp_sbp.cfg + fi + done + + #exit + + echo "### `pwd -P`" + echo "### $i ###" + + $base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file + #$base_path/coolfunc_calc_bolo.sh ${T_file} $abund $nh $z cfunc_bolo.dat + #$base_path/coolfunc_calc_0.7-7.sh ${T_file} $abund $nh $z cfunc_0.7-7.dat + #$base_path/coolfunc_calc_0.1-2.4.sh ${T_file} $abund $nh $z cfunc_0.1-2.4.dat + $base_path/coolfunc_calc_erg.sh ${T_file} $abund $nh $z "cfunc_" ${BLIST} + $base_path/$prog temp_sbp.cfg $rout cfunc_bolo.dat cfunc_0.7-7.dat cfunc_0.1-2.4.dat 2> /dev/null + #grep Lx $lx_res |awk '{print $2}' >>summary_lx.dat + LX1=`grep 'Lx1' $lx_res |awk '{print $2}'` + LX2=`grep 'Lx2' $lx_res |awk '{print $2}'` + LX3=`grep 'Lx3' $lx_res |awk '{print $2}'` + FX1=`grep 'Fx1' $lx_res |awk '{print $2}'` + FX2=`grep 'Fx2' $lx_res |awk '{print $2}'` + FX3=`grep 'Fx3' $lx_res |awk '{print $2}'` + + echo $LX1 $LX2 $LX3 >>summary_lx.dat + echo $FX1 $FX2 $FX3 >>summary_fx.dat +done # end of 'for' + +# analyze lx & fx +$base_path/analyze_lx.py +$base_path/analyze_fx.py + +exit 0 + diff --git a/mass_profile/calc_lx_dbeta.cpp b/mass_profile/calc_lx_dbeta.cpp new file mode 100644 index 0000000..f105869 --- /dev/null +++ b/mass_profile/calc_lx_dbeta.cpp @@ -0,0 +1,550 @@ +/* + Perform a double-beta density model fitting to the surface brightness data + Author: Junhua Gu + Last modified: 2011.01.01 + This code is distributed with no warrant +*/ + + +#include <iostream> +#include <fstream> +#include <list> +using namespace std; +#include "vchisq.hpp" +#include "dbeta.hpp" +#include "beta_cfg.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <core/freeze_param.hpp> +#include <error_estimator/error_estimator.hpp> +#include "spline.h" +using namespace opt_utilities; +//double s=5.63136645E20; +const double kpc=3.086E21;//kpc in cm +const double Mpc=kpc*1000; +double dbeta_func(double r, + double n01,double rc1,double beta1, + double n02,double rc2,double beta2) +{ + + return abs(n01)*pow(1+r*r/rc1/rc1,-3./2.*abs(beta1))+abs(n02)*pow(1+r*r/rc2/rc2,-3./2.*abs(beta2)); +} + + + //calculate critical density from z, under following cosmological constants +static double calc_critical_density(double z, + const double H0=2.3E-18, + const double Omega_m=.27) +{ + const double G=6.673E-8;//cm^3 g^-1 s^2 + const double E=std::sqrt(Omega_m*(1+z)*(1+z)*(1+z)+1-Omega_m); + const double H=H0*E; + return 3*H*H/8/pi/G; +} + + +//A class enclosing the spline interpolation method of cooling function +//check spline.h for more detailed information +//this class is a thin wrapper for the spline class defined in spline.h +class spline_func_obj + :public func_obj<double,double> +{ + //has an spline object + spline<double> spl; +public: + //This function is used to calculate the intepolated value + double do_eval(const double& x) + { + 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); + } +}; + +int main(int argc,char* argv[]) +{ + if(argc<4) + { + cerr<<argv[0]<<" <configure file> <rout in kpc> <bolo erg cfunc file> "<<endl; + return -1; + } + //initialize the parameters list + ifstream cfg_file(argv[1]); + assert(cfg_file.is_open()); + cfg_map cfg=parse_cfg_file(cfg_file); + + //check the existence of following parameters + + const double z=cfg.z; + + //initialize the radius list, sbp list and sbp error list + std::vector<double> radii; + std::vector<double> sbps; + std::vector<double> sbpe; + std::vector<double> radii_all; + std::vector<double> sbps_all; + std::vector<double> sbpe_all; + //read sbp and sbp error data + for(ifstream ifs(cfg.sbp_file.c_str());;) + { + assert(ifs.is_open()); + double x,xe; + ifs>>x>>xe; + if(!ifs.good()) + { + break; + } + if(x/xe<2) + { + break; + } + cerr<<x<<"\t"<<xe<<endl; + sbps.push_back(x); + sbpe.push_back(xe); + sbps_all.push_back(x); + sbpe_all.push_back(xe); + } + + //read radius data + for(ifstream ifs(cfg.radius_file.c_str());;) + { + assert(ifs.is_open()); + double x; + ifs>>x; + if(!ifs.good()) + { + break; + } + cerr<<x<<endl; + radii.push_back(x); + radii_all.push_back(x); + } + //initialize the cm/pixel value + double cm_per_pixel=cfg.cm_per_pixel; + double rmin=5*kpc/cm_per_pixel; + if(cfg.rmin_pixel>0) + { + rmin=cfg.rmin_pixel; + } + else + { + rmin=cfg.rmin_kpc*kpc/cm_per_pixel; + } + + cerr<<"rmin="<<rmin<<endl; + std::list<double> radii_tmp,sbps_tmp,sbpe_tmp; + radii_tmp.resize(radii.size()); + sbps_tmp.resize(sbps.size()); + sbpe_tmp.resize(sbpe.size()); + copy(radii.begin(),radii.end(),radii_tmp.begin()); + copy(sbps.begin(),sbps.end(),sbps_tmp.begin()); + copy(sbpe.begin(),sbpe.end(),sbpe_tmp.begin()); + for(list<double>::iterator i=radii_tmp.begin();i!=radii_tmp.end();) + { + if(*i<rmin) + { + radii_tmp.pop_front(); + sbps_tmp.pop_front(); + sbpe_tmp.pop_front(); + i=radii_tmp.begin(); + continue; + } + ++i; + } + radii.resize(radii_tmp.size()); + sbps.resize(sbps_tmp.size()); + sbpe.resize(sbpe_tmp.size()); + copy(radii_tmp.begin(),radii_tmp.end(),radii.begin()); + copy(sbps_tmp.begin(),sbps_tmp.end(),sbps.begin()); + copy(sbpe_tmp.begin(),sbpe_tmp.end(),sbpe.begin()); + + //read cooling function data + spline_func_obj cf; + for(ifstream ifs(cfg.cfunc_file.c_str());;) + { + assert(ifs.is_open()); + double x,y,y1,y2; + ifs>>x>>y; + if(!ifs.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; + if(x>radii.back()) + { + break; + } + //cf.add_point(x,y*2.1249719395939022e-68);//change with source + cf.add_point(x,y);//change with source + } + cf.gen_spline(); + + //read temperature profile data + spline_func_obj Tprof; + int tcnt=0; + for(ifstream ifs1(cfg.T_file.c_str());;++tcnt) + { + assert(ifs1.is_open()); + double x,y; + ifs1>>x>>y; + if(!ifs1.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; +#if 0 + if(tcnt==0) + { + Tprof.add_point(0,y); + } +#endif + Tprof.add_point(x,y); + } + + + Tprof.gen_spline(); + + default_data_set<std::vector<double>,std::vector<double> > ds; + ds.add_data(data<std::vector<double>,std::vector<double> >(radii,sbps,sbpe,sbpe,radii,radii)); + + //initial fitter + fitter<vector<double>,vector<double>,vector<double>,double> f; + f.load_data(ds); + //initial the object, which is used to calculate projection effect + projector<double> a; + bool tie_beta=false; + if(cfg.param_map.find("beta")!=cfg.param_map.end() + &&cfg.param_map.find("beta1")==cfg.param_map.end() + &&cfg.param_map.find("beta2")==cfg.param_map.end()) + { + dbeta2<double> dbetao; + a.attach_model(dbetao); + tie_beta=true; + } + else if((cfg.param_map.find("beta1")!=cfg.param_map.end() + ||cfg.param_map.find("beta2")!=cfg.param_map.end()) + &&cfg.param_map.find("beta")==cfg.param_map.end()) + { + dbeta<double> dbetao; + a.attach_model(dbetao); + tie_beta=false; + } + else + { + cerr<<"Error, cannot decide whether to tie beta together or let them vary freely!"<<endl; + assert(0); + } + + //attach the cooling function + a.attach_cfunc(cf); + a.set_cm_per_pixel(cm_per_pixel); + + f.set_model(a); + //chi^2 statistic + vchisq<double> c; + c.verbose(true); + c.set_limit(); + f.set_statistic(c); + //optimization method + f.set_opt_method(powell_method<double,std::vector<double> >()); + //initialize the initial values + double n01=0; + double rc1=0; + double n02=0; + double rc2=0; + double beta=0; + double bkg=0; + if(tie_beta) + { + f.set_param_value("beta",.7); + f.set_param_lower_limit("beta",.3); + f.set_param_upper_limit("beta",1.4); + } + else + { + f.set_param_value("beta1",.7); + f.set_param_lower_limit("beta1",.3); + f.set_param_upper_limit("beta1",1.4); + f.set_param_value("beta2",.7); + f.set_param_lower_limit("beta2",.3); + f.set_param_upper_limit("beta2",1.4); + } + for(std::map<std::string,std::vector<double> >::iterator i=cfg.param_map.begin(); + i!=cfg.param_map.end();++i) + { + std::string pname=i->first; + f.set_param_value(pname,i->second.at(0)); + if(i->second.size()==3) + { + double a1=i->second[1]; + double a2=i->second[2]; + double u=std::max(a1,a2); + double l=std::min(a1,a2); + f.set_param_upper_limit(pname,u); + f.set_param_lower_limit(pname,l); + } + else + { + if(pname=="beta"||pname=="beta1"||pname=="beta2") + { + f.set_param_lower_limit(pname,.3); + f.set_param_upper_limit(pname,1.4); + } + } + } + + + + //perform the fitting, first freeze beta1, beta2, rc1, and rc2 + if(tie_beta) + { + f.set_param_modifier(freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("beta")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("rc1")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("rc2") + ); + } + else + { + f.set_param_modifier(freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("beta1")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("beta2")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("rc1")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("rc2") + ); + } + + f.fit(); + + f.clear_param_modifier(); + + //then perform the fitting, freeze beta1 and beta2 + //f.set_param_modifier(freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("beta")); + //f.set_param_modifier(freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("bkg")); + f.fit(); + //f.clear_param_modifier(); + + //finally thaw all parameters + f.fit(); + double beta1=0; + double beta2=0; + + n01=f.get_param_value("n01"); + rc1=f.get_param_value("rc1"); + n02=f.get_param_value("n02"); + rc2=f.get_param_value("rc2"); + if(tie_beta) + { + beta=f.get_param_value("beta"); + beta1=beta; + beta2=beta; + } + else + { + beta1=f.get_param_value("beta1"); + beta2=f.get_param_value("beta2"); + } + //output the params + ofstream param_output("lx_dbeta_param.txt"); + //output the datasets and fitting results + for(int i=0;i<f.get_num_params();++i) + { + if(f.get_param_info(i).get_name()=="rc1") + { + cerr<<"rc1_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + param_output<<"rc1_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + } + if(f.get_param_info(i).get_name()=="rc2") + { + cerr<<"rc2_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + param_output<<"rc2_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + } + cerr<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + param_output<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + } + cerr<<"chi square="<<f.get_statistic_value()/(radii.size()-f.get_model().get_num_free_params())<<endl; + param_output<<"chi square="<<f.get_statistic_value()/(radii.size()-f.get_model().get_num_free_params())<<endl; + + //c.verbose(false); + //f.set_statistic(c); + //f.fit(); + std::vector<double> p=f.get_all_params(); + f.clear_param_modifier(); + std::vector<double> mv=f.eval_model(radii,p); + + + ofstream ofs_sbp("lx_sbp_fit.qdp"); + ofs_sbp<<"read serr 2"<<endl; + ofs_sbp<<"skip single"<<endl; + + ofs_sbp<<"line on 2"<<endl; + ofs_sbp<<"line on 3"<<endl; + ofs_sbp<<"line on 4"<<endl; + ofs_sbp<<"line on 5"<<endl; + ofs_sbp<<"line on 7"<<endl; + ofs_sbp<<"ls 2 on 7"<<endl; + ofs_sbp<<"ls 2 on 3"<<endl; + ofs_sbp<<"ls 2 on 4"<<endl; + ofs_sbp<<"ls 2 on 5"<<endl; + + + + ofs_sbp<<"!LAB POS Y 4.00"<<endl; + ofs_sbp<<"!LAB ROT"<<endl; + ofs_sbp<<"win 1"<<endl; + ofs_sbp<<"yplot 1 2 3 4 5"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .4 .9 .9"<<endl; + ofs_sbp<<"la y cnt/s/pixel/cm\\u2\\d"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[sbps.size()-2]+radii[sbps.size()-1])/2*cm_per_pixel/kpc<<endl; + ofs_sbp<<"win 2"<<endl; + ofs_sbp<<"yplot 6 7"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .1 .9 .4"<<endl; + ofs_sbp<<"la x radius (kpc)"<<endl; + ofs_sbp<<"la y chi"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y off"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[sbps.size()-2]+radii[sbps.size()-1])/2*cm_per_pixel/kpc<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<y<<"\t"<<ye<<endl; + } + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<ym<<"\t"<<0<<endl; + } + //bkg + ofs_sbp<<"no no no"<<endl; + double bkg_level=abs(f.get_param_value("bkg")); + for(int i=0;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<bkg_level<<"\t0"<<endl; + } + //rc1 + ofs_sbp<<"no no no"<<endl; + double rc1_kpc=abs(f.get_param_value("rc1")*cm_per_pixel/kpc); + double max_sbp=*max_element(sbps.begin(),sbps.end()); + double min_sbp=*min_element(sbps.begin(),sbps.end()); + for(double x=min_sbp;x<=max_sbp;x+=(max_sbp-min_sbp)/100) + { + ofs_sbp<<rc1_kpc<<"\t"<<x<<"\t"<<"0"<<endl; + } + //rc2 + ofs_sbp<<"no no no"<<endl; + double rc2_kpc=abs(f.get_param_value("rc2")*cm_per_pixel/kpc); + for(double x=min_sbp;x<=max_sbp;x+=(max_sbp-min_sbp)/100) + { + ofs_sbp<<rc2_kpc<<"\t"<<x<<"\t"<<"0"<<endl; + } + //resid + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<(ym-sbps[i-1])/sbpe[i-1]<<"\t"<<1<<endl; + } + //zero level in resid map + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<0<<"\t"<<0<<endl; + } + + + mv=f.eval_model_raw(radii,p); + ofstream ofs_rho("lx_rho_fit.qdp"); + ofstream ofs_rho_data("lx_rho_fit.dat"); + //ofstream ofs_entropy("entropy.qdp"); + ofs_rho<<"la x radius (kpc)"<<endl; + ofs_rho<<"la y density (cm\\u-3\\d)"<<endl; + /* + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double ym=mv[i-1]; + ofs_rho<<x*cm_per_pixel/kpc<<"\t"<<ym<<endl; + } + */ + + p.back()=0; + + radii.clear(); + double rout=atof(argv[2])*kpc; + for(double r=0;r<rout;r+=1*kpc)//step size=1kpc + { + double r_pix=r/cm_per_pixel; + radii.push_back(r_pix); + } + + double Da=cm_per_pixel/(.492/3600./180.*pi); + double Dl=Da*(1+z)*(1+z); + cout<<"dl="<<Dl/kpc<<endl; + for(int n=3;n<argc;++n) + { + spline_func_obj cf_bolo_erg; + for(ifstream ifs(argv[n]);;) + { + assert(ifs.is_open()); + double x,y; + ifs>>x>>y; + if(!ifs.good()) + { + break; + } + //cerr<<x<<"\t"<<y<<endl; + + cf_bolo_erg.add_point(x,y);//change with source + } + cf_bolo_erg.gen_spline(); + + projector<double>& pj=dynamic_cast<projector<double>&>(f.get_model()); + pj.attach_cfunc(cf_bolo_erg); + + mv=f.eval_model_raw(radii,p); + double flux_erg=0; + for(int i=0;i<radii.size()-1;++i) + { + double S=pi*(radii[i+1]+radii[i])*(radii[i+1]-radii[i]); + flux_erg+=S*mv[i]; + } + cout<<flux_erg*4*pi*Dl*Dl<<endl; + cout<<flux_erg<<endl; + param_output<<"Lx"<<n-2<<"\t"<<flux_erg*4*pi*Dl*Dl<<endl; + param_output<<"Fx"<<n-2<<"\t"<<flux_erg<<endl; + } +} diff --git a/mass_profile/calc_lx_dbeta.sh b/mass_profile/calc_lx_dbeta.sh new file mode 100755 index 0000000..104e4b3 --- /dev/null +++ b/mass_profile/calc_lx_dbeta.sh @@ -0,0 +1,161 @@ +#!/bin/sh + +echo "### \$#: $#" +echo "### `pwd -P`" +if [ $# -gt 1 ] +then + : +else + echo "Usage:$0 <cfg file> <rout in kpc> [c]" + echo "If central value only, append a \"c\"" + exit +fi +export PATH="/usr/local/bin:/usr/bin:/bin:$PATH" +export PGPLOT_FONT="${HEADAS}/lib/grfont.dat" + +# blist file +# (energy bands to calc cooling function data) +BLIST="blist.txt" +[ -e "${BLIST}" ] && mv -f ${BLIST} ${BLIST}_bak +cat > ${BLIST} << _EOF_ +bolo +0.7 7 +0.1 2.4 +_EOF_ + +cfg_file=$1 +rout=$2 +base_path=`dirname $0` +echo $base_path +#initialize sbp config file +sbp_cfg=`grep '^sbp_cfg' $cfg_file|awk '{print $2}'` +#initialize profile type name +t_profile_type=`grep '^t_profile' $cfg_file|awk '{print $2}'` +#initialize data file name +t_data_file=`grep '^t_data_file' $cfg_file|awk '{print $2}'` +#initialize sbp data file +sbp_data_file=`grep '^sbp_file' $sbp_cfg | awk '{ print $2 }'` +#initialize the temperature profile file +T_file=`grep '^T_file' $sbp_cfg|awk '{print $2}'` +#initialize the rmin_kpc for nfw mass profile fitting +nfw_rmin_kpc=`grep '^nfw_rmin_kpc' $cfg_file|awk '{print $2}'` +#echo $t_profile_type +cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` +da=`python -c "print($cm_per_pixel/(.492/3600/180*3.1415926))"` + +#determine which temperature profile to be used, and fit the T profile +if [ "$t_profile_type" = "wang2012" ]; then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel 2> /dev/null + mv -f wang2012_dump.qdp ${T_file} +else + echo temperature profile name invalid! + exit +fi + +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{print $2}'` +z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` +dl=`python -c "print($da*(1+$z)**2)"` +abund=`grep '^abund' ${cfg_file} |awk '{print $2}'` +nh=`grep '^nh' ${cfg_file} |awk '{print $2}'` +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file +#$base_path/coolfunc_calc_bolo.sh ${T_file} $abund $nh $z cfunc_bolo.dat +#$base_path/coolfunc_calc_0.7-7.sh ${T_file} $abund $nh $z cfunc_0.7-7.dat +#$base_path/coolfunc_calc_0.1-2.4.sh ${T_file} $abund $nh $z cfunc_0.1-2.4.dat +$base_path/coolfunc_calc_erg.sh ${T_file} $abund $nh $z "cfunc_" ${BLIST} +mv flux_cnt_ratio.txt flux_cnt_ratio_center.txt +#fit sbp +prog="calc_lx_dbeta" +lx_res="lx_dbeta_param.txt" +$base_path/${prog} $sbp_cfg $rout cfunc_bolo.dat cfunc_0.7-7.dat cfunc_0.1-2.4.dat 2> /dev/null +LX1=`grep 'Lx1' $lx_res |awk '{print $2}'` +LX2=`grep 'Lx2' $lx_res |awk '{print $2}'` +LX3=`grep 'Lx3' $lx_res |awk '{print $2}'` +FX1=`grep 'Fx1' $lx_res |awk '{print $2}'` +FX2=`grep 'Fx2' $lx_res |awk '{print $2}'` +FX3=`grep 'Fx3' $lx_res |awk '{print $2}'` + +echo $LX1 $LX2 $LX3 >summary_lx.dat +echo $FX1 $FX2 $FX3 >summary_fx.dat +echo $cfunc_file +#exit + +#store central value +mv ${lx_res} ${lx_res%.txt}_center.txt +mv lx_sbp_fit.qdp lx_sbp_fit_center.qdp +mv lx_rho_fit.dat lx_rho_fit_center.dat + +#rm -f summary_lx.dat +#calculate cooling time +#echo $dl + +## calculate center values +if [ $# -eq 3 ]; then + $base_path/analyze_lx.py + $base_path/analyze_fx.py + exit 0 +fi + + +########################################################### +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +for i in `seq 1 100`; do + echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + #t_data_file=temp_shuffled_t.dat + #exit + + if [ "$t_profile_type" = "wang2012" ]; then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel 2> /dev/null + mv -f wang2012_dump.qdp ${T_file} + else + echo temperature profile name invalid! + exit + fi + + echo >temp_sbp.cfg + + cat $sbp_cfg | while read l; do + if echo $l|grep sbp_file >/dev/null + then + echo sbp_file temp_shuffled_sbp.dat >>temp_sbp.cfg + elif echo $l|grep T_file >/dev/null + then + echo T_file ${T_file} >>temp_sbp.cfg + else + echo $l >>temp_sbp.cfg + fi + done + + #exit + + echo "### `pwd -P`" + echo "### $i ###" + + $base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file + #$base_path/coolfunc_calc_bolo.sh ${T_file} $abund $nh $z cfunc_bolo.dat + #$base_path/coolfunc_calc_0.7-7.sh ${T_file} $abund $nh $z cfunc_0.7-7.dat + #$base_path/coolfunc_calc_0.1-2.4.sh ${T_file} $abund $nh $z cfunc_0.1-2.4.dat + $base_path/coolfunc_calc_erg.sh ${T_file} $abund $nh $z "cfunc_" ${BLIST} + $base_path/$prog temp_sbp.cfg $rout cfunc_bolo.dat cfunc_0.7-7.dat cfunc_0.1-2.4.dat 2> /dev/null + #grep Lx $lx_res |awk '{print $2}' >>summary_lx.dat + LX1=`grep 'Lx1' $lx_res |awk '{print $2}'` + LX2=`grep 'Lx2' $lx_res |awk '{print $2}'` + LX3=`grep 'Lx3' $lx_res |awk '{print $2}'` + FX1=`grep 'Fx1' $lx_res |awk '{print $2}'` + FX2=`grep 'Fx2' $lx_res |awk '{print $2}'` + FX3=`grep 'Fx3' $lx_res |awk '{print $2}'` + + echo $LX1 $LX2 $LX3 >>summary_lx.dat + echo $FX1 $FX2 $FX3 >>summary_fx.dat +done # end of 'for' + +# analyze lx & fx +$base_path/analyze_lx.py +$base_path/analyze_fx.py + +exit 0 + diff --git a/mass_profile/calc_lxfx_simple.sh b/mass_profile/calc_lxfx_simple.sh new file mode 100755 index 0000000..4b6d632 --- /dev/null +++ b/mass_profile/calc_lxfx_simple.sh @@ -0,0 +1,75 @@ +#!/bin/sh +# +########################################################### +# to calculate the Lx Fx data +# based on 'loop_lx.sh', but to calculate one src per time +# +# LIweitiaNux +# 2013/10/30 +########################################################### + + +full_path=`readlink -f $0` +base_dir=`dirname $full_path` + +if [ $# -lt 2 ]; then + printf "usage:\n" + printf " `basename $0` <global.cfg> [c] < 500 | 200 > ...\n" + exit 1 +fi + +cfg_file="$1" +pre_results="final_result.txt" + +case "$2" in + [cC]*) + F_C="YES" + shift + ;; + *) + F_C="NO" + ;; +esac + +shift +echo "delta: $@" # 'printf' not work + +if [ "${F_C}" = "YES" ]; then + printf "MODE: center\n" +fi + +# exit + +if [ ! -r "${cfg_file}" ]; then + printf "ERROR: global cfg not accessible\n" +elif [ ! -r "${pre_results}" ]; then + printf "ERROR: previous '${pre_results}' not accessible\n" +else + sbp_cfg=`grep '^sbp_cfg' $cfg_file | awk '{ print $2 }'` + ## + for delta in $@; do + if grep -q '^beta2' $sbp_cfg; then + MODEL="dbeta" + else + MODEL="beta" + fi + rout=`grep "^r${delta}" ${pre_results} | sed -e 's/=/ /' | awk '{ print $2 }'` + if [ "${F_C}" = "YES" ]; then + lx_res="lx_result_${delta}_c.txt" + fx_res="fx_result_${delta}_c.txt" + CMD="$base_dir/calc_lx_${MODEL}.sh $cfg_file $rout c" + else + lx_res="lx_result_${delta}.txt" + fx_res="fx_result_${delta}.txt" + CMD="$base_dir/calc_lx_${MODEL}.sh $cfg_file $rout" + fi + [ -e "${lx_res}" ] && mv -f ${lx_res} ${lx_res}_bak + [ -e "${fx_res}" ] && mv -f ${fx_res} ${fx_res}_bak + ${CMD} + mv -f lx_result.txt ${lx_res} + mv -f fx_result.txt ${fx_res} + done +fi + +exit 0 + diff --git a/mass_profile/call_calc_distance.cc b/mass_profile/call_calc_distance.cc new file mode 100644 index 0000000..cbdd69a --- /dev/null +++ b/mass_profile/call_calc_distance.cc @@ -0,0 +1,52 @@ +#include "calc_distance.h" +#include <cstdlib> +#include <cmath> +#include <iostream> +using namespace std; + +static double cm=1; +static double s=1; +static double km=1000*100; +static double Mpc=3.08568e+24*cm; +static double kpc=3.08568e+21*cm; +static double yr=365.*24.*3600.; +static double Gyr=1e9*yr; +static double H=71.*km/s/Mpc; +static const double c=299792458.*100.*cm; +//const double c=3e8*100*cm; +static const double pi=4*atan(1); +static const double omega_m=0.27; +static const double omega_l=0.73; +static const double arcsec2arc_ratio=1./60/60/180*pi; + + + + +int main(int argc,char* argv[]) +{ + if(argc<2) + { + cerr<<"Usage:"<<argv[0]<<" z"<<endl; + exit(-1); + } + if(argc==3) + { + H=atof(argv[2])*km/s/Mpc; + } + double z=atof(argv[1]); + double d=c/H*calc_angular_distance(z); + //double age=calc_age(z); + //cout<<d<<endl; + cout<<"d_a_cm= "<<d<<" #angular distance in cm"<<endl; + cout<<"d_a_mpc= "<<d/Mpc<<"#angular distance in Mpc"<<endl; + cout<<"d_l_cm= "<<(1+z)*(1+z)*d<<" #luminosity distance in cm"<<endl; + cout<<"d_l_mpc= "<<(1+z)*(1+z)*d/Mpc<<" #luminosity in Mpc"<<endl; + cout<<"kpc_per_sec= "<<d/kpc*arcsec2arc_ratio<<" #kpc per arcsec"<<endl; + cout<<"For Chandra:"<<endl; + cout<<"kpc_per_pixel= "<<d/kpc*0.492*arcsec2arc_ratio<<" #kpc per chandra pixel"<<endl; + cout<<"cm_per_pixel= "<<d*.492*arcsec2arc_ratio<<" #cm per chandra pixel"<<endl; + cout<<"norm= "<<1E-14/(4*pi*pow(d*(1+z),2))<<" #norm used to calc cooling function"<<endl; + //cout<<ddivid(calc_distance,d,0,1,.0001)<<endl; + cout<<"E(z)= "<<E(z)<<endl; +} + diff --git a/mass_profile/change.log b/mass_profile/change.log new file mode 100644 index 0000000..c26f514 --- /dev/null +++ b/mass_profile/change.log @@ -0,0 +1,25 @@ +Changes: +v201208132246: + Change the fitting plot of surface brightness to log-log from the original linear one. + Add a constraint over the power law component and the Gaussian component of zyy model. + +v201208161900: + Utilize the mass calculation of +http://adsabs.harvard.edu/abs/2012MNRAS.422.3503W + +v201208172340: + Output the both components of the double beta model in rho_fit.qdp + added the cm per pixel parameter to fit_zyy_model +v201208180209: + add the cooling function calculation program +v201208181800: + add the 1-beta model fitting tools +v201208201200: + add the wang2012 model + make the temperature fitting programmes output fit_result.dat with a kpc x-axis +v201208261700: + use nfw to calcualte mass profile extrapolation +v201208281500: + change from calculate std error to 68% double-sided error + added output of ra and dec in query_source_info.sh + diff --git a/mass_profile/chisq.hpp b/mass_profile/chisq.hpp new file mode 100644 index 0000000..575f1c0 --- /dev/null +++ b/mass_profile/chisq.hpp @@ -0,0 +1,219 @@ +/**
+ \file chisq.hpp
+ \brief chi-square statistic
+ \author Junhua Gu
+ */
+
+#ifndef CHI_SQ_HPP
+#define CHI_SQ_HPP
+#define OPT_HEADER
+#include <core/fitter.hpp>
+#include <iostream>
+#include <vector>
+#include <misc/optvec.hpp>
+#include <cmath>
+#include "plot_reporter.hpp"
+#include <cpgplot.h>
+using std::cerr;using std::endl;
+
+namespace opt_utilities
+{
+ static const int display_interval=10;
+ /**
+ \brief chi-square statistic
+ \tparam Ty the return type of model
+ \tparam Tx the type of the self-var
+ \tparam Tp the type of model parameter
+ \tparam Ts the type of the statistic
+ \tparam Tstr the type of the string used
+ */
+ template<typename Ty,typename Tx,typename Tp,typename Ts,typename Tstr>
+ class chisq
+ :public statistic<Ty,Tx,Tp,Ts,Tstr>
+ {
+ };
+ template<>
+ class chisq<double,double,std::vector<double>,double,std::string>
+ :public statistic<double,double,std::vector<double> ,double,std::string>
+ {
+ public:
+ typedef double Ty;
+ typedef double Tx;
+ typedef std::vector<double> Tp;
+ typedef double Ts;
+ typedef std::string Tstr;
+ private:
+ bool verb;
+ bool limit_bound;
+ int n;
+
+ statistic<Ty,Tx,Tp,Ts,Tstr>* do_clone()const
+ {
+ // return const_cast<statistic<Ty,Tx,Tp>*>(this);
+ return new chisq<Ty,Tx,Tp,Ts,Tstr>(*this);
+ }
+
+ const char* do_get_type_name()const
+ {
+ return "chi^2 statistics (specialized for double)";
+ }
+ public:
+ void verbose(bool v)
+ {
+ verb=v;
+ }
+
+ void set_limit()
+ {
+ limit_bound=true;
+ }
+
+ void clear_limit()
+ {
+ limit_bound=false;
+ }
+ public:
+ chisq()
+ :verb(true),limit_bound(false)
+ {}
+
+
+
+ Ty do_eval(const Tp& p)
+ {
+ if(limit_bound)
+ {
+ Tp p1=this->get_fitter().get_model().reform_param(p);
+ for(int i=0;i<p1.size();++i)
+ {
+ if(p1[i]>this->get_fitter().get_param_info(i).get_upper_limit()||
+ p1[i]<this->get_fitter().get_param_info(i).get_lower_limit())
+ {
+ return 1e99;
+ }
+ }
+ }
+ Ty result(0);
+ std::vector<float> vx;
+ std::vector<float> vy;
+ std::vector<float> vye1;
+ std::vector<float> vye2;
+ std::vector<float> my;
+ float xmin=1e99,xmax=-1e99,ymin=1e99,ymax=-1e99;
+ if(verb)
+ {
+ n++;
+ if(n%display_interval==0)
+ {
+ vx.resize(this->get_data_set().size());
+ vy.resize(this->get_data_set().size());
+ vye1.resize(this->get_data_set().size());
+ vye2.resize(this->get_data_set().size());
+ my.resize(this->get_data_set().size());
+ }
+
+ }
+
+ for(int i=(this->get_data_set()).size()-1;i>=0;--i)
+ {
+
+#ifdef HAVE_X_ERROR
+ Tx x1=this->get_data_set().get_data(i).get_x()-this->get_data_set().get_data(i).get_x_lower_err();
+ Tx x2=this->get_data_set().get_data(i).get_x()+this->get_data_set().get_data(i).get_x_upper_err();
+ Tx x=this->get_data_set().get_data(i).get_x();
+ Ty errx1=(this->eval_model(x1,p)-this->eval_model(x,p));
+ Ty errx2=(this->eval_model(x2,p)-this->eval_model(x,p));
+ //Ty errx=0;
+#else
+ Ty errx1=0;
+ Ty errx2=0;
+#endif
+
+ Ty y_model=this->eval_model(this->get_data_set().get_data(i).get_x(),p);
+ Ty y_obs=this->get_data_set().get_data(i).get_y();
+ Ty y_err;
+
+ Ty errx=0;
+ if(errx1<errx2)
+ {
+ if(y_obs<y_model)
+ {
+ errx=errx1>0?errx1:-errx1;
+ }
+ else
+ {
+ errx=errx2>0?errx2:-errx2;
+ }
+ }
+ else
+ {
+ if(y_obs<y_model)
+ {
+ errx=errx2>0?errx2:-errx2;
+ }
+ else
+ {
+ errx=errx1>0?errx1:-errx1;
+ }
+ }
+
+
+ if(y_model>y_obs)
+ {
+ y_err=this->get_data_set().get_data(i).get_y_upper_err();
+ }
+ else
+ {
+ y_err=this->get_data_set().get_data(i).get_y_lower_err();
+ }
+
+ Ty chi=(y_obs-y_model)/std::sqrt(y_err*y_err+errx*errx);
+
+ result+=chi*chi;
+
+ if(verb&&n%display_interval==0)
+ {
+ vx.at(i)=this->get_data_set().get_data(i).get_x();
+ vy.at(i)=this->get_data_set().get_data(i).get_y();
+ vye1.at(i)=std::abs(this->get_data_set().get_data(i).get_y_lower_err());
+ vye2.at(i)=std::abs(this->get_data_set().get_data(i).get_y_upper_err());
+ my.at(i)=y_model;
+
+ xmin=std::min(vx.at(i),xmin);
+ ymin=std::min(vy.at(i),ymin-vye1[i]);
+ xmax=std::max(vx.at(i),xmax);
+ ymax=std::max(vy.at(i),ymax+vye2[i]);
+ }
+
+
+ }
+ if(verb)
+ {
+ if(n%display_interval==0)
+ {
+ cerr<<result<<"\t";
+ for(int i=0;i<(int)get_size(p);++i)
+ {
+ cerr<<get_element(p,i)<<",";
+ }
+ cerr<<endl;
+ //cerr<<x1<<"\t"<<x2<<endl;
+ pr.init_xyrange(xmin,xmax,ymin,ymax,0);
+ pr.plot_err2_dot(vx,vy,vye1,vye2);
+ pr.plot_line(vx,my);
+ cpgask(0);
+ }
+
+ }
+
+ return result;
+ }
+ };
+
+
+}
+
+#endif
+//EOF
+
+
diff --git a/mass_profile/constrained_dbeta.hpp b/mass_profile/constrained_dbeta.hpp new file mode 100644 index 0000000..24a1ebb --- /dev/null +++ b/mass_profile/constrained_dbeta.hpp @@ -0,0 +1,80 @@ +#ifndef CONSTRAINED_DBETA +#define CONSTRAINED_DBETA +#include "projector.hpp" + + +namespace opt_utilities +{ + template <typename T> + class constrained_dbeta + :public model<std::vector<T>,std::vector<T>,std::vector<T> > + { + public: + constrained_dbeta() + { + this->push_param_info(param_info<std::vector<T>,std::string>("n01",1)); + this->push_param_info(param_info<std::vector<T>,std::string>("beta1",.66)); + this->push_param_info(param_info<std::vector<T>,std::string>("rc1",100)); + + this->push_param_info(param_info<std::vector<T>,std::string>("n02",1)); + this->push_param_info(param_info<std::vector<T>,std::string>("beta2",.67)); + this->push_param_info(param_info<std::vector<T>,std::string>("rc2",110)); + + } + + public: + constrained_dbeta<T>* do_clone()const + { + return new constrained_dbeta<T>(*this); + } + + std::vector<T> do_eval(const std::vector<T> & x, + const std::vector<T>& p) + { + T n01=std::abs(p[0]); + T beta1=p[1]; + T rc1=p[2]; + + T n02=std::abs(p[3]); + T beta2=p[4]; + T rc2=p[5]; + + + + std::vector<T> result(x.size()-1); + for(int i=1;i<x.size();++i) + { + T xi=(x[i]+x[i-1])/2; + T yi=0; + yi=n01*pow(1+xi*xi/rc1/rc1,-3./2.*beta1)+n02*pow(1+xi*xi/rc2/rc2,-3./2.*beta2); + result[i-1]=yi; + } + return result; + } + + bool do_meets_constraint(const std::vector<T>& p)const + { + if(p.size()!=6) + { + cerr<<p.size()<<endl; + cerr<<this->get_num_params()<<endl; + assert(0); + } + + T rc1=p.at(2); + T rc2=p.at(5); + if(rc2>rc1) + { + return true; + } + else + { + cerr<<rc2<<"\t"<<rc1<<endl; + cerr<<"***"<<endl; + return false; + } + } + }; +} + +#endif diff --git a/mass_profile/coolfunc_calc.sh b/mass_profile/coolfunc_calc.sh new file mode 100755 index 0000000..c4935b7 --- /dev/null +++ b/mass_profile/coolfunc_calc.sh @@ -0,0 +1,138 @@ +#!/bin/sh +# +# unalias -a +# +########################################################### +## Task: ## +## Calc `cooling function' data according to ## +## given `temperature profile' ## +## ## +## NOTE: ## +## given `tprofile': <radius> <temperature> ## +## calc `cooling function' by invoking `XSPEC' ## +## using model `wabs*apec' ## +## ## +## LIweitiaNux <liweitianux@gmail.com> ## +## August 17, 2012 ## +########################################################### + +## cmdline arguments {{{ +if [ $# -ne 5 ]; then + printf "usage:\n" + printf " `basename $0` <tprofile> <avg_abund> <nH> <redshift> <coolfunc_outfile>\n" + exit 1 +fi +base_path=`dirname $0` +TPROFILE=$1 +ABUND_VAL=$2 +N_H=$3 +REDSHIFT=$4 +NORM=`$base_path/calc_distance $REDSHIFT|grep norm|awk '{print $2}'` + +echo $NORM + + +COOLFUNC_DAT=$5 +COOLFUNC_DAT_RATIO=flux_cnt_ratio.txt + +if [ ! -r "${TPROFILE}" ]; then + printf "ERROR: given tprofile '${TPROFILE}' NOT accessiable\n" + exit 2 +fi +[ -e "${COOLFUNC_DAT}" ] && rm -f ${COOLFUNC_DAT} +[ -e "${COOLFUNC_DAT_RATIO}" ] && rm -f ${COOLFUNC_DAT_RATIO} +## arguments }}} + +## specify variable name outside while loop +## otherwise the inside vars invisible +XSPEC_CF_XCM="_coolfunc_calc.xcm" +[ -e "${XSPEC_CF_XCM}" ] && rm -f ${XSPEC_CF_XCM} + +## generate xspec script {{{ +cat >> ${XSPEC_CF_XCM} << _EOF_ +## XSPEC Tcl script +## calc cooling function data +## +## generated by: `basename $0` +## date: `date` + +set xs_return_results 1 +set xs_echo_script 0 +# set tcl_precision 12 +dummyrsp .01 100 4096 +## set basic data {{{ +set nh ${N_H} +set redshift ${REDSHIFT} +set abund_val ${ABUND_VAL} +set norm ${NORM} +## basic }}} + +## xspec related {{{ +# debug settings {{{ +chatter 0 +# debug }}} +query yes +abund grsa +dummyrsp 0.3 11.0 1024 +# load model 'wabs*apec' to calc cooling function +model wabs*apec & \${nh} & 1.0 & \${abund_val} & \${redshift} & \${norm} & /* +## xspec }}} + +## set input and output filename +set tpro_fn "${TPROFILE}" +set cf_fn "${COOLFUNC_DAT}" +set cff_fn "${COOLFUNC_DAT_RATIO}" +if { [ file exists \${cf_fn} ] } { + exec rm -fv \${cf_fn} +} + +if { [ file exists \${cff_fn} ] } { + exec rm -fv \${cff_fn} +} + +## open files +set tpro_fd [ open \${tpro_fn} r ] +set cf_fd [ open \${cf_fn} w ] +set cff_fd [ open \${cff_fn} w ] + +## read data from tprofile line by line +while { [ gets \${tpro_fd} tpro_line ] != -1 } { + # gets one line + scan \${tpro_line} "%f %f" radius temp_val + #puts "radius: \${radius}, temperature: \${temp_val}" + # set temperature value + newpar 2 \${temp_val} + # calc flux & tclout + flux 0.7 7.0 + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" holder holder holder cf_data + #puts "cf_data: \${cf_data}" + puts \${cf_fd} "\${radius} \${cf_data}" + flux 0.01 100.0 + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" cff_data holder holder holder + puts \${cff_fd} "\${radius} [expr \${cff_data}/\${cf_data}]" +} + +## close opened files +close \${tpro_fd} +close \${cf_fd} + +## exit +tclexit +_EOF_ + +## extract xcm }}} + +## invoke xspec to calc +printf "invoking XSPEC to calculate cooling function data ...\n" +# xspec - ${XSPEC_CF_XCM} +xspec - ${XSPEC_CF_XCM} > /dev/null + +## clean +# if [ -e "${XSPEC_CF_XCM}" ]; then +# rm -f ${XSPEC_CF_XCM} +# fi + +exit 0 + diff --git a/mass_profile/coolfunc_calc2.sh b/mass_profile/coolfunc_calc2.sh new file mode 100755 index 0000000..c469619 --- /dev/null +++ b/mass_profile/coolfunc_calc2.sh @@ -0,0 +1,173 @@ +#!/bin/sh +# +# unalias -a +# +########################################################### +## Task: ## +## Calc `cooling function' data according to ## +## given `temperature profile' ## +## ## +## NOTE: ## +## given `tprofile': <radius> <temperature> ## +## calc `cooling function' by invoking `XSPEC' ## +## using model `wabs*apec' ## +## ## +## LIweitiaNux <liweitianux@gmail.com> ## +## August 17, 2012 ## +########################################################### + +## cmdline arguments {{{ +if [ $# -eq 5 ]; then + : +elif [ $# -eq 6 ]; then + COOLFUNC_BOLO=$6 + [ -e "${COOLFUNC_BOLO}" ] && rm -f ${COOLFUNC_BOLO} +else + printf "usage:\n" + printf " `basename $0` <tprofile> <avg_abund> <nH> <redshift> <coolfunc_outfile> [coolfunc_bolo]\n" + exit 1 +fi +base_path=`dirname $0` +TPROFILE=$1 +ABUND_VAL=$2 +N_H=$3 +REDSHIFT=$4 +NORM=`$base_path/calc_distance $REDSHIFT | grep norm | awk '{ print $2 }'` +COOLFUNC_DAT=$5 +COOLFUNC_DAT_RATIO="flux_cnt_ratio.txt" + +if [ ! -r "${TPROFILE}" ]; then + printf "ERROR: given tprofile '${TPROFILE}' NOT accessiable\n" + exit 2 +fi +[ -e "${COOLFUNC_DAT}" ] && rm -f ${COOLFUNC_DAT} +[ -e "${COOLFUNC_DAT_RATIO}" ] && rm -f ${COOLFUNC_DAT_RATIO} +## arguments }}} + +## specify variable name outside while loop +## otherwise the inside vars invisible +XSPEC_CF_XCM="_coolfunc_calc.xcm" +[ -e "${XSPEC_CF_XCM}" ] && rm -f ${XSPEC_CF_XCM} + +## generate xspec script {{{ +cat >> ${XSPEC_CF_XCM} << _EOF_ +## XSPEC Tcl script +## calc cooling function data +## +## generated by: `basename $0` +## date: `date` + +set xs_return_results 1 +set xs_echo_script 0 +# set tcl_precision 12 +dummyrsp .01 100 4096 +## set basic data {{{ +set nh ${N_H} +set redshift ${REDSHIFT} +set abund_val ${ABUND_VAL} +set norm ${NORM} +## basic }}} + +## xspec related {{{ +# debug settings {{{ +chatter 0 +# debug }}} +query yes +abund grsa +dummyrsp 0.3 11.0 1024 +# load model 'wabs*apec' to calc cooling function +model wabs*apec & \${nh} & 1.0 & \${abund_val} & \${redshift} & \${norm} & /* +## xspec }}} + +## set input and output filename & open files +set tpro_fn "${TPROFILE}" +set cf_fn "${COOLFUNC_DAT}" +set cff_fn "${COOLFUNC_DAT_RATIO}" +if { [ file exists \${cf_fn} ] } { + exec rm -fv \${cf_fn} +} +if { [ file exists \${cff_fn} ] } { + exec rm -fv \${cff_fn} +} + +## open files +set tpro_fd [ open \${tpro_fn} r ] +set cf_fd [ open \${cf_fn} w ] +set cff_fd [ open \${cff_fn} w ] + +_EOF_ + +if [ ! -z "${COOLFUNC_BOLO}" ]; then + cat >> ${XSPEC_CF_XCM} << _EOF_ +# coolfunc bolometric +set cfbolo_fn "${COOLFUNC_BOLO}" +if { [ file exists \${cfbolo_fn} ] } { + exec rm -fv \${cfbolo_fn} +} +set cfbolo_fd [ open \${cfbolo_fn} w ] + +_EOF_ +fi + +cat >> ${XSPEC_CF_XCM} << _EOF_ +## read data from tprofile line by line +while { [ gets \${tpro_fd} tpro_line ] != -1 } { + # gets one line + scan \${tpro_line} "%f %f" radius temp_val + #puts "radius: \${radius}, temperature: \${temp_val}" + # set temperature value + newpar 2 \${temp_val} + # calc flux & tclout + flux 0.7 7.0 + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" holder holder holder cf_data + #puts "cf_data: \${cf_data}" + puts \${cf_fd} "\${radius} \${cf_data}" + flux 0.01 100.0 + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" cff_data holder holder holder + puts \${cff_fd} "\${radius} [expr \${cff_data}/\${cf_data}]" +_EOF_ +if [ ! -z "${COOLFUNC_BOLO}" ]; then + cat >> ${XSPEC_CF_XCM} << _EOF_ + # coolfunc bolometric + set cfbolo_data \$cff_data + #puts "cfbolo_data: \${cfbolo_data}" + puts \${cfbolo_fd} "\${radius} \${cfbolo_data}" +_EOF_ +fi +cat >> ${XSPEC_CF_XCM} << _EOF_ +} + +## close opened files +close \${tpro_fd} +close \${cf_fd} +_EOF_ + +if [ ! -z "${COOLFUNC_BOLO}" ]; then + cat >> ${XSPEC_CF_XCM} << _EOF_ +# coolfunc bolometric +close \${cfbolo_fd} + +_EOF_ +fi + +cat >> ${XSPEC_CF_XCM} << _EOF_ +## exit +tclexit +_EOF_ + +## extract xcm }}} + +## invoke xspec to calc +printf "invoking XSPEC to calculate cooling function data ...\n" +# xspec - ${XSPEC_CF_XCM} +xspec - ${XSPEC_CF_XCM} > /dev/null + +## clean +# if [ -e "${XSPEC_CF_XCM}" ]; then +# rm -f ${XSPEC_CF_XCM} +# fi + +exit 0 + diff --git a/mass_profile/coolfunc_calc_0.1-2.4.sh b/mass_profile/coolfunc_calc_0.1-2.4.sh new file mode 100755 index 0000000..599e429 --- /dev/null +++ b/mass_profile/coolfunc_calc_0.1-2.4.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# unalias -a +# +########################################################### +## Task: ## +## Calc `cooling function' data according to ## +## given `temperature profile' ## +## ## +## NOTE: ## +## given `tprofile': <radius> <temperature> ## +## calc `cooling function' by invoking `XSPEC' ## +## using model `wabs*apec' ## +## ## +## LIweitiaNux <liweitianux@gmail.com> ## +## August 17, 2012 ## +########################################################### + +## cmdline arguments {{{ +if [ $# -ne 5 ]; then + printf "usage:\n" + printf " `basename $0` <tprofile> <avg_abund> <nH> <redshift> <coolfunc_outfile>\n" + exit 1 +fi +base_path=`dirname $0` +TPROFILE=$1 +ABUND_VAL=$2 +N_H=$3 +REDSHIFT=$4 +NORM=`$base_path/calc_distance $REDSHIFT|grep norm|awk '{print $2}'` + +echo $NORM + + +COOLFUNC_DAT=$5 +#COOLFUNC_DAT_RATIO=flux_cnt_ratio.txt + +if [ ! -r "${TPROFILE}" ]; then + printf "ERROR: given tprofile '${TPROFILE}' NOT accessiable\n" + exit 2 +fi +[ -e "${COOLFUNC_DAT}" ] && rm -f ${COOLFUNC_DAT} +#[ -e "${COOLFUNC_DAT_RATIO}" ] && rm -f ${COOLFUNC_DAT_RATIO} +## arguments }}} + +## specify variable name outside while loop +## otherwise the inside vars invisible +XSPEC_CF_XCM="_coolfunc_calc.xcm" +[ -e "${XSPEC_CF_XCM}" ] && rm -f ${XSPEC_CF_XCM} + +## generate xspec script {{{ +cat >> ${XSPEC_CF_XCM} << _EOF_ +## XSPEC Tcl script +## calc cooling function data +## +## generated by: `basename $0` +## date: `date` + +set xs_return_results 1 +set xs_echo_script 0 +# set tcl_precision 12 +dummyrsp .01 100 4096 +## set basic data {{{ +set nh ${N_H} +set redshift ${REDSHIFT} +set abund_val ${ABUND_VAL} +set norm ${NORM} +## basic }}} + +## xspec related {{{ +# debug settings {{{ +chatter 0 +# debug }}} +query yes +abund grsa +dummyrsp 0.3 11.0 1024 +# load model 'wabs*apec' to calc cooling function +#model wabs*apec & \${nh} & 1.0 & \${abund_val} & \${redshift} & \${norm} & +model wabs*apec & 0 & 1.0 & \${abund_val} & \${redshift} & \${norm} & +## xspec }}} + +## set input and output filename +set tpro_fn "${TPROFILE}" +set cf_fn "${COOLFUNC_DAT}" +##set cff_fn "${COOLFUNC_DAT_RATIO}" +if { [ file exists \${cf_fn} ] } { + exec rm -fv \${cf_fn} +} + +#if { [ file exists \${cff_fn} ] } { +# exec rm -fv \${cff_fn} +#} + +## open files +set tpro_fd [ open \${tpro_fn} r ] +set cf_fd [ open \${cf_fn} w ] +#set cff_fd [ open \${cff_fn} w ] + +## read data from tprofile line by line +while { [ gets \${tpro_fd} tpro_line ] != -1 } { + # gets one line + scan \${tpro_line} "%f %f" radius temp_val + #puts "radius: \${radius}, temperature: \${temp_val}" + # set temperature value + newpar 2 \${temp_val} + # calc flux & tclout + flux 0.1 2.4 + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" cf_data holder holder holder + #puts "cf_data: \${cf_data}" + puts \${cf_fd} "\${radius} \${cf_data}" +# flux 0.01 100.0 +# tclout flux 1 +# scan \${xspec_tclout} "%f %f %f %f" cff_data holder holder holder +# puts \${cff_fd} "\${radius} [expr \${cff_data}/\${cf_data}]" +} + +## close opened files +close \${tpro_fd} +close \${cf_fd} + +## exit +tclexit +_EOF_ + +## extract xcm }}} + +## invoke xspec to calc +printf "invoking XSPEC to calculate cooling function data ...\n" +# xspec - ${XSPEC_CF_XCM} +xspec - ${XSPEC_CF_XCM} > /dev/null + +## clean +# if [ -e "${XSPEC_CF_XCM}" ]; then +# rm -f ${XSPEC_CF_XCM} +# fi + +exit 0 + diff --git a/mass_profile/coolfunc_calc_0.7-7.sh b/mass_profile/coolfunc_calc_0.7-7.sh new file mode 100755 index 0000000..46902a2 --- /dev/null +++ b/mass_profile/coolfunc_calc_0.7-7.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# unalias -a +# +########################################################### +## Task: ## +## Calc `cooling function' data according to ## +## given `temperature profile' ## +## ## +## NOTE: ## +## given `tprofile': <radius> <temperature> ## +## calc `cooling function' by invoking `XSPEC' ## +## using model `wabs*apec' ## +## ## +## LIweitiaNux <liweitianux@gmail.com> ## +## August 17, 2012 ## +########################################################### + +## cmdline arguments {{{ +if [ $# -ne 5 ]; then + printf "usage:\n" + printf " `basename $0` <tprofile> <avg_abund> <nH> <redshift> <coolfunc_outfile>\n" + exit 1 +fi +base_path=`dirname $0` +TPROFILE=$1 +ABUND_VAL=$2 +N_H=$3 +REDSHIFT=$4 +NORM=`$base_path/calc_distance $REDSHIFT|grep norm|awk '{print $2}'` + +echo $NORM + + +COOLFUNC_DAT=$5 +#COOLFUNC_DAT_RATIO=flux_cnt_ratio.txt + +if [ ! -r "${TPROFILE}" ]; then + printf "ERROR: given tprofile '${TPROFILE}' NOT accessiable\n" + exit 2 +fi +[ -e "${COOLFUNC_DAT}" ] && rm -f ${COOLFUNC_DAT} +#[ -e "${COOLFUNC_DAT_RATIO}" ] && rm -f ${COOLFUNC_DAT_RATIO} +## arguments }}} + +## specify variable name outside while loop +## otherwise the inside vars invisible +XSPEC_CF_XCM="_coolfunc_calc.xcm" +[ -e "${XSPEC_CF_XCM}" ] && rm -f ${XSPEC_CF_XCM} + +## generate xspec script {{{ +cat >> ${XSPEC_CF_XCM} << _EOF_ +## XSPEC Tcl script +## calc cooling function data +## +## generated by: `basename $0` +## date: `date` + +set xs_return_results 1 +set xs_echo_script 0 +# set tcl_precision 12 +dummyrsp .01 100 4096 +## set basic data {{{ +set nh ${N_H} +set redshift ${REDSHIFT} +set abund_val ${ABUND_VAL} +set norm ${NORM} +## basic }}} + +## xspec related {{{ +# debug settings {{{ +chatter 0 +# debug }}} +query yes +abund grsa +dummyrsp 0.3 11.0 1024 +# load model 'wabs*apec' to calc cooling function +#model wabs*apec & \${nh} & 1.0 & \${abund_val} & \${redshift} & \${norm} & +model wabs*apec & 0 & 1.0 & \${abund_val} & \${redshift} & \${norm} & +## xspec }}} + +## set input and output filename +set tpro_fn "${TPROFILE}" +set cf_fn "${COOLFUNC_DAT}" +##set cff_fn "${COOLFUNC_DAT_RATIO}" +if { [ file exists \${cf_fn} ] } { + exec rm -fv \${cf_fn} +} + +#if { [ file exists \${cff_fn} ] } { +# exec rm -fv \${cff_fn} +#} + +## open files +set tpro_fd [ open \${tpro_fn} r ] +set cf_fd [ open \${cf_fn} w ] +#set cff_fd [ open \${cff_fn} w ] + +## read data from tprofile line by line +while { [ gets \${tpro_fd} tpro_line ] != -1 } { + # gets one line + scan \${tpro_line} "%f %f" radius temp_val + #puts "radius: \${radius}, temperature: \${temp_val}" + # set temperature value + newpar 2 \${temp_val} + # calc flux & tclout + flux 0.7 7.0 + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" cf_data holder holder holder + #puts "cf_data: \${cf_data}" + puts \${cf_fd} "\${radius} \${cf_data}" +# flux 0.01 100.0 +# tclout flux 1 +# scan \${xspec_tclout} "%f %f %f %f" cff_data holder holder holder +# puts \${cff_fd} "\${radius} [expr \${cff_data}/\${cf_data}]" +} + +## close opened files +close \${tpro_fd} +close \${cf_fd} + +## exit +tclexit +_EOF_ + +## extract xcm }}} + +## invoke xspec to calc +printf "invoking XSPEC to calculate cooling function data ...\n" +# xspec - ${XSPEC_CF_XCM} +xspec - ${XSPEC_CF_XCM} > /dev/null + +## clean +# if [ -e "${XSPEC_CF_XCM}" ]; then +# rm -f ${XSPEC_CF_XCM} +# fi + +exit 0 + diff --git a/mass_profile/coolfunc_calc_bolo.sh b/mass_profile/coolfunc_calc_bolo.sh new file mode 100755 index 0000000..5c4ef5d --- /dev/null +++ b/mass_profile/coolfunc_calc_bolo.sh @@ -0,0 +1,139 @@ +#!/bin/sh +# +# unalias -a +# +########################################################### +## Task: ## +## Calc `cooling function' data according to ## +## given `temperature profile' ## +## ## +## NOTE: ## +## given `tprofile': <radius> <temperature> ## +## calc `cooling function' by invoking `XSPEC' ## +## using model `wabs*apec' ## +## ## +## LIweitiaNux <liweitianux@gmail.com> ## +## August 17, 2012 ## +########################################################### + +## cmdline arguments {{{ +if [ $# -ne 5 ]; then + printf "usage:\n" + printf " `basename $0` <tprofile> <avg_abund> <nH> <redshift> <coolfunc_outfile>\n" + exit 1 +fi +base_path=`dirname $0` +TPROFILE=$1 +ABUND_VAL=$2 +N_H=$3 +REDSHIFT=$4 +NORM=`$base_path/calc_distance $REDSHIFT|grep norm|awk '{print $2}'` + +echo $NORM + + +COOLFUNC_DAT=$5 +#COOLFUNC_DAT_RATIO=flux_cnt_ratio.txt + +if [ ! -r "${TPROFILE}" ]; then + printf "ERROR: given tprofile '${TPROFILE}' NOT accessiable\n" + exit 2 +fi +[ -e "${COOLFUNC_DAT}" ] && rm -f ${COOLFUNC_DAT} +#[ -e "${COOLFUNC_DAT_RATIO}" ] && rm -f ${COOLFUNC_DAT_RATIO} +## arguments }}} + +## specify variable name outside while loop +## otherwise the inside vars invisible +XSPEC_CF_XCM="_coolfunc_calc.xcm" +[ -e "${XSPEC_CF_XCM}" ] && rm -f ${XSPEC_CF_XCM} + +## generate xspec script {{{ +cat >> ${XSPEC_CF_XCM} << _EOF_ +## XSPEC Tcl script +## calc cooling function data +## +## generated by: `basename $0` +## date: `date` + +set xs_return_results 1 +set xs_echo_script 0 +# set tcl_precision 12 +dummyrsp .01 100 4096 +## set basic data {{{ +set nh ${N_H} +set redshift ${REDSHIFT} +set abund_val ${ABUND_VAL} +set norm ${NORM} +## basic }}} + +## xspec related {{{ +# debug settings {{{ +chatter 0 +# debug }}} +query yes +abund grsa +dummyrsp 0.3 11.0 1024 +# load model 'wabs*apec' to calc cooling function +#model wabs*apec & \${nh} & 1.0 & \${abund_val} & \${redshift} & \${norm} & +model wabs*apec & 0 & 1.0 & \${abund_val} & \${redshift} & \${norm} & +## xspec }}} + +## set input and output filename +set tpro_fn "${TPROFILE}" +set cf_fn "${COOLFUNC_DAT}" +##set cff_fn "${COOLFUNC_DAT_RATIO}" +if { [ file exists \${cf_fn} ] } { + exec rm -fv \${cf_fn} +} + +#if { [ file exists \${cff_fn} ] } { +# exec rm -fv \${cff_fn} +#} + +## open files +set tpro_fd [ open \${tpro_fn} r ] +set cf_fd [ open \${cf_fn} w ] +#set cff_fd [ open \${cff_fn} w ] + +## read data from tprofile line by line +while { [ gets \${tpro_fd} tpro_line ] != -1 } { + # gets one line + scan \${tpro_line} "%f %f" radius temp_val + #puts "radius: \${radius}, temperature: \${temp_val}" + # set temperature value + newpar 2 \${temp_val} + # calc flux & tclout + flux 0.01 100.0 + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" cf_data holder holder holder + #puts "cf_data: \${cf_data}" + puts \${cf_fd} "\${radius} \${cf_data}" +# flux 0.01 100.0 +# tclout flux 1 +# scan \${xspec_tclout} "%f %f %f %f" cff_data holder holder holder +# puts \${cff_fd} "\${radius} [expr \${cff_data}/\${cf_data}]" +} + +## close opened files +close \${tpro_fd} +close \${cf_fd} + +## exit +tclexit +_EOF_ + +## extract xcm }}} + +## invoke xspec to calc +printf "invoking XSPEC to calculate cooling function data ...\n" +# xspec - ${XSPEC_CF_XCM} +xspec - ${XSPEC_CF_XCM} > /dev/null + +## clean +# if [ -e "${XSPEC_CF_XCM}" ]; then +# rm -f ${XSPEC_CF_XCM} +# fi + +exit 0 + diff --git a/mass_profile/coolfunc_calc_bolo_cnt.sh b/mass_profile/coolfunc_calc_bolo_cnt.sh new file mode 100755 index 0000000..7327ae5 --- /dev/null +++ b/mass_profile/coolfunc_calc_bolo_cnt.sh @@ -0,0 +1,138 @@ +#!/bin/sh +# +# unalias -a +# +########################################################### +## Task: ## +## Calc `cooling function' data according to ## +## given `temperature profile' ## +## ## +## NOTE: ## +## given `tprofile': <radius> <temperature> ## +## calc `cooling function' by invoking `XSPEC' ## +## using model `wabs*apec' ## +## ## +## LIweitiaNux <liweitianux@gmail.com> ## +## August 17, 2012 ## +########################################################### + +## cmdline arguments {{{ +if [ $# -ne 5 ]; then + printf "usage:\n" + printf " `basename $0` <tprofile> <avg_abund> <nH> <redshift> <coolfunc_outfile>\n" + exit 1 +fi +base_path=`dirname $0` +TPROFILE=$1 +ABUND_VAL=$2 +N_H=$3 +REDSHIFT=$4 +NORM=`$base_path/calc_distance $REDSHIFT|grep norm|awk '{print $2}'` + +echo $NORM + + +COOLFUNC_DAT=$5 +#COOLFUNC_DAT_RATIO=flux_cnt_ratio.txt + +if [ ! -r "${TPROFILE}" ]; then + printf "ERROR: given tprofile '${TPROFILE}' NOT accessiable\n" + exit 2 +fi +[ -e "${COOLFUNC_DAT}" ] && rm -f ${COOLFUNC_DAT} +#[ -e "${COOLFUNC_DAT_RATIO}" ] && rm -f ${COOLFUNC_DAT_RATIO} +## arguments }}} + +## specify variable name outside while loop +## otherwise the inside vars invisible +XSPEC_CF_XCM="_coolfunc_calc.xcm" +[ -e "${XSPEC_CF_XCM}" ] && rm -f ${XSPEC_CF_XCM} + +## generate xspec script {{{ +cat >> ${XSPEC_CF_XCM} << _EOF_ +## XSPEC Tcl script +## calc cooling function data +## +## generated by: `basename $0` +## date: `date` + +set xs_return_results 1 +set xs_echo_script 0 +# set tcl_precision 12 +dummyrsp .01 100 4096 +## set basic data {{{ +set nh ${N_H} +set redshift ${REDSHIFT} +set abund_val ${ABUND_VAL} +set norm ${NORM} +## basic }}} + +## xspec related {{{ +# debug settings {{{ +chatter 0 +# debug }}} +query yes +abund grsa +dummyrsp 0.3 11.0 1024 +# load model 'wabs*apec' to calc cooling function +model wabs*apec & \${nh} & 1.0 & \${abund_val} & \${redshift} & \${norm} & /* +## xspec }}} + +## set input and output filename +set tpro_fn "${TPROFILE}" +set cf_fn "${COOLFUNC_DAT}" +#set cff_fn "${COOLFUNC_DAT_RATIO}" +if { [ file exists \${cf_fn} ] } { + exec rm -fv \${cf_fn} +} + +#if { [ file exists \${cff_fn} ] } { +# exec rm -fv \${cff_fn} +#} + +## open files +set tpro_fd [ open \${tpro_fn} r ] +set cf_fd [ open \${cf_fn} w ] +#set cff_fd [ open \${cff_fn} w ] + +## read data from tprofile line by line +while { [ gets \${tpro_fd} tpro_line ] != -1 } { + # gets one line + scan \${tpro_line} "%f %f" radius temp_val + #puts "radius: \${radius}, temperature: \${temp_val}" + # set temperature value + newpar 2 \${temp_val} + # calc flux & tclout + flux 0.01 100.0 + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" holder holder holder cf_data + #puts "cf_data: \${cf_data}" + puts \${cf_fd} "\${radius} \${cf_data}" +# flux 0.01 100.0 +# tclout flux 1 +# scan \${xspec_tclout} "%f %f %f %f" cff_data holder holder holder +# puts \${cff_fd} "\${radius} [expr \${cff_data}/\${cf_data}]" +} + +## close opened files +close \${tpro_fd} +close \${cf_fd} + +## exit +tclexit +_EOF_ + +## extract xcm }}} + +## invoke xspec to calc +printf "invoking XSPEC to calculate cooling function data ...\n" +# xspec - ${XSPEC_CF_XCM} +xspec - ${XSPEC_CF_XCM} > /dev/null + +## clean +# if [ -e "${XSPEC_CF_XCM}" ]; then +# rm -f ${XSPEC_CF_XCM} +# fi + +exit 0 + diff --git a/mass_profile/coolfunc_calc_erg.sh b/mass_profile/coolfunc_calc_erg.sh new file mode 100755 index 0000000..d884302 --- /dev/null +++ b/mass_profile/coolfunc_calc_erg.sh @@ -0,0 +1,145 @@ +#!/bin/sh +# +# unalias -a +# +########################################################### +## Task: ## +## Calc `cooling function' data according to ## +## given `temperature profile' ## +## ## +## NOTE: ## +## given `tprofile': <radius> <temperature> ## +## calc `cooling function' by invoking `XSPEC' ## +## using model `wabs*apec' ## +## ## +## LIweitiaNux <liweitianux@gmail.com> ## +## August 17, 2012 ## +########################################################### + +## cmdline arguments {{{ +if [ $# -ne 6 ]; then + printf "usage:\n" + printf " `basename $0` <tprofile> <avg_abund> <nH> <redshift> <coolfunc_prefix> <band_list>\n" + exit 1 +fi +base_path=`dirname $0` +TPROFILE=$1 +ABUND_VAL=$2 +N_H=$3 +REDSHIFT=$4 +BLIST=$6 +NORM=`$base_path/calc_distance $REDSHIFT|grep norm|awk '{print $2}'` + +echo $NORM + + +COOLFUNC_PREFIX=$5 +#COOLFUNC_DAT_RATIO=flux_cnt_ratio.txt + +if [ ! -r "${TPROFILE}" ]; then + printf "ERROR: given tprofile '${TPROFILE}' NOT accessiable\n" + exit 2 +fi +#[ -e "${COOLFUNC_DAT}" ] && rm -f ${COOLFUNC_DAT} +#[ -e "${COOLFUNC_DAT_RATIO}" ] && rm -f ${COOLFUNC_DAT_RATIO} +## arguments }}} + +## specify variable name outside while loop +## otherwise the inside vars invisible +XSPEC_CF_XCM="_coolfunc_calc.xcm" +[ -e "${XSPEC_CF_XCM}" ] && rm -f ${XSPEC_CF_XCM} + +## generate xspec script {{{ +cat >> ${XSPEC_CF_XCM} << _EOF_ +## XSPEC Tcl script +## calc cooling function data +## +## generated by: `basename $0` +## date: `date` + +set xs_return_results 1 +set xs_echo_script 0 +# set tcl_precision 12 +dummyrsp .01 100 4096 +## set basic data {{{ +set nh ${N_H} +set redshift ${REDSHIFT} +set abund_val ${ABUND_VAL} +set norm ${NORM} +## basic }}} + +## xspec related {{{ +# debug settings {{{ +chatter 0 +# debug }}} +query yes +abund grsa +dummyrsp 0.3 11.0 1024 +# load model 'wabs*apec' to calc cooling function +#model wabs*apec & \${nh} & 1.0 & \${abund_val} & \${redshift} & \${norm} & +model wabs*apec & 0 & 1.0 & \${abund_val} & \${redshift} & \${norm} & +## xspec }}} + +## set input and output filename +set tpro_fn "${TPROFILE}" +set blist_fn "${BLIST}" +set cf_prefix "${COOLFUNC_PREFIX}" +##set cff_fn "${COOLFUNC_DAT_RATIO}" + +#if { [ file exists \${cff_fn} ] } { +# exec rm -fv \${cff_fn} +#} + +## open files +set blist_fd [ open \${blist_fn} r ] +#set cff_fd [ open \${cff_fn} w ] + +while { [ gets \${blist_fd} blist_line ] != -1 } { +if { "\${blist_line}" == "bolo" } { set e1 .01; set e2 100.0; set name_suffix bolo } { set e1 [ lindex \${blist_line} 0 ]; set e2 [ lindex \${blist_line} 1]; set name_suffix "\${e1}-\${e2}" } +## read data from tprofile line by line +set cf_fn "\${cf_prefix}\${name_suffix}.dat" +if { [ file exists \${cf_fn} ] } { + exec rm -fv \${cf_fn} +} +set cf_fd [ open \${cf_fn} w ] +set tpro_fd [ open \${tpro_fn} r ] +while { [ gets \${tpro_fd} tpro_line ] != -1 } { + # gets one line + scan \${tpro_line} "%f %f" radius temp_val + #puts "radius: \${radius}, temperature: \${temp_val}" + # set temperature value + newpar 2 \${temp_val} + # calc flux & tclout + flux \${e1} \${e2} + tclout flux 1 + scan \${xspec_tclout} "%f %f %f %f" cf_data holder holder holder + #puts "cf_data: \${cf_data}" + puts \${cf_fd} "\${radius} \${cf_data}" +# flux 0.01 100.0 +# tclout flux 1 +# scan \${xspec_tclout} "%f %f %f %f" cff_data holder holder holder +# puts \${cff_fd} "\${radius} [expr \${cff_data}/\${cf_data}]" +} +close \${tpro_fd} +close \${cf_fd} +} +## close opened files + +## exit +tclexit +_EOF_ + +## extract xcm }}} + +## invoke xspec to calc +printf "invoking XSPEC to calculate cooling function data ...\n" +# xspec - ${XSPEC_CF_XCM} +xspec - ${XSPEC_CF_XCM} > /dev/null + +## clean +# if [ -e "${XSPEC_CF_XCM}" ]; then +# rm -f ${XSPEC_CF_XCM} +# fi + +exit 0 + diff --git a/mass_profile/cooling_time.cpp b/mass_profile/cooling_time.cpp new file mode 100644 index 0000000..12b869e --- /dev/null +++ b/mass_profile/cooling_time.cpp @@ -0,0 +1,62 @@ +#include <iostream> +#include <fstream> +#include <cmath> +#include "spline.h" + + +using namespace std; +const double kB=1.60217646E-9;//erg/keV +const double pi=atan(1)*4; +int main(int argc,char* argv[]) +{ + if(argc!=6) + { + cerr<<"Usage:"<<argv[0]<<" <rho_fit.dat> <T file> <bolo cooling function file> <dl> <cm_per_pixel>"<<endl; + return -1; + } + double cm_per_pixel=atof(argv[5]); + double dl=atof(argv[4]); + spline<double> cf,t_profile; + ifstream ifs(argv[2]); + for(;;) + { + double x,T; + ifs>>x>>T; + if(!ifs.good()) + { + break; + } + x=x*cm_per_pixel/3.08567758E21;//convert to kpc + t_profile.push_point(x,T); + } + t_profile.gen_spline(0,0); + ifs.close(); + ifs.open(argv[3]); + for(;;) + { + double x,c; + ifs>>x>>c; + if(!ifs.good()) + { + break; + } + x=x*cm_per_pixel/3.08567758E21;//convert to kpc + cf.push_point(x,c); + } + cf.gen_spline(0,0); + + ifs.close(); + ifs.open(argv[1]); + for(;;) + { + double r,ne; + ifs>>r>>ne; + if(!ifs.good()) + { + break; + } + double nh=ne*1.2; + double tcool=3./2.*(ne+nh)*kB*t_profile.get_value(r)/ne/nh/(cf.get_value(r)*4*pi*dl*dl);//s; + cout<<r<<"\t"<<tcool/(24*3600*365*1E9)<<endl; + } +} diff --git a/mass_profile/cooling_time2.sh b/mass_profile/cooling_time2.sh new file mode 100755 index 0000000..cb0a55e --- /dev/null +++ b/mass_profile/cooling_time2.sh @@ -0,0 +1,592 @@ +#!/bin/sh +# +unalias -a +export LC_COLLATE=C +########################################################### +## based on `ciao_r500avgt' ## +## for calculating the `cooling time ' ## +## within (0.-0.048 r500) region ## +## ## +## Junhua Gu ## +## August 22, 2012 ## +## ## +## LIweitiaNux ## +## 2013/04/28 ## +########################################################### + +########################################################### +## ChangeLogs +########################################################### + +## comology calculator {{{ +## XXX: MODIFY THIS TO YOUR OWN CASE +## and make sure this `calc' is executable +## NOTES: use `$HOME' instead of `~' in path +BASE_PATH=`dirname $0` +# COSCALC="`which cosmo_calc calc_distance | head -n 1`" +COSCALC="${BASE_PATH}/calc_distance" +if [ -z "${COSCALC}" ] || [ ! -x ${COSCALC} ]; then + printf "ERROR: \`COSCALC: ${COSCALC}' neither specified nor executable\n" + exit 255 +fi +## }}} + +## about, used in `usage' {{{ +VERSION="v1.1" +UPDATE="2012-08-26" +## about }}} + +## error code {{{ +ERR_USG=1 +ERR_DIR=11 +ERR_EVT=12 +ERR_BKG=13 +ERR_REG=14 +ERR_ASOL=21 +ERR_BPIX=22 +ERR_PBK=23 +ERR_MSK=24 +ERR_BKGTY=31 +ERR_SPEC=32 +ERR_ARF=51 +ERR_RMF=52 +ERR_UNI=61 +## error code }}} + +## usage, help {{{ +case "$1" in + -[hH]*|--[hH]*) + printf "usage:\n" + printf " `basename $0` evt=<evt2_clean> r500=<r500_kpc> regin=<input_reg> regout=<output_reg> bkgd=<blank_evt | lbkg_reg | bkg_spec> nh=<nH> z=<redshift> arf=<warf_file> rmf=<wrmf_file> [ grpcmd=<grppha_cmd> log=<log_file> ]\n" + printf "\nversion:\n" + printf "${VERSION}, ${UPDATE}\n" + exit ${ERR_USG} + ;; +esac +## usage, help }}} + +## default parameters {{{ +# default `event file' which used to match `blanksky' files +#DFT_EVT="_NOT_EXIST_" +DFT_EVT="`ls evt2*_clean.fits 2> /dev/null`" +# default `bkgd', use `bkgcorr_blanksky*' corrected bkg spectrum +DFT_BKGD="`ls bkgcorr_blanksky_*.pi 2> /dev/null`" +# default basedir +DFT_BASEDIR="../.." +# default info_json pattern +DFT_JSON_PAT="*_INFO.json" +# default `radial region file' +#DFT_REG_IN="_NOT_EXIST_" +DFT_REG_IN="rspec.reg" +# default output region file (0.1-0.5 r500 region) +DFT_REG_OUT="cooling.reg" +# default ARF/RMF, the one of the outmost region +DFT_ARF="`ls r1_*.warf 2> /dev/null`" +DFT_RMF="`ls r1_*.wrmf 2> /dev/null`" + +# default `group command' for `grppha' +#DFT_GRP_CMD="group 1 128 2 129 256 4 257 512 8 513 1024 16" +DFT_GRP_CMD="group min 20" +# default `log file' +DFT_LOGFILE="cooling_`date '+%Y%m%d'`.log" + +INNER=0.0 +OUTER=0.048 +CT_RES="cooling_results.txt" +# default output xspec scripts +XSPEC_SCRIPT="xspec_cooling.xcm" +# deproj xspec script, generated by `deproj_spectra' +# from which get `nh' and `redshift' +XSPEC_DEPROJ="xspec_deproj.xcm" +## default parameters }}} + +## functions {{{ +# process commandline arguments +# cmdline arg format: `KEY=VALUE' +getopt_keyval() { + until [ -z "$1" ] + do + key=${1%%=*} # extract key + val=${1#*=} # extract value + keyval="${key}=\"${val}\"" + echo "## getopt: eval '${keyval}'" + eval ${keyval} + shift # shift, process next one + done +} + +## background renormalization (BACKSCAL) {{{ +# renorm background according to particle background +# energy range: 9.5-12.0 keV (channel: 651-822) +CH_LOW=651 +CH_HI=822 +pb_flux() { + punlearn dmstat + COUNTS=`dmstat "$1[channel=${CH_LOW}:${CH_HI}][cols COUNTS]" | grep -i 'sum:' | awk '{ print $2 }'` + punlearn dmkeypar + EXPTIME=`dmkeypar $1 EXPOSURE echo=yes` + BACK=`dmkeypar $1 BACKSCAL echo=yes` + # fix `scientific notation' bug for `bc' + EXPTIME_B=`echo ${EXPTIME} | sed 's/[eE]/\*10\^/' | sed 's/+//'` + BACK_B=`echo "( ${BACK} )" | sed 's/[eE]/\*10\^/' | sed 's/+//'` + PB_FLUX=`echo "scale = 16; ${COUNTS} / ${EXPTIME_B} / ${BACK_B}" | bc -l` + echo ${PB_FLUX} +} + +bkg_renorm() { + # $1: src spectrum, $2: back spectrum + PBFLUX_SRC=`pb_flux $1` + PBFLUX_BKG=`pb_flux $2` + BACK_OLD=`dmkeypar $2 BACKSCAL echo=yes` + BACK_OLD_B=`echo "( ${BACK_OLD} )" | sed 's/[eE]/\*10\^/' | sed 's/+//'` + BACK_NEW=`echo "scale = 16; ${BACK_OLD_B} * ${PBFLUX_BKG} / ${PBFLUX_SRC}" | bc -l` + printf "\`$2': BACKSCAL:\n" + printf " ${BACK_OLD} --> ${BACK_NEW}\n" + punlearn dmhedit + dmhedit infile=$2 filelist=none operation=add \ + key=BACKSCAL value=${BACK_NEW} comment="old value: ${BACK_OLD}" +} +## bkg renorm }}} +## functions end }}} + +## parameters {{{ +# process cmdline args using `getopt_keyval' +getopt_keyval "$@" + +## check log parameters {{{ +if [ ! -z "${log}" ]; then + LOGFILE="${log}" +else + LOGFILE=${DFT_LOGFILE} +fi +printf "## use logfile: \`${LOGFILE}'\n" +[ -e "${LOGFILE}" ] && mv -fv ${LOGFILE} ${LOGFILE}_bak +TOLOG="tee -a ${LOGFILE}" +echo "process script: `basename $0`" >> ${LOGFILE} +echo "process date: `date`" >> ${LOGFILE} +## log }}} + +# check given parameters +# process `nh' and `redshift' {{{ +if [ ! -r "${XSPEC_DEPROJ}" ]; then + printf "## the script \`${XSPEC_DEPROJ}' generated by \`deproj_spectra' NOT found\n" | ${TOLOG} + printf "## please supply the value of \`nh' and \`redshift' manully\n" | ${TOLOG} + read -p "> value of nh: " N_H + read -p "> value of redshift: " REDSHIFT +else + # get `nh' and `redshift' from xspec script + LN=`grep -n 'projct\*wabs\*apec' ${XSPEC_DEPROJ} | tail -n 1 | cut -d':' -f1` + # calc the line number of which contains `nh' + LN_NH=`expr ${LN} + 4` + NH_XCM=`head -n ${LN_NH} ${XSPEC_DEPROJ} | tail -n 1 | awk '{ print $1 }'` + # calc the line number of `redshift' + LN_RS=`expr ${LN} + 7` + RS_XCM=`head -n ${LN_RS} ${XSPEC_DEPROJ} | tail -n 1 | awk '{ print $1 }'` + printf "## get value of nh: \`${NH_XCM}' (from \`${XSPEC_DEPROJ}')\n" | ${TOLOG} + printf "## get value of redshift: \`${RS_XCM}' (from \`${XSPEC_DEPROJ}')\n" | ${TOLOG} + + ## if `nh' and `redshift' supplied in cmdline, then use them + if [ ! -z "${nh}" ]; then + N_H=${nh} + else + N_H=${NH_XCM} + fi + # redshift + if [ ! -z "${z}" ]; then + REDSHIFT=${z} + else + REDSHIFT=${RS_XCM} + fi +fi +printf "## use nH: ${N_H}\n" | ${TOLOG} +printf "## use redshift: ${REDSHIFT}\n" | ${TOLOG} +# nh & redshift }}} + +# check basedir & json file +if [ -d "${basedir}" ]; then + BASEDIR=${basedir} +else + BASEDIR=${DFT_BASEDIR} +fi +if [ ! -z "${json}" ] && [ -r "${BASEDIR}/${json}" ]; then + JSON_FILE="${BASEDIR}/${json}" +elif [ `ls ${BASEDIR}/${DFT_JSON_PAT} 2> /dev/null | wc -l` -eq 1 ]; then + JSON_FILE=`ls ${BASEDIR}/${DFT_JSON_PAT}` +else + read -p "> JSON_file: " JSON_FILE + if [ ! -r "${JSON_FILE}" ]; then + printf "ERROR: cannot access given \`${JSON_FILE}'\n" + exit ${ERR_JSON} + fi +fi +printf "## use json_file: \`${JSON_FILE}'\n" | ${TOLOG} + +# process `r500' {{{ +R500_RAW=`grep '"R500.*kpc' ${JSON_FILE} | sed 's/.*"R500.*":\ //' | sed 's/\ *,$//'` +if [ ! -z "${r500}" ]; then + R500_RAW=${r500} +fi +if [ -z "${R500_RAW}" ]; then + printf "## input R500 followed with unit, e.g.: 800kpc, 400pix\n" + read -p "> value of \`R500' (in pixel/kpc): " R500_RAW +fi +R500_VAL=`echo "${R500_RAW}" | tr -d 'a-zA-Z, '` +R500_UNI=`echo "${R500_RAW}" | tr -d '0-9, '` +printf "## get \`R500': ${R500_VAL} in unit \`${R500_UNI}'\n" | ${TOLOG} + +# if in kpc, convert to pix +case "${R500_UNI}" in + [pP]*) + printf "## units in \`pixel', conversion not needed\n" | ${TOLOG} + R500_PIX_B=`echo ${R500_VAL} | sed 's/[eE]/\*10\^/' | sed 's/+//'` + ;; + *) + printf "## units in \`kpc', convert to \`Chandra pixel'\n" | ${TOLOG} + KPC_PER_PIX=`${COSCALC} ${REDSHIFT} | grep 'kpc.*pix' | tr -d 'a-zA-Z_#=(),:/ '` + # convert scientific notation for `bc' + KPC_PER_PIX_B=`echo ${KPC_PER_PIX} | sed 's/[eE]/\*10\^/' | sed 's/+//'` + printf "## calculated \`kpc/pixel': ${KPC_PER_PIX_B}\n" + R500_VAL_B=`echo ${R500_VAL} | sed 's/[eE]/\*10\^/' | sed 's/+//'` + R500_PIX_B=`echo "scale = 4; ${R500_VAL_B} / ( ${KPC_PER_PIX_B} )" | bc -l` + ;; +esac +# calc (inner-outer R500) +R_IN=`echo "scale = 4; ${INNER} * ${R500_PIX_B}" | bc -l` +R_OUT=`echo "scale = 4; ${OUTER} * ${R500_PIX_B}" | bc -l` +printf "## R500 in units pixel: ${R500_PIX_B}\n" | ${TOLOG} +printf "## (${INNER}-${OUTER} R500) range in pixel: ${R_IN} - ${R_OUT}\n" | ${TOLOG} +# r500 }}} + +# check evt file +if [ -r "${evt}" ]; then + EVT=${evt} +elif [ -r "${DFT_EVT}" ]; then + EVT=${DFT_EVT} +else + read -p "> clean evt2 file: " EVT + if [ ! -r "${EVT}" ]; then + printf "ERROR: cannot access given \`${EVT}' evt file\n" + exit ${ERR_EVT} + fi +fi +printf "## use evt file: \`${EVT}'\n" | ${TOLOG} + +# input and output region files {{{ +if [ -r "${regin}" ]; then + REG_IN="${regin}" +elif [ -r "${DFT_REG_IN}" ]; then + REG_IN=${DFT_REG_IN} +else + read -p "> previous used radial spec regfile: " REG_IN + if [ ! -r "${REG_IN}" ]; then + printf "ERROR: cannot access given \`${REG_IN}' region file\n" + exit ${ERR_REG} + fi +fi +printf "## use previous regfile: \`${REG_IN}'\n" | ${TOLOG} +if [ ! -z "${regout}" ]; then + REG_OUT="${regout}" +else + REG_OUT=${DFT_REG_OUT} +fi +[ -e "${REG_OUT}" ] && mv -fv ${REG_OUT} ${REG_OUT}_bak +printf "## set output regfile (0.1-0.5 r500 region): \`${REG_OUT}'\n" | ${TOLOG} + +# get center position from `regin' +# only consider `pie' or `annulus'-shaped region +TMP_REG=`grep -iE '(pie|annulus)' ${REG_IN} | head -n 1` +XC=`echo ${TMP_REG} | tr -d ' ' | awk -F'[(),]' '{ print $2 }'` +YC=`echo ${TMP_REG} | tr -d ' ' | awk -F'[(),]' '{ print $3 }'` +printf "## get center coord: (${XC},${YC})\n" | ${TOLOG} +# region files }}} + +# check given bkgd, determine background {{{ +if [ -r "${bkgd}" ]; then + BKGD=${bkgd} +elif [ -r "${DFT_BKGD}" ]; then + BKGD=${DFT_BKGD} +else + read -p "> background (blanksky_evt | lbkg_reg | bkg_spec): " BKGD + if [ ! -r "${BKGD}" ]; then + printf "ERROR: cannot access given \`${BKGD}'\n" + exit ${ERR_BKG} + fi +fi +printf "## use bkgd: \`${BKGD}'\n" | ${TOLOG} +# determine bkg type: blanksky, lbkg_reg, bkg_spec ? +# according to file type first: text / FITS +# if FITS, then get values of `HDUCLAS1' and `OBJECT' +if file -bL ${BKGD} | grep -qi 'text'; then + printf "## given \`${BKGD}' is a \`text file'\n" + printf "## use it as local bkg region file\n" + printf "## use *LOCAL BKG SPEC*\n" | ${TOLOG} + # just set flags, extract spectrum later + USE_LBKG_REG=YES + USE_BLANKSKY=NO + USE_BKG_SPEC=NO +elif file -bL ${BKGD} | grep -qi 'FITS'; then + printf "## given \`${BKGD}' is a \`FITS file'\n" + # get FITS header keyword + HDUCLAS1=`dmkeypar ${BKGD} HDUCLAS1 echo=yes` + if [ "${HDUCLAS1}" = "EVENTS" ]; then + # event file + printf "## given file is \`event'\n" + # check if `blanksky' or `stowed bkg' + BKG_OBJ=`dmkeypar ${BKGD} OBJECT echo=yes` + if [ "${BKG_OBJ}" = "BACKGROUND DATASET" ] || [ "${BKG_OBJ}" = "ACIS STOWED" ]; then + # valid bkg evt file + printf "## given FITS file is a valid bkgrnd file\n" + printf "## use *BLANKSKY*\n" | ${TOLOG} + USE_BLANKSKY=YES + USE_LBKG_REG=NO + USE_BKG_SPEC=NO + # specify `BLANKSKY' + BLANKSKY=${BKGD} + else + # invalid bkg evt file + printf "ERROR: invalid bkg evt file given\n" + exit ${ERR_BKGTY} + fi + elif [ "${HDUCLAS1}" = "SPECTRUM" ]; then + # spectrum file + printf "## given file is \`spectrum'\n" + printf "## use *BKG SPECTRUM*\n" | ${TOLOG} + USE_BKG_SPEC=YES + USE_BLANKSKY=NO + USE_LBKG_REG=NO + # specify `BKG_SPEC' + BKG_SPEC=${BKGD} + else + # other type + printf "ERROR: other type FITS given\n" + exit ${ERR_BKGTY} + fi +else + printf "ERROR: given \`${BKGD}' type UNKNOWN\n" + exit ${ERR_BKGTY} +fi +# bkgd }}} + +# check `arf' and `rmf' {{{ +if [ -r "${arf}" ]; then + ARF=${arf} +elif [ -r "${DFT_ARF}" ]; then + ARF=${DFT_ARF} +else + read -p "> provide the ARF to use: " ARF + if [ ! -r "${ARF}" ]; then + printf "ERROR: cannot access given \`${ARF}'\n" + exit ${ERR_ARF} + fi +fi +printf "## use ARF: \`${ARF}'\n" | ${TOLOG} +# rmf +if [ -r "${rmf}" ]; then + RMF=${rmf} +elif [ -r "${DFT_RMF}" ]; then + RMF=${DFT_RMF} +else + read -p "> provide the RMF to use: " RMF + if [ ! -r "${RMF}" ]; then + printf "ERROR: cannot access given \`${RMF}'\n" + exit ${ERR_RMF} + fi +fi +printf "## use RMF: \`${RMF}'\n" | ${TOLOG} +# arf & rmf }}} + +# check given `grpcmd' +if [ ! -z "${grpcmd}" ]; then + GRP_CMD="${grpcmd}" +else + GRP_CMD="${DFT_GRP_CMD}" +fi +printf "## use grppha cmd: \`${GRP_CMD}'\n" | ${TOLOG} +## parameters }}} + +################################################## +#### main +## D_A +D_A_CM=`${COSCALC} ${REDSHIFT} | grep '^d_a_cm' | awk '{ print $2 }'` +printf "D_A_CM(${REDSHIFT})= ${D_A_CM}\n" + +## region related {{{ +## generate the needed region file +printf "generate the output region file ...\n" +cat > ${REG_OUT} << _EOF_ +# Region file format: CIAO version 1.0 +pie(${XC},${YC},${R_IN},${R_OUT},0,360) +_EOF_ + +## open the evt file to verify or modify +printf "## check the generated pie region ...\n" +printf "## if modified, save with the same name \`${REG_OUT}' (overwrite)\n" +ds9 ${EVT} -regions ${REG_OUT} -cmap sls -bin factor 4 + +## check the (modified) region (pie region end angle) +printf "check the above region (for pie region end angle) ...\n" +INVALID=`grep -i 'pie' ${REG_OUT} | awk -F'[,()]' '$7 > 360'` +if [ "x${INVALID}" != "x" ]; then + printf "*** WARNING: there are pie regions' END_ANGLE > 360\n" | ${TOLOG} + printf "*** will to fix ...\n" + mv -fv ${REG_OUT} ${REG_OUT}_tmp + # using `awk' to fix + awk -F'[,()]' '{ + if ($7 > 360) { + printf "%s(%.2f,%.2f,%.2f,%.2f,%.2f,%.2f)\n", $1,$2,$3,$4,$5,$6,($7-360) + } + else { + print $0 + } + }' ${REG_OUT}_tmp > ${REG_OUT} + rm -f ${REG_OUT}_tmp +fi +## region related }}} + +## generate spectrum {{{ +# check counts +punlearn dmlist +CNT_RC=`dmlist infile="${EVT}[sky=region(${REG_OUT})][energy=700:7000]" opt=block | grep 'EVENTS' | awk '{ print $8 }'` +if [ ${CNT_RC} -lt 500 ]; then + F_WC=true + WC="LOW_COUNTS" + printf "*** WARNING: counts_in_0.048R500=${CNT_RC} < 500 ***\n" +fi + +# object +printf "extract object spectrum \`${AVGT_SPEC}' ...\n" +AVGT_SPEC="${REG_OUT%.reg}.pi" +AVGT_SPEC_GRP="${AVGT_SPEC%.pi}_grp.pi" +punlearn dmextract +dmextract infile="${EVT}[sky=region(${REG_OUT})][bin PI]" \ + outfile="${AVGT_SPEC}" wmap="[bin det=8]" clobber=yes +# group spectrum +printf "group object spectrum ...\n" +grppha infile="${AVGT_SPEC}" outfile="${AVGT_SPEC_GRP}" \ + comm="${GRP_CMD} & exit" clobber=yes > /dev/null + +# background +printf "generate the background spectrum ...\n" +AVGT_BKG="${AVGT_SPEC%.pi}_bkg.pi" +if [ "${USE_BLANKSKY}" = "YES" ]; then + # use blanksky as background file + printf "extract spectrum from blanksky ...\n" + punlearn dmextract + dmextract infile="${BLANKSKY}[sky=region(${REG_OUT})][bin PI]" \ + outfile=${AVGT_BKG} wmap="[bin det=8]" clobber=yes +elif [ "${USE_LBKG_REG}" = "YES" ]; then + printf "extract local background ...\n" + punlearn dmextract + dmextract infile="${EVT}[sky=region(${BKGD})][bin PI]" \ + outfile=${AVGT_BKG} wmap="[bin det=8]" clobber=yes +elif [ "${USE_BKG_SPEC}" = "YES" ]; then + printf "copy specified background spectrum ...\n" + cp -fv ${BKG_SPEC} ${AVGT_BKG} +fi + +printf "renormalize the background ...\n" +bkg_renorm ${AVGT_SPEC} ${AVGT_BKG} +## spectrum }}} + +## generate XSPEC script {{{ +printf "generate a XSPEC script ...\n" +[ -e "${XSPEC_SCRIPT}" ] && mv -fv ${XSPEC_SCRIPT} ${XSPEC_SCRIPT}_bak +cat > ${XSPEC_SCRIPT} << _EOF_ +## XSPEC script +## spectrum analysis to get the average temperatue with (0-0.048 R500) +## +## generated by: \``basename $0`' +## date: \``date`' +## + +# xspec settings +statistic chi +abund grsa +query yes + +# data +data ${AVGT_SPEC_GRP} +response ${RMF} +arf ${ARF} +backgrnd ${AVGT_BKG} + +# fitting range +ignore bad +ignore 0.0-0.7,7.0-** + +# plot related +setplot energy + +method leven 10 0.01 +xsect bcmc +cosmo 70 0 0.73 +xset delta 0.01 +systematic 0 + +# model +model wabs*apec + ${N_H} -0.001 0 0 100000 1e+06 + 1.0 0.01 0.008 0.008 64 64 + 0.4 0.001 0 0 5 5 + ${REDSHIFT} -0.01 -0.999 -0.999 10 10 + 0.0 0.01 0 0 1e+24 1e+24 + +## xspec script end + +proc calc_cooling_time {} { + set rout ${R_OUT} + set d_a_cm ${D_A_CM} + fit 1000 + tclout param 4 + set z [ lindex \$xspec_tclout 0 ] + tclout param 2 + set T [ lindex \$xspec_tclout 0 ] + tclout param 5 + set norm [ lindex \$xspec_tclout 0 ] + newpar 1 0 + dummyrsp .001 100 + flux .001 100 + + tclout flux + set flux [ lindex \$xspec_tclout 0 ] + puts "flux(0.01-100kev): \$flux" + set rout_cm [ expr \$rout*.492/3600/180*3.14159*\$d_a_cm ] + set V [ expr 4./3.*3.14159*\$rout_cm*\$rout_cm*\$rout_cm ] + set nenh [ expr \$norm*1E14*4*3.14159*\$d_a_cm*\$d_a_cm*(1+\$z)*(1+\$z)*(1+\$z)*(1+\$z)/\$V ] + set d_l_cm [ expr \$d_a_cm*(1+\$z)*(1+\$z) ] + set ne_np_ratio 1.2 + set ne [ expr sqrt(\$nenh*\$ne_np_ratio) ] + set lx [ expr \$flux*4*3.14159*\$d_l_cm*\$d_l_cm ] + set kb 1.602E-9 + set ct [ expr 3./2.*(\$ne+\$ne/\$ne_np_ratio)*\$kb*\$T*\$V/\$lx ] + set ct_gyr [ expr \$ct/(3600*24*365.25*1E9) ] + puts "Cooling_time= \$ct_gyr Gyr" +} + +fit 1000 +calc_cooling_time + +tclexit +_EOF_ +## xspec script }}} + +## invoke xspec to calc +if [ "x${F_WC}" = "xtrue" ]; then + printf "\n*** WC: LOW_COUNTS ***\n" + printf "*** WARNING: counts_in_0.048R500=${CNT_RC} < 500 ***\n" +else + [ -e "${CT_RES}" ] && mv -f ${CT_RES} ${CT_RES}_bak + printf "invoking XSPEC to calculate cooling time ...\n" + xspec - ${XSPEC_SCRIPT} | tee ${CT_RES} + + OBS_ID=`grep '"Obs.*ID' ${JSON_FILE} | awk -F':' '{ print $2 }' | tr -d ' ,'` + OBJ_NAME=`grep '"Source\ Name' ${JSON_FILE} | awk -F':' '{ print $2 }' | sed -e 's/\ *"//' -e 's/"\ *,$//'` + CT=`grep -i '^Cooling_time' ${CT_RES} | awk '{ print $2 }'` + + printf "\n" | tee -a ${CT_RES} + printf "# OBS_ID,OBJ_NAME,CT_gyr\n" | tee -a ${CT_RES} + printf "# $OBS_ID,$OBJ_NAME,$CT\n" | tee -a ${CT_RES} +fi + +exit 0 + diff --git a/mass_profile/csb_calc_lwt.sh b/mass_profile/csb_calc_lwt.sh new file mode 100755 index 0000000..381c545 --- /dev/null +++ b/mass_profile/csb_calc_lwt.sh @@ -0,0 +1,166 @@ +#!/bin/sh +# +# for 'z>0.3' or 'counts_in_0.048R500<500' +# + +ERR_CALC=1 +ERR_DIR=2 +ERR_JSON=3 +ERR_Z=4 +ERR_CNT=5 + +## cosmology claculator {{{ +## write the path of cosmo claculator here +BASE_PATH=`dirname $0` +COSMO_CALC="${BASE_PATH}/cosmo_calc" +if [ -z "${COSMO_CALC}" ] || [ ! -x ${COSMO_CALC} ] ; then + printf "ERROR: ${COSMO_CALC} neither executable nor specified\n" + exit ${ERR_CALC} +fi +## }}} + +# default basedir relative to 'spc/profile' +DFT_BASEDIR="../.." +# default imgdir relative to 'basedir' +DFT_IMGDIR="img" +DFT_JSON_PAT="*_INFO.json" +RSPEC_REG="rspec.reg" +CSB_RES="csb_results_`date '+%Y%m%d'`.txt" + +## functions {{{ +# process commandline arguments +# cmdline arg format: `KEY=VALUE' +getopt_keyval() { + until [ -z "$1" ] + do + key=${1%%=*} # extract key + val=${1#*=} # extract value + keyval="${key}=\"${val}\"" + echo "## getopt: eval '${keyval}'" + eval ${keyval} + shift # shift, process next one + done +} +## functions }}} + +## parameters {{{ +# process cmdline args using `getopt_keyval' +getopt_keyval "$@" + +# basedir +if [ -d "${basedir}" ] && ls ${basedir}/*repro_evt2.fits > /dev/null 2>&1; then + BASEDIR=${basedir} +elif [ -d "${DFT_BASEDIR}" ] && ls ${DFT_BASEDIR}/*repro_evt2.fits > /dev/null 2>&1; then + BASEDIR=${DFT_BASEDIR} +else + read -p "> basedir (contains info json): " BASEDIR + if [ ! -d "${BASEDIR}" ] || ! ls ${BASEDIR}/*repro_evt2.fits >/dev/null 2>&1; then + printf "ERROR: given \`${BASEDIR}' invalid!\n" + exit ${ERR_DIR} + fi +fi +BASEDIR=`( cd ${BASEDIR} && pwd -P )` +printf "## use basedir: \`${BASEDIR}'\n" +# mass dir +if [ ! -z "${imgdir}" ] && [ -d "${BASEDIR}/${imgdir}" ]; then + IMG_DIR=`( cd ${BASEDIR}/${imgdir} && pwd -P )` +elif [ -d "${BASEDIR}/${DFT_IMGDIR}" ]; then + IMG_DIR=`( cd ${BASEDIR}/${DFT_IMGDIR} && pwd -P )` +else + read -p "> img dir (relative to basedir): " IMG_DIR + if [ ! -d "${BASEDIR}/${IMG_DIR}" ]; then + printf "ERROR: given \`${IMG_DIR}' invalid\n" + exit ${ERR_DIR} + else + IMG_DIR="${BASEDIR}/${IMG_DIR}" + fi +fi +printf "## use imgdir: \`${IMG_DIR}'\n" +# info json +if [ ! -z "${json}" ] && [ -r "${BASEDIR}/${json}" ]; then + JSON_FILE="${BASEDIR}/${json}" +elif [ `ls -1 ${BASEDIR}/${DFT_JSON_PAT} 2>/dev/null | wc -l` -eq 1 ]; then + JSON_FILE="`ls ${BASEDIR}/${DFT_JSON_PAT} 2>/dev/null`" +else + read -p "> info json: " JSON_FILE + if [ ! -r "${BASEDIR}/${JSON_FILE}" ]; then + printf "ERROR: given \`${JSON_FILE}' not exist!\n" + exit ${ERR_JSON} + fi +fi +printf "## use json_file: \`${JSON_FILE}'\n" +## }}} + +## main {{{ +# in 'spc/profile' +X=`grep -iE '(pie|annulus)' ${RSPEC_REG} | head -n 1 | awk -F'(' '{ print $2 }' | awk -F',' '{ print $1 }'` +Y=`grep -iE '(pie|annulus)' ${RSPEC_REG} | head -n 1 | awk -F'(' '{ print $2 }' | awk -F',' '{ print $2 }'` +# json file +Z=`grep -i '"redshift"' ${JSON_FILE} | awk -F':' '{ print $2 }' | tr -d ' ,'` +R500=`grep '"R500.*kpc' ${JSON_FILE} | awk -F':' '{ print $2 }' | tr -d ' ,'` +OBS_ID=`grep '"Obs.*ID' ${JSON_FILE} | awk -F':' '{ print $2 }' | tr -d ' ,'` +OBJ_NAME=`grep '"Source\ Name' ${JSON_FILE} | awk -F':' '{ print $2 }' | sed -e 's/\ *"//' -e 's/"\ *,$//'` +CT=`grep '"Cooling_time' ${JSON_FILE} | awk -F':' '{ print $2 }' | tr -d ' ,'` + +cd ${IMG_DIR} +printf "entered img directory\n" +EXPMAP=`ls expmap*.fits 2> /dev/null` +EVT_E=`ls evt*e700-7000*.fits 2> /dev/null` + +### test Z>0.3? +if [ `echo "${Z} < 0.3" | bc -l` -eq 1 ]; then + F_WZ=true + WZ="WZ" + printf "*** WARNING: redshift z=${Z} < 0.3 ***\n" +# exit ${ERR_Z} +fi + +KPC_PER_PIXEL=`${COSMO_CALC} ${Z} | grep 'kpc/pixel' | awk '{ print $3 }'` +RC_PIX=`echo "scale=2; 0.048 * ${R500} / ${KPC_PER_PIXEL}" | bc -l` +# test counts_in_0.048R500<500? +RC_REG="pie(${X},${Y},0,${RC_PIX},0,360)" +punlearn dmlist +CNT_RC=`dmlist infile="${EVT_E}[sky=${RC_REG}]" opt=block | grep 'EVENTS' | awk '{ print $8 }'` +printf "R500=${R500}, 0.048R500_pix=${RC_PIX}, counts_in_0.048R500=${CNT_RC}\n" +if [ ${CNT_RC} -gt 500 ]; then + F_WC=true + WC="WC" + printf "*** WARNING: counts_in_0.048R500=${CNT_RC} > 500 ***\n" +# exit ${ERR_CNT} +fi + +TMP_REG="_tmp_csb.reg" +TMP_S="_tmp_csb.fits" + +R1=`echo "scale=2; 40 / ${KPC_PER_PIXEL}" | bc -l` +R2=`echo "scale=2; 400 / ${KPC_PER_PIXEL}" | bc -l` +cat > ${TMP_REG} << _EOF_ +pie(${X},${Y},0,${R1},0,360) +pie(${X},${Y},0,${R2},0,360) +_EOF_ + +printf "CHECK the regions (R1=${R1}, R2=${R2}) ...\n" +ds9 ${EVT_E} -regions ${TMP_REG} -cmap sls -bin factor 4 + +punlearn dmextract +dmextract infile="${EVT_E}[bin sky=@${TMP_REG}]" outfile="${TMP_S}" exp=${EXPMAP} opt=generic clobber=yes +punlearn dmlist +S1=`dmlist "${TMP_S}[cols SUR_FLUX]" opt="data,clean" | grep -v '#' | sed -n -e 's/\ *//' -e '1p'` +S2=`dmlist "${TMP_S}[cols SUR_FLUX]" opt="data,clean" | grep -v '#' | sed -n -e 's/\ *//' -e '2p'` +CSB=`echo "${S1} ${S2}" | awk '{ print $1/$2/100 }'` + +[ -e ${CSB_RES} ] && mv -f ${CSB_RES} ${CSB_RES}_bak +printf "\n==============================\n" +printf "z=${Z}, R500=${R500} (kpc)\n" | tee -a ${CSB_RES} +printf "0.048R500=${RC_PIX}, counts=${CNT_RC}\n" | tee -a ${CSB_RES} +printf "R1=${R1}, R2=${R2} (pixel)\n" | tee -a ${CSB_RES} +printf "S1=${S1}, S2=${S2} (sur_flux)\n" | tee -a ${CSB_RES} +printf "C_sb: ${CSB}\n" | tee -a ${CSB_RES} +[ "x${F_WZ}" = "xtrue" ] && printf "${WZ}\n" | tee -a ${CSB_RES} +[ "x${F_WC}" = "xtrue" ] && printf "${WC}\n" | tee -a ${CSB_RES} +printf "# OBS_ID,OBJ_NAME,Z,R500,RC_PIX,CNT_RC,CT,R1_PIX,R2_PIX,S1,S2,CSB,WRDSHFT,WCNT\n" | tee -a ${CSB_RES} +printf "# $OBS_ID,$OBJ_NAME,$Z,$R500,$RC_PIX,$CNT_RC,$CT,$R1,$R2,$S1,$S2,$CSB,$WZ,$WC\n\n" | tee -a ${CSB_RES} +## main }}} + +exit 0 + diff --git a/mass_profile/dbeta.hpp b/mass_profile/dbeta.hpp new file mode 100644 index 0000000..8c3a7c5 --- /dev/null +++ b/mass_profile/dbeta.hpp @@ -0,0 +1,108 @@ +#ifndef DBETA +#define DBETA +#include "projector.hpp" + +/** + dbeta: double beta model for density + dbeta2: double beta model for density with only one beta +*/ + + +namespace opt_utilities +{ + template <typename T> + class dbeta + :public model<std::vector<T>,std::vector<T>,std::vector<T> > + { + public: + dbeta() + { + this->push_param_info(param_info<std::vector<T>,std::string>("n01",1)); + this->push_param_info(param_info<std::vector<T>,std::string>("beta1",.66)); + this->push_param_info(param_info<std::vector<T>,std::string>("rc1",100)); + + this->push_param_info(param_info<std::vector<T>,std::string>("n02",1)); + this->push_param_info(param_info<std::vector<T>,std::string>("beta2",.67)); + this->push_param_info(param_info<std::vector<T>,std::string>("rc2",110)); + + } + + public: + dbeta<T>* do_clone()const + { + return new dbeta<T>(*this); + } + + std::vector<T> do_eval(const std::vector<T> & x, + const std::vector<T>& p) + { + T n01=std::abs(p[0]); + T beta1=p[1]; + T rc1=p[2]; + + T n02=std::abs(p[3]); + T beta2=p[4]; + T rc2=p[5]; + + + + std::vector<T> result(x.size()-1); + for(int i=1;i<x.size();++i) + { + T xi=(x[i]+x[i-1])/2; + T yi=0; + yi=n01*pow(1+xi*xi/rc1/rc1,-3./2.*beta1)+n02*pow(1+xi*xi/rc2/rc2,-3./2.*beta2); + result[i-1]=yi; + } + return result; + } + }; + + template <typename T> + class dbeta2 + :public model<std::vector<T>,std::vector<T>,std::vector<T> > + { + public: + dbeta2() + { + this->push_param_info(param_info<std::vector<T>,std::string>("n01",1)); + this->push_param_info(param_info<std::vector<T>,std::string>("rc1",100)); + this->push_param_info(param_info<std::vector<T>,std::string>("n02",1)); + this->push_param_info(param_info<std::vector<T>,std::string>("rc2",110)); + this->push_param_info(param_info<std::vector<T>,std::string>("beta",.67)); + + } + + public: + dbeta2<T>* do_clone()const + { + return new dbeta2<T>(*this); + } + + std::vector<T> do_eval(const std::vector<T> & x, + const std::vector<T>& p) + { + T n01=std::abs(p[0]); + T rc1=p[1]; + + T n02=std::abs(p[2]); + T rc2=p[3]; + T beta=p[4]; + T beta1=beta; + T beta2=beta; + + std::vector<T> result(x.size()-1); + for(int i=1;i<x.size();++i) + { + T xi=(x[i]+x[i-1])/2; + T yi=0; + yi=n01*pow(1+xi*xi/rc1/rc1,-3./2.*beta1)+n02*pow(1+xi*xi/rc2/rc2,-3./2.*beta2); + result[i-1]=yi; + } + return result; + } + }; + +} + +#endif diff --git a/mass_profile/dump_fit_qdp.cpp b/mass_profile/dump_fit_qdp.cpp new file mode 100644 index 0000000..556edea --- /dev/null +++ b/mass_profile/dump_fit_qdp.cpp @@ -0,0 +1,55 @@ +#include "dump_fit_qdp.hpp" + +namespace opt_utilities +{ + const static double kpc=3.086E21; + void dump_sbp_beta(std::ostream& os,fitter<double,double,std::vector<double>,double,std::string>& f,double cm_per_pixel,const std::vector<double>& r,const std::vector<double>& y,const std::vector<double>& ye) + { + os<<"read serr 1 2"<<std::endl; + os<<"skip single"<<std::endl; + os<<"la x \"radius (kpc)\""<<std::endl; + os<<"la y \"surface brightness (cts s\\u-1\\d pixel\\u-2\\d)\""<<std::endl; + os<<"li on 2"<<std::endl; + for(int i=1;i<r.size();++i) + { + os<<(r[i]+r[i-1])/2*cm_per_pixel/kpc<<"\t"<<(r[i]-r[i-1])/2*cm_per_pixel/kpc<<"\t"<<y[i-1]<<"\t"<<ye[i-1]<<std::endl; + } + os<<"no no no"<<std::endl; + std::vector<double> p=f.get_all_params(); + for(int i=1;i<r.size();++i) + { + double x=(r[i]+r[i-1])/2; + os<<x*cm_per_pixel/kpc<<"\t"<<0<<"\t"<<f.eval_model_raw(x,p)<<"\t"<<0<<std::endl; + } + } + + void dump_rho_beta(std::ostream& os,fitter<std::vector<double>,std::vector<double>,std::vector<double>,double,std::string>& f,double cm_per_pixel,const std::vector<double>& r,const std::vector<double>& sbps,const std::vector<double>& sbpe) + { + os<<"read serr 1 2"<<std::endl; + os<<"skip single"<<std::endl; + os<<"la x \"radius (kpc)\""<<std::endl; + os<<"la y \"density (cm\\u-3\\d)\""<<std::endl; + os<<"li on 2"<<std::endl; + + for(int i=1;i<r.size();++i) + { + double x=(r[i]+r[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + os<<x*cm_per_pixel/kpc<<"\t0\t"<<y<<"\t"<<ye<<std::endl; + } + + os<<"no no no"<<std::endl; + std::vector<double> p=f.get_all_params(); + std::vector<double> mv=f.eval_model_raw(r,p); + for(int i=1;i<r.size();++i) + { + double x=(r[i]+r[i-1])/2; + double y=mv[i-1]; + double ye=0; + os<<x*cm_per_pixel/kpc<<"\t0\t"<<y<<"\t"<<ye<<std::endl; + } + + } + +}; diff --git a/mass_profile/dump_fit_qdp.hpp b/mass_profile/dump_fit_qdp.hpp new file mode 100644 index 0000000..8364dfd --- /dev/null +++ b/mass_profile/dump_fit_qdp.hpp @@ -0,0 +1,16 @@ +#ifndef DUMP_FIT_QDP_HPP +#define DUMP_FIT_QDP_HPP + +#include <core/fitter.hpp> +#include <vector> +#include <iostream> +#include <string> + +namespace opt_utilities +{ + void dump_sbp_beta(std::ostream& os,fitter<double,double,std::vector<double>,double,std::string>& f,double cm_per_pixel,const std::vector<double>& r,const std::vector<double>& y,const std::vector<double>& ye); + void dump_rho_beta(std::ostream& os,fitter<std::vector<double>,std::vector<double>,std::vector<double>,double,std::string>& f,double cm_per_pixel,const std::vector<double>& r,const std::vector<double>& sbps,const std::vector<double>& sbpe); + void dump_rho_dbeta(std::ostream& os,fitter<std::vector<double>,std::vector<double>,std::vector<double>,double,std::string>& f,double cm_per_pixel); +}; + +#endif diff --git a/mass_profile/extract_tcool.py b/mass_profile/extract_tcool.py new file mode 100755 index 0000000..393af27 --- /dev/null +++ b/mass_profile/extract_tcool.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import sys +rcool=float(sys.argv[1]) + +for l in open('cooling_time.dat'): + r,t=l.split() + r=float(r) + t=float(t) + if r>rcool: + print("cooling time at %f kpc=%f Gyr"%(rcool,t)) + sys.exit(0) diff --git a/mass_profile/fg_2500_500.py b/mass_profile/fg_2500_500.py new file mode 100755 index 0000000..67a1a11 --- /dev/null +++ b/mass_profile/fg_2500_500.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python + +import sys +import numpy +import scipy.interpolate + +confidence_level=.68 +def read_file(param): + delta=float(param[0]) + + file_mass_center=open("mass_int_center.qdp").readlines(); + file_delta_center=open("overdensity_center.qdp").readlines(); + + center_r=0 + center_m=0 + center_gm=0 + center_gf=0 + + + for i in range(0,len(file_mass_center)): + lm=file_mass_center[i].strip(); + ld=file_delta_center[i].strip(); + r,m=lm.split() + r,d=ld.split() + r=float(r) + d=float(d) + m=float(m) + if m<1e11: + continue + if d<delta: + center_r=r + center_m=m + for j in open("gas_mass_int_center.qdp"): + rgm,gm=j.strip().split() + rgm=float(rgm) + gm=float(gm) + if rgm>r: + + center_gm=gm + center_gf=gm/m + break + break + if len(param)>1 and param[1]=='c': + #print("%s(<r%d)=%E solar mass"%("mass",delta,center_m)) + #print("%s%d=%E kpc"%("r",delta,center_r)) + #print("%s(<r%d)=%E solar mass"%("gas mass",delta,center_gm)) + #print("%s(<r%d)=%E"%("gas fraction",delta,center_gf)) + return center_m,center_r,center_gm,center_gf,None,None,None,None + + +#print(center_gm,center_gf) + file_mass=open('summary_mass_profile.qdp').readlines() + file_delta=open('summary_overdensity.qdp').readlines() + file_gm=open('summary_gas_mass_profile.qdp') + + + flag=True + rlist=[] + mlist=[] + gmlist=[] + gflist=[] + old_m=0 + invalid_count=0 + for i in range(0,len(file_mass)): + lm=file_mass[i].strip() + ld=file_delta[i].strip() + if lm[0]=='n': + flag=True + old_m=0 + continue + if not flag: + continue + r,m=lm.split() + m=float(m) + if m<1e12: + continue + if m<old_m: + invalid_count+=1 + flag=False + continue + r,d=ld.split() + d=float(d) + r=float(r) + + if d<delta: + #print("%s %e"%(d,m)) + mlist.append(m) + rlist.append(r) + flag1=True + while True: + lgm=file_gm.readline().strip() + if lgm[0]=='n': + break + rgm,gm=lgm.split() + rgm=float(rgm) + gm=float(gm) + if rgm>r and flag1: + gmlist.append(gm) + + flag1=False + gflist.append(gm/mlist[-1]) + #print(gm,gflist[-1]) + flag=False + old_m=m + print("%d abnormal data dropped"%(invalid_count)) + + + return center_m,center_r,center_gm,center_gf,mlist,rlist,gmlist,gflist +#center_m=numpy.mean(mlist) +#center_r=numpy.mean(rlist) + +if len(sys.argv)>1: + center_m2500,center_r2500,center_gm2500,center_gf2500,mlist2500,rlist2500,gmlist2500,gflist2500=read_file([2500,sys.argv[1]]) + center_m500,center_r500,center_gm500,center_gf500,mlist500,rlist500,gmlist500,gflist500=read_file([500,sys.argv[1]]) +else: + center_m2500,center_r2500,center_gm2500,center_gf2500,mlist2500,rlist2500,gmlist2500,gflist2500=read_file([2500]) + center_m500,center_r500,center_gm500,center_gf500,mlist500,rlist500,gmlist500,gflist500=read_file([500]) + +if mlist2500!=None and len(mlist2500)!=len(mlist500): + raise Exception("Something wrong, the number of 2500 and 500 data are different") + + +if mlist2500==None: + print("gas fraction between r2500 and r500 is %E"%((center_gm500-center_gm2500)/(center_m500-center_m2500))) + sys.exit(0) + +gf_2500_500=[] + +for i in range(0,len(mlist500)): + if mlist500[i]-mlist2500[i]<=0: + continue + gf_2500_500.append((gmlist500[i]-gmlist2500[i])/(mlist500[i]-mlist2500[i])) + +gf_2500_500.sort(); + + +center_gf_2500_500=(center_gm500-center_gm2500)/(center_m500-center_m2500) +gf_idx=-1 + +for i in range(len(gf_2500_500)-1): + if (center_gf_2500_500-gf_2500_500[i])*(center_gf_2500_500-gf_2500_500[i+1])<=0: + gf_idx=i + break +if gf_idx==-1: + raise Exception("Something wrong!") + +gflidx=int(gf_idx*(1-confidence_level)) +gfuidx=gf_idx-1+int((len(gf_2500_500)-gf_idx)*confidence_level) + +gferr1=gf_2500_500[gflidx]-center_gf_2500_500 +gferr2=gf_2500_500[gfuidx]-center_gf_2500_500 + +print("gas_fraction between r2500 and r500=\t%e\t %e/+%e (1 sigma)"%(center_gf_2500_500,gferr1,gferr2)) diff --git a/mass_profile/fit_beta_entropy.sh b/mass_profile/fit_beta_entropy.sh new file mode 100755 index 0000000..f52e4a1 --- /dev/null +++ b/mass_profile/fit_beta_entropy.sh @@ -0,0 +1,150 @@ +#!/bin/bash + +echo $# +if [ $# -eq 2 ] +then + : +else + echo "Usage:$0 <cfg file> <radius in kpc>" + exit +fi +export PGPLOT_FONT=`locate grfont.dat|head -1` + +mkdir -p entropy_files + +cfg_file=$1 +base_path=`dirname $0` +echo $base_path +#initialize profile type name +t_profile_type=`grep t_profile $cfg_file|awk '{print $2}'` +#initialize data file name +t_data_file=`grep t_data_file $cfg_file|awk '{print $2}'` +#initialize sbp config file +sbp_cfg=`grep sbp_cfg $cfg_file|awk '{print $2}'` +#initialize the temperature profile file +T_file=`grep '^T_file' $sbp_cfg|awk '{print $2}'` +#echo $t_profile_type +cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` + +#determine which temperature profile to be used, and fit the T profile +if [ $t_profile_type == zyy ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zyy_model $t_data_file $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} +elif [ $t_profile_type == m0603246 ] +then + $base_path/fit_m0603246 $t_data_file $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} +elif [ $t_profile_type == wang2012 ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} +elif [ $t_profile_type == allen ] +then + $base_path/fit_allen_model $t_data_file $cm_per_pixel + mv -f allen_dump.qdp ${T_file} +elif [ $t_profile_type == zzl ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zzl_model $t_data_file $t_param_file + mv -f zzl_dump.qdp ${T_file} +else + echo temperature profile name invalid! + exit +fi + +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{print $2}'` +z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` +abund=`grep '^abund' ${cfg_file} |awk '{print $2}'` +nh=`grep '^nh' ${cfg_file} |awk '{print $2}'` +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file +mv flux_cnt_ratio.txt flux_cnt_ratio_center_entropy.txt +#fit sbp +$base_path/fit_beta_sbp $sbp_cfg +echo $cfunc_file +#exit + +#store central valu +mv sbp_fit.qdp sbp_fit_center_entropy.qdp +mv mass_int.qdp mass_int_center_entropy.qdp +mv overdensity.qdp overdensity_center_entropy.qdp +mv gas_mass_int.qdp gas_mass_int_center_entropy.qdp +mv entropy.qdp entropy_center.qdp +sbp_data_file=`grep sbp_file $sbp_cfg|awk '{print $2}'` +radius_sbp_file=`grep radius_sbp_file ${cfg_file}|awk '{print $2}'` + +if [ x"$radius_sbp_file" == x ] +then + echo "Error, must have radius_sbp_file assigned, this file should be a 4-column file, which contains the radius, radius err, sbp, and sbp err" + exit +fi + +cat ${radius_sbp_file} | sed 's/#.*$//' | grep -Ev '^\s*$' > .tmp.txt +mv .tmp.txt ${radius_sbp_file} + +rm -f summary_entropy.qdp +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +for i in `seq 1 100` +do + echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + +#exit + if [ $t_profile_type == zyy ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zyy_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} + elif [ $t_profile_type == m0603246 ] + then + $base_path/fit_m0603246 temp_shuffled_t.dat $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} + elif [ $t_profile_type == wang2012 ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} + elif [ $t_profile_type == allen ] + then + $base_path/fit_allen_model temp_shuffled_t.dat $cm_per_pixel + mv -f allen_dump.qdp ${T_file} + elif [ $t_profile_type == zzl ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zzl_model temp_shuffled_t.dat $t_param_file + mv -f zzl_dump.qdp ${T_file} + else + echo temperature profile name invalid! + exit + fi + +#exit + echo >temp_sbp.cfg + + cat $sbp_cfg|while read l +do + if echo $l|grep sbp_file >/dev/null + then + echo sbp_file temp_shuffled_sbp.dat >>temp_sbp.cfg + elif echo $l|grep T_file >/dev/null + then + echo T_file ${T_file} >>temp_sbp.cfg + else + echo $l >>temp_sbp.cfg + fi + +done + +#$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file + +$base_path/fit_beta_sbp temp_sbp.cfg + +cat entropy.qdp >>summary_entropy.qdp +echo no no no >>summary_entropy.qdp +done + +$base_path/analyze_entropy_profile.py $2 |tee entropy_result.txt diff --git a/mass_profile/fit_beta_mass_profile.sh b/mass_profile/fit_beta_mass_profile.sh new file mode 100755 index 0000000..3795189 --- /dev/null +++ b/mass_profile/fit_beta_mass_profile.sh @@ -0,0 +1,200 @@ +#!/bin/bash + +echo $# +if [ $# -eq 1 ] +then + : +else + echo "Usage:$0 <cfg file>" + exit +fi +export PGPLOT_FONT=`locate grfont.dat|head -1` + +cfg_file=$1 +base_path=`dirname $0` +echo $base_path +#initialize profile type name +t_profile_type=`grep t_profile $cfg_file|awk '{print $2}'` +#initialize data file name +t_data_file=`grep t_data_file $cfg_file|awk '{print $2}'` +#initialize sbp config file +sbp_cfg=`grep sbp_cfg $cfg_file|awk '{print $2}'` +#initialize the temperature profile file +T_file=`grep '^T_file' $sbp_cfg|awk '{print $2}'` +#echo $t_profile_type +cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` + +#determine which temperature profile to be used, and fit the T profile +if [ $t_profile_type == zyy ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zyy_model $t_data_file $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} +elif [ $t_profile_type == m0603246 ] +then + $base_path/fit_m0603246 $t_data_file $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} +elif [ $t_profile_type == wang2012 ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} +elif [ $t_profile_type == allen ] +then + $base_path/fit_allen_model $t_data_file $cm_per_pixel + mv -f allen_dump.qdp ${T_file} +elif [ $t_profile_type == zzl ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zzl_model $t_data_file $t_param_file + mv -f zzl_dump.qdp ${T_file} +else + echo temperature profile name invalid! + exit +fi + +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{print $2}'` +z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` +abund=`grep '^abund' ${cfg_file} |awk '{print $2}'` +nh=`grep '^nh' ${cfg_file} |awk '{print $2}'` +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file +mv flux_cnt_ratio.txt flux_cnt_ratio_center.txt +#fit sbp +$base_path/fit_beta_sbp $sbp_cfg +echo $cfunc_file +#exit + +#store central valu +mv sbp_fit.qdp sbp_fit_center.qdp +mv mass_int.qdp mass_int_center.qdp +mv overdensity.qdp overdensity_center.qdp +mv gas_mass_int.qdp gas_mass_int_center.qdp +sbp_data_file=`grep sbp_file $sbp_cfg|awk '{print $2}'` +radius_sbp_file=`grep radius_sbp_file ${cfg_file}|awk '{print $2}'` + +if [ x"$radius_sbp_file" == x ] +then + echo "Error, must have radius_sbp_file assigned, this file should be a 4-column file, which contains the radius, radius err, sbp, and sbp err" + exit +fi + +cat ${radius_sbp_file} | sed 's/#.*$//' | grep -Ev '^\s*$' > .tmp.txt +mv .tmp.txt ${radius_sbp_file} + +rm -f summary_shuffle_mass_profile.qdp +rm -f summary_overdensity.qdp +rm -f summary_mass_profile.qdp +rm -f summary_gas_mass_profile.qdp + +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +for i in `seq 1 100` +do + echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + +#exit + if [ $t_profile_type == zyy ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zyy_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} + elif [ $t_profile_type == m0603246 ] + then + $base_path/fit_m0603246 temp_shuffled_t.dat $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} + elif [ $t_profile_type == wang2012 ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} + elif [ $t_profile_type == allen ] + then + $base_path/fit_allen_model temp_shuffled_t.dat $cm_per_pixel + mv -f allen_dump.qdp ${T_file} + elif [ $t_profile_type == zzl ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zzl_model temp_shuffled_t.dat $t_param_file + mv -f zzl_dump.qdp ${T_file} + else + echo temperature profile name invalid! + exit + fi + +#exit + echo >temp_sbp.cfg + + cat $sbp_cfg|while read l +do + if echo $l|grep sbp_file >/dev/null + then + echo sbp_file temp_shuffled_sbp.dat >>temp_sbp.cfg + elif echo $l|grep T_file >/dev/null + then + echo T_file ${T_file} >>temp_sbp.cfg + else + echo $l >>temp_sbp.cfg + fi + +done + +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file + +$base_path/fit_beta_sbp temp_sbp.cfg +cat mass_int.qdp >>summary_mass_profile.qdp +echo no no no >>summary_mass_profile.qdp + +cat overdensity.qdp >>summary_overdensity.qdp +echo no no no >>summary_overdensity.qdp + +cat gas_mass_int.qdp >>summary_gas_mass_profile.qdp +echo no no no >>summary_gas_mass_profile.qdp +done +#analys the errors +$base_path/analyze_mass_profile.py 200 +$base_path/analyze_mass_profile.py 500 +$base_path/analyze_mass_profile.py 1500 +#$base_path/analyze_mass_profile.py 2500 + +r500=`$base_path/analyze_mass_profile.py 500|grep r500|awk '{print $2}'` +#$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r500 $t_data_file +r200=`$base_path/analyze_mass_profile.py 200|grep r200|awk '{print $2}'` +#$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r200 $t_data_file + +r500e=`$base_path/analyze_mass_profile.py 500|grep '^r500' 2>/dev/null|awk '{print $2,$3}'` +m500e=`$base_path/analyze_mass_profile.py 500|grep '^m500' 2>/dev/null|awk '{print $2,$3}'` +L500=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r500 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg500e=`$base_path/analyze_mass_profile.py 500|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg500e=`$base_path/analyze_mass_profile.py 500|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + + +r200e=`$base_path/analyze_mass_profile.py 200|grep '^r200' 2>/dev/null|awk '{print $2,$3}'` +m200e=`$base_path/analyze_mass_profile.py 200|grep '^m200' 2>/dev/null|awk '{print $2,$3}'` +L200=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r200 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg200e=`$base_path/analyze_mass_profile.py 200|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg200e=`$base_path/analyze_mass_profile.py 200|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + + + +echo "******************" +echo "Final results:" +echo "******************" +echo +echo + +echo r500= $r500e kpc +echo m500= $m500e M_sun +echo L500= $L500 erg/s +echo gas mass 500= $mg500e M_sun +echo gas fractho 500= $fg500e x100% + +echo r200= $r200e kpc +echo m200= $m200e M_sun +echo L200= $L200 erg/s +echo gas mass 200= $mg200e M_sun +echo gas fractho 200= $fg200e x100% + + + diff --git a/mass_profile/fit_beta_nfw_mass_profile.sh b/mass_profile/fit_beta_nfw_mass_profile.sh new file mode 100755 index 0000000..a623c0c --- /dev/null +++ b/mass_profile/fit_beta_nfw_mass_profile.sh @@ -0,0 +1,227 @@ +#!/bin/bash + +echo $# +if [ $# -gt 0 ] +then + : +else + echo "Usage:$0 <cfg file> [c]" + echo "If central value only, append a \"c\"" + exit +fi +export PGPLOT_FONT=`locate grfont.dat|head -1` + +cfg_file=$1 +base_path=`dirname $0` +echo $base_path +#initialize profile type name +t_profile_type=`grep t_profile $cfg_file|awk '{print $2}'` +#initialize data file name +t_data_file=`grep t_data_file $cfg_file|awk '{print $2}'` +#initialize sbp config file +sbp_cfg=`grep sbp_cfg $cfg_file|awk '{print $2}'` +#initialize the temperature profile file +T_file=`grep '^T_file' $sbp_cfg|awk '{print $2}'` +#initialize the rmin_kpc for nfw mass profile fitting +nfw_rmin_kpc=`grep '^nfw_rmin_kpc' $cfg_file|awk '{print $2}'` +#echo $t_profile_type +cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` +da=`python -c "print($cm_per_pixel/(.492/3600/180*3.1415926))"` +#determine which temperature profile to be used, and fit the T profile +if [ $t_profile_type == wang2012 ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} +else + echo temperature profile name invalid! + exit +fi + +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{print $2}'` +z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` +dl=`python -c "print($da*(1+$z)**2)"` +abund=`grep '^abund' ${cfg_file} |awk '{print $2}'` +nh=`grep '^nh' ${cfg_file} |awk '{print $2}'` +$base_path/coolfunc_calc_bolo.sh ${T_file} $abund $nh $z cfunc_bolo.dat +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file +mv flux_cnt_ratio.txt flux_cnt_ratio_center.txt +#fit sbp +$base_path/fit_beta_sbp $sbp_cfg +$base_path/fit_nfw_mass mass_int.dat $z $nfw_rmin_kpc +echo $cfunc_file +#exit + + +#store central valu +mv sbp_fit.qdp sbp_fit_center.qdp +mv nfw_dump.qdp mass_int_center.qdp +mv overdensity.qdp overdensity_center.qdp +mv gas_mass_int.qdp gas_mass_int_center.qdp +mv nfw_param.txt nfw_param_center.qdp +mv beta_param.txt beta_param_center.txt +mv rho_fit.dat rho_fit_center.dat + + +#calculate cooling time +echo $dl + +$base_path/cooling_time rho_fit_center.dat $T_file cfunc_bolo.dat $dl $cm_per_pixel >cooling_time.dat + +sbp_data_file=`grep sbp_file $sbp_cfg|awk '{print $2}'` +radius_sbp_file=`grep radius_sbp_file ${cfg_file}|awk '{print $2}'` + +if [ x"$radius_sbp_file" == x ] +then + echo "Error, must have radius_sbp_file assigned, this file should be a 4-column file, which contains the radius, radius err, sbp, and sbp err" + exit +fi + +cat ${radius_sbp_file} | sed 's/#.*$//' | grep -Ev '^\s*$' > .tmp.txt +mv .tmp.txt ${radius_sbp_file} + + +#radius to calculate tcool, not the cooling time! +rcool=`$base_path/analyze_mass_profile.py 500 c|grep ^r500|awk -F "=" '{print .048*$2}'` + +if [ $# -eq 2 ] +then + rm -f center_only_results.txt + $base_path/analyze_mass_profile.py 200 c |tee -a center_only_results.txt + $base_path/analyze_mass_profile.py 500 c |tee -a center_only_results.txt + $base_path/analyze_mass_profile.py 1500 c |tee -a center_only_results.txt + $base_path/analyze_mass_profile.py 2500 c |tee -a center_only_results.txt + $base_path/extract_tcool.py $rcool |tee -a center_only_results.txt + $base_path/fg_2500_500.py c |tee -a center_only_results.txt + exit +fi + + + +rm -f summary_shuffle_mass_profile.qdp +rm -f summary_overdensity.qdp +rm -f summary_mass_profile.qdp +rm -f summary_gas_mass_profile.qdp + +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +for i in `seq 1 100` +do + echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + #t_data_file=temp_shuffled_t.dat +#exit + if [ $t_profile_type == wang2012 ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} + else + echo temperature profile name invalid! + exit + fi + +#exit + echo >temp_sbp.cfg + + cat $sbp_cfg|while read l +do + if echo $l|grep sbp_file >/dev/null + then + echo sbp_file temp_shuffled_sbp.dat >>temp_sbp.cfg + elif echo $l|grep T_file >/dev/null + then + echo T_file ${T_file} >>temp_sbp.cfg + else + echo $l >>temp_sbp.cfg + fi + +done + +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file + +$base_path/fit_beta_sbp temp_sbp.cfg +$base_path/fit_nfw_mass mass_int.dat $z $nfw_rmin_kpc +cat nfw_dump.qdp >>summary_mass_profile.qdp +echo no no no >>summary_mass_profile.qdp + +cat overdensity.qdp >>summary_overdensity.qdp +echo no no no >>summary_overdensity.qdp + +cat gas_mass_int.qdp >>summary_gas_mass_profile.qdp +echo no no no >>summary_gas_mass_profile.qdp +done +#analys the errors +$base_path/analyze_mass_profile.py 200 +$base_path/analyze_mass_profile.py 500 +$base_path/analyze_mass_profile.py 1500 +$base_path/analyze_mass_profile.py 2500 + +r500=`$base_path/analyze_mass_profile.py 500|grep r500|awk '{print $2}'` +#$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r500 $t_data_file +r200=`$base_path/analyze_mass_profile.py 200|grep r200|awk '{print $2}'` +r1500=`$base_path/analyze_mass_profile.py 1500|grep r1500|awk '{print $2}'` +r2500=`$base_path/analyze_mass_profile.py 2500|grep r2500|awk '{print $2}'` +#$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r200 $t_data_file + +r500e=`$base_path/analyze_mass_profile.py 500|grep '^r500' 2>/dev/null|awk '{print $2,$3}'` +m500e=`$base_path/analyze_mass_profile.py 500|grep '^m500' 2>/dev/null|awk '{print $2,$3}'` +L500=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r500 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg500e=`$base_path/analyze_mass_profile.py 500|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg500e=`$base_path/analyze_mass_profile.py 500|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + + +r200e=`$base_path/analyze_mass_profile.py 200|grep '^r200' 2>/dev/null|awk '{print $2,$3}'` +m200e=`$base_path/analyze_mass_profile.py 200|grep '^m200' 2>/dev/null|awk '{print $2,$3}'` +L200=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r200 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg200e=`$base_path/analyze_mass_profile.py 200|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg200e=`$base_path/analyze_mass_profile.py 200|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + +r2500e=`$base_path/analyze_mass_profile.py 2500|grep '^r2500' 2>/dev/null|awk '{print $2,$3}'` +m2500e=`$base_path/analyze_mass_profile.py 2500|grep '^m2500' 2>/dev/null|awk '{print $2,$3}'` +L2500=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r2500 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg2500e=`$base_path/analyze_mass_profile.py 2500|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg2500e=`$base_path/analyze_mass_profile.py 2500|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + +r1500e=`$base_path/analyze_mass_profile.py 1500|grep '^r1500' 2>/dev/null|awk '{print $2,$3}'` +m1500e=`$base_path/analyze_mass_profile.py 1500|grep '^m1500' 2>/dev/null|awk '{print $2,$3}'` +L1500=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r1500 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg1500e=`$base_path/analyze_mass_profile.py 1500|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg1500e=`$base_path/analyze_mass_profile.py 1500|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + + + +echo "******************" +echo "Final results:" +echo "******************" +echo +echo + +rm -f final_result.txt +echo r500= $r500e kpc |tee -a final_result.txt +echo m500= $m500e M_sun |tee -a final_result.txt +echo L500= $L500 erg/s |tee -a final_result.txt +echo gas mass 500= $mg500e M_sun |tee -a final_result.txt +echo gas fractho 500= $fg500e x100% |tee -a final_result.txt + +echo r200= $r200e kpc |tee -a final_result.txt +echo m200= $m200e M_sun |tee -a final_result.txt +echo L200= $L200 erg/s |tee -a final_result.txt +echo gas mass 200= $mg200e M_sun |tee -a final_result.txt +echo gas fractho 200= $fg200e x100% |tee -a final_result.txt + +echo r1500= $r1500e kpc |tee -a final_result.txt +echo m1500= $m1500e M_sun |tee -a final_result.txt +echo L1500= $L1500 erg/s |tee -a final_result.txt +echo gas mass 1500= $mg1500e M_sun |tee -a final_result.txt +echo gas fractho 1500= $fg1500e x100% |tee -a final_result.txt + +echo r2500= $r2500e kpc |tee -a final_result.txt +echo m2500= $m2500e M_sun |tee -a final_result.txt +echo L2500= $L2500 erg/s |tee -a final_result.txt +echo gas mass 2500= $mg2500e M_sun |tee -a final_result.txt +echo gas fractho 2500= $fg2500e x100% |tee -a final_result.txt + +$base_path/extract_tcool.py $rcool |tee -a final_result.txt +$base_path/fg_2500_500.py |tee -a final_result.txt diff --git a/mass_profile/fit_beta_sbp.cpp b/mass_profile/fit_beta_sbp.cpp new file mode 100644 index 0000000..ce3b43a --- /dev/null +++ b/mass_profile/fit_beta_sbp.cpp @@ -0,0 +1,531 @@ +/* + Perform a double-beta density model fitting to the surface brightness data + Author: Junhua Gu + Last modified: 2011.01.01 + This code is distributed with no warrant +*/ + +#include <unistd.h> +#include <iostream> +#include <fstream> +#include <list> +#include <algorithm> +using namespace std; +#include "beta_cfg.hpp" +#include "dump_fit_qdp.hpp" +#include "report_error.hpp" +#include "vchisq.hpp" +#include "chisq.hpp" +#include "beta.hpp" +#include "models/beta1d.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <core/freeze_param.hpp> +#include <error_estimator/error_estimator.hpp> +#include "spline.h" +using namespace opt_utilities; +//double s=5.63136645E20; +const double kpc=3.086E21;//kpc in cm +const double Mpc=kpc*1000; +double beta_func(double r, + double n0,double rc,double beta) +{ + + return abs(n0)*pow(1+r*r/rc/rc,-3./2.*abs(beta)); +} + + + //calculate critical density from z, under following cosmological constants +static double calc_critical_density(double z, + const double H0=2.3E-18, + const double Omega_m=.27) +{ + const double G=6.673E-8;//cm^3 g^-1 s^2 + const double E=std::sqrt(Omega_m*(1+z)*(1+z)*(1+z)+1-Omega_m); + const double H=H0*E; + return 3*H*H/8/pi/G; +} + + +//A class enclosing the spline interpolation method of cooling function +//check spline.h for more detailed information +//this class is a thin wrapper for the spline class defined in spline.h +class spline_func_obj + :public func_obj<double,double> +{ + //has an spline object + spline<double> spl; +public: + //This function is used to calculate the intepolated value + double do_eval(const double& x) + { + 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); + } +}; + +int main(int argc,char* argv[]) +{ + if(argc!=2) + { + cerr<<argv[0]<<" <configure file>"<<endl; + return -1; + } + //initialize the parameters list + ifstream cfg_file(argv[1]); + assert(cfg_file.is_open()); + cfg_map cfg=parse_cfg_file(cfg_file); + + //check the existence of following parameters + + const double z=cfg.z; + + //initialize the radius list, sbp list and sbp error list + std::vector<double> radii; + std::vector<double> sbps; + std::vector<double> sbpe; + std::vector<double> radii_all; + std::vector<double> sbps_all; + std::vector<double> sbpe_all; + //read sbp and sbp error data + for(ifstream ifs(cfg.sbp_file.c_str());;) + { + assert(ifs.is_open()); + double x,xe; + ifs>>x>>xe; + if(!ifs.good()) + { + break; + } + if(x/xe<2) + { + break; + } + cerr<<x<<"\t"<<xe<<endl; + sbps.push_back(x); + sbpe.push_back(xe); + sbps_all.push_back(x); + sbpe_all.push_back(xe); + } + + //read radius data + for(ifstream ifs(cfg.radius_file.c_str());;) + { + assert(ifs.is_open()); + double x; + ifs>>x; + if(!ifs.good()) + { + break; + } + cerr<<x<<endl; + radii.push_back(x); + radii_all.push_back(x); + } + //initialize the cm/pixel value + double cm_per_pixel=cfg.cm_per_pixel; + double rmin=5*kpc/cm_per_pixel; + if(cfg.rmin_pixel>0) + { + rmin=cfg.rmin_pixel; + } + else + { + rmin=cfg.rmin_kpc*kpc/cm_per_pixel; + } + + cerr<<"rmin="<<rmin<<endl; + std::list<double> radii_tmp,sbps_tmp,sbpe_tmp; + radii_tmp.resize(radii.size()); + sbps_tmp.resize(sbps.size()); + sbpe_tmp.resize(sbpe.size()); + copy(radii.begin(),radii.end(),radii_tmp.begin()); + copy(sbps.begin(),sbps.end(),sbps_tmp.begin()); + copy(sbpe.begin(),sbpe.end(),sbpe_tmp.begin()); + for(list<double>::iterator i=radii_tmp.begin();i!=radii_tmp.end();) + { + if(*i<rmin) + { + radii_tmp.pop_front(); + sbps_tmp.pop_front(); + sbpe_tmp.pop_front(); + i=radii_tmp.begin(); + continue; + } + ++i; + } + radii.resize(radii_tmp.size()); + sbps.resize(sbps_tmp.size()); + sbpe.resize(sbpe_tmp.size()); + copy(radii_tmp.begin(),radii_tmp.end(),radii.begin()); + copy(sbps_tmp.begin(),sbps_tmp.end(),sbps.begin()); + copy(sbpe_tmp.begin(),sbpe_tmp.end(),sbpe.begin()); + + //read cooling function data + spline_func_obj cf; + for(ifstream ifs(cfg.cfunc_file.c_str());;) + { + assert(ifs.is_open()); + double x,y,y1,y2; + ifs>>x>>y; + if(!ifs.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; + if(x>radii.back()) + { + break; + } + //cf.add_point(x,y*2.1249719395939022e-68);//change with source + cf.add_point(x,y);//change with source + } + cf.gen_spline(); + + //read temperature profile data + spline_func_obj Tprof; + int tcnt=0; + for(ifstream ifs1(cfg.T_file.c_str());;++tcnt) + { + assert(ifs1.is_open()); + double x,y; + ifs1>>x>>y; + if(!ifs1.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; +#if 0 + if(tcnt==0) + { + Tprof.add_point(0,y); + } +#endif + Tprof.add_point(x,y); + } + + + Tprof.gen_spline(); + + default_data_set<std::vector<double>,std::vector<double> > ds; + ds.add_data(data<std::vector<double>,std::vector<double> >(radii,sbps,sbpe,sbpe,radii,radii)); + + //initial fitter + fitter<vector<double>,vector<double>,vector<double>,double> f; + f.load_data(ds); + //initial the object, which is used to calculate projection effect + projector<double> a; + beta<double> betao; + //attach the cooling function + a.attach_cfunc(cf); + a.set_cm_per_pixel(cm_per_pixel); + a.attach_model(betao); + f.set_model(a); + //chi^2 statistic + vchisq<double> c; + c.verbose(true); + c.set_limit(); + f.set_statistic(c); + //optimization method + f.set_opt_method(powell_method<double,std::vector<double> >()); + //initialize the initial values + double n0=0; + //double beta=atof(arg_map["beta"].c_str()); + double beta=0; + double rc=0; + double bkg=0; + + for(std::map<std::string,std::vector<double> >::iterator i=cfg.param_map.begin(); + i!=cfg.param_map.end();++i) + { + std::string pname=i->first; + f.set_param_value(pname,i->second.at(0)); + if(i->second.size()==3) + { + double a1=i->second[1]; + double a2=i->second[2]; + double u=std::max(a1,a2); + double l=std::min(a1,a2); + f.set_param_upper_limit(pname,u); + f.set_param_lower_limit(pname,l); + } + else + { + if(pname=="beta") + { + f.set_param_lower_limit(pname,.3); + f.set_param_upper_limit(pname,1.4); + } + } + } + + f.fit(); + f.fit(); + std::vector<double> p=f.get_all_params(); + n0=f.get_param_value("n0"); + rc=f.get_param_value("rc"); + beta=f.get_param_value("beta"); + //output the datasets and fitting results + ofstream param_output("beta_param.txt"); + for(int i=0;i<f.get_num_params();++i) + { + if(f.get_param_info(i).get_name()=="rc") + { + cerr<<"rc_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + param_output<<"rc_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + } + cerr<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + param_output<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + } + cerr<<"chi square="<<f.get_statistic_value()/(radii.size()-f.get_model().get_num_free_params())<<endl; + param_output<<"chi square="<<f.get_statistic_value()/(radii.size()-f.get_model().get_num_free_params())<<endl; + + std::vector<double> mv=f.eval_model_raw(radii_all,p); + int sbps_inner_cut_size=int(sbps_all.size()-sbps.size()); + ofstream ofs_sbp("sbp_fit.qdp"); + ofs_sbp<<"read serr 2"<<endl; + ofs_sbp<<"skip single"<<endl; + ofs_sbp<<"line off "<<endl; + if(sbps_inner_cut_size>=1) + { + ofs_sbp<<"line on 2"<<endl; + ofs_sbp<<"line on 3"<<endl; + ofs_sbp<<"line on 4"<<endl; + ofs_sbp<<"line on 5"<<endl; + ofs_sbp<<"ls 2 on 2"<<endl; + ofs_sbp<<"ls 2 on 4"<<endl; + ofs_sbp<<"ls 2 on 5"<<endl; + ofs_sbp<<"line on 7"<<endl; + ofs_sbp<<"ls 2 on 7"<<endl; + + ofs_sbp<<"ma 1 on 2"<<endl; + ofs_sbp<<"color 1 on 1"<<endl; + ofs_sbp<<"color 2 on 2"<<endl; + ofs_sbp<<"color 3 on 3"<<endl; + ofs_sbp<<"color 4 on 4"<<endl; + ofs_sbp<<"color 5 on 5"<<endl; + + ofs_sbp<<"win 1"<<endl; + ofs_sbp<<"yplot 1 2 3 4 5"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .4 .9 .9"<<endl; + ofs_sbp<<"la y cnt/s/pixel/cm^2"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[sbps.size()-2]+radii[sbps.size()-1])/2*cm_per_pixel/kpc<<endl; + ofs_sbp<<"win 2"<<endl; + ofs_sbp<<"yplot 6 7"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .1 .9 .4"<<endl; + ofs_sbp<<"la x radius (kpc)"<<endl; + ofs_sbp<<"la y chi"<<endl; + ofs_sbp<<"log y off"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[sbps.size()-2]+radii[sbps.size()-1])/2*cm_per_pixel/kpc<<endl; + } + else + { + ofs_sbp<<"line on 2"<<endl; + ofs_sbp<<"line on 3"<<endl; + ofs_sbp<<"line on 4"<<endl; + ofs_sbp<<"ls 2 on 3"<<endl; + ofs_sbp<<"ls 2 on 4"<<endl; + ofs_sbp<<"line on 6"<<endl; + ofs_sbp<<"ls 2 on 6"<<endl; + + ofs_sbp<<"color 1 on 1"<<endl; + ofs_sbp<<"color 3 on 2"<<endl; + ofs_sbp<<"color 4 on 3"<<endl; + ofs_sbp<<"color 5 on 4"<<endl; + //ofs_sbp<<"ma 1 on 2"<<endl; + + ofs_sbp<<"win 1"<<endl; + ofs_sbp<<"yplot 1 2 3 4"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .4 .9 .9"<<endl; + ofs_sbp<<"la y cnt/s/pixel/cm^2"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[radii.size()-2]+radii[radii.size()-1])/2*cm_per_pixel/kpc<<endl; + ofs_sbp<<"win 2"<<endl; + ofs_sbp<<"yplot 5 6"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .1 .9 .4"<<endl; + ofs_sbp<<"la x radius (kpc)"<<endl; + ofs_sbp<<"la y chi"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y off"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[radii.size()-2]+radii[radii.size()-1])/2*cm_per_pixel/kpc<<endl; + + } + // cout<<sbps_all.size()<<"\t"<<sbps.size()<<"\t"<<sbps_inner_cut_size<<endl; + for(int i=1;i<sbps_all.size();++i) + { + double x=(radii_all[i]+radii_all[i-1])/2; + double y=sbps_all[i-1]; + double ye=sbpe_all[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<y<<"\t"<<ye<<endl; + } + if(sbps_inner_cut_size>=1) + { + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps_inner_cut_size+1;++i) + { + double x=(radii_all[i]+radii_all[i-1])/2; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<ym<<"\t"<<"0"<<endl; + } + } + ofs_sbp<<"no no no"<<endl; + for(int i=sbps_inner_cut_size;i<sbps_all.size();++i) + { + double x=(radii_all[i]+radii_all[i-1])/2; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<ym<<"\t"<<"0"<<endl; + } + ofs_sbp<<"no no no"<<endl; + //bkg level + double bkg_level=abs(f.get_param_value("bkg")); + for(int i=0;i<sbps_all.size();++i) + { + double x=(radii_all[i]+radii_all[i-1])/2; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<bkg_level<<"\t0"<<endl; + } + ofs_sbp<<"no no no"<<endl; + //rc + double rc_kpc=abs(f.get_param_value("rc")*cm_per_pixel/kpc); + double max_sbp=*max_element(sbps_all.begin(),sbps_all.end()); + double min_sbp=*min_element(sbps_all.begin(),sbps_all.end()); + for(double x=min_sbp;x<=max_sbp;x+=(max_sbp-min_sbp)/100) + { + ofs_sbp<<rc_kpc<<"\t"<<x<<"\t"<<"0"<<endl; + } + //resid + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<(ym-sbps[i-1])/sbpe[i-1]<<"\t"<<1<<endl; + } + + //zero level of resid + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<0<<"\t"<<0<<endl; + } + + mv=betao.eval(radii,p); + ofstream ofs_rho("rho_fit.qdp"); + ofstream ofs_rho_data("rho_fit.dat"); + ofstream ofs_entropy("entropy.qdp"); + ofs_rho<<"la x radius (kpc)"<<endl; + ofs_rho<<"la y density (cm\\u-3\\d)"<<endl; + /* + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double ym=mv[i-1]; + ofs_rho<<x*cm_per_pixel/kpc<<"\t"<<ym<<endl; + } + */ + + double lower,upper; + double dr=1; + //calculate the mass profile + const double G=6.673E-8;//cm^3 g^-1 s^-2 + static const double mu=1.4074; + static const double mp=1.67262158E-24;//g + static const double M_sun=1.98892E33;//g + static const double k=1.38E-16; + + ofstream ofs_mass("mass_int.qdp"); + ofstream ofs_mass_dat("mass_int.dat"); + ofstream ofs_overdensity("overdensity.qdp"); + ofstream ofs_gas_mass("gas_mass_int.qdp"); + //ofs_mass<<"la x radius (kpc)"<<endl; + //ofs_mass<<"la y mass enclosed (solar mass)"<<endl; + //ofs_overdensity<<"la x radius (kpc)"<<endl; + //ofs_overdensity<<"la y overdensity"<<endl; + double gas_mass=0; + for(double r=1;r<200000;r+=dr) + { + dr=r/100; + double r1=r+dr; + double r_cm=r*cm_per_pixel; + double r1_cm=r1*cm_per_pixel; + double dr_cm=dr*cm_per_pixel; + double V_cm3=4./3.*pi*(dr_cm*(r1_cm*r1_cm+r_cm*r_cm+r_cm*r1_cm)); + double ne=beta_func(r,n0,rc,beta);//cm^-3 + + double dmgas=V_cm3*ne*mu*mp/M_sun; + gas_mass+=dmgas; + + ofs_gas_mass<<r*cm_per_pixel/kpc<<"\t"<<gas_mass<<endl; + double ne1=beta_func(r1,n0,rc,beta);//cm^3 + + double T_keV=Tprof(r); + double T1_keV=Tprof(r1); + + double T_K=T_keV*11604505.9; + double T1_K=T1_keV*11604505.9; + + double dlnT=log(T1_keV/T_keV); + double dlnr=log(r+dr)-log(r); + double dlnn=log(ne1/ne); + + double r_kpc=r_cm/kpc; + double r_Mpc=r_cm/Mpc; + //double M=-r_cm*T_K*k/G/mu/mp*(dlnT/dlnr+dlnn/dlnr); + //ref:http://adsabs.harvard.edu/abs/2012MNRAS.422.3503W + //Walker et al. 2012 + double M=-3.68E13*M_sun*T_keV*r_Mpc*(dlnT/dlnr+dlnn/dlnr); + double rho=M/(4./3.*pi*r_cm*r_cm*r_cm); + + double S=T_keV/pow(ne,2./3.); + //cout<<r<<"\t"<<M/M_sun<<endl; + //cout<<r<<"\t"<<T_keV<<endl; + + ofs_rho<<r*cm_per_pixel/kpc<<"\t"<<ne<<endl; + ofs_rho_data<<r*cm_per_pixel/kpc<<"\t"<<ne<<endl; + ofs_entropy<<r*cm_per_pixel/kpc<<"\t"<<S<<endl; +#if 0 + if(r*cm_per_pixel/kpc<5) + { + continue; + } +#endif + ofs_mass<<r*cm_per_pixel/kpc<<"\t"<<M/M_sun<<endl; + if(r<radii.at(sbps.size())) + { + ofs_mass_dat<<r*cm_per_pixel/kpc<<"\t0\t"<<M/M_sun<<"\t"<<M/M_sun*.1<<endl; + } + ofs_overdensity<<r*cm_per_pixel/kpc<<"\t"<<rho/calc_critical_density(z)<<endl; + + } +} diff --git a/mass_profile/fit_dbeta_entropy.sh b/mass_profile/fit_dbeta_entropy.sh new file mode 100755 index 0000000..3f1bbda --- /dev/null +++ b/mass_profile/fit_dbeta_entropy.sh @@ -0,0 +1,149 @@ +#!/bin/bash + +echo $# +if [ $# -eq 2 ] +then + : +else + echo "Usage:$0 <cfg file> <radius in kpc>" + exit +fi +export PGPLOT_FONT=`locate grfont.dat|head -1` + +cfg_file=$1 +base_path=`dirname $0` +echo $base_path +#initialize profile type name +t_profile_type=`grep t_profile $cfg_file|awk '{print $2}'` +#initialize data file name +t_data_file=`grep t_data_file $cfg_file|awk '{print $2}'` +#initialize sbp config file +sbp_cfg=`grep sbp_cfg $cfg_file|awk '{print $2}'` +#initialize the temperature profile file +T_file=`grep '^T_file' $sbp_cfg|awk '{print $2}'` +#echo $t_profile_type +cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` +#determine which temperature profile to be used, and fit the T profile +if [ $t_profile_type == zyy ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zyy_model $t_data_file $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} +elif [ $t_profile_type == m0603246 ] +then + $base_path/fit_m0603246 $t_data_file $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} +elif [ $t_profile_type == wang2012 ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} +elif [ $t_profile_type == allen ] +then + $base_path/fit_allen_model $t_data_file $cm_per_pixel + mv -f allen_dump.qdp ${T_file} +elif [ $t_profile_type == zzl ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zzl_model $t_data_file $t_param_file + mv -f zzl_dump.qdp ${T_file} +else + echo temperature profile name invalid! + exit +fi + +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{print $2}'` +z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` +abund=`grep '^abund' ${cfg_file} |awk '{print $2}'` +nh=`grep '^nh' ${cfg_file} |awk '{print $2}'` +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file +mv flux_cnt_ratio.txt flux_cnt_ratio_center_entropy.txt +#fit sbp +$base_path/fit_dbeta_sbp $sbp_cfg +echo $cfunc_file +#exit + +#store central valu +mv sbp_fit.qdp sbp_fit_center_entropy.qdp +mv mass_int.qdp mass_int_center_entropy.qdp +mv overdensity.qdp overdensity_center_entropy.qdp +mv gas_mass_int.qdp gas_mass_int_center_entropy.qdp +mv entropy.qdp entropy_center.qdp +sbp_data_file=`grep sbp_file $sbp_cfg|awk '{print $2}'` +radius_sbp_file=`grep radius_sbp_file ${cfg_file}|awk '{print $2}'` + +if [ x"$radius_sbp_file" == x ] +then + echo "Error, must have radius_sbp_file assigned, this file should be a 4-column file, which contains the radius, radius err, sbp, and sbp err" + exit +fi + +cat ${radius_sbp_file} | sed 's/#.*$//' | grep -Ev '^\s*$' > .tmp.txt +mv .tmp.txt ${radius_sbp_file} + +rm -f summary_entropy.qdp + +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +for i in `seq 1 100` +do + echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + +#exit + if [ $t_profile_type == zyy ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zyy_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} + elif [ $t_profile_type == m0603246 ] + then + $base_path/fit_m0603246 temp_shuffled_t.dat $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} + elif [ $t_profile_type == wang2012 ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} + elif [ $t_profile_type == allen ] + then + $base_path/fit_allen_model temp_shuffled_t.dat $cm_per_pixel + mv -f allen_dump.qdp ${T_file} + elif [ $t_profile_type == zzl ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zzl_model temp_shuffled_t.dat $t_param_file + mv -f zzl_dump.qdp ${T_file} + else + echo temperature profile name invalid! + exit + fi + +#exit + echo >temp_sbp.cfg + + cat $sbp_cfg|while read l +do + if echo $l|grep sbp_file >/dev/null + then + echo sbp_file temp_shuffled_sbp.dat >>temp_sbp.cfg + elif echo $l|grep T_file >/dev/null + then + echo T_file ${T_file} >>temp_sbp.cfg + else + echo $l >>temp_sbp.cfg + fi + +done + +#$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file + +$base_path/fit_dbeta_sbp temp_sbp.cfg + +cat entropy.qdp >>summary_entropy.qdp +echo no no no >>summary_entropy.qdp +done + +$base_path/analyze_entropy_profile.py $2 |tee entropy_result.txt + diff --git a/mass_profile/fit_dbeta_mass_profile.sh b/mass_profile/fit_dbeta_mass_profile.sh new file mode 100755 index 0000000..a57c3a8 --- /dev/null +++ b/mass_profile/fit_dbeta_mass_profile.sh @@ -0,0 +1,198 @@ +#!/bin/bash + +echo $# +if [ $# -eq 1 ] +then + : +else + echo "Usage:$0 <cfg file>" + exit +fi +export PGPLOT_FONT=`locate grfont.dat|head -1` + +cfg_file=$1 +base_path=`dirname $0` +echo $base_path +#initialize profile type name +t_profile_type=`grep t_profile $cfg_file|awk '{print $2}'` +#initialize data file name +t_data_file=`grep t_data_file $cfg_file|awk '{print $2}'` +#initialize sbp config file +sbp_cfg=`grep sbp_cfg $cfg_file|awk '{print $2}'` +#initialize the temperature profile file +T_file=`grep '^T_file' $sbp_cfg|awk '{print $2}'` +#echo $t_profile_type +cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` +#determine which temperature profile to be used, and fit the T profile +if [ $t_profile_type == zyy ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zyy_model $t_data_file $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} +elif [ $t_profile_type == m0603246 ] +then + $base_path/fit_m0603246 $t_data_file $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} +elif [ $t_profile_type == wang2012 ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} +elif [ $t_profile_type == allen ] +then + $base_path/fit_allen_model $t_data_file $cm_per_pixel + mv -f allen_dump.qdp ${T_file} +elif [ $t_profile_type == zzl ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zzl_model $t_data_file $t_param_file + mv -f zzl_dump.qdp ${T_file} +else + echo temperature profile name invalid! + exit +fi + +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{print $2}'` +z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` +abund=`grep '^abund' ${cfg_file} |awk '{print $2}'` +nh=`grep '^nh' ${cfg_file} |awk '{print $2}'` +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file +mv flux_cnt_ratio.txt flux_cnt_ratio_center.txt +#fit sbp +$base_path/fit_dbeta_sbp $sbp_cfg +echo $cfunc_file +#exit + +#store central valu +mv sbp_fit.qdp sbp_fit_center.qdp +mv mass_int.qdp mass_int_center.qdp +mv overdensity.qdp overdensity_center.qdp +mv gas_mass_int.qdp gas_mass_int_center.qdp +sbp_data_file=`grep sbp_file $sbp_cfg|awk '{print $2}'` +radius_sbp_file=`grep radius_sbp_file ${cfg_file}|awk '{print $2}'` + +if [ x"$radius_sbp_file" == x ] +then + echo "Error, must have radius_sbp_file assigned, this file should be a 4-column file, which contains the radius, radius err, sbp, and sbp err" + exit +fi + +cat ${radius_sbp_file} | sed 's/#.*$//' | grep -Ev '^\s*$' > .tmp.txt +mv .tmp.txt ${radius_sbp_file} + +rm -f summary_shuffle_mass_profile.qdp +rm -f summary_overdensity.qdp +rm -f summary_mass_profile.qdp +rm -f summary_gas_mass_profile.qdp + +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +for i in `seq 1 100` +do + echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + +#exit + if [ $t_profile_type == zyy ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zyy_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} + elif [ $t_profile_type == m0603246 ] + then + $base_path/fit_m0603246 temp_shuffled_t.dat $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} + elif [ $t_profile_type == wang2012 ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} + elif [ $t_profile_type == allen ] + then + $base_path/fit_allen_model temp_shuffled_t.dat $cm_per_pixel + mv -f allen_dump.qdp ${T_file} + elif [ $t_profile_type == zzl ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_zzl_model temp_shuffled_t.dat $t_param_file + mv -f zzl_dump.qdp ${T_file} + else + echo temperature profile name invalid! + exit + fi + +#exit + echo >temp_sbp.cfg + + cat $sbp_cfg|while read l +do + if echo $l|grep sbp_file >/dev/null + then + echo sbp_file temp_shuffled_sbp.dat >>temp_sbp.cfg + elif echo $l|grep T_file >/dev/null + then + echo T_file ${T_file} >>temp_sbp.cfg + else + echo $l >>temp_sbp.cfg + fi + +done + +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file + +$base_path/fit_dbeta_sbp temp_sbp.cfg +cat mass_int.qdp >>summary_mass_profile.qdp +echo no no no >>summary_mass_profile.qdp + +cat overdensity.qdp >>summary_overdensity.qdp +echo no no no >>summary_overdensity.qdp + +cat gas_mass_int.qdp >>summary_gas_mass_profile.qdp +echo no no no >>summary_gas_mass_profile.qdp +done +#analys the errors +$base_path/analyze_mass_profile.py 200 +$base_path/analyze_mass_profile.py 500 +$base_path/analyze_mass_profile.py 1500 +#$base_path/analyze_mass_profile.py 2500 + +r500=`$base_path/analyze_mass_profile.py 500|grep r500|awk '{print $2}'` +#$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r500 $t_data_file +r200=`$base_path/analyze_mass_profile.py 200|grep r200|awk '{print $2}'` +#$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r200 $t_data_file + +r500e=`$base_path/analyze_mass_profile.py 500|grep '^r500' 2>/dev/null|awk '{print $2,$3}'` +m500e=`$base_path/analyze_mass_profile.py 500|grep '^m500' 2>/dev/null|awk '{print $2,$3}'` +L500=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r500 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg500e=`$base_path/analyze_mass_profile.py 500|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg500e=`$base_path/analyze_mass_profile.py 500|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + + +r200e=`$base_path/analyze_mass_profile.py 200|grep '^r200' 2>/dev/null|awk '{print $2,$3}'` +m200e=`$base_path/analyze_mass_profile.py 200|grep '^m200' 2>/dev/null|awk '{print $2,$3}'` +L200=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r200 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg200e=`$base_path/analyze_mass_profile.py 200|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg200e=`$base_path/analyze_mass_profile.py 200|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + + + +echo "******************" +echo "Final results:" +echo "******************" +echo +echo + +echo r500= $r500e kpc +echo m500= $m500e M_sun +echo L500= $L500 erg/s +echo gas mass 500= $mg500e M_sun +echo gas fractho 500= $fg500e x100% + +echo r200= $r200e kpc +echo m200= $m200e M_sun +echo L200= $L200 erg/s +echo gas mass 200= $mg200e M_sun +echo gas fractho 200= $fg200e x100% + + diff --git a/mass_profile/fit_dbeta_nfw_mass_profile.sh b/mass_profile/fit_dbeta_nfw_mass_profile.sh new file mode 100755 index 0000000..76c6420 --- /dev/null +++ b/mass_profile/fit_dbeta_nfw_mass_profile.sh @@ -0,0 +1,224 @@ +#!/bin/bash + +echo $# +if [ $# -gt 0 ] +then + : +else + echo "Usage:$0 <cfg file> [c]" + echo "If central value only, append a \"c\"" + exit +fi +export PGPLOT_FONT=`locate grfont.dat|head -1` + +cfg_file=$1 +base_path=`dirname $0` +echo $base_path +#initialize profile type name +t_profile_type=`grep t_profile $cfg_file|awk '{print $2}'` +#initialize data file name +t_data_file=`grep t_data_file $cfg_file|awk '{print $2}'` +#initialize sbp config file +sbp_cfg=`grep sbp_cfg $cfg_file|awk '{print $2}'` +#initialize the temperature profile file +T_file=`grep '^T_file' $sbp_cfg|awk '{print $2}'` +#initialize the rmin_kpc for nfw mass profile fitting +nfw_rmin_kpc=`grep '^nfw_rmin_kpc' $cfg_file|awk '{print $2}'` +#echo $t_profile_type +cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` +da=`python -c "print($cm_per_pixel/(.492/3600/180*3.1415926))"` + +#determine which temperature profile to be used, and fit the T profile +if [ $t_profile_type == wang2012 ] +then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} +else + echo temperature profile name invalid! + exit +fi + +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{print $2}'` +z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` +dl=`python -c "print($da*(1+$z)**2)"` +abund=`grep '^abund' ${cfg_file} |awk '{print $2}'` +nh=`grep '^nh' ${cfg_file} |awk '{print $2}'` +$base_path/coolfunc_calc_bolo.sh ${T_file} $abund $nh $z cfunc_bolo.dat +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file +mv flux_cnt_ratio.txt flux_cnt_ratio_center.txt +#fit sbp +$base_path/fit_dbeta_sbp $sbp_cfg +$base_path/fit_nfw_mass mass_int.dat $z $nfw_rmin_kpc +echo $cfunc_file +#exit + +#store central value +mv sbp_fit.qdp sbp_fit_center.qdp +mv nfw_dump.qdp mass_int_center.qdp +mv overdensity.qdp overdensity_center.qdp +mv gas_mass_int.qdp gas_mass_int_center.qdp +mv nfw_param.txt nfw_param_center.qdp +mv dbeta_param.txt dbeta_param_center.txt +mv rho_fit.dat rho_fit_center.dat + +#calculate cooling time +echo $dl +$base_path/cooling_time rho_fit_center.dat $T_file cfunc_bolo.dat $dl $cm_per_pixel >cooling_time.dat + +sbp_data_file=`grep sbp_file $sbp_cfg|awk '{print $2}'` +radius_sbp_file=`grep radius_sbp_file ${cfg_file}|awk '{print $2}'` + +if [ x"$radius_sbp_file" == x ] +then + echo "Error, must have radius_sbp_file assigned, this file should be a 4-column file, which contains the radius, radius err, sbp, and sbp err" + exit +fi + +cat ${radius_sbp_file} | sed 's/#.*$//' | grep -Ev '^\s*$' > .tmp.txt +mv .tmp.txt ${radius_sbp_file} + +#radius to calculate tcool, not the cooling time! +rcool=`$base_path/analyze_mass_profile.py 500 c|grep ^r500|awk -F "=" '{print .048*$2}'` +if [ $# -eq 2 ] +then + rm -f center_only_results.txt + $base_path/analyze_mass_profile.py 200 c |tee -a center_only_results.txt + $base_path/analyze_mass_profile.py 500 c |tee -a center_only_results.txt + $base_path/analyze_mass_profile.py 1500 c |tee -a center_only_results.txt + $base_path/analyze_mass_profile.py 2500 c |tee -a center_only_results.txt + $base_path/extract_tcool.py $rcool |tee -a center_only_results.txt + $base_path/fg_2500_500.py c |tee -a center_only_results.txt + exit +fi + + + +rm -f summary_shuffle_mass_profile.qdp +rm -f summary_overdensity.qdp +rm -f summary_mass_profile.qdp +rm -f summary_gas_mass_profile.qdp + +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +for i in `seq 1 100` +do + echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + #t_data_file=temp_shuffled_t.dat +#exit + if [ $t_profile_type == wang2012 ] + then + t_param_file=`grep t_param_file $cfg_file|awk '{print $2}'` + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f wang2012_dump.qdp ${T_file} + else + echo temperature profile name invalid! + exit + fi + +#exit + echo >temp_sbp.cfg + + cat $sbp_cfg|while read l +do + if echo $l|grep sbp_file >/dev/null + then + echo sbp_file temp_shuffled_sbp.dat >>temp_sbp.cfg + elif echo $l|grep T_file >/dev/null + then + echo T_file ${T_file} >>temp_sbp.cfg + else + echo $l >>temp_sbp.cfg + fi + +done + +$base_path/coolfunc_calc.sh ${T_file} $abund $nh $z $cfunc_file + +$base_path/fit_dbeta_sbp temp_sbp.cfg +$base_path/fit_nfw_mass mass_int.dat $z $nfw_rmin_kpc +cat nfw_dump.qdp >>summary_mass_profile.qdp +echo no no no >>summary_mass_profile.qdp + +cat overdensity.qdp >>summary_overdensity.qdp +echo no no no >>summary_overdensity.qdp + +cat gas_mass_int.qdp >>summary_gas_mass_profile.qdp +echo no no no >>summary_gas_mass_profile.qdp +done +#analys the errors +$base_path/analyze_mass_profile.py 200 +$base_path/analyze_mass_profile.py 500 +$base_path/analyze_mass_profile.py 1500 +$base_path/analyze_mass_profile.py 2500 + +r500=`$base_path/analyze_mass_profile.py 500|grep r500|awk '{print $2}'` +#$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r500 $t_data_file +r200=`$base_path/analyze_mass_profile.py 200|grep r200|awk '{print $2}'` +r1500=`$base_path/analyze_mass_profile.py 1500|grep r1500|awk '{print $2}'` +r2500=`$base_path/analyze_mass_profile.py 2500|grep r2500|awk '{print $2}'` +#$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r200 $t_data_file + +r500e=`$base_path/analyze_mass_profile.py 500|grep '^r500' 2>/dev/null|awk '{print $2,$3}'` +m500e=`$base_path/analyze_mass_profile.py 500|grep '^m500' 2>/dev/null|awk '{print $2,$3}'` +L500=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r500 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg500e=`$base_path/analyze_mass_profile.py 500|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg500e=`$base_path/analyze_mass_profile.py 500|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + + +r200e=`$base_path/analyze_mass_profile.py 200|grep '^r200' 2>/dev/null|awk '{print $2,$3}'` +m200e=`$base_path/analyze_mass_profile.py 200|grep '^m200' 2>/dev/null|awk '{print $2,$3}'` +L200=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r200 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg200e=`$base_path/analyze_mass_profile.py 200|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg200e=`$base_path/analyze_mass_profile.py 200|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + +r1500e=`$base_path/analyze_mass_profile.py 1500|grep '^r1500' 2>/dev/null|awk '{print $2,$3}'` +m1500e=`$base_path/analyze_mass_profile.py 1500|grep '^m1500' 2>/dev/null|awk '{print $2,$3}'` +L1500=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r1500 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg1500e=`$base_path/analyze_mass_profile.py 1500|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg1500e=`$base_path/analyze_mass_profile.py 1500|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + +r2500e=`$base_path/analyze_mass_profile.py 2500|grep '^r2500' 2>/dev/null|awk '{print $2,$3}'` +m2500e=`$base_path/analyze_mass_profile.py 2500|grep '^m2500' 2>/dev/null|awk '{print $2,$3}'` +L2500=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $r2500 Tprofile.dat 2>/dev/null|awk '{print $2,$3,$4}'` +mg2500e=`$base_path/analyze_mass_profile.py 2500|grep '^gas_m' 2>/dev/null|awk '{print $2,$3}'` +fg2500e=`$base_path/analyze_mass_profile.py 2500|grep '^gas_fraction' 2>/dev/null|awk '{print $2,$3}'` + + + +echo "******************" +echo "Final results:" +echo "******************" +echo +echo + +rm -f final_result.txt +echo r500= $r500e kpc |tee -a final_result.txt +echo m500= $m500e M_sun |tee -a final_result.txt +echo L500= $L500 erg/s |tee -a final_result.txt +echo gas mass 500= $mg500e M_sun |tee -a final_result.txt +echo gas fractho 500= $fg500e x100% |tee -a final_result.txt + +echo r200= $r200e kpc |tee -a final_result.txt +echo m200= $m200e M_sun |tee -a final_result.txt +echo L200= $L200 erg/s |tee -a final_result.txt +echo gas mass 200= $mg200e M_sun |tee -a final_result.txt +echo gas fractho 200= $fg200e x100% |tee -a final_result.txt + +echo r1500= $r1500e kpc |tee -a final_result.txt +echo m1500= $m1500e M_sun |tee -a final_result.txt +echo L1500= $L1500 erg/s |tee -a final_result.txt +echo gas mass 1500= $mg1500e M_sun |tee -a final_result.txt +echo gas fractho 1500= $fg1500e x100% |tee -a final_result.txt + + +echo r2500= $r2500e kpc |tee -a final_result.txt +echo m2500= $m2500e M_sun |tee -a final_result.txt +echo L2500= $L2500 erg/s |tee -a final_result.txt +echo gas mass 2500= $mg2500e M_sun |tee -a final_result.txt +echo gas fractho 2500= $fg2500e x100% |tee -a final_result.txt + +$base_path/extract_tcool.py $rcool |tee -a final_result.txt +$base_path/fg_2500_500.py |tee -a final_result.txt diff --git a/mass_profile/fit_dbeta_sbp.cpp b/mass_profile/fit_dbeta_sbp.cpp new file mode 100644 index 0000000..b74dc0c --- /dev/null +++ b/mass_profile/fit_dbeta_sbp.cpp @@ -0,0 +1,585 @@ +/* + Perform a double-beta density model fitting to the surface brightness data + Author: Junhua Gu + Last modified: 2011.01.01 + This code is distributed with no warrant +*/ + + +#include <iostream> +#include <fstream> +#include <list> +using namespace std; +#include "vchisq.hpp" +#include "dbeta.hpp" +#include "beta_cfg.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <core/freeze_param.hpp> +#include <error_estimator/error_estimator.hpp> +#include "spline.h" +using namespace opt_utilities; +//double s=5.63136645E20; +const double kpc=3.086E21;//kpc in cm +const double Mpc=kpc*1000; +double dbeta_func(double r, + double n01,double rc1,double beta1, + double n02,double rc2,double beta2) +{ + + return abs(n01)*pow(1+r*r/rc1/rc1,-3./2.*abs(beta1))+abs(n02)*pow(1+r*r/rc2/rc2,-3./2.*abs(beta2)); +} + + + //calculate critical density from z, under following cosmological constants +static double calc_critical_density(double z, + const double H0=2.3E-18, + const double Omega_m=.27) +{ + const double G=6.673E-8;//cm^3 g^-1 s^2 + const double E=std::sqrt(Omega_m*(1+z)*(1+z)*(1+z)+1-Omega_m); + const double H=H0*E; + return 3*H*H/8/pi/G; +} + + +//A class enclosing the spline interpolation method of cooling function +//check spline.h for more detailed information +//this class is a thin wrapper for the spline class defined in spline.h +class spline_func_obj + :public func_obj<double,double> +{ + //has an spline object + spline<double> spl; +public: + //This function is used to calculate the intepolated value + double do_eval(const double& x) + { + 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); + } +}; + +int main(int argc,char* argv[]) +{ + if(argc!=2) + { + cerr<<argv[0]<<" <configure file>"<<endl; + return -1; + } + //initialize the parameters list + ifstream cfg_file(argv[1]); + assert(cfg_file.is_open()); + cfg_map cfg=parse_cfg_file(cfg_file); + + //check the existence of following parameters + + const double z=cfg.z; + + //initialize the radius list, sbp list and sbp error list + std::vector<double> radii; + std::vector<double> sbps; + std::vector<double> sbpe; + std::vector<double> radii_all; + std::vector<double> sbps_all; + std::vector<double> sbpe_all; + //read sbp and sbp error data + for(ifstream ifs(cfg.sbp_file.c_str());;) + { + assert(ifs.is_open()); + double x,xe; + ifs>>x>>xe; + if(!ifs.good()) + { + break; + } + if(x/xe<2) + { + break; + } + cerr<<x<<"\t"<<xe<<endl; + sbps.push_back(x); + sbpe.push_back(xe); + sbps_all.push_back(x); + sbpe_all.push_back(xe); + } + + //read radius data + for(ifstream ifs(cfg.radius_file.c_str());;) + { + assert(ifs.is_open()); + double x; + ifs>>x; + if(!ifs.good()) + { + break; + } + cerr<<x<<endl; + radii.push_back(x); + radii_all.push_back(x); + } + //initialize the cm/pixel value + double cm_per_pixel=cfg.cm_per_pixel; + double rmin=5*kpc/cm_per_pixel; + if(cfg.rmin_pixel>0) + { + rmin=cfg.rmin_pixel; + } + else + { + rmin=cfg.rmin_kpc*kpc/cm_per_pixel; + } + + cerr<<"rmin="<<rmin<<endl; + std::list<double> radii_tmp,sbps_tmp,sbpe_tmp; + radii_tmp.resize(radii.size()); + sbps_tmp.resize(sbps.size()); + sbpe_tmp.resize(sbpe.size()); + copy(radii.begin(),radii.end(),radii_tmp.begin()); + copy(sbps.begin(),sbps.end(),sbps_tmp.begin()); + copy(sbpe.begin(),sbpe.end(),sbpe_tmp.begin()); + for(list<double>::iterator i=radii_tmp.begin();i!=radii_tmp.end();) + { + if(*i<rmin) + { + radii_tmp.pop_front(); + sbps_tmp.pop_front(); + sbpe_tmp.pop_front(); + i=radii_tmp.begin(); + continue; + } + ++i; + } + radii.resize(radii_tmp.size()); + sbps.resize(sbps_tmp.size()); + sbpe.resize(sbpe_tmp.size()); + copy(radii_tmp.begin(),radii_tmp.end(),radii.begin()); + copy(sbps_tmp.begin(),sbps_tmp.end(),sbps.begin()); + copy(sbpe_tmp.begin(),sbpe_tmp.end(),sbpe.begin()); + + //read cooling function data + spline_func_obj cf; + for(ifstream ifs(cfg.cfunc_file.c_str());;) + { + assert(ifs.is_open()); + double x,y,y1,y2; + ifs>>x>>y; + if(!ifs.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; + if(x>radii.back()) + { + break; + } + //cf.add_point(x,y*2.1249719395939022e-68);//change with source + cf.add_point(x,y);//change with source + } + cf.gen_spline(); + + //read temperature profile data + spline_func_obj Tprof; + int tcnt=0; + for(ifstream ifs1(cfg.T_file.c_str());;++tcnt) + { + assert(ifs1.is_open()); + double x,y; + ifs1>>x>>y; + if(!ifs1.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; +#if 0 + if(tcnt==0) + { + Tprof.add_point(0,y); + } +#endif + Tprof.add_point(x,y); + } + + + Tprof.gen_spline(); + + default_data_set<std::vector<double>,std::vector<double> > ds; + ds.add_data(data<std::vector<double>,std::vector<double> >(radii,sbps,sbpe,sbpe,radii,radii)); + + //initial fitter + fitter<vector<double>,vector<double>,vector<double>,double> f; + f.load_data(ds); + //initial the object, which is used to calculate projection effect + projector<double> a; + bool tie_beta=false; + if(cfg.param_map.find("beta")!=cfg.param_map.end() + &&cfg.param_map.find("beta1")==cfg.param_map.end() + &&cfg.param_map.find("beta2")==cfg.param_map.end()) + { + dbeta2<double> dbetao; + a.attach_model(dbetao); + tie_beta=true; + } + else if((cfg.param_map.find("beta1")!=cfg.param_map.end() + ||cfg.param_map.find("beta2")!=cfg.param_map.end()) + &&cfg.param_map.find("beta")==cfg.param_map.end()) + { + dbeta<double> dbetao; + a.attach_model(dbetao); + tie_beta=false; + } + else + { + cerr<<"Error, cannot decide whether to tie beta together or let them vary freely!"<<endl; + assert(0); + } + + //attach the cooling function + a.attach_cfunc(cf); + a.set_cm_per_pixel(cm_per_pixel); + + f.set_model(a); + //chi^2 statistic + vchisq<double> c; + c.verbose(true); + c.set_limit(); + f.set_statistic(c); + //optimization method + f.set_opt_method(powell_method<double,std::vector<double> >()); + //initialize the initial values + double n01=0; + double rc1=0; + double n02=0; + double rc2=0; + double beta=0; + double bkg=0; + if(tie_beta) + { + f.set_param_value("beta",.7); + f.set_param_lower_limit("beta",.3); + f.set_param_upper_limit("beta",1.4); + } + else + { + f.set_param_value("beta1",.7); + f.set_param_lower_limit("beta1",.3); + f.set_param_upper_limit("beta1",1.4); + f.set_param_value("beta2",.7); + f.set_param_lower_limit("beta2",.3); + f.set_param_upper_limit("beta2",1.4); + } + for(std::map<std::string,std::vector<double> >::iterator i=cfg.param_map.begin(); + i!=cfg.param_map.end();++i) + { + std::string pname=i->first; + f.set_param_value(pname,i->second.at(0)); + if(i->second.size()==3) + { + double a1=i->second[1]; + double a2=i->second[2]; + double u=std::max(a1,a2); + double l=std::min(a1,a2); + f.set_param_upper_limit(pname,u); + f.set_param_lower_limit(pname,l); + } + else + { + if(pname=="beta"||pname=="beta1"||pname=="beta2") + { + f.set_param_lower_limit(pname,.3); + f.set_param_upper_limit(pname,1.4); + } + } + } + + + + //perform the fitting, first freeze beta1, beta2, rc1, and rc2 + if(tie_beta) + { + f.set_param_modifier(freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("beta")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("rc1")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("rc2") + ); + } + else + { + f.set_param_modifier(freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("beta1")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("beta2")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("rc1")+ + freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("rc2") + ); + } + + f.fit(); + + f.clear_param_modifier(); + + //then perform the fitting, freeze beta1 and beta2 + //f.set_param_modifier(freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("beta")); + //f.set_param_modifier(freeze_param<std::vector<double>,std::vector<double>,std::vector<double>,std::string>("bkg")); + f.fit(); + //f.clear_param_modifier(); + + //finally thaw all parameters + f.fit(); + double beta1=0; + double beta2=0; + + n01=f.get_param_value("n01"); + rc1=f.get_param_value("rc1"); + n02=f.get_param_value("n02"); + rc2=f.get_param_value("rc2"); + if(tie_beta) + { + beta=f.get_param_value("beta"); + beta1=beta; + beta2=beta; + } + else + { + beta1=f.get_param_value("beta1"); + beta2=f.get_param_value("beta2"); + } + //output the params + ofstream param_output("dbeta_param.txt"); + //output the datasets and fitting results + for(int i=0;i<f.get_num_params();++i) + { + if(f.get_param_info(i).get_name()=="rc1") + { + cerr<<"rc1_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + param_output<<"rc1_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + } + if(f.get_param_info(i).get_name()=="rc2") + { + cerr<<"rc2_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + param_output<<"rc2_kpc"<<"\t"<<abs(f.get_param_info(i).get_value())*cm_per_pixel/kpc<<endl; + } + cerr<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + param_output<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + } + cerr<<"chi square="<<f.get_statistic_value()/(radii.size()-f.get_model().get_num_free_params())<<endl; + param_output<<"chi square="<<f.get_statistic_value()/(radii.size()-f.get_model().get_num_free_params())<<endl; + + //c.verbose(false); + //f.set_statistic(c); + //f.fit(); + std::vector<double> p=f.get_all_params(); + f.clear_param_modifier(); + std::vector<double> mv=f.eval_model(radii,p); + + + ofstream ofs_sbp("sbp_fit.qdp"); + ofs_sbp<<"read serr 2"<<endl; + ofs_sbp<<"skip single"<<endl; + + ofs_sbp<<"line on 2"<<endl; + ofs_sbp<<"line on 3"<<endl; + ofs_sbp<<"line on 4"<<endl; + ofs_sbp<<"line on 5"<<endl; + ofs_sbp<<"line on 7"<<endl; + ofs_sbp<<"ls 2 on 7"<<endl; + ofs_sbp<<"ls 2 on 3"<<endl; + ofs_sbp<<"ls 2 on 4"<<endl; + ofs_sbp<<"ls 2 on 5"<<endl; + + + + ofs_sbp<<"!LAB POS Y 4.00"<<endl; + ofs_sbp<<"!LAB ROT"<<endl; + ofs_sbp<<"win 1"<<endl; + ofs_sbp<<"yplot 1 2 3 4 5"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .4 .9 .9"<<endl; + ofs_sbp<<"la y cnt/s/pixel/cm^2"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[sbps.size()-2]+radii[sbps.size()-1])/2*cm_per_pixel/kpc<<endl; + ofs_sbp<<"win 2"<<endl; + ofs_sbp<<"yplot 6 7"<<endl; + ofs_sbp<<"loc 0 0 1 1"<<endl; + ofs_sbp<<"vie .1 .1 .9 .4"<<endl; + ofs_sbp<<"la x radius (kpc)"<<endl; + ofs_sbp<<"la y chi"<<endl; + ofs_sbp<<"log x"<<endl; + ofs_sbp<<"log y off"<<endl; + ofs_sbp<<"r x "<<(radii[1]+radii[0])/2*cm_per_pixel/kpc<<" "<<(radii[sbps.size()-2]+radii[sbps.size()-1])/2*cm_per_pixel/kpc<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<y<<"\t"<<ye<<endl; + } + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<ym<<"\t"<<0<<endl; + } + //bkg + ofs_sbp<<"no no no"<<endl; + double bkg_level=abs(f.get_param_value("bkg")); + for(int i=0;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<bkg_level<<"\t0"<<endl; + } + //rc1 + ofs_sbp<<"no no no"<<endl; + double rc1_kpc=abs(f.get_param_value("rc1")*cm_per_pixel/kpc); + double max_sbp=*max_element(sbps.begin(),sbps.end()); + double min_sbp=*min_element(sbps.begin(),sbps.end()); + for(double x=min_sbp;x<=max_sbp;x+=(max_sbp-min_sbp)/100) + { + ofs_sbp<<rc1_kpc<<"\t"<<x<<"\t"<<"0"<<endl; + } + //rc2 + ofs_sbp<<"no no no"<<endl; + double rc2_kpc=abs(f.get_param_value("rc2")*cm_per_pixel/kpc); + for(double x=min_sbp;x<=max_sbp;x+=(max_sbp-min_sbp)/100) + { + ofs_sbp<<rc2_kpc<<"\t"<<x<<"\t"<<"0"<<endl; + } + //resid + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<(ym-sbps[i-1])/sbpe[i-1]<<"\t"<<1<<endl; + } + //zero level in resid map + ofs_sbp<<"no no no"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<0<<"\t"<<0<<endl; + } + + + mv=f.eval_model_raw(radii,p); + ofstream ofs_rho("rho_fit.qdp"); + ofstream ofs_rho_data("rho_fit.dat"); + ofstream ofs_entropy("entropy.qdp"); + ofs_rho<<"la x radius (kpc)"<<endl; + ofs_rho<<"la y density (cm\\u-3\\d)"<<endl; + /* + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double ym=mv[i-1]; + ofs_rho<<x*cm_per_pixel/kpc<<"\t"<<ym<<endl; + } + */ + + double lower,upper; + double dr=1; + //calculate the mass profile + const double G=6.673E-8;//cm^3 g^-1 s^-2 + static const double mu=1.4074; + static const double mp=1.67262158E-24;//g + static const double M_sun=1.98892E33;//g + static const double k=1.38E-16; + + ofstream ofs_mass("mass_int.qdp"); + ofstream ofs_mass_dat("mass_int.dat"); + ofstream ofs_overdensity("overdensity.qdp"); + ofstream ofs_gas_mass("gas_mass_int.qdp"); + //ofs_mass<<"la x radius (kpc)"<<endl; + //ofs_mass<<"la y mass enclosed (solar mass)"<<endl; + //ofs_overdensity<<"la x radius (kpc)"<<endl; + //ofs_overdensity<<"la y overdensity"<<endl; + double gas_mass=0; + for(double r=1;r<200000;r+=dr) + { + dr=r/100; + double r1=r+dr; + double r_cm=r*cm_per_pixel; + double r1_cm=r1*cm_per_pixel; + double dr_cm=dr*cm_per_pixel; + double V_cm3=4./3.*pi*(dr_cm*(r1_cm*r1_cm+r_cm*r_cm+r_cm*r1_cm)); + double ne=dbeta_func(r,n01,rc1,beta1, + n02,rc2,beta2);//cm^3 + + double dmgas=V_cm3*ne*mu*mp/M_sun; + gas_mass+=dmgas; + + ofs_gas_mass<<r*cm_per_pixel/kpc<<"\t"<<gas_mass<<endl; + double ne_beta1=dbeta_func(r,n01,rc1,beta1, + 0,rc2,beta2); + + double ne_beta2=dbeta_func(r,0,rc1,beta1, + n02,rc2,beta2); + + double ne1=dbeta_func(r1,n01,rc1,beta1, + n02,rc2,beta2);//cm^3 + + double T_keV=Tprof(r); + double T1_keV=Tprof(r1); + + double T_K=T_keV*11604505.9; + double T1_K=T1_keV*11604505.9; + + double dlnT=log(T1_keV/T_keV); + double dlnr=log(r+dr)-log(r); + double dlnn=log(ne1/ne); + + double r_kpc=r_cm/kpc; + double r_Mpc=r_cm/Mpc; + //double M=-r_cm*T_K*k/G/mu/mp*(dlnT/dlnr+dlnn/dlnr); + //ref:http://adsabs.harvard.edu/abs/2012MNRAS.422.3503W + //Walker et al. 2012 + double M=-3.68E13*M_sun*T_keV*r_Mpc*(dlnT/dlnr+dlnn/dlnr); + double rho=M/(4./3.*pi*r_cm*r_cm*r_cm); + + double S=T_keV/pow(ne,2./3.); + //cout<<r<<"\t"<<M/M_sun<<endl; + //cout<<r<<"\t"<<T_keV<<endl; + + ofs_rho<<r*cm_per_pixel/kpc<<"\t"<<ne<<"\t"<<ne_beta1<<"\t"<<ne_beta2<<endl; + ofs_rho_data<<r*cm_per_pixel/kpc<<"\t"<<ne<<endl; + ofs_entropy<<r*cm_per_pixel/kpc<<"\t"<<S<<endl; +#if 0 + if(r*cm_per_pixel/kpc<5) + { + continue; + } +#endif + ofs_mass<<r*cm_per_pixel/kpc<<"\t"<<M/M_sun<<endl; + if(r<radii.back()) + { + ofs_mass_dat<<r*cm_per_pixel/kpc<<"\t0\t"<<M/M_sun<<"\t"<<M/M_sun*.1<<endl; + } + ofs_overdensity<<r*cm_per_pixel/kpc<<"\t"<<rho/calc_critical_density(z)<<endl; + + } +} diff --git a/mass_profile/fit_direct_beta.cpp b/mass_profile/fit_direct_beta.cpp new file mode 100644 index 0000000..cc1d7c9 --- /dev/null +++ b/mass_profile/fit_direct_beta.cpp @@ -0,0 +1,61 @@ +#include <iostream> +#include <string> +#include <vector> +#include <statistics/chisq.hpp> +#include <methods/powell/powell_method.hpp> +#include <data_sets/default_data_set.hpp> +#include <misc/data_loaders.hpp> +#include "methods/aga/aga.hpp" +#include <models/beta1d.hpp> +using namespace std; +using namespace opt_utilities; + + + +int main(int argc,char* argv[]) +{ + + if(argc!=2) + { + cerr<<"Usage:"<<argv[0]<<" <sbp data>"<<endl; + return -1; + } + + fitter<double,double,vector<double>,double,string> f; + + f.set_statistic(chisq<double,double,vector<double>,double,string>()); + f.set_opt_method(powell_method<double,vector<double> >()); + f.set_model(beta1d<double>()); + dl_x_xe_y_ye<double,double> dl; + ifstream ifs(argv[1]); + ifs>>dl; + f.load_data(dl.get_data_set()); + f.fit(); + + double rmin=f.get_data_set().get_data(0).get_x(); + double rmax=f.get_data_set().get_data(f.get_data_set().size()-1).get_x(); + cout<<"read terr 1 2\nskip single\n"; + for(int i=0;i<f.get_data_set().size();++i) + { + cout<<f.get_data_set().get_data(i).get_x()<<"\t"<< + -abs(f.get_data_set().get_data(i).get_x_lower_err())<<"\t"<< + abs(f.get_data_set().get_data(i).get_x_upper_err())<<"\t"<< + f.get_data_set().get_data(i).get_y()<<"\t"<< + -abs(f.get_data_set().get_data(i).get_y_lower_err())<<"\t"<< + abs(f.get_data_set().get_data(i).get_y_upper_err())<<endl; + + + } + cout<<"no no no\n"; + + for(double i=rmin;i<rmax;i+=1) + { + cout<<i<<"\t0\t0\t"<<f.eval_model(i,f.get_all_params())<<"\t0\t0"<<endl; + } + + for(int i=0;i<f.get_num_params();++i) + { + cerr<<f.get_param_info(i).get_name()<<"="<< + f.get_param_info(i).get_value()<<endl; + } +} diff --git a/mass_profile/fit_lt_bpl.cpp b/mass_profile/fit_lt_bpl.cpp new file mode 100644 index 0000000..5637dca --- /dev/null +++ b/mass_profile/fit_lt_bpl.cpp @@ -0,0 +1,336 @@ +/* + Perform a double-beta density model fitting to the surface brightness data + Author: Junhua Gu + Last modified: 2011.01.01 + This code is distributed with no warrant +*/ + +//#define HAVE_X_ERROR +#include <iomanip> +#include <iostream> +#include <sstream> +#include <fstream> +#include <models/bpl1d.hpp> +#include <models/lin1d.hpp> +#include "statistics/chisq.hpp" +#include "statistics/logchisq.hpp" +#include "statistics/leastsq.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <methods/gsl_simplex/gsl_simplex.hpp> +#include <core/freeze_param.hpp> + +using namespace std; +using namespace opt_utilities; +//double s=5.63136645E20; +const double kpc=3.086E21;//kpc in cm +const double Mpc=kpc*1000; +const double pi=4*atan(1); +double std_norm_rand() +{ + double u=0; + double v=0; + while(u<=0||v<=0) + { + u=rand()/(double)RAND_MAX; + rand(); + v=rand()/(double)RAND_MAX; + } + double x=std::sqrt(-log(u))*cos(2*pi*v); + return x; +} + +double shuffle_data(double xc,double xl,double xu) +{ + double lxc=log(xc); + double lxl=log(xc-xl)-log(xc); + double lxu=log(xc+xu)-log(xc); + + if(std_norm_rand()>0) + { + double result=std::exp(lxc-std::abs(std_norm_rand()*lxl)); + return result; + } + else + { + double result=std::exp(lxc+std::abs(std_norm_rand()*lxu)); + return result; + } +} + +int main(int argc,char* argv[]) +{ + srand(time(0)); + if(argc!=4) + { + cerr<<"Usage:"<<argv[0]<<" <a 5 column file with T -Terr +Terr L Lerr> <initial broken temperature> <T lower limit>"<<endl; + return -1; + } + double T_lower_limit(atof(argv[3])); + double Tb=atof(argv[2]); + assert(Tb>0); + ifstream ifs_data(argv[1]); + default_data_set<double,double> ds; + ofstream ofs_result("l-t_bpl_result.qdp"); + ofs_result<<"read terr 1 2"<<endl; + ofs_result<<"skip single"<<endl; + ofs_result<<"log"<<endl; + //ofs_result<<"li on 2"<<endl; + ofs_result<<"time off"<<endl; + ofs_result<<"la f"<<endl; + ofs_result<<"la x temperature (keV)"<<endl; + ofs_result<<"la y luminosity (10\\u43\\d erg s\\u-1\\d)"<<endl; + double yunit=1E43; + double sxxl=0; + double s1l=0; + double sxl=0; + double syl=0; + double sxyl=0; + + double sxxu=0; + double s1u=0; + double sxu=0; + double syu=0; + double sxyu=0; + + bool is_first_nonono=true; + + for(;;) + { + double T,Tl,Tu; + double L,Ll,Lu; + std::string line; + getline(ifs_data,line); + //ifs_data>>T>>Tl>>Tu>>M>>Ml>>Mu; + if(!ifs_data.good()) + { + break; + } + line+=" "; + istringstream iss(line); + + if(line[0]=='#') + { + if(!is_first_nonono) + { + ofs_result<<"no no no"<<endl; + } + else + { + is_first_nonono=false; + } + continue; + } + iss>>T>>Tl>>Tu>>L>>Ll; + Lu=Ll; + //std::cerr<<L<<"\t"<<Lerr<<endl; + if(!iss.good()) + { + continue; + } + + if(T<T_lower_limit||L<0) + { + continue; + } + if(std::abs(Lu)+std::abs(Ll)<L*.1) + { + double k=L*.1/(std::abs(Lu)+std::abs(Ll)); + Lu*=k; + Ll*=k; + } + if(std::abs(Ll)>std::abs(L)) + { + continue; + } + Tl=std::abs(Tl); + Tu=std::abs(Tu); + Ll=std::abs(Ll); + Lu=std::abs(Lu); + ofs_result<<T<<"\t"<<-std::abs(Tl)<<"\t"<<+std::abs(Tu)<<"\t"<<L/yunit<<"\t"<<-std::abs(Ll/yunit)<<"\t"<<+std::abs(Lu/yunit)<<endl; + double x=(T); + double y=(L); + double xu=Tu; + double xl=Tl; + + double yu=Lu; + double yl=Ll; + if(T>Tb) + { + sxxl+=log(x)*log(x); + sxl+=log(x); + syl+=log(y); + sxyl+=log(y)*log(x); + s1l+=1; + } + else + { + sxxu+=log(x)*log(x); + sxu+=log(x); + syu+=log(y); + sxyu+=log(y)*log(x); + s1u+=1; + } + data<double,double> d(x,y,std::abs(yl),std::abs(yu), + std::abs(xl),std::abs(xu)); + ds.add_data(d); + } + + double Ml=sxxl*s1l-sxl*sxl; + double Mal=sxyl*s1l-syl*sxl; + double Mbl=sxxl*syl-sxl*sxyl; + double k0l=Mal/Ml; + double b0l=Mbl/Ml; + + double Mu=sxxu*s1u-sxu*sxu; + double Mau=sxyu*s1u-syu*sxu; + double Mbu=sxxu*syu-sxu*sxyu; + double k0u=Mau/Mu; + double b0u=Mbu/Mu; + + double gamma0l=k0l; + double gamma0u=k0u; + + double ampl0l=exp(b0l)*pow(Tb,gamma0l); + double ampl0u=exp(b0u)*pow(Tb,gamma0u);; + + + + ofs_result<<"no no no"<<endl; + fitter<double,double,vector<double>,double,std::string> fit; + fit.set_opt_method(powell_method<double,vector<double> >()); + + fit.set_statistic(logchisq<double,double,vector<double>,double,std::string>()); + //fit.set_statistic(leastsq<double,double,vector<double>,double,std::string>()); + fit.set_model(bpl1d<double>()); + fit.load_data(ds); + + cerr<<"k0l="<<k0l<<endl; + cerr<<"k0u="<<k0u<<endl; + cerr<<"Ampl0="<<(ampl0l+ampl0u)/2<<endl; + + fit.set_param_value("bpx",Tb); + fit.set_param_value("bpy",(ampl0l+ampl0u)/2); + fit.set_param_value("gamma1",gamma0l); + fit.set_param_value("gamma2",gamma0u); + + fit.fit(); + //fit.set_opt_method(gsl_simplex<double,vector<double> >()); + fit.fit(); + std::vector<double> p=fit.fit(); + Tb=fit.get_param_value("bpx"); + ///std::cout<<"chi="<<fit.get_statistic().eval(p)<<std::endl; + for(double i=.5;i<12;i*=1.01) + { + ofs_result<<i<<"\t0\t0\t"<<fit.eval_model_raw(i,p)/yunit<<"\t0\t0\n"; + } + + + std::vector<double> mean_p(p.size()); + std::vector<double> mean_p2(p.size()); + int cnt=0; + for(int n=0;n<100;++n) + { + ++cnt; + cerr<<"."; + double sxxl=0; + double s1l=0; + double sxl=0; + double syl=0; + double sxyl=0; + + double sxxu=0; + double s1u=0; + double sxu=0; + double syu=0; + double sxyu=0; + + opt_utilities::default_data_set<double,double> ds1; + for(int i=0;i<ds.size();++i) + { + double x=ds.get_data(i).get_x(); + double y=ds.get_data(i).get_y(); + double xl=ds.get_data(i).get_x_lower_err(); + double xu=ds.get_data(i).get_x_upper_err(); + double yl=ds.get_data(i).get_y_lower_err(); + double yu=ds.get_data(i).get_y_upper_err(); + + double new_x=shuffle_data(x, + xl, + xu); + double new_y=shuffle_data(y, + yl, + yu); + + ds1.add_data(data<double,double>(new_x,new_y, + yl/y*new_y, + yu/y*new_y, + xl/x*new_x, + xu/x*new_x)); + + x=new_x; + y=new_y; + if(x>Tb) + { + sxxl+=log(x)*log(x); + sxl+=log(x); + syl+=log(y); + sxyl+=log(y)*log(x); + s1l+=1; + } + else + { + sxxu+=log(x)*log(x); + sxu+=log(x); + syu+=log(y); + sxyu+=log(y)*log(x); + s1u+=1; + } + } + double Ml=sxxl*s1l-sxl*sxl; + double Mal=sxyl*s1l-syl*sxl; + double Mbl=sxxl*syl-sxl*sxyl; + double k0l=Mal/Ml; + double b0l=Mbl/Ml; + + double Mu=sxxu*s1u-sxu*sxu; + double Mau=sxyu*s1u-syu*sxu; + double Mbu=sxxu*syu-sxu*sxyu; + double k0u=Mau/Mu; + double b0u=Mbu/Mu; + + double gamma0l=k0l; + double gamma0u=k0u; + + double ampl0l=exp(b0l)*pow(Tb,gamma0l); + double ampl0u=exp(b0u)*pow(Tb,gamma0u);; + + fit.set_param_value("bpx",Tb); + fit.set_param_value("bpy",(ampl0l+ampl0u)/2); + fit.set_param_value("gamma1",gamma0l); + fit.set_param_value("gamma2",gamma0u); + + + fit.load_data(ds1); + + fit.fit(); + vector<double> p=fit.fit(); + for(int i=0;i<p.size();++i) + { + mean_p[i]+=p[i]; + mean_p2[i]+=p[i]*p[i]; + } + //cerr<<fit.get_param_value("gamma1")<<"\t"<<fit.get_param_value("gamma2")<<endl; + + } + vector<double> std_p(p.size()); + cerr<<endl; + for(int i=0;i<mean_p.size();++i) + { + mean_p[i]/=cnt; + mean_p2[i]/=cnt; + std_p[i]=std::sqrt(mean_p2[i]-mean_p[i]*mean_p[i]); + cout<<fit.get_param_info(i).get_name()<<"= "<<p[i]<<" +/- "<<std_p[i]<<endl; + } + std::cout<<"Num of sources:"<<ds.size()<<endl; +} diff --git a/mass_profile/fit_lt_pl.cpp b/mass_profile/fit_lt_pl.cpp new file mode 100644 index 0000000..e1686e5 --- /dev/null +++ b/mass_profile/fit_lt_pl.cpp @@ -0,0 +1,239 @@ +/* + Perform a double-beta density model fitting to the surface brightness data + Author: Junhua Gu + Last modified: 2011.01.01 + This code is distributed with no warrant +*/ + +//#define HAVE_X_ERROR +#include <iostream> +#include <sstream> +#include <fstream> +#include <models/pl1d.hpp> +#include <models/lin1d.hpp> +#include "statistics/chisq.hpp" +#include "statistics/leastsq.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <core/freeze_param.hpp> + +using namespace std; +using namespace opt_utilities; +//double s=5.63136645E20; +const double kpc=3.086E21;//kpc in cm +const double Mpc=kpc*1000; +const double pi=4*atan(1); +double std_norm_rand() +{ + double x=0; + double u=0; + double v=0; + + do + { + u=rand()/(double)RAND_MAX; + rand(); + v=rand()/(double)RAND_MAX; + + x=std::sqrt(-log(u))*cos(2*pi*v); + }while(isnan(x)); + return x; +} + +double shuffle_data(double xc,double xl,double xu) +{ + double result=0; + assert(!isnan(xc)); + assert(!isnan(xl)); + assert(!isnan(xu)); + if(std_norm_rand()>0) + { + result=xc-std::abs(std_norm_rand()*xl); + } + else + { + result=xc+std::abs(std_norm_rand()*xu); + } + assert(!isnan(result)); + return result; +} + +int main(int argc,char* argv[]) +{ + if(argc!=3) + { + cerr<<"Usage:"<<argv[0]<<" <a 5 column file with T -Terr +Terr L Lerr> <T lower limit>"<<endl; + return -1; + } + double T_lower_limit(atof(argv[2])); + ifstream ifs_data(argv[1]); + default_data_set<double,double> ds; + ofstream ofs_result("l-t_result.qdp"); + ofs_result<<"read terr 1"<<endl; + ofs_result<<"read serr 2"<<endl; + ofs_result<<"skip single"<<endl; + ofs_result<<"log"<<endl; + //ofs_result<<"li on 2"<<endl; + ofs_result<<"time off"<<endl; + ofs_result<<"la f"<<endl; + ofs_result<<"la x temperature (keV)"<<endl; + ofs_result<<"la y Luminosity (10\\u43\\d erg s\\u-1\\d)"<<endl; + double yunit=1E43; + double sxx=0; + double s1=0; + double sx=0; + double sy=0; + double sxy=0; + bool is_first_nonono=true; + for(;;) + { + double T,Tl,Tu; + double L,Lerr; + std::string line; + getline(ifs_data,line); + + + if(!ifs_data.good()) + { + break; + } + line+=" "; + istringstream iss(line); + + if(line[0]=='#') + { + if(!is_first_nonono) + { + ofs_result<<"no no no"<<endl; + } + else + { + is_first_nonono=false; + } + continue; + } + + iss>>T>>Tl>>Tu>>L>>Lerr; + //std::cerr<<L<<"\t"<<Lerr<<endl; + if(!iss.good()) + { + continue; + } + if(T<T_lower_limit||L<0) + { + continue; + } + if(Lerr<L*.1) + { + Lerr=L*.1; + } + double Ll=Lerr; + double Lu=Lerr; + Tl=std::abs(Tl); + Tu=std::abs(Tu); + Ll=std::abs(Ll); + Lu=std::abs(Lu); + ofs_result<<T<<"\t"<<-std::abs(Tl)<<"\t"<<+std::abs(Tu)<<"\t"<<L/yunit<<"\t"<<std::abs(Lerr)/yunit<<endl; + double x=log(T); + double y=log(L); + double xu=log(T+Tu)-log(T); + double xl=log(T-Tl)-log(T); + + double yu=log(L+Lu)-log(L); + double yl=log(L-Ll)-log(L); + if(isnan(x)||isnan(y)||isnan(yl)||isnan(yu)|| + isnan(xl)||isnan(xu)) + { + std::cerr<<"one data with error > data, skipped"<<endl; + std::cerr<<line<<endl; + continue; + } + sxx+=x*x; + sx+=x; + sy+=y; + sxy+=y*x; + s1+=1; + data<double,double> d(x,y,std::abs(yl),std::abs(yu), + std::abs(xl),std::abs(xu)); + ds.add_data(d); + } + + double M=sxx*s1-sx*sx; + double Ma=sxy*s1-sy*sx; + double Mb=sxx*sy-sx*sxy; + double k0=Ma/M; + double b0=Mb/M; + + ofs_result<<"no no no"<<endl; + fitter<double,double,vector<double>,double,std::string> fit; + fit.set_opt_method(powell_method<double,vector<double> >()); + fit.set_statistic(chisq<double,double,vector<double>,double,std::string>()); + //fit.set_statistic(leastsq<double,double,vector<double>,double,std::string>()); + fit.set_model(lin1d<double>()); + fit.load_data(ds); + + cerr<<"k0="<<k0<<endl; + cerr<<"b0="<<b0<<endl; + cerr<<"Ampl0="<<exp(b0)<<endl; + cerr<<"gamma0="<<k0<<endl; + fit.set_param_value("k",k0); + fit.set_param_value("b",b0); + fit.fit(); + std::vector<double> p=fit.fit(); + for(double i=.5;i<12;i*=1.01) + { + ofs_result<<i<<"\t0\t0\t"<<exp(fit.eval_model_raw(log(i),p))/yunit<<"\t0\n"; + } + + + double mean_A=0; + double mean_A2=0; + double mean_g=0; + double mean_g2=0; + int cnt=0; + for(int n=0;n<100;++n) + { + ++cnt; + cerr<<"."; + opt_utilities::default_data_set<double,double> ds1; + for(int i=0;i<ds.size();++i) + { + double new_x=shuffle_data(ds.get_data(i).get_x(), + ds.get_data(i).get_x_lower_err(), + ds.get_data(i).get_x_upper_err()); + double new_y=shuffle_data(ds.get_data(i).get_y(), + ds.get_data(i).get_y_lower_err(), + ds.get_data(i).get_y_upper_err()); + ds1.add_data(data<double,double>(new_x,new_y, + ds.get_data(i).get_y_lower_err(), + ds.get_data(i).get_y_upper_err(), + ds.get_data(i).get_y_lower_err(), + ds.get_data(i).get_y_upper_err())); + //cerr<<new_x<<"\t"<<new_y<<endl; + } + fit.load_data(ds1); + + fit.fit(); + double k=fit.get_param_value("k"); + double b=fit.get_param_value("b"); + double A=exp(b); + double g=k; + mean_A+=A; + mean_A2+=A*A; + mean_g+=g; + mean_g2+=g*g; + } + std::cerr<<endl; + mean_A/=cnt; + mean_A2/=cnt; + mean_g/=cnt; + mean_g2/=cnt; + double std_A=std::sqrt(mean_A2-mean_A*mean_A); + double std_g=std::sqrt(mean_g2-mean_g*mean_g); + + std::cerr<<"L=L0*T^gamma"<<endl; + std::cout<<"L0= "<<exp(p[1])<<"+/-"<<std_A<<endl; + std::cout<<"gamma= "<<p[0]<<"+/-"<<std_g<<endl; + std::cout<<"Num of sources:"<<ds.size()<<endl; + +} diff --git a/mass_profile/fit_mass.sh b/mass_profile/fit_mass.sh new file mode 100755 index 0000000..141d16c --- /dev/null +++ b/mass_profile/fit_mass.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# + +if [ $# -eq 1 ]; then + : +elif [ $# -eq 2 ]; then + CENTER_VALUE="YES" +else + printf "usage: $0 <mass_conf> [c]\n" + exit 1 +fi +cfg_file=$1 +if [ "$0" = `basename $0` ]; then + script_path=`which $0` + base_path=`dirname ${script_path}` +else + base_path=`dirname $0` +fi + +sbp_cfg=`grep '^sbp_cfg' $cfg_file | awk '{ print $2 }'` + +if grep -q '^beta2' $sbp_cfg; then + MODEL="double-beta" + PROG=fit_nfwmass_dbeta.sh +else + MODEL="single-beta" + PROG=fit_nfwmass_beta.sh +fi + +printf "## MODEL: ${MODEL}\n" +if [ "x${CENTER_VALUE}" = "xYES" ]; then + $base_path/$PROG $cfg_file c +else + $base_path/$PROG $cfg_file +fi + diff --git a/mass_profile/fit_mt_bpl.cpp b/mass_profile/fit_mt_bpl.cpp new file mode 100644 index 0000000..7cf22b2 --- /dev/null +++ b/mass_profile/fit_mt_bpl.cpp @@ -0,0 +1,350 @@ +/* + Perform a double-beta density model fitting to the surface brightness data + Author: Junhua Gu + Last modified: 2011.01.01 + This code is distributed with no warrant +*/ + +//#define HAVE_X_ERROR +#include <iomanip> +#include <iostream> +#include <sstream> +#include <fstream> +#include <models/bpl1d.hpp> +#include <models/lin1d.hpp> +#include "statistics/chisq.hpp" +#include "statistics/logchisq.hpp" +#include "statistics/leastsq.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <methods/gsl_simplex/gsl_simplex.hpp> +#include <core/freeze_param.hpp> + +using namespace std; +using namespace opt_utilities; +//double s=5.63136645E20; +const double kpc=3.086E21;//kpc in cm +const double Mpc=kpc*1000; +const double pi=4*atan(1); +double std_norm_rand() +{ + double u=0; + double v=0; + while(u<=0||v<=0) + { + u=rand()/(double)RAND_MAX; + rand(); + v=rand()/(double)RAND_MAX; + } + double x=std::sqrt(-log(u))*cos(2*pi*v); + return x; +} + +double shuffle_data(double xc,double xl,double xu) +{ + double lxc=log(xc); + double lxl=log(xc-xl)-log(xc); + double lxu=log(xc+xu)-log(xc); + + if(std_norm_rand()>0) + { + double result=std::exp(lxc-std::abs(std_norm_rand()*lxl)); + return result; + } + else + { + double result=std::exp(lxc+std::abs(std_norm_rand()*lxu)); + return result; + } +} + +int main(int argc,char* argv[]) +{ + srand(time(0)); + if(argc!=4) + { + cerr<<"Usage:"<<argv[0]<<" <a 6 column file with T -Terr +Terr M -Merr +Merr> <initial broken temperature> <T lower limit>"<<endl; + return -1; + } + double T_lower_limit(atof(argv[3])); + double Tb=atof(argv[2]); + assert(Tb>0); + ifstream ifs_data(argv[1]); + default_data_set<double,double> ds; + ofstream ofs_result("m-t_bpl_result.qdp"); + ofs_result<<"read terr 1 2"<<endl; + ofs_result<<"skip single"<<endl; + ofs_result<<"log"<<endl; + //ofs_result<<"li on 2"<<endl; + ofs_result<<"time off"<<endl; + ofs_result<<"la f"<<endl; + ofs_result<<"la x temperature (keV)"<<endl; + ofs_result<<"la y mass (M\\d\\(2281)\\u)"<<endl; + double sxxl=0; + double s1l=0; + double sxl=0; + double syl=0; + double sxyl=0; + + double sxxu=0; + double s1u=0; + double sxu=0; + double syu=0; + double sxyu=0; + + bool is_first_nonono=true; + + for(;;) + { + double T,Tl,Tu; + double M,Ml,Mu; + std::string line; + getline(ifs_data,line); + //ifs_data>>T>>Tl>>Tu>>M>>Ml>>Mu; + if(!ifs_data.good()) + { + break; + } + line+=" "; + istringstream iss(line); + + if(line[0]=='#') + { + if(!is_first_nonono) + { + ofs_result<<"no no no"<<endl; + } + else + { + is_first_nonono=false; + } + continue; + } + iss>>T>>Tl>>Tu>>M>>Ml>>Mu; + //std::cerr<<L<<"\t"<<Lerr<<endl; + if(!iss.good()) + { + continue; + } + + if(T<T_lower_limit||M<0) + { + continue; + } + + if(std::abs(Mu)<M*.1||std::abs(Ml)<M*.1) + { + cerr<<"mass error less than 10%, skipped"<<endl; + cerr<<line<<endl; + continue; + } +#if 1 + if(std::abs(Tu)<.1||std::abs(Tl)<.1) + { + cerr<<"T error less than 10%, skipped"<<endl; + cerr<<line<<endl; + continue; + } +#endif + + if(std::abs(Mu)+std::abs(Ml)<M*.1) + { + double k=M*.1/(std::abs(Mu)+std::abs(Ml)); + Mu*=k; + Ml*=k; + } + if(std::abs(Ml)>std::abs(M)) + { + continue; + } + Tl=std::abs(Tl); + Tu=std::abs(Tu); + Ml=std::abs(Ml); + Mu=std::abs(Mu); + ofs_result<<T<<"\t"<<-std::abs(Tl)<<"\t"<<+std::abs(Tu)<<"\t"<<M<<"\t"<<-std::abs(Ml)<<"\t"<<+std::abs(Mu)<<endl; + double x=(T); + double y=(M); + double xu=Tu; + double xl=Tl; + + double yu=Mu; + double yl=Ml; + if(T>Tb) + { + sxxl+=log(x)*log(x); + sxl+=log(x); + syl+=log(y); + sxyl+=log(y)*log(x); + s1l+=1; + } + else + { + sxxu+=log(x)*log(x); + sxu+=log(x); + syu+=log(y); + sxyu+=log(y)*log(x); + s1u+=1; + } + data<double,double> d(x,y,std::abs(yl),std::abs(yu), + std::abs(xl),std::abs(xu)); + ds.add_data(d); + } + + double Ml=sxxl*s1l-sxl*sxl; + double Mal=sxyl*s1l-syl*sxl; + double Mbl=sxxl*syl-sxl*sxyl; + double k0l=Mal/Ml; + double b0l=Mbl/Ml; + + double Mu=sxxu*s1u-sxu*sxu; + double Mau=sxyu*s1u-syu*sxu; + double Mbu=sxxu*syu-sxu*sxyu; + double k0u=Mau/Mu; + double b0u=Mbu/Mu; + + double gamma0l=k0l; + double gamma0u=k0u; + + double ampl0l=exp(b0l)*pow(Tb,gamma0l); + double ampl0u=exp(b0u)*pow(Tb,gamma0u);; + + + + ofs_result<<"no no no"<<endl; + fitter<double,double,vector<double>,double,std::string> fit; + fit.set_opt_method(powell_method<double,vector<double> >()); + + fit.set_statistic(logchisq<double,double,vector<double>,double,std::string>()); + //fit.set_statistic(leastsq<double,double,vector<double>,double,std::string>()); + fit.set_model(bpl1d<double>()); + fit.load_data(ds); + + cerr<<"k0l="<<k0l<<endl; + cerr<<"k0u="<<k0u<<endl; + cerr<<"Ampl0="<<(ampl0l+ampl0u)/2<<endl; + + fit.set_param_value("bpx",Tb); + fit.set_param_value("bpy",(ampl0l+ampl0u)/2); + fit.set_param_value("gamma1",gamma0l); + fit.set_param_value("gamma2",gamma0u); + + fit.fit(); + //fit.set_opt_method(gsl_simplex<double,vector<double> >()); + fit.fit(); + std::vector<double> p=fit.fit(); + Tb=fit.get_param_value("bpx"); + //std::cout<<"chi="<<fit.get_statistic().eval(p)<<std::endl; + for(double i=.5;i<12;i*=1.01) + { + ofs_result<<i<<"\t0\t0\t"<<fit.eval_model_raw(i,p)<<"\t0\t0\n"; + } + + + std::vector<double> mean_p(p.size()); + std::vector<double> mean_p2(p.size()); + int cnt=0; + for(int n=0;n<100;++n) + { + ++cnt; + cerr<<"."; + double sxxl=0; + double s1l=0; + double sxl=0; + double syl=0; + double sxyl=0; + + double sxxu=0; + double s1u=0; + double sxu=0; + double syu=0; + double sxyu=0; + + opt_utilities::default_data_set<double,double> ds1; + for(int i=0;i<ds.size();++i) + { + double x=ds.get_data(i).get_x(); + double y=ds.get_data(i).get_y(); + double xl=ds.get_data(i).get_x_lower_err(); + double xu=ds.get_data(i).get_x_upper_err(); + double yl=ds.get_data(i).get_y_lower_err(); + double yu=ds.get_data(i).get_y_upper_err(); + + double new_x=shuffle_data(x, + xl, + xu); + double new_y=shuffle_data(y, + yl, + yu); + + ds1.add_data(data<double,double>(new_x,new_y, + yl/y*new_y, + yu/y*new_y, + xl/x*new_x, + xu/x*new_x)); + + x=new_x; + y=new_y; + if(x>Tb) + { + sxxl+=log(x)*log(x); + sxl+=log(x); + syl+=log(y); + sxyl+=log(y)*log(x); + s1l+=1; + } + else + { + sxxu+=log(x)*log(x); + sxu+=log(x); + syu+=log(y); + sxyu+=log(y)*log(x); + s1u+=1; + } + } + double Ml=sxxl*s1l-sxl*sxl; + double Mal=sxyl*s1l-syl*sxl; + double Mbl=sxxl*syl-sxl*sxyl; + double k0l=Mal/Ml; + double b0l=Mbl/Ml; + + double Mu=sxxu*s1u-sxu*sxu; + double Mau=sxyu*s1u-syu*sxu; + double Mbu=sxxu*syu-sxu*sxyu; + double k0u=Mau/Mu; + double b0u=Mbu/Mu; + + double gamma0l=k0l; + double gamma0u=k0u; + + double ampl0l=exp(b0l)*pow(Tb,gamma0l); + double ampl0u=exp(b0u)*pow(Tb,gamma0u);; + + fit.set_param_value("bpx",Tb); + fit.set_param_value("bpy",(ampl0l+ampl0u)/2); + fit.set_param_value("gamma1",gamma0l); + fit.set_param_value("gamma2",gamma0u); + + + fit.load_data(ds1); + + fit.fit(); + vector<double> p=fit.fit(); + for(int i=0;i<p.size();++i) + { + mean_p[i]+=p[i]; + mean_p2[i]+=p[i]*p[i]; + } + //cerr<<fit.get_param_value("gamma1")<<"\t"<<fit.get_param_value("gamma2")<<endl; + + } + vector<double> std_p(p.size()); + cerr<<endl; + for(int i=0;i<mean_p.size();++i) + { + mean_p[i]/=cnt; + mean_p2[i]/=cnt; + std_p[i]=std::sqrt(mean_p2[i]-mean_p[i]*mean_p[i]); + cout<<fit.get_param_info(i).get_name()<<"= "<<p[i]<<" +/- "<<std_p[i]<<endl; + } + std::cout<<"Num of sources:"<<ds.size()<<endl; +} diff --git a/mass_profile/fit_mt_pl.cpp b/mass_profile/fit_mt_pl.cpp new file mode 100644 index 0000000..a2246a7 --- /dev/null +++ b/mass_profile/fit_mt_pl.cpp @@ -0,0 +1,265 @@ +/* + Perform a double-beta density model fitting to the surface brightness data + Author: Junhua Gu + Last modified: 2011.01.01 + This code is distributed with no warrant +*/ + +//#define HAVE_X_ERROR +#include <iomanip> +#include <iostream> +#include <sstream> +#include <fstream> +#include <models/pl1d.hpp> +#include <models/lin1d.hpp> +#include "statistics/chisq.hpp" +#include "statistics/leastsq.hpp" +#include "statistics/robust_chisq.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <core/freeze_param.hpp> + +using namespace std; +using namespace opt_utilities; +//double s=5.63136645E20; +const double kpc=3.086E21;//kpc in cm +const double Mpc=kpc*1000; +const double pi=4*atan(1); +double std_norm_rand() +{ + double u=0; + double v=0; + while(u<=0||v<=0) + { + u=rand()/(double)RAND_MAX; + rand(); + v=rand()/(double)RAND_MAX; + } + double x=std::sqrt(-log(u))*cos(2*pi*v); + return x; +} + +double shuffle_data(double xc,double xl,double xu) +{ + if(std_norm_rand()>0) + { + double result=xc-std::abs(std_norm_rand()*xl); + return result; + } + else + { + double result= xc+std::abs(std_norm_rand()*xu); + return result; + } +} + +int main(int argc,char* argv[]) +{ + if(argc!=3) + { + cerr<<"Usage:"<<argv[0]<<" <a 6 column file with T -Terr +Terr M -Merr +Merr> <lower T limit>"<<endl; + return -1; + } + double T_lower_limit(atof(argv[2])); + ifstream ifs_data(argv[1]); + default_data_set<double,double> ds; + ofstream ofs_result("m-t_result.qdp"); + ofs_result<<"read terr 1 2"<<endl; + ofs_result<<"skip single"<<endl; + ofs_result<<"log"<<endl; + //ofs_result<<"li on 2"<<endl; + ofs_result<<"time off"<<endl; + ofs_result<<"la f"<<endl; + ofs_result<<"la x temperature (keV)"<<endl; + ofs_result<<"la y mass (M\\dsun\\u)"<<endl; + double sxx=0; + double s1=0; + double sx=0; + double sy=0; + double sxy=0; + bool is_first_nonono=true; + + for(;;) + { + double T,Tl,Tu; + double M,Ml,Mu; + std::string line; + getline(ifs_data,line); + //ifs_data>>T>>Tl>>Tu>>M>>Ml>>Mu; + if(!ifs_data.good()) + { + break; + } + line+=" "; + istringstream iss(line); + + if(line[0]=='#') + { + if(!is_first_nonono) + { + ofs_result<<"no no no"<<endl; + } + else + { + is_first_nonono=false; + } + continue; + } + iss>>T>>Tl>>Tu>>M>>Ml>>Mu; + //std::cerr<<L<<"\t"<<Lerr<<endl; + if(!iss.good()) + { + continue; + } + + if(T<T_lower_limit||M<0) + { + continue; + } + if(std::abs(Mu)<M*.1||std::abs(Ml)<M*.1) + { + cerr<<"mass error less than 10%, skipped"<<endl; + cerr<<line<<endl; + continue; + } +#if 1 + if(std::abs(Tu)<.1||std::abs(Tl)<.1) + { + cerr<<"T error less than 10%, skipped"<<endl; + cerr<<line<<endl; + continue; + } +#endif + if(std::abs(Mu)+std::abs(Ml)<M*.1) + { + double k=M*.1/(std::abs(Mu)+std::abs(Ml)); + Mu*=k; + Ml*=k; + } + Tl=std::abs(Tl); + Tu=std::abs(Tu); + Ml=std::abs(Ml); + Mu=std::abs(Mu); + ofs_result<<T<<"\t"<<-std::abs(Tl)<<"\t"<<+std::abs(Tu)<<"\t"<<M<<"\t"<<-std::abs(Ml)<<"\t"<<+std::abs(Mu)<<endl; + double x=log(T); + double y=log(M); + double xu=log(T+Tu)-log(T); + double xl=log(T-Tl)-log(T); + + double yu=log(M+Mu)-log(M); + double yl=log(M-Ml)-log(M); + if(isnan(x)||isnan(y)||isnan(yl)||isnan(yu)|| + isnan(xl)||isnan(xu)) + { + std::cerr<<"one data with error > data, skipped"<<endl; + std::cerr<<line<<endl; + continue; + } + sxx+=x*x; + sx+=x; + sy+=y; + sxy+=y*x; + s1+=1; + data<double,double> d(x,y,std::abs(yl),std::abs(yu), + std::abs(xl),std::abs(xu)); + ds.add_data(d); + } + + double M=sxx*s1-sx*sx; + double Ma=sxy*s1-sy*sx; + double Mb=sxx*sy-sx*sxy; + double k0=Ma/M; + double b0=Mb/M; + + ofs_result<<"no no no"<<endl; + fitter<double,double,vector<double>,double,std::string> fit; + fit.set_opt_method(powell_method<double,vector<double> >()); + fit.set_statistic(chisq<double,double,vector<double>,double,std::string>()); + //fit.set_statistic(robust_chisq<double,double,vector<double>,double,std::string>()); + //fit.set_statistic(leastsq<double,double,vector<double>,double,std::string>()); + fit.set_model(lin1d<double>()); + fit.load_data(ds); + + cerr<<"k0="<<k0<<endl; + cerr<<"b0="<<b0<<endl; + cerr<<"Ampl0="<<exp(b0)<<endl; + cerr<<"gamma0="<<k0<<endl; + fit.set_param_value("k",k0); + fit.set_param_value("b",b0); + std::vector<double> p=fit.get_all_params(); + std::cout<<"chi="<<fit.get_statistic().eval(p)<<std::endl; + fit.fit(); + fit.fit(); + p=fit.fit(); + + std::cout<<"chi="<<fit.get_statistic().eval(p)<<std::endl; + for(double i=.5;i<12;i*=1.01) + { + ofs_result<<i<<"\t0\t0\t"<<exp(fit.eval_model_raw(log(i),p))<<"\t0\t0\n"; + } + + ofstream ofs_resid("resid.qdp"); + ofs_resid<<"read terr 1 2 3"<<endl; + ofs_resid<<"skip single"<<endl; + ofs_resid<<"ma 3 on 1"<<endl; + ofs_resid<<"log x"<<endl; + for(int i=0;i<ds.size();++i) + { + double x=ds.get_data(i).get_x(); + double y=ds.get_data(i).get_y(); + double xe1=-ds.get_data(i).get_x_lower_err()*0; + double xe2=ds.get_data(i).get_x_upper_err()*0; + double ye1=-ds.get_data(i).get_y_lower_err(); + double ye2=ds.get_data(i).get_y_upper_err(); + ofs_resid<<exp(x)<<"\t"<<0<<"\t"<<0<<"\t"<<y-fit.eval_model_raw(x,p)<<"\t"<<ye1<<"\t"<<ye2<<"\t"<<"0\t0\t0"<<endl; + } + double mean_A=0; + double mean_A2=0; + double mean_g=0; + double mean_g2=0; + int cnt=0; + for(int n=0;n<100;++n) + { + ++cnt; + cerr<<"."; + opt_utilities::default_data_set<double,double> ds1; + for(int i=0;i<ds.size();++i) + { + double new_x=shuffle_data(ds.get_data(i).get_x(), + ds.get_data(i).get_x_lower_err(), + ds.get_data(i).get_x_upper_err()); + double new_y=shuffle_data(ds.get_data(i).get_y(), + ds.get_data(i).get_y_lower_err(), + ds.get_data(i).get_y_upper_err()); + ds1.add_data(data<double,double>(new_x,new_y, + ds.get_data(i).get_y_lower_err(), + ds.get_data(i).get_y_upper_err(), + ds.get_data(i).get_y_lower_err(), + ds.get_data(i).get_y_upper_err())); + } + fit.load_data(ds1); + + fit.fit(); + double k=fit.get_param_value("k"); + double b=fit.get_param_value("b"); + double A=exp(b); + double g=k; + mean_A+=A; + mean_A2+=A*A; + mean_g+=g; + mean_g2+=g*g; + } + std::cerr<<endl; + mean_A/=cnt; + mean_A2/=cnt; + mean_g/=cnt; + mean_g2/=cnt; + double std_A=std::sqrt(mean_A2-mean_A*mean_A); + double std_g=std::sqrt(mean_g2-mean_g*mean_g); + + std::cerr<<"M=M0*T^gamma"<<endl; + std::cout<<"M0= "<<exp(p[1])<<"+/-"<<std_A<<endl; + std::cout<<"gamma= "<<p[0]<<"+/-"<<std_g<<endl; + std::cout<<"Num of sources:"<<ds.size()<<endl; + +} diff --git a/mass_profile/fit_nfw_mass.cpp b/mass_profile/fit_nfw_mass.cpp new file mode 100644 index 0000000..48064be --- /dev/null +++ b/mass_profile/fit_nfw_mass.cpp @@ -0,0 +1,159 @@ +/* + Fitting nfw mass profile model + Author: Junhua Gu + Last modification 20120721 +*/ + +#include "nfw.hpp" +#include <core/optimizer.hpp> +#include <core/fitter.hpp> +#include <data_sets/default_data_set.hpp> +#include "chisq.hpp" +#include <methods/powell/powell_method.hpp> +#include <iostream> +#include <fstream> +#include <vector> +#include <string> + +using namespace opt_utilities; +using namespace std; +const double cm=1; +const double kpc=3.08568e+21*cm; +const double pi=4*atan(1); +static double calc_critical_density(double z, + const double H0=2.3E-18, + const double Omega_m=.27) +{ + const double G=6.673E-8;//cm^3 g^-1 s^2 + const double E=std::sqrt(Omega_m*(1+z)*(1+z)*(1+z)+1-Omega_m); + const double H=H0*E; + return 3*H*H/8/pi/G; +} + + +int main(int argc,char* argv[]) +{ + if(argc<3) + { + cerr<<"Usage:"<<argv[0]<<" <data file with 4 columns of x, xe, y, ye> <z> [rmin in kpc]"<<endl; + return -1; + } + double rmin_kpc=1; + if(argc>=4) + { + rmin_kpc=atof(argv[3]); + } + double z=0; + z=atof(argv[2]); + //define the fitter + fitter<double,double,vector<double>,double,std::string> fit; + //define the data set + default_data_set<double,double> ds; + //open the data file + ifstream ifs(argv[1]); + //cout<<"read serr 2"<<endl; + ofstream ofs_fit_result("nfw_fit_result.qdp"); + + ofs_fit_result<<"read serr 1 2"<<endl; + ofs_fit_result<<"skip single"<<endl; + ofs_fit_result<<"line off"<<endl; + ofs_fit_result<<"li on 2"<<endl; + ofs_fit_result<<"li on 4"<<endl; + ofs_fit_result<<"ls 2 on 4"<<endl; + + ofs_fit_result<<"win 1"<<endl; + ofs_fit_result<<"yplot 1 2"<<endl; + ofs_fit_result<<"loc 0 0 1 1"<<endl; + ofs_fit_result<<"vie .1 .4 .9 .9"<<endl; + ofs_fit_result<<"la y Mass (solar)"<<endl; + ofs_fit_result<<"log x"<<endl; + ofs_fit_result<<"log y"<<endl; + ofs_fit_result<<"win 2"<<endl; + ofs_fit_result<<"yplot 3 4"<<endl; + ofs_fit_result<<"loc 0 0 1 1"<<endl; + ofs_fit_result<<"vie .1 .1 .9 .4"<<endl; + ofs_fit_result<<"la x radius (kpc)"<<endl; + ofs_fit_result<<"la y chi"<<endl; + ofs_fit_result<<"log x"<<endl; + ofs_fit_result<<"log y off"<<endl; + for(;;) + { + //read radius, temperature and error + double r,re,m,me; + ifs>>r>>re>>m>>me; + if(!ifs.good()) + { + break; + } + if(r<rmin_kpc) + { + continue; + } + data<double,double> d(r,m,me,me,re,re); + ofs_fit_result<<r<<"\t"<<re<<"\t"<<m<<"\t"<<me<<endl; + ds.add_data(d); + } + ofs_fit_result<<"no no no"<<endl; + //load data + fit.load_data(ds); + //define the optimization method + fit.set_opt_method(powell_method<double,vector<double> >()); + //use chi^2 statistic + fit.set_statistic(chisq<double,double,vector<double>,double,std::string>()); + fit.set_model(nfw<double>()); + //fit.set_param_value("rs",4); + //fit.set_param_value("rho0",100); + fit.fit(); + fit.fit(); + vector<double> p=fit.fit(); + //output parameters + ofstream ofs_param("nfw_param.txt"); + for(int i=0;i<fit.get_num_params();++i) + { + cout<<fit.get_param_info(i).get_name()<<"\t"<<fit.get_param_info(i).get_value()<<endl; + ofs_param<<fit.get_param_info(i).get_name()<<"\t"<<fit.get_param_info(i).get_value()<<endl; + } + cout<<"reduced chi^2="<<fit.get_statistic_value()<<endl; + ofs_param<<"reduced chi^2="<<fit.get_statistic_value()<<endl; + ofstream ofs_model("nfw_dump.qdp"); + ofstream ofs_overdensity("overdensity.qdp"); + const double G=6.673E-8;//cm^3 g^-1 s^-2 + static const double mu=1.4074; + static const double mp=1.67262158E-24;//g + static const double M_sun=1.98892E33;//g + static const double k=1.38E-16; + + double xmax=0; + for(double x=std::max(rmin_kpc,ds.get_data(0).get_x());;x+=1) + { + double model_value=fit.eval_model(x,p); + ofs_model<<x<<"\t"<<model_value<<endl; + ofs_fit_result<<x<<"\t0\t"<<model_value<<"\t0"<<endl; + double V=4./3.*pi*pow(x*kpc,3); + double m=model_value*M_sun; + double rho=m/V;//g/cm^3 + double over_density=rho/calc_critical_density(z); + ofs_overdensity<<x<<"\t"<<over_density<<endl; + xmax=x; + if(over_density<100) + { + break; + } + } + ofs_fit_result<<"no no no"<<endl; + for(int i=0;i<ds.size();++i) + { + data<double,double> d=ds.get_data(i); + double x=d.get_x(); + double y=d.get_y(); + double ye=d.get_y_lower_err(); + double ym=fit.eval_model(x,p); + ofs_fit_result<<x<<"\t"<<0<<"\t"<<(y-ym)/ye<<"\t"<<1<<endl; + } + ofs_fit_result<<"no no no"<<endl; + for(double x=std::max(rmin_kpc,ds.get_data(0).get_x());x<xmax;x+=1) + { + ofs_fit_result<<x<<"\t"<<0<<"\t"<<0<<"\t"<<0<<endl; + } + +} diff --git a/mass_profile/fit_nfw_sbp.cpp b/mass_profile/fit_nfw_sbp.cpp new file mode 100644 index 0000000..6343dea --- /dev/null +++ b/mass_profile/fit_nfw_sbp.cpp @@ -0,0 +1,417 @@ +/* + 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 <iostream> +#include <fstream> +#include "vchisq.hpp" +#include "nfw_ne.hpp" +#include <data_sets/default_data_set.hpp> +#include <methods/powell/powell_method.hpp> +#include <core/freeze_param.hpp> +#include <error_estimator/error_estimator.hpp> +#include "spline.h" +#include <cpgplot.h> +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 of cooling function +//check spline.h for more detailed information +//this class is a thin wrapper for the spline class defined in spline.h +class spline_func_obj + :public func_obj<double,double> +{ + //has an spline object + spline<double> 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<<argv[0]<<" <configure file>"<<endl; + cerr<<"Here is a sample of the configure file"<<endl; + cerr<<"radius_file radius1.dat\n" + "sbp_file\tsbp1.dat\n" + "cfunc_file\tcfunc.dat\n" + "n0\t\t.04\n" + "rs\t\t816\n" + "rho0\t\t.01\n" + "bkg\t\t0\n" + "cm_per_pixel\t1.804E21\n" + "z\t\t0.062476\n" + "T_file\t\tT.dat" + <<endl; + cerr<<"Notes:"<<endl; + cerr<<"n0 is in the unit of cm^-3"<<endl; + cerr<<"rs is in the unit of pixel"<<endl; + cerr<<"rho0 is in the unit of mass of proton per cm^3"<<endl; + + return -1; + } + //define a map to store the parameters + std::map<std::string,std::string> 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 "<<r_min<<endl; + } + //note that in this program, the radius are not the central value of each annuli or pie region, but the boundaries. + //for example, if we have a set of radius and surface brightness values as follows: + /* + radius width surface brightness + 1 1 x + 2 1 x + 3 1 x + + then the radius is stored as + 0 1.5 2.5 3.5 + note that there should be 4 radius values, although only to represent 3 annuli. + this will be convenient to calculate the volume of each spherical shell, + and can naturally ensure the annuli are adjacent with each other, with out any gaps. + + + */ + + std::vector<double> radii;//to store radius + std::vector<double> sbps;//to store the surface brightness value + std::vector<double> 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 <ENTER> 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<r_min) + { + ++ncut; + continue; + } + cerr<<x<<endl; + radii.push_back(x); + } + //read in surface brightness file + /* + the surface brightness file contains two columns, that are surface brightness and the error, respectively. + */ + for(ifstream ifs(arg_map["sbp_file"].c_str());;) + { + assert(ifs.is_open()); + double x,xe; + ifs>>x>>xe; + if(!ifs.good()) + { + break; + } + if(ncut) + { + --ncut; + continue; + } + cerr<<x<<"\t"<<xe<<endl; + sbps.push_back(x); + sbpe.push_back(xe); + } + //cerr<<radii.size()<<"\t"<<sbps.size()<<endl; + //return 0; + spline_func_obj cf; + + //read in the cooling function file + /* + the cooling function file contains two columns, that are radius (central value, in pixel) and the ``reduced cooling function'' + the reduced cooling function is calculated as follows + by using wabs*apec model, fill the kT, z, nH to the actual value (derived from deproject spectral fitting), + and fill norm as 1E-14/(4*pi*(Da*(1+z))^2). + then use flux e1 e2 (e1 and e2 are the energy limits of the surface brightness profile) to get the cooling function (in photon counts, + not in erg/s) + */ + for(ifstream ifs(arg_map["cfunc_file"].c_str());;) + { + assert(ifs.is_open()); + double x,y,y1,y2; + ifs>>x>>y; + if(!ifs.good()) + { + break; + } + cerr<<x<<"\t"<<y<<endl; + //cf.add_point(x,y*2.1249719395939022e-68);//change with source + cf.add_point(x,y);//change with source + } + cf.gen_spline(); + + for(double x=0;x<1000;x++) + { + //cout<<x<<"\t"<<cf(x)<<endl; + } + //return 0; + //cout<<radii.size()<<endl; + //cout<<sbps.size()<<endl; + + //initial a data set object and put the data together + default_data_set<std::vector<double>,std::vector<double> > ds; + ds.add_data(data<std::vector<double>,std::vector<double> >(radii,sbps,sbpe,sbpe,radii,radii)); + + //initial a fitter object + fitter<vector<double>,vector<double>,vector<double>,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<double> a; + //define the nfw surface brightness profofile model + nfw_ne<double> 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<r_min) + { + continue; + } + tf.add_point(x,y); + } + tf.gen_spline(); + + //attach the temperature, surface brightness model and projector together + nfw.attach_Tfunc(tf); + a.attach_model(nfw); + f.set_model(a); + //define the chi-square statistic + vchisq<double> c; + c.verbose(true); + f.set_statistic(c); + //set the optimization method, here we use powell method + f.set_opt_method(powell_method<double,std::vector<double> >()); + //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<<f.get_data_set().size()<<endl; + cout<<f.get_num_params()<<endl; +#if 1 + //perform the fitting + f.fit(); + f.set_precision(1e-10); + f.fit(); + f.clear_param_modifier(); + f.fit(); +#endif + //output the parameters + ofstream param_output("nfw_param.txt"); + + for(int i=0;i<f.get_num_params();++i) + { + cout<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + param_output<<f.get_param_info(i).get_name()<<"\t"<<abs(f.get_param_info(i).get_value())<<endl; + } + c.verbose(false); + f.set_statistic(c); +#if 1 + f.fit(); + f.fit(); +#endif + //fetch the fitting result + std::vector<double> p=f.get_all_params(); + f.clear_param_modifier(); + std::vector<double> mv=f.eval_model(radii,p); + cerr<<mv.size()<<endl; + //output the results + ofstream ofs_sbp("sbp_fit.qdp"); + ofstream ofs_resid("resid.qdp"); + ofs_resid<<"read serr 2"<<endl; + //output the surface brightness profile + ofs_sbp<<"read serr 2"<<endl; + ofs_sbp<<"skip single"<<endl; + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double y=sbps[i-1]; + double ye=sbpe[i-1]; + double ym=mv[i-1]; + ofs_sbp<<x*cm_per_pixel/kpc<<"\t"<<y<<"\t"<<ye<<"\t"<<ym<<endl; + ofs_resid<<x*cm_per_pixel/kpc<<"\t"<<(y-ym)/ye<<"\t1\n"; + } + //output the electron density + mv=nfw.eval(radii,p); + ofstream ofs_rho("rho_fit.qdp"); + for(int i=1;i<sbps.size();++i) + { + double x=(radii[i]+radii[i-1])/2; + double ym=mv[i-1]; + ofs_rho<<x*cm_per_pixel/kpc<<"\t"<<ym<<endl; + } + //output integral mass profile + rho0=f.get_param_value("rho0")*1.67E-24; + rs=f.get_param_value("rs")*cm_per_pixel; + ofstream ofs_int_mass("mass_int.qdp"); + for(double r=0;r<2000*kpc;r+=kpc) + { + ofs_int_mass<<r/kpc<<"\t"<<nfw_mass_enclosed(r,abs(rho0),abs(rs))/M_sun<<endl; + } + //calculate the overdensity profile + ofstream ofs_overdensity("overdensity.qdp"); + + std::vector<double> radius_list; + std::vector<double> 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"<<r/kpc<<"\t\t"<<r/cm_per_pixel<<"\t\t"<<nfw_mass_enclosed(r,abs(rho0),abs(rs))/M_sun<<endl; + break; + } + if(delta<=500&&!hit_500) + { + hit_500=true; + cerr<<500<<"\t"<<r/kpc<<"\t\t"<<r/cm_per_pixel<<"\t\t"<<nfw_mass_enclosed(r,abs(rho0),abs(rs))/M_sun<<endl; + } + */ + ofs_overdensity<<r/kpc<<"\t"<<delta<<endl; + } + + for(int i=0;i<radius_list.size()-1;++i) + { + double r=radius_list[i]; + if(delta_list[i]>=200&&delta_list[i+1]<200) + { + cerr<<200<<"\t"<<r/kpc<<"\t\t"<<r/cm_per_pixel<<"\t\t"<<nfw_mass_enclosed(r,abs(rho0),abs(rs))/M_sun<<endl; + } + + if(delta_list[i]>=500&&delta_list[i+1]<500) + { + cerr<<500<<"\t"<<r/kpc<<"\t\t"<<r/cm_per_pixel<<"\t\t"<<nfw_mass_enclosed(r,abs(rho0),abs(rs))/M_sun<<endl; + } + + if(delta_list[i]>=1500&&delta_list[i+1]<1500) + { + cerr<<1500<<"\t"<<r/kpc<<"\t\t"<<r/cm_per_pixel<<"\t\t"<<nfw_mass_enclosed(r,abs(rho0),abs(rs))/M_sun<<endl; + } + + if(delta_list[i]>=2500&&delta_list[i+1]<2500) + { + cerr<<2500<<"\t"<<r/kpc<<"\t\t"<<r/cm_per_pixel<<"\t\t"<<nfw_mass_enclosed(r,abs(rho0),abs(rs))/M_sun<<endl; + } + + } + + //output the M200 and R200 + //cerr<<"M200="<<nfw_mass_enclosed(r200,abs(rho0),abs(rs))/M_sun<<" solar mass"<<endl; + //cerr<<"R200="<<r200/kpc<<" kpc"<<endl; + //for(int i=0;i<p.size();++i) + //{ + //cerr<<p[i]<<endl; + //} + return 0; +} diff --git a/mass_profile/fit_nfwmass_beta.sh b/mass_profile/fit_nfwmass_beta.sh new file mode 100755 index 0000000..1c844b5 --- /dev/null +++ b/mass_profile/fit_nfwmass_beta.sh @@ -0,0 +1,314 @@ +#!/bin/sh + +# modified by LIweitaNux, 2012/09/06 +# export PATH="$ASCDS_BIN:$PATH" +export PATH="/usr/local/bin:/usr/bin:/bin:$PATH" + +if [ $# -eq 1 ]; then + : +elif [ $# -eq 2 ]; then + CENTER_VAL="YES" +else + printf "usage:\n" + printf " `basename $0` <cfg_file> [c]" + exit 1 +fi + +if ! which xspec > /dev/null; then + printf "*** ERROR: please initialize HEASOFT first\n" + exit 2 +fi + +if [ -z "${HEADAS}" ]; then + printf "*** ERROR: variable \`HEADAS' not properly set\n" + exit 3 +fi + +export PGPLOT_FONT="${HEADAS}/lib/grfont.dat" +printf "## PGPLOT_FONT: \`${PGPLOT_FONT}'\n" + +if [ "$0" = `basename $0` ]; then + script_path=`which $0` + base_path=`dirname ${script_path}` +else + base_path=`dirname $0` +fi +printf "## base_path: \`${base_path}'\n" +cfg_file="$1" +printf "## use configuration file: \`${cfg_file}'\n" + +# rmin for fit_nfw_mass +nfw_rmin_kpc=`grep '^nfw_rmin_kpc' $cfg_file | awk '{ print $2 }'` +# profile type name +t_profile_type=`grep '^t_profile' $cfg_file | awk '{ print $2 }'` +printf "## t_profile_type: \`$t_profile_type'\n" +# data file name +t_data_file=`grep '^t_data_file' $cfg_file | awk '{ print $2 }'` +t_param_file=`grep '^t_param_file' $cfg_file | awk '{ print $2 }'` +# sbp config file +sbp_cfg=`grep '^sbp_cfg' $cfg_file | awk '{ print $2 }'` +# temperature profile file +T_file=`grep '^T_file' $sbp_cfg | awk '{ print $2 }'` +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{ print $2 }'` +abund=`grep '^abund' ${cfg_file} |awk '{ print $2 }'` +nh=`grep '^nh' ${cfg_file} |awk '{ print $2 }'` +## calc `cm_per_pixel' instead {{{ +# cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg | awk '{ print $2 }'` +z=`grep '^z' $sbp_cfg | awk '{ print $2 }'` +cm_per_pixel=`${base_path}/calc_distance ${z} | grep 'cm_per_pixel' | awk '{ print $2 }'` +sed -i'' "s/^cm_per_pixel.*$/cm_per_pixel ${cm_per_pixel}/" ${sbp_cfg} +printf "## redshift: ${z}, cm_per_pixel: ${cm_per_pixel}\n" +## cm_per_pixel }}} +da=`python -c "print($cm_per_pixel/(.492/3600/180*3.1415926))"` +dl=`python -c "print($da*(1+$z)**2)"` +printf "da= ${da}\n" +printf "dl= ${dl}\n" +## sbp {{{ +sbp_data_file=`grep '^sbp_file' $sbp_cfg | awk '{ print $2 }'` +radius_sbp_file=`grep '^radius_sbp_file' ${cfg_file} | awk '{ print $2 }'` + +if [ "x$radius_sbp_file" = "x" ]; then + printf "*** ERROR: radius_sbp_file not found\n" + exit 200 +fi + +TMP_RSBP="_tmp_rsbp.txt" +[ -e "${TMP_RSBP}" ] && rm -f ${TMP_RSBP} +cat ${radius_sbp_file} | sed 's/#.*$//' | grep -Ev '^\s*$' > ${TMP_RSBP} +# mv -f _tmp_rsbp.txt ${radius_sbp_file} +radius_sbp_file="${TMP_RSBP}" +## sbp }}} + +# determine which temperature profile to be used, and fit the T profile {{{ +if [ "$t_profile_type" = "zyy" ]; then + $base_path/fit_zyy_model $t_data_file $t_param_file $cm_per_pixel + # mv -f zyy_dump.qdp ${T_file} + mv -f zyy_dump.qdp zyy_dump_center.qdp +elif [ "$t_profile_type" = "m0603246" ]; then + $base_path/fit_m0603246 $t_data_file $cm_per_pixel + # mv -f m0603246_dump.qdp ${T_file} + mv -f m0603246_dump.qdp m0603246_dump_center.qdp +elif [ "$t_profile_type" = "wang2012" ]; then + T_param_center="wang2012_center_param.txt" + T_file_center="wang2012_dump_center.qdp" + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel 2> /dev/null | tee ${T_param_center} + # mv -f wang2012_dump.qdp ${T_file} + cp -fv wang2012_dump.qdp ${T_file} + mv -fv wang2012_dump.qdp ${T_file_center} + mv -fv fit_result.qdp wang2012_fit_center.qdp +elif [ "$t_profile_type" = "allen" ]; then + $base_path/fit_allen_model $t_data_file $cm_per_pixel + # mv -f allen_dump.qdp ${T_file} + mv -f allen_dump.qdp allen_dump_center.qdp +elif [ "$t_profile_type" = "zzl" ]; then + $base_path/fit_zzl_model $t_data_file $t_param_file + # mv -f zzl_dump.qdp ${T_file} + mv -f zzl_dump.qdp zzl_dump_center.qdp +else + printf "ERROR: temperature profile name \`${t_profile_type}' invalid!\n" + exit 10 +fi +# temp profile }}} + +$base_path/coolfunc_calc2.sh ${T_file_center} $abund $nh $z $cfunc_file cfunc_bolo.dat +cfunc_file_center="coolfunc_data_center.txt" +cp -f ${cfunc_file} ${cfunc_file_center} +mv -fv flux_cnt_ratio.txt flux_cnt_ratio_center.txt +# fit sbp (single-beta) +MODEL="single-beta" +SBP_PROG="fit_beta_sbp" +RES_SBPFIT="beta_param.txt" +RES_SBPFIT_CENTER="beta_param_center.txt" +${base_path}/${SBP_PROG} $sbp_cfg 2> /dev/null +mv -fv ${RES_SBPFIT} ${RES_SBPFIT_CENTER} +cat ${RES_SBPFIT_CENTER} +mv -fv sbp_fit.qdp sbp_fit_center.qdp +mv -fv rho_fit.qdp rho_fit_center.qdp +mv -fv rho_fit.dat rho_fit_center.dat +$base_path/fit_nfw_mass mass_int.dat $z $nfw_rmin_kpc 2> /dev/null +mv -fv nfw_param.txt nfw_param_center.txt +mv -fv nfw_fit_result.qdp nfw_fit_center.qdp +mv -fv nfw_dump.qdp mass_int_center.qdp +mv -fv overdensity.qdp overdensity_center.qdp +mv -fv gas_mass_int.qdp gas_mass_int_center.qdp + +#exit 233 + +## cooling time (-> use 'ciao_calc_ct.sh') +$base_path/cooling_time rho_fit_center.dat ${T_file_center} cfunc_bolo.dat $dl $cm_per_pixel > cooling_time.dat +## radius to calculate tcool, not the cooling time! +rcool=`$base_path/analyze_mass_profile.py 500 c | grep '^r500' | awk -F'=' '{ print .048*$2 }'` +printf "rcool= ${rcool}\n" + +## center value {{{ +if [ "${CENTER_VAL}" = "YES" ]; then + RES_CENTER="center_only_results.txt" + [ -e "${RES_CENTER}" ] && mv -f ${RES_CENTER} ${RES_CENTER}_bak + $base_path/analyze_mass_profile.py 200 c | tee -a ${RES_CENTER} + $base_path/analyze_mass_profile.py 500 c | tee -a ${RES_CENTER} + $base_path/analyze_mass_profile.py 1500 c | tee -a ${RES_CENTER} + $base_path/analyze_mass_profile.py 2500 c | tee -a ${RES_CENTER} + $base_path/extract_tcool.py $rcool | tee -a ${RES_CENTER} + $base_path/fg_2500_500.py c | tee -a ${RES_CENTER} + exit 0 +fi +## center value }}} + +# clean previous files +rm -f summary_shuffle_mass_profile.qdp +rm -f summary_overdensity.qdp +rm -f summary_mass_profile.qdp +rm -f summary_gas_mass_profile.qdp + +## count +COUNT=1 + +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +printf "\n+++++++++++++++++++ Monte Carlo +++++++++++++++++++++\n" +for i in `seq 1 100`; do + # echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + # t_data_file=temp_shuffled_t.dat +#exit + + if [ "$t_profile_type" = "zyy" ]; then + $base_path/fit_zyy_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} + elif [ "$t_profile_type" = "m0603246" ]; then + $base_path/fit_m0603246 temp_shuffled_t.dat $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} + elif [ "$t_profile_type" = "wang2012" ]; then + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel 2> /dev/null + mv -f wang2012_dump.qdp ${T_file} + elif [ "$t_profile_type" = "allen" ]; then + $base_path/fit_allen_model temp_shuffled_t.dat $cm_per_pixel + mv -f allen_dump.qdp ${T_file} + elif [ "$t_profile_type" = "zzl" ]; then + $base_path/fit_zzl_model temp_shuffled_t.dat $t_param_file + mv -f zzl_dump.qdp ${T_file} + else + printf "ERROR: temperature profile name \`${t_profile_type}' invalid!\n" + exit 10 + fi + + #exit + + # clear ${TMP_SBP_CFG} + TMP_SBP_CFG="temp_sbp.cfg" + # : > ${TMP_SBP_CFG} + [ -e "${TMP_SBP_CFG}" ] && rm -f ${TMP_SBP_CFG} + + cat $sbp_cfg | while read l; do + if echo "$l" | grep -q 'sbp_file'; then + echo "sbp_file temp_shuffled_sbp.dat" >> ${TMP_SBP_CFG} + elif echo "$l" | grep -q 'T_file'; then + echo "T_file ${T_file}" >> ${TMP_SBP_CFG} + else + echo "$l" >> ${TMP_SBP_CFG} + fi + done + + ## count + printf "## ${COUNT} ##\n" + COUNT=`expr ${COUNT} + 1` + printf "## `pwd` ##\n" + $base_path/coolfunc_calc2.sh ${T_file} ${abund} ${nh} ${z} ${cfunc_file} + + ${base_path}/${SBP_PROG} ${TMP_SBP_CFG} 2> /dev/null + cat ${RES_SBPFIT} + $base_path/fit_nfw_mass mass_int.dat ${z} ${nfw_rmin_kpc} 2> /dev/null + cat nfw_dump.qdp >> summary_mass_profile.qdp + echo "no no no" >> summary_mass_profile.qdp + cat overdensity.qdp >> summary_overdensity.qdp + echo "no no no" >> summary_overdensity.qdp + cat gas_mass_int.qdp >> summary_gas_mass_profile.qdp + echo "no no no" >> summary_gas_mass_profile.qdp + +done # end `while' +# recover `center_files' +cp -f ${cfunc_file_center} ${cfunc_file} +cp -f ${T_file_center} ${T_file} +printf "\n+++++++++++++++++ MONTE CARLO END +++++++++++++++++++\n" + +## analyze results +RES_TMP="_tmp_result_mrl.txt" +RES_FINAL="final_result.txt" +[ -e "${RES_TMP}" ] && mv -fv ${RES_TMP} ${RES_TMP}_bak +[ -e "${RES_FINAL}" ] && mv -fv ${RES_FINAL} ${RES_FINAL}_bak + +$base_path/analyze_mass_profile.py 200 | tee -a ${RES_TMP} +$base_path/analyze_mass_profile.py 500 | tee -a ${RES_TMP} +$base_path/analyze_mass_profile.py 1500 | tee -a ${RES_TMP} +$base_path/analyze_mass_profile.py 2500 | tee -a ${RES_TMP} + +R200_VAL=`grep '^r200' ${RES_TMP} | awk '{ print $2 }'` +R500_VAL=`grep '^r500' ${RES_TMP} | awk '{ print $2 }'` +R1500_VAL=`grep '^r1500' ${RES_TMP} | awk '{ print $2 }'` +R2500_VAL=`grep '^r2500' ${RES_TMP} | awk '{ print $2 }'` +printf "## R200: ${R200_VAL}\n" +printf "## R500: ${R500_VAL}\n" +printf "## R1500: ${R1500_VAL}\n" +printf "## R2500: ${R2500_VAL}\n" +L200E=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $R200_VAL $t_data_file | grep '^Lx' | awk '{ print $2,$3,$4 }'` +L500E=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $R500_VAL $t_data_file | grep '^Lx' | awk '{ print $2,$3,$4 }'` +L1500E=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $R1500_VAL $t_data_file | grep '^Lx' | awk '{ print $2,$3,$4 }'` +L2500E=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $R2500_VAL $t_data_file | grep '^Lx' | awk '{ print $2,$3,$4 }'` +R200E=`grep '^r200' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +R500E=`grep '^r500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +R1500E=`grep '^r1500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +R2500E=`grep '^r2500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +M200E=`grep '^m200' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +M500E=`grep '^m500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +M1500E=`grep '^m1500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +M2500E=`grep '^m2500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +MG200E=`grep '^gas_m200' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +MG500E=`grep '^gas_m500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +MG1500E=`grep '^gas_m1500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +MG2500E=`grep '^gas_m2500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +FG200E=`grep '^gas_fraction200' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +FG500E=`grep '^gas_fraction500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +FG1500E=`grep '^gas_fraction1500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +FG2500E=`grep '^gas_fraction2500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` + +printf "\n+++++++++++++++ RESULTS (${MODEL}) +++++++++++++++\n" +printf "cfg: ${cfg_file}\n" | tee -a ${RES_FINAL} +printf "model: ${MODEL}\n" | tee -a ${RES_FINAL} +printf "\n" | tee -a ${RES_FINAL} +cat ${RES_SBPFIT_CENTER} | tee -a ${RES_FINAL} +printf "\n" | tee -a ${RES_FINAL} +printf "r200= ${R200E} kpc\n" | tee -a ${RES_FINAL} +printf "m200= ${M200E} M_sun\n" | tee -a ${RES_FINAL} +printf "L200= ${L200E} erg/s\n" | tee -a ${RES_FINAL} +printf "gas_m200= ${MG200E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas_fraction200= ${FG200E} x100%%\n" | tee -a ${RES_FINAL} +printf "r500= ${R500E} kpc\n" | tee -a ${RES_FINAL} +printf "m500= ${M500E} M_sun\n" | tee -a ${RES_FINAL} +printf "L500= ${L500E} erg/s\n" | tee -a ${RES_FINAL} +printf "gas_m500= ${MG500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas_fraction500= ${FG500E} x100%%\n" | tee -a ${RES_FINAL} +printf "r1500= ${R1500E} kpc\n" | tee -a ${RES_FINAL} +printf "m1500= ${M1500E} M_sun\n" | tee -a ${RES_FINAL} +printf "L1500= ${L1500E} erg/s\n" | tee -a ${RES_FINAL} +printf "gas_m1500= ${MG1500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas_fraction1500= ${FG1500E} x100%%\n" | tee -a ${RES_FINAL} +printf "r2500= ${R2500E} kpc\n" | tee -a ${RES_FINAL} +printf "m2500= ${M2500E} M_sun\n" | tee -a ${RES_FINAL} +printf "L2500= ${L2500E} erg/s\n" | tee -a ${RES_FINAL} +printf "gas_m2500= ${MG2500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas_fraction2500= ${FG2500E} x100%%\n" | tee -a ${RES_FINAL} +printf "\n" | tee -a ${RES_FINAL} +printf "gas mass 200= ${MG200E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas fractho 200= ${FG200E} x100%%\n" | tee -a ${RES_FINAL} +printf "gas mass 500= ${MG500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas fractho 500= ${FG500E} x100%%\n" | tee -a ${RES_FINAL} +printf "gas mass 1500= ${MG1500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas fractho 1500= ${FG1500E} x100%%\n" | tee -a ${RES_FINAL} +printf "gas mass 2500= ${MG2500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas fractho 2500= ${FG2500E} x100%%\n" | tee -a ${RES_FINAL} +printf "\n" | tee -a ${RES_FINAL} +$base_path/extract_tcool.py $rcool | tee -a ${RES_FINAL} +$base_path/fg_2500_500.py | tee -a ${RES_FINAL} +printf "\n+++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + diff --git a/mass_profile/fit_nfwmass_dbeta.sh b/mass_profile/fit_nfwmass_dbeta.sh new file mode 100755 index 0000000..1e9b7c1 --- /dev/null +++ b/mass_profile/fit_nfwmass_dbeta.sh @@ -0,0 +1,314 @@ +#!/bin/sh + +# modified by LIweitaNux, 2012/09/06 +# export PATH="$ASCDS_BIN:$PATH" +export PATH="/usr/local/bin:/usr/bin:/bin:$PATH" + +if [ $# -eq 1 ]; then + : +elif [ $# -eq 2 ]; then + CENTER_VAL="YES" +else + printf "usage:\n" + printf " `basename $0` <cfg_file> [c]" + exit 1 +fi + +if ! which xspec > /dev/null; then + printf "*** ERROR: please initialize HEASOFT first\n" + exit 2 +fi + +if [ -z "${HEADAS}" ]; then + printf "*** ERROR: variable \`HEADAS' not properly set\n" + exit 3 +fi + +export PGPLOT_FONT="${HEADAS}/lib/grfont.dat" +printf "## PGPLOT_FONT: \`${PGPLOT_FONT}'\n" + +if [ "$0" = `basename $0` ]; then + script_path=`which $0` + base_path=`dirname ${script_path}` +else + base_path=`dirname $0` +fi +printf "## base_path: \`${base_path}'\n" +cfg_file="$1" +printf "## use configuration file: \`${cfg_file}'\n" + +# rmin for fit_nfw_mass +nfw_rmin_kpc=`grep '^nfw_rmin_kpc' $cfg_file | awk '{ print $2 }'` +# profile type name +t_profile_type=`grep '^t_profile' $cfg_file | awk '{ print $2 }'` +printf "## t_profile_type: \`$t_profile_type'\n" +# data file name +t_data_file=`grep '^t_data_file' $cfg_file | awk '{ print $2 }'` +t_param_file=`grep '^t_param_file' $cfg_file | awk '{ print $2 }'` +# sbp config file +sbp_cfg=`grep '^sbp_cfg' $cfg_file | awk '{ print $2 }'` +# temperature profile file +T_file=`grep '^T_file' $sbp_cfg | awk '{ print $2 }'` +cfunc_file=`grep '^cfunc_file' ${sbp_cfg} |awk '{ print $2 }'` +abund=`grep '^abund' ${cfg_file} |awk '{ print $2 }'` +nh=`grep '^nh' ${cfg_file} |awk '{ print $2 }'` +## calc `cm_per_pixel' instead {{{ +# cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg | awk '{ print $2 }'` +z=`grep '^z' $sbp_cfg | awk '{ print $2 }'` +cm_per_pixel=`${base_path}/calc_distance ${z} | grep 'cm_per_pixel' | awk '{ print $2 }'` +sed -i'' "s/^cm_per_pixel.*$/cm_per_pixel ${cm_per_pixel}/" ${sbp_cfg} +printf "## redshift: ${z}, cm_per_pixel: ${cm_per_pixel}\n" +## cm_per_pixel }}} +da=`python -c "print($cm_per_pixel/(.492/3600/180*3.1415926))"` +dl=`python -c "print($da*(1+$z)**2)"` +printf "da= ${da}\n" +printf "dl= ${dl}\n" +## sbp {{{ +sbp_data_file=`grep '^sbp_file' $sbp_cfg | awk '{ print $2 }'` +radius_sbp_file=`grep '^radius_sbp_file' ${cfg_file} | awk '{ print $2 }'` + +if [ "x$radius_sbp_file" = "x" ]; then + printf "*** ERROR: radius_sbp_file not found\n" + exit 200 +fi + +TMP_RSBP="_tmp_rsbp.txt" +[ -e "${TMP_RSBP}" ] && rm -f ${TMP_RSBP} +cat ${radius_sbp_file} | sed 's/#.*$//' | grep -Ev '^\s*$' > ${TMP_RSBP} +# mv -f _tmp_rsbp.txt ${radius_sbp_file} +radius_sbp_file="${TMP_RSBP}" +## sbp }}} + +# determine which temperature profile to be used, and fit the T profile {{{ +if [ "$t_profile_type" = "zyy" ]; then + $base_path/fit_zyy_model $t_data_file $t_param_file $cm_per_pixel + # mv -f zyy_dump.qdp ${T_file} + mv -f zyy_dump.qdp zyy_dump_center.qdp +elif [ "$t_profile_type" = "m0603246" ]; then + $base_path/fit_m0603246 $t_data_file $cm_per_pixel + # mv -f m0603246_dump.qdp ${T_file} + mv -f m0603246_dump.qdp m0603246_dump_center.qdp +elif [ "$t_profile_type" = "wang2012" ]; then + T_param_center="wang2012_center_param.txt" + T_file_center="wang2012_dump_center.qdp" + $base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel 2> /dev/null | tee ${T_param_center} + # mv -f wang2012_dump.qdp ${T_file} + cp -fv wang2012_dump.qdp ${T_file} + mv -fv wang2012_dump.qdp ${T_file_center} + mv -fv fit_result.qdp wang2012_fit_center.qdp +elif [ "$t_profile_type" = "allen" ]; then + $base_path/fit_allen_model $t_data_file $cm_per_pixel + # mv -f allen_dump.qdp ${T_file} + mv -f allen_dump.qdp allen_dump_center.qdp +elif [ "$t_profile_type" = "zzl" ]; then + $base_path/fit_zzl_model $t_data_file $t_param_file + # mv -f zzl_dump.qdp ${T_file} + mv -f zzl_dump.qdp zzl_dump_center.qdp +else + printf "ERROR: temperature profile name \`${t_profile_type}' invalid!\n" + exit 10 +fi +# temp profile }}} + +$base_path/coolfunc_calc2.sh ${T_file_center} $abund $nh $z $cfunc_file cfunc_bolo.dat +cfunc_file_center="coolfunc_data_center.txt" +cp -f ${cfunc_file} ${cfunc_file_center} +mv -fv flux_cnt_ratio.txt flux_cnt_ratio_center.txt +# fit sbp (double-beta) +MODEL="double-beta" +SBP_PROG="fit_dbeta_sbp" +RES_SBPFIT="dbeta_param.txt" +RES_SBPFIT_CENTER="dbeta_param_center.txt" +${base_path}/${SBP_PROG} $sbp_cfg 2> /dev/null +mv -fv ${RES_SBPFIT} ${RES_SBPFIT_CENTER} +cat ${RES_SBPFIT_CENTER} +mv -fv sbp_fit.qdp sbp_fit_center.qdp +mv -fv rho_fit.qdp rho_fit_center.qdp +mv -fv rho_fit.dat rho_fit_center.dat +$base_path/fit_nfw_mass mass_int.dat $z $nfw_rmin_kpc 2> /dev/null +mv -fv nfw_param.txt nfw_param_center.txt +mv -fv nfw_fit_result.qdp nfw_fit_center.qdp +mv -fv nfw_dump.qdp mass_int_center.qdp +mv -fv overdensity.qdp overdensity_center.qdp +mv -fv gas_mass_int.qdp gas_mass_int_center.qdp + +#exit 233 + +## cooling time (-> use 'ciao_calc_ct.sh') +$base_path/cooling_time rho_fit_center.dat ${T_file_center} cfunc_bolo.dat $dl $cm_per_pixel > cooling_time.dat +## radius to calculate tcool, not the cooling time! +rcool=`$base_path/analyze_mass_profile.py 500 c | grep '^r500' | awk -F'=' '{ print .048*$2 }'` +printf "rcool= ${rcool}\n" + +## center value {{{ +if [ "${CENTER_VAL}" = "YES" ]; then + RES_CENTER="center_only_results.txt" + [ -e "${RES_CENTER}" ] && mv -f ${RES_CENTER} ${RES_CENTER}_bak + $base_path/analyze_mass_profile.py 200 c | tee -a ${RES_CENTER} + $base_path/analyze_mass_profile.py 500 c | tee -a ${RES_CENTER} + $base_path/analyze_mass_profile.py 1500 c | tee -a ${RES_CENTER} + $base_path/analyze_mass_profile.py 2500 c | tee -a ${RES_CENTER} + $base_path/extract_tcool.py $rcool | tee -a ${RES_CENTER} + $base_path/fg_2500_500.py c | tee -a ${RES_CENTER} + exit 0 +fi +## center value }}} + +# clean previous files +rm -f summary_shuffle_mass_profile.qdp +rm -f summary_overdensity.qdp +rm -f summary_mass_profile.qdp +rm -f summary_gas_mass_profile.qdp + +## count +COUNT=1 + +#100 times of Monte-carlo simulation to determine error +#just repeat above steps +printf "\n+++++++++++++++++++ Monte Carlo +++++++++++++++++++++\n" +for i in `seq 1 100`; do + # echo $t_data_file + $base_path/shuffle_T.py $t_data_file temp_shuffled_t.dat + $base_path/shuffle_sbp.py $sbp_data_file temp_shuffled_sbp.dat + # t_data_file=temp_shuffled_t.dat +#exit + + if [ "$t_profile_type" = "zyy" ]; then + $base_path/fit_zyy_model temp_shuffled_t.dat $t_param_file $cm_per_pixel + mv -f zyy_dump.qdp ${T_file} + elif [ "$t_profile_type" = "m0603246" ]; then + $base_path/fit_m0603246 temp_shuffled_t.dat $cm_per_pixel + mv -f m0603246_dump.qdp ${T_file} + elif [ "$t_profile_type" = "wang2012" ]; then + $base_path/fit_wang2012_model temp_shuffled_t.dat $t_param_file $cm_per_pixel 2> /dev/null + mv -f wang2012_dump.qdp ${T_file} + elif [ "$t_profile_type" = "allen" ]; then + $base_path/fit_allen_model temp_shuffled_t.dat $cm_per_pixel + mv -f allen_dump.qdp ${T_file} + elif [ "$t_profile_type" = "zzl" ]; then + $base_path/fit_zzl_model temp_shuffled_t.dat $t_param_file + mv -f zzl_dump.qdp ${T_file} + else + printf "ERROR: temperature profile name \`${t_profile_type}' invalid!\n" + exit 10 + fi + + #exit + + # clear ${TMP_SBP_CFG} + TMP_SBP_CFG="temp_sbp.cfg" + # : > ${TMP_SBP_CFG} + [ -e "${TMP_SBP_CFG}" ] && rm -f ${TMP_SBP_CFG} + + cat $sbp_cfg | while read l; do + if echo "$l" | grep -q 'sbp_file'; then + echo "sbp_file temp_shuffled_sbp.dat" >> ${TMP_SBP_CFG} + elif echo "$l" | grep -q 'T_file'; then + echo "T_file ${T_file}" >> ${TMP_SBP_CFG} + else + echo "$l" >> ${TMP_SBP_CFG} + fi + done + + ## count + printf "## ${COUNT} ##\n" + COUNT=`expr ${COUNT} + 1` + printf "## `pwd` ##\n" + $base_path/coolfunc_calc2.sh ${T_file} ${abund} ${nh} ${z} ${cfunc_file} + + ${base_path}/${SBP_PROG} ${TMP_SBP_CFG} 2> /dev/null + cat ${RES_SBPFIT} + $base_path/fit_nfw_mass mass_int.dat ${z} ${nfw_rmin_kpc} 2> /dev/null + cat nfw_dump.qdp >> summary_mass_profile.qdp + echo "no no no" >> summary_mass_profile.qdp + cat overdensity.qdp >> summary_overdensity.qdp + echo "no no no" >> summary_overdensity.qdp + cat gas_mass_int.qdp >> summary_gas_mass_profile.qdp + echo "no no no" >> summary_gas_mass_profile.qdp + +done # end `while' +# recover `center_files' +cp -f ${cfunc_file_center} ${cfunc_file} +cp -f ${T_file_center} ${T_file} +printf "\n+++++++++++++++++ MONTE CARLO END +++++++++++++++++++\n" + +## analyze results +RES_TMP="_tmp_result_mrl.txt" +RES_FINAL="final_result.txt" +[ -e "${RES_TMP}" ] && mv -fv ${RES_TMP} ${RES_TMP}_bak +[ -e "${RES_FINAL}" ] && mv -fv ${RES_FINAL} ${RES_FINAL}_bak + +$base_path/analyze_mass_profile.py 200 | tee -a ${RES_TMP} +$base_path/analyze_mass_profile.py 500 | tee -a ${RES_TMP} +$base_path/analyze_mass_profile.py 1500 | tee -a ${RES_TMP} +$base_path/analyze_mass_profile.py 2500 | tee -a ${RES_TMP} + +R200_VAL=`grep '^r200' ${RES_TMP} | awk '{ print $2 }'` +R500_VAL=`grep '^r500' ${RES_TMP} | awk '{ print $2 }'` +R1500_VAL=`grep '^r1500' ${RES_TMP} | awk '{ print $2 }'` +R2500_VAL=`grep '^r2500' ${RES_TMP} | awk '{ print $2 }'` +printf "## R200: ${R200_VAL}\n" +printf "## R500: ${R500_VAL}\n" +printf "## R1500: ${R1500_VAL}\n" +printf "## R2500: ${R2500_VAL}\n" +L200E=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $R200_VAL $t_data_file | grep '^Lx' | awk '{ print $2,$3,$4 }'` +L500E=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $R500_VAL $t_data_file | grep '^Lx' | awk '{ print $2,$3,$4 }'` +L1500E=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $R1500_VAL $t_data_file | grep '^Lx' | awk '{ print $2,$3,$4 }'` +L2500E=`$base_path/calc_lx $radius_sbp_file flux_cnt_ratio_center.txt $z $R2500_VAL $t_data_file | grep '^Lx' | awk '{ print $2,$3,$4 }'` +R200E=`grep '^r200' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +R500E=`grep '^r500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +R1500E=`grep '^r1500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +R2500E=`grep '^r2500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +M200E=`grep '^m200' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +M500E=`grep '^m500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +M1500E=`grep '^m1500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +M2500E=`grep '^m2500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +MG200E=`grep '^gas_m200' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +MG500E=`grep '^gas_m500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +MG1500E=`grep '^gas_m1500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +MG2500E=`grep '^gas_m2500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +FG200E=`grep '^gas_fraction200' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +FG500E=`grep '^gas_fraction500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +FG1500E=`grep '^gas_fraction1500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` +FG2500E=`grep '^gas_fraction2500' ${RES_TMP} | tail -n 1 | awk '{ print $2,$3 }'` + +printf "\n+++++++++++++++ RESULTS (${MODEL}) +++++++++++++++\n" +printf "cfg: ${cfg_file}\n" | tee -a ${RES_FINAL} +printf "model: ${MODEL}\n" | tee -a ${RES_FINAL} +printf "\n" | tee -a ${RES_FINAL} +cat ${RES_SBPFIT_CENTER} | tee -a ${RES_FINAL} +printf "\n" | tee -a ${RES_FINAL} +printf "r200= ${R200E} kpc\n" | tee -a ${RES_FINAL} +printf "m200= ${M200E} M_sun\n" | tee -a ${RES_FINAL} +printf "L200= ${L200E} erg/s\n" | tee -a ${RES_FINAL} +printf "gas_m200= ${MG200E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas_fraction200= ${FG200E} x100%%\n" | tee -a ${RES_FINAL} +printf "r500= ${R500E} kpc\n" | tee -a ${RES_FINAL} +printf "m500= ${M500E} M_sun\n" | tee -a ${RES_FINAL} +printf "L500= ${L500E} erg/s\n" | tee -a ${RES_FINAL} +printf "gas_m500= ${MG500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas_fraction500= ${FG500E} x100%%\n" | tee -a ${RES_FINAL} +printf "r1500= ${R1500E} kpc\n" | tee -a ${RES_FINAL} +printf "m1500= ${M1500E} M_sun\n" | tee -a ${RES_FINAL} +printf "L1500= ${L1500E} erg/s\n" | tee -a ${RES_FINAL} +printf "gas_m1500= ${MG1500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas_fraction1500= ${FG1500E} x100%%\n" | tee -a ${RES_FINAL} +printf "r2500= ${R2500E} kpc\n" | tee -a ${RES_FINAL} +printf "m2500= ${M2500E} M_sun\n" | tee -a ${RES_FINAL} +printf "L2500= ${L2500E} erg/s\n" | tee -a ${RES_FINAL} +printf "gas_m2500= ${MG2500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas_fraction2500= ${FG2500E} x100%%\n" | tee -a ${RES_FINAL} +printf "\n" | tee -a ${RES_FINAL} +printf "gas mass 200= ${MG200E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas fractho 200= ${FG200E} x100%%\n" | tee -a ${RES_FINAL} +printf "gas mass 500= ${MG500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas fractho 500= ${FG500E} x100%%\n" | tee -a ${RES_FINAL} +printf "gas mass 1500= ${MG1500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas fractho 1500= ${FG1500E} x100%%\n" | tee -a ${RES_FINAL} +printf "gas mass 2500= ${MG2500E} M_sun\n" | tee -a ${RES_FINAL} +printf "gas fractho 2500= ${FG2500E} x100%%\n" | tee -a ${RES_FINAL} +printf "\n" | tee -a ${RES_FINAL} +$base_path/extract_tcool.py $rcool | tee -a ${RES_FINAL} +$base_path/fg_2500_500.py | tee -a ${RES_FINAL} +printf "\n+++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + diff --git a/mass_profile/fit_sbp.sh b/mass_profile/fit_sbp.sh new file mode 100755 index 0000000..76aaaaf --- /dev/null +++ b/mass_profile/fit_sbp.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# + +if [ $# -ne 1 ]; then + printf "usage: $0 <mass_conf>\n" + exit 1 +fi +cfg_file=$1 +if [ "$0" = `basename $0` ]; then + script_path=`which $0` + base_path=`dirname ${script_path}` +else + base_path=`dirname $0` +fi + +sbp_cfg=`grep '^sbp_cfg' $cfg_file | awk '{ print $2 }'` +t_data_file=`grep '^t_data_file' $cfg_file | awk '{ print $2 }'` +t_param_file=`grep '^t_param_file' $cfg_file | awk '{ print $2 }'` +nh=`grep '^nh' $cfg_file | awk '{ print $2 }'` +abund=`grep '^abund' $cfg_file | awk '{ print $2 }'` +z=`grep '^z' $sbp_cfg | awk '{ print $2 }'` +cm_per_pixel=`${base_path}/calc_distance ${z} | grep 'cm_per_pixel' | awk '{ print $2 }'` +sed -i'' "s/^cm_per_pixel.*$/cm_per_pixel ${cm_per_pixel}/" ${sbp_cfg} +cfunc_file=`grep '^cfunc_file' $sbp_cfg | awk '{ print $2 }'` +T_file=`grep '^T_file' $sbp_cfg | awk '{ print $2 }'` + +if grep -q '^beta2' $sbp_cfg; then + MODEL="double-beta" + PROG=fit_dbeta_sbp +else + MODEL="single-beta" + PROG=fit_beta_sbp +fi + +$base_path/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel 2> /dev/null +cp wang2012_dump.qdp $T_file +if [ ! -f ${cfunc_file} ]; then + $base_path/coolfunc_calc2.sh $T_file $abund $nh $z $cfunc_file +fi +$base_path/$PROG $sbp_cfg +printf "## MODEL: ${MODEL}\n" +printf "## z: ${z}\n" + diff --git a/mass_profile/fit_wang2012_model.cpp b/mass_profile/fit_wang2012_model.cpp new file mode 100644 index 0000000..3fe14b6 --- /dev/null +++ b/mass_profile/fit_wang2012_model.cpp @@ -0,0 +1,195 @@ +/* + Fitting Jy Wang's temperature profile model + Author: Jingying Wang + Last modification 20120819 + +*/ + +#include "wang2012_model.hpp" +#include <core/optimizer.hpp> +#include <core/fitter.hpp> +#include <data_sets/default_data_set.hpp> +#include "chisq.hpp" +#include <methods/powell/powell_method.hpp> +#include <core/freeze_param.hpp> +#include <iostream> +#include <fstream> +#include <vector> +#include <string> + +using namespace opt_utilities; +using namespace std; +const double cm=1; +const double kpc=3.08568e+21*cm; + +int main(int argc,char* argv[]) +{ + if(argc<2) + { + cerr<<"Usage:"<<argv[0]<<" <data file with 4 columns of x, xe, y, ye> [param file] [cm per pixel]"<<endl; + return -1; + } + double cm_per_pixel=-1; + if(argc>=4) + { + cm_per_pixel=atof(argv[3]); + } + + //define the fitter + fitter<double,double,vector<double>,double,std::string> fit; + //define the data set + default_data_set<double,double> ds; + //open the data file + ifstream ifs(argv[1]); + double min_r=1e9; + //cout<<"read serr 2"<<endl; + ofstream ofs_fit_result("fit_result.qdp"); + ofs_fit_result<<"read serr 1 2"<<endl; + ofs_fit_result<<"skip single"<<endl; + if(cm_per_pixel>0) + { + ofs_fit_result<<"la x radius (kpc)"<<endl; + } + else + { + ofs_fit_result<<"la x radius (pixel)"<<endl; + } + ofs_fit_result<<"la y temperature (keV)"<<endl; + for(;;) + { + //read radius, temperature and error + double r,re,t,te; + ifs>>r>>re>>t>>te; + if(!ifs.good()) + { + break; + } + min_r=min(r,min_r); + data<double,double> d(r,t,te,te,re,re); + //std::cerr<<r<<"\t"<<t<<"\t"<<te<<endl; + if(cm_per_pixel>0) + { + ofs_fit_result<<r*cm_per_pixel/kpc<<"\t"<<re*cm_per_pixel/kpc<<"\t"<<t<<"\t"<<te<<endl; + } + else + { + ofs_fit_result<<r<<"\t"<<re<<"\t"<<t<<"\t"<<te<<endl; + } + ds.add_data(d); + } + ofs_fit_result<<"no no no"<<endl; + //load data + fit.load_data(ds); + //define the optimization method + fit.set_opt_method(powell_method<double,vector<double> >()); + //use chi^2 statistic + chisq<double,double,vector<double>,double,std::string> chisq_object; + chisq_object.set_limit(); + fit.set_statistic(chisq_object); + //fit.set_statistic(chisq<double,double,vector<double>,double,std::string>()); + fit.set_model(wang2012_model<double>()); + + if(argc>=3&&std::string(argv[2])!="NONE") + { + std::vector<std::string> freeze_list; + ifstream ifs_param(argv[2]); + assert(ifs_param.is_open()); + for(;;) + { + string pname; + double pvalue; + double lower,upper; + char param_status; + ifs_param>>pname>>pvalue>>lower>>upper>>param_status; + if(!ifs_param.good()) + { + break; + } + if(param_status=='F') + { + freeze_list.push_back(pname); + } + if(pvalue<=lower||pvalue>=upper) + { + cerr<<"Invalid initial value, central value not enclosed by the lower and upper boundaries, adjust automatically"<<endl; + pvalue=std::max(pvalue,lower); + pvalue=std::min(pvalue,upper); + } + fit.set_param_value(pname,pvalue); + fit.set_param_lower_limit(pname,lower); + fit.set_param_upper_limit(pname,upper); + } + if(!freeze_list.empty()) + { + freeze_param<double,double,std::vector<double>,std::string> fp(freeze_list[0]); + fit.set_param_modifier(fp); + for(int i=1;i<freeze_list.size();++i) + { + dynamic_cast<freeze_param<double,double,std::vector<double>,std::string>&>(fit.get_param_modifier())+=freeze_param<double,double,std::vector<double>,std::string>(freeze_list[i]); + } + } + } + + for(int i=0;i<100;++i) + { + fit.fit(); + } + vector<double> p=fit.fit(); +#if 0 + ofstream output_param; + if(argc>=3&&std::string(argv[2])!="NONE") + { + output_param.open(argv[2]); + } + else + { + output_param.open("para0.txt"); + } +#endif + //output parameters + for(int i=0;i<fit.get_num_params();++i) + { + std::string pname=fit.get_param_info(i).get_name(); + std::string pstatus=fit.get_model().report_param_status(pname); + + if(pstatus==""||pstatus=="thawed") + { + pstatus="T"; + } + else + { + pstatus="F"; + } + cout<<fit.get_param_info(i).get_name()<<"\t"<<fit.get_param_info(i).get_value()<<"\t"<<fit.get_param_info(i).get_lower_limit()<<"\t"<<fit.get_param_info(i).get_upper_limit()<<"\t"<<pstatus<<endl; + //if(argc>=3&&std::string(argv[2])!="NONE") +#if 0 + { + output_param<<fit.get_param_info(i).get_name()<<"\t"<<fit.get_param_info(i).get_value()<<"\t"<<fit.get_param_info(i).get_lower_limit()<<"\t"<<fit.get_param_info(i).get_upper_limit()<<"\t"<<pstatus<<endl; + } +#endif + } + + //cout<<"T0"<<"\t"<<fit.get_param_value("T0")<<endl; + //cout<<"T1"<<"\t"<<fit.get_param_value("T1")<<endl; + //cout<<"xt"<<"\t"<<fit.get_param_value("xt")<<endl; + //cout<<"eta"<<"\t"<<fit.get_param_value("eta")<<endl; + //dump the data for checking + ofstream ofs_model("wang2012_dump.qdp"); + + + min_r=0; + for(double x=min_r;x<3000;x+=10) + { + double model_value=fit.eval_model_raw(x,p); + + ofs_model<<x<<"\t"<<model_value<<endl; + if(cm_per_pixel>0) + { + ofs_fit_result<<x*cm_per_pixel/kpc<<"\t0\t"<<model_value<<"\t0"<<endl; + } + else + { + ofs_fit_result<<x<<"\t0\t"<<model_value<<"\t0"<<endl; + } + } +} diff --git a/mass_profile/get_center_params.sh b/mass_profile/get_center_params.sh new file mode 100755 index 0000000..a250e07 --- /dev/null +++ b/mass_profile/get_center_params.sh @@ -0,0 +1,46 @@ +#!/bin/bash +origin_point=$PWD +ZERO=`readlink -f $0` +basedir=`dirname $ZERO` + +for i in `cat list.txt` +do +# echo $i + file_path=`dirname $i` + cd $file_path + mkdir -p center_results + cp global.cfg center_results + t_data_file=`grep ^t_data_file global.cfg|awk '{print $2}'` + t_param_file=`grep ^t_param_file global.cfg|awk '{print $2}'` + sbp_cfg=`grep ^sbp_cfg global.cfg|awk '{print $2}'` + cm_per_pixel=`grep '^cm_per_pixel' $sbp_cfg|awk '{print $2}'` + radius_sbp_file=`grep '^radius_sbp_file' global.cfg|awk '{print $2}'` + radius_file=`grep '^radius_file' $sbp_cfg|awk '{print $2}'` + sbp_file=`grep '^sbp_file' $sbp_cfg|awk '{print $2}'` + cfunc_file=`grep '^cfunc_file' $sbp_cfg|awk '{print $2}'` + T_file=`grep '^T_file' $sbp_cfg |awk '{print $2}'` + + cp $t_data_file $t_param_file $sbp_cfg $radius_sbp_file $radius_file $sbp_file $cfunc_file center_results + cd center_results + nh=`grep '^nh' global.cfg |awk '{print $2}'` + z=`grep '^z' ${sbp_cfg}|awk '{print $2}'` + abund=`grep '^abund' global.cfg |awk '{print $2}'` + + $basedir/fit_wang2012_model $t_data_file $t_param_file $cm_per_pixel + #echo $t_param_file + mv wang2012_dump.qdp wang2012_center_dump.qdp + cp -f wang2012_center_dump.qdp t_profile_dump.qdp + $basedir/coolfunc_calc.sh wang2012_center_dump.qdp $abund $nh $z cfunc.dat + if grep '^beta2' ${sbp_cfg} + then + $basedir/fit_dbeta_sbp $sbp_cfg + mv dbeta_param.txt sbp_param_center.txt + else + $basedir/fit_beta_sbp $sbp_cfg + mv beta_param.txt sbp_param_center.txt + fi + + $basedir/fit_nfw_mass mass_int.dat $z >nfw_param_center.txt + + cd $origin_point +done diff --git a/mass_profile/get_lxfx_data.sh b/mass_profile/get_lxfx_data.sh new file mode 100755 index 0000000..dbb07dd --- /dev/null +++ b/mass_profile/get_lxfx_data.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# +# collect data for 'loop_lx.sh' & 'calc_lxfx_simple.sh' +# + +if [ $# -lt 2 ]; then + printf "usage:\n" + printf " `basename $0` <dir> [c] <delta ...>\n" + exit 1 +fi + +DIR="$1" +shift +case "$1" in + [cC]*) + F_C="YES" + shift + ;; + *) + F_C="NO" + ;; +esac +printf "CENTER_MODE: $F_C\n" +echo "DELTA: $@" + +cd $DIR +pwd -P + +INFO=`ls ../*_INFO.json 2> /dev/null` +if [ ! -z "$INFO" ]; then + OI=`grep '"Obs\.\ ID' ${INFO} | sed 's/.*"Obs.*":\ //' | sed 's/\ *,$//'` + NAME=`grep '"Source\ Name' ${INFO} | sed 's/.*"Source.*":\ //' | sed 's/^"//' | sed 's/"\ *,$//'` + UNAME=`grep '"Unified\ Name' ${INFO} | sed 's/.*"Unified.*":\ //' | sed 's/^"//' | sed 's/"\ *,$//'` + Z=`grep '"redshift' ${INFO} | sed 's/.*"redshift.*":\ //' | sed 's/\ *,$//'` +fi + +printf "# OI,NAME,UNAME,Z" +if [ "${F_C}" = "YES" ]; then + for DELTA in $@; do + printf ",L${DELTA}(bolo),L${DELTA}(0.7-7),L${DELTA}(0.1-2.4),F${DELTA}(bolo),F${DELTA}(0.7-7),F${DELTA}(0.1-2.4)" + done + printf "\n" +else + for DELTA in $@; do + printf ",L${DELTA}(bolo),L${DELTA}ERR(bolo),L${DELTA}(0.7-7),L${DELTA}ERR(0.7-7),L${DELTA}(0.1-2.4),L${DELTA}ERR(0.1-2.4),F${DELTA}(bolo),F${DELTA}ERR(bolo),F${DELTA}(0.7-7),F${DELTA}ERR(0.7-7),F${DELTA}(0.1-2.4),F${DELTA}ERR(0.1-2.4)" + done + printf "\n" +fi + +printf "# $OI,$NAME,$UNAME,$Z" + +if [ "${F_C}" = "YES" ]; then + for DELTA in $@; do + LX_RES="lx_result_${DELTA}_c.txt" + FX_RES="fx_result_${DELTA}_c.txt" + if [ -r ${LX_RES} ] && [ -r ${FX_RES} ]; then + Lbolo=`grep '^Lx(bolo' ${LX_RES} | awk '{ print $2 }'` + L077=`grep '^Lx(0\.7-7' ${LX_RES} | awk '{ print $2 }'` + L0124=`grep '^Lx(0\.1-2\.4' ${LX_RES} | awk '{ print $2 }'` + Fbolo=`grep '^Fx(bolo' ${FX_RES} | awk '{ print $2 }'` + F077=`grep '^Fx(0\.7-7' ${FX_RES} | awk '{ print $2 }'` + F0124=`grep '^Fx(0\.1-2\.4' ${FX_RES} | awk '{ print $2 }'` + printf ",$Lbolo,$L077,$L0124,$Fbolo,$F077,$F0124" + fi + done + printf "\n" +else + for DELTA in $@; do + LX_RES="lx_result_${DELTA}.txt" + FX_RES="fx_result_${DELTA}.txt" + if [ -r ${LX_RES} ] && [ -r ${FX_RES} ]; then + Lbolo=`grep '^Lx(bolo' ${LX_RES} | awk '{ print $2 }'` + LboloERR=`grep '^Lx(bolo' ${LX_RES} | awk '{ print $4 }'` + L077=`grep '^Lx(0\.7-7' ${LX_RES} | awk '{ print $2 }'` + L077ERR=`grep '^Lx(0\.7-7' ${LX_RES} | awk '{ print $4 }'` + L0124=`grep '^Lx(0\.1-2\.4' ${LX_RES} | awk '{ print $2 }'` + L0124ERR=`grep '^Lx(0\.1-2\.4' ${LX_RES} | awk '{ print $4 }'` + Fbolo=`grep '^Fx(bolo' ${FX_RES} | awk '{ print $2 }'` + FboloERR=`grep '^Fx(bolo' ${FX_RES} | awk '{ print $4 }'` + F077=`grep '^Fx(0\.7-7' ${FX_RES} | awk '{ print $2 }'` + F077ERR=`grep '^Fx(0\.7-7' ${FX_RES} | awk '{ print $4 }'` + F0124=`grep '^Fx(0\.1-2\.4' ${FX_RES} | awk '{ print $2 }'` + F0124ERR=`grep '^Fx(0\.1-2\.4' ${FX_RES} | awk '{ print $4 }'` + printf ",$Lbolo,$LboloERR,$L077,$L077ERR,$L0124,$L0124ERR,$Fbolo,$FboloERR,$F077,$F077ERR,$F0124,$F0124ERR" + fi + done + printf "\n" +fi + diff --git a/mass_profile/init.sh b/mass_profile/init.sh new file mode 100755 index 0000000..0bcdd66 --- /dev/null +++ b/mass_profile/init.sh @@ -0,0 +1,6 @@ +ln -sf $XANBIN/lib/libcpgplot*.a ./libcpgplot.a +ln -sf $XANBIN/lib/libpgplot*.a ./libpgplot.a +echo LIB ./ >pgplot_path.txt +echo INC $XANBIN/include >>pgplot_path.txt + +chmod a+x *.py diff --git a/mass_profile/loop_lx.sh b/mass_profile/loop_lx.sh new file mode 100755 index 0000000..c468d86 --- /dev/null +++ b/mass_profile/loop_lx.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +full_path=`readlink -f $0` +base_dir=`dirname $full_path` + +if [ $# -lt 2 ]; then + printf "usage:\n" + printf " `basename $0` <cfg.list> [c] < 500 | 200 > ...\n" + exit 1 +fi + +file_list="$1" +init_dir=`pwd -P` +pre_results="final_result.txt" + +case "$2" in + [cC]*) + F_C="YES" + shift + ;; + *) + F_C="NO" + ;; +esac + +shift +echo "delta: $@" # 'printf' not work + +if [ "${F_C}" = "YES" ]; then + printf "MODE: center\n" +fi + +# exit + +cat $file_list | while read line; do + cd $init_dir + obj_dir=`dirname $line` + obj_cfg=`basename $line` + cd $obj_dir + pwd -P + ## + if [ ! -r "${obj_cfg}" ]; then + printf "ERROR: global cfg not accessible\n" + elif [ ! -r "${pre_results}" ]; then + printf "ERROR: previous '${pre_results}' not accessible\n" + else + sbp_cfg=`grep '^sbp_cfg' $obj_cfg | awk '{ print $2 }'` + ## + for delta in $@; do + if grep -q '^beta2' $sbp_cfg; then + MODEL="dbeta" + else + MODEL="beta" + fi + rout=`grep "^r${delta}" ${pre_results} | sed -e 's/=/ /' | awk '{ print $2 }'` + if [ "${F_C}" = "YES" ]; then + lx_res="lx_result_${delta}_c.txt" + fx_res="fx_result_${delta}_c.txt" + CMD="$base_dir/calc_lx_${MODEL}.sh $obj_cfg $rout c" + else + lx_res="lx_result_${delta}.txt" + fx_res="fx_result_${delta}.txt" + CMD="$base_dir/calc_lx_${MODEL}.sh $obj_cfg $rout" + fi + [ -e "${lx_res}" ] && mv -f ${lx_res} ${lx_res}_bak + [ -e "${fx_res}" ] && mv -f ${fx_res} ${fx_res}_bak + ${CMD} + mv -f lx_result.txt ${lx_res} + mv -f fx_result.txt ${fx_res} + done + fi +done + diff --git a/mass_profile/nfw.hpp b/mass_profile/nfw.hpp new file mode 100644 index 0000000..8e3e59e --- /dev/null +++ b/mass_profile/nfw.hpp @@ -0,0 +1,56 @@ +/** + \file nfw.hpp + \brief Jingying Wang's model + \author Jingying Wang + */ + + +#ifndef NFW +#define NFW +#define OPT_HEADER +#include <core/fitter.hpp> +#include <cmath> + +namespace opt_utilities +{ + template <typename T> + class nfw + :public model<T,T,std::vector<T>,std::string> + { + private: + model<T,T,std::vector<T> >* do_clone()const + { + return new nfw<T>(*this); + } + + const char* do_get_type_name()const + { + return "1d power law"; + } + public: + nfw() + { + this->push_param_info(param_info<std::vector<T> >("rho0",1,0,1e99)); + this->push_param_info(param_info<std::vector<T> >("rs",100,0,1e99)); + } + + T do_eval(const T& r,const std::vector<T>& param) + { + T rho0=std::abs(param[0]); + T rs=std::abs(param[1]); + static const T pi=4*std::atan(1); + return 4*pi*rho0*rs*rs*rs*(std::log((r+rs)/rs)-r/(r+rs)); + } + + private: + std::string do_get_information()const + { + return ""; + } + }; +} + + + +#endif +//EOF diff --git a/mass_profile/nfw_ne.hpp b/mass_profile/nfw_ne.hpp new file mode 100644 index 0000000..5842bb8 --- /dev/null +++ b/mass_profile/nfw_ne.hpp @@ -0,0 +1,198 @@ +/* + Gas density profile derived from nfw mass profile and temperature profile + Author: Junhua Gu + Last modification: 20120721 +*/ + +#ifndef NFW_NE +#define NFW_NE +#include "projector.hpp" +#include <algorithm> +#include <functional> +#include <numeric> + +//a series of physical constants +static const double G=6.673E-8;//cm^3 g^-1 s^2 +static const double mu=1.4074; +static const double mp=1.67262158E-24;//g +static const double k=1.60217646E-9;//erg/keV +static const double c=2.99792458E10;//cm/s + + +namespace opt_utilities +{ + //the nfw mass enclosed within a radius r, with parameter rho0 and rs + template <typename T> + T nfw_mass_enclosed(T r,T rho0,T rs) + { + return 4*pi*rho0*rs*rs*rs*(std::log((r+rs)/rs)-r/(r+rs)); + } + + //average mass density + template <typename T> + T nfw_average_density(T r,T rho0,T rs) + { + if(r==0) + { + return rho0; + } + + return nfw_mass_enclosed(r,rho0,rs)/(4.*pi/3*r*r*r); + } + + //calculate critical density from z, under following cosmological constants + static double calc_critical_density(double z, + const double H0=2.3E-18, + const double Omega_m=.27) + { + const double E=std::sqrt(Omega_m*(1+z)*(1+z)*(1+z)+1-Omega_m); + const double H=H0*E; + return 3*H*H/8/pi/G; + } + + + //a class wraps method of calculating gas density from mass profile and temperature profile + template <typename T> + class nfw_ne + :public model<std::vector<T>,std::vector<T>,std::vector<T> > + { + private: + //pointer to temperature profile function + func_obj<T,T>* pTfunc; + //cm per pixel + T cm_per_pixel; + public: + //default constructor + nfw_ne() + :pTfunc(0),cm_per_pixel(1) + { + + this->push_param_info(param_info<std::vector<T>,std::string>("rho0",1));//in mp + this->push_param_info(param_info<std::vector<T>,std::string>("rs",100)); + this->push_param_info(param_info<std::vector<T>,std::string>("n0",.01)); + } + + //copy constructor + nfw_ne(const nfw_ne& rhs) + :cm_per_pixel(rhs.cm_per_pixel) + { + if(rhs.pTfunc) + { + pTfunc=rhs.pTfunc->clone(); + } + else + { + pTfunc=0; + } + //initial parameter list + this->push_param_info(param_info<std::vector<T>,std::string>("rho0",rhs.get_param_info("rho0").get_value())); + this->push_param_info(param_info<std::vector<T>,std::string>("rs",rhs.get_param_info("rs").get_value())); + this->push_param_info(param_info<std::vector<T>,std::string>("n0",rhs.get_param_info("n0").get_value())); + } + + //assignment operator + nfw_ne& operator=(const nfw_ne& rhs) + { + cm_per_pixel=rhs.cm_per_pixel; + if(pTfunc) + { + pTfunc->destroy(); + } + if(rhs.pTfunc) + { + pTfunc=rhs.pTfunc->clone(); + } + } + + //destructor + ~nfw_ne() + { + if(pTfunc) + { + pTfunc->destroy(); + } + } + + public: + //attach the temperature profile function + void attach_Tfunc(const func_obj<T,T>& Tf) + { + if(pTfunc) + { + pTfunc->destroy(); + } + pTfunc=Tf.clone(); + } + + //set the cm per pixel value + void set_cm_per_pixel(const T& x) + { + cm_per_pixel=x; + } + + //clone self + nfw_ne<T>* do_clone()const + { + return new nfw_ne<T>(*this); + } + + + //calculate density under parameters p, at radius r + /* + r is a vector, which stores a series of radius values + the annuli or pie regions are enclosed between any two + adjacent radii. + so the returned value has length smaller than r by 1. + */ + std::vector<T> do_eval(const std::vector<T> & r, + const std::vector<T>& p) + { + assert(pTfunc); + //const T kT_erg=k*5; + T rho0=std::abs(p[0])*mp; + T rs=std::abs(p[1]); + T n0=std::abs(p[2]); + T rs_cm=rs*cm_per_pixel; + + std::vector<T> yvec(r.size()); + const T kT_erg0=pTfunc->eval((r.at(0)+r.at(1))/2)*k; + //calculate the integration +#pragma omp parallel for schedule(dynamic) + for(int i=0;i<r.size();++i) + { + T r_cm=r[i]*cm_per_pixel; + T kT_erg=pTfunc->eval(r[i])*k; + if(abs(r_cm)==0) + { + continue; + } + yvec.at(i)=G*nfw_mass_enclosed(r_cm,rho0,rs_cm)*mu*mp/kT_erg/r_cm/r_cm; + //std::cout<<r_cm/1e20<<"\t"<<nfw_mass_enclosed(r_cm,rho0,rs_cm)/1e45<<std::endl; + //std::cout<<r_cm/1e20<<"\t"<<G*nfw_mass_enclosed(r_cm,rho0,rs_cm)*mu*mp/kT_erg/r_cm/r_cm<<std::endl; + } + + std::vector<T> ydxvec(r.size()-1); +#pragma omp parallel for schedule(dynamic) + for(int i=1;i<r.size();++i) + { + T dr=r[i]-r[i-1]; + T dr_cm=dr*cm_per_pixel; + ydxvec.at(i-1)=(yvec[i]+yvec[i-1])/2*dr_cm; + } + std::partial_sum(ydxvec.begin(),ydxvec.end(),ydxvec.begin()); + //construct the result + std::vector<T> result(r.size()-1); +#pragma omp parallel for schedule(dynamic) + for(int i=0;i<r.size()-1;++i) + { + T y=-ydxvec.at(i); + T kT_erg=pTfunc->eval(r[i])*k; + //std::cout<<y<<std::endl; + result.at(i)=n0*exp(y)*kT_erg0/kT_erg; + } + return result; + } + }; +} + +#endif diff --git a/mass_profile/pgplot_path.txt b/mass_profile/pgplot_path.txt new file mode 100644 index 0000000..70726e3 --- /dev/null +++ b/mass_profile/pgplot_path.txt @@ -0,0 +1,2 @@ +LIB ./ +INC /usr/local/heasoft/x86_64-unknown-linux-gnu/include diff --git a/mass_profile/plot_reporter.cpp b/mass_profile/plot_reporter.cpp new file mode 100644 index 0000000..b5fc9ff --- /dev/null +++ b/mass_profile/plot_reporter.cpp @@ -0,0 +1,70 @@ +#include "plot_reporter.hpp" +#include <cpgplot.h> +#include <cassert> +#include <cstdlib> + +plot_reporter::plot_reporter() +{ + const char* pgplot_device=getenv("PGPLOT_DEVICE"); + if(pgplot_device==NULL) + { + if (cpgopen("/null") < 1) + { + assert(0); + } + } + else + { + if (cpgopen(pgplot_device) < 1) + { + assert(0); + } + } + cpgask(0); +} + + +plot_reporter::~plot_reporter() +{ + cpgclos(); +} + + +void plot_reporter::init_xyrange(float x1, + float x2, + float y1, + float y2, + int axis_flag) +{ + cpgenv(x1, x2, y1, y2, 0, axis_flag); +} + + +void plot_reporter::plot_line(std::vector<float>& x,std::vector<float>& y) +{ + cpgbbuf(); + cpgline(x.size(),x.data(),y.data()); + cpgebuf(); +} + +void plot_reporter::plot_err1_dot(std::vector<float>& x,std::vector<float>& y, + std::vector<float>& e) +{ + cpgbbuf(); + cpgpt(x.size(),x.data(),y.data(),1); + cpgerrb(6,x.size(),x.data(),y.data(),e.data(),0); + cpgebuf(); +} + + +void plot_reporter::plot_err2_dot(std::vector<float>& x,std::vector<float>& y, + std::vector<float>& e1,std::vector<float>& e2) +{ + cpgbbuf(); + cpgpt(x.size(),x.data(),y.data(),1); + cpgerrb(2,x.size(),x.data(),y.data(),e1.data(),0); + cpgerrb(4,x.size(),x.data(),y.data(),e2.data(),0); + cpgebuf(); +} + +plot_reporter pr; diff --git a/mass_profile/plot_reporter.hpp b/mass_profile/plot_reporter.hpp new file mode 100644 index 0000000..5625f47 --- /dev/null +++ b/mass_profile/plot_reporter.hpp @@ -0,0 +1,23 @@ +#ifndef PLOT_REPORTER_HPP +#define PLOT_REPORTER_HPP +#include <vector> +class plot_reporter +{ +private: + plot_reporter(const plot_reporter&); + plot_reporter& operator=(const plot_reporter&); +public: + plot_reporter(); + ~plot_reporter(); + void init_xyrange(float x1,float x2,float y1,float y2,int axis_flag); + void plot_line(std::vector<float>& x,std::vector<float>& y); + void plot_err1_dot(std::vector<float>& x,std::vector<float>& y, + std::vector<float>& e); + void plot_err2_dot(std::vector<float>& x,std::vector<float>& y, + std::vector<float>& e1,std::vector<float>& e2); + +}; + +extern plot_reporter pr; + +#endif diff --git a/mass_profile/projector.hpp b/mass_profile/projector.hpp new file mode 100644 index 0000000..a8af645 --- /dev/null +++ b/mass_profile/projector.hpp @@ -0,0 +1,206 @@ +#ifndef PROJ_HPP +#define PROJ_HPP +/* + Defining the class that is used to consider the projection effect + Author: Junhua Gu + Last modified: 2011.01.01 +*/ + + +#include <core/fitter.hpp> +#include <vector> +#include <cmath> +static const double pi=4*atan(1); +static const double ne_np_ratio=1.2; +namespace opt_utilities +{ + //This is used to project a 3-D surface brightness model to 2-D profile + template <typename T> + class projector + :public model<std::vector<T>,std::vector<T>,std::vector<T> > + { + private: + //Points to a 3-D model that is to be projected + model<std::vector<T>,std::vector<T>,std::vector<T> >* pmodel; + func_obj<T,T>* pcfunc; + T cm_per_pixel; + public: + //default cstr + projector() + :pmodel(NULL_PTR),pcfunc(NULL_PTR),cm_per_pixel(1) + {} + //copy cstr + projector(const projector& rhs) + :cm_per_pixel(rhs.cm_per_pixel) + { + attach_model(*(rhs.pmodel)); + if(rhs.pcfunc) + { + pcfunc=rhs.pcfunc->clone(); + } + else + { + pcfunc=NULL_PTR; + } + + } + //assign operator + projector& operator=(const projector& rhs) + { + cm_per_pixel=rhs.cm_per_pixel; + if(pmodel) + { + pmodel->destroy(); + } + if(pcfunc) + { + pcfunc->destroy(); + } + if(rhs.pcfunc) + { + pcfunc=rhs.pcfunc->clone(); + } + if(rhs.pmodel) + { + pmodel=rhs.pmodel->clone(); + } + } + //destr + ~projector() + { + if(pmodel) + { + pmodel->destroy(); + } + if(pcfunc) + { + pcfunc->destroy(); + } + } + //used to clone self + model<std::vector<T>,std::vector<T>,std::vector<T> >* + do_clone()const + { + return new projector(*this); + } + + public: + void set_cm_per_pixel(const T& x) + { + cm_per_pixel=x; + } + + //attach the model that is to be projected + void attach_model(const model<std::vector<T>,std::vector<T>,std::vector<T> >& m) + { + this->clear_param_info(); + for(int i=0;i<m.get_num_params();++i) + { + this->push_param_info(m.get_param_info(i)); + } + this->push_param_info(param_info<std::vector<T>,std::string>("bkg",0,0,1E99)); + pmodel=m.clone(); + pmodel->clear_param_modifier(); + } + + void attach_cfunc(const func_obj<T,T>& cf) + { + if(pcfunc) + { + pcfunc->destroy(); + } + pcfunc=cf.clone(); + } + + public: + //calc the volume + /* + This is a sphere that is subtracted by a cycline. + /| |\ + / | | \ + | | | | + | | | | + \ | | / + \| |/ + */ + T calc_v_ring(T rsph,T rcyc) + { + if(rcyc<rsph) + { + double a=rsph*rsph-rcyc*rcyc; + return 4.*pi/3.*std::sqrt(a*a*a); + } + return 0; + } + + //calc the No. nsph sphere's projection volume on the No. nrad pie region + T calc_v(const std::vector<T>& rlist,int nsph,int nrad) + { + if(nsph<nrad) + { + return 0; + } + if(nsph==nrad) + { + return calc_v_ring(rlist[nsph+1],rlist[nrad]); + } + + return calc_v_ring(rlist[nsph+1],rlist[nrad])-calc_v_ring(rlist[nsph],rlist[nrad])-calc_v_ring(rlist[nsph+1],rlist[nrad+1])+calc_v_ring(rlist[nsph],rlist[nrad+1]); + + } + public: + bool do_meets_constraint(const std::vector<T>& p)const + { + std::vector<T> p1(this->reform_param(p)); + for(size_t i=0;i!=p1.size();++i) + { + if(get_element(p1,i)>this->get_param_info(i).get_upper_limit()|| + get_element(p1,i)<this->get_param_info(i).get_lower_limit()) + { + // std::cerr<<this->get_param_info(i).get_name()<<"\t"<<p1[i]<<std::endl; + return false; + } + } + std::vector<T> p2(p1.size()-1); + for(int i=0;i<p1.size()-1;++i) + { + p2.at(i)=p1[i]; + } + + return pmodel->meets_constraint(p2); + } + public: + //Perform the projection + std::vector<T> do_eval(const std::vector<T>& x,const std::vector<T>& p) + { + T bkg=std::abs(p.back()); + //I think following codes are clear enough :). + std::vector<T> unprojected(pmodel->eval(x,p)); + std::vector<T> projected(unprojected.size()); + + for(int nrad=0;nrad<x.size()-1;++nrad) + { + double v1=0; + for(int nsph=nrad;nsph<x.size()-1;++nsph) + { + double v=calc_v(x,nsph,nrad)*cm_per_pixel*cm_per_pixel*cm_per_pixel; + v1+=v; + if(pcfunc) + { + projected[nrad]+=v*ne_np_ratio*unprojected[nsph]*unprojected[nsph]*(*pcfunc)((x[nrad+1]+x[nrad])/2.); + } + else + { + projected[nrad]+=v*unprojected[nsph]*unprojected[nsph]; + } + } + projected[nrad]/=(pi*(x[nrad+1]*x[nrad+1]-x[nrad]*x[nrad])); + projected[nrad]+=bkg; + + } + return projected; + } + }; +}; + +#endif diff --git a/mass_profile/query_source_info.sh b/mass_profile/query_source_info.sh new file mode 100755 index 0000000..4e78941 --- /dev/null +++ b/mass_profile/query_source_info.sh @@ -0,0 +1,129 @@ +#!/bin/bash + +#-------------------------------------------# +#Program: script for querying source info # +#Author: Junhua Gu # +#return codes: # +# 1: usage not correct # +# 2: source not found # +# 3: redshift not available # +# 4: heasoft not initialized # +# 5: item invalid # +#Created at 20120822 # +#-------------------------------------------# + + +if [ $# -ge 1 ] +then +: +else + echo "Usage: $0 <source name> [item]" + echo "Item can either be nh, z, norm, cm_per_pixel" + exit 1 +fi + +if which nh >/dev/null +then + : +else + echo "Should initialize heasoft before hand" + exit 4 +fi + +src_name=$1 +#convert some special characters in the name into standard coded string +src_url_name=`perl -MURI::Escape -e "print uri_escape(\"$src_name\");" "$2"` +#form the url string +ned_url="http://ned.ipac.caltech.edu/cgi-bin/objsearch?objname=${src_url_name}&extend=no&hconst=73&omegam=0.27&omegav=0.73&corr_z=1&out_csys=Equatorial&out_equinox=J2000.0&obj_sort=RA+or+Longitude&of=ascii_bar&zv_breaker=30000.0&list_limit=5&img_stamp=YES" + +#echo $ned_url +#fetch the ned web page + +#if the string is leaded by <html> +#the source name cannot be resolved +#print an error message and exit + +if wget --quiet "$ned_url" -O - >/dev/null +then + : +else + echo "Source not found" + echo "Maybe the source name is not in a standard form" + echo "Please check it manually" + exit 2 +fi + +content=`wget --quiet "$ned_url" -O -|tail -1` +#echo $content + +#extract interested information +ra=`echo $content |awk -F '|' '{print $3}'` +dec=`echo $content |awk -F '|' '{print $4}'` +z=`echo $content |awk -F '|' '{print $7}'` +ned_name=`echo $content |awk -F '|' '{print $2}'` + +#echo $ra $dec $z +#use heasoft tool nh to calculate the weighted nh +ra_hhmmss=`echo $ra|awk '{printf("%sh%sm%ss",int($1/360*24),int((($1/360*24)%1*60)),(($1/360*24*60)%1*60))}'` +dec_ddmmss=`echo $dec|awk '{printf("%sd%sm%ss",sqrt($1*$1)/$1*int(sqrt($1*$1)),int(((sqrt($1*$1))%1*60)),((sqrt($1*$1)*60)%1*60))}'` +#echo $ra_hhmms +nh=`nh 2000 $ra $dec|tail -1` +#and convert to standard xspec unit +nh=`python -c "print(float(\"$nh\".split()[-1])/1e22)"` + +if [ $# -eq 1 ] +then + echo ned_name: $ned_name + echo nh: $nh + echo z: $z + echo ra: $ra_hhmmss + echo dec: $dec_ddmmss +fi + +#what if the redshift is not available... +if [ x"$z" == "x" ] +then + echo "no redshift data available" + exit 3 +fi + +base_dir=`dirname $0` + +cm_per_pixel=`$base_dir/calc_distance $z|grep ^cm_per_pixel|awk '{print $2}'` +norm=`$base_dir/calc_distance $z|grep ^norm|awk '{print $2}'` +Ez=`$base_dir/calc_distance $z|grep '^E(z)'|awk '{print $2}'` +if [ $# -eq 1 ] +then + echo cm_per_pixel: $cm_per_pixel + echo norm: $norm + echo "E(z):" $Ez +fi +#normally exit + +if [ $# -gt 1 ] +then + item=$2 + if [ $item == "nh" ] + then + echo $nh + elif [ $item == "z" ] + then + echo $z + elif [ $item == "ra" ] + then + echo $ra_hhmmss + elif [ $item == "dec" ] + then + echo $dec_ddmmss + elif [ $item == "norm" ] + then + echo $norm + elif [ $item == "cm_per_pixel" ] + then + echo $cm_per_pixel + else + echo "item invalid" + exit 5 + fi +fi + diff --git a/mass_profile/report_error.cpp b/mass_profile/report_error.cpp new file mode 100644 index 0000000..23e6a26 --- /dev/null +++ b/mass_profile/report_error.cpp @@ -0,0 +1,39 @@ +#include <iostream> + +using namespace std; +void report_error(const char* message) +{ + cerr<<"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"<<endl; + cerr<<"MMMMMMMMMMMM MMMMMMMMMMMM"<<endl; + cerr<<"MMMMMMMMMM MMMMMMMMMM"<<endl; + cerr<<"MMMMMMMMM MMMMMMMMM"<<endl; + cerr<<"MMMMMMMM MMMMMMMM"<<endl; + cerr<<"MMMMMMM MMMMMMMM"<<endl; + cerr<<"MMMMMMM MMMMMMM"<<endl; + cerr<<"MMMMMMM MMMMMMM"<<endl; + cerr<<"MMMMMMM MMM MMM MMMMMMM"<<endl; + cerr<<"MMMMMMM MMMMM MMMM MMMMMMM"<<endl; + cerr<<"MMMMMMM MMMMM MMMM MMMMMMM"<<endl; + cerr<<"MMMMMMMM MMMM M MMMM MMMMMMMM"<<endl; + cerr<<"MMMMMMMM M MMMMMMM"<<endl; + cerr<<"MMMMMMMM MMM MMMMMMMM"<<endl; + cerr<<"MMMMMMMMMMMM MMM MMMMMMMMMMMM"<<endl; + cerr<<"MMMMMMMMMM MM M MMMMMMMMM"<<endl; + cerr<<"MMMMMMMMMM M M M M M MMMMMMMMMM"<<endl; + cerr<<"MMMM MMMMM MMMMMMMMM MMMMM MM"<<endl; + cerr<<"MMM MMMM M MMMMM M MMMM MM"<<endl; + cerr<<"MMM MMMM M M M MMMMM MMM"<<endl; + cerr<<"MMMM MMMM MMM MM"<<endl; + cerr<<"MMM MMMM MMMM MM"<<endl; + cerr<<"MMM MMMMMMMM M MMM"<<endl; + cerr<<"MMMM MMM MMM MMMMMMMM"<<endl; + cerr<<"MMMMMMMMMMM MM MMMMMMM M"<<endl; + cerr<<"MMM MMMMMMM MMMMMMMMM M"<<endl; + cerr<<"MM MMM MM M"<<endl; + cerr<<"MM MMMM MM"<<endl; + cerr<<"MMM MMMMMMMMMMMMM M"<<endl; + cerr<<"MM MMMMMMMMMMMMMMMMMMM M"<<endl; + cerr<<"MMM MMMMMMMMMMMMMMMMMMMMMM M"<<endl; + cerr<<"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"<<endl; + cerr<<message<<endl; +} diff --git a/mass_profile/report_error.hpp b/mass_profile/report_error.hpp new file mode 100644 index 0000000..30607e5 --- /dev/null +++ b/mass_profile/report_error.hpp @@ -0,0 +1,6 @@ +#ifndef REPORT_ERR +#define REPORT_ERR + +void report_error(const char* message); + +#endif diff --git a/mass_profile/sample.cfg b/mass_profile/sample.cfg new file mode 100644 index 0000000..072c4a8 --- /dev/null +++ b/mass_profile/sample.cfg @@ -0,0 +1,11 @@ +radius_file radius.dat +sbp_file sbp1.dat +cfunc_file cfunc1.dat +n01 0.00613826 +rc1 30 +beta1 0.62447 +n02 0.0315466 +rc2 85.7819 +beta2 0.99971 +bkg 1.1715e-09 +cm_per_pixel 5.29E20 diff --git a/mass_profile/shuffle_T.py b/mass_profile/shuffle_T.py new file mode 100755 index 0000000..24e7393 --- /dev/null +++ b/mass_profile/shuffle_T.py @@ -0,0 +1,18 @@ +#!/usr/bin/python + +import sys +import scipy + +output_file=open(sys.argv[2],'w') +for i in open(sys.argv[1]): + r,re,c,s=i.strip().split() + c=float(c) + s=float(s) + + if c>0 and s>0: + c1=-1 + while c1<=0: + c1=scipy.random.normal(0,1)*s+c + + output_file.write("%s\t%s\t%s\t%s\n"%(r,re,c1,s)) + diff --git a/mass_profile/shuffle_sbp.py b/mass_profile/shuffle_sbp.py new file mode 100755 index 0000000..210bfb8 --- /dev/null +++ b/mass_profile/shuffle_sbp.py @@ -0,0 +1,18 @@ +#!/usr/bin/python + +import sys +import scipy + +output_file=open(sys.argv[2],'w') +for i in open(sys.argv[1]): + c,s=i.strip().split() + c=float(c) + s=float(s) + + if c>0 and s>0: + c1=-1 + while c1<=0: + c1=scipy.random.normal(0,1)*s+c + + output_file.write("%s\t%s\n"%(c1,s)) + diff --git a/mass_profile/spline.h b/mass_profile/spline.h new file mode 100644 index 0000000..8bc0225 --- /dev/null +++ b/mass_profile/spline.h @@ -0,0 +1,109 @@ +#ifndef SPLINEH +#define SPLINEH +#include <vector> +#include <cstdlib> +#include <cassert> +#include <cmath> +#include <limits> + +template <typename T> +class spline +{ +public: + std::vector<T> x_list; + std::vector<T> y_list; + std::vector<T> y2_list; + +public: + void push_point(T x,T y) + { + if(!x_list.empty()) + { + assert(x>*(x_list.end()-1)); + } + x_list.push_back(x); + y_list.push_back(y); + } + + T get_value(T x) + { + if(x<=x_list[0]) + { + return y_list[0]; + } + if(x>=x_list.back()) + { + return y_list.back(); + } + assert(x_list.size()==y2_list.size()); + assert(x>x_list[0]); + assert(x<x_list.back()); + int n1,n2; + n1=0; + n2=x_list.size()-1; + while((n2-n1)!=1) + { + //cerr<<n1<<"\t"<<n2<<endl; + if(x_list[n1+1]<=x) + { + n1++; + } + if(x_list[n2-1]>x) + { + n2--; + } + } + T h=x_list[n2]-x_list[n1]; + double a=(x_list[n2]-x)/h; + double b=(x-x_list[n1])/h; + return a*y_list[n1]+b*y_list[n2]+((a*a*a-a)*y2_list[n1]+ + (b*b*b-b)*y2_list[n2])*(h*h)/6.; + + } + + void gen_spline(T y2_0,T y2_N) + { + int n=x_list.size(); + y2_list.resize(0); + y2_list.resize(x_list.size()); + std::vector<T> u(x_list.size()); + if(std::abs(y2_0)<std::numeric_limits<T>::epsilon()) + { + y2_list[0]=0; + u[0]=0; + } + else + { + y2_list[0]=-.5; + u[0]=(3./(x_list[1]-x_list[0]))*((y_list[1]-y_list[0])/(x_list[1]-x_list[0])-y2_0); + } + for(int i=1;i<n-1;++i) + { + double sig=(x_list[i]-x_list[i-1])/(x_list[i+1]-x_list[i-1]); + double p=sig*y2_list[i-1]+2.; + y2_list[i]=(sig-1.)/p; + u[i]=(y_list[i+1]-y_list[i])/(x_list[i+1]-x_list[i]) + -(y_list[i]-y_list[i-1])/(x_list[i]-x_list[i-1]); + u[i]=(6.*u[i]/(x_list[i+1]-x_list[i-1])-sig*u[i-1])/p; + } + double qn,un; + if(std::abs(y2_N)<std::numeric_limits<T>::epsilon()) + { + qn=un=0; + } + else + { + qn=.5; + un=(3./(x_list[n-1]-x_list[n-2]))*(y2_N-(y_list[n-1]-y_list[n-2])/(x_list[n-1]-x_list[n-2])); + + } + y2_list[n-1]=(un-qn*u[n-2])/(qn*y2_list[n-2]+1.); + for(int i=n-2;i>=0;--i) + { + y2_list[i]=y2_list[i]*y2_list[i+1]+u[i]; + } + } + +}; + +#endif diff --git a/mass_profile/try_beta.sh b/mass_profile/try_beta.sh new file mode 100755 index 0000000..8848c26 --- /dev/null +++ b/mass_profile/try_beta.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +tmp_beta_cfg="_tmp_beta.cfg" +tmp_dbeta_cfg="_tmp_dbeta.cfg" +base_path=`dirname $0` +rm -f $tmp_beta_cfg +rm -f $tmp_dbeta_cfg + + + +if [ $# -lt 1 ] +then + for i in radius_file sbp_file cfunc_file T_file + do + file=`zenity --file-selection --title="$i"` + echo $i $file >>$tmp_beta_cfg + done + + for i in n0 rc beta bkg cm_per_pixel z + do + value=`zenity --entry --text="entry initial value for $i"` + echo $i $value >>$tmp_beta_cfg + done +else + cp $1 $tmp_beta_cfg +fi + +rfile=`grep radius_file $tmp_beta_cfg|awk '{print $2}'` +sfile=`grep sbp_file $tmp_beta_cfg|awk '{print $2}'` +cfile=`grep cfunc_file $tmp_beta_cfg|awk '{print $2}'` +tfile=`grep T_file $tmp_beta_cfg|awk '{print $2}'` + +$base_path/fit_beta_sbp $tmp_beta_cfg +rm -f pgplot.gif +qdp sbp_fit.qdp<<EOF +/null +log +plot +cpd pgplot.gif/gif +plot +quit +EOF + +eog pgplot.gif& +sleep 3 +kill $! >/dev/null + +if zenity --question --text="single beta ok?" +then + mv beta_param.txt sbp_param.txt + exit +fi + +if [ $# -lt 2 ] +then + echo radius_file $rfile >>$tmp_dbeta_cfg + echo sbp_file $sfile >>$tmp_dbeta_cfg + echo cfunc_file $cfile >>$tmp_dbeta_cfg + echo T_file $tfile >>$tmp_dbeta_cfg + + + for i in cm_per_pixel z n01 rc1 beta1 n02 rc2 beta2 bkg + do + value=`zenity --entry --text="entry initial value for $i"` + echo $i $value >>$tmp_dbeta_cfg + done +else + cp $2 $tmp_dbeta_cfg +fi + + +$base_path/fit_dbeta_sbp5 $tmp_dbeta_cfg +rm -f pgplot.gif +qdp sbp_fit.qdp<<EOF +/null +log +plot +cpd pgplot.gif/gif +plot +quit +EOF +eog pgplot.gif& +sleep 3 +kill $! >/dev/null + +mv dbeta_param.txt sbp_param.txt diff --git a/mass_profile/vchisq.hpp b/mass_profile/vchisq.hpp new file mode 100644 index 0000000..0780ce8 --- /dev/null +++ b/mass_profile/vchisq.hpp @@ -0,0 +1,157 @@ +/**
+ \file vchisq.hpp
+ \brief chi-square statistic
+ \author Junhua Gu
+ */
+
+#ifndef VCHI_SQ_HPP
+#define VCHI_SQ_HPP
+#define OPT_HEADER
+#include <core/fitter.hpp>
+#include <iostream>
+#include <vector>
+#include <misc/optvec.hpp>
+#include <cmath>
+#include "plot_reporter.hpp"
+#include <cpgplot.h>
+using std::cerr;using std::endl;
+
+namespace opt_utilities
+{
+
+ template<typename T>
+ class vchisq
+ :public statistic<std::vector<T>,std::vector<T>,std::vector<T>,T,std::string>
+ {
+ private:
+ bool verb;
+ int n;
+ bool limit_bound;
+ typedef std::vector<T> Tp;
+
+ vchisq<T>* do_clone()const
+ {
+ return new vchisq<T>(*this);
+ }
+
+ const char* do_get_type_name()const
+ {
+ return "chi^2 statistic";
+ }
+
+ public:
+ void verbose(bool v)
+ {
+ verb=v;
+ }
+
+ void set_limit()
+ {
+ limit_bound=true;
+ }
+
+ void clear_limit()
+ {
+ limit_bound=false;
+ }
+ public:
+ vchisq()
+ :verb(false),limit_bound(false)
+ {}
+
+
+
+ T do_eval(const std::vector<T>& p)
+ {
+ if(limit_bound)
+ {
+ if(!this->get_fitter().get_model().meets_constraint(p))
+ {
+ return 1e99;
+ }
+ }
+ T result(0);
+
+ std::vector<float> vx;
+ std::vector<float> vy;
+ std::vector<float> vye;
+ std::vector<float> my;
+ float x1=1e99,x2=-1e99,y1=1e99,y2=-1e99;
+ if(verb)
+ {
+ n++;
+
+ if(n%100==0)
+ {
+ vx.resize(this->get_data_set().get_data(0).get_y().size());
+ vy.resize(this->get_data_set().get_data(0).get_y().size());
+ vye.resize(this->get_data_set().get_data(0).get_y().size());
+ my.resize(this->get_data_set().get_data(0).get_y().size());
+ }
+
+ }
+ for(int i=(this->get_data_set()).size()-1;i>=0;--i)
+ {
+ const std::vector<double> y_model(this->eval_model(this->get_data_set().get_data(i).get_x(),p));
+ const std::vector<double>& y=this->get_data_set().get_data(i).get_y();
+ const std::vector<double>& ye=this->get_data_set().get_data(i).get_y_lower_err();
+ for(int j=0;j<y.size();++j)
+ {
+ double chi=(y_model[j]-y[j])/ye[j];
+ result+=chi*chi;
+ }
+
+
+ if(verb&&n%100==0)
+ {
+
+ for(int j=0;j<y.size();++j)
+ {
+ vx.at(j)=((this->get_data_set().get_data(i).get_x().at(j)+this->get_data_set().get_data(i).get_x().at(j+1))/2.);
+ vy.at(j)=(y[j]);
+ vye.at(j)=ye[j];
+ my.at(j)=(y_model[j]);
+ x1=std::min(vx.at(j),x1);
+ y1=std::min(vy.at(j),y1);
+ x2=std::max(vx.at(j),x2);
+ y2=std::max(vy.at(j),y2);
+ vye[j]=log10(vy[j]+vye[j])-log10(vy[j]);
+ vx[j]=log10(vx[j]);
+ vy[j]=log10(vy[j]);
+ my[j]=log10(my[j]);
+
+ }
+
+ }
+
+ }
+ if(verb)
+ {
+
+ if(n%100==0)
+ {
+
+ cerr<<result<<"\t";
+ for(size_t i=0;i<get_size(p);++i)
+ {
+ cerr<<get_element(p,i)<<",";
+ }
+ cerr<<endl;
+ }
+ if(n%100==0)
+ {
+ //cpgask(1);
+ //std::cerr<<x1<<"\t"<<y1<<std::endl;
+ pr.init_xyrange(log10(x1/1.5),log10(x2*1.5),log10(y1/1.5),log10(y2*1.5),30);
+ //pr.init_xyrange((x1),(x2),(y1),(y2));
+ pr.plot_err1_dot(vx,vy,vye);
+ pr.plot_line(vx,my);
+ }
+ }
+
+ return result;
+ }
+ };
+
+}
+#endif
diff --git a/mass_profile/wang2012_model.hpp b/mass_profile/wang2012_model.hpp new file mode 100644 index 0000000..c678970 --- /dev/null +++ b/mass_profile/wang2012_model.hpp @@ -0,0 +1,67 @@ +/** + \file wang2012_model.hpp + \brief Jingying Wang's model + \author Jingying Wang + */ + + +#ifndef WANG2012_MODEL +#define WANG2012_MODEL +#define OPT_HEADER +#include <core/fitter.hpp> +#include <cmath> + +namespace opt_utilities +{ + template <typename T> + class wang2012_model + :public model<T,T,std::vector<T>,std::string> + { + private: + model<T,T,std::vector<T> >* do_clone()const + { + return new wang2012_model<T>(*this); + } + + const char* do_get_type_name()const + { + return "1d power law"; + } + public: + wang2012_model() + { + this->push_param_info(param_info<std::vector<T> >("A",5,0,500)); + this->push_param_info(param_info<std::vector<T> >("n",1.66,0,10)); + this->push_param_info(param_info<std::vector<T> >("xi",0.45,0,1)); + this->push_param_info(param_info<std::vector<T> >("a2",1500,0,1e8)); + this->push_param_info(param_info<std::vector<T> >("a3",50,0,1e8)); + this->push_param_info(param_info<std::vector<T> >("beta",0.49,0.1,0.7)); + this->push_param_info(param_info<std::vector<T> >("T0",0,0,10)); + + } + + T do_eval(const T& x,const std::vector<T>& param) + { + T A=param[0]; + T n=param[1]; + T xi=param[2]; + T a2=param[3]; + T a3=param[4]; + T beta=param[5]; + T T0=param[6]; + return A*(pow(x,n)+xi*a2)/(pow(x,n)+a2)/pow(1+x*x/a3/a3,beta)+T0; + //return A*(pow(x,n)+a1)/(pow(x,n)+1)/pow(1+x*x/a3/a3,beta)+T0; + } + + private: + std::string do_get_information()const + { + return ""; + } + }; +} + + + +#endif +//EOF |