render_hkl.c 16.4 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
/*
 * render_hkl.c
 *
 * Draw pretty renderings of reflection lists
 *
 * (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
#ifdef HAVE_CAIRO
Thomas White's avatar
Thomas White committed
24
25
#include <cairo.h>
#include <cairo-pdf.h>
26
#endif
27
28
29

#include "utils.h"
#include "reflections.h"
30
#include "povray.h"
31
#include "symmetry.h"
32
#include "render.h"
33

34
35
36
37
enum {
	WGHT_I,
	WGHT_SQRTI,
	WGHT_COUNTS,
38
	WGHT_RAWCOUNTS,
39
};
40

41
42
43
44
static void show_help(const char *s)
{
	printf("Syntax: %s [options] <file.hkl>\n\n", s);
	printf(
45
"Render intensity lists in various ways.\n"
46
"\n"
47
"      --povray            Render a 3D animation using POV-ray.\n"
48
#ifdef HAVE_CAIRO
49
"      --zone-axis         Render a 2D zone axis pattern.\n"
50
#endif
51
"\n"
52
"  -d, --down=<h>,<k>,<l>  Indices for the axis in the downward direction.\n"
53
"                           Default: 1,0,0.\n"
54
"  -r, --right=<h>,<k>,<l> Indices for the axis in the 'right' (roughly)\n"
55
56
"                           direction.  Default: 0,1,0.\n"
"  -o, --output=<filename> Output filename (not for POV-ray).\n"
57
58
59
"      --boost=<val>       Squash colour scale by <val>.\n"
"  -p, --pdb=<file>        PDB file from which to get the unit cell.\n"
"  -y, --symmetry=<sym>    Expand reflections according to point group <sym>.\n"
60
61
62
63
64
65
66
"\n"
"  -c, --colscale=<scale>  Use the given colour scale.  Choose from:\n"
"                           mono    : Greyscale, black is zero.\n"
"                           invmono : Greyscale, white is zero.\n"
"                           colour  : Colours scale:\n"
"                                     black-blue-pink-red-orange-yellow-white\n"
"\n"
67
68
"  -w  --weighting=<wght>  Colour/shade the reciprocal lattice points\n"
"                           according to:\n"
69
70
71
72
73
74
"                            I      : the intensity of the reflection.\n"
"                            sqrtI  : the square root of the intensity.\n"
"                            count  : the number of hits for the reflection.\n"
"                                     (after correcting for 'epsilon')\n"
"                            rawcts : the raw number of hits for the\n"
"                                     reflection (no 'epsilon' correction).\n"
75
76
77
78
"\n"
"      --colour-key        Draw (only) the key for the current colour scale.\n"
"  -j <n>                  Run <n> instances of POV-ray in parallel.\n"
"  -h, --help              Display this help message.\n"
79
);
80
81
82
}


83
#ifdef HAVE_CAIRO
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
static void draw_circles(signed int xh, signed int xk, signed int xl,
                         signed int yh, signed int yk, signed int yl,
                         signed int zh, signed int zk, signed int zl,
                         double *ref, unsigned int *counts, ReflItemList *items,
                         const char *sym,
                         cairo_t *dctx, int wght, double boost, int colscale,
                         UnitCell *cell, double radius, double theta,
                         double as, double bs, double cx, double cy,
                         double scale,
                         signed int *max_ux, signed int *max_uy,
                         double *max_val, double *max_u, double *max_v,
                         double *max_res)
{
	signed int xi, yi;

	if ( dctx == NULL ) {
		*max_u = 0.0;  *max_v = 0.0;  *max_val = 0.0;
		*max_res = 0.0;  *max_ux = 0;  *max_uy = 0;
	}

	/* Loop across the two basis directions */
	for ( xi=-INDMAX; xi<INDMAX; xi++ ) {
	for ( yi=-INDMAX; yi<INDMAX; yi++ ) {

		double u, v, val, res;
		signed int h, k, l;
Thomas White's avatar
Thomas White committed
110
		signed int he, ke, le;
111
112
113
114
115
116

		h = xi*xh + yi*yh;
		k = xi*xk + yi*yk;
		l = xi*xl + yi*yl;

		/* Got this reflection? */
Thomas White's avatar
Thomas White committed
117
118
		if ( find_unique_equiv(items, h, k, l, sym,
		                       &he, &ke, &le) == 0 ) continue;
119
120
121

		switch ( wght ) {
		case WGHT_I :
Thomas White's avatar
Thomas White committed
122
			val = lookup_intensity(ref, he, ke, le);
123
124
			break;
		case WGHT_SQRTI :
Thomas White's avatar
Thomas White committed
125
			val = lookup_intensity(ref, he, ke, le);
126
127
128
			val = (val>0.0) ? sqrt(val) : 0.0;
			break;
		case WGHT_COUNTS :
Thomas White's avatar
Thomas White committed
129
130
			val = lookup_count(counts, he, ke, le);
			val /= (float)num_equivs(he, ke, le, sym);
131
132
			break;
		case WGHT_RAWCOUNTS :
Thomas White's avatar
Thomas White committed
133
			val = lookup_count(counts, he, ke, le);
134
135
136
137
138
139
			break;
		default :
			ERROR("Invalid weighting.\n");
			abort();
		}

140
		/* Absolute location in image based on 2D basis */
Thomas White's avatar
Thomas White committed
141
142
		u = (double)xi*as*sin(theta);
		v = (double)xi*as*cos(theta) + (double)yi*bs;
143

144
		if ( dctx != NULL ) {
145

146
			float r, g, b;
147

148
149
150
			cairo_arc(dctx, ((double)cx)+u*scale,
			                ((double)cy)+v*scale,
			                radius, 0, 2*M_PI);
151

152
153
154
155
			render_scale(val, *max_val/boost, colscale,
			             &r, &g, &b);
			cairo_set_source_rgb(dctx, r, g, b);
			cairo_fill(dctx);
156

157
		} else {
158

159
160
161
			/* Find max vectors in plane for scaling */
			if ( fabs(u) > fabs(*max_u) ) *max_u = fabs(u);
			if ( fabs(v) > fabs(*max_v) ) *max_v = fabs(v);
162

163
164
165
			/* Find max value for colour scale */
			if ( fabs(val) > fabs(*max_val) ) {
				*max_val = fabs(val);
166
167
			}

168
			/* Find max indices */
Thomas White's avatar
Thomas White committed
169
170
171
172
			if ( (yi==0) && (fabs(xi) > *max_ux) )
				*max_ux = fabs(xi);
			if ( (xi==0) && (fabs(yi) > *max_uy) )
				*max_uy = fabs(yi);
173
174

			/* Find max resolution */
Thomas White's avatar
Thomas White committed
175
			res = resolution(cell, h, k, l);
176
			if ( res > *max_res ) *max_res = res;
177
178
179
180
181
182
183
		}

	}
	}
}


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
static void render_overlined_indices(cairo_t *dctx,
                                     signed int h, signed int k, signed int l)
{
	char tmp[256];
	cairo_text_extents_t size;
	double x, y;
	const double sh = 39.0;

	cairo_get_current_point(dctx, &x, &y);
	cairo_set_line_width(dctx, 4.0);

	/* Draw 'h' */
	snprintf(tmp, 255, "%i", abs(h));
	cairo_text_extents(dctx, tmp, &size);
	cairo_show_text(dctx, tmp);
	cairo_fill(dctx);
	if ( h < 0 ) {
		cairo_move_to(dctx, x+size.x_bearing, y-sh);
		cairo_rel_line_to(dctx, size.width, 0.0);
		cairo_stroke(dctx);
	}
	x += size.x_advance;

	/* Draw 'k' */
	cairo_move_to(dctx, x, y);
	snprintf(tmp, 255, "%i", abs(k));
	cairo_text_extents(dctx, tmp, &size);
	cairo_show_text(dctx, tmp);
	cairo_fill(dctx);
	if ( k < 0 ) {
		cairo_move_to(dctx, x+size.x_bearing, y-sh);
		cairo_rel_line_to(dctx, size.width, 0.0);
		cairo_stroke(dctx);
	}
	x += size.x_advance;

	/* Draw 'l' */
	cairo_move_to(dctx, x, y);
	snprintf(tmp, 255, "%i", abs(l));
	cairo_text_extents(dctx, tmp, &size);
	cairo_show_text(dctx, tmp);
	cairo_fill(dctx);
	if ( l < 0 ) {
		cairo_move_to(dctx, x+size.x_bearing, y-sh);
		cairo_rel_line_to(dctx, size.width, 0.0);
		cairo_stroke(dctx);
	}
}


