EMAN2
Public Member Functions | Public Attributes | Private Member Functions | List of all members
EMAN::EMAN2Ctf Class Reference

EMAN2Ctf is the default CTF model used in EMAN2. More...

#include <ctf.h>

Inheritance diagram for EMAN::EMAN2Ctf:
Inheritance graph
[legend]
Collaboration diagram for EMAN::EMAN2Ctf:
Collaboration graph
[legend]

Public Member Functions

vector< float > get_snr ()
 
void set_snr (const vector< float > &vf)
 
vector< float > get_background ()
 
void set_background (const vector< float > &vf)
 
 EMAN2Ctf ()
 
 EMAN2Ctf (const vector< float > &vf)
 
 ~EMAN2Ctf ()
 
vector< float > compute_1d (int size, float ds, CtfType type, XYData *struct_factor=0)
 
vector< float > compute_1d_fromimage (int size, float ds, EMData *image)
 
void compute_2d_real (EMData *image, CtfType type, XYData *struct_factor=0)
 
void compute_2d_complex (EMData *image, CtfType type, XYData *struct_factor=0)
 
int from_string (const string &ctf)
 
string to_string () const
 
void from_dict (const Dict &dict)
 
Dict to_dict () const
 
void from_vector (const vector< float > &vctf)
 
vector< float > to_vector () const
 
void copy_from (const Ctf *new_ctf)
 
bool equal (const Ctf *ctf1) const
 
float zero (int n) const
 
float stos2 (float s, float dZ)
 
float get_phase () const
 
void set_phase (float phase)
 
- Public Member Functions inherited from EMAN::Ctf
virtual ~Ctf ()
 

Public Attributes

float dfdiff
 
float dfang
 
float ampcont
 
float dsbg
 
vector< float > background
 
vector< float > snr
 
- Public Attributes inherited from EMAN::Ctf
float defocus
 
float bfactor
 
float voltage
 
float cs
 
float apix
 

Private Member Functions

float lambda () const
 
float df (float ang) const
 
float calc_noise (float s) const
 

Additional Inherited Members

- Public Types inherited from EMAN::Ctf
enum  CtfType {
  CTF_AMP , CTF_SIGN , CTF_BACKGROUND , CTF_SNR ,
  CTF_SNR_SMOOTH , CTF_WIENER_FILTER , CTF_TOTAL , CTF_FITREF ,
  CTF_NOISERATIO , CTF_INTEN , CTF_POWEVAL , CTF_ALIFILT ,
  CTF_ABS
}
 

Detailed Description

EMAN2Ctf is the default CTF model used in EMAN2.

Definition at line 236 of file ctf.h.

Constructor & Destructor Documentation

◆ EMAN2Ctf() [1/2]

EMAN2Ctf::EMAN2Ctf ( )

Definition at line 488 of file ctf.cpp.

489{
490 defocus = 0;
491 dfdiff = 0;
492 dfang = 0;
493 bfactor = 0;
494 ampcont = 0;
495 voltage = 0;
496 cs = 0;
497 apix = 1.0;
498 dsbg=-1;
499 background.clear();
500 snr.clear();
501}
float cs
Definition: ctf.h:87
float bfactor
Definition: ctf.h:85
float voltage
Definition: ctf.h:86
float apix
Definition: ctf.h:88
float defocus
Definition: ctf.h:84
vector< float > background
Definition: ctf.h:248
vector< float > snr
Definition: ctf.h:249
float dfdiff
Definition: ctf.h:240
float dfang
Definition: ctf.h:241
float ampcont
Definition: ctf.h:243
float dsbg
Definition: ctf.h:247

References ampcont, EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, snr, and EMAN::Ctf::voltage.

◆ EMAN2Ctf() [2/2]

EMAN::EMAN2Ctf::EMAN2Ctf ( const vector< float > &  vf)
inline

Definition at line 258 of file ctf.h.

258{from_vector(vf);} //for unpickling
void from_vector(const vector< float > &vctf)
Definition: ctf.cpp:612

References from_vector().

◆ ~EMAN2Ctf()

EMAN2Ctf::~EMAN2Ctf ( )

Definition at line 504 of file ctf.cpp.

505{
506}

Member Function Documentation

◆ calc_noise()

float EMAN::EMAN2Ctf::calc_noise ( float  s) const
inlineprivate

Definition at line 305 of file ctf.h.

306 {
307 int si=(int)(s/dsbg);
308 if (si>(int)background.size()||si<0) return background.back();
309 return background[si];
310 }

References background, and dsbg.

Referenced by compute_1d(), and compute_2d_complex().

◆ compute_1d()

vector< float > EMAN2Ctf::compute_1d ( int  size,
float  ds,
CtfType  type,
XYData struct_factor = 0 
)
virtual

Implements EMAN::Ctf.

Definition at line 731 of file ctf.cpp.

