#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 #include #include static const double pi=4*atan(1); // Ratio of the electron density (n_e) to the proton density (n_p) // n_gas = n_e + n_p ~= 1.826 n_e => n_e / n_p ~= 1.21 // Reference: Ettori et al. 2013, Space Sci. Rev., 177, 119-154; Eq.(9) below static const double ne_np_ratio = 1.21; namespace opt_utilities { //This is used to project a 3-D surface brightness model to 2-D profile template class projector :public model,std::vector,std::vector > { private: //Points to a 3-D model that is to be projected model,std::vector,std::vector >* pmodel; func_obj* 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,std::vector >* 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,std::vector >& m) { this->clear_param_info(); for(size_t i=0;ipush_param_info(m.get_param_info(i)); } this -> push_param_info(param_info, std::string>("bkg",0,0,1E99)); pmodel=m.clone(); pmodel->clear_param_modifier(); } void attach_cfunc(const func_obj& 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& rlist,int nsph,int nrad) { if(nsph& p)const { std::vector 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)get_param_info(i).get_lower_limit()) { // std::cerr<get_param_info(i).get_name()<<"\t"< p2(p1.size()-1); for(size_t i=0;imeets_constraint(p2); } public: //Perform the projection std::vector do_eval(const std::vector& x,const std::vector& p) { T bkg=std::abs(p.back()); //I think following codes are clear enough :). std::vector unprojected(pmodel->eval(x,p)); std::vector projected(unprojected.size()); for(size_t nrad=0; nrad