5 #include <qwt_plot_marker.h>
10 #include <QtConcurrentMap>
23 # ifdef LINSOLVERS_RETAIN_MEMORY
25 # pragma message("LINSOLVERS_RETAIN_MEMORY is not safe in a multithreaded environment and should be turned off!")
27 # warning LINSOLVERS_RETAIN_MEMORY is not safe in a multithreaded environment and should be turned off!
33 m_CenterX(saver, this,
"centerX", 0,
"X Center"),
34 m_CenterY(saver, this,
"centerY", 0,
"Y Center"),
35 m_CenterStep(saver, this,
"centerStep", 1,
"Center Step"),
36 m_DetectorXPixelSize(saver, this,
"detectorXPixelSize", 200,
"Detector X Pixels (um)"),
37 m_DetectorYPixelSize(saver, this,
"detectorYPixelSize", 200,
"Detector Y Pixels (um)"),
38 m_DetectorDistance(saver, this,
"detectorDistance", 1000,
"Sample-Detector Distance (mm)"),
39 m_DetectorDistanceStep(saver, this,
"detectorDistanceStep", 100,
"Sample-Detector Distance Step (mm)"),
40 m_Energy(saver, this,
"energy", 20000,
"Beam Energy (eV)"),
41 m_ImplementTilt(saver, this,
"implementTilt", false,
"Implement Detector Tilt?"),
42 m_DetectorTilt(saver, this,
"detectorTilt", 0,
"Tilt Angle (deg)"),
43 m_DetectorTiltStep(saver, this,
"detectorTiltStep", 0.1,
"Tilt Angle Step(deg)"),
44 m_TiltPlaneRotation(saver, this,
"tiltPlaneRotation", 90,
"Tilt Plane Rotation (deg)"),
45 m_TiltPlaneRotationStep(saver, this,
"tiltPlaneRotationStep", 10,
"Tilt Plane Rotation Step (deg)"),
48 m_RingRadius(saver, this,
"ringRadius", 0.0,
"Estimated Powder Ring Radius"),
49 m_RingRadiusA(saver, this,
"ringRadiusA", 0.0,
"Estimated Powder Ellipse Major Axis Radius"),
50 m_RingRadiusB(saver, this,
"ringRadiusB", 0.0,
"Estimated Powder Ellipse Minor Axis Radius"),
51 m_RingRotation(saver, this,
"ringRotation", 0.0,
"Estimated Powder Ellipse Major Axis Rotation"),
52 m_PeakFitRadius(saver, this,
"peakFitRadius", 10,
"Half size of fitted area for peak fitting"),
53 m_PeakHeight(saver, this,
"peakHeight", 100.0,
"Height of fitted peak"),
54 m_PeakCenterX(saver, this,
"peakCenterX", 0,
"X Center of fitted peak"),
55 m_PeakCenterY(saver, this,
"peakCenterY", 0,
"Y Center of fitted peak"),
56 m_PeakWidth(saver, this,
"peakWidth", 2.0,
"Width of fitted peak"),
57 m_PeakBackground(saver, this,
"peakBackground", 0,
"Background Height of fitted peak"),
58 m_PeakBackgroundX(saver, this,
"peakBackgroundX", 0,
"X Slope of Background"),
59 m_PeakBackgroundY(saver, this,
"peakBackgroundY", 0,
"Y Slope of Background"),
60 m_PeakFitDebug(saver, this,
"peakFitDebug", false,
"Debug Print for peak fitting"),
61 m_PeakFitIterations(saver, this,
"peakFitIterations", 200,
"Max Iterations during fitting"),
62 m_RingAngles(saver, this,
"ringAngles",
QcepDoubleVector(),
"Diffraction ring angles"),
63 m_RingAngleTolerance(saver, this,
"ringAngleTolerance", 0.1,
"Diffraction ring angle tolerance"),
64 m_PowderFitOptions(saver, this,
"powderFitOptions", 0,
"Powder fitting options"),
65 m_RingIndex(saver, this,
"ringIndex", 0,
"Fitted Powder Ring Index"),
66 m_SubtractRingAverages(saver, this,
"subtractRingAverages", false,
"Plot deviations of each ring from average"),
67 m_RingAverageDisplacement(saver, this,
"ringAverageDisplacement", 0.0,
"Extra displacement between curves in ring radius plot"),
68 m_FittedWidthMin(saver, this,
"fittedWidthMin", 0.5,
"Minimum acceptable fitted width (pixels)"),
69 m_FittedWidthMax(saver, this,
"fittedWidthMax", 3.0,
"Maximum acceptable fitted width (pixels)"),
70 m_FittedHeightMinRatio(saver, this,
"fittedHeightMinRatio", 0.25,
"Minimum acceptable peak height ratio"),
71 m_FittedPositionMaxDistance(saver, this,
"fittedPositionMaxDistance", 2.0,
"Maximum acceptable fitted position shift (pixels)"),
72 m_FitPowderPointPosition(saver, this,
"fitPowderPointPosition", true,
"Fit to nearby peak when adding powder points individually"),
75 qRegisterMetaType<QPointF>(
"QPointF");
94 printf(
"Deleting center finder\n");
114 ht =
m_Data->get_Height();
157 return getTTH(pt.x(), pt.y());
162 if (get_ImplementTilt()) {
163 double beta = get_DetectorTilt()*M_PI/180.0;
164 double rot = get_TiltPlaneRotation()*M_PI/180.0;
166 return getTwoTheta(get_CenterX(), get_CenterY(), get_DetectorDistance(),
167 x, y, get_DetectorXPixelSize(), get_DetectorYPixelSize(),
168 cos(beta), sin(beta), cos(rot), sin(rot));
170 return getTwoTheta(get_CenterX(), get_CenterY(), get_DetectorDistance(),
171 x, y, get_DetectorXPixelSize(), get_DetectorYPixelSize(),
179 double beta = get_DetectorTilt()*M_PI/180.0;
180 double rot = get_TiltPlaneRotation()*M_PI/180.0;
182 if (get_ImplementTilt()) {
187 get_DetectorXPixelSize(), get_DetectorYPixelSize(),
188 rot, cos(beta), sin(beta), 1.0, 0.0, cos(rot), sin(rot),
194 get_DetectorXPixelSize(), get_DetectorYPixelSize(),
195 rot, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0,
204 return getQ(pt.x(), pt.y());
210 double beta = get_DetectorTilt()*M_PI/180.0;
211 double rot = get_TiltPlaneRotation()*M_PI/180.0;
213 if (get_ImplementTilt()) {
214 getQChi(get_CenterX(), get_CenterY(), get_DetectorDistance(),
216 x, y, get_DetectorXPixelSize(), get_DetectorYPixelSize(),
217 rot, cos(beta), sin(beta), 1.0, 0.0, cos(rot), sin(rot),
220 getQChi(get_CenterX(), get_CenterY(), get_DetectorDistance(),
222 x, y, get_DetectorXPixelSize(), get_DetectorYPixelSize(),
223 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0,
232 return getChi(pt.x(), pt.y());
238 double beta = get_DetectorTilt()*M_PI/180.0;
239 double rot = get_TiltPlaneRotation()*M_PI/180.0;
241 if (get_ImplementTilt()) {
242 getQChi(get_CenterX(), get_CenterY(), get_DetectorDistance(),
244 x, y, get_DetectorXPixelSize(), get_DetectorYPixelSize(),
245 rot, cos(beta), sin(beta), 1.0, 0.0, cos(rot), sin(rot),
248 getQChi(get_CenterX(), get_CenterY(), get_DetectorDistance(),
250 x, y, get_DetectorXPixelSize(), get_DetectorYPixelSize(),
251 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0,
260 return getDist(pt.x(), pt.y());
267 return get_DetectorDistance()/cos(tth*M_PI/180.0);
272 return getR(pt.x(), pt.y());
277 double tth =
getTTH(x, y);
278 double r = get_DetectorDistance()*tan(tth*M_PI/180.0);
285 if (get_FitPowderPointPosition()) {
297 exp->printMessage(msg, ts);
306 exp->statusMessage(msg, ts);
314 int niter = fitter.
fit();
320 message.append(tr(
"Circle Fitting Succeeded after %1 iterations\n").arg(niter));
321 message.append(tr(
"Old Center = [%1,%2]\n").arg(get_CenterX()).arg(get_CenterY()));
322 message.append(tr(
"New Center = [%1,%2], New Radius = %3\n").arg(fitter.
fittedX()).arg(fitter.
fittedY()).arg(fitter.
fittedR()));
323 double dx = fitter.
fittedX() - get_CenterX();
324 double dy = fitter.
fittedY() - get_CenterY();
325 message.append(tr(
"Moved by [%1,%2] = %3\n").arg(dx).arg(dy).arg(sqrt(dx*dx + dy*dy)));
327 message.append(tr(
"Circle Fitting Failed: Reason = %1\n").arg(fitter.
reasonString()));
334 if (app && app->get_GuiWanted()) {
336 message.append(tr(
"Do you want to update the beam centering parameters?"));
338 if (QMessageBox::question(NULL,
"Update Fitted Center?", message, QMessageBox::Ok | QMessageBox::No, QMessageBox::Ok) == QMessageBox::Ok) {
342 QMessageBox::information(NULL,
"Fitting Failed", message);
344 }
else if (niter >= 0){
351 set_RingRadius(fitter.
fittedR());
359 int niter = fitter.
fit();
365 message.append(tr(
"Ellipse Fitting Succeeded after %1 iterations\n").arg(niter));
366 message.append(tr(
"Old Center = [%1,%2]\n").arg(get_CenterX()).arg(get_CenterY()));
367 message.append(tr(
"New Center = [%1,%2], New Radii = %3,%4\n")
369 message.append(tr(
"Major Axis rotation = %1 deg\n").arg(fitter.
fittedRot()*180.0/M_PI));
371 double dx = fitter.
fittedX() - get_CenterX();
372 double dy = fitter.
fittedY() - get_CenterY();
373 message.append(tr(
"Moved by [%1,%2] = %3\n").arg(dx).arg(dy).arg(sqrt(dx*dx + dy*dy)));
375 message.append(tr(
"Ellipse Fitting Failed: Reason = %1\n").arg(fitter.
reasonString()));
382 if (app && app->get_GuiWanted()) {
384 message.append(tr(
"Do you want to update the beam centering parameters?"));
385 if (QMessageBox::question(NULL,
"Update Fitted Center?", message, QMessageBox::Ok | QMessageBox::No, QMessageBox::Ok) == QMessageBox::Ok) {
389 QMessageBox::information(NULL,
"Fitting Failed", message);
391 }
else if (niter >= 0){
398 set_RingRadiusA(fitter.
fittedA());
399 set_RingRadiusB(fitter.
fittedB());
408 QVector<QxrdFitterRingEllipse> fits;
410 for (
int i=0; i<nrings; i++) {
415 for (
int i=0; i<nrings; i++) {
421 fitDone.waitForFinished();
426 for (
int i=0; i<nrings; i++) {
430 printMessage(tr(
"Fitted Ring %1: x: %2, y: %3, a: %4, b: %5, rot: %6, rzn: %7")
441 set_FittedRings(pts);
451 double newLambda = 2.0*dlatt*sin(th*M_PI/180.0);
452 double newEnergy = 12398.4187/newLambda;
456 message.append(tr(
"Ring %1 average TTH = %2\n").arg(n).arg(tth));
457 message.append(tr(
"Calibrant Peak %1 TTH = %2\n").arg(n).arg(caltth));
458 message.append(tr(
"Adjust Energy from %1 to %2\n").arg(get_Energy()).arg(newEnergy));
459 message.append(tr(
"to improve fit to ring %1").arg(n));
461 if (QMessageBox::question(NULL,
"Update Energy?",
462 message, QMessageBox::Ok | QMessageBox::No, QMessageBox::Ok)
463 == QMessageBox::Ok) {
464 set_Energy(newEnergy);
472 double d = r/tan(tth*M_PI/180.0);
476 message.append(tr(
"Ring %1 average radius = %2\n").arg(n).arg(r));
477 message.append(tr(
"Calibrant Peak %1 TTH = %2\n").arg(n).arg(tth));
478 message.append(tr(
"Adjust sample - detector distance from %1 to %2\n")
479 .arg(get_DetectorDistance()).arg(d));
480 message.append(tr(
"to improve fit to ring %1").arg(n));
482 if (QMessageBox::question(NULL,
"Update Detector Distance?",
483 message, QMessageBox::Ok | QMessageBox::No, QMessageBox::Ok)
484 == QMessageBox::Ok) {
485 set_DetectorDistance(d);
491 return get_MarkedPoints().value(i);
500 for (
int i=0; i<pts.count(); i++) {
502 double dist = sqrt(pow(x-pt.
x(), 2) + pow(y-pt.
y(), 2));
504 if (nearest == -1 || dist < nearestDist) {
527 set_MarkedPoints(pts);
533 m_MarkedPoints.appendValue(
QxrdPowderPoint(get_RingIndex(), 0, 0, x,y, 0,0,0));
538 m_MarkedPoints.appendValue(
QxrdPowderPoint(n1,n2,n3, x, y, r1, r2, az));
550 }
else if (pt.
n1() > n) {
555 set_MarkedPoints(res);
564 for (
int i=0; i<pts.count(); i++) {
565 if (pts[i].n1() == n) {
571 printMessage(tr(
"Disabled %1 points in ring %2").arg(np).arg(n));
573 set_MarkedPoints(pts);
582 for (
int i=0; i<pts.count(); i++) {
583 if (pts[i].n1() == n) {
588 printMessage(tr(
"Enabled %1 points in ring %2").arg(np).arg(n));
590 set_MarkedPoints(pts);
595 m_MarkedPoints.clear();
607 double r =
getR(pt.
x(), pt.
y());
614 if (maxR > 0 && maxR < 10000) {
615 int nbins = (int) maxR + 5;
616 QVector<int> npts(nbins);
621 double r =
getR(pt.
x(), pt.
y());
627 for (
int i=0; i<nbins-1; i++) {
629 if (npts[i+1] == 0) {
630 npts[i] = ringIndex++;
645 for (
int i=0; i<n; i++) {
648 double r =
getR(pt.
x(), pt.
y());
649 int idx = npts[(int) r];
654 set_MarkedPoints(pts);
655 set_RingIndex(ringIndex);
661 printMessage(tr(
"centering.fitPeakNear(%1,%2)").arg(x).arg(y));
667 set_PeakCenterX(fit.
fittedX());
668 set_PeakCenterY(fit.
fittedY());
687 printMessage(tr(
"centering.fitRingNear(%1,%2)").arg(x0).arg(y0));
693 set_PeakCenterX(fit.
fittedX());
694 set_PeakCenterY(fit.
fittedY());
713 printMessage(tr(
"centering.traceRingNear(%1,%2,%3)").arg(x0).arg(y0).arg(step));
716 double xc = get_CenterX();
717 double yc = get_CenterY();
720 double az = atan2(dy, dx);
722 double r = sqrt(dx*dx + dy*dy);
724 double dr = get_PeakFitRadius();
729 printMessage(tr(
"Initial fit: az: %1, x: %2, y: %3, nx: %4, ny: %5, wd: %6, ht: %7, rz: %8")
734 double bkgd = (
imageValue(xc+(r+dr)*cos(az), yc+(r+dr)*sin(az))
735 +
imageValue(xc+(r-dr)*cos(az), yc+(r-dr)*sin(az)))/2.0;
739 int width = 0, height = 0;
742 width =
m_Data->get_Width()+1;
743 height =
m_Data->get_Height()+1;
746 QVector<QxrdFitterRingPoint> fits;
749 if (x >= 0 && y >= 0 && x <= width && y <= height) {
755 printMessage(tr(
"Fit Ring Near: az: %1, x: %2, y: %3, nx: %4, ny: %5, wd: %6, ht: %7, rz: %8")
765 r = sqrt((x-xc)*(x-xc) + (y-yc)*(y-yc));
772 if ((az-az0) >= 2*M_PI)
break;
774 if ((az-az0) <= -2*M_PI)
break;
781 int npts = fits.count();
788 for(
int i=0; i<fits.count(); i++) {
796 nreason[fit.
reason()] += 1;
808 scan = data->newColumnScan(tr(
"fitted/ring%1").arg(get_RingIndex()));
814 scan->appendColumn(
"i");
815 scan->appendColumn(
"index");
816 scan->appendColumn(
"Reason");
817 scan->appendColumn(
"X0");
818 scan->appendColumn(
"Y0");
819 scan->appendColumn(
"pkht");
820 scan->appendColumn(
"bkgd");
821 scan->appendColumn(
"XFit");
822 scan->appendColumn(
"YFit");
823 scan->appendColumn(
"WdFit");
824 scan->appendColumn(
"HtFit");
825 scan->appendColumn(
"BkgdFit");
826 scan->appendColumn(
"BkgdXFit");
827 scan->appendColumn(
"BkgdYFit");
828 scan->appendColumn(
"RFit");
829 scan->appendColumn(
"AzFit");
830 scan->appendColumn(
"dx");
831 scan->appendColumn(
"dy");
832 scan->appendColumn(
"dr");
834 scan->resizeRows(fits.count());
836 for (
int i=0; i<fits.count(); i++) {
842 double dr = sqrt(dx*dx + dy*dy);
844 scan->setValue(col++, i, i);
845 scan->setValue(col++, i, fit.
index());
846 scan->setValue(col++, i, fit.
reason());
847 scan->setValue(col++, i, fit.
x0());
848 scan->setValue(col++, i, fit.
y0());
849 scan->setValue(col++, i, fit.
pkht());
850 scan->setValue(col++, i, fit.
bkgd());
851 scan->setValue(col++, i, fit.
fittedX());
852 scan->setValue(col++, i, fit.
fittedY());
858 scan->setValue(col++, i, fit.
fittedR());
859 scan->setValue(col++, i, fit.
fittedAz()*180.0/M_PI);
860 scan->setValue(col++, i, dx);
861 scan->setValue(col++, i, dy);
862 scan->setValue(col++, i, dr);
869 QString msg(tr(
"centering.traceRingNear : %1/%2 fitted points").arg(nok).arg(npts));
875 if (nreason[i] > 0) {
882 prop_RingIndex()->incValue(1);
883 set_MarkedPoints(pts);
892 appendPowderPoint(get_RingIndex(), -1, 0, x, y,
getR(x,y),
getR(x,y),
getChi(x,y));
893 prop_RingIndex()->incValue(1);
1032 if (i>=0 && i<pts.count()) {
1038 set_MarkedPoints(pts);
1050 if (i>=0 && i<get_MarkedPoints().count()) {
1051 QScriptValue val = eng->newObject();
1054 val.setProperty(
"n1", pt.
n1());
1055 val.setProperty(
"n2", pt.
n2());
1056 val.setProperty(
"x", pt.
x());
1057 val.setProperty(
"y", pt.
y());
1058 val.setProperty(
"r1", pt.
r1());
1059 val.setProperty(
"r2", pt.
r2());
1060 val.setProperty(
"az", pt.
az());
1067 return QScriptValue();
1080 QScriptValue val = eng->newArray();
1082 for (
int i=0; i<pts.count(); i++) {
1083 QScriptValue item = eng->newObject();
1086 item.setProperty(
"n1", pt.
n1());
1087 item.setProperty(
"n2", pt.
n2());
1088 item.setProperty(
"x", pt.
x());
1089 item.setProperty(
"y", pt.
y());
1090 item.setProperty(
"r1", pt.
r1());
1091 item.setProperty(
"r2", pt.
r2());
1092 item.setProperty(
"az", pt.
az());
1094 val.setProperty(tr(
"%1").arg(i), item);
1101 return QScriptValue();
1106 int n1 = val.property(
"n1").toInteger();
1107 int n2 = val.property(
"n2").toInteger();
1108 int n3 = val.property(
"n3").toInteger();
1109 double x = val.property(
"x").toNumber();
1110 double y = val.property(
"y").toNumber();
1111 double r1 = val.property(
"r1").toNumber();
1112 double r2 = val.property(
"r2").toNumber();
1113 double az = val.property(
"az").toNumber();
1127 return m_Data->value(x,y);
1137 return "Stopped by Small Gradient";
1141 return "Stopped by Small Dp";
1145 return "Stopped by iteration limit";
1149 return "Stopped by singular matrix";
1153 return "No further error reduction possible";
1157 return "Stopped by small ||e||^2";
1161 return "Stopped by invalid (i.e. NaN or Inf) function values";
1165 return "Unknown reason for failure";
1175 int n = pts.count();
1177 for (
int i=0; i<n; i++) {
1194 return get_MarkedPoints().count();
1204 if (pt.
n1() == r || r < 0) {
1214 return get_MarkedPoints().value(i);
1224 if (pt.
n1() == r || r < 0) {
1240 double sum = 0, npts = 0;
1245 sum +=
getR(pt.
x(), pt.
y());
1256 double sum = 0, npts = 0;
1261 sum +=
getQ(pt.
x(), pt.
y());
1272 double sum = 0, npts = 0;
1372 double res = qQNaN();
1380 res = dsp->calibrantDSpacing(n);
1389 double res = qQNaN();
1397 res = dsp->calibrantTTH(n);
1411 else if (p1->
x > p2->
x)
1424 return (a.
x != b.
x) || (a.
y != b.
y);
1427 static int nearby(
double x1,
double y1,
double x2,
double y2)
1429 double dx = x1 - x2;
1430 double dy = y1 - y2;
1432 return sqrt(dx*dx + dy*dy) < 100;
1445 res -> fill(nan(
""));
1447 int wd = res->get_Width();
1448 int ht = res->get_Height();
1456 for (
int i=0; i<np; i++) {
1462 double tth =
getTTH(x, y);
1464 double disp = get_DetectorDistance()*(tan(tth*M_PI/180.0)/tan(tthNom*M_PI/180.0)-1.0);
1492 pc.
x = 0; pc.
y = 0; pc.
z = f00.
value(0,0); verts.append(pc);
printMessage(tr(
"appended (%1,%2,%3)").arg(pc.
x).arg(pc.
y).arg(pc.
z));
1493 pc.
x = 0; pc.
y = ht; pc.
z = f01.
value(0,ht); verts.append(pc);
printMessage(tr(
"appended (%1,%2,%3)").arg(pc.
x).arg(pc.
y).arg(pc.
z));
1494 pc.
x = wd; pc.
y = 0; pc.
z = f10.
value(wd,0); verts.append(pc);
printMessage(tr(
"appended (%1,%2,%3)").arg(pc.
x).arg(pc.
y).arg(pc.
z));
1495 pc.
x = wd; pc.
y = ht; pc.
z = f11.
value(wd,ht); verts.append(pc);
printMessage(tr(
"appended (%1,%2,%3)").arg(pc.
x).arg(pc.
y).arg(pc.
z));
1499 std::sort(verts.begin(), verts.end(),
compareXYX);
1501 int n = verts.count();
1505 for (
int i=0; i<n; i++) {
1507 uniq.append(verts[i]);
1511 int drop = verts.count() - uniq.count();
1514 printMessage(tr(
"Dropped %1 duplicated vertices").arg(drop));
1523 QVector<ITRIANGLE> tris(n*3);
1531 int ndup = 0, nMsg = 0;
1533 for (
int i=0; i<ntri; i++) {
1534 int p1 = tris[i].p1;
1535 int p2 = tris[i].p2;
1536 int p3 = tris[i].p3;
1545 double x1 = uniq[p1].x;
1546 double x2 = uniq[p2].x;
1547 double x3 = uniq[p3].x;
1548 double y1 = uniq[p1].y;
1549 double y2 = uniq[p2].y;
1550 double y3 = uniq[p3].y;
1551 double z1 = uniq[p1].z;
1552 double z2 = uniq[p2].z;
1553 double z3 = uniq[p3].z;
1555 double minX = qMax((
double) 0,floor(qMin(qMin(x1,x2),x3)));
1556 double maxX = qMin((
double) wd,ceil(qMax(qMax(x1,x2),x3)));
1557 double minY = qMax((
double) 0,floor(qMin(qMin(y1,y2),y3)));
1558 double maxY = qMin((
double) ht,ceil(qMax(qMax(y1,y2),y3)));
1560 double detT = (y2 - y3)*(x1 - x3) + (x3 - x2)*(y1 - y3);
1565 for (
double y=minY; y<=maxY; y++) {
1566 for (
double x=minX; x<=maxX; x++) {
1567 double l1 = ((y2 - y3)*(x - x3) + (x3 - x2)*(y - y3))/detT;
1568 double l2 = ((y3 - y1)*(x - x3) + (x1 - x3)*(y - y3))/detT;
1569 double l3 = 1 - l1 - l2;
1571 if (0 < l1 && l1 < 1.0 &&
1572 0 < l2 && l2 < 1.0 &&
1573 0 < l3 && l3 < 1.0) {
1574 double z = l1*z1 + l2*z2 + l3*z3;
1576 double val = res->getImageData(x,y);
1581 res -> setImageData(x,y, i);
1583 res -> setImageData(x,y, z);
1591 if (ndupt > 0 && nMsg++ < 50) {
1592 printMessage(tr(
"Triangle %1 : (%2,%3) - (%4,%5) - (%6,%7) : %8/%9 dups")
1594 .arg(uniq[p1].x).arg(uniq[p1].y)
1595 .arg(uniq[p2].x).arg(uniq[p2].y)
1596 .arg(uniq[p3].x).arg(uniq[p3].y)
1597 .arg(ndupt).arg(nptst));
1603 for (
int y=0; y<ht; y++) {
1604 for (
int x=0; x<wd; x++) {
1605 double val = res->getImageData(x,y);
1613 for (
int y=0; y<ht; y+=ht-1) {
1614 for (
int x=0; x<wd; x+=wd-1) {
1615 double val = res->getImageData(x,y);
1623 printMessage(tr(
"%1 duplicated points, %2 unset pixels").arg(ndup).arg(nunset));
1631 return engine->newQObject(proc.data());
1636 QObject *qobj = obj.toQObject();
QSharedPointer< QxrdExperiment > QxrdExperimentPtr
double getChi(double x, double y) const
virtual ~QxrdCenterFinder()
int getPowderPointN2(int i)
QSharedPointer< QxrdCenterFinder > QxrdCenterFinderPtr
double getTTH(double x, double y) const
void disablePowderRing(int n)
static double convertEnergyToWavelength(double energy)
qint64 qcepDebug(int cond)
QcepDoubleImageDataPtr data() const
int countPowderRingPoints() const
static int nearby(double x1, double y1, double x2, double y2)
void fitPowderCircle(int n=0)
static int XYZCompare(const void *v1, const void *v2)
double getQ(double x, double y) const
virtual void readSettings(QSettings *set, QString section)
void adjustDistance(int n)
void deletePowderPoints()
QSharedPointer< QcepDataColumnScan > QcepDataColumnScanPtr
void addPoint(double x, double y, double z)
QSharedPointer< QxrdDataProcessor > QxrdDataProcessorPtr
double getR(double x, double y) const
void calculateCalibration()
QSharedPointer< QxrdScriptEngine > QxrdScriptEnginePtr
int countPowderRings() const
double fittedWidth() const
void setData(QcepDoubleImageDataPtr data)
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)
double calibrantDSpacing(int n)
int Triangulate(int nv, XYZ *pxyz, ITRIANGLE *v, int *ntri)
void printMessage(QString msg, QDateTime ts=QDateTime::currentDateTime()) const
QWeakPointer< QxrdExperiment > QxrdExperimentWPtr
static QString levmarFailureReason(int n)
bool traceRingNear(double x0, double y0, double step=25.0)
void onPointSelected(QPointF pt)
void writeSettings(QSettings *settings, QString section)
QScriptValue getPowderPoint(int i)
static void fromScriptValue(const QScriptValue &obj, QxrdCenterFinderPtr &proc)
QVector< double > QcepDoubleVector
QScriptValue getPowderPoints()
double powderRingAverageQ(int r) const
bool missingRingNear(double x, double y)
static double convertTwoThetaToQ(double twoTheta, double wavelength)
static int differentVertices(const XYZ &a, const XYZ &b)
double getPowderPointY(int i)
static QScriptValue toScriptValue(QScriptEngine *engine, const QxrdCenterFinderPtr &proc)
QPointF getXY(double tth, double chi)
double powderRingAverageTTH(int r) const
bool fitPeakNear(double x, double y)
QxrdCenterFinder(QcepSettingsSaverWPtr saver, QxrdExperimentWPtr expt)
void setPowderPoint(int i, int n1, int n2, int n3, double x, double y, double r1, double r2, double az)
QcepDoubleImageDataPtr m_Data
QSharedPointer< QxrdCalibrantDSpacings > QxrdCalibrantDSpacingsPtr
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)
double fittedBkgdX() const
double calibrantTTH(int n)
QxrdPowderPoint nearestPowderPoint(double x, double y)
void readSettings(QSettings *settings, QString section)
void onCenterChanged(QPointF pt)
QxrdPowderPoint powderRingPoint(int i) const
QxrdExperimentWPtr m_Experiment
bool fitRingNear(double x0, double y0)
QString reasonString() const
virtual void writeSettings(QSettings *set, QString section)
QxrdExperimentWPtr experiment() const
QuadInt(int n=0, int h=-1, int k=-1, int l=-1)
void normalizePowderRings()
void deletePowderRing(int n)
double powderRingAverageR(int r) const
static int compareXYX(const XYZ &a, const XYZ &b)
QcepApplication * g_Application
double getDist(double x, double y) const
void statusMessage(QString msg, QDateTime ts=QDateTime::currentDateTime()) const
QxrdPowderPoint powderPoint(int i)
int getPowderPointN1(int i)
int nearestPowderPointIndex(double x, double y)
void enablePowderRing(int n)
void valueChanged(double val, int index)
static void getXY(double xCenter, double yCenter, double distance, double energy, double q, double chi, 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 *xPixel, double *yPixel)
void appendPowderPoint(double x, double y)
QSharedPointer< QcepMaskData > QcepMaskDataPtr
void deletePowderPointNear(double x, double y)
double imageValue(double x, double y)
double fittedBkgd() const
double getPowderPointX(int i)
double fittedBkgdY() const
double fittedHeight() const
QSharedPointer< QcepDatasetModel > QcepDatasetModelPtr
void fitPowderEllipse(int n=0)
void valueChanged(bool val, int index)
QWeakPointer< QcepSettingsSaver > QcepSettingsSaverWPtr
QcepDoubleImageDataPtr newData()
double value(double x, double y)
QSharedPointer< QcepDoubleImageData > QcepDoubleImageDataPtr