aboutsummaryrefslogtreecommitdiffstats
path: root/mass_profile
diff options
context:
space:
mode:
authorAaron LI <aaronly.me@gmail.com>2016-05-27 22:47:24 +0800
committerAaron LI <aaronly.me@gmail.com>2016-05-27 22:47:24 +0800
commitffd178e0bd72562a3c2cff9747b6e656edc881dc (patch)
tree8800b7b5b2e8bc3df1a6760df5cd54eaaa686702 /mass_profile
parent5c35fad9240fb42c1371c721e0b2af7379bd9ea0 (diff)
downloadchandra-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')
-rw-r--r--mass_profile/.gitignore24
-rw-r--r--mass_profile/Makefile57
-rw-r--r--mass_profile/adapt_trapezoid.h124
-rwxr-xr-xmass_profile/analyze_entropy_profile.py54
-rwxr-xr-xmass_profile/analyze_fx.py32
-rwxr-xr-xmass_profile/analyze_lx.py32
-rwxr-xr-xmass_profile/analyze_mass_profile.py195
-rw-r--r--mass_profile/beta.hpp45
-rw-r--r--mass_profile/beta_cfg.cpp91
-rw-r--r--mass_profile/beta_cfg.hpp24
-rwxr-xr-xmass_profile/calc_all_cooling_time.sh30
-rwxr-xr-xmass_profile/calc_all_entropy.sh39
-rw-r--r--mass_profile/calc_distance.cc61
-rw-r--r--mass_profile/calc_distance.h8
-rw-r--r--mass_profile/calc_lx.cpp218
-rw-r--r--mass_profile/calc_lx_beta.cpp506
-rwxr-xr-xmass_profile/calc_lx_beta.sh161
-rw-r--r--mass_profile/calc_lx_dbeta.cpp550
-rwxr-xr-xmass_profile/calc_lx_dbeta.sh161
-rwxr-xr-xmass_profile/calc_lxfx_simple.sh75
-rw-r--r--mass_profile/call_calc_distance.cc52
-rw-r--r--mass_profile/change.log25
-rw-r--r--mass_profile/chisq.hpp219
-rw-r--r--mass_profile/constrained_dbeta.hpp80
-rwxr-xr-xmass_profile/coolfunc_calc.sh138
-rwxr-xr-xmass_profile/coolfunc_calc2.sh173
-rwxr-xr-xmass_profile/coolfunc_calc_0.1-2.4.sh139
-rwxr-xr-xmass_profile/coolfunc_calc_0.7-7.sh139
-rwxr-xr-xmass_profile/coolfunc_calc_bolo.sh139
-rwxr-xr-xmass_profile/coolfunc_calc_bolo_cnt.sh138
-rwxr-xr-xmass_profile/coolfunc_calc_erg.sh145
-rw-r--r--mass_profile/cooling_time.cpp62
-rwxr-xr-xmass_profile/cooling_time2.sh592
-rwxr-xr-xmass_profile/csb_calc_lwt.sh166
-rw-r--r--mass_profile/dbeta.hpp108
-rw-r--r--mass_profile/dump_fit_qdp.cpp55
-rw-r--r--mass_profile/dump_fit_qdp.hpp16
-rwxr-xr-xmass_profile/extract_tcool.py12
-rwxr-xr-xmass_profile/fg_2500_500.py153
-rwxr-xr-xmass_profile/fit_beta_entropy.sh150
-rwxr-xr-xmass_profile/fit_beta_mass_profile.sh200
-rwxr-xr-xmass_profile/fit_beta_nfw_mass_profile.sh227
-rw-r--r--mass_profile/fit_beta_sbp.cpp531
-rwxr-xr-xmass_profile/fit_dbeta_entropy.sh149
-rwxr-xr-xmass_profile/fit_dbeta_mass_profile.sh198
-rwxr-xr-xmass_profile/fit_dbeta_nfw_mass_profile.sh224
-rw-r--r--mass_profile/fit_dbeta_sbp.cpp585
-rw-r--r--mass_profile/fit_direct_beta.cpp61
-rw-r--r--mass_profile/fit_lt_bpl.cpp336
-rw-r--r--mass_profile/fit_lt_pl.cpp239
-rwxr-xr-xmass_profile/fit_mass.sh36
-rw-r--r--mass_profile/fit_mt_bpl.cpp350
-rw-r--r--mass_profile/fit_mt_pl.cpp265
-rw-r--r--mass_profile/fit_nfw_mass.cpp159
-rw-r--r--mass_profile/fit_nfw_sbp.cpp417
-rwxr-xr-xmass_profile/fit_nfwmass_beta.sh314
-rwxr-xr-xmass_profile/fit_nfwmass_dbeta.sh314
-rwxr-xr-xmass_profile/fit_sbp.sh43
-rw-r--r--mass_profile/fit_wang2012_model.cpp195
-rwxr-xr-xmass_profile/get_center_params.sh46
-rwxr-xr-xmass_profile/get_lxfx_data.sh89
-rwxr-xr-xmass_profile/init.sh6
-rwxr-xr-xmass_profile/loop_lx.sh73
-rw-r--r--mass_profile/nfw.hpp56
-rw-r--r--mass_profile/nfw_ne.hpp198
-rw-r--r--mass_profile/pgplot_path.txt2
-rw-r--r--mass_profile/plot_reporter.cpp70
-rw-r--r--mass_profile/plot_reporter.hpp23
-rw-r--r--mass_profile/projector.hpp206
-rwxr-xr-xmass_profile/query_source_info.sh129
-rw-r--r--mass_profile/report_error.cpp39
-rw-r--r--mass_profile/report_error.hpp6
-rw-r--r--mass_profile/sample.cfg11
-rwxr-xr-xmass_profile/shuffle_T.py18
-rwxr-xr-xmass_profile/shuffle_sbp.py18
-rw-r--r--mass_profile/spline.h109
-rwxr-xr-xmass_profile/try_beta.sh86
-rw-r--r--mass_profile/vchisq.hpp157
-rw-r--r--mass_profile/wang2012_model.hpp67
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