aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2021-03-26 15:24:09 +0100
committerThomas White <taw@physics.org>2021-03-26 18:19:47 +0100
commit760cb454d937b1d4cf9fa528e409b00362f380c2 (patch)
tree0ce998682c601fba8103423f579bc08afda7bdb9
parente8549ceba2a5936e0bef11c00dd989e22b190370 (diff)
indexamajig: Add --harvest-file
-rw-r--r--src/indexamajig.c150
-rw-r--r--src/json-utils.h60
2 files changed, 210 insertions, 0 deletions
diff --git a/src/indexamajig.c b/src/indexamajig.c
index eb39a32c..589fe6ed 100644
--- a/src/indexamajig.c
+++ b/src/indexamajig.c
@@ -64,6 +64,7 @@
#include "im-sandbox.h"
#include "version.h"
+#include "json-utils.h"
struct indexamajig_arguments
@@ -92,6 +93,7 @@ struct indexamajig_arguments
int profile; /* Whether to do wall-clock time profiling */
char **copy_headers;
int n_copy_headers;
+ char *harvest_file;
TakeTwoOptions **taketwo_opts_ptr;
FelixOptions **felix_opts_ptr;
@@ -101,6 +103,141 @@ struct indexamajig_arguments
};
+static double nan_if_neg(double n)
+{
+ if ( n < 0.0 ) {
+ return NAN;
+ } else {
+ return n;
+ }
+}
+
+
+static void write_json_cell(FILE *fh, const char *name, UnitCell *cell)
+{
+ double a, b, c, al, be, ga;
+ cell_get_parameters(cell, &a, &b, &c, &al, &be, &ga);
+
+ fprintf(fh, " \"%s\": {\n", name);
+ fprintf(fh, " \"lattice_type\": \"%s\",\n",
+ str_lattice(cell_get_lattice_type(cell)));
+ fprintf(fh, " \"centering\": \"%c\",\n",
+ cell_get_centering(cell));
+ fprintf(fh, " \"unique_axis\": \"%c\",\n",
+ cell_get_unique_axis(cell));
+ fprintf(fh, " \"a_Angstrom\": %f,\n", a*1e10);
+ fprintf(fh, " \"b_Angstrom\": %f,\n", b*1e10);
+ fprintf(fh, " \"c_Angstrom\": %f,\n", c*1e10);
+ fprintf(fh, " \"alpha_deg\": %f,\n", rad2deg(al));
+ fprintf(fh, " \"beta_deg\": %f,\n", rad2deg(be));
+ fprintf(fh, " \"gamma_deg\": %f\n", rad2deg(ga)); /* NB No comma */
+ fprintf(fh, " },\n");
+}
+
+
+static void write_methods(FILE *fh, const char *name, IndexingPrivate *ipriv)
+{
+ int i, n;
+ const IndexingMethod *methods;
+
+ fprintf(fh, " \"%s\": [", name);
+
+ methods = indexing_methods(ipriv, &n);
+ for ( i=0; i<n; i++ ) {
+ fprintf(fh, " \"%s\"", indexer_str(methods[i]));
+ if ( i < n-1 ) {
+ fprintf(fh, ",");
+ }
+ }
+ fprintf(fh, " ],\n");
+}
+
+
+static void write_harvest_file(struct index_args *args,
+ const char *filename,
+ int if_multi, int if_refine, int if_retry,
+ int if_peaks, int if_checkcell)
+{
+ FILE *fh;
+ char *tmp;
+
+ fh = fopen(filename, "w");
+ if ( fh == NULL ) {
+ ERROR("Unable to write parameter harvesting file.\n");
+ return;
+ }
+
+ fprintf(fh, "{\n");
+ fprintf(fh, " \"input\": {\n");
+ write_float(fh, 0, "highres", args->highres);
+ fprintf(fh, " },\n");
+
+ fprintf(fh, " \"peaksearch\": {\n");
+ write_str(fh, 1, "method", str_peaksearch(args->peaks));
+ write_float(fh, 1, "radius_inner_px", args->pk_inn);
+ write_float(fh, 1, "radius_middle_px", args->pk_mid);
+ write_float(fh, 1, "radius_outer_px", args->pk_out);
+ write_bool(fh, 1, "noise_filter", args->noisefilter);
+ write_int(fh, 1, "median_filter", args->median_filter);
+ write_float(fh, 1, "threshold_adu", args->threshold);
+ write_float(fh, 1, "min_squared_gradient_adu2", args->min_sq_gradient);
+ write_float(fh, 1, "min_snr", args->min_snr);
+ write_bool(fh, 1, "check_hdf5_snr", args->check_hdf5_snr);
+ write_bool(fh, 1, "half_pixel_shift", args->half_pixel_shift);
+ write_int(fh, 1, "min_res_px", args->min_res);
+ write_int(fh, 1, "max_res_px", args->max_res);
+ write_int(fh, 1, "max_num_peaks", args->max_n_peaks);
+ write_int(fh, 1, "max_pixel_count", args->max_pix_count);
+ write_int(fh, 1, "local_bg_radius_px", args->local_bg_radius);
+ write_bool(fh, 1, "use_saturated", args->use_saturated);
+ write_bool(fh, 1, "revalidate_hdf5", 1-args->no_revalidate);
+ write_float(fh, 1, "min_snr_of_biggest_pixel", args->min_snr_biggest_pix);
+ write_float(fh, 1, "min_snr_of_peak_pixel", args->min_snr_peak_pix);
+ write_float(fh, 1, "min_sig_adu", args->min_sig);
+ write_float(fh, 0, "min_peak_over_neighbour_adu", args->min_peak_over_neighbour);
+ fprintf(fh, " },\n");
+
+ fprintf(fh, " \"hitfinding\": {\n");
+ write_int(fh, 0, "min_num_peaks", args->min_peaks);
+ fprintf(fh, " },\n");
+
+ fprintf(fh, " \"indexing\": {\n");
+ write_methods(fh, "methods", args->ipriv);
+ write_json_cell(fh, "target_cell", args->cell);
+ write_float(fh, 1, "tolerance_a_percent", 100.0*args->tols[0]);
+ write_float(fh, 1, "tolerance_b_percent", 100.0*args->tols[1]);
+ write_float(fh, 1, "tolerance_c_percent", 100.0*args->tols[2]);
+ write_float(fh, 1, "tolerance_alpha_deg", rad2deg(args->tols[3]));
+ write_float(fh, 1, "tolerance_beta_deg", rad2deg(args->tols[4]));
+ write_float(fh, 1, "tolerance_gamma_deg", rad2deg(args->tols[5]));
+ write_bool(fh, 1, "multi_lattice", if_multi);
+ write_bool(fh, 1, "refine", if_refine);
+ write_bool(fh, 1, "retry", if_retry);
+ write_bool(fh, 1, "check_peaks", if_peaks);
+ write_bool(fh, 1, "check_cell", if_checkcell);
+ write_float(fh, 1, "wavelength_estimate_m", args->wavelength_estimate);
+ write_float(fh, 0, "clen_estimate_m", args->clen_estimate);
+ fprintf(fh, " },\n");
+
+ fprintf(fh, " \"integration\": {\n");
+ tmp = str_integration_method(args->int_meth);
+ write_str(fh, 1, "method", tmp);
+ free(tmp);
+ write_float(fh, 1, "radius_inner_px", args->ir_inn);
+ write_float(fh, 1, "radius_middle_px", args->ir_mid);
+ write_float(fh, 1, "radius_outer_px", args->ir_out);
+ write_float(fh, 1, "push_res_invm", args->push_res);
+ write_float(fh, 1, "fix_profile_radius_invm", nan_if_neg(args->fix_profile_r));
+ write_float(fh, 1, "fix_divergence_rad", nan_if_neg(args->fix_divergence));
+ write_bool(fh, 0, "overpredict", args->overpredict);
+ fprintf(fh, " }\n"); /* NB No comma */
+
+ fprintf(fh, "}\n");
+
+ fclose(fh);
+}
+
+
static void show_version(FILE *fh, struct argp_state *state)
{
printf("CrystFEL: %s\n", crystfel_version_string());
@@ -589,6 +726,10 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
}
break;
+ case 606 :
+ args->harvest_file = strdup(arg);
+ break;
+
default :
return ARGP_ERR_UNKNOWN;
@@ -636,6 +777,7 @@ int main(int argc, char *argv[])
args.profile = 0;
args.copy_headers = NULL;
args.n_copy_headers = 0;
+ args.harvest_file = NULL;
args.taketwo_opts_ptr = &taketwo_opts;
args.felix_opts_ptr = &felix_opts;
args.xgandalf_opts_ptr = &xgandalf_opts;
@@ -822,6 +964,8 @@ int main(int argc, char *argv[])
"in stream"},
{"serial-start", 605, "n", OPTION_NO_USAGE, "Start the serial numbers in the stream "
"here"},
+ {"harvest-file", 606, "filename", OPTION_NO_USAGE, "Write the actual parameters "
+ "used in JSON format"},
{NULL, 0, 0, OPTION_DOC, "More information:", 99},
@@ -1057,6 +1201,12 @@ int main(int argc, char *argv[])
stream_write_target_cell(st, args.iargs.cell);
stream_write_indexing_methods(st, args.indm_str);
+ if ( args.harvest_file != NULL ) {
+ write_harvest_file(&args.iargs, args.harvest_file,
+ args.if_multi, args.if_refine, args.if_retry,
+ args.if_peaks, args.if_checkcell);
+ }
+
free(args.outfile);
free(args.indm_str);
diff --git a/src/json-utils.h b/src/json-utils.h
new file mode 100644
index 00000000..5c03256b
--- /dev/null
+++ b/src/json-utils.h
@@ -0,0 +1,60 @@
+/*
+ * json-utils.h
+ *
+ * JSON writing utilities
+ *
+ * Copyright © 2021 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2021 Thomas White <taw@physics.org>
+ *
+ * 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/>.
+ *
+ */
+
+static void write_float(FILE *fh, int comma, const char *name, float val)
+{
+ const char *cs = comma ? "," : "";
+
+ if ( isnan(val) ) {
+ fprintf(fh, " \"%s\": null%s\n", name, cs);
+ } else if ( val > 0.0001 ) {
+ fprintf(fh, " \"%s\": %f%s\n", name, val, cs);
+ } else {
+ fprintf(fh, " \"%s\": %e%s\n", name, val, cs);
+ }
+}
+
+
+static void write_bool(FILE *fh, int comma, const char *name, int val)
+{
+ fprintf(fh, " \"%s\": %s%s\n",
+ name, val?"true":"false", comma?",":"");
+}
+
+
+static void write_int(FILE *fh, int comma, const char *name, int val)
+{
+ fprintf(fh, " \"%s\": %i%s\n", name, val, comma?",":"");
+}
+
+
+static void write_str(FILE *fh, int comma, const char *name, const char *val)
+{
+ fprintf(fh, " \"%s\": \"%s\"%s\n", name, val, comma?",":"");
+}
+