| Bsoft 2.0.5 Bernard's software package

model_mask.cpp
Go to the documentation of this file.
1
9 #include "rwmodel.h"
10 #include "model_mask.h"
11 #include "model_shell.h"
12 #include "model_util.h"
13 #include "matrix_linear.h"
14 #include "Vector3.h"
15 #include "utilities.h"
16
17 // Declaration of global variables
18 extern int verbose; // Level of output to the screen
19
20
34 Bimage* model_create_mask(Bmodel* model, Vector3<long> size,
35 Vector3<double> ori, Vector3<double> sam, double edge)
36 {
37 if ( sam[0] <= 0) sam = sam.max(1);
38
39 long i, nv;
40 double width = edge/sam[0];
41 Vector3<double> loc, start, end;
42 Bcomponent* comp;
43 Blink* link;
44
45 Bimage* p = new Bimage(Float, TSimple, size, 1);
46 if ( ori[0] == 0 && ori[1] == 0 && ori[2] == 0 )
47 p->origin(p->default_origin());
48 else
49 p->origin(ori);
50 ori = p->image->origin();
51 p->sampling(sam);
52
53 long datasize = p->data_size();
54
55 if ( verbose ) {
56 cout << "Generating a model mask:" << endl;
57 cout << "Size: " << p->size() << endl;
58 cout << "Origin: " << p->image->origin() << endl;
59 cout << "Sampling: " << p->sampling() << " A/voxel" << endl;
60 }
61
62 for ( comp = model->comp; comp; comp = comp->next ) {
63 loc[0] = (long) (comp->loc[0]/p->sampling()[0] + p->image->origin()[0] + 0.5);
64 loc[1] = (long) (comp->loc[1]/p->sampling()[1] + p->image->origin()[1] + 0.5);
65 loc[2] = (long) (comp->loc[2]/p->sampling()[2] + p->image->origin()[2] + 0.5);
66 p->sphere(loc, comp->radius/p->sampling()[0], width, FILL_USER, 1);
67 }
68
69 for ( link = model->link; link; link = link->next ) {
70 start[0] = (long) (link->comp[0]->loc[0]/p->sampling()[0] + p->image->origin()[0] + 0.5);
71 start[1] = (long) (link->comp[0]->loc[1]/p->sampling()[1] + p->image->origin()[1] + 0.5);
72 start[2] = (long) (link->comp[0]->loc[2]/p->sampling()[2] + p->image->origin()[2] + 0.5);
73 end[0] = (long) (link->comp[1]->loc[0]/p->sampling()[0] + p->image->origin()[0] + 0.5);
74 end[1] = (long) (link->comp[1]->loc[1]/p->sampling()[1] + p->image->origin()[1] + 0.5);
75 end[2] = (long) (link->comp[1]->loc[2]/p->sampling()[2] + p->image->origin()[2] + 0.5);
76 p->bar(start, end, 2*link->radius/p->sampling()[0], width, FILL_USER, 1);
77 }
78
79 // Calculate the mask volume
80 for ( i=nv=0; i<datasize; i++ ) if ( (*p)[i] > 0.5 ) nv++;
81
82 if ( verbose )
83 cout << "Mask volume: " << nv * sam.volume() << " A3" << endl << endl;
84
85 return p;
86 }
87
103 Bimage* model_create_hull_mask(Bmodel* model, Vector3<long> size,
104 Vector3<double> ori, Vector3<double> sam, int curv_flag, int fast)
105 {
106 if ( sam[0] <= 0) sam = sam.max(1);
107
108 long i, nv, x, y, z;
109 double d, min = 1e30, max = 0;
110 Vector3<double> vec;
111 Bcomponent* comp;
112
113 Bimage* p = new Bimage(Float, TSimple, size, 1);
114 if ( ori[0] == 0 && ori[1] == 0 && ori[2] == 0 )
115 p->origin(p->default_origin());
116 else
117 p->origin(ori);
118 ori = p->image->origin();
119 p->sampling(sam);
120
121 if ( verbose ) {
122 cout << "Generating a hull mask:" << endl;
123 cout << "Size: " << p->size() << endl;
124 cout << "Origin: " << p->image->origin() << endl;
125 cout << "Sampling: " << p->sampling() << " A/voxel" << endl;
126 cout << "Surface: ";
127 if ( curv_flag ) cout << "Curved" << endl;
128 else cout << "Planar" << endl;
129 }
130
131 // Calculate the center of the vertices
132 Vector3<double> center = model_center_of_mass(model);
133 center /= sam;
134
135 // cout << "center=" << center << endl;
136
137 // Calculate the minimum and maximum distances from the center
138 for ( comp = model->comp; comp; comp = comp->next ) {
139 comp->vec = (comp->loc/p->sampling()) - center;
140 d = comp->vec.length();
141 if ( min > d ) min = d;
142 if ( max < d ) max = d;
143 }
144
145 if ( curv_flag < 1 ) min = 0;
146
147 center += ori;
148
149 // cout << "center=" << center << endl;
150
151 // Calculate the mask
152 for ( i=z=nv=0; z<p->sizeZ(); z++ ) {
153 if ( verbose & VERB_FULL )
154 cout << "Calculating slice " << z << endl;
155 vec[2] = z - center[2];
156 for ( y=0; y<p->sizeY(); y++ ) {
157 vec[1] = y - center[1];
158 for ( x=0; x<p->sizeX(); x++, i++ ) {
159 vec[0] = x - center[0];
160 d = vec.length();
161 if ( d < min ) p->set(i,1);
162 else if ( d > max ) p->set(i,0);
163 else if ( model_inside_outside(vec, model, curv_flag, fast) > 0 ) p->set(i,1);
164 if ( (*p)[i] ) nv++;
165 }
166 }
167 }
168
169 if ( verbose )
170 cout << "Mask volume: " << nv * sam.volume() << " A3" << endl << endl;
171
172 return p;
173 }
174
191 Bimage* model_create_shell_mask(Bmodel* model, Vector3<long> size,
192 Vector3<double> ori, Vector3<double> sam, double shell_width, int curv_flag, int fast)
193 {
194 if ( sam[0] <= 0) sam = sam.max(1);
195
196 long i, x, y, z, nv=0, ni=0, no=0;
197 double d, min = 1e30, max = 0, half_width = shell_width/(2*sam[0]);
198 if ( half_width < 0.5 ) half_width = 0.5;
199 shell_width = 2*sam[0]*half_width;
200
201 Vector3<double> vec;
202 Bcomponent* comp;
203
204 Bimage* p = new Bimage(Float, TSimple, size, 1);
205 if ( ori[0] == 0 && ori[1] == 0 && ori[2] == 0 )
206 p->origin(p->default_origin());
207 else
208 p->origin(ori);
209 ori = p->image->origin();
210 p->sampling(sam);
211
212 if ( verbose ) {
213 cout << "Generating a shell mask:" << endl;
214 cout << "Size: " << p->size() << endl;
215 cout << "Origin: " << p->image->origin() << endl;
216 cout << "Sampling: " << p->sampling() << " A/voxel" << endl;
217 cout << "Shell width: " << shell_width << " A" << endl;
218 if ( curv_flag ) cout << "Curved" << endl;
219 else cout << "Planar" << endl;
220 }
221
222 // Calculate the center of the vertices
223 Vector3<double> center = model_center_of_mass(model);
224 center /= sam;
225
226 // Calculate the minimum and maximum distances from the center
227 for ( comp = model->comp; comp; comp = comp->next ) {
228 comp->vec = (comp->loc/p->sampling()) - center;
229 d = comp->vec.length();
230 if ( min > d ) min = d;
231 if ( max < d ) max = d;
232 }
233
234 min -= half_width;
235 max += half_width;
236
237 if ( curv_flag < 1 ) min = 0;
238
239 center += ori;
240
241 // Calculate the mask
242 for ( i=z=0; z<p->sizeZ(); z++ ) {
243 if ( verbose & VERB_FULL )
244 cout << "Calculating slice " << z << endl;
245 vec[2] = z - center[2];
246 for ( y=0; y<p->sizeY(); y++ ) {
247 vec[1] = y - center[1];
248 for ( x=0; x<p->sizeX(); x++, i++ ) {
249 vec[0] = x - center[0];
250 d = vec.length();
251 // data[i] = 0;
252 if ( d < min ) ni++;
253 else if ( d > max ) no++;
254 else {
255 d = model_inside_outside(vec, model, curv_flag, fast);
256 if ( fabs(d) <= half_width ) p->set(i,1);
257 else if ( d > 0 ) ni++;
258 else no++;
259 }
260 if ( (*p)[i] ) nv++;
261 }
262 }
263 }
264
265 if ( verbose ) {
266 cout << "Mask volume: " << nv * sam.volume() << " A3" << endl;
267 cout << "Inner volume: " << ni * sam.volume() << " A3" << endl;
268 cout << "Outer volume: " << no * sam.volume() << " A3" << endl << endl;
269 }
270
271 return p;
272 }
273
285 Bimage* model_create_level_mask(Bmodel* model, Vector3<long> size,
286 Vector3<double> ori, Vector3<double> sam)
287 {
288 if ( sam[0] <= 0) sam = sam.max(1);
289
290 Vector3<double> loc;
291 Bmodel* mp;
292 Bcomponent* comp;
293
294 Bimage* p = new Bimage(Integer, TSimple, size, 1);
295 if ( ori[0] == 0 && ori[1] == 0 && ori[2] == 0 )
296 p->origin(p->default_origin());
297 else
298 p->origin(ori);
299 ori = p->image->origin();
300 p->sampling(sam);
301
302 if ( verbose ) {
303 cout << "Generating a level mask:" << endl;
304 cout << "Size: " << p->size() << endl;
305 cout << "Origin: " << p->image->origin() << endl;
306 cout << "Sampling: " << p->sampling() << " A/voxel" << endl;
307 }
308
309 int level;
310
311 // Calculate the levels
312 for ( level=1, mp = model; mp; mp = mp->next, level++ ) {
313 for ( comp = mp->comp; comp; comp = comp->next ) {
314 loc[0] = (long) (comp->loc[0]/p->sampling()[0] + p->image->origin()[0] + 0.5);
315 loc[1] = (long) (comp->loc[1]/p->sampling()[1] + p->image->origin()[1] + 0.5);
316 loc[2] = (long) (comp->loc[2]/p->sampling()[2] + p->image->origin()[2] + 0.5);
317 p->sphere(loc, comp->radius/p->sampling()[0], 0, FILL_USER, level);
318 }
319 }
320
321 return p;
322 }
323
334 Bimage* img_extract_segments_using_model(Bimage* p, Bmodel* model, int multi_level)
335 {
336 if ( !p || !model ) return NULL;
337 if ( !p->data_pointer() ) return NULL;
338 if ( !model->comp ) return NULL;
339
340 Bmodel* mp;
341 Bcomponent* comp;
342 int ncomp = model_component_count(model);
343
344 long i, j, k, x, y, z, n;
345
346 if ( verbose ) {
347 cout << "Extracting segments from a multi-level mask:" << endl;
348 cout << "Model: " << model->id << endl;
349 cout << "Number of components: " << ncomp << endl;
350 if ( multi_level ) cout << "Multi-level" << endl;
351 else cout << "Single level" << endl;
352 cout << endl;
353 }
354
355 Bimage* pseg = new Bimage(Integer, TSimple, p->sizeX(), p->sizeY(), p->sizeZ(), p->images());
356 pseg->sampling(p->sampling());
357 for ( i=0; i<p->images(); i++ ) pseg->image[i] = p->image[i];
358
359 int level;
360 long max = (long) (p->maximum()+1);
361 long datasize = p->data_size();
362 int* lut = new int[max];
363 for ( i=0; i<max; i++ ) lut[i] = 0;
364
365 for ( k=1, mp = model; mp; mp = mp->next ) {
366 for ( comp = model->comp; comp; comp = comp->next, k++ ) {
367 n = mp->img_num;
368 x = (long) (comp->loc[0]/p->sampling()[0] + p->image[n].origin()[0] + 0.5);
369 y = (long) (comp->loc[1]/p->sampling()[1] + p->image[n].origin()[1] + 0.5);
370 z = (long) (comp->loc[2]/p->sampling()[2] + p->image[n].origin()[2] + 0.5);
371 if ( x < p->sizeX() && y < p->sizeY() && z < p->sizeZ() ) {
372 i = p->index(0, x, y, z, n);
373 level = (int) ((*p)[i] + 0.5);
374 if ( level > 0 ) lut[level] = k;
375 if ( verbose & VERB_DEBUG )
376 cout << "DEBUG img_extract_segments_using_model: " << x << tab << y << tab << z << tab << n << tab << level << endl;
377 }
378 }
379 }
380
381 for ( i=j=0; i<datasize; i++ ) {
382 level = (int) ((*p)[i] + 0.5);
383 if ( level > 0 && lut[level] ) {
384 if ( multi_level ) pseg->set(i, lut[level]);
385 else pseg->set(i, 1);
386 }
387 }
388
389 delete[] lut;
390
391 pseg->statistics();
392
393 return pseg;
394 }
395
405 int img_add_model_to_mask(Bimage* p, Bmodel* model)
406 {
407 if ( !p || !model ) return -1;
408 if ( !p->data_pointer() ) return -1;
409 if ( !model->comp ) return -1;
410
411 p->change_type(Integer);
412
413 Bmodel* mp;
414 Bcomponent* comp;
415
416 long i, x, y, z, n;
417 int new_value, count = (int) p->maximum();
418
419 if ( verbose )
420 cout << "Adding model " << model->id << " to mask " << p->file_name() << endl << endl;
421
422 for ( mp = model; mp; mp = mp->next ) if ( mp->sel ) {
423 for ( comp = model->comp; comp; comp = comp->next ) if ( comp->sel ) {
424 n = mp->img_num;
425 x = (long) (comp->loc[0]/p->sampling()[0] + p->image[n].origin()[0] + 0.5);
426 y = (long) (comp->loc[1]/p->sampling()[1] + p->image[n].origin()[1] + 0.5);
427 z = (long) (comp->loc[2]/p->sampling()[2] + p->image[n].origin()[2] + 0.5);
428 if ( x < p->sizeX() && y < p->sizeY() && z < p->sizeZ() ) {
429 i = p->index(0, x, y, z, n);
430 if ( (*p)[i] < 1 ) {
431 new_value = p->check_neighbors(i);
432 if ( new_value > 0 ) p->set(i, new_value);
433 else p->set(i, count++);
434 }
435 }
436 }
437 }
438
439 p->maximum(count);
440
441 return 0;
442 }
443
452 Bmodel* model_from_multilevel_mask(Bimage* p)
453 {
454 p->change_type(Integer);
455
456 if ( verbose ) {
457 cout << "Generating a model from a multi-level mask:" << endl;
458 cout << "Mask file: " << p->file_name() << endl;
459 cout << "Number of levels: " << p->maximum() << endl << endl;
460 }
461
462 long i, j, x, y, z, n;
463 long nlev = (long)p->maximum() + 1;
464 double u = p->sampling().volume();
465 Bmodel* model = NULL;
466 Bmodel* m = NULL;
467 Bstring id, comptype("SEG");
468 Bcomponent* comp = NULL;
469 Bcomptype* ct;
470 Vector3<double> coor;
471
472 int* num = new int[nlev];
473 Vector3<float>* loc = new Vector3<float>[nlev];
474
475 int* mask = (int *) p->data_pointer();
476
477 for ( n=i=0; n<p->images(); n++ ) {
478 id = Bstring(n, "Segments_%d");
479 m = model_add(&m, id);
480 if ( !model ) model = m;
481 m->fmap = p->file_name();
482 m->img_num = n;
483 ct = model_add_type_by_id(m, comptype);
484 for ( j=0; j<=p->maximum(); j++ ) {
485 num[j] = 0;
486 loc[j] = 0;
487 }
488 for ( z=0; z<p->sizeZ(); z++ ) {
489 coor[2] = (z - p->image[n].origin()[2])*p->sampling()[2];
490 for ( y=0; y<p->sizeY(); y++ ) {
491 coor[1] = (y - p->image[n].origin()[1])*p->sampling()[1];
492 for ( x=0; x<p->sizeX(); x++, i++ ) if ( mask[i] > 0 ) {
493 coor[0] = (x - p->image[n].origin()[0])*p->sampling()[0];
494 num[mask[i]]++;
495 loc[mask[i]] += coor;
496 }
497 }
498 }
499 for ( j=1; j<=p->maximum(); j++ ) if ( num[j] ) {
500 id = Bstring(j, "%d");
501 comp = component_add(&comp, id);
502 if ( !m->comp ) m->comp = comp;
503 comp->type = ct;
504 comp->loc = loc[j]/num[j];
505 comp->radius = pow(3*num[j]*u/(4*M_PI), 1.0/3.0);
506 comp->view = View(comp->loc[0], comp->loc[1], comp->loc[2], 0);
507 comp->color[0] = 0;
508 }
509 }
510
511 delete[] num;
512 delete[] loc;
513
514 return model;
515 }
516
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bmodel::img_num
int img_num
Definition: rwmodel.h:127
verbose
int verbose
img_extract_segments_using_model
Bimage * img_extract_segments_using_model(Bimage *p, Bmodel *model, int multi_level)
Extracts segmentss from a multi-level mask around points defined by a model.
Definition: model_mask.cpp:334
Bcomponent::type
Bcomptype * type
Definition: rwmodel.h:54
model_create_level_mask
Bimage * model_create_level_mask(Bmodel *model, Vector3< long > size, Vector3< double > ori, Vector3< double > sam)
Calculates a mask with one level per model.
Definition: model_mask.cpp:285
Blink
Definition: rwmodel.h:82
Bmodel::id
Bstring id
Definition: rwmodel.h:121
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
utilities.h
Header file for general utilities.
model_util.h
Library routines used for model processing.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
model_shell.h
Library routines used for shell model processing.
Bimage::bar
int bar(Vector3< double > start, Vector3< double > end, double width, double edge_width, int fill_type=0, double fill=0)
Generates a bar between start and end points.
Definition: Bimage_edit.cpp:729
Integer
Definition: utilities.h:154
model_from_multilevel_mask
Bmodel * model_from_multilevel_mask(Bimage *p)
Generates components at the center of mass of each mask level.
Definition: model_mask.cpp:452
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
model_component_count
int model_component_count(Bmodel *model)
Counts the total number of components.
Definition: rwmodel.cpp:635
model_create_hull_mask
Bimage * model_create_hull_mask(Bmodel *model, Vector3< long > size, Vector3< double > ori, Vector3< double > sam, int curv_flag, int fast)
Calculates a mask based on the periphery of a model structure.
Definition: model_mask.cpp:103
component_add
Bcomponent * component_add(Bcomponent **comp, Bstring &id)
Adds a component to a linked list.
Definition: rwmodel.cpp:267
Bmodel::sel
int sel
Definition: rwmodel.h:129
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
Blink::comp
Bcomponent * comp[2]
Definition: rwmodel.h:84
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Vector3::max
Type max()
Definition: Vector3.h:175
Bimage
General image parameter class.
Definition: Bimage.h:163
M_PI
#define M_PI
Definition: utilities.h:59
Bimage::maximum
double maximum()
Definition: Bimage.h:535
Bcomponent::view
View view
Definition: rwmodel.h:59
Blink::next
Blink * next
Definition: rwmodel.h:83
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bimage::sphere
int sphere(Vector3< double > center, double radius, double width=0, int fill_type=0, double fill=0)
Fills a sphere within an image with a uniform value.
Definition: Bimage_edit.cpp:438
Blink::radius
float radius
Definition: rwmodel.h:87
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
img_add_model_to_mask
int img_add_model_to_mask(Bimage *p, Bmodel *model)
Adds to the mask the component locations.
Definition: model_mask.cpp:405
level
size_t level(0)
FILL_USER
#define FILL_USER
Definition: utilities.h:172
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bmodel::next
Bmodel * next
Definition: rwmodel.h:120
Bcomponent::sel
int sel
Definition: rwmodel.h:66
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
Bimage::check_neighbors
long check_neighbors(long idx)
Check neighbors in region map and assign a value if a neighbor is assigned.
Definition: Bimage_segment.cpp:419
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
Bstring
Definition: Bstring.h:29
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
Bmodel::link
Blink * link
Definition: rwmodel.h:133
Bimage::default_origin
Vector3< double > default_origin()
Definition: Bimage.h:585
Bmodel::fmap
Bstring fmap
Definition: rwmodel.h:125
matrix_linear.h
Header file for matrix functions.
model_add
Bmodel * model_add(Bmodel **model, Bstring &id)
Adds a model to a linked list.
Definition: rwmodel.cpp:178
Bcomponent::vec
Vector3< float > vec
Definition: rwmodel.h:60
Bcomponent::next
Bcomponent * next
Definition: rwmodel.h:52
rwmodel.h
Header file for reading and writing atomic model files.
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< long >
model_create_shell_mask
Bimage * model_create_shell_mask(Bmodel *model, Vector3< long > size, Vector3< double > ori, Vector3< double > sam, double shell_width, int curv_flag, int fast)
Calculates a shell mask covering a model structure.
Definition: model_mask.cpp:191
Vector3.h
Class for 3-value vectors.
View
Definition: View.h:26
model_mask.h
Functions to generate masks from models.
Bmodel
Definition: rwmodel.h:119
Bcomptype
Definition: rwmodel.h:25
model_center_of_mass
Vector3< double > model_center_of_mass(Bmodel *model)
Definition: model_util.cpp:475
Bimage::images
long images()
Definition: Bimage.h:491
Bmodel::comp
Bcomponent * comp
Definition: rwmodel.h:132
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
model_inside_outside
double model_inside_outside(Vector3< double > vec, Bmodel *model, int curv_flag, int fast)
Definition: model_shell.cpp:401
Bcomponent::loc
Vector3< float > loc
Definition: rwmodel.h:58
Bimage::data_size
long data_size()
Definition: Bimage.h:255
Bcomponent::color
RGBA< float > color
Definition: rwmodel.h:63
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
model_create_mask
Bimage * model_create_mask(Bmodel *model, Vector3< long > size, Vector3< double > ori, Vector3< double > sam, double edge)
Calculates a mask of the components and links of a model structure.
Definition: model_mask.cpp:34
Bcomponent
Definition: rwmodel.h:51