hdfsee.c 7.15 KB
Newer Older
Thomas White's avatar
Thomas White committed
1
2
3
4
5
/*
 * hdfsee.c
 *
 * Quick yet non-crappy HDF viewer
 *
6
7
 * Copyright © 2012 Deutsches Elektronen-Synchrotron DESY,
 *                  a research centre of the Helmholtz Association.
8
 * Copyright © 2012 Richard Kirian
9
10
11
 *
 * Authors:
 *   2009-2012 Thomas White <taw@physics.org>
12
 *   2012      Richard Kirian
Thomas White's avatar
Thomas White committed
13
 *
Thomas White's avatar
Thomas White committed
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * This file is part of CrystFEL.
 *
 * CrystFEL is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * CrystFEL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with CrystFEL.  If not, see <http://www.gnu.org/licenses/>.
Thomas White's avatar
Thomas White committed
28
29
30
31
32
33
34
35
36
 *
 */


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

#include <gtk/gtk.h>
37
#include <getopt.h>
Thomas White's avatar
Thomas White committed
38

39
#include "dw-hdfsee.h"
Thomas White's avatar
Thomas White committed
40
#include "utils.h"
41
#include "render.h"
Thomas White's avatar
Thomas White committed
42
43
44
45
46
47
48


/* Global program state */
DisplayWindow *main_window_list[64];
size_t main_n_windows = 0;


49
50
51
52
53
54
55
56
57
static void show_help(const char *s)
{
	printf("Syntax: %s [options] image.h5\n\n", s);
	printf(
"Quick HDF5 image viewer.\n"
"\n"
"  -h, --help                       Display this help message.\n"
"\n"
"  -p, --peak-overlay=<filename>    Draw circles in positions listed in file.\n"
58
"      --ring-size=<n>              Set the size for those circles.\n"
59
"  -i, --int-boost=<n>              Multiply intensity by <n>.\n"
60
"  -b, --binning=<n>                Set display binning to <n>.\n"
61
62
63
64
65
"      --filter-cm                  Perform common-mode noise subtraction.\n"
"      --filter-noise               Apply an aggressive noise filter which\n"
"                                    sets all pixels in each 3x3 region to\n"
"                                    zero if any of them have negative\n"
"                                    values.\n"
66
67
"      --show-rings                 Overlay rings that indicate resolution.\n"
"      --simple-rings=XX,YY,...     Overlay rings at specified radii XX, YY, ...\n"
Thomas White's avatar
Thomas White committed
68
"                                    in pixel units.\n"
69
70
71
72
73
74
"  -c, --colscale=<scale>           Use the given colour scale.  Choose from:\n"
"                                    mono    : Greyscale, black is zero.\n"
"                                    invmono : Greyscale, white is zero.\n"
"                                    colour  : Colour scale:\n"
"                                               black-blue-pink-red-orange-\n"
"                                               -yellow-white.\n"
Thomas White's avatar
Thomas White committed
75
76
"  -e, --image=<element>            Start up displaying this image from the\n"
"                                    HDF5 file.  Example: /data/data0.\n"
Thomas White's avatar
Thomas White committed
77
"  -g, --geometry=<filename>        Use geometry from file for display.\n"
78
79
80
81
"\n");
}


Thomas White's avatar
Thomas White committed
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
/* Called to notify that an image display window has been closed */
void hdfsee_window_closed(DisplayWindow *dw)
{
	size_t i;

	for ( i=0; i<main_n_windows; i++ ) {

		if ( main_window_list[i] == dw ) {

			size_t j;

			for ( j=i+1; j<main_n_windows; j++ ) {
				main_window_list[j] = main_window_list[j+1];
			}

		}

	}

	main_n_windows--;

	if ( main_n_windows == 0 ) gtk_exit(0);

}


