aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2019-09-23 14:56:27 +0200
committerThomas White <taw@physics.org>2019-09-23 14:56:27 +0200
commit7251c3d83cc0bce49597ec41f97f930d5f70fb78 (patch)
tree4f0801ede67a2143cc05c86c314ecab40502e46a
parent7fcddbf213e2674871ef078a3b228a32fd9f488f (diff)
parentaad71902c94b3bc21ab34b0e2c92972400921574 (diff)
Merge branch 'tom/pinkindexer'
-rw-r--r--doc/man/indexamajig.140
-rw-r--r--libcrystfel/CMakeLists.txt3
-rw-r--r--libcrystfel/config.h.cmake.in2
-rw-r--r--libcrystfel/src/detector.c14
-rw-r--r--libcrystfel/src/geometry.c2
-rw-r--r--libcrystfel/src/image.h2
-rw-r--r--libcrystfel/src/index.c71
-rw-r--r--libcrystfel/src/index.h11
-rw-r--r--libcrystfel/src/pinkindexer.c535
-rw-r--r--libcrystfel/src/pinkindexer.h65
-rw-r--r--src/im-sandbox.c20
-rw-r--r--src/im-sandbox.h2
-rw-r--r--src/indexamajig.c30
-rw-r--r--src/process_image.c13
-rw-r--r--src/process_image.h1
15 files changed, 779 insertions, 32 deletions
diff --git a/doc/man/indexamajig.1 b/doc/man/indexamajig.1
index 5b51566f..9dfdd70d 100644
--- a/doc/man/indexamajig.1
+++ b/doc/man/indexamajig.1
@@ -90,6 +90,11 @@ Use the TakeTwo algorithm. See Ginn et al., Acta Cryst. (2016). D72, 956-965.
.PD
Invoke XGANDALF - eXtended GrAdieNt Descent Algorithm for Lattice Finding. Xgandalf must be installed in order to be able to use it.
+.IP \fBpinkIndexer\fR
+.PD
+Invoke pinkIndexer. pinkIndexer must be installed in order to be able to use it. The geometry file should contain the value photon_energy_bandwidth, which sets the bandwidth as (delta energy)/(mean energy).
+
+
.PP
You can add one or more of the following to the above indexing methods, to control what information should be provided to them. Note that indexamajig performs a series of checks on the indexing results, including checking that the result is consistent with the target unit cell parameters. To get completely "raw" indexing, you need to disable these checks (see below) \fBand\fR not provide prior information.
@@ -437,6 +442,38 @@ These set low-level parameters for the XGANDALF indexing algorithm.
.IP
\fB--xgandalf-fast-execution\fR Shortcut to set --xgandalf-sampling-pitch=2 --xgandalf-grad-desc-iterations=3
+.PD 0
+.IP \fB--pinkIndexer-considered-peaks-count=\fIn\fR
+.IP \fB--pinkIndexer-angle-resolution=\fIn\fR
+.IP \fB--pinkIndexer-refinement-type=\fIn\fR
+.IP \fB--pinkIndexer-tolerance=\fIn\fR
+.IP \fB--pinkIndexer-reflection-radius=\fIn\fR
+.IP \fB--pinkIndexer-max-resolution-for-indexing=\fIn\fR
+.IP \fB--pinkIndexer-multi=\fIn\fR
+.IP \fB--pinkIndexer-thread-count=\fIn\fR
+.IP \fB--pinkIndexer-no-check-indexed=\fIn\fR
+
+.PD
+These set low-level parameters for the XGANDALF indexing algorithm.
+.IP
+\fB--pinkIndexer-considered-peaks-count\fR selects how many peaks are considered for indexing. [0-4] (veryFew to manyMany). Default is 4 (manyMany).
+.IP
+\fB--pinkIndexer-angle-resolution\fR selects how dense the orientation angles of the sample lattice are sampled. [0-4] (extremelyLoose to extremelyDense). Default is 2 (normal).
+.IP
+\fB--pinkIndexer-refinement-type\fR selects the refinement type. 0 = none, 1 = fixedLatticeParameters, 2 = variableLatticeParameters, 3 = firstFixedThenVariableLatticeParameters, 4 = firstFixedThenVariableLatticeParametersMultiSeed, 5 = firstFixedThenVariableLatticeParametersCenterAdjustmentMultiSeed.
+.IP
+\fB--pinkIndexer-tolerance\fR selects the tolerance of the pinkIndexer (relative tolerance of the lattice vectors). Default is 0.06. For bad geometrys or cell parameters use a high tolerance. For a well known geometry and cell use a small tolerance. Only important for refinement and indexed/not indexed identificaton. Too small tolerance will lead to refining to only a fraction of the peaks and possibly discarding of correctly indexed images. Too high tolerance will lead to bad fitting in presence of multiples or noise and can mark wrongly-indexed patterns as indexed.
+.IP
+\fB--pinkIndexer-reflection-radius\fR sets radius of the reflections in reciprocal space in 1/A. Default is 2%% of a* (which works quiet well for X-rays). Should be chosen much bigger for electrons (~0.002).
+.IP
+\fB--pinkIndexer-max-resolution-for-indexing\fR sets the maximum resolition in 1/A used for indexing. Peaks at high resolution don't add much information, but they add a lot of computation time. Default is infinity. Does not influence the refinement.
+.IP
+\fB--pinkIndexer-multi\fR Use pinkIndexers own multi indexing. Should be combined with the --no-multi flag.
+.IP
+\fB--pinkIndexer-thread-count\fR sets the thread count for internal parallelization. Default is 1. Very useful for small datasets (e.g. for screening). Internal parallelization does not significantly increase the amount of RAM needed, whereas CrystFELs parallelization does. For HPCs typically a mixture of both parallelizations leads to best results.
+.IP
+\fB--pinkIndexer-no-check-indexed\fR Leave the check whether a pattern is indexed completely to CrystFEL. Useful for monochromatic (since CrystFELs prediction model is smarter than the one of pinkIndexer) or in combnation with --no-check-peaks for geometry optimization. This flag is meant to eventually disappear, when the full pink pipeline is implemented.
+
.SH INTEGRATION OPTIONS
.PD 0
.IP \fB--integration=\fR\fImethod\fR
@@ -445,10 +482,9 @@ Integrate the reflections using \fImethod\fR. See the section titled \fBPEAK IN
.PD 0
.IP \fB--fix-profile-radius=\fIn\fR
-.IP \fB--fix-bandwidth=\fIn\fR
.IP \fB--fix-divergence=\fIn\fR
.PD
-Fix the beam and crystal paramters to the given values. The profile radius is given in m^-1, the bandwidth as a decimal fraction and the divergence in radians (full angle). The default is to set the divergence to zero, the bandwidth to a very small value, and then to automatically determine the profile radius.
+Fix the beam and crystal paramters to the given values. The profile radius is given in m^-1 and the divergence in radians (full angle). The default is to set the divergence to zero, and then to automatically determine the profile radius.
.IP
You do not have to use all three of these options together. For example, if the automatic profile radius determination is not working well for your data set, you could fix that alone and continue using the default values for the other parameters (which might be automatically determined in future versions of CrystFEL, but are not currently).
diff --git a/libcrystfel/CMakeLists.txt b/libcrystfel/CMakeLists.txt
index e037abf6..10e0584d 100644
--- a/libcrystfel/CMakeLists.txt
+++ b/libcrystfel/CMakeLists.txt
@@ -12,6 +12,7 @@ pkg_search_module(FFTW fftw3)
set(HAVE_CURSES ${CURSES_FOUND})
set(HAVE_FFTW ${FFTW_FOUND})
set(HAVE_XGANDALF ${XGANDALF_FOUND})
+set(HAVE_PINKINDEXER ${PINKINDEXER_FOUND})
set(HAVE_FDIP ${FDIP_FOUND})
# Find out where forkpty() is declared
@@ -65,6 +66,7 @@ set(LIBCRYSTFEL_SOURCES
src/peakfinder8.c
src/taketwo.c
src/xgandalf.c
+ src/pinkindexer.c
src/rational.c
src/spectrum.c
${BISON_symopp_OUTPUTS}
@@ -106,6 +108,7 @@ set(LIBCRYSTFEL_HEADERS
src/peakfinder8.h
src/taketwo.h
src/xgandalf.h
+ src/pinkindexer.h
src/rational.h
src/spectrum.h
)
diff --git a/libcrystfel/config.h.cmake.in b/libcrystfel/config.h.cmake.in
index ea26c1a2..b7ad4c7a 100644
--- a/libcrystfel/config.h.cmake.in
+++ b/libcrystfel/config.h.cmake.in
@@ -4,6 +4,8 @@
#cmakedefine HAVE_CPU_AFFINITY
#cmakedefine HAVE_FFTW
#cmakedefine HAVE_XGANDALF
+#cmakedefine HAVE_NBP
+#cmakedefine HAVE_PINKINDEXER
#cmakedefine HAVE_FDIP
#cmakedefine HAVE_CURSES
diff --git a/libcrystfel/src/detector.c b/libcrystfel/src/detector.c
index 201b9041..4d008e65 100644
--- a/libcrystfel/src/detector.c
+++ b/libcrystfel/src/detector.c
@@ -1070,6 +1070,19 @@ static void parse_toplevel(struct detector *det, struct beam_params *beam,
}
}
+ } else if ( strcmp(key, "photon_energy_bandwidth") == 0 ) {
+ if ( beam != NULL ) {
+ double v;
+ char *end;
+ v = strtod(val, &end);
+ if ( (val[0] != '\0') && (end[0] == '\0') ) {
+ beam->bandwidth = v;
+ } else {
+ ERROR("Invalid value for "
+ "photon_energy_bandwidth\n");
+ }
+ }
+
} else if ( strcmp(key, "photon_energy_scale") == 0 ) {
if ( beam != NULL ) {
beam->photon_energy_scale = atof(val);
@@ -1202,6 +1215,7 @@ struct detector *get_detector_geometry_from_string(const char *string,
beam->photon_energy = 0.0;
beam->photon_energy_from = NULL;
beam->photon_energy_scale = 1.0;
+ beam->bandwidth = 0.00000001;
}
det->n_panels = 0;
diff --git a/libcrystfel/src/geometry.c b/libcrystfel/src/geometry.c
index 5b2107d1..fc42a8de 100644
--- a/libcrystfel/src/geometry.c
+++ b/libcrystfel/src/geometry.c
@@ -332,7 +332,7 @@ static Reflection *check_reflection(struct image *image, Crystal *cryst,
/* Closest point on Ewald sphere.
* Project zl to 0, bit of a hack... */
- const double zlp0 = zl>0?zl:0;
+ const double zlp0 = zl<0?zl:0;
exerr2 = (x-xl)*(x-xl) + (y-yl)*(y-yl) + (z-zl)*(z-zl);
/* Weighted average between projected lattice point
diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h
index 706b06b1..04fb18a0 100644
--- a/libcrystfel/src/image.h
+++ b/libcrystfel/src/image.h
@@ -110,6 +110,8 @@ struct beam_params
char *photon_energy_from; /**< HDF5 dataset name */
double photon_energy_scale; /**< Scale factor for photon energy, if it
* comes from an image header */
+ double bandwidth; /**< FWHM bandwidth as a fraction of
+ * wavelength */
};
diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c
index f6e81109..049c3ba0 100644
--- a/libcrystfel/src/index.c
+++ b/libcrystfel/src/index.c
@@ -58,6 +58,7 @@
#include "predict-refine.h"
#include "taketwo.h"
#include "xgandalf.h"
+#include "pinkindexer.h"
/** \file index.h */
@@ -71,6 +72,7 @@ struct _indexingprivate
struct taketwo_options *ttopts;
struct xgandalf_options *xgandalf_opts;
+ struct pinkIndexer_options *pinkIndexer_opts;
int n_methods;
IndexingMethod *methods;
@@ -195,6 +197,10 @@ static char *base_indexer_str(IndexingMethod indm)
strcpy(str, "xgandalf");
break;
+ case INDEXING_PINKINDEXER:
+ strcpy(str, "pinkIndexer");
+ break;
+
case INDEXING_SIMULATION :
strcpy(str, "simulation");
break;
@@ -232,7 +238,9 @@ static char *friendly_indexer_name(IndexingMethod m)
static void *prepare_method(IndexingMethod *m, UnitCell *cell,
+ struct detector *det, struct beam_params *beam,
struct xgandalf_options *xgandalf_opts,
+ struct pinkIndexer_options* pinkIndexer_opts,
struct felix_options *felix_opts)
{
char *str;
@@ -277,6 +285,11 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell,
priv = xgandalf_prepare(m, cell, xgandalf_opts);
break;
+ case INDEXING_PINKINDEXER :
+ priv = pinkIndexer_prepare(m, cell, pinkIndexer_opts,
+ det, beam);
+ break;
+
default :
ERROR("Don't know how to prepare indexing method %i\n", *m);
break;
@@ -305,10 +318,11 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell,
IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell,
- struct detector *det, float *tols,
- IndexingFlags flags,
+ struct detector *det, struct beam_params *beam,
+ float *tols, IndexingFlags flags,
struct taketwo_options *ttopts,
struct xgandalf_options *xgandalf_opts,
+ struct pinkIndexer_options *pinkIndexer_opts,
struct felix_options *felix_opts)
{
int i, n;
@@ -333,7 +347,6 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell,
ERROR("The indexing method should contain only the method itself and ");
ERROR("prior information modifiers ('cell' or 'latt')\n");
ERROR("To disable prediction refinement ('norefine'), use --no-refine.\n");
- ERROR("To check cell axes only ('axes'), use --no-cell-combinations.\n");
ERROR("To disable all unit cell checks ('raw'), use --no-check-cell.\n");
ERROR("To disable peak alignment check ('bad'), use --no-check-peaks.\n");
ERROR("To disable indexing retry ('noretry'), use --no-retry.\n");
@@ -403,11 +416,36 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell,
int j;
ipriv->engine_private[i] = prepare_method(&methods[i], cell,
+ det, beam,
xgandalf_opts,
+ pinkIndexer_opts,
felix_opts);
if ( ipriv->engine_private[i] == NULL ) return NULL;
+ if ( (methods[i] & INDEXING_METHOD_MASK) == INDEXING_PINKINDEXER ) {
+ if ( n > 1 ) {
+ ERROR("WARNING: Using PinkIndexer at the same "
+ "time as other indexers is not "
+ "recommended.\n");
+ }
+
+ if ( flags & INDEXING_CHECK_PEAKS ) {
+ ERROR("WARNING: Setting --no-check-peaks "
+ "because PinkIndexer is in use.\n");
+ }
+ flags |= INDEXING_CHECK_PEAKS;
+ flags ^= INDEXING_CHECK_PEAKS;
+
+ if ( flags & INDEXING_REFINE ) {
+ ERROR("WARNING: Setting --no-refine because "
+ "PinkIndexer is in use.\n");
+ }
+ flags |= INDEXING_REFINE;
+ flags ^= INDEXING_REFINE;
+ }
+
+
for ( j=0; j<i; j++ ) {
if ( methods[i] == methods[j] ) {
ERROR("Duplicate indexing method.\n");
@@ -430,6 +468,7 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell,
ipriv->ttopts = ttopts;
ipriv->xgandalf_opts = xgandalf_opts;
+ ipriv->pinkIndexer_opts = pinkIndexer_opts;
STATUS("List of indexing methods:\n");
for ( i=0; i<n; i++ ) {
@@ -445,6 +484,13 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell,
}
+const IndexingMethod *indexing_methods(IndexingPrivate *p, int *n)
+{
+ *n = p->n_methods;
+ return p->methods;
+}
+
+
void cleanup_indexing(IndexingPrivate *ipriv)
{
int n;
@@ -490,6 +536,10 @@ void cleanup_indexing(IndexingPrivate *ipriv)
xgandalf_cleanup(ipriv->engine_private[n]);
break;
+ case INDEXING_PINKINDEXER :
+ pinkIndexer_cleanup(ipriv->engine_private[n]);
+ break;
+
default :
ERROR("Don't know how to clean up indexing method %i\n",
ipriv->methods[n]);
@@ -602,6 +652,11 @@ static int try_indexer(struct image *image, IndexingMethod indm,
r = taketwo_index(image, ipriv->ttopts, mpriv);
break;
+ case INDEXING_PINKINDEXER :
+ set_last_task(last_task, "indexing:pinkindexer");
+ r = run_pinkIndexer(image, mpriv);
+ break;
+
case INDEXING_XGANDALF :
set_last_task(last_task, "indexing:xgandalf");
r = run_xgandalf(image, mpriv);
@@ -1000,6 +1055,13 @@ IndexingMethod get_indm_from_string_2(const char *str, int *err)
method = INDEXING_DEFAULTS_XGANDALF;
have_method = 1;
+ } else if ( (strcmp(bits[i], "pinkIndexer") == 0)
+ || (strcmp(bits[i], "pinkindexer") == 0) )
+ {
+ if ( have_method ) return warn_method(str);
+ method = INDEXING_DEFAULTS_PINKINDEXER;
+ have_method = 1;
+
} else if ( strcmp(bits[i], "none") == 0) {
if ( have_method ) return warn_method(str);
method = INDEXING_NONE;
@@ -1098,9 +1160,10 @@ char *detect_indexing_methods(UnitCell *cell)
do_probe(asdf_probe, cell, methods);
do_probe(xds_probe, cell, methods);
do_probe(xgandalf_probe, cell, methods);
- /* Don't automatically use TakeTwo or Felix (yet) */
+ /* Don't automatically use TakeTwo, Felix or PinkIndexer (yet) */
//do_probe(taketwo_probe, cell, methods);
//do_probe(felix_probe, cell, methods);
+ //do_probe(pinkIndexer_probe, cell, methods);
if ( strlen(methods) == 0 ) {
free(methods);
diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h
index eb5cf7e4..5e9e40ad 100644
--- a/libcrystfel/src/index.h
+++ b/libcrystfel/src/index.h
@@ -63,6 +63,8 @@
#define INDEXING_DEFAULTS_XGANDALF (INDEXING_XGANDALF | INDEXING_USE_CELL_PARAMETERS)
+#define INDEXING_DEFAULTS_PINKINDEXER (INDEXING_PINKINDEXER | INDEXING_USE_CELL_PARAMETERS)
+
/**
* An enumeration of all the available indexing methods.
**/
@@ -79,6 +81,7 @@ typedef enum {
INDEXING_ASDF = 8, /**< Use built-in ASDF algorithm */
INDEXING_TAKETWO = 9, /**< Use built-in TakeTwo algorithm */
INDEXING_XGANDALF = 10, /**< Use XGANDALF (via optional library) */
+ INDEXING_PINKINDEXER = 11,/**< Use PinkIndexer (via optional library) */
INDEXING_ERROR = 255, /**< Special value for unrecognised indexing
* engine */
@@ -146,16 +149,20 @@ extern IndexingMethod get_indm_from_string_2(const char *method, int *err);
#include "image.h"
#include "taketwo.h"
#include "xgandalf.h"
+#include "pinkindexer.h"
#include "felix.h"
-
extern IndexingPrivate *setup_indexing(const char *methods, UnitCell *cell,
- struct detector *det, float *ltl,
+ struct detector *det,
+ struct beam_params *beam, float *ltl,
IndexingFlags flags,
struct taketwo_options *ttopts,
struct xgandalf_options *xgandalf_opts,
+ struct pinkIndexer_options *pinkIndexer_opts,
struct felix_options *felix_opts);
+extern const IndexingMethod *indexing_methods(IndexingPrivate *p, int *n);
+
extern char *detect_indexing_methods(UnitCell *cell);
extern void index_pattern(struct image *image, IndexingPrivate *ipriv);
diff --git a/libcrystfel/src/pinkindexer.c b/libcrystfel/src/pinkindexer.c
new file mode 100644
index 00000000..811aa3c8
--- /dev/null
+++ b/libcrystfel/src/pinkindexer.c
@@ -0,0 +1,535 @@
+/*
+ * pinkindexer.c
+ *
+ * Interface to PinkIndexer
+ *
+ * Copyright © 2017-2019 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2017-2019 Yaroslav Gevorkov <yaroslav.gevorkov@desy.de>
+ *
+ * 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/>.
+ *
+ */
+
+#include "pinkindexer.h"
+
+#ifdef HAVE_PINKINDEXER
+
+#include <stdlib.h>
+
+#include "utils.h"
+#include "cell-utils.h"
+#include "peaks.h"
+
+#include "pinkIndexer/adaptions/crystfel/Lattice.h"
+#include "pinkIndexer/adaptions/crystfel/ExperimentSettings.h"
+#include "pinkIndexer/adaptions/crystfel/PinkIndexer.h"
+
+#define MAX_MULTI_LATTICE_COUNT 8
+
+struct pinkIndexer_private_data {
+ PinkIndexer *pinkIndexer;
+ reciprocalPeaks_1_per_A_t reciprocalPeaks_1_per_A;
+ float *intensities;
+
+ IndexingMethod indm;
+ UnitCell *cellTemplate;
+ int threadCount;
+ int multi;
+ int min_peaks;
+
+ int no_check_indexed;
+
+ IntegerMatrix *centeringTransformation;
+ LatticeTransform_t latticeReductionTransform;
+};
+
+//static void reduceCell(UnitCell* cell, LatticeTransform_t* appliedReductionTransform);
+//static void restoreCell(UnitCell *cell, LatticeTransform_t* appliedReductionTransform);
+static void reduceReciprocalCell(UnitCell* cell, LatticeTransform_t* appliedReductionTransform);
+static void restoreReciprocalCell(UnitCell *cell, LatticeTransform_t* appliedReductionTransform);
+static void makeRightHanded(UnitCell* cell);
+static void update_detector(struct detector *det, double xoffs, double yoffs);
+
+int run_pinkIndexer(struct image *image, void *ipriv)
+{
+ struct pinkIndexer_private_data* pinkIndexer_private_data = (struct pinkIndexer_private_data*) ipriv;
+ reciprocalPeaks_1_per_A_t* reciprocalPeaks_1_per_A = &(pinkIndexer_private_data->reciprocalPeaks_1_per_A);
+ float *intensities = pinkIndexer_private_data->intensities;
+
+ int peakCountMax = image_feature_count(image->features);
+ if (peakCountMax < 5) {
+ int goodLatticesCount = 0;
+ return goodLatticesCount;
+ }
+ reciprocalPeaks_1_per_A->peakCount = 0;
+ for (int i = 0; i < peakCountMax && i < MAX_PEAK_COUNT_FOR_INDEXER; i++) {
+ struct imagefeature *f;
+ f = image_get_feature(image->features, i);
+ if (f == NULL) {
+ continue;
+ }
+
+ reciprocalPeaks_1_per_A->coordinates_x[reciprocalPeaks_1_per_A->peakCount] = f->rz * 1e-10;
+ reciprocalPeaks_1_per_A->coordinates_y[reciprocalPeaks_1_per_A->peakCount] = f->rx * 1e-10;
+ reciprocalPeaks_1_per_A->coordinates_z[reciprocalPeaks_1_per_A->peakCount] = f->ry * 1e-10;
+ intensities[reciprocalPeaks_1_per_A->peakCount] = (float) (f->intensity);
+ reciprocalPeaks_1_per_A->peakCount++;
+ }
+ int indexed = 0;
+ Lattice_t indexedLattice[MAX_MULTI_LATTICE_COUNT];
+ float center_shift[MAX_MULTI_LATTICE_COUNT][2];
+
+ float maxRefinementDisbalance = 0.4;
+
+ do {
+ int peakCount = reciprocalPeaks_1_per_A->peakCount;
+ int matchedPeaksCount = PinkIndexer_indexPattern(pinkIndexer_private_data->pinkIndexer,
+ &(indexedLattice[indexed]), center_shift[indexed], reciprocalPeaks_1_per_A, intensities,
+ maxRefinementDisbalance,
+ pinkIndexer_private_data->threadCount);
+
+ if ((matchedPeaksCount >= 25 && matchedPeaksCount >= peakCount * 0.30)
+ || matchedPeaksCount >= peakCount * 0.4
+ || matchedPeaksCount >= 70
+ || pinkIndexer_private_data->no_check_indexed == 1)
+ {
+ UnitCell *uc;
+ uc = cell_new();
+
+ Lattice_t *l = &(indexedLattice[indexed]);
+
+ cell_set_reciprocal(uc, l->ay * 1e10, l->az * 1e10, l->ax * 1e10,
+ l->by * 1e10, l->bz * 1e10, l->bx * 1e10,
+ l->cy * 1e10, l->cz * 1e10, l->cx * 1e10);
+
+ restoreReciprocalCell(uc, &pinkIndexer_private_data->latticeReductionTransform);
+
+ UnitCell *new_cell_trans = cell_transform_intmat(uc, pinkIndexer_private_data->centeringTransformation);
+ cell_free(uc);
+ uc = new_cell_trans;
+
+ cell_set_lattice_type(new_cell_trans, cell_get_lattice_type(pinkIndexer_private_data->cellTemplate));
+ cell_set_centering(new_cell_trans, cell_get_centering(pinkIndexer_private_data->cellTemplate));
+ cell_set_unique_axis(new_cell_trans, cell_get_unique_axis(pinkIndexer_private_data->cellTemplate));
+
+ if (validate_cell(uc)) {
+ ERROR("pinkIndexer: problem with returned cell!\n");
+ }
+
+ Crystal * cr = crystal_new();
+ if (cr == NULL) {
+ ERROR("Failed to allocate crystal.\n");
+ return 0;
+ }
+ crystal_set_cell(cr, uc);
+ crystal_set_det_shift(cr, center_shift[indexed][0], center_shift[indexed][1]);
+ update_detector(image->det, center_shift[indexed][0], center_shift[indexed][1]);
+ image_add_crystal(image, cr);
+ indexed++;
+
+ } else {
+ break;
+ }
+ } while (pinkIndexer_private_data->multi
+ && indexed <= MAX_MULTI_LATTICE_COUNT
+ && reciprocalPeaks_1_per_A->peakCount >= pinkIndexer_private_data->min_peaks);
+
+ return indexed;
+}
+
+void *pinkIndexer_prepare(IndexingMethod *indm, UnitCell *cell,
+ struct pinkIndexer_options *pinkIndexer_opts,
+ struct detector *det, struct beam_params *beam)
+{
+ if ( beam->photon_energy_from != NULL ) {
+ ERROR("For pinkIndexer, the photon_energy must be defined as a "
+ "constant in the geometry file\n");
+ return NULL;
+ }
+ if ( (det->panels[0].clen_from != NULL) && pinkIndexer_opts->refinement_type ==
+ REFINEMENT_TYPE_firstFixedThenVariableLatticeParametersCenterAdjustmentMultiSeed) {
+ ERROR("Using center refinement makes it necessary to have the detector distance fixed in the geometry file!");
+ }
+
+ struct pinkIndexer_private_data* pinkIndexer_private_data = malloc(sizeof(struct pinkIndexer_private_data));
+ allocReciprocalPeaks(&(pinkIndexer_private_data->reciprocalPeaks_1_per_A));
+ pinkIndexer_private_data->intensities = malloc(MAX_PEAK_COUNT_FOR_INDEXER * sizeof(float));
+ pinkIndexer_private_data->indm = *indm;
+ pinkIndexer_private_data->cellTemplate = cell;
+ pinkIndexer_private_data->threadCount = pinkIndexer_opts->thread_count;
+ pinkIndexer_private_data->multi = pinkIndexer_opts->multi;
+ pinkIndexer_private_data->min_peaks = pinkIndexer_opts->min_peaks;
+ pinkIndexer_private_data->no_check_indexed = pinkIndexer_opts->no_check_indexed;
+
+ UnitCell* primitiveCell = uncenter_cell(cell, &pinkIndexer_private_data->centeringTransformation, NULL);
+
+ //reduceCell(primitiveCell, &pinkIndexer_private_data->latticeReductionTransform);
+ reduceReciprocalCell(primitiveCell, &pinkIndexer_private_data->latticeReductionTransform);
+
+ double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz;
+ int ret = cell_get_reciprocal(primitiveCell, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz);
+ if (ret != 0) {
+ ERROR("cell_get_reciprocal did not finish properly!");
+ }
+
+ Lattice_t lattice = { .ax = asz * 1e-10, .ay = asx * 1e-10, .az = asy * 1e-10,
+ .bx = bsz * 1e-10, .by = bsx * 1e-10, .bz = bsy * 1e-10,
+ .cx = csz * 1e-10, .cy = csx * 1e-10, .cz = csy * 1e-10 };
+
+ float detectorDistance_m;
+ if ( det->panels[0].clen_from != NULL ) {
+ detectorDistance_m = 0.25; /* fake value */
+ } else {
+ detectorDistance_m = det->panels[0].clen + det->panels[0].coffset;
+ }
+
+ float beamEenergy_eV = beam->photon_energy;
+ float nonMonochromaticity = beam->bandwidth;
+ float reflectionRadius_1_per_A;
+ if (pinkIndexer_opts->reflectionRadius < 0) {
+ reflectionRadius_1_per_A = 0.02
+ * sqrt(lattice.ax * lattice.ax + lattice.ay * lattice.ay + lattice.az * lattice.az);
+ }
+ else {
+ reflectionRadius_1_per_A = pinkIndexer_opts->reflectionRadius;
+ }
+
+ float divergenceAngle_deg = 0.01; //fake
+
+ float tolerance = pinkIndexer_opts->tolerance;
+ Lattice_t sampleReciprocalLattice_1_per_A = lattice;
+ float detectorRadius_m = 0.03; //fake, only for prediction
+ ExperimentSettings* experimentSettings = ExperimentSettings_new(beamEenergy_eV, detectorDistance_m,
+ detectorRadius_m, divergenceAngle_deg, nonMonochromaticity, sampleReciprocalLattice_1_per_A, tolerance,
+ reflectionRadius_1_per_A);
+
+ consideredPeaksCount_t consideredPeaksCount = pinkIndexer_opts->considered_peaks_count;
+ angleResolution_t angleResolution = pinkIndexer_opts->angle_resolution;
+ refinementType_t refinementType = pinkIndexer_opts->refinement_type;
+ float maxResolutionForIndexing_1_per_A = pinkIndexer_opts->maxResolutionForIndexing_1_per_A;
+ pinkIndexer_private_data->pinkIndexer = PinkIndexer_new(experimentSettings, consideredPeaksCount, angleResolution,
+ refinementType,
+ maxResolutionForIndexing_1_per_A);
+
+ ExperimentSettings_delete(experimentSettings);
+ cell_free(primitiveCell);
+
+ /* Flags that pinkIndexer knows about */
+ *indm &= INDEXING_METHOD_MASK
+ | INDEXING_USE_CELL_PARAMETERS;
+
+ return pinkIndexer_private_data;
+}
+
+//static void reduceCell(UnitCell *cell, LatticeTransform_t* appliedReductionTransform)
+//{
+// double ax, ay, az, bx, by, bz, cx, cy, cz;
+// cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz);
+//
+// Lattice_t l = { ax, ay, az, bx, by, bz, cx, cy, cz };
+//
+// reduceLattice(&l, appliedReductionTransform);
+//
+// cell_set_cartesian(cell, l.ax, l.ay, l.az,
+// l.bx, l.by, l.bz,
+// l.cx, l.cy, l.cz);
+//
+// makeRightHanded(cell);
+//}
+//
+//static void restoreCell(UnitCell *cell, LatticeTransform_t* appliedReductionTransform)
+//{
+//
+// double ax, ay, az, bx, by, bz, cx, cy, cz;
+// cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz);
+//
+// Lattice_t l = { ax, ay, az, bx, by, bz, cx, cy, cz };
+//
+// restoreLattice(&l, appliedReductionTransform);
+//
+// cell_set_cartesian(cell, l.ax, l.ay, l.az,
+// l.bx, l.by, l.bz,
+// l.cx, l.cy, l.cz);
+//
+// makeRightHanded(cell);
+//}
+
+static void reduceReciprocalCell(UnitCell *cell, LatticeTransform_t* appliedReductionTransform)
+{
+ double ax, ay, az, bx, by, bz, cx, cy, cz;
+ cell_get_reciprocal(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz);
+
+ Lattice_t l = { ax, ay, az, bx, by, bz, cx, cy, cz };
+
+ reduceLattice(&l, appliedReductionTransform);
+
+ cell_set_reciprocal(cell, l.ax, l.ay, l.az,
+ l.bx, l.by, l.bz,
+ l.cx, l.cy, l.cz);
+
+ makeRightHanded(cell);
+}
+
+static void restoreReciprocalCell(UnitCell *cell, LatticeTransform_t* appliedReductionTransform)
+{
+
+ double ax, ay, az, bx, by, bz, cx, cy, cz;
+ cell_get_reciprocal(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz);
+
+ Lattice_t l = { ax, ay, az, bx, by, bz, cx, cy, cz };
+
+ restoreLattice(&l, appliedReductionTransform);
+
+ cell_set_reciprocal(cell, l.ax, l.ay, l.az,
+ l.bx, l.by, l.bz,
+ l.cx, l.cy, l.cz);
+
+ makeRightHanded(cell);
+}
+
+static void makeRightHanded(UnitCell *cell)
+{
+ double ax, ay, az, bx, by, bz, cx, cy, cz;
+ cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz);
+
+ if (!right_handed(cell)) {
+ cell_set_cartesian(cell, -ax, -ay, -az, -bx, -by, -bz, -cx, -cy, -cz);
+ }
+}
+
+//hack for electron crystallography while crystal_set_det_shift is not working approprietly
+static void update_detector(struct detector *det, double xoffs, double yoffs)
+{
+ int i;
+
+ for (i = 0; i < det->n_panels; i++) {
+ struct panel *p = &det->panels[i];
+ p->cnx += xoffs * p->res;
+ p->cny += yoffs * p->res;
+ }
+}
+
+void pinkIndexer_cleanup(void *pp)
+{
+ struct pinkIndexer_private_data* pinkIndexer_private_data = (struct pinkIndexer_private_data*) pp;
+
+ freeReciprocalPeaks(pinkIndexer_private_data->reciprocalPeaks_1_per_A);
+ free(pinkIndexer_private_data->intensities);
+ intmat_free(pinkIndexer_private_data->centeringTransformation);
+ PinkIndexer_delete(pinkIndexer_private_data->pinkIndexer);
+}
+
+const char *pinkIndexer_probe(UnitCell *cell)
+{
+ return "pinkIndexer";
+}
+
+#else /* HAVE_PINKINDEXER */
+
+int run_pinkIndexer(struct image *image, void *ipriv)
+{
+ ERROR("This copy of CrystFEL was compiled without PINKINDEXER support.\n");
+ return 0;
+}
+
+extern void *pinkIndexer_prepare(IndexingMethod *indm, UnitCell *cell,
+ struct pinkIndexer_options *pinkIndexer_opts,
+ struct detector *det, struct beam_params *beam)
+{
+ ERROR("This copy of CrystFEL was compiled without PINKINDEXER support.\n");
+ ERROR("To use PINKINDEXER indexing, recompile with PINKINDEXER.\n");
+ return NULL;
+}
+
+void pinkIndexer_cleanup(void *pp)
+{
+}
+
+const char *pinkIndexer_probe(UnitCell *cell)
+{
+ return NULL;
+}
+
+#endif /* HAVE_PINKINDEXER */
+
+static void show_help()
+{
+ printf("Parameters for the PinkIndexer indexing algorithm:\n"
+" --pinkIndexer-considered-peaks-count\n"
+" Considered peaks count, 0 (fewest) to 4 (most)\n"
+" Default: 4\n"
+" --pinkIndexer-angle-resolution\n"
+" Angle resolution, 0 (loosest) to 4 (most dense)\n"
+" Default: 2\n"
+" --pinkIndexer-refinement-type\n"
+" Refinement type, 0 (none) to 5 (most accurate)\n"
+" Default: 1\n"
+" --pinkIndexer-tolerance\n"
+" Relative tolerance of the lattice vectors.\n"
+" Default 0.06\n"
+" --pinkIndexer-reflection-radius\n"
+" Radius of the reflections in reciprocal space.\n"
+" Specified in 1/A. Default is 2%% of a*.\n"
+" --pinkIndexer-max-resolution-for-indexing\n"
+" Measured in 1/A\n"
+" --pinkIndexer-multi Use pinkIndexers own multi indexing.\n"
+" --pinkIndexer-thread-count\n"
+" Thread count for internal parallelization \n"
+" Default: 1\n"
+" --pinkIndexer-no-check-indexed\n"
+" Disable internal check for correct indexing\n"
+" solutions\n"
+);
+}
+
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+ float tmp;
+ struct pinkIndexer_options **opts_ptr = state->input;
+
+ switch ( key ) {
+
+ case ARGP_KEY_INIT :
+ *opts_ptr = malloc(sizeof(struct pinkIndexer_options));
+ if ( *opts_ptr == NULL ) return ENOMEM;
+ (*opts_ptr)->considered_peaks_count = 4;
+ (*opts_ptr)->angle_resolution = 2;
+ (*opts_ptr)->refinement_type = 1;
+ (*opts_ptr)->tolerance = 0.06;
+ (*opts_ptr)->maxResolutionForIndexing_1_per_A = +INFINITY;
+ (*opts_ptr)->thread_count = 1;
+ (*opts_ptr)->multi = 0;
+ (*opts_ptr)->no_check_indexed = 0;
+ (*opts_ptr)->min_peaks = 2;
+ (*opts_ptr)->reflectionRadius = -1;
+ break;
+
+ case 1 :
+ show_help();
+ return EINVAL;
+
+ case 2 :
+ if (sscanf(arg, "%u", &(*opts_ptr)->considered_peaks_count) != 1)
+ {
+ ERROR("Invalid value for "
+ "--pinkIndexer-considered-peaks-count\n");
+ return EINVAL;
+ }
+ break;
+
+ case 3 :
+ if (sscanf(arg, "%u", &(*opts_ptr)->angle_resolution) != 1)
+ {
+ ERROR("Invalid value for "
+ "--pinkIndexer-angle_resolution\n");
+ return EINVAL;
+ }
+ break;
+
+ case 4 :
+ if (sscanf(arg, "%u", &(*opts_ptr)->refinement_type) != 1)
+ {
+ ERROR("Invalid value for "
+ "--pinkIndexer-refinement-type\n");
+ return EINVAL;
+ }
+ break;
+
+ case 5 :
+ if (sscanf(arg, "%d", &(*opts_ptr)->thread_count) != 1)
+ {
+ ERROR("Invalid value for --pinkIndexer-thread-count\n");
+ return EINVAL;
+ }
+ break;
+
+ case 6 :
+ if (sscanf(arg, "%f", &(*opts_ptr)->maxResolutionForIndexing_1_per_A) != 1)
+ {
+ ERROR("Invalid value for "
+ "--pinkIndexer-max-resolution-for-indexing\n");
+ return EINVAL;
+ }
+ break;
+
+ case 7 :
+ if (sscanf(arg, "%f", &(*opts_ptr)->tolerance) != 1)
+ {
+ ERROR("Invalid value for --pinkIndexer-tolerance\n");
+ return EINVAL;
+ }
+ break;
+
+ case 8 :
+ (*opts_ptr)->multi = 1;
+ break;
+
+ case 9 :
+ (*opts_ptr)->no_check_indexed = 1;
+ break;
+
+ case 10 :
+ if (sscanf(arg, "%f", &tmp) != 1) {
+ ERROR("Invalid value for --pinkIndexer-reflection-radius\n");
+ return EINVAL;
+ }
+ (*opts_ptr)->reflectionRadius = tmp / 1e10; /* A^-1 to m^-1 */
+ break;
+
+ }
+
+ return 0;
+}
+
+
+static struct argp_option options[] = {
+
+ {"help-pinkindexer", 1, NULL, OPTION_NO_USAGE,
+ "Show options for PinkIndexer indexing algorithm", 99},
+
+ {"pinkIndexer-considered-peaks-count", 2, "n", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-cpc", 2, "n", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-angle-resolution", 3, "ang", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-ar", 3, "ang", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-refinement-type", 4, "t", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-rt", 4, "t", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-thread-count", 5, "n", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-tc", 5, "n", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-max-resolution-for-indexing", 6, "res", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-mrfi", 6, "res", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-tolerance", 7, "tol", OPTION_HIDDEN, NULL},
+ {"pinkIndexer-tol", 7, "tol", OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-multi", 8, NULL, OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-no-check-indexed", 9, NULL, OPTION_HIDDEN, NULL},
+
+ {"pinkIndexer-reflection-radius", 10, "r", OPTION_HIDDEN, NULL},
+
+ {0}
+};
+
+
+struct argp pinkIndexer_argp = { options, parse_arg, NULL, NULL, NULL, NULL, NULL };
diff --git a/libcrystfel/src/pinkindexer.h b/libcrystfel/src/pinkindexer.h
new file mode 100644
index 00000000..0169d028
--- /dev/null
+++ b/libcrystfel/src/pinkindexer.h
@@ -0,0 +1,65 @@
+/*
+ * pinkindexer.h
+ *
+ * Interface to PinkIndexer
+ *
+ * Copyright © 2017-2019 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2017-2019 Yaroslav Gevorkov <yaroslav.gevorkov@desy.de>
+ *
+ * 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/>.
+ *
+ */
+
+#ifndef LIBCRYSTFEL_SRC_PINKINDEXER_H_
+#define LIBCRYSTFEL_SRC_PINKINDEXER_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+typedef struct pinkIndexer_options PinkIndexerOptions;
+extern struct argp pinkIndexer_argp;
+
+struct pinkIndexer_options {
+ unsigned int considered_peaks_count;
+ unsigned int angle_resolution;
+ unsigned int refinement_type;
+ float maxResolutionForIndexing_1_per_A;
+ float tolerance;
+ int multi;
+ int thread_count;
+ int min_peaks;
+ int no_check_indexed;
+ float reflectionRadius; /* In m^-1 */
+};
+
+#include <stddef.h>
+#include "index.h"
+
+extern int run_pinkIndexer(struct image *image, void *ipriv);
+
+extern void *pinkIndexer_prepare(IndexingMethod *indm, UnitCell *cell,
+ struct pinkIndexer_options *pinkIndexer_opts,
+ struct detector *det, struct beam_params *beam);
+
+extern void pinkIndexer_cleanup(void *pp);
+
+extern const char *pinkIndexer_probe(UnitCell *cell);
+
+#endif /* LIBCRYSTFEL_SRC_PINKINDEXER_H_ */
diff --git a/src/im-sandbox.c b/src/im-sandbox.c
index da632618..8097c273 100644
--- a/src/im-sandbox.c
+++ b/src/im-sandbox.c
@@ -73,6 +73,12 @@ struct sandbox
int n_processed_last_stats;
time_t t_last_stats;
+ /* Processing timeout in seconds. After this long without responding
+ * to a ping, the worker will be killed. After 3 times this long
+ * working on one image, even with ping responses, a warning will be
+ * shown to the user. */
+ int timeout;
+
struct index_args *iargs;
/* Worker processes */
@@ -158,17 +164,18 @@ static void check_hung_workers(struct sandbox *sb)
stamp_response(sb, i);
}
- if ( tnow - sb->last_response[i] > 240 ) {
- STATUS("Worker %i did not respond for 4 minutes - "
- "sending it SIGKILL.\n", i);
+ if ( tnow - sb->last_response[i] > sb->timeout ) {
+ STATUS("Worker %i did not respond for %i seconds - "
+ "sending it SIGKILL.\n", i, sb->timeout);
kill(sb->pids[i], SIGKILL);
stamp_response(sb, i);
}
- if ( tnow - sb->shared->time_last_start[i] > 600 ) {
+ if ( tnow - sb->shared->time_last_start[i] > sb->timeout*3 ) {
if ( !sb->shared->warned_long_running[i] ) {
STATUS("Worker %i has been working on one "
- "frame for more than 10 minutes.\n", i);
+ "frame for more than %i seconds (just "
+ "for info).\n", i, sb->timeout);
STATUS("Event ID is: %s\n",
sb->shared->last_ev[i]);
STATUS("Task ID is: %s\n",
@@ -1045,7 +1052,7 @@ char *create_tempdir(const char *temp_location)
int create_sandbox(struct index_args *iargs, int n_proc, char *prefix,
int config_basename, FILE *fh,
Stream *stream, const char *tmpdir, int serial_start,
- const char *zmq_address, int profile)
+ const char *zmq_address, int timeout, int profile)
{
int i;
struct sandbox *sb;
@@ -1075,6 +1082,7 @@ int create_sandbox(struct index_args *iargs, int n_proc, char *prefix,
sb->serial = serial_start;
sb->tmpdir = tmpdir;
sb->profile = profile;
+ sb->timeout = timeout;
if ( zmq_address != NULL ) {
sb->zmq = 1;
sb->zmq_address = zmq_address;
diff --git a/src/im-sandbox.h b/src/im-sandbox.h
index 2c43a543..3acd62db 100644
--- a/src/im-sandbox.h
+++ b/src/im-sandbox.h
@@ -84,6 +84,6 @@ extern void set_last_task(char *lt, const char *task);
extern int create_sandbox(struct index_args *iargs, int n_proc, char *prefix,
int config_basename, FILE *fh, Stream *stream,
const char *tempdir, int serial_start,
- const char *zmq_address, int profile);
+ const char *zmq_address, int timeout, int profile);
#endif /* IM_SANDBOX_H */
diff --git a/src/indexamajig.c b/src/indexamajig.c
index bb115cc3..e607ec29 100644
--- a/src/indexamajig.c
+++ b/src/indexamajig.c
@@ -117,6 +117,7 @@ struct indexamajig_arguments
TakeTwoOptions **taketwo_opts_ptr;
FelixOptions **felix_opts_ptr;
XGandalfOptions **xgandalf_opts_ptr;
+ PinkIndexerOptions **pinkindexer_opts_ptr;
};
@@ -139,6 +140,7 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
state->child_inputs[0] = args->taketwo_opts_ptr;
state->child_inputs[1] = args->felix_opts_ptr;
state->child_inputs[2] = args->xgandalf_opts_ptr;
+ state->child_inputs[3] = args->pinkindexer_opts_ptr;
break;
case 'h' :
@@ -255,6 +257,7 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
ERROR("Invalid value for --min-peaks\n");
return EINVAL;
}
+ (*(args->pinkindexer_opts_ptr))->min_peaks = args->iargs.min_peaks;
break;
case 304 :
@@ -479,10 +482,8 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
break;
case 503 :
- if ( sscanf(arg, "%f", &args->iargs.fix_bandwidth) != 1 ) {
- ERROR("Invalid value for --fix-bandwidth\n");
- return EINVAL;
- }
+ ERROR("The option --fix-bandwidth is no longer used.\n");
+ ERROR("Set the bandwidth in the geometry file instead.\n");
break;
case 504 :
@@ -593,9 +594,11 @@ int main(int argc, char *argv[])
int r;
struct beam_params beam;
char *zmq_address = NULL;
+ int timeout = 240;
TakeTwoOptions *taketwo_opts = NULL;
FelixOptions *felix_opts = NULL;
XGandalfOptions *xgandalf_opts = NULL;
+ PinkIndexerOptions *pinkindexer_opts = NULL;
/* Defaults for "top level" arguments */
args.filename = NULL;
@@ -620,6 +623,7 @@ int main(int argc, char *argv[])
args.taketwo_opts_ptr = &taketwo_opts;
args.felix_opts_ptr = &felix_opts;
args.xgandalf_opts_ptr = &xgandalf_opts;
+ args.pinkindexer_opts_ptr = &pinkindexer_opts;
/* Defaults for process_image arguments */
args.iargs.cell = NULL;
@@ -675,7 +679,6 @@ int main(int argc, char *argv[])
args.iargs.push_res = -1.0;
args.iargs.highres = +INFINITY;
args.iargs.fix_profile_r = -1.0;
- args.iargs.fix_bandwidth = -1.0;
args.iargs.fix_divergence = -1.0;
args.iargs.no_image_data = 0;
@@ -809,6 +812,7 @@ int main(int argc, char *argv[])
{&taketwo_argp, 0, NULL, -2},
{&felix_argp, 0, NULL, -2},
{&xgandalf_argp, 0, NULL, -2},
+ {&pinkIndexer_argp, 0, NULL, -2},
{0}
};
@@ -979,6 +983,8 @@ int main(int argc, char *argv[])
} else {
+ int i, n;
+ const IndexingMethod *methods;
IndexingFlags flags = 0;
if ( args.iargs.cell != NULL ) {
@@ -1005,16 +1011,26 @@ int main(int argc, char *argv[])
}
args.iargs.ipriv = setup_indexing(args.indm_str, args.iargs.cell,
- args.iargs.det,
+ args.iargs.det, args.iargs.beam,
args.iargs.tols, flags,
taketwo_opts,
xgandalf_opts,
+ pinkindexer_opts,
felix_opts);
if ( args.iargs.ipriv == NULL ) {
ERROR("Failed to set up indexing system\n");
return 1;
}
+ methods = indexing_methods(args.iargs.ipriv, &n);
+ for ( i=0; i<n; i++ ) {
+ if ( methods[i] & INDEXING_PINKINDEXER ) {
+ /* Extend timeout if using pinkIndexer */
+ timeout = 3000;
+ break;
+ }
+ }
+
}
/* Change back to where we were before. Sandbox code will create
@@ -1056,7 +1072,7 @@ int main(int argc, char *argv[])
r = create_sandbox(&args.iargs, args.n_proc, args.prefix, args.basename,
fh, st, tmpdir, args.serial_start, zmq_address,
- args.profile);
+ timeout, args.profile);
free_imagefile_field_list(args.iargs.copyme);
cell_free(args.iargs.cell);
diff --git a/src/process_image.c b/src/process_image.c
index 654ffd46..f28952bc 100644
--- a/src/process_image.c
+++ b/src/process_image.c
@@ -226,6 +226,8 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs,
&imfile) ) return;
}
+ image.bw = iargs->beam->bandwidth;
+
/* Take snapshot of image before applying horrible noise filters */
time_accounts_set(taccs, TACC_FILTER);
set_last_task(last_task, "image filter");
@@ -369,17 +371,12 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs,
} else {
image.div = 0.0;
}
- if ( iargs->fix_bandwidth >= 0.0 ) {
- image.bw = iargs->fix_bandwidth;
- } else {
- image.bw = 0.00000001;
- }
-
- /* Set beam spectrum for pink beam data */
+ /* Set beam spectrum */
if ( iargs->spectrum != NULL ) {
image.spectrum = iargs->spectrum;
} else {
- image.spectrum = spectrum_generate_gaussian(image.lambda, image.bw);
+ image.spectrum = spectrum_generate_gaussian(image.lambda,
+ image.bw);
}
if ( image_feature_count(image.features) < iargs->min_peaks ) {
diff --git a/src/process_image.h b/src/process_image.h
index 1b899619..395a54cd 100644
--- a/src/process_image.h
+++ b/src/process_image.h
@@ -107,7 +107,6 @@ struct index_args
float push_res;
float highres;
float fix_profile_r;
- float fix_bandwidth;
float fix_divergence;
int overpredict;
Spectrum *spectrum;