QXRD  0.11.16
qxrdintegratorcache.cpp
Go to the documentation of this file.
1 #include "qxrddebug.h"
2 #include "qxrdintegratorcache.h"
3 #include "qxrdintegrator.h"
4 #include "qcepimagedata.h"
5 #include "qcepmaskdata.h"
6 #include "qcepintegrateddata.h"
7 #include "qxrddetectorgeometry.h"
8 #include "qxrdapplication.h"
9 #include "qxrdexperiment.h"
10 #include "qcepdebug.h"
11 #include "qcepallocator.h"
12 #include "qxrdintegrator.h"
13 #include "qxrdpolartransform.h"
14 #include "qxrdcenterfinder.h"
15 #include "qcepmutexlocker.h"
16 #include "qcepdataobject.h"
17 
18 #include <stdio.h>
19 #include <QThread>
20 
21 #include "qmath.h"
22 
23 #include <qmath.h>
24 
25 #include <QtConcurrentRun>
26 
29  QxrdIntegratorWPtr integ,
32  QObject(),
33  m_ThreadCount(QThreadPool::globalInstance()->maxThreadCount()),
34  m_Oversample(1),
35  m_RadialStep(0.001),
36  m_RadialNSteps(0),
37  m_RadialStart(0),
38  m_RadialEnd(100000),
40  m_PolarStep(0.5),
41  m_PolarNSteps(0),
42  m_PolarStart(0),
43  m_PolarEnd(360),
45  m_CenterX(0),
46  m_CenterY(0),
49  m_DetectorDistance(1000),
50  m_Energy(20000),
51  m_ImplementTilt(false),
52  m_DetectorTilt(0),
54  m_EnableGeometry(false),
55  m_EnablePolarization(false),
56  m_Polarization(1.0),
57  m_EnableAbsorption(false),
59  m_NRows(-1),
60  m_NCols(-1),
61  m_NPix(-1),
62  m_RStep(0),
63  m_RMin(0),
64  m_RMax(0),
65  m_Beta(0),
66  m_CosBeta(1),
67  m_SinBeta(0),
68  m_Rot(0),
69  m_CosRot(0),
70  m_SinRot(0),
73  m_ScalingFactor(1.0),
74  m_CacheFillLevel(-1),
75  m_CacheFullLevel(-1),
76  m_HasChi(false),
77  m_Experiment(exp),
78  m_Integrator(integ),
79  m_PolarTransform(xform),
80  m_CenterFinder(cf)
81 {
83  printf("QxrdIntegratorCache::QxrdIntegratorCache(%p)\n", this);
84  }
85 
88 
89  if (integp == NULL && xformp) {
90  integp = xformp->integrator();
91  }
92 
93  if (integp) {
94  m_Oversample = integp->get_Oversample();
95  m_RadialStep = integp->get_IntegrationStep();
96  m_RadialNSteps = integp->get_IntegrationNSteps();
97  m_RadialStart = integp->get_IntegrationMinimum();
98  m_RadialEnd = integp->get_IntegrationMaximum();
99  m_RadialUnits = integp->get_IntegrationXUnits();
100 
101  m_EnableGeometry = integp->get_EnableGeometricCorrections();
102  m_EnablePolarization = integp->get_EnablePolarizationCorrections();
103  m_Polarization = integp->get_Polarization();
104  m_EnableAbsorption = integp->get_EnableAbsorptionCorrections();
105  m_AttenuationLength = integp->get_AttenuationLength();
106 
107  m_EnableUserGeometry = integp->get_EnableUserGeometry();
108  m_UserGeometryScript = integp->get_UserGeometryScript();
109  m_UserGeometryFunction = integp->get_UserGeometryFunction();
110 
111  m_EnableUserAbsorption = integp->get_EnableUserAbsorption();
112  m_UserAbsorptionScript = integp->get_UserAbsorptionScript();
113  m_UserAbsorptionFunction = integp->get_UserAbsorptionFunction();
114 
115  m_ScalingFactor = integp->get_ScalingFactor();
116 
117  m_SelfNormalization = integp->get_SelfNormalization();
118  m_SelfNormalizationMinimum = integp->get_SelfNormalizationMinimum();
119  m_SelfNormalizationMaximum = integp->get_SelfNormalizationMaximum();
120  }
121 
122  if (xformp) {
123  m_RadialStep = xformp->get_RadialStep();
124  m_RadialNSteps = xformp->get_RadialNSteps();
125  m_RadialStart = xformp->get_RadialStart();
126  m_RadialEnd = xformp->get_RadialEnd();
127  m_RadialUnits = xformp->get_RadialUnits();
128 
129  m_PolarStep = xformp->get_PolarStep();
130  m_PolarNSteps = xformp->get_PolarNSteps();
131  m_PolarStart = xformp->get_PolarStart();
132  m_PolarEnd = xformp->get_PolarEnd();
133  m_PolarUnits = xformp->get_PolarUnits();
134 
135  m_Oversample = xformp->get_Oversample();
136  m_EnableGeometry = xformp->get_EnableGeometricCorrections();
137  m_EnablePolarization = xformp->get_EnablePolarizationCorrections();
138  m_Polarization = xformp->get_Polarization();
139 
140  m_HasChi = true;
141  }
142 
144 
145  if (cfp) {
146  m_CenterX = cfp->get_CenterX();
147  m_CenterY = cfp->get_CenterY();
148  m_DetectorXPixelSize = cfp->get_DetectorXPixelSize();
149  m_DetectorYPixelSize = cfp->get_DetectorYPixelSize();
150  m_DetectorDistance = cfp->get_DetectorDistance();
151  m_Energy = cfp->get_Energy();
152  m_ImplementTilt = cfp->get_ImplementTilt();
153  m_DetectorTilt = cfp->get_DetectorTilt();
154  m_TiltPlaneRotation = cfp->get_TiltPlaneRotation();
155  }
156 }
157 
159 {
161  printf("QxrdIntegratorCache::~QxrdIntegratorCache(%p)\n", this);
162  }
163 }
164 
166 {
167  return m_NRows;
168 }
169 
171 {
172  return m_NCols;
173 }
174 
175 double QxrdIntegratorCache::getTTH(double x, double y)
176 {
177  double beta = m_DetectorTilt*M_PI/180.0;
178  double rot = m_TiltPlaneRotation*M_PI/180.0;
179 
180  if (m_ImplementTilt) {
183  cos(beta), sin(beta), cos(rot), sin(rot));
184  } else {
187  1.0, 0.0, 1.0, 0.0);
188  }
189 }
190 
191 double QxrdIntegratorCache::getDistance(double x, double y)
192 {
193  double tth = getTTH(x, y)*M_PI/180.0;
194 
195  return m_DetectorDistance/cos(tth);
196 }
197 
198 double QxrdIntegratorCache::getChi(double x, double y)
199 {
200  double q,chi;
201  double beta = m_DetectorTilt*M_PI/180.0;
202  double rot = m_TiltPlaneRotation*M_PI/180.0;
203 
204  if (m_ImplementTilt) {
206  m_Energy,
208  rot, cos(beta), sin(beta), 1.0, 0.0, cos(rot), sin(rot),
209  &q, &chi);
210  } else {
212  m_Energy,
214  0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0,
215  &q, &chi);
216  }
217 
218  return chi;
219 }
220 
221 double QxrdIntegratorCache::getQ(double x, double y)
222 {
223  double q,chi;
224  double beta = m_DetectorTilt*M_PI/180.0;
225  double rot = m_TiltPlaneRotation*M_PI/180.0;
226 
227  if (m_ImplementTilt) {
229  m_Energy,
231  rot, cos(beta), sin(beta), 1.0, 0.0, cos(rot), sin(rot),
232  &q, &chi);
233  } else {
235  m_Energy,
237  0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0,
238  &q, &chi);
239  }
240 
241  return q;
242 }
243 
244 double QxrdIntegratorCache::getR(double x, double y)
245 {
246  double tth = getTTH(x, y);
247  double r = m_DetectorDistance*tan(tth*M_PI/180.0);
248 
249  return r;
250 }
251 
252 double QxrdIntegratorCache::XValue(double x, double y)
253 {
254  double xVal = 0;
255 
256  if (m_EnableUserGeometry == 0) {
257  switch(m_RadialUnits) {
259  xVal = getTTH(x,y);
260  break;
261 
263  xVal = getQ(x,y);
264  break;
265 
267  xVal = getR(x,y);
268  break;
269  }
270  } else {
271  xVal = m_UserGeometryFunctionValue.call(QScriptValue(), QScriptValueList() << x << y).toNumber();
272  }
273 
274  return xVal;
275 }
276 
277 double QxrdIntegratorCache::YValue(double x, double y)
278 {
279  double yVal = 0;
280 
281  switch (m_PolarUnits) {
283  yVal = getChi(x,y);
284  }
285 
286  return yVal;
287 }
288 
289 double QxrdIntegratorCache::NormValue(double x, double y)
290 {
291  double res = 1;
292 
294  double distance = getDistance(x, y);
295  double tth = getTTH(x,y)*M_PI/180.0;
296  double chi = getChi(x,y)*M_PI/180.0;
297 
298  if (m_EnableGeometry) {
299  res *= pow(distance/m_DetectorDistance, 2)/cos(tth);
300  }
301 
302  if (m_EnableAbsorption) {
303  res *= exp((distance-m_DetectorDistance)/m_AttenuationLength);
304  }
305 
306  if (m_EnablePolarization) {
307  res *= (m_Polarization *(1 - pow(sin(chi)*sin(tth),2)) +
308  (1 - m_Polarization)*(1 - pow(cos(chi)*sin(tth),2)));
309  }
310 
311  switch (m_EnableUserAbsorption) {
313  res *= m_UserAbsorptionFunctionValue.call(QScriptValue(), QScriptValueList() << x << y).toNumber();
314  break;
315 
317  res *= m_UserAbsorptionFunctionValue.call(QScriptValue(), QScriptValueList() << x - m_CenterX << y - m_CenterY).toNumber();
318  break;
319 
321  res *= m_UserAbsorptionFunctionValue.call(QScriptValue(), QScriptValueList() << getR(x,y) << chi).toNumber();
322  break;
323 
325  res *= m_UserAbsorptionFunctionValue.call(QScriptValue(), QScriptValueList() << getQ(x,y) << chi).toNumber();
326  break;
327 
328  default:
329  break;
330  }
331  }
332 
333  return res;
334 }
335 
336 class QThreadAccess : public QThread {
337 public:
338  static void sleep(int sec)
339  {
340  QThread::sleep(sec);
341  }
342 
343  static void usleep(int usec)
344  {
345  QThread::usleep(usec);
346  }
347 
348  static void msleep(int msec)
349  {
350  QThread::msleep(msec);
351  }
352 };
353 
355 {
356  QString label = "";
357 
358  switch(m_RadialUnits) {
360  label = "TTH";
361  break;
362 
364  label = "Q";
365  break;
366 
368  label = "r";
369  break;
370  }
371 
372  return label;
373 }
374 
376 {
377  QString units = "";
378 
379  switch(m_RadialUnits) {
381  units = "deg";
382  break;
383 
385  units = "/&Ang;";
386  break;
387 
389  units = "mm";
390  break;
391  }
392 
393  return units;
394 }
395 
397 {
398  return "Chi";
399 }
400 
402 {
403  return "deg";
404 }
405 
407 {
408  int strideSize = m_NRows / m_ThreadCount;
409 
410  while (strideSize*m_ThreadCount < m_NRows) {
411  strideSize++;
412  }
413 
414  int rowStart = strideSize*i;
415  int rowEnd = rowStart + strideSize;
416 
417  if (rowEnd > m_NRows) {
418  rowEnd = m_NRows;
419  }
420 
421  int noversample = m_Oversample;
422  double oversampleStep = 1.0/m_Oversample;
423  double halfOversampleStep = oversampleStep/2.0;
424 
425  double rMin=0, rMax=0, cMin=0, cMax=0;
426  bool rFirst=true, cFirst=true;
427 
428  for(int y = rowStart; y<rowEnd; y++) {
429  for (int x = 0; x < m_NCols; x++) {
430  for (int oversampley = 0; oversampley < noversample; oversampley++) {
431  double yy = y+oversampley*oversampleStep+halfOversampleStep;
432  int iy = y*noversample+oversampley;
433  for (int oversamplex = 0; oversamplex < noversample; oversamplex++) {
434  double xx = x+oversamplex*oversampleStep+halfOversampleStep;
435  int ix = x*noversample+oversamplex;
436 
437  double r = XValue(xx, yy);
438 
439  if (r==r) {
440  if (rFirst) {
441  rMin = r;
442  rMax = r;
443  rFirst = false;
444  } else if (r > rMax) {
445  rMax = r;
446  } else if (r < rMin) {
447  rMin = r;
448  }
449  }
450 
451  m_CachedRadialValues->setValue(ix, iy, r);
452 
453  if (m_HasChi) {
454  double c = YValue(xx, yy);
455 
456  if (c==c) {
457  if (cFirst) {
458  cMin = c;
459  cMax = c;
460  cFirst = false;
461  } else if (c > cMax) {
462  cMax = c;
463  } else if (c < cMin) {
464  cMin = c;
465  }
466  }
467 
468  m_CachedPolarValues->setValue(ix, iy, c);
469  }
470  }
471  }
472  }
473  }
474 
475  if (rFirst == false || cFirst == false) {
476  QcepMutexLocker lock(__FILE__, __LINE__, &m_Mutex);
477 
478  if (rFirst == false) {
479  if (m_RFirst) {
480  m_RMin = rMin;
481  m_RMax = rMax;
482  m_RFirst = false;
483  } else {
484  m_RMin = qMin(m_RMin, rMin);
485  m_RMax = qMax(m_RMax, rMax);
486  }
487 
489 
490  if (m_RStep == 0) {
491  int nStep = m_RadialNSteps;
492 
493  if (nStep <= 0) {
494  nStep = 512;
495  }
496 
497  m_RStep = (m_RMax - m_RMin)/nStep;
498  }
499  }
500 
501  if (cFirst == false) {
502  if (m_CFirst) {
503  m_CMin = cMin;
504  m_CMax = cMax;
505  m_CFirst = false;
506  } else {
507  m_CMin = qMin(m_CMin, cMin);
508  m_CMax = qMax(m_CMax, cMax);
509  }
510 
512 
513  if (m_CStep == 0) {
514  int nStep = m_PolarNSteps;
515 
516  if (nStep <= 0) {
517  nStep = 360;
518  }
519 
520  m_CStep = (m_CMax - m_CMin)/nStep;
521  }
522  }
523  }
524 }
525 
527 {
528  int strideSize = m_NRows / m_ThreadCount;
529 
530  while (strideSize*m_ThreadCount < m_NRows) {
531  strideSize++;
532  }
533 
534  int rowStart = strideSize*i;
535  int rowEnd = rowStart + strideSize;
536 
537  if (rowEnd > m_NRows) {
538  rowEnd = m_NRows;
539  }
540 
541  int noversample = m_Oversample;
542  double oversampleStep = 1.0/m_Oversample;
543  double halfOversampleStep = oversampleStep/2.0;
544 
545  for(int y = rowStart; y<rowEnd; y++) {
546  for (int x = 0; x < m_NCols; x++) {
547  for (int oversampley = 0; oversampley < noversample; oversampley++) {
548  double yy = y+oversampley*oversampleStep+halfOversampleStep;
549  int iy = y*noversample+oversampley;
550  for (int oversamplex = 0; oversamplex < noversample; oversamplex++) {
551  double xx = x+oversamplex*oversampleStep+halfOversampleStep;
552  int ix = x*noversample+oversamplex;
553 
554  double r = m_CachedRadialValues->value(ix, iy) - m_RadialStart;
555  double n = -1;
556 
557  if (r == r) {
558  n = floor(r / m_RStep);
559  }
560 
561  if (n >= 0 && n < m_NRSteps) {
562  m_CachedRadialBinNumbers->setValue(ix, iy, n);
563  m_CachedNormalization->setValue(ix, iy, NormValue(xx, yy));
564  } else {
565  m_CachedRadialBinNumbers->setValue(ix, iy, -1);
566  m_CachedNormalization->setValue(ix, iy, 0.0);
567  }
568 
569  if (m_HasChi) {
570  double chi = m_CachedPolarValues->value(ix, iy) - m_PolarStart;
571  double n = -1;
572 
573  if (chi == chi) {
574  n = floor(chi / m_CStep);
575  }
576 
577  if (n >= 0 && n < m_NCSteps) {
578  m_CachedPolarBinNumbers->setValue(ix, iy, n);
579  } else {
580  m_CachedPolarBinNumbers->setValue(ix, iy, -1);
581  }
582  }
583  }
584  }
585  }
586  }
587 }
588 
590  int i,
591  int n,
593  QcepMaskDataPtr mask,
594  int normalize)
595 {
596  int strideSize = m_NRows / m_ThreadCount;
597 
598  while (strideSize*m_ThreadCount < m_NRows) {
599  strideSize++;
600  }
601 
602  int rowStart = strideSize*i;
603  int rowEnd = rowStart + strideSize;
604 
605  if (rowEnd > m_NRows) {
606  rowEnd = m_NRows;
607  }
608 
609  int noversample = m_Oversample;
610  double oversampleStep = 1.0/m_Oversample;
611  double halfOversampleStep = oversampleStep/2.0;
612 
613  QVector<double> integral(m_ResultSize), sumValue(m_ResultSize);
614 
615  for(int y = rowStart; y<rowEnd; y++) {
616  for (int x = 0; x < m_NCols; x++) {
617  if ((mask == NULL) || (mask->value(x, y))) {
618  double val = dimg->value(x,y);
619  for (int oversampley = 0; oversampley < noversample; oversampley++) {
620  int iy = y*noversample+oversampley;
621  for (int oversamplex = 0; oversamplex < noversample; oversamplex++) {
622  int ix = x*noversample+oversamplex;
623 
624  int rbin = m_CachedRadialBinNumbers->value(ix,iy);
625  double norm = m_CachedNormalization->value(ix,iy);
626 
627  int bin = -1;
628 
629  if (m_HasChi) {
630  int cbin = m_CachedPolarBinNumbers->value(ix,iy);
631 
632  if (cbin >= 0) {
633  bin = cbin*m_NRSteps + rbin;
634  }
635  } else {
636  bin = rbin;
637  }
638 
639  if (bin >= 0) {
640  integral[bin] += val*norm;
641  sumValue[bin] += 1;
642  }
643  }
644  }
645  }
646  }
647  }
648 
649  {
650  QcepMutexLocker lock(__FILE__, __LINE__, &m_Mutex);
651 
652  double *s1 = m_SumValue.data();
653  double *s2 = sumValue.data();
654  double *v1 = m_Integral.data();
655  double *v2 = integral.data();
656 
657  for (int i=0; i<m_ResultSize; i++) {
658  if (s2[i] > 0) {
659  v1[i] += v2[i];
660  s1[i] += s2[i];
661  }
662  }
663  }
664 }
665 
667  QcepDataObjectPtr res,
669  QcepMaskDataPtr mask,
670  int normalize)
671 {
672  QTime tic;
673  tic.start();
674 
676 
677  if (expt) {
679  expt->printMessage(tr("QxrdIntegratorCache::performIntegration"));
680  }
681 
682  m_Integral.resize(0);
683  m_SumValue.resize(0);
684 
685  if (res && dimg) {
686  int noversample = m_Oversample;
687  double oversampleStep = 1.0/m_Oversample;
688  double halfOversampleStep = oversampleStep/2.0;
689 
690  m_NRows = dimg->get_Height();
691  m_NCols = dimg->get_Width();
693 
694  m_CacheFullLevel.fetchAndStoreOrdered(m_NPix);
695 
696  QcepDoubleList norm = dimg->get_Normalization();
697 
698  double normVal = 1;
699 
700  if (norm.length()>=1) {
701  normVal = norm[0];
702  }
703 
704  if (m_CacheFillLevel.testAndSetOrdered(-1,0)) {
706  expt->printMessage(tr("QxrdIntegratorCache::performIntegration - fill cache"));
707  }
708 
709  // Allocate new cache and fill it...
710 
712  m_NCols*m_Oversample,
713  m_NRows*m_Oversample, expt.data());
714 
716  m_NCols*m_Oversample,
717  m_NRows*m_Oversample, expt.data());
718 
720  m_NCols*m_Oversample,
721  m_NRows*m_Oversample, expt.data());
722 
723  if (m_PolarTransform) {
725  m_NCols*m_Oversample,
726  m_NRows*m_Oversample, expt.data());
727 
729  m_NCols*m_Oversample,
730  m_NRows*m_Oversample, expt.data());
731  }
732 
733  if (m_CachedRadialBinNumbers && m_CachedNormalization) {
734  m_CachedRadialBinNumbers -> clear();
735  m_CachedNormalization -> clear();
736 
738  m_CachedPolarBinNumbers -> clear();
739  }
740 
741  if (m_CachedPolarValues) {
742  m_CachedPolarValues -> clear();
743  }
744 
746  expt->printMessage(tr("Threaded integration disabled because of user supplied functions"));
747 
748  m_ThreadCount = 1;
749 
751  }
752 
753  m_RFirst = true;
754  m_CFirst = true;
755 
756  // Step one fills m_CachedRadialValues ( & m_CachedPolarValues if 2D)
757  // and sets m_RMin, m_RMax (& m_CMin and m_CMax) to range of values
758 
759  if (m_ThreadCount == 1) {
761  } else {
762  QVector< QFuture<void> > res;
763 
764  for (int i=0; i<m_ThreadCount; i++) {
765  res.append(QtConcurrent::run(this, &QxrdIntegratorCache::partialIntegrationStep1, i, m_ThreadCount));
766  }
767 
768  for (int i=0; i<m_ThreadCount; i++) {
769  res[i].waitForFinished();
770  }
771  }
772 
774 
775  if (m_RStep == 0) {
777 
778  if (m_NRSteps <= 0) {
779  m_NRSteps = 512;
780  }
781 
783  } else {
785  }
786 
787  if (m_HasChi) {
789 
790  if (m_CStep == 0) {
792 
793  if (m_NCSteps <= 0) {
794  m_NCSteps = 512;
795  }
796 
798  } else {
800  }
801  }
802 
804  expt->printMessage(tr("1st stage complete after %1 msec").arg(tic.elapsed()));
805  }
806 
807  // Step two calculates the bin numbers and stores them in m_CachedRadialBinNumbers
808  // and m_CachedPolarBinNumbers
809 
810  if (m_ThreadCount == 1) {
812  } else {
813  QVector< QFuture<void> > res;
814 
815  for (int i=0; i<m_ThreadCount; i++) {
816  res.append(QtConcurrent::run(this, &QxrdIntegratorCache::partialIntegrationStep2, i, m_ThreadCount));
817  }
818 
819  for (int i=0; i<m_ThreadCount; i++) {
820  res[i].waitForFinished();
821  }
822  }
823 
824  if (m_HasChi) {
826  } else {
828  }
829 
831  expt->printMessage(tr("2nd stage complete after %1 msec").arg(tic.elapsed()));
832  }
833 
834  m_CacheFillLevel.fetchAndStoreOrdered(m_NPix);
835 
838  }
839  }
840 
842  expt->printMessage(tr("QxrdIntegratorCache::performIntegration - cache finished"));
843  }
844  }
845 
846  while (m_CacheFillLevel.fetchAndAddOrdered(0) < m_CacheFullLevel.fetchAndAddOrdered(0)) {
848  expt->printMessage(tr("QxrdIntegratorCache::performIntegration - waiting for cache [%1,%2]")
849  .arg(m_CacheFillLevel.fetchAndAddOrdered(0))
850  .arg(m_CacheFullLevel.fetchAndAddOrdered(0)));
851  }
852 
854  }
855 
856  if (m_CacheFillLevel.fetchAndAddOrdered(0) != m_CacheFullLevel.fetchAndAddOrdered(0)) {
857  expt->printMessage(tr("QxrdIntegratorCache::performIntegration - anomalous cache [%1,%2]")
858  .arg(m_CacheFillLevel.fetchAndAddOrdered(0))
859  .arg(m_CacheFullLevel.fetchAndAddOrdered(0)));
860  } else {
862  expt->printMessage(tr("QxrdIntegratorCache::performIntegration - use cache"));
863  }
864 
865  m_Integral.resize(m_ResultSize);
866  m_SumValue.resize(m_ResultSize);
867 
868  if (m_ThreadCount == 1) {
869  partialIntegrationStep3(0, 1, dimg, mask, normalize);
870  } else {
871  QVector< QFuture<void> > res;
872 
873  for (int i=0; i<m_ThreadCount; i++) {
874  res.append(QtConcurrent::run(this, &QxrdIntegratorCache::partialIntegrationStep3,
875  i, m_ThreadCount, dimg, mask, normalize));
876  }
877 
878  for (int i=0; i<m_ThreadCount; i++) {
879  res[i].waitForFinished();
880  }
881  }
882 
884  expt->printMessage(tr("Stage 3 complete after %1 msec").arg(tic.elapsed()));
885  }
886 
887  double scalingFactor = m_ScalingFactor;
888 
889  if (m_SelfNormalization) {
890  double nsum = 0, ninteg = 0;
891 
892  for(int ir=0; ir<m_ResultSize; ir++) {
893  int sv = m_SumValue[ir];
894 
895  if (sv > 0) {
896  double xv = m_RMin + (ir+0.5)*m_RStep;
897 
899  nsum += sv;
900  ninteg += m_Integral[ir];
901  }
902  }
903  }
904 
905  if ((nsum > 0) && (ninteg != 0)) {
906  scalingFactor = m_ScalingFactor * nsum / ninteg;
907  }
908  }
909 
910  if (m_HasChi) {
911  QcepDoubleImageDataPtr img = qSharedPointerDynamicCast<QcepDoubleImageData>(res);
912 
913  img->resize(m_NRSteps, m_NCSteps);
914 
915  img->set_HStart(m_RadialStart);
916  img->set_HStep(m_RStep);
917  img->set_VStart(m_PolarStart);
918  img->set_VStep(m_CStep);
919 
920  img->set_HLabel(XLabel());
921  img->set_HUnits(XUnits());
922  img->set_VLabel(YLabel());
923  img->set_VUnits(YUnits());
924 
925  img->set_Title(dimg->get_Title());
926 
927  for (int y=0; y<m_NCSteps; y++) {
928  for (int x=0; x<m_NRSteps; x++) {
929  int bin = y*m_NRSteps + x;
930 
931  int sv = m_SumValue[bin];
932  double v = m_Integral[bin];
933 
934  if (sv > 0) {
935  img->setValue(x,y, scalingFactor*normVal*v/sv);
936  } else {
937  img->setValue(x,y, qQNaN());
938  }
939  }
940  }
941 
942  img->dataObjectChanged();
943  } else {
944  QcepIntegratedDataPtr integ = qSharedPointerDynamicCast<QcepIntegratedData>(res);
945 
946  if (integ) {
947  integ -> resize(0);
948  integ -> set_Center(m_CenterX, m_CenterY);
949 
950  for(int ir=0; ir<m_ResultSize; ir++) {
951  int sv = m_SumValue[ir];
952 
953  if (sv > 0) {
954  double xv = m_RadialStart + (ir+0.5)*m_RStep;
955 
956  if (normalize) {
957  integ -> append(xv, scalingFactor*normVal*m_Integral[ir]/sv);
958  } else {
959  integ -> append(xv, scalingFactor*normVal*m_Integral[ir]/sv*(ir*oversampleStep+halfOversampleStep));
960  }
961  }
962  }
963 
964  integ->set_XUnitsLabel(XLabel());
965  integ->set_Oversample(m_Oversample);
966  // Integrate entirely out of cache
967  }
968  }
969  }
970 
971  expt->printMessage(tr("Integration of %1 took %2 msec")
972  .arg(dimg->get_Title())
973  .arg(tic.restart()));
974  } else {
975  expt->printMessage(tr("QxrdIntegratorCache::performIntegration - integration failed"));
976  }
977  }
978 }
979 
981 {
983 
984  if (exp) {
985  QxrdScriptEnginePtr engine = exp->scriptEngine();
986 
987  if (engine) {
988  engine->lock();
989 
990  m_UserGeometryFunctionValue = QScriptValue();
991  m_UserAbsorptionFunctionValue = QScriptValue();
992 
993  if (m_EnableUserGeometry) {
994  engine->evaluate(m_UserGeometryScript);
995 
997 
998  if (!m_UserGeometryFunctionValue.isFunction()) {
999  m_UserGeometryFunctionValue = engine->globalObject().property(m_UserGeometryFunctionValue.toString());
1000  }
1001 
1002  if (m_UserGeometryFunctionValue.isFunction()) {
1003  exp->printMessage(tr("Using User Geometry Function %1").arg(m_UserGeometryFunctionValue.toString()));
1004  } else {
1005  exp->printMessage(tr("User Geometry Function %1 is not a function").arg(m_UserGeometryFunctionValue.toString()));
1006  }
1007  }
1008 
1009  if (m_EnableUserAbsorption) {
1010  engine->evaluate(m_UserAbsorptionScript);
1011 
1013 
1014  if (!m_UserAbsorptionFunctionValue.isFunction()) {
1015  m_UserAbsorptionFunctionValue = engine->globalObject().property(m_UserAbsorptionFunctionValue.toString());
1016  }
1017 
1018  if (m_UserAbsorptionFunctionValue.isFunction()) {
1019  exp->printMessage(tr("Using User Absorption Function %1").arg(m_UserAbsorptionFunctionValue.toString()));
1020  } else {
1021  exp->printMessage(tr("User Absorption Function %1 is not a function").arg(m_UserAbsorptionFunctionValue.toString()));
1022  }
1023  }
1024  }
1025  }
1026 }
1027 
1029 {
1031 
1032  m_UserGeometryFunctionValue = QScriptValue();
1033  m_UserAbsorptionFunctionValue = QScriptValue();
1034 
1035  if (exp) {
1036  QxrdScriptEnginePtr engine = exp->scriptEngine();
1037 
1038  if (engine) {
1039  engine->unlock();
1040 
1041  if (m_EnableUserGeometry) {
1042  exp->printMessage(tr("User Geometry Function Completed"));
1043  }
1044 
1045  if (m_EnableUserAbsorption) {
1046  exp->printMessage(tr("User Absorption Function Completed"));
1047  }
1048  }
1049  }
1050 }
1051 
1053 {
1054  return m_CachedRadialBinNumbers;
1055 }
1056 
1058 {
1059  return m_CachedNormalization;
1060 }
QSharedPointer< QxrdExperiment > QxrdExperimentPtr
QSharedPointer< QxrdCenterFinder > QxrdCenterFinderPtr
QcepDoubleImageDataPtr m_CachedRadialValues
qint64 qcepDebug(int cond)
Definition: qcepdebug.cpp:26
QxrdIntegratorCache(QxrdExperimentWPtr exp, QxrdIntegratorWPtr integ, QxrdPolarTransformWPtr xform, QxrdCenterFinderWPtr cf)
QWeakPointer< QxrdCenterFinder > QxrdCenterFinderWPtr
QcepInt32ImageDataPtr m_CachedPolarBinNumbers
void performIntegration(QcepDataObjectPtr res, QcepDoubleImageDataPtr dimg, QcepMaskDataPtr mask, int normalize)
QSharedPointer< QxrdScriptEngine > QxrdScriptEnginePtr
QScriptValue m_UserGeometryFunctionValue
QcepDoubleImageDataPtr m_CachedPolarValues
static void getQChi(double xCenter, double yCenter, double distance, double energy, double xPixel, double yPixel, double pixelLength, double pixelHeight, double rotation, double cos_beta, double sin_beta, double cos_alpha, double sin_alpha, double cos_rotation, double sin_rotation, double *q, double *chi)
void partialIntegrationStep3(int i, int n, QcepDoubleImageDataPtr dimg, QcepMaskDataPtr mask, int normalize)
QWeakPointer< QxrdExperiment > QxrdExperimentWPtr
double getR(double x, double y)
QSharedPointer< QcepIntegratedData > QcepIntegratedDataPtr
double getChi(double x, double y)
static QcepDoubleImageDataPtr newDoubleImage(AllocationStrategy strat, int width, int height, QcepObject *parent)
double XValue(double x, double y)
void partialIntegrationStep1(int i, int n)
QSharedPointer< QxrdPolarTransform > QxrdPolarTransformPtr
QVector< double > m_Integral
static void msleep(int msec)
QcepDoubleImageDataPtr m_CachedNormalization
double NormValue(double x, double y)
static double getTwoTheta(double xCenter, double yCenter, double distance, double xPixel, double yPixel, double pixelLength, double pixelHeight, double cos_beta, double sin_beta, double cos_rotation, double sin_rotation)
QList< double > QcepDoubleList
Definition: qcepmacros.h:28
QcepInt32ImageDataPtr m_CachedRadialBinNumbers
QcepInt32ImageDataPtr cachedGeometry()
QVector< double > m_SumValue
double YValue(double x, double y)
QSharedPointer< QxrdIntegrator > QxrdIntegratorPtr
QxrdIntegratorWPtr m_Integrator
static void usleep(int usec)
QScriptValue m_UserAbsorptionFunctionValue
QWeakPointer< QxrdPolarTransform > QxrdPolarTransformWPtr
QcepDoubleImageDataPtr cachedIntensity()
QWeakPointer< QxrdIntegrator > QxrdIntegratorWPtr
QSharedPointer< QcepDataObject > QcepDataObjectPtr
QSharedPointer< QcepInt32ImageData > QcepInt32ImageDataPtr
QxrdCenterFinderWPtr m_CenterFinder
QSharedPointer< QcepMaskData > QcepMaskDataPtr
double getTTH(double x, double y)
QxrdPolarTransformWPtr m_PolarTransform
double getQ(double x, double y)
static QcepInt32ImageDataPtr newInt32Image(AllocationStrategy strat, int width, int height, QcepObject *parent)
QxrdExperimentWPtr m_Experiment
double getDistance(double x, double y)
void partialIntegrationStep2(int i, int n)
QSharedPointer< QcepDoubleImageData > QcepDoubleImageDataPtr
static void sleep(int sec)