732{
733 Assert(size > 0);
734
735// float tmp_f1 = sqrt((float) 2) * size / 2;
736// int np = (int) ceil(tmp_f1) + 2;
737 int np=size/2;
738 vector < float >r;
739
740 r.resize(np);
741
742 float s = 0;
743 float g1=M_PI/2.0*cs*1.0e7*pow(lambda(),3.0f); // s^4 coefficient for gamma, cached in a variable for simplicity (maybe speed? depends on the compiler)
744 float g2=M_PI*lambda()*defocus*10000.0; // s^2 coefficient for gamma
745// float acac=acos(ampcont/100.0); // instead of ac*cos(g)+sqrt(1-ac^2)*sin(g), we can use cos(g-acos(ac)) and save a trig op
746 float acac=M_PI/2.0-get_phase();
747 switch (type) {
748 case CTF_AMP:
749 for (int i = 0; i < np; i++) {
750 float gam=-g1*s*s*s*s+g2*s*s;
751 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s * s));
752 s += ds;
753 }
754 break;
755
756 case CTF_ABS:
757 for (int i = 0; i < np; i++) {
758 float gam=-g1*s*s*s*s+g2*s*s;
759 r[i] = fabs(cos(gam-acac)*exp(-(bfactor/4.0f * s * s)));
760 s += ds;
761 }
762 break;
763
764 case CTF_INTEN:
765 for (int i = 0; i < np; i++) {
766 float gam=-g1*s*s*s*s+g2*s*s;
767 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
768 r[i]*=r[i];
769 s += ds;
770 }
771 break;
772
773 case CTF_SIGN:
774 for (int i = 0; i < np; i++) {
775 float gam=-g1*s*s*s*s+g2*s*s;
776 r[i] = cos(gam-acac)<0?-1.0:1.0;
777 s += ds;
778 }
779 break;
780
781 case CTF_BACKGROUND:
782 for (int i = 0; i < np; i++) {
783 float f = s/dsbg;
784 int j = (int)floor(f);
785 f-=j;
786 if (j>(int)background.size()-2) r[i]=background.back();
787 else r[i]=background[j]*(1.0f-f)+background[j+1]*f;
788 s+=ds;
789 }
790 break;
791
792 case CTF_SNR:
793 if (snr.size()<1) {
794 throw InvalidValueException("CTF_SNR"," ERROR: No SNR info in CTF header.");
795 break;
796 }
797 for (int i = 0; i < np; i++) {
798 float f = s/dsbg;
799 int j = (int)floor(f);
800 f-=j;
801 if (j>(int)snr.size()-2) r[i]=snr.back();
802 else r[i]=snr[j]*(1.0f-f)+snr[j+1]*f;
803// printf("%d\t%f\n",j,snr[j]);
804 s+=ds;
805 }
806 break;
807 case CTF_SNR_SMOOTH:
808 // This apparently complicated routine tries to make a nice smooth and accurate SNR curve. It does this
809 // by fitting local regions of the SNR vs the theoretical SNR (theoretical CTF^2/measured background),
810 // then taking the slope of the result times the theoretical SNR to produce a local SNR estimate
811
812 { // <- is to permit new temporary value allocation
813 vector < float >tsnr; // theoretical SNR
814 tsnr.resize(np);
815 vector < float >dsnr; // data SNR
816 dsnr.resize(np);
817
818 float s0=s;
819
820 for (int i = 0; i < np; i++) {
821 float gam=-g1*s*s*s*s+g2*s*s;
822 tsnr[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s * s)); // ctf amp
823
824 // background value
825 float f = s/dsbg;
826 int j = (int)floor(f);
827 f-=j;
828 float bg;
829 if (j>(int)background.size()-2) bg=background.back();
830 else bg=background[j]*(1.0f-f)+background[j+1]*f;
831 if (bg <=0) bg=.001f;
832
833 tsnr[i] = tsnr[i]*tsnr[i]/bg; // This is now a SNR curve
834 if (sf && s) {
835 tsnr[i] *= sf->get_yatx(s);
836 }
837
838
839 // This is the SNR computed from the data without fitting
840 if (j>(int)snr.size()-2) dsnr[i]=snr.back();
841 else dsnr[i]=snr[j]*(1.0f-f)+snr[j+1]*f;
842
843 s+=ds;
844 }
845
846 int npsm=np/25; // 1/2 number of points to smooth over, 25 is arbitrary
847 if (npsm<2) npsm=2;
848
849 s=s0;
850 for (int i = 1; i < np; i++) {
851 // simple linear regression embedded here
852 double sum = 0;
853 double sum_x = 0;
854 double sum_y = 0;
855 double sum_xx = 0;
856 double sum_xy = 0;
857
858 for (int k=max_int(i-npsm,1); k<=min_int(i+npsm,np-1); k++) {
859 double y = dsnr[k];
860 double x = tsnr[k];
861
862 sum_x += x;
863 sum_y += y;
864 sum_xx += x * x;
865 sum_xy += x * y;
866 sum++;
867 }
868
869 double div = sum * sum_xx - sum_x * sum_x;
870// if (div == 0) {
871// div = 0.0000001f;
872// }
873
874 // *intercept = (float) ((sum_xx * sum_y - sum_x * sum_xy) / div);
875 // *slope = (float) ((sum * sum_xy - sum_x * sum_y) / div);
876
877 if (div!=0.0) r[i]=(float) ((sum * sum_xy - sum_x * sum_y) / div)*tsnr[i];
878 else r[i]=0.0;
879 if (r[i]<0) r[i]=0;
880
881 s+=ds;
882 }
883 r[0]=0;
884 }
885 break;
886
888// if (!sf) {
889// LOGERR("CTF computation error, no SF found\n");
890// return r;
891// }
892
893 for (int i = 0; i < np; i++) {
894 float f = s/dsbg;
895 int j = (int)floor(f);
896 float bg;
897 f-=j;
898 if (j>(int)snr.size()-2) {
899/* r[i]=snr.back();
900 bg=background.back();*/
901 r[i]=0;
902 }
903 else {
904 r[i]=snr[j]*(1.0f-f)+snr[j+1]*f;
905 bg=background[j]*(1.0f-f)+background[j+1]*f;
906 }
907 if (r[i]<0) r[i]=0;
908 r[i]=r[i]/(r[i]+1.0f); // Full Wiener filter assuming perfect image with noise
909// r[i]=sqrt(r[i]/bg)/(r[i]+1.0); // Wiener filter with 1/CTF term (sort of) to restore image then filter
910 s+=ds;
911 }
912 r[0]=0;
913 break;
914
915 case CTF_TOTAL:
916
917 for (int i = 0; i < np; i++) {
918 float gam=-g1*s*s*s*s+g2*s*s;
919 if (sf) {
920 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
921 r[i] = r[i] * r[i] * sf->get_yatx(s) + calc_noise(s);
922 }
923 else {
924 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
925 r[i] = r[i] * r[i] + calc_noise(s);
926 }
927 s += ds;
928 }
929 break;
930 case CTF_NOISERATIO:
931 for (int i = 0; i < np; i++) {
932 float gam=-g1*s*s*s*s+g2*s*s;
933 if (sf) {
934 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
935 r[i] = r[i] * r[i] * sf->get_yatx(s);
936 r[i] = r[i]/(r[i]+calc_noise(s));
937 }
938 else {
939 r[i] = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
940 r[i] = r[i] * r[i];
941 r[i] = r[i]/(r[i]+calc_noise(s));
942 }
943
944 s+=ds;
945 }
946
947 break;
948 default:
949 break;
950 }
951
952 return r;
953}
@ CTF_TOTAL
Definition: ctf.h:71
@ CTF_NOISERATIO
Definition: ctf.h:73
@ CTF_SNR_SMOOTH
Definition: ctf.h:69
@ CTF_WIENER_FILTER
Definition: ctf.h:70
@ CTF_AMP
Definition: ctf.h:65
@ CTF_INTEN
Definition: ctf.h:74
@ CTF_SIGN
Definition: ctf.h:66
@ CTF_BACKGROUND
Definition: ctf.h:67
@ CTF_SNR
Definition: ctf.h:68
@ CTF_ABS
Definition: ctf.h:77
float calc_noise(float s) const
Definition: ctf.h:305
float get_phase() const
Definition: ctf.cpp:671
float lambda() const
Definition: ctf.h:293
int max_int(int a, int b)
Definition: ctf.cpp:728
int min_int(int a, int b)
Definition: ctf.cpp:729
#define Assert(s)
Define Assert() function that is effective only when -DDEBUG is used.
Definition: emassert.h:42
void div(float f)
make each pixel value divided by a float number.
#define InvalidValueException(val, desc)
Definition: exception.h:285
#define y(i, j)
Definition: projector.cpp:1516
#define x(i)
Definition: projector.cpp:1517

