VEXPController.cpp 10.6 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
	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");
59
	fx.init(this, NOSAVE, "fx");
60
	ss.init(this, NOSAVE, "ss");
legoc's avatar
legoc committed
61
62
63
64
65
66
67

	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");
yannick legoc's avatar
yannick legoc committed
68
	a3p.init(this, NOSAVE, "a3p");
legoc's avatar
legoc committed
69
70
71
72
	a4.init(this, NOSAVE, "a4");
	a5.init(this, NOSAVE, "a5");
	a6.init(this, NOSAVE, "a6");

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

	calca1.init(this, NOSAVE, "calca1");
	calca2.init(this, NOSAVE, "calca2");
	calca3.init(this, NOSAVE, "calca3");
yannick legoc's avatar
yannick legoc committed
78
	calca3p.init(this, NOSAVE, "calca3p");
ics's avatar
ics committed
79
80
81
82
	calca4.init(this, NOSAVE, "calca4");
	calca5.init(this, NOSAVE, "calca5");
	calca6.init(this, NOSAVE, "calca6");

83
	calculationStatus.init(this, NOSAVE, "calculation_status");
84
85
	calculationError.init(this, NOSAVE, "calculation_error");

legoc's avatar
legoc committed
86
	errorMessage.init(this, NOSAVE, "error_message");
87
	moveModel.init(this, SAVE, "move_model");
legoc's avatar
legoc committed
88
89
90
91
92
93

	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
94
95
96
97

	a1Controller.init(this, "A1");
	a2Controller.init(this, "A2");
	a3Controller.init(this, "A3");
yannick legoc's avatar
yannick legoc committed
98
	a3pController.init(this, "A3P");
legoc's avatar
legoc committed
99
100
101
102
103
104
	a4Controller.init(this, "A4");
	a5Controller.init(this, "A5");
	a6Controller.init(this, "A6");
}

VEXPController::VEXPController(const VEXPController& controller) :
105
	ExperimentController(controller) {
legoc's avatar
legoc committed
106
107
108
}

VEXPController::~VEXPController() {
109
}
legoc's avatar
legoc committed
110
111
112
113

void VEXPController::updateUMatrix() {
	u.update(sample->uRef());
	u.setSize(sample->uRef.getSize());
114
	u.sendEvent();
legoc's avatar
legoc committed
115
116
117
118
119
}

void VEXPController::updateBMatrix() {
	b.update(tasSettings->b());
	b.setSize(tasSettings->b.getSize());
120
	b.sendEvent();
legoc's avatar
legoc committed
121
122
}

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

125
	//cout << "refreshCalcParameters " << value << endl;
126

ics's avatar
ics committed
127
128
129
	// Parse the values.
	rapidjson::Document document;
	document.Parse(value.c_str());
130

ics's avatar
ics committed
131
132
133
134
135
	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"];
136
	rapidjson::Value& fx = document["fx"];
137
	rapidjson::Value& ss = document["ss"];
138

ics's avatar
ics committed
139
	// Calculate the angles and the status.
140
	calculate(ki.GetDouble(), kf.GetDouble(), qh.GetDouble(), qk.GetDouble(), ql.GetDouble(), fx.GetInt(), ss.GetInt());
141
142
}

143
double toDouble(double value) {
ics's avatar
ics committed
144

145
146
147
	if (isinf(value)) {
		return numeric_limits<double>::max();
	}
ics's avatar
ics committed
148

149
150
151
	if (isnan(value)) {
		return 0.0;
	}
legoc's avatar
legoc committed
152

153
154
	return value;
}
ics's avatar
ics committed
155

156
void VEXPController::refreshFloat64Property(SimpleProperty<float64>& property, float64 value) {
legoc's avatar
legoc committed
157
158
159

	// Update the value.
	property = value;
legoc's avatar
legoc committed
160
161
}

162
163
164
165
166
167
168
169
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
170
void VEXPController::updateProperties() {
legoc's avatar
legoc committed
171

legoc's avatar
legoc committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
	// 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
189
190
191
192
193
	qh.update(scattering->qh());
	qk.update(scattering->qk());
	ql.update(scattering->ql());
	en.update(scattering->en());
	qm.update(scattering->qm());
194
	fx.update(scattering->fx());
195
	ss.update(scattering->sens());
ics's avatar
ics committed
196
197
198
199
200
201
202

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

	a1.update(a1Controller->position());
	a2.update(a2Controller->position());
	a3.update(a3Controller->position());
yannick legoc's avatar
yannick legoc committed
203
	a3p.update(a3pController->position());
ics's avatar
ics committed
204
205
206
207
208
209
	a4.update(a4Controller->position());
	a5.update(a5Controller->position());
	a6.update(a6Controller->position());
}

