Beispiel #1
0
void SicsCache::remove_old_vars()
{
	const t_real dEpoch = tl::epoch<t_real>();
	const t_real dMaxAge = t_real(2. / 1000.) * t_real(m_iPollRate);

	decltype(m_mapCache)::iterator iter = m_mapCache.begin();
	while(iter!=m_mapCache.end())
	{
		decltype(m_mapCache)::iterator iterNext = std::next(iter);

		const auto& _val = *iter;
		const std::string& strKey = _val.first;
		const CacheVal& val = _val.second;
		const t_real dAge = dEpoch - val.dTimestamp;

		// clean up x plot data
		if(dAge > dMaxAge && tl::begins_with(strKey, std::string("scan."), 0))
		{
			//std::cout << "removing " << strKey << std::endl;
			m_mapCache.erase(iter);
			iter = iterNext;
			continue;
		}
		++iter;
	}
}
void SpurionDlg::CalcBragg()
{
	const unsigned int NUM_POINTS = 512;

	const bool bFixedEi = radioFixedEi->isChecked();
	t_real dE = t_real(spinE->value());
	bool bImag;
	tl::t_wavenumber_si<t_real> k = tl::E2k(dE*meV, bImag);

	const t_real dMinq = spinMinQ->value();
	const t_real dMaxq = spinMaxQ->value();

	m_vecQ = tl::linspace(dMinq, dMaxq, NUM_POINTS);
	m_vecE.clear();
	m_vecE.reserve(m_vecQ.size());

	for(t_real dq : m_vecQ)
	{
		tl::t_wavenumber_si<t_real> q = dq/angs;
		tl::t_energy_si<t_real> E = tl::get_bragg_tail(k, q, bFixedEi);

		m_vecE.push_back(E/meV);
	}

	set_qwt_data<t_real>()(*m_plotwrap, m_vecQ, m_vecE);
}
Beispiel #3
0
t_real SqwJl::operator()(t_real dh, t_real dk, t_real dl, t_real dE) const
{
	if(!m_bOk)
	{
		tl::log_err("Julia interpreter has not initialised, cannot query S(q,w).");
		return t_real(0);
	}

	std::lock_guard<std::mutex> lock(*m_pmtx);

	jl_value_t *phklE[4] =
		{ jl_box_float64(dh), jl_box_float64(dk),
		jl_box_float64(dl), jl_box_float64(dE) };
	jl_value_t *pSqw = jl_call((jl_function_t*)m_pSqw, phklE, 4);
	return t_real(jl_unbox_float64(pSqw));
}
Beispiel #4
0
void Real3DDlg::CalcPeaks(const LatticeCommon<t_real_glob>& latticecommon)
{
	m_pPlot->SetEnabled(0);
	m_pPlot->clear();
	m_pPlot->SetObjectCount(latticecommon.vecAllAtoms.size());

	t_real dA = 0.7;
	std::vector<std::vector<t_real>> vecColor = {
		{1., 0., 0., dA},
		{0., 1., 0., dA},
		{0., 0., 1., dA},
		{1., 1., 0., dA},
		{0., 1., 1., dA},
		{1., 0., 1., dA},

		{0.5, 0., 0., dA},
		{0., 0.5, 0., dA},
		{0., 0., 0.5, dA},
		{0.5, 0.5, 0., dA},
		{0., 0.5, 0.5, dA},
		{0.5, 0., 0.5, dA},

		{1., 1., 1., dA},
		{0., 0., 0., dA},
		{0.5, 0.5, 0.5, dA},
	};

	std::size_t iPeakIdx = 0;
	const t_real dLimMax = std::numeric_limits<t_real>::max();
	std::vector<t_real> vecMin = {dLimMax, dLimMax, dLimMax},
		vecMax = {-dLimMax, -dLimMax, -dLimMax};

	t_real d = t_real(0.5);
	t_vec vecPeaks[] = {
		latticecommon.lattice.GetPos(-d,0,0), latticecommon.lattice.GetPos(d,0,0),
		latticecommon.lattice.GetPos(0,-d,0), latticecommon.lattice.GetPos(0,d,0),
		latticecommon.lattice.GetPos(0,0,-d), latticecommon.lattice.GetPos(0,0,d),
	};

	for(const t_vec& vecPeak : vecPeaks)
		for(unsigned int i=0; i<3; ++i)
		{
			vecMin[i] = std::min(vecPeak[i], vecMin[i]);
			vecMax[i] = std::max(vecPeak[i], vecMax[i]);
		}

	for(std::size_t iAtom=0; iAtom<latticecommon.vecAllAtoms.size(); ++iAtom)
	{
		const std::string& strElem = latticecommon.vecAllNames[iAtom];
		const t_vec& vecThisAtom = latticecommon.vecAllAtoms[iAtom];
		const t_vec& vecThisAtomFrac = latticecommon.vecAllAtomsFrac[iAtom];
		std::size_t iCurAtomType = latticecommon.vecAllAtomTypes[iAtom];

		m_pPlot->PlotSphere(vecThisAtom, 0.1, iPeakIdx);
		m_pPlot->SetObjectColor(iPeakIdx, vecColor[iCurAtomType % vecColor.size()]);

		/*for(unsigned int i=0; i<3; ++i)
		{
			vecMin[i] = std::min(vecThisAtom[i], vecMin[i]);
			vecMax[i] = std::max(vecThisAtom[i], vecMax[i]);
		}*/

		std::ostringstream ostrTip;
		ostrTip.precision(g_iPrecGfx);
		ostrTip << strElem;
		ostrTip << "\n("
			<< vecThisAtomFrac[0] << ", "
			<< vecThisAtomFrac[1] << ", "
			<< vecThisAtomFrac[2] << ") frac";
		ostrTip << "\n("
			<< vecThisAtom[0] << ", "
			<< vecThisAtom[1] << ", "
			<< vecThisAtom[2] << ") A";

		m_pPlot->SetObjectLabel(iPeakIdx, ostrTip.str());

		++iPeakIdx;
	}

	m_pPlot->SetMinMax(vecMin, vecMax);
	m_pPlot->SetEnabled(1);
}
static inline int monteconvo_simple(const char* pcNeutrons, const char* pcSqw)
{
	std::ifstream ifstrNeutr(pcNeutrons);
	if(!ifstrNeutr.is_open())
	{
		tl::log_err("Cannot open neutrons file \"", pcNeutrons, "\".");
		return -1;
	}

	std::shared_ptr<SqwBase> ptrSqw(new SqwKdTree(pcSqw));
	SqwBase *psqw = ptrSqw.get();
	if(!psqw->IsOk())
	{
		tl::log_err("Cannot open Sqw file \"", pcSqw, "\".");
		return -2;
	}

	unsigned int iCurNeutr = 0;
	std::unordered_map<std::string, std::string> mapNeutrParams;
	t_real dS = 0.;
	t_real dhklE[4] = {0., 0., 0., 0.};

	while(!ifstrNeutr.eof())
	{
		std::string strLine;
		std::getline(ifstrNeutr, strLine);
		tl::trim(strLine);

		if(strLine.size() == 0)
			continue;

		if(strLine[0] == '#')
		{
			strLine[0] = ' ';
			mapNeutrParams.insert(tl::split_first(strLine, std::string(":"), 1));
			continue;
		}

		std::vector<t_real> vecNeutr;
		tl::get_tokens<t_real>(strLine, std::string(" \t"), vecNeutr);
		if(vecNeutr.size() != 4)
		{
			tl::log_err("Need h,k,l,E data.");
			return -3;
		}

		for(int i=0; i<4; ++i) dhklE[i] += vecNeutr[i];
		//sqw.SetNeutronParams(&mapNeutrParams);
		dS += (*psqw)(vecNeutr[0], vecNeutr[1], vecNeutr[2], vecNeutr[3]);

		++iCurNeutr;
	}

	dS /= t_real(iCurNeutr+1);

	for(int i=0; i<4; ++i)
		dhklE[i] /= t_real(iCurNeutr+1);

	tl::log_info("Processed ",  iCurNeutr, " MC neutrons.");
	tl::log_info("S(", dhklE[0], ", ", dhklE[1],  ", ", dhklE[2], ", ", dhklE[3], ") = ", dS);
	return 0;
}
static inline int monteconvo(const char* pcRes, const char* pcCrys,
	const char* pcSqw, const char* pcSteps, const char* pcOut)
{
	TASReso reso;
	tl::log_info("Loading resolution file \"", pcRes, "\".");
	if(!reso.LoadRes(pcRes))
		return -1;

	tl::log_info("Loading crystal file \"", pcRes, "\".");
	if(!reso.LoadLattice(pcCrys))
		return -2;


	tl::DatFile<t_real, char> steps;
	tl::log_info("Loading scan steps file \"", pcRes, "\".");
	if(!steps.Load(pcSteps))
	{
		tl::log_err("Cannot load steps file.");
		return -3;
	}
	if(steps.GetColumnCount() != 4)
	{
		tl::log_err("Need 4 columns in step file: h k l E.");
		return -3;
	}
	const unsigned int iNumSteps = steps.GetRowCount();
	tl::log_info("Number of scan steps: ", iNumSteps);
	const t_real *pH = steps.GetColumn(0).data();
	const t_real *pK = steps.GetColumn(1).data();
	const t_real *pL = steps.GetColumn(2).data();
	const t_real *pE = steps.GetColumn(3).data();

	unsigned int iNumNeutrons = 0;
	try
	{
		iNumNeutrons = tl::str_to_var<unsigned int>(steps.GetHeader().at("num_neutrons"));
		reso.SetAlgo(ResoAlgo(tl::str_to_var<int>(steps.GetHeader().at("algo"))));
		bool bFixedKi = tl::str_to_var<bool>(steps.GetHeader().at("fixed_ki"));
		t_real dKFix = tl::str_to_var<t_real>(steps.GetHeader().at("kfix"));

		reso.SetKiFix(bFixedKi);
		reso.SetKFix(dKFix);
	}
	catch(const std::out_of_range& ex)
	{
		tl::log_err("Need keys \"num_neutrons\", \"fixed_ki\", \"kfix\" and \"algo\" in steps file.");
		return -3;
	}


	tl::log_info("Number of neutrons: ", iNumNeutrons);


	std::shared_ptr<SqwBase> ptrSqw;

	if(pcSqw)
	{
		tl::log_info("Loading S(Q,w) file \"", pcSqw, "\".");
		ptrSqw.reset(new SqwKdTree(pcSqw));
	}
	else
	{
		tl::log_info("Using phonon model.");
		ptrSqw.reset(new SqwPhonon(tl::make_vec({4.,4.,0}),
				tl::make_vec({0.,0.,1.}), tl::make_vec({1.,-1.,0.}),
				40., M_PI/2., 0.5, 0.5, 1.,
				12., M_PI/2., 0.5, 0.5, 1.,
				18., M_PI/2., 0.5, 0.5, 1.,
				100.));
	}


	SqwBase *psqw = ptrSqw.get();

	if(!psqw->IsOk())
	{
		tl::log_err("Cannot init Sqw.");
		return -4;
	}


	std::ofstream ofstrOut(pcOut);
	ofstrOut << "#\n";
	ofstrOut << "# Format: h k l E S\n";
	ofstrOut << "#\n";

	std::vector<ublas::vector<t_real>> vecNeutrons;
	for(unsigned int iStep=0; iStep<iNumSteps; ++iStep)
	{
		t_real dProgress = t_real(iStep)/t_real(iNumSteps)*100.;

		tl::log_info("------------------------------------------------------------");
		tl::log_info("Step ", iStep+1, " of ", iNumSteps, ".");
		tl::log_info("Q = (", pH[iStep], " ", pK[iStep], " ", pL[iStep], "), E = ", pE[iStep], " meV.");
		if(!reso.SetHKLE(pH[iStep], pK[iStep], pL[iStep], pE[iStep]))
		{
			tl::log_err("Invalid position.");
			break;
		}

		std::cout <<"\x1b]0;"
			<< std::setprecision(3) << dProgress <<  "%"
			<< " - generating MC neutrons"
			<< "\x07" << std::flush;
		Ellipsoid4d<t_real> elli = reso.GenerateMC(iNumNeutrons, vecNeutrons);

		t_real dS = 0.;
		t_real dhklE_mean[4] = {0., 0., 0., 0.};

		std::cout <<"\x1b]0;"
			<< std::setprecision(3) << dProgress <<  "%"
			<< " - calculating S(q,w)"
			<< "\x07" << std::flush;
		for(const ublas::vector<t_real>& vecHKLE : vecNeutrons)
		{
			dS += (*psqw)(vecHKLE[0], vecHKLE[1], vecHKLE[2], vecHKLE[3]);

			for(int i=0; i<4; ++i)
				dhklE_mean[i] += vecHKLE[i];
		}

		dS /= t_real(iNumNeutrons);
		for(int i=0; i<4; ++i)
			dhklE_mean[i] /= t_real(iNumNeutrons);

		ofstrOut.precision(16);
		ofstrOut << std::left << std::setw(20) << pH[iStep] << " "
			<< std::left << std::setw(20) << pK[iStep] << " "
			<< std::left << std::setw(20) << pL[iStep] << " "
			<< std::left << std::setw(20) << pE[iStep] << " "
			<< std::left << std::setw(20) << dS << "\n";

		tl::log_info("Mean position: Q = (", dhklE_mean[0], " ", dhklE_mean[1], " ", dhklE_mean[2], "), E = ", dhklE_mean[3], " meV.");
		tl::log_info("S(", pH[iStep], ", ", pK[iStep],  ", ", pL[iStep], ", ", pE[iStep], ") = ", dS);
	}
	std::cout <<"\x1b]0;" << "100%" << "\x07" << std::flush;

	tl::log_info("Wrote output file \"", pcOut, "\".");
	ofstrOut.close();
	return 0;
}