| Bsoft 2.0.5 Bernard's software package

bint.cpp
Go to the documentation of this file.
1
9 #include "rwimg.h"
10 #include "options.h"
11 #include "timer.h"
12
13 // Declaration of global variables
14 extern int verbose; // Level of output to the screen
15
16 // Usage assistance
17 const char* use[] = {
18 " ",
19 "Usage: bint [options] input.img output.img",
20 "------------------------------------------",
21 "Applies geometric transformations requiring interpolation to 2D and 3D images.",
22 "The transformation is set up so that only a single interpolation is done",
23 "to preserve information as far as possible.",
24 " ",
25 "Actions:",
26 "-size 10,50,8 New size (pixels).",
27 "-translate 0,-10,30 Translation after rotating (default 0,0,0).",
28 "-rotate -2.5,5.5,9,45 Rotate around a vector by an angle (default 0,0,0,0).",
29 "-toview 0.3,0.5,0.8,33 Rotate to view: vector {xyz} and angle (default 0,0,1,0).",
30 "-fromview 0.3,0.5,0.8,33 Rotate from view: vector {xyz} and angle (default 0,0,1,0).",
31 "-toeuler 16,120,85 Euler angle rotation: Phi, theta, psi (around axes z, y, z).",
32 "-fromeuler 16,120,85 Euler angle rotation: Psi, theta, phi (around axes z, y, z).",
33 "-scale 1.5,1.5,1.5 Relative scale (changes the units).",
34 "-enlarge 2,3,1 Enlarge the image by the given integer scale.",
35 "-integer 2,32 Special integer interpolation by given kernel size (changes units).",
36 " If old origin falls on a voxel, new origin also falls on a voxel.",
37 " Second value forces odd/even dimensions (default all odd).",
38 "-bin 3,2,1 Binning by given kernel size - one value = isotropic binning.",
39 " (i.e., 2 = binning with a 2x2 kernel, changes the units).",
40 "-median 3 Median binning (changes the units).",
41 "-invert Invert density in the image.",
42 "-slices Interpret multiple 2D images as z-slices of a single 3D image",
43 "-images Interpret slices of a single 3D image as 2D images",
44 "-rescale -0.1,5.2 Rescale output data to average and standard deviation.",
45 "-project Project a 3D image along the z-axis after transformation.",
46 "-Skew + + skews and - removes skewing (default off).",
47 " ",
48 "Parameters:",
49 "-verbose 7 Verbosity of output.",
50 "-datatype u Force writing of a new data type.",
51 "-sampling 1.2,0.7,2.0 Sampling before transformations (angstrom/pixel).",
52 "-newsampling 1.2,0.7,2.0 Sampling set after transformations (angstrom/pixel).",
53 "-origin 10,-10,20 Origin for rotation (default 0,0,0).",
54 "-neworigin 10,-10,20 Origin set after transformations.",
55 "-fill 127 Fill value for resizing (default background).",
56 "-unitcell 10,23,77,90,90,90 Unit cell parameters.",
57 " ",
58 NULL
59 };
60
61 int main(int argc, char **argv)
62 {
63 // Initialize variables
64 DataType nudatatype(Unknown_Type); // Conversion to new type
65 Vector3<double> sampling; // Units for the three axes (A/pixel)
66 Vector3<double> newsampling; // Units for the three axes (A/pixel)
67 int setinvert(0); // Flag to invert density
68 int znswitch(0); // 0=not, 1=n2z, 2=z2n
69 int setresize(0);
70 int settransform(0);
71 int setproject(0);
72 int setrescale(0);
73 double nuavg(0), nustd(0); // Rescaling to average and stdev
74 int rotate(0); // Rotation flag
75 int backward(0); // Backward rotation flag
76 int set_skew(0); // Skewing flag
77 Vector3<long> bin = {1,1,1}; // No binning
78 int median_binning(0); // No median binning
79 int integer_factor(0); // No special integer interpolation
80 int intbin_flag(21); // Odd dimesnions for integer interpolation
81 Vector3<long> newsize;
82 Vector3<double> origin; // Origin for rotation
83 int set_origin(0); // Flag to set origin
84 int set_nuorigin(0); // Flag to set new origin
85 Vector3<double> nuorigin; // Origin set after transformations
86 int fill_type(FILL_BACKGROUND); // Type of fill value
87 double fill(0); // Fill value for new areas
88 Vector3<long> enlarge; // Scale for integer enlargement
89 Vector3<double> scale(1.0,1.0,1.0);
90 Vector3<long> shift;
91 Vector3<double> translate;
92 double angle(0); // Rotation angle
93 Vector3<double> axis(0.0,0.0,1.0); // Rotation axis
94 View view; // View to rotate to
95 Euler euler; // Euler angles
96 UnitCell uc(0,0,0,M_PI_2,M_PI_2,M_PI_2);
97
98 int i, optind;
99 Boption* option = get_option_list(use, argc, argv, optind);
100 Boption* curropt;
101 for ( curropt = option; curropt; curropt = curropt->next ) {
102 if ( curropt->tag == "datatype" )
103 nudatatype = curropt->datatype();
104 if ( curropt->tag == "invert" )
105 setinvert = 1;
106 if ( curropt->tag == "slices" )
107 znswitch = 1;
108 if ( curropt->tag == "images" )
109 znswitch = 2;
110 if ( curropt->tag == "rescale" ) {
111 if ( curropt->values(nuavg, nustd) < 2 )
112 cerr << "-rescale: Both average and standard deviation must be specified!" << endl;
113 else
114 setrescale = 1;
115 if ( nustd <= 0 ) setrescale = 0;
116 }
117 if ( curropt->tag == "sampling" )
118 sampling = curropt->sampling();
119 if ( curropt->tag == "newsampling" )
120 newsampling = curropt->sampling();
121 if ( curropt->tag == "size" ) {
122 newsize = curropt->size();
123 settransform = 1;
124 }
125 if ( curropt->tag == "origin" ) {
126 if ( curropt->value[0] == 'c' ) {
127 set_origin = 2;
128 } else {
129 origin = curropt->origin();
130 set_origin = 1;
131 }
132 }
133 if ( curropt->tag == "neworigin" ) {
134 if ( curropt->value[0] == 'c' ) {
135 set_nuorigin = 2;
136 } else {
137 nuorigin = curropt->origin();
138 set_nuorigin = 1;
139 }
140 }
141 if ( curropt->tag == "translate" ) {
142 translate = curropt->vector3();
143 if ( translate.length() )
144 settransform = 1;
145 else
146 cerr << "-translate: At least one translation value must be specified!" << endl;
147 }
148 if ( curropt->tag == "rotate" ) {
149 if ( curropt->values(axis[0], axis[1], axis[2], angle) < 4 )
150 cerr << "-rotate: All three vector elements and an angle must be specified!" << endl;
151 else {
152 settransform = 1;
153 rotate = 1;
154 angle *= M_PI/180.0;
155 }
156 }
157 if ( curropt->tag == "toview" ) {
158 view = curropt->view();
159 settransform = 1;
160 rotate = 1;
161 backward = 1;
162 }
163 if ( curropt->tag == "fromview" ) {
164 view = curropt->view();
165 settransform = 1;
166 rotate = 1;
167 }
168 if ( curropt->tag == "toeuler" ) {
169 euler = curropt->euler();
170 view = euler.view();
171 settransform = 1;
172 rotate = 1;
173 backward = 1;
174 }
175 if ( curropt->tag == "fromeuler" ) {
176 euler = curropt->euler();
177 view = euler.view();
178 settransform = 1;
179 rotate = 1;
180 }
181 if ( curropt->tag == "scale" ) {
182 scale = curropt->scale();
183 if ( scale.volume() )
184 settransform = 1;
185 else
186 cerr << "-scale: At least one value must be specified!" << endl;
187 }
188 if ( curropt->tag == "enlarge" ) {
189 enlarge = curropt->scale();
190 if ( enlarge.volume() < 1 )
191 cerr << "-enlarge: All three values must be specified!" << endl;
192 }
193 if ( curropt->tag == "integer" )
194 if ( curropt->values(integer_factor, intbin_flag) < 1 )
195 cerr << "-integer: An integer must be specified!" << endl;
196 if ( curropt->tag == "bin" ) {
197 if ( ( i = curropt->values(bin[0], bin[1], bin[2]) ) < 1 )
198 cerr << "-bin: At least one bin size must be specified!" << endl;
199 else
200 if ( i < 2 ) bin[2] = bin[1] = bin[0];
201 }
202 if ( curropt->tag == "median" )
203 if ( ( median_binning = curropt->value.integer() ) < 1 )
204 cerr << "-median: A binning size must be specified!" << endl;
205 if ( curropt->tag == "project" )
206 setproject = 1;
207 if ( curropt->tag == "Skew" ) {
208 settransform = 1;
209 if ( curropt->value.contains("+" ) )
210 set_skew = 1;
211 else if ( curropt->value.contains("-" ) )
212 set_skew = -1;
213 else {
214 cerr << "-Skew: A skewing direction (+/-) must be specified!" << endl;
215 settransform = 0;
216 }
217 }
218 if ( curropt->tag == "fill" )
219 fill = curropt->fill(fill_type);
220 if ( curropt->tag == "unitcell" ) {
221 uc = curropt->unit_cell();
222 settransform = 1;
223 }
224 }
225 option_kill(option);
226
227 double ti = timer_start();
228
229 // Read image file
230 int dataflag(0);
231 if ( optind < argc - 1 ) dataflag = 1;
232 Bimage* p = read_img(argv[optind++], dataflag, -1);
233 if ( p == NULL ) {
234 cerr << "Error: No input file read!" << endl;
235 bexit(-1);
236 }
237
238 if ( znswitch == 1 )
239 if ( p->images_to_slices() < 0 ) bexit(-1);
240
241 if ( znswitch == 2 )
242 if ( p->slices_to_images() < 0 ) bexit(-1);
243
244 if ( nudatatype == Unknown_Type )
245 nudatatype = p->data_type(); // Preserve the old type
246 else if ( nudatatype > p->data_type() )
247 p->change_type(nudatatype);
248
249 if ( sampling.volume() > 0 ) p->sampling(sampling);
250
251 // Scaling is always positive
252 if ( fabs(scale.volume()) < 0.001 ) {
253 cerr << "Error: Scales too small!" << endl;
254 bexit(-1);
255 }
256
257 if ( setinvert ) p->invert();
258
259 if ( p->background(long(0)) < 1e-37 ) p->calculate_background();
260 if ( fill_type == FILL_AVERAGE ) fill = p->average();
261 if ( fill_type == FILL_BACKGROUND ) fill = p->background(long(0));
262
263 if ( uc.check() ) p->unit_cell(uc);
264 else uc = p->unit_cell();
265
266 if ( set_origin ) {
267 if ( set_origin == 2 ) p->origin(p->size()/2);
268 else p->origin(origin);
269 }
270
271 if ( bin[0] )
272 p->bin(bin);
273 else if ( median_binning )
274 p->median_bin(median_binning);
275 else if ( integer_factor )
276 p->integer_interpolation(integer_factor, intbin_flag);
277
278 if ( enlarge.volume() )
279 p->enlarge(enlarge);
280
281 Matrix3 mat(1);
282 Bimage* pnu = NULL;
283
284 if ( settransform ) {
285
286 if ( set_skew ) {
287 mat = uc.skew_rotation(set_skew==-1);
288 } else if ( rotate ) {
289 if ( view[2] < 1 || view.angle() != 0 ) {
290 if ( p->sizeZ() < 2 ) view = View(0, 0, 1, view.angle());
291 mat = view.matrix();
292 if ( backward )
293 mat = mat.transpose();
294 } else if ( angle != 0 ) {
295 if ( p->sizeZ() < 2 ) {
296 axis[0] = axis[1] = 0;
297 axis[2] = 1;
298 }
299 mat = Matrix3(axis, angle);
300 // cout << mat << endl;
301 }
302 view = View(mat.transpose());
303 if ( verbose & VERB_FULL )
304 cout << "View: " << view << endl;
305 }
306
307 if ( fabs(scale[0] - 1) < 1e-10 ) setresize += 1;
308 if ( fabs(scale[1] - 1) < 1e-10 ) setresize += 1;
309 if ( fabs(scale[2] - 1) < 1e-10 ) setresize += 1;
310 shift[0] = (long)floor(translate[0]+0.5);
311 shift[1] = (long)floor(translate[1]+0.5);
312 shift[2] = (long)floor(translate[2]+0.5);
313 if ( fabs(translate[0] - shift[0]) < 1e-10 ) setresize += 1;
314 if ( fabs(translate[1] - shift[1]) < 1e-10 ) setresize += 1;
315 if ( fabs(translate[2] - shift[2]) < 1e-10 ) setresize += 1;
316
317 if ( set_skew || rotate || setresize < 6 ) {
318 if ( newsize.volume() < 1 ) newsize = p->size();
319 pnu = p->transform(newsize, scale, p->image->origin(), translate, mat, fill_type, fill);
320 delete p;
321 p = pnu;
322 } else { //cerr << "minimal!" << endl;
323 p->resize(newsize, shift, fill_type, fill);
324 }
325
326 if ( verbose & VERB_DEBUG )
327 cout << "DEBUG bint: Transformations done" << endl;
328 }
329
330 if ( setrescale ) p->rescale_to_avg_std(nuavg, nustd);
331
332 if ( setproject ) p->project('z', 1);
333
334 if ( newsampling.volume() > 0 ) p->sampling(newsampling);
335
336 if ( set_nuorigin ) {
337 if ( set_nuorigin == 2 ) p->origin(p->size()/2);
338 else p->origin(nuorigin);
339 }
340
341 if ( optind < argc ) {
342 p->label(get_cmd_line(argc, argv));
343 p->change_type(nudatatype);
344 write_img(argv[optind], p, 0);
345 }
346
347 delete p;
348
349 if ( verbose & VERB_TIME )
350 timer_report(ti);
351
352 bexit(0);
353 }
354
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Boption::unit_cell
UnitCell unit_cell()
Definition: options.h:291
M_PI_2
#define M_PI_2
Definition: utilities.h:62
UnitCell
Definition: UnitCell.h:22
Boption::fill
double fill(int &fill_type)
Definition: options.h:138
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
Boption::euler
Euler euler()
Definition: options.h:271
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
Euler
Definition: Euler.h:28
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
Bimage::slices_to_images
int slices_to_images()
Changes the slices in a 3D image into a set of 2D images.
Definition: Bimage.cpp:2052
Bimage::invert
void invert()
Inverts the data in the image.
Definition: Bimage.cpp:3108
Boption::sampling
Vector3< double > sampling()
Definition: options.h:202
Boption::value
Bstring value
Definition: options.h:30
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Boption::tag
Bstring tag
Definition: options.h:29
Bimage::median_bin
int median_bin(int binning)
Bins by an integer size, selecting the kernel median.
Definition: Bimage_bin.cpp:388
Matrix3
Definition: Matrix3.h:17
FILL_AVERAGE
#define FILL_AVERAGE
Definition: utilities.h:173
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
get_cmd_line
string get_cmd_line(int argc, char **argv)
Returns the command line as a string.
Definition: utilities.cpp:36
timer.h
Utilities for timing functions.
Bimage
General image parameter class.
Definition: Bimage.h:163
Boption::size
Vector3< long > size()
Definition: options.h:163
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
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
Boption::view
View view()
Definition: options.h:259
verbose
int verbose
Boption
A class for a command line input option.
Definition: options.h:26
Bimage::label
void label(string s)
Definition: Bimage.h:235
Bimage::resize
int resize(Vector3< long > nusize, Vector3< long > translate, int fill_type=0, double fill=0)
Resizes without interpolation or rescaling.
Definition: Bimage_resize.cpp:28
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
Bimage::rescale_to_avg_std
int rescale_to_avg_std(double nuavg, double nustd)
Rescales the image data to a given average and standard deviation.
Definition: Bimage_rescale.cpp:163
UnitCell::skew_rotation
Matrix3 skew_rotation(int invert)
Definition: UnitCell.cpp:65
Bimage::unit_cell
void unit_cell(UnitCell uc)
Definition: Bimage.h:601
main
int main(int argc, char **argv)
Definition: bint.cpp:61
Boption::scale
Vector3< double > scale()
Definition: options.h:190
Bimage::project
Bimage * project(char axis, int flags=1)
Projects a 3D image to a 2D image down one of the three major axes.
Definition: Bimage_project.cpp:31
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
Boption::datatype
DataType datatype()
Definition: options.h:93
Boption::next
Boption * next
Definition: options.h:28
Bimage::images_to_slices
int images_to_slices()
Changes the 2D images to slices in a 3D image.
Definition: Bimage.cpp:2093
View::matrix
Matrix3 matrix()
Definition: View.h:150
Matrix3::transpose
Matrix3 transpose() const
Definition: Matrix3.h:268
Boption::vector3
Vector3< double > vector3()
Definition: options.h:148
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< double >
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
option_kill
int option_kill(Boption *option)
Deallocates a linked list of option structures.
Definition: options.cpp:109
Bimage::integer_interpolation
int integer_interpolation(int integer_factor)
Definition: Bimage_bin.cpp:16
Bimage::enlarge
int enlarge(Vector3< long > scale)
Enlarges an image by an inetger scale.
Definition: Bimage_resize.cpp:503
Euler::view
View view()
Definition: Euler.h:62
Bstring::integer
long integer()
Definition: Bstring.cpp:539
Bimage::average
double average(long cc, double xf, double yf, double zf, long nn, double iscale)
Averages in 3D when scaling is less than 1.
Definition: Bimage.cpp:1349
use
const char * use[]
Definition: bint.cpp:17
Unknown_Type
Definition: utilities.h:147
rwimg.h
Header file for 2D and 3D image I/O.
options.h
Header file for option handlers.
UnitCell::check
bool check()
Definition: UnitCell.h:34
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::background
double background(long nn)
Definition: Bimage.h:542
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Boption::values
long values(T1 &v1, T2 &v2)
Definition: options.h:115
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
timer_start
double timer_start()
Starts timer and prints the time.
Definition: timer.cpp:52
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563