| Bsoft 2.0.5 Bernard's software package

bsim.cpp
Go to the documentation of this file.
1
9 #include "mg_processing.h"
10 #include "mg_multislice.h"
11 #include "rwmg.h"
12 #include "rwmolecule.h"
13 #include "utilities.h"
14 #include "options.h"
15 #include "timer.h"
16
17 // Declaration of global variables
18 extern int verbose; // Level of output to the screen
19
20 /* Usage assistance */
21 const char* use[] = {
22 " ",
23 "Usage: bsim [options] in.star [in2.star]",
24 "----------------------------------------",
25 "Simulates TEM images from atomic coordinates.",
26 "The program has different entry and exit points:",
27 "A new STAR file can be generated (use -generate or -symmetry option and no input STAR file)",
28 " or parameters can be read in from existing STAR files.",
29 "The provision of a coordinate file leads to calculation of potential slices.",
30 "Input of STAR file(s) without a coordinate file implies that the potentials",
31 " have already been calculated and will be used for multislice simulation.",
32 " ",
33 "Actions:",
34 "-generate 10,3,50 Generate a project, specifying number of fields, number of",
35 " micrographs per field and number particles per micrograph.",
36 "-symmetry C5 Generates images based on a grid in the asymmetric unit.",
37 "-coordinates file.pdb Input coordinate file, generate simulated images in project.",
38 "-image Generate a final image and parameter file (default not).",
39 "-poisson Add poisson noise (default not).",
40 "-gaussian 0.2 Add gaussian noise with the given signal-to-noise ratio.",
41 "-MTF 17.5 Set the MTF decay constant (required to impose MTF).",
42 " ",
43 "Parameters:",
44 "-verbose 7 Verbosity of output.",
45 " ",
46 "Parameters for generation:",
47 "-translate 2.4 Standard deviation for random translation (default 0).",
48 "-origin 120 Set the particle image origin (default 50 pixels).",
49 "-angles 8,6 Step sizes for theta and phi in the asymmetric unit, one value sets both.",
50 " Use with the -symmetry option (default 10,10).",
51 "-Pixelsize 5.5 Set the particle pixel size (default 1 angstrom/pixel).",
52 "-electrondose 35.5 Set the electron dose (default 20 electrons/angstrom).",
53 "-Cs 2.0 Set the spherical aberration, Cs (default 2 mm).",
54 "-Cc 2.0 Set the chromatic aberration, Cc (default 2.0 mm).",
55 "-alpha 0.15 Set the illumination half-angle (default 0.1 milliradians).",
56 "-energyspread 2e-5 Set the effective energy spread (default 1e-5).",
57 "-Volt 100 Set the acceleration voltage (default 120 kV).",
58 "-Amplitude 0.07 Set the amplitude contrast (fraction, default 0.07).",
59 "-Defocus 0.5,3.4 Defocus range (required to apply CTF).",
60 "-fieldbasename field Field-of-view base name (default field).",
61 "-fieldnumber 5 Field starting number (default 1).",
62 "-mgbasename mg Micrograph base name (default mg).",
63 "-mgnumber 23 Micrograph starting number (default 1).",
64 "-partbasename part Particle base name (default part).",
65 "-partnumber 158 Particle starting number (default 1).",
66 " ",
67 "Parameters for simulation:",
68 "-fieldname field Field-of-view name (for selecting a specific field).",
69 "-mgname mg Micrograph base name (for selecting a specific micrograph).",
70 "-partselect 132 Particle selection for potential generation (default all).",
71 "-type real Type of potential calculation (default reciprocal, other gauss).",
72 "-size 100,80,120 Size of enclosing box (default based on input coordinates).",
73 "-thickness 20 Slice thickness in angstrom (default 10 A).",
74 "-resolution 8.5 Resolution limits (default Nyquest frequency).",
75 "-Bfactor 24.5 Set the overall temperature factor (default 0 A^2).",
76 " ",
77 "Input:",
78 "-parameters param.star Parameter file name for electron scattering curves (default atom_prop.star).",
79 "-Water water.pdb Block of water to embed the molecule into (default none).",
80 " ",
81 "Output:",
82 "-output mg.star Parameter file (use with generate option).",
83 " ",
84 NULL
85 };
86
87 int main(int argc, char **argv)
88 {
89 /* Initialize variables */
90 int genfield(0), genmg(0), genpart(0); // Number of randomly oriented molecules to generate
91 Bstring symmetry_string; // Default: none
92 double theta_step(M_PI*10.0/180.0); // Angular step size for theta
93 double phi_step(M_PI*10.0/180.0); // Angular step size for phi
94 double tsigma(0); // No random shift in origins
95 double img_origin(0); // Particle image origin
96 double pixel_size(1); // Take pixel size from input files
97 double dose(20); // Electron dose
98 double Cs(2e7); // Spherical aberration
99 double Cc(2e7); // Chromatic aberration (angstrom)
100 double Volts(120000); // Acceleration voltage
101 double Amp(0.07); // Amplitude contrast contribution
102 double def_min(0), def_max(0); // Defocus range (angstrom) default none
103 // DataType datatype = Float; // Default data type for projection
104 int pottype(0); // Reciprocal space potential calculation
105 Vector3<long> size; // Simulated box size
106 double thickness(10); // Slice thickness in angstrom
107 double resolution(0); // High resolution limit
108 double Bfactor(0); // Overall temperature factor
109 double alpha(0.0001); // Illumination half-angle (radians)
110 double energy_spread(1e-5); // Effective energy spread
111 int image_flag(0); // Flag to generate the final image and parameter file
112 int poisson(0); // No poisson noise added
113 double gauss(1e10); // Gaussian signal-to-noise ratio, > 1000 means no noise
114 double kmtf(0); // MTF decay constant
115 Bstring atom_select("ALL");
116 Bstring fieldbase("field"); // Field-of-view base name
117 Bstring fieldname; // Selected field-of-view name
118 Bstring mgbase("mg"); // Micrograph base name
119 Bstring mgname; // Selected micrograph name
120 Bstring partbase("part"); // Particle base name
121 int fieldnumber(1); // Starting field number
122 int mgnumber(1); // Starting micrograph number
123 int partnumber(1); // Starting particle ID
124 int partselect(0); // Selected particle ID
125 Bstring coorfile; // Input coordinate file
126 Bstring waterfile; // Input solvent coordinate file
127 Bstring paramfile; // Use default parameter file for atomic properties
128 Bstring outfile; // Output parameter file
129
130 int i, optind;
131 Boption* option = get_option_list(use, argc, argv, optind);
132 Boption* curropt;
133 for ( curropt = option; curropt; curropt = curropt->next ) {
134 if ( curropt->tag == "generate" )
135 if ( curropt->values(genfield, genmg, genpart) < 3 )
136 cerr << "-generate: Three numbers must be specified!" << endl;
137 if ( curropt->tag == "symmetry" )
138 symmetry_string = curropt->symmetry_string();
139 if ( curropt->tag == "angles" ) {
140 if ( ( i = curropt->values(theta_step, phi_step) ) < 1 )
141 cerr << "-angles: An angle step size must be specified!" << endl;
142 else {
143 theta_step *= M_PI/180.0;
144 if ( i < 2 ) phi_step = theta_step;
145 else phi_step *= M_PI/180.0;
146 }
147 }
148 if ( curropt->tag == "translate" )
149 if ( ( tsigma = curropt->value.real() ) < 1e-30 )
150 cerr << "-translate: A translation standard deviation must be specified!" << endl;
151 if ( curropt->tag == "origin" )
152 if ( ( img_origin = curropt->value.real() ) < 1e-30 )
153 cerr << "-origin: The image origin must be specified!" << endl;
154 if ( curropt->tag == "Pixelsize" )
155 if ( ( pixel_size = curropt->value.real() ) < 1e-30 )
156 cerr << "-Pixelsize: The particle pixel size must be specified!" << endl;
157 if ( curropt->tag == "electrondose" )
158 if ( ( dose = curropt->value.real() ) < 1e-30 )
159 cerr << "-electrondose: The electron dose must be specified!" << endl;
160 if ( curropt->tag == "Cs" ) {
161 if ( ( Cs = curropt->value.real() ) < 1e-30 )
162 cerr << "-Cs: A Cs value must be specified!" << endl;
163 else if ( Cs < 1e3 ) Cs *= 1e7; // Assume mm
164 }
165 if ( curropt->tag == "Cc" ) {
166 if ( ( Cc = curropt->value.real() ) < 1e-30 )
167 cerr << "-Cc: A Cc value must be specified!" << endl;
168 else if ( Cc < 1e3 ) Cc *= 1e7; // Assume mm
169 }
170 if ( curropt->tag == "alpha" ) {
171 if ( ( alpha = curropt->value.real() ) < 1e-30 )
172 cerr << "-alpha: The illumination half-angle must be specified!" << endl;
173 else {
174 if ( alpha > 0.01 ) alpha /= 1000; // Assume milliradians
175 if ( alpha < 0 ) alpha = 0.0001;
176 }
177 }
178 if ( curropt->tag == "energyspread" ) {
179 if ( ( energy_spread = curropt->value.real() ) < 1e-30 )
180 cerr << "-energyspread: A energy spread must be specified!" << endl;
181 else {
182 if ( energy_spread > 0.001 ) energy_spread /= 1e5; // Assume eV
183 if ( energy_spread < 0 ) energy_spread = 0;
184 }
185 }
186 if ( curropt->tag == "Volt" ) {
187 if ( ( Volts = curropt->value.real() ) < 1e-30 )
188 cerr << "-Volt: A voltage must be specified!" << endl;
189 else if ( Volts < 1e3 ) Volts *= 1e3; // Assume kilovolts
190 }
191 if ( curropt->tag == "Amplitude" ) {
192 if ( ( Amp = curropt->value.real() ) < 1e-30 )
193 cerr << "-Amplitude: A fraction must be specified!" << endl;
194 else if ( Amp > 1 ) Amp /= 100; // Assume percentage
195 }
196 if ( curropt->tag == "Defocus" ) {
197 if ( curropt->values(def_min, def_max) < 1 )
198 cerr << "-Defocus: Both defocus minimum and maximum must be specified!" << endl;
199 if ( def_max < def_min ) def_max = def_min;
200 if ( def_min < 100 && def_max < 100 ) { // Assume um
201 def_min *= 1e4;
202 def_max *= 1e4;
203 }
204 }
205 // if ( curropt->tag == "datatype" )
206 // datatype = curropt->datatype();
207 if ( curropt->tag == "type" ) {
208 pottype = 0;
209 if ( curropt->value.contains("rea") ) pottype = 1;
210 if ( curropt->value.contains("gau") ) pottype = 2;
211 }
212 if ( curropt->tag == "size" )
213 size = curropt->size();
214 if ( curropt->tag == "thickness" )
215 if ( ( thickness = curropt->value.real() ) < 1e-30 )
216 cerr << "-thickness: A slice thickness must be specified!" << endl;
217 if ( curropt->tag == "resolution" )
218 if ( ( resolution = curropt->value.real() ) < 0.001 )
219 cerr << "-resolution: A resolution limit must be specified!" << endl;
220 if ( curropt->tag == "Bfactor" )
221 if ( ( Bfactor = curropt->value.real() ) < 0.001 )
222 cerr << "-Bfactor: A temperature factor must be specified!" << endl;
223 if ( curropt->tag == "image" )
224 image_flag = 1;
225 if ( curropt->tag == "poisson" )
226 poisson = 1;
227 if ( curropt->tag == "MTF" )
228 if ( ( kmtf = curropt->value.real() ) < 1e-30 )
229 cerr << "-MTF: The MTF decay constant must be specified!" << endl;
230 if ( curropt->tag == "gaussian" )
231 if ( ( gauss = curropt->value.real() ) < 1e-30 )
232 cerr << "-gaussian: The signal-to-noise ratio must be specified!" << endl;
233 if ( curropt->tag == "fieldbasename" ) {
234 if ( curropt->value.length() > 0 ) fieldbase = curropt->value;
235 else cerr << "-fieldbasename: A field-of-view base name must be specified!" << endl;
236 }
237 if ( curropt->tag == "fieldname" ) {
238 if ( curropt->value.length() > 0 ) fieldname = curropt->value;
239 else cerr << "-fieldname: A field-of-view name must be specified!" << endl;
240 }
241 if ( curropt->tag == "mgbasename" ) {
242 if ( curropt->value.length() > 0 ) mgbase = curropt->value;
243 else cerr << "-mgbasename: A micrograph base name must be specified!" << endl;
244 }
245 if ( curropt->tag == "mgname" ) {
246 if ( curropt->value.length() > 0 ) mgname = curropt->value;
247 else cerr << "-mgname: A micrograph name must be specified!" << endl;
248 }
249 if ( curropt->tag == "partbasename" ) {
250 if ( curropt->value.length() > 0 ) partbase = curropt->value;
251 else cerr << "-partbasename: A particle base name must be specified!" << endl;
252 }
253 if ( curropt->tag == "fieldnumber" )
254 if ( ( fieldnumber = curropt->value.integer() ) < 1 )
255 cerr << "-fieldnumber: A field-of-view starting number must be specified!" << endl;
256 if ( curropt->tag == "mgnumber" )
257 if ( ( mgnumber = curropt->value.integer() ) < 1 )
258 cerr << "-mgnumber: A micrograph starting number must be specified!" << endl;
259 if ( curropt->tag == "partnumber" )
260 if ( ( partnumber = curropt->value.integer() ) < 1 )
261 cerr << "-partnumber: A particle starting number must be specified!" << endl;
262 if ( curropt->tag == "partselect" )
263 if ( ( partselect = curropt->value.integer() ) < 1 )
264 cerr << "-partselect: A particle number must be specified!" << endl;
265 if ( curropt->tag == "coordinates" )
266 coorfile = curropt->filename();
267 if ( curropt->tag == "Water" )
268 waterfile = curropt->filename();
269 if ( curropt->tag == "Parameter" )
270 paramfile = curropt->filename();
271 if ( curropt->tag == "output" )
272 outfile = curropt->filename();
273 }
274 option_kill(option);
275
276 double ti = timer_start();
277
278 // Read all the parameter files
279 Bstring* file_list = NULL;
280 Bproject* project = NULL;
281 while ( optind < argc ) string_add(&file_list, argv[optind++]);
282 if ( file_list ) {
283 project = read_project(file_list);
284 string_kill(file_list);
285 }
286
287 if ( img_origin <= 0 ) img_origin = size[0]/2;
288
289 if ( !project ) {
290 if ( symmetry_string.length() > 0 ) {
291 project = project_generate_asu(symmetry_string, pixel_size, img_origin,
292 theta_step, phi_step, Volts, Cs, Cc, alpha, energy_spread, Amp,
293 def_min, dose, mgbase, partbase);
294 } else if ( genfield*genmg*genpart > 0 ) {
295 project = project_generate(genfield, genmg, genpart, pixel_size, img_origin,
296 Volts, Cs, Cc, alpha, energy_spread, Amp, def_min, def_max, dose,
297 tsigma, fieldbase, mgbase, partbase, fieldnumber, mgnumber, partnumber);
298 }
299 }
300
301 if ( !project ) {
302 cerr << "Error: No STAR file generated or read!" << endl;
303 bexit(-1);
304 }
305
306 if ( outfile.c_str() ) {
307 project_update_comment(project, argc, argv);
308 write_project(outfile, project, 0, 0);
309 }
310
311 Bmolgroup* molgroup = NULL;
312 Bmolgroup* water = NULL;
313 if ( coorfile.length() ) {
314 molgroup = read_molecule(coorfile, atom_select, paramfile);
315 if ( !molgroup ) {
316 error_show(coorfile.c_str(), __FILE__, __LINE__);
317 bexit(-1);
318 }
319 molecule_update_comment(molgroup, argc, argv);
320 if ( waterfile.c_str() ) {
321 water = read_molecule(waterfile, atom_select, paramfile);
322 if ( !water ) {
323 error_show(waterfile.c_str(), __FILE__, __LINE__);
324 bexit(-1);
325 }
326 }
327 project_generate_potential(molgroup, water, project, fieldname, mgname, partselect,
328 size, thickness, resolution, Bfactor, pottype, paramfile);
329 }
330
331 Bstring outfile2;
332 Bstring insert("_tfn.");
333 if ( image_flag ) {
334 // Generates an image with an average of one and the CTF applied
335 // Thickness and resolution must correspond to the values used for potential calculation
336 project_generate_image(project, thickness, resolution);
337
338 if ( outfile.length() ) {
339 // Adjust for dose and apply noise and envelope functions
340 project_apply_distortions(project, poisson, gauss, kmtf);
341 // outfile2 = insert_in_filename(outfile, insert, '_');
342 outfile2 = outfile.pre_rev('.') + insert + outfile.post_rev('.');
343 write_project(outfile2, project, 0, 0);
344 }
345 }
346
347 molgroup_kill(molgroup);
348 molgroup_kill(water);
349 project_kill(project);
350
351 if ( verbose & VERB_TIME )
352 timer_report(ti);
353
354 bexit(0);
355 }
356
write_project
int write_project(const char *filename, Bproject *project)
Writing micrograph parameters to a file.
Definition: rwmg.cpp:320
rwmg.h
Header file for reading and writing micrograph parameters.
Bstring::real
double real()
Definition: Bstring.cpp:545
string_add
Bstring * string_add(Bstring **list, const char *string)
Adds a string to a linked list.
Definition: Bstring.cpp:705
insert
string insert(string &filename, string ins)
Definition: string_util.cpp:48
project_apply_distortions
int project_apply_distortions(Bproject *project, int poisson, double gauss, double kmtf)
Applies imaging distortions to the final images from a multislice calculation.
Definition: mg_multislice.cpp:674
Boption::symmetry_string
Bstring symmetry_string()
Definition: options.h:245
utilities.h
Header file for general utilities.
Boption::value
Bstring value
Definition: options.h:30
Boption::tag
Bstring tag
Definition: options.h:29
read_project
Bproject * read_project(const char *filename, int flags=0)
Reading micrograph parameters from files.
Definition: rwmg.cpp:140
Bstring::length
long length() const
Definition: Bstring.cpp:263
project
Bproject * project
Definition: bshow.cpp:31
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
Boption::filename
Bstring filename()
Definition: options.h:85
timer.h
Utilities for timing functions.
verbose
int verbose
project_generate_potential
int project_generate_potential(Bmolgroup *molgroup, Bmolgroup *water, Bproject *project, Bstring &fieldname, Bstring &mgname, int partselect, Vector3< long > size, double thickness, double resolution, double Bfactor, int pottype, Bstring &paramfile)
Generates potential images using a multislice calculation.
Definition: mg_multislice.cpp:502
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
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
molgroup_kill
int molgroup_kill(Bmolgroup *molgroup)
Destroys a molecule group.
Definition: rwmolecule.cpp:374
project_generate
Bproject * project_generate(int nfield, int nmg, int npart, double pixel_size, double img_origin, double volt, double Cs, double Cc, double alpha, double energy_spread, double amp_shift, double def_min, double def_max, double dose, double tsigma, Bstring &fieldbase, Bstring &mgbase, Bstring &partbase, int fieldnumber, int mgnumber, int partnumber)
Generates a project for multislice simulations.
Definition: mg_multislice.cpp:344
use
const char * use[]
Definition: bsim.cpp:21
Bstring::c_str
const char * c_str()
Definition: Bstring.h:70
Bstring::post_rev
Bstring post_rev(char c)
Definition: Bstring.cpp:428
mg_multislice.h
Generates and manipulates projects for multislice calculations.
Boption::next
Boption * next
Definition: options.h:28
Bstring
Definition: Bstring.h:29
project_kill
int project_kill(Bproject *project)
Frees a whole project.
Definition: mg_processing.cpp:1224
molecule_update_comment
int molecule_update_comment(Bmolgroup *molgroup, int n, char **strings)
Puts a set of strings and time in the main comment of a molecule group.
Definition: rwmolecule.cpp:1462
Vector3< long >
project_generate_image
int project_generate_image(Bproject *project, double thickness, double resolution)
Generates final images from a multislice calculation.
Definition: mg_multislice.cpp:602
timer_report
double timer_report(double lasttime)
Reports the time elapsed since a given time.
Definition: timer.cpp:67
main
int main(int argc, char **argv)
Definition: bsim.cpp:87
option_kill
int option_kill(Boption *option)
Deallocates a linked list of option structures.
Definition: options.cpp:109
Bstring::integer
long integer()
Definition: Bstring.cpp:539
mg_processing.h
Header file for micrograph processing.
options.h
Header file for option handlers.
Bstring::pre_rev
Bstring pre_rev(char c)
Definition: Bstring.cpp:413
project_update_comment
int project_update_comment(Bproject *project, int n, char **strings)
Puts a set of strings and time in the main comment of a project.
Definition: rwmg.cpp:468
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
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
Bproject
Definition: mg_processing.h:333
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
string_kill
int string_kill(Bstring *list)
Kills a string linked list.
Definition: Bstring.cpp:760
project_generate_asu
Bproject * project_generate_asu(Bstring &symmetry_string, double pixel_size, double img_origin, double theta_step, double phi_step, double volt, double Cs, double Cc, double alpha, double energy_spread, double amp_shift, double defocus, double dose, Bstring &mgbase, Bstring &partbase)
Generates a project for multislice calculations of an asymmetric unit.
Definition: mg_multislice.cpp:441