QXRD  0.11.16
qxrdcalibrant.cpp
Go to the documentation of this file.
1 #include "qxrdcalibrant.h"
2 #include "qxrdcalibrantlibrary.h"
5 #include "qcepsettingssaver.h"
6 #include "qxrdexperiment.h"
7 #include <QScriptEngine>
8 #include "qxrddebug.h"
9 
10 #include <qmath.h>
11 
13  : QcepObject("calibrant", NULL),
14  m_Index(QcepSettingsSaverWPtr(), this, "index", index, "Calibrant Index"),
15  m_IsUsed(saver, this, "isUsed", 0, "Is Calibrant used?"),
16  m_Flags(saver, this, "flags", 0, "Calibrant flags"),
17  m_Description(saver, this, "description", "Description", "Calibrant Description"),
18  m_Symmetry(saver, this, "symmetry", 0, "Calibrant Symmetry"),
19  m_A(saver, this, "a", 1, "calibrant a-axis"),
20  m_B(saver, this, "b", 1, "calibrant b-axis"),
21  m_C(saver, this, "c", 1, "calibrant c-axis"),
22  m_Alpha(saver, this, "alpha", 90, "calibrant alpha angle (deg)"),
23  m_Beta(saver, this, "beta", 90, "calibrant beta angle (deg)"),
24  m_Gamma(saver, this, "gamma", 90, "calibrant gamma angle (deg)"),
25  m_Experiment(exp),
27 {
28 
29 }
30 
32 {
33 
34 }
35 
37 {
38  return (get_Flags() & 1) == 0;
39 }
40 
41 QScriptValue QxrdCalibrant::toScriptValue(QScriptEngine *engine, const QxrdCalibrantWPtr &cal)
42 {
43  return engine->newQObject(cal.data());
44 }
45 
46 void QxrdCalibrant::fromScriptValue(const QScriptValue &obj, QxrdCalibrantWPtr &cal)
47 {
48  QObject *qobj = obj.toQObject();
49 
50  if (qobj) {
51  QxrdCalibrant *qcal = qobject_cast<QxrdCalibrant*>(qobj);
52 
53  if (qcal) {
54  cal = QxrdCalibrantPtr(qcal);
55  }
56  }
57 }
58 
60 {
61  return QxrdCalibrantDSpacing(get_Index(), h,k,l, 1, sqrt(h*h + k*k + l*l), 0);
62 }
63 
65 public:
66  QxrdCalibrantQuadInt(int n=0, int h=-1, int k=-1, int l=-1) : m_N(n), m_H(h), m_K(k), m_L(l) {}
67 
68  int & n() { return m_N; }
69  int & h() { return m_H; }
70  int & k() { return m_K; }
71  int & l() { return m_L; }
72 
73 private:
74  int m_N;
75  int m_H;
76  int m_K;
77  int m_L;
78 };
79 
81 {
82  int s = get_Symmetry();
83 
84  switch (s) {
85 
86  case SimpleCubic:
87  case BodyCenteredCubic:
88  case FaceCenteredCubic:
89  case DiamondCubic:
90  return dSpacingsCubic(energy);
91 
92  case Hexagonal:
93  case RHexagonal:
94  return dSpacingsHexagonal(energy);
95 
96  default:
97  return QxrdCalibrantDSpacings();
98  }
99 }
100 
102 {
103  int s = get_Symmetry();
104  double a = get_A();
105  double lambda = (energy>100 ? 12398.4187/energy : energy);
106 
107  int mmax = 2.0*a/lambda + 1;
108 
109 // if (qcepDebug(DEBUG_CALIBRANT)) {
110 // printMessage(tr("mmax = %1").arg(mmax));
111 // }
112 
113  QVector<QxrdCalibrantQuadInt> ex(mmax*mmax);
114 
115  for (int h=1; h<=mmax; h++) {
116  for (int k=0; k<=h; k++) {
117  for (int l=0; l<=k; l++) {
118  int r = h*h+k*k+l*l;
119 
120  if (r < mmax*mmax) {
121  bool ok=false;
122 
123  switch (s) {
124  case SimpleCubic: // Simple cubic - all OK
125  ok = true;
126  break;
127 
128  case BodyCenteredCubic: // BCC h+k+l even
129  ok = ((h + k + l) % 2) == 0;
130  break;
131 
132  case FaceCenteredCubic: // FCC h,k,l all even or all odd
133  {
134  int n = h%2 + k%2 + l%2;
135  ok = (n==0) || (n==3);
136  }
137  break;
138 
139  case DiamondCubic:
140  {
141  int nn = h%2 + k%2 + l%2;
142 
143  if (nn==0 || nn==3) { // If nn==0 - all even, nn==3 - all odd
144  int n = (h + k + l);
145 
146  if (n%2 == 0) {
147  ok = (n%4 == 0);
148  } else {
149  ok = true;
150  }
151  }
152  }
153  break;
154  }
155 
156  if (ok) {
157  if (ex[r].n() == 0) {
158  ex[r] = QxrdCalibrantQuadInt(1, h,k,l);
159  } else {
160  ex[r].n()++;
161  }
162  }
163  }
164  }
165  }
166  }
167 
169 
170  for (int i=1; i<mmax*mmax; i++) {
171  QxrdCalibrantQuadInt e = ex[i];
172  if (e.n() > 0) {
173  double d = a/sqrt(i);
174  double tth = 2.0*asin(lambda/(2.0*d))*180.0/M_PI;
175 
176  if (tth <= 90) {
177  pts.append(QxrdCalibrantDSpacing(get_Index(), e.h(), e.k(), e.l(), e.n(), d, tth));
178 
179  if (qcepDebug(DEBUG_CALIBRANT)) {
180  printMessage(tr("%1(%2): [%3,%4,%5], d:%6, tth:%7").arg(i).arg(e.n()).arg(e.h()).arg(e.k()).arg(e.l()).arg(d).arg(tth));
181  }
182  }
183  }
184  }
185 
186  return pts;
187 }
188 
190 {
191  return d1.tth() < d2.tth();
192 }
193 
195 {
196  int s = get_Symmetry();
197  double a = get_A();
198  double c = get_C();
199 
200  double lambda = (energy>100 ? 12398.4187/energy : energy);
201 
202  int hkmax = 2.0*a/lambda + 1;
203  int lmax = 2.0*c/lambda + 1;
204 
205 // if (qcepDebug(DEBUG_CALIBRANT)) {
206 // printMessage(tr("mmax = %1").arg(mmax));
207 // }
208 
210 
211  int lmin = 0;
212  if (s == RHexagonal) {
213  lmin = -lmax;
214  }
215 
216  for (int l=lmin; l<=lmax+1; l++) {
217  for (int k=0; k<=hkmax+1; k++) {
218 
219  int hmin=k;
220  if (l<0) {
221  hmin += 1;
222  }
223 
224  for (int h=hmin; h<=hkmax+1; h++) {
225  if (h || k || l) {
226  int ok = false;
227 
228  switch (s) {
229  case RHexagonal:
230  ok = ((-h+k+l)%3 == 0);
231  break;
232  case Hexagonal:
233  ok = true;
234  break;
235  }
236 
237  if (ok) {
238  double d = 1.0/sqrt((4.0/3.0)*(h*h + h*k + k*k)/(a*a) + (l*l)/(c*c));
239  double tth = 2.0*asin(lambda/(2.0*d))*180.0/M_PI;
240 
241  if (tth < 90) {
242  pts.insertUnique(get_Index(), h,k,l,d,tth);
243  }
244  }
245  }
246  }
247  }
248  }
249 
250  qSort(pts.begin(), pts.end(), lessThan);
251 
252  return pts;
253 }
254 
QWeakPointer< QxrdCalibrant > QxrdCalibrantWPtr
qint64 qcepDebug(int cond)
Definition: qcepdebug.cpp:26
void insertUnique(int index, int h, int k, int l, double d, double tth)
QxrdCalibrantDSpacings dSpacingsHexagonal(double energy)
QxrdCalibrantDSpacing dSpacing(int h, int k, int l)
bool lessThan(const QxrdCalibrantDSpacing &d1, const QxrdCalibrantDSpacing &d2)
QWeakPointer< QxrdExperiment > QxrdExperimentWPtr
QSharedPointer< QxrdCalibrant > QxrdCalibrantPtr
static void fromScriptValue(const QScriptValue &obj, QxrdCalibrantWPtr &cal)
QxrdCalibrant(QcepSettingsSaverWPtr saver, QxrdExperimentWPtr exp, QxrdCalibrantLibraryWPtr lib, int index)
QxrdCalibrantLibraryWPtr m_CalibrantLibrary
Definition: qxrdcalibrant.h:94
QWeakPointer< QxrdCalibrantLibrary > QxrdCalibrantLibraryWPtr
QxrdCalibrantQuadInt(int n=0, int h=-1, int k=-1, int l=-1)
static QScriptValue toScriptValue(QScriptEngine *engine, const QxrdCalibrantWPtr &cal)
QxrdCalibrantDSpacings dSpacingsCubic(double energy)
virtual void printMessage(QString msg, QDateTime dt=QDateTime::currentDateTime()) const
Definition: qcepobject.cpp:84
QxrdExperimentWPtr m_Experiment
Definition: qxrdcalibrant.h:93
QxrdCalibrantDSpacings dSpacings(double energy)
QWeakPointer< QcepSettingsSaver > QcepSettingsSaverWPtr