VEXPController.cpp 9.71 KB
Newer Older
legoc's avatar
legoc committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Nomad Instrument Control Software
 *
 * Copyright 2011 Institut Laue-Langevin
 *
 * Licensed under the EUPL, Version 1.1 only (the "License");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://joinup.ec.europa.eu/software/page/eupl
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the Licence is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Licence for the specific language governing permissions and
 * limitations under the Licence.
 */

#include "VEXPController.h"
#include "controllers/common/family/Families.h"
ics's avatar
ics committed
21
22
23
24
25
#include "contrib/rapidjson/document.h"
#include "contrib/rapidjson/reader.h"
#include "contrib/rapidjson/writer.h"
#include "contrib/rapidjson/stringbuffer.h"
#include "contrib/rapidjson/prettywriter.h"
legoc's avatar
legoc committed
26

legoc's avatar
legoc committed
27
using namespace boost;
ics's avatar
ics committed
28
using namespace std;
legoc's avatar
legoc committed
29

legoc's avatar
legoc committed
30
31
32
33
34
namespace vexp {

const string VEXPController::TYPE = "vexp_controller";

VEXPController::VEXPController(const string& name) :
35
	ExperimentController(name) {
36

legoc's avatar
legoc committed
37
38
	setFamily(family::HIDDEN);

legoc's avatar
legoc committed
39
40
41
42
43
44
45
46
47
48
49
50
	as.init(this, NOSAVE, "as");
	bs.init(this, NOSAVE, "bs");
	cs.init(this, NOSAVE, "cs");
	aa.init(this, NOSAVE, "aa");
	bb.init(this, NOSAVE, "bb");
	cc.init(this, NOSAVE, "cc");
	ax.init(this, NOSAVE, "ax");
	ay.init(this, NOSAVE, "ay");
	az.init(this, NOSAVE, "az");
	bx.init(this, NOSAVE, "bx");
	by.init(this, NOSAVE, "by");
	bz.init(this, NOSAVE, "bz");
legoc's avatar
legoc committed
51
52
53
	u.init(this, NOSAVE, "Umatrix");
	b.init(this, NOSAVE, "Bmatrix");

legoc's avatar
legoc committed
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
	qh.init(this, NOSAVE, "qh");
	qk.init(this, NOSAVE, "qk");
	ql.init(this, NOSAVE, "ql");
	en.init(this, NOSAVE, "en");
	qm.init(this, NOSAVE, "qm");

	ki.init(this, NOSAVE, "ki");
	kf.init(this, NOSAVE, "kf");

	a1.init(this, NOSAVE, "a1");
	a2.init(this, NOSAVE, "a2");
	a3.init(this, NOSAVE, "a3");
	a4.init(this, NOSAVE, "a4");
	a5.init(this, NOSAVE, "a5");
	a6.init(this, NOSAVE, "a6");

ics's avatar
ics committed
70
71
72
73
74
75
76
77
78
	calcvalues.init(this, NOSAVE, "calcvalues");

	calca1.init(this, NOSAVE, "calca1");
	calca2.init(this, NOSAVE, "calca2");
	calca3.init(this, NOSAVE, "calca3");
	calca4.init(this, NOSAVE, "calca4");
	calca5.init(this, NOSAVE, "calca5");
	calca6.init(this, NOSAVE, "calca6");

79
	calculationStatus.init(this, NOSAVE, "calculation_status");
legoc's avatar
legoc committed
80
	errorMessage.init(this, NOSAVE, "error_message");
81
	moveModel.init(this, SAVE, "move_model");
legoc's avatar
legoc committed
82
83
84
85
86
87

	tasSettings.init(this, "tas_settings");
	sample.init(this, "sample");
	scattering.init(this, "scattering");
	incidentBeam.init(this, "incident_beam");
	scatteredBeam.init(this, "scattered_beam");
legoc's avatar
legoc committed
88
89
90
91
92
93
94
95
96
97

	a1Controller.init(this, "A1");
	a2Controller.init(this, "A2");
	a3Controller.init(this, "A3");
	a4Controller.init(this, "A4");
	a5Controller.init(this, "A5");
	a6Controller.init(this, "A6");
}

VEXPController::VEXPController(const VEXPController& controller) :
98
	ExperimentController(controller) {
legoc's avatar
legoc committed
99
100
101
}

VEXPController::~VEXPController() {
102
}
legoc's avatar
legoc committed
103
104
105
106

void VEXPController::updateUMatrix() {
	u.update(sample->uRef());
	u.setSize(sample->uRef.getSize());
107
	u.sendEvent();
legoc's avatar
legoc committed
108
109
110
111
112
}

void VEXPController::updateBMatrix() {
	b.update(tasSettings->b());
	b.setSize(tasSettings->b.getSize());
113
	b.sendEvent();
legoc's avatar
legoc committed
114
115
}

ics's avatar
ics committed
116
void VEXPController::refreshCalcParameters(const std::string& value) {
117

118
	//cout << "refreshCalcParameters " << value << endl;
119

ics's avatar
ics committed
120
121
122
	// Parse the values.
	rapidjson::Document document;
	document.Parse(value.c_str());
123

ics's avatar
ics committed
124
125
126
127
128
	rapidjson::Value& ki = document["ki"];
	rapidjson::Value& kf = document["kf"];
	rapidjson::Value& qh = document["qh"];
	rapidjson::Value& qk = document["qk"];
	rapidjson::Value& ql = document["ql"];
129

ics's avatar
ics committed
130
131
	// Calculate the angles and the status.
	calculate(ki.GetDouble(), kf.GetDouble(), qh.GetDouble(), qk.GetDouble(), ql.GetDouble());
132
133
}

134
double toDouble(double value) {
ics's avatar
ics committed
135

136
137
138
	if (isinf(value)) {
		return numeric_limits<double>::max();
	}
ics's avatar
ics committed
139

140
141
142
	if (isnan(value)) {
		return 0.0;
	}
legoc's avatar
legoc committed
143

144
145
	return value;
}
ics's avatar
ics committed
146

147
void VEXPController::refreshFloat64Property(SimpleProperty<float64>& property, float64 value) {
legoc's avatar
legoc committed
148
149
150

	// Update the value.
	property = value;
legoc's avatar
legoc committed
151
152
}

153
154
155
156
157
158
159
160
void VEXPController::refreshFloat64PropertyToMoveModel(SimpleProperty<float64>& property, float64 value) {

	// Update the value only in case moveModel is true.
	if (moveModel()) {
		property = value;
	}
}

ics's avatar
ics committed
161
void VEXPController::updateProperties() {
legoc's avatar
legoc committed
162

legoc's avatar
legoc committed
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
	// Copy the values.
	as.update(tasSettings->as());
	bs.update(tasSettings->bs());
	cs.update(tasSettings->cs());
	aa.update(tasSettings->aa());
	bb.update(tasSettings->bb());
	cc.update(tasSettings->cc());
	ax.update(tasSettings->ax());
	ay.update(tasSettings->ay());
	az.update(tasSettings->az());
	bx.update(tasSettings->bx());
	by.update(tasSettings->by());
	bz.update(tasSettings->bz());

	updateUMatrix();
	updateBMatrix();

ics's avatar
ics committed
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	qh.update(scattering->qh());
	qk.update(scattering->qk());
	ql.update(scattering->ql());
	en.update(scattering->en());
	qm.update(scattering->qm());

	ki.update(incidentBeam->ki());
	kf.update(scatteredBeam->kf());

	a1.update(a1Controller->position());
	a2.update(a2Controller->position());
	a3.update(a3Controller->position());
	a4.update(a4Controller->position());
	a5.update(a5Controller->position());
	a6.update(a6Controller->position());
}

void VEXPController::postConfiguration() {
198
199
200
201
202
203
204
205
206
207
208
209
210
211

	// Register the property updaters.
	registerPropertyCopierByUpdate(tasSettings->as, as);
	registerPropertyCopierByUpdate(tasSettings->bs, bs);
	registerPropertyCopierByUpdate(tasSettings->cs, cs);
	registerPropertyCopierByUpdate(tasSettings->aa, aa);
	registerPropertyCopierByUpdate(tasSettings->bb, bb);
	registerPropertyCopierByUpdate(tasSettings->cc, cc);
	registerPropertyCopierByUpdate(tasSettings->ax, ax);
	registerPropertyCopierByUpdate(tasSettings->ay, ay);
	registerPropertyCopierByUpdate(tasSettings->az, az);
	registerPropertyCopierByUpdate(tasSettings->bx, bx);
	registerPropertyCopierByUpdate(tasSettings->by, by);
	registerPropertyCopierByUpdate(tasSettings->bz, bz);
legoc's avatar
legoc committed
212
213
214
215

	registerUpdater(sample->uRef, &VEXPController::updateUMatrix, this);
	registerUpdater(sample->b, &VEXPController::updateBMatrix, this);

ics's avatar
ics committed
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
	registerPropertyCopierByUpdate(scattering->qh, qh);
	registerPropertyCopierByUpdate(scattering->qk, qk);
	registerPropertyCopierByUpdate(scattering->ql, ql);
	registerPropertyCopierByUpdate(scattering->en, en);
	registerPropertyCopierByUpdate(scattering->qm, qm);

	registerPropertyCopierByUpdate(incidentBeam->ki, ki);
	registerPropertyCopierByUpdate(scatteredBeam->kf, kf);

	registerPropertyCopierByUpdate(a1Controller->position, a1);
	registerPropertyCopierByUpdate(a2Controller->position, a2);
	registerPropertyCopierByUpdate(a3Controller->position, a3);
	registerPropertyCopierByUpdate(a4Controller->position, a4);
	registerPropertyCopierByUpdate(a5Controller->position, a5);
	registerPropertyCopierByUpdate(a6Controller->position, a6);


	// To calculate the angles.
	registerRefresher(calcvalues, &VEXPController::refreshCalcParameters, this);

	// To move the model.
237
238
239
240
241
242
	registerRefresher(calca1, &VEXPController::refreshFloat64PropertyToMoveModel, this, a1Controller->position);
	registerRefresher(calca2, &VEXPController::refreshFloat64PropertyToMoveModel, this, a2Controller->position);
	registerRefresher(calca3, &VEXPController::refreshFloat64PropertyToMoveModel, this, a3Controller->position);
	registerRefresher(calca4, &VEXPController::refreshFloat64PropertyToMoveModel, this, a4Controller->position);
	registerRefresher(calca5, &VEXPController::refreshFloat64PropertyToMoveModel, this, a5Controller->position);
	registerRefresher(calca6, &VEXPController::refreshFloat64PropertyToMoveModel, this, a6Controller->position);
ics's avatar
ics committed
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

	updateProperties();
}

void VEXPController::calculate(float64 ki, float64 kf, float64 qh, float64 qk, float64 ql) {

	// Reset status.
	calculationStatus.setIdle();

	// Ki.
	incidentBeam->calcki = ki;

	// calca1, calca2, calcStatus are calculated.
	incidentBeam->calculate(tas::Beam::K_MODE);

258
259
	calca1 = toDouble(incidentBeam->calca1());
	calca2 = toDouble(incidentBeam->calca2());
ics's avatar
ics committed
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

	cout << "calc A1 " << calca1() << endl;
	cout << "calc A2 " << calca2() << endl;
	cout << "calc A3 " << calca3() << endl;
	cout << "calc A4 " << calca4() << endl;
	cout << "calc A5 " << calca5() << endl;
	cout << "calc A6 " << calca6() << endl << endl;

	// Manage the status.
	if (incidentBeam->calcStatus.isError()) {
		calculationStatus.setError();
	}
	else if (incidentBeam->calcStatus.isWarning()) {
		calculationStatus.setWarning();
	}

	//cout << "Ki -> status " << incidentBeam->calcStatus() << endl;

	// Kf.
	scatteredBeam->calckf = kf;

	// calca1, calca2, calcStatus are calculated.
	scatteredBeam->calculate(tas::Beam::K_MODE);

284
285
	calca5 = toDouble(scatteredBeam->calca5());
	calca6 = toDouble(scatteredBeam->calca6());
ics's avatar
ics committed
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

	// Manage the status.
	if (scatteredBeam->calcStatus.isError()) {
		calculationStatus.setError();
	}
	else if (scatteredBeam->calcStatus.isWarning() && !calculationStatus.isError()) {
		calculationStatus.setWarning();
	}

	//cout << "Kf -> status " << scatteredBeam->calcStatus() << endl;

	// Q.
	scattering->calcqh = qh;
	scattering->calcqk = qk;
	scattering->calcql = ql;
	scattering->calcen = 2.072 * (ki * ki - kf * kf);
	scattering->calcki = ki;
	scattering->calckf = kf;

	// Calculate by fixing Ki.
	scattering->calculate(tas::Beam::K_MODE, 1);

308
309
	calca3 = toDouble(scattering->calca3());
	calca4 = toDouble(scattering->calca4());
ics's avatar
ics committed
310

311
312
313
314
315
316
//	cout << "calc A1 " << calca1() << endl;
//	cout << "calc A2 " << calca2() << endl;
//	cout << "calc A3 " << calca3() << endl;
//	cout << "calc A4 " << calca4() << endl;
//	cout << "calc A5 " << calca5() << endl;
//	cout << "calc A6 " << calca6() << endl << endl;
ics's avatar
ics committed
317
318
319
320
321
322
323
324
325
326
327

	// Manage the status.
	if (scattering->calcStatus.isError()) {
		calculationStatus.setError();
	}
	else if (scattering->calcStatus.isWarning() && !calculationStatus.isError()) {
		calculationStatus.setWarning();
		cerr << "Warning: Calculated Kf are different" << endl;
	}

	//cout << "Q -> status " << scattering->calcStatus() << endl;
legoc's avatar
legoc committed
328
329
330
}

}