| Bsoft 2.0.5 Bernard's software package

View.cpp
Go to the documentation of this file.
1
9 #include "View.h"
10 #include "linked_list.h"
11 #include "random_numbers.h"
12 #include "utilities.h"
13
14 // Declaration of global variables
15 extern int verbose; // Level of output to the screen
16
17 ostream& operator<<(ostream& output, View v) {
18 output.setf(ios::fixed, ios::floatfield);
19 output << v.vector3() << tab << setw(10) << v.angle()*180.0/M_PI;
20 return output;
21 }
22
28 int show_views(View* v)
29 {
30 int n(0);
31
32 for ( ; v; v = v->next, n++ )
33 cout << *v << endl;
34
35 return n;
36 }
37
44 View* view_array(View* v, long& n)
45 {
46 long i;
47
48 n = count_list((char *)v);
49
50 View* varr = new View[n];
51
52 for ( i=0; v; v=v->next, i++ ) varr[i] = *v;
53
54 return varr;
55 }
56
70 View* tilt_views(double ang_min, double ang_max, double ang_step, double axis)
71 {
72 if ( ang_max < ang_min ) swap(ang_max, ang_min);
73 if ( ang_step < 0 ) ang_step = -ang_step;
74
75 double ang;
76 int n(0);
77 View* view = NULL;
78 View* v = NULL;
79
80 for ( n=0, ang=ang_min; ang<ang_max+0.5*ang_step; ang+=ang_step, n++ ) {
81 v = (View *) add_item((char **) &view, sizeof(View));
82 // *v = view_from_tilt_and_axis(ang, axis);
83 *v = View(ang, axis);
84 }
85
86 if ( verbose & VERB_PROCESS )
87 cout << "Getting " << n << " views for tilting from " << ang_min*180.0/M_PI <<
88 " to " << ang_max*180.0/M_PI << " by step " << ang_step*180.0/M_PI <<
89 " around axis " << axis*180.0/M_PI << endl;
90
91 return view;
92 }
93
101 View random_view()
102 {
103 double irm = 2.0/get_rand_max();
104 View v;
105
106 v[0] = random()*irm - 1;
107 v[1] = random()*irm - 1;
108 v[2] = random()*irm - 1;
109 v[3] = M_PI*(random()*irm - 1);
110 v.normalize();
111
112 return v;
113 }
114
123 View view_random_reslice()
124 {
125 double irm = 1.0/get_rand_max();
126 View v;
127
128 int rv = (int) (5.999*irm*random());
129 int ra = (int) (3.999*irm*random());
130 switch ( rv ) {
131 case 0: v = View(1,0,0,ra*M_PI_2); break;
132 case 1: v = View(0,1,0,ra*M_PI_2); break;
133 case 2: v = View(0,0,1,ra*M_PI_2); break;
134 case 3: v = View(-1,0,0,ra*M_PI_2); break;
135 case 4: v = View(0,-1,0,ra*M_PI_2); break;
136 case 5: v = View(0,0,-1,ra*M_PI_2); break;
137 }
138
139 return v;
140 }
141
147 View* random_views(int nviews)
148 {
149 if ( nviews < 1 ) {
150 error_show("Error in random_views: No views defined!", __FILE__, __LINE__);
151 return NULL;
152 }
153
154 random_seed();
155
156 int i;
157 View* view = NULL;
158 View* v = NULL;
159
160 for ( i=0; i<nviews; i++ ) {
161 v = (View *) add_item((char **) &v, sizeof(View));
162 if ( !view ) view = v;
163 *v = random_view();
164 }
165
166 return view;
167 }
168
180 double random_view_error(View& v, double std)
181 {
182 double angle = random_gaussian(0.0, std);
183
184 Vector3<double> axis = vector3_random(-1.0, 1.0);
185 axis.normalize();
186
187 Quaternion q(v.quaternion()*Quaternion(axis, angle));
188
189 v = View(q);
190
191 return angle;
192 }
193
207 View* views_within_limits(View theview, double theta_step, double phi_step,
208 double alpha_step, double view_angle_limit, double alpha_angle_limit)
209 {
210 double theta, phi, alpha;
211 double theta_start = (theta_step)? -theta_step*floor(view_angle_limit/theta_step): 0;
212 double phi_start = (phi_step)? -phi_step*floor(view_angle_limit/phi_step): 0;
213 double alpha_start = theview.angle();
214 double alpha_end = alpha_start;
215
216 if ( alpha_step > 0 && alpha_angle_limit > 0 ) {
217 alpha = alpha_step*floor(alpha_angle_limit/alpha_step);
218 alpha_start -= alpha;
219 alpha_end += alpha;
220 }
221
222 if ( alpha_step <= 0 ) alpha_step = 1;
223
224 Vector3<double> ref_axis(0,0,1);
225
226 theview.normalize();
227
228 Vector3<double> vv(theview[0], theview[1], theview[2]);
229
230 Vector3<double> axis1 = vv.cross(ref_axis);
231 if ( axis1.length() < 0.001 ) axis1[0] = 1;
232 axis1.normalize();
233
234 Vector3<double> axis2 = vv.cross(axis1);
235 if ( axis2.length() < 0.001 ) axis2[1] = 1;
236 axis2.normalize();
237
238 View* view = NULL;
239 View* v = NULL;
240 Quaternion q1, q;
241 Quaternion qv(0, theview[0], theview[1], theview[2]);
242
243 if ( verbose & VERB_FULL )
244 cout << qv << endl;
245
246 if ( verbose & VERB_DEBUG ) {
247 cout << "DEBUG views_within_limits: The View: " << theview << endl;
248 cout << "DEBUG views_within_limits: theta_step: "<< theta_step*180/M_PI
249 << ", phi_step: " << phi_step*180/M_PI
250 << ", alpha_step: " << alpha_step*180/M_PI << endl;
251 cout << "DEBUG views_within_limits: Axis1: " << axis1 << endl;
252 cout << "DEBUG views_within_limits: Axis2: " << axis2 << endl;
253 }
254
255 if ( theta_step < 1e-6 ) theta_step = 1e6;
256 if ( phi_step < 1e-6 ) phi_step = 1e6;
257 if ( alpha_step < 1e-6 ) alpha_step = 1e6;
258 for ( theta = theta_start; theta <= view_angle_limit; theta += theta_step ) {
259 // q1 = quaternion_from_angle_and_axis3(theta, axis1);
260 q1 = Quaternion(axis1, theta);
261 for ( phi = phi_start; phi <= view_angle_limit; phi += phi_step ) {
262 // q = quaternion_from_angle_and_axis3(phi, axis2);
263 q = Quaternion(axis2, phi);
264 q *= q1;
265 q = q.rotate(qv);
266 for ( alpha = alpha_start; alpha <= alpha_end; alpha += alpha_step ) {
267 v = (View *) add_item((char **) &v, sizeof(View));
268 if ( !view ) view = v;
269 *v = View(q[1], q[2], q[3], alpha);
270 if ( verbose & VERB_DEBUG )
271 cout << "DEBUG views_within_limits: " << *v << " - " << theview.angle(*v)*180/M_PI << endl;
272 }
273 }
274 }
275
276 return view;
277 }
278
285 View* views_for_refinement(View theview, double alpha_step)
286 {
287 View* view = NULL;
288
289 if ( alpha_step <= 0 ) {
290 view = (View *) add_item((char **) &view, sizeof(View));
291 *view = theview;
292 return view;
293 }
294
295 double alpha1, alpha2, alpha3;
296 Vector3<double> ref_axis(0,0,1);
297
298 theview.normalize();
299
300 Vector3<double> vv(theview[0], theview[1], theview[2]);
301
302 Vector3<double> axis1 = vv.cross(ref_axis);
303 if ( axis1.length() < 0.001 ) axis1[0] = 1;
304 axis1.normalize();
305
306 Vector3<double> axis2 = vv.cross(axis1);
307 if ( axis2.length() < 0.001 ) axis2[1] = 1;
308 axis2.normalize();
309
310 View* v = NULL;
311 Quaternion q1, q;
312 Quaternion qv(0, theview[0], theview[1], theview[2]);
313
314 if ( verbose & VERB_FULL )
315 cout << qv << endl;
316
317 if ( verbose & VERB_DEBUG ) {
318 cout << "DEBUG views_for_refinement: The View: " << theview << endl;
319 cout << "DEBUG views_for_refinement: alpha_step: "<< alpha_step*180/M_PI << endl;
320 cout << "DEBUG views_for_refinement: Axis1: " << axis1 << endl;
321 cout << "DEBUG views_for_refinement: Axis2: " << axis2 << endl;
322 }
323
324 for ( alpha1 = -alpha_step; alpha1 <= alpha_step; alpha1 += alpha_step ) {
325 // q1 = quaternion_from_angle_and_axis3(alpha1, axis1);
326 q1 = Quaternion(axis1, alpha1);
327 for ( alpha2 = -alpha_step; alpha2 <= alpha_step; alpha2 += alpha_step ) {
328 // q = quaternion_from_angle_and_axis3(alpha2, axis2);
329 q = Quaternion(axis2, alpha2);
330 q *= q1;
331 q = q.rotate(qv);
332 for ( alpha3 = -alpha_step; alpha3 <= alpha_step; alpha3 += alpha_step ) {
333 v = (View *) add_item((char **) &v, sizeof(View));
334 if ( !view ) view = v;
335 *v = View(q[1], q[2], q[3], theview.angle() + alpha3);
336 if ( verbose & VERB_DEBUG )
337 cout << "DEBUG views_for_refinement: " << *v << " - " << theview.angle(*v)*180/M_PI << endl;
338 }
339 }
340 }
341
342 return view;
343 }
344
354 View* views_for_refinement(View theview, double alpha_step1, double alpha_step2,
355 double alpha_step3, double max_alpha3)
356 {
357 View* view = NULL;
358
359 if ( alpha_step1 <= 0 && alpha_step2 <= 0 && alpha_step3 <= 0 ) {
360 view = (View *) add_item((char **) &view, sizeof(View));
361 *view = theview;
362 return view;
363 }
364
365 if ( alpha_step1 < 0 ) alpha_step1 = 0;
366 if ( alpha_step2 < 0 ) alpha_step2 = 0;
367 if ( alpha_step3 <= 0 ) alpha_step3 = max_alpha3 = 0;
368
369 double tol(M_PI/1800.0); // Tolerance for small angles: 0.1 degrees
370 double alpha1, alpha2, alpha3;
371 Vector3<double> ref_axis(0,0,1);
372
373 theview.normalize();
374
375 Vector3<double> vv(theview[0], theview[1], theview[2]);
376
377 Vector3<double> axis1 = vv.cross(ref_axis);
378 if ( axis1.length() < 0.001 ) axis1[0] = 1;
379 axis1.normalize();
380
381 Vector3<double> axis2 = vv.cross(axis1);
382 if ( axis2.length() < 0.001 ) axis2[1] = 1;
383 axis2.normalize();
384
385 View* v = NULL;
386 Quaternion q1, q;
387 Quaternion qv(0, theview[0], theview[1], theview[2]);
388
389 if ( verbose & VERB_FULL )
390 cout << qv << endl;
391
392 if ( verbose & VERB_DEBUG ) {
393 cout << "DEBUG views_for_refinement: The View: " << theview << endl;
394 cout << "DEBUG views_for_refinement: alpha_steps: " << alpha_step1*180/M_PI
395 << " " << alpha_step2*180/M_PI << " " << alpha_step3*180/M_PI << endl;
396 cout << "DEBUG views_for_refinement: Axis1: " << axis1 << endl;
397 cout << "DEBUG views_for_refinement: Axis2: " << axis2 << endl;
398 }
399
400 for ( alpha1 = -alpha_step1; alpha1 <= alpha_step1; alpha1 += alpha_step1 ) {
401 // q1 = quaternion_from_angle_and_axis3(alpha1, axis1);
402 q1 = Quaternion(axis1, alpha1);
403 for ( alpha2 = -alpha_step2; alpha2 <= alpha_step2; alpha2 += alpha_step2 ) {
404 // q = quaternion_from_angle_and_axis3(alpha2, axis2);
405 q = Quaternion(axis2, alpha2);
406 q *= q1;
407 q = q.rotate(qv);
408 for ( alpha3 = -max_alpha3; alpha3 <= max_alpha3; alpha3 += alpha_step3 ) {
409 v = (View *) add_item((char **) &v, sizeof(View));
410 if ( !view ) view = v;
411 *v = View(q[1], q[2], q[3], theview.angle() + alpha3);
412 if ( verbose & VERB_DEBUG )
413 cout << "DEBUG views_for_refinement: " << *v << " - " << theview.angle(*v)*180/M_PI << endl;
414 if ( alpha_step3 < tol ) alpha3 += 1;
415 }
416 if ( alpha_step2 < tol ) alpha2 += 1;
417 }
418 if ( alpha_step1 < tol ) alpha1 += 1;
419 }
420
421 return view;
422 }
423
435 View* view_list_expand_angles(View* views, double amin, double amax, double astep)
436 {
437 double a;
438 View* newviews = NULL;
439 View* v = NULL;
440 View* vn = NULL;
441
442 if ( verbose & VERB_DEBUG )
443 cout << "DEBUG view_list_expand_angles: amin=" << amin << " amax=" << amax << " astep=" << astep << endl;
444
445 for ( v = views; v; v = v->next ) {
446 if ( verbose & VERB_FULL )
447 cout << "Old view: " << v << ": " << *v << endl;
448 for ( a = amin; a <= amax; a += astep ) {
449 vn = (View *) add_item((char **) &vn, sizeof(View));
450 if ( !newviews ) newviews = vn;
451 *vn = *v;
452 (*vn)[3] += a;
453 if ( verbose & VERB_FULL )
454 cout << vn << *vn << endl;
455 }
456 }
457
458 if ( verbose & VERB_FULL )
459 show_views(newviews);
460
461 return newviews;
462 }
463
474 int view_list_subset(View** view_list, int start, int size)
475 {
476 if ( size < 1 ) {
477 cerr << "Warning: No subset selected - view list remains the same!" << endl;
478 return 0;
479 }
480
481 int i;
482 View* view;
483 View* view_next = NULL;
484
485 if ( start > 0 ) {
486 for ( i=0, view = *view_list; view && i<start-1; view = view->next, i++ ) ;
487 if ( view ) {
488 view_next = view->next;
489 view->next = NULL;
490 }
491
492 kill_list((char *) *view_list, sizeof(View));
493
494 *view_list = view_next;
495 }
496
497 if ( !*view_list ) {
498 cerr << "Error: No views selected!" << endl;
499 return -1;
500 }
501
502 for ( i=0, view = *view_list; view && i<size-1; view = view->next, i++ ) ;
503
504 if ( view ) {
505 i++;
506 view_next = view->next;
507 view->next = NULL;
508 kill_list((char *) view_next, sizeof(View));
509 }
510
511
512 if ( verbose & VERB_PROCESS )
513 cout << "Number of views selected: " << i << endl;
514
515 return i;
516 }
517
518
M_PI_2
#define M_PI_2
Definition: utilities.h:62
Vector3::cross
Vector3 cross(const Vector3 &v)
Definition: Vector3.h:250
vector3_random
Vector3< double > vector3_random(const double min, const double max)
Generates a random vector within a defined cube.
Definition: random_numbers.cpp:440
Vector3::normalize
double normalize()
Definition: Vector3.h:236
random_seed
long random_seed()
Gets a random seed and sets the flag.
Definition: random_numbers.cpp:41
Vector3::length
double length()
Definition: Vector3.h:222
View::next
View * next
Definition: View.h:28
Quaternion::rotate
Quaternion rotate(const Quaternion &point)
Definition: Quaternion.h:173
utilities.h
Header file for general utilities.
views_within_limits
View * views_within_limits(View theview, double theta_step, double phi_step, double alpha_step, double view_angle_limit, double alpha_angle_limit)
Generates a list of views within an angular distance from the input view.
Definition: View.cpp:207
tilt_views
View * tilt_views(double ang_min, double ang_max, double ang_step, double axis)
Initializes a set of views tilted around the y axis.
Definition: View.cpp:70
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
random_views
View * random_views(int nviews)
Calculates a set of random views.
Definition: View.cpp:147
kill_list
long kill_list(char *list, unsigned long size)
Frees all the items in a linked list.
Definition: linked_list.cpp:214
add_item
char * add_item(char **list, unsigned long size)
Adds an item to a linked list.
Definition: linked_list.cpp:26
count_list
long count_list(char *list)
Counts the number of items in a linked list.
Definition: linked_list.cpp:235
Quaternion
Definition: Quaternion.h:25
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
M_PI
#define M_PI
Definition: utilities.h:59
linked_list.h
Header file for generalized linked list functions.
random_gaussian
double random_gaussian(double avg, double std)
Generates a value with a gaussian random distribution.
Definition: random_numbers.cpp:123
view_list_subset
int view_list_subset(View **view_list, int start, int size)
Replaces a view list with a subset of it.
Definition: View.cpp:474
view_array
View * view_array(View *v, long &n)
Copies views from a list into an array.
Definition: View.cpp:44
show_views
int show_views(View *v)
Displays a linked list of views.
Definition: View.cpp:28
view_list_expand_angles
View * view_list_expand_angles(View *views, double amin, double amax, double astep)
Expands each view to several views with different rotation angles.
Definition: View.cpp:435
irm
double irm(1.0L/get_rand_max())
operator<<
ostream & operator<<(ostream &output, View v)
Definition: View.cpp:17
View::vector3
Vector3< double > vector3()
Definition: View.h:126
View::normalize
double normalize()
Definition: View.h:106
get_rand_max
long get_rand_max()
Finds the maximum random number for a system.
Definition: random_numbers.cpp:22
verbose
int verbose
random_view
View random_view()
Calculates a random view.
Definition: View.cpp:101
random_numbers.h
Header file for functions for creating random images.
View::quaternion
Quaternion quaternion()
Definition: View.h:127
Vector3< double >
View::angle
double angle()
Definition: View.h:95
View
Definition: View.h:26
random_view_error
double random_view_error(View &v, double std)
Calculates a new view with a random error from the given view.
Definition: View.cpp:180
view_random_reslice
View view_random_reslice()
Generates a random reslicing 3x3 rotation matrix.
Definition: View.cpp:123
View.h
View object.
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
views_for_refinement
View * views_for_refinement(View theview, double alpha_step)
Generates a 3x3 grid of views around an input view.
Definition: View.cpp:285