76 std::stringstream ss(aux);
77 std::istream_iterator<std::string> begin(ss);
78 std::istream_iterator<std::string> end;
79 std::vector<std::string> vstrings(begin, end);
80 sigma.resize(vstrings.size());
81 std::transform(vstrings.begin(), vstrings.end(),
sigma.begin(), [](
const std::string& val)
83 return std::stod(val);
102 <<
"Output directory: " <<
fnOutDir << std::endl
103 <<
"Reference volume: " <<
fnVolR << std::endl
104 <<
"Forward model mask: " <<
fnMaskRF << std::endl
105 <<
"Backward model mask: " <<
fnMaskRB << std::endl
106 <<
"Sampling: " <<
Ts << std::endl
107 <<
"Max. Radius Deform. " <<
RmaxDef << std::endl
108 <<
"Zernike Degree: " <<
L1 << std::endl
109 <<
"SH Degree: " <<
L2 << std::endl
111 <<
"Correct CTF: " <<
useCTF << std::endl
112 <<
"Correct heretogeneity: " <<
useZernike << std::endl
114 <<
"Regularization: " <<
lambda << std::endl
115 <<
"Number of iterations: " <<
niter << std::endl
116 <<
"Save every # iterations: " <<
save_iter << std::endl;
122 addUsageLine(
"Template-based canonical volume reconstruction through Zernike3D coefficients");
129 addParamsLine(
" [--maskf <m=\"\">] : ART forward model reconstruction mask");
130 addParamsLine(
" [--maskb <m=\"\">] : ART backward model reconstruction mask");
131 addParamsLine(
" [--odir <outputDir=\".\">] : Output directory");
132 addParamsLine(
" [--sampling <Ts=1>] : Sampling rate (A/pixel)");
133 addParamsLine(
" [--RDef <r=-1>] : Maximum radius of the deformation (px). -1=Half of volume size");
134 addParamsLine(
" [--l1 <l1=3>] : Degree Zernike Polynomials=1,2,3,...");
135 addParamsLine(
" [--l2 <l2=2>] : Harmonical depth of the deformation=1,2,3,...");
136 addParamsLine(
" [--blobr <b=4>] : Blob radius for forward mapping splatting");
138 addParamsLine(
" [--sigma <Matrix1D=\"2\">] : Gaussian sigma");
139 addParamsLine(
" [--useZernike] : Correct heterogeneity with Zernike3D coefficients");
140 addParamsLine(
" [--useCTF] : Correct CTF during ART reconstruction");
141 addParamsLine(
" [--phaseFlipped] : Input images have been phase flipped");
142 addParamsLine(
" [--regularization <l=0.01>] : ART regularization weight");
143 addParamsLine(
" [--niter <n=1>] : Number of ART iterations");
144 addParamsLine(
" [--save_iter <s=0>] : Save intermidiate volume after #save_iter iterations");
145 addParamsLine(
" [--sort_last <N=2>] : The algorithm sorts projections in the most orthogonally possible way. ");
146 addParamsLine(
" : The most orthogonal way is defined as choosing the projection which maximizes the ");
147 addParamsLine(
" : dot product with the N previous inserted projections. Use -1 to sort with all ");
150 addParamsLine(
" [--thr <N=-1>] : Maximal number of the processing CPU threads");
152 addExampleLine(
"xmipp_parallel_forward_art_zernike3d -i anglesFromContinuousAssignment.xmd --ref reference.vol -o assigned_anglesAndDeformations.xmd --l1 3 --l2 2");
175 first_image.
read(fn_first_image);
176 size_t Xdim_first =
XSIZE(first_image());
177 V().initZeros(Xdim_first, Xdim_first, Xdim_first);
179 V().setXmippOrigin();
185 p = std::make_unique<std::atomic<double*>>(
nullptr);
190 p = std::make_unique<std::atomic<double*>>(
nullptr);
193 Vout().initZeros(
V());
194 Vout().setXmippOrigin();
323 if (img_enabled == -1)
return;
330 std::vector<double> vectortemp;
334 std::vector<double> vec(vectortemp.begin(), vectortemp.end());
356 std::cout <<
"Processing " << fnImg << std::endl;
359 I().setXmippOrigin();
362 artModel<Direction::Forward>();
365 artModel<Direction::Backward>();
370 for (
int h = 0; h <= l2; h++)
372 int numSPH = 2 * h + 1;
373 int count = l1 - h + 1;
374 int numEven = (count >> 1) + (count & 1 && !(h & 1));
377 vecSize += numSPH * numEven;
381 vecSize += numSPH * (l1 - h + 1 - numEven);
394 for (
int h = 0; h <= l2; h++)
396 int totalSPH = 2 * h + 1;
398 for (
int l = h; l <= l1; l += 2)
400 for (
int m = 0;
m < totalSPH;
m++)
412 void ProgParallelForwardArtZernike3D::splattingAtPos(std::array<double, 2> r,
double weight,
422 int idn = (idy) * (mP).xdim + (idx);
436 auto &mVout =
Vout();
442 void ProgParallelForwardArtZernike3D::run()
444 FileName fnImg, fnImgOut, fullBaseName;
471 std::cout <<
"Running iteration " <<
current_iter + 1 <<
" with lambda=" <<
lambda << std::endl;
480 if (rowIn ==
nullptr)
continue;
484 std::cout <<
"Current image ID: " <<
num_images << std::endl;
542 void ProgParallelForwardArtZernike3D::sortOrthogonal()
552 int min_prod_proj = 0;
553 std::vector<double>
rot;
554 std::vector<double>
tilt;
563 for (i = 0; i < numIMG; i++)
582 std::cout <<
"Sorting projections orthogonally...\n" 585 for (i = 1; i < numIMG; i++)
593 for (j = 0; j < numIMG; j++)
601 if (
A1D_ELEM(product, j) < min_prod)
611 A1D_ELEM(chosen, min_prod_proj) = 1;
615 template <ProgParallelForwardArtZernike3D::Direction DIRECTION>
616 void ProgParallelForwardArtZernike3D::artModel()
618 if (DIRECTION == Direction::Forward)
624 P[
i]().setXmippOrigin();
626 W[
i]().setXmippOrigin();
629 Idiff().setXmippOrigin();
630 I_shifted().initZeros((
int)
XSIZE(
I()), (
int)
XSIZE(
I()));
631 I_shifted().setXmippOrigin();
634 zernikeModel<true, Direction::Forward>();
636 zernikeModel<false, Direction::Forward>();
663 xmipp_transformation::IS_NOT_INV, xmipp_transformation::DONT_WRAP, 0.);
668 const auto &mIsh = I_shifted();
675 for (
int ids = 0; ids <
sigma.size(); ids++)
677 const auto &mP =
P[ids]();
678 const auto &mW =
W[ids]();
679 const auto sg =
sigma[ids];
680 if (
sigma.size() > 1)
688 error += (diffVal) * (diffVal);
695 for (
int ids = 0; ids <
sigma.size(); ids++)
701 std::cout <<
"Press any key" << std::endl;
711 else if (DIRECTION == Direction::Backward)
714 zernikeModel<true, Direction::Backward>();
716 zernikeModel<false, Direction::Backward>();
720 template <
bool USESZERNIKE, ProgParallelForwardArtZernike3D::Direction DIRECTION>
721 void ProgParallelForwardArtZernike3D::zernikeModel()
725 const int step = DIRECTION == Direction::Forward ?
loop_step : 1;
728 auto futures = std::vector<std::future<void>>();
729 futures.reserve(mV.
zdim);
730 auto routine_forward = [
this](
int thrId,
int k) {
731 forwardModel(
k, USESZERNIKE);
734 auto routine_backward = [
this](
int thrId,
int k) {
735 backwardModel(
k, USESZERNIKE);
740 if (DIRECTION == Direction::Forward)
742 else if (DIRECTION == Direction::Backward)
746 for (
auto &
f : futures)
752 void ProgParallelForwardArtZernike3D::forwardModel(
int k,
bool usesZernike)
755 const size_t idxY0 = usesZernike ? (
clnm.size() / 3) : 0;
756 const size_t idxZ0 = usesZernike ? (2 * idxY0) : 0;
757 const double RmaxF = usesZernike ?
RmaxDef : 0;
758 const double RmaxF2 = usesZernike ? (RmaxF * RmaxF) : 0;
759 const double iRmaxF = usesZernike ? (1.0 / RmaxF) : 0;
761 constexpr
size_t matrixSize = 3;
777 double gx = 0.0, gy = 0.0, gz = 0.0;
781 if (
sigma.size() > 1)
785 img_idx = it -
sigma.begin();
787 auto &mP =
P[img_idx]();
788 auto &mW =
W[img_idx]();
792 auto kr = k * iRmaxF;
793 auto k2i2 = k2 +
i *
i;
794 auto ir = i * iRmaxF;
795 auto r2 = k2i2 +
j *
j;
796 auto jr = j * iRmaxF;
797 auto rr =
sqrt(
r2) * iRmaxF;
798 for (
size_t idx = 0; idx < idxY0; idx++)
804 if (rr > 0 || l2 == 0)
807 gx +=
clnm[idx] * (zsph);
808 gy +=
clnm[idx + idxY0] * (zsph);
809 gz +=
clnm[idx + idxZ0] * (zsph);
818 auto pos = std::array<double, 2>{};
822 splattingAtPos(pos, voxel_mV, mP, mW, mV,
sigma[img_idx]);
828 void ProgParallelForwardArtZernike3D::backwardModel(
int k,
bool usesZernike)
832 const size_t idxY0 = usesZernike ? (
clnm.size() / 3) : 0;
833 const size_t idxZ0 = usesZernike ? (2 * idxY0) : 0;
834 const double RmaxF = usesZernike ?
RmaxDef : 0;
835 const double RmaxF2 = usesZernike ? (RmaxF * RmaxF) : 0;
836 const double iRmaxF = usesZernike ? (1.0 / RmaxF) : 0;
838 constexpr
size_t matrixSize = 3;
854 double gx = 0.0, gy = 0.0, gz = 0.0;
860 auto kr = k * iRmaxF;
861 auto k2i2 = k2 +
i *
i;
862 auto ir = i * iRmaxF;
863 auto r2 = k2i2 +
j *
j;
864 auto jr = j * iRmaxF;
865 auto rr =
sqrt(
r2) * iRmaxF;
866 for (
size_t idx = 0; idx < idxY0; idx++)
872 if (rr > 0 || l2 == 0)
875 gx +=
clnm[idx] * (zsph);
876 gy +=
clnm[idx + idxY0] * (zsph);
877 gz +=
clnm[idx + idxZ0] * (zsph);
888 double voxel = mId.interpolatedElement2D(pos_x, pos_y);
#define A2D_ELEM(v, i, j)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
std::vector< std::unique_ptr< std::atomic< double * > > > w_busy_elem
double getDoubleParam(const char *param, int arg=0)
MultidimArray< int > VRecMaskF
__host__ __device__ float2 floor(const float2 v)
#define REPORT_ERROR(nerr, ErrormMsg)
FileName removeFileFormat() const
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
virtual void finishProcessing()
auto push(F &&f, Rest &&... rest) -> std::future< decltype(f(0, rest...))>
void sqrt(Image< double > &op)
std::vector< SelLine >::iterator find(std::vector< SelLine > &text, const std::string &img_name)
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
void fillVectorTerms(int l1, int l2, Matrix1D< int > &vL1, Matrix1D< int > &vN, Matrix1D< int > &vL2, Matrix1D< int > &vM)
Zernike and SPH coefficients allocation.
FileName removeAllExtensions() const
void numCoefficients(int l1, int l2, int &vecSize)
Length of coefficients vector.
static unsigned findCores()
void resize(int nThreads)
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
FileName afterLastOf(const String &str) const
bool enable_CTF
Enable CTF part.
#define MAT_ELEM(m, i, j)
#define A3D_ELEM(V, k, i, j)
MultidimArray< size_t > ordered_list
std::vector< Image< double > > W
std::vector< Image< double > > P
T & getValue(MDLabel label)
ProgParallelForwardArtZernike3D()
Empty constructor.
~ProgParallelForwardArtZernike3D()
Destructor.
const char * getParam(const char *param, int arg=0)
String findAndReplace(const String &tInput, const String &tFind, const String &tReplace)
double Tm
Sampling rate (A/pixel)
void addExampleLine(const char *example, bool verbatim=true)
void readFromMdRow(const MDRow &row, bool disable_if_not_K=true)
ctpl::thread_pool m_threadPool
int verbose
Verbosity level.
const T & getValueOrDefault(MDLabel label, const T &def) const
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
void generate_mask(bool apply_geo=false)
void setRow(size_t i, const Matrix1D< T > &v)
virtual bool containsLabel(MDLabel label) const =0
T dotProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
bool outside(int k, int i, int j) const
#define BINARY_CIRCULAR_MASK
void produceSideInfo()
Produce Side information.
String getFileFormat() const
void defineParams()
Define parameters.
bool checkParam(const char *param)
MultidimArray< int > VRecMaskB
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
std::vector< std::unique_ptr< std::atomic< double * > > > p_busy_elem
std::vector< double > clnm
std::string to_string(bond_type bondType)
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
MultidimArray< int > mask2D
bool enable_CTFnoise
Enable CTFnoise part.
const MultidimArray< int > & get_binary_mask() const
void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
int getIntParam(const char *param, int arg=0)
FileName fnOutDir
Output directory.
std::vector< double > sigma
void generateMask(MultidimArray< double > &v)
void getRow(size_t i, Matrix1D< T > &v) const
FileName getBaseName() const
void addParamsLine(const String &line)
void readParams()
Read argument from command line.
void applyMaskSpace(MultidimArray< double > &v)
std::map< String, CommentList > defaultComments