24 #include "ObjCryst/ObjCryst/ReflectionProfile.h"
25 #include "ObjCryst/Quirks/VFNStreamFormat.h"
27 #include "ObjCryst/wxCryst/wxPowderPattern.h"
30 #ifdef HAVE_SSE_MATHFUN
31 #include "ObjCryst/Quirks/sse_mathfun.h"
36 #if defined(_MSC_VER) || defined(__BORLANDC__)
40 double erfc(
const double x)
42 if(x<0.0)
return 2.0-erfc(-x);
46 for(
int i=1;i<=50;i++)
51 static const double spi=2/sqrt(M_PI);
52 return 1-spi*exp(-x*x)*y;
55 for(
int i=1;i<=10;i++)
60 static const double invsqrtpi=1.0/sqrt(M_PI);
61 return invsqrtpi*exp(-x*x)/x*y;
70 ObjRegistry<ReflectionProfile>
77 ReflectionProfile::ReflectionProfile():
80 ReflectionProfile::ReflectionProfile(
const ReflectionProfile &old)
82 ReflectionProfile::~ReflectionProfile()
84 bool ReflectionProfile::IsAnisotropic()
const
91 ReflectionProfilePseudoVoigt::ReflectionProfilePseudoVoigt():
93 mCagliotiU(0),mCagliotiV(0),mCagliotiW(.01*DEG2RAD*DEG2RAD),
94 mPseudoVoigtEta0(0.5),mPseudoVoigtEta1(0.0),
95 mAsymBerarBaldinozziA0(0.0),mAsymBerarBaldinozziA1(0.0),
96 mAsymBerarBaldinozziB0(0.0),mAsymBerarBaldinozziB1(0.0),
97 mAsym0(1.0),mAsym1(0.0),mAsym2(0.0)
99 this->InitParameters();
102 ReflectionProfilePseudoVoigt::ReflectionProfilePseudoVoigt
103 (
const ReflectionProfilePseudoVoigt &old):
104 mCagliotiU(old.mCagliotiU),mCagliotiV(old.mCagliotiV),mCagliotiW(old.mCagliotiW),
105 mPseudoVoigtEta0(old.mPseudoVoigtEta0),mPseudoVoigtEta1(old.mPseudoVoigtEta1),
106 mAsymBerarBaldinozziA0(old.mAsymBerarBaldinozziA0),
107 mAsymBerarBaldinozziA1(old.mAsymBerarBaldinozziA1),
108 mAsymBerarBaldinozziB0(old.mAsymBerarBaldinozziB0),
109 mAsymBerarBaldinozziB1(old.mAsymBerarBaldinozziB1),
110 mAsym0(old.mAsym0),mAsym1(old.mAsym1),mAsym2(old.mAsym2)
112 this->InitParameters();
115 ReflectionProfilePseudoVoigt::~ReflectionProfilePseudoVoigt()
126 ReflectionProfilePseudoVoigt* ReflectionProfilePseudoVoigt::CreateCopy()
const
128 return new ReflectionProfilePseudoVoigt(*
this);
133 static string className=
"ReflectionProfilePseudoVoigt";
138 const REAL center,
const REAL h,
const REAL k,
const REAL l)
const
140 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::GetProfile(),c="<<center,2)
141 REAL fwhm= mCagliotiW
142 +mCagliotiV*tan(center/2.0)
146 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigt::GetProfile(): fwhm**2<0 ! "
147 <<h<<
","<<k<<
","<<l<<
":"<<center<<
","<<
mCagliotiU<<
","<<mCagliotiV<<
","<<
","<<mCagliotiW<<
":"<<fwhm,10);
150 else fwhm=sqrt(fwhm);
151 CrystVector_REAL profile,tmpV;
152 const REAL asym=
mAsym0+mAsym1/sin(center)+mAsym2/pow((REAL)sin(center),(REAL)2.0);
153 profile=PowderProfileGauss(x,fwhm,center,asym);
161 tmpV=PowderProfileLorentz(x,fwhm,center,asym);
167 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::GetProfile()",2)
172 const REAL fwhmCagliotiU,
173 const REAL fwhmCagliotiV,
178 mCagliotiV=fwhmCagliotiV;
179 mCagliotiW=fwhmCagliotiW;
181 mPseudoVoigtEta1=eta1;
187 const REAL center,
const REAL h,
const REAL k,
const REAL l)
189 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth()",2)
191 const int halfnb=nb/2;
192 CrystVector_REAL x(nb);
194 REAL fwhm= mCagliotiW
195 +mCagliotiV*tan(center/2.0)
197 if(fwhm<=0) fwhm=1e-6;
198 else fwhm=sqrt(fwhm);
199 CrystVector_REAL prof;
204 const REAL tmp=fwhm*n/nb;
205 for(
int i=0;i<nb;i++) *p++ = tmp*(i-halfnb);
209 const REAL max=prof.max();
210 const REAL test=max*relativeIntensity;
212 if((prof(0)<test)&&(prof(nb-1)<test))
215 while(*p<test){ p++; n1++;n2++;}
217 while(*p>test){ p++; n2++;}
218 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth():"<<x(n2)-x(n1),2)
221 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth():"<<relativeIntensity<<
","
222 <<fwhm<<
","<<center<<
","<<h<<
","<<k<<
","<<l<<
","<<max<<
","<<test,2)
234 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
240 RefinablePar tmp(
"V",&mCagliotiV,-1/RAD2DEG/RAD2DEG,1./RAD2DEG/RAD2DEG,
242 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
250 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
257 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
264 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
272 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
279 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
286 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
293 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
301 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
308 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
315 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
324 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::XMLOutput():"<<this->
GetName(),5)
325 for(
int i=0;i<indent;i++) os <<
" " ;
367 tag.SetIsEndTag(
true);
368 for(
int i=0;i<indent;i++) os <<
" " ;
370 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::XMLOutput():"<<this->
GetName(),5)
374 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::XMLInput():"<<this->
GetName(),5)
375 for(
unsigned int i=0;i<tagg.GetNbAttribute();i++)
377 if(
"Name"==tagg.GetAttributeName(i)) this->
SetName(tagg.GetAttributeValue(i));
382 if((
"ReflectionProfilePseudoVoigt"==tag.GetName())&&tag.IsEndTag())
385 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::Exit():"<<this->
GetName(),5)
388 if(
"Par"==tag.GetName())
390 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
392 if(
"Name"==tag.GetAttributeName(i))
394 if(
"U"==tag.GetAttributeValue(i))
399 if(
"V"==tag.GetAttributeValue(i))
404 if(
"W"==tag.GetAttributeValue(i))
409 if(
"Eta0"==tag.GetAttributeValue(i))
414 if(
"Eta1"==tag.GetAttributeValue(i))
419 if(
"Asym0"==tag.GetAttributeValue(i))
424 if(
"Asym1"==tag.GetAttributeValue(i))
429 if(
"Asym2"==tag.GetAttributeValue(i))
435 if(
"AsymA0"==tag.GetAttributeValue(i))
440 if(
"AsymA1"==tag.GetAttributeValue(i))
445 if(
"AsymB0"==tag.GetAttributeValue(i))
450 if(
"AsymB1"==tag.GetAttributeValue(i))
460 if(
"Option"==tag.GetName())
462 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
463 if(
"Name"==tag.GetAttributeName(i))
470 WXCrystObjBasic* ReflectionProfilePseudoVoigt::WXCreate(wxWindow* parent)
472 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::WXCreate()",6)
486 ReflectionProfilePseudoVoigtAnisotropic::ReflectionProfilePseudoVoigtAnisotropic():
487 mCagliotiU(0),mCagliotiV(0),mCagliotiW(.01*DEG2RAD*DEG2RAD),mScherrerP(0),mLorentzX(0),mLorentzY(0),
488 mLorentzGammaHH(0),mLorentzGammaKK(0),mLorentzGammaLL(0),mLorentzGammaHK(0),mLorentzGammaHL(0),mLorentzGammaKL(0),
494 ReflectionProfilePseudoVoigtAnisotropic::ReflectionProfilePseudoVoigtAnisotropic(
const ReflectionProfilePseudoVoigtAnisotropic &old):
495 mCagliotiU(old.mCagliotiU),mCagliotiV(old.mCagliotiV),mCagliotiW(old.mCagliotiW),mScherrerP(old.mScherrerP),mLorentzX(old.mLorentzX),mLorentzY(old.mLorentzY),
496 mLorentzGammaHH(old.mLorentzGammaHH),mLorentzGammaKK(old.mLorentzGammaKK),mLorentzGammaLL(old.mLorentzGammaLL),mLorentzGammaHK(old.mLorentzGammaHK),mLorentzGammaHL(old.mLorentzGammaHL),mLorentzGammaKL(old.mLorentzGammaKL),
497 mPseudoVoigtEta0(old.mPseudoVoigtEta0),mPseudoVoigtEta1(old.mPseudoVoigtEta1),mAsym0(old.mAsym0),mAsym1(old.mAsym1),mAsym2(old.mAsym2)
501 ReflectionProfilePseudoVoigtAnisotropic::~ReflectionProfilePseudoVoigtAnisotropic()
512 ReflectionProfilePseudoVoigtAnisotropic* ReflectionProfilePseudoVoigtAnisotropic::CreateCopy()
const
514 return new ReflectionProfilePseudoVoigtAnisotropic(*
this);
519 static string className=
"ReflectionProfilePseudoVoigtAnisotropic";
524 const REAL h,
const REAL k,
const REAL l)
const
526 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigtAnisotropic::GetProfile()",2)
527 const REAL tantheta=tan(center/2.0);
528 const REAL costheta=cos(center/2.0);
529 const REAL sintheta=sin(center/2.0);
530 const REAL fwhmG=sqrt(abs( mCagliotiW+mCagliotiV*tantheta+
mCagliotiU*tantheta*tantheta+mScherrerP/(costheta*costheta)));
531 const REAL gam=mLorentzGammaHH*h*h+mLorentzGammaKK*k*k+mLorentzGammaLL*l*l+2*mLorentzGammaHK*h*k+2*mLorentzGammaHL*h*l+2*mLorentzGammaKL*k*l;
532 const REAL fwhmL= mLorentzX/costheta+(mLorentzY+gam/(sintheta*sintheta))*tantheta;
538 CrystVector_REAL profile(x.numElements()),tmpV(x.numElements());
539 const REAL asym=
mAsym0+mAsym1/sin(center)+mAsym2/pow((REAL)sin(center),(REAL)2.0);
540 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigtAnisotropic::GetProfile():("<<
int(h)<<
","<<
int(k)<<
","<<
int(l)<<
"),fwhmG="<<fwhmG<<
",fwhmL="<<fwhmL<<
",gam="<<gam<<
",asym="<<asym<<
",center="<<center<<
",eta="<<eta, 2)
543 profile=PowderProfileGauss(x,fwhmG,center,asym);
549 tmpV=PowderProfileLorentz(x,fwhmL,center,asym);
554 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigtAnisotropic::GetProfile()",2)
559 const REAL fwhmCagliotiU,
560 const REAL fwhmCagliotiV,
561 const REAL fwhmGaussP,
562 const REAL fwhmLorentzX,
563 const REAL fwhmLorentzY,
564 const REAL fwhmLorentzGammaHH,
565 const REAL fwhmLorentzGammaKK,
566 const REAL fwhmLorentzGammaLL,
567 const REAL fwhmLorentzGammaHK,
568 const REAL fwhmLorentzGammaHL,
569 const REAL fwhmLorentzGammaKL,
570 const REAL pseudoVoigtEta0,
571 const REAL pseudoVoigtEta1,
578 mCagliotiV=fwhmCagliotiV;
579 mCagliotiW=fwhmCagliotiW;
580 mLorentzX=fwhmLorentzX;
581 mLorentzY=fwhmLorentzY;
582 mLorentzGammaHH=fwhmLorentzGammaHH;
583 mLorentzGammaKK=fwhmLorentzGammaKK;
584 mLorentzGammaLL=fwhmLorentzGammaLL;
585 mLorentzGammaHK=fwhmLorentzGammaHK;
586 mLorentzGammaHL=fwhmLorentzGammaHL;
587 mLorentzGammaKL=fwhmLorentzGammaKL;
589 mPseudoVoigtEta1=pseudoVoigtEta1;
597 const REAL h,
const REAL k,
const REAL l)
599 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth()",2)
601 const int halfnb=nb/2;
602 CrystVector_REAL x(nb);
604 const REAL tantheta=tan(center/2.0);
605 const REAL costheta=cos(center/2.0);
606 const REAL sintheta=sin(center/2.0);
607 const REAL fwhmG=sqrt(abs( mCagliotiW+mCagliotiV*tantheta+
mCagliotiU*tantheta*tantheta+mScherrerP/(costheta*costheta)));
608 const REAL gam=mLorentzGammaHH*h*h+mLorentzGammaKK*k*k+mLorentzGammaLL*l*l+2*mLorentzGammaHK*h*k+2*mLorentzGammaHL*h*l+2*mLorentzGammaKL*k*l;
609 const REAL fwhmL= mLorentzX/costheta+(mLorentzY+gam/(sintheta*sintheta))*tantheta;
612 REAL fwhm=fwhmL*eta+fwhmG*(1-eta);
613 if(fwhm<=0) fwhm=1e-3;
614 CrystVector_REAL prof;
619 const REAL tmp=fwhm*n/nb;
620 for(
int i=0;i<nb;i++) *p++ = tmp*(i-halfnb);
623 const REAL max=prof.max();
624 const REAL test=max*relativeIntensity;
626 if((prof(0)<test)&&(prof(nb-1)<test))
629 while(*p<test){ p++; n1++;n2++;}
631 while(*p>test){ p++; n2++;}
632 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigtAnisotropic::GetFullProfileWidth():"<<x(n2)-x(n1),2)
635 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigtAnisotropic::GetFullProfileWidth():"<<relativeIntensity<<
","
636 <<fwhm<<
","<<center<<
","<<h<<
","<<k<<
","<<l<<
","<<max<<
","<<test,2)
649 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigtAnisotropic::XMLOutput():"<<this->
GetName(),5)
650 for(
int i=0;i<indent;i++) os <<
" " ;
651 XMLCrystTag tag(
"ReflectionProfilePseudoVoigtAnisotropic");
706 tag.SetIsEndTag(
true);
707 for(
int i=0;i<indent;i++) os <<
" " ;
709 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigtAnisotropic::XMLOutput():"<<this->
GetName(),5)
714 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigtAnisotropic::XMLInput():"<<this->
GetName(),5)
715 for(
unsigned int i=0;i<tagg.GetNbAttribute();i++)
717 if(
"Name"==tagg.GetAttributeName(i)) this->
SetName(tagg.GetAttributeValue(i));
722 if((
"ReflectionProfilePseudoVoigtAnisotropic"==tag.GetName())&&tag.IsEndTag())
725 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigtAnisotropic::Exit():"<<this->
GetName(),5)
728 if(
"Par"==tag.GetName())
730 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
732 if(
"Name"==tag.GetAttributeName(i))
734 if(
"U"==tag.GetAttributeValue(i))
739 if(
"V"==tag.GetAttributeValue(i))
744 if(
"W"==tag.GetAttributeValue(i))
749 if(
"P"==tag.GetAttributeValue(i))
754 if(
"X"==tag.GetAttributeValue(i))
759 if(
"Y"==tag.GetAttributeValue(i))
764 if(
"G_HH"==tag.GetAttributeValue(i))
769 if(
"G_KK"==tag.GetAttributeValue(i))
774 if(
"G_LL"==tag.GetAttributeValue(i))
779 if(
"G_HK"==tag.GetAttributeValue(i))
784 if(
"G_HL"==tag.GetAttributeValue(i))
789 if(
"G_KL"==tag.GetAttributeValue(i))
794 if(
"Eta0"==tag.GetAttributeValue(i))
799 if(
"Eta1"==tag.GetAttributeValue(i))
804 if(
"Asym0"==tag.GetAttributeValue(i))
809 if(
"Asym1"==tag.GetAttributeValue(i))
814 if(
"Asym2"==tag.GetAttributeValue(i))
823 if(
"Option"==tag.GetName())
825 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
826 if(
"Name"==tag.GetAttributeName(i))
838 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
844 RefinablePar tmp(
"V",&mCagliotiV,-1/RAD2DEG/RAD2DEG,1./RAD2DEG/RAD2DEG,
846 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
854 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
860 RefinablePar tmp(
"P",&mScherrerP,-1./RAD2DEG/RAD2DEG,1./RAD2DEG/RAD2DEG,
862 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
870 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
878 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
884 RefinablePar tmp(
"G_HH",&mLorentzGammaHH,-1./RAD2DEG,1./RAD2DEG,
886 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
892 RefinablePar tmp(
"G_KK",&mLorentzGammaKK,-1./RAD2DEG,1./RAD2DEG,
894 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
900 RefinablePar tmp(
"G_LL",&mLorentzGammaLL,-1./RAD2DEG,1./RAD2DEG,
902 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
908 RefinablePar tmp(
"G_HK",&mLorentzGammaHK,-1./RAD2DEG,1./RAD2DEG,
910 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
916 RefinablePar tmp(
"G_HL",&mLorentzGammaHL,-1./RAD2DEG,1./RAD2DEG,
918 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
924 RefinablePar tmp(
"G_KL",&mLorentzGammaKL,-1./RAD2DEG,1./RAD2DEG,
926 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
933 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
940 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
947 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
954 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
961 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
969 WXCrystObjBasic* ReflectionProfilePseudoVoigtAnisotropic::WXCreate(wxWindow* parent)
971 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::WXCreate()",6)
986 mInstrumentAlpha0(0.0),
987 mInstrumentAlpha1(0.0952),
988 mInstrumentBeta0(0.0239),
989 mInstrumentBeta1(0.0043),
990 mGaussianSigma0(0.0),
991 mGaussianSigma1(7.0),
992 mGaussianSigma2(0.0),
993 mLorentzianGamma0(0.0),
994 mLorentzianGamma1(0.0),
995 mLorentzianGamma2(0.414),
998 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::ReflectionProfileDoubleExponentialPseudoVoigt()",10)
1005 mInstrumentAlpha0(0.0),
1006 mInstrumentAlpha1(0.0952),
1007 mInstrumentBeta0(0.0239),
1008 mInstrumentBeta1(0.0043),
1009 mGaussianSigma0(0.0),
1010 mGaussianSigma1(7.0),
1011 mGaussianSigma2(0.0),
1012 mLorentzianGamma0(0.0),
1013 mLorentzianGamma1(0.0),
1014 mLorentzianGamma2(0.414),
1017 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::ReflectionProfileDoubleExponentialPseudoVoigt()",10)
1018 this->InitParameters();
1024 mInstrumentAlpha0(old.mInstrumentAlpha0),
1025 mInstrumentAlpha1(old.mInstrumentAlpha1),
1026 mInstrumentBeta0(old.mInstrumentBeta0),
1027 mInstrumentBeta1(old.mInstrumentBeta1),
1028 mGaussianSigma0(old.mGaussianSigma0),
1029 mGaussianSigma1(old.mGaussianSigma1),
1030 mGaussianSigma2(old.mGaussianSigma2),
1031 mLorentzianGamma0(old.mLorentzianGamma0),
1032 mLorentzianGamma1(old.mLorentzianGamma1),
1033 mLorentzianGamma2(old.mLorentzianGamma2),
1036 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::ReflectionProfileDoubleExponentialPseudoVoigt()",10)
1042 #ifdef __WX__CRYST__
1045 delete mpWXCrystObj;
1052 ReflectionProfileDoubleExponentialPseudoVoigt::CreateCopy()
const
1059 static string className=
"ReflectionProfileDoubleExponentialPseudoVoigt";
1064 ::GetProfile(
const CrystVector_REAL &x,
const REAL center,
1065 const REAL h,
const REAL k,
const REAL l)
const
1067 VFN_DEBUG_ENTRY(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetProfile()",4)
1071 REAL hh=h,kk=k,ll=l;
1073 dcenter=1.0/sqrt(hh*hh+kk*kk+ll*ll);
1075 const REAL alpha=mInstrumentAlpha0+mInstrumentAlpha1/dcenter;
1076 const REAL beta=mInstrumentBeta0+mInstrumentBeta1/pow(dcenter,4);
1077 const REAL siggauss2= mGaussianSigma0
1078 +mGaussianSigma1*pow(dcenter,2)
1079 +mGaussianSigma2*pow(dcenter,4);
1080 static const REAL log2=log(2.0);
1081 const REAL hg=sqrt(8*siggauss2*log2);
1082 const REAL hl= mLorentzianGamma0
1083 +mLorentzianGamma1*dcenter
1084 +mLorentzianGamma2*dcenter*dcenter;
1085 const REAL hcom=pow(pow(hg,5)+2.69269*pow(hg,4)*hl+2.42843*pow(hg,3)*hl*hl
1086 +4.47163*hg*hg*pow(hl,3)+0.07842*hg*pow(hl,4)+pow(hl,5),0.2);
1087 const REAL sigcom2=hcom*hcom/(8.0*log2);
1088 const REAL eta=1.36603*hl/hcom-0.47719*pow(hl/hcom,2)+0.11116*pow(hl/hcom,3);
1089 const long nbPoints=x.numElements();
1090 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetProfile():alpha="
1091 <<alpha<<
",beta="<<beta<<
",siggauss2="<<siggauss2
1092 <<
",hg="<<hg<<
",hl="<<hl<<
",hcom="<<hcom<<
",sigcom2="<<sigcom2
1094 CrystVector_REAL prof;
1097 REAL *pp=prof.data();
1098 for(
long i=0;i<nbPoints;i++)
1100 const double u=alpha/2*(alpha*sigcom2+2* *pp);
1101 const double nu=beta/2*(beta *sigcom2-2* *pp);
1102 const double y=(alpha*sigcom2+*pp)/sqrt(2*sigcom2);
1103 const double z=(beta *sigcom2-*pp)/sqrt(2*sigcom2);
1104 const complex<double> p(alpha* *pp,alpha*hcom/2);
1105 const complex<double> q(-beta* *pp, beta*hcom/2);
1108 VFN_DEBUG_MESSAGE(
"dt="<<*pp<<
", u="<<u<<
",nu="<<nu<<
",y="<<y<<
",z="<<z
1109 <<
",p=("<<p.real()<<
","<<p.imag()
1110 <<
"),q=("<<q.real()<<
","<<q.imag()
1111 <<
"),e^p*E1(p)=("<<e1p.real()<<
","<<e1p.imag()
1112 <<
"),e^q*E1(q)=("<<e1q.real()<<
","<<e1q.imag(),2)
1113 REAL expnu_erfcz,expu_erfcy;
1115 if(z>10.0) expnu_erfcz=exp(nu-z*z)/(z*sqrt(M_PI));
1116 else expnu_erfcz=exp(nu)*erfc(z);
1118 if(y>10.0) expu_erfcy=exp(u-y*y)/(y*sqrt(M_PI));
1119 else expu_erfcy=exp(u)*erfc(y);
1122 double tmp=(1-eta)*alpha*beta/(2*(alpha+beta))*(expu_erfcy+expnu_erfcz)
1123 -eta*alpha*beta/(M_PI*(alpha+beta))*(e1p.imag()+e1q.imag());
1126 cout<<
"*pp==numeric_limits<REAL>::quiet_NaN()"<<endl;
1127 cout<<
"ReflectionProfileDoubleExponentialPseudoVoigt::GetProfile():"<<endl
1128 <<
" alpha="<<alpha<<
",beta="<<beta<<
",siggauss2="<<siggauss2
1129 <<
",hg="<<hg<<
",hl="<<hl<<
",hcom="<<hcom<<
",sigcom2="<<sigcom2
1130 <<
",eta="<<eta<<endl;
1131 cout<<
" dt="<<*pp<<
", u="<<u<<
",nu="<<nu<<
",y="<<y<<
",z="<<z
1132 <<
",e^u*E1(y)="<<expu_erfcy
1133 <<
",e^nu*E1(z)="<<expnu_erfcz
1135 <<
" p=("<<p.real()<<
","<<p.imag()
1136 <<
"),q=("<<q.real()<<
","<<q.imag()
1137 <<
"),e^p*E1(p)=("<<e1p.real()<<
","<<e1p.imag()
1138 <<
"),e^q*E1(q)=("<<e1q.real()<<
","<<e1q.imag()<<endl;
1139 cout<<(1-eta)*alpha*beta/(2*(alpha+beta))*(expu_erfcy+expnu_erfcz)<<endl
1140 <<eta*alpha*beta/(M_PI*(alpha+beta))*(e1p.imag()+e1q.imag())<<endl
1145 if(abs(*pp)==numeric_limits<REAL>::infinity())
1147 cout<<
"*pp==numeric_limits<REAL>::infinity()"<<endl;
1152 *pp++=(1-eta)*alpha*beta/(2*(alpha+beta))*(expu_erfcy+expnu_erfcz)
1153 -eta*alpha*beta/(M_PI*(alpha+beta))*(e1p.imag()+e1q.imag());
1155 VFN_DEBUG_EXIT(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetProfile()",4)
1161 const REAL instrumentAlpha1,
1162 const REAL instrumentBeta0,
1163 const REAL instrumentBeta1,
1164 const REAL gaussianSigma0,
1165 const REAL gaussianSigma1,
1166 const REAL gaussianSigma2,
1167 const REAL lorentzianGamma0,
1168 const REAL lorentzianGamma1,
1169 const REAL lorentzianGamma2)
1171 mInstrumentAlpha0=instrumentAlpha0;
1172 mInstrumentAlpha1=instrumentAlpha1;
1173 mInstrumentBeta0=instrumentBeta0;
1174 mInstrumentBeta1=instrumentBeta1;
1175 mGaussianSigma0=gaussianSigma0;
1176 mGaussianSigma1=gaussianSigma1;
1177 mGaussianSigma2=gaussianSigma2;
1178 mLorentzianGamma0=lorentzianGamma0;
1179 mLorentzianGamma1=lorentzianGamma1;
1180 mLorentzianGamma2=lorentzianGamma2;
1186 const REAL h,
const REAL k,
const REAL l)
1188 VFN_DEBUG_ENTRY(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetFullProfileWidth()",5)
1192 REAL hh=h,kk=k,ll=l;
1193 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetFullProfileWidth(),"<<dcenter<<
","<<mpCell->
GetName(),5)
1195 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetFullProfileWidth(),"<<dcenter,5)
1196 dcenter=sqrt(hh*hh+kk*kk+ll*ll);
1198 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetFullProfileWidth(),"<<dcenter,5)
1200 const int halfnb=nb/2;
1201 CrystVector_REAL x(nb);
1203 const REAL siggauss2= mGaussianSigma0
1204 +mGaussianSigma1*pow(dcenter,2)
1205 +mGaussianSigma2*pow(dcenter,4);
1206 static const REAL log2=log(2.0);
1207 const REAL hg=sqrt(8*siggauss2*log2);
1208 const REAL hl= mLorentzianGamma0
1209 +mLorentzianGamma1*dcenter
1210 +mLorentzianGamma2*dcenter*dcenter;
1211 const REAL fwhm=pow(pow(hg,5)+2.69269*pow(hg,4)*hl+2.42843*pow(hg,3)*hl*hl
1212 +4.47163*hg*hg*pow(hl,3)+0.07842*hg*pow(hl,4)+pow(hl,5),0.2);
1213 CrystVector_REAL prof;
1217 const REAL tmp=fwhm*n/nb;
1218 for(
int i=0;i<nb;i++) *p++ = tmp*(i-halfnb);
1221 const REAL max=prof.max();
1222 const REAL test=max*relativeIntensity;
1224 if((prof(0)<test)&&(prof(nb-1)<test))
1227 while(*p<test){ p++; n1++;n2++;}
1229 while(*p>test){ p++; n2++;}
1230 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth():"<<x(n2)-x(n1),5)
1231 return abs(x(n2)-x(n1));
1233 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth():"<<max<<
","<<test
1248 VFN_DEBUG_ENTRY(
"ReflectionProfileDoubleExponentialPseudoVoigt::XMLOutput():"<<this->
GetName(),5)
1249 for(
int i=0;i<indent;i++) os <<
" " ;
1250 XMLCrystTag tag(
"ReflectionProfileDoubleExponentialPseudoVoigt");
1275 this->
GetPar(&mLorentzianGamma0).
XMLOutput(os,
"LorentzianGamma0",indent);
1278 this->
GetPar(&mLorentzianGamma1).
XMLOutput(os,
"LorentzianGamma1",indent);
1281 this->
GetPar(&mLorentzianGamma2).
XMLOutput(os,
"LorentzianGamma2",indent);
1285 tag.SetIsEndTag(
true);
1286 for(
int i=0;i<indent;i++) os <<
" " ;
1288 VFN_DEBUG_EXIT(
"ReflectionProfileDoubleExponentialPseudoVoigt::XMLOutput():"<<this->
GetName(),5)
1294 VFN_DEBUG_ENTRY(
"ReflectionProfileDoubleExponentialPseudoVoigt::XMLInput():"<<this->
GetName(),5)
1295 for(
unsigned int i=0;i<tagg.GetNbAttribute();i++)
1297 if(
"Name"==tagg.GetAttributeName(i)) this->
SetName(tagg.GetAttributeValue(i));
1302 if((
"ReflectionProfileDoubleExponentialPseudoVoigt"==tag.GetName())&&tag.IsEndTag())
1305 VFN_DEBUG_EXIT(
"ReflectionProfileDoubleExponentialPseudoVoigt::Exit():"<<this->
GetName(),5)
1308 if(
"Par"==tag.GetName())
1310 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
1312 if(
"Name"==tag.GetAttributeName(i))
1319 if(
"Option"==tag.GetName())
1321 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
1322 if(
"Name"==tag.GetAttributeName(i))
1331 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::SetUnitCell()",10)
1340 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1347 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1354 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1361 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1368 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1375 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1382 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1389 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1396 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1403 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1410 #ifdef __WX__CRYST__
1411 WXCrystObjBasic* ReflectionProfileDoubleExponentialPseudoVoigt::WXCreate(wxWindow* parent)
1415 return mpWXCrystObj;
1423 CrystVector_REAL PowderProfileGauss (
const CrystVector_REAL ttheta,
const REAL fw,
1424 const REAL center,
const REAL asym)
1426 TAU_PROFILE(
"PowderProfileGauss()",
"Vector (Vector,REAL)",TAU_DEFAULT);
1428 if(fwhm<=0) fwhm=1e-6;
1429 const long nbPoints=ttheta.numElements();
1430 CrystVector_REAL result(nbPoints);
1438 result *= -4.*log(2.)/fwhm/fwhm;
1442 const REAL c1= -(1.+asym)/asym*(1.+asym)/asym*log(2.)/fwhm/fwhm;
1443 const REAL c2= -(1.+asym) *(1.+asym) *log(2.)/fwhm/fwhm;
1446 const REAL *pt=ttheta.data();
1447 for(i=0;i<nbPoints;i++){ *p++ *= c1;
if(*pt++>center)
break;}
1449 for( ;i<nbPoints;i++) *p++ *= c2;
1455 for(
long i=0;i<nbPoints;i++) { *p = pow((
float)2.71828182846,(
float)*p) ; p++ ;}
1460 #ifdef HAVE_SSE_MATHFUN
1461 v4sf x=_mm_loadu_ps(p);
1462 _mm_storeu_ps(p,exp_ps(x));
1465 for(
unsigned int j=0;j<4;++j)
1472 for(;i>0;i--) { *p = exp(*p) ; p++ ;}
1480 for(;i<nbPoints;i+=4)
1481 for(
unsigned int j=0;j<4;++j)
1483 *p = pow((
float)2.71828182846,(
float)*p) ;
1488 for(;i<nbPoints;i+=1)
1498 result *= 2. / fwhm * sqrt(log(2.)/M_PI);
1502 CrystVector_REAL PowderProfileLorentz(
const CrystVector_REAL ttheta,
const REAL fw,
1503 const REAL center,
const REAL asym)
1505 TAU_PROFILE(
"PowderProfileLorentz()",
"Vector (Vector,REAL)",TAU_DEFAULT);
1507 if(fwhm<=0) fwhm=1e-6;
1508 const long nbPoints=ttheta.numElements();
1509 CrystVector_REAL result(nbPoints);
1517 result *= 4./fwhm/fwhm;
1521 const REAL c1= (1+asym)/asym*(1+asym)/asym/fwhm/fwhm;
1522 const REAL c2= (1+asym) *(1+asym) /fwhm/fwhm;
1525 const REAL *pt=ttheta.data();
1526 for(i=0;i<nbPoints;i++){ *p++ *= c1;
if(*pt++>center)
break;}
1528 for( ;i<nbPoints;i++) *p++ *= c2 ;
1532 for(
long i=0;i<nbPoints;i++) { *p = 1/(*p) ; p++ ;}
1533 result *= 2./M_PI/fwhm;
1538 const REAL fw,
const REAL center,
1539 const REAL a0,
const REAL a1,
1540 const REAL b0,
const REAL b1)
1542 TAU_PROFILE(
"AsymmetryBerarBaldinozzi()",
"Vector (Vector,REAL)",TAU_DEFAULT);
1544 if(fwhm<=0) fwhm=1e-6;
1545 const long nbPoints=x.numElements();
1546 CrystVector_REAL result(nbPoints);
1550 REAL *p=result.data();
1551 const REAL a=a0/tan(center/2)+a1/tan(center);
1552 const REAL b=b0/tan(center/2)+b1/tan(center);
1553 for(
long i=0;i<nbPoints;i++)
1555 *p = 1+*p * exp(-*p * *p)*(2*a+b*(8* *p * *p-12));
1609 const T zr=z.real();
1612 if(zn==0.0)
return 1e100;
1613 if((zn<10.0)||((zr<0.0)&&(zn<20.0)))
1615 ce1=complex<T>(1,0);
1617 for(
unsigned int i=1;i<=150;i++)
1619 y=-y*(T)i*z / (T)((i+1)*(i+1));
1621 if(abs(y)<=abs(ce1)*1e-15)
break;
1623 static const T EulerMascheroni=0.5772156649015328606065120900;
1624 return exp(z)*(z*ce1-EulerMascheroni-log(z));
1628 if(zn>500)
return 1.0/z;
1629 complex<T> y(0.0,0.0);
1630 for(
unsigned int i=120;i>=1;i--) y=(T)i/((T)1+(T)i/(z+y));
1632 if((zr<0)&&(z.imag()==0)) ce1 -= complex<T>(0.0,M_PI)*exp(z);
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
const RefParType * gpRefParTypeScattDataProfileWidth
Type for reflection profile width.
ObjRegistry< ReflectionProfile > gReflectionProfileRegistry("List of all ReflectionProfile types")
Global registry for all ReflectionProfile objects.
const RefParType * gpRefParTypeScattDataProfile
Type for reflection profile.
std::complex< T > ExponentialIntegral1_ExpZ(const complex< T > z)
E1(z)*exp(z)
const RefParType * gpRefParTypeScattDataProfileType
Type for reflection profiles type (e.g. gaussian/lorentzian mix)
CrystVector_REAL AsymmetryBerarBaldinozzi(const CrystVector_REAL x, const REAL fw, const REAL center, const REAL a0, const REAL a1, const REAL b0, const REAL b1)
Asymmetry function [Ref J. Appl. Cryst 26 (1993), 128-129.
std::complex< T > ExponentialIntegral1(const complex< T > z)
Complex exponential integral E1(z) (Abramowitz & Stegun, chap.
const RefParType * gpRefParTypeScattDataProfileAsym
Type for reflection profile asymmetry.
Abstract base class for reflection profiles.
Pseudo-Voigt reflection profile.
virtual void XMLOutput(ostream &os, int indent=0) const
Output to stream in well-formed XML.
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
void InitParameters()
Initialize parameters.
void SetProfilePar(const REAL fwhmCagliotiW, const REAL fwhmCagliotiU=0, const REAL fwhmCagliotiV=0, const REAL eta0=0.5, const REAL eta1=0.)
Set reflection profile parameters.
REAL mCagliotiU
FWHM parameters, following Caglioti's law.
REAL mAsym0
Asymmetry parameters, following the analytical function for asymmetric pseudo-voigt given by Toraya i...
CrystVector_REAL GetProfile(const CrystVector_REAL &x, const REAL xcenter, const REAL h, const REAL k, const REAL l) const
Get the reflection profile.
virtual REAL GetFullProfileWidth(const REAL relativeIntensity, const REAL xcenter, const REAL h, const REAL k, const REAL l)
Get the (approximate) full profile width at a given percentage of the profile maximum (e....
bool IsAnisotropic() const
Is the profile anisotropic ?
REAL mPseudoVoigtEta0
Pseudo-Voigt mixing parameter : eta=eta0 +2*theta*eta1 eta=1 -> pure Lorentzian ; eta=0 -> pure Gauss...
REAL mAsymBerarBaldinozziA0
Asymmetry parameters, following the Bérar & Baldinozzi approach ( Bérar & baldinozzi,...
virtual void XMLInput(istream &is, const XMLCrystTag &tag)
Input From stream.
void InitParameters()
Initialize parameters.
virtual REAL GetFullProfileWidth(const REAL relativeIntensity, const REAL xcenter, const REAL h, const REAL k, const REAL l)
Get the (approximate) full profile width at a given percentage of the profile maximum (e....
REAL mPseudoVoigtEta0
Pseudo-Voigt mixing parameter : eta=1 -> pure Lorentzian ; eta=0 -> pure Gaussian.
REAL mCagliotiU
FWHM parameters:
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
CrystVector_REAL GetProfile(const CrystVector_REAL &x, const REAL xcenter, const REAL h, const REAL k, const REAL l) const
Get the reflection profile.
virtual void XMLInput(istream &is, const XMLCrystTag &tag)
Input From stream.
virtual void XMLOutput(ostream &os, int indent=0) const
Output to stream in well-formed XML.
void SetProfilePar(const REAL fwhmCagliotiW, const REAL fwhmCagliotiU=0, const REAL fwhmCagliotiV=0, const REAL fwhmGaussP=0, const REAL fwhmLorentzX=0, const REAL fwhmLorentzY=0, const REAL fwhmLorentzGammaHH=0, const REAL fwhmLorentzGammaKK=0, const REAL fwhmLorentzGammaLL=0, const REAL fwhmLorentzGammaHK=0, const REAL fwhmLorentzGammaHL=0, const REAL fwhmLorentzGammaKL=0, const REAL pseudoVoigtEta0=0, const REAL pseudoVoigtEta1=0, const REAL asymA0=0, const REAL asymA1=0, const REAL asymA2=0)
Set reflection profile parameters.
REAL mAsym0
Asymmetry parameters, following the analytical function for asymmetric pseudo-voigt given by Toraya i...
bool IsAnisotropic() const
Is the profile anisotropic ?
Double-Exponential Pseudo-Voigt profile for TOF.
void SetProfilePar(const REAL instrumentAlpha0, const REAL instrumentAlpha1, const REAL instrumentBeta0, const REAL instrumentBeta1, const REAL gaussianSigma0, const REAL gaussianSigma1, const REAL gaussianSigma2, const REAL lorentzianGamma0, const REAL lorentzianGamma1, const REAL lorentzianGamma2)
Set reflection profile parameters.
bool IsAnisotropic() const
Is the profile anisotropic ?
virtual void XMLOutput(ostream &os, int indent=0) const
Output to stream in well-formed XML.
void InitParameters()
Initialize parameters.
CrystVector_REAL GetProfile(const CrystVector_REAL &x, const REAL xcenter, const REAL h, const REAL k, const REAL l) const
Get the reflection profile.
virtual void XMLInput(istream &is, const XMLCrystTag &tag)
Input From stream.
void SetUnitCell(const UnitCell &cell)
Set unit cell.
virtual REAL GetFullProfileWidth(const REAL relativeIntensity, const REAL xcenter, const REAL h, const REAL k, const REAL l)
Get the (approximate) full profile width at a given percentage of the profile maximum (e....
ReflectionProfileDoubleExponentialPseudoVoigt()
Constructor, without unit cell.
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
Unit Cell class: Unit cell with spacegroup information.
void MillerToOrthonormalCoords(REAL &x, REAL &y, REAL &z) const
Get Miller H,K, L indices from orthonormal coordinates in reciprocal space.
class to input or output a well-formatted xml beginning or ending tag.
void Click()
Record an event for this clock (generally, the 'time' an object has been modified,...
Generic class for parameters of refinable objects.
void XMLOutput(ostream &os, const string &name, int indent=0) const
XMLOutput to stream in well-formed XML.
void SetDerivStep(const REAL)
Fixed step to use to compute numerical derivative.
void AssignClock(RefinableObjClock &clock)
void XMLInput(istream &is, const XMLCrystTag &tag)
XMLInput From stream.
void AddPar(const RefinablePar &newRefPar)
Add a refinable parameter.
virtual void SetName(const string &name)
Name of the object.
RefinablePar & GetPar(const long i)
Access all parameters in the order they were inputted.
virtual const string & GetName() const
Name of the object.
ObjRegistry< RefObjOpt > mOptionRegistry
List of options for this object.
virtual void UpdateDisplay() const
If there is an interface, this should be automatically be called each time there is a 'new,...
RefinableObjClock mClockMaster
Master clock, which is changed whenever the object has been altered.
output one or several vectors as (a) column(s):
Abstract base class for all objects in wxCryst.
Class to display a Powder Pattern Pseudo-Voigt Profile.
Class to display a Powder Pattern Pseudo-Voigt Profile with Anisotropic broadening.
Class to display a Powder Pattern Pseudo-Voigt Profile.