diff --git a/Base/Axis/Frame.cpp b/Base/Axis/Frame.cpp index 38847e0d0f0350a154d937f563d12d442d1a50b7..ddc66982a7660c6be867a71a58333af9143ba5d1 100644 --- a/Base/Axis/Frame.cpp +++ b/Base/Axis/Frame.cpp @@ -165,3 +165,9 @@ Frame* Frame::flat() const outaxes.emplace_back(s->clone()); return new Frame(std::move(outaxes)); } + +void Frame::setScale(size_t k_axis, Scale* scale) +{ + m_axes.replace_at(k_axis, scale); + m_size = FrameUtil::product_size(m_axes.reference()); +} diff --git a/Base/Axis/Frame.h b/Base/Axis/Frame.h index 58215319a14f5813120285e8be8b43883e65c677..5cbc1e9d9ed8df921267f47f65a86a4276aaaa8b 100644 --- a/Base/Axis/Frame.h +++ b/Base/Axis/Frame.h @@ -83,6 +83,7 @@ public: Frame* flat() const; #ifndef SWIG + void setScale(size_t k_axis, Scale* scale); std::vector<const Scale*> clonedAxes() const; private: diff --git a/Base/Types/OwningVector.h b/Base/Types/OwningVector.h index bac97140c22896f1944a71999f2b99172e91928d..ca8e04b40c2614adde7fa2389e2e2d38c6b470fc 100644 --- a/Base/Types/OwningVector.h +++ b/Base/Types/OwningVector.h @@ -18,6 +18,7 @@ #ifndef BORNAGAIN_BASE_TYPES_OWNINGVECTOR_H #define BORNAGAIN_BASE_TYPES_OWNINGVECTOR_H +#include "Base/Util/Assert.h" #include <cstddef> #include <utility> #include <vector> @@ -45,9 +46,6 @@ public: OwningVector& operator=(OwningVector&& other) = default; void reserve(size_t n) { m_v.reserve(n); } - void emplace_back(T* e) { m_v.emplace_back(e); } - void insert_at(size_t index, T* e) { m_v.insert(m_v.begin() + index, e); } - void clear() { for (T* e : *this) @@ -82,6 +80,15 @@ public: m_v.erase(m_v.begin() + i); return result; } + void emplace_back(T* e) { m_v.emplace_back(e); } + void insert_at(size_t i, T* e) { m_v.insert(m_v.begin() + i, e); } + void replace_at(size_t i, T* e) + { + ASSERT(i < m_v.size()); + delete m_v[i]; + m_v[i] = e; + } + T* release_back() { diff --git a/Device/Data/Datafield.cpp b/Device/Data/Datafield.cpp index 08038dc68f1140db86514f46b4784b73a4334790..e1429ba1347a32beb38748eed8f183db1899a7d0 100644 --- a/Device/Data/Datafield.cpp +++ b/Device/Data/Datafield.cpp @@ -255,6 +255,7 @@ double Datafield::minVal() const Datafield* Datafield::crop(double xmin, double ymin, double xmax, double ymax) const { + ASSERT(false); // needs renovation, similar to Datafield::crop(double xmin, double xmax) const auto xclipped = std::make_unique<Scale>(xAxis().clipped(xmin, xmax)); const auto yclipped = std::make_unique<Scale>(yAxis().clipped(ymin, ymax)); @@ -271,16 +272,30 @@ Datafield* Datafield::crop(double xmin, double ymin, double xmax, double ymax) c Datafield* Datafield::crop(double xmin, double xmax) const { - const auto xclipped = std::make_unique<Scale>(xAxis().clipped(xmin, xmax)); + std::vector<Bin1D> outbins; + for (size_t i = 0; i < xAxis().size(); ++i) { + const double x = xAxis().binCenter(i); + if (xmin <= x && x <= xmax) + outbins.push_back(xAxis().bin(i)); + } - std::vector<double> out(size()); - size_t iout = 0; - for (size_t i = 0; i < size(); ++i) { + auto* xclipped = new Scale(xAxis().axisLabel(), outbins); + + const size_t N = size(); + std::vector<double> out; + std::vector<double> errout; + for (size_t i = 0; i < N; ++i) { const double x = frame().projectedCoord(i, 0); - if (xclipped->rangeComprises(x)) - out[iout++] = m_values[i]; + if (xmin <= x && x <= xmax) { + out.push_back(m_values[i]); + if (hasErrorSigmas()) + errout.push_back(m_errSigmas[i]); + } } - return new Datafield(frame().clone(), out); + Frame* outframe = frame().clone(); + outframe->setScale(0, xclipped); + ASSERT(outframe->xAxis().size() == out.size()); + return new Datafield(outframe, out, errout); } #ifdef BORNAGAIN_PYTHON diff --git a/Device/IO/ReadReflectometry.cpp b/Device/IO/ReadReflectometry.cpp index 71343ca33773993265584e7244fafc7c5cb90a57..4cf7920691057b290cf9e2da94cad0f059706796 100644 --- a/Device/IO/ReadReflectometry.cpp +++ b/Device/IO/ReadReflectometry.cpp @@ -69,7 +69,7 @@ Datafield* Util::RW::readReflectometryTable(std::istream& s, const ImportSetting double fac = 1.; Coordinate outCoord = p.xCoord; if (outCoord.unit() == "1/angstrom") { - fac = 0.1; + fac = 10; outCoord = {outCoord.name(), "1/nm"}; } else if (outCoord.unit() == "deg") { fac = pi / 180.; diff --git a/GUI/Model/Model/ParameterTreeUtil.cpp b/GUI/Model/Model/ParameterTreeUtil.cpp index 9c3e106882c749c243704c291be6b19f8862c443..54671288089ea0670d2563fb1ea9c568ce046d26 100644 --- a/GUI/Model/Model/ParameterTreeUtil.cpp +++ b/GUI/Model/Model/ParameterTreeUtil.cpp @@ -43,7 +43,7 @@ QString labelWithUnit(const QString& label, variant<QString, Unit> unit) : unitAsString(std::get<Unit>(unit)); if (!s.isEmpty()) - return label + " [" + s + "]"; + return label + " (" + s + ")"; return label; } diff --git a/GUI/View/MaterialEditor/MaterialEditorModel.cpp b/GUI/View/MaterialEditor/MaterialEditorModel.cpp index 34138a5ca9f51b20e3f21eda2fce19a1c9f9ac3a..3714fa455d6cf19e914b48bcde28053ed5f3e077 100644 --- a/GUI/View/MaterialEditor/MaterialEditorModel.cpp +++ b/GUI/View/MaterialEditor/MaterialEditorModel.cpp @@ -48,7 +48,7 @@ QVariant MaterialEditorModel::headerData(int section, Qt::Orientation /*orientat case PARAMETERS: return "Material parameters"; case MAGNETIZATION: - return "Magnetization [A/m]"; + return "Magnetization (A/m)"; default: return {}; } diff --git a/GUI/View/Numeric/NumWidgetUtil.cpp b/GUI/View/Numeric/NumWidgetUtil.cpp index 68110dd28bad3d91bb07ddef5f0896571c4a5c92..0be3617e5fed7ec0e70978a04305c5f4d9fc1b72 100644 --- a/GUI/View/Numeric/NumWidgetUtil.cpp +++ b/GUI/View/Numeric/NumWidgetUtil.cpp @@ -44,7 +44,7 @@ QString GUI::Util::labelWithUnit(const QString& label, variant<QString, Unit> un const QString s = std::holds_alternative<QString>(unit) ? std::get<QString>(unit) : unitAsString(std::get<Unit>(unit)); if (!s.isEmpty()) - return label + " [" + s + "]"; + return label + " (" + s + ")"; return label; } diff --git a/GUI/View/SampleDesigner/LayerEditorUtil.cpp b/GUI/View/SampleDesigner/LayerEditorUtil.cpp index 2667f1380b84c16f66d3dc6c08ec5db59abaa70a..dfb442e5874b0917f480390bb4540f6e3da02f28 100644 --- a/GUI/View/SampleDesigner/LayerEditorUtil.cpp +++ b/GUI/View/SampleDesigner/LayerEditorUtil.cpp @@ -46,7 +46,7 @@ void updateLabelUnit(QLabel* label, const QString& unit) text.chop(1); if (!unit.isEmpty()) - text += " [" + unit + "]"; + text += " (" + unit + ")"; if (hasColon) text += ":"; label->setText(text); diff --git a/auto/Examples/fit/specular/Honeycomb_fit.py b/auto/Examples/fit/specular/Honeycomb_fit.py index 13020d2e508b3cded972e011c84ac6008e3e0b8e..9a9a01df3d491da0885dbd9cb03280343d79e4f1 100755 --- a/auto/Examples/fit/specular/Honeycomb_fit.py +++ b/auto/Examples/fit/specular/Honeycomb_fit.py @@ -139,11 +139,11 @@ def plot(q, rs, exps, shifts, labels): ax.set_yscale('log') plt.legend() - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("q (1/nm)") plt.ylabel("R") plt.tight_layout() - plt.close() + #plt.close() def plot_sld_profile(P): @@ -159,12 +159,12 @@ def plot_sld_profile(P): plt.plot(z_150p, np.real(sld_150p)*1e6, label=r"150K $+$") plt.plot(z_150m, np.real(sld_150m)*1e6, label=r"150K $-$") - plt.xlabel(r"$z$ [A]") + plt.xlabel(r"$z (\AA)$") plt.ylabel(r"$\delta(z) \cdot 10^6$") plt.legend() plt.tight_layout() - plt.close() + #plt.close() #################################################################### # Main @@ -181,18 +181,6 @@ if __name__ == '__main__': "t_Py2": (56, 46, 66), "t_Py1": (56, 46, 66), "t_SiO2": (22, 15, 29), - "sld_PyOx_real": (1.995, 1.92, 2.07), - "sld_Py2_real": (5, 4.7, 5.3), - "sld_Py1_real": (4.62, 4.32, 4.92), - "rPyOx": (27, 15, 35), - "rPy2": (12, 2, 20), - "rPy1": (12, 2, 20), - "rSiO2": (15, 5, 25), - "rSi": (15, 5, 25), - "msld_PyOx": (0.25, 0, 1), - "msld_Py2": (0.63, 0, 1), - "msld_Py1": (0.64, 0, 1), - "ms150": (1.05, 1.0, 1.1), } # For fixed parameters, bounds are ignored. We leave them here just @@ -206,6 +194,19 @@ if __name__ == '__main__': "sld_SiO2_real": (3.47, 3, 4), "sld_Si_real": (2.0704, 2, 3), "dq": (0.018, 0, 0.1), + # Start by moving the following back to startPnB: + "sld_PyOx_real": (1.995, 1.92, 2.07), + "sld_Py2_real": (5, 4.7, 5.3), + "sld_Py1_real": (4.62, 4.32, 4.92), + "rPyOx": (27, 15, 35), + "rPy2": (12, 2, 20), + "rPy1": (12, 2, 20), + "rSiO2": (15, 5, 25), + "rSi": (15, 5, 25), + "msld_PyOx": (0.25, 0, 1), + "msld_Py2": (0.63, 0, 1), + "msld_Py1": (0.64, 0, 1), + "ms150": (1.05, 1.0, 1.1), } fixedP = {d: v[0] for d, v in fixedPnB.items()} @@ -261,8 +262,8 @@ if __name__ == '__main__': result = scipy.optimize.differential_evolution( objective_function, bounds, - maxiter=500, - popsize=10, + maxiter=5, # for a serious DE fit, choose 500 + popsize=3, # for a serious DE fit, choose 10 tol=1e-2, mutation=(0.5, 1.5), seed=0, diff --git a/auto/Examples/fit/specular/PolarizedSpinAsymmetry.py b/auto/Examples/fit/specular/PolarizedSpinAsymmetry.py index 91f3571438b9c1f013a7101089422ce6b7d8502c..d859c5ea1d5954e5a9c88d36021a46d1b46092f2 100755 --- a/auto/Examples/fit/specular/PolarizedSpinAsymmetry.py +++ b/auto/Examples/fit/specular/PolarizedSpinAsymmetry.py @@ -131,7 +131,7 @@ def plotData(qs, rs, exps, labels, colors): ax.set_yscale('log') plt.legend() - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("q (1/nm)") plt.ylabel("R") plt.tight_layout() @@ -164,7 +164,7 @@ def plotSpinAsymmetry(data_pp, data_mm, q, r_pp, r_mm): plt.gca().set_ylim((-0.3, 0.5)) - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("Q (1/nm)") plt.ylabel("Spin asymmetry") plt.tight_layout() diff --git a/auto/Examples/fit/specular/Pt_layer_fit.py b/auto/Examples/fit/specular/Pt_layer_fit.py index a9b82577a8b3665631eb793b3af5daecdedb1e41..1af4988e7659c3c294d4abd9d0ea38aabf298eee 100755 --- a/auto/Examples/fit/specular/Pt_layer_fit.py +++ b/auto/Examples/fit/specular/Pt_layer_fit.py @@ -47,6 +47,7 @@ def get_simulation(q_axis, P): sample = get_sample(P) scan = ba.QzScan(q_axis) + scan.setIntensity(P["intensity"]) scan.setOffset(P["q_offset"]) distr = ba.DistributionGaussian(0., 1., 25, 4.) @@ -56,44 +57,18 @@ def get_simulation(q_axis, P): return simulation -#################################################################### -# Experimental data -#################################################################### - -def load_data(filename, qmin, qmax): - filepath = os.path.join(datadir, filename) - data = np.genfromtxt(filepath, unpack=True) - - r0 = np.where(data[0] - np.roll(data[0], 1) == 0) - data = np.delete(data, r0, 1) - - data[0] = data[0]/angstrom - data[3] = data[3]/angstrom - - data[1] = data[1] - data[2] = data[2] - - so = np.argsort(data[0]) - - data = data[:, so] - - minIndex = np.argmin(np.abs(data[0] - qmin)) - maxIndex = np.argmin(np.abs(data[0] - qmax)) - - return data[:, minIndex:maxIndex + 1] - #################################################################### # Plotting #################################################################### -def plot(q, r, exp, P): +def plot(q, r, data, P): fig = plt.figure() ax = fig.add_subplot(111) - ax.errorbar(exp[0], - exp[1], - xerr=exp[3], - yerr=exp[2], + ax.errorbar(data.npXcenters(), + data.npArray(), + # xerr=data.xxx, TODO restore + yerr=data.npErrors(), label="R", fmt='.', markersize=1., @@ -104,7 +79,7 @@ def plot(q, r, exp, P): ax.set_yscale('log') - ax.set_xlabel("Q [nm$^{^-1}$]") + ax.set_xlabel("q (1/nm)") ax.set_ylabel("R") y = 0.5 @@ -129,6 +104,7 @@ if __name__ == '__main__': } startPnB = { + "intensity": (1., 0.8, 1.2), "q_offset": (0.01, -0.02, 0.02), "q_res/q": (0.01, 0, 0.02), "t_pt/nm": (50, 45, 55), @@ -143,25 +119,28 @@ if __name__ == '__main__': qmin = 0.18 qmax = 2.4 - - data = load_data("specular/RvsQ_36563_36662.dat.gz", qmin, qmax) - qzs = np.linspace(qmin, qmax, 1500) - # Plot data with initial model: + fpath = os.path.join(datadir, "specular/RvsQ_36563_36662.dat.gz") + flags = ba.ImportSettings1D("q (1/angstrom)", "#", "", 1, 2, 3, 4) + data = ba.readData1D(fpath, ba.csv1D, flags) + + # Initial plot r = get_simulation(qzs, initialP | fixedP).simulate().npArray() plot(qzs, r, data, initialP) - # Fit: + # Restrict data to given q range - Q, R, dR = (data[0], data[1], data[2]) + data = data.crop(qmin, qmax) + + # Fit: fit_objective = ba.FitObjective() fit_objective.setObjectiveMetric("chi2") fit_objective.initPrint(10) - fit_objective.addSimulationAndData( - lambda P: get_simulation(Q, P | fixedP), R, dR, 1) + fit_objective.addFitPair( + lambda P: get_simulation(data.npXcenters(), P | fixedP), data, 1) P = ba.Parameters() for name, p in startPnB.items(): diff --git a/auto/Examples/specular/PolarizedSpinAsymmetry.py b/auto/Examples/specular/PolarizedSpinAsymmetry.py index 91f3571438b9c1f013a7101089422ce6b7d8502c..d859c5ea1d5954e5a9c88d36021a46d1b46092f2 100755 --- a/auto/Examples/specular/PolarizedSpinAsymmetry.py +++ b/auto/Examples/specular/PolarizedSpinAsymmetry.py @@ -131,7 +131,7 @@ def plotData(qs, rs, exps, labels, colors): ax.set_yscale('log') plt.legend() - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("q (1/nm)") plt.ylabel("R") plt.tight_layout() @@ -164,7 +164,7 @@ def plotSpinAsymmetry(data_pp, data_mm, q, r_pp, r_mm): plt.gca().set_ylim((-0.3, 0.5)) - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("Q (1/nm)") plt.ylabel("Spin asymmetry") plt.tight_layout() diff --git a/auto/MiniExamples/fit/specular/Honeycomb_fit.py b/auto/MiniExamples/fit/specular/Honeycomb_fit.py index c6cbc5a32c6241bc1e51acf157c7d9d9460baf22..b07ea2c3d0084de2b9aea5765b77109e7d1a5ac7 100755 --- a/auto/MiniExamples/fit/specular/Honeycomb_fit.py +++ b/auto/MiniExamples/fit/specular/Honeycomb_fit.py @@ -139,11 +139,11 @@ def plot(q, rs, exps, shifts, labels): ax.set_yscale('log') plt.legend() - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("q (1/nm)") plt.ylabel("R") #plt.tight_layout() - #plt.close() + ##plt.close() def plot_sld_profile(P): @@ -159,12 +159,12 @@ def plot_sld_profile(P): plt.plot(z_150p, np.real(sld_150p)*1e6, label=r"150K $+$") plt.plot(z_150m, np.real(sld_150m)*1e6, label=r"150K $-$") - plt.xlabel(r"$z$ [A]") + plt.xlabel(r"$z (\AA)$") plt.ylabel(r"$\delta(z) \cdot 10^6$") plt.legend() #plt.tight_layout() - #plt.close() + ##plt.close() #################################################################### # Main @@ -181,18 +181,6 @@ if __name__ == '__main__': "t_Py2": (56, 46, 66), "t_Py1": (56, 46, 66), "t_SiO2": (22, 15, 29), - "sld_PyOx_real": (1.995, 1.92, 2.07), - "sld_Py2_real": (5, 4.7, 5.3), - "sld_Py1_real": (4.62, 4.32, 4.92), - "rPyOx": (27, 15, 35), - "rPy2": (12, 2, 20), - "rPy1": (12, 2, 20), - "rSiO2": (15, 5, 25), - "rSi": (15, 5, 25), - "msld_PyOx": (0.25, 0, 1), - "msld_Py2": (0.63, 0, 1), - "msld_Py1": (0.64, 0, 1), - "ms150": (1.05, 1.0, 1.1), } # For fixed parameters, bounds are ignored. We leave them here just @@ -206,6 +194,19 @@ if __name__ == '__main__': "sld_SiO2_real": (3.47, 3, 4), "sld_Si_real": (2.0704, 2, 3), "dq": (0.018, 0, 0.1), + # Start by moving the following back to startPnB: + "sld_PyOx_real": (1.995, 1.92, 2.07), + "sld_Py2_real": (5, 4.7, 5.3), + "sld_Py1_real": (4.62, 4.32, 4.92), + "rPyOx": (27, 15, 35), + "rPy2": (12, 2, 20), + "rPy1": (12, 2, 20), + "rSiO2": (15, 5, 25), + "rSi": (15, 5, 25), + "msld_PyOx": (0.25, 0, 1), + "msld_Py2": (0.63, 0, 1), + "msld_Py1": (0.64, 0, 1), + "ms150": (1.05, 1.0, 1.1), } fixedP = {d: v[0] for d, v in fixedPnB.items()} @@ -261,8 +262,8 @@ if __name__ == '__main__': result = scipy.optimize.differential_evolution( objective_function, bounds, - maxiter=2, - popsize=2, + maxiter=2, # for a serious DE fit, choose 500 + popsize=2, # for a serious DE fit, choose 10 tol=1e-2, mutation=(0.5, 1.5), seed=0, diff --git a/auto/MiniExamples/fit/specular/PolarizedSpinAsymmetry.py b/auto/MiniExamples/fit/specular/PolarizedSpinAsymmetry.py index 0123529d57f5d1fbcc58a736a26deb88705e0d01..3185a2719f2c01d1ab3a1ddb56083135a0937efa 100755 --- a/auto/MiniExamples/fit/specular/PolarizedSpinAsymmetry.py +++ b/auto/MiniExamples/fit/specular/PolarizedSpinAsymmetry.py @@ -131,7 +131,7 @@ def plotData(qs, rs, exps, labels, colors): ax.set_yscale('log') plt.legend() - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("q (1/nm)") plt.ylabel("R") plt.tight_layout() @@ -164,7 +164,7 @@ def plotSpinAsymmetry(data_pp, data_mm, q, r_pp, r_mm): plt.gca().set_ylim((-0.3, 0.5)) - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("Q (1/nm)") plt.ylabel("Spin asymmetry") plt.tight_layout() diff --git a/auto/MiniExamples/fit/specular/Pt_layer_fit.py b/auto/MiniExamples/fit/specular/Pt_layer_fit.py index b64d78e7e0813cd56a865fef7c1bfc5316ee46e1..6370c896f527e8ca7534253bfb0a0ecf3f1f16b4 100755 --- a/auto/MiniExamples/fit/specular/Pt_layer_fit.py +++ b/auto/MiniExamples/fit/specular/Pt_layer_fit.py @@ -47,6 +47,7 @@ def get_simulation(q_axis, P): sample = get_sample(P) scan = ba.QzScan(q_axis) + scan.setIntensity(P["intensity"]) scan.setOffset(P["q_offset"]) distr = ba.DistributionGaussian(0., 1., 25, 4.) @@ -56,44 +57,18 @@ def get_simulation(q_axis, P): return simulation -#################################################################### -# Experimental data -#################################################################### - -def load_data(filename, qmin, qmax): - filepath = os.path.join(datadir, filename) - data = np.genfromtxt(filepath, unpack=True) - - r0 = np.where(data[0] - np.roll(data[0], 1) == 0) - data = np.delete(data, r0, 1) - - data[0] = data[0]/angstrom - data[3] = data[3]/angstrom - - data[1] = data[1] - data[2] = data[2] - - so = np.argsort(data[0]) - - data = data[:, so] - - minIndex = np.argmin(np.abs(data[0] - qmin)) - maxIndex = np.argmin(np.abs(data[0] - qmax)) - - return data[:, minIndex:maxIndex + 1] - #################################################################### # Plotting #################################################################### -def plot(q, r, exp, P): +def plot(q, r, data, P): fig = plt.figure() ax = fig.add_subplot(111) - ax.errorbar(exp[0], - exp[1], - xerr=exp[3], - yerr=exp[2], + ax.errorbar(data.npXcenters(), + data.npArray(), + # xerr=data.xxx, TODO restore + yerr=data.npErrors(), label="R", fmt='.', markersize=1., @@ -104,7 +79,7 @@ def plot(q, r, exp, P): ax.set_yscale('log') - ax.set_xlabel("Q [nm$^{^-1}$]") + ax.set_xlabel("q (1/nm)") ax.set_ylabel("R") y = 0.5 @@ -129,6 +104,7 @@ if __name__ == '__main__': } startPnB = { + "intensity": (1., 0.8, 1.2), "q_offset": (0.01, -0.02, 0.02), "q_res/q": (0.01, 0, 0.02), "t_pt/nm": (50, 45, 55), @@ -143,25 +119,28 @@ if __name__ == '__main__': qmin = 0.18 qmax = 2.4 - - data = load_data("specular/RvsQ_36563_36662.dat.gz", qmin, qmax) - qzs = np.linspace(qmin, qmax, 1500) - # Plot data with initial model: + fpath = os.path.join(datadir, "specular/RvsQ_36563_36662.dat.gz") + flags = ba.ImportSettings1D("q (1/angstrom)", "#", "", 1, 2, 3, 4) + data = ba.readData1D(fpath, ba.csv1D, flags) + + # Initial plot r = get_simulation(qzs, initialP | fixedP).simulate().npArray() plot(qzs, r, data, initialP) - # Fit: + # Restrict data to given q range - Q, R, dR = (data[0], data[1], data[2]) + data = data.crop(qmin, qmax) + + # Fit: fit_objective = ba.FitObjective() fit_objective.setObjectiveMetric("chi2") fit_objective.initPrint(10) - fit_objective.addSimulationAndData( - lambda P: get_simulation(Q, P | fixedP), R, dR, 1) + fit_objective.addFitPair( + lambda P: get_simulation(data.npXcenters(), P | fixedP), data, 1) P = ba.Parameters() for name, p in startPnB.items(): diff --git a/auto/MiniExamples/specular/PolarizedSpinAsymmetry.py b/auto/MiniExamples/specular/PolarizedSpinAsymmetry.py index 0123529d57f5d1fbcc58a736a26deb88705e0d01..3185a2719f2c01d1ab3a1ddb56083135a0937efa 100755 --- a/auto/MiniExamples/specular/PolarizedSpinAsymmetry.py +++ b/auto/MiniExamples/specular/PolarizedSpinAsymmetry.py @@ -131,7 +131,7 @@ def plotData(qs, rs, exps, labels, colors): ax.set_yscale('log') plt.legend() - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("q (1/nm)") plt.ylabel("R") plt.tight_layout() @@ -164,7 +164,7 @@ def plotSpinAsymmetry(data_pp, data_mm, q, r_pp, r_mm): plt.gca().set_ylim((-0.3, 0.5)) - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("Q (1/nm)") plt.ylabel("Spin asymmetry") plt.tight_layout() diff --git a/rawEx/fit/specular/Honeycomb_fit.py b/rawEx/fit/specular/Honeycomb_fit.py index 7135c1efc2fb8db6308b18870cea0f0c330716b6..dcb28876ff26f0f90edfd084568a425952362758 100755 --- a/rawEx/fit/specular/Honeycomb_fit.py +++ b/rawEx/fit/specular/Honeycomb_fit.py @@ -139,11 +139,11 @@ def plot(q, rs, exps, shifts, labels): ax.set_yscale('log') plt.legend() - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("q (1/nm)") plt.ylabel("R") <%= sm ? "#" : "" %>plt.tight_layout() - <%= sm ? "#" : "" %>plt.close() + #<%= sm ? "#" : "" %>plt.close() def plot_sld_profile(P): @@ -159,12 +159,12 @@ def plot_sld_profile(P): plt.plot(z_150p, np.real(sld_150p)*1e6, label=r"150K $+$") plt.plot(z_150m, np.real(sld_150m)*1e6, label=r"150K $-$") - plt.xlabel(r"$z$ [A]") + plt.xlabel(r"$z (\AA)$") plt.ylabel(r"$\delta(z) \cdot 10^6$") plt.legend() <%= sm ? "#" : "" %>plt.tight_layout() - <%= sm ? "#" : "" %>plt.close() + #<%= sm ? "#" : "" %>plt.close() #################################################################### # Main @@ -181,18 +181,6 @@ if __name__ == '__main__': "t_Py2": (56, 46, 66), "t_Py1": (56, 46, 66), "t_SiO2": (22, 15, 29), - "sld_PyOx_real": (1.995, 1.92, 2.07), - "sld_Py2_real": (5, 4.7, 5.3), - "sld_Py1_real": (4.62, 4.32, 4.92), - "rPyOx": (27, 15, 35), - "rPy2": (12, 2, 20), - "rPy1": (12, 2, 20), - "rSiO2": (15, 5, 25), - "rSi": (15, 5, 25), - "msld_PyOx": (0.25, 0, 1), - "msld_Py2": (0.63, 0, 1), - "msld_Py1": (0.64, 0, 1), - "ms150": (1.05, 1.0, 1.1), } # For fixed parameters, bounds are ignored. We leave them here just @@ -206,6 +194,19 @@ if __name__ == '__main__': "sld_SiO2_real": (3.47, 3, 4), "sld_Si_real": (2.0704, 2, 3), "dq": (0.018, 0, 0.1), + # Start by moving the following back to startPnB: + "sld_PyOx_real": (1.995, 1.92, 2.07), + "sld_Py2_real": (5, 4.7, 5.3), + "sld_Py1_real": (4.62, 4.32, 4.92), + "rPyOx": (27, 15, 35), + "rPy2": (12, 2, 20), + "rPy1": (12, 2, 20), + "rSiO2": (15, 5, 25), + "rSi": (15, 5, 25), + "msld_PyOx": (0.25, 0, 1), + "msld_Py2": (0.63, 0, 1), + "msld_Py1": (0.64, 0, 1), + "ms150": (1.05, 1.0, 1.1), } fixedP = {d: v[0] for d, v in fixedPnB.items()} @@ -261,8 +262,8 @@ if __name__ == '__main__': result = scipy.optimize.differential_evolution( objective_function, bounds, - maxiter=<%= sm ? 2 : 500 %>, - popsize=<%= sm ? 2 : 10 %>, + maxiter=<%= sm ? 2 : 5 %>, # for a serious DE fit, choose 500 + popsize=<%= sm ? 2 : 3 %>, # for a serious DE fit, choose 10 tol=1e-2, mutation=(0.5, 1.5), seed=0, diff --git a/rawEx/fit/specular/Pt_layer_fit.py b/rawEx/fit/specular/Pt_layer_fit.py index 0d0b68d43839ac197d3c39e6b4e24ecd82905332..cc9200f315465156efe249e1e99079881dac4730 100755 --- a/rawEx/fit/specular/Pt_layer_fit.py +++ b/rawEx/fit/specular/Pt_layer_fit.py @@ -47,6 +47,7 @@ def get_simulation(q_axis, P): sample = get_sample(P) scan = ba.QzScan(q_axis) + scan.setIntensity(P["intensity"]) scan.setOffset(P["q_offset"]) distr = ba.DistributionGaussian(0., 1., 25, 4.) @@ -56,44 +57,18 @@ def get_simulation(q_axis, P): return simulation -#################################################################### -# Experimental data -#################################################################### - -def load_data(filename, qmin, qmax): - filepath = os.path.join(datadir, filename) - data = np.genfromtxt(filepath, unpack=True) - - r0 = np.where(data[0] - np.roll(data[0], 1) == 0) - data = np.delete(data, r0, 1) - - data[0] = data[0]/angstrom - data[3] = data[3]/angstrom - - data[1] = data[1] - data[2] = data[2] - - so = np.argsort(data[0]) - - data = data[:, so] - - minIndex = np.argmin(np.abs(data[0] - qmin)) - maxIndex = np.argmin(np.abs(data[0] - qmax)) - - return data[:, minIndex:maxIndex + 1] - #################################################################### # Plotting #################################################################### -def plot(q, r, exp, P): +def plot(q, r, data, P): fig = plt.figure() ax = fig.add_subplot(111) - ax.errorbar(exp[0], - exp[1], - xerr=exp[3], - yerr=exp[2], + ax.errorbar(data.npXcenters(), + data.npArray(), + # xerr=data.xxx, TODO restore + yerr=data.npErrors(), label="R", fmt='.', markersize=1., @@ -104,7 +79,7 @@ def plot(q, r, exp, P): ax.set_yscale('log') - ax.set_xlabel("Q [nm$^{^-1}$]") + ax.set_xlabel("q (1/nm)") ax.set_ylabel("R") y = 0.5 @@ -129,6 +104,7 @@ if __name__ == '__main__': } startPnB = { + "intensity": (1., 0.8, 1.2), "q_offset": (0.01, -0.02, 0.02), "q_res/q": (0.01, 0, 0.02), "t_pt/nm": (50, 45, 55), @@ -143,25 +119,28 @@ if __name__ == '__main__': qmin = 0.18 qmax = 2.4 - - data = load_data("specular/RvsQ_36563_36662.dat.gz", qmin, qmax) - qzs = np.linspace(qmin, qmax, 1500) - # Plot data with initial model: + fpath = os.path.join(datadir, "specular/RvsQ_36563_36662.dat.gz") + flags = ba.ImportSettings1D("q (1/angstrom)", "#", "", 1, 2, 3, 4) + data = ba.readData1D(fpath, ba.csv1D, flags) + + # Initial plot r = get_simulation(qzs, initialP | fixedP).simulate().npArray() plot(qzs, r, data, initialP) - # Fit: + # Restrict data to given q range - Q, R, dR = (data[0], data[1], data[2]) + data = data.crop(qmin, qmax) + + # Fit: fit_objective = ba.FitObjective() fit_objective.setObjectiveMetric("chi2") fit_objective.initPrint(10) - fit_objective.addSimulationAndData( - lambda P: get_simulation(Q, P | fixedP), R, dR, 1) + fit_objective.addFitPair( + lambda P: get_simulation(data.npXcenters(), P | fixedP), data, 1) P = ba.Parameters() for name, p in startPnB.items(): diff --git a/rawEx/specular/PolarizedSpinAsymmetry.py b/rawEx/specular/PolarizedSpinAsymmetry.py index 9378c689fd107345d13dfeaf1b09918ce3625511..cba1b8ac600aa6455fbf3a1639fd6b77212d787f 100755 --- a/rawEx/specular/PolarizedSpinAsymmetry.py +++ b/rawEx/specular/PolarizedSpinAsymmetry.py @@ -131,7 +131,7 @@ def plotData(qs, rs, exps, labels, colors): ax.set_yscale('log') plt.legend() - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("q (1/nm)") plt.ylabel("R") plt.tight_layout() @@ -164,7 +164,7 @@ def plotSpinAsymmetry(data_pp, data_mm, q, r_pp, r_mm): plt.gca().set_ylim((-0.3, 0.5)) - plt.xlabel("Q [nm${}^{-1}$]") + plt.xlabel("Q (1/nm)") plt.ylabel("Spin asymmetry") plt.tight_layout()