References Assert, background, EMAN::Ctf::bfactor, calc_noise(), EMAN::Ctf::cs, EMAN::Ctf::CTF_ABS, EMAN::Ctf::CTF_AMP, EMAN::Ctf::CTF_BACKGROUND, EMAN::Ctf::CTF_INTEN, EMAN::Ctf::CTF_NOISERATIO, EMAN::Ctf::CTF_SIGN, EMAN::Ctf::CTF_SNR, EMAN::Ctf::CTF_SNR_SMOOTH, EMAN::Ctf::CTF_TOTAL, EMAN::Ctf::CTF_WIENER_FILTER, EMAN::Ctf::defocus, div(), dsbg, get_phase(), EMAN::XYData::get_yatx(), InvalidValueException, lambda(), max_int(), min_int(), snr, x, and y.

Referenced by EMAN::CtfSimProcessor::process(), and EMAN::CTFCorrProcessor::process_inplace().

◆ compute_1d_fromimage()

vector< float > EMAN2Ctf::compute_1d_fromimage ( int  size,
float  ds,
EMData image 
)
virtual

Implements EMAN::Ctf.

Definition at line 685 of file ctf.cpp.

686{
687 size/=2; // to be consistent with the next routine
688 vector <float> ret(size);
689 vector <float> norm(size);
690
691 if (!image->is_complex() || !image->is_ri()) ImageFormatException("EMAN2Ctf::compute_1d_fromimage requires a complex, ri image");
692 int isinten=image->get_attr_default("is_intensity",0);
693 if (isinten) ImageFormatException("EMAN2Ctf::compute_1d_fromimage does not take intensity images");
694
695 int nx=image->get_attr("nx");
696 int ny=image->get_attr("ny");
697 float *data=image->get_data();
698
699 int x,y,i;
700 for (y=i=0; y<ny; y++) {
701 for (x=0; x<nx; x+=2,i+=2) {
702 if (x==0 && y>ny/2) continue;
703 float r=(float)(Util::hypot_fast(x/2,y<ny/2?y:ny-y)); // origin at 0,0; periodic
704 float a=(float)atan2((float)(y<ny/2?y:ny-y),(float)(x/2)); // angle to point (radians)
705 r=stos2(r*ds,-dfdiff/2*cos(2.0*a-2.0*M_PI/180.0*dfang))/ds; // angle-based defocus -> convert s to remove astigmatism, dfang in degrees
706 int f=int(r); // safe truncation, so floor isn't needed
707 r-=float(f); // r is now the fractional spacing between bins
708
709 float v=Util::square_sum(data[i],data[i+1]); //intensity
710 if (f>=0 && f<size) {
711 ret[f]+=v*(1.0f-r);
712 norm[f]+=(1.0f-r);
713 if (f<size-1) {
714 ret[f+1]+=v*r;
715 norm[f+1]+=r;
716 }
717 }
718 }
719 }
720
721 for (i=0; i<size; i++) ret[i]/=norm[i]?norm[i]:1.0f; // Normalize
722
723
724 return ret;
725}
float stos2(float s, float dZ)
Definition: ctf.h:280
static float square_sum(float x, float y)
Calcuate (x*x + y*y).
Definition: util.h:764
static float hypot_fast(int x, int y)
Euclidean distance in 2D for integers computed fast using a cached lookup table.
Definition: util.cpp:742
#define ImageFormatException(desc)
Definition: exception.h:147

