get_hkl.c 4.54 KB
Newer Older
1
2
3
4
5
/*
 * get_hkl.c
 *
 * Small program to write out a list of h,k,l,I values given a structure
 *
Thomas White's avatar
Thomas White committed
6
 * (c) 2006-2010 Thomas White <taw@physics.org>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *
 * 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>

#include "utils.h"
#include "sfac.h"
#include "reflections.h"


static void show_help(const char *s)
{
	printf("Syntax: %s [options]\n\n", s);
	printf(
"Write idealised intensity lists.\n"
"\n"
Thomas White's avatar
Thomas White committed
35
36
"  -h, --help                 Display this help message.\n"
"\n"
Thomas White's avatar
Thomas White committed
37
38
"  -t, --template=<filename>  Only include reflections mentioned in file.\n"
"      --poisson              Simulate Poisson samples.\n"
Thomas White's avatar
Thomas White committed
39
"      --twin                 Generate twinned data.\n"
40
41
"  -o, --output=<filename>    Output filename (default: stdout).\n"
"  -i, --intensities=<file>   Read intensities from file instead of\n"
42
43
44
"                              calculating them from scratch.  You might use\n"
"                              this if you need to apply noise or twinning.\n"
"  -p, --pdb=<file>           PDB file from which to get the structure.\n"
Thomas White's avatar
Thomas White committed
45
);
Thomas White's avatar
Thomas White committed
46
47
48
49
50
51
52
53
54
55
56
57
58
}


/* Apply Poisson noise to all reflections */
static void noisify_reflections(double *ref)
{
	signed int h, k, l;

	for ( h=-INDMAX; h<INDMAX; h++ ) {
	for ( k=-INDMAX; k<INDMAX; k++ ) {
	for ( l=-INDMAX; l<INDMAX; l++ ) {

		double val;
Thomas White's avatar
Thomas White committed
59
		int c;
Thomas White's avatar
Thomas White committed
60
61

		val = lookup_intensity(ref, h, k, l);
Thomas White's avatar
Thomas White committed
62
63
		c = poisson_noise(val);
		set_intensity(ref, h, k, l, c);
Thomas White's avatar
Thomas White committed
64
65
66

	}
	}
Thomas White's avatar
Thomas White committed
67
	progress_bar(h+INDMAX, 2*INDMAX, "Simulating noise");
Thomas White's avatar
Thomas White committed
68
	}
69
70
71
72
73
74
}


