hdfsee.c 7.07 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
		case 'h' :
155
156
			show_help(argv[0]);
			return 0;
Thomas White's avatar
Thomas White committed
157

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

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

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

179
180
181
182
		case 'c' :
			cscale = strdup(optarg);
			break;

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

187
188
189
190
		case 'g' :
			geometry = strdup(optarg);
			break;

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

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

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

Thomas White's avatar
Thomas White committed
225
		default :
226
227
			return 1;
		}
Thomas White's avatar
Thomas White committed
228
229
230

	}

231
232
233
234
235
236
237
	nfiles = argc-optind;

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

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
	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);

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

	if ( main_n_windows == 0 ) return 0;
Thomas White's avatar
Thomas White committed
272
273
274
275
	gtk_main();

	return 0;
}