References dfang, dfdiff, EMAN::Util::hypot_fast(), ImageFormatException, EMAN::Util::square_sum(), stos2(), x, and y.

◆ compute_2d_complex()

void EMAN2Ctf::compute_2d_complex ( EMData image,
CtfType  type,
XYData struct_factor = 0 
)
virtual

Implements EMAN::Ctf.

Definition at line 964 of file ctf.cpp.

965{
966 if (!image) {
967 LOGERR("image is null. cannot computer 2D complex CTF");
968 return;
969 }
970
971 if (image->is_complex() == false) {
972 LOGERR("compute_2d_complex can only work on complex images");
973 return;
974 }
975
976 int nx = image->get_xsize();
977 int ny = image->get_ysize();
978
979 if ((ny%2==1 && nx!=ny+1) || (ny%2==0 && nx != ny + 2)) {
980 printf("nx=%d ny=%d\n",nx,ny);
981 LOGERR("compute_2d_complex only works on (nx, nx-2) images");
982 return;
983 }
984
985 float ds = 1.0f / (apix * ny);
986 image->to_one();
987
988 float *d = image->get_data();
989 float g1=M_PI/2.0*cs*1.0e7*pow(lambda(),3.0f); // s^4 coefficient for gamma, cached in a variable for simplicity (maybe speed? depends on the compiler)
990 float g2=M_PI*lambda()*10000.0; // s^2 coefficient for gamma
991// float acac=acos(ampcont/100.0); // instead of ac*cos(g)+sqrt(1-ac^2)*sin(g), we can use cos(g-acos(ac)) and save a trig op
992 float acac=M_PI/2.0-get_phase();
993
994 if (type == CTF_BACKGROUND) {
995 for (int y = -ny/2; y < ny/2; y++) {
996 int y2=(y+ny)%ny;
997 int ynx = y2 * nx;
998
999 for (int x = 0; x < nx / 2; x++) {
1000 float s = (float) Util::hypot_fast(x, y ) * ds;
1001 d[x * 2 + ynx] = calc_noise(s);
1002 d[x * 2 + ynx + 1] = 0; // The phase is somewhat arbitrary
1003 }
1004 }
1005 }
1006 else if (type == CTF_AMP) {
1007 for (int y = -ny/2; y < ny/2; y++) {
1008 int y2=(y+ny)%ny;
1009 int ynx = y2 * nx;
1010
1011 for (int x = 0; x < nx / 2; x++) {
1012 float s = (float)Util::hypot_fast(x,y ) * ds;
1013 float gam;
1014 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1015 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1016 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1017 d[x * 2 + ynx] = v;
1018 d[x * 2 + ynx + 1] = 0;
1019 }
1020 }
1021 }
1022 else if (type == CTF_ABS) {
1023 for (int y = -ny/2; y < ny/2; y++) {
1024 int y2=(y+ny)%ny;
1025 int ynx = y2 * nx;
1026
1027 for (int x = 0; x < nx / 2; x++) {
1028 float s = (float)Util::hypot_fast(x,y ) * ds;
1029 float gam;
1030 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1031 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1032 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1033 d[x * 2 + ynx] = fabs(v);
1034 d[x * 2 + ynx + 1] = 0;
1035 }
1036 }
1037 }
1038 else if (type == CTF_INTEN) {
1039 for (int y = -ny/2; y < ny/2; y++) {
1040 int y2=(y+ny)%ny;
1041 int ynx = y2 * nx;
1042
1043 for (int x = 0; x < nx / 2; x++) {
1044 float s = (float)Util::hypot_fast(x,y ) * ds;
1045 float gam;
1046 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1047 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1048 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1049 d[x * 2 + ynx] = v*v;
1050 d[x * 2 + ynx + 1] = 0;
1051 }
1052 }
1053 }
1054 else if (type == CTF_POWEVAL) {
1055 for (int y = -ny/2; y < ny/2; y++) {
1056 int y2=(y+ny)%ny;
1057 int ynx = y2 * nx;
1058
1059 for (int x = 0; x < nx / 2; x++) {
1060 float s = (float)Util::hypot_fast(x,y ) * ds;
1061 float gam;
1062 // mf is used to gradually "turn on" the curve as we approach 20 A
1063 float mf=1.0;
1064 if (s<.04) mf=0.0;
1065 else if (s<.05) mf=1.0-exp(-pow((s-.04f)*300.0f,2.0f));
1066 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1067 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1068 float v = cos(gam-acac);
1069 if (v>0.9) v=exp(-(50.0f/4.0f * s*s));
1070 else v=0;
1071 d[x * 2 + ynx] = mf*v*v;
1072 d[x * 2 + ynx + 1] = 0;
1073 }
1074 }
1075 }
1076 else if (type == CTF_SIGN) {
1077 for (int y = -ny/2; y < ny/2; y++) {
1078 int y2=(y+ny)%ny;
1079 int ynx = y2 * nx;
1080 for (int x = 0; x < nx / 2; x++) {
1081 float s = (float)Util::hypot_fast(x,y ) * ds;
1082 float gam;
1083 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1084 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1085 float v = cos(gam-acac);
1086 d[x * 2 + ynx] = v<0?-1.0:1.0;
1087 d[x * 2 + ynx + 1] = 0;
1088 }
1089 }
1090 }
1091 else if (type == CTF_FITREF) {
1092 for (int y = -ny/2; y < ny/2; y++) {
1093 int y2=(y+ny)%ny;
1094 int ynx = y2 * nx;
1095
1096 for (int x = 0; x < nx / 2; x++) {
1097 float s = (float)Util::hypot_fast(x,y ) * ds;
1098 // We exclude very low frequencies from consideration due to the strong structure factor
1099 if (s<.04) {
1100 d[x * 2 + ynx] = 0;
1101 d[x * 2 + ynx + 1] = 0;
1102 continue;
1103 }
1104 // Rather than suddenly "turning on" the CTF, we do it gradually
1105 float mf=1.0;
1106 if (s<.05) {
1107 mf=1.0-exp(-pow((s-.04f)*300.0f,2.0f));
1108 }
1109 float gam;
1110 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1111 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1112 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1113 d[x * 2 + ynx] = mf*v*v;
1114 d[x * 2 + ynx + 1] = 0;
1115 }
1116 }
1117 }
1118 else if (type == CTF_SNR) {
1119
1120 for (int y = -ny/2; y < ny/2; y++) {
1121 int y2=(y+ny)%ny;
1122 int ynx = y2 * nx;
1123
1124 for (int x = 0; x < nx / 2; x++) {
1125
1126 float s = (float)Util::hypot_fast(x,y ) * ds;
1127 float f = s/dsbg;
1128 int j = (int)floor(f);
1129 f-=j;
1130 if (j>(int)snr.size()-2) d[x*2+ynx]=snr.back();
1131 else d[x*2+ynx]=snr[j]*(1.0f-f)+snr[j+1]*f;
1132 d[x * 2 + ynx + 1] = 0;
1133 }
1134 }
1135 d[0]=0;
1136 }
1137 else if (type == CTF_SNR_SMOOTH) {
1138 for (int y = -ny/2; y < ny/2; y++) {
1139 int y2=(y+ny)%ny;
1140 int ynx = y2 * nx;
1141
1142 for (int x = 0; x < nx / 2; x++) {
1143
1144 float s = (float)Util::hypot_fast(x,y ) * ds;
1145 float f = s/dsbg;
1146 int j = (int)floor(f);
1147 f-=j;
1148 if (j>(int)snr.size()-2) d[x*2+ynx]=snr.back();
1149 else d[x*2+ynx]=snr[j]*(1.0f-f)+snr[j+1]*f;
1150 d[x * 2 + ynx + 1] = 0;
1151 }
1152 }
1153 d[0]=0;
1154 }
1155 else if (type == CTF_WIENER_FILTER) {
1156 if (dsbg==0) printf("Warning, DSBG set to 0\n");
1157 for (int y = -ny/2; y < ny/2; y++) {
1158 int y2=(y+ny)%ny;
1159 int ynx = y2 * nx;
1160
1161 for (int x = 0; x < nx / 2; x++) {
1162
1163 float s = (float)Util::hypot_fast(x,y ) * ds;
1164 float f = s/dsbg;
1165 int j = (int)floor(f);
1166 float bg,snrf;
1167 f-=j;
1168 if (j>(int)snr.size()-2) {
1169/* bg=background.back();
1170 d[x*2+ynx]=snr.back()/(snr.back()+1.0);*/
1171 d[x*2+ynx]=0;
1172 }
1173 else {
1174 bg=background[j]*(1.0f-f)+background[j+1]*f;
1175 snrf=snr[j]*(1.0f-f)+snr[j+1]*f;
1176
1177// printf("%d\t%f\n",x,sqrt(snrf/bg)/(snrf+1.0));
1178 if (snrf<0) snrf=0.0;
1179// d[x*2+ynx]=sqrt(snrf/bg)/(snrf+1.0); // Note that this is a Wiener filter with a 1/CTF term to compensate for the filtration already applied, but needs to be multiplied by the structure factor
1180 d[x*2+ynx]=snrf/(snrf+1); // This is just the simple Wiener filter
1181
1182 }
1183 d[x * 2 + ynx + 1] = 0;
1184 }
1185 }
1186 d[0]=0;
1187 }
1188 else if (type == CTF_TOTAL) {
1189
1190 for (int y = -ny/2; y < ny/2; y++) {
1191 int y2=(y+ny)%ny;
1192 int ynx = y2 * nx;
1193
1194 for (int x = 0; x < nx / 2; x++) {
1195 float s = (float)Util::hypot_fast(x,y ) * ds;
1196 float gam;
1197 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1198 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1199 float v = cos(gam-acac)*exp(-(bfactor/4.0f * s*s));
1200 d[x * 2 + ynx] = v*v+calc_noise(s);
1201 d[x * 2 + ynx + 1] = 0;
1202// if ((x==101||x==100) && y2==79) printf("%f %f %f %f\n",s,gam,v,d[x * 2 + ynx]);
1203 }
1204 }
1205 }
1206 else if (type == CTF_ALIFILT) {
1207 double vt=0;
1208 for (int y = -ny/2; y < ny/2; y++) {
1209 int y2=(y+ny)%ny;
1210 int ynx = y2 * nx;
1211
1212 for (int x = 0; x < nx / 2; x++) {
1213 float s = (float)Util::hypot_fast(x,y ) * ds;
1214 float gam;
1215 if (dfdiff==0) gam=-g1*s*s*s*s+g2*defocus*s*s;
1216 else gam=-g1*s*s*s*s+g2*df(atan2((float)y,(float)x))*s*s;
1217 // this make values near the zero crossings negative to cancel out 0,0 correlation
1218// float v = (pow(cos(gam-acac),2.0)-0.5)*exp(-(bfactor/4.0f * s*s));
1219 // Basically just a CTF weight
1220 float v = (pow((float)cos(gam-acac),2.0f))*exp(-(bfactor/4.0f * s*s));
1221 //v*=v;
1222 //v=fabs(v);
1223 d[x * 2 + ynx] = v;
1224 d[x * 2 + ynx + 1] = 0;
1225 vt+=v;
1226 }
1227 }
1228 vt/=nx*ny/2;
1229// for (size_t i=0; i<image->get_xsize()*image->get_ysize(); i+=2) d[i]=(d[i]-vt)<0?-1.0:1.0;
1230// for (size_t i=0; i<image->get_xsize()*image->get_ysize(); i+=2) d[i]=(d[i]-vt);
1231 }
1232 else printf("Unknown CTF image mode\n");
1233
1234 image->update();
1235}
@ CTF_FITREF
Definition: ctf.h:72
@ CTF_ALIFILT
Definition: ctf.h:76
@ CTF_POWEVAL
Definition: ctf.h:75
float df(float ang) const
Definition: ctf.h:300
#define LOGERR
Definition: log.h:51

References EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, calc_noise(), EMAN::Ctf::cs, EMAN::Ctf::CTF_ABS, EMAN::Ctf::CTF_ALIFILT, EMAN::Ctf::CTF_AMP, EMAN::Ctf::CTF_BACKGROUND, EMAN::Ctf::CTF_FITREF, EMAN::Ctf::CTF_INTEN, EMAN::Ctf::CTF_POWEVAL, EMAN::Ctf::CTF_SIGN, EMAN::Ctf::CTF_SNR, EMAN::Ctf::CTF_SNR_SMOOTH, EMAN::Ctf::CTF_TOTAL, EMAN::Ctf::CTF_WIENER_FILTER, EMAN::Ctf::defocus, df(), dfdiff, dsbg, get_phase(), EMAN::Util::hypot_fast(), lambda(), LOGERR, snr, x, and y.

◆ compute_2d_real()

void EMAN2Ctf::compute_2d_real ( EMData image,
CtfType  type,
XYData struct_factor = 0 
)
virtual

Implements EMAN::Ctf.

Definition at line 956 of file ctf.cpp.

957{
958
959
960}

◆ copy_from()

void EMAN2Ctf::copy_from ( const Ctf new_ctf)
virtual

Implements EMAN::Ctf.

Definition at line 653 of file ctf.cpp.