int main(int argc, char *argv[])
{
	int c;
Thomas White's avatar
Thomas White committed
75
	double *ideal_ref;
76
	double *phases;
77
	struct molecule *mol;
Thomas White's avatar
Thomas White committed
78
79
	char *template = NULL;
	int config_noisify = 0;
Thomas White's avatar
Thomas White committed
80
	int config_twin = 0;
Thomas White's avatar
Thomas White committed
81
	char *output = NULL;
82
	char *input = NULL;
Thomas White's avatar
Thomas White committed
83
	signed int h, k, l;
84
	char *filename = NULL;
Thomas White's avatar
Thomas White committed
85
86
	ReflItemList *input_items;
	ReflItemList *write_items;
87
88
89
90

	/* Long options */
	const struct option longopts[] = {
		{"help",               0, NULL,               'h'},
Thomas White's avatar
Thomas White committed
91
92
		{"template",           1, NULL,               't'},
		{"poisson",            0, &config_noisify,     1},
Thomas White's avatar
Thomas White committed
93
		{"output",             1, NULL,               'o'},
Thomas White's avatar
Thomas White committed
94
		{"twin",               0, &config_twin,        1},
95
		{"intensities",        1, NULL,               'i'},
96
		{"pdb",                1, NULL,               'p'},
97
98
99
100
		{0, 0, NULL, 0}
	};

	/* Short options */
101
	while ((c = getopt_long(argc, argv, "ht:o:i:p:", longopts, NULL)) != -1) {
102
103

		switch (c) {
Thomas White's avatar
Thomas White committed
104
		case 'h' :
105
106
107
			show_help(argv[0]);
			return 0;

Thomas White's avatar
Thomas White committed
108
		case 't' :
Thomas White's avatar
Thomas White committed
109
110
111
			template = strdup(optarg);
			break;

Thomas White's avatar
Thomas White committed
112
		case 'o' :
Thomas White's avatar
Thomas White committed
113
114
115
			output = strdup(optarg);
			break;

Thomas White's avatar
Thomas White committed
116
		case 'i' :
117
118
119
			input = strdup(optarg);
			break;

Thomas White's avatar
Thomas White committed
120
		case 'p' :
121
122
123
			filename = strdup(optarg);
			break;

Thomas White's avatar
Thomas White committed
124
		case 0 :
125
126
			break;

Thomas White's avatar
Thomas White committed
127
		default :
128
129
130
131
132
			return 1;
		}

	}

133
134
135
136
137
	if ( filename == NULL ) {
		filename = strdup("molecule.pdb");
	}

	mol = load_molecule(filename);
Thomas White's avatar
Thomas White committed
138
	phases = new_list_phase();
139
	if ( input == NULL ) {
Thomas White's avatar
Thomas White committed
140
		input_items = new_items();
141
		ideal_ref = get_reflections(mol, eV_to_J(1790.0), 1/(0.05e-9),
Thomas White's avatar
Thomas White committed
142
		                            phases, input_items);
143
	} else {
Thomas White's avatar
Thomas White committed
144
145
146
		ideal_ref = new_list_intensity();
		phases = new_list_phase();
		input_items = read_reflections(input, ideal_ref, phases, NULL);
147
148
		free(input);
	}
149

150
	if ( config_noisify ) noisify_reflections(ideal_ref);
Thomas White's avatar
Thomas White committed
151

Thomas White's avatar
Thomas White committed
152
153
154
155
156
157
	if ( config_twin ) {

		for ( h=-INDMAX; h<=INDMAX; h++ ) {
		for ( k=-INDMAX; k<=INDMAX; k++ ) {
		for ( l=-INDMAX; l<=INDMAX; l++ ) {

158
159
160
161
162
163
164
			double a, b, c, d;
			double t;

			if ( abs(h+k) > INDMAX ) {
				set_intensity(ideal_ref, h, k, l, 0.0);
				continue;
			}
Thomas White's avatar
Thomas White committed
165

166
167
			a = lookup_intensity(ideal_ref, h, k, l);
			b = lookup_intensity(ideal_ref, k, h, -l);
168
169
170
171
			c = lookup_intensity(ideal_ref, -(h+k), k, -l);
			d = lookup_intensity(ideal_ref, -(h+k), h, l);

			t = (a+b+c+d)/4.0;
Thomas White's avatar
Thomas White committed
172

173
174
175
176
			set_intensity(ideal_ref, h, k, l, t);
			set_intensity(ideal_ref, k, h, -l, t);
			set_intensity(ideal_ref, -(h+k), h, l, t);
			set_intensity(ideal_ref, -(h+k), k, -l, t);
Thomas White's avatar
Thomas White committed
177
178
179
180
181
182
183

		}
		}
		}

	}

Thomas White's avatar
Thomas White committed
184
185
186
187
188
189
190
191
192
193
	if ( template ) {
		/* Write out only reflections which are in the template
		 * (and which we have in the input) */
		ReflItemList *template_items;
		template_items = read_reflections(template, NULL, NULL, NULL);
		write_items = intersection_items(input_items, template_items);
		delete_items(template_items);
	} else {
		/* Write out all reflections */
		write_items = new_items();
Thomas White's avatar
Thomas White committed
194
		/* (quick way of copying a list) */
Thomas White's avatar
Thomas White committed
195
196
197
198
199
200
201
202
		union_items(write_items, input_items);
	}

	write_reflections(output, write_items, ideal_ref, phases, NULL,
	                  mol->cell);

	delete_items(input_items);
	delete_items(write_items);
203
204
205

	return 0;
}