| Bsoft 2.0.5 Bernard's software package

bmatch.cpp
Go to the documentation of this file.
1
11 #include "rwimg.h"
12 #include "rwmodel.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 Bmodel* img_match(Bimage* p, Bimage* pref, double res_hi, double res_lo,
21 double angle_inc, double threshold, long exclusion, double mask_rad);
22 Bmodel* img_match_one(Bimage* p, long img_num, Bimage* pref, double res_hi, double res_lo,
23 double angle_inc, double threshold, long exclusion, double mask_rad, fft_plan planf, fft_plan planb);
24
25 /* Usage assistance */
26 const char* use[] = {
27 " ",
28 "Usage: bmatch [options] img.mrc cc.map",
29 "--------------------------------------",
30 "Searching an image with a set of 2D templates/references",
31 "Orientations are taken from the input projections.",
32 " ",
33 //"Actions:",
34 //"-variance Calculate shell variances of input projections.",
35 " ",
36 "Parameters:",
37 "-verbose 7 Verbosity of output.",
38 "-datatype u Force writing of a new data type.",
39 "-sampling 2,3.5,1 Sampling before rescaling (angstrom/voxel, a single value sets all three).",
40 "-resolution 25,200 Resolution limits (angstrom).",
41 "-angle 2.5 Angular increment (default 3 degrees).",
42 "-origin 0.8,-10,15.7 Set the origin (default from input image).",
43 "-threshold 0.24 Threshold to find correlation peaks.",
44 "-exclusion 150 Minimum distance between correlation peaks.",
45 "-radius 50 Mask radius (slightly bigger than particle).",
46 " ",
47 "Input:",
48 "-reference file.pif Input reference projections file.",
49 " ",
50 "Output:",
51 "-output newmod.star New model file.",
52 " ",
53 NULL
54 };
55
56 int main(int argc, char **argv)
57 {
58 // Initialize variables
59 DataType nudatatype(Unknown_Type); // Conversion to new type
60
61 Vector3<double> origin; // Origin
62 int set_origin(0); // Flag for setting the origin
63 Vector3<double> sampling; // Sampling before rescaling
64 double res_hi(0); // High resolution limit
65 double res_lo(0); // Low resolution limit
66 double angle_inc(M_PI/60); // Angular increment
67 double threshold(0.1); // Threshold for peak detection
68 long exclusion(10); // Peak detection exclusion size
69 double mask_rad(70); // Particle masking radius
70 Bstring ref_filename; // Input projections file name
71 Bstring outfile; // Output parameter file name
72
73 int optind;
74 Boption* option = get_option_list(use, argc, argv, optind);
75 Boption* curropt;
76 for ( curropt = option; curropt; curropt = curropt->next ) {
77 if ( curropt->tag == "datatype" )
78 nudatatype = curropt->datatype();
79 if ( curropt->tag == "origin" ) {
80 if ( curropt->value[0] == 'c' ) {
81 set_origin = 2;
82 } else {
83 origin = curropt->origin();
84 set_origin = 1;
85 }
86 }
87 if ( curropt->tag == "resolution" )
88 if ( curropt->values(res_hi, res_lo) < 1 )
89 cerr << "-resolution: A resolution limit must be specified!" << endl;
90 if ( curropt->tag == "angle" )
91 if ( ( angle_inc = curropt->value.real() ) < 0.1 )
92 cerr << "-angle: An angle must be specified!" << endl;
93 if ( curropt->tag == "sampling" )
94 sampling = curropt->sampling();
95 if ( curropt->tag == "threshold" )
96 if ( ( threshold = curropt->value.real() ) < 0.001 )
97 cerr << "-threshold: A resolution limit must be specified!" << endl;
98 if ( curropt->tag == "exclusion" )
99 if ( ( exclusion = curropt->value.integer() ) < 2 )
100 cerr << "-exclusion: A minimum distance between peaks must be specified!" << endl;
101 if ( curropt->tag == "radius" )
102 if ( ( mask_rad = curropt->value.real() ) < 0.001 )
103 cerr << "-radius: A mask radius in pixels must be specified!" << endl;
104 if ( curropt->tag == "reference" )
105 ref_filename = curropt->filename();
106 if ( curropt->tag == "output" )
107 outfile = curropt->filename();
108 }
109 option_kill(option);
110
111 double ti = timer_start();
112
113 Bimage* p = NULL;
114 Bimage* pref = NULL;
115
116 if ( ( p = read_img(argv[optind++], 1, -1) ) == NULL ) {
117 cerr << "Error: File not read!" << endl;
118 bexit(-1);
119 }
120
121 if ( set_origin ) {
122 if ( set_origin == 2 ) p->origin(p->size()/2);
123 else p->origin(origin);
124 }
125
126 if ( ref_filename.length() ) {
127 if ( ( pref = read_img(ref_filename, 1, -1) ) == NULL ) {
128 cerr << "Error: File not read!" << endl;
129 bexit(-1);
130 }
131 }
132
133 if ( set_origin ) {
134 if ( set_origin == 2 ) pref->origin(p->size()/2);
135 else pref->origin(origin);
136 }
137
138 if ( nudatatype == Unknown_Type )
139 nudatatype = p->data_type();
140
141 if ( sampling.volume() > 0 ) {
142 p->sampling(sampling);
143 if ( pref ) pref->sampling(sampling);
144 }
145
146 Bmodel* model = NULL;
147 if ( pref )
148 model = img_match(p, pref, res_hi, res_lo, angle_inc, threshold, exclusion, mask_rad);
149
150 // Write an output parameter format file if a name is given
151 if ( outfile.length() && model ) {
152 model_update_comment(model, argc, argv);
153 write_model(outfile, model);
154 }
155
156 model_kill(model);
157
158 delete p;
159 delete pref;
160
161 if ( verbose & VERB_TIME )
162 timer_report(ti);
163
164 return 0;
165 }
166
167 Bmodel* img_match(Bimage* p, Bimage* pref, double res_hi, double res_lo,
168 double angle_inc, double threshold, long exclusion, double mask_rad)
169 {
170 Bmodel* modlist = NULL;
171 Bmodel* model;
172
173 fft_plan planf = fft_setup_plan(p->size(), FFTW_FORWARD, 1);
174 fft_plan planb = fft_setup_plan(p->size(), FFTW_BACKWARD, 1);
175
176 for ( long n = 0; n < p->images(); ++n ) {
177 model = img_match_one(p, n, pref, res_hi, res_lo,
178 angle_inc, threshold, exclusion, mask_rad, planf, planb);
179 model_add(&modlist, model);
180 }
181
182 fft_destroy_plan(planf);
183 fft_destroy_plan(planb);
184
185 return modlist;
186 }
187
188 Bimage* img_reference_prepare(Bimage* pref, long nn, Vector3<long> size)
189 {
190 Bimage* pref1 = pref->extract(nn);
191
192 if ( pref1->size() != size ) {
193 pref1->calculate_background();
194 pref1->pad(size, FILL_BACKGROUND);
195 }
196
197 // write_img("t.pif", pref1, 0);
198
199 return pref1;
200 }
201
202
203 /*
204 */
205 Bmodel* img_match_one(Bimage* p, long img_num, Bimage* pref, double res_hi, double res_lo,
206 double angle_inc, double threshold, long exclusion, double mask_rad, fft_plan planf, fft_plan planb)
207 {
208 if ( angle_inc < M_PI/180 ) angle_inc = M_PI/180;
209
210 long i, j, k, nn;
211 double angle, amin(0), amax(TWOPI), ccmax(0), ccmax1;
212 Vector3<long> coor, rect(2*mask_rad, 2*mask_rad, 1);
213 Vector3<double> start, nucoor;
214 View view;
215
216 Bstring id(img_num, "%d");
217 Bmodel* model = model_init(id);
218 Bcomponent* comp = NULL;
219 Bcomptype* ct = NULL;
220
221 model->fmap = p->file_name();
222 model->img_num = img_num;
223
224 Bimage* p1 = p->extract(img_num);
225
226 p1->calculate_background();
227
228 Bimage* pcc = new Bimage(Float, TSimple, p1->size(), 1);
229 Bimage* pang = pcc->copy();
230 Bimage* pnn = new Bimage(Integer, TSimple, p1->size(), 1);
231 pnn->fill(-1);
232
233 if ( verbose ) {
234 cout << "Global search for image " << img_num << ":" << endl;
235 cout << "Proj\tvx\tvy\tvz\tva\tccmax" << setprecision(4) << endl;
236 }
237 for ( nn=0; nn<pref->images(); ++nn ) {
238 id = Bstring(nn+1, "%d");
239 model_add_type_by_id(model, id);
240 Bimage* pref1 = img_reference_prepare(pref, nn, p1->size());
241 ccmax1 = 0;
242 for ( angle = amin; angle <= amax; angle += angle_inc ) {
243 Bimage* prot = pref1->rotate(pref1->size(), angle);
244 Bimage* pcc1 = p1->cross_correlate(prot, res_hi, res_lo, planf, planb);
245 if ( !pcc1 ) bexit(-1);
246 for ( j=0; j<pcc1->image_size(); ++j ) if ( (*pcc)[j] < (*pcc1)[j] ) {
247 pcc->set(j, (*pcc1)[j]);
248 pang->set(j, angle);
249 pnn->set(j, nn);
250 }
251 if ( ccmax1 < pcc1->maximum() ) ccmax1 = pcc1->maximum();
252 delete pcc1;
253 delete prot;
254 }
255 if ( verbose )
256 cout << nn << tab << pref->image[nn].view() << tab << ccmax1 << endl;
257 if ( ccmax < ccmax1 ) ccmax = ccmax1;
258 delete pref1;
259 }
260 if ( verbose )
261 cout << endl;
262
263 if ( threshold >= ccmax ) {
264 threshold = 0.95*ccmax;
265 if ( verbose )
266 cout << "Adjusting threshold to " << threshold << endl;
267 }
268
269 Bimage* ppeak = pcc->region_peaks(exclusion, threshold, 0, 1);
270 write_img("cc.pif", pcc, 0);
271 write_img("nn.pif", pnn, 0);
272
273 pcc->clear();
274
275 for ( i=j=0; i<ppeak->image_size(); ++i ) if ( (*ppeak)[i] ) j++;
276
277 if ( verbose )
278 cout << "Number of peaks: " << j << endl << endl;
279
280 threshold *= p1->sizeX()*1.0/pref->sizeX();
281
282 if ( verbose ) {
283 cout << "Adjusting threshold to " << threshold << endl;
284 cout << "Local search for image " << img_num << ":" << endl;
285 cout << "x\ty\tz\tvx\tvy\tvz\tva\tccmax" << setprecision(4) << endl;
286 }
287 rect = Vector3<long>(2*mask_rad, 2*mask_rad, 1);
288 angle_inc /= 10;
289 for ( i=j=0; i<ppeak->image_size(); ++i ) if ( (*ppeak)[i] ) {
290 nn = (*pnn)[i];
291 for ( k=0, ct = model->type; k<nn; ++k ) ct = ct->next;
292 Bimage* pref1 = pref->extract(nn);
293 pref1->calculate_background();
294 coor = vector3_set_PBC(pref1->image->origin() + ppeak->coordinates(i), p->size());
295 start[0] = coor[0] - mask_rad;
296 start[1] = coor[1] - mask_rad;
297 Bimage* pe = p1->copy();
298 pe->calculate_background();
299 pe->origin(pref1->image->origin());
300 pe->edge(0, 1, rect, start, 5, FILL_BACKGROUND);
301 // Bstring fn(j+1, "t%d.pif");
302 // write_img(fn, pe, 0);
303 ccmax1 = 0;
304 amin = (*pang)[i] - 10*angle_inc;
305 amax = (*pang)[i] + 10*angle_inc;
306 coor = vector3_set_PBC(ppeak->coordinates(i), p->size());
307 nucoor = coor;
308 for ( angle = amin; angle <= amax; angle += angle_inc ) {
309 Bimage* prot = pref1->rotate(pref1->size(), angle);
310 Bimage* pcc1 = pe->cross_correlate(prot, res_hi, res_lo);
311 if ( !pcc1 ) bexit(-1);
312 pcc1->origin(coor);
313 pcc1->find_peak(5);
314 if ( (*pcc)[i] < pcc1->image->FOM() ) {
315 pcc->set(i, pcc1->image->FOM());
316 pang->set(i, angle);
317 nucoor = pcc1->image->origin();
318 }
319 if ( ccmax1 < pcc1->image->FOM() ) ccmax1 = pcc1->image->FOM();
320 delete pcc1;
321 delete prot;
322 }
323 delete pe;
324 delete pref1;
325 view = pref->image[nn].view();
326 view.angle(view.angle() - (*pang)[i]);
327 if ( p->sizeX() > 1 && nucoor[0] >= p->sizeX()/2 ) nucoor[0] -= p->sizeX();
328 if ( p->sizeY() > 1 && nucoor[1] >= p->sizeY()/2 ) nucoor[1] -= p->sizeY();
329 if ( p->sizeZ() > 1 && nucoor[2] >= p->sizeZ()/2 ) nucoor[2] -= p->sizeZ();
330 if ( verbose )
331 cout << nucoor << tab << view << tab << ccmax1 << endl;
332 if ( ccmax1 >= threshold ) {
333 comp = component_add(&model->comp, ++j);
334 comp->type = ct;
335 comp->loc = nucoor*p->sampling();
336 comp->view = view.backward();
337 comp->fom = ccmax1;
338 comp->radius = 10*p->sampling()[0];
339 }
340 }
341 if ( verbose )
342 cout << "Number of peaks: " << j << endl << endl;
343
344 delete ppeak;
345 delete pcc;
346 delete pang;
347 delete pnn;
348 delete p1;
349
350 return model;
351 }
352
353
Bmodel::img_num
int img_num
Definition: rwmodel.h:127
Bstring::real
double real()
Definition: Bstring.cpp:545
Bcomponent::type
Bcomptype * type
Definition: rwmodel.h:54
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:143
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
planb
fft_plan planb
Definition: bico.cpp:24
vector3_set_PBC
Vector3< T1 > vector3_set_PBC(Vector3< T1 > coord, Vector3< T2 > box)
Definition: Vector3.h:682
Bimage::image_size
long image_size()
Definition: Bimage.h:267
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
planf
fft_plan planf
Definition: bico.cpp:24
Integer
Definition: utilities.h:154
Bimage::edge
int edge(int type, Vector3< long > rect, Vector3< double > start, double width, int fill_type=0, double fill=0)
Smooths the image edge with a soft rectangular function.
Definition: Bimage_edit.cpp:319
Bstring::length
long length() const
Definition: Bstring.cpp:263
component_add
Bcomponent * component_add(Bcomponent **comp, Bstring &id)
Adds a component to a linked list.
Definition: rwmodel.cpp:267
verbose
int verbose
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
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
Boption::filename
Bstring filename()
Definition: options.h:85
TSimple
Definition: Bimage.h:58
timer.h
Utilities for timing functions.
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
M_PI
#define M_PI
Definition: utilities.h:59
model_kill
int model_kill(Bmodel *model)
Deallocates all memory in the list.
Definition: rwmodel.cpp:1124
Bimage::extract
Bimage * extract(long nn)
Extracts one sub-image into new image structure.
Definition: Bimage_extract.cpp:21
model_init
Bmodel * model_init(Bstring &id)
Initializes a model structure.
Definition: rwmodel.cpp:144
Bimage::maximum
double maximum()
Definition: Bimage.h:535
Bcomponent::view
View view
Definition: rwmodel.h:59
img_reference_prepare
Bimage * img_reference_prepare(Bimage *pref, long nn, Vector3< long > size)
Definition: bmatch.cpp:188
Bcomponent::fom
float fom
Definition: rwmodel.h:65
Bimage::cross_correlate
Bimage * cross_correlate(Bimage *p, double hires, double lores, fft_plan planf, fft_plan planb)
Calculates a cross-correlation map by Fast Fourier transformation.
Definition: Bimage_correlate.cpp:363
Boption
A class for a command line input option.
Definition: options.h:26
Bmodel::type
Bcomptype * type
Definition: rwmodel.h:131
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
fft_plan
fftwf_plan fft_plan
Definition: fft.h:16
model_update_comment
int model_update_comment(Bmodel *model, int n, char **strings)
Puts a set of strings and time in the comment of a model.
Definition: rwmodel.cpp:1158
Bsub_image::FOM
double FOM()
Definition: Bimage.h:151
Bimage::find_peak
int find_peak(double radius=1e30, double sigma=0)
Finds the peak in an image to the nearest voxel.
Definition: Bimage_correlate.cpp:1338
View::backward
View backward()
Definition: View.h:115
write_img
int write_img(const char *filename, Bimage *p, int compression)
General driver function to write multiple image formats.
Definition: rwimg.cpp:280
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::calculate_background
int calculate_background(long nn, int flag)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:27
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
model_add_type_by_id
Bcomptype * model_add_type_by_id(Bmodel *model, Bstring &id)
Add a type to a model if the identifier does not exist already.
Definition: rwmodel.cpp:411
Bcomponent::radius
float radius
Definition: rwmodel.h:62
model
Bmodel * model
Definition: bshow.cpp:32
write_model
int write_model(Bstring &filename, Bmodel *model)
Writes model parameters.
Definition: rwmodel.cpp:91
Boption::datatype
DataType datatype()
Definition: options.h:93
Boption::next
Boption * next
Definition: options.h:28
Bstring
Definition: Bstring.h:29
Bimage::pad
int pad(long sz, int fill_type=0, double fill=0)
Pads an image to a new size with a given fill value.
Definition: Bimage_resize.cpp:351
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
Bimage::clear
void clear()
Definition: Bimage.h:697
Bmodel::fmap
Bstring fmap
Definition: rwmodel.h:125
model_add
Bmodel * model_add(Bmodel **model, Bstring &id)
Adds a model to a linked list.
Definition: rwmodel.cpp:178
rwmodel.h
Header file for reading and writing atomic model files.
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< double >
fft_destroy_plan
int fft_destroy_plan(fft_plan plan)
Deallocates a plan for fast Fourier transforms.
Definition: fft.cpp:87
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
View::angle
double angle()
Definition: View.h:95
View
Definition: View.h:26
Bimage::rotate
int rotate()
Rotates an image using parameters defined in the image in place.
Definition: Bimage_transform.cpp:253
fft_setup_plan
fft_plan fft_setup_plan(long x, long y, long z, fft_direction dir, int opt)
Sets up a plan for fast Fourier transforms.
Definition: fft.cpp:31
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
Bmodel
Definition: rwmodel.h:119
use
const char * use[]
Definition: bmatch.cpp:26
Unknown_Type
Definition: utilities.h:147
img_match
Bmodel * img_match(Bimage *p, Bimage *pref, double res_hi, double res_lo, double angle_inc, double threshold, long exclusion, double mask_rad)
Definition: bmatch.cpp:167
rwimg.h
Header file for 2D and 3D image I/O.
options.h
Header file for option handlers.
Bcomptype
Definition: rwmodel.h:25
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::coordinates
void coordinates(long i, long &nx, long &ny, long &nz)
Definition: Bimage.h:416
Bmodel::comp
Bcomponent * comp
Definition: rwmodel.h:132
Bimage::fill
void fill(double v)
Definition: Bimage.h:698
main
int main(int argc, char **argv)
Definition: bmatch.cpp:56
Bimage::region_peaks
Bimage * region_peaks(long kernel_size, double threshold, int flood=0, int wrap=0)
Generates a segmented image from peaks above a threshold value.
Definition: Bimage_segment.cpp:470
Vector3::volume
double volume()
Definition: Vector3.h:235
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bcomponent::loc
Vector3< float > loc
Definition: rwmodel.h:58
img_match_one
Bmodel * img_match_one(Bimage *p, long img_num, Bimage *pref, double res_hi, double res_lo, double angle_inc, double threshold, long exclusion, double mask_rad, fft_plan planf, fft_plan planb)
Definition: bmatch.cpp:205
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
TWOPI
#define TWOPI
Definition: utilities.h:68
timer_start
double timer_start()
Starts timer and prints the time.
Definition: timer.cpp:52
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bcomptype::next
Bcomptype * next
Definition: rwmodel.h:26
Bcomponent
Definition: rwmodel.h:51