16 #include "autolctuner.h"
17 #include "ui_autolctunerform.h"
19 REGISTER_TYPE(
XDriverList, AutoLCTuner,
"NMR LC autotuner");
21 static const double TUNE_DROT_APPROACH = 5.0,
22 TUNE_DROT_FINETUNE = 2.0, TUNE_DROT_ABORT = 180.0;
23 static const double TUNE_TRUST_APPROACH = 720.0, TUNE_TRUST_FINETUNE = 360.0;
24 static const double TUNE_FINETUNE_START = 0.7;
25 static const double TUNE_DROT_REQUIRED_N_SIGMA_FINETUNE = 1.0;
26 static const double TUNE_DROT_REQUIRED_N_SIGMA_APPROACH = 2.0;
27 static const double SOR_FACTOR_MAX = 0.9;
28 static const double SOR_FACTOR_MIN = 0.3;
29 static const double TUNE_DROT_MUL_FINETUNE = 2.5;
30 static const double TUNE_DROT_MUL_APPROACH = 3.5;
33 XAutoLCTuner::XAutoLCTuner(
const char *name,
bool runtime,
34 Transaction &tr_meas,
const shared_ptr<XMeasure> &meas) :
39 m_tuning(create<
XBoolNode>(
"Tuning", true)),
40 m_succeeded(create<
XBoolNode>(
"Succeeded", true)),
42 m_reflectionTargeted(create<
XDoubleNode>(
"ReflectionTargeted", false)),
43 m_reflectionRequired(create<
XDoubleNode>(
"ReflectionRequired", false)),
44 m_useSTM1(create<
XBoolNode>(
"UseSTM1", false)),
45 m_useSTM2(create<
XBoolNode>(
"UseSTM2", false)),
52 m_form->setWindowTitle(i18n(
"NMR LC autotuner - ") +
getLabel() );
55 xqcon_create<XQComboBoxConnector>(stm1(), m_form->m_cmbSTM1, ref(tr_meas)),
56 xqcon_create<XQComboBoxConnector>(stm2(), m_form->m_cmbSTM2, ref(tr_meas)),
57 xqcon_create<XQComboBoxConnector>(netana(), m_form->m_cmbNetAna, ref(tr_meas)),
58 xqcon_create<XQLineEditConnector>(target(), m_form->m_edTarget),
59 xqcon_create<XQLineEditConnector>(reflectionTargeted(), m_form->m_edReflectionTargeted),
60 xqcon_create<XQLineEditConnector>(reflectionRequired(), m_form->m_edReflectionRequired),
61 xqcon_create<XQButtonConnector>(m_abortTuning, m_form->m_btnAbortTuning),
62 xqcon_create<XQLedConnector>(m_tuning, m_form->m_ledTuning),
63 xqcon_create<XQLedConnector>(m_succeeded, m_form->m_ledSucceeded),
64 xqcon_create<XQToggleButtonConnector>(m_useSTM1, m_form->m_ckbUseSTM1),
65 xqcon_create<XQToggleButtonConnector>(m_useSTM2, m_form->m_ckbUseSTM2)
69 tr[ *m_tuning] =
false;
70 tr[ *m_succeeded] =
false;
71 tr[ *m_reflectionTargeted] = -15.0;
72 tr[ *m_reflectionRequired] = -7.0;
73 tr[ *m_useSTM1] =
true;
74 tr[ *m_useSTM2] =
true;
75 m_lsnOnTargetChanged = tr[ *m_target].onValueChanged().connectWeakly(
76 shared_from_this(), &XAutoLCTuner::onTargetChanged);
77 m_lsnOnAbortTouched = tr[ *m_abortTuning].onTouch().connectWeakly(
78 shared_from_this(), &XAutoLCTuner::onAbortTuningTouched);
81 XAutoLCTuner::~XAutoLCTuner() {
89 shared_ptr<XMotorDriver> stm1__ = shot_this[ *stm1()];
90 shared_ptr<XMotorDriver> stm2__ = shot_this[ *stm2()];
91 const unsigned int tunebits = 0xffu;
94 tr[ *stm1__->active()] =
true;
95 tr[ *stm1__->auxBits()] = tunebits;
100 tr[ *stm2__->active()] =
true;
101 tr[ *stm2__->auxBits()] = tunebits;
105 tr[ *m_tuning] =
true;
106 tr[ *succeeded()] =
false;
107 tr[ *
this].iteration_count = 0;
108 tr[ *
this].ref_f0_best = 1e10;
109 tr[ *
this].isSTMChanged =
true;
110 tr[ *
this].sor_factor = SOR_FACTOR_MAX;
111 tr[ *
this].stage = Payload::STAGE_FIRST;
112 tr[ *
this].trace.clear();
113 tr[ *
this].dCa = 0.0;
114 tr[ *
this].dCb = 0.0;
115 tr[ *
this].started = XTime::now();
116 tr[ *
this].isTargetAbondoned =
false;
123 tr[ *m_tuning] =
false;
124 tr[ *
this].isSTMChanged =
false;
129 XAutoLCTuner::determineNextC(
double &deltaC1,
double &deltaC2,
130 double x,
double x_err,
131 double y,
double y_err,
132 double dxdC1,
double dxdC2,
133 double dydC1,
double dydC2) {
134 double det = dxdC1 * dydC2 - dxdC2 *dydC1;
135 double slimit = 1e-60;
136 x -= ((x > 0) ? 1 : -1) * std::min(x_err, fabs(x));
137 y -= ((y > 0) ? 1 : -1) * std::min(y_err, fabs(y));
139 deltaC1 = -(dydC2 * x - dxdC2 * y) / det;
140 deltaC2 = -( -dydC1 * x + dxdC1 * y) / det;
143 if(fabs(x) > x_err) {
145 if(fabs(dxdC2) > slimit) {
146 deltaC2 = -x / dxdC2;
148 if(fabs(dxdC1) > slimit) {
149 deltaC1 = -x / dxdC1;
153 if(fabs(dydC2) > slimit) {
154 deltaC2 = -y / dydC2;
156 if(fabs(dydC1) > slimit) {
157 deltaC1 = -y / dydC1;
165 const shared_ptr<XMotorDriver> stm1__ = shot_this[ *stm1()];
166 const shared_ptr<XMotorDriver> stm2__ = shot_this[ *stm2()];
167 const shared_ptr<XNetworkAnalyzer> na__ = shot_this[ *netana()];
172 if(emitter != na__.get())
179 fprintf(stderr,
"LCtuner: Rolls back.\n");
181 tr[ *
this].isSTMChanged =
true;
182 tr[ *
this].dCa = 0.0;
183 tr[ *
this].dCb = 0.0;
184 tr[ *
this].stm1 = tr[ *
this].stm1_best;
185 tr[ *
this].stm2 = tr[ *
this].stm2_best;
186 tr[ *
this].ref_f0_best = 1e10;
187 throw XSkippedRecordError(__FILE__, __LINE__);
190 XAutoLCTuner::abortTuningFromAnalyze(
Transaction &tr, std::complex<double> reff0) {
191 double tune_approach_goal2 = pow(10.0, 0.05 * tr[ *reflectionRequired()]);
192 if(tune_approach_goal2 > std::abs(tr[ *
this].ref_f0_best)) {
193 fprintf(stderr,
"LCtuner: Softens target value.\n");
194 tr[ *
this].iteration_count = 0;
195 tr[ *
this].ref_f0_best = 1e10;
196 tr[ *
this].isSTMChanged =
true;
197 tr[ *
this].sor_factor = SOR_FACTOR_MAX;
198 tr[ *
this].stage = Payload::STAGE_FIRST;
199 tr[ *
this].trace.clear();
200 tr[ *
this].started = XTime::now();
201 tr[ *
this].isTargetAbondoned =
true;
204 tr[ *m_tuning] =
false;
205 if(std::abs(reff0) > std::abs(tr[ *
this].ref_f0_best)) {
206 tr[ *
this].isSTMChanged =
true;
207 tr[ *
this].stm1 = tr[ *
this].stm1_best;
208 tr[ *
this].stm2 = tr[ *
this].stm2_best;
209 throw XRecordError(i18n(
"Aborting. Out of tune, or capacitors have sticked. Back to better positions."), __FILE__, __LINE__);
211 throw XRecordError(i18n(
"Aborting. Out of tune, or capacitors have sticked."), __FILE__, __LINE__);
216 XDriver *emitter)
throw (XRecordError&) {
218 const Snapshot &shot_na(shot_emitter);
220 shared_ptr<XMotorDriver> stm1__ = shot_this[ *stm1()];
221 shared_ptr<XMotorDriver> stm2__ = shot_this[ *stm2()];
224 tr[ *
this].stm1 = shot_others[ *stm1__->position()->value()];
226 tr[ *
this].stm2 = shot_others[ *stm2__->position()->value()];
227 if( !shot_this[ *useSTM1()]) stm1__.reset();
228 if( !shot_this[ *useSTM2()]) stm2__.reset();
230 if( (stm1__ && !shot_others[ *stm1__->ready()]) ||
231 ( stm2__ && !shot_others[ *stm2__->ready()]))
232 throw XSkippedRecordError(__FILE__, __LINE__);
233 if( shot_this[ *
this].isSTMChanged) {
234 tr[ *
this].isSTMChanged =
false;
235 throw XSkippedRecordError(__FILE__, __LINE__);
237 if( !shot_this[ *tuning()]) {
238 throw XSkippedRecordError(__FILE__, __LINE__);
241 if( !stm1__ && !stm2__) {
242 tr[ *m_tuning] =
false;
243 throw XSkippedRecordError(__FILE__, __LINE__);
246 const shared_ptr<XNetworkAnalyzer> na__ = shot_this[ *netana()];
248 int trace_len = shot_na[ *na__].length();
249 double ref_sigma = 0.0;
251 const std::complex<double> *trace = shot_na[ *na__].trace();
252 if(shot_this[ *
this].trace.size() != trace_len) {
254 tr[ *
this].trace.resize(trace_len);
255 for(
int i = 0; i < trace_len; ++i) {
256 tr[ *
this].trace[i] = trace[i];
259 throw XSkippedRecordError(__FILE__, __LINE__);
263 for(
int i = 0; i < trace_len; ++i) {
264 ref_sigma += std::norm(trace[i] - shot_this[ *
this].trace[i]);
265 tr[ *
this].trace[i] = (shot_this[ *
this].trace[i] + trace[i]) / 2.0;
267 ref_sigma = sqrt(ref_sigma / trace_len);
268 if(ref_sigma > 0.1) {
269 tr[ *
this].trace.clear();
270 throw XSkippedRecordError(i18n(
"Too large errors in the trace."), __FILE__, __LINE__);
273 double trace_dfreq = shot_na[ *na__].freqInterval();
274 double trace_start = shot_na[ *na__].startFreq();
277 std::complex<double> reffmin(0.0);
278 double f0 = shot_this[ *target()];
279 std::complex<double> reff0(0.0);
280 double reffmin_sigma, reff0_sigma;
283 const std::complex<double> *trace = &shot_this[ *
this].trace[0];
285 std::complex<double> reffmin_peak(1e10);
287 double fmin_peak = 0;
288 for(
int i = 0; i < trace_len; ++i) {
289 double z = std::abs(trace[i]);
290 if(std::abs(reffmin_peak) > z) {
291 reffmin_peak = trace[i];
292 fmin_peak = trace_start + i * trace_dfreq;
297 reffmin = reffmin_peak;
298 double ref_sigma_sq = ref_sigma * ref_sigma;
299 for(
int cnt = 0; cnt < 2; ++cnt) {
302 std::complex<double> refsum = 0.0;
305 for(
int i = 0; i < trace_len; ++i) {
306 double f = trace_start + i * trace_dfreq;
307 double zsq = std::norm(trace[i] - reffmin);
308 if(zsq < ref_sigma_sq * 10) {
309 double w = exp( -zsq / (2.0 * ref_sigma_sq));
312 refsum += w * trace[i];
314 fsqsum += w * w * (f - fmin) * (f - fmin);
318 fmin_err = sqrt(fsqsum / wsum / wsum + trace_dfreq * trace_dfreq);
319 reffmin = refsum / wsum;
320 reffmin_sigma = ref_sigma * sqrt(wsqsum) / wsum;
325 std::complex<double> refsum = 0.0;
326 double f0_err = std::min(trace_dfreq * 5, fmin_err);
327 for(
int i = 0; i < trace_len; ++i) {
328 double f = trace_start + i * trace_dfreq;
329 if(fabs(f - f0) < f0_err * 10) {
330 double w = exp( -(f - f0) * (f - f0) / (2.0 * f0_err * f0_err));
333 refsum += w * trace[i];
336 reff0 = refsum / wsum;
337 reff0_sigma = ref_sigma * sqrt(wsqsum / wsum * wsum);
338 fprintf(stderr,
"LCtuner: fmin=%.4f+-%.4f, reffmin=%.3f+-%.3f, reff0=%.3f+-%.3f\n",
339 fmin, fmin_err, std::abs(reffmin), reffmin_sigma, std::abs(reff0), reff0_sigma);
341 tr[ *
this].trace.clear();
344 if(std::abs(reff0) < reff0_sigma * 2) {
345 tr[ *succeeded()] =
true;
346 fprintf(stderr,
"LCtuner: tuning done within errors.\n");
350 if(( !stm1__ || !stm2__) && (std::abs(fmin - f0) < fmin_err)) {
351 tr[ *succeeded()] =
true;
352 fprintf(stderr,
"LCtuner: tuning done within errors.\n");
357 double tune_approach_goal = pow(10.0, 0.05 * shot_this[ *reflectionTargeted()]);
358 if(shot_this[ *
this].isTargetAbondoned)
359 tune_approach_goal = pow(10.0, 0.05 * shot_this[ *reflectionRequired()]);
360 if(std::abs(reff0) < tune_approach_goal) {
361 fprintf(stderr,
"LCtuner: tuning done satisfactorily.\n");
362 tr[ *succeeded()] =
true;
366 tr[ *
this].iteration_count++;
367 if(std::abs(shot_this[ *
this].ref_f0_best) > std::abs(reff0)) {
368 tr[ *
this].iteration_count = 0;
370 tr[ *
this].stm1_best = tr[ *
this].stm1;
371 tr[ *
this].stm2_best = tr[ *
this].stm2;
372 tr[ *
this].fmin_best = fmin;
373 tr[ *
this].ref_f0_best = std::abs(reff0) + reff0_sigma;
374 tr[ *
this].sor_factor = (tr[ *
this].sor_factor + SOR_FACTOR_MAX) / 2;
379 bool timeout = (XTime::now() - shot_this[ *
this].started > 360);
381 fprintf(stderr,
"LCtuner: Time out.\n");
382 abortTuningFromAnalyze(tr, reff0);
386 Payload::STAGE stage = shot_this[ *
this].stage;
388 if(stage == Payload::STAGE_FIRST) {
389 if((std::abs(shot_this[ *
this].ref_f0_best) + reff0_sigma < std::abs(reff0)) &&
390 ((shot_this[ *
this].iteration_count > 10) ||
391 ((shot_this[ *
this].iteration_count > 4) && (std::abs(shot_this[ *
this].ref_f0_best) * 1.5 < std::abs(reff0) - reff0_sigma)))) {
392 tr[ *
this].iteration_count = 0;
393 tr[ *
this].sor_factor = (tr[ *
this].sor_factor + SOR_FACTOR_MIN) / 2;
394 if(shot_this[ *
this].sor_factor < (SOR_FACTOR_MAX - SOR_FACTOR_MIN) * pow(2.0, -6.0) + SOR_FACTOR_MIN) {
395 abortTuningFromAnalyze(tr, reff0);
402 if(stage == Payload::STAGE_FIRST) {
403 fprintf(stderr,
"LCtuner: the first stage\n");
405 if(std::abs(reff0) < TUNE_FINETUNE_START) {
406 fprintf(stderr,
"LCtuner: finetune mode\n");
407 tr[ *
this].mode = Payload::TUNE_FINETUNE;
410 fprintf(stderr,
"LCtuner: approach mode\n");
411 tr[ *
this].mode = Payload::TUNE_APPROACHING;
415 std::complex<double> ref_targeted;
416 double tune_drot_required_nsigma;
417 double tune_drot_mul;
418 switch(shot_this[ *
this].mode) {
419 case Payload::TUNE_FINETUNE:
420 ref_targeted = reff0;
421 ref_sigma = reff0_sigma;
422 tune_drot_required_nsigma = TUNE_DROT_REQUIRED_N_SIGMA_FINETUNE;
423 tune_drot_mul = TUNE_DROT_MUL_FINETUNE;
425 case Payload::TUNE_APPROACHING:
426 ref_targeted = reffmin;
427 ref_sigma = reffmin_sigma;
428 tune_drot_required_nsigma = TUNE_DROT_REQUIRED_N_SIGMA_APPROACH;
429 tune_drot_mul = TUNE_DROT_MUL_APPROACH;
434 case Payload::STAGE_FIRST:
436 tr[ *
this].fmin_first = fmin;
437 tr[ *
this].ref_first = ref_targeted;
439 switch(shot_this[ *
this].mode) {
440 case Payload::TUNE_APPROACHING:
441 tune_drot = TUNE_DROT_APPROACH;
443 case Payload::TUNE_FINETUNE:
444 tune_drot = TUNE_DROT_FINETUNE;
447 tr[ *
this].dCa /= tune_drot_mul * tune_drot_mul;
448 tr[ *
this].dCb /= tune_drot_mul * tune_drot_mul;
449 if(fabs(tr[ *
this].dCa) < tune_drot)
450 tr[ *
this].dCa = tune_drot * ((shot_this[ *
this].dfmin_dCa * (fmin - f0) < 0) ? 1.0 : -1.0);
451 if(fabs(tr[ *
this].dCb) < tune_drot)
452 tr[ *
this].dCb = tune_drot * ((shot_this[ *
this].dfmin_dCb * (fmin - f0) < 0) ? 1.0 : -1.0);
454 tr[ *
this].isSTMChanged =
true;
455 tr[ *
this].stage = Payload::STAGE_DCA;
457 tr[ *
this].stm1 += tr[ *
this].dCa;
459 tr[ *
this].stm2 += tr[ *
this].dCa;
460 throw XSkippedRecordError(__FILE__, __LINE__);
462 case Payload::STAGE_DCA:
464 fprintf(stderr,
"LCtuner: +dCa\n");
466 tr[ *
this].fmin_plus_dCa = fmin;
467 tr[ *
this].ref_plus_dCa = ref_targeted;
470 double dfmin = shot_this[ *
this].fmin_plus_dCa - shot_this[ *
this].fmin_first;
471 tr[ *
this].dfmin_dCa = dfmin / shot_this[ *
this].dCa;
474 std::complex<double> dref;
475 dref = shot_this[ *
this].ref_plus_dCa - shot_this[ *
this].ref_first;
476 tr[ *
this].dref_dCa = dref / shot_this[ *
this].dCa;
478 if((fabs(dfmin) < fmin_err * tune_drot_required_nsigma) &&
479 (std::abs(dref) < ref_sigma * tune_drot_required_nsigma)) {
480 if(fabs(tr[ *
this].dCa) < TUNE_DROT_ABORT) {
481 tr[ *
this].dCa *= tune_drot_mul;
482 tr[ *
this].fmin_first = fmin;
483 tr[ *
this].ref_first = ref_targeted;
485 tr[ *
this].stm1 += tr[ *
this].dCa;
487 tr[ *
this].stm2 += tr[ *
this].dCa;
488 tr[ *
this].isSTMChanged =
true;
489 tr[ *
this].stage = Payload::STAGE_DCA;
490 fprintf(stderr,
"LCtuner: increasing dCa to %f\n", (
double)tr[ *
this].dCa);
491 throw XSkippedRecordError(__FILE__, __LINE__);
493 if( !stm1__ || !stm2__) {
494 abortTuningFromAnalyze(tr, reff0);
499 if(stm1__ && stm2__) {
500 tr[ *
this].isSTMChanged =
true;
501 tr[ *
this].stage = Payload::STAGE_DCB;
502 tr[ *
this].stm2 += tr[ *
this].dCb;
503 throw XSkippedRecordError(__FILE__, __LINE__);
507 case Payload::STAGE_DCB:
508 fprintf(stderr,
"LCtuner: +dCb\n");
511 double dfmin = fmin - shot_this[ *
this].fmin_plus_dCa;
512 tr[ *
this].dfmin_dCb = dfmin / shot_this[ *
this].dCb;
515 std::complex<double> dref;
516 dref = ref_targeted - shot_this[ *
this].ref_plus_dCa;
517 tr[ *
this].dref_dCb = dref / shot_this[ *
this].dCb;
519 if((std::min(fabs(shot_this[ *
this].dfmin_dCa * shot_this[ *
this].dCa), fabs(dfmin)) < fmin_err * tune_drot_required_nsigma) &&
520 (std::min(std::abs(shot_this[ *
this].dref_dCa * shot_this[ *
this].dCa), std::abs(dref)) < ref_sigma * tune_drot_required_nsigma)) {
521 if(fabs(tr[ *
this].dCb) < TUNE_DROT_ABORT) {
522 tr[ *
this].dCb *= tune_drot_mul;
523 tr[ *
this].fmin_plus_dCa = fmin;
524 tr[ *
this].ref_plus_dCa = ref_targeted;
525 tr[ *
this].stm2 += tr[ *
this].dCb;
526 tr[ *
this].isSTMChanged =
true;
527 fprintf(stderr,
"LCtuner: increasing dCb to %f\n", (
double)tr[ *
this].dCb);
529 throw XSkippedRecordError(__FILE__, __LINE__);
531 if(fabs(tr[ *
this].dCa) >= TUNE_DROT_ABORT) {
532 abortTuningFromAnalyze(tr, reff0);
539 tr[ *
this].stage = Payload::STAGE_FIRST;
541 std::complex<double> dref_dCa = shot_this[ *
this].dref_dCa;
542 std::complex<double> dref_dCb = shot_this[ *
this].dref_dCb;
544 switch(shot_this[ *
this].mode) {
545 case Payload::TUNE_FINETUNE:
548 case Payload::TUNE_APPROACHING:
552 double a = gamma * 2.0 * pow(std::norm(ref_targeted), gamma - 1.0);
554 double drefgamma_dCa = a * (std::real(ref_targeted) * std::real(dref_dCa) + std::imag(ref_targeted) * std::imag(dref_dCa));
555 double drefgamma_dCb = a * (std::real(ref_targeted) * std::real(dref_dCb) + std::imag(ref_targeted) * std::imag(dref_dCb));
557 double dfmin_dCa = shot_this[ *
this].dfmin_dCa;
558 double dfmin_dCb = shot_this[ *
this].dfmin_dCb;
559 if( !stm1__ || !stm2__) {
567 fprintf(stderr,
"LCtuner: dref_dCa=%.2g, dref_dCb=%.2g, dfmin_dCa=%.2g, dfmin_dCb=%.2g\n",
568 drefgamma_dCa, drefgamma_dCb, dfmin_dCa, dfmin_dCb);
570 determineNextC( dCa_next, dCb_next,
571 pow(std::norm(ref_targeted), gamma), pow(ref_sigma, gamma * 2.0),
572 (fmin - f0), fmin_err,
573 drefgamma_dCa, drefgamma_dCb,
574 dfmin_dCa, dfmin_dCb);
576 fprintf(stderr,
"LCtuner: deltaCa=%f, deltaCb=%f\n", dCa_next, dCb_next);
580 switch(shot_this[ *
this].mode) {
581 case Payload::TUNE_APPROACHING:
582 dc_trust = TUNE_TRUST_APPROACH;
584 case Payload::TUNE_FINETUNE:
585 dc_trust = TUNE_TRUST_FINETUNE;
588 double dca_trust = fabs(shot_this[ *
this].dCa) * 50;
589 double dcb_trust = fabs(shot_this[ *
this].dCb) * 50;
591 double sor = shot_this[ *
this].sor_factor;
592 double red_fac = 1.0;
593 if(fabs(tr[ *
this].dCa) < fabs(dCa_next)) {
595 dCa_next = dCa_next * sor + (tr[ *
this].stm1_best - tr[ *
this].stm1) * (1.0 - sor);
597 dCa_next = dCa_next * sor + (tr[ *
this].stm2_best - tr[ *
this].stm2) * (1.0 - sor);
598 red_fac =std::min(red_fac, std::min(dc_trust, dca_trust) / fabs(dCa_next));
600 if(fabs(tr[ *
this].dCb) < fabs(dCb_next)) {
602 dCb_next = dCb_next * sor + (tr[ *
this].stm2_best - tr[ *
this].stm2) * (1.0 - sor);
603 red_fac =std::min(red_fac, std::min(dc_trust, dcb_trust) / fabs(dCb_next));
607 fprintf(stderr,
"LCtuner: deltaCa=%f, deltaCb=%f\n", dCa_next, dCb_next);
609 tr[ *
this].isSTMChanged =
true;
611 tr[ *
this].stm1 += dCa_next;
614 tr[ *
this].stm2 += dCb_next;
616 tr[ *
this].stm2 += dCa_next;
618 tr[ *
this].dCa = dCa_next;
619 tr[ *
this].dCb = dCb_next;
620 throw XSkippedRecordError(__FILE__, __LINE__);
624 const shared_ptr<XMotorDriver> stm1__ = shot_this[ *stm1()];
625 const shared_ptr<XMotorDriver> stm2__ = shot_this[ *stm2()];
626 if(shot_this[ *
tuning()]) {
627 if(shot_this[ *succeeded()]){
628 const unsigned int tunebits = 0;
631 tr[ *stm1__->active()] =
false;
632 tr[ *stm1__->auxBits()] = tunebits;
637 tr[ *stm2__->active()] =
false;
638 tr[ *stm2__->auxBits()] = tunebits;
642 trans( *
tuning()) =
false;
645 if(shot_this[ *
this].isSTMChanged) {
647 stm1__->iterate_commit_while([=](
Transaction &tr)->
bool{
648 if(tr[ *stm1__->position()->value()] == shot_this[ *
this].stm1)
650 tr[ *stm1__->target()] = shot_this[ *
this].stm1;
655 stm2__->iterate_commit_while([=](
Transaction &tr)->
bool{
656 if(tr[ *stm2__->position()->value()] == shot_this[ *
this].stm2)
658 tr[ *stm2__->target()] = shot_this[ *
this].stm2;
663 if( !shot_this[ *
tuning()]) {
664 trans( *this).isSTMChanged =
false;