void VEXPController::postConfiguration() {
210
211
212
213
214
215
216
217
218
219
220
221
222
223

	// 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
224
225
226
227

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

ics's avatar
ics committed
228
229
230
231
232
	registerPropertyCopierByUpdate(scattering->qh, qh);
	registerPropertyCopierByUpdate(scattering->qk, qk);
	registerPropertyCopierByUpdate(scattering->ql, ql);
	registerPropertyCopierByUpdate(scattering->en, en);
	registerPropertyCopierByUpdate(scattering->qm, qm);
233
	registerPropertyCopierByUpdate(scattering->fx, fx);
234
	registerPropertyCopierByUpdate(scattering->sens, ss);
ics's avatar
ics committed
235
236
237
238
239
240
241

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

	registerPropertyCopierByUpdate(a1Controller->position, a1);
	registerPropertyCopierByUpdate(a2Controller->position, a2);
	registerPropertyCopierByUpdate(a3Controller->position, a3);
yannick legoc's avatar
yannick legoc committed
242
	registerPropertyCopierByUpdate(a3pController->position, a3p);
ics's avatar
ics committed
243
244
245
246
247
248
249
250
251
	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.
252
253
254
	registerRefresher(calca1, &VEXPController::refreshFloat64PropertyToMoveModel, this, a1Controller->position);
	registerRefresher(calca2, &VEXPController::refreshFloat64PropertyToMoveModel, this, a2Controller->position);
	registerRefresher(calca3, &VEXPController::refreshFloat64PropertyToMoveModel, this, a3Controller->position);
yannick legoc's avatar
yannick legoc committed
255
	registerRefresher(calca3p, &VEXPController::refreshFloat64PropertyToMoveModel, this, a3pController->position);
256
257
258
	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
259
260
261
262

	updateProperties();
}

263
void VEXPController::calculate(float64 ki, float64 kf, float64 qh, float64 qk, float64 ql, int32 fx, int32 ss) {
ics's avatar
ics committed
264
265
266

	// Reset status.
	calculationStatus.setIdle();
267
	calculationError = 0;
ics's avatar
ics committed
268

ics's avatar
ics committed
269
270
271
272
273
274
275
276
277
278
279
280
281
	try {
		// Ki.
		incidentBeam->calcki = ki;

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

		calca1 = toDouble(incidentBeam->calca1());
		calca2 = toDouble(incidentBeam->calca2());

		// Manage the status.
		if (incidentBeam->calcStatus.isError()) {
			calculationStatus.setError();
282
			calculationError = incidentBeam->calcError();
ics's avatar
ics committed
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
		}
		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);

		calca5 = toDouble(scatteredBeam->calca5());
		calca6 = toDouble(scatteredBeam->calca6());

		// Manage the status.
		if (scatteredBeam->calcStatus.isError()) {
			calculationStatus.setError();
302
			calculationError = scatteredBeam->calcError();
ics's avatar
ics committed
303
304
305
306
307
308
309
310
311
312
313
314
315
316
		}
		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;
317
		scattering->calcsens = ss;
ics's avatar
ics committed
318
319

		// Calculate by fixing Ki.
320
		scattering->calculate(tas::Beam::K_MODE, fx);
ics's avatar
ics committed
321
322
323
324
325

		calca3 = toDouble(scattering->calca3());
		calca3p = toDouble(scattering->calca3p());
		calca4 = toDouble(scattering->calca4());

326
327
328
329
330
331
332
//		cout << "calc A1 " << calca1() << endl;
//		cout << "calc A2 " << calca2() << endl;
//		cout << "calc A3 " << calca3() << endl;
//		cout << "calc A3P " << calca3p() << endl;
//		cout << "calc A4 " << calca4() << endl;
//		cout << "calc A5 " << calca5() << endl;
//		cout << "calc A6 " << calca6() << endl << endl;
ics's avatar
ics committed
333
334
335
336
337


		// Manage the status.
		if (scattering->calcStatus.isError()) {
			calculationStatus.setError();
338
			calculationError = scattering->calcError();
ics's avatar
ics committed
339
340
341
342
343
		}
		else if (scattering->calcStatus.isWarning() && !calculationStatus.isError()) {
			calculationStatus.setWarning();
			cerr << "Warning: Calculated Kf are different" << endl;
		}
ics's avatar
ics committed
344
	}
ics's avatar
ics committed
345
	catch (...) {
ics's avatar
ics committed
346
		calculationStatus.setError();
347
		calculationError = 0;
ics's avatar
ics committed
348
349
	}

350
351
352
//	if (calculationError() != 0) {
//		cout << "VEXP error " << calculationError() << endl;
//	}
legoc's avatar
legoc committed
353
354
355
}

}