| Bsoft 2.0.5 Bernard's software package

jsubtomo.cpp
Go to the documentation of this file.
1
23 #include "rwimg.h"
24 #include "mg_subtomo.h"
25 #include "mg_processing.h"
26 #include "mg_particle_select.h"
27 #include "mg_extract.h"
28 #include "mg_img_proc.h"
29 #include "rwmg.h"
30 #include "ps_micrograph.h"
31 #include "Matrix.h"
32 #include "linked_list.h"
33 #include "file_util.h"
34 #include "options.h"
35 #include "utilities.h"
36 #include "timer.h"
37
38 // Declaration of global variables
39 extern int verbose; // Level of output to the screen
40
41 // Usage assistance
42 const char* use[] = {
43 " ",
44 "Usage: jsubtomo [options] input.star/input.img [input.star/input.img]",
45 "---------------------------------------------------------------------",
46 "Finds particles (subtomograms) in a tomographic reconstruction and refines their orientations and origins.",
47 "Extracts particles from the tomograms and transforms them for averaging,",
48 "or applies the inverse transformations on the template to position it in the original tomogram.",
49 " ",
50 "Actions mode:",
51 "-mode refine Search, Refine or Extract.",
52 " ",
53 " Search: Searches the particles in the input.image.",
54 " Refine: Refines the orientations of the particles in the input.star.",
55 " Extract: Writes selected particles to image files.",
56 " ",
57 "Actions:",
58 "-transform Transform the particle before extraction (use only in Extract mode).",
59 "-inverse Transform the template instead of the particle (use only in Extract mode).",
60 "-star Output a star file for each extracted particle (use only in Extract mode).",
61 "-wedges Output rotated missing wedge masks for each particle (use only in Extract mode).",
62 "-iterate 2 Iterate angular refinement (default 1 iteration).",
63 " The original step sizes and limits are halved after every iteration (use only in Refine mode with angle limits).",
64 " ",
65 "Parameters:",
66 "-verbose 7 Verbosity of output.",
67 "-datatype u Force writing of a new data type (default is float).",
68 "-sampling 1.5,1.5,1.5 Sampling (A/pixel; default from input file; a single value can be given).",
69 "-origin 110,50,44 Origin for rotations of the template (default taken from template image).",
70 "-convert Convert the first particle in the star-file into a reconstruction.",
71 " ",
72 "Parameters for search and refinement:",
73 "-angles 8.8,2.5,5.2 Step size for alpha, theta and phi, one value sets all (default 45 degrees).",
74 "-alphalimit 30 Angular limit for alpha (default: 180 degrees).",
75 "-thetaphilimit 5 Angular limit for theta & phi (default: 180 degrees, cannot be used with option symmetry).",
76 "-shiftlimit 5 Radial limit to search for shift in cross-correlation map, around the location given in input.star.",
77 " (pixels; default: whole map in Search mode, 1/2 template in Refine mode).",
78 "-resolution 15.6,200 Resolution limits for cross-correlation (default 0).",
79 "-symmetry I Symmetry of the template (default: no symmetry, thetaphilimit used instead).",
80 "-bin 3 Binning of input, template and mask by given kernel size,",
81 " output image remains same size as input.",
82 "-refinepeaks Refine peaks from cc search to subpixel accuracy.",
83 " ",
84 "Parameters for search:",
85 "-threshold 0.5 Report only particles above the ccc threshold.",
86 "-maxhits 10 Maximum number of particles to report for each orientation (default: all).",
87 " ",
88 "Parameters for refinement:",
89 "-zshiftlimit 10 Shift allowed in addition to 'shiftlimit' in the direction of the view vector (Use only in Refine mode, no xyshiftlimit).",
90 "-xyshiftlimit 10 Shift allowed in addition to 'shiftlimit' in the orthogonal to the view vector (Use only in Refine mode, no zshiftlimit).",
91 " ",
92 "Parameters for particle selection:",
93 "-all Reset selection to all particles before other selections.",
94 "-mindist 64 Discard overlapping particles (default: size of the template in Search, selection number set to zero).",
95 "-minangledif 50 Discard particles with too similar orientations (selection number set to zero).",
96 "-fom 0.3 Discard particles below the threshold (selection number set to zero).",
97 "-spheremindist 5 Discard particles too far from a sphere that best fits all the particles (selection number set to zero).",
98 "-topp 75.0 Select only the best percentage of particles (default 100%).",
99 "-topn 100 Select only a number of best particles from each reconstruction (default all).",
100 "-withindist 100,100,100,45 Select only particles within a set distance from a point.",
101 "-remove Remove all particles with selection number 0 after other selections.",
102 "-renumber Renumber particles.",
103 " ",
104 "Parameters for particle extraction:",
105 "-select 1 Extract particles with this selection number (default: all > 0).",
106 "-size 50,50,50 New size for transformed particles (use only in Extract mode. one value sets all).",
107 "-partpath dir/subdir Set the particle file paths (use only in Extract mode).",
108 "-partextension pif Set the particle image file format (dafault: map. use only in Extract mode).",
109 " ",
110 "Input:",
111 "-Template image.map Template to search for or to refine.",
112 "-mask mask_1.map Mask in real space to apply on template. Use a soft edged mask.",
113 "-Mask mask_2.map Mask in reciprocal space to apply during cross-correlation and for CCC normalization.",
114 " ",
115 "Output:",
116 "-output file.star Output parameter file with orientations.",
117 "-ccmax ccmax.img Output image with maximum cross-correlation coefficient value for each position (use only in Search mode).",
118 " ",
119 NULL
120 };
121
122 int main(int argc, char **argv)
123 {
124 // Initialize variables
125 DataType nudatatype(Unknown_Type); // Conversion to new type
126 Bstring mode; // Mode, default is none
127 Bstring rec_id; // Reconstruction ID
128 Vector3<double> sam; // Units for the three axes (A/pixel)
129 Vector3<double> origin; // Template origin
130 Vector3<double> origin2; // Transformation origin
131 Vector3<double> origin3; // Wedge mask origin
132 int set_origin(0); // Flag to set origin
133 int set_sampling(0); // Flag to set sampling
134 double alpha_step(M_PI_4); // Angular step size for alpha
135 double theta_step(M_PI_4); // Angular step size for theta
136 double phi_step(M_PI_4); // Angular step size for phi
137 double alpha_limit(M_PI); // Angular limit of alpha in search
138 double thetaphi_limit(M_PI); // Angular limit of theta and phi in search
139 double hires(0), lores(0); // Limiting resolution for cross-correlation
140 double shiftlimit(-1); // Use default search radius
141 double shiftlimitz(0);
142 double shiftlimitxy(0);
143 View ref_view; // Reference view
144 Quaternion quat;
145 int applytransform(0); // Rotate and shift in extraction (default not)
146 int extractparticle(1); // 0 = template, 1 = particle
147 int refinepeaks(0); // No refinement of the cc peaks to subpixel accuracy
148 Vector3<long> bin = {1,1,1}; // No binning by default
149 Bstring template_file; // Reference template
150 Bstring mask_file; // Reciprocal space mask
151 Bstring mask_file2; // Real space mask
152 Bstring ps_file; // Postscript output
153 Bstring param_file; // Parameter file
154 Bstring ccmax_file; // CCC max value image file
155 double threshold(0.005); // Threshold for cross correlation search
156 int maxhits(-1); // Maximum nimber of hits in cross correlation search
157 Vector3<long> size; // Boxsize for extracting particles
158 Vector3<long> size2; // Boxsize for extracting particles
159 Bstring partpath; // Particle file path
160 Bstring part_ext; // Particle image file format
161 double randomlocations(0); // Standard deviation for origin errors (angstrom)
162 double randomviews(0); // Standard deviation for view errors (degrees)
163 double randommag(0); // Standard deviation for magnification errors (fraction)
164 int iters(1); // Number of iterations
165 double mindist(-1); // Minimum distance between positions
166 double peakdist;
167 double minangledif(-1); // Minimum difference in the angles
168 double spheremindist(-1); // Minimum distance to a sphere fitted to the particles
169 double angledif;
170 double fom_cutoff(-1);
171 double fom_percentage(-1); // Percentage particles to accept
172 int num_to_select(-1); // Number of particles to accept
173 double withindist_x(0);
174 double withindist_y(0);
175 double withindist_z(0);
176 Vector3<double> withindist_point;
177 double withindist_d(-1);
178 int reset(0); // Keep selection as read from file
179 int select(-1);
180 int renumber(0);
181 int convert(0); // Promotes a subtomogram to a tomogram
182 int remove(0);
183 int extractstar(0);
184 int extractwedges(0);
185 int ipart;
186 int i, optind;
187 Bsymmetry* sym = NULL;
188
189 Boption* option = get_option_list(use, argc, argv, optind);
190 Boption* curropt;
191
192 for ( curropt = option; curropt; curropt = curropt->next ) {
193 if ( curropt->tag == "datatype" )
194 nudatatype = curropt->datatype();
195 if ( curropt->tag == "mode" ) {
196 mode = curropt->value.lower();
197 if ( mode.length() < 1 ) {
198 cerr << "-mode: A mode must be specified" << endl;
199 bexit(-1);
200 }
201 }
202 if ( curropt->tag == "inverse" )
203 extractparticle = 0;
204 if ( curropt->tag == "transform")
205 applytransform = 1;
206 if ( curropt->tag == "star")
207 extractstar = 1;
208 if ( curropt->tag == "wedges")
209 extractwedges = 1;
210 if ( curropt->tag == "sampling") {
211 sam = curropt->sampling();
212 set_sampling = 1;
213 }
214 if ( curropt->tag == "origin") {
215 origin = curropt->origin();
216 set_origin = 1;
217 }
218 if ( curropt->tag == "angles") {
219 if ( ( i = curropt->values(alpha_step, theta_step, phi_step) ) < 1 ) {
220 cerr << "-angles: An angle step size must be specified" << endl;
221 bexit(-1);
222 }
223 else {
224 if ( i < 2 ) phi_step = theta_step = alpha_step;
225 else if ( i < 3 ) phi_step = theta_step;
226
227 if ( alpha_step < 0.01 ) { alpha_step=1; }
228 if ( theta_step < 0.01 ) { theta_step=1; }
229 if ( phi_step < 0.01 ) { phi_step=1; }
230
231 alpha_step *= M_PI/180.0;
232 theta_step *= M_PI/180.0;
233 phi_step *= M_PI/180.0;
234 }
235 }
236 if ( curropt->tag == "alphalimit" ) {
237 if ( ( alpha_limit = curropt->value.real() ) < 0.001 ) {
238 cerr << "-alphalimit: An angular limit for alpha must be specified!" << endl;
239 bexit(-1);
240 }
241 else {
242 alpha_limit *= M_PI/180.0;
243 }
244 }
245 if ( curropt->tag == "thetaphilimit" ) {
246 if ( ( thetaphi_limit = curropt->value.real() ) < 0.001 ) {
247 cerr << "-thetaphilimit: An angular limit for theta & phi must be specified!" << endl;
248 bexit(-1);
249 }
250 else {
251 thetaphi_limit *= M_PI/180.0;
252 }
253 }
254 if ( curropt->tag == "resolution" ) {
255 if ( curropt->values(hires, lores) < 1 ) {
256 cerr << "-resolution: A resolution must be specified!" << endl;
257 bexit(-1);
258 }
259 }
260 if ( curropt->tag == "shiftlimit" ) {
261 if ( ( shiftlimit = curropt->value.real() ) < 0.001 ) {
262 cerr << "-shiftlimit: A shift search radius must be specified!" << endl;
263 bexit(-1);
264 }
265 else {
266 if ( shiftlimit < 0 ) { shiftlimit = 0; }
267 }
268 }
269 if ( curropt->tag == "zshiftlimit") {
270 if ( ( shiftlimitz = curropt->value.real() ) < 0.001 ) {
271 cerr << "-zshiftlimit: A maximum shift in the direction of the view vector must be specified!" << endl;
272 bexit(-1);
273 }
274 else {
275 if ( shiftlimitz < 0 ) { shiftlimitz = 0; }
276 }
277 }
278 if ( curropt->tag == "xyshiftlimit") {
279 if ( ( shiftlimitxy = curropt->value.real() ) < 0.001 ) {
280 cerr << "-xyshiftlimit: A maximum shift orthogonal to the view vector must be specified!" << endl;
281 bexit(-1);
282 }
283 else {
284 if ( shiftlimitxy < 0 ) { shiftlimitxy = 0; }
285 }
286 }
287 if ( curropt->tag == "mindist") {
288 if ( ( mindist = curropt->value.real() ) < 0.001 ) {
289 cerr << "-mindist: A minimum distance between particles must be specified!" << endl;
290 bexit(-1);
291 }
292 }
293 if ( curropt->tag == "spheremindist") {
294 if ( ( spheremindist = curropt->value.real() ) < 0.001 ) {
295 cerr << "-spheremindist: A minimum distance between particles and a fitted sphere!" << endl;
296 bexit(-1);
297 }
298 }
299 if ( curropt->tag == "minangledif") {
300 if ( ( minangledif = curropt->value.real() ) < 0.001 ) {
301 cerr << "-minangledif: A minimum difference in the orientations between particles must be specified!" << endl;
302 bexit(-1);
303 }
304 else {
305 minangledif *= M_PI/180.0;
306 }
307
308 }
309 if ( curropt->tag == "symmetry" )
310 sym = curropt->symmetry();
311 if ( curropt->tag == "bin" ) {
312 if ( ( bin[0] = curropt->value.integer() ) < 1 ) {
313 cerr << "-bin: A bin size must be specified!" << endl;
314 bexit(-1);
315 } else {
316 bin[2] = bin[1] = bin[0];
317 }
318 }
319 if ( curropt->tag == "refinepeaks" ) {
320 refinepeaks = 1;
321 }
322 if ( curropt->tag == "threshold" ) {
323 if ( ( threshold = curropt->value.real() ) < 0.001 ) {
324 cerr << "-threshold: A threshold must be specified!" << endl;
325 bexit(-1);
326 }
327 }
328 if ( curropt->tag == "topp" ) {
329 if ( ( fom_percentage = curropt->value.real() ) < 0.001 ) {
330 cerr << "-topp: A percentage must be specified!" << endl;
331 bexit(-1);
332 }
333 }
334 if ( curropt->tag == "topn" ) {
335 if ( ( num_to_select = curropt->value.integer() ) < 1 ) {
336 cerr << "-topn: A number must be specified!" << endl;
337 bexit(-1);
338 }
339 }
340 if ( curropt->tag == "withindist" ) {
341 if ( ( i = curropt->values(withindist_x, withindist_y, withindist_z, withindist_d) ) < 4 ) {
342 cerr << "-withindist: Three coordinates and a maximum distance (in pixels) must be specified" << endl;
343 bexit(-1);
344 } else {
345 withindist_point = Vector3<double>(withindist_x, withindist_y, withindist_z);
346 }
347 }
348 if ( curropt->tag == "maxhits" ) {
349 if ( ( maxhits = curropt->value.integer() ) < 1 ) {
350 cerr << "-maxhits: The maximum number of hits must be specified!" << endl;
351 bexit(-1);
352 }
353 }
354 if ( curropt->tag == "Template" ) {
355 template_file = curropt->filename();
356 }
357 if ( curropt->tag == "mask" ) {
358 mask_file2 = curropt->filename();
359 }
360 if ( curropt->tag == "Mask" ) {
361 mask_file = curropt->filename();
362 }
363 if ( curropt->tag == "output" ) {
364 param_file = curropt->filename();
365 }
366 if ( curropt->tag == "ccmax" ) {
367 ccmax_file = curropt->filename();
368
369 }
370 if ( curropt->tag == "size" ) {
371 size = curropt->size();
372 if ( size.volume() < 1 ) {
373 cerr << "-size: A box size must be specified." << endl;
374 bexit(-1);
375 }
376 }
377 if ( curropt->tag == "partpath" ) {
378 partpath = curropt->value;
379 if ( partpath.length() < 1 )
380 cerr << "-partpath: The particle file path must be specified!" << endl;
381 else {
382 if ( partpath[-1] != '/' ) partpath += "/";
383 }
384 }
385 if ( curropt->tag == "partextension" ) {
386 part_ext = curropt->value;
387 if ( part_ext.length() < 1 ) {
388 cerr << "-partextension: The particle file extension must be specified!" << endl;
389 bexit(-1);
390 }
391 }
392 if ( curropt->tag == "randomlocations" ) {
393 if ( ( randomlocations = curropt->value.real() ) < 0.001 ) {
394 cerr << "-randomlocations: A standard deviation must be specified!" << endl;
395 bexit(-1);
396 }
397 else if ( randomlocations < 0 ) randomlocations = 0;
398 }
399 if ( curropt->tag == "randomviews" ) {
400 if ( ( randomviews = curropt->value.real() ) < 0.001 )
401 cerr << "-randomviews: A standard deviation must be specified!" << endl;
402 else {
403 randomviews *= M_PI/180.0; // Assume degrees
404 if ( randomviews < 0 ) randomviews = 0;
405 }
406 }
407 if ( curropt->tag == "randommag" ) {
408 if ( ( randommag = curropt->value.real() ) < 0.00001 ) {
409 cerr << "-randommag: A standard deviation must be specified!" << endl;
410 bexit(-1);
411 }
412 else {
413 if ( randommag < 0 ) randommag = 0;
414 }
415 }
416 if ( curropt->tag == "iterate" ) {
417 if ( ( iters = curropt->value.integer() ) < 1 ) {
418 cerr << "-iterate: The number of iterations must be specified!" << endl;
419 bexit(-1);
420 }
421 else {
422 if ( iters < 1 ) { iters = 1; }
423 }
424 }
425
426 if ( curropt->tag == "renumber" )
427 renumber = 1;
428 if ( curropt->tag == "fom" ) {
429 if ( ( fom_cutoff = curropt->value.real() ) < 0.001 ) {
430 cerr << "-fom: A threshold value must be specified!" << endl;
431 bexit(-1);
432 }
433 }
434 if ( curropt->tag == "all" ) {
435 reset = 1;
436 }
437 if ( curropt->tag == "remove" ) {
438 remove = 1;
439 }
440 if ( curropt->tag == "select" ) {
441 if ( ( select = curropt->value.integer() ) < 1 ) {
442 cerr << "-select: A selection number must be specified!" << endl;
443 bexit(-1);
444 }
445 }
446 if ( curropt->tag == "convert" ) {
447 convert = 1;
448 }
449 }
450 option_kill(option);
451
452 double ti = timer_start();
453
454 Vector3<double> currshift, bestshift;
455
456 Bimage* p = NULL;
457 Bimage* p2 = NULL;
458 Bimage* p3 = NULL;
459 Bimage* ptemp = NULL;
460 Bimage* pmask = NULL;
461 Bimage* pmask2 = NULL;
462 Bimage* pmask3 = NULL;
463 Bstring filename;
464 Bstring starfilename;
465 Bstring wedgefilename;
466 Vector3<double> scale(1,1,1);
467 Bproject* project = NULL;
468 Bproject* partproject = NULL;
469 Breconstruction* rec = NULL;
470 Breconstruction* newrec = NULL;
471 Bparticle* part = NULL;
472 Bparticle* part2 = NULL;
473 Bparticle* newpart = NULL;
474 Vector3<long> psize, ptempsize;
475 long npart = 0;
476 Matrix3 mat;
477 Vector3<double> translate;
478 Vector3<long> obin(bin[0], bin[1], bin[2]);
479
480 // Read template
481 if ( template_file.length() ) {
482 if ( verbose & VERB_PROCESS ) { cout << "Reading the template." << endl << endl; }
483 ptemp = read_img(template_file, 1, 0);
484 ptemp->change_type(Float);
485 ptempsize = ptemp->size();
486 }
487
488 // Template required for these modes
489 if ( ( (mode == "search") || (mode == "refine") ) && ptemp == NULL ) {
490 cerr << "Error: No template file specified!" << endl << endl;
491 bexit(-1);
492 }
493
494 // Template required for search and extract mode with inverse option
495 if ( (mode == "extract") && ( extractparticle == 0) && ptemp == NULL ) {
496 cerr << "Error: No template file specified!" << endl << endl;
497 bexit(-1);
498 }
499
500 // Read all the parameter files (or reconstructions)
501 if ( verbose & VERB_PROCESS ) { cout << "Reading the input file(s)." << endl << endl; }
502 Bstring* file_list = NULL;
503 while ( optind < argc ) string_add(&file_list, argv[optind++]);
504 if ( !file_list ) {
505 cerr << "Error: No parameter files specified!" << endl << endl;
506 bexit(-1);
507 }
508 if ( file_type(*file_list) == Micrograph ) {
509
510 project = read_project(file_list);
511
512 // Promote a subtomogram to a tomogram
513 if ( convert ) {
514 for ( rec=project->rec; rec; rec=rec->next ) {
515 rec->frec = rec->part->fpart;
516 rec->part->fpart = NULL;
517 rec->fpart = NULL;
518 rec->symmetry = 0;
519 // old origin becomes new location
520 rec->part->loc = rec->part->ori;
521 // new origin
522 rec->part->ori = origin;
523 }
524 }
525 }
526 else {
527 project = project_create_from_images(file_list, 0);
528 for ( rec=project->rec; rec; rec=rec->next ) { // Remove the particle record which was created unnecessarily
529 rec->fpart=NULL;
530 if ( ptemp ) {
531 rec->box_size = ptempsize;
532 }
533 }
534 }
535
536 string_kill(file_list);
537
538 // Read reciprocal space mask (missing wedge mask)
539 if ( mask_file.length() ) {
540 if ( verbose & VERB_PROCESS ) { cout << "Reading the reciprocal space mask." << endl << endl; }
541 pmask = read_img(mask_file, 1, 0);
542 if (!( pmask )) {
543 cerr << "Error: No mask found!" << endl;
544 bexit (-1);
545 }
546 }
547 if ( (mode == "extract") && ( extractwedges == 1 ) && pmask == NULL ) {
548 cerr << "Error: No reciprocal space mask file specified!" << endl << endl;
549 bexit(-1);
550 }
551
552 // Read real space mask
553 if ( mask_file2.length() ) {
554 if ( verbose & VERB_PROCESS ) { cout << "Reading the real space mask." << endl << endl; }
555 pmask2 = read_img(mask_file2, 1, 0);
556 if (!( pmask2 )) {
557 cerr << "Error: No mask found!" << endl;
558 bexit (-1);
559 }
560 }
561
562 // Set the origin and bin the template
563 if ( ptemp ) {
564 if ( set_origin ) { ptemp->origin(origin); }
565 if ( set_sampling ) { ptemp->sampling(sam); }
566 if ( bin[0] > 1 ) {
567 if ( verbose & VERB_PROCESS ) { cout << "Binning the template." << endl << endl; }
568 ptemp->bin(bin);
569 }
570 ptempsize = ptemp->size();
571 }
572
573 // Set the origin and bin the real space mask
574 if ( pmask2 ) {
575 if ( set_origin ) { pmask2->origin(origin); }
576 if ( set_sampling ) { pmask2->sampling(sam); }
577 if ( bin[0] > 1 ) {
578 if ( verbose & VERB_PROCESS ) { cout << "Binning the real space mask." << endl << endl; }
579 pmask2->bin(bin);
580 }
581 }
582
583 // Real space mask must be the same size as template
584 if ( pmask2 && ptemp ) {
585 if (ptemp->size() != pmask2->size()) {
586 cerr << "Error: Real space mask and template must be of the same size!" << endl << endl;
587 bexit(-1);
588 }
589 }
590
591 if ( mode != "refine" ) {
592 shiftlimitz = 0;
593 shiftlimitxy = 0;
594 }
595
596 if ( shiftlimitz && shiftlimitxy ) {
597 cerr << "Error: Both zshiftlimit and xyshiftlimit specified!" << endl << endl;
598 }
599
600 // Take binning into account in distance limits
601 if ( bin[0] > 1 ) {
602 mindist /= bin[0];
603 shiftlimit /= bin[0];
604 shiftlimitz /= bin[0];
605 shiftlimitxy /= bin[0];
606 }
607
608 if ( !sym ) sym = init_point_group_symmetry("C1");
609
610 // Run in given mode for all the reconstructions in the project
611 for ( rec=project->rec; rec; rec=rec->next ) {
612
613 // Set origin of all particles
614 if ( set_origin == 1 ) {
615 if ( verbose & VERB_PROCESS )
616 cout << endl << "Setting particle origins." << endl;
617 for (part = rec->part; part; part=part->next ) { part->ori = origin; }
618 }
619
620 // Read the reconstruction
621 if ( (mode == "search") || (mode == "refine") || ( (mode == "extract") && (extractparticle == 1)) ) {
622 if ( verbose & VERB_PROCESS )
623 cout << endl << "Reading the reconstruction." << endl << endl;
624 p = read_img(rec->frec, 1, 0);
625 if ( !p ) {
626 cerr << "Error: No reconstruction found!" << endl;
627 bexit (-1);
628 }
629 if ( set_sampling ) { p->sampling(sam); }
630 if ( bin[0] > 1 ) { p->bin(bin); }
631 p->change_type(Float);
632 }
633
634 // SEARCH MODE
635
636 if ( mode == "search" ) {
637 npart = reconstruction_search_subtomo(rec, p, ptemp, pmask, pmask2,
638 alpha_step, theta_step, phi_step, alpha_limit, thetaphi_limit,
639 hires, lores, shiftlimit, mindist,
640 threshold, maxhits, bin, sym, refinepeaks, ccmax_file);
641
642 if ( verbose ) {
643 if ( npart > 0 )
644 cout << endl << "Found " << npart << " particle(s), some of which maybe overlapping each other." << endl;
645 else
646 cout << endl << "No particles found." << endl;
647 }
648 }
649
650 // REFINE MODE
651
652 if ( mode == "refine" ) {
653 npart = reconstruction_refine_subtomo(rec, p, ptemp, pmask, pmask2,
654 alpha_step, theta_step, phi_step, alpha_limit, thetaphi_limit,
655 hires, lores, shiftlimit, shiftlimitz, shiftlimitxy,
656 mindist, bin, sym, iters, refinepeaks, ccmax_file);
657
658 if ( verbose & VERB_PROCESS )
659 cout << "Refined " << npart << " particle(s)." << endl;
660 }
661
662 // Normalize particle views automatically
663
664 if ( verbose & VERB_PROCESS )
665 cout << endl << "Normalizing particle views." << endl;
666 for ( part = rec->part; part; part=part->next ) part->view.normalize();
667
668 // PARTICLE SELECTIONS
669
670 // Select all particles
671 if ( reset == 1 ) {
672 if ( verbose & VERB_PROCESS )
673 cout << endl << "Resetting particle selections." << endl;
674 for ( part = rec->part; part; part=part->next ) part->sel = 1;
675 }
676
677 // Determine the ccc threshold from percentage
678 if ( (fom_percentage >= 0) || (num_to_select >= 0) ) {
679 int_float* rank = part_fom_order(rec->part, npart, 0);
680
681 if (fom_percentage >= 0) { num_to_select = (int) (npart*fom_percentage/100.0); }
682 if (num_to_select > npart) { num_to_select = npart; }
683
684 fom_cutoff = rank[num_to_select].f;
685
686 delete[] rank;
687 }
688
689 // Discard below the ccc threshold
690 if ( fom_cutoff > 0 ) {
691 if ( verbose & VERB_PROCESS ) { cout << endl << "Discarding particles below threshold." << endl; }
692 for (part = rec->part; part; part=part->next ) {
693 if ( part->fom[0] <= fom_cutoff ) { part->sel = 0; }
694 }
695 }
696
697 // Discard overlapping particles
698 if ( mindist > 0 ) {
699
700 if ( verbose & VERB_PROCESS ) { cout << endl << "Selecting the best particle for each position." << endl; }
701
702 // for each particle, check if all its followers are worse. If not, unselect
703 part = rec->part;
704 while ( part ) {
705 if ( part->sel != 0 ) {
706 part2 = part->next;
707 while ( part2 ) {
708 if ( part2->sel != 0 ) {
709 peakdist = (part->loc-part2->loc).length();
710 // mindist in binned units
711 if ( peakdist < mindist * bin[0] ) {
712 if ( part2->fom[0] > part->fom[0] ) {
713 part->sel = 0;
714 } else {
715 part2->sel = 0;
716 }
717 }
718 }
719 part2 = part2->next;
720 }
721 }
722 part = part->next;
723 }
724 if ( verbose & VERB_PROCESS ) { cout << endl << "Minimum distance between particles: " << mindist * bin[0] << endl; }
725 }
726
727 // Discard particles with too similar views
728 Vector3<double> part_view;
729 Vector3<double> part2_view;
730 View view;
731 View view2;
732
733 if ( minangledif > 0 ) {
734
735 if ( verbose & VERB_PROCESS ) { cout << endl << "Selecting the best particle for each view." << endl; }
736
737 // for each particle, check if all its followers are worse. If not, unselect
738 part = rec->part;
739 while ( part ) {
740 if ( part->sel != 0 ) {
741 part2 = part->next;
742 while ( part2 ) {
743 if ( part2->sel != 0 ) {
744 view = part->view;
745 view2 = part2->view;
746
747 part_view = Vector3<double>(view[0],view[1],view[2]);
748 part2_view = Vector3<double>(view2[0],view2[1],view2[2]);
749
750 angledif = part_view.angle(part2_view);
751
752 // cout << "part %d--part %d: " << part->id, part2->id, (angledif*180/M_PI));
753 if ( angledif < minangledif ) {
754 if ( part2->fom[0] > part->fom[0] ) {
755 part->sel = 0;
756 cout << "unselected part: " << part->id;
757 } else {
758 part2->sel = 0;
759 cout << "unselected part: " << part2->id;
760 }
761 }
762 }
763 part2 = part2->next;
764 }
765 }
766 part = part->next;
767 }
768 if ( verbose & VERB_PROCESS ) {
769 cout << endl << "Minimum difference in the view angles between particles: " << (minangledif*180/M_PI) << endl;
770 }
771 }
772
773 // Discard particles too far from a specified point
774 if ( withindist_d > 0 ) {
775 if ( verbose & VERB_PROCESS ) { cout << endl << "Discarding particles further than " << withindist_d << " from the given point." << endl; }
776 for (part = rec->part; part; part=part->next ) {
777 cout << "ID " << part->id << ": distance: " << (part->loc-withindist_point).length() << endl;
778 if ( ((part->loc-withindist_point).length()) > withindist_d ) { part->sel = 0; }
779 }
780 }
781
782 // Discard particles too far from a fitted sphere surface
783 if ( spheremindist > 0 ) {
784 Sphere sphere = {0,0,0,0};
785 double distance;
786 double sumdistances2(0);
787 if ( verbose & VERB_PROCESS ) { cout << endl << "Fitting a sphere to particles locations" << endl; }
788 sphere = locations_fit_sphere(rec->part, 100, 0.1);
789 if ( verbose & VERB_PROCESS ) { cout << "Found a sphere with center " << sphere.A << " " << sphere.B << " " << sphere.C << " and radius " << sphere.R << endl; }
790 if ( verbose & VERB_PROCESS ) { cout << "Discarding particles further than " << spheremindist << " pix from the surface of the sphere." << endl; }
791 for (part = rec->part; part; part=part->next ) {
792 distance = (part->loc-Vector3<double>(sphere.A,sphere.B,sphere.C)).length()-sphere.R;
793 sumdistances2 += distance*distance;
794 if ( verbose & VERB_PROCESS ) { cout << "ID " << part->id << ": distance: " << distance << endl; }
795 if ( fabs(distance) > spheremindist ) { part->sel = 0; }
796 }
797 if ( verbose & VERB_PROCESS ) { cout << "RMSD of all locations: " << sqrt(sumdistances2)/particle_count(rec->part) << " pix" << endl; }
798 }
799
800 // remove unselected particles if wanted (currently removed particle structures are not killed)
801 if ( remove ) {
802 part2=rec->part;
803
804 while ( part2 ) {
805 if ( part2->sel == 0 ) {
806 if ( verbose & VERB_PROCESS ) {
807 cout << "Removing particle: " << part2->id << endl;
808 }
809 if ( part ) {
810 part->next = part2->next;
811 part2=part->next;
812 }
813 else {
814 rec->part = part2->next;
815 part2 = part2->next;
816 }
817
818 } else {
819 part = part2;
820 part2 = part2->next;
821 }
822 }
823 }
824
825 if ( renumber ) {
826 for (part = rec->part, ipart=1; part; part=part->next, ipart++) {
827 part->id = ipart;
828 }
829 }
830
831 if ( verbose ) project_show_selected(project);
832
833 // EXTRACT MODE
834
835 if ( mode == "extract" ) {
836
837 part = rec->part;
838 npart = particle_count_selected(part);
839
840 if ( part_ext.length() < 1 ) { part_ext = "map"; }
841
842 if ( verbose & VERB_PROCESS ) { cout << endl << "Extracting " << npart << " particle(s)." << endl; }
843
844 if ( !applytransform ) { cerr << "Warning: -transform option not give given, particles will not be rotated, only shifted." << endl; }
845
846 // give box size is relative to unbinned units
847 size = size / obin;
848
849 if ( extractwedges ) {
850 if ( size.volume() == 0 ) {
851 // size of the template by default
852 if ( ptemp ) { size = ptemp->size(); }
853 else { size = p->size(); }
854 }
855
856 // Scale the reciprocal space mask to match the size of the extracted particle
857 if ( pmask->size() != size ) {
858 if ( verbose & VERB_PROCESS ) { cout << endl << "Scaling the reciprocal space mask to the size of the extracted particle." << endl; }
859 // img_transform(pmask, size, size/pmask->size(),
860 // Vector3<double>(0,0,0), Vector3<double>(0,0,0), ref_view.matrix(), FILL_BACKGROUND, 0);
861 pmask->mask_fspace_resize(size);
862 }
863 }
864
865 // extract the images
866 filename = rec->fpart;
867 if ( filename.length() < 3 )
868 filename = rec->frec.pre_rev('.') + "_part." + part_ext;
869
870 particle_setup_filenames(rec->part, filename, partpath);
871
872 for ( part = rec->part; part; part = part-> next ) {
873
874 if ( ((select < 0) && (part->sel > 0)) || (part->sel == select) ) {
875
876 view = part->view;
877 view.normalize();
878
879 if ( extractparticle == 1 ) { // Extract the particle (and the corresponding wedge mask)
880 // p2 = p->copy();
881
882 if ( ( size.volume() == 0 ) ) {
883 // size of the template by default
884 if ( ptemp ) { size = ptemp->size(); }
885 else { size = p->size(); }
886 }
887
888 // origin2 = part -> loc / Vector3<double>( bin[0],bin[1],bin[2] );
889 origin2 = part->loc / obin;
890 // p2->origin(origin2);
891 //pmask2->origin(origin2);
892
893 // translate = ( part->ori - part->loc ) / Vector3<double>(bin[0],bin[1],bin[2]);
894 translate = ( part->ori - part->loc ) / obin;
895
896 // keep extracted particle in the center
897 // translate = ( translate - ( part->ori - Vector3<double>(size[0],size[1],size[2]) / 2 ) ) / Vector3<double>(bin[0],bin[1],bin[2]);
898 // translate = ( translate - ( part->ori - size) / 2 ) / bin;
899
900 if ( applytransform ) {
901 mat = view.matrix();
902 } else {
903 mat = ref_view.matrix();
904 }
905
906 // p2 = img_transform_copy(p, size, scale, origin2, translate, mat, FILL_BACKGROUND, 0);
907 p2 = p->transform(size, scale, origin2, translate, mat, FILL_BACKGROUND, 0);
908
909 if ( pmask2 ) {
910 if ( verbose & VERB_PROCESS ) { cout << endl << "Masking the extracted particle." << endl; }
911 p2->multiply(pmask2);
912 }
913
914 if ( extractwedges ) {
915 // pmask3 = pmask->copy();
916 // origin3 = pmask3->size()/2;
917 // pmask3->origin(origin3);
918 // img_transform(pmask3, size, scale, origin3, Vector3<double>(0,0,0), mat, FILL_BACKGROUND, 0);
919 origin3 = pmask->size()/2;
920 pmask3 = pmask->transform(size, scale, origin3, Vector3<double>(0,0,0), mat, FILL_BACKGROUND, 0);
921 pmask3->origin(origin3);
922 wedgefilename = part->fpart.pre_rev('.') + "_mask." + part_ext;
923 pmask3->change_type(nudatatype);
924 pmask3->label(get_cmd_line(argc, argv));
925 write_img(wedgefilename, pmask3, 0);
926 delete pmask3;
927 }
928 // p2->origin(origin);
929 p2->origin(part->ori/obin);
930 }
931
932 if ( extractparticle == 0 ) { // Transform the template instead
933 if ( applytransform ) {
934 mat = view.matrix();
935 mat = mat.transpose();
936 } else {
937 mat = ref_view.matrix();
938 }
939
940 // origin = part -> ori / Vector3<double>( bin[0],bin[1],bin[2] );
941 origin = part->ori / obin;
942
943 p2 = ptemp->copy();
944
945 p2->origin(origin);
946
947 if ( pmask2 ) {
948 if ( verbose & VERB_PROCESS ) { cout << "Masking the template before transformation." << endl; }
949 p2->multiply(pmask2);
950 }
951
952 // If no size is specified no translation is applied and the origin will reflect the location of the particle
953 // in the reconstruction
954
955 // If size is specified, translation will be applied and origin is set to zero
956
957 if ( size.volume() == 0 ) {
958 // img_transform(p2, ptempsize, scale, origin, Vector3<double>(0,0,0), mat, FILL_BACKGROUND, 0);
959 p2->transform(scale, origin, Vector3<double>(0,0,0), mat, FILL_BACKGROUND, 0);
960 // origin = -(part->loc - part->ori) / Vector3<double>(bin[0],bin[1],bin[2]);
961 origin = -(part->loc - part->ori) / obin;
962 } else {
963 // translate = (part->loc - part->ori) / Vector3<double>(bin[0],bin[1],bin[2]);
964 translate = (part->loc - part->ori) / obin;
965 // img_transform(p2, size, scale, origin, translate, mat, FILL_BACKGROUND, 0);
966 p3 = p2->transform(size, scale, origin, translate, mat, FILL_BACKGROUND, 0);
967 delete p2;
968 p2 = p3;
969 // origin = Vector3<double>(0,0,0);
970 origin = p2->size()/2;
971 }
972
973 p2->origin(origin);
974 }
975
976 p2->change_type(nudatatype);
977 p2->label(get_cmd_line(argc, argv));
978 write_img(part->fpart, p2, 0);
979 delete p2;
980
981 if ( extractstar ) {
982 partproject = project_create(0, 1);
983
984 newrec = partproject->rec;
985 newrec->id=part->fpart.pre_rev('.');
986 newrec->frec=part->fpart;
987 newrec->voxel_size=rec->voxel_size;
988 newrec->box_size=rec->box_size;
989 newpart = particle_add(&newrec->part, 1);
990
991 if ( set_origin == 1 ) {
992 newpart->loc = origin;
993 newpart->ori = origin;
994 }
995 else if ( size[0] * size[1] * size[2] > 0 ) {
996 newpart->loc = Vector3<double>(size[0]/2, size[1]/2, size[2]/2);
997 newpart->ori = Vector3<double>(size[0]/2, size[1]/2, size[2]/2);
998 }
999 else {
1000 newpart->loc = part->loc;
1001 newpart->ori = part->ori;
1002 }
1003
1004 if ( applytransform ) {
1005 newpart->view = ref_view;
1006 }
1007 else {
1008 newpart->view = view;
1009 }
1010
1011 newpart->fom[0] = part->fom[0];
1012
1013 starfilename = part->fpart.pre_rev('.') + ".star";
1014 project_update_comment(partproject, argc, argv);
1015
1016 if ( starfilename.length() ) { write_project(starfilename, partproject, 0, 0); }
1017
1018 project_kill(partproject);
1019 }
1020 }
1021 }
1022 }
1023
1024 delete p;
1025 delete pmask2;
1026 }
1027
1028 kill_symmetry(sym);
1029 delete pmask;
1030 delete ptemp;
1031
1032 project_update_comment(project, argc, argv);
1033
1034 if ( param_file.length() )
1035 write_project(param_file, project, 0, 0);
1036
1037 project_kill(project);
1038
1039 if ( verbose & VERB_TIME )
1040 timer_report(ti);
1041
1042 bexit(0);
1043 }
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
write_project
int write_project(const char *filename, Bproject *project)
Writing micrograph parameters to a file.
Definition: rwmg.cpp:320
Bparticle::id
int id
Definition: mg_processing.h:92
rwmg.h
Header file for reading and writing micrograph parameters.
distance
double distance(vector< T1 > &v1, vector< T2 > &v2)
Definition: Vector3.h:536
Bstring::real
double real()
Definition: Bstring.cpp:545
ps_micrograph.h
Header file for postscript tools dealing with micrograph particle sets.
string_add
Bstring * string_add(Bstring **list, const char *string)
Adds a string to a linked list.
Definition: Bstring.cpp:705
Bproject::rec
Breconstruction * rec
Definition: mg_processing.h:344
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
particle_setup_filenames
int particle_setup_filenames(Bparticle *part, Bstring filename, Bstring partpath)
Sets up individual particle file names for extraction.
Definition: mg_extract.cpp:35
Bparticle::view
View view
Definition: mg_processing.h:101
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Breconstruction::part
Bparticle * part
Definition: mg_processing.h:304
Breconstruction::fpart
Bstring fpart
Definition: mg_processing.h:288
mg_particle_select.h
Select particles.
particle_count_selected
long particle_count_selected(Bparticle *part)
Counts the number of particles in a linked list.
Definition: mg_processing.cpp:1169
utilities.h
Header file for general utilities.
Boption::sampling
Vector3< double > sampling()
Definition: options.h:202
Boption::value
Bstring value
Definition: options.h:30
Breconstruction
Definition: mg_processing.h:280
Boption::tag
Bstring tag
Definition: options.h:29
mg_img_proc.h
Header file for image processing from micrograph structures.
project_create_from_images
Bproject * project_create_from_images(Bstring *file_list, Bstring type)
Creates a project structure using image file names.
Definition: mg_img_proc.cpp:224
file_type
FileType file_type(const char *filename)
Checks the file type using the extension and contents.
Definition: file_util.cpp:178
Bparticle::fom
double fom[NFOM]
Definition: mg_processing.h:102
read_project
Bproject * read_project(const char *filename, int flags=0)
Reading micrograph parameters from files.
Definition: rwmg.cpp:140
Matrix3
Definition: Matrix3.h:17
particle_add
Bparticle * particle_add(Bparticle **part, int pid)
Adds a particle parameter structure to a linked list.
Definition: mg_processing.cpp:527
Bstring::length
long length() const
Definition: Bstring.cpp:263
project
Bproject * project
Definition: bshow.cpp:31
Bimage::mask_fspace_resize
Vector3< double > mask_fspace_resize(Vector3< long > nusize)
Resizes a reciprocal space mask.
Definition: Bimage_mask.cpp:683
Quaternion
Definition: Quaternion.h:25
particle_count
long particle_count(Bparticle *part)
Counts the number of particles in a linked list.
Definition: mg_processing.cpp:1151
Matrix.h
Generalized matrix class.
kill_symmetry
int kill_symmetry(Bsymmetry *sym)
Deallocates a symmetry structure.
Definition: symmetry.cpp:207
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
sphere
int sphere(Bimage *p)
Definition: radon_util.cpp:114
Bimage::multiply
void multiply(long j, Complex< double > cv)
Definition: Bimage.h:312
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
Breconstruction::box_size
Vector3< long > box_size
Definition: mg_processing.h:296
read_img
Bimage * read_img(char *filename, int readdata, int img_select)
General driver function to read multiple image formats.
Definition: rwimg.cpp:76
locations_fit_sphere
Sphere locations_fit_sphere(Bparticle *part, int N, double Nstop)
Least squares fit a sphere to 3D data (particle locations)
Definition: mg_subtomo.cpp:906
project_show_selected
long project_show_selected(Bproject *project)
Shows the selected particles in a project.
Definition: mg_processing.cpp:2446
main
int main(int argc, char **argv)
Definition: jsubtomo.cpp:122
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
timer.h
Utilities for timing functions.
Float
Definition: utilities.h:157
M_PI_4
#define M_PI_4
Definition: utilities.h:65
int_float::f
float f
Definition: qsort_functions.h:12
Bimage
General image parameter class.
Definition: Bimage.h:163
Boption::size
Vector3< long > size()
Definition: options.h:163
Micrograph
Definition: file_util.h:23
Bparticle::sel
long sel
Definition: mg_processing.h:103
Bimage::transform
int transform(Vector3< double > scale, Vector3< double > origin, Vector3< double > translate, Matrix3 mat, int fill_type=0, double fill=0)
Transforms an image by translation, rotation, scaling and skewing, in place.
Definition: Bimage_transform.cpp:37
M_PI
#define M_PI
Definition: utilities.h:59
linked_list.h
Header file for generalized linked list functions.
part_fom_order
int_float * part_fom_order(Bparticle *partlist, long &npart, int fom_index)
Definition: mg_particle_select.cpp:89
Boption
A class for a command line input option.
Definition: options.h:26
Bimage::label
void label(string s)
Definition: Bimage.h:235
Vector3::angle
double angle(Vector3< T2 > &v)
Definition: Vector3.h:257
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
length
double length(vector< T > v)
Definition: Vector3.h:528
init_point_group_symmetry
Bsymmetry * init_point_group_symmetry(Bstring symmetry_string)
Sets up a symmetry structure from a string identifier.
Definition: symmetry.cpp:39
Boption::symmetry
Bsymmetry * symmetry()
Definition: options.h:252
mg_extract.h
Header file for functions to extract particles from micrographs.
write_img
int write_img(const char *filename, Bimage *p, int compression)
General driver function to write multiple image formats.
Definition: rwimg.cpp:280
int_float
Definition: qsort_functions.h:12
Breconstruction::symmetry
Bstring symmetry
Definition: mg_processing.h:286
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
reconstruction_refine_subtomo
long reconstruction_refine_subtomo(Breconstruction *rec, Bimage *p, Bimage *ptemp, Bimage *pmask, Bimage *pmask2, double alpha_step, double theta_step, double phi_step, double alpha_limit, double thetaphi_limit, double hires, double lores, double shiftlimit, double shiftlimitz, double shiftlimitxy, double mindist, Vector3< long > bin, Bsymmetry *sym, int iters, int refinepeaks, Bstring ccmax_file)
Refines the view vectors for particles already in the project.
Definition: mg_subtomo.cpp:333
file_util.h
Header file for file checking functions.
View::normalize
double normalize()
Definition: View.h:106
Bparticle::fpart
Bstring fpart
Definition: mg_processing.h:91
Bparticle::ori
Vector3< double > ori
Definition: mg_processing.h:100
Bsymmetry
Definition: symmetry.h:38
Boption::datatype
DataType datatype()
Definition: options.h:93
project_create
Bproject * project_create(int nmg, int nrec)
Creates a micrograph processing project parameter structure.
Definition: mg_processing.cpp:47
Boption::next
Boption * next
Definition: options.h:28
Bparticle
Definition: mg_processing.h:89
Bstring
Definition: Bstring.h:29
reconstruction_search_subtomo
long reconstruction_search_subtomo(Breconstruction *rec, Bimage *p, Bimage *ptemp, Bimage *pmask, Bimage *pmask2, double alpha_step, double theta_step, double phi_step, double alpha_limit, double thetaphi_limit, double hires, double lores, double shiftlimit, double mindist, double threshold, int maxhits, Vector3< long > bin, Bsymmetry *sym, int refinepeaks, Bstring ccmax_file)
Definition: mg_subtomo.cpp:140
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
project_kill
int project_kill(Bproject *project)
Frees a whole project.
Definition: mg_processing.cpp:1224
View::matrix
Matrix3 matrix()
Definition: View.h:150
Matrix3::transpose
Matrix3 transpose() const
Definition: Matrix3.h:268
Vector3< double >
Bparticle::loc
Vector3< double > loc
Definition: mg_processing.h:99
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
Bstring::lower
Bstring lower()
Definition: Bstring.cpp:308
View
Definition: View.h:26
use
const char * use[]
Definition: jsubtomo.cpp:42
option_kill
int option_kill(Boption *option)
Deallocates a linked list of option structures.
Definition: options.cpp:109
verbose
int verbose
Bstring::integer
long integer()
Definition: Bstring.cpp:539
mg_processing.h
Header file for micrograph processing.
Breconstruction::frec
Bstring frec
Definition: mg_processing.h:287
Breconstruction::voxel_size
double voxel_size
Definition: mg_processing.h:292
Unknown_Type
Definition: utilities.h:147
rwimg.h
Header file for 2D and 3D image I/O.
options.h
Header file for option handlers.
Bstring::pre_rev
Bstring pre_rev(char c)
Definition: Bstring.cpp:413
Vector3::volume
double volume()
Definition: Vector3.h:235
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
Bparticle::next
Bparticle * next
Definition: mg_processing.h:90
Sphere
Definition: mg_subtomo.h:20
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
Breconstruction::next
Breconstruction * next
Definition: mg_processing.h:281
mg_subtomo.h
Header file for functions finding particles (subtomograms) in a tomogram.
timer_start
double timer_start()
Starts timer and prints the time.
Definition: timer.cpp:52
Bproject
Definition: mg_processing.h:333
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Breconstruction::id
Bstring id
Definition: mg_processing.h:282
string_kill
int string_kill(Bstring *list)
Kills a string linked list.
Definition: Bstring.cpp:760