234
static void render_za(UnitCell *cell, ReflItemList *items,
235
                      double *ref, unsigned int *counts,
236
237
                      double boost, const char *sym, int wght, int colscale,
                      signed int xh, signed int xk, signed int xl,
238
239
                      signed int yh, signed int yk, signed int yl,
                      const char *outfile)
240
{
Thomas White's avatar
Thomas White committed
241
242
	cairo_surface_t *surface;
	cairo_t *dctx;
243
	double max_u, max_v, max_res, max_val;
244
	double scale_u, scale_v, scale;
Thomas White's avatar
Thomas White committed
245
	double sep_u, sep_v, max_r;
246
	double u, v;
247
	signed int max_ux, max_uy;
Thomas White's avatar
Thomas White committed
248
	double as, bs, theta;
249
250
251
	double asx, asy, asz;
	double bsx, bsy, bsz;
	double csx, csy, csz;
Thomas White's avatar
Thomas White committed
252
	float wh, ht;
253
254
255
256
257
258
259
260
	signed int zh, zk, zl;
	double xx, xy, xz;
	double yx, yy, yz;
	char tmp[256];
	cairo_text_extents_t size;
	double cx, cy;
	const double border = 200.0;

261
	/* Vector product to determine the zone axis. */
262
263
264
265
	zh = xk*yl - xl*yk;
	zk = - xh*yl + xl*yh;
	zl = xh*yk - xk*yh;
	STATUS("Zone axis is %i %i %i\n", zh, zk, zl);
266

267
	/* Size of output and centre definition */
Thomas White's avatar
Thomas White committed
268
269
	wh = 1024;
	ht = 1024;
270

Thomas White's avatar
Thomas White committed
271
	/* Work out reciprocal lattice spacings and angles for this cut */
272
	if ( cell_get_reciprocal(cell, &asx, &asy, &asz,
Thomas White's avatar
Thomas White committed
273
	                          &bsx, &bsy, &bsz,
274
275
276
277
	                          &csx, &csy, &csz) ) {
		ERROR("Couldn't get reciprocal parameters\n");
		return;
	}
278
279
280
281
282
283
284
285
286
287
	xx = xh*asx + xk*bsx + xl*csx;
	xy = xh*asy + xk*bsy + xl*csy;
	xz = xh*asz + xk*bsz + xl*csz;
	yx = yh*asx + yk*bsx + yl*csx;
	yy = yh*asy + yk*bsy + yl*csy;
	yz = yh*asz + yk*bsz + yl*csz;
	theta = angle_between(xx, xy, xz, yx, yy, yz);
	as = modulus(xx, xy, xz) / 1e9;
	bs = modulus(yx, yy, yz) / 1e9;

288
	scale = 1.0;
289
290
291
292
	draw_circles(xh, xk, xl, yh, yk, yl, zh, zk, zl,
	             ref, counts, items, sym, NULL, wght, boost, colscale, cell,
	             0.0, theta, as, bs, cx, cy, scale,
	             &max_ux, &max_uy, &max_val, &max_u, &max_v, &max_res);
293

Thomas White's avatar
Thomas White committed
294
	max_res /= 1e9;
295
296
	printf("Maximum resolution is 1/d = %5.3f nm^-1, d = %5.3f nm\n",
	       max_res*2.0, 1.0/(max_res*2.0));
Thomas White's avatar
Thomas White committed
297

298
	if ( max_val <= 0.0 ) {
Thomas White's avatar
Thomas White committed
299
		max_r = 4.0;
300
		STATUS("Couldn't find max value.\n");
Thomas White's avatar
Thomas White committed
301
		goto out;
302
303
	}

Thomas White's avatar
Thomas White committed
304
	/* Choose whichever scaling factor gives the smallest value */
305
306
	scale_u = ((double)wh-border) / (2.0*max_u);
	scale_v = ((double)ht-border) / (2.0*max_v);
307
	scale = (scale_u < scale_v) ? scale_u : scale_v;
308

309
310
	sep_u = scale*as;
	sep_v = scale*bs;
311
	/* We are interested in the smaller of the two separations */
312
	max_r = (sep_u < sep_v) ? sep_u : sep_v;
313
	max_r /= 2.0;  /* Max radius is half the separation */
314
	max_r -= 1.0;  /* Add a tiny separation between circles */
315
316
317
	if ( max_r < 1.0 ) {
		ERROR("Circle radius is probably too small (%f).\n", max_r);
	}
Thomas White's avatar
Thomas White committed
318

319
320
	if ( outfile == NULL ) outfile = "za.pdf";
	surface = cairo_pdf_surface_create(outfile, wh, ht);
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342

	if ( cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS ) {
		fprintf(stderr, "Couldn't create Cairo surface\n");
		cairo_surface_destroy(surface);
		return;
	}

	dctx = cairo_create(surface);

	/* Black background */
	cairo_rectangle(dctx, 0.0, 0.0, wh, ht);
	cairo_set_source_rgb(dctx, 0.0, 0.0, 0.0);
	cairo_fill(dctx);

	/* Test size of text that goes to the right(ish) */
	cairo_set_font_size(dctx, 40.0);
	snprintf(tmp, 255, "%i%i%i", abs(xh), abs(xk), abs(xl));
	cairo_text_extents(dctx, tmp, &size);

	cx = 532.0 - size.width;
	cy = 512.0 - 20.0;

343
344
345
346
	draw_circles(xh, xk, xl, yh, yk, yl, zh, zk, zl,
	             ref, counts, items, sym, dctx, wght, boost, colscale, cell,
	             max_r, theta, as, bs, cx, cy, scale,
	             NULL, NULL, &max_val, NULL, NULL, NULL);
347

Thomas White's avatar
Thomas White committed
348
349
out:
	/* Centre marker */
350
351
	cairo_arc(dctx, (double)cx,
			(double)cy, max_r, 0, 2*M_PI);
Thomas White's avatar
Thomas White committed
352
353
354
	cairo_set_source_rgb(dctx, 1.0, 0.0, 0.0);
	cairo_fill(dctx);

355
	/* Draw indexing lines */
356
	cairo_set_line_cap(dctx, CAIRO_LINE_CAP_ROUND);
357
	cairo_set_line_width(dctx, 4.0);
358
	cairo_move_to(dctx, (double)cx, (double)cy);
359
360
	u = (2.0+max_ux)*as*sin(theta);
	v = (2.0+max_ux)*as*cos(theta);
361
	cairo_line_to(dctx, cx+u*scale, cy+v*scale);
362
363
364
	cairo_set_source_rgb(dctx, 0.0, 1.0, 0.0);
	cairo_stroke(dctx);

365
	cairo_set_font_size(dctx, 40.0);
366
	snprintf(tmp, 255, "%i%i%i", abs(xh), abs(xk), abs(xl));
367
368
369
	cairo_text_extents(dctx, tmp, &size);

	cairo_move_to(dctx, cx+u*scale + 20.0, cy+v*scale + size.height/2.0);
370
	render_overlined_indices(dctx, xh, xk, xl);
371
372
	cairo_fill(dctx);

373
	snprintf(tmp, 255, "%i%i%i", abs(yh), abs(yk), abs(yl));
374
375
376
	cairo_text_extents(dctx, tmp, &size);

	cairo_move_to(dctx, (double)cx, (double)cy);
377
	u = 0.0;
378
	v = (2.0+max_uy)*bs;
379
	cairo_line_to(dctx, cx+u*scale, cy+v*scale);
380
381
382
	cairo_set_source_rgb(dctx, 0.0, 1.0, 0.0);
	cairo_stroke(dctx);

383
384
	cairo_move_to(dctx, cx+u*scale - size.width/2.0,
	                    cy+v*scale + size.height + 20.0);
385
	render_overlined_indices(dctx, yh, yk, yl);
386
387
	cairo_fill(dctx);

Thomas White's avatar
Thomas White committed
388
389
390
	cairo_surface_finish(surface);
	cairo_destroy(dctx);
}
391