int main(int argc, char *argv[])
{
110
111
112
113
	int c;
	size_t i;
	int nfiles;
	char *peaks = NULL;
114
115
	int boost = 1;
	int binning = 2;
116
117
	int config_cmfilter = 0;
	int config_noisefilter = 0;
Thomas White's avatar
Thomas White committed
118
	int config_showrings = 0;
119
120
	int colscale = SCALE_COLOUR;
	char *cscale = NULL;
Thomas White's avatar
Thomas White committed
121
	char *element = NULL;
122
	char *geometry = NULL;
123
	double ring_size = 5.0;
124
125
126
	char *reslist = NULL;
	double ring_radii[128];
	int n_rings = -1;
Thomas White's avatar
Thomas White committed
127

128
129
130
131
	/* Long options */
	const struct option longopts[] = {
		{"help",               0, NULL,               'h'},
		{"peak-overlay",       1, NULL,               'p'},
132
133
		{"int-boost",          1, NULL,               'i'},
		{"binning",            1, NULL,               'b'},
134
135
		{"filter-cm",          0, &config_cmfilter,    1},
		{"filter-noise",       0, &config_noisefilter, 1},
136
		{"colscale",           1, NULL,               'c'},
Thomas White's avatar
Thomas White committed
137
		{"image",              1, NULL,               'e'},
138
		{"geometry",           1, NULL,               'g'},
Thomas White's avatar
Thomas White committed
139
		{"show-rings",         0, &config_showrings,   1},
140
		{"ring-size",          1, NULL,                2},
141
		{"simple-rings",       1, NULL,               'r'},
142
143
144
		{0, 0, NULL, 0}
	};

Thomas White's avatar
Thomas White committed
145
146
	gtk_init(&argc, &argv);

147
	/* Short options */
148
	while ((c = getopt_long(argc, argv, "hp:b:i:c:e:g:2:r:",
149
	                        longopts, NULL)) != -1) {
Thomas White's avatar
Thomas White committed
150

151
152
		char *test;

153
		switch (c) {
Thomas White's avatar
Thomas White committed
154
155

			case 'h' :
156
157
			show_help(argv[0]);
			return 0;
Thomas White's avatar
Thomas White committed
158

Thomas White's avatar
Thomas White committed
159
			case 'p' :
160
161
			peaks = strdup(optarg);
			break;
Thomas White's avatar
Thomas White committed
162

Thomas White's avatar
Thomas White committed
163
			case 'i' :
164
165
166
167
			boost = atoi(optarg);
			if ( boost < 1 ) {
				ERROR("Intensity boost must be a positive"
				      " integer.\n");
168
				return 1;
169
170
171
			}
			break;

Thomas White's avatar
Thomas White committed
172
			case 'b' :
173
			binning = atoi(optarg);
174
			if ( binning < 1 ) {
175
				ERROR("Binning must be a positive integer.\n");
176
				return 1;
177
178
179
			}
			break;

Thomas White's avatar
Thomas White committed
180
			case 'c' :
181
182
183
			cscale = strdup(optarg);
			break;

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

Thomas White's avatar
Thomas White committed
188
			case 'g' :
189
190
191
			geometry = strdup(optarg);
			break;

Thomas White's avatar
Thomas White committed
192
			case 2 :
193
194
195
196
197
			ring_size = strtod(optarg, &test);
			if ( test == optarg ) {
				ERROR("Ring size must be numerical.\n");
				return 1;
			}
198
			break;
Thomas White's avatar
Thomas White committed
199

Thomas White's avatar
Thomas White committed
200
			case 'r' :
201
202
203
204
205
			config_showrings = 1;
			reslist = strdup(optarg);
			int nchar = strlen(reslist);
			char thisvalue[128];
			int i;
Thomas White's avatar
Thomas White committed
206
			int j = 0;
207
208
			n_rings = 0;
			for ( i=0; i<=nchar; i++ ) {
Thomas White's avatar
Thomas White committed
209
210
211
				if ( ( reslist[i] != ',' )
				  && ( reslist[i] != '\0' ) )
				{
212
213
214
					thisvalue[j] = reslist[i];
					j++;
				} else {
Thomas White's avatar
Thomas White committed
215
					thisvalue[j] = '\0';
216
217
					ring_radii[n_rings] = atof(thisvalue);
					n_rings++;
Thomas White's avatar
Thomas White committed
218
					j = 0;
219
220
221
				}
			}
			break;
Thomas White's avatar
Thomas White committed
222

Thomas White's avatar
Thomas White committed
223
			case 0 :
224
			break;
Thomas White's avatar
Thomas White committed
225

226
227
228
			case '?' :
			break;

Thomas White's avatar
Thomas White committed
229
			default :
230
231
			ERROR("Unhandled option '%c'\n", c);
			break;
232
		}
Thomas White's avatar
Thomas White committed
233
234
235

	}

236
237
238
239
240
241
242
	nfiles = argc-optind;

	if ( nfiles < 1 ) {
		ERROR("You need to give me a file to open!\n");
		return -1;
	}

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
	if ( cscale == NULL ) cscale = strdup("colour");
	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);

258
	for ( i=0; i<nfiles; i++ ) {
259
		main_window_list[i] = displaywindow_open(argv[optind+i], peaks,
260
		                                         boost, binning,
261
		                                         config_cmfilter,
262
		                                         config_noisefilter,
263
		                                         colscale, element,
Thomas White's avatar
Thomas White committed
264
		                                         geometry,
265
		                                         config_showrings,
266
267
		                                         ring_radii,
		                                         n_rings,
268
		                                         ring_size);
269
270
271
272
273
274
		if ( main_window_list[i] == NULL ) {
			ERROR("Couldn't open display window\n");
		} else {
			main_n_windows++;
		}
	}
275
276

	if ( main_n_windows == 0 ) return 0;
Thomas White's avatar
Thomas White committed
277
278
279
280
	gtk_main();

	return 0;
}