#include #include #include #include #include #include #include #include "catima/catima.h" #include "catima/nucdata.h" #include "json.hpp" using namespace std; using namespace catima; using json = nlohmann::json; void help(){ std::cout<<"usage: catima_calculator config_file.json\n"; } json load_json(const char *fname); char* getCmdOption(char ** begin, char ** end, const std::string & option); Material json_material(json &j); int main( int argc, char * argv[] ) { Projectile projectile; Layers layers; std::vector energies; Config conf; if(argc == 1 ){ help(); return 0; } try{ auto j = load_json(argv[1]); // load projectile data if(j.count("projectile")){ if(j["projectile"].is_array()){ projectile.A = j["projectile"].at(0).get(); projectile.Z = j["projectile"].at(1).get(); } } else{ throw std::invalid_argument("projectile field is missing"); } // load energy data if(j.count("energy")){ auto e = j.at("energy"); if(e.is_number()){ energies.push_back(j["energy"].get()); } if(e.is_string()){ double _e = std::stod(j["energy"].get()); energies.push_back(_e); } if(e.is_array()){ for(auto &el:e){ if(el.is_number()) energies.push_back(el.get()); } } if(e.is_object()){ if(e.count("min")>0 && e.count("max")>0 && (e.count("num")>0 || e.count("step")>0)){ double emin = e["min"].get(); double emax = e["max"].get(); int num; if(e.count("step")){ num = 1+(emax-emin)/e["step"].get(); } if(e.count("num")){ num = e["num"].get(); } energies = linspace_vector(emin,emax,num); } } } else{ throw std::invalid_argument("energy field is missing"); } if(j.count("material")){ auto e = j.at("material"); if(e.is_array()){ for(auto& entry : e){ if(!entry.is_object()){ throw std::invalid_argument("material error"); } layers.add(json_material(entry)); } } if(e.is_object()){ layers.add(json_material(e)); } } else{ throw std::invalid_argument("material field is missing"); } if(j.count("config")>0){ auto e = j["config"]; if(e.is_string()){ std::string cstr = e.get(); if(cstr=="atimav1.3"){ conf.z_effective = z_eff_type::pierce_blann; cout<<"using config: Atima v1.3\n"; } if(cstr=="atimav1.4"){ conf.z_effective = z_eff_type::atima14; cout<<"using config: Atima v1.4\n"; } } } } // end of try catch(...){ cout<<"Could not load the config file"<<"\n"; return 0; } if(layers.num()==0){ cout<<"no material specified\n"; return 0; } if(energies.size()==0){ cout<<"no energy specified\n"; return 0; } cout<<"******** CAtima calculator ********\n"; cout<<"Projectile: A = "< res; std::ifstream jfile(fname,std::ifstream::in); if(!jfile){ throw std::invalid_argument("Could not open config file"); } std::string content; jfile.seekg(0, std::ios::end); content.resize(jfile.tellg()); jfile.seekg(0, std::ios::beg); jfile.read(&content[0], content.size()); jfile.close(); try{ auto j = json::parse(content); return j; } catch(...){ cout<<"JSON parsing error\n"; throw std::invalid_argument("Could not parse json file"); } }; Material json_material(json &j){ if(!j.is_object()){ throw std::invalid_argument("Wrong material definition"); } try{ double a=0; int z=0; double ipot=0.0; double density=0.0; double th=0.0; if(j.count("density")>0){ density = j["density"].get(); } if(j.count("thickness")>0){ th = j["thickness"].get(); } if(j.count("Ipot")>0){ ipot = j["Ipot"].get(); } if(j.count("A")>0){ a = j["A"].get(); } if(j.count("Z")>0){ z = j["Z"].get(); } if(z<=0){ cout<<"Z="<0){ Material m(a,z,density,th); if(ipot>0)m.I(ipot); return m; } else{ Material m = get_material(z); m.thickness(th); return m; } } catch(...){ cout<<"JSON parsing error: material definition\n"; throw std::invalid_argument("Could not parse json file"); } } char* getCmdOption(char ** begin, char ** end, const std::string & option) { char ** itr = std::find(begin, end, option); if (itr != end && ++itr != end) { return *itr; } return nullptr; }