392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
static int render_key(int colscale)
{
	cairo_surface_t *surface;
	cairo_t *dctx;
	float wh, ht;
	float y;

	wh = 128;
	ht = 1024;

	surface = cairo_pdf_surface_create("key.pdf", wh, ht);

	if ( cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS ) {
		fprintf(stderr, "Couldn't create Cairo surface\n");
		cairo_surface_destroy(surface);
		return 1;
	}

	dctx = cairo_create(surface);

	for ( y=0; y<ht; y++ ) {

		float r, g, b;

		cairo_rectangle(dctx, 0.0, y, wh, y+1.0);

		render_scale(ht-y, ht, colscale, &r, &g, &b);
		cairo_set_source_rgb(dctx, r, g, b);

		cairo_fill(dctx);

	}

	cairo_surface_finish(surface);
	cairo_destroy(dctx);

	return 0;
}
431
#endif
Thomas White's avatar
Thomas White committed
432
433
434
435
436
437
438
439
440
441


int main(int argc, char *argv[])
{
	int c;
	UnitCell *cell;
	char *infile;
	double *ref;
	int config_povray = 0;
	int config_zoneaxis = 0;
Thomas White's avatar
Thomas White committed
442
	int config_sqrt = 0;
443
	int config_colkey = 0;
Thomas White's avatar
Thomas White committed
444
	unsigned int nproc = 1;
445
	char *pdb = NULL;
446
	int r = 0;
447
	double boost = 1.0;
448
	char *sym = NULL;
449
450
	char *weighting = NULL;
	int wght;
451
452
	int colscale;
	char *cscale = NULL;
Thomas White's avatar
Thomas White committed
453
	unsigned int *cts;
454
455
456
457
	signed int dh=1, dk=0, dl=0;
	signed int rh=0, rk=1, rl=0;
	char *down = NULL;
	char *right = NULL;
458
	char *outfile = NULL;
Thomas White's avatar
Thomas White committed
459
460
461
462
463
464

	/* Long options */
	const struct option longopts[] = {
		{"help",               0, NULL,               'h'},
		{"povray",             0, &config_povray,      1},
		{"zone-axis",          0, &config_zoneaxis,    1},
465
		{"output",             1, NULL,               'o'},
466
		{"pdb",                1, NULL,               'p'},
467
		{"boost",              1, NULL,               'b'},
468
		{"symmetry",           1, NULL,               'y'},
469
		{"weighting",          1, NULL,               'w'},
470
		{"colscale",           1, NULL,               'c'},
471
472
		{"down",               1, NULL,               'd'},
		{"right",              1, NULL,               'r'},
473
		{"counts",             0, &config_sqrt,        1},
474
		{"colour-key",         0, &config_colkey,      1},
Thomas White's avatar
Thomas White committed
475
476
477
478
		{0, 0, NULL, 0}
	};

	/* Short options */
479
	while ((c = getopt_long(argc, argv, "hj:p:w:c:y:d:r:",
480
	                        longopts, NULL)) != -1) {
Thomas White's avatar
Thomas White committed
481
482

		switch (c) {
Thomas White's avatar
Thomas White committed
483
		case 'h' :
Thomas White's avatar
Thomas White committed
484
485
486
			show_help(argv[0]);
			return 0;

Thomas White's avatar
Thomas White committed
487
		case 'j' :
Thomas White's avatar
Thomas White committed
488
489
490
			nproc = atoi(optarg);
			break;

491
492
493
494
		case 'p' :
			pdb = strdup(optarg);
			break;

495
496
497
498
		case 'b' :
			boost = atof(optarg);
			break;

499
500
501
502
		case 'y' :
			sym = strdup(optarg);
			break;

503
504
505
506
		case 'w' :
			weighting = strdup(optarg);
			break;

507
508
509
510
		case 'c' :
			cscale = strdup(optarg);
			break;

511
512
513
514
515
516
517
518
		case 'd' :
			down = strdup(optarg);
			break;

		case 'r' :
			right = strdup(optarg);
			break;

519
520
521
522
		case 'o' :
			outfile = strdup(optarg);
			break;

Thomas White's avatar
Thomas White committed
523
		case 0 :
Thomas White's avatar
Thomas White committed
524
525
			break;

Thomas White's avatar
Thomas White committed
526
		default :
Thomas White's avatar
Thomas White committed
527
528
529
530
531
			return 1;
		}

	}

532
533
534
535
	if ( pdb == NULL ) {
		pdb = strdup("molecule.pdb");
	}

536
537
538
539
	if ( sym == NULL ) {
		sym = strdup("1");
	}

540
541
542
543
544
545
546
547
548
549
	if ( weighting == NULL ) {
		weighting = strdup("I");
	}

	if ( strcmp(weighting, "I") == 0 ) {
		wght = WGHT_I;
	} else if ( strcmp(weighting, "sqrtI") == 0 ) {
		wght = WGHT_SQRTI;
	} else if ( strcmp(weighting, "count") == 0 ) {
		wght = WGHT_COUNTS;
550
551
	} else if ( strcmp(weighting, "counts") == 0 ) {
		wght = WGHT_COUNTS;
552
553
	} else if ( strcmp(weighting, "rawcts") == 0 ) {
		wght = WGHT_RAWCOUNTS;
554
555
556
557
	} else if ( strcmp(weighting, "rawcount") == 0 ) {
		wght = WGHT_RAWCOUNTS;
	} else if ( strcmp(weighting, "rawcounts") == 0 ) {
		wght = WGHT_RAWCOUNTS;
558
559
560
561
	} else {
		ERROR("Unrecognised weighting '%s'\n", weighting);
		return 1;
	}
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
	free(weighting);

	if ( cscale == NULL ) {
		cscale = strdup("mono");
	}

	if ( strcmp(cscale, "mono") == 0 ) {
		colscale = SCALE_MONO;
	} else if ( strcmp(cscale, "invmono") == 0 ) {
		colscale = SCALE_INVMONO;
	} else if ( strcmp(cscale, "colour") == 0 ) {
		colscale = SCALE_COLOUR;
	} else if ( strcmp(cscale, "color") == 0 ) {
		colscale = SCALE_COLOUR;
	} else {
		ERROR("Unrecognised colour scale '%s'\n", cscale);
		return 1;
	}
	free(cscale);
581

582
583
584
585
	if ( config_colkey ) {
		return render_key(colscale);
	}

586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
	if ( config_zoneaxis ) {
		if ( (( down == NULL ) && ( right != NULL ))
		  || (( down != NULL ) && ( right == NULL )) ) {
			ERROR("Either specify both 'down' and 'right', or neither.\n");
			return 1;
		}
		if ( down != NULL ) {
			int r;
			r = sscanf(down, "%i,%i,%i", &dh, &dk, &dl);
			if ( r != 3 ) {
				ERROR("Invalid format for 'down'\n");
				return 1;
			}
		}
		if ( right != NULL ) {
			int r;
			r = sscanf(right, "%i,%i,%i", &rh, &rk, &rl);
			if ( r != 3 ) {
				ERROR("Invalid format for 'right'\n");
				return 1;
			}
		}
	}

Thomas White's avatar
Thomas White committed
610
611
	infile = argv[optind];

612
	cell = load_cell_from_pdb(pdb);
613
614
615
616
	if ( cell == NULL ) {
		ERROR("Couldn't load unit cell from %s\n", pdb);
		return 1;
	}
Thomas White's avatar
Thomas White committed
617
	ref = new_list_intensity();
Thomas White's avatar
Thomas White committed
618
	cts = new_list_count();
Thomas White's avatar
Thomas White committed
619
	ReflItemList *items = read_reflections(infile, ref, NULL, cts);
Thomas White's avatar
Thomas White committed
620
621
622
623
624
625
	if ( ref == NULL ) {
		ERROR("Couldn't open file '%s'\n", infile);
		return 1;
	}

	if ( config_povray ) {
626
		r = povray_render_animation(cell, ref, cts, nproc);
Thomas White's avatar
Thomas White committed
627
	} else if ( config_zoneaxis ) {
628
#ifdef HAVE_CAIRO
629
		render_za(cell, items, ref, cts, boost, sym, wght, colscale,
630
		          rh, rk, rl, dh, dk, dl, outfile);
631
632
633
634
635
#else
		ERROR("This version of CrystFEL was compiled without Cairo");
		ERROR(" support, which is required to plot a zone axis");
		ERROR(" pattern.  Sorry!\n");
#endif
Thomas White's avatar
Thomas White committed
636
637
638
639
	} else {
		ERROR("Try again with either --povray or --zone-axis.\n");
	}

640
	free(pdb);
641
	free(sym);
642
	delete_items(items);
643
	if ( outfile != NULL ) free(outfile);
644

645
	return r;
646
}