facetron.c 5.41 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * facetron.c
 *
 * Profile fitting for coherent nanocrystallography
 *
 * (c) 2006-2010 Thomas White <taw@physics.org>
 *
 * Part of CrystFEL - crystallography with a FEL
 *
 */


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
23
#include <errno.h>
24
25
26

#include "image.h"
#include "cell.h"
27
28
#include "hdf5-file.h"
#include "detector.h"
29
#include "geometry.h"
30
31
32
33
34
35
36
37
38
39


static void show_help(const char *s)
{
	printf("Syntax: %s [options]\n\n", s);
	printf(
"Profile fitting for coherent nanocrystallography.\n"
"\n"
"  -h, --help                 Display this help message.\n"
"\n"
40
41
"  -i, --input=<filename>     Specify the name of the input stream.\n"
"                              Can be '-' for stdin.\n"
Thomas White's avatar
Thomas White committed
42
43
44
45
"  -g. --geometry=<file>      Get detector geometry from file.\n"
"  -x, --prefix=<p>           Prefix filenames from input file with <p>.\n"
"      --basename             Remove the directory parts of the filenames.\n"
"      --no-check-prefix      Don't attempt to correct the --prefix.\n"
46
47
48
49
);
}


Thomas White's avatar
Thomas White committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
static UnitCell *read_orientation_matrix(FILE *fh)
{
	float u, v, w;
	struct rvec as, bs, cs;
	UnitCell *cell;
	char line[1024];

	if ( fgets(line, 1023, fh) == NULL ) return NULL;
	if ( sscanf(line, "astar = %f %f %f", &u, &v, &w) != 3 ) {
		ERROR("Couldn't read a-star\n");
		return NULL;
	}
	as.u = u*1e9;  as.v = v*1e9;  as.w = w*1e9;
	if ( fgets(line, 1023, fh) == NULL ) return NULL;
	if ( sscanf(line, "bstar = %f %f %f", &u, &v, &w) != 3 ) {
		ERROR("Couldn't read b-star\n");
		return NULL;
	}
	bs.u = u*1e9;  bs.v = v*1e9;  bs.w = w*1e9;
	if ( fgets(line, 1023, fh) == NULL ) return NULL;
	if ( sscanf(line, "cstar = %f %f %f", &u, &v, &w) != 3 ) {
		ERROR("Couldn't read c-star\n");
		return NULL;
	}
	cs.u = u*1e9;  cs.v = v*1e9;  cs.w = w*1e9;
	cell = cell_new_from_axes(as, bs, cs);

	return cell;
}


static int find_chunk(FILE *fh, UnitCell **cell, char **filename)
{
	char line[1024];
	char *rval = NULL;

	do {

		rval = fgets(line, 1023, fh);
		if ( rval == NULL ) continue;

		chomp(line);

		if ( strncmp(line, "Reflections from indexing", 25) != 0 ) {
			continue;
		}

		*filename = strdup(line+29);

		/* Skip two lines (while checking for errors) */
		rval = fgets(line, 1023, fh);
		if ( rval == NULL ) continue;
		rval = fgets(line, 1023, fh);
		if ( rval == NULL ) continue;

		*cell = read_orientation_matrix(fh);
		if ( *cell == NULL ) {
			STATUS("Got filename but no cell for %s\n", *filename);
			continue;
		}

		return 0;

	} while ( rval != NULL );

	return 1;
}


Thomas White's avatar
Thomas White committed
119
120
static char *twiddle_filename(char *filename, int config_basename,
                              const char *prefix)
Thomas White's avatar
Thomas White committed
121
{
Thomas White's avatar
Thomas White committed
122
123
124
125
126
127
128
129
130
131
132
	char *f3;
	size_t len;

	if ( config_basename ) {
		char *f2;
		/* Happy with either the GNU or non-GNU versions of basename()
		 * here.  Because _GNU_SOURCE is defined in configure.ac, we
		 * should have the GNU version. */
		f2 = strdup(basename(filename));
		free(filename);
		filename = f2;
133
134
	}

Thomas White's avatar
Thomas White committed
135
136
137
	len = strlen(prefix)+strlen(filename)+1;
	f3 = malloc(len);
	snprintf(f3, len, "%s%s", prefix, filename);
Thomas White's avatar
Thomas White committed
138

Thomas White's avatar
Thomas White committed
139
140
	free(filename);
	return f3;
141
142
143
}


