pattern_sim.c 4.33 KB
Newer Older
1
2
3
4
5
/*
 * main.c
 *
 * (c) 2006-2009 Thomas White <thomas.white@desy.de>
 *
6
 * pattern_sim - Simulate diffraction patterns from small crystals
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 */


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

#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
Thomas White's avatar
Thomas White committed
20
#include <getopt.h>
21

22
#include "image.h"
Thomas White's avatar
Thomas White committed
23
#include "diffraction.h"
24
#include "cell.h"
25
26
#include "utils.h"
#include "hdf5-file.h"
Thomas White's avatar
Thomas White committed
27
#include "detector.h"
28
29
30
31


/* Crystal size in metres */
#define CRYSTAL_SIZE (500.0e-9)
32

33

Thomas White's avatar
Thomas White committed
34
static void show_help(const char *s)
35
{
Thomas White's avatar
Thomas White committed
36
37
	printf("Syntax: %s\n\n", s);
	printf("Simulate diffraction patterns from small crystals\n");
38
39
40
41
42
43
44
	printf(" probed with femosecond pulses from a free electron laser.\n\n");
	printf(" -h, --help                Display this help message\n");
	printf(" --simulation-details      Show details of the simulation\n");
	printf(" --near-bragg              Output h,k,l,I near Bragg conditions\n");
	printf(" -r, --random-orientation  Use a randomly generated orientation\n");
	printf("                            (a new orientation will be used for each image)\n");
	printf(" -n, --number=<N>          Generate N images.  Default 1\n");
Thomas White's avatar
Thomas White committed
45
46
47
}


48
static void show_details()
Thomas White's avatar
Thomas White committed
49
{
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
	printf("This program simulates diffraction patterns from small crystals illuminated\n");
	printf("with femtosecond X-ray pulses from a free electron laser.\n\n");
	printf("Scattering Factors\n");
	printf("------------------\n");
	printf("Scattering factors\n");
}


static struct quaternion read_quaternion()
{
	do {

		int r;
		float w, x, y, z;
		char line[1024];
		char *rval;

		printf("Please input quaternion: w x y z\n");
		rval = fgets(line, 1023, stdin);
		if ( rval == NULL ) return invalid_quaternion();
		chomp(line);

		r = sscanf(line, "%f %f %f %f", &w, &x, &y, &z);
		if ( r == 4 ) {

			struct quaternion quat;

			quat.w = w;
			quat.x = x;
			quat.y = y;
			quat.z = z;

			return quat;

		} else {
			fprintf(stderr, "Invalid rotation '%s'\n", line);
		}

	} while ( 1 );
89
90
91
92
93
}


int main(int argc, char *argv[])
{
94
	int c;
95
	struct image image;
96
	char filename[1024];
Thomas White's avatar
Thomas White committed
97
	int config_simdetails = 0;
98
99
100
101
102
	int config_nearbragg = 0;
	int config_randomquat = 0;
	int number = 1;  /* Index for the current image */
	int n_images = 1;  /* Generate one image by default */
	int done = 0;
Thomas White's avatar
Thomas White committed
103

104
	/* Long options */
Thomas White's avatar
Thomas White committed
105
	const struct option longopts[] = {
106
107
108
109
110
111
		{"help",               0, NULL,               'h'},
		{"simulation-details", 0, &config_simdetails,  1},
		{"near-bragg",         0, &config_nearbragg,   1},
		{"random-orientation", 0, NULL,               'r'},
		{"number",             1, NULL,               'n'},
		{0, 0, NULL, 0}
Thomas White's avatar
Thomas White committed
112
	};
113

114
115
	/* Short options */
	while ((c = getopt_long(argc, argv, "hrn:", longopts, NULL)) != -1) {
116

Thomas White's avatar
Thomas White committed
117
118
119
120
121
		switch (c) {
		case 'h' : {
			show_help(argv[0]);
			return 0;
		}
122

123
124
125
126
127
128
129
130
131
132
		case 'r' : {
			config_randomquat = 1;
			break;
		}

		case 'n' : {
			n_images = atoi(optarg);
			break;
		}

Thomas White's avatar
Thomas White committed
133
134
135
		case 0 : {
			break;
		}
136

Thomas White's avatar
Thomas White committed
137
138
139
		default : {
			return 1;
		}
140
141
142
143
		}

	}

Thomas White's avatar
Thomas White committed
144
	if ( config_simdetails ) {
145
		show_details();
Thomas White's avatar
Thomas White committed
146
147
148
		return 0;
	}

Thomas White's avatar
Thomas White committed
149
	/* Define image parameters */
Thomas White's avatar
Thomas White committed
150
151
	image.width = 1024;
	image.height = 1024;
Thomas White's avatar
Thomas White committed
152
	image.fmode = FORMULATION_CLEN;
Thomas White's avatar
Thomas White committed
153
154
	image.x_centre = 512.5;
	image.y_centre = 512.5;
Thomas White's avatar
Thomas White committed
155
	image.camera_len = 0.05;  /* 5 cm (front CCD can move from 5cm-20cm) */
Thomas White's avatar
Thomas White committed
156
	image.resolution = 13333.3; /* 75 micron pixel size */
Thomas White's avatar
Thomas White committed
157
158
159
160
161
162
163
	image.xray_energy = eV_to_J(2.0e3); /* 2 keV energy */
	image.lambda = ph_en_to_lambda(image.xray_energy);  /* Wavelength */
	image.molecule = NULL;

	/* Splurge a few useful numbers */
	printf("Wavelength is %f nm\n", image.lambda/1.0e-9);

164
165
	do {

166
167
168
		/* Read quaternion from stdin */
		if ( config_randomquat ) {
			image.orientation = random_quaternion();
169
		} else {
170
			image.orientation = read_quaternion();
171
172
		}

173
174
175
176
177
178
179
180
181
182
183
		if ( quaternion_valid(image.orientation) ) {
			fprintf(stderr, "Orientation modulus is not zero!\n");
			return 1;
		}

		/* Ensure no residual information */
		image.qvecs = NULL;
		image.sfacs = NULL;
		image.data = NULL;
		image.twotheta = NULL;
		image.hdr = NULL;
184

185
186
		get_diffraction(&image);
		record_image(&image);
Thomas White's avatar
Thomas White committed
187

188
189
		snprintf(filename, 1023, "results/sim-%i.h5", number);
		number++;
Thomas White's avatar
Thomas White committed
190

191
192
		/* Write the output file */
		hdf5_write(filename, image.data, image.width, image.height);
193

194
195
196
197
198
199
		/* Clean up */
		free(image.data);
		free(image.qvecs);
		free(image.hdr);
		free(image.sfacs);
		free(image.twotheta);
Thomas White's avatar
Thomas White committed
200

201
		if ( n_images && (number >= n_images) ) done = 1;
Thomas White's avatar
Thomas White committed
202

203
	} while ( !done );
204
}