real calc_check(int check,const char * exp) { real opd_stack[STACK_SIZE]; int opr_stack[STACK_SIZE]; int opd_size = 0,opr_size = 0; int state = 1/*,i*/; extern VAR * find_var (const char *); if (check) { match_exp(exp); l_get_token(); if (token_type!=TT_LINE_END) { merror_msg("illegal expr"); } } pline = exp; while(1) { l_get_token();//puts(token);SHOW_STACK; // exit if (token_type==TT_LINE_END) { break; } else if (token_type==TT_ID) { VAR * v;ARRAY * a; if (state!=1 && !check) { l_put_back(); break; } v = find_var(token); if (v!=NULL) { push_opd(v->value); move2(2); continue; } a = find_array (token); if (a!=NULL) { int index; l_get_token();//skip ( index = (int)calc_check(FALSE,pline); // delete this line,calc_check call skip ( automatically //l_get_token();//skip ) push_opd(get_element(a,index)); move2(2); continue; } merror_msg("Unrecognized identifier '%s'",token); } // constant else if (token_type==TT_INT || token_type==TT_FLOAT) { push_opd((real)atof(token)); move2(2); } // operator else if (IS_OPR(token_type)) { // neg "-" judgement if (token_type==OPR_SUB && state==1) { token_type = OPR_NEG; } // if (opr_size>0 && opr_stack[opr_size-1]!=TT_LBK && priority(token_type) <= priority(opr_stack[opr_size-1])) { real result; result = calc_pop(opd_stack,opr_stack,&opd_size,&opr_size); push_opd(result); } push_opr(token_type); move2(1); } // process '(' and ')' else if (token_type==TT_LBK) { push_opr(token_type); } else if (token_type==TT_RBK) { while(opr_stack[opr_size-1] /* top */ != TT_LBK && opr_size > 0) { real result; result = calc_pop(opd_stack,opr_stack,&opd_size,&opr_size); push_opd(result); } if (opr_stack[opr_size-1] /* top */ == TT_LBK) { opr_size--; // pop '(' } else // funcition call end { break; } } // built-in function call else if (IS_RESWORD(token_type)) { int argc = token_ext,i; real result; FUNCTION func = get_func(token_type); //printf("call <%s>\n",token); // skip '(' l_get_token (); // get all arg and push them in stack for (i=0;i<argc;++i) { result = calc_check(FALSE,pline); push_opd(result); //printf("[%d] |%.4lf|\n",i,result); } // call func result = func(opd_stack + opd_size - argc); // pop args opd_size -= argc; // push result push_opd(result); //printf("call end\n"); } else { if (check) merror_illegal_token(); else { l_put_back(); break; } } } // pop up all while(opr_size > 0) { real result; result = calc_pop(opd_stack,opr_stack,&opd_size,&opr_size); push_opd(result); } if (opd_size != 1) { merror_msg("calc:unknown error!"); } return opd_stack[0]; }
bool TASReso::SetHKLE(t_real h, t_real k, t_real l, t_real E) { static const t_real s_dPlaneDistTolerance = std::cbrt(tl::get_epsilon<t_real>()); ResoResults& resores = m_res[0]; //std::cout << "UB = " << m_opts.matUB << std::endl; //std::cout << h << " " << k << " " << l << ", " << E << std::endl; if(m_opts.matUB.size1() < 3 || m_opts.matUB.size2() < 3) { const char* pcErr = "Invalid UB matrix."; tl::log_err(pcErr); resores.strErr = pcErr; resores.bOk = false; return false; } t_vec vecHKLE; if(m_opts.matUB.size1() == 3) vecHKLE = tl::make_vec({h, k, l}); else vecHKLE = tl::make_vec({h, k, l, E}); t_vec vecQ = ublas::prod(m_opts.matUB, vecHKLE); if(vecQ.size() > 3) vecQ.resize(3, true); m_tofreso.Q = m_reso.Q = ublas::norm_2(vecQ) / angs; m_tofreso.E = m_reso.E = E * meV; //tl::log_info("kfix = ", m_dKFix, ", E = ", E, ", Q = ", vecQ); wavenumber kother = tl::get_other_k(m_reso.E, m_dKFix/angs, m_bKiFix); //tl::log_info("kother = ", t_real(kother*angs)); if(m_bKiFix) { m_tofreso.ki = m_reso.ki = m_dKFix / angs; m_tofreso.kf = m_reso.kf = kother; } else { m_tofreso.ki = m_reso.ki = kother; m_tofreso.kf = m_reso.kf = m_dKFix / angs; } m_reso.thetam = units::abs(tl::get_mono_twotheta(m_reso.ki, m_reso.mono_d, /*m_reso.dmono_sense>=0.*/1)*t_real(0.5)); m_reso.thetaa = units::abs(tl::get_mono_twotheta(m_reso.kf, m_reso.ana_d, /*m_reso.dana_sense>=0.*/1)*t_real(0.5)); m_tofreso.twotheta = m_reso.twotheta = units::abs(tl::get_sample_twotheta(m_reso.ki, m_reso.kf, m_reso.Q, 1)); //tl::log_info("thetam = ", tl::r2d(m_reso.thetam/rads)); //tl::log_info("thetaa = ", tl::r2d(m_reso.thetaa/rads)); //tl::log_info("twothetas = ", tl::r2d(m_reso.twotheta/rads)); m_tofreso.angle_ki_Q = m_reso.angle_ki_Q = tl::get_angle_ki_Q(m_reso.ki, m_reso.kf, m_reso.Q, /*m_reso.dsample_sense>=0.*/1); m_tofreso.angle_kf_Q = m_reso.angle_kf_Q = tl::get_angle_kf_Q(m_reso.ki, m_reso.kf, m_reso.Q, /*m_reso.dsample_sense>=0.*/1); //tl::log_info("kiQ = ", tl::r2d(m_reso.angle_ki_Q/rads)); //m_reso.angle_ki_Q = units::abs(m_reso.angle_ki_Q); //m_reso.angle_kf_Q = units::abs(m_reso.angle_kf_Q); if(m_foc != ResoFocus::FOC_UNCHANGED) { if((unsigned(m_foc) & unsigned(ResoFocus::FOC_MONO_FLAT)) != 0) // flat mono m_reso.bMonoIsCurvedH = m_reso.bMonoIsCurvedV = 0; if((unsigned(m_foc) & unsigned(ResoFocus::FOC_MONO_H)) != 0) // optimally curved mono (h) m_reso.bMonoIsCurvedH = m_reso.bMonoIsOptimallyCurvedH = 1; if((unsigned(m_foc) & unsigned(ResoFocus::FOC_MONO_V)) != 0) // optimally curved mono (v) m_reso.bMonoIsCurvedV = m_reso.bMonoIsOptimallyCurvedV = 1; if((unsigned(m_foc) & unsigned(ResoFocus::FOC_ANA_FLAT)) != 0) // flat ana m_reso.bAnaIsCurvedH = m_reso.bAnaIsCurvedV = 0; if((unsigned(m_foc) & unsigned(ResoFocus::FOC_ANA_H)) != 0) // optimally curved ana (h) m_reso.bAnaIsCurvedH = m_reso.bAnaIsOptimallyCurvedH = 1; if((unsigned(m_foc) & unsigned(ResoFocus::FOC_ANA_V)) != 0) // optimally curved ana (v) m_reso.bAnaIsCurvedV = m_reso.bAnaIsOptimallyCurvedV = 1; //tl::log_info("Mono focus (h,v): ", m_reso.bMonoIsOptimallyCurvedH, ", ", m_reso.bMonoIsOptimallyCurvedV); //tl::log_info("Ana focus (h,v): ", m_reso.bAnaIsOptimallyCurvedH, ", ", m_reso.bAnaIsOptimallyCurvedV); // remove collimators /*if(m_reso.bMonoIsCurvedH) { m_reso.coll_h_pre_mono = 99999. * rads; m_reso.coll_h_pre_sample = 99999. * rads; } if(m_reso.bMonoIsCurvedV) { m_reso.coll_v_pre_mono = 99999. * rads; m_reso.coll_v_pre_sample = 99999. * rads; } if(m_reso.bAnaIsCurvedH) { m_reso.coll_h_post_sample = 99999. * rads; m_reso.coll_h_post_ana = 99999. * rads; } if(m_reso.bAnaIsCurvedV) { m_reso.coll_v_post_sample = 99999. * rads; m_reso.coll_v_post_ana = 99999. * rads; }*/ } /*tl::log_info("thetam = ", m_reso.thetam); tl::log_info("thetaa = ", m_reso.thetaa); tl::log_info("2theta = ", m_reso.twotheta);*/ if(std::fabs(vecQ[2]) > s_dPlaneDistTolerance) { tl::log_err("Position Q = (", h, " ", k, " ", l, "),", " E = ", E, " meV not in scattering plane."); resores.strErr = "Not in scattering plane."; resores.bOk = false; return false; } vecQ.resize(2, true); m_opts.dAngleQVec0 = -tl::vec_angle(vecQ); //tl::log_info("angle Q vec0 = ", m_opts.dAngleQVec0); //tl::log_info("calc r0: ", m_reso.bCalcR0); for(ResoResults& resores_cur : m_res) { // if only one sample position is requested, don't randomise if(m_res.size() > 1) { /*m_reso.pos_x = tl::rand_real(-t_real(m_reso.sample_w_q*0.5/cm), t_real(m_reso.sample_w_q*0.5/cm)) * cm; m_reso.pos_y = tl::rand_real(-t_real(m_reso.sample_w_perpq*0.5/cm), t_real(m_reso.sample_w_perpq*0.5/cm)) * cm; m_reso.pos_z = tl::rand_real(-t_real(m_reso.sample_h*0.5/cm), t_real(m_reso.sample_h*0.5/cm)) * cm;*/ m_reso.pos_x = tl::rand_norm(t_real(0), t_real(tl::get_FWHM2SIGMA<t_real>()*m_reso.sample_w_q/cm)) * cm; m_reso.pos_y = tl::rand_norm(t_real(0), t_real(tl::get_FWHM2SIGMA<t_real>()*m_reso.sample_w_perpq/cm)) * cm; m_reso.pos_z = tl::rand_norm(t_real(0), t_real(tl::get_FWHM2SIGMA<t_real>()*m_reso.sample_h/cm)) * cm; } // calculate resolution at (hkl) and E if(m_algo == ResoAlgo::CN) { //tl::log_info("Algorithm: Cooper-Nathans (TAS)"); resores_cur = calc_cn(m_reso); } else if(m_algo == ResoAlgo::POP) { //tl::log_info("Algorithm: Popovici (TAS)"); resores_cur = calc_pop(m_reso); } else if(m_algo == ResoAlgo::ECK) { //tl::log_info("Algorithm: Eckold-Sobolev (TAS)"); resores_cur = calc_eck(m_reso); } else if(m_algo == ResoAlgo::VIOL) { //tl::log_info("Algorithm: Violini (TOF)"); m_reso.flags &= ~CALC_R0; resores_cur = calc_viol(m_tofreso); } else { const char* pcErr = "Unknown algorithm selected."; tl::log_err(pcErr); resores_cur.strErr = pcErr; resores_cur.bOk = false; return false; } if(!resores_cur.bOk) { tl::log_err("Error calculating resolution: ", resores_cur.strErr); tl::log_debug("R0: ", resores_cur.dR0); tl::log_debug("res: ", resores_cur.reso); } } return resores.bOk; }