2734 int nsoln = nrsoln*2;
2735 if (nrsoln<8) nsoln=8;
2741 if (this_img->is_complex()) base_this=this_img->copy();
2743 base_this=this_img->do_fft();
2744 base_this->process_inplace(
"xform.phaseorigin.tocorner");
2747 if (to->is_complex()) base_to=to->copy();
2749 base_to=to->do_fft();
2750 base_to->process_inplace(
"xform.phaseorigin.tocorner");
2757 if (maxres<0.1) maxres=0.1;
2759 if (base_this->get_xsize()!=base_this->get_ysize()+2 || base_to->get_xsize()!=base_to->get_ysize()+2 )
throw InvalidCallException(
"ERROR (RT2DTreeAligner): requires cubic images with even numbered box sizes");
2761 base_this->process_inplace(
"xform.fourierorigin.tocenter");
2762 base_to->process_inplace(
"xform.fourierorigin.tocenter");
2764 float apix=(float)this_img->get_attr(
"apix_x");
2765 int ny=this_img->get_ysize();
2766 if (maxshift<0) maxshift=ny*3/8;
2767 float maxs = ny*apix/maxres;
2771 vector<float> s_score(nsoln,0.0f);
2772 vector<Transform> s_xform(nsoln);
2774 if (verbose>0) printf(
"%d solutions\n",nsoln);
2777 for (
int sexp=5; sexp<10; sexp++) {
2778 int ss=pow(2.0,sexp);
2781 rescale=(float)ny/pow(2.0,sexp-1);
2784 if (verbose>0) printf(
"\nSize %d\n",ss);
2789 EMData *small_to= base_to-> get_clip(
Region(0,(ny-ss)/2,ss+2,ss));
2790 small_this->process_inplace(
"xform.fourierorigin.tocorner");
2792 if (maxs<cut2) cut2=maxs;
2793 small_this->process_inplace(
"filter.highpass.gauss",
Dict(
"cutoff_pixels",3));
2794 small_this->process_inplace(
"filter.lowpass.gauss",
Dict(
"cutoff_pixels",cut2));
2795 small_to->process_inplace(
"xform.fourierorigin.tocorner");
2796 small_to->process_inplace(
"filter.highpass.gauss",
Dict(
"cutoff_pixels",3));
2797 small_to->process_inplace(
"filter.lowpass.gauss",
Dict(
"cutoff_pixels",cut2));
2800 float astep = 360.0/int(M_PI/atan(1.25/ss));
2803 for (
int i=0; i<nsoln; i++) {
2811 if (verbose>1) printf(
"stage 1 - ang step %1.2f, filter %1.3f\n",astep,cut2/(apix*ny));
2812 vector<Transform> transforms;
2813 for (
float a=astep/2.0; a<359.9; a+=astep) {
2814 transforms.push_back(
Transform(
Dict(
"type",
"2d",
"alpha",a,
"mirror",0)));
2815 if (flip) transforms.push_back(
Transform(
Dict(
"type",
"2d",
"alpha",a,
"mirror",1)));
2817 if (verbose>0) printf(
"%lu orientations to test\n",transforms.size());
2820 for (
unsigned int it=0; it<transforms.size(); it++) {
2824 EMData *stt=small_this->process(
"xform",
Dict(
"transform",
EMObject(&t),
"zerocorners",1));
2827 int lmaxs=maxshift/ss;
2829 float sim=ccf->get_attr(
"minimum");
2831 for (
int y=-lmaxs;
y<=lmaxs;
y++) {
2832 for (
int x=-lmaxs;
x<=lmaxs;
x++) {
2833 float v=ccf->get_value_at_wrap(
x,
y);
2850 t.
set_params(
Dict(
"tx",(
int)ml[0],
"ty",(
int)ml[1],
"tz",(
int)ml[2]));
2862 for (
int i=0; i<nsoln; i++) {
2863 if (s_score[i]==-1.0e24) { worst=i;
break; }
2864 if (s_score[i]<s_score[worst]) worst=i;
2869 if (sim>s_score[worst]) {
2877 for (
int i=0; i<nsoln; i++) {
2878 Dict aap=s_xform[i].get_params(
"2d");
2879 printf(
"%d) %d\t%1.1f\t%1.1f\t%1.2f\t%1.1f\n",i,(
int)aap[
"mirror"],(
float)aap[
"tx"],(
float)aap[
"ty"],(
float)aap[
"alpha"],s_score[i]);
2887 if (verbose>1) printf(
"stage 2 (%1.2f, %1.2f, %d) filter: %1.3f\n",astep,rescale,nsoln,cut2/(apix*ny));
2888 for (
int i=0; i<nsoln; i++) {
2890 Dict aap=s_xform[i].get_params(
"2d");
2891 aap[
"tx"]=(float)aap[
"tx"]*rescale;
2892 aap[
"ty"]=(float)aap[
"ty"]*rescale;
2893 float alpha=aap[
"alpha"];
2894 for (
float a=alpha-astep; a<=alpha+astep; a+=astep) {
2896 EMData *stt=small_this->process(
"xform",
Dict(
"transform",
EMObject(&t),
"zerocorners",1));
2904 for (
int y=-4+ty;
y<=4+ty;
y++) {
2905 for (
int x=-4+tx;
x<=4+tx;
x++) {
2906 float v=ccf->get_value_at_wrap(
x,
y);
2919 aap=s_xform[i].get_params(
"2d");
2920 printf(
"%d) %d\t%1.1f\t%1.1f\t%1.2f\t%1.1f\n",i,(
int)aap[
"mirror"],(
float)aap[
"tx"],(
float)aap[
"ty"],(
float)aap[
"alpha"],s_score[i]);
2927 for (
unsigned int i=0; i<nsoln-1; i++) {
2928 for (
unsigned int j=i+1; j<nsoln; j++) {
2929 if (s_score[i]<s_score[j]) {
2930 float t=s_score[i]; s_score[i]=s_score[j]; s_score[j]=t;
2931 Transform tt=s_xform[i]; s_xform[i]=s_xform[j]; s_xform[j]=tt;
2939 if (nsoln<nrsoln) nsoln=nrsoln;
2953 for (
unsigned int i = 0; i < nrsoln; ++i ) {
2955 d[
"score"] = -s_score[i];
2957 if (s_xform[i].get_mirror()) {
2960 s_xform[i].set_trans(t);
2962 d[
"xform.align2d"] = &s_xform[i];
2966 Dict aap=s_xform[0].get_params(
"2d");
2967 printf(
"Final: %d\t%1.1f\t%1.1f\t%1.2f\n",(
int)aap[
"mirror"],(
float)aap[
"tx"],(
float)aap[
"ty"],(
float)aap[
"alpha"]);
Dict is a dictionary to store <string, EMObject> pair.
type set_default(const string &key, type val)
Default setting behavior This can be achieved using a template - d.woolford Jan 2008 (before there wa...
EMData stores an image's data and defines core image processing routines.
EMData * get_clip(const Region &area, const float fill=0) const
Get an inclusive clip.
EMObject is a wrapper class for types including int, float, double, etc as defined in ObjectType.
IntPoint defines an integer-coordinate point in a 1D/2D/3D space.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
#define InvalidParameterException(desc)
#define InvalidCallException(desc)
EMData * calc_ccf(EMData *with=0, fp_flag fpflag=CIRCULANT, bool center=false)
Calculate Cross-Correlation Function (CCF).