| Bsoft 2.0.5 Bernard's software package

bmultislice.cpp
Go to the documentation of this file.
1
9 #include "rwmolecule.h"
10 #include "rwimg.h"
11 #include "mg_multislice.h"
12 #include "mg_ctf.h"
13 #include "molecule_to_map.h"
14 #include "mol_util.h"
15 #include "Matrix.h"
16 #include "options.h"
17 #include "utilities.h"
18 #include "timer.h"
19
20 // Declaration of global variables
21 extern int verbose; // Level of output to the screen
22
23 // Usage assistance
24 const char* use[] = {
25 " ",
26 "Usage: bmultislice [options] input.pdb/input_pot.img output.img",
27 "---------------------------------------------------------------",
28 "Simulates electron imaging using a multi-slice approach.",
29 "The output file contains the projection image.",
30 "The calculation of the atomic potential can be done in real space (fast but less accurate).",
31 "or in reciprocal space (slow but more accurate), both using atomic electron scattering curves.",
32 " ",
33 "Actions:",
34 "-Volt 100 Set the acceleration voltage (required to calculate exit wave and final image).",
35 "-Defocus 1.2,1.0,47 Defocus average & deviation, and astigmatism angle (required to apply CTF).",
36 "-poisson Add poisson noise.",
37 "-gaussian 0.2 Add gaussian noise with the given signal-to-noise ratio.",
38 "-MTF 17.5 Set the MTF decay constant (required to impose MTF).",
39 " ",
40 "Parameters:",
41 "-verbose 7 Verbosity of output.",
42 "-datatype b Data type of the projection image (default floating point).",
43 "-size 100,80,70 Size (default automatic voxels).",
44 "-origin 0,0,0 Origin placement within image (default 0,0,0).",
45 "-sampling 1,1.3,1.1 Sampling in angstrom/voxel (default 1,1,1).",
46 "-thickness 20 Slice thickness in angstrom (default 10).",
47 "-resolution 8.5 Resolution limits (default Nyquest frequency).",
48 "-Cs 2.0 Set the spherical aberration, Cs (default 2.0 mm).",
49 "-Cc 2.0 Set the chromatic aberration, Cc (default 2.0 mm).",
50 "-Amplitude 0.07 Set the amplitude contrast (default 0.07).",
51 "-alpha 0.5 Set the source size (default 0.1 milliradians).",
52 "-energyspread 2e-5 Set the effective energy spread (default 1e-5).",
53 "-electrondose 35.5 Set the electron dose (default 20 angstrom/pixel).",
54 "-Bfactor 24.5 Set the overall temperature factor (default 0).",
55 "-type real Type of potential calculation (default reciprocal, other gauss).",
56 " ",
57 "Input:",
58 "-parameters param.star Parameter file name for electron scattering curves(default atom_prop.star).",
59 " ",
60 "Output:",
61 "-potential pot.img Output atomic potential image(s).",
62 "-wave wav.img Output exit wave image.",
63 " ",
64 NULL
65 };
66
67 int main(int argc, char **argv)
68 {
69 // Initialize variables
70 DataType nudatatype(Float); // Default data type for projection
71 Vector3<long> size = {1024,1024,1}; // Simulated projection size
72 Vector3<double> origin; // Coordinate origin placement
73 // int set_origin(0); // Flag to set origin
74 Vector3<double> sam = {1,1,1}; // Sampling in angstrom
75 int set_sampling(0); // Flag to set sampling
76 double thickness(10); // Slice thickness in angstrom
77 double resolution(0); // High resolution limit
78 double def_avg(0); // Defocus average (angstrom)
79 double def_dev(0); // Defocus deviation (angstrom)
80 double ast_angle(-1); // Astigmatism angle
81 double volt(0); // Acceleration voltage (volt)
82 double amp_fac(0.07); // Amplitude contrast contribution
83 double Cs(2e7); // Spherical aberration (angstrom)
84 double Cc(2e7); // Chromatic aberration (angstrom)
85 double alpha(0.0001); // Beam source size (radians)
86 double energy_spread(1e-5); // Effective energy spread
87 int poisson(0); // No poisson noise added
88 double gauss(1e10); // Gaussian signal-to-noise ratio, > 1000 means no noise
89 double dose(20); // Electron dose
90 double kmtf(0); // MTF decay constant
91 double Bfactor(0); // Overall temperature factor
92 int pottype(0); // Reciprocal space potential calculation
93 Bstring atom_select("all");
94 Bstring potentialfile; // Atomic potential filename
95 Bstring exitwavefile; // Exit wave filename
96 Bstring paramfile; // Use default parameter file for atomic properties
97
98 int optind;
99 Boption* option = get_option_list(use, argc, argv, optind);
100 Boption* curropt;
101 for ( curropt = option; curropt; curropt = curropt->next ) {
102 if ( curropt->tag == "datatype" )
103 nudatatype = curropt->datatype();
104 if ( curropt->tag == "size" )
105 size = curropt->size();
106 if ( curropt->tag == "origin" ) {
107 origin = curropt->origin();
108 // set_origin = 1;
109 }
110 if ( curropt->tag == "sampling" ) {
111 sam = curropt->sampling();
112 set_sampling = 1;
113 }
114 if ( curropt->tag == "thickness" )
115 if ( ( thickness = curropt->value.real() ) < 0.001 )
116 cerr << "-thickness: A slice thickness must be specified!" << endl;
117 if ( curropt->tag == "resolution" )
118 if ( ( resolution = curropt->value.real() ) < 0.001 )
119 cerr << "-resolution: A resolution limit must be specified!" << endl;
120 if ( curropt->tag == "Defocus" ) {
121 if ( curropt->values(def_avg, def_dev, ast_angle) < 1 )
122 cerr << "-Defocus: At least the defocus average must be specified!" << endl;
123 else {
124 if ( def_avg < 100 ) def_avg *= 1e4;// Assume um
125 if ( def_dev < 100 ) def_dev *= 1e4;// Assume um
126 ast_angle *= M_PI/180; // Assume degrees
127 }
128 }
129 if ( curropt->tag == "Cs" ) {
130 if ( ( Cs = curropt->value.real() ) < 0.001 )
131 cerr << "-Cs: A Cs value must be specified!" << endl;
132 else if ( Cs < 1e3 ) Cs *= 1e7; // Assume mm
133 }
134 if ( curropt->tag == "Cc" ) {
135 if ( ( Cc = curropt->value.real() ) < 0.001 )
136 cerr << "-Cc: A Cc value must be specified!" << endl;
137 else if ( Cc < 1e3 ) Cc *= 1e7; // Assume mm
138 }
139 if ( curropt->tag == "Volt" ) {
140 if ( ( volt = curropt->value.real() ) < 0.001 )
141 cerr << "-Volt: A voltage must be specified!" << endl;
142 else
143 if ( volt < 1e3 ) volt *= 1e3; // Assume kilovolts
144 }
145 if ( curropt->tag == "Amplitude" ) {
146 if ( ( amp_fac = curropt->value.real() ) < 0 )
147 cerr << "-Amplitude: A fraction must be specified!" << endl;
148 else {
149 if ( amp_fac > 1 ) amp_fac /= 100; // Assume percentage
150 if ( amp_fac < 0 ) amp_fac = 0;
151 }
152 }
153 if ( curropt->tag == "alpha" ) {
154 if ( ( alpha = curropt->value.real() ) < 0.001 )
155 cerr << "-alpha: A beam source size or divergence must be specified!" << endl;
156 else {
157 if ( alpha > 0.01 ) alpha /= 1000; // Assume milliradians
158 if ( alpha < 0 ) alpha = 0;
159 }
160 }
161 if ( curropt->tag == "energyspread" ) {
162 if ( ( energy_spread = curropt->value.real() ) < 0.001 )
163 cerr << "-energyspread: A energy spread must be specified!" << endl;
164 else {
165 if ( energy_spread > 0.001 ) energy_spread /= 1e5; // Assume eV
166 if ( energy_spread < 0 ) energy_spread = 0;
167 }
168 }
169 if ( curropt->tag == "electrondose" )
170 if ( ( dose = curropt->value.real() ) < 0.001 )
171 cerr << "-electrondose: The electron dose must be specified!" << endl;
172 if ( curropt->tag == "poisson" )
173 poisson = 1;
174 if ( curropt->tag == "gaussian" )
175 if ( ( gauss = curropt->value.real() ) < 0.0000001 )
176 cerr << "-gaussian: The signal-to-noise ratio must be specified!" << endl;
177 if ( curropt->tag == "MTF" )
178 if ( ( kmtf = curropt->value.real() ) < 0.001 )
179 cerr << "-MTF: The MTF decay constant must be specified!" << endl;
180 if ( curropt->tag == "Bfactor" )
181 if ( ( Bfactor = curropt->value.real() ) < 0.001 )
182 cerr << "-Bfactor: A temperature factor must be specified!" << endl;
183 if ( curropt->tag == "type" ) {
184 pottype = 0;
185 if ( curropt->value.contains("rea") ) pottype = 1;
186 if ( curropt->value.contains("gau") ) pottype = 2;
187 }
188 if ( curropt->tag == "Parameter" )
189 paramfile = curropt->filename();
190 if ( curropt->tag == "potential" )
191 potentialfile = curropt->filename();
192 if ( curropt->tag == "wave" )
193 exitwavefile = curropt->filename();
194 }
195 option_kill(option);
196
197 double ti = timer_start();
198
199 // Read the atomic structure file
200 Bstring filename(argv[optind]);
201 Bmolgroup* molgroup = read_molecule(filename, atom_select, paramfile);
202
203 Bimage* p = NULL;
204 Bimage* ppot = NULL;
205 Bimage* pgrate = NULL;
206 Bimage* pwav = NULL;
207 if ( molgroup ) {
208 ppot = img_calc_potential(molgroup, size, origin, sam, thickness,
209 resolution, Bfactor, paramfile, pottype);
210 if ( potentialfile.length() ) {
211 pgrate = ppot->copy();
212 ppot->complex_to_real();
213 if ( verbose )
214 cout << "Writing the atomic potential image(s)" << endl;
215 ppot->label(get_cmd_line(argc, argv));
216 ppot->change_type(nudatatype);
217 write_img(potentialfile, ppot, 0);
218 delete ppot;
219 } else {
220 pgrate = ppot;
221 }
222 optind++;
223 } else {
224 pgrate = read_img(argv[optind++], 1, -1);
225 if ( set_sampling ) pgrate->sampling(sam);
226 pgrate->simple_to_complex();
227 }
228
229 if ( pgrate == NULL ) {
230 cerr << "Error: No coordinate or image file given!" << endl;
231 bexit(-1);
232 }
233
234 p = pgrate;
235
236 double dose_per_pixel = dose*p->sampling()[0]*p->sampling()[1];
237 if ( volt ) {
238 img_calc_phase_grating(pgrate, volt);
239
240 p = img_calc_multi_slice(pgrate, thickness, volt, resolution);
241
242 p->label(get_cmd_line(argc, argv));
243
244 if ( exitwavefile.length() ) {
245 pwav = p->copy();
246 pwav->fft(FFTW_BACKWARD, 2);
247 pwav->complex_to_intensities();
248 pwav->change_type(nudatatype);
249 pwav->label(get_cmd_line(argc, argv));
250 if ( verbose )
251 cout << "Writing the exit wave image" << endl;
252 write_img(exitwavefile, pwav, 0);
253 delete pwav;
254 }
255
256 if ( def_avg )
257 img_apply_complex_CTF(p, def_avg, def_dev, ast_angle, volt, Cs, Cc, sin(amp_fac), alpha, energy_spread);
258
259 p->fft(FFTW_BACKWARD, 2);
260 if ( p->compound_type() == TComplex ) p->complex_to_intensities();
261 p->rescale(dose_per_pixel, 0);
262
263 // The inherent SNR is calculated as the ratio of the image variance to the dose
264 // where the dose gives the expected variance of the correlated poisson noise
265 if ( verbose )
266 cout << "Inherent signal-to-noise ratio: " << p->standard_deviation()*p->standard_deviation()/dose_per_pixel << endl;
267
268 if ( poisson )
269 p->noise_poisson(p->average());
270
271 if ( gauss < 1000 )
272 p->noise_gaussian(0, p->standard_deviation()/sqrt(gauss));
273
274 if ( kmtf > 0 )
275 p->fspace_weigh_B_factor(4*kmtf);
276 }
277
278 if ( optind < argc ) {
279 if ( p->fourier_type() > NoTransform ) p->fft(FFTW_BACKWARD, 0);
280 if ( p->compound_type() == TComplex ) p->complex_to_intensities();
281 p->change_type(nudatatype);
282 p->label(get_cmd_line(argc, argv));
283 if ( verbose )
284 cout << "Writing the simulated projection image" << endl;
285 write_img(argv[optind], p, 0);
286 }
287
288 if ( p != pgrate ) delete pgrate;
289 delete p;
290
291 molgroup_kill(molgroup);
292
293 if ( verbose & VERB_TIME )
294 timer_report(ti);
295
296 bexit(0);
297 }
298
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bstring::real
double real()
Definition: Bstring.cpp:545
img_calc_phase_grating
int img_calc_phase_grating(Bimage *p, double volt)
Calculates the phase grating approximation from the atomic potential.
Definition: mg_multislice.cpp:206
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
molecule_to_map.h
Header file for functions to calculate a 3D map from atomic coordinates.
Bimage::fft
int fft()
Definition: Bimage.h:822
utilities.h
Header file for general utilities.
Boption::sampling
Vector3< double > sampling()
Definition: options.h:202
Boption::value
Bstring value
Definition: options.h:30
Boption::tag
Bstring tag
Definition: options.h:29
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
Bstring::length
long length() const
Definition: Bstring.cpp:263
Matrix.h
Generalized matrix class.
mg_ctf.h
Functions for CTF (contrast transfer function) processing.
TComplex
Definition: Bimage.h:59
get_option_list
Boption * get_option_list(const char *use[], int argc, char *argv[], int &optind)
Parses command line arguments based on a template.
Definition: options.cpp:40
read_img
Bimage * read_img(char *filename, int readdata, int img_select)
General driver function to read multiple image formats.
Definition: rwimg.cpp:76
get_cmd_line
string get_cmd_line(int argc, char **argv)
Returns the command line as a string.
Definition: utilities.cpp:36
Boption::filename
Bstring filename()
Definition: options.h:85
Bimage::noise_gaussian
int noise_gaussian(double ravg=0, double rstd=1)
Generates an image with a gaussian random distribution of densities.
Definition: Bimage_noise.cpp:72
timer.h
Utilities for timing functions.
Float
Definition: utilities.h:157
verbose
int verbose
Bimage::rescale
int rescale(double scale, double shift)
Rescales the image data with a given multiplier and offset.
Definition: Bimage_rescale.cpp:27
mol_util.h
Library routines used for atomic coordinates.
Bimage
General image parameter class.
Definition: Bimage.h:163
img_apply_complex_CTF
int img_apply_complex_CTF(Bimage *p, double def_avg, double def_dev, double ast_angle, double volts, double Cs, double Cc, double amp_shift, double alpha, double energy_spread)
Applies a complex CTF function to a Fourier transform.
Definition: mg_multislice.cpp:252
Boption::size
Vector3< long > size()
Definition: options.h:163
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
M_PI
#define M_PI
Definition: utilities.h:59
rwmolecule.h
Header file for reading reflection files.
Bmolgroup
Definition: rwmolecule.h:170
Boption
A class for a command line input option.
Definition: options.h:26
Bimage::label
void label(string s)
Definition: Bimage.h:235
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
molgroup_kill
int molgroup_kill(Bmolgroup *molgroup)
Destroys a molecule group.
Definition: rwmolecule.cpp:374
Bimage::simple_to_complex
void simple_to_complex()
A simple image is converted to a complex image.
Definition: Bimage_complex.cpp:22
Bimage::complex_to_intensities
void complex_to_intensities()
The intensities from a complex image is written to a simple image.
Definition: Bimage_complex.cpp:92
write_img
int write_img(const char *filename, Bimage *p, int compression)
General driver function to write multiple image formats.
Definition: rwimg.cpp:280
img_calc_potential
Bimage * img_calc_potential(Bmolgroup *molgroup, Vector3< long > size, Vector3< double > origin, Vector3< double > sam, double thickness, double resolution, double Bfactor, Bstring &paramfile, int type)
Calculates the atomic potential.
Definition: mg_multislice.cpp:139
main
int main(int argc, char **argv)
Definition: bmultislice.cpp:67
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:537
Bimage::noise_poisson
int noise_poisson(double ravg)
Generates an image with a poisson random distribution of densities.
Definition: Bimage_noise.cpp:115
Bimage::complex_to_real
void complex_to_real()
The real part of a complex image is written to a simple image.
Definition: Bimage_complex.cpp:50
Boption::datatype
DataType datatype()
Definition: options.h:93
mg_multislice.h
Generates and manipulates projects for multislice calculations.
Boption::next
Boption * next
Definition: options.h:28
Bstring
Definition: Bstring.h:29
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
use
const char * use[]
Definition: bmultislice.cpp:24
Bimage::fspace_weigh_B_factor
int fspace_weigh_B_factor(double B, double resolution=0)
Weighs an image's amplitudes with B-factor (gaussian) curve.
Definition: Bimage_fspace.cpp:1185
Vector3< long >
Boption::origin
Vector3< double > origin()
Definition: options.h:180
timer_report
double timer_report(double lasttime)
Reports the time elapsed since a given time.
Definition: timer.cpp:67
option_kill
int option_kill(Boption *option)
Deallocates a linked list of option structures.
Definition: options.cpp:109
Bimage::average
double average(long cc, double xf, double yf, double zf, long nn, double iscale)
Averages in 3D when scaling is less than 1.
Definition: Bimage.cpp:1349
rwimg.h
Header file for 2D and 3D image I/O.
options.h
Header file for option handlers.
NoTransform
Definition: Bimage.h:40
Boption::values
long values(T1 &v1, T2 &v2)
Definition: options.h:115
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
timer_start
double timer_start()
Starts timer and prints the time.
Definition: timer.cpp:52
Bimage::fourier_type
FourierType fourier_type()
Definition: Bimage.h:367
read_molecule
Bmolgroup * read_molecule(const char *filename, const char *select, const char *paramfile)
The generalized function for reading molecular files.
Definition: rwmolecule.cpp:818
img_calc_multi_slice
Bimage * img_calc_multi_slice(Bimage *pgrate, double thickness, double volt, double resolution)
Simulates the electron imaging process using a multi-slice approach.
Definition: mg_multislice.cpp:89