예제 #1
0
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];
}
예제 #2
0
파일: TASReso.cpp 프로젝트: t-weber/takin
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;
}