| Bsoft 2.0.0 Bernard's software package

mg2imod.c
Go to the documentation of this file.
1 /*
2 mg2imod.c
3 Converts between IMOD files and a micrograph parameter file
4 Authors: Bernard Heymann
5 Created: 20070501 Modified: 20120123
6 Compile with:
7 g++ mg2imod.c -o mg2imod -I$BSOFT/include -L$BSOFT/lib -lbsoft
8 */
9
10 #include "mg_processing.h"
11 #include "mg_img_proc.h"
12 #include "mg_tomography.h"
13 #include "rwmg.h"
14 #include "rwimg.h"
15 #include "linked_list.h"
16 #include "utilities.h"
17 #include "options.h"
18 #include "timer.h"
19
20 // Declaration of global variables
21 extern int verbose; // Level of output to the screen
22 extern long memory; // Total memory allocated
23
24 Bproject* project_from_IMOD(Bstring* file_list, int flag);
25 int write_IMOD_parameters(Bstring& imodfile, Bproject* project);
26
27 // Usage assistance
28 const char* use[] = {
29 " ",
30 "Usage: mg2imod [options] input.mrc input.xf input.tlt input.xyz",
31 "---------------------------------------------------------------",
32 "Converts between IMOD files and a micrograph parameter file.",
33 " ",
34 "Actions:",
35 "-topif Flag to convert the image file to multi-image PIF (default not).",
36 " ",
37 "Parameters:",
38 "-verbose 7 Verbosity of output.",
39 "-sampling 1.5 Sampling (A/pixel).",
40 " ",
41 "Output:",
42 "-output file.star Output micrograph parameter file.",
43 "-imod file.xf Output IMOD parameter files.",
44 " ",
45 NULL
46 };
47
48
49 int main(int argc, char** argv)
50 {
51 // Initializing variables
52 int flag = 0; // Flag to rewrite the image file
53 float sampling; // A/pixel
54 Bstring outfile; // Output parameter file
55 Bstring imodfile; // IMOD output parameter file
56
57 int optind;
58 Option* option = get_option_list(use, argc, argv, &optind);
59 Option* curropt;
60 for ( curropt = option; curropt; curropt = curropt->next ) {
61 if ( strcmp(curropt->tag, "topif") == 0 ) flag = 1;
62 if ( strcmp(curropt->tag, "sampling") == 0 )
63 if ( sscanf(curropt->value, "%f", &sampling) < 1 )
64 cerr << "-sampling: A pixel size must be specified" << endl;
65 if ( strcmp(curropt->tag, "output") == 0 )
66 outfile = get_option_filename(curropt->value);
67 if ( strcmp(curropt->tag, "imod") == 0 )
68 imodfile = get_option_filename(curropt->value);
69 }
70 option_kill(option);
71
72 double ti;
73 if ( verbose & VERB_TIME )
74 ti = timer_start();
75
76 // Read all the parameter files
77 Bstring* file_list = NULL;
78 while ( optind < argc ) string_add(&file_list, argv[optind++]);
79 if ( !file_list ) {
80 cerr << "Error: No parameter files specified!" << endl;
81 bexit(-1);
82 }
83
84 Bproject* project = NULL;
85 Bstring ext = file_list->extension();
86
87 if ( ext.contains("star") || ext.contains("xml") )
88 project = read_project(file_list);
89 else
90 project = project_from_IMOD(file_list, flag);
91
92 string_kill(file_list);
93
94 if ( project == NULL ) {
95 cerr << "Error: No project generated!" << endl;
96 bexit(-1);
97 }
98
99 if ( sampling > 0.1 )
100 project_set_pixel_size(project, sampling);
101
102 project_update_comment(project, argc, argv);
103
104 if ( outfile.length() )
105 write_project(outfile, project, 0, 0);
106
107 if ( imodfile.length() )
108 write_IMOD_parameters(imodfile, project);
109
110 project_kill(project);
111
112 if ( verbose & VERB_TIME )
113 timer_report(ti);
114
115 bexit(0);
116 }
117
118 /************************************************************************
119 @Function: project_from_IMOD
120 @Description:
121 Creates a project structure using IMOD parameters.
122 @Algorithm:
123 Requirements:
124 Tilt series micrograph image (if 3D then converted to multi-2D)
125 2D transform file (.xf)
126 Tilt angle file (.tlt)
127 Calculations:
128 Tilt angle: from tilt angle file
129 Tilt axis: ta = (atan2(-A11, A12) + atan2(-A22, -A21))/2
130 Mg origin: o = on - Ad
131 where
132 A: 2x2 transformation matrix
133 ta: tilt axis angle
134 on: nominal micrograph origin (center of mg)
135 o: aligned micrograph origin
136 d: shift for micrograph
137 @Arguments:
138 Bstring* file_list list of IMOD parameter file names.
139 int flag flag to indicate conversion of the image file.
140 @Returns:
141 Bproject* new project parameter structure.
142 *************************************************************************/
143 Bproject* project_from_IMOD(Bstring* file_list, int flag)
144 {
145 if ( file_list->empty() ) {
146 cerr << "No filenames given to create a project!" << endl;
147 exit(-1);
148 }
149
150 Bimage* p = NULL;
151 Bstring base, imgfile;
152 Bstring* thisfile = NULL;
153 Bstring ext;
154
155 for ( thisfile = file_list; thisfile; thisfile = thisfile->next ) {
156 ext = thisfile->extension();
157 if ( ext.contains("pif") || ext.contains("mrc") || ext.contains("st") ) {
158 imgfile = *thisfile;
159 base = imgfile.base();
160 if ( ext.contains("st") ) imgfile += ":mrc";
161 p = read_img(imgfile, 0, -1);
162 if ( !p ) {
163 cerr << "Error: Image file " << imgfile << " not read!" << endl;
164 error_show("project_from_IMOD", __FILE__, __LINE__);
165 return(NULL);
166 }
167 if ( p->z > 1 ) {
168 p->slices_to_images();
169 if ( flag ) {
170 delete p;
171 p = read_img(imgfile, 1, 0);
172 p->slices_to_images();
173 imgfile = base + ".pif";
174 write_img(imgfile, p);
175 }
176 }
177 }
178 }
179
180 if ( !p ) {
181 cerr << "Error: No image file provided!" << endl;
182 error_show("project_from_IMOD", __FILE__, __LINE__);
183 return(NULL);
184 }
185
186 int j, n;
187 Bstring mg_id, rec_id, rec_name;
188 Bproject* project = project_init();
189 Bfield* field = field_add(&project->field, base);
190 Bmicrograph* mg = NULL;
191 Breconstruction* rec = NULL;
192 Bmarker* mark = NULL;
193
194 for ( n=0; n<p->images(); n++ ) {
195 mg_id = base + Bstring(n+1, "_%03d");
196 mg = micrograph_add(&mg, mg_id);
197 if ( !field->mg ) field->mg = mg;
198 mg->block = n;
199 mg->img_num = n;
200 mg->fmg = imgfile;
201 mg->pixel_size = p->sampling().x();
202 mg->origin] = p->size()/2;
203 if ( verbose & VERB_FULL )
204 cout << "Creating field \"" << field->id << "\", micrograph \"" << mg->id << "\"" << endl;
205 }
206
207 delete p;
208
209 FILE* fd = NULL;
210 char aline[100], *aptr;
211 int mark_id, dum;
212 float x, y, z;
213 double a[4], dx, dy, ta;
214
215 for ( thisfile = file_list; thisfile; thisfile = thisfile->next ) {
216 ext = thisfile->extension();
217 if ( ext.contains("xf") ) {
218 if ( ( fd = fopen(thisfile->c_str(), "r") ) == NULL ) {
219 cerr << "Error: A text file specifying 2D transformations must be given!" << endl;
220 return(NULL);
221 }
222 if ( verbose & VERB_PROCESS )
223 cout << "Reading 2D transformations from \"" << *thisfile << "\"" << endl;
224 for ( mg = field->mg; mg; mg = mg->next ) {
225 fscanf(fd, "%lf %lf %lf %lf %lf %lf", &a[0], &a[1], &a[2], &a[3], &dx, &dy);
226 mg->tilt_axis = (atan2(-a[0], a[1]) + atan2(-a[3], -a[2]))/2.0;
227 mg->origin[0] -= a[0]*dx + a[2]*dy;
228 mg->origin[1] -= a[1]*dx + a[3]*dy;
229 }
230 fclose(fd);
231 } else if ( ext.contains("tlt") ) {
232 if ( ( fd = fopen(thisfile->c_str(), "r") ) == NULL ) {
233 cerr << "Error: A text file specifying tilt angles must be given!" << endl;
234 return(NULL);
235 }
236 if ( verbose & VERB_PROCESS )
237 cout << "Reading tilt angles from \"" << *thisfile << "\"" << endl;
238 for ( mg = field->mg; mg; mg = mg->next ) {
239 fscanf(fd, "%lf", &ta);
240 mg->tilt_angle = ta*M_PI/180.0;
241 }
242 fclose(fd);
243 } else if ( ext.contains("xyz") ) {
244 if ( ( fd = fopen(thisfile->c_str(), "r") ) == NULL ) {
245 cerr << "Error: A text file specifying the 3D marker model must be given!" << endl;
246 return(NULL);
247 }
248 if ( verbose & VERB_PROCESS )
249 cout << "Reading the 3D marker model from \"" << *thisfile << "\"" << endl;
250 rec_id = base;
251 rec = reconstruction_add(&project->rec, rec_id);
252 rec_name = base + ".rec";
253 if ( access(rec_name.c_str(), R_OK) ) {
254 fgets(aline, 100, fd);
255 aptr = strstr(aline, "Pix");
256 sscanf(aptr, "Pix: %f Dim: %f %f\n", &rec->voxel_size, &rec->origin[0], &rec->origin[1]);
257 rec->origin /= 2;
258 rewind(fd);
259 } else {
260 rec->frec = rec_name;
261 rec_name += ":mrc";
262 p = read_img(rec_name, 0, -1);
263 rec->voxel_size = p->sampling().x();
264 rec->origin = p->size()/2;
265 delete p;
266 }
267 while ( fgets(aline, 100, fd) ) {
268 if ( sscanf(aline, "%d %f %f %f %d %d", &mark_id, &x, &y, &z, &dum, &dum) > 5 ) {
269 mark = (Bmarker *) add_item((char **) &mark, sizeof(Bmarker));
270 if ( !rec->mark ) rec->mark = mark;
271 mark->id = mark_id;
272 mark->loc = Vector3<float>(x - rec->origin.x(), y - rec->origin.y(), z);
273 mark->fom = 1;
274 mark->sel = 1;
275 }
276 }
277 fclose(fd);
278 }
279 }
280
281 project_mg_tilt_to_matrix(project);
282
283 return(project);
284 }
285
286 /************************************************************************
287 @Function: write_IMOD_parameters
288 @Description:
289 Creates IMOD parameter files from a project structure.
290 @Algorithm:
291 Writes both .xf and .tlt files.
292 Calculations:
293 Tilt angle: from micrograph tilt angle
294 Matrix: A = {cos(ta), -sin(ta), sin(ta), cos(ta)}
295 Shift: d = o - on
296 where
297 A: 2x2 transformation matrix
298 ta: tilt axis angle
299 on: nominal micrograph origin (center of mg)
300 o: aligned micrograph origin
301 d: shift for micrograph
302 @Arguments:
303 Bstring& imodfile IMOD parameter file name.
304 Bproject* project project structure.
305 @Returns:
306 int 0.
307 *************************************************************************/
308 int write_IMOD_parameters(Bstring& imodfile, Bproject* project)
309 {
310 Bstring paramfile = imodfile.base() + ".xf";
311 Bmicrograph* mg = project->field->mg;
312 Breconstruction* rec = project->rec;
313 Bmarker* mark = NULL;
314
315 Vector3<float> d, origin = micrograph_get_nominal_origin(mg);
316
317 FILE* fd = NULL;
318
319 if ( ( fd = fopen(paramfile.c_str(), "w") ) == NULL ) {
320 error_show("write_IMOD_parameters", __FILE__, __LINE__);
321 return(NULL);
322 }
323
324 if ( verbose & VERB_PROCESS )
325 cout << "Writing 2D transformations to \"" << paramfile << "\"" << endl;
326
327 double a[4];
328
329 for ( mg = project->field->mg; mg; mg = mg->next ) {
330 a[0] = a[3] = -sin(mg->tilt_axis);
331 a[1] = cos(mg->tilt_axis);
332 a[2] = -cos(mg->tilt_axis);
333 d = origin - mg->origin;
334 fprintf(fd, "%12.7lf%12.7lf%12.7lf%12.7lf%12.3lf%12.3lf\n", a[0], a[1],
335 a[2], a[3], a[0]*d.x() + a[1]*d.y(), a[2]*d.x() + a[3]*d.y());
336 }
337
338 fclose(fd);
339
340 paramfile = imodfile.base() + ".tlt";
341
342 if ( ( fd = fopen(paramfile.c_str(), "w") ) == NULL ) {
343 error_show("write_IMOD_parameters", __FILE__, __LINE__);
344 return(NULL);
345 }
346
347 if ( verbose & VERB_PROCESS )
348 cout << "Writing tilt angles to \"" << paramfile << "\"" << endl;
349
350 for ( mg = project->field->mg; mg; mg = mg->next )
351 fprintf(fd, "%g\n", mg->tilt_angle*180.0/M_PI);
352
353 fclose(fd);
354
355 if ( rec && rec->mark ) {
356 paramfile = imodfile.base() + "fid.xyz";
357
358 if ( ( fd = fopen(paramfile.c_str(), "w") ) == NULL ) {
359 error_show("write_IMOD_parameters", __FILE__, __LINE__);
360 return(NULL);
361 }
362
363 if ( verbose & VERB_PROCESS )
364 cout << "Writing the 3D marker model to \"" << paramfile << "\"" << endl;
365
366 for ( mark = rec->mark; mark; mark = mark->next ) {
367 fprintf(fd, "%4d%10.2f%10.2f%10.2f %6d %4d", mark->id,
368 mark->loc.x() + rec->origin.x(), mark->loc.y() + rec->origin.y(), mark->loc.z(), 1, mark->id);
369 if ( mark == rec->mark )
370 fprintf(fd, " Pix: %11.5f Dim: %5.0f %5.0f\n",
371 rec->voxel_size, 2*rec->origin.x(), 2*rec->origin.y());
372 else
373 fprintf(fd, "\n");
374 }
375
376 fclose(fd);
377 }
378
379 return(0);
380 }
write_project
int write_project(const char *filename, Bproject *project)
Writing micrograph parameters to a file.
Definition: rwmg.cpp:292
rwmg.h
Header file for reading and writing micrograph parameters.
verbose
int verbose
string_add
Bstring * string_add(Bstring **list, const char *string)
Adds a string to a linked list.
Definition: Bstring.cpp:730
Bproject::rec
Breconstruction * rec
Definition: mg_processing.h:327
Breconstruction::mark
Bmarker * mark
Definition: mg_processing.h:290
Bmicrograph::origin
Vector3< float > origin
Definition: mg_processing.h:204
Bimage::slices_to_images
int slices_to_images()
Changes the slices in a 3D image into a set of 2D images.
Definition: Bimage.cpp:1758
Bmicrograph::id
Bstring id
Definition: mg_processing.h:186
Bmicrograph::img_num
int img_num
Definition: mg_processing.h:195
Vector3::z
Type z()
Definition: Vector3.h:159
utilities.h
Header file for general utilities.
Breconstruction
Definition: mg_processing.h:263
read_img
Bimage * read_img(Bstring filename, int readdata, int img_select)
General driver function to read multiple image formats.
Definition: rwimg.cpp:82
mg_img_proc.h
Header file for image processing from micrograph structures.
Bmarker
Definition: marker.h:21
add_item
char * add_item(char **list, unsigned long size)
Adds an item to a linked list.
Definition: linked_list.cpp:26
read_project
Bproject * read_project(const char *filename, int flags=0)
Reading micrograph parameters from files.
Definition: rwmg.cpp:138
Bstring::length
long length() const
Definition: Bstring.cpp:263
project
Bproject * project
Definition: bshow.cpp:31
error_show
int error_show(const char *message, const char *file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:687
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:101
main
int main(int argc, char **argv)
Definition: mg2imod.c:49
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
write_img
int write_img(Bstring filename, Bimage *p)
General driver function to write multiple image formats.
Definition: rwimg.cpp:263
Bmicrograph::tilt_axis
float tilt_axis
Definition: mg_processing.h:200
project_init
Bproject * project_init()
Initializes a micrograph processing project parameter structure.
Definition: mg_processing.cpp:29
use
const char * use[]
Definition: mg2imod.c:28
timer.h
Utilities for timing functions.
project_from_IMOD
Bproject * project_from_IMOD(Bstring *file_list, int flag)
Creates a project structure using IMOD parameters.
Definition: mg2imod.c:143
Bimage
General image parameter class.
Definition: Bimage.h:140
reconstruction_add
Breconstruction * reconstruction_add(Breconstruction **rec, Bstring &rec_id)
Adds a reconstruction parameter structure to a linked list.
Definition: mg_processing.cpp:672
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
Bfield
Definition: mg_processing.h:240
M_PI
#define M_PI
Definition: utilities.h:53
linked_list.h
Header file for generalized linked list functions.
Bmicrograph::pixel_size
float pixel_size
Definition: mg_processing.h:198
Bfield::id
Bstring id
Definition: mg_processing.h:242
Bstring::next
Bstring * next
Definition: Bstring.h:30
Bimage::sampling
void sampling(double s)
Definition: Bimage.h:426
Bproject::field
Bfield * field
Definition: mg_processing.h:326
VERB_TIME
#define VERB_TIME
Definition: utilities.h:104
Bstring::extension
Bstring extension()
Definition: Bstring.cpp:515
Breconstruction::voxel_size
float voxel_size
Definition: mg_processing.h:275
project_mg_tilt_to_matrix
int project_mg_tilt_to_matrix(Bproject *project)
Sets the matrix from the tilt and axis angles for each micrograph.
Definition: mg_tomography.cpp:1764
Bmicrograph
Definition: mg_processing.h:184
mg_tomography.h
Header file for single particle image processing in Bsoft.
Bmarker::fom
float fom
Definition: marker.h:28
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:314
Bmarker::id
int id
Definition: marker.h:23
Bstring::c_str
const char * c_str()
Definition: Bstring.h:68
Bmarker::next
Bmarker * next
Definition: marker.h:22
Bfield::mg
Bmicrograph * mg
Definition: mg_processing.h:247
field_add
Bfield * field_add(Bfield **field, Bstring &field_id)
Adds a field-of-view parameter structure to a linked list.
Definition: mg_processing.cpp:120
Bstring::base
Bstring base()
Definition: Bstring.cpp:508
Vector3::x
Type x()
Definition: Vector3.h:157
Bmicrograph::block
int block
Definition: mg_processing.h:188
Bstring
Definition: Bstring.h:28
project_kill
int project_kill(Bproject *project)
Frees a whole project.
Definition: mg_processing.cpp:1177
project_set_pixel_size
int project_set_pixel_size(Bproject *project, double pixel_size)
Sets the pixel size for all the micrographs.
Definition: mg_processing.cpp:3222
write_IMOD_parameters
int write_IMOD_parameters(Bstring &imodfile, Bproject *project)
Creates IMOD parameter files from a project structure.
Definition: mg2imod.c:308
Vector3< float >
Bmicrograph::fmg
Bstring fmg
Definition: mg_processing.h:189
timer_report
double timer_report(double lasttime)
Reports the time elapsed since a given time.
Definition: timer.cpp:67
micrograph_get_nominal_origin
Vector3< double > micrograph_get_nominal_origin(Bmicrograph *mg)
Gets the nominal origin for a micrograph.
Definition: mg_img_proc.cpp:423
memory
long memory
Bmarker::loc
Vector3< float > loc
Definition: marker.h:25
Bmicrograph::tilt_angle
float tilt_angle
Definition: mg_processing.h:201
option_kill
int option_kill(Boption *option)
Deallocates a linked list of option structures.
Definition: options.cpp:109
mg_processing.h
Header file for micrograph processing.
Breconstruction::frec
Bstring frec
Definition: mg_processing.h:270
rwimg.h
Header file for 2D and 3D image I/O.
options.h
Header file for option handlers.
Vector3::y
Type y()
Definition: Vector3.h:158
Bimage::images
long images()
Definition: Bimage.h:420
Bstring::empty
bool empty()
Definition: Bstring.h:69
Breconstruction::origin
Vector3< float > origin
Definition: mg_processing.h:276
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:434
VERB_FULL
#define VERB_FULL
Definition: utilities.h:103
micrograph_add
Bmicrograph * micrograph_add(Bmicrograph **mg, Bstring &mg_id)
Adds a micrograph parameter structure to a linked list.
Definition: mg_processing.cpp:461
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:287
timer_start
double timer_start()
Starts timer and prints the time.
Definition: timer.cpp:52
Bmarker::sel
int sel
Definition: marker.h:29
Bproject
Definition: mg_processing.h:316
string_kill
int string_kill(Bstring *list)
Kills a string linked list.
Definition: Bstring.cpp:785
Bmicrograph::next
Bmicrograph * next
Definition: mg_processing.h:185