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 REAL asym=
mAsym0+mAsym1/sin(center)+mAsym2/pow((REAL)sin(center),(REAL)2.0);
153 if(asym<0.05) asym=0.05;
154 if(asym>20.0) asym=20.0;
155 profile=PowderProfileGauss(x,fwhm,center,asym);
163 tmpV=PowderProfileLorentz(x,fwhm,center,asym);
169 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::GetProfile()",2)
174 const REAL fwhmCagliotiU,
175 const REAL fwhmCagliotiV,
180 mCagliotiV=fwhmCagliotiV;
181 mCagliotiW=fwhmCagliotiW;
183 mPseudoVoigtEta1=eta1;
189 const REAL center,
const REAL h,
const REAL k,
const REAL l)
191 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth()",2)
193 const int halfnb=nb/2;
194 CrystVector_REAL x(nb);
196 REAL fwhm= mCagliotiW
197 +mCagliotiV*tan(center/2.0)
199 if(fwhm<=0) fwhm=1e-6;
200 else fwhm=sqrt(fwhm);
201 CrystVector_REAL prof;
206 const REAL tmp=fwhm*n/nb;
207 for(
int i=0;i<nb;i++) *p++ = tmp*(i-halfnb);
211 const REAL max=prof.max();
212 const REAL test=max*relativeIntensity;
214 if((prof(0)<test)&&(prof(nb-1)<test))
217 while(*p<test){ p++; n1++;n2++;}
219 while(*p>test){ p++; n2++;}
220 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth():"<<x(n2)-x(n1),2)
223 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth():"<<relativeIntensity<<
","
224 <<fwhm<<
","<<center<<
","<<h<<
","<<k<<
","<<l<<
","<<max<<
","<<test,2)
236 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
242 RefinablePar tmp(
"V",&mCagliotiV,-1/RAD2DEG/RAD2DEG,1./RAD2DEG/RAD2DEG,
244 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
252 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
259 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
266 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
274 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
281 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
288 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
295 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
303 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
310 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
317 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
326 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::XMLOutput():"<<this->
GetName(),5)
327 for(
int i=0;i<indent;i++) os <<
" " ;
369 tag.SetIsEndTag(
true);
370 for(
int i=0;i<indent;i++) os <<
" " ;
372 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::XMLOutput():"<<this->
GetName(),5)
376 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::XMLInput():"<<this->
GetName(),5)
377 for(
unsigned int i=0;i<tagg.GetNbAttribute();i++)
379 if(
"Name"==tagg.GetAttributeName(i)) this->
SetName(tagg.GetAttributeValue(i));
384 if((
"ReflectionProfilePseudoVoigt"==tag.GetName())&&tag.IsEndTag())
387 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::Exit():"<<this->
GetName(),5)
390 if(
"Par"==tag.GetName())
392 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
394 if(
"Name"==tag.GetAttributeName(i))
396 if(
"U"==tag.GetAttributeValue(i))
401 if(
"V"==tag.GetAttributeValue(i))
406 if(
"W"==tag.GetAttributeValue(i))
411 if(
"Eta0"==tag.GetAttributeValue(i))
416 if(
"Eta1"==tag.GetAttributeValue(i))
421 if(
"Asym0"==tag.GetAttributeValue(i))
426 if(
"Asym1"==tag.GetAttributeValue(i))
431 if(
"Asym2"==tag.GetAttributeValue(i))
437 if(
"AsymA0"==tag.GetAttributeValue(i))
442 if(
"AsymA1"==tag.GetAttributeValue(i))
447 if(
"AsymB0"==tag.GetAttributeValue(i))
452 if(
"AsymB1"==tag.GetAttributeValue(i))
462 if(
"Option"==tag.GetName())
464 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
465 if(
"Name"==tag.GetAttributeName(i))
472 WXCrystObjBasic* ReflectionProfilePseudoVoigt::WXCreate(wxWindow* parent)
474 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::WXCreate()",6)
488 ReflectionProfilePseudoVoigtAnisotropic::ReflectionProfilePseudoVoigtAnisotropic():
489 mCagliotiU(0),mCagliotiV(0),mCagliotiW(.01*DEG2RAD*DEG2RAD),mScherrerP(0),mLorentzX(0),mLorentzY(0),
490 mLorentzGammaHH(0),mLorentzGammaKK(0),mLorentzGammaLL(0),mLorentzGammaHK(0),mLorentzGammaHL(0),mLorentzGammaKL(0),
496 ReflectionProfilePseudoVoigtAnisotropic::ReflectionProfilePseudoVoigtAnisotropic(
const ReflectionProfilePseudoVoigtAnisotropic &old):
497 mCagliotiU(old.mCagliotiU),mCagliotiV(old.mCagliotiV),mCagliotiW(old.mCagliotiW),mScherrerP(old.mScherrerP),mLorentzX(old.mLorentzX),mLorentzY(old.mLorentzY),
498 mLorentzGammaHH(old.mLorentzGammaHH),mLorentzGammaKK(old.mLorentzGammaKK),mLorentzGammaLL(old.mLorentzGammaLL),mLorentzGammaHK(old.mLorentzGammaHK),mLorentzGammaHL(old.mLorentzGammaHL),mLorentzGammaKL(old.mLorentzGammaKL),
499 mPseudoVoigtEta0(old.mPseudoVoigtEta0),mPseudoVoigtEta1(old.mPseudoVoigtEta1),mAsym0(old.mAsym0),mAsym1(old.mAsym1),mAsym2(old.mAsym2)
503 ReflectionProfilePseudoVoigtAnisotropic::~ReflectionProfilePseudoVoigtAnisotropic()
514 ReflectionProfilePseudoVoigtAnisotropic* ReflectionProfilePseudoVoigtAnisotropic::CreateCopy()
const
516 return new ReflectionProfilePseudoVoigtAnisotropic(*
this);
521 static string className=
"ReflectionProfilePseudoVoigtAnisotropic";
526 const REAL h,
const REAL k,
const REAL l)
const
528 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigtAnisotropic::GetProfile()",2)
529 const REAL tantheta=tan(center/2.0);
530 const REAL costheta=cos(center/2.0);
531 const REAL sintheta=sin(center/2.0);
532 const REAL fwhmG=sqrt(abs( mCagliotiW+mCagliotiV*tantheta+
mCagliotiU*tantheta*tantheta+mScherrerP/(costheta*costheta)));
533 const REAL gam=mLorentzGammaHH*h*h+mLorentzGammaKK*k*k+mLorentzGammaLL*l*l+2*mLorentzGammaHK*h*k+2*mLorentzGammaHL*h*l+2*mLorentzGammaKL*k*l;
534 const REAL fwhmL= mLorentzX/costheta+(mLorentzY+gam/(sintheta*sintheta))*tantheta;
540 CrystVector_REAL profile(x.numElements()),tmpV(x.numElements());
541 REAL asym=
mAsym0+mAsym1/sin(center)+mAsym2/pow((REAL)sin(center),(REAL)2.0);
542 if(asym<0.05) asym=0.05;
543 if(asym>20.0) asym=20.0;
544 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigtAnisotropic::GetProfile():("<<
int(h)<<
","<<
int(k)<<
","<<
int(l)<<
"),fwhmG="<<fwhmG<<
",fwhmL="<<fwhmL<<
",gam="<<gam<<
",asym="<<asym<<
",center="<<center<<
",eta="<<eta, 2)
547 profile=PowderProfileGauss(x,fwhmG,center,asym);
553 tmpV=PowderProfileLorentz(x,fwhmL,center,asym);
558 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigtAnisotropic::GetProfile()",2)
563 const REAL fwhmCagliotiU,
564 const REAL fwhmCagliotiV,
565 const REAL fwhmGaussP,
566 const REAL fwhmLorentzX,
567 const REAL fwhmLorentzY,
568 const REAL fwhmLorentzGammaHH,
569 const REAL fwhmLorentzGammaKK,
570 const REAL fwhmLorentzGammaLL,
571 const REAL fwhmLorentzGammaHK,
572 const REAL fwhmLorentzGammaHL,
573 const REAL fwhmLorentzGammaKL,
574 const REAL pseudoVoigtEta0,
575 const REAL pseudoVoigtEta1,
582 mCagliotiV=fwhmCagliotiV;
583 mCagliotiW=fwhmCagliotiW;
584 mLorentzX=fwhmLorentzX;
585 mLorentzY=fwhmLorentzY;
586 mLorentzGammaHH=fwhmLorentzGammaHH;
587 mLorentzGammaKK=fwhmLorentzGammaKK;
588 mLorentzGammaLL=fwhmLorentzGammaLL;
589 mLorentzGammaHK=fwhmLorentzGammaHK;
590 mLorentzGammaHL=fwhmLorentzGammaHL;
591 mLorentzGammaKL=fwhmLorentzGammaKL;
593 mPseudoVoigtEta1=pseudoVoigtEta1;
601 const REAL h,
const REAL k,
const REAL l)
603 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth()",2)
605 const int halfnb=nb/2;
606 CrystVector_REAL x(nb);
608 const REAL tantheta=tan(center/2.0);
609 const REAL costheta=cos(center/2.0);
610 const REAL sintheta=sin(center/2.0);
611 const REAL fwhmG=sqrt(abs( mCagliotiW+mCagliotiV*tantheta+
mCagliotiU*tantheta*tantheta+mScherrerP/(costheta*costheta)));
612 const REAL gam=mLorentzGammaHH*h*h+mLorentzGammaKK*k*k+mLorentzGammaLL*l*l+2*mLorentzGammaHK*h*k+2*mLorentzGammaHL*h*l+2*mLorentzGammaKL*k*l;
613 const REAL fwhmL= mLorentzX/costheta+(mLorentzY+gam/(sintheta*sintheta))*tantheta;
616 REAL fwhm=fwhmL*eta+fwhmG*(1-eta);
617 if(fwhm<=0) fwhm=1e-3;
618 CrystVector_REAL prof;
623 const REAL tmp=fwhm*n/nb;
624 for(
int i=0;i<nb;i++) *p++ = tmp*(i-halfnb);
627 const REAL max=prof.max();
628 const REAL test=max*relativeIntensity;
630 if((prof(0)<test)&&(prof(nb-1)<test))
633 while(*p<test){ p++; n1++;n2++;}
635 while(*p>test){ p++; n2++;}
636 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigtAnisotropic::GetFullProfileWidth():"<<x(n2)-x(n1),2)
639 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigtAnisotropic::GetFullProfileWidth():"<<relativeIntensity<<
","
640 <<fwhm<<
","<<center<<
","<<h<<
","<<k<<
","<<l<<
","<<max<<
","<<test,2)
653 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigtAnisotropic::XMLOutput():"<<this->
GetName(),5)
654 for(
int i=0;i<indent;i++) os <<
" " ;
655 XMLCrystTag tag(
"ReflectionProfilePseudoVoigtAnisotropic");
710 tag.SetIsEndTag(
true);
711 for(
int i=0;i<indent;i++) os <<
" " ;
713 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigtAnisotropic::XMLOutput():"<<this->
GetName(),5)
718 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigtAnisotropic::XMLInput():"<<this->
GetName(),5)
719 for(
unsigned int i=0;i<tagg.GetNbAttribute();i++)
721 if(
"Name"==tagg.GetAttributeName(i)) this->
SetName(tagg.GetAttributeValue(i));
726 if((
"ReflectionProfilePseudoVoigtAnisotropic"==tag.GetName())&&tag.IsEndTag())
729 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigtAnisotropic::Exit():"<<this->
GetName(),5)
732 if(
"Par"==tag.GetName())
734 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
736 if(
"Name"==tag.GetAttributeName(i))
738 if(
"U"==tag.GetAttributeValue(i))
743 if(
"V"==tag.GetAttributeValue(i))
748 if(
"W"==tag.GetAttributeValue(i))
753 if(
"P"==tag.GetAttributeValue(i))
758 if(
"X"==tag.GetAttributeValue(i))
763 if(
"Y"==tag.GetAttributeValue(i))
768 if(
"G_HH"==tag.GetAttributeValue(i))
773 if(
"G_KK"==tag.GetAttributeValue(i))
778 if(
"G_LL"==tag.GetAttributeValue(i))
783 if(
"G_HK"==tag.GetAttributeValue(i))
788 if(
"G_HL"==tag.GetAttributeValue(i))
793 if(
"G_KL"==tag.GetAttributeValue(i))
798 if(
"Eta0"==tag.GetAttributeValue(i))
803 if(
"Eta1"==tag.GetAttributeValue(i))
808 if(
"Asym0"==tag.GetAttributeValue(i))
813 if(
"Asym1"==tag.GetAttributeValue(i))
818 if(
"Asym2"==tag.GetAttributeValue(i))
827 if(
"Option"==tag.GetName())
829 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
830 if(
"Name"==tag.GetAttributeName(i))
842 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
848 RefinablePar tmp(
"V",&mCagliotiV,-1/RAD2DEG/RAD2DEG,1./RAD2DEG/RAD2DEG,
850 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
858 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
864 RefinablePar tmp(
"P",&mScherrerP,-1./RAD2DEG/RAD2DEG,1./RAD2DEG/RAD2DEG,
866 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG*RAD2DEG);
874 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
882 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
888 RefinablePar tmp(
"G_HH",&mLorentzGammaHH,-1./RAD2DEG,1./RAD2DEG,
890 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
896 RefinablePar tmp(
"G_KK",&mLorentzGammaKK,-1./RAD2DEG,1./RAD2DEG,
898 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
904 RefinablePar tmp(
"G_LL",&mLorentzGammaLL,-1./RAD2DEG,1./RAD2DEG,
906 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
912 RefinablePar tmp(
"G_HK",&mLorentzGammaHK,-1./RAD2DEG,1./RAD2DEG,
914 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
920 RefinablePar tmp(
"G_HL",&mLorentzGammaHL,-1./RAD2DEG,1./RAD2DEG,
922 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
928 RefinablePar tmp(
"G_KL",&mLorentzGammaKL,-1./RAD2DEG,1./RAD2DEG,
930 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false,RAD2DEG);
937 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
944 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
951 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
958 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
965 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
973 WXCrystObjBasic* ReflectionProfilePseudoVoigtAnisotropic::WXCreate(wxWindow* parent)
975 VFN_DEBUG_ENTRY(
"ReflectionProfilePseudoVoigt::WXCreate()",6)
990 mInstrumentAlpha0(0.0),
991 mInstrumentAlpha1(0.0952),
992 mInstrumentBeta0(0.0239),
993 mInstrumentBeta1(0.0043),
994 mGaussianSigma0(0.0),
995 mGaussianSigma1(7.0),
996 mGaussianSigma2(0.0),
997 mLorentzianGamma0(0.0),
998 mLorentzianGamma1(0.0),
999 mLorentzianGamma2(0.414),
1002 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::ReflectionProfileDoubleExponentialPseudoVoigt()",10)
1009 mInstrumentAlpha0(0.0),
1010 mInstrumentAlpha1(0.0952),
1011 mInstrumentBeta0(0.0239),
1012 mInstrumentBeta1(0.0043),
1013 mGaussianSigma0(0.0),
1014 mGaussianSigma1(7.0),
1015 mGaussianSigma2(0.0),
1016 mLorentzianGamma0(0.0),
1017 mLorentzianGamma1(0.0),
1018 mLorentzianGamma2(0.414),
1021 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::ReflectionProfileDoubleExponentialPseudoVoigt()",10)
1022 this->InitParameters();
1028 mInstrumentAlpha0(old.mInstrumentAlpha0),
1029 mInstrumentAlpha1(old.mInstrumentAlpha1),
1030 mInstrumentBeta0(old.mInstrumentBeta0),
1031 mInstrumentBeta1(old.mInstrumentBeta1),
1032 mGaussianSigma0(old.mGaussianSigma0),
1033 mGaussianSigma1(old.mGaussianSigma1),
1034 mGaussianSigma2(old.mGaussianSigma2),
1035 mLorentzianGamma0(old.mLorentzianGamma0),
1036 mLorentzianGamma1(old.mLorentzianGamma1),
1037 mLorentzianGamma2(old.mLorentzianGamma2),
1040 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::ReflectionProfileDoubleExponentialPseudoVoigt()",10)
1046 #ifdef __WX__CRYST__
1049 delete mpWXCrystObj;
1056 ReflectionProfileDoubleExponentialPseudoVoigt::CreateCopy()
const
1063 static string className=
"ReflectionProfileDoubleExponentialPseudoVoigt";
1068 ::GetProfile(
const CrystVector_REAL &x,
const REAL center,
1069 const REAL h,
const REAL k,
const REAL l)
const
1071 VFN_DEBUG_ENTRY(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetProfile()",4)
1075 REAL hh=h,kk=k,ll=l;
1077 dcenter=1.0/sqrt(hh*hh+kk*kk+ll*ll);
1079 const REAL alpha=mInstrumentAlpha0+mInstrumentAlpha1/dcenter;
1080 const REAL beta=mInstrumentBeta0+mInstrumentBeta1/pow(dcenter,4);
1081 const REAL siggauss2= mGaussianSigma0
1082 +mGaussianSigma1*pow(dcenter,2)
1083 +mGaussianSigma2*pow(dcenter,4);
1084 static const REAL log2=log(2.0);
1085 const REAL hg=sqrt(8*siggauss2*log2);
1086 const REAL hl= mLorentzianGamma0
1087 +mLorentzianGamma1*dcenter
1088 +mLorentzianGamma2*dcenter*dcenter;
1089 const REAL hcom=pow(pow(hg,5)+2.69269*pow(hg,4)*hl+2.42843*pow(hg,3)*hl*hl
1090 +4.47163*hg*hg*pow(hl,3)+0.07842*hg*pow(hl,4)+pow(hl,5),0.2);
1091 const REAL sigcom2=hcom*hcom/(8.0*log2);
1092 const REAL eta=1.36603*hl/hcom-0.47719*pow(hl/hcom,2)+0.11116*pow(hl/hcom,3);
1093 const long nbPoints=x.numElements();
1094 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetProfile():alpha="
1095 <<alpha<<
",beta="<<beta<<
",siggauss2="<<siggauss2
1096 <<
",hg="<<hg<<
",hl="<<hl<<
",hcom="<<hcom<<
",sigcom2="<<sigcom2
1098 CrystVector_REAL prof;
1101 REAL *pp=prof.data();
1102 for(
long i=0;i<nbPoints;i++)
1104 const double u=alpha/2*(alpha*sigcom2+2* *pp);
1105 const double nu=beta/2*(beta *sigcom2-2* *pp);
1106 const double y=(alpha*sigcom2+*pp)/sqrt(2*sigcom2);
1107 const double z=(beta *sigcom2-*pp)/sqrt(2*sigcom2);
1108 const complex<double> p(alpha* *pp,alpha*hcom/2);
1109 const complex<double> q(-beta* *pp, beta*hcom/2);
1112 VFN_DEBUG_MESSAGE(
"dt="<<*pp<<
", u="<<u<<
",nu="<<nu<<
",y="<<y<<
",z="<<z
1113 <<
",p=("<<p.real()<<
","<<p.imag()
1114 <<
"),q=("<<q.real()<<
","<<q.imag()
1115 <<
"),e^p*E1(p)=("<<e1p.real()<<
","<<e1p.imag()
1116 <<
"),e^q*E1(q)=("<<e1q.real()<<
","<<e1q.imag(),2)
1117 REAL expnu_erfcz,expu_erfcy;
1119 if(z>10.0) expnu_erfcz=exp(nu-z*z)/(z*sqrt(M_PI));
1120 else expnu_erfcz=exp(nu)*erfc(z);
1122 if(y>10.0) expu_erfcy=exp(u-y*y)/(y*sqrt(M_PI));
1123 else expu_erfcy=exp(u)*erfc(y);
1126 double tmp=(1-eta)*alpha*beta/(2*(alpha+beta))*(expu_erfcy+expnu_erfcz)
1127 -eta*alpha*beta/(M_PI*(alpha+beta))*(e1p.imag()+e1q.imag());
1130 cout<<
"*pp==numeric_limits<REAL>::quiet_NaN()"<<endl;
1131 cout<<
"ReflectionProfileDoubleExponentialPseudoVoigt::GetProfile():"<<endl
1132 <<
" alpha="<<alpha<<
",beta="<<beta<<
",siggauss2="<<siggauss2
1133 <<
",hg="<<hg<<
",hl="<<hl<<
",hcom="<<hcom<<
",sigcom2="<<sigcom2
1134 <<
",eta="<<eta<<endl;
1135 cout<<
" dt="<<*pp<<
", u="<<u<<
",nu="<<nu<<
",y="<<y<<
",z="<<z
1136 <<
",e^u*E1(y)="<<expu_erfcy
1137 <<
",e^nu*E1(z)="<<expnu_erfcz
1139 <<
" p=("<<p.real()<<
","<<p.imag()
1140 <<
"),q=("<<q.real()<<
","<<q.imag()
1141 <<
"),e^p*E1(p)=("<<e1p.real()<<
","<<e1p.imag()
1142 <<
"),e^q*E1(q)=("<<e1q.real()<<
","<<e1q.imag()<<endl;
1143 cout<<(1-eta)*alpha*beta/(2*(alpha+beta))*(expu_erfcy+expnu_erfcz)<<endl
1144 <<eta*alpha*beta/(M_PI*(alpha+beta))*(e1p.imag()+e1q.imag())<<endl
1149 if(abs(*pp)==numeric_limits<REAL>::infinity())
1151 cout<<
"*pp==numeric_limits<REAL>::infinity()"<<endl;
1156 *pp++=(1-eta)*alpha*beta/(2*(alpha+beta))*(expu_erfcy+expnu_erfcz)
1157 -eta*alpha*beta/(M_PI*(alpha+beta))*(e1p.imag()+e1q.imag());
1159 VFN_DEBUG_EXIT(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetProfile()",4)
1165 const REAL instrumentAlpha1,
1166 const REAL instrumentBeta0,
1167 const REAL instrumentBeta1,
1168 const REAL gaussianSigma0,
1169 const REAL gaussianSigma1,
1170 const REAL gaussianSigma2,
1171 const REAL lorentzianGamma0,
1172 const REAL lorentzianGamma1,
1173 const REAL lorentzianGamma2)
1175 mInstrumentAlpha0=instrumentAlpha0;
1176 mInstrumentAlpha1=instrumentAlpha1;
1177 mInstrumentBeta0=instrumentBeta0;
1178 mInstrumentBeta1=instrumentBeta1;
1179 mGaussianSigma0=gaussianSigma0;
1180 mGaussianSigma1=gaussianSigma1;
1181 mGaussianSigma2=gaussianSigma2;
1182 mLorentzianGamma0=lorentzianGamma0;
1183 mLorentzianGamma1=lorentzianGamma1;
1184 mLorentzianGamma2=lorentzianGamma2;
1190 const REAL h,
const REAL k,
const REAL l)
1192 VFN_DEBUG_ENTRY(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetFullProfileWidth()",5)
1196 REAL hh=h,kk=k,ll=l;
1197 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetFullProfileWidth(),"<<dcenter<<
","<<mpCell->
GetName(),5)
1199 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetFullProfileWidth(),"<<dcenter,5)
1200 dcenter=sqrt(hh*hh+kk*kk+ll*ll);
1202 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::GetFullProfileWidth(),"<<dcenter,5)
1204 const int halfnb=nb/2;
1205 CrystVector_REAL x(nb);
1207 const REAL siggauss2= mGaussianSigma0
1208 +mGaussianSigma1*pow(dcenter,2)
1209 +mGaussianSigma2*pow(dcenter,4);
1210 static const REAL log2=log(2.0);
1211 const REAL hg=sqrt(8*siggauss2*log2);
1212 const REAL hl= mLorentzianGamma0
1213 +mLorentzianGamma1*dcenter
1214 +mLorentzianGamma2*dcenter*dcenter;
1215 const REAL fwhm=pow(pow(hg,5)+2.69269*pow(hg,4)*hl+2.42843*pow(hg,3)*hl*hl
1216 +4.47163*hg*hg*pow(hl,3)+0.07842*hg*pow(hl,4)+pow(hl,5),0.2);
1217 CrystVector_REAL prof;
1221 const REAL tmp=fwhm*n/nb;
1222 for(
int i=0;i<nb;i++) *p++ = tmp*(i-halfnb);
1225 const REAL max=prof.max();
1226 const REAL test=max*relativeIntensity;
1228 if((prof(0)<test)&&(prof(nb-1)<test))
1231 while(*p<test){ p++; n1++;n2++;}
1233 while(*p>test){ p++; n2++;}
1234 VFN_DEBUG_EXIT(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth():"<<x(n2)-x(n1),5)
1235 return abs(x(n2)-x(n1));
1237 VFN_DEBUG_MESSAGE(
"ReflectionProfilePseudoVoigt::GetFullProfileWidth():"<<max<<
","<<test
1252 VFN_DEBUG_ENTRY(
"ReflectionProfileDoubleExponentialPseudoVoigt::XMLOutput():"<<this->
GetName(),5)
1253 for(
int i=0;i<indent;i++) os <<
" " ;
1254 XMLCrystTag tag(
"ReflectionProfileDoubleExponentialPseudoVoigt");
1279 this->
GetPar(&mLorentzianGamma0).
XMLOutput(os,
"LorentzianGamma0",indent);
1282 this->
GetPar(&mLorentzianGamma1).
XMLOutput(os,
"LorentzianGamma1",indent);
1285 this->
GetPar(&mLorentzianGamma2).
XMLOutput(os,
"LorentzianGamma2",indent);
1289 tag.SetIsEndTag(
true);
1290 for(
int i=0;i<indent;i++) os <<
" " ;
1292 VFN_DEBUG_EXIT(
"ReflectionProfileDoubleExponentialPseudoVoigt::XMLOutput():"<<this->
GetName(),5)
1298 VFN_DEBUG_ENTRY(
"ReflectionProfileDoubleExponentialPseudoVoigt::XMLInput():"<<this->
GetName(),5)
1299 for(
unsigned int i=0;i<tagg.GetNbAttribute();i++)
1301 if(
"Name"==tagg.GetAttributeName(i)) this->
SetName(tagg.GetAttributeValue(i));
1306 if((
"ReflectionProfileDoubleExponentialPseudoVoigt"==tag.GetName())&&tag.IsEndTag())
1309 VFN_DEBUG_EXIT(
"ReflectionProfileDoubleExponentialPseudoVoigt::Exit():"<<this->
GetName(),5)
1312 if(
"Par"==tag.GetName())
1314 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
1316 if(
"Name"==tag.GetAttributeName(i))
1323 if(
"Option"==tag.GetName())
1325 for(
unsigned int i=0;i<tag.GetNbAttribute();i++)
1326 if(
"Name"==tag.GetAttributeName(i))
1335 VFN_DEBUG_MESSAGE(
"ReflectionProfileDoubleExponentialPseudoVoigt::SetUnitCell()",10)
1344 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1351 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1358 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1365 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1372 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1379 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1386 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1393 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1400 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1407 REFPAR_DERIV_STEP_ABSOLUTE,
true,
true,
true,
false);
1414 #ifdef __WX__CRYST__
1415 WXCrystObjBasic* ReflectionProfileDoubleExponentialPseudoVoigt::WXCreate(wxWindow* parent)
1419 return mpWXCrystObj;
1427 CrystVector_REAL PowderProfileGauss (
const CrystVector_REAL ttheta,
const REAL fw,
1428 const REAL center,
const REAL asym)
1430 TAU_PROFILE(
"PowderProfileGauss()",
"Vector (Vector,REAL)",TAU_DEFAULT);
1432 if(fwhm<=0) fwhm=1e-6;
1433 const long nbPoints=ttheta.numElements();
1434 CrystVector_REAL result(nbPoints);
1442 result *= -4.*log(2.)/fwhm/fwhm;
1446 const REAL c1= -(1.+asym)/asym*(1.+asym)/asym*log(2.)/fwhm/fwhm;
1447 const REAL c2= -(1.+asym) *(1.+asym) *log(2.)/fwhm/fwhm;
1450 const REAL *pt=ttheta.data();
1451 for(i=0;i<nbPoints;i++){ *p++ *= c1;
if(*pt++>center)
break;}
1453 for( ;i<nbPoints;i++) *p++ *= c2;
1459 for(
long i=0;i<nbPoints;i++) { *p = pow((
float)2.71828182846,(
float)*p) ; p++ ;}
1464 #ifdef HAVE_SSE_MATHFUN
1465 v4sf x=_mm_loadu_ps(p);
1466 _mm_storeu_ps(p,exp_ps(x));
1469 for(
unsigned int j=0;j<4;++j)
1476 for(;i>0;i--) { *p = exp(*p) ; p++ ;}
1484 for(;i<nbPoints;i+=4)
1485 for(
unsigned int j=0;j<4;++j)
1487 *p = pow((
float)2.71828182846,(
float)*p) ;
1492 for(;i<nbPoints;i+=1)
1502 result *= 2. / fwhm * sqrt(log(2.)/M_PI);
1506 CrystVector_REAL PowderProfileLorentz(
const CrystVector_REAL ttheta,
const REAL fw,
1507 const REAL center,
const REAL asym)
1509 TAU_PROFILE(
"PowderProfileLorentz()",
"Vector (Vector,REAL)",TAU_DEFAULT);
1511 if(fwhm<=0) fwhm=1e-6;
1512 const long nbPoints=ttheta.numElements();
1513 CrystVector_REAL result(nbPoints);
1521 result *= 4./fwhm/fwhm;
1525 const REAL c1= (1+asym)/asym*(1+asym)/asym/fwhm/fwhm;
1526 const REAL c2= (1+asym) *(1+asym) /fwhm/fwhm;
1529 const REAL *pt=ttheta.data();
1530 for(i=0;i<nbPoints;i++){ *p++ *= c1;
if(*pt++>center)
break;}
1532 for( ;i<nbPoints;i++) *p++ *= c2 ;
1536 for(
long i=0;i<nbPoints;i++) { *p = 1/(*p) ; p++ ;}
1537 result *= 2./M_PI/fwhm;
1542 const REAL fw,
const REAL center,
1543 const REAL a0,
const REAL a1,
1544 const REAL b0,
const REAL b1)
1546 TAU_PROFILE(
"AsymmetryBerarBaldinozzi()",
"Vector (Vector,REAL)",TAU_DEFAULT);
1548 if(fwhm<=0) fwhm=1e-6;
1549 const long nbPoints=x.numElements();
1550 CrystVector_REAL result(nbPoints);
1554 REAL *p=result.data();
1555 const REAL a=a0/tan(center/2)+a1/tan(center);
1556 const REAL b=b0/tan(center/2)+b1/tan(center);
1557 for(
long i=0;i<nbPoints;i++)
1559 *p = 1+*p * exp(-*p * *p)*(2*a+b*(8* *p * *p-12));
1613 const T zr=z.real();
1616 if(zn==0.0)
return 1e100;
1617 if((zn<10.0)||((zr<0.0)&&(zn<20.0)))
1619 ce1=complex<T>(1,0);
1621 for(
unsigned int i=1;i<=150;i++)
1623 y=-y*(T)i*z / (T)((i+1)*(i+1));
1625 if(abs(y)<=abs(ce1)*1e-15)
break;
1627 static const T EulerMascheroni=0.5772156649015328606065120900;
1628 return exp(z)*(z*ce1-EulerMascheroni-log(z));
1632 if(zn>500)
return 1.0/z;
1633 complex<T> y(0.0,0.0);
1634 for(
unsigned int i=120;i>=1;i--) y=(T)i/((T)1+(T)i/(z+y));
1636 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.