QXRD  0.11.16
qxrdintegrator.cpp
Go to the documentation of this file.
1 #include "qxrddebug.h"
2 #include "qxrdintegrator.h"
3 #include "qxrddataprocessor.h"
4 #include "qcepimagedata.h"
5 #include "qcepmaskdata.h"
6 #include "qxrdcenterfinder.h"
7 #include "qcepintegrateddata.h"
8 #include "qcepallocator.h"
9 #include "qxrdapplication.h"
10 #include "qxrdexperiment.h"
11 #include "qxrdintegratorcache.h"
12 #include "qcepallocator.h"
13 #include "qcepdatasetmodel.h"
14 
15 #include <QTime>
16 #include <QtConcurrentRun>
17 #include "qcepmutexlocker.h"
18 
19 #define _USE_MATH_DEFINES
20 
21 #include <cmath>
22 
24  : QcepObject("integrator", NULL),
25  m_Oversample(saver, this, "oversample", 1, "Oversampling for Integration"),
26  m_IntegrationStep(saver, this, "integrationStep", 0.001, "Integration Step Size"),
27  m_IntegrationNSteps(saver, this, "integrationNSteps", 0, "Integration Number of Steps"),
28  m_IntegrationMinimum(saver, this, "integrationMinimum", 0, "Integration Minimum"),
29  m_IntegrationMaximum(saver, this, "integrationMaximum", 100000, "Integration Maximum"),
30  m_IntegrationXUnits(saver, this, "integrationXUnits", RadialIntegrateTTH, "X Units for Integration (0 = TTH, 1 = Q, 2 = R)"),
31  m_EnableGeometricCorrections(saver, this, "enableGeometricCorrections", false, "Enable Geometric Corrections (tilt and distance) in Integration"),
32  m_EnablePolarizationCorrections(saver, this, "enablePolarizationCorrections", false, "Enable Polarization Corrections in Integration"),
33  m_Polarization(saver, this, "polarization", 1.0, "Beam Polarization Factor"),
34  m_EnableAbsorptionCorrections(saver, this, "enableAbsorptionCorrections", false, "Enable Absorption Correction in Integration"),
35  m_AttenuationLength(saver, this, "attenuationLength", 0, "Attenuation Length (mm)"),
36  m_EnableUserGeometry(saver, this, "enableUserGeometry", 0, "Apply user-defined geometry function in integration"),
37  m_UserGeometryScript(saver, this, "userGeometryScript", defaultUserGeometryScript(), "Script to define user defined geometry functions"),
38  m_UserGeometryFunction(saver, this, "userGeometryFunction", "userGeometry", "Name of user defined geometry function"),
39  m_EnableUserAbsorption(saver, this, "enableUserAbsorption", 0, "Apply user-defined geometry function in integration"),
40  m_UserAbsorptionScript(saver, this, "userAbsorptionScript", defaultUserAbsorptionScript(), "Script to define user defined absorption functions"),
41  m_UserAbsorptionFunction(saver, this, "userAbsorptionFunction", "userAbsorb1", "Name of user defined absorption function"),
42  m_ScalingFactor(saver, this, "scalingFactor", 1.0, "Scaling factor for integrated intensity"),
43  m_SelfNormalization(saver, this, "selfNormalization", false, "Normalize result based on average value within specified range"),
44  m_SelfNormalizationMinimum(saver, this, "selfNormalizationMinimum", 0, "Self Normalization Range Minimum"),
45  m_SelfNormalizationMaximum(saver, this, "selfNormalizationMaximum", 0, "Self Normalization Range Maximum"),
46  m_Saver(saver),
47  m_Experiment(exp),
48  m_CenterFinder(cfw),
50 {
52  printf("QxrdIntegrator::QxrdIntegrator(%p)\n", this);
53  }
54 
55  connect(this->prop_Oversample(), &QcepIntProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
56  connect(this->prop_IntegrationStep(), &QcepDoubleProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
57  connect(this->prop_IntegrationNSteps(), &QcepIntProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
58  connect(this->prop_IntegrationMinimum(), &QcepDoubleProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
59  connect(this->prop_IntegrationMaximum(), &QcepDoubleProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
60  connect(this->prop_IntegrationXUnits(), &QcepIntProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
61 
62  connect(prop_EnableGeometricCorrections(), &QcepBoolProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
63  connect(prop_EnablePolarizationCorrections(), &QcepBoolProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
64  connect(prop_Polarization(), &QcepDoubleProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
65  connect(prop_EnableAbsorptionCorrections(), &QcepBoolProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
66  connect(prop_AttenuationLength(), &QcepDoubleProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
67 
68  connect(prop_EnableUserGeometry(), &QcepIntProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
69  connect(prop_UserGeometryScript(), &QcepStringProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
70  connect(prop_UserGeometryFunction(), &QcepStringProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
71 
72  connect(prop_EnableUserAbsorption(), &QcepIntProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
73  connect(prop_UserAbsorptionScript(), &QcepStringProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
74  connect(prop_UserAbsorptionFunction(), &QcepStringProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
75 
76  connect(prop_ScalingFactor(), &QcepDoubleProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
77  connect(prop_SelfNormalization(), &QcepBoolProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
78  connect(prop_SelfNormalizationMinimum(), &QcepDoubleProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
79  connect(prop_SelfNormalizationMaximum(), &QcepDoubleProperty::valueChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
80 
82 
83  if (cf) {
84  connect(cf.data(), &QxrdCenterFinder::parameterChanged, this, &QxrdIntegrator::onIntegrationParametersChanged, Qt::DirectConnection);
85  }
86 }
87 
89 {
90 #ifndef QT_NO_DEBUG
91  printf("Deleting integrator\n");
92 #endif
93 
95  printf("QxrdIntegrator::~QxrdIntegrator(%p)\n", this);
96  }
97 }
98 
100 {
102 
103  if (expt) {
104  return expt->dataProcessor();
105  } else {
106  return QxrdDataProcessorWPtr();
107  }
108 }
109 
111 {
112  return m_Experiment;
113 }
114 
116 {
119 
120  if (expt) {
121  expt->printMessage("Integration parameters changed");
122  }
123  }
124 
126 }
127 
129 {
131 
132  if (res) {
133  return performIntegration(res, dimg, mask);
134  } else {
135  return res;
136  }
137 }
138 
140 {
143 
144  if (expt) {
145  expt->printMessage(tr("QxrdIntegrator::performIntegration(\"%1\")")
146  .arg(dimg->get_FileName()));
147  }
148  }
149 
150  QThread::currentThread()->setObjectName("performIntegration");
151 
153 
154  if (cache == NULL ||
155  dimg->get_Width() != cache->get_NCols() ||
156  dimg->get_Height() != cache->get_NRows()) {
157 
158  cache = QxrdIntegratorCachePtr(
160  (QxrdIntegratorWPtr) sharedFromThis(),
162  m_CenterFinder));
163 
164  m_IntegratorCache = cache;
165  }
166 
167  cache->performIntegration(integ, dimg, mask, true);
168 
169  return integ;
170 }
171 
172 double QxrdIntegrator::XValue(QPointF pt) const
173 {
174  return XValue(pt.x(), pt.y());
175 }
176 
177 double QxrdIntegrator::XValue(double x, double y) const
178 {
179  double xVal = 0;
180 
182 
183  if (cf) {
184  switch(get_IntegrationXUnits()) {
185  case RadialIntegrateTTH:
186  xVal = cf->getTTH(x,y);
187  break;
188 
189  case RadialIntegrateQ:
190  xVal = cf->getQ(x,y);
191  break;
192 
193  case RadialIntegrateR:
194  xVal = cf->getR(x,y);
195  break;
196  }
197  }
198 
199  return xVal;
200 }
201 
202 double QxrdIntegrator::XValue(double x, double y,
203  int xUnits, QxrdCenterFinderPtr cf,
204  double xc, double yc,
205  double dst, double nrg,
206  double pxl, double pxh,
207  double rot, double cosr, double sinr,
208  double cosb, double sinb,
209  double cosa, double sina
210  ) const
211 {
212  double xVal = 0;
213  double junk;
214 
215  switch(xUnits) {
216  case RadialIntegrateTTH:
217  xVal = cf->getTwoTheta(xc,yc,dst,x,y,pxl,pxh,cosb,sinb,cosr,sinr);
218  break;
219 
220  case RadialIntegrateQ:
221  cf->getQChi(xc,yc,dst,nrg,x,y,pxl,pxh,rot,cosb,sinb,cosa,sina,cosr,sinr,&xVal, &junk);
222  break;
223 
224  case RadialIntegrateR:
225  xVal = cf->getRadius(xc,yc,dst,x,y,pxl,pxh,cosb,sinb,cosr,sinr);
226  break;
227  }
228 
229  return xVal;
230 }
231 
232 QString QxrdIntegrator::XLabel() const
233 {
234  QString label = "";
235 
236  switch(get_IntegrationXUnits()) {
237  case RadialIntegrateTTH:
238  label = "2 Theta (deg)";
239  break;
240 
241  case RadialIntegrateQ:
242  label = "Q";
243  break;
244 
245  case RadialIntegrateR:
246  label = "r (mm)";
247  break;
248  }
249 
250  return label;
251 }
252 
253 QcepIntegratedDataPtr QxrdIntegrator::sliceLine(QcepIntegratedDataPtr integ, QcepDoubleImageDataPtr image, double x0, double y0, double x1, double y1, double width)
254 {
255  try {
256  QVector<QPointF> poly;
257  poly.append(QPointF(x0,y0));
258  poly.append(QPointF(x1,y1));
259 
260  return slicePolygon(integ, image, poly, width);
261  }
262 
263  catch (...) {
265 
266  if (expt) {
267  expt->printMessage("QxrdIntegrator::sliceLine failed");
268  }
269  }
270 
271  return QcepIntegratedDataPtr();
272 }
273 
275 {
276  QThread::currentThread()->setObjectName("slicePolygon");
277 
278  if (integ && image) {
279  double length = 0;
280 
281  if (poly.size() >= 2) {
282  QPointF p0 = poly[0];
283 
284  for (int i=1; i<poly.size(); i++) {
285  QPointF p1 = poly[i];
286  double dx = p1.x() - p0.x();
287  double dy = p1.y() - p0.y();
288  length += sqrt(dx*dx + dy*dy);
289  p0=p1;
290  }
291 
292  p0 = poly[0];
293  double r = 0;
294  double r0 = 0;
295 
296  // QVector<double> xs,ys;
297  integ -> resize(0);
298 
299  for (int i=1; i<poly.size(); i++) {
300  QPointF p1 = poly[i];
301  double dx = p1.x() - p0.x();
302  double dy = p1.y() - p0.y();
303  double len = sqrt(dx*dx + dy*dy);
304 
305  if (len > 0) {
306  for (; r<len; r+=1) {
307  double x = p0.x() + r*dx/len;
308  double y = p0.y() + r*dy/len;
309 
310  integ -> append(r+r0, image->value((int) x, (int) y));
311  }
312  }
313 
314  p0 = p1;
315  r0 += len;
316  r -= len;
317  }
318  //
319  // emit newIntegrationAvailable(image->get_Title(),xs,ys);
320  }
321  } else {
323 
324  if (expt) {
325  expt->printMessage("QxrdIntegrator::slicePolygon failed");
326  }
327  }
328 
329  return integ;
330 }
331 
333 {
334  set_IntegrationXUnits(RadialIntegrateQ);
335 }
336 
338 {
339  set_IntegrationXUnits(RadialIntegrateR);
340 }
341 
343 {
344  set_IntegrationXUnits(RadialIntegrateTTH);
345 }
346 
348 {
349  if (m_IntegratorCache) {
350  return m_IntegratorCache->cachedGeometry();
351  } else {
352  return QcepInt32ImageDataPtr();
353  }
354 }
355 
357 {
358  if (m_IntegratorCache) {
359  return m_IntegratorCache->cachedIntensity();
360  } else {
361  return QcepDoubleImageDataPtr();
362  }
363 }
364 
366 {
367  QFile def(":/qxrdexampleusergeometry.js");
368 
369  if (def.open(QFile::ReadOnly)) {
370  return def.readAll();
371  } else {
372  return "Couldn't open resource file";
373  }
374 }
375 
377 {
378  QFile def(":/qxrdexampleuserabsorption.js");
379 
380  if (def.open(QFile::ReadOnly)) {
381  return def.readAll();
382  } else {
383  return "Couldn't open resource file";
384  }
385 }
386 
388 {
390 
391  if (expt) {
392  QcepDatasetModelPtr ds = expt->dataset();
393 
394  if (ds) {
395  QcepDoubleImageDataPtr data = ds->image(resPath);
396 
397  if (!data) {
398  data = ds->newImage(resPath);
399  }
400 
401  if (data) {
402  appendIntegration(data, integ);
403  } else {
404  printMessage(tr("Unable to accumulate integrated data into %1").arg(resPath));
405  }
406  }
407  }
408 }
409 
411 {
413 
414  if (expt) {
415  QcepDatasetModelPtr ds = expt->dataset();
416 
417  if (ds) {
418  QcepDoubleImageDataPtr data = ds->image(resPath);
419 
420  if (!data) {
421  data = ds->newImage(resPath);
422  }
423 
424  if (data) {
425  appendIntegration(data, dimg, mask);
426  }
427  }
428  }
429 }
430 
432 {
433  QcepIntegratedDataPtr integ = performIntegration(dimg, mask);
434 
435  appendIntegration(res, integ);
436 }
437 
439 {
440  if (res && integ) {
441  int width = res->get_Width();
442  int ht = res->get_Height();
443  int npts = integ->size();
444 
445  res->resize(npts, ht+1);
446 
447  for (int i=0; i<npts; i++) {
448  res->setValue(i, ht, integ->y(i));
449  }
450 
451  emit res->dataObjectChanged();
452  }
453 }
454 
455 void QxrdIntegrator::clearAccumulator(QString resPath)
456 {
458 
459  if (expt) {
460  QcepDatasetModelPtr ds = expt->dataset();
461 
462  if (ds) {
463  QcepDoubleImageDataPtr data = ds->image(resPath);
464 
465  if (!data) {
466  data = ds->newImage(resPath);
467  }
468 
469  if (data) {
470  data->resize(0, 0);
471  }
472  }
473  }
474 }
475 
476 void QxrdIntegrator::prepareAccumulator(QString resPath, int nImages)
477 {
479 
480  if (expt) {
481  QcepDatasetModelPtr ds = expt->dataset();
482 
483  if (ds) {
484  QcepDoubleImageDataPtr data = ds->image(resPath);
485 
486  if (!data) {
487  data = ds->newImage(resPath);
488  }
489  }
490  }
491 }
492 
494 {
495 }
496 
497 void QxrdIntegrator::saveAccumulator(QString resPath, QString &fileName, QString filter)
498 {
500 
501  if (expt) {
502  QcepDatasetModelPtr ds = expt->dataset();
503 
504  if (ds) {
505  QcepDoubleImageDataPtr data = ds->image(resPath);
506 
507  if (data) {
508  data -> saveData(fileName, filter);
509  }
510  }
511  }
512 }
513 
514 QScriptValue QxrdIntegrator::toScriptValue(QScriptEngine *engine, const QxrdIntegratorPtr &proc)
515 {
516  return engine->newQObject(proc.data());
517 }
518 
519 void QxrdIntegrator::fromScriptValue(const QScriptValue &obj, QxrdIntegratorPtr &proc)
520 {
521  QObject *qobj = obj.toQObject();
522 
523  if (qobj) {
524  QxrdIntegrator *f = qobject_cast<QxrdIntegrator*>(qobj);
525 
526  if (f) {
527  proc = QxrdIntegratorPtr(f);
528  }
529  }
530 }
QSharedPointer< QxrdExperiment > QxrdExperimentPtr
QcepIntegratedDataPtr slicePolygon(QcepIntegratedDataPtr integ, QcepDoubleImageDataPtr dimg, QVector< QPointF > poly, double width)
void saveAccumulator(QString resPath, QString &fileName, QString filter)
QSharedPointer< QxrdCenterFinder > QxrdCenterFinderPtr
QxrdDataProcessorWPtr dataProcessor() const
QxrdExperimentWPtr m_Experiment
QWeakPointer< QxrdDataProcessor > QxrdDataProcessorWPtr
static QcepIntegratedDataPtr newIntegratedData(AllocationStrategy strat, QcepDoubleImageDataPtr image, QcepObject *parent)
QSharedPointer< QxrdIntegratorCache > QxrdIntegratorCachePtr
qint64 qcepDebug(int cond)
Definition: qcepdebug.cpp:26
void valueChanged(QString val, int index)
QcepInt32ImageDataPtr cachedGeometry()
QWeakPointer< QxrdCenterFinder > QxrdCenterFinderWPtr
QcepIntegratedDataPtr performIntegration(QcepIntegratedDataPtr integ, QcepDoubleImageDataPtr dimg, QcepMaskDataPtr mask)
QString XLabel() const
QxrdExperimentWPtr experiment() const
static void fromScriptValue(const QScriptValue &obj, QxrdIntegratorPtr &proc)
QWeakPointer< QxrdExperiment > QxrdExperimentWPtr
QSharedPointer< QcepIntegratedData > QcepIntegratedDataPtr
QcepDoubleImageDataPtr cachedIntensity()
void onIntegrationParametersChanged()
double XValue(double x, double y) const
QString defaultUserGeometryScript()
QxrdCenterFinderWPtr m_CenterFinder
QxrdIntegrator(QcepSettingsSaverWPtr saver, QxrdExperimentWPtr exp, QxrdCenterFinderWPtr cfw)
QSharedPointer< QxrdIntegrator > QxrdIntegratorPtr
void clearAccumulator(QString resPath)
void parameterChanged()
void appendIntegration(QString resPath, QcepDoubleImageDataPtr dimg, QcepMaskDataPtr mask=QcepMaskDataPtr())
QWeakPointer< QxrdPolarTransform > QxrdPolarTransformWPtr
virtual void printMessage(QString msg, QDateTime dt=QDateTime::currentDateTime()) const
Definition: qcepobject.cpp:84
QWeakPointer< QxrdIntegrator > QxrdIntegratorWPtr
void completeAccumulator(QString path)
QSharedPointer< QcepInt32ImageData > QcepInt32ImageDataPtr
QcepSettingsSaverWPtr m_Saver
static QScriptValue toScriptValue(QScriptEngine *engine, const QxrdIntegratorPtr &proc)
void valueChanged(double val, int index)
void valueChanged(int val, int index)
QSharedPointer< QcepMaskData > QcepMaskDataPtr
virtual ~QxrdIntegrator()
QString defaultUserAbsorptionScript()
QSharedPointer< QcepDatasetModel > QcepDatasetModelPtr
void prepareAccumulator(QString resPath, int nImages)
QxrdIntegratorCachePtr m_IntegratorCache
void valueChanged(bool val, int index)
QWeakPointer< QcepSettingsSaver > QcepSettingsSaverWPtr
QcepIntegratedDataPtr sliceLine(QcepIntegratedDataPtr integ, QcepDoubleImageDataPtr dimg, double x0, double y0, double x1, double y1, double width)
QSharedPointer< QcepDoubleImageData > QcepDoubleImageDataPtr