654{
655 if (new_ctf) {
656 const EMAN2Ctf *c = static_cast<const EMAN2Ctf *>(new_ctf);
657 defocus = c->defocus;
658 dfdiff = c->dfdiff;
659 dfang = c->dfang;
660 bfactor = c->bfactor;
661 ampcont = c->ampcont;
662 voltage = c->voltage;
663 cs = c->cs;
664 apix = c->apix;
665 dsbg = c->dsbg;
667 snr = c->snr;
668 }
669}
EMAN2Ctf is the default CTF model used in EMAN2.
Definition: ctf.h:237

References ampcont, EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, snr, and EMAN::Ctf::voltage.

Referenced by EMAN::CTFCorrProcessor::process_inplace().

◆ df()

float EMAN::EMAN2Ctf::df ( float  ang) const
inlineprivate

Definition at line 300 of file ctf.h.

300 {
301 if (dfdiff==0.0) return defocus;
302 return defocus+dfdiff/2.0f*cos(2.0f*ang-2.0f*M_PI/180.0f*dfang);
303 }

References EMAN::Ctf::defocus, dfang, and dfdiff.

Referenced by compute_2d_complex().

◆ equal()

bool EMAN2Ctf::equal ( const Ctf ctf1) const
virtual

Implements EMAN::Ctf.

Definition at line 1239 of file ctf.cpp.

1240{
1241 if (ctf1) {
1242 const EMAN2Ctf *c = static_cast<const EMAN2Ctf *>(ctf1);
1243 if (defocus != c->defocus ||
1244 dfdiff != c->dfdiff ||
1245 dfang != c->dfang ||
1246 bfactor != c->bfactor ||
1247 ampcont != c->ampcont ||
1248 voltage != c->voltage ||
1249 cs != c->cs ||
1250 apix != c->apix ||
1251 dsbg != c->dsbg ||
1252 background.size() != c->background.size() ||
1253 snr.size() != c->snr.size()
1254 ) return false;
1255
1256 for (unsigned int i=0; i<background.size(); i++) {
1257 if (background[i]!=c->background[i]) return false;
1258 }
1259 for (unsigned int i=0; i<snr.size(); i++) {
1260 if (snr[i]!=c->snr[i]) return false;
1261 }
1262 return true;
1263 }
1264 return false;
1265}

References ampcont, EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, snr, and EMAN::Ctf::voltage.

◆ from_dict()

void EMAN2Ctf::from_dict ( const Dict dict)
virtual

Implements EMAN::Ctf.

Definition at line 567 of file ctf.cpp.