144
145
146
147
int main(int argc, char *argv[])
{
	int c;
	char *infile = NULL;
148
	FILE *fh;
149
	UnitCell *cell;
150
151
152
	char *filename;
	struct detector *det;
	char *geometry = NULL;
Thomas White's avatar
Thomas White committed
153
154
155
	char *prefix = NULL;
	int config_basename = 0;
	int config_checkprefix = 1;
156
157
158
159
160

	/* Long options */
	const struct option longopts[] = {
		{"help",               0, NULL,               'h'},
		{"input",              1, NULL,               'i'},
161
		{"geometry",           1, NULL,               'g'},
Thomas White's avatar
Thomas White committed
162
163
164
		{"prefix",             1, NULL,               'x'},
		{"basename",           0, &config_basename,    1},
		{"no-check-prefix",    0, &config_checkprefix, 0},
165
166
167
168
		{0, 0, NULL, 0}
	};

	/* Short options */
Thomas White's avatar
Thomas White committed
169
	while ((c = getopt_long(argc, argv, "hi:g:x:", longopts, NULL)) != -1) {
170
171
172
173
174
175
176
177
178
179

		switch (c) {
		case 'h' :
			show_help(argv[0]);
			return 0;

		case 'i' :
			infile = strdup(optarg);
			break;

180
181
		case 'g' :
			geometry = strdup(optarg);
182
183
			break;

Thomas White's avatar
Thomas White committed
184
185
186
187
		case 'x' :
			prefix = strdup(optarg);
			break;

188
189
190
191
192
193
194
195
196
		case 0 :
			break;

		default :
			return 1;
		}

	}

197
198
199
200
201
202
203
204
205
206
207
208
	if ( infile == NULL ) infile = strdup("-");
	if ( strcmp(infile, "-") == 0 ) {
		fh = stdin;
	} else {
		fh = fopen(infile, "r");
	}
	free(infile);
	if ( fh == NULL ) {
		ERROR("Couldn't open input stream '%s'\n", infile);
		return ENOENT;
	}

Thomas White's avatar
Thomas White committed
209
210
211
212
213
214
215
216
	if ( prefix == NULL ) {
		prefix = strdup("");
	} else {
		if ( config_checkprefix ) {
			prefix = check_prefix(prefix);
		}
	}

217
218
219
	det = get_detector_geometry(geometry);
	if ( det == NULL ) {
		ERROR("Failed to read detector geometry from '%s'\n", geometry);
220
221
		return 1;
	}
222
223
224
225
226
227
228
	free(geometry);

	/* Loop over all successfully indexed patterns */
	while ( find_chunk(fh, &cell, &filename) == 0 ) {

		struct image image;
		struct hdfile *hdfile;
Thomas White's avatar
Thomas White committed
229
		struct reflhit *hits;
Thomas White's avatar
Thomas White committed
230
		int np;
231

Thomas White's avatar
Thomas White committed
232
233
		filename = twiddle_filename(filename, config_basename, prefix);

234
235
236
237
238
239
240
241
242
243
244
245
246
		STATUS("Integrating intensities from '%s'\n", filename);

		image.det = det;

		hdfile = hdfile_open(filename);
		if ( hdfile == NULL ) {
			return ENOENT;
		} else if ( hdfile_set_image(hdfile, "/data/data0") ) {
			ERROR("Couldn't select path\n");
			return ENOENT;
		}

		hdf5_read(hdfile, &image, 0);
Thomas White's avatar
Thomas White committed
247

Thomas White's avatar
Thomas White committed
248
		hits = find_intersections(&image, cell, 5.0e-3, 0.0001, &np, 1);
249
250

		hdfile_close(hdfile);
251
		cell_free(cell);
252
253
254
255
256
		free(filename);
		free(image.data);
		free(image.flags);

	}
257

258
259
260
	free(det->panels);
	free(det);
	fclose(fh);
Thomas White's avatar
Thomas White committed
261
	free(prefix);
262
263
264

	return 0;
}