diff options
-rw-r--r-- | doc/man/indexamajig.1 | 115 | ||||
-rw-r--r-- | libcrystfel/src/felix.c | 195 | ||||
-rw-r--r-- | libcrystfel/src/felix.h | 14 | ||||
-rw-r--r-- | libcrystfel/src/index.c | 11 | ||||
-rw-r--r-- | libcrystfel/src/index.h | 6 | ||||
-rw-r--r-- | src/indexamajig.c | 133 | ||||
-rw-r--r-- | src/process_image.h | 3 |
7 files changed, 232 insertions, 245 deletions
diff --git a/doc/man/indexamajig.1 b/doc/man/indexamajig.1 index 38654294..e1e1e19f 100644 --- a/doc/man/indexamajig.1 +++ b/doc/man/indexamajig.1 @@ -362,114 +362,17 @@ These set low-level parameters for the TakeTwo indexing algorithm. Respectively The defaults are: \fB--taketwo-member-threshold=20\fR, \fB--taketwo-len-tolernace=0.001\fR, \fB--taketwo-angle-tolerance=0.6\fR and \fB--taketwo-trace-tolerance=3\fR. .PD 0 -.IP \fB--felix-options\fR -.PD -Specify a comma-separated list of keyword arguments to change the default parameters passed to the felix indexer. For asthetics, this list can also be preceeded and followed by quotations - as in: \fB--felix-options="arg1=10,arg2=600"\fR. A list of parameters which can be modified through this option is detailed below. - -.PD 0 -.IP "\fBspacegroup=\fIn\fR" -.PD -Specify the spacegroup number of the crystal structure. For example: spacegroup=96 is P43212. - -.PD 0 -.IP "\fBn_voxels=\fIn\fR" -.PD -Specify the number of voxels used in the Rodrigues space search. -(Default: 100) - -.PD 0 -.IP "\fBtest_fraction=\fIfract\fR" -.PD -Specify the fraction of space to test. -(Default: 0.75) - -.PD 0 -.IP "\fBsigma_tth=\fIsig\fR" -.PD -Specify the sigma of the two-theta angle. -(Default: 0.15) - +.IP \fB--felix-tthrange-min=\fIn\fR +.IP \fB--felix-tthrange-max=\fIn\fR +.IP \fB--felix-min-measurements=\fIn\fR +.IP \fB--felix-min-completeness=\fIn\fR +.IP \fB--felix-min-uniqueness=\fIn\fR +.IP \fB--felix-num-voxels=\fIn\fR +.IP \fB--felix-test-fraction=\fIn\fR +.IP \fB--felix-sigma=\fIn\fR .PD 0 -.IP "\fBsigma_eta=\fIsig\fR" -.PD -Specify the sigma of the eta angle. -(Default: 0.2) - -.PD 0 -.IP "\fBsigma_omega=\fIsig\fR" -.PD -Specify the sigma of the omega angle. -(Default: 0.2) - -.PD 0 -.IP "\fBn_sigmas=\fIn\fR" -.PD -Specify the number of sigmas to use. -(Default: 2) - -.PD 0 -.IP "\fBtthrange_min=\fImin\fR" -.PD -Specify the lower bound of the 2theta angle to consider when indexing (degrees). -(Default: 0.0) - -.PD 0 -.IP "\fBtthrange_max=\fImax\fR" -.PD -Specify the upper bound of the 2theta angle to consider when indexing (degrees). -(Default: 30.0) +These set low-level parameters for the Felix indexing algorithm. -.PD 0 -.IP "\fBetarange_min=\fImin\fR" -.PD -Specify the lower bound of the eta angle to consider when indexing (degrees). -(Default: 0.0) - -.PD 0 -.IP "\fBetarange_max=\fImax\fR" -.PD -Specify the upper bound of the eta angle to consider when indexing (degrees). -(Default: 360.0) - -.PD 0 -.IP "\fBmin_measurements=\fIn\fR" -.PD -Specify a cutoff for how many Rodrigues lines cross in the first search. -(Default: 15) - -.PD 0 -.IP "\fBmin_completeness=\fIfract\fR" -.PD -Specify a cutoff for the fraction of projected spots which are found in the pattern. -(Default: 0.001) - -.PD 0 -.IP "\fBmin_uniqueness=\fIn\fR" -.PD -Specify a cutoff for the fraction of found spots which can belong to other crystallites. -(Default: 0.5) - -.PD 0 -.IP "\fBforce4frustums\fR" -.PD -Tell Felix to use four frustums. - -.PD 0 -.IP "\fBorispace_octa\fR" -.PD -Tell Felix to use octahedral orispace as opposed to frustum. -(Only possible with Felix.0.31) - -.PD 0 -.IP "\fBreadhkl=\fIfile\fR" -.PD -Specify a file from which to read in the ideal gvectors for the crystal. - -.PD 0 -.IP "\fBmaxtime=\fIn\fR" -.PD -Specify a maximum time which Felix is allowed to attempt to index the pattern (seconds) -(Default: 30 s) .SH INTEGRATION OPTIONS .PD 0 .IP \fB--integration=\fR\fImethod\fR diff --git a/libcrystfel/src/felix.c b/libcrystfel/src/felix.c index 973b0513..fc1b9e4d 100644 --- a/libcrystfel/src/felix.c +++ b/libcrystfel/src/felix.c @@ -188,7 +188,9 @@ static int read_felix(struct felix_private *gp, struct image *image, cell_set_cartesian(cell, ubi12/1e10, ubi13/1e10, ubi11/1e10, ubi22/1e10, ubi23/1e10, ubi21/1e10, ubi32/1e10, ubi33/1e10, ubi31/1e10); + cell_set_lattice_type(cell, cell_get_lattice_type(gp->cell)); cell_set_centering(cell, cell_get_centering(gp->cell)); + cell_set_unique_axis(cell, cell_get_unique_axis(gp->cell)); cr = crystal_new(); if ( cr == NULL ) { @@ -383,7 +385,8 @@ static char *write_ini(struct image *image, struct felix_private *gp) &tt, 1.0/image->lambda); fprintf(fh, "spacegroup %i\n", gp->spacegroup); - fprintf(fh, "tthrange %f %f\n", gp->tthrange_min, gp->tthrange_max); + fprintf(fh, "tthrange %f %f\n", rad2deg(gp->tthrange_min), + rad2deg(gp->tthrange_max)); fprintf(fh, "etarange %f %f\n", gp->etarange_min, gp->etarange_max); fprintf(fh, "domega %f\n", gp->domega); fprintf(fh, "omegarange %f %f\n", gp->omegarange_min, gp->omegarange_max); @@ -544,116 +547,70 @@ int felix_index(struct image *image, IndexingPrivate *ipriv) } -static void parse_options(const char *options, struct felix_private *gp) +static int sg_number_for_cell(UnitCell *cell) { - char *temp_options; - char *option; - char *freeme; - - temp_options = strdup(options); - freeme = temp_options; - - while ( (option=strsep(&temp_options, ",")) != NULL ) { - - if ( strncmp(option, "spacegroup=", 11) == 0 ){ - gp->spacegroup = atoi(option+11); - } - - if ( strncmp(option, "tthrange_min=", 13) == 0 ){ - gp->tthrange_min = atof(option+13); - } - - if ( strncmp(option, "tthrange_max=", 13 ) == 0 ){ - gp->tthrange_max = atof(option+13); - } - - if ( strncmp(option, "etarange_min=", 13 ) == 0 ){ - gp->etarange_min = atof(option+13); - } - - if ( strncmp(option, "etarange_max=", 13 ) == 0 ){ - gp->etarange_max = atof(option+13); - } - - if ( strncmp(option, "domega=", 7) == 0 ){ - gp->domega = atof(option+7); - } - - if ( strncmp(option, "omegarange_min=", 15) == 0 ){ - gp->omegarange_min = atof(option+15); - } - - if ( strncmp(option, "omegarange_max=", 15) == 0 ){ - gp->omegarange_max = atof(option+15); - } - - if ( strncmp(option, "min_measurements=", 17) == 0 ){ - gp->min_measurements = atoi(option+17); - } - - if ( strncmp(option, "min_completeness=", 17) == 0 ){ - gp->min_completeness = atof(option+17); + LatticeType lattice = cell_get_lattice_type(cell); + char cen = cell_get_centering(cell); + + switch (lattice) + { + case L_TRICLINIC: + return 1; /* P1 */ + + case L_MONOCLINIC: + switch ( cen ) { + case 'P' : return 3; /* P2 */ + case 'C' : return 5; /* C2 */ + default : return 0; } - if ( strncmp(option, "min_uniqueness=", 15) == 0 ){ - gp->min_uniqueness = atof(option+15); + case L_ORTHORHOMBIC: + switch ( cen ) { + case 'P' : return 16; /* P222 */ + case 'C' : return 21; /* C222 */ + case 'F' : return 22; /* F222 */ + case 'I' : return 23; /* I222 */ + case 'A' : return 38; /* Amm2 */ + default : return 0; } - if ( strncmp(option, "n_voxels=", 9) == 0 ){ - gp->n_voxels = atoi(option+9); + case L_TETRAGONAL: + switch ( cen ) { + case 'P' : return 89; /* P422 */ + case 'I' : return 97; /* I422 */ + default : return 0; } - if ( strncmp(option, "test_fraction=", 14) == 0 ){ - gp->test_fraction = atof(option+14); - } - - if ( strncmp(option, "sigma_tth=", 10) == 0 ){ - gp->sigma_tth = atof(option+10); - } - - if ( strncmp(option, "sigma_eta=", 10) == 0 ){ - gp->sigma_eta = atof(option+10); - } - - if ( strncmp(option, "sigma_omega=", 12) == 0 ){ - gp->sigma_omega = atof(option+12); - } + case L_RHOMBOHEDRAL: + return 155; /* R32 */ - if ( strncmp(option, "n_sigmas=", 9) == 0 ){ - gp->n_sigmas = atoi(option+9); + case L_HEXAGONAL: + switch ( cen ) { + case 'P' : return 177; /* P622 */ + case 'H' : return 143; /* P3 */ + default : return 0; } - if ( strncmp(option, "force4frustums", 14) == 0 ){ - gp->force4frustums = 1; - } - - /* Only allow one orispace command. - * orispace frustum is the default, so have to turn off to use octa. - */ - if ( strncmp(option, "orispace_octa", 13) == 0 ){ - gp->orispace_octa = 1; - gp->orispace_frustum = 0; - } - - if ( strncmp(option, "readhkl=", 8) == 0 ){ - gp->readhkl_file = strdup(option+8); - } - - if ( strncmp(option, "maxtime=", 8) == 0 ){ - gp->maxtime = atof(option+8); + case L_CUBIC: + switch ( cen ) { + case 'P' : return 207; /* P432 */ + case 'F' : return 209; /* F432 */ + case 'I' : return 211; /* I432 */ + default : return 0; } + default: + return 0; } - - free(freeme); - free(option); } -void *felix_prepare(IndexingMethod *indm, UnitCell *cell, const char *options) + +void *felix_prepare(IndexingMethod *indm, UnitCell *cell, + struct felix_options *opts) { struct felix_private *gp; - if ( cell == NULL ) { + if ( !cell_has_parameters(cell) ) { ERROR("Felix needs a unit cell.\n"); return NULL; } @@ -669,9 +626,15 @@ void *felix_prepare(IndexingMethod *indm, UnitCell *cell, const char *options) gp->indm = *indm; /* Default values of felix options */ - gp->spacegroup = 0; - gp->tthrange_min = 0; - gp->tthrange_max = 30.0; + gp->spacegroup = sg_number_for_cell(cell); + if ( gp->spacegroup == 0 ) { + ERROR("Couldn't determine representative space group for your cell.\n"); + ERROR("Try again with a more conventional cell.\n"); + return NULL; + } + + /* Default parameters */ + gp->n_voxels = 100; gp->etarange_min = 0; gp->etarange_max = 360; gp->domega = 2; @@ -680,9 +643,8 @@ void *felix_prepare(IndexingMethod *indm, UnitCell *cell, const char *options) gp->min_measurements = 15; gp->min_completeness = 0.001; gp->min_uniqueness = 0.5; - gp->n_voxels = 100; gp->test_fraction = 0.75; - gp->sigma_tth = 0.15; + gp->sigma_tth = 0.2; gp->sigma_eta = 0.2; gp->sigma_omega = 0.2; gp->n_sigmas = 2; @@ -691,17 +653,34 @@ void *felix_prepare(IndexingMethod *indm, UnitCell *cell, const char *options) gp->orispace_octa = 0; gp->readhkl_file = NULL; gp->maxtime = 30.0; + gp->tthrange_min = deg2rad(0.0); + gp->tthrange_max = deg2rad(30.0); - /* Parse the options string and fill in the necessary - * private variables. */ - if ( options != NULL ) parse_options(options, gp); - - /* Make sure that they at least specified the spacegroup number.*/ - - if ( gp->spacegroup == 0 ) { - ERROR("Felix requires that you specify the spacegroup number.\n"); - ERROR("You should use the argument --felix-options=spacegroup=xx\n"); - return NULL; + if ( opts->ttmin > 0.0 ) { + gp->tthrange_min = opts->ttmin; + } + if ( opts->ttmax > 0.0 ) { + gp->tthrange_max = opts->ttmax; + } + if ( opts->min_measurements > 0 ) { + gp->min_measurements = opts->min_measurements; + } + if ( opts->min_completeness > 0.0 ) { + gp->min_completeness = opts->min_completeness; + } + if ( opts->min_uniqueness > 0.0 ) { + gp->min_uniqueness = opts->min_uniqueness; + } + if ( opts->n_voxels > 0 ) { + gp->n_voxels = opts->n_voxels; + } + if ( opts->test_fraction > 0.0 ) { + gp->test_fraction = opts->test_fraction; + } + if ( opts->sigma > 0.0 ) { + gp->sigma_tth = opts->sigma; + gp->sigma_eta = opts->sigma; + gp->sigma_omega = opts->sigma; } return (IndexingPrivate *)gp; diff --git a/libcrystfel/src/felix.h b/libcrystfel/src/felix.h index 40568d37..ab9ba744 100644 --- a/libcrystfel/src/felix.h +++ b/libcrystfel/src/felix.h @@ -36,8 +36,20 @@ #include "cell.h" +struct felix_options +{ + double ttmin; /* radians */ + double ttmax; /* radians */ + int min_measurements; + double min_completeness; + double min_uniqueness; + int n_voxels; + double test_fraction; + double sigma; +}; + extern void *felix_prepare(IndexingMethod *indm, UnitCell *cell, - const char *options); + struct felix_options *opts); extern void felix_cleanup(IndexingPrivate *pp); diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 8ac04368..03bd6ae3 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -197,7 +197,7 @@ static char *friendly_indexer_name(IndexingMethod m) static void *prepare_method(IndexingMethod *m, UnitCell *cell, - const char *options) + struct felix_options *felix_opts) { char *str; IndexingMethod in = *m; @@ -230,7 +230,7 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, break; case INDEXING_FELIX : - priv = felix_prepare(m, cell, options); + priv = felix_prepare(m, cell, felix_opts); break; case INDEXING_TAKETWO : @@ -266,8 +266,9 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell, struct detector *det, float *ltl, - IndexingFlags flags, const char *options, - struct taketwo_options *ttopts) + IndexingFlags flags, + struct taketwo_options *ttopts, + struct felix_options *felix_opts) { int i, n; char **method_strings; @@ -359,7 +360,7 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell, int j; ipriv->engine_private[i] = prepare_method(&methods[i], cell, - options); + felix_opts); if ( ipriv->engine_private[i] == NULL ) return NULL; diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h index ac386390..15843b2a 100644 --- a/libcrystfel/src/index.h +++ b/libcrystfel/src/index.h @@ -135,12 +135,14 @@ extern IndexingMethod get_indm_from_string(const char *method); #include "cell.h" #include "image.h" #include "taketwo.h" +#include "felix.h" extern IndexingPrivate *setup_indexing(const char *methods, UnitCell *cell, struct detector *det, float *ltl, - IndexingFlags flags, const char *options, - struct taketwo_options *ttopts); + IndexingFlags flags, + struct taketwo_options *ttopts, + struct felix_options *felix_opts); extern void index_pattern(struct image *image, IndexingPrivate *ipriv); diff --git a/src/indexamajig.c b/src/indexamajig.c index 691d6e11..88b61563 100644 --- a/src/indexamajig.c +++ b/src/indexamajig.c @@ -129,6 +129,7 @@ static void show_help(const char *s) " --no-refine Skip the prediction refinement step\n" " --check-peaks Check that most of the peaks can be accounted for\n" " by the indexing solution\n" +"\n" " --taketwo-member-threshold\n" " Minimum number of members in network\n" " --taketwo-len-tolerance\n" @@ -137,8 +138,25 @@ static void show_help(const char *s) " Reciprocal space angle tolerance (in degrees)\n" " --taketwo-trace-tolerance\n" " Rotation matrix equivalence tolerance (in degrees)\n" -" --felix-options Change the default arguments passed to the indexer\n" -" Comma-separated list of options, key=val\n" +"\n" +" --felix-tthrange-min Minimum 2theta to consider for indexing (degrees)\n" +" Default: 0\n" +" --felix-tthrange-max Maximum 2theta to consider for indexing (degrees)\n" +" Default: 30\n" +" --felix-min-measurements\n" +" How many Rodrigue lines cross in the first search\n" +" Default: 15\n" +" --felix-min-completeness\n" +" Fraction of projected spots found in the pattern\n" +" Default: 0.001\n" +" --felix-min-uniqueness\n" +" Fraction of found spots which can belong to other\n" +" crystallites. Default: 0.5\n" +" --felix-num-voxels Number of voxels for Rodrigues space search\n" +" Default: 100\n" +" --felix-test-fraction Fraction of space to test. Default: 0.75\n" +" --felix-sigma The sigma of the 2theta, eta and omega angles.\n" +" Default: 0.2\n" "\nIntegration options:\n\n" " --integration=<meth> Integration method (rings,prof2d)-(cen,nocen)\n" " Default: rings-nocen\n" @@ -208,7 +226,6 @@ int main(int argc, char *argv[]) char *geom_filename = NULL; struct beam_params beam; int have_push_res = 0; - int len; char *command_line_peak_path = NULL; int if_refine = 1; int if_nocomb = 0; @@ -266,12 +283,19 @@ int main(int argc, char *argv[]) iargs.fix_profile_r = -1.0; iargs.fix_bandwidth = -1.0; iargs.fix_divergence = -1.0; - iargs.felix_options = NULL; iargs.profile = 0; iargs.taketwo_opts.member_thresh = -1; iargs.taketwo_opts.len_tol = -1.0; iargs.taketwo_opts.angle_tol = -1.0; iargs.taketwo_opts.trace_tol = -1.0; + iargs.felix_opts.ttmin = -1.0; + iargs.felix_opts.ttmax = -1.0; + iargs.felix_opts.min_measurements = 0; + iargs.felix_opts.min_completeness = -1.0; + iargs.felix_opts.min_uniqueness = -1.0; + iargs.felix_opts.n_voxels = 0; + iargs.felix_opts.test_fraction = -1.0; + iargs.felix_opts.sigma = -1.0; /* Long options */ const struct option longopts[] = { @@ -347,13 +371,21 @@ int main(int argc, char *argv[]) {"max-res", 1, NULL, 30}, {"min-peaks", 1, NULL, 31}, {"taketwo-member-threshold", 1, NULL, 32}, - {"taketwo-member-thresh", 1, NULL, 32}, + {"taketwo-member-thresh", 1, NULL, 32}, /* compat */ {"taketwo-len-tolerance", 1, NULL, 33}, - {"taketwo-len-tol", 1, NULL, 33}, + {"taketwo-len-tol", 1, NULL, 33}, /* compat */ {"taketwo-angle-tolerance", 1, NULL, 34}, - {"taketwo-angle-tol", 1, NULL, 34}, + {"taketwo-angle-tol", 1, NULL, 34}, /* compat */ {"taketwo-trace-tolerance", 1, NULL, 35}, - {"taketwo-trace-tol", 1, NULL, 35}, + {"taketwo-trace-tol", 1, NULL, 35}, /* compat */ + {"felix-ttrange-min", 1, NULL, 36}, + {"felix-ttrange-max", 1, NULL, 37}, + {"felix-min-measurements", 1, NULL, 38}, + {"felix-min-completeness", 1, NULL, 39}, + {"felix-min-uniqueness", 1, NULL, 40}, + {"felix-num-voxels", 1, NULL, 41}, + {"felix-test-fraction", 1, NULL, 42}, + {"felix-sigma", 1, NULL, 43}, {0, 0, NULL, 0} }; @@ -524,18 +556,9 @@ int main(int argc, char *argv[]) break; case 25 : - /* Remove leading and trailing quotes */ - len = strlen(optarg); - if ( optarg[len-1] == '\'' || optarg[len-1] == '\"' ){ - optarg[len-1] = 0; - } - if ( optarg[0] == '\'' || optarg[0] == '\"' ){ - iargs.felix_options = strdup( optarg+1 ); - } - else { - iargs.felix_options = strdup( optarg ); - } - break; + ERROR("--felix-options is no longer used.\n"); + ERROR("See --help for the new Felix options.\n"); + return 1; case 26: iargs.min_pix_count = atoi(optarg); @@ -599,6 +622,72 @@ int main(int argc, char *argv[]) iargs.taketwo_opts.trace_tol = deg2rad(iargs.taketwo_opts.trace_tol); break; + case 36: + if ( sscanf(optarg, "%lf", &iargs.felix_opts.ttmin) != 1 ) + { + ERROR("Invalid value for --felix-tthrange-min\n"); + return 1; + } + iargs.felix_opts.ttmin = deg2rad(iargs.felix_opts.ttmin); + break; + + case 37: + if ( sscanf(optarg, "%lf", &iargs.felix_opts.ttmax) != 1 ) + { + ERROR("Invalid value for --felix-tthrange-max\n"); + return 1; + } + iargs.felix_opts.ttmax = deg2rad(iargs.felix_opts.ttmax); + break; + + case 38: + if ( sscanf(optarg, "%i", &iargs.felix_opts.min_measurements) != 1 ) + { + ERROR("Invalid value for --felix-min-measurements\n"); + return 1; + } + break; + + case 39: + if ( sscanf(optarg, "%lf", &iargs.felix_opts.min_completeness) != 1 ) + { + ERROR("Invalid value for --felix-min-completeness\n"); + return 1; + } + break; + + case 40: + if ( sscanf(optarg, "%lf", &iargs.felix_opts.min_uniqueness) != 1 ) + { + ERROR("Invalid value for --felix-min-uniqueness\n"); + return 1; + } + break; + + case 41: + if ( sscanf(optarg, "%i", &iargs.felix_opts.n_voxels) != 1 ) + { + ERROR("Invalid value for --felix-num-voxels\n"); + return 1; + } + break; + + case 42: + if ( sscanf(optarg, "%lf", &iargs.felix_opts.test_fraction) != 1 ) + { + ERROR("Invalid value for --felix-test-fraction\n"); + return 1; + } + break; + + case 43: + if ( sscanf(optarg, "%lf", &iargs.felix_opts.sigma) != 1 ) + { + ERROR("Invalid value for --felix-sigma\n"); + return 1; + } + break; + case 0 : break; @@ -892,8 +981,8 @@ int main(int argc, char *argv[]) iargs.ipriv = setup_indexing(indm_str, iargs.cell, iargs.det, iargs.tols, flags, - iargs.felix_options, - &iargs.taketwo_opts); + &iargs.taketwo_opts, + &iargs.felix_opts); if ( iargs.ipriv == NULL ) { ERROR("Failed to set up indexing system\n"); return 1; diff --git a/src/process_image.h b/src/process_image.h index 3e87b922..861ee203 100644 --- a/src/process_image.h +++ b/src/process_image.h @@ -40,6 +40,7 @@ struct index_args; #include "im-sandbox.h" #include "time-accounts.h" #include "taketwo.h" +#include "felix.h" enum { @@ -99,9 +100,9 @@ struct index_args float fix_profile_r; float fix_bandwidth; float fix_divergence; - char *felix_options; int profile; /* Whether or not to do wall clock profiling */ struct taketwo_options taketwo_opts; + struct felix_options felix_opts; }; |