FOX/ObjCryst++  1.10.X (development)
DiffractionDataSingleCrystal.cpp
1 /* ObjCryst++ Object-Oriented Crystallographic Library
2  (c) 2000-2002 Vincent Favre-Nicolin vincefn@users.sourceforge.net
3  2000-2001 University of Geneva (Switzerland)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /*
20 * source file for ObjCryst++ DiffractionData class
21 *
22 */
23 
24 //#include <cmath>
25 #include <cstdlib>
26 
27 #include <typeinfo>
28 
29 #include "ObjCryst/ObjCryst/DiffractionDataSingleCrystal.h"
30 #include "ObjCryst/ObjCryst/CIF.h"
31 #include "ObjCryst/Quirks/VFNDebug.h"
32 #include "ObjCryst/Quirks/VFNStreamFormat.h"
33 
34 #ifdef __WX__CRYST__
35 #include "ObjCryst/wxCryst/wxDiffractionSingleCrystal.h"
36 #endif
37 
38 #include <fstream>
39 #include <iomanip>
40 #include <stdio.h> //for sprintf()
41 
42 //#include <xmmintrin.h>
43 
44 #ifdef _MSC_VER // MS VC++ predefined macros....
45 #undef min
46 #undef max
47 #endif
48 
49 namespace ObjCryst
50 {
51 //######################################################################
52 // DiffractionDataSingleCrystal
53 //######################################################################
54 ObjRegistry<DiffractionDataSingleCrystal>
55  gDiffractionDataSingleCrystalRegistry("Global DiffractionDataSingleCrystal Registry");
56 
58 mHasObservedData(false),mScaleFactor(1.)
59 {
60  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::DiffractionDataSingleCrystal()",5)
61  this->InitRefParList();
62  this->InitOptions();
63  if(regist) gDiffractionDataSingleCrystalRegistry.Register(*this);
64  if(regist) gTopRefinableObjRegistry.Register(*this);
66  this->AddSubRefObj(mRadiation);
67 }
69 mHasObservedData(false),mScaleFactor(1.)
70 {
71  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::DiffractionDataSingleCrystal()",5)
72  this->InitRefParList();
73  this->SetCrystal(cryst);
74  this->InitOptions();
75  if(regist) gDiffractionDataSingleCrystalRegistry.Register(*this);
76  if(regist) gTopRefinableObjRegistry.Register(*this);
78  this->AddSubRefObj(mRadiation);
79 }
80 
82 ScatteringData(old),
83 mHasObservedData(old.mHasObservedData),mRadiation(old.mRadiation)
84 {
86  // Keep a copy as squared F(hkl), to enable fourier maps
87  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
90 
91  mObsSigma=old.mObsSigma;
92  mWeight=old.mWeight;
95  this->InitOptions();
96  mGroupOption.SetChoice(old.mGroupOption.GetChoice());
98  gTopRefinableObjRegistry.Register(*this);
100  this->AddSubRefObj(mRadiation);
101 }
102 
103 DiffractionDataSingleCrystal::~DiffractionDataSingleCrystal()
104 {
105  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::~DiffractionDataSingleCrystal()",5)
106  gDiffractionDataSingleCrystalRegistry.DeRegister(*this);
107  gTopRefinableObjRegistry.DeRegister(*this);
108 }
109 
111 {
112  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::CreateCopy()",5)
113  return new DiffractionDataSingleCrystal(*this);
114 }
115 
117 {
118  const static string className="DiffractionDataSingleCrystal";
119  return className;
120 }
121 
122 void DiffractionDataSingleCrystal::SetHklIobs(const CrystVector_long &h,
123  const CrystVector_long &k,
124  const CrystVector_long &l,
125  const CrystVector_REAL &iObs,
126  const CrystVector_REAL &sigma)
127 {
128  VFN_DEBUG_ENTRY("DiffractionDataSingleCrystal::SetHklIobs(h,k,l,i,s)",5)
129  mNbRefl=h.numElements();
130  mH.resize(mNbRefl);
131  mK.resize(mNbRefl);
132  mL.resize(mNbRefl);
133  mObsIntensity.resize(mNbRefl);
134  mObsSigma.resize(mNbRefl);
135  mWeight.resize(mNbRefl);
136  mMultiplicity.resize(mNbRefl);
137 
138  mH=h;
139  mK=k;
140  mL=l;
141  mObsIntensity=iObs;
142  mObsSigma=sigma;
143  mMultiplicity=1;
144 
145  this->PrepareHKLarrays();
146 
147  this->CalcSinThetaLambda();
149  this->SetWeightToInvSigma2(1e-4,0);
150 
151  mHasObservedData=true;
152 
153  // Keep a copy as squared F(hkl), to enable fourier maps
154  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
157 
158  /*{
159  char buf [200];
160  sprintf(buf,"Changed HKL list, with %d reflections",(int)mNbRefl);
161  (*fpObjCrystInformUser)((string)buf);
162  }*/
163  VFN_DEBUG_EXIT("DiffractionDataSingleCrystal::SetHklIobs(h,k,l,i,s)",5)
164 }
165 
166 const CrystVector_REAL& DiffractionDataSingleCrystal::GetIcalc()const
167 {
168  this->CalcIcalc();
169  return mCalcIntensity;
170 }
171 
172 std::map<RefinablePar*, CrystVector_REAL> & DiffractionDataSingleCrystal::GetIcalc_FullDeriv(std::set<RefinablePar *> &vPar)
173 {
174  this->CalcIcalc_FullDeriv(vPar);
175  return mCalcIntensity_FullDeriv;
176 }
177 
178 const CrystVector_REAL& DiffractionDataSingleCrystal::GetIobs()const
179 {
180  //if(mHasObservedData==false) DoSomething
181  return mObsIntensity;
182 }
183 
184 void DiffractionDataSingleCrystal::SetIobs(const CrystVector_REAL &obs)
185 {
186  mObsIntensity=obs;
187  // Keep a copy as squared F(hkl), to enable fourier maps
188  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
191 }
192 
193 const CrystVector_REAL& DiffractionDataSingleCrystal::GetSigma()const
194 {
195  //if(mHasObservedData=false) DoSomething
196  return mObsSigma;
197 }
198 
199 void DiffractionDataSingleCrystal::SetSigma(const CrystVector_REAL& sigma) {mObsSigma=sigma;}
200 
201 const CrystVector_REAL& DiffractionDataSingleCrystal::GetWeight()const
202 {
203  //if(mHasObservedData=false) DoSomething
204  return mWeight;
205 }
206 
207 void DiffractionDataSingleCrystal::SetWeight(const CrystVector_REAL& weight)
208 {
209  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::SetWeight(w)",5)
210  mWeight=weight;
212 }
213 
215 {
216  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::SetIobsToIcalc()",5)
217  mObsIntensity=this->GetIcalc();
218  mObsSigma.resize(mNbRefl);
219  mWeight.resize(mNbRefl);
220  mWeight=1;
221  mObsSigma=0;
222  mHasObservedData=true;
223  // Keep a copy as squared F(hkl), to enable fourier maps
224  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
228 }
229 
230 
232  const long nbRefl,
233  const int skipLines)
234 {
235  //configure members
236  mNbRefl=nbRefl;
237  mH.resize(mNbRefl);
238  mK.resize(mNbRefl);
239  mL.resize(mNbRefl);
240  mObsIntensity.resize(mNbRefl);
241  mObsSigma.resize(mNbRefl);
242 
243  //Import data
244  {
245  //:TODO: Skip the lines if required !!!
246  cout << "inputing reflections from file : "+fileName<<endl;
247  ifstream fin (fileName.c_str());
248  if(!fin)
249  {
250  throw ObjCrystException("DiffractionDataSingleCrystal::ImportHklIobs() : \
251 Error opening file for input:"+fileName);
252  }
253  cout << "Number of reflections to import : " << nbRefl << endl ;
254  for(long i=0;i<nbRefl;i++)
255  { // :TODO: A little faster....
256  //:TODO: Check for the end of the stream if(!fin.good()) {throw...}
257  fin >> mH(i);
258  fin >> mK(i);
259  fin >> mL(i);
260  fin >> mObsIntensity(i);
261  mObsSigma(i)=sqrt(fabs(mObsIntensity(i)));
262  //cout << mObsIntensity(i) <<endl;
263  }
264  cout << "Finished reading data>"<< endl;
265  fin.close();
266  }
267  //Finish
268  mWeight.resize(mNbRefl);
269  const REAL minIobs=mObsIntensity.max()*1e-6;
270  for(int i=0;i<mNbRefl;i++)
271  if(mObsIntensity(i)<minIobs) mWeight(i)=1./minIobs;
272  else mWeight(i)=1./mObsIntensity(i);
273  mHasObservedData=true;
274 
275  mMultiplicity.resize(mNbRefl);
276  mMultiplicity=1;
277 
278  // Keep a copy as squared F(hkl), to enable fourier maps
279  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
282 
283  this->PrepareHKLarrays();
285  {
286  char buf [200];
287  sprintf(buf,"Imported HKLIobs, with %d reflections",(int)mNbRefl);
288  (*fpObjCrystInformUser)((string)buf);
289  }
290 
291  cout << "Finished storing data..."<< endl ;
292 }
293 
295  const long nbRefl,
296  const int skipLines)
297 {
298  //configure members
299  mNbRefl=nbRefl;
300  mH.resize(mNbRefl);
301  mK.resize(mNbRefl);
302  mL.resize(mNbRefl);
303  mObsIntensity.resize(mNbRefl);
304  mObsSigma.resize(mNbRefl);
305 
306  //Import data
307  {
308  cout << "inputing reflections from file : "+fileName<<endl;
309  ifstream fin (fileName.c_str());
310  if(!fin)
311  {
312  throw ObjCrystException("DiffractionDataSingleCrystal::ImportHklIobsSigma() : \
313 Error opening file for input:"+fileName);
314  }
315  if(skipLines>0)
316  {//Get rid of first lines if required
317  char tmpComment[200];
318  for(int i=0;i<skipLines;i++) fin.getline(tmpComment,150);
319  }
320  cout << "Number of reflections to import : " << nbRefl << endl ;
321  for(long i=0;i<nbRefl;i++)
322  { // :TODO: A little faster....
323  //:TODO: Check for the end of the stream if(!fin.good()) {throw...}
324  fin >> mH(i);
325  fin >> mK(i);
326  fin >> mL(i);
327  fin >> mObsIntensity(i);
328  fin >> mObsSigma(i);
329  //cout << mH(i)<<" "<<mK(i)<<" "<<mL(i)<<" "<<mObsIntensity(i)<<" "<<mObsSigma(i)<<endl;
330  }
331  cout << "Finished reading data>"<< endl;
332  fin.close();
333  }
334  //Finish
335  mWeight.resize(mNbRefl);
336  this->SetWeightToInvSigma2(1e-4,0);
337  mHasObservedData=true;
338 
339  mMultiplicity.resize(mNbRefl);
340  mMultiplicity=1;
341 
342  // Keep a copy as squared F(hkl), to enable fourier maps
343  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
346 
347  this->PrepareHKLarrays();
349  {
350  char buf [200];
351  sprintf(buf,"Imported HKLIobsSigma, with %d reflections",(int)mNbRefl);
352  (*fpObjCrystInformUser)((string)buf);
353  }
354 
355  cout << "Finished storing data..."<< endl ;
356 
357 }
358 
360 {
361  VFN_DEBUG_ENTRY("DiffractionDataSingleCrystal::ImportShelxHKLF4():"<<fileName,10);
362  char buf[101];
363  //configure members
364  mNbRefl=100;
365  mH.resize(mNbRefl);
366  mK.resize(mNbRefl);
367  mL.resize(mNbRefl);
368  mObsIntensity.resize(mNbRefl);
369  mObsSigma.resize(mNbRefl);
370  long h=1,k=1,l=1,i=0;
371  float iobs,sigma;
372  //Import data
373  {
374  VFN_DEBUG_MESSAGE("inputing reflections from file (HKLF4): "<<fileName,10);
375  ifstream fin (fileName.c_str());
376  if(!fin)
377  {
378  throw ObjCrystException("DiffractionDataSingleCrystal::ImportShelxHKLF4() : Error opening file for input:"+fileName);
379  }
380  for(;;)
381  {
382  fin.getline(buf,100);
383  h=(int) atoi(string(buf).substr(0,4).c_str());
384  k=(int) atoi(string(buf).substr(4,4).c_str());
385  l=(int) atoi(string(buf).substr(8,4).c_str());
386  iobs=string2floatC(string(buf).substr(12,8));
387  sigma=string2floatC(string(buf).substr(20,8));
388  if((abs(h)+abs(k)+abs(l))==0) break;
389  if(i==mNbRefl)
390  {
391  mNbRefl+=100;
392  mH.resizeAndPreserve(mNbRefl);
393  mK.resizeAndPreserve(mNbRefl);
394  mL.resizeAndPreserve(mNbRefl);
395  mObsIntensity.resizeAndPreserve(mNbRefl);
396  mObsSigma.resizeAndPreserve(mNbRefl);
397  }
398  mH(i)=REAL(h);
399  mK(i)=REAL(k);
400  mL(i)=REAL(l);
401  mObsIntensity(i)=REAL(iobs);
402  mObsSigma(i)=REAL(sigma);
403  i++;
404  }
405  VFN_DEBUG_MESSAGE("Finished reading from file (HKLF4) ",10);
406  fin.close();
407  }
408  //Finish
409  mNbRefl=i;
410  mH.resizeAndPreserve(mNbRefl);
411  mK.resizeAndPreserve(mNbRefl);
412  mL.resizeAndPreserve(mNbRefl);
413  mObsIntensity.resizeAndPreserve(mNbRefl);
414  mObsSigma.resizeAndPreserve(mNbRefl);
415 
416  mWeight.resize(mNbRefl);
417  this->SetWeightToInvSigma2(1e-4,0);
418  mHasObservedData=true;
419 
420  mMultiplicity.resize(mNbRefl);
421  mMultiplicity=1;
422 
423  // Keep a copy as squared F(hkl), to enable fourier maps
424  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
427 
428  this->PrepareHKLarrays();
430  {
431  char buf [200];
432  sprintf(buf,"Imported Shelx HKLF 4 file, with %d reflections",(int)mNbRefl);
433  (*fpObjCrystInformUser)((string)buf);
434  }
435  VFN_DEBUG_EXIT("DiffractionDataSingleCrystal::ImportShelxHKLF4() read "<<mNbRefl<<" reflections",10);
436 }
437 
438 void DiffractionDataSingleCrystal::ImportCIF(const string &fileName)
439 {
440  VFN_DEBUG_EXIT("DiffractionDataSingleCrystal::ImportCIF(): "<<fileName,10);
441  ifstream fin (fileName.c_str());
442  if(!fin)
443  {
444  throw ObjCrystException("DiffractionDataSingleCrystal::ImportCIF(): Error opening file for input:"+fileName);
445  }
446  ObjCryst::CIF cif(fin,true,true);
447  for(map<string,CIFData>::iterator pos=cif.mvData.begin();pos!=cif.mvData.end();++pos)
448  {
449  if(pos->second.mH.numElements()>0)
450  {
451  this->SetHklIobs(pos->second.mH,pos->second.mK,pos->second.mL,pos->second.mIobs,pos->second.mSigma);
452  break;
453  }
454  }
455  VFN_DEBUG_EXIT("DiffractionDataSingleCrystal::ImportCIF() read "<<mNbRefl<<" reflections",10);
456 }
457 
459 {
460  //configure members
461  mNbRefl=1000;//reasonable beginning value ?
462  mH.resize(mNbRefl);
463  mK.resize(mNbRefl);
464  mL.resize(mNbRefl);
465  mObsIntensity.resize(mNbRefl);
466  mObsSigma.resize(mNbRefl);
467 
468  //Import data
469  {
470  cout << "inputing reflections from Jana98 file : "+fileName<<endl;
471  ifstream fin (fileName.c_str());
472  if(!fin)
473  {
474  throw ObjCrystException("DiffractionDataSingleCrystal::ImportHklIobsSigmaJanaM91() : \
475 Error opening file for input:"+fileName);
476  }
477  long i=0;
478  REAL tmpH;
479  REAL junk;
480  fin >> tmpH;
481  while(tmpH != 999)
482  { // :TODO: A little faster....
483  //:TODO: Check for the end of the stream if(!fin.good()) {throw...}
484  i++;
485  if(i>=mNbRefl)
486  {
487  cout << mNbRefl << " reflections imported..." << endl;
488  mNbRefl+=1000;
489  mH.resizeAndPreserve(mNbRefl);
490  mK.resizeAndPreserve(mNbRefl);
491  mL.resizeAndPreserve(mNbRefl);
492  mObsIntensity.resizeAndPreserve(mNbRefl);
493  mObsSigma.resizeAndPreserve(mNbRefl);
494  }
495  mH(i)=tmpH;
496  fin >> mK(i);
497  fin >> mL(i);
498  fin >> mObsIntensity(i);
499  fin >> mObsSigma(i);
500  fin >> junk;
501  fin >> junk;
502  fin >> junk;
503  fin >> junk;
504  fin >> tmpH;
505  }
506  fin.close();
507  mNbRefl=i;
508  cout << mNbRefl << " reflections imported." << endl;
509  mH.resizeAndPreserve(mNbRefl);
510  mK.resizeAndPreserve(mNbRefl);
511  mL.resizeAndPreserve(mNbRefl);
512  mObsIntensity.resizeAndPreserve(mNbRefl);
513  mObsSigma.resizeAndPreserve(mNbRefl);
514  }
515  //Finish
516  mWeight.resize(mNbRefl);
517  mWeight=1;
518 
519  mMultiplicity.resize(mNbRefl);
520  mMultiplicity=1;
521 
522  // Keep a copy as squared F(hkl), to enable fourier maps
523  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
526 
527  this->PrepareHKLarrays();
529  cout << "Finished storing data..."<< endl ;
530 
531  mHasObservedData=true;
532  {
533  char buf [200];
534  sprintf(buf,"Imported HKLIobsSigma from Jana, with %d reflections",(int)mNbRefl);
535  (*fpObjCrystInformUser)((string)buf);
536  }
537 }
538 
539 void DiffractionDataSingleCrystal::ImportHklIobsGroup(const string &fileName,const unsigned int skipLines)
540 {
541  //configure members
542  mNbRefl=0;
543  mNbGroup=0;
544  mH.resize(500);
545  mK.resize(500);
546  mL.resize(500);
547  mObsIntensity.resize(500);
548  mObsSigma.resize(500);
549  mGroupIndex.resize(500);
550  mGroupIobs.resize(500);
551  mGroupSigma.resize(500);
552  mGroupWeight.resize(500);
553  //Import data
554  {
555  //:TODO: Skip the lines if required !!!
556  cout << "inputing reflections from file : "+fileName<<endl;
557  ifstream fin (fileName.c_str());
558  if(!fin)
559  {
560  throw ObjCrystException("DiffractionDataSingleCrystal::ImportHklIobs() : \
561 Error opening file for input:"+fileName);
562  }
563  string buffer;
564  REAL h,k,l,iobs,sigma;
565  while(true)
566  {
567  getline(fin,buffer);
568  istringstream linestream(buffer);
569  int nn = (linestream >> h >> k >> l) ? 3 : 0;
570  nn += bool(linestream >> iobs);
571  nn += bool(linestream >> sigma);
572  const int n = nn;
573  if(n<3) break;
574  mH(mNbRefl)=h;
575  mK(mNbRefl)=k;
576  mL(mNbRefl)=l;
578  //cout<<mNbRefl<<" "<<h<<" "<<k<<" "<<l<<"(g="<<mNbGroup<<") n="<<n;
579  if(n>=4)
580  {
581  //cout<<" Iobs="<<iobs;
582  mObsIntensity(mNbRefl)=iobs;
583  if(n!=5)
584  sigma=sqrt(fabs(iobs)+1e-6);
585  mObsSigma(mNbRefl)=sigma;
586  mGroupIobs(mNbGroup)=iobs;
587  mGroupSigma(mNbGroup)=sigma;
588  mGroupWeight(mNbGroup)=1/(sigma*sigma+1e-6);
589  mNbGroup++;
590  if(mNbGroup==mGroupIobs.numElements())
591  {
592  mGroupIobs.resizeAndPreserve(mNbGroup+500);
593  mGroupSigma.resizeAndPreserve(mNbGroup+500);
594  mGroupWeight.resizeAndPreserve(mNbGroup+500);
595  }
596  }
597  else
598  {
600  mObsSigma(mNbRefl)=0;
601  }
602  //cout<<endl;
603  mNbRefl++;
604  if(mNbRefl==mH.numElements())
605  {
606  mH.resizeAndPreserve(mNbRefl+500);
607  mK.resizeAndPreserve(mNbRefl+500);
608  mL.resizeAndPreserve(mNbRefl+500);
609  mObsIntensity.resizeAndPreserve(mNbRefl+500);
610  mObsSigma.resizeAndPreserve(mNbRefl+500);
611  mGroupIndex.resizeAndPreserve(mNbRefl+500);
612  }
613  if(fin.eof()) break;
614  }
615  fin.close();
616  }
617  // This must NOT be changed with this kind of data.
618  mGroupOption.SetChoice(2);
619  // So de-register the option so that it is hidden from the user's view
620  mOptionRegistry.DeRegister(mGroupOption);
622  //Finish
623  mH.resizeAndPreserve(mNbRefl);
624  mK.resizeAndPreserve(mNbRefl);
625  mL.resizeAndPreserve(mNbRefl);
626  mObsIntensity.resizeAndPreserve(mNbRefl);
627  mObsSigma.resizeAndPreserve(mNbRefl);
628  mWeight.resize(mNbRefl);
629  mGroupIndex.resizeAndPreserve(mNbRefl);// this will change after sorting reflections
630  mGroupIobs.resizeAndPreserve(mNbGroup);
631  mGroupWeight.resizeAndPreserve(mNbGroup);
632  mGroupSigma.resizeAndPreserve(mNbGroup);
633 
634  const REAL minIobs=mObsIntensity.max()*1e-6;
635  for(int i=0;i<mNbRefl;i++)
636  if(mObsIntensity(i)<minIobs) mWeight(i)=1./minIobs;
637  else mWeight(i)=1./mObsIntensity(i);
638  mHasObservedData=true;
639 
640  mMultiplicity.resize(mNbRefl);
641  mMultiplicity=1;
642 
643  this->PrepareHKLarrays();
644  {
645  char buf [200];
646  sprintf(buf,"Imported HKLIobs, with %d reflections",(int)mNbRefl);
647  (*fpObjCrystInformUser)((string)buf);
648  }
650  this->CalcIcalc();
651 }
652 
653 
655 {
656  TAU_PROFILE("DiffractionData::Rw()"," REAL()",TAU_DEFAULT);
657  VFN_DEBUG_MESSAGE("DiffractionData::Rw()",3);
658  if(mHasObservedData==false)
659  {
660  return 0;
661  }
662  REAL tmp1=0;
663  REAL tmp2=0;
664  const REAL *p1;
665  const REAL *p2;
666  const REAL *p3;
667  long nb;
668  if(mGroupOption.GetChoice()==0)
669  {
670  p1=mCalcIntensity.data();
671  p2=mObsIntensity.data();
672  p3=mWeight.data();
673  nb=mNbReflUsed;
674  }
675  else
676  {
677  p1=mGroupIcalc.data();
678  p2=mGroupIobs.data();
679  p3=mGroupWeight.data();
680  nb=mGroupIobs.numElements();
681  }
682 
683  for(long i=nb;i>0;i--)
684  {
685  tmp1 += *p3 * ( *p1 - *p2) * ( *p1 - *p2);
686  tmp2 += *p3 * *p2 * *p2;
687  p1++;p2++;p3++;
688  }
689  tmp1=sqrt(tmp1/tmp2);
690  VFN_DEBUG_MESSAGE("DiffractionData::Rw()="<<tmp1,3);
691  return tmp1 ;// /this->GetNbRefl();
692 }
693 
695 {
696  TAU_PROFILE("DiffractionData::R()"," REAL()",TAU_DEFAULT);
697  VFN_DEBUG_MESSAGE("DiffractionData::R()",3);
698  if(mHasObservedData==false)
699  {
700  return 0;
701  }
702 
703  REAL tmp1=0;
704  REAL tmp2=0;
705  const REAL *p1;
706  const REAL *p2;
707  long nb;
708  if(mGroupOption.GetChoice()==0)
709  {
710  p1=mCalcIntensity.data();
711  p2=mObsIntensity.data();
712  nb=mNbReflUsed;
713  }
714  else
715  {
716  p1=mGroupIcalc.data();
717  p2=mGroupIobs.data();
718  nb=mGroupIobs.numElements();
719  }
720 
721  for(long i=nb;i>0;i--)
722  {
723  tmp1 += ( *p1 - *p2) * ( *p1 - *p2);
724  tmp2 += *p2 * *p2;
725  p1++;p2++;
726  }
727  tmp1=sqrt(tmp1/tmp2);
728 
729  VFN_DEBUG_MESSAGE("DiffractionData::R()="<<tmp1,3);
730  return tmp1 ;
731 }
732 
734 {
735  if(mHasObservedData==false)
736  {
737  mChi2=0;
738  return mChi2;
739  }
741  if(mClockChi2>mClockMaster) return mChi2;
742 
743  this->CalcIcalc();
744  if(mClockChi2>mClockIcalc) return mChi2;
745 
746  TAU_PROFILE("DiffractionData::Chi2()"," REAL()",TAU_DEFAULT);
747  VFN_DEBUG_ENTRY("DiffractionData::Chi2()",3);
748  this->FitScaleFactorForRw();
749  mChi2=0;
750  const REAL *p1;
751  const REAL *p2;
752  const REAL *p3;
753  long nb;
754  if(mGroupOption.GetChoice()==0)
755  {
756  p1=mCalcIntensity.data();
757  p2=mObsIntensity.data();
758  p3=mWeight.data();
759  nb=mNbReflUsed;
760  }
761  else
762  {
763  p1=mGroupIcalc.data();
764  p2=mGroupIobs.data();
765  p3=mGroupWeight.data();
766  nb=mGroupIobs.numElements();
767  }
768 
769  for(long i=nb;i>0;i--)
770  {
771  mChi2 += *p3++ * ( *p1 - *p2) * ( *p1 - *p2);
772  p1++;p2++;
773  }
774  /*
775  // SSE code gives about 30% faster code on P3 (tested with 10000 reflections),
776  // but scarcely any improvement on athlon-xp
777  union sse4f
778  {
779  __m128 m128;
780  struct
781  {
782  float x, y, z, w;
783  };
784  } ;
785  const long nb=mNbReflUsed/4;
786  const float* p1=mCalcIntensity.data();
787  const float* p2=mObsIntensity.data();
788  const float* p3=mWeight.data();
789  for(long i=0;i<nb;i++)
790  {
791  //segfaults with _mm_load_ps() instead of _mm_loadu_ps? Alignment problem ?
792  __m128 a = _mm_sub_ps(_mm_loadu_ps(p1),_mm_loadu_ps(p2));
793  union sse4f b;
794  b.m128= _mm_mul_ps(_mm_loadu_ps(p3),_mm_mul_ps(a,a));
795  mChi2 += b.x+b.y+b.z+b.w;
796  p1+=4;p2+=4;p3+=4;
797  }
798  p1-=4;p2-=4;p3-=4;
799  for(long i=nb*4;i<mNbReflUsed;i++)
800  {
801  mChi2 += *p3++ * ( *p1 - *p2) * ( *p1 - *p2);
802  p1++;p2++;
803  }
804  */
805  mClockChi2.Click();
806  VFN_DEBUG_EXIT("DiffractionData::Chi2()="<<mChi2,3);
807  return mChi2;
808 }
809 
811 {
812  TAU_PROFILE("DiffractionData::FitScaleFactorForRw()","void ()",TAU_DEFAULT);
813  VFN_DEBUG_MESSAGE("DiffractionData::FitScaleFactorForRw()",3);
814  if(mHasObservedData==false)
815  {//throw exception here ?
816  return;
817  //throw ObjCrystException("DiffractionData::FitScaleFactorForRw() Cannot compute Rw
818  // or scale factor: there is no observed data !");
819  }
820  REAL tmp1=0;
821  REAL tmp2=0;
822  const REAL *p1;
823  const REAL *p2;
824  const REAL *p3;
825  long nb;
826  if(mGroupOption.GetChoice()==0)
827  {
828  p1=mCalcIntensity.data();
829  p2=mObsIntensity.data();
830  p3=mWeight.data();
831  nb=mNbReflUsed;
832  }
833  else
834  {
835  p1=mGroupIcalc.data();
836  p2=mGroupIobs.data();
837  p3=mGroupWeight.data();
838  nb=mGroupIobs.numElements();
839  }
840 
841  for(long i=nb;i>0;i--)
842  {
843  tmp1 += *p3 * (*p1) * (*p2++);
844  tmp2 += *p3++ * (*p1) * (*p1);
845  p1++;
846  }
847  mScaleFactor *= tmp1/tmp2;
849 
850  mCalcIntensity *= tmp1/tmp2;
851  if(0!=mGroupOption.GetChoice()) mGroupIcalc*= tmp1/tmp2;
852  mClockIcalc.Click();
853 }
854 
856 {
857  TAU_PROFILE("DiffractionData::FitScaleFactorForR()","void ()",TAU_DEFAULT);
858  VFN_DEBUG_MESSAGE("DiffractionData::FitScaleFactorForR()",3);
859  if(mHasObservedData==false)
860  {//throw exception here ?
861  return;
862  //throw ObjCrystException("DiffractionData::FitScaleFactorForR() Cannot compute R
863  // or scale factor: there is no observed data !");
864  }
865  REAL tmp1=0;
866  REAL tmp2=0;
867  const REAL *p1;
868  const REAL *p2;
869  long nb;
870  if(mGroupOption.GetChoice()==0)
871  {
872  p1=mCalcIntensity.data();
873  p2=mObsIntensity.data();
874  nb=mNbReflUsed;
875  }
876  else
877  {
878  p1=mGroupIcalc.data();
879  p2=mGroupIobs.data();
880  nb=mGroupIobs.numElements();
881  }
882 
883  for(long i=nb;i>0;i--)
884  {
885  tmp1 += (*p1) * (*p2++);
886  tmp2 += (*p1) * (*p1);
887  p1++;
888  }
889  mScaleFactor *= tmp1/tmp2;
891 
892  mCalcIntensity *= tmp1/tmp2;
893  if(0!=mGroupOption.GetChoice()) mGroupIcalc*= tmp1/tmp2;
894  mClockIcalc.Click();
895 }
896 
898 {
899  TAU_PROFILE("DiffractionData::GetBestRFactor()","void ()",TAU_DEFAULT);
900  VFN_DEBUG_MESSAGE("DiffractionData::GetBestRFactor()",3);
901  this->FitScaleFactorForR();
902  return this->GetR();
903 }
904 
906 {
907  for(long i=0;i<mObsIntensity.numElements();i++) mObsSigma(i)=sqrt(fabs(mObsIntensity(i)));
908  if(1==mGroupOption.GetChoice()) mClockPrepareTwinningCorr.Reset();
909  // This is not needed for mGroupOption==2
910 }
911 
912 void DiffractionDataSingleCrystal::SetWeightToInvSigma2(const REAL minRelatSigma, const REAL minIobsSigmaRatio)
913 {
914  //:KLUDGE: If less than 1e-6*max, set to 0.... Do not give weight to unobserved points
915  const REAL min=MaxAbs(mObsSigma)*minRelatSigma;
916  for(long i=0;i<mObsSigma.numElements();i++)
917  {
918  if(mObsSigma(i)<min) mWeight(i)=0 ; else mWeight(i) =1./mObsSigma(i)/mObsSigma(i);
919  if(mObsIntensity(i)<(minIobsSigmaRatio*mObsSigma(i))) mWeight(i)=0;
920  }
921  if(1==mGroupOption.GetChoice()) mClockPrepareTwinningCorr.Reset();
922  // This is not needed for mGroupOption==2
923 }
924 
926 
927 //void DiffractionDataSingleCrystal::SetScaleFactor(const REAL s) {mScaleFactor=s;}
928 
930 {
931  this->CalcSinThetaLambda();
932  cout << "DiffractionData : " << mName <<endl;
933  cout << "Number of observed reflections : " << mNbRefl << endl;
934  cout << " H K L Iobs Sigma sin(theta)/lambda)" <<endl;
935  cout << mH.numElements()<<endl;
936  cout << mK.numElements()<<endl;
937  cout << mL.numElements()<<endl;
938  cout << mObsIntensity.numElements()<<endl;
939  cout << mObsSigma.numElements()<<endl;
940  cout << mSinThetaLambda.numElements()<<endl;
941  cout << FormatVertVectorHKLFloats<REAL>
943 }
944 
946 {
947  this->CalcIcalc();
948  CrystVector_REAL tmpTheta=mTheta;
949  tmpTheta*= RAD2DEG;
950  /*
951  CrystVector_REAL tmp=mObsIntensity;
952  CrystVector_REAL tmpS=mObsSigma;
953  if(true==mHasObservedData)
954  {
955  cout << "Scale factor : " << mScaleFactor <<endl;
956  tmp*= mScaleFactor*mScaleFactor;//the scale factor is computed for F's
957  tmpS*=mScaleFactor;
958  } else cout << "No observed data. Default scale factor =1." <<endl;
959  */
960  cout << "DiffractionData : " << mName <<endl;
961  cout << " Scale Factor : " << mScaleFactor <<endl;
962  cout << "Number of observed reflections : " << mNbRefl << endl;
963 
964  cout << " H K L Iobs Sigma Icalc ";
965  cout << " multiplicity Theta SiThSL Re(F) Im(F) Weight" <<endl;
966  cout << FormatVertVectorHKLFloats<REAL>(mH,mK,mL,
969  mFhklCalcReal,mFhklCalcImag,mWeight,12,4);
970 }
971 
972 void DiffractionDataSingleCrystal::SetUseOnlyLowAngleData(
973  const bool useOnlyLowAngle,const REAL angle)
974 {
975  throw ObjCrystException("DiffractionDataSingleCrystal::SetUseOnlyLowAngleData() :\
976  not yet implemented for DiffractionDataSingleCrystal.");
977 }
978 
980 {
981  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::SaveHKLIobsIcalc",5)
982  this->GetIcalc();
983  ofstream out(filename.c_str());
984  CrystVector_REAL theta;
985  theta=mTheta;
986  theta *= RAD2DEG;
987 
988  if(false == mHasObservedData)
989  {
990  out << "# H K L Icalc theta sin(theta)/lambda"
991  <<" Re(F) Im(F)" << endl;
992  out << FormatVertVectorHKLFloats<REAL>(mH,mK,mL,mCalcIntensity,
993  theta,mSinThetaLambda,mFhklCalcReal,mFhklCalcImag,12,4);
994  }
995  else
996  {
997  out << "# H K L Iobs Icalc theta"
998  <<" sin(theta)/lambda Re(F) Im(F)" << endl;
999  out << FormatVertVectorHKLFloats<REAL>(mH,mK,mL,mObsIntensity,mCalcIntensity,
1000  theta,mSinThetaLambda,mFhklCalcReal,mFhklCalcImag,12,4);
1001  }
1002  out.close();
1003  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::SaveHKLIobsIcalc:End",3)
1004 }
1005 
1006 void DiffractionDataSingleCrystal::GlobalOptRandomMove(const REAL mutationAmplitude,
1007  const RefParType *type)
1008 {
1009  this->RefinableObj::GlobalOptRandomMove(mutationAmplitude,type);
1010  //this->FitScaleFactorForRw();
1011 }
1012 
1014 {
1015  return this->GetChi2();
1016 }
1017 
1018 void DiffractionDataSingleCrystal::InitRefParList()
1019 {
1020  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::InitRefParList()",5)
1021  RefinablePar tmp("Scale factor",&mScaleFactor,
1022  1e-10,1e10,gpRefParTypeScattDataScale,REFPAR_DERIV_STEP_RELATIVE,
1023  false,true,true,false,1.);
1024  tmp.SetGlobalOptimStep(0.);
1025  tmp.AssignClock(mClockScaleFactor);
1026  tmp.SetDerivStep(1e-4);
1027  this->AddPar(tmp);
1028 }
1029 unsigned int DiffractionDataSingleCrystal::GetNbLSQFunction()const{return 1;}
1030 const CrystVector_REAL&
1032 {return this->GetIcalc();}
1033 
1034 const CrystVector_REAL&
1036 {return this->GetIobs();}
1037 
1038 const CrystVector_REAL&
1040 {return this->GetWeight();}
1041 
1042 std::map<RefinablePar*, CrystVector_REAL> & DiffractionDataSingleCrystal::GetLSQ_FullDeriv(const unsigned int,std::set<RefinablePar *> &vPar)
1043 {
1044  #if 0
1045  this->GetIcalc_FullDeriv(vPar);
1046  std::map<RefinablePar*, CrystVector_REAL> fullderiv_old;
1047  std::vector<const CrystVector_REAL*> v;
1048  int n=0;
1049  for(std::map<RefinablePar*, CrystVector_REAL>::reverse_iterator pos=mCalcIntensity_FullDeriv.rbegin();pos!=mCalcIntensity_FullDeriv.rend();++pos)
1050  {
1051  v.push_back(&(pos->second));
1052  fullderiv_old[pos->first]=this->GetLSQDeriv(0,*(pos->first));
1053  v.push_back(&(fullderiv_old[pos->first]));
1054  cout<<pos->first->GetName()<<":"<<pos->second.size()<<","<<mFhklCalcSq_FullDeriv[pos->first].size()<<endl;
1055  if(++n>8) break;
1056  }
1057  cout<<FormatVertVector<REAL>(v,10)<<endl;
1058  //exit(0);
1059  #endif
1060  return this->GetIcalc_FullDeriv(vPar);
1061 }
1062 
1063 const Radiation& DiffractionDataSingleCrystal::GetRadiation()const { return mRadiation;}
1066 {
1067  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::SetRadiationType():End",5)
1068  mRadiation.SetRadiationType(radiation);
1069 }
1070 
1072 {
1073  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::SetWavelength() to "<<lambda,5)
1074  this->GetRadiation().SetWavelength(lambda);
1075 }
1076 
1077 void DiffractionDataSingleCrystal::SetWavelength(const string &XRayTubeElementName,
1078  const REAL alpha2Alpha2ratio)
1079 {
1080  VFN_DEBUG_MESSAGE("DiffractionDataSingleCrystal::SetWavelength() to "<<XRayTubeElementName,5)
1081  this->GetRadiation().SetWavelength(XRayTubeElementName,alpha2Alpha2ratio);
1082 }
1083 
1085 {
1086  this->SetWavelength(12398.4/energy);
1087 }
1088 
1090 {
1091  TAU_PROFILE("DiffractionData::CalcIcalc()","void ()",TAU_DEFAULT);
1092  VFN_DEBUG_MESSAGE("DiffractionData::CalcIcalc():"<<this->GetName(),3)
1093  this->GetFhklCalcSq();
1095  && ((0==mGroupOption.GetChoice()) || (mClockPrepareTwinningCorr<mClockIcalc)) ) return;
1096 
1099  if(0!=mGroupOption.GetChoice())
1100  {
1101  if(1==mGroupOption.GetChoice()) this->PrepareTwinningCalc();
1102  mGroupIcalc.resize(mNbGroup);
1103  mGroupIcalc=0;
1104  long first=0;
1105  for(long i=0;i<mNbGroup;i++)
1106  {
1107  //cout<<"Group #"<<i<<":"<<first<<"->"<<mGroupIndex(i)<<endl;
1108  for(long j=first;j<mGroupIndex(i);j++)
1109  {
1110  //cout <<" " << mIntH(j)<<" "<< mIntK(j)<<" "<< mIntL(j)<<" " << mCalcIntensity(j)<<endl;
1111  mGroupIcalc(i)+=mCalcIntensity(j);
1112  }
1113  first=mGroupIndex(i);
1114  //cout << " => Icalc="<< mGroupIcalc(i) <<" , Iobs="<< mGroupIobs(i)<<endl<<endl;
1115  }
1116  }
1117  mClockIcalc.Click();
1118 }
1119 void DiffractionDataSingleCrystal::CalcIcalc_FullDeriv(std::set<RefinablePar *> &vPar)
1120 {
1121  TAU_PROFILE("DiffractionDataSingleCrystal::CalcIcalc_FullDeriv()","void ()",TAU_DEFAULT);
1122  this->GetFhklCalcSq_FullDeriv(vPar);
1123  // :TODO: instead of clear(), only add/remove when necessary ?
1124  mCalcIntensity_FullDeriv.clear();
1125  mCalcIntensity_FullDeriv=mFhklCalcSq_FullDeriv;
1126  //:TODO: multiplication only up to mNbReflUsed
1127  for(std::map<RefinablePar*, CrystVector_REAL>::iterator pos=mCalcIntensity_FullDeriv.begin(); pos!=mCalcIntensity_FullDeriv.end();pos++)
1128  {
1129  if(pos->first==0)
1130  {// This is Icalc, not derived
1131  pos->second *=mScaleFactor;
1132  continue;
1133  }
1134  if(pos->first->GetPointer()!=&mScaleFactor)
1135  {
1136  /*if(pos->second.size()>0) */ // not needed
1137  pos->second *=mScaleFactor;
1138  }
1139  else
1140  {
1141  pos->second=mFhklCalcSq;
1142  }
1143  }
1144 
1145  if(0!=mGroupOption.GetChoice())
1146  {//:TODO:
1147  if(1==mGroupOption.GetChoice()) this->PrepareTwinningCalc();
1148  // :TODO: instead of clear(), only add/remove when necessary ?
1149  mGroupIcalc_FullDeriv.clear();
1150  for(std::map<RefinablePar*, CrystVector_REAL>::iterator pos=mCalcIntensity_FullDeriv.begin(); pos!=mCalcIntensity_FullDeriv.end();pos++)
1151  {
1152  mGroupIcalc_FullDeriv[pos->first].resize(mNbGroup);
1153  mGroupIcalc_FullDeriv[pos->first]=0;
1154  long first=0;
1155 
1156  for(long i=0;i<mNbGroup;i++)
1157  {
1158  for(long j=first;j<mGroupIndex(i);j++)
1159  {
1160  mGroupIcalc_FullDeriv[pos->first](i)+=mCalcIntensity_FullDeriv[pos->first](j);
1161  }
1162  first=mGroupIndex(i);
1163  }
1164  }
1165  }
1166 }
1167 
1169 {
1170  TAU_PROFILE("DiffractionDataSingleCrystal::SortReflectionBySinThetaOverLambda()","void ()",TAU_DEFAULT);
1171  VFN_DEBUG_ENTRY("DiffractionDataSingleCrystal::SortReflectionBySinThetaOverLambda()",5)
1172  // ScatteringData::SortReflectionBySinThetaOverLambda only sorts H,K,L and multiplicity.
1173  CrystVector_long index=this->ScatteringData::SortReflectionBySinThetaOverLambda(maxSTOL);
1174 
1175  if(mObsIntensity.numElements()==mNbRefl)
1176  {
1177  CrystVector_REAL tmpObs,tmpSigma,tmpWeight;
1178  tmpObs=mObsIntensity;
1179  tmpSigma=mObsSigma;
1180  tmpWeight=mWeight;
1181  for(long i=0;i<mNbRefl;i++)
1182  {
1183  mObsIntensity(i)=tmpObs(index(i));
1184  mObsSigma(i)=tmpSigma(index(i));
1185  mWeight(i)=tmpWeight(index(i));
1186  }
1187  // Keep a copy as squared F(hkl), to enable fourier maps
1188  // :TODO: stop using mObsIntensity and just keep mFhklObsSq ?
1191 
1192  if(mGroupOption.GetChoice()==2)
1193  {
1194  CrystVector_long tmp;//,oldgroup(mNbGroup);;
1195  tmp=mGroupIndex;
1196  for(long i=0;i<mNbRefl;i++) mGroupIndex(i)=tmp(index(i));
1197  /*
1198  for(long i=0;i<mNbRefl;i++)
1199  cout<<mIntH(i)<<" "<<mIntK(i)<<" "<<mIntL(i)<<" "
1200  <<mObsIntensity(i)<<" "<<mObsSigma(i)<<" "<<mWeight(i)<< ":"<<mGroupIndex(i)<<endl;
1201  */
1202  // Now re-index the groups of reflections in
1203  // ascending order
1204  {
1205  index.resize(mNbGroup);
1206  index=-1;
1207  long group=0;
1208  CrystVector_REAL oldGroupIobs, oldGroupWeight,oldGroupSigma;
1209  oldGroupIobs =mGroupIobs;
1210  oldGroupWeight=mGroupWeight;
1211  oldGroupSigma=mGroupSigma;
1212  for(long i=0;i<mNbRefl;i++)
1213  {
1214  if(index(mGroupIndex(i))==-1)// first reflection of a group ?
1215  {
1216  mGroupIobs(group)=oldGroupIobs(mGroupIndex(i));
1217  mGroupSigma(group)=oldGroupSigma(mGroupIndex(i));
1218  mGroupWeight(group)=oldGroupWeight(mGroupIndex(i));
1219  //oldgroup(group)=mGroupIndex(i);
1220  index(mGroupIndex(i))=group++;
1221  }
1222  mGroupIndex(i)=index(mGroupIndex(i));
1223  }
1224  }
1225  /*
1226  cout<<mIntH.numElements()<<","
1227  <<mIntK.numElements()<<","
1228  <<mIntL.numElements()<<","
1229  <<oldgroup.numElements()<<","<<mGroupIndex.numElements()<<endl;
1230  for(long i=0;i<mNbRefl;i++)
1231  cout<<mIntH(i)<<" "<<mIntK(i)<<" "<<mIntL(i)<<endl
1232  <<" :"<<oldgroup(mGroupIndex(i))<<"->"<<mGroupIndex(i)<<endl;
1233  */
1234  // Now re-group the reflections
1235  index=SortSubs(mGroupIndex);
1236  {
1237  CrystVector_long oldH,oldK,oldL,oldMult;
1238  oldH=mH;
1239  oldK=mK;
1240  oldL=mL;
1241  oldMult=mMultiplicity;
1242  tmpObs=mObsIntensity;
1243  tmpSigma=mObsSigma;
1244  tmpWeight=mWeight;
1245  for(long i=0;i<mNbRefl;i++)
1246  {
1247  const long subs=index(i);
1248  mH(i)=oldH(subs);
1249  mK(i)=oldK(subs);
1250  mL(i)=oldL(subs);
1251  mMultiplicity(i)=oldMult(subs);
1252  mObsIntensity(i)=tmpObs(subs);
1253  mObsSigma(i)=tmpSigma(subs);
1254  mWeight(i)=tmpWeight(subs);
1255  }
1256  mClockHKL.Click();
1257  this->PrepareHKLarrays();
1258  this->CalcSinThetaLambda();
1259  }
1260 
1261  // re-write mGroupIndex so that it marks the
1262  // last reflection of each group.
1263  index=mGroupIndex;
1264  mGroupIndex.resize(mNbGroup);
1265  long group=0;
1266  for(long i=0;i<mNbRefl;i++)
1267  if(index(i)!=group)
1268  mGroupIndex(group++)=i;
1270  }
1271  }
1272  else
1273  {// if there are no observed values, enter dummy ones
1274  mObsIntensity.resize(mNbRefl);
1275  mObsSigma.resize(mNbRefl);
1276  mWeight.resize(mNbRefl);
1277  mObsIntensity=100.;
1278  mObsSigma=1.;
1279  mWeight=1.;
1280  mFhklObsSq.resize(0);
1282  }
1283  VFN_DEBUG_EXIT("DiffractionDataSingleCrystal::SortReflectionBySinThetaOverLambda()",5)
1284  return index;
1285 }
1286 
1288 {
1289  static string GroupOption;
1290  static string GroupOptionChoices[3];
1291  static bool needInitNames=true;
1292  if(true==needInitNames)
1293  {
1294  GroupOption="Group Reflections";
1295  GroupOptionChoices[0]="No";
1296  GroupOptionChoices[1]="Sum equally-spaced reflections";
1297  GroupOptionChoices[2]="Sum according to user data";
1298  needInitNames=false;
1299  }
1300  mGroupOption.Init(3,&GroupOption,GroupOptionChoices);
1301  mGroupOption.SetChoice(0);
1302  this->AddOption(&mGroupOption);
1303 }
1304 
1306 {
1308  VFN_DEBUG_ENTRY("DiffractionDataSingleCrystal::PrepareTwinningCalc()",5)
1309  // first get the index of reflections which limit each block of summed reflections
1310  mNbGroup=0;
1311  {
1312  const REAL dSiThOvLa=.0001;
1313  mGroupIndex.resize(mNbReflUsed);
1314  this->CalcSinThetaLambda();
1315  REAL sithol0=mSinThetaLambda(0)+dSiThOvLa;
1316  for(long i=1;i<mNbReflUsed;i++)
1317  {
1318  if(mSinThetaLambda(i)>sithol0)
1319  {
1320  mGroupIndex(mNbGroup++)=i;
1321  sithol0=mSinThetaLambda(i)+dSiThOvLa;
1322  }
1323  }
1325  mGroupIndex.resizeAndPreserve(mNbGroup);
1326  }
1327  // Calculate summed Iobs and weight
1328  {
1329  mGroupIobs.resize(mNbGroup);
1330  mGroupIobs=0;
1331  mGroupWeight.resize(mNbGroup);
1332  mGroupWeight=0;
1333  mGroupSigma.resize(mNbGroup);
1334  mGroupSigma=0;
1335  long first=0;
1336  for(long i=0;i<mNbGroup;i++)
1337  {
1338  for(long j=first;j<mGroupIndex(i);j++)
1339  {
1340  mGroupIobs(i)+=mObsIntensity(j);
1341  mGroupSigma(i)+=mObsSigma(j)*mObsSigma(j);
1342  mGroupWeight(i)+=mObsSigma(j)*mObsSigma(j);
1343  }
1344  mGroupWeight(i)=1./mGroupWeight(i);
1345  mGroupSigma(i)=sqrt(fabs(mGroupSigma(i)));
1346  first=mGroupIndex(i);
1347  }
1348  }
1350  VFN_DEBUG_EXIT("DiffractionDataSingleCrystal::PrepareTwinningCalc()",5)
1351 }
1352 
1353 #ifdef __WX__CRYST__
1354 WXCrystObjBasic* DiffractionDataSingleCrystal::WXCreate(wxWindow* parent)
1355 {
1356  //:TODO: Check mpWXCrystObj==0
1357  mpWXCrystObj=new WXDiffractionSingleCrystal(parent,this);
1358  return mpWXCrystObj;
1359 }
1360 #endif
1361 
1362 }//namespace
virtual long GetNbReflBelowMaxSinThetaOvLambda() const
Recalc, and get the number of reflections which should be actually used, due to the maximuml sin(thet...
RefinableObjClock mClockHKL
Clock for the list of hkl.
void AddSubRefObj(RefinableObj &)
void AddPar(const RefinablePar &newRefPar)
Add a refinable parameter.
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
virtual REAL GetLogLikelihood() const
Get -log(likelihood) of the current configuration for the object.
const CrystVector_REAL & GetIcalc() const
returns the calculated diffracted intensity.
void ImportHklIobsSigmaJanaM91(const string &fileName)
Import h,k,l,I,Sigma from a Jana98 '*.m91' file.
virtual void PrepareHKLarrays()
float string2floatC(const string &s)
Function to convert a substring to a floating point value, imposing a C locale (using '...
Definition: ObjCryst/IO.cpp:59
const CrystVector_REAL & GetIobs() const
Return the array of observed intensities for all peaks.
RefObjOpt mGroupOption
Option for the type of grouping (0:no, 1:by theta values (twinning), 2:user-supplied groups) ...
const CrystVector_REAL & GetWeight() const
Return the weights (for each reflection) used for computing Rw.
virtual void CalcSinThetaLambda() const
virtual void GlobalOptRandomMove(const REAL mutationAmplitude, const RefParType *type=gpRefParTypeObjCryst)
Make a random move of the current configuration.
virtual void PrintObsData() const
Print H, K, L Iobs sigma for all reflections.
REAL GetScaleFactor() const
Scale factor (applied to Icalc to match Iobs)
virtual const Radiation & GetRadiation() const
Get the radiation object for this data.
virtual void SetSigmaToSqrtIobs()
Set sigma for all observed intensities to sqrt(obs)
virtual void FitScaleFactorForRw() const
Compute the best scale factor minimising Rw.
void ImportHklIobs(const string &fileName, const long nbRefl, const int skipLines=0)
Import h,k,l,I from a file.
void SetIobs(const CrystVector_REAL &)
Return the array of observed intensities for all peaks.
virtual CrystVector_long SortReflectionBySinThetaOverLambda(const REAL maxTheta=-1.)
void SetWeight(const CrystVector_REAL &)
Change the weights (for each reflection) used for computing Rw.
CrystVector_REAL mGroupIcalc
The calculated intensities summed on all reflections that are grouped.
void Click()
Record an event for this clock (generally, the 'time' an object has been modified, or some computation has been made)
void AddChild(const RefinableObjClock &)
Add a 'child' clock.
RefinableObjClock mClockScaleFactor
Last modification of the scale factor.
CrystVector_long mGroupIndex
The index of reflections which need to be summed.
long mNbRefl
Number of H,K,L reflections.
virtual void SetCrystal(Crystal &crystal)
Set the crystal for this experiment.
virtual const CrystVector_REAL & GetLSQObs(const unsigned int) const
Get the observed values for the LSQ function.
virtual const CrystVector_REAL & GetLSQCalc(const unsigned int) const
Get the current calculated value for the LSQ function.
virtual unsigned int GetNbLSQFunction() const
Number of LSQ functions.
Class to compute structure factors for a set of reflections and a Crystal.
ObjRegistry< RefinableObj > gTopRefinableObjRegistry("Global Top RefinableObj registry")
This is a special registry for 'top' object for an optimization.
RefinableObjClock mClockMaster
Master clock, which is changed whenever the object has been altered.
const RefParType * gpRefParTypeScattDataScale
Type for scattering data scale factors.
CrystVector_int mMultiplicity
Multiplicity for each reflections (mostly for powder diffraction)
virtual CrystVector_long SortReflectionBySinThetaOverLambda(const REAL maxSTOL=-1.)
Abstract base class for all objects in wxCryst.
Definition: wxCryst.h:127
CrystVector_REAL mObsSigma
Sigma for observed intensities (either individual reflections or spectrum)
ObjRegistry< DiffractionDataSingleCrystal > gDiffractionDataSingleCrystalRegistry("Global DiffractionDataSingleCrystal Registry")
Global registry for all PowderPattern objects.
CrystVector_REAL mTheta
theta for the crystal and the HKL in ReciprSpace (in radians)
string mName
Name for this RefinableObject. Should be unique, at least in the same scope.+.
virtual void GlobalOptRandomMove(const REAL mutationAmplitude, const RefParType *type=gpRefParTypeObjCryst)
Make a random move of the current configuration.
CrystVector_REAL mGroupWeight
The weight on each reflection sum in case of grouped reflections.
virtual const CrystVector_REAL & GetLSQDeriv(const unsigned int, RefinablePar &)
Get the first derivative values for the LSQ function, for a given parameter.
virtual void SetRadiationType(const RadiationType radiation)
Set : neutron or x-ray experiment ? Wavelength ?
CrystVector_REAL mH
H,K,L coordinates.
virtual const CrystVector_REAL & GetLSQWeight(const unsigned int) const
Get the weight values for the LSQ function.
DiffractionData object for Single Crystal analysis.
CrystVector_REAL mSinThetaLambda
for the crystal and the reflections in ReciprSpace
DiffractionDataSingleCrystal(const bool regist=true)
Default constructor.
CrystVector_REAL mCalcIntensity
Calculated intensities.
void RemoveChild(const RefinableObjClock &)
remove a child clock. This also tells the child clock to remove the parent.
void SetWavelength(const REAL)
Set the (monochromatic) wavelength of the beam.
const CrystVector_REAL & GetFhklCalcSq() const
Returns the Array of calculated |F(hkl)|^2 for all reflections.
void SetHklIobs(const CrystVector_long &h, const CrystVector_long &k, const CrystVector_long &l, const CrystVector_REAL &iObs, const CrystVector_REAL &sigma)
input H,K,L, Iobs and Sigma
virtual void FitScaleFactorForR() const
Compute the best scale factor minimising R.
void SaveHKLIobsIcalc(const string &filename="hklIobsIcalc.out")
Save H,K,L Iobs Icalc to a file, text format, 3 columns theta Iobs Icalc.
Main CIF class - parses the stream and separates data blocks, comments, items, loops.
Definition: CIF.h:169
void SetEnergy(const REAL)
Set the (monochromatic) energy of the beam.
void SetRadiationType(const RadiationType)
Set the radiation type (X-Rays, Neutron)
virtual std::map< RefinablePar *, CrystVector_REAL > & GetLSQ_FullDeriv(const unsigned int, std::set< RefinablePar * > &vPar)
Get the first derivative for the LSQ function for each parameter supplied in a list.
void PrepareTwinningCalc() const
Determine the index of reflections to be summed because of twinning (GroupOption==1) The reflections ...
CrystVector_REAL mFhklObsSq
Observed squared structure factors (zero-sized if none)
CrystVector_REAL mGroupIobs
The observed intensities summed on all reflections that are (or could be) overlapped dur to a twinnin...
CrystVector_REAL mFhklCalcSq
F(HKL)^2 calc for each reflection.
WX Class for DiffractionDataSingleCrystal objects.
void ImportShelxHKLF4(const string &fileName)
Import h,k,l,I,Sigma from a file using shelx HKLF 4 format.
std::map< std::string, CIFData > mvData
The data blocks, after parsing. The key is the name of the data block.
Definition: CIF.h:181
long mNbReflUsed
Number of reflections which are below the max.
CrystVector_REAL mGroupSigma
The uncertainty on observed grouped intensities.
const CrystVector_REAL & GetSigma() const
Return the array of sigmas for observed intensities, for all peaks.
void ImportHklIobsGroup(const string &fileName, const unsigned int skipLines=0)
Import h,k,l and grouped intensities from a file.
virtual REAL GetR() const
Return the Crystal R-factor (unweighted)
void Reset()
Reset a Clock to 0, to force an update.
Exception class for ObjCryst++ library.
Definition: General.h:119
virtual void SetWeightToInvSigma2(const REAL minRelatSigma=1e-4, const REAL minIobsSigmaRatio=0)
Set the weight for all observed intensities to 1/sigma^2.
virtual REAL GetBestRFactor() const
Compute the best scale factor to minimize R, apply this scale factor and return the R value obtained...
RefinableObjClock mClockIcalc
Last time Icalc was computed.
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: Atom.cpp:47
CrystVector_REAL mObsIntensity
Observed intensity (after ABS and LP corrections)
RefinableObjClock mClockChi2
Clock the last time Chi^2 was computed.
Generic class for parameters of refinable objects.
Definition: RefinableObj.h:223
RefinableObjClock mClockStructFactorSq
Clock for the square modulus of the structure factor.
RefinableObjClock mClockFhklObsSq
Last time observed squared structure factors were altered.
virtual const string & GetName() const
Name of the object.
void SetSigma(const CrystVector_REAL &)
Return the array of sigmas for observed intensities, for all peaks.
RadiationType
Type of radiation used.
Definition: General.h:94
void ImportHklIobsSigma(const string &fileName, const long nbRefl, const int skipLines=0)
Import h,k,l,I,Sigma from a file.
void SetIobsToIcalc()
Set Iobs to current values of Icalc. Mostly used for tests.
CrystVector_REAL mWeight
weight for computing R-Factor, for each observed value.
Crystal class: Unit cell, spacegroup, scatterers.
Definition: Crystal.h:97
void InitOptions()
Init options (currently only twinning).
void SetGlobalOptimStep(const RefParType *type, const REAL step)
Change the maximum step to use during Global Optimization algorithms.
RefinableObjClock mClockPrepareTwinningCorr
Clock for twinning, when the preparation of twinning correction was last made.
virtual REAL GetRw() const
Return the Crystal R-factor (weighted)
ObjRegistry< RefObjOpt > mOptionRegistry
List of options for this object.
class of refinable parameter types.
Definition: RefinableObj.h:78
bool mHasObservedData
Are there observed intensities ?
CrystVector_REAL mFhklCalcReal
real &imaginary parts of F(HKL)calc
Class to define the radiation (type, monochromaticity, wavelength(s)) of an experiment.
virtual DiffractionDataSingleCrystal * CreateCopy() const
So-called virtual copy constructor.
void AddOption(RefObjOpt *opt)
virtual void PrintObsCalcData() const
Print H, K, L Iobs sigma Icalc for all reflections Iobs and sigma (if given) are scaled to Icalc (if ...
std::map< RefinablePar *, CrystVector_REAL > & GetIcalc_FullDeriv(std::set< RefinablePar * > &vPar)
virtual REAL GetChi2() const
Return conventionnal Chi^2.
void ImportCIF(const string &fileName)
Import diffraction data from a CIF file.
void SetWavelength(const REAL)
Set the (monochromatic) wavelength of the beam.