568{
569// printf("st\n");
570 defocus = (float)dict["defocus"];
571// printf("df\n");
572 dfdiff = (float)dict["dfdiff"];
573// printf("dfd\n");
574 dfang = (float)dict["dfang"];
575// printf("dfa\n");
576 bfactor = (float)dict["bfactor"];
577// printf("bf\n");
578 ampcont = (float)dict["ampcont"];
579// printf("ac\n");
580 voltage = (float)dict["voltage"];
581// printf("vo\n");
582 cs = (float)dict["cs"];
583// printf("cs\n");
584 apix = (float)dict["apix"];
585// printf("ap\n");
586 dsbg = (float)dict["dsbg"];
587// printf("ds\n");
588 background = dict["background"];
589// printf("bg\n");
590 snr = dict["snr"];
591// printf("done\n");
592}

References ampcont, EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, snr, and EMAN::Ctf::voltage.

◆ from_string()

int EMAN2Ctf::from_string ( const string &  ctf)
virtual

Implements EMAN::Ctf.

Definition at line 509 of file ctf.cpp.

510{
511 Assert(ctf != "");
512 char type=' ';
513 int pos=-1,i,j;
514 int bglen=0,snrlen=0;
515 float v;
516 const char *s=ctf.c_str();
517
518 sscanf(s, "%c%f %f %f %f %f %f %f %f %f %d%n",
519 &type,&defocus, &dfdiff,&dfang,&bfactor,&ampcont,&voltage, &cs, &apix,&dsbg,&bglen,&pos);
520 if (type!='E') throw InvalidValueException(type,"Trying to initialize Ctf object with bad string");
521 if (pos==-1) throw InvalidValueException(s," Invalid CTF string");
522
523
524 background.resize(bglen);
525 for (i=0; i<bglen; i++) {
526 if (sscanf(s+pos,",%f%n",&v,&j)<1) return(1);
527 background[i]=v;
528 pos+=j;
529 }
530
531 sscanf(s+pos," %d%n",&snrlen,&j);
532 pos+=j;
533 snr.resize(snrlen);
534 for (i=0; i<snrlen; i++) {
535 if (sscanf(s+pos,",%f%n",&v,&j)<1) return(1);
536 snr[i]=v;
537 pos+=j;
538 }
539
540 return 0;
541
542}

References ampcont, EMAN::Ctf::apix, Assert, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, InvalidValueException, snr, and EMAN::Ctf::voltage.

◆ from_vector()

void EMAN2Ctf::from_vector ( const vector< float > &  vctf)
virtual

Implements EMAN::Ctf.

Definition at line 612 of file ctf.cpp.

613{
614 int i;
615 defocus = vctf[0];
616 dfdiff = vctf[1];
617 dfang = vctf[2];
618 bfactor = vctf[3];
619 ampcont = vctf[4];
620 voltage = vctf[5];
621 cs = vctf[6];
622 apix = vctf[7];
623 dsbg = vctf[8];
624 background.resize((int)vctf[9]);
625 for (i=0; i<(int)vctf[9]; i++) background[i]=vctf[i+10];
626 snr.resize((int)vctf[i+10]);
627 for (int j=0; j<(int)vctf[i+10]; j++) snr[j]=vctf[i+j+11];
628}

References ampcont, EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, snr, and EMAN::Ctf::voltage.

Referenced by EMAN2Ctf().

◆ get_background()

vector< float > EMAN::EMAN2Ctf::get_background ( )
inline

Definition at line 253 of file ctf.h.

253{ return background;}

References background.

◆ get_phase()

float EMAN2Ctf::get_phase ( ) const
virtual

Implements EMAN::Ctf.

Definition at line 671 of file ctf.cpp.

671 {
672 if (ampcont>-100.0 && ampcont<=100.0) return asin(ampcont/100.0);
673 if (ampcont>100.0) return M_PI-asin(2.0f-ampcont/100.0);
674 return -M_PI-asin(-2.0-ampcont/100.0);
675}

References ampcont.

Referenced by compute_1d(), compute_2d_complex(), and zero().

◆ get_snr()

vector< float > EMAN::EMAN2Ctf::get_snr ( )
inline

Definition at line 251 of file ctf.h.

251{ return snr;}

References snr.

◆ lambda()

float EMAN::EMAN2Ctf::lambda ( ) const
inlineprivate

Definition at line 293 of file ctf.h.

294 {
295 float lambda = 12.2639f / sqrt(voltage * 1000.0f + 0.97845f * voltage * voltage);
296 return lambda;
297 }
EMData * sqrt() const
return square root of current image

References lambda(), sqrt(), and EMAN::Ctf::voltage.

Referenced by compute_1d(), compute_2d_complex(), lambda(), stos2(), and zero().

◆ set_background()

void EMAN::EMAN2Ctf::set_background ( const vector< float > &  vf)
inline

Definition at line 254 of file ctf.h.

254{background = vf;}

References background.

◆ set_phase()

void EMAN2Ctf::set_phase ( float  phase)
virtual

Implements EMAN::Ctf.

Definition at line 677 of file ctf.cpp.

677 {
678 if (phase>=-M_PI/2.0f && phase<M_PI/2.0f) ampcont=sin(phase)*100.0;
679 else if (phase>=M_PI/2.0f && phase<=M_PI) ampcont=(2.0-sin(phase))*100.0;
680 else if (phase>-M_PI && phase<-M_PI/2.0f) ampcont=(-2.0-sin(phase))*100.0;
681 else printf("Phase = %0.4f deg out of range\n",phase*180.0/M_PI);
682
683}
EMData * phase() const
return phase part of a complex image as a real image format

