hdfsee.c 7.01 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
8
9
10
 * Copyright © 2012 Deutsches Elektronen-Synchrotron DESY,
 *                  a research centre of the Helmholtz Association.
 *
 * Authors:
 *   2009-2012 Thomas White <taw@physics.org>
Thomas White's avatar
Thomas White committed
11
 *
Thomas White's avatar
Thomas White committed
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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
26
27
28
29
30
31
32
33
34
 *
 */


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

#include <gtk/gtk.h>
35
#include <getopt.h>
Thomas White's avatar
Thomas White committed
36

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


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


47
48
49
50
51
52
53
54
55
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"
56
"      --ring-size=<n>              Set the size for those circles.\n"
57
"  -i, --int-boost=<n>              Multiply intensity by <n>.\n"
58
"  -b, --binning=<n>                Set display binning to <n>.\n"
59
60
61
62
63
"      --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"
64
65
"      --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
66
"                                    in pixel units.\n"
67
68
69
70
71
72
"  -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
73
74
"  -e, --image=<element>            Start up displaying this image from the\n"
"                                    HDF5 file.  Example: /data/data0.\n"
Thomas White's avatar
Thomas White committed
75
"  -g, --geometry=<filename>        Use geometry from file for display.\n"
76
77
78
79
"\n");
}


Thomas White's avatar
Thomas White committed
80
81
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
/* 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[])
{
108
109
110
111
	int c;
	size_t i;
	int nfiles;
	char *peaks = NULL;
112
113
	int boost = 1;
	int binning = 2;
114
115
	int config_cmfilter = 0;
	int config_noisefilter = 0;
Thomas White's avatar
Thomas White committed
116
	int config_showrings = 0;
117
118
	int colscale = SCALE_COLOUR;
	char *cscale = NULL;
Thomas White's avatar
Thomas White committed
119
	char *element = NULL;
120
	char *geometry = NULL;
121
	double ring_size = 5.0;
122
123
124
	char *reslist = NULL;
	double ring_radii[128];
	int n_rings = -1;
Thomas White's avatar
Thomas White committed
125

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

Thomas White's avatar
Thomas White committed
143
144
	gtk_init(&argc, &argv);

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

149
150
		char *test;

151
		switch (c) {
Thomas White's avatar
Thomas White committed
152
		case 'h' :
153
154
			show_help(argv[0]);
			return 0;
Thomas White's avatar
Thomas White committed
155

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

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

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

177
178
179
180
		case 'c' :
			cscale = strdup(optarg);
			break;

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

185
186
187
188
		case 'g' :
			geometry = strdup(optarg);
			break;

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

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

Thomas White's avatar
Thomas White committed
220
		case 0 :
221
			break;
Thomas White's avatar
Thomas White committed
222

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

	}

229
230
231
232
233
234
235
	nfiles = argc-optind;

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

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

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

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

	return 0;
}