facetron.c 5.36 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"
Thomas White's avatar
Thomas White committed
40
41
"  -i, --input=<filename>     Specify the name of the input 'stream'.\n"
"                              (must be a file, not e.g. 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
	if ( infile == NULL ) infile = strdup("-");
Thomas White's avatar
Thomas White committed
198
	fh = fopen(infile, "r");
199
200
201
202
	if ( fh == NULL ) {
		ERROR("Couldn't open input stream '%s'\n", infile);
		return ENOENT;
	}
Thomas White's avatar
Thomas White committed
203
	free(infile);
204

Thomas White's avatar
Thomas White committed
205
206
207
208
209
210
211
212
	if ( prefix == NULL ) {
		prefix = strdup("");
	} else {
		if ( config_checkprefix ) {
			prefix = check_prefix(prefix);
		}
	}

213
214
215
	det = get_detector_geometry(geometry);
	if ( det == NULL ) {
		ERROR("Failed to read detector geometry from '%s'\n", geometry);
216
217
		return 1;
	}
218
219
220
221
222
223
224
	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
225
		struct reflhit *hits;
Thomas White's avatar
Thomas White committed
226
		int np;
227

Thomas White's avatar
Thomas White committed
228
229
		filename = twiddle_filename(filename, config_basename, prefix);

230
231
232
233
234
235
236
237
238
239
240
241
242
		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
243

Thomas White's avatar
Thomas White committed
244
		hits = find_intersections(&image, cell, 5.0e-3, 0.0001, &np, 1);
245
246

		hdfile_close(hdfile);
247
		cell_free(cell);
248
249
250
251
252
		free(filename);
		free(image.data);
		free(image.flags);

	}
253

254
255
256
	free(det->panels);
	free(det);
	fclose(fh);
Thomas White's avatar
Thomas White committed
257
	free(prefix);
258
259
260

	return 0;
}