References ampcont, and phase().

◆ set_snr()

void EMAN::EMAN2Ctf::set_snr ( const vector< float > &  vf)
inline

Definition at line 252 of file ctf.h.

252{snr = vf;}

References snr.

◆ stos2()

float EMAN::EMAN2Ctf::stos2 ( float  s,
float  dZ 
)
inline

Definition at line 280 of file ctf.h.

280 {
281 float lmb=lambda();
282 return sqrt((defocus*1.0e4f-sqrt(defocus*defocus*1.0e8f -2.0e11f*cs*s*s*(defocus-dZ)*lmb*lmb+1.0e14f*cs*cs*pow(s*lmb,4.0f)))/(1.0e7f*cs*lmb*lmb));
283 }

References EMAN::Ctf::cs, EMAN::Ctf::defocus, lambda(), and sqrt().

Referenced by compute_1d_fromimage().

◆ to_dict()

Dict EMAN2Ctf::to_dict ( ) const
virtual

Implements EMAN::Ctf.

Definition at line 594 of file ctf.cpp.

595{
596 Dict dict;
597 dict["defocus"] = defocus;
598 dict["dfdiff"] = dfdiff;
599 dict["dfang"] = dfang;
600 dict["bfactor"] = bfactor;
601 dict["ampcont"] = ampcont;
602 dict["voltage"] = voltage;
603 dict["cs"] = cs;
604 dict["apix"] = apix;
605 dict["dsbg"] = dsbg;
606 dict["background"] = background;
607 dict["snr"] = snr;
608
609 return dict;
610}
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385

References ampcont, EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, snr, and EMAN::Ctf::voltage.

◆ to_string()

string EMAN2Ctf::to_string ( ) const
virtual

Implements EMAN::Ctf.

Definition at line 544 of file ctf.cpp.

545{
546 char ctf[256];
547 sprintf(ctf, "E%1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %1.10g %d",
549
550 string ret=ctf;
551 for (int i=0; i<(int)background.size(); i++) {
552 sprintf(ctf,",%1.3g",background[i]);
553 ret+=ctf;
554 }
555
556 sprintf(ctf, " %d",(int)snr.size());
557 ret+=ctf;
558 for (int i=0; i<(int)snr.size(); i++) {
559 sprintf(ctf,",%1.3g",snr[i]);
560 ret+=ctf;
561 }
562
563
564 return ret;
565}

References ampcont, EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, snr, and EMAN::Ctf::voltage.

◆ to_vector()

vector< float > EMAN2Ctf::to_vector ( ) const
virtual

Implements EMAN::Ctf.

Definition at line 630 of file ctf.cpp.

631{
632 vector<float> vctf;
633
634 vctf.push_back(defocus);
635 vctf.push_back(dfdiff);
636 vctf.push_back(dfang);
637 vctf.push_back(bfactor);
638 vctf.push_back(ampcont);
639 vctf.push_back(voltage);
640 vctf.push_back(cs);
641 vctf.push_back(apix);
642 vctf.push_back(dsbg);
643 vctf.push_back((float)background.size());
644 for (unsigned int i=0; i<background.size(); i++) vctf.push_back(background[i]);
645 vctf.push_back((float)snr.size());
646 for (unsigned int j=0; j<snr.size(); j++) vctf.push_back(snr[j]);
647
648 return vctf;
649}

References ampcont, EMAN::Ctf::apix, background, EMAN::Ctf::bfactor, EMAN::Ctf::cs, EMAN::Ctf::defocus, dfang, dfdiff, dsbg, snr, and EMAN::Ctf::voltage.

◆ zero()

float EMAN2Ctf::zero ( int  n) const
virtual

Implements EMAN::Ctf.

Definition at line 1267 of file ctf.cpp.

1267 {
1268vector <float>zeroes;
1269float lam=lambda();
1270float acac=M_PI/2.0-get_phase();
1271
1272int m=n*2;
1273if (m<15) m=15; // A bit arbitrary. I believe this will always get us the zeroes we need in any practical situation
1274for (int i=-m; i<m; i++) {
1275 float r1=defocus*defocus*1.0e8 + cs*lam*1.0e7 - 2.0*cs*i*lam*1.0e7 - 2*cs*1.0e7*lam*acac/M_PI;
1276// printf("%f\n",r1);
1277 if (r1<0) continue;
1278 float r2=defocus*1.0e4+sqrt(r1);
1279 if (r2>0) zeroes.push_back(sqrt(r2/(cs*lam*lam*1.0e7)));
1280 float r2a=defocus*1.0e4-sqrt(r1);
1281 if (r2a>0) zeroes.push_back(sqrt(r2a/(cs*lam*lam*1.0e7)));
1282}
1283if (zeroes.size()==0) return 0.0f;
1284std::sort(zeroes.begin(),zeroes.end());
1285
1286return zeroes[n];
1287}

References EMAN::Ctf::cs, EMAN::Ctf::defocus, get_phase(), lambda(), and sqrt().

Member Data Documentation

◆ ampcont

float EMAN::EMAN2Ctf::ampcont

◆ background

vector<float> EMAN::EMAN2Ctf::background

◆ dfang

float EMAN::EMAN2Ctf::dfang

◆ dfdiff

float EMAN::EMAN2Ctf::dfdiff

◆ dsbg

float EMAN::EMAN2Ctf::dsbg

◆ snr

vector<float> EMAN::EMAN2Ctf::snr

The documentation for this class was generated from the following files: