From e377768607f11d48106bd1381f1312379c342d7e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 8 Nov 2023 16:24:41 +0100 Subject: Crystal: Remove reference to image structure (part 1) --- libcrystfel/src/crystal.c | 21 --------------- libcrystfel/src/crystal.h | 3 --- libcrystfel/src/geometry.c | 58 +++++++++++++--------------------------- libcrystfel/src/geometry.h | 8 +++--- libcrystfel/src/index.c | 1 - libcrystfel/src/integration.c | 2 +- libcrystfel/src/predict-refine.c | 6 ++--- src/partialator.c | 5 ---- 8 files changed, 28 insertions(+), 76 deletions(-) diff --git a/libcrystfel/src/crystal.c b/libcrystfel/src/crystal.c index 71d707d6..cece3eb4 100644 --- a/libcrystfel/src/crystal.c +++ b/libcrystfel/src/crystal.c @@ -41,9 +41,6 @@ struct _crystal { - /* The image containing the crystal */ - struct image *image; - /* Information about the crystal */ UnitCell *cell; double m; /* Mosaicity in radians */ @@ -222,18 +219,6 @@ long long int crystal_get_num_implausible_reflections(Crystal *cryst) } -struct image *crystal_get_image(Crystal *cryst) -{ - return cryst->image; -} - - -const struct image *crystal_get_image_const(const Crystal *cryst) -{ - return cryst->image; -} - - double crystal_get_osf(Crystal *cryst) { return cryst->osf; @@ -311,12 +296,6 @@ void crystal_set_num_implausible_reflections(Crystal *cryst, long long int n) } -void crystal_set_image(Crystal *cryst, struct image *image) -{ - cryst->image = image; -} - - void crystal_set_osf(Crystal *cryst, double osf) { cryst->osf = osf; diff --git a/libcrystfel/src/crystal.h b/libcrystfel/src/crystal.h index 5a4ca3f6..33764bc0 100644 --- a/libcrystfel/src/crystal.h +++ b/libcrystfel/src/crystal.h @@ -64,8 +64,6 @@ extern long long int crystal_get_num_implausible_reflections(Crystal *cryst); extern int crystal_get_user_flag(Crystal *cryst); extern double crystal_get_osf(Crystal *cryst); extern double crystal_get_Bfac(Crystal *cryst); -extern struct image *crystal_get_image(Crystal *cryst); -extern const struct image *crystal_get_image_const(const Crystal *cryst); extern double crystal_get_mosaicity(Crystal *cryst); extern const char *crystal_get_notes(Crystal *cryst); extern void crystal_get_det_shift(Crystal *cryst, @@ -82,7 +80,6 @@ extern void crystal_set_num_implausible_reflections(Crystal *cryst, extern void crystal_set_user_flag(Crystal *cryst, int flag); extern void crystal_set_osf(Crystal *cryst, double osf); extern void crystal_set_Bfac(Crystal *cryst, double B); -extern void crystal_set_image(Crystal *cryst, struct image *image); extern void crystal_set_mosaicity(Crystal *cryst, double m); extern void crystal_set_notes(Crystal *cryst, const char *notes); extern void crystal_set_det_shift(Crystal *cryst, diff --git a/libcrystfel/src/geometry.c b/libcrystfel/src/geometry.c index 674fe4d0..32da348a 100644 --- a/libcrystfel/src/geometry.c +++ b/libcrystfel/src/geometry.c @@ -425,14 +425,15 @@ static Reflection *check_reflection(struct image *image, Crystal *cryst, /** * \param cryst: A \ref Crystal + * \param image: An image structure * \param max_res: Maximum resolution to predict to (m^-1) * - * Calculates reflection positions for \p crys, up to maximum 1/d value - * \p max_res + * Calculates reflection positions for \p crys, as seen in \p image, + * up to maximum 1/d value \p max_res * * \returns A list of predicted reflections */ -RefList *predict_to_res(Crystal *cryst, double max_res) +RefList *predict_to_res(Crystal *cryst, struct image *image, double max_res) { double ax, ay, az; double bx, by, bz; @@ -445,7 +446,6 @@ RefList *predict_to_res(Crystal *cryst, double max_res) double mres; signed int h, k, l; UnitCell *cell; - struct image *image; cell = crystal_get_cell(cryst); if ( cell == NULL ) return NULL; @@ -462,7 +462,6 @@ RefList *predict_to_res(Crystal *cryst, double max_res) cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); - image = crystal_get_image(cryst); mres = detgeom_max_resolution(image->detgeom, image->lambda); if ( mres > max_res ) mres = max_res; @@ -498,7 +497,7 @@ RefList *predict_to_res(Crystal *cryst, double max_res) yl = h*asy + k*bsy + l*csy; zl = h*asz + k*bsz + l*csz; - refl = check_reflection(crystal_get_image(cryst), cryst, + refl = check_reflection(image, cryst, h, k, l, xl, yl, zl, NULL); if ( refl != NULL ) { @@ -534,12 +533,11 @@ static void set_unity_partialities(Crystal *cryst) } -static void set_random_partialities(Crystal *cryst) +static void set_random_partialities(Crystal *cryst, int image_serial) { RefList *list; Reflection *refl; RefListIterator *iter; - struct image *image; list = crystal_get_reflections(cryst); if ( list == NULL ) { @@ -547,19 +545,13 @@ static void set_random_partialities(Crystal *cryst) return; } - image = crystal_get_image(cryst); - if ( image == NULL ) { - ERROR("No image structure for partiality calculation!\n"); - return; - } - for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { signed int h, k, l; get_symmetric_indices(refl, &h, &k, &l); - set_partiality(refl, random_partiality(h, k, l, image->serial)); + set_partiality(refl, random_partiality(h, k, l, image_serial)); set_lorentz(refl, 1.0); } } @@ -682,13 +674,12 @@ static double do_integral(double q2, double zl, double R, } -static void ginn_spectrum_partialities(Crystal *cryst) +static void ginn_spectrum_partialities(Crystal *cryst, struct image *image) { RefList *list; Reflection *refl; RefListIterator *iter; double r0, m; - struct image *image; UnitCell *cell; double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; @@ -698,12 +689,6 @@ static void ginn_spectrum_partialities(Crystal *cryst) return; } - image = crystal_get_image(cryst); - if ( image == NULL ) { - ERROR("No image for partiality calculation!\n"); - return; - } - cell = crystal_get_cell(cryst); if ( cell == NULL ) { ERROR("No unit cell for partiality calculation!\n"); @@ -753,13 +738,12 @@ static void ginn_spectrum_partialities(Crystal *cryst) } -static void ewald_offset_partialities(Crystal *cryst) +static void ewald_offset_partialities(Crystal *cryst, struct image *image) { RefList *list; Reflection *refl; RefListIterator *iter; double r0, m; - struct image *image; UnitCell *cell; double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; @@ -769,12 +753,6 @@ static void ewald_offset_partialities(Crystal *cryst) return; } - image = crystal_get_image(cryst); - if ( image == NULL ) { - ERROR("No image for partiality calculation!\n"); - return; - } - cell = crystal_get_cell(cryst); if ( cell == NULL ) { ERROR("No unit cell for partiality calculation!\n"); @@ -826,7 +804,8 @@ static void ewald_offset_partialities(Crystal *cryst) * called \ref predict_to_res or \ref update_predictions, because this function * relies on the limiting wavelength values calculated by those functions. */ -void calculate_partialities(Crystal *cryst, PartialityModel pmodel) +void calculate_partialities(Crystal *cryst, struct image *image, + PartialityModel pmodel) { switch ( pmodel ) { @@ -835,15 +814,15 @@ void calculate_partialities(Crystal *cryst, PartialityModel pmodel) break; case PMODEL_XSPHERE : - ginn_spectrum_partialities(cryst); + ginn_spectrum_partialities(cryst, image); break; case PMODEL_OFFSET : - ewald_offset_partialities(cryst); + ewald_offset_partialities(cryst, image); break; case PMODEL_RANDOM : - set_random_partialities(cryst); + set_random_partialities(cryst, image->serial); break; case PMODEL_GGPM : @@ -861,22 +840,23 @@ void calculate_partialities(Crystal *cryst, PartialityModel pmodel) /** * \param cryst A \ref Crystal + * \param image An image structure * * Updates the predicted reflections (positions and excitation errors, but not - * the actual partialities) of \p cryst's reflections according to - * the current state of the crystal (e.g. its unit cell parameters). + * the actual partialities) of \p cryst's reflections as seen in \p image, + * according to the current state of the crystal (e.g. its unit cell + * parameters). * * If you need to update the partialities as well, call * \ref calculate_partialities afterwards. */ -void update_predictions(Crystal *cryst) +void update_predictions(Crystal *cryst, struct image *image) { Reflection *refl; RefListIterator *iter; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; - struct image *image = crystal_get_image(cryst); cell_get_reciprocal(crystal_get_cell(cryst), &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); diff --git a/libcrystfel/src/geometry.h b/libcrystfel/src/geometry.h index d05c8832..b9f98694 100644 --- a/libcrystfel/src/geometry.h +++ b/libcrystfel/src/geometry.h @@ -35,6 +35,7 @@ #include "cell.h" #include "crystal.h" #include "detgeom.h" +#include "image.h" #ifdef __cplusplus extern "C" { @@ -77,11 +78,12 @@ struct polarisation }; -extern RefList *predict_to_res(Crystal *cryst, double max_res); +extern RefList *predict_to_res(Crystal *cryst, struct image *image, double max_res); -extern void calculate_partialities(Crystal *cryst, PartialityModel pmodel); +extern void calculate_partialities(Crystal *cryst, struct image *image, + PartialityModel pmodel); -extern void update_predictions(Crystal *cryst); +extern void update_predictions(Crystal *cryst, struct image *image); extern struct polarisation parse_polarisation(const char *text); extern void polarisation_correction(RefList *list, UnitCell *cell, struct polarisation p); diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index d93664b1..db2058a5 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -701,7 +701,6 @@ static int try_indexer(struct image *image, IndexingMethod indm, /* ... starting at the end of the (complete) list ... */ Crystal *cr = image->crystals[this_crystal]; - crystal_set_image(cr, image); crystal_set_profile_radius(cr, 0.02e9); crystal_set_mosaicity(cr, 0.0); diff --git a/libcrystfel/src/integration.c b/libcrystfel/src/integration.c index 8b05efe7..3912114a 100644 --- a/libcrystfel/src/integration.c +++ b/libcrystfel/src/integration.c @@ -1665,7 +1665,7 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, res = estimate_resolution(image->crystals[i], image); crystal_set_resolution_limit(image->crystals[i], res); - list = predict_to_res(image->crystals[i], res+push_res); + list = predict_to_res(image->crystals[i], image, res+push_res); crystal_set_reflections(image->crystals[i], list); if ( overpredict ) { diff --git a/libcrystfel/src/predict-refine.c b/libcrystfel/src/predict-refine.c index d5a3b403..24045ddb 100644 --- a/libcrystfel/src/predict-refine.c +++ b/libcrystfel/src/predict-refine.c @@ -489,7 +489,7 @@ static int pair_peaks(struct image *image, Crystal *cr, /* Get the excitation errors and detector positions for the candidate * reflections */ crystal_set_reflections(cr, all_reflist); - update_predictions(cr); + update_predictions(cr, image); /* Pass over the peaks again, keeping only the ones which look like * good pairings */ @@ -570,7 +570,7 @@ int refine_radius(Crystal *cr, struct image *image) return 1; } crystal_set_reflections(cr, reflist); - update_predictions(cr); + update_predictions(cr, image); crystal_set_reflections(cr, NULL); qsort(rps, n_acc, sizeof(struct reflpeak), cmpd2); @@ -855,7 +855,7 @@ int refine_prediction(struct image *image, Crystal *cr, /* Refine (max 5 cycles) */ for ( i=0; i<5; i++ ) { - update_predictions(cr); + update_predictions(cr, image); if ( iterate(rps, n, crystal_get_cell(cr), image, Minvs, total_shifts) ) { crystal_set_reflections(cr, NULL); diff --git a/src/partialator.c b/src/partialator.c index 9b1803b0..76fce8c8 100644 --- a/src/partialator.c +++ b/src/partialator.c @@ -1614,7 +1614,6 @@ int main(int argc, char *argv[]) return 1; } - crystal_set_image(cr, image_for_crystal); *image_for_crystal = *image; image_for_crystal->n_crystals = 1; image_for_crystal->crystals = malloc(sizeof(Crystal *)); @@ -1835,10 +1834,6 @@ int main(int argc, char *argv[]) /* Clean up */ gsl_rng_free(rng); - for ( icryst=0; icryst Date: Wed, 8 Nov 2023 17:08:51 +0100 Subject: Crystal: Remove reference to image structure (part 2) --- src/partialator.c | 52 +++++++++++++++++++++++++++----------------- tests/gradient_check.c | 2 +- tests/gradient_check_utils.c | 3 +-- tests/prof2d_check.c | 1 - 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/partialator.c b/src/partialator.c index 76fce8c8..de59efde 100644 --- a/src/partialator.c +++ b/src/partialator.c @@ -259,7 +259,7 @@ static char *insert_into_filename(const char *fn, const char *add) /* Write custom split results (including a two-way split) */ static void write_custom_split(struct custom_split *csplit, int dsn, - Crystal **crystals, int n_crystals, + Crystal **crystals, struct image **images, int n_crystals, PartialityModel pmodel, int min_measurements, double push_res, SymOpList *sym, int nthreads, const char *outfile) @@ -277,8 +277,8 @@ static void write_custom_split(struct custom_split *csplit, int dsn, char *id; int dsn_crystal; - fn = crystal_get_image(crystals[i])->filename; - evs = crystal_get_image(crystals[i])->ev; + fn = images[i]->filename; + evs = images[i]->ev; if ( evs == NULL ) evs = "//"; id = malloc(strlen(evs)+strlen(fn)+2); @@ -362,7 +362,7 @@ static void show_help(const char *s) } -static signed int find_first_crystal(Crystal **crystals, int n_crystals, +static signed int find_first_crystal(Crystal **crystals, struct image **images, int n_crystals, struct custom_split *csplit, int dsn) { int i; @@ -373,8 +373,8 @@ static signed int find_first_crystal(Crystal **crystals, int n_crystals, char *id; int dsn_crystal; - fn = crystal_get_image(crystals[i])->filename; - evs = crystal_get_image(crystals[i])->ev; + fn = images[i]->filename; + evs = images[i]->ev; if ( evs == NULL ) evs = "//"; id = malloc(strlen(evs)+strlen(fn)+2); @@ -394,7 +394,7 @@ static signed int find_first_crystal(Crystal **crystals, int n_crystals, } -static void check_csplit(Crystal **crystals, int n_crystals, +static void check_csplit(Crystal **crystals, struct image **images, int n_crystals, struct custom_split *csplit) { int i; @@ -412,8 +412,8 @@ static void check_csplit(Crystal **crystals, int n_crystals, char *id; int dsn_crystal; - fn = crystal_get_image(crystals[i])->filename; - evs = crystal_get_image(crystals[i])->ev; + fn = images[i]->filename; + evs = images[i]->ev; if ( evs == NULL ) evs = "//"; id = malloc(strlen(evs)+strlen(fn)+2); @@ -437,7 +437,7 @@ static void check_csplit(Crystal **crystals, int n_crystals, for ( i=0; in_datasets; i++ ) { /* Try to find a crystal with dsn = i */ - if ( find_first_crystal(crystals, n_crystals, csplit, i) != -1 ) + if ( find_first_crystal(crystals, images, n_crystals, csplit, i) != -1 ) { n_cry++; } else { @@ -621,11 +621,10 @@ static void skip_to_end(FILE *fh) } -static int set_initial_params(Crystal *cr, FILE *fh, double force_bandwidth, - double force_radius, double force_lambda) +static int set_initial_params(Crystal *cr, struct image *image, FILE *fh, + double force_bandwidth, double force_radius, + double force_lambda) { - struct image *image = crystal_get_image(cr); - if ( fh != NULL ) { int err; @@ -1085,6 +1084,7 @@ int main(int argc, char *argv[]) int no_Bscale = 0; int no_pr = 0; Crystal **crystals; + struct image **images; char *pmodel_str = NULL; PartialityModel pmodel = PMODEL_XSPHERE; int min_measurements = 2; @@ -1526,6 +1526,7 @@ int main(int argc, char *argv[]) n_crystals = 0; n_crystals_seen = 0; crystals = NULL; + images = NULL; if ( sparams_fn != NULL ) { char line[1024]; sparams_fh = fopen(sparams_fn, "r"); @@ -1575,6 +1576,7 @@ int main(int argc, char *argv[]) Crystal *cr; Crystal **crystals_new; + struct image **images_new; RefList *cr_refl; RefList *cr_refl_raw; struct image *image_for_crystal; @@ -1606,6 +1608,14 @@ int main(int argc, char *argv[]) crystals[n_crystals] = crystal_copy_deep(image->crystals[i]); cr = crystals[n_crystals]; + images_new = realloc(images, + (n_crystals+1)*sizeof(struct image *)); + if ( images_new == NULL ) { + ERROR("Failed to allocate memory for image list\n"); + return 1; + } + images = images_new; + /* Create a completely new, separate image * structure for this crystal. */ image_for_crystal = image_new(); @@ -1615,6 +1625,7 @@ int main(int argc, char *argv[]) } *image_for_crystal = *image; + images[n_crystals] = image_for_crystal; image_for_crystal->n_crystals = 1; image_for_crystal->crystals = malloc(sizeof(Crystal *)); image_for_crystal->crystals[0] = cr; @@ -1641,7 +1652,8 @@ int main(int argc, char *argv[]) crystal_set_user_flag(cr, PRFLAG_OK); reflist_free(cr_refl); - if ( set_initial_params(cr, sparams_fh, force_bandwidth, + if ( set_initial_params(cr, image_for_crystal, + sparams_fh, force_bandwidth, force_radius, force_lambda) ) { ERROR("Failed to set initial parameters\n"); @@ -1681,16 +1693,16 @@ int main(int argc, char *argv[]) for ( icryst=0; icrystn_datasets; j++ ) { write_custom_split(csplit, j, crystals, - n_crystals, pmodel, + images, n_crystals, pmodel, min_measurements, push_res, sym, nthreads, tmp); @@ -1826,7 +1838,7 @@ int main(int argc, char *argv[]) if ( csplit != NULL ) { int i; for ( i=0; in_datasets; i++ ) { - write_custom_split(csplit, i, crystals, n_crystals, + write_custom_split(csplit, i, crystals, images, n_crystals, pmodel, min_measurements, push_res, sym, nthreads, outfile); } diff --git a/tests/gradient_check.c b/tests/gradient_check.c index 001bff7a..48b8311b 100644 --- a/tests/gradient_check.c +++ b/tests/gradient_check.c @@ -115,7 +115,7 @@ int main(int argc, char *argv[]) return 1; } - update_predictions(image.crystals[0]); + update_predictions(image.crystals[0], &image); after = make_dev_list(rps, n_refls, image.detgeom); for ( i=0; idetgeom, image->lambda)); + refls = predict_to_res(cr, image, detgeom_max_resolution(image->detgeom, image->lambda)); crystal_set_reflections(cr, refls); n_refls = num_reflections(refls); diff --git a/tests/prof2d_check.c b/tests/prof2d_check.c index 28ecd67c..71e56d49 100644 --- a/tests/prof2d_check.c +++ b/tests/prof2d_check.c @@ -125,7 +125,6 @@ int main(int argc, char *argv[]) cr = crystal_new(); crystal_set_profile_radius(cr, 0.001e9); crystal_set_mosaicity(cr, 0.0); /* radians */ - crystal_set_image(cr, &image); crystal_set_cell(cr, cell); image.n_crystals = 1; -- cgit v1.2.3 From e42773c17459e5bad58632b2792a3f18abb70178 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 9 Nov 2023 09:56:00 +0100 Subject: Crystal: Remove reference to image structure (part 3) --- src/partialator.c | 19 +++++++---- src/post-refinement.c | 88 +++++++++++++++++++++++++-------------------------- src/post-refinement.h | 11 ++++--- tests/prof2d_check.c | 4 +-- 4 files changed, 64 insertions(+), 58 deletions(-) diff --git a/src/partialator.c b/src/partialator.c index de59efde..6d362a01 100644 --- a/src/partialator.c +++ b/src/partialator.c @@ -896,6 +896,7 @@ struct log_qargs int iter; int next; Crystal **crystals; + struct image **images; int n_crystals; RefList *full; int scaleflags; @@ -908,6 +909,7 @@ struct log_qargs struct log_args { Crystal *cr; + struct image *image; RefList *full; int scaleflags; PartialityModel pmodel; @@ -928,6 +930,7 @@ static void *get_log_task(void *vp) if ( task == NULL ) return NULL; task->cr = qargs->crystals[qargs->next]; + task->image = qargs->images[qargs->next]; task->full = qargs->full; task->iter = qargs->iter; task->cnum = qargs->next; @@ -943,11 +946,11 @@ static void *get_log_task(void *vp) static void write_logs(void *vp, int cookie) { struct log_args *args = vp; - write_specgraph(args->cr, args->full, args->iter, args->cnum, + write_specgraph(args->cr, args->image, args->full, args->iter, args->cnum, args->log_folder); - write_gridscan(args->cr, args->full, args->iter, args->cnum, + write_gridscan(args->cr, args->image, args->full, args->iter, args->cnum, args->scaleflags, args->pmodel, args->log_folder); - write_test_logs(args->cr, args->full, args->iter, args->cnum, + write_test_logs(args->cr, args->image, args->full, args->iter, args->cnum, args->log_folder); } @@ -962,7 +965,8 @@ static void done_log(void *vqargs, void *vp) } -static void write_logs_parallel(Crystal **crystals, int n_crystals, +static void write_logs_parallel(Crystal **crystals, struct image **images, + int n_crystals, RefList *full, int iter, int n_threads, int scaleflags, PartialityModel pmodel, const char *log_folder) @@ -973,6 +977,7 @@ static void write_logs_parallel(Crystal **crystals, int n_crystals, qargs.next = 0; qargs.full = full; qargs.crystals = crystals; + qargs.images = images; qargs.n_done = 0; qargs.n_crystals = n_crystals; qargs.scaleflags = scaleflags; @@ -1727,7 +1732,7 @@ int main(int argc, char *argv[]) if ( do_write_logs ) { write_pgraph(full, crystals, n_crystals, 0, "", log_folder); - write_logs_parallel(crystals, n_crystals, full, 0, nthreads, + write_logs_parallel(crystals, images, n_crystals, full, 0, nthreads, scaleflags, pmodel, log_folder); } @@ -1737,7 +1742,7 @@ int main(int argc, char *argv[]) STATUS("Scaling and refinement cycle %i of %i\n", itn+1, n_iter); if ( !no_pr ) { - refine_all(crystals, n_crystals, full, nthreads, pmodel, + refine_all(crystals, images, n_crystals, full, nthreads, pmodel, itn+1, no_logs, sym, amb, scaleflags, log_folder); } @@ -1816,7 +1821,7 @@ int main(int argc, char *argv[]) show_all_residuals(crystals, n_crystals, full, no_free); if ( do_write_logs ) { write_pgraph(full, crystals, n_crystals, -1, "", log_folder); - write_logs_parallel(crystals, n_crystals, full, -1, nthreads, + write_logs_parallel(crystals, images, n_crystals, full, -1, nthreads, scaleflags, pmodel, log_folder); } diff --git a/src/post-refinement.c b/src/post-refinement.c index 70b14a0f..79557e18 100644 --- a/src/post-refinement.c +++ b/src/post-refinement.c @@ -56,13 +56,14 @@ struct rf_alteration struct rf_priv { - Crystal *cr; /**< Original crystal (before any refinement) */ + Crystal *cr; /**< Original crystal (before any refinement) */ + struct image *image; /**< Original image (before any refinement) */ const RefList *full; int serial; int scaleflags; PartialityModel pmodel; - Crystal *cr_tgt; /**< Crystal to use for testing modifications */ + Crystal *cr_tgt; /**< Crystal to use for testing modifications */ struct image image_tgt; /**< Image structure to go with cr_tgt */ }; @@ -151,32 +152,30 @@ static void rotate_cell_xy(UnitCell *source, UnitCell *tgt, static void apply_parameters(Crystal *cr_orig, Crystal *cr_tgt, + struct image *im_orig, struct image *im_tgt, struct rf_alteration alter) { - double R, lambda; + double R; struct gaussian g; - struct image *image; - image = crystal_get_image(cr_tgt); R = crystal_get_profile_radius(cr_orig); - lambda = crystal_get_image_const(cr_orig)->lambda; rotate_cell_xy(crystal_get_cell(cr_orig), crystal_get_cell(cr_tgt), alter.rot_x, alter.rot_y); crystal_set_profile_radius(cr_tgt, R+alter.delta_R); - image->lambda = lambda+alter.delta_wave; + im_tgt->lambda = im_orig->lambda+alter.delta_wave; - g.kcen = 1.0/image->lambda; - g.sigma = image->bw/image->lambda; + g.kcen = 1.0/im_tgt->lambda; + g.sigma = im_tgt->bw/im_tgt->lambda; g.area = 1; - spectrum_set_gaussians(image->spectrum, &g, 1); + spectrum_set_gaussians(im_tgt->spectrum, &g, 1); } static double calc_residual(struct rf_priv *pv, struct rf_alteration alter, int free) { - apply_parameters(pv->cr, pv->cr_tgt, alter); + apply_parameters(pv->cr, pv->cr_tgt, pv->image, &pv->image_tgt, alter); if ( fabs(crystal_get_profile_radius(pv->cr_tgt)) > 5e9 ) { STATUS("radius > 5e9\n"); @@ -189,13 +188,13 @@ static double calc_residual(struct rf_priv *pv, struct rf_alteration alter, return NAN; } - if ( crystal_get_image(pv->cr_tgt)->lambda <= 0.0 ) { + if ( pv->image_tgt.lambda <= 0.0 ) { STATUS("lambda < 0\n"); return NAN; } - update_predictions(pv->cr_tgt); - calculate_partialities(pv->cr_tgt, pv->pmodel); + update_predictions(pv->cr_tgt, &pv->image_tgt); + calculate_partialities(pv->cr_tgt, &pv->image_tgt, pv->pmodel); return residual(pv->cr_tgt, pv->full, free, NULL, NULL); @@ -264,7 +263,7 @@ static void reindex_cell(UnitCell *cell, SymOpList *amb, int idx) } -static void try_reindex(Crystal *crin, const RefList *full, +static void try_reindex(Crystal *crin, struct image *image, const RefList *full, SymOpList *sym, SymOpList *amb, int scaleflags, PartialityModel pmodel) { @@ -296,8 +295,8 @@ static void try_reindex(Crystal *crin, const RefList *full, amb, sym, idx); crystal_set_reflections(cr, list); - update_predictions(cr); - calculate_partialities(cr, pmodel); + update_predictions(cr, image); + calculate_partialities(cr, image, pmodel); if ( scale_one_crystal(cr, full, scaleflags) ) return; residual_flipped = residual(cr, full, 0, NULL, NULL); @@ -316,12 +315,11 @@ static void try_reindex(Crystal *crin, const RefList *full, } -void write_test_logs(Crystal *crystal, const RefList *full, +void write_test_logs(Crystal *crystal, struct image *image, const RefList *full, signed int cycle, int serial, const char *log_folder) { FILE *fh; - struct image *image = crystal_get_image(crystal); char tmp[256]; char ins[16]; @@ -367,7 +365,7 @@ void write_test_logs(Crystal *crystal, const RefList *full, } -void write_specgraph(Crystal *crystal, const RefList *full, +void write_specgraph(Crystal *crystal, struct image *image, const RefList *full, signed int cycle, int serial, const char *log_folder) { @@ -378,7 +376,6 @@ void write_specgraph(Crystal *crystal, const RefList *full, double G = crystal_get_osf(crystal); double B = crystal_get_Bfac(crystal); UnitCell *cell; - struct image *image = crystal_get_image(crystal); char ins[16]; snprintf(tmp, 256, "%s/specgraph-crystal%i.dat", log_folder, serial); @@ -443,7 +440,7 @@ void write_specgraph(Crystal *crystal, const RefList *full, } -static void write_angle_grid(Crystal *cr, const RefList *full, +static void write_angle_grid(Crystal *cr, struct image *image, const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) @@ -462,10 +459,9 @@ static void write_angle_grid(Crystal *cr, const RefList *full, priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); - priv.image_tgt = *crystal_get_image(cr); + priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - crystal_set_image(priv.cr_tgt, &priv.image_tgt); list = copy_reflist(crystal_get_reflections(cr)); crystal_set_reflections(priv.cr_tgt, list); cell = cell_new_from_cell(crystal_get_cell(cr)); @@ -510,7 +506,7 @@ static void write_angle_grid(Crystal *cr, const RefList *full, } -static void write_radius_grid(Crystal *cr, const RefList *full, +static void write_radius_grid(Crystal *cr, struct image *image, const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) @@ -529,10 +525,9 @@ static void write_radius_grid(Crystal *cr, const RefList *full, priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); - priv.image_tgt = *crystal_get_image(cr); + priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - crystal_set_image(priv.cr_tgt, &priv.image_tgt); list = copy_reflist(crystal_get_reflections(cr)); crystal_set_reflections(priv.cr_tgt, list); cell = cell_new_from_cell(crystal_get_cell(cr)); @@ -577,13 +572,13 @@ static void write_radius_grid(Crystal *cr, const RefList *full, } -void write_gridscan(Crystal *cr, const RefList *full, +void write_gridscan(Crystal *cr, struct image *image, const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) { - write_angle_grid(cr, full, cycle, serial, scaleflags, pmodel, log_folder); - write_radius_grid(cr, full, cycle, serial, scaleflags, pmodel, log_folder); + write_angle_grid(cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); + write_radius_grid(cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); } @@ -631,7 +626,7 @@ static int refine_loop(struct rf_alteration *cur, struct rf_alteration *dirns, *total_iter, lowest_fom, freefom, cur->rot_x, cur->rot_y, crystal_get_profile_radius(priv->cr)+cur->delta_R, - crystal_get_image_const(priv->cr)->lambda+cur->delta_wave); + priv->image->lambda+cur->delta_wave); } } while ( (best != 0) && (n_iter < 10) ); @@ -649,7 +644,7 @@ static void zero_alter(struct rf_alteration *alter) } -static void do_pr_refine(Crystal *cr, const RefList *full, +static void do_pr_refine(Crystal *cr, struct image *image, const RefList *full, PartialityModel pmodel, int serial, int cycle, int write_logs, SymOpList *sym, SymOpList *amb, int scaleflags, @@ -664,7 +659,7 @@ static void do_pr_refine(Crystal *cr, const RefList *full, UnitCell *cell; Spectrum *spectrum; - try_reindex(cr, full, sym, amb, scaleflags, pmodel); + try_reindex(cr, image, full, sym, amb, scaleflags, pmodel); zero_alter(&alter); @@ -674,10 +669,9 @@ static void do_pr_refine(Crystal *cr, const RefList *full, priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); - priv.image_tgt = *crystal_get_image(cr); + priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - crystal_set_image(priv.cr_tgt, &priv.image_tgt); list = copy_reflist(crystal_get_reflections(cr)); crystal_set_reflections(priv.cr_tgt, list); cell = cell_new_from_cell(crystal_get_cell(cr)); @@ -700,7 +694,7 @@ static void do_pr_refine(Crystal *cr, const RefList *full, n_iter, fom, freefom, alter.rot_x, alter.rot_y, crystal_get_profile_radius(cr)+alter.delta_R, - crystal_get_image(cr)->lambda+alter.delta_wave); + image->lambda+alter.delta_wave); } } @@ -724,15 +718,15 @@ static void do_pr_refine(Crystal *cr, const RefList *full, refine_loop(&alter, dirns, 2, &priv, &n_iter, fh); /* Apply the final shifts */ - apply_parameters(cr, cr, alter); - update_predictions(cr); - calculate_partialities(cr, pmodel); + apply_parameters(cr, cr, image, image, alter); + update_predictions(cr, image); + calculate_partialities(cr, image, pmodel); if ( write_logs ) { - write_gridscan(cr, full, cycle, serial, scaleflags, + write_gridscan(cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); - write_specgraph(cr, full, cycle, serial, log_folder); - write_test_logs(cr, full, cycle, serial, log_folder); + write_specgraph(cr, image, full, cycle, serial, log_folder); + write_test_logs(cr, image, full, cycle, serial, log_folder); } if ( crystal_get_profile_radius(cr) > 5e9 ) { @@ -753,6 +747,7 @@ struct refine_args { RefList *full; Crystal *crystal; + struct image *image; PartialityModel pmodel; int serial; int cycle; @@ -769,6 +764,7 @@ struct pr_queue_args int n_started; int n_done; Crystal **crystals; + struct image **images; int n_crystals; struct refine_args task_defaults; }; @@ -777,12 +773,11 @@ struct pr_queue_args static void refine_image(void *task, int id) { struct refine_args *pargs = task; - Crystal *cr = pargs->crystal; int write_logs = 0; write_logs = !pargs->no_logs && (pargs->serial % 20 == 0); - do_pr_refine(cr, pargs->full, pargs->pmodel, + do_pr_refine(pargs->crystal, pargs->image, pargs->full, pargs->pmodel, pargs->serial, pargs->cycle, write_logs, pargs->sym, pargs->amb, pargs->scaleflags, pargs->log_folder); @@ -798,6 +793,7 @@ static void *get_image(void *vqargs) memcpy(task, &qargs->task_defaults, sizeof(struct refine_args)); task->crystal = qargs->crystals[qargs->n_started]; + task->image = qargs->images[qargs->n_started]; task->serial = qargs->n_started; qargs->n_started++; @@ -817,7 +813,7 @@ static void done_image(void *vqargs, void *task) } -void refine_all(Crystal **crystals, int n_crystals, +void refine_all(Crystal **crystals, struct image **images, int n_crystals, RefList *full, int nthreads, PartialityModel pmodel, int cycle, int no_logs, SymOpList *sym, SymOpList *amb, int scaleflags, @@ -828,6 +824,7 @@ void refine_all(Crystal **crystals, int n_crystals, task_defaults.full = full; task_defaults.crystal = NULL; + task_defaults.image = NULL; task_defaults.pmodel = pmodel; task_defaults.cycle = cycle; task_defaults.no_logs = no_logs; @@ -842,6 +839,7 @@ void refine_all(Crystal **crystals, int n_crystals, qargs.n_done = 0; qargs.n_crystals = n_crystals; qargs.crystals = crystals; + qargs.images = images; /* Don't have threads which are doing nothing */ if ( n_crystals < nthreads ) nthreads = n_crystals; diff --git a/src/post-refinement.h b/src/post-refinement.h index 546050a4..7eb1fd0b 100644 --- a/src/post-refinement.h +++ b/src/post-refinement.h @@ -58,18 +58,20 @@ enum prflag extern const char *str_prflag(enum prflag flag); -extern void refine_all(Crystal **crystals, int n_crystals, +extern void refine_all(Crystal **crystals, struct image **images, int n_crystals, RefList *full, int nthreads, PartialityModel pmodel, int cycle, int no_logs, SymOpList *sym, SymOpList *amb, int scaleflags, const char *log_folder); -extern void write_gridscan(Crystal *cr, const RefList *full, +extern void write_gridscan(Crystal *cr, struct image *image, + const RefList *full, int cycle, int serial, int scaleflags, PartialityModel model, const char *log_folder); -extern void write_specgraph(Crystal *crystal, const RefList *full, +extern void write_specgraph(Crystal *crystal, struct image *image, + const RefList *full, signed int cycle, int serial, const char *log_folder); @@ -77,7 +79,8 @@ extern void write_specgraph(Crystal *crystal, const RefList *full, extern double gradient(Crystal *cr, int k, Reflection *refl, PartialityModel pmodel); -extern void write_test_logs(Crystal *crystal, const RefList *full, +extern void write_test_logs(Crystal *crystal, struct image *image, + const RefList *full, signed int cycle, int serial, const char *log_folder); diff --git a/tests/prof2d_check.c b/tests/prof2d_check.c index 71e56d49..d2ff0bcd 100644 --- a/tests/prof2d_check.c +++ b/tests/prof2d_check.c @@ -130,8 +130,8 @@ int main(int argc, char *argv[]) image.n_crystals = 1; image.crystals = &cr; - list = predict_to_res(cr, detgeom_max_resolution(image.detgeom, - image.lambda)); + list = predict_to_res(cr, &image, detgeom_max_resolution(image.detgeom, + image.lambda)); crystal_set_reflections(cr, list); for ( fs=0; fs Date: Fri, 10 Nov 2023 22:29:34 +0100 Subject: image_add_feature: Remove "image" argument It hasn't been needed for ages. --- libcrystfel/src/image-hdf5.c | 6 ++---- libcrystfel/src/image-msgpack.c | 3 +-- libcrystfel/src/image.c | 3 +-- libcrystfel/src/image.h | 4 +--- libcrystfel/src/peakfinder8.c | 3 +-- libcrystfel/src/peaks.c | 7 +++---- libcrystfel/src/stream.c | 3 +-- tests/stream_roundtrip.c | 2 +- 8 files changed, 11 insertions(+), 20 deletions(-) diff --git a/libcrystfel/src/image-hdf5.c b/libcrystfel/src/image-hdf5.c index 66b93d90..37d333ac 100644 --- a/libcrystfel/src/image-hdf5.c +++ b/libcrystfel/src/image-hdf5.c @@ -1410,8 +1410,7 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl, ERROR("Failed to convert %i,%i to " "panel-relative coordinates\n", fs, ss); } else { - image_add_feature(features, fs, ss, pn, - NULL, val, NULL); + image_add_feature(features, fs, ss, pn, val, NULL); } } @@ -1537,8 +1536,7 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl, ERROR("Failed to convert %i,%i to " "panel-relative coordinates\n", fs, ss); } else { - image_add_feature(features, fs, ss, pn, - NULL, val, NULL); + image_add_feature(features, fs, ss, pn, val, NULL); } } diff --git a/libcrystfel/src/image-msgpack.c b/libcrystfel/src/image-msgpack.c index 0fdb104c..4ec55921 100644 --- a/libcrystfel/src/image-msgpack.c +++ b/libcrystfel/src/image-msgpack.c @@ -220,8 +220,7 @@ ImageFeatureList *image_msgpack_read_peaks(const DataTemplate *dtempl, ERROR("Failed to convert %i,%i to " "panel-relative coordinates\n", fs, ss); } else { - image_add_feature(features, fs, ss, pn, - NULL, val, NULL); + image_add_feature(features, fs, ss, pn, val, NULL); } } diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 95bc56e5..53ae796d 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -153,8 +153,7 @@ struct _imagefeaturelist void image_add_feature(ImageFeatureList *flist, double fs, double ss, - int pn, - struct image *parent, double intensity, const char *name) + int pn, double intensity, const char *name) { if ( flist->n_features == flist->max_features ) { struct imagefeature *nf; diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h index eafc5f83..7e4bad1f 100644 --- a/libcrystfel/src/image.h +++ b/libcrystfel/src/image.h @@ -201,9 +201,7 @@ extern ImageFeatureList *image_feature_list_new(void); extern void image_feature_list_free(ImageFeatureList *flist); extern void image_add_feature(ImageFeatureList *flist, double x, double y, - int pn, - struct image *parent, double intensity, - const char *name); + int pn, double intensity, const char *name); extern void image_remove_feature(ImageFeatureList *flist, int idx); diff --git a/libcrystfel/src/peakfinder8.c b/libcrystfel/src/peakfinder8.c index 80a219cb..4c41040a 100644 --- a/libcrystfel/src/peakfinder8.c +++ b/libcrystfel/src/peakfinder8.c @@ -1457,8 +1457,7 @@ int peakfinder8(struct image *img, int max_n_peaks, image_add_feature(img->features, pkdata->com_fs[pki]+0.5, pkdata->com_ss[pki]+0.5, - pi, img, pkdata->tot_i[pki], - NULL); + pi, pkdata->tot_i[pki], NULL); } } profile_end("pf8-search"); diff --git a/libcrystfel/src/peaks.c b/libcrystfel/src/peaks.c index 837c00fc..6de36e4a 100644 --- a/libcrystfel/src/peaks.c +++ b/libcrystfel/src/peaks.c @@ -401,7 +401,7 @@ static void search_peaks_in_panel(struct image *image, float threshold, /* Add using "better" coordinates */ image_add_feature(image->features, f_fs, f_ss, pn, - image, intensity, NULL); + intensity, NULL); nacc++; if ( nacc > 10000 ) { @@ -547,7 +547,7 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, image_add_feature(image->features, peakList.centerOfMass_rawX[peak_number], peakList.centerOfMass_rawY[peak_number], - panel_number, image, + panel_number, peakList.totalIntensity[peak_number], NULL); } @@ -723,8 +723,7 @@ void validate_peaks(struct image *image, double min_snr, } /* Add using "better" coordinates */ - image_add_feature(flist, f->fs, f->ss, f->pn, image, - intensity, NULL); + image_add_feature(flist, f->fs, f->ss, f->pn, intensity, NULL); } diff --git a/libcrystfel/src/stream.c b/libcrystfel/src/stream.c index e767b59f..71dd7413 100644 --- a/libcrystfel/src/stream.c +++ b/libcrystfel/src/stream.c @@ -148,8 +148,7 @@ static ImageFeatureList *read_peaks(Stream *st, struct image *image) ERROR("Failed to convert peak coords\n"); } else { image_add_feature(features, x, y, - pn, image, intensity, - NULL); + pn, intensity, NULL); } } diff --git a/tests/stream_roundtrip.c b/tests/stream_roundtrip.c index d36191bb..79231b62 100644 --- a/tests/stream_roundtrip.c +++ b/tests/stream_roundtrip.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) image->features = image_feature_list_new(); for ( i=0; ifeatures, peak_fs[i], peak_ss[i], - peak_pn[i], image, peak_i[i], NULL); + peak_pn[i], peak_i[i], NULL); } st = stream_open_for_write("stream_roundtrip.stream", dtempl); -- cgit v1.2.3 From 9ad42732052c3e2ff41c00bed8b5cec013c8941e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 14 Nov 2023 11:51:40 +0100 Subject: Add missing image initialisers --- src/post-refinement.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/post-refinement.c b/src/post-refinement.c index 79557e18..1bad55ea 100644 --- a/src/post-refinement.c +++ b/src/post-refinement.c @@ -459,6 +459,7 @@ static void write_angle_grid(Crystal *cr, struct image *image, const RefList *fu priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); + priv.image = image; priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; @@ -525,6 +526,7 @@ static void write_radius_grid(Crystal *cr, struct image *image, const RefList *f priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); + priv.image = image; priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; @@ -669,6 +671,7 @@ static void do_pr_refine(Crystal *cr, struct image *image, const RefList *full, priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); + priv.image = image; priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; -- cgit v1.2.3 From 5960cc81e3e35e4d38fdd720680c98bef070d695 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 16 Jan 2024 12:00:20 +0100 Subject: Add hooks for custom memory allocation in libcrystfel --- libcrystfel/src/utils.c | 96 +++++++++++++++++++++++++++++++++++++++---------- libcrystfel/src/utils.h | 14 ++++++++ 2 files changed, 91 insertions(+), 19 deletions(-) diff --git a/libcrystfel/src/utils.c b/libcrystfel/src/utils.c index 44faa7ee..04e028e9 100644 --- a/libcrystfel/src/utils.c +++ b/libcrystfel/src/utils.c @@ -375,6 +375,83 @@ void ERROR(const char *format, ...) } +/* ---------------------------- Memory management --------------------------- */ + +struct _mmconf { + void *(*malloc)(size_t size); + void (*free)(void *ptr); + void *(*calloc)(size_t nmemb, size_t size); + void *(*realloc)(void *ptr, size_t size); +} mm_conf = { malloc, free, calloc, realloc }; + +void *cfmalloc(size_t size) +{ + return mm_conf.malloc(size); +} + +void cffree(void *ptr) +{ + mm_conf.free(ptr); +} + +void *cfcalloc(size_t nmemb, size_t size) +{ + return mm_conf.calloc(nmemb, size); +} + +void *cfrealloc(void *ptr, size_t size) +{ + return mm_conf.realloc(ptr, size); +} + +int set_mm_funcs(void *(*cfmalloc)(size_t size), + void (*cffree)(void *ptr), + void *(*cfcalloc)(size_t nmemb, size_t size), + void *(*cfrealloc)(void *ptr, size_t size)) +{ + mm_conf.malloc = cfmalloc; + mm_conf.free = cffree; + mm_conf.calloc = cfcalloc; + mm_conf.realloc = cfrealloc; + return 0; +} + +char *cfstrdup(const char *s) +{ + size_t l = strlen(s); + char *r = cfmalloc(l+1); + if ( r == NULL ) return NULL; + strcpy(r, s); + return r; +} + +char *cfstrndup(const char *s, size_t n) +{ + char *r = cfmalloc(n+1); + if ( r == NULL ) return NULL; + strncpy(r, s, n); + r[n] = '\0'; + return r; +} + +void *srealloc(void *arr, size_t new_size) +{ + void *new_arr = realloc(arr, new_size); + if ( new_arr == NULL ) { + free(arr); + return NULL; + } else { + return new_arr; + } +} + +char *safe_strdup(const char *in) +{ + if ( in == NULL ) return NULL; + return strdup(in); +} + + /* ------------------------------ Useful functions ---------------------------- */ int convert_int(const char *str, int *pval) @@ -672,13 +749,6 @@ char *check_prefix(char *prefix) } -char *safe_strdup(const char *in) -{ - if ( in == NULL ) return NULL; - return strdup(in); -} - - char *safe_basename(const char *in) { int i; @@ -957,18 +1027,6 @@ int compare_double(const void *av, const void *bv) } -void *srealloc(void *arr, size_t new_size) -{ - void *new_arr = realloc(arr, new_size); - if ( new_arr == NULL ) { - free(arr); - return NULL; - } else { - return new_arr; - } -} - - /* -------------------------- libcrystfel features ------------------------ */ int crystfel_has_peakfinder9() diff --git a/libcrystfel/src/utils.h b/libcrystfel/src/utils.h index cb68069e..30a7c4ef 100644 --- a/libcrystfel/src/utils.h +++ b/libcrystfel/src/utils.h @@ -239,6 +239,20 @@ extern void set_log_message_func(LogMsgFunc new_log_msg_func, void *vp); +/* ---------------------------- Memory management --------------------------- */ + +extern void *cfmalloc(size_t size); +extern void cffree(void *ptr); +extern void *cfcalloc(size_t nmemb, size_t size); +extern void *cfrealloc(void *ptr, size_t size); +extern char *cfstrdup(const char *s); +extern char *cfstrndup(const char *s, size_t n); +extern int set_mm_funcs(void *(*cfmalloc)(size_t size), + void (*cffree)(void *ptr), + void *(*cfcalloc)(size_t nmemb, size_t size), + void *(*cfrealloc)(void *ptr, size_t size)); + + /* ------------------------------ File handling ----------------------------- */ extern char *check_prefix(char *prefix); -- cgit v1.2.3 From 4ad424f132dc3311502567e58b695fecdeb10106 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 16 Jan 2024 12:03:15 +0100 Subject: Use libcrystfel memory allocation routines everywhere --- libcrystfel/src/cell-utils.c | 26 +-- libcrystfel/src/cell.c | 4 +- libcrystfel/src/crystal.c | 18 +- libcrystfel/src/crystfel-mille.c | 14 +- libcrystfel/src/datatemplate.c | 186 ++++++++-------- libcrystfel/src/detgeom.c | 14 +- libcrystfel/src/filters.c | 8 +- libcrystfel/src/fom.c | 100 ++++----- libcrystfel/src/image-cbf.c | 46 ++-- libcrystfel/src/image-hdf5.c | 274 ++++++++++++------------ libcrystfel/src/image-msgpack.c | 18 +- libcrystfel/src/image-seedee.c | 24 +-- libcrystfel/src/image.c | 104 ++++----- libcrystfel/src/index.c | 40 ++-- libcrystfel/src/indexers/asdf.c | 68 +++--- libcrystfel/src/indexers/dirax.c | 31 ++- libcrystfel/src/indexers/felix.c | 38 ++-- libcrystfel/src/indexers/fromfile.c | 18 +- libcrystfel/src/indexers/mosflm.c | 45 ++-- libcrystfel/src/indexers/pinkindexer.c | 8 +- libcrystfel/src/indexers/taketwo.c | 86 ++++---- libcrystfel/src/indexers/xds.c | 4 +- libcrystfel/src/indexers/xgandalf.c | 6 +- libcrystfel/src/integer_matrix.c | 12 +- libcrystfel/src/integration.c | 70 +++--- libcrystfel/src/peakfinder8.c | 376 ++++++++++++++++----------------- libcrystfel/src/peaks.c | 12 +- libcrystfel/src/predict-refine.c | 22 +- libcrystfel/src/profile.c | 31 +-- libcrystfel/src/rational.c | 20 +- libcrystfel/src/reflist-utils.c | 16 +- libcrystfel/src/reflist.c | 46 ++-- libcrystfel/src/spectrum.c | 40 ++-- libcrystfel/src/stream.c | 66 +++--- libcrystfel/src/symmetry.c | 146 ++++++------- libcrystfel/src/thread-pool.c | 12 +- libcrystfel/src/utils.c | 30 +-- 37 files changed, 1039 insertions(+), 1040 deletions(-) diff --git a/libcrystfel/src/cell-utils.c b/libcrystfel/src/cell-utils.c index 2398c5f2..d751172e 100644 --- a/libcrystfel/src/cell-utils.c +++ b/libcrystfel/src/cell-utils.c @@ -996,14 +996,14 @@ UnitCell *load_cell_from_file(const char *filename) n1 = assplode(line, " \t", &bits, ASSPLODE_NONE); if ( n1 < 3 ) { - for ( i=0; ia = 1.0; @@ -140,7 +140,7 @@ UnitCell *cell_new() void cell_free(UnitCell *cell) { if ( cell == NULL ) return; - free(cell); + cffree(cell); } diff --git a/libcrystfel/src/crystal.c b/libcrystfel/src/crystal.c index cece3eb4..e5978795 100644 --- a/libcrystfel/src/crystal.c +++ b/libcrystfel/src/crystal.c @@ -81,7 +81,7 @@ Crystal *crystal_new() { Crystal *cryst; - cryst = malloc(sizeof(Crystal)); + cryst = cfmalloc(sizeof(Crystal)); if ( cryst == NULL ) return NULL; cryst->cell = NULL; @@ -116,7 +116,7 @@ Crystal *crystal_copy(const Crystal *cryst) if ( c == NULL ) return NULL; memcpy(c, cryst, sizeof(Crystal)); - if ( c->notes != NULL ) c->notes = strdup(c->notes); + if ( c->notes != NULL ) c->notes = cfstrdup(c->notes); return c; } @@ -140,7 +140,7 @@ Crystal *crystal_copy_deep(const Crystal *cryst) if ( c == NULL ) return NULL; memcpy(c, cryst, sizeof(Crystal)); - if ( c->notes != NULL ) c->notes = strdup(c->notes); + if ( c->notes != NULL ) c->notes = cfstrdup(c->notes); if ( cryst->cell != NULL ) { UnitCell *cell; @@ -169,8 +169,8 @@ Crystal *crystal_copy_deep(const Crystal *cryst) void crystal_free(Crystal *cryst) { if ( cryst == NULL ) return; - free(cryst->notes); - free(cryst); + cffree(cryst->notes); + cffree(cryst); } @@ -322,8 +322,8 @@ void crystal_set_mosaicity(Crystal *cryst, double m) void crystal_set_notes(Crystal *cryst, const char *notes) { - free(cryst->notes); /* free(NULL) is OK */ - cryst->notes = strdup(notes); + cffree(cryst->notes); /* free(NULL) is OK */ + cryst->notes = cfstrdup(notes); } @@ -338,7 +338,7 @@ void crystal_add_notes(Crystal *cryst, const char *notes_add) } len = strlen(notes_add) + strlen(cryst->notes) + 2; - nnotes = malloc(len); + nnotes = cfmalloc(len); if ( nnotes == NULL ) { ERROR("Failed to add notes to crystal.\n"); return; @@ -347,7 +347,7 @@ void crystal_add_notes(Crystal *cryst, const char *notes_add) strcpy(nnotes, cryst->notes); strcat(nnotes, "\n"); strcat(nnotes, notes_add); - free(cryst->notes); + cffree(cryst->notes); cryst->notes = nnotes; } diff --git a/libcrystfel/src/crystfel-mille.c b/libcrystfel/src/crystfel-mille.c index 8eacaa60..381ee60a 100644 --- a/libcrystfel/src/crystfel-mille.c +++ b/libcrystfel/src/crystfel-mille.c @@ -106,8 +106,8 @@ static void mille_add_measurement(Mille *m, new_max_entries *= 2; } - new_float_arr = realloc(m->float_arr, new_max_entries*sizeof(float)); - new_int_arr = realloc(m->int_arr, new_max_entries*sizeof(int)); + new_float_arr = cfrealloc(m->float_arr, new_max_entries*sizeof(float)); + new_int_arr = cfrealloc(m->int_arr, new_max_entries*sizeof(int)); if ( (new_float_arr == NULL) || (new_int_arr == NULL) ) return; m->float_arr = new_float_arr; @@ -285,7 +285,7 @@ Mille *crystfel_mille_new(const char *outFileName) { Mille *m; - m = malloc(sizeof(Mille)); + m = cfmalloc(sizeof(Mille)); if ( m == NULL ) return NULL; m->max_entries = 0; @@ -296,7 +296,7 @@ Mille *crystfel_mille_new(const char *outFileName) m->fh = fopen(outFileName, "wb"); if ( m->fh == NULL ) { ERROR("Failed to open Mille file '%s'\n", outFileName); - free(m); + cffree(m); return NULL; } @@ -309,9 +309,9 @@ void crystfel_mille_free(Mille *m) { if ( m == NULL ) return; fclose(m->fh); - free(m->float_arr); - free(m->int_arr); - free(m); + cffree(m->float_arr); + cffree(m->int_arr); + cffree(m); } diff --git a/libcrystfel/src/datatemplate.c b/libcrystfel/src/datatemplate.c index a01baba5..9c992c70 100644 --- a/libcrystfel/src/datatemplate.c +++ b/libcrystfel/src/datatemplate.c @@ -73,14 +73,14 @@ static struct panel_group_template *add_group(const char *name, DataTemplate *dt return NULL; } - gt = malloc(sizeof(struct panel_group_template)); + gt = cfmalloc(sizeof(struct panel_group_template)); if ( gt == NULL ) return NULL; - gt->name = strdup(name); + gt->name = cfstrdup(name); gt->n_children = 0; if ( gt->name == NULL ) { - free(gt); + cffree(gt); return NULL; } @@ -140,8 +140,8 @@ static int parse_group(const char *name, DataTemplate *dt, const char *val) } - for ( i=0; in_panels++; - det->panels = realloc(det->panels, - det->n_panels*sizeof(struct panel_template)); + det->panels = cfrealloc(det->panels, + det->n_panels*sizeof(struct panel_template)); new = &det->panels[det->n_panels-1]; memcpy(new, defaults, sizeof(struct panel_template)); /* Set name */ - new->name = strdup(name); + new->name = cfstrdup(name); /* Copy strings */ new->data = safe_strdup(defaults->data); @@ -186,7 +186,7 @@ static struct dt_badregion *new_bad_region(DataTemplate *det, const char *name) struct dt_badregion *new; det->n_bad++; - det->bad = realloc(det->bad, det->n_bad*sizeof(struct dt_badregion)); + det->bad = cfrealloc(det->bad, det->n_bad*sizeof(struct dt_badregion)); new = &det->bad[det->n_bad-1]; new->min_x = NAN; @@ -257,12 +257,12 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) /* Add plus at start if no sign there already */ if ( (a_orig[0] != '+') && (a_orig[0] != '-') ) { len += 1; - a = malloc(len+1); + a = cfmalloc(len+1); snprintf(a, len+1, "+%s", a_orig); a[len] = '\0'; } else { - a = strdup(a_orig); + a = cfstrdup(a_orig); } /* Count the expressions */ @@ -271,7 +271,7 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) if ( (a[i] == '+') || (a[i] == '-') ) nexp++; } - bits = calloc(nexp, sizeof(char *)); + bits = cfcalloc(nexp, sizeof(char *)); /* Break the string up */ idx = -1; @@ -288,7 +288,7 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) if ( (ch == '+') || (ch == '-') ) { if ( idx >= 0 ) bits[idx][istr] = '\0'; idx++; - bits[idx] = malloc(len+1); + bits[idx] = cfmalloc(len+1); istr = 0; } @@ -306,7 +306,7 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) if ( idx >= 0 ) bits[idx][istr] = '\0'; *pbits = bits; - free(a); + cffree(a); return nexp; } @@ -381,10 +381,10 @@ static int dir_conv(const char *a, double *sx, double *sy, double *sz) break; } - free(bits[i]); + cffree(bits[i]); } - free(bits); + cffree(bits); return 0; } @@ -450,7 +450,7 @@ static int parse_mask(struct panel_template *panel, return 1; } - key = strdup(key_orig); + key = cfstrdup(key_orig); if ( key == NULL ) return 1; key[4] = '_'; @@ -459,16 +459,16 @@ static int parse_mask(struct panel_template *panel, * Double underscore is deliberate! */ if ( strcmp(key, "mask__file") == 0 ) { - panel->masks[n].filename = strdup(val); + panel->masks[n].filename = cfstrdup(val); } else if ( strcmp(key, "mask__data") == 0 ) { if ( strncmp(val, "/", 1) != 0 ) { ERROR("Invalid mask location '%s'\n", val); - free(key); + cffree(key); return 1; } - panel->masks[n].data_location = strdup(val); + panel->masks[n].data_location = cfstrdup(val); } else if ( strcmp(key, "mask__goodbits") == 0 ) { @@ -478,7 +478,7 @@ static int parse_mask(struct panel_template *panel, if ( end != val ) { panel->masks[n].good_bits = v; } else { - free(key); + cffree(key); return 1; } @@ -490,19 +490,19 @@ static int parse_mask(struct panel_template *panel, if ( end != val ) { panel->masks[n].bad_bits = v; } else { - free(key); + cffree(key); return 1; } } else { ERROR("Invalid mask directive '%s'\n", key_orig); - free(key); + cffree(key); return 1; } panel->masks[n].mask_default = def; - free(key); + cffree(key); return 0; } @@ -538,8 +538,8 @@ static int parse_field_for_panel(struct panel_template *panel, const char *key, reject = 1; } else if ( strcmp(key, "data") == 0 ) { - free(panel->data); - panel->data = strdup(val); + cffree(panel->data); + panel->data = cfstrdup(val); panel->data_default = def; } else if ( strcmp(key, "mask_edge_pixels") == 0 ) { @@ -563,10 +563,10 @@ static int parse_field_for_panel(struct panel_template *panel, const char *key, reject = parse_mask(panel, key, val, def); } else if ( strcmp(key, "saturation_map") == 0 ) { - panel->satmap = strdup(val); + panel->satmap = cfstrdup(val); panel->satmap_default = def; } else if ( strcmp(key, "saturation_map_file") == 0 ) { - panel->satmap_file = strdup(val); + panel->satmap_file = cfstrdup(val); panel->satmap_file_default = def; } else if ( strcmp(key, "coffset") == 0) { @@ -685,7 +685,7 @@ static int parse_field_bad(struct dt_badregion *badr, const char *key, badr->max_ss = atof(val); reject = check_badr_fsss(badr, 1); } else if ( strcmp(key, "panel") == 0 ) { - badr->panel_name = strdup(val); + badr->panel_name = cfstrdup(val); } else { ERROR("Unrecognised field '%s'\n", key); } @@ -701,13 +701,13 @@ static int parse_electron_voltage(const char *val, char *valcpy; char *sp; - valcpy = strdup(val); + valcpy = cfstrdup(val); if ( valcpy == NULL ) return 1; /* "electron_voltage" directive must have explicit units */ sp = strchr(valcpy, ' '); if ( sp == NULL ) { - free(valcpy); + cffree(valcpy); return 1; } @@ -716,7 +716,7 @@ static int parse_electron_voltage(const char *val, } else if ( strcmp(sp+1, "kV") == 0 ) { *punit = WAVELENGTH_ELECTRON_KV; } else { - free(valcpy); + cffree(valcpy); return 1; } @@ -733,13 +733,13 @@ static int parse_wavelength(const char *val, char *valcpy; char *sp; - valcpy = strdup(val); + valcpy = cfstrdup(val); if ( valcpy == NULL ) return 1; /* "wavelength" directive must have explicit units */ sp = strchr(valcpy, ' '); if ( sp == NULL ) { - free(valcpy); + cffree(valcpy); return 1; } @@ -748,7 +748,7 @@ static int parse_wavelength(const char *val, } else if ( strcmp(sp+1, "A") == 0 ) { *punit = WAVELENGTH_A; } else { - free(valcpy); + cffree(valcpy); return 1; } @@ -765,7 +765,7 @@ static int parse_photon_energy(const char *val, char *valcpy; char *sp; - valcpy = strdup(val); + valcpy = cfstrdup(val); if ( valcpy == NULL ) return 1; /* "photon_energy" is the only one of the wavelength @@ -781,7 +781,7 @@ static int parse_photon_energy(const char *val, sp[0] = '\0'; } else { /* Unit specified, but unrecognised */ - free(valcpy); + cffree(valcpy); return 1; } @@ -819,13 +819,13 @@ static int parse_toplevel(DataTemplate *dt, int *defaults_updated) { if ( strcmp(key, "detector_shift_x") == 0 ) { - dt->shift_x_from = strdup(val); + dt->shift_x_from = cfstrdup(val); } else if ( strcmp(key, "detector_shift_y") == 0 ) { - dt->shift_y_from = strdup(val); + dt->shift_y_from = cfstrdup(val); } else if ( strcmp(key, "clen") == 0 ) { - dt->cnz_from = strdup(val); + dt->cnz_from = cfstrdup(val); } else if ( strcmp(key, "photon_energy") == 0 ) { return parse_photon_energy(val, @@ -843,7 +843,7 @@ static int parse_toplevel(DataTemplate *dt, &dt->wavelength_unit); } else if ( strcmp(key, "peak_list") == 0 ) { - dt->peak_list = strdup(val); + dt->peak_list = cfstrdup(val); } else if ( strcmp(key, "peak_list_type") == 0 ) { return parse_peak_layout(val, &dt->peak_list_type); @@ -1024,7 +1024,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) struct panel_template defaults; int have_unused_defaults = 0; - dt = calloc(1, sizeof(DataTemplate)); + dt = cfcalloc(1, sizeof(DataTemplate)); if ( dt == NULL ) return NULL; dt->n_panels = 0; @@ -1078,7 +1078,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) defaults.satmap_default = 1; defaults.satmap_file = NULL; defaults.satmap_file_default = 1; - defaults.data = strdup("/data/data"); + defaults.data = cfstrdup("/data/data"); defaults.data_default = 1; defaults.name = NULL; defaults.dims[0] = DIM_SS; @@ -1086,7 +1086,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) for ( i=2; in_panels == 0 ) { ERROR("No panel descriptions in geometry file.\n"); - free(dt); + cffree(dt); return NULL; } @@ -1390,10 +1390,10 @@ DataTemplate *data_template_new_from_string(const char *string_in) } } - free(defaults.data); + cffree(defaults.data); for ( i=0; igroups[0]->name); } - free(string_orig); + cffree(string_orig); if ( reject ) return NULL; @@ -1422,7 +1422,7 @@ DataTemplate *data_template_new_from_file(const char *filename) } dt = data_template_new_from_string(contents); - free(contents); + cffree(contents); return dt; } @@ -1437,33 +1437,33 @@ void data_template_free(DataTemplate *dt) int j; - free(dt->panels[i].name); - free(dt->panels[i].data); - free(dt->panels[i].satmap); - free(dt->panels[i].satmap_file); + cffree(dt->panels[i].name); + cffree(dt->panels[i].data); + cffree(dt->panels[i].satmap); + cffree(dt->panels[i].satmap_file); for ( j=0; jpanels[i].masks[j].filename); - free(dt->panels[i].masks[j].data_location); + cffree(dt->panels[i].masks[j].filename); + cffree(dt->panels[i].masks[j].data_location); } } for ( i=0; in_headers_to_copy; i++ ) { - free(dt->headers_to_copy[i]); + cffree(dt->headers_to_copy[i]); } for ( i=0; in_groups; i++ ) { - free(dt->groups[i]->name); - free(dt->groups[i]); + cffree(dt->groups[i]->name); + cffree(dt->groups[i]); } - free(dt->wavelength_from); - free(dt->peak_list); - free(dt->cnz_from); + cffree(dt->wavelength_from); + cffree(dt->peak_list); + cffree(dt->cnz_from); - free(dt->panels); - free(dt->bad); - free(dt); + cffree(dt->panels); + cffree(dt->bad); + cffree(dt); } @@ -1564,7 +1564,7 @@ void data_template_add_copy_header(DataTemplate *dt, return; } - dt->headers_to_copy[dt->n_headers_to_copy++] = strdup(header); + dt->headers_to_copy[dt->n_headers_to_copy++] = cfstrdup(header); } @@ -1682,14 +1682,14 @@ static int separate_value_and_units(const char *from, if ( from == NULL ) return 1; - fromcpy = strdup(from); + fromcpy = cfstrdup(from); if ( fromcpy == NULL ) return 1; sp = strchr(fromcpy, ' '); if ( sp == NULL ) { unitscpy = NULL; } else { - unitscpy = strdup(sp+1); + unitscpy = cfstrdup(sp+1); sp[0] = '\0'; } @@ -1725,14 +1725,14 @@ static int im_get_length(struct image *image, const char *from, if ( convert_float(value_str, pval) == 0 ) { /* Literal value with no units */ - free(value_str); + cffree(value_str); return 0; } else { int r; r = image_read_header_float(image, value_str, pval); - free(value_str); + cffree(value_str); if ( r == 0 ) { /* Value read from headers with no units */ @@ -1756,16 +1756,16 @@ static int im_get_length(struct image *image, const char *from, scale = 1.0; } else { ERROR("Invalid length unit '%s'\n", units); - free(value_str); - free(units); + cffree(value_str); + cffree(units); return 1; } if ( convert_float(value_str, pval) == 0 ) { /* Literal value, units specified */ - free(value_str); - free(units); + cffree(value_str); + cffree(units); *pval *= scale; return 0; @@ -1773,7 +1773,7 @@ static int im_get_length(struct image *image, const char *from, int r; r = image_read_header_float(image, value_str, pval); - free(value_str); + cffree(value_str); if ( r == 0 ) { /* Value read from headers, units specified */ @@ -1849,10 +1849,10 @@ static struct detgeom_panel_group *walk_group(const DataTemplate *dtempl, if ( gt == NULL ) return NULL; - gr = malloc(sizeof(struct detgeom_panel_group)); + gr = cfmalloc(sizeof(struct detgeom_panel_group)); if ( gr == NULL ) return NULL; - gr->name = strdup(gt->name); + gr->name = cfstrdup(gt->name); gr->n_children = gt->n_children; if ( gr->n_children == 0 ) { @@ -1888,9 +1888,9 @@ static struct detgeom_panel_group *walk_group(const DataTemplate *dtempl, double tz = 0.0; gr->panel = NULL; - gr->children = malloc(gt->n_children*sizeof(struct detgeom_panel_group *)); + gr->children = cfmalloc(gt->n_children*sizeof(struct detgeom_panel_group *)); if ( gr->children == NULL ) { - free(gr); + cffree(gr); return NULL; } @@ -1928,14 +1928,14 @@ struct detgeom *create_detgeom(struct image *image, return NULL; } - detgeom = malloc(sizeof(struct detgeom)); + detgeom = cfmalloc(sizeof(struct detgeom)); if ( detgeom == NULL ) return NULL; detgeom->top_group = NULL; - detgeom->panels = malloc(dtempl->n_panels*sizeof(struct detgeom_panel)); + detgeom->panels = cfmalloc(dtempl->n_panels*sizeof(struct detgeom_panel)); if ( detgeom->panels == NULL ) { - free(detgeom); + cffree(detgeom); return NULL; } @@ -1946,8 +1946,8 @@ struct detgeom *create_detgeom(struct image *image, || (dtempl->shift_x_from != NULL) || (dtempl->shift_y_from != NULL) ) { - free(detgeom->panels); - free(detgeom); + cffree(detgeom->panels); + cffree(detgeom); return NULL; } } @@ -2680,7 +2680,7 @@ struct dg_group_info *data_template_group_info(const DataTemplate *dtempl, int * int i; struct panel_group_template *group; - ginfo = malloc(sizeof(struct dg_group_info)*dtempl->n_groups); + ginfo = cfmalloc(sizeof(struct dg_group_info)*dtempl->n_groups); if ( ginfo == NULL ) return NULL; group = find_group(dtempl, "all"); diff --git a/libcrystfel/src/detgeom.c b/libcrystfel/src/detgeom.c index b4835317..39b00663 100644 --- a/libcrystfel/src/detgeom.c +++ b/libcrystfel/src/detgeom.c @@ -74,9 +74,9 @@ static void free_group(struct detgeom_panel_group *g) free_group(g->children[i]); } - free(g->name); - free(g->children); - free(g); + cffree(g->name); + cffree(g->children); + cffree(g); } @@ -87,12 +87,12 @@ void detgeom_free(struct detgeom *detgeom) if ( detgeom == NULL ) return; for ( i=0; in_panels; i++ ) { - free(detgeom->panels[i].name); + cffree(detgeom->panels[i].name); } free_group(detgeom->top_group); - free(detgeom->panels); - free(detgeom); + cffree(detgeom->panels); + cffree(detgeom); } @@ -250,7 +250,7 @@ gsl_matrix **make_panel_minvs(struct detgeom *dg) int i; gsl_matrix **Minvs; - Minvs = malloc(dg->n_panels * sizeof(gsl_matrix *)); + Minvs = cfmalloc(dg->n_panels * sizeof(gsl_matrix *)); if ( Minvs == NULL ) return NULL; for ( i=0; in_panels; i++ ) { diff --git a/libcrystfel/src/filters.c b/libcrystfel/src/filters.c index 4bc41f3d..e3316b1d 100644 --- a/libcrystfel/src/filters.c +++ b/libcrystfel/src/filters.c @@ -136,7 +136,7 @@ void filter_median(struct image *image, int size) nn = nn*nn; /* "localBg" is way too big, but guaranteed big enough */ - buffer = calloc(nn, sizeof(float)); + buffer = cfcalloc(nn, sizeof(float)); if ( buffer == NULL ) { ERROR("Failed to allocate LB buffer.\n"); return; @@ -153,7 +153,7 @@ void filter_median(struct image *image, int size) p = &image->detgeom->panels[pn]; - localBg = calloc(p->w*p->h, sizeof(float)); + localBg = cfcalloc(p->w*p->h, sizeof(float)); if ( localBg == NULL ) { ERROR("Failed to allocate LB buffer.\n"); return; @@ -195,8 +195,8 @@ void filter_median(struct image *image, int size) image->dp[pn][i] -= localBg[i]; } - free(localBg); + cffree(localBg); } - free(buffer); + cffree(buffer); } diff --git a/libcrystfel/src/fom.c b/libcrystfel/src/fom.c index e0149e6e..8c105533 100644 --- a/libcrystfel/src/fom.c +++ b/libcrystfel/src/fom.c @@ -78,14 +78,14 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) struct fom_context *fctx; int i; - fctx = malloc(sizeof(struct fom_context)); + fctx = cfmalloc(sizeof(struct fom_context)); if ( fctx == NULL ) return NULL; fctx->fom = fom; fctx->nshells = nshells; - fctx->cts = malloc(nshells*sizeof(int)); + fctx->cts = cfmalloc(nshells*sizeof(int)); if ( fctx->cts == NULL ) { - free(fctx); + cffree(fctx); return NULL; } for ( i=0; ifom ) { case FOM_RANORSPLIT : - fctx->num2 = malloc(nshells*sizeof(double)); - fctx->den2 = malloc(nshells*sizeof(double)); + fctx->num2 = cfmalloc(nshells*sizeof(double)); + fctx->den2 = cfmalloc(nshells*sizeof(double)); if ( (fctx->num2 == NULL) || (fctx->den2 == NULL) ) goto out; for ( i=0; inum2[i] = 0.0; @@ -123,8 +123,8 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) case FOM_MEAN_INTENSITY : case FOM_SNR : case FOM_REDUNDANCY : - fctx->num = malloc(nshells*sizeof(double)); - fctx->den = malloc(nshells*sizeof(double)); + fctx->num = cfmalloc(nshells*sizeof(double)); + fctx->den = cfmalloc(nshells*sizeof(double)); if ( (fctx->num == NULL) || (fctx->den == NULL) ) goto out; for ( i=0; inum[i] = 0.0; @@ -137,7 +137,7 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) break; case FOM_NUM_MEASUREMENTS : - fctx->n_meas = calloc(nshells, sizeof(long int)); + fctx->n_meas = cfcalloc(nshells, sizeof(long int)); if ( fctx->n_meas == NULL ) goto out; break; @@ -145,20 +145,20 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) case FOM_CCSTAR : case FOM_CCANO : case FOM_CRDANO : - fctx->vec1 = malloc(nshells*sizeof(double *)); - fctx->vec2 = malloc(nshells*sizeof(double *)); + fctx->vec1 = cfmalloc(nshells*sizeof(double *)); + fctx->vec2 = cfmalloc(nshells*sizeof(double *)); if ( (fctx->vec1 == NULL) || (fctx->vec2 == NULL) ) goto out; for ( i=0; ivec1[i] = NULL; fctx->vec2[i] = NULL; } for ( i=0; ivec1[i] = malloc(nmax*sizeof(double)); + fctx->vec1[i] = cfmalloc(nmax*sizeof(double)); if ( fctx->vec1[i] == NULL ) goto out; - fctx->vec2[i] = malloc(nmax*sizeof(double)); + fctx->vec2[i] = cfmalloc(nmax*sizeof(double)); if ( fctx->vec2[i] == NULL ) goto out; } - fctx->n = malloc(nshells*sizeof(int)); + fctx->n = cfmalloc(nshells*sizeof(int)); if ( fctx->n == NULL ) goto out; for ( i=0; in[i] = 0; @@ -168,7 +168,7 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) case FOM_D1SIG : case FOM_D2SIG : - fctx->n_within = malloc(nshells*sizeof(int)); + fctx->n_within = cfmalloc(nshells*sizeof(int)); if ( fctx->n_within == NULL ) goto out; for ( i=0; in_within[i] = 0; @@ -180,26 +180,26 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) return fctx; out: - free(fctx->num2); - free(fctx->den2); - free(fctx->num); - free(fctx->den); - free(fctx->n_meas); + cffree(fctx->num2); + cffree(fctx->den2); + cffree(fctx->num); + cffree(fctx->den); + cffree(fctx->n_meas); if ( fctx->vec1 != NULL ) { for ( i=0; ivec1[i]); + cffree(fctx->vec1[i]); } - free(fctx->vec1); + cffree(fctx->vec1); } if ( fctx->vec2 != NULL ) { for ( i=0; ivec2[i]); + cffree(fctx->vec2[i]); } - free(fctx->vec2); + cffree(fctx->vec2); } - free(fctx->n); - free(fctx->n_within); - free(fctx); + cffree(fctx->n); + cffree(fctx->n_within); + cffree(fctx); return NULL; } @@ -404,8 +404,8 @@ double fom_overall_value(struct fom_context *fctx) case FOM_CC : case FOM_CCSTAR : case FOM_CCANO : - overall_vec1 = malloc(fctx->nmax*sizeof(double)); - overall_vec2 = malloc(fctx->nmax*sizeof(double)); + overall_vec1 = cfmalloc(fctx->nmax*sizeof(double)); + overall_vec2 = cfmalloc(fctx->nmax*sizeof(double)); overall_n = 0; for ( i=0; inshells; i++ ) { int j; @@ -417,13 +417,13 @@ double fom_overall_value(struct fom_context *fctx) } cc = gsl_stats_correlation(overall_vec1, 1, overall_vec2, 1, overall_n); - free(overall_vec1); - free(overall_vec2); + cffree(overall_vec1); + cffree(overall_vec2); break; case FOM_CRDANO : - overall_along_diagonal = malloc(fctx->nmax*sizeof(double)); - overall_perpend_diagonal = malloc(fctx->nmax*sizeof(double)); + overall_along_diagonal = cfmalloc(fctx->nmax*sizeof(double)); + overall_perpend_diagonal = cfmalloc(fctx->nmax*sizeof(double)); overall_n = 0; for ( i=0; inshells; i++ ) { int j; @@ -443,8 +443,8 @@ double fom_overall_value(struct fom_context *fctx) 1, overall_n, 0.0); cc = sqrt(variance_signal / variance_error ); - free(overall_along_diagonal); - free(overall_perpend_diagonal); + cffree(overall_along_diagonal); + cffree(overall_perpend_diagonal); break; case FOM_D1SIG : @@ -566,8 +566,8 @@ double fom_shell_value(struct fom_context *fctx, int i) (2.0*(fctx->num2[i]/fctx->den2[i]) / sqrt(2.0)); case FOM_CRDANO : - along_diagonal = malloc(fctx->n[i] * sizeof(double)); - perpend_diagonal = malloc(fctx->n[i] * sizeof(double)); + along_diagonal = cfmalloc(fctx->n[i] * sizeof(double)); + perpend_diagonal = cfmalloc(fctx->n[i] * sizeof(double)); for ( j=0; jn[i]; j++ ) { along_diagonal[j] = ( fctx->vec1[i][j] + fctx->vec2[i][j] ) / sqrt(2.0); @@ -578,8 +578,8 @@ double fom_shell_value(struct fom_context *fctx, int i) fctx->n[i], 0.0); variance_error = gsl_stats_variance_m(perpend_diagonal, 1, fctx->n[i], 0.0); - free(along_diagonal); - free(perpend_diagonal); + cffree(along_diagonal); + cffree(perpend_diagonal); return sqrt(variance_signal / variance_error); case FOM_D1SIG : @@ -616,17 +616,17 @@ struct fom_shells *fom_make_resolution_shells(double rmin, double rmax, double total_vol, vol_per_shell; int i; - s = malloc(sizeof(struct fom_shells)); + s = cfmalloc(sizeof(struct fom_shells)); if ( s == NULL ) return NULL; - s->rmins = malloc(nshells*sizeof(double)); - s->rmaxs = malloc(nshells*sizeof(double)); + s->rmins = cfmalloc(nshells*sizeof(double)); + s->rmaxs = cfmalloc(nshells*sizeof(double)); if ( (s->rmins==NULL) || (s->rmaxs==NULL) ) { ERROR("Couldn't allocate memory for resolution shells.\n"); - free(s->rmins); - free(s->rmaxs); - free(s); + cffree(s->rmins); + cffree(s->rmaxs); + cffree(s); return NULL; } @@ -705,8 +705,8 @@ static int wilson_scale(RefList *list1, RefList *list2, UnitCell *cell) double G, B; double c0, c1, cov00, cov01, cov11, chisq; - x = malloc(max_n*sizeof(double)); - y = malloc(max_n*sizeof(double)); + x = cfmalloc(max_n*sizeof(double)); + y = cfmalloc(max_n*sizeof(double)); if ( (x==NULL) || (y==NULL) ) { ERROR("Failed to allocate memory for scaling.\n"); return 1; @@ -772,8 +772,8 @@ static int wilson_scale(RefList *list1, RefList *list2, UnitCell *cell) STATUS("A positive relative B factor means that the second reflection " "list falls off with resolution more quickly than the first.\n"); - free(x); - free(y); + cffree(x); + cffree(y); /* Apply the scaling factor */ for ( refl2 = first_refl(list2, &iter); @@ -808,12 +808,12 @@ static int calculate_possible(struct fom_context *fctx, double cx, cy, cz; signed int h, k, l; - fctx->possible = calloc(fctx->nshells, sizeof(long int)); + fctx->possible = cfcalloc(fctx->nshells, sizeof(long int)); if ( fctx->possible == NULL ) return 1; counted = reflist_new(); if ( counted == NULL ) { - free(fctx->possible); + cffree(fctx->possible); return 1; } diff --git a/libcrystfel/src/image-cbf.c b/libcrystfel/src/image-cbf.c index 0fb3b61c..c0e38283 100644 --- a/libcrystfel/src/image-cbf.c +++ b/libcrystfel/src/image-cbf.c @@ -302,7 +302,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) gzbuffer(gzfh, 128*1024); #endif - buf = malloc(bufsz); + buf = cfmalloc(bufsz); if ( buf == NULL ) return NULL; len = 0; @@ -322,7 +322,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) fh = fmemopen(buf, len, "rb"); if ( fh == NULL ) { - free(buf); + cffree(buf); return NULL; } @@ -365,7 +365,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) const char *elbo = line+29; if ( strcmp(elbo, "LITTLE_ENDIAN") != 0 ) { ERROR("Unsupported endianness: %s\n", elbo); - free(buf); + cffree(buf); fclose(fh); return NULL; } @@ -380,7 +380,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) data_conversion = CBF_PACKED; } else if ( strstr(line, "conversions=") != NULL ) { ERROR("Unrecognised CBF content conversion: %s\n", line); - free(buf); + cffree(buf); fclose(fh); return NULL; } @@ -393,7 +393,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) if ( data_type == CBF_NO_TYPE ) { ERROR("Unrecognised element type: %s\n", eltype); - free(buf); + cffree(buf); fclose(fh); return NULL; } @@ -418,29 +418,29 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) if ( data_compressed_len == 0 ) { ERROR("Found CBF data before X-Binary-Size!\n"); - free(buf); + cffree(buf); fclose(fh); return NULL; } if ( (*w == 0) || (*h == 0) ) { ERROR("Found CBF data before dimensions!\n"); - free(buf); + cffree(buf); fclose(fh); return NULL; } if ( data_compressed_len > 100*1024*1024 ) { ERROR("Stated CBF data size too big\n"); - free(buf); + cffree(buf); fclose(fh); return NULL; } - data_compressed = malloc(data_compressed_len); + data_compressed = cfmalloc(data_compressed_len); if ( data_compressed == NULL ) { ERROR("Failed to allocate memory for CBF data\n"); - free(buf); + cffree(buf); fclose(fh); return NULL; } @@ -449,18 +449,18 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) len_read = fread(data_compressed, 1, data_compressed_len, fh); if ( len_read < data_compressed_len ) { ERROR("Couldn't read entire CBF data\n"); - free(buf); - free(data_compressed); + cffree(buf); + cffree(data_compressed); fclose(fh); return NULL; } nmemb_exp = (*w) * (*h); - data_out = malloc(nmemb_exp*sizeof(float)); + data_out = cfmalloc(nmemb_exp*sizeof(float)); if ( data_out == NULL ) { ERROR("Failed to allocate memory for CBF data\n"); - free(buf); - free(data_compressed); + cffree(buf); + cffree(data_compressed); fclose(fh); return NULL; } @@ -483,23 +483,23 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) case CBF_CANONICAL: ERROR("Don't yet know how to decompress " "CBF_PACKED or CBF_CANONICAL\n"); - free(buf); - free(data_compressed); + cffree(buf); + cffree(data_compressed); fclose(fh); return NULL; } - free(data_compressed); + cffree(data_compressed); if ( r ) { - free(buf); - free(data_out); + cffree(buf); + cffree(data_out); fclose(fh); return NULL; } - free(buf); + cffree(buf); fclose(fh); return data_out; @@ -508,7 +508,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) } while ( rval != NULL ); ERROR("Reached end of CBF file before finding data.\n"); - free(buf); /* might be NULL */ + cffree(buf); /* might be NULL */ return NULL; } @@ -598,7 +598,7 @@ int image_cbf_read(struct image *image, ERROR("Failed to read CBF data\n"); return 1; } - free(data); + cffree(data); //cbf_fill_in_beam_parameters(image->beam, f, image); //cbf_fill_in_clen(image->det, f); diff --git a/libcrystfel/src/image-hdf5.c b/libcrystfel/src/image-hdf5.c index 37d333ac..a148c307 100644 --- a/libcrystfel/src/image-hdf5.c +++ b/libcrystfel/src/image-hdf5.c @@ -60,7 +60,7 @@ char **read_path_parts(const char *ev_orig, int *pn_plvals) int n_plvals = 0; char *start; - plvals = malloc(MAX_PATH_PARTS*sizeof(char *)); + plvals = cfmalloc(MAX_PATH_PARTS*sizeof(char *)); if ( plvals == NULL ) return NULL; if ( ev_orig == NULL ) { @@ -69,9 +69,9 @@ char **read_path_parts(const char *ev_orig, int *pn_plvals) return plvals; } - ev = strdup(ev_orig); + ev = cfstrdup(ev_orig); if ( ev == NULL ) { - free(plvals); + cffree(plvals); return NULL; } @@ -87,8 +87,8 @@ char **read_path_parts(const char *ev_orig, int *pn_plvals) * must at least have // */ ERROR("Couldn't read path parts ('%s')\n", start); - free(ev); - free(plvals); + cffree(ev); + cffree(plvals); return NULL; } @@ -97,19 +97,19 @@ char **read_path_parts(const char *ev_orig, int *pn_plvals) if ( n_plvals == MAX_PATH_PARTS ) { ERROR("Too many path parts: %s\n", ev_orig); - free(ev); - free(plvals); + cffree(ev); + cffree(plvals); return NULL; } sep[0] = '\0'; - plvals[n_plvals++] = strdup(start); + plvals[n_plvals++] = cfstrdup(start); start = sep+1; } while ( 1 ); - free(ev); + cffree(ev); *pn_plvals = n_plvals; return plvals; } @@ -135,7 +135,7 @@ int *read_dim_parts(const char *ev_orig, int *pn_dvals) ev = strstr(ev_orig, "//"); if ( ev == NULL ) return NULL; - dvals = malloc(MAX_DIMS*sizeof(int)); + dvals = cfmalloc(MAX_DIMS*sizeof(int)); if ( dvals == NULL ) return NULL; if ( ev[2] == '\0' ) { @@ -144,9 +144,9 @@ int *read_dim_parts(const char *ev_orig, int *pn_dvals) return dvals; /* NB Not NULL */ } - ev = strdup(ev+2); + ev = cfstrdup(ev+2); if ( ev == NULL ) { - free(dvals); + cffree(dvals); return NULL; } @@ -164,15 +164,15 @@ int *read_dim_parts(const char *ev_orig, int *pn_dvals) if ( n_dvals == MAX_PATH_PARTS ) { ERROR("Too many path parts: %s\n", ev_orig); - free(ev); - free(dvals); + cffree(ev); + cffree(dvals); return NULL; } if ( start[0] == '\0' ) { ERROR("Missing dimension: %s\n", ev_orig); - free(ev); - free(dvals); + cffree(ev); + cffree(dvals); return NULL; } @@ -182,7 +182,7 @@ int *read_dim_parts(const char *ev_orig, int *pn_dvals) } while ( !done ); - free(ev); + cffree(ev); *pn_dvals = n_dvals; return dvals; } @@ -247,19 +247,19 @@ char *substitute_path(const char *ev, const char *pattern, int skip_ok) if ( n_pl_exp == 0 ) { /* No placeholders in path */ for ( i=0; iname, panel_full_path); profile_end("H5Dopen2"); - free(panel_full_path); + cffree(panel_full_path); return 1; } profile_end("H5Dopen2"); - free(panel_full_path); + cffree(panel_full_path); /* Set up dataspace for file * (determine where to read the data from) */ @@ -446,12 +446,12 @@ static int load_hdf5_hyperslab(struct panel_template *p, n_dt_dims = total_dt_dims; } - f_offset = malloc(ndims*sizeof(hsize_t)); - f_count = malloc(ndims*sizeof(hsize_t)); + f_offset = cfmalloc(ndims*sizeof(hsize_t)); + f_count = cfmalloc(ndims*sizeof(hsize_t)); if ( (f_offset == NULL) || (f_count == NULL ) ) { ERROR("Failed to allocate offset or count.\n"); - free(f_offset); - free(f_count); + cffree(f_offset); + cffree(f_count); H5Dclose(dh); return 1; } @@ -492,15 +492,15 @@ static int load_hdf5_hyperslab(struct panel_template *p, } } - free(dim_vals); + cffree(dim_vals); check = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, f_offset, NULL, f_count, NULL); if ( check < 0 ) { ERROR("Error selecting file dataspace for panel %s\n", p->name); - free(f_offset); - free(f_count); + cffree(f_offset); + cffree(f_count); H5Dclose(dh); return 1; } @@ -515,15 +515,15 @@ static int load_hdf5_hyperslab(struct panel_template *p, if ( r < 0 ) { ERROR("Couldn't read data for panel %s\n", p->name); - free(f_offset); - free(f_count); - free(data); + cffree(f_offset); + cffree(f_count); + cffree(data); H5Dclose(dh); return 1; } - free(f_offset); - free(f_count); + cffree(f_offset); + cffree(f_count); if ( orig_type != NULL ) { *orig_type = H5Dget_type(dh); @@ -679,7 +679,7 @@ int image_hdf5_read_mask(struct panel_template *p, return 1; } - mask = malloc(p_w*p_h*sizeof(int)); + mask = cfmalloc(p_w*p_h*sizeof(int)); if ( mask == NULL ) return 1; if ( load_hdf5_hyperslab(p, fh, event, @@ -687,7 +687,7 @@ int image_hdf5_read_mask(struct panel_template *p, sizeof(int), 1, mask_location, NULL) ) { ERROR("Failed to load mask data\n"); - free(mask); + cffree(mask); return 1; } @@ -703,7 +703,7 @@ int image_hdf5_read_mask(struct panel_template *p, } - free(mask); + cffree(mask); return 0; } @@ -724,7 +724,7 @@ static char *read_single_fixed_string(hid_t dh) sh = H5Screate(H5S_SCALAR); type = H5Dget_type(dh); size = H5Tget_size(type); - tmp = malloc(size+1); + tmp = cfmalloc(size+1); if ( tmp == NULL ) { H5Tclose(type); return NULL; @@ -733,7 +733,7 @@ static char *read_single_fixed_string(hid_t dh) H5Sclose(sh); H5Tclose(type); if ( r < 0 ) { - free(tmp); + cffree(tmp); ERROR("Couldn't read scalar string\n"); return NULL; } else { @@ -802,7 +802,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) dh = H5Dopen2(fh, subst_name, H5P_DEFAULT); if ( dh < 0 ) { ERROR("No such numeric field '%s'\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return 1; } @@ -822,7 +822,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) ERROR("HDF5 header is not a recognised type (%s).\n", subst_name); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } @@ -833,7 +833,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( ndims > 64 ) { ERROR("Too many dimensions for numeric value\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } H5Sget_simple_extent_dims(sh, size, NULL); @@ -855,12 +855,12 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( r < 0 ) { ERROR("Couldn't read scalar value from %s.\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return 1; } image_cache_header_float(image, name, val); - free(subst_name); + cffree(subst_name); return 0; } else if ( class == H5T_INTEGER ) { @@ -871,12 +871,12 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( r < 0 ) { ERROR("Couldn't read scalar value from %s.\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return 1; } image_cache_header_int(image, name, val); - free(subst_name); + cffree(subst_name); return 0; } else if ( class == H5T_STRING ) { @@ -902,7 +902,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( val != NULL ) { image_cache_header_str(image, name, val); - free(val); + cffree(val); rv = 0; } else { ERROR("Failed to read string '%s'\n", @@ -910,14 +910,14 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) rv = 1; } - free(subst_name); + cffree(subst_name); close_hdf5(fh); return rv; } else { /* Should never be reached */ ERROR("Invalid HDF5 class %i\n", class); - free(subst_name); + cffree(subst_name); return 1; } } @@ -926,16 +926,16 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( dim_vals == NULL ) { ERROR("Couldn't parse event '%s'\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } - f_offset = malloc(ndims*sizeof(hsize_t)); - f_count = malloc(ndims*sizeof(hsize_t)); + f_offset = cfmalloc(ndims*sizeof(hsize_t)); + f_count = cfmalloc(ndims*sizeof(hsize_t)); if ( (f_offset == NULL) || (f_count == NULL) ) { ERROR("Couldn't allocate dimension arrays\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } @@ -953,8 +953,8 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) subst_name, i, dim_vals[dim_val_pos], size[i]); close_hdf5(fh); - free(subst_name); - free(dim_vals); + cffree(subst_name); + cffree(dim_vals); return 1; } @@ -970,21 +970,21 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) } } - free(dim_vals); + cffree(dim_vals); check = H5Sselect_hyperslab(sh, H5S_SELECT_SET, f_offset, NULL, f_count, NULL); if ( check < 0 ) { ERROR("Error selecting dataspace for header value\n"); - free(f_offset); - free(f_count); - free(subst_name); + cffree(f_offset); + cffree(f_count); + cffree(subst_name); close_hdf5(fh); return 1; } - free(f_offset); - free(f_count); + cffree(f_offset); + cffree(f_count); ms = H5Screate_simple(1,msdims,NULL); check = H5Sselect_hyperslab(ms, H5S_SELECT_SET, @@ -992,7 +992,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( check < 0 ) { ERROR("Error selecting memory dataspace for header value\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } @@ -1003,13 +1003,13 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( r < 0 ) { ERROR("Couldn't read value.\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } image_cache_header_float(image, name, val); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 0; } else if ( class == H5T_INTEGER ) { @@ -1019,13 +1019,13 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( r < 0 ) { ERROR("Couldn't read value.\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } image_cache_header_int(image, name, val); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 0; } else if ( class == H5T_STRING ) { @@ -1044,16 +1044,16 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( rv < 0 ) { ERROR("Can't read HDF5 vlen string from array - %s\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return 1; } else { chomp(val); image_cache_header_str(image, name, val); - free(val); + cffree(val); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 0; } @@ -1066,10 +1066,10 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) size_t ssize; ssize = H5Tget_size(stype); - val = malloc(ssize+1); + val = cfmalloc(ssize+1); if ( val == NULL ) { close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } rv = H5Dread(dh, stype, ms, sh, H5P_DEFAULT, val); @@ -1078,16 +1078,16 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) ERROR("Couldn't read HDF5 fixed string from array - %s\n", subst_name); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } else { val[ssize] = '\0'; chomp(val); image_cache_header_str(image, name, val); - free(val); + cffree(val); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 0; } @@ -1098,7 +1098,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) /* Should never be reached */ ERROR("Invalid HDF5 class %i\n", class); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } } @@ -1279,7 +1279,7 @@ static float *read_peak_line(hid_t fh, char *path, int line, return NULL; } - buf = malloc(size[1]*sizeof(float)); + buf = cfmalloc(size[1]*sizeof(float)); if ( buf == NULL ) return NULL; r = H5Dread(dh, H5T_NATIVE_FLOAT, mh, sh, H5P_DEFAULT, buf); if ( r < 0 ) { @@ -1336,19 +1336,19 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl, dim_vals = read_dim_parts(event, &n_dim_vals); if ( dim_vals == NULL ) { ERROR("Couldn't parse event '%s'\n"); - free(subst_name); + cffree(subst_name); return NULL; } if ( n_dim_vals < 1 ) { ERROR("Not enough dimensions in event ID to use CXI " "peak lists (%i)\n", n_dim_vals); - free(subst_name); + cffree(subst_name); return NULL; } line = dim_vals[0]; - free(dim_vals); + cffree(dim_vals); snprintf(path_n, 1024, "%s/nPeaks", subst_name); snprintf(path_x, 1024, "%s/peakXPosRaw", subst_name); @@ -1358,37 +1358,37 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl, fh = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT); if ( fh < 0 ) { ERROR("Couldn't open file (peaks/cxi): %s\n", filename); - free(subst_name); + cffree(subst_name); return NULL; } r = read_peak_count(fh, path_n, line, &num_peaks); if ( r != 0 ) { close_hdf5(fh); - free(subst_name); + cffree(subst_name); return NULL; } buf_x = read_peak_line(fh, path_x, line, num_peaks); if ( buf_x == NULL ) { close_hdf5(fh); - free(subst_name); + cffree(subst_name); return NULL; } buf_y = read_peak_line(fh, path_y, line, num_peaks); if ( buf_y == NULL ) { - free(buf_x); - free(subst_name); + cffree(buf_x); + cffree(subst_name); close_hdf5(fh); return NULL; } buf_i = read_peak_line(fh, path_i, line, num_peaks); if ( buf_i == NULL ) { - free(buf_x); - free(buf_y); - free(subst_name); + cffree(buf_x); + cffree(buf_y); + cffree(subst_name); close_hdf5(fh); return NULL; } @@ -1415,10 +1415,10 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl, } - free(buf_x); - free(buf_y); - free(buf_i); - free(subst_name); + cffree(buf_x); + cffree(buf_y); + cffree(buf_i); + cffree(subst_name); close_hdf5(fh); @@ -1470,11 +1470,11 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl, dh = H5Dopen2(fh, subst_name, H5P_DEFAULT); if ( dh < 0 ) { ERROR("Peak list (%s) not found.\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return NULL; } - free(subst_name); + cffree(subst_name); sh = H5Dget_space(dh); if ( sh < 0 ) { @@ -1500,7 +1500,7 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl, return NULL; } - buf = malloc(sizeof(float)*size[0]*size[1]); + buf = cfmalloc(sizeof(float)*size[0]*size[1]); if ( buf == NULL ) { ERROR("Couldn't reserve memory for the peak list.\n"); close_hdf5(fh); @@ -1541,7 +1541,7 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl, } - free(buf); + cffree(buf); close_hdf5(fh); return features; @@ -1555,7 +1555,7 @@ static char *matches_pattern(const char *name, const char *pattern, const char *ev_str_old) { if ( strcmp(pattern, "%") == 0 ) { - char *nstr = malloc(strlen(ev_str_old)+strlen(name)+2); + char *nstr = cfmalloc(strlen(ev_str_old)+strlen(name)+2); if ( nstr == NULL ) { ERROR("Couldn't allocate memory\n"); return NULL; @@ -1566,7 +1566,7 @@ static char *matches_pattern(const char *name, const char *pattern, return nstr; } else { if ( strcmp(name, pattern) == 0 ) { - return strdup(ev_str_old); + return cfstrdup(ev_str_old); } else { return NULL; } @@ -1586,14 +1586,14 @@ struct ev_list static int add_ev_to_list(struct ev_list *list, char *ev_str) { if ( list->n_events == list->max_events ) { - char **new_events = realloc(list->events, - (list->max_events+128)*sizeof(char *)); + char **new_events = cfrealloc(list->events, + (list->max_events+128)*sizeof(char *)); if ( new_events == NULL ) return 1; list->max_events += 128; list->events = new_events; } - list->events[list->n_events++] = strdup(ev_str); + list->events[list->n_events++] = cfstrdup(ev_str); return 0; } @@ -1604,9 +1604,9 @@ static char *demunge_event(const char *orig) size_t len = strlen(orig); char *slash; - if ( len == 0 ) return strdup("//"); + if ( len == 0 ) return cfstrdup("//"); - slash = malloc(len+3); + slash = cfmalloc(len+3); if ( slash == NULL ) return NULL; strcpy(slash, orig+1); strcat(slash, "//"); @@ -1641,7 +1641,7 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, return 1; } - name = malloc(size+1); + name = cfmalloc(size+1); if ( name == NULL ) { ERROR("Couldn't allocate memory\n"); return 1; @@ -1658,7 +1658,7 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, ev_str_new = matches_pattern(name, pattern_bits[0], ev_str); if ( ev_str_new == NULL ) { - free(name); + cffree(name); continue; } @@ -1666,8 +1666,8 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, H5_ITER_INC, i, &obj_info, 0) < 0 ) { ERROR("Couldn't get info\n"); - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } @@ -1678,16 +1678,16 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, if ( n_pattern_bits == 1 ) { ERROR("Pattern doesn't match file" " (too short)\n"); - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } child_gh = H5Gopen1(gh, name); if ( child_gh < 0 ) { ERROR("Couldn't open '%s'\n", name); - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } @@ -1696,12 +1696,12 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, &pattern_bits[1], n_pattern_bits - 1) ) { - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } - free(ev_str_new); + cffree(ev_str_new); H5Gclose(child_gh); } else if ( obj_info.type == H5O_TYPE_DATASET ) { @@ -1712,21 +1712,21 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, ERROR("Pattern doesn't match file" " (too long by %i)\n", n_pattern_bits); - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } addme = demunge_event(ev_str_new); if ( addme != NULL ) { add_ev_to_list(list, addme); - free(addme); + cffree(addme); } - free(ev_str_new); + cffree(ev_str_new); } - free(name); + cffree(name); } @@ -1755,7 +1755,7 @@ char **expand_paths(hid_t fh, char *pattern, int *n_evs) if ( pattern[i] == '/' ) n_sep++; } - pattern_bits = malloc(n_sep*sizeof(char *)); + pattern_bits = cfmalloc(n_sep*sizeof(char *)); if ( pattern_bits == NULL ) return NULL; start = pattern+1; @@ -1764,7 +1764,7 @@ char **expand_paths(hid_t fh, char *pattern, int *n_evs) if ( sep == NULL ) { sep = start+strlen(start); } - pattern_bits[i] = strndup(start, sep-start); + pattern_bits[i] = cfstrndup(start, sep-start); if ( pattern_bits[i] == NULL ) return NULL; start = sep+1; } @@ -1776,9 +1776,9 @@ char **expand_paths(hid_t fh, char *pattern, int *n_evs) rec_expand_paths(fh, &list, "", pattern_bits, n_sep); for ( i=0; i 16*1024 ) return NULL; - str = malloc(len+1); + str = cfmalloc(len+1); if ( str == NULL ) return NULL; strncpy(str, ptr, len); str[len] = '\0'; @@ -301,7 +301,7 @@ int image_msgpack_read_header_to_cache(struct image *image, } image_cache_header_str(image, name, str); - free(str); + cffree(str); msgpack_unpacked_destroy(&unpacked); return 0; @@ -356,23 +356,23 @@ static int load_msgpack_data(struct panel_template *p, ERROR("Data 'type' isn't a string\n"); return 1; } - dtype = strndup(type_obj->via.str.ptr, type_obj->via.str.size); + dtype = cfstrndup(type_obj->via.str.ptr, type_obj->via.str.size); shape_obj = find_msgpack_kv(obj, "shape"); if ( shape_obj == NULL ) { ERROR("Data 'shape' not found\n"); - free(dtype); + cffree(dtype); return 1; } if ( shape_obj->type != MSGPACK_OBJECT_ARRAY ) { ERROR("Data 'shape' isn't an array\n"); - free(dtype); + cffree(dtype); return 1; } if ( shape_obj->via.array.size != 2 ) { ERROR("Data 'shape' has wrong number of dimensions (%i)\n", shape_obj->via.array.size); - free(dtype); + cffree(dtype); return 1; } data_size_ss = shape_obj->via.array.ptr[0].via.u64; @@ -393,12 +393,12 @@ static int load_msgpack_data(struct panel_template *p, data_obj = find_msgpack_kv(obj, "data"); if ( data_obj == NULL ) { ERROR("Data 'data' not found\n"); - free(dtype); + cffree(dtype); return 1; } if ( data_obj->type != MSGPACK_OBJECT_BIN ) { ERROR("Data 'data' isn't binary\n"); - free(dtype); + cffree(dtype); return 1; } @@ -434,7 +434,7 @@ static int load_msgpack_data(struct panel_template *p, ERROR("Unrecognised data type '%s'\n", dtype); } - free(dtype); + cffree(dtype); return 0; } diff --git a/libcrystfel/src/image-seedee.c b/libcrystfel/src/image-seedee.c index 2a4328ec..1b68aead 100644 --- a/libcrystfel/src/image-seedee.c +++ b/libcrystfel/src/image-seedee.c @@ -170,20 +170,20 @@ int image_seedee_read(struct image *image, data_block, data_block_size, &zero_copy, &array); profile_end("seedee-get-size"); - array.data = malloc(array.size); - array.shape = malloc(array.ndims*sizeof(int)); + array.data = cfmalloc(array.size); + array.shape = cfmalloc(array.ndims*sizeof(int)); if ( (array.data == NULL) || (array.shape == NULL) ) { cJSON_Delete(json); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 1; } if ( array.ndims != 2 ) { ERROR("Seedee data has unexpected number of dimensions " "(%i, expected 2)\n", array.ndims); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 1; } @@ -195,8 +195,8 @@ int image_seedee_read(struct image *image, cJSON_Delete(json); if ( r < 0 ) { ERROR("Seedee deserialiation failed.\n"); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 1; } @@ -208,15 +208,15 @@ int image_seedee_read(struct image *image, ERROR("Failed to load data for panel '%s'\n", dtempl->panels[i].name); profile_end("seedee-panel"); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 1; } } profile_end("seedee-panel"); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 0; } diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 53ae796d..0789c6a3 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -158,7 +158,7 @@ void image_add_feature(ImageFeatureList *flist, double fs, double ss, if ( flist->n_features == flist->max_features ) { struct imagefeature *nf; int nmf = flist->max_features + 128; - nf = realloc(flist->features, nmf*sizeof(struct imagefeature)); + nf = cfrealloc(flist->features, nmf*sizeof(struct imagefeature)); if ( nf == NULL ) return; flist->features = nf; flist->max_features = nmf; @@ -178,7 +178,7 @@ ImageFeatureList *image_feature_list_new() { ImageFeatureList *flist; - flist = malloc(sizeof(ImageFeatureList)); + flist = cfmalloc(sizeof(ImageFeatureList)); flist->n_features = 0; flist->max_features = 0; @@ -207,9 +207,9 @@ ImageFeatureList *image_feature_list_copy(const ImageFeatureList *flist) n = image_feature_list_new(); if ( n == NULL ) return NULL; - n->features = malloc(flist->n_features*sizeof(struct imagefeature)); + n->features = cfmalloc(flist->n_features*sizeof(struct imagefeature)); if ( n->features == NULL ) { - free(n); + cffree(n); return NULL; } @@ -241,8 +241,8 @@ ImageFeatureList *sort_peaks(ImageFeatureList *flist) void image_feature_list_free(ImageFeatureList *flist) { if ( flist == NULL ) return; - free(flist->features); - free(flist); + cffree(flist->features); + cffree(flist); } @@ -323,7 +323,7 @@ void image_add_crystal(struct image *image, Crystal *cryst) int n; n = image->n_crystals; - crs = realloc(image->crystals, (n+1)*sizeof(Crystal *)); + crs = cfrealloc(image->crystals, (n+1)*sizeof(Crystal *)); if ( crs == NULL ) { ERROR("Failed to allocate memory for crystals.\n"); return; @@ -370,7 +370,7 @@ void free_all_crystals(struct image *image) cell_free(crystal_get_cell(cr)); crystal_free(image->crystals[i]); } - free(image->crystals); + cffree(image->crystals); image->n_crystals = 0; } @@ -397,10 +397,10 @@ void image_cache_header_int(struct image *image, } else { struct header_cache_entry *ce; - ce = malloc(sizeof(struct header_cache_entry)); + ce = cfmalloc(sizeof(struct header_cache_entry)); if ( ce != NULL ) { - ce->header_name = strdup(header_name); + ce->header_name = cfstrdup(header_name); ce->val_int = header_val; ce->type = HEADER_INT; image->header_cache[image->n_cached_headers++] = ce; @@ -420,10 +420,10 @@ void image_cache_header_float(struct image *image, } else { struct header_cache_entry *ce; - ce = malloc(sizeof(struct header_cache_entry)); + ce = cfmalloc(sizeof(struct header_cache_entry)); if ( ce != NULL ) { - ce->header_name = strdup(header_name); + ce->header_name = cfstrdup(header_name); ce->val_float = header_val; ce->type = HEADER_FLOAT; image->header_cache[image->n_cached_headers++] = ce; @@ -448,11 +448,11 @@ void image_cache_header_str(struct image *image, } else { struct header_cache_entry *ce; - ce = malloc(sizeof(struct header_cache_entry)); + ce = cfmalloc(sizeof(struct header_cache_entry)); if ( ce != NULL ) { - ce->header_name = strdup(header_name); - ce->val_str = strdup(header_val); + ce->header_name = cfstrdup(header_name); + ce->val_str = cfstrdup(header_val); ce->type = HEADER_STR; image->header_cache[image->n_cached_headers++] = ce; } else { @@ -612,7 +612,7 @@ struct _image_data_arrays ImageDataArrays *image_data_arrays_new() { - ImageDataArrays *ida = malloc(sizeof(struct _image_data_arrays)); + ImageDataArrays *ida = cfmalloc(sizeof(struct _image_data_arrays)); if ( ida == NULL ) return NULL; ida->dp = NULL; @@ -628,14 +628,14 @@ void image_data_arrays_free(ImageDataArrays *ida) int i; for ( i=0; inp; i++ ) { - if ( ida->dp != NULL ) free(ida->dp[i]); - if ( ida->bad != NULL ) free(ida->bad[i]); + if ( ida->dp != NULL ) cffree(ida->dp[i]); + if ( ida->bad != NULL ) cffree(ida->bad[i]); } - free(ida->dp); - free(ida->bad); + cffree(ida->dp); + cffree(ida->bad); - free(ida); + cffree(ida); } @@ -656,16 +656,16 @@ int image_create_dp_bad(struct image *image, /* Allocate new arrays */ - image->dp = malloc(dtempl->n_panels*sizeof(float *)); + image->dp = cfmalloc(dtempl->n_panels*sizeof(float *)); if ( image->dp == NULL ) { ERROR("Failed to allocate data array.\n"); return 1; } - image->bad = malloc(dtempl->n_panels*sizeof(int *)); + image->bad = cfmalloc(dtempl->n_panels*sizeof(int *)); if ( image->bad == NULL ) { ERROR("Failed to allocate bad pixel mask\n"); - free(image->dp); + cffree(image->dp); return 1; } @@ -679,17 +679,17 @@ int image_create_dp_bad(struct image *image, size_t nel = PANEL_WIDTH(&dtempl->panels[i]) * PANEL_HEIGHT(&dtempl->panels[i]); - image->dp[i] = malloc(nel*sizeof(float)); - image->bad[i] = malloc(nel*sizeof(int)); + image->dp[i] = cfmalloc(nel*sizeof(float)); + image->bad[i] = cfmalloc(nel*sizeof(int)); if ( (image->dp[i] == NULL)|| (image->bad[i] == NULL) ) { ERROR("Failed to allocate panel data arrays\n"); for ( i=0; in_panels; i++ ) { - free(image->dp[i]); - free(image->bad[i]); + cffree(image->dp[i]); + cffree(image->bad[i]); } - free(image->dp); - free(image->bad); + cffree(image->dp); + cffree(image->bad); return 1; } @@ -1115,7 +1115,7 @@ static int create_satmap(struct image *image, if ( !any ) return 0; - image->sat = malloc(dtempl->n_panels * sizeof(float *)); + image->sat = cfmalloc(dtempl->n_panels * sizeof(float *)); if ( image->sat == NULL ) { ERROR("Failed to allocate saturation map\n"); return 1; @@ -1136,7 +1136,7 @@ static int create_satmap(struct image *image, p_w = p->orig_max_fs - p->orig_min_fs + 1; p_h = p->orig_max_ss - p->orig_min_ss + 1; - image->sat[i] = malloc(p_w*p_h*sizeof(float)); + image->sat[i] = cfmalloc(p_w*p_h*sizeof(float)); if ( image->sat[i] != NULL ) { long int j; @@ -1319,11 +1319,11 @@ struct image *image_read(const DataTemplate *dtempl, return NULL; } - image->filename = strdup(filename); + image->filename = cfstrdup(filename); if ( event != NULL ) { - image->ev = strdup(event); + image->ev = cfstrdup(event); } else { - image->ev = strdup("//"); /* Null event */ + image->ev = cfstrdup("//"); /* Null event */ } image->data_block = NULL; image->data_block_size = 0; @@ -1390,10 +1390,10 @@ void image_free(struct image *image) image_feature_list_free(image->features); free_all_crystals(image); spectrum_free(image->spectrum); - free(image->filename); - free(image->ev); - free(image->data_block); - free(image->meta_data); + cffree(image->filename); + cffree(image->ev); + cffree(image->data_block); + cffree(image->meta_data); if ( image->detgeom != NULL ) { np = image->detgeom->n_panels; @@ -1405,23 +1405,23 @@ void image_free(struct image *image) if ( image->ida == NULL ) { for ( i=0; idp != NULL ) free(image->dp[i]); - if ( image->sat != NULL ) free(image->sat[i]); - if ( image->bad != NULL ) free(image->bad[i]); + if ( image->dp != NULL ) cffree(image->dp[i]); + if ( image->sat != NULL ) cffree(image->sat[i]); + if ( image->bad != NULL ) cffree(image->bad[i]); } - free(image->dp); - free(image->sat); - free(image->bad); + cffree(image->dp); + cffree(image->sat); + cffree(image->bad); } /* else the arrays belong to the IDA structure */ for ( i=0; in_cached_headers; i++ ) { - free(image->header_cache[i]->header_name); - free(image->header_cache[i]); + cffree(image->header_cache[i]->header_name); + cffree(image->header_cache[i]); } - free(image); + cffree(image); } @@ -1429,7 +1429,7 @@ struct image *image_new() { struct image *image; - image = malloc(sizeof(struct image)); + image = cfmalloc(sizeof(struct image)); if ( image == NULL ) return NULL; image->dp = NULL; @@ -1536,11 +1536,11 @@ char **image_expand_frames(const DataTemplate *dtempl, } else { char **list; - list = malloc(sizeof(char *)); + list = cfmalloc(sizeof(char *)); if ( list == NULL ) return NULL; - list[0] = strdup("//"); + list[0] = cfstrdup("//"); if ( list[0] == NULL ) { - free(list); + cffree(list); return NULL; } *n_frames = 1; diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index db2058a5..4c35d2ca 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -121,7 +121,7 @@ char *base_indexer_str(IndexingMethod indm) { char *str; - str = malloc(256); + str = cfmalloc(256); if ( str == NULL ) { ERROR("Failed to allocate string.\n"); return NULL; @@ -270,11 +270,11 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, if ( priv == NULL ) { ERROR("Failed to prepare indexing method %s\n", str); - free(str); + cffree(str); return NULL; } - free(str); + cffree(str); if ( in != *m ) { ERROR("Note: flags were altered to take into account " @@ -296,7 +296,7 @@ IndexingMethod *parse_indexing_methods(const char *method_list, n = assplode(method_list, ",", &method_strings, ASSPLODE_NONE); - methods = malloc(n * sizeof(IndexingMethod)); + methods = cfmalloc(n * sizeof(IndexingMethod)); if ( methods == NULL ) { ERROR("Failed to allocate indexing method list\n"); return NULL; @@ -316,12 +316,12 @@ IndexingMethod *parse_indexing_methods(const char *method_list, ERROR("To disable indexing retry ('noretry'), use --no-retry.\n"); ERROR("To enable multi-lattice indexing by 'delete and retry', use --multi\n"); ERROR("------------------\n"); - free(methods); + cffree(methods); return NULL; } - free(method_strings[i]); + cffree(method_strings[i]); } - free(method_strings); + cffree(method_strings); *pn = n; return methods; @@ -393,13 +393,13 @@ IndexingPrivate *setup_indexing(const char *method_list, } - ipriv = malloc(sizeof(struct _indexingprivate)); + ipriv = cfmalloc(sizeof(struct _indexingprivate)); if ( ipriv == NULL ) { ERROR("Failed to allocate indexing data\n"); return NULL; } - ipriv->engine_private = malloc((n+1) * sizeof(void *)); + ipriv->engine_private = cfmalloc((n+1) * sizeof(void *)); for ( i=0; iengine_private[i] == NULL ) { - free(ipriv->engine_private); + cffree(ipriv->engine_private); return NULL; } for ( j=0; jengine_private); + cffree(ipriv->engine_private); return NULL; } } @@ -449,8 +449,8 @@ IndexingPrivate *setup_indexing(const char *method_list, char *str = indexer_str(methods[i]); char *tmp = friendly_indexer_name(methods[i]); STATUS(" %2i: %-25s (%s)\n", i, str, tmp); - free(str); - free(tmp); + cffree(str); + cffree(tmp); } show_indexing_flags(flags); @@ -523,10 +523,10 @@ void cleanup_indexing(IndexingPrivate *ipriv) } - free(ipriv->methods); - free(ipriv->engine_private); + cffree(ipriv->methods); + cffree(ipriv->engine_private); cell_free(ipriv->target_cell); - free(ipriv); + cffree(ipriv); } @@ -1194,10 +1194,10 @@ IndexingMethod get_indm_from_string_2(const char *str, int *err) return INDEXING_ERROR; } - free(bits[i]); + cffree(bits[i]); } - free(bits); + cffree(bits); if ( !have_method ) return warn_method(str); @@ -1229,7 +1229,7 @@ char *detect_indexing_methods(UnitCell *cell) { char *methods; - methods = malloc(1024); + methods = cfmalloc(1024); if ( methods == NULL ) return NULL; methods[0] = '\0'; @@ -1244,7 +1244,7 @@ char *detect_indexing_methods(UnitCell *cell) //do_probe(pinkIndexer_probe, cell, methods); if ( strlen(methods) == 0 ) { - free(methods); + cffree(methods); return NULL; } diff --git a/libcrystfel/src/indexers/asdf.c b/libcrystfel/src/indexers/asdf.c index 2222144b..919e570f 100644 --- a/libcrystfel/src/indexers/asdf.c +++ b/libcrystfel/src/indexers/asdf.c @@ -132,7 +132,7 @@ struct tvector tvector_new(int n) t.t = gsl_vector_alloc(3); t.n = 0; - t.fits = malloc(sizeof(int) * n); + t.fits = cfmalloc(sizeof(int) * n); return t; } @@ -141,7 +141,7 @@ struct tvector tvector_new(int n) static int tvector_free(struct tvector t) { gsl_vector_free(t.t); - free(t.fits); + cffree(t.fits); return 1; } @@ -155,12 +155,12 @@ static int asdf_cell_free(struct asdf_cell *c) gsl_vector_free(c->reciprocal[i]); } - free(c->reflections); + cffree(c->reflections); for ( i = 0; i < c->N_refls; i++ ) { - free(c->indices[i]); + cffree(c->indices[i]); } - free(c->indices); - free(c); + cffree(c->indices); + cffree(c); return 1; } @@ -169,7 +169,7 @@ static int asdf_cell_free(struct asdf_cell *c) static struct asdf_cell *asdf_cell_new(int n) { struct asdf_cell *c; - c = malloc(sizeof(struct asdf_cell)); + c = cfmalloc(sizeof(struct asdf_cell)); int i; for ( i = 0; i < 3; i++ ) { @@ -178,20 +178,20 @@ static struct asdf_cell *asdf_cell_new(int n) } c->N_refls = n; - c->reflections = malloc(sizeof(int) * n); + c->reflections = cfmalloc(sizeof(int) * n); if (c->reflections == NULL) return NULL; - c->indices = malloc(sizeof(double *) * n); + c->indices = cfmalloc(sizeof(double *) * n); if (c->indices == NULL) { - free(c->reflections); + cffree(c->reflections); return NULL; } for ( i = 0; i < n; i++ ) { - c->indices[i] = malloc(sizeof(double) * 3); + c->indices[i] = cfmalloc(sizeof(double) * 3); if (c->indices[i] == NULL) { - free(c->reflections); - free(c->indices); + cffree(c->reflections); + cffree(c->indices); return NULL; } } @@ -224,7 +224,7 @@ static int asdf_cell_memcpy(struct asdf_cell *dest, struct asdf_cell *src) memcpy(dest->indices[i], src->indices[i], sizeof(double) * 3); } for ( i=n; iN_refls; i++ ) { - free(dest->indices[i]); + cffree(dest->indices[i]); } dest->N_refls = n; @@ -928,7 +928,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) } *N = N_triplets; - int **triplets = malloc(N_triplets * sizeof(int *)); + int **triplets = cfmalloc(N_triplets * sizeof(int *)); if ( triplets == NULL ) { ERROR("Failed to allocate triplets in generate_triplets!\n"); @@ -940,7 +940,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) // Reservoir sampling: for ( i = 0; i < N_triplets_tot; i++ ) { if ( n < N_triplets ) { - triplets[n] = (int *)malloc(3 * sizeof(int)); + triplets[n] = (int *)cfmalloc(3 * sizeof(int)); if (triplets[n] == NULL) { ERROR("Failed to allocate triplet in generate_triplets!\n"); return NULL; @@ -957,10 +957,10 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) } } else { // Random selection from the whole set: - int *tidx = (int *)malloc(N_triplets * sizeof(int)); + int *tidx = (int *)cfmalloc(N_triplets * sizeof(int)); if ( tidx == NULL ) { ERROR("Failed to allocate tidx in generate_triplets_2!\n"); - free(triplets); + cffree(triplets); return NULL; } while ( n < N_triplets ) { @@ -973,7 +973,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) } } tidx[n] = ri; - triplets[n] = (int *)malloc(3 * sizeof(int)); + triplets[n] = (int *)cfmalloc(3 * sizeof(int)); if ( triplets[n] == NULL ) { ERROR("Failed to allocate triplet in generate_triplets!\n"); return NULL; @@ -981,7 +981,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) get_triplet_by_index(ri, N_reflections, triplets[n]); n += 1; } - free(tidx); + cffree(tidx); } return triplets; } @@ -1002,7 +1002,7 @@ static int index_refls(gsl_vector **reflections, int N_reflections, int N_refl_m gsl_vector **refl_sample; if ( N_reflections > N_refl_max ) { - refl_sample = (gsl_vector **)malloc(N_refl_max * sizeof(gsl_vector *)); + refl_sample = (gsl_vector **)cfmalloc(N_refl_max * sizeof(gsl_vector *)); n = 0; for ( i = 0; i < N_reflections; i++ ) { if (i < N_refl_max) { @@ -1029,18 +1029,18 @@ static int index_refls(gsl_vector **reflections, int N_reflections, int N_refl_m double projections[N_refl_max]; double ds; - int *fits = malloc(N_refl_max * sizeof(int)); + int *fits = cfmalloc(N_refl_max * sizeof(int)); if ( fits == NULL ) { ERROR("Failed to allocate fits in index_refls!\n"); - if ( N_reflections > N_refl_max ) free(refl_sample); + if ( N_reflections > N_refl_max ) cffree(refl_sample); return 0; } - struct tvector *tvectors = malloc(N_triplets * sizeof(struct tvector)); + struct tvector *tvectors = cfmalloc(N_triplets * sizeof(struct tvector)); if ( tvectors == NULL ) { ERROR("Failed to allocate tvectors in index_refls!\n"); - if ( N_reflections > N_refl_max ) free(refl_sample); - free(fits); + if ( N_reflections > N_refl_max ) cffree(refl_sample); + cffree(fits); return 0; } @@ -1113,20 +1113,20 @@ static int index_refls(gsl_vector **reflections, int N_reflections, int N_refl_m } } profile_end("asdf-search"); - free(fits); + cffree(fits); for ( i = 0; i < N_tvectors; i++ ) { tvector_free(tvectors[i]); } - free(tvectors); + cffree(tvectors); for ( i = 0; i < N_triplets; i++ ) { - free(triplets[i]); + cffree(triplets[i]); } - free(triplets); + cffree(triplets); gsl_vector_free(normal); - if ( N_reflections > N_refl_max ) free(refl_sample); + if ( N_reflections > N_refl_max ) cffree(refl_sample); if ( c->n ) return 1; @@ -1262,7 +1262,7 @@ void *asdf_prepare(IndexingMethod *indm, UnitCell *cell, struct asdf_options *as /* Flags that asdf knows about */ *indm &= INDEXING_METHOD_MASK | INDEXING_USE_CELL_PARAMETERS; - dp = malloc(sizeof(struct asdf_private)); + dp = cfmalloc(sizeof(struct asdf_private)); if ( dp == NULL ) return NULL; dp->template = cell; @@ -1279,7 +1279,7 @@ void asdf_cleanup(void *pp) struct asdf_private *p; p = (struct asdf_private *)pp; fftw_vars_free(p->fftw); - free(p); + cffree(p); } @@ -1332,7 +1332,7 @@ int asdf_default_options(struct asdf_options **opts_ptr) { struct asdf_options *opts; - opts = malloc(sizeof(struct asdf_options)); + opts = cfmalloc(sizeof(struct asdf_options)); if ( opts == NULL ) return ENOMEM; opts->fast_execution = 0; diff --git a/libcrystfel/src/indexers/dirax.c b/libcrystfel/src/indexers/dirax.c index 9c427879..88384e11 100644 --- a/libcrystfel/src/indexers/dirax.c +++ b/libcrystfel/src/indexers/dirax.c @@ -118,13 +118,13 @@ static void dirax_parseline(const char *line, struct image *image, #if DIRAX_VERBOSE char *copy; - copy = strdup(line); + copy = cfstrdup(line); for ( i=0; ipty, line, strlen(line)) == -1 ) { @@ -399,7 +399,7 @@ static int dirax_readable(struct image *image, struct dirax_data *dirax) case DIRAX_INPUT_LINE : /* Make buffer a bit too big to keep Valgrind * quiet about alignment errors */ - block_buffer = malloc(i+4); + block_buffer = cfmalloc(i+4); memcpy(block_buffer, dirax->rbuffer, i); block_buffer[i] = '\0'; @@ -408,7 +408,7 @@ static int dirax_readable(struct image *image, struct dirax_data *dirax) } dirax_parseline(block_buffer, image, dirax); - free(block_buffer); + cffree(block_buffer); endbit_length = i+2; break; @@ -441,8 +441,7 @@ static int dirax_readable(struct image *image, struct dirax_data *dirax) - endbit_length; new_rbuflen = dirax->rbuflen - endbit_length; if ( new_rbuflen == 0 ) new_rbuflen = 256; - dirax->rbuffer = realloc(dirax->rbuffer, - new_rbuflen); + dirax->rbuffer = cfrealloc(dirax->rbuffer, new_rbuflen); dirax->rbuflen = new_rbuflen; } else { @@ -450,8 +449,8 @@ static int dirax_readable(struct image *image, struct dirax_data *dirax) if ( dirax->rbufpos == dirax->rbuflen ) { /* More buffer space is needed */ - dirax->rbuffer = realloc(dirax->rbuffer, - dirax->rbuflen + 256); + dirax->rbuffer = cfrealloc(dirax->rbuffer, + dirax->rbuflen + 256); dirax->rbuflen = dirax->rbuflen + 256; /* The new space gets used at the next * read, shortly... */ @@ -511,7 +510,7 @@ int run_dirax(struct image *image, void *ipriv) write_drx(image); - dirax = malloc(sizeof(struct dirax_data)); + dirax = cfmalloc(sizeof(struct dirax_data)); if ( dirax == NULL ) { ERROR("Couldn't allocate memory for DirAx data.\n"); return 0; @@ -538,7 +537,7 @@ int run_dirax(struct image *image, void *ipriv) } - dirax->rbuffer = malloc(256); + dirax->rbuffer = cfmalloc(256); dirax->rbuflen = 256; dirax->rbufpos = 0; @@ -595,7 +594,7 @@ int run_dirax(struct image *image, void *ipriv) } while ( !rval && !dirax->success ); close(dirax->pty); - free(dirax->rbuffer); + cffree(dirax->rbuffer); waitpid(dirax->pid, &status, 0); if ( dirax->finished_ok == 0 ) { @@ -603,7 +602,7 @@ int run_dirax(struct image *image, void *ipriv) } rval = dirax->success; - free(dirax); + cffree(dirax); return rval; } @@ -621,7 +620,7 @@ void *dirax_prepare(IndexingMethod *indm, UnitCell *cell) /* Flags that DirAx knows about */ *indm &= INDEXING_METHOD_MASK; - dp = malloc(sizeof(struct dirax_private)); + dp = cfmalloc(sizeof(struct dirax_private)); if ( dp == NULL ) return NULL; dp->template = cell; @@ -635,7 +634,7 @@ void dirax_cleanup(void *pp) { struct dirax_private *p; p = (struct dirax_private *)pp; - free(p); + cffree(p); } diff --git a/libcrystfel/src/indexers/felix.c b/libcrystfel/src/indexers/felix.c index db7da8c4..d6632e42 100644 --- a/libcrystfel/src/indexers/felix.c +++ b/libcrystfel/src/indexers/felix.c @@ -277,7 +277,7 @@ static int felix_readable(struct image *image, struct felix_data *gs) unsigned int endbit_length; char *block_buffer = NULL; - block_buffer = malloc(i+1); + block_buffer = cfmalloc(i+1); memcpy(block_buffer, gs->rbuffer, i); block_buffer[i] = '\0'; @@ -286,7 +286,7 @@ static int felix_readable(struct image *image, struct felix_data *gs) } gs_parseline(block_buffer, image, gs); - free(block_buffer); + cffree(block_buffer); endbit_length = i+2; /* Now the block's been parsed, it should be @@ -299,7 +299,7 @@ static int felix_readable(struct image *image, struct felix_data *gs) gs->rbufpos = gs->rbufpos - endbit_length; new_rbuflen = gs->rbuflen - endbit_length; if ( new_rbuflen == 0 ) new_rbuflen = 256; - gs->rbuffer = realloc(gs->rbuffer, new_rbuflen); + gs->rbuffer = cfrealloc(gs->rbuffer, new_rbuflen); gs->rbuflen = new_rbuflen; } else { @@ -307,8 +307,8 @@ static int felix_readable(struct image *image, struct felix_data *gs) if ( gs->rbufpos == gs->rbuflen ) { /* More buffer space is needed */ - gs->rbuffer = realloc(gs->rbuffer, - gs->rbuflen + 256); + gs->rbuffer = cfrealloc(gs->rbuffer, + gs->rbuflen + 256); gs->rbuflen = gs->rbuflen + 256; /* The new space gets used at the next * read, shortly... */ @@ -374,7 +374,7 @@ static char *write_ini(struct image *image, struct felix_private *gp) char gveFilename[1024]; char logFilename[1024]; - filename = malloc(1024); + filename = cfmalloc(1024); if ( filename == NULL ) return NULL; snprintf(filename, 1023, "xfel.ini"); @@ -384,7 +384,7 @@ static char *write_ini(struct image *image, struct felix_private *gp) fh = fopen(filename, "w"); if ( !fh ) { ERROR("Couldn't open temporary file '%s'\n", filename); - free(filename); + cffree(filename); return NULL; } @@ -413,7 +413,7 @@ static char *write_ini(struct image *image, struct felix_private *gp) fprintf(fh, "orispace octa\n"); } else{ ERROR("No felix supported orispace specified.\n"); - free(filename); + cffree(filename); filename = NULL; } @@ -450,7 +450,7 @@ int felix_index(struct image *image, IndexingPrivate *ipriv) return 0; } - felix = malloc(sizeof(struct felix_data)); + felix = cfmalloc(sizeof(struct felix_data)); if ( felix == NULL ) { ERROR("Couldn't allocate memory for Felix data.\n"); return 0; @@ -483,9 +483,9 @@ int felix_index(struct image *image, IndexingPrivate *ipriv) } - free(ini_filename); + cffree(ini_filename); - felix->rbuffer = malloc(256); + felix->rbuffer = cfmalloc(256); felix->rbuflen = 256; felix->rbufpos = 0; @@ -534,18 +534,18 @@ int felix_index(struct image *image, IndexingPrivate *ipriv) } while ( !rval ); close(felix->pty); - free(felix->rbuffer); + cffree(felix->rbuffer); waitpid(felix->pid, &status, 0); if ( status != 0 ) { ERROR("Felix either timed out, or is not working properly.\n"); - free(felix); + cffree(felix); return 0; } rval = read_felix(gp, image, gff_filename); - free(felix); + cffree(felix); return rval; } @@ -625,7 +625,7 @@ void *felix_prepare(IndexingMethod *indm, UnitCell *cell, return NULL; } - gp = calloc(1, sizeof(*gp)); + gp = cfcalloc(1, sizeof(*gp)); if ( gp == NULL ) return NULL; /* Flags that Felix knows about */ @@ -640,7 +640,7 @@ void *felix_prepare(IndexingMethod *indm, UnitCell *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"); - free(gp); + cffree(gp); return NULL; } @@ -710,8 +710,8 @@ void felix_cleanup(IndexingPrivate *pp) struct felix_private *p; p = (struct felix_private *) pp; - free(p->readhkl_file); - free(p); + cffree(p->readhkl_file); + cffree(p); } @@ -812,7 +812,7 @@ int felix_default_options(struct felix_options **opts_ptr) { struct felix_options *opts; - opts = malloc(sizeof(struct felix_options)); + opts = cfmalloc(sizeof(struct felix_options)); if ( opts == NULL ) return ENOMEM; opts->ttmin = -1.0; diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index 1716dd66..c7f1d1ba 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -101,7 +101,7 @@ struct fromfile_entry *add_unique(struct fromfile_entry **phead, struct fromfile_entry *item; - item = malloc(sizeof(struct fromfile_entry)); + item = cfmalloc(sizeof(struct fromfile_entry)); if ( item == NULL ) return NULL; item->n_crystals = 0; @@ -197,12 +197,12 @@ void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) if ( opts->filename[0] == '/' ) { fh = fopen(opts->filename, "r"); } else { - char *prefixed_fn = malloc(4+strlen(opts->filename)); + char *prefixed_fn = cfmalloc(4+strlen(opts->filename)); if ( prefixed_fn == NULL ) return NULL; strcpy(prefixed_fn, "../"); strcat(prefixed_fn, opts->filename); fh = fopen(prefixed_fn, "r"); - free(prefixed_fn); + cffree(prefixed_fn); } if ( fh == NULL ) { @@ -210,7 +210,7 @@ void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) return NULL; } - dp = malloc(sizeof(struct fromfile_private)); + dp = cfmalloc(sizeof(struct fromfile_private)); if ( dp == NULL ) { fclose(fh); return NULL; @@ -305,8 +305,8 @@ void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) } - for ( i=0; ifilename = NULL; *opts_ptr = opts; @@ -402,7 +402,7 @@ static error_t fromfile_parse_arg(int key, char *arg, return EINVAL; case 2 : - (*opts_ptr)->filename = strdup(arg); + (*opts_ptr)->filename = cfstrdup(arg); break; default : diff --git a/libcrystfel/src/indexers/mosflm.c b/libcrystfel/src/indexers/mosflm.c index 1bd53119..1cec0a35 100644 --- a/libcrystfel/src/indexers/mosflm.c +++ b/libcrystfel/src/indexers/mosflm.c @@ -162,13 +162,13 @@ static void mosflm_parseline(const char *line, struct image *image, char *copy; int i; - copy = strdup(line); + copy = cfstrdup(line); for ( i=0; ipty, line, strlen(line)) == -1 ) { @@ -469,7 +469,7 @@ static char *mosflm_spacegroup_for_lattice(UnitCell *cell) } assert(g != NULL); - result = malloc(32); + result = cfmalloc(32); if ( result == NULL ) return NULL; snprintf(result, 31, "%c%s", centering, g); @@ -512,7 +512,7 @@ static void mosflm_send_next(struct image *image, struct mosflm_data *mosflm) symm = mosflm_spacegroup_for_lattice(mosflm->mp->template); snprintf(tmp, 255, "SYMM %s\n", symm); //STATUS("Asking MOSFLM for '%s'\n", symm); - free(symm); + cffree(symm); mosflm_sendline(tmp, mosflm); } else { @@ -629,7 +629,7 @@ static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) switch ( type ) { case MOSFLM_INPUT_LINE : - block_buffer = malloc(i+1); + block_buffer = cfmalloc(i+1); memcpy(block_buffer, mosflm->rbuffer, i); block_buffer[i] = '\0'; @@ -638,7 +638,7 @@ static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) } mosflm_parseline(block_buffer, image, mosflm); - free(block_buffer); + cffree(block_buffer); endbit_length = i+2; break; @@ -667,8 +667,8 @@ static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) - endbit_length; new_rbuflen = mosflm->rbuflen - endbit_length; if ( new_rbuflen == 0 ) new_rbuflen = 256; - mosflm->rbuffer = realloc(mosflm->rbuffer, - new_rbuflen); + mosflm->rbuffer = cfrealloc(mosflm->rbuffer, + new_rbuflen); mosflm->rbuflen = new_rbuflen; } else { @@ -676,9 +676,8 @@ static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) if ( mosflm->rbufpos==mosflm->rbuflen ) { /* More buffer space is needed */ - mosflm->rbuffer = realloc( - mosflm->rbuffer, - mosflm->rbuflen + 256); + mosflm->rbuffer = cfrealloc(mosflm->rbuffer, + mosflm->rbuflen + 256); mosflm->rbuflen = mosflm->rbuflen + 256; /* The new space gets used at the next * read, shortly... */ @@ -701,7 +700,7 @@ int run_mosflm(struct image *image, void *ipriv) int status; int rval; - mosflm = malloc(sizeof(struct mosflm_data)); + mosflm = cfmalloc(sizeof(struct mosflm_data)); if ( mosflm == NULL ) { ERROR("Couldn't allocate memory for MOSFLM data.\n"); return 0; @@ -720,7 +719,7 @@ int run_mosflm(struct image *image, void *ipriv) if ( mosflm->pid == -1 ) { ERROR("Failed to fork for MOSFLM: %s\n", strerror(errno)); - free(mosflm); + cffree(mosflm); return 0; } if ( mosflm->pid == 0 ) { @@ -741,7 +740,7 @@ int run_mosflm(struct image *image, void *ipriv) } - mosflm->rbuffer = malloc(256); + mosflm->rbuffer = cfmalloc(256); mosflm->rbuflen = 256; mosflm->rbufpos = 0; @@ -796,7 +795,7 @@ int run_mosflm(struct image *image, void *ipriv) } while ( !rval ); close(mosflm->pty); - free(mosflm->rbuffer); + cffree(mosflm->rbuffer); waitpid(mosflm->pid, &status, 0); if ( mosflm->finished_ok == 0 ) { @@ -807,7 +806,7 @@ int run_mosflm(struct image *image, void *ipriv) } rval = mosflm->success; - free(mosflm); + cffree(mosflm); return rval; } @@ -835,7 +834,7 @@ void *mosflm_prepare(IndexingMethod *indm, UnitCell *cell) "monoclinic C cell choice.\n"); } - mp = malloc(sizeof(struct mosflm_private)); + mp = cfmalloc(sizeof(struct mosflm_private)); if ( mp == NULL ) return NULL; mp->template = cell; @@ -849,7 +848,7 @@ void mosflm_cleanup(void *pp) { struct mosflm_private *p; p = (struct mosflm_private *)pp; - free(p); + cffree(p); } diff --git a/libcrystfel/src/indexers/pinkindexer.c b/libcrystfel/src/indexers/pinkindexer.c index 929c209b..180246c2 100644 --- a/libcrystfel/src/indexers/pinkindexer.c +++ b/libcrystfel/src/indexers/pinkindexer.c @@ -83,7 +83,7 @@ int run_pinkIndexer(struct image *image, void *ipriv, int n_threads) } reciprocalPeaks_1_per_A.peakCount = 0; - intensities = malloc(npk*sizeof(float)); + intensities = cfmalloc(npk*sizeof(float)); allocReciprocalPeaks(&reciprocalPeaks_1_per_A); if ( intensities == NULL ) return 0; @@ -116,7 +116,7 @@ int run_pinkIndexer(struct image *image, void *ipriv, int n_threads) pinkIndexer_private_data->maxRefinementDisbalance, n_threads); - free(intensities); + cffree(intensities); freeReciprocalPeaks(reciprocalPeaks_1_per_A); if ( matchedPeaksCount == -1 ) { @@ -205,7 +205,7 @@ void *pinkIndexer_prepare(IndexingMethod *indm, return NULL; } - struct pinkIndexer_private_data* pinkIndexer_private_data = malloc(sizeof(struct pinkIndexer_private_data)); + struct pinkIndexer_private_data* pinkIndexer_private_data = cfmalloc(sizeof(struct pinkIndexer_private_data)); pinkIndexer_private_data->indm = *indm; pinkIndexer_private_data->cellTemplate = cell; pinkIndexer_private_data->maxRefinementDisbalance = pinkIndexer_opts->maxRefinementDisbalance; @@ -424,7 +424,7 @@ int pinkIndexer_default_options(struct pinkindexer_options **opts_ptr) { struct pinkindexer_options *opts; - opts = malloc(sizeof(struct pinkindexer_options)); + opts = cfmalloc(sizeof(struct pinkindexer_options)); if ( opts == NULL ) return ENOMEM; opts->considered_peaks_count = 4; diff --git a/libcrystfel/src/indexers/taketwo.c b/libcrystfel/src/indexers/taketwo.c index 0b652b9f..c87d6b3d 100644 --- a/libcrystfel/src/indexers/taketwo.c +++ b/libcrystfel/src/indexers/taketwo.c @@ -524,7 +524,7 @@ static double matrix_trace(gsl_matrix *a) static char *add_unique_axis(const char *inp, char ua) { - char *pg = malloc(64); + char *pg = cfmalloc(64); if ( pg == NULL ) return NULL; snprintf(pg, 63, "%s_ua%c", inp, ua); return pg; @@ -584,7 +584,7 @@ static char *get_chiral_holohedry(UnitCell *cell) if ( add_ua ) { return add_unique_axis(pg, cell_get_unique_axis(cell)); } else { - return strdup(pg); + return cfstrdup(pg); } } @@ -595,7 +595,7 @@ static SymOpList *sym_ops_for_cell(UnitCell *cell) char *pg = get_chiral_holohedry(cell); rawList = get_pointgroup(pg); - free(pg); + cffree(pg); return rawList; } @@ -845,7 +845,7 @@ static int obs_vecs_match_angles(int her, int his, new_size *= sizeof(struct Seed); /* Reallocate the array to fit in another match */ - struct Seed *tmp_seeds = realloc(*seeds, new_size); + struct Seed *tmp_seeds = cfrealloc(*seeds, new_size); if ( tmp_seeds == NULL ) { apologise(); @@ -878,8 +878,8 @@ static signed int finish_solution(gsl_matrix *rot, struct SpotVec *obs_vecs, gsl_matrix *sub = gsl_matrix_calloc(3, 3); gsl_matrix *mul = gsl_matrix_calloc(3, 3); - gsl_matrix **rotations = malloc(sizeof(*rotations)* pow(member_num, 2) - - member_num); + gsl_matrix **rotations = cfmalloc(sizeof(*rotations)* pow(member_num, 2) + - member_num); int i, j, count; @@ -929,7 +929,7 @@ static signed int finish_solution(gsl_matrix *rot, struct SpotVec *obs_vecs, gsl_matrix_free(rotations[i]); } - free(rotations); + cffree(rotations); gsl_matrix_free(sub); gsl_matrix_free(mul); @@ -1011,7 +1011,7 @@ static int weed_duplicate_matches(struct Seed **seeds, } } - free(old_mats); + cffree(old_mats); return 1; } @@ -1310,8 +1310,8 @@ static unsigned int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2, } /* indices of members of the self-consistent network of vectors */ - obs_members = malloc((cell->member_thresh+3)*sizeof(int)); - match_members = malloc((cell->member_thresh+3)*sizeof(int)); + obs_members = cfmalloc((cell->member_thresh+3)*sizeof(int)); + match_members = cfmalloc((cell->member_thresh+3)*sizeof(int)); if ( (obs_members == NULL) || (match_members == NULL) ) { apologise(); return 0; @@ -1334,8 +1334,8 @@ static unsigned int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2, while ( 1 ) { if (start > obs_vec_count) { - free(obs_members); - free(match_members); + cffree(obs_members); + cffree(match_members); return 0; } @@ -1347,8 +1347,8 @@ static unsigned int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2, &match_found, cell); if ( member_num < 2 ) { - free(obs_members); - free(match_members); + cffree(obs_members); + cffree(match_members); return 0; } @@ -1383,8 +1383,8 @@ static unsigned int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2, finish_solution(rot, obs_vecs, obs_members, match_members, member_num, cell); - free(obs_members); - free(match_members); + cffree(obs_members); + cffree(match_members); return ( member_num ); } @@ -1519,7 +1519,7 @@ static int find_seeds(struct TakeTwoCell *cell, struct taketwo_private *tp) size_t new_size = cell->seed_count + seed_num; new_size *= sizeof(struct Seed); - struct Seed *tmp = realloc(cell->seeds, new_size); + struct Seed *tmp = cfrealloc(cell->seeds, new_size); if (tmp == NULL) { apologise(); @@ -1539,7 +1539,7 @@ static int find_seeds(struct TakeTwoCell *cell, struct taketwo_private *tp) cell->seed_count++; } - free(seeds); + cffree(seeds); } } @@ -1590,12 +1590,12 @@ static unsigned int start_seeds(gsl_matrix **rotation, struct TakeTwoCell *cell) } if (member_num >= NETWORK_MEMBER_THRESHOLD) { - free(seeds); + cffree(seeds); return max_members; } } - free(seeds); + cffree(seeds); return max_members; } @@ -1652,7 +1652,7 @@ static int generate_rotation_sym_ops(struct TakeTwoCell *ttCell) int i, j, k; int numOps = num_equivs(rawList, NULL); - ttCell->rotSymOps = malloc(numOps * sizeof(gsl_matrix *)); + ttCell->rotSymOps = cfmalloc(numOps * sizeof(gsl_matrix *)); ttCell->numOps = numOps; if (ttCell->rotSymOps == NULL) { @@ -1764,13 +1764,13 @@ static int match_obs_to_cell_vecs(struct TheoryVec *cell_vecs, int cell_vec_coun /* Sort in order to get most agreeable matches first */ qsort(for_sort, count, sizeof(struct sortme), sort_theory_distances); - *match_array = malloc(count*sizeof(struct TheoryVec)); + *match_array = cfmalloc(count*sizeof(struct TheoryVec)); *match_count = count; for ( j=0; jobs_vecs, - count*sizeof(struct SpotVec)); + temp_obs_vecs = cfrealloc(cell->obs_vecs, + count*sizeof(struct SpotVec)); if ( temp_obs_vecs == NULL ) { return 0; @@ -1899,8 +1899,8 @@ static int gen_theoretical_vecs(UnitCell *cell, struct TheoryVec **cell_vecs, count++; struct TheoryVec *temp_cell_vecs; - temp_cell_vecs = realloc(*cell_vecs, - count*sizeof(struct TheoryVec)); + temp_cell_vecs = cfrealloc(*cell_vecs, + count*sizeof(struct TheoryVec)); if ( temp_cell_vecs == NULL ) { return 0; @@ -1929,10 +1929,10 @@ static void cleanup_taketwo_obs_vecs(struct SpotVec *obs_vecs, { int i; for ( i=0; inumOps; i++ ) { gsl_matrix_free(ttCell->rotSymOps[i]); } - free(ttCell->rotSymOps); + cffree(ttCell->rotSymOps); cleanup_taketwo_obs_vecs(ttCell->obs_vecs, ttCell->obs_vec_count); @@ -2056,12 +2056,12 @@ static UnitCell *run_taketwo(UnitCell *cell, const struct taketwo_options *opts, /* Add the current solution to the previous solutions list */ int new_size = (tp->numPrevs + 1) * sizeof(gsl_matrix *); - gsl_matrix **tmp = realloc(tp->prevSols, new_size); - double *tmpScores = realloc(tp->prevScores, + gsl_matrix **tmp = cfrealloc(tp->prevSols, new_size); + double *tmpScores = cfrealloc(tp->prevScores, (tp->numPrevs + 1) * sizeof(double)); unsigned int *tmpSuccesses; - tmpSuccesses = realloc(tp->membership, - (tp->numPrevs + 1) * sizeof(unsigned int)); + tmpSuccesses = cfrealloc(tp->membership, + (tp->numPrevs + 1) * sizeof(unsigned int)); if (!tmp) { apologise(); @@ -2096,11 +2096,11 @@ static void partial_taketwo_cleanup(struct taketwo_private *tp) gsl_matrix_free(tp->prevSols[i]); } - free(tp->prevSols); + cffree(tp->prevSols); } - free(tp->prevScores); - free(tp->membership); + cffree(tp->prevScores); + cffree(tp->membership); tp->prevScores = NULL; tp->membership = NULL; tp->xtal_num = 0; @@ -2143,7 +2143,7 @@ int taketwo_index(struct image *image, void *priv) tp->xtal_num = image->n_crystals; } - rlps = malloc((image_feature_count(image->features)+1)*sizeof(struct rvec)); + rlps = cfmalloc((image_feature_count(image->features)+1)*sizeof(struct rvec)); for ( i=0; ifeatures); i++ ) { double r[3]; @@ -2164,7 +2164,7 @@ int taketwo_index(struct image *image, void *priv) rlps[n_rlps++].w = 0.0; cell = run_taketwo(tp->cell, tp->opts, rlps, n_rlps, tp); - free(rlps); + cffree(rlps); if ( cell == NULL ) return 0; cr = crystal_new(); @@ -2222,7 +2222,7 @@ void *taketwo_prepare(IndexingMethod *indm, struct taketwo_options *opts, STATUS("\n"); - tp = malloc(sizeof(struct taketwo_private)); + tp = cfmalloc(sizeof(struct taketwo_private)); if ( tp == NULL ) return NULL; tp->cell = cell; @@ -2248,9 +2248,9 @@ void taketwo_cleanup(IndexingPrivate *pp) struct taketwo_private *tp = (struct taketwo_private *)pp; partial_taketwo_cleanup(tp); - free(tp->theory_vecs); + cffree(tp->theory_vecs); - free(tp); + cffree(tp); } @@ -2280,7 +2280,7 @@ int taketwo_default_options(struct taketwo_options **opts_ptr) { struct taketwo_options *opts; - opts = malloc(sizeof(struct taketwo_options)); + opts = cfmalloc(sizeof(struct taketwo_options)); if ( opts == NULL ) return ENOMEM; opts->member_thresh = -1.0; opts->len_tol = -1.0; diff --git a/libcrystfel/src/indexers/xds.c b/libcrystfel/src/indexers/xds.c index 8ef496cf..23274dc4 100644 --- a/libcrystfel/src/indexers/xds.c +++ b/libcrystfel/src/indexers/xds.c @@ -468,7 +468,7 @@ void *xds_prepare(IndexingMethod *indm, UnitCell *cell) return NULL; } - xp = calloc(1, sizeof(*xp)); + xp = cfcalloc(1, sizeof(*xp)); if ( xp == NULL ) return NULL; /* Flags that XDS knows about */ @@ -487,7 +487,7 @@ void xds_cleanup(void *pp) struct xds_private *xp; xp = (struct xds_private *)pp; - free(xp); + cffree(xp); } diff --git a/libcrystfel/src/indexers/xgandalf.c b/libcrystfel/src/indexers/xgandalf.c index 6c50a38b..defef243 100644 --- a/libcrystfel/src/indexers/xgandalf.c +++ b/libcrystfel/src/indexers/xgandalf.c @@ -158,7 +158,7 @@ int run_xgandalf(struct image *image, void *ipriv) void *xgandalf_prepare(IndexingMethod *indm, UnitCell *cell, struct xgandalf_options *xgandalf_opts) { - struct xgandalf_private_data *xgandalf_private_data = malloc(sizeof(struct xgandalf_private_data)); + struct xgandalf_private_data *xgandalf_private_data = cfmalloc(sizeof(struct xgandalf_private_data)); allocReciprocalPeaks(&(xgandalf_private_data->reciprocalPeaks_1_per_A)); xgandalf_private_data->indm = *indm; xgandalf_private_data->cellTemplate = NULL; @@ -264,7 +264,7 @@ void xgandalf_cleanup(void *pp) if(xgandalf_private_data->centeringTransformation != NULL){ intmat_free(xgandalf_private_data->centeringTransformation); } - free(xgandalf_private_data); + cffree(xgandalf_private_data); } static void reduceCell(UnitCell *cell, LatticeTransform_t* appliedReductionTransform) @@ -382,7 +382,7 @@ int xgandalf_default_options(struct xgandalf_options **opts_ptr) { struct xgandalf_options *opts; - opts = malloc(sizeof(struct xgandalf_options)); + opts = cfmalloc(sizeof(struct xgandalf_options)); if ( opts == NULL ) return ENOMEM; opts->sampling_pitch = 6; diff --git a/libcrystfel/src/integer_matrix.c b/libcrystfel/src/integer_matrix.c index c6527d82..f7881d0a 100644 --- a/libcrystfel/src/integer_matrix.c +++ b/libcrystfel/src/integer_matrix.c @@ -62,12 +62,12 @@ IntegerMatrix *intmat_new(unsigned int rows, unsigned int cols) { IntegerMatrix *m; - m = malloc(sizeof(IntegerMatrix)); + m = cfmalloc(sizeof(IntegerMatrix)); if ( m == NULL ) return NULL; - m->v = calloc(rows*cols, sizeof(signed int)); + m->v = cfcalloc(rows*cols, sizeof(signed int)); if ( m->v == NULL ) { - free(m); + cffree(m); return NULL; } @@ -109,8 +109,8 @@ IntegerMatrix *intmat_copy(const IntegerMatrix *m) void intmat_free(IntegerMatrix *m) { if ( m == NULL ) return; - free(m->v); - free(m); + cffree(m->v); + cffree(m); } @@ -190,7 +190,7 @@ signed int *transform_indices(const IntegerMatrix *P, const signed int *hkl) signed int *ans; unsigned int j; - ans = malloc(P->rows * sizeof(signed int)); + ans = cfmalloc(P->rows * sizeof(signed int)); if ( ans == NULL ) return NULL; for ( j=0; jcols; j++ ) { diff --git a/libcrystfel/src/integration.c b/libcrystfel/src/integration.c index 3912114a..cad0a75c 100644 --- a/libcrystfel/src/integration.c +++ b/libcrystfel/src/integration.c @@ -393,7 +393,7 @@ static int alloc_boxes(struct intcontext *ic, int new_max_boxes) { struct peak_box *boxes_new; - boxes_new = realloc(ic->boxes, sizeof(struct peak_box)*new_max_boxes); + boxes_new = cfrealloc(ic->boxes, sizeof(struct peak_box)*new_max_boxes); if ( boxes_new == NULL ) return 1; ic->boxes = boxes_new; @@ -467,7 +467,7 @@ struct intcontext *intcontext_new(struct image *image, int i; struct intcontext *ic; - ic = malloc(sizeof(struct intcontext)); + ic = cfmalloc(sizeof(struct intcontext)); if ( ic == NULL ) return NULL; ic->halfw = ir_out; @@ -481,36 +481,36 @@ struct intcontext *intcontext_new(struct image *image, ic->int_diag = INTDIAG_NONE; ic->w = 2*ic->halfw + 1; - ic->bm = malloc(ic->w * ic->w * sizeof(enum boxmask_val)); + ic->bm = cfmalloc(ic->w * ic->w * sizeof(enum boxmask_val)); if ( ic->bm == NULL ) { ERROR("Failed to allocate box mask.\n"); - free(ic); + cffree(ic); return NULL; } /* How many reference profiles? */ ic->n_reference_profiles = 1; - ic->reference_profiles = calloc(ic->n_reference_profiles, - sizeof(double *)); + ic->reference_profiles = cfcalloc(ic->n_reference_profiles, + sizeof(double *)); if ( ic->reference_profiles == NULL ) { - free(ic); + cffree(ic); return NULL; } - ic->reference_den = calloc(ic->n_reference_profiles, sizeof(double *)); + ic->reference_den = cfcalloc(ic->n_reference_profiles, sizeof(double *)); if ( ic->reference_den == NULL ) { - free(ic); + cffree(ic); return NULL; } - ic->n_profiles_in_reference = calloc(ic->n_reference_profiles, - sizeof(int)); + ic->n_profiles_in_reference = cfcalloc(ic->n_reference_profiles, + sizeof(int)); if ( ic->n_profiles_in_reference == NULL ) { - free(ic); + cffree(ic); return NULL; } for ( i=0; in_reference_profiles; i++ ) { - ic->reference_profiles[i] = malloc(ic->w*ic->w*sizeof(double)); + ic->reference_profiles[i] = cfmalloc(ic->w*ic->w*sizeof(double)); if ( ic->reference_profiles[i] == NULL ) return NULL; - ic->reference_den[i] = malloc(ic->w*ic->w*sizeof(double)); + ic->reference_den[i] = cfmalloc(ic->w*ic->w*sizeof(double)); if ( ic->reference_den[i] == NULL ) return NULL; } zero_profiles(ic); @@ -519,7 +519,7 @@ struct intcontext *intcontext_new(struct image *image, ic->n_boxes = 0; ic->max_boxes = 0; if ( alloc_boxes(ic, 32) ) { - free(ic); + cffree(ic); return NULL; } @@ -534,20 +534,20 @@ void intcontext_free(struct intcontext *ic) int i; for ( i=0; in_boxes; i++ ) { - free(ic->boxes[i].bm); + cffree(ic->boxes[i].bm); gsl_matrix_free(ic->boxes[i].bgm); } - free(ic->boxes); + cffree(ic->boxes); for ( i=0; in_reference_profiles; i++ ) { - free(ic->reference_profiles[i]); - free(ic->reference_den[i]); - } - free(ic->reference_profiles); - free(ic->reference_den); - free(ic->n_profiles_in_reference); - free(ic->bm); - free(ic); + cffree(ic->reference_profiles[i]); + cffree(ic->reference_den[i]); + } + cffree(ic->reference_profiles); + cffree(ic->reference_den); + cffree(ic->n_profiles_in_reference); + cffree(ic->bm); + cffree(ic); } @@ -604,7 +604,7 @@ static void delete_box(struct intcontext *ic, struct peak_box *bx) return; } - free(bx->bm); + cffree(bx->bm); gsl_matrix_free(bx->bgm); memmove(&ic->boxes[i], &ic->boxes[i+1], @@ -803,7 +803,7 @@ static int check_box(struct intcontext *ic, struct peak_box *bx, int *sat) if ( sat != NULL ) *sat = 0; - bx->bm = malloc(ic->w*ic->w*sizeof(enum boxmask_val)); + bx->bm = cfmalloc(ic->w*ic->w*sizeof(enum boxmask_val)); if ( bx->bm == NULL ) { ERROR("Failed to allocate box mask\n"); return 1; @@ -980,7 +980,7 @@ static int center_and_check_box(struct intcontext *ic, struct peak_box *bx, t_offs_fs += ifs; t_offs_ss += iss; - free(bx->bm); + cffree(bx->bm); if ( check_box(ic, bx, sat) ) { return 1; } @@ -1515,7 +1515,7 @@ static double estimate_resolution(Crystal *cr, struct image *image) UnitCell *cell; - acc = malloc(max_acc*sizeof(double)); + acc = cfmalloc(max_acc*sizeof(double)); if ( acc == NULL ) { ERROR("Allocation failed during estimate_resolution!\n"); return INFINITY; @@ -1577,7 +1577,7 @@ static double estimate_resolution(Crystal *cr, struct image *image) if ( n_acc < 3 ) { STATUS("WARNING: Too few peaks to estimate resolution.\n"); - free(acc); + cffree(acc); return 0.0; } @@ -1587,7 +1587,7 @@ static double estimate_resolution(Crystal *cr, struct image *image) if ( n < 2 ) n = 2; max_res = acc[(n_acc-1)-n]; - free(acc); + cffree(acc); return max_res; } @@ -1711,7 +1711,7 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, } for ( i=0; idetgeom->n_panels; i++ ) { - free(masks[i]); + cffree(masks[i]); } } @@ -1794,7 +1794,7 @@ char *str_integration_method(IntegrationMethod m) strcat(tmp, "-grad"); } - return strdup(tmp); + return cfstrdup(tmp); } @@ -1854,10 +1854,10 @@ IntegrationMethod integration_method(const char *str, int *err) return INTEGRATION_NONE; } - free(methods[i]); + cffree(methods[i]); } - free(methods); + cffree(methods); return meth; diff --git a/libcrystfel/src/peakfinder8.c b/libcrystfel/src/peakfinder8.c index 4c41040a..95153191 100644 --- a/libcrystfel/src/peakfinder8.c +++ b/libcrystfel/src/peakfinder8.c @@ -119,26 +119,26 @@ static struct radial_stats_pixels *compute_rstats_pixels(struct radius_maps *rma int i; struct radial_stats_pixels *rsp = NULL; - rsp = (struct radial_stats_pixels *)malloc(sizeof(struct radial_stats_pixels)); + rsp = (struct radial_stats_pixels *)cfmalloc(sizeof(struct radial_stats_pixels)); if ( rsp == NULL ) { return NULL; } - rsp->n_pixels = (int *)malloc(rmaps->n_rmaps * sizeof(int)); + rsp->n_pixels = (int *)cfmalloc(rmaps->n_rmaps * sizeof(int)); if ( rsp->n_pixels == NULL ) { - free(rsp); + cffree(rsp); return NULL; } - rsp->pidx = (int **)malloc(rmaps->n_rmaps * sizeof(int *)); + rsp->pidx = (int **)cfmalloc(rmaps->n_rmaps * sizeof(int *)); if ( rsp->pidx == NULL ) { - free(rsp->n_pixels); - free(rsp); + cffree(rsp->n_pixels); + cffree(rsp); return NULL; } - rsp->radius = (int **)malloc(rmaps->n_rmaps * sizeof(int *)); + rsp->radius = (int **)cfmalloc(rmaps->n_rmaps * sizeof(int *)); if ( rsp->radius == NULL ) { - free(rsp->n_pixels); - free(rsp->pidx); - free(rsp); + cffree(rsp->n_pixels); + cffree(rsp->pidx); + cffree(rsp); return NULL; } srand(0); @@ -147,16 +147,16 @@ static struct radial_stats_pixels *compute_rstats_pixels(struct radius_maps *rma // Assuming 5000 is the maximum possible radius int n_bins = 5000; - int *n_pixels = (int *)malloc(n_bins * sizeof(int)); // selected pixels per bin - int *n_tot_pixels = (int *)malloc(n_bins * sizeof(int));; // total pixels per bin - int **panel = (int **)malloc(n_bins * sizeof(int *)); // panel ID of selected pixels - int **idx = (int **)malloc(n_bins * sizeof(int *)); // index of selected pixels + int *n_pixels = (int *)cfmalloc(n_bins * sizeof(int)); // selected pixels per bin + int *n_tot_pixels = (int *)cfmalloc(n_bins * sizeof(int));; // total pixels per bin + int **panel = (int **)cfmalloc(n_bins * sizeof(int *)); // panel ID of selected pixels + int **idx = (int **)cfmalloc(n_bins * sizeof(int *)); // index of selected pixels for ( i = 0; i < n_bins; i++ ) { n_pixels[i] = 0; n_tot_pixels[i] = 0; - panel[i] = (int *)malloc(n_pixels_per_bin * sizeof(int)); - idx[i] = (int *)malloc(n_pixels_per_bin * sizeof(int)); + panel[i] = (int *)cfmalloc(n_pixels_per_bin * sizeof(int)); + idx[i] = (int *)cfmalloc(n_pixels_per_bin * sizeof(int)); } int radius; @@ -186,40 +186,40 @@ static struct radial_stats_pixels *compute_rstats_pixels(struct radius_maps *rma } } - int *sidx = (int *)malloc(rmaps->n_rmaps * sizeof(int)); + int *sidx = (int *)cfmalloc(rmaps->n_rmaps * sizeof(int)); if ( sidx == NULL ) { - free(rsp->n_pixels); - free(rsp->pidx); - free(rsp->radius); - free(rsp); + cffree(rsp->n_pixels); + cffree(rsp->pidx); + cffree(rsp->radius); + cffree(rsp); return NULL; } for ( p = 0; p < rmaps->n_rmaps; p++ ) { - rsp->pidx[p] = (int *)malloc(rsp->n_pixels[p] * sizeof(int)); + rsp->pidx[p] = (int *)cfmalloc(rsp->n_pixels[p] * sizeof(int)); if ( rsp->pidx[p] == NULL ) { for ( i = 0; i < p; i++ ) { - free(rsp->pidx[i]); - free(rsp->radius[i]); + cffree(rsp->pidx[i]); + cffree(rsp->radius[i]); } - free(rsp->pidx); - free(rsp->radius); - free(rsp->n_pixels); - free(rsp); - free(sidx); + cffree(rsp->pidx); + cffree(rsp->radius); + cffree(rsp->n_pixels); + cffree(rsp); + cffree(sidx); return NULL; } - rsp->radius[p] = (int *)malloc(rsp->n_pixels[p] * sizeof(int)); + rsp->radius[p] = (int *)cfmalloc(rsp->n_pixels[p] * sizeof(int)); if ( rsp->radius[p] == NULL ) { for ( i = 0; i < p; i++ ) { - free(rsp->pidx[i]); - free(rsp->radius[i]); + cffree(rsp->pidx[i]); + cffree(rsp->radius[i]); } - free(rsp->pidx[p]); - free(rsp->pidx); - free(rsp->radius); - free(rsp->n_pixels); - free(rsp); - free(sidx); + cffree(rsp->pidx[p]); + cffree(rsp->pidx); + cffree(rsp->radius); + cffree(rsp->n_pixels); + cffree(rsp); + cffree(sidx); return NULL; } sidx[p] = 0; @@ -233,15 +233,15 @@ static struct radial_stats_pixels *compute_rstats_pixels(struct radius_maps *rma sidx[p] += 1; } } - free(sidx); + cffree(sidx); for ( i = 0; i < n_bins; i++ ) { - free(panel[i]); - free(idx[i]); + cffree(panel[i]); + cffree(idx[i]); } - free(panel); - free(idx); - free(n_pixels); - free(n_tot_pixels); + cffree(panel); + cffree(idx); + cffree(n_pixels); + cffree(n_tot_pixels); rsp->n_panels = rmaps->n_rmaps; return rsp; @@ -251,13 +251,13 @@ static void free_rstats_pixels(struct radial_stats_pixels *rsp) { int i; for ( i = 0; i < rsp->n_panels; i++ ) { - free(rsp->pidx[i]); - free(rsp->radius[i]); + cffree(rsp->pidx[i]); + cffree(rsp->radius[i]); } - free(rsp->pidx); - free(rsp->radius); - free(rsp->n_pixels); - free(rsp); + cffree(rsp->pidx); + cffree(rsp->radius); + cffree(rsp->n_pixels); + cffree(rsp); } @@ -267,20 +267,20 @@ static struct radius_maps *compute_radius_maps(struct detgeom *det) struct detgeom_panel p; struct radius_maps *rm = NULL; - rm = (struct radius_maps *)malloc(sizeof(struct radius_maps)); + rm = (struct radius_maps *)cfmalloc(sizeof(struct radius_maps)); if ( rm == NULL ) { return NULL; } - rm->r_maps = (float **)malloc(det->n_panels*sizeof(float*)); + rm->r_maps = (float **)cfmalloc(det->n_panels*sizeof(float*)); if ( rm->r_maps == NULL ) { - free(rm); + cffree(rm); return NULL; } - rm->n_pixels = (int *)malloc(det->n_panels*sizeof(int*)); + rm->n_pixels = (int *)cfmalloc(det->n_panels*sizeof(int*)); if ( rm->r_maps == NULL ) { - free(rm); + cffree(rm); return NULL; } @@ -289,13 +289,13 @@ static struct radius_maps *compute_radius_maps(struct detgeom *det) for( i=0 ; in_panels ; i++ ) { p = det->panels[i]; - rm->r_maps[i] = (float *)malloc(p.h*p.w*sizeof(float)); + rm->r_maps[i] = (float *)cfmalloc(p.h*p.w*sizeof(float)); if ( rm->r_maps[i] == NULL ) { for ( u = 0; ur_maps[u]); + cffree(rm->r_maps[u]); } - free(rm); + cffree(rm); return NULL; } rm->n_pixels[i] = p.h * p.w; @@ -323,11 +323,11 @@ static void free_radius_maps(struct radius_maps *r_maps) int i; for ( i=0 ; in_rmaps ; i++ ) { - free(r_maps->r_maps[i]); + cffree(r_maps->r_maps[i]); } - free(r_maps->r_maps); - free(r_maps->n_pixels); - free(r_maps); + cffree(r_maps->r_maps); + cffree(r_maps->n_pixels); + cffree(r_maps); } @@ -339,13 +339,13 @@ struct pf8_private_data *prepare_peakfinder8(struct detgeom *det, int fast_mode) return NULL; } - data = (struct pf8_private_data *)malloc(sizeof(struct pf8_private_data)); + data = (struct pf8_private_data *)cfmalloc(sizeof(struct pf8_private_data)); if ( data == NULL ) { return NULL; } data->rmaps = compute_radius_maps(det); if ( data->rmaps == NULL ) { - free(data); + cffree(data); return NULL; } if ( fast_mode ) { @@ -369,7 +369,7 @@ void free_pf8_private_data(struct pf8_private_data *data) if ( data->fast_mode ) { free_rstats_pixels(data->rpixels); } - free(data); + cffree(data); } @@ -381,8 +381,8 @@ static struct peakfinder_mask *create_peakfinder_mask(struct image *img, int i; struct peakfinder_mask *msk; - msk = (struct peakfinder_mask *)malloc(sizeof(struct peakfinder_mask)); - msk->masks =(char **) malloc(img->detgeom->n_panels*sizeof(char*)); + msk = (struct peakfinder_mask *)cfmalloc(sizeof(struct peakfinder_mask)); + msk->masks =(char **) cfmalloc(img->detgeom->n_panels*sizeof(char*)); msk->n_masks = img->detgeom->n_panels; for ( i=0; idetgeom->n_panels; i++) { @@ -391,7 +391,7 @@ static struct peakfinder_mask *create_peakfinder_mask(struct image *img, p = img->detgeom->panels[i]; - msk->masks[i] = (char *)calloc(p.w*p.h,sizeof(char)); + msk->masks[i] = (char *)cfcalloc(p.w*p.h,sizeof(char)); for ( iss=0 ; issn_masks ; i++ ) { - free(pfmask->masks[i]); + cffree(pfmask->masks[i]); } - free(pfmask->masks); - free(pfmask); + cffree(pfmask->masks); + cffree(pfmask); } @@ -434,29 +434,29 @@ static struct peakfinder_panel_data *allocate_panel_data(int num_panels) struct peakfinder_panel_data *pfdata; - pfdata = (struct peakfinder_panel_data *)malloc(sizeof(struct peakfinder_panel_data)); + pfdata = (struct peakfinder_panel_data *)cfmalloc(sizeof(struct peakfinder_panel_data)); if ( pfdata == NULL ) { return NULL; } - pfdata->panel_h = (int *)malloc(num_panels*sizeof(int)); + pfdata->panel_h = (int *)cfmalloc(num_panels*sizeof(int)); if ( pfdata->panel_h == NULL ) { - free(pfdata); + cffree(pfdata); return NULL; } - pfdata->panel_w = (int *)malloc(num_panels*sizeof(int)); + pfdata->panel_w = (int *)cfmalloc(num_panels*sizeof(int)); if ( pfdata->panel_w == NULL ) { - free(pfdata->panel_h); - free(pfdata); + cffree(pfdata->panel_h); + cffree(pfdata); return NULL; } - pfdata->panel_data = (float **)malloc(num_panels*sizeof(float*)); + pfdata->panel_data = (float **)cfmalloc(num_panels*sizeof(float*)); if ( pfdata->panel_data == NULL ) { - free(pfdata->panel_w); - free(pfdata->panel_h); - free(pfdata); + cffree(pfdata->panel_w); + cffree(pfdata->panel_h); + cffree(pfdata); return NULL; } @@ -468,10 +468,10 @@ static struct peakfinder_panel_data *allocate_panel_data(int num_panels) static void free_panel_data(struct peakfinder_panel_data *pfdata) { - free(pfdata->panel_data); - free(pfdata->panel_w); - free(pfdata->panel_h); - free(pfdata); + cffree(pfdata->panel_data); + cffree(pfdata->panel_w); + cffree(pfdata->panel_h); + cffree(pfdata); } @@ -496,48 +496,48 @@ static struct radial_stats* allocate_radial_stats(int num_rad_bins) { struct radial_stats* rstats; - rstats = (struct radial_stats *)malloc(sizeof(struct radial_stats)); + rstats = (struct radial_stats *)cfmalloc(sizeof(struct radial_stats)); if ( rstats == NULL ) { return NULL; } - rstats->roffset = (float *)malloc(num_rad_bins*sizeof(float)); + rstats->roffset = (float *)cfmalloc(num_rad_bins*sizeof(float)); if ( rstats->roffset == NULL ) { - free(rstats); + cffree(rstats); return NULL; } - rstats->rthreshold = (float *)malloc(num_rad_bins*sizeof(float)); + rstats->rthreshold = (float *)cfmalloc(num_rad_bins*sizeof(float)); if ( rstats->rthreshold == NULL ) { - free(rstats->roffset); - free(rstats); + cffree(rstats->roffset); + cffree(rstats); return NULL; } - rstats->lthreshold = (float *)malloc(num_rad_bins*sizeof(float)); + rstats->lthreshold = (float *)cfmalloc(num_rad_bins*sizeof(float)); if ( rstats->lthreshold == NULL ) { - free(rstats->rthreshold); - free(rstats->roffset); - free(rstats); + cffree(rstats->rthreshold); + cffree(rstats->roffset); + cffree(rstats); return NULL; } - rstats->rsigma = (float *)malloc(num_rad_bins*sizeof(float)); + rstats->rsigma = (float *)cfmalloc(num_rad_bins*sizeof(float)); if ( rstats->rsigma == NULL ) { - free(rstats->roffset); - free(rstats->rthreshold); - free(rstats->lthreshold); - free(rstats); + cffree(rstats->roffset); + cffree(rstats->rthreshold); + cffree(rstats->lthreshold); + cffree(rstats); return NULL; } - rstats->rcount = (int *)malloc(num_rad_bins*sizeof(int)); + rstats->rcount = (int *)cfmalloc(num_rad_bins*sizeof(int)); if ( rstats->rcount == NULL ) { - free(rstats->roffset); - free(rstats->rthreshold); - free(rstats->lthreshold); - free(rstats->rsigma); - free(rstats); + cffree(rstats->roffset); + cffree(rstats->rthreshold); + cffree(rstats->lthreshold); + cffree(rstats->rsigma); + cffree(rstats); return NULL; } @@ -549,12 +549,12 @@ static struct radial_stats* allocate_radial_stats(int num_rad_bins) static void free_radial_stats(struct radial_stats *rstats) { - free(rstats->roffset); - free(rstats->rthreshold); - free(rstats->lthreshold); - free(rstats->rsigma); - free(rstats->rcount); - free(rstats); + cffree(rstats->roffset); + cffree(rstats->rthreshold); + cffree(rstats->lthreshold); + cffree(rstats->rsigma); + cffree(rstats->rcount); + cffree(rstats); } @@ -663,85 +663,85 @@ struct peakfinder_peak_data *allocate_peak_data(int max_num_peaks) { struct peakfinder_peak_data *pkdata; - pkdata = (struct peakfinder_peak_data*)malloc(sizeof(struct peakfinder_peak_data)); + pkdata = (struct peakfinder_peak_data*)cfmalloc(sizeof(struct peakfinder_peak_data)); if ( pkdata == NULL ) { return NULL; } - pkdata->npix = (int *)malloc(max_num_peaks*sizeof(int)); + pkdata->npix = (int *)cfmalloc(max_num_peaks*sizeof(int)); if ( pkdata->npix == NULL ) { - free(pkdata->npix); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata); return NULL; } - pkdata->com_fs = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->com_fs = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->com_fs == NULL ) { - free(pkdata->npix); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata); return NULL; } - pkdata->com_ss = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->com_ss = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->com_ss == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata); return NULL; } - pkdata->com_index = (int *)malloc(max_num_peaks*sizeof(int)); + pkdata->com_index = (int *)cfmalloc(max_num_peaks*sizeof(int)); if ( pkdata->com_ss == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata); return NULL; } - pkdata->tot_i = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->tot_i = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->tot_i == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata); return NULL; } - pkdata->max_i = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->max_i = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->max_i == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata->tot_i); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata->tot_i); + cffree(pkdata); return NULL; } - pkdata->sigma = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->sigma = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->sigma == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata->tot_i); - free(pkdata->max_i); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata->tot_i); + cffree(pkdata->max_i); + cffree(pkdata); return NULL; } - pkdata->snr = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->snr = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->snr == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata->tot_i); - free(pkdata->max_i); - free(pkdata->sigma); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata->tot_i); + cffree(pkdata->max_i); + cffree(pkdata->sigma); + cffree(pkdata); return NULL; } @@ -750,15 +750,15 @@ struct peakfinder_peak_data *allocate_peak_data(int max_num_peaks) static void free_peak_data(struct peakfinder_peak_data *pkdata) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata->tot_i); - free(pkdata->max_i); - free(pkdata->sigma); - free(pkdata->snr); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata->tot_i); + cffree(pkdata->max_i); + cffree(pkdata->sigma); + cffree(pkdata->snr); + cffree(pkdata); } @@ -768,38 +768,38 @@ static struct peakfinder_intern_data *allocate_peakfinder_intern_data(int data_s struct peakfinder_intern_data *intern_data; - intern_data = (struct peakfinder_intern_data *)malloc(sizeof(struct peakfinder_intern_data)); + intern_data = (struct peakfinder_intern_data *)cfmalloc(sizeof(struct peakfinder_intern_data)); if ( intern_data == NULL ) { return NULL; } - intern_data->pix_in_peak_map =(char *)calloc(data_size, sizeof(char)); + intern_data->pix_in_peak_map =(char *)cfcalloc(data_size, sizeof(char)); if ( intern_data->pix_in_peak_map == NULL ) { - free(intern_data); + cffree(intern_data); return NULL; } - intern_data->infs =(int *)calloc(data_size, sizeof(int)); + intern_data->infs =(int *)cfcalloc(data_size, sizeof(int)); if ( intern_data->infs == NULL ) { - free(intern_data->pix_in_peak_map); - free(intern_data); + cffree(intern_data->pix_in_peak_map); + cffree(intern_data); return NULL; } - intern_data->inss =(int *)calloc(data_size, sizeof(int)); + intern_data->inss =(int *)cfcalloc(data_size, sizeof(int)); if ( intern_data->inss == NULL ) { - free(intern_data->pix_in_peak_map); - free(intern_data->infs); - free(intern_data); + cffree(intern_data->pix_in_peak_map); + cffree(intern_data->infs); + cffree(intern_data); return NULL; } - intern_data->peak_pixels =(int *)calloc(max_pix_count, sizeof(int)); + intern_data->peak_pixels =(int *)cfcalloc(max_pix_count, sizeof(int)); if ( intern_data->peak_pixels == NULL ) { - free(intern_data->pix_in_peak_map); - free(intern_data->infs); - free(intern_data->inss); - free(intern_data); + cffree(intern_data->pix_in_peak_map); + cffree(intern_data->infs); + cffree(intern_data->inss); + cffree(intern_data); return NULL; } @@ -809,11 +809,11 @@ static struct peakfinder_intern_data *allocate_peakfinder_intern_data(int data_s static void free_peakfinder_intern_data(struct peakfinder_intern_data *pfid) { - free(pfid->peak_pixels); - free(pfid->pix_in_peak_map); - free(pfid->infs); - free(pfid->inss); - free(pfid); + cffree(pfid->peak_pixels); + cffree(pfid->pix_in_peak_map); + cffree(pfid->infs); + cffree(pfid->inss); + cffree(pfid); } diff --git a/libcrystfel/src/peaks.c b/libcrystfel/src/peaks.c index 6de36e4a..d56f6d03 100644 --- a/libcrystfel/src/peaks.c +++ b/libcrystfel/src/peaks.c @@ -115,7 +115,7 @@ int *make_BgMask(struct image *image, struct detgeom_panel *p, int *mask; int i; - mask = calloc(p->w*p->h, sizeof(int)); + mask = cfcalloc(p->w*p->h, sizeof(int)); if ( mask == NULL ) return NULL; if ( image->crystals == NULL ) return mask; @@ -524,10 +524,10 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, det_size_one_panel.pix_ny = h; det_size_one_panel.pix_nn = w * h; - data_copy_new = realloc(data_copy, w*h*sizeof(*data_copy)); + data_copy_new = cfrealloc(data_copy, w*h*sizeof(*data_copy)); if ( data_copy_new == NULL ) { if ( data_copy != NULL ) { - free(data_copy); + cffree(data_copy); } freePeakList(peakList); return 1; @@ -555,7 +555,7 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, } freePeakList(peakList); - free(data_copy); + cffree(data_copy); return 0; } @@ -747,7 +747,7 @@ double estimate_peak_resolution(ImageFeatureList *peaks, double lambda, /* No peaks -> no resolution! */ if ( npk == 0 ) return 0.0; - rns = malloc(npk*sizeof(double)); + rns = cfmalloc(npk*sizeof(double)); if ( rns == NULL ) return -1.0; /* Get resolution values for all peaks */ @@ -771,7 +771,7 @@ double estimate_peak_resolution(ImageFeatureList *peaks, double lambda, if ( ncut < 2 ) ncut = 0; max_res = rns[(npk-1)-ncut]; - free(rns); + cffree(rns); return max_res; } diff --git a/libcrystfel/src/predict-refine.c b/libcrystfel/src/predict-refine.c index 24045ddb..4cd0e54e 100644 --- a/libcrystfel/src/predict-refine.c +++ b/libcrystfel/src/predict-refine.c @@ -558,14 +558,14 @@ int refine_radius(Crystal *cr, struct image *image) RefList *reflist; /* Maximum possible size */ - rps = malloc(image_feature_count(image->features) - * sizeof(struct reflpeak)); + rps = cfmalloc(image_feature_count(image->features) + * sizeof(struct reflpeak)); if ( rps == NULL ) return 1; reflist = reflist_new(); n_acc = pair_peaks(image, cr, reflist, rps); if ( n_acc < 3 ) { - free(rps); + cffree(rps); reflist_free(reflist); return 1; } @@ -579,7 +579,7 @@ int refine_radius(Crystal *cr, struct image *image) crystal_set_profile_radius(cr, fabs(get_exerr(rps[n].refl))); reflist_free(reflist); - free(rps); + cffree(rps); return 0; } @@ -784,7 +784,7 @@ static double pred_residual(struct reflpeak *rps, int n, struct detgeom *det, /* NB Only for use when the list of reflpeaks was created without a RefList. - * If a RefList was used, then reflist_free the list then just free() the rps */ + * If a RefList was used, then reflist_free the list then just cffree() the rps */ static void free_rps_noreflist(struct reflpeak *rps, int n) { int i; @@ -792,7 +792,7 @@ static void free_rps_noreflist(struct reflpeak *rps, int n) for ( i=0; ifeatures) - * sizeof(struct reflpeak)); + rps = cfmalloc(image_feature_count(image->features) + * sizeof(struct reflpeak)); if ( rps == NULL ) return 1; reflist = reflist_new(); n = pair_peaks(image, cr, reflist, rps); if ( n < 10 ) { - free(rps); + cffree(rps); reflist_free(reflist); return 1; } @@ -832,7 +832,7 @@ int refine_prediction(struct image *image, Crystal *cr, } if ( max_I <= 0.0 ) { ERROR("All peaks negative?\n"); - free(rps); + cffree(rps); crystal_set_reflections(cr, NULL); return 1; } @@ -888,7 +888,7 @@ int refine_prediction(struct image *image, Crystal *cr, for ( i=0; idetgeom->n_panels; i++ ) { gsl_matrix_free(Minvs[i]); } - free(Minvs); + cffree(Minvs); crystal_set_reflections(cr, NULL); reflist_free(reflist); diff --git a/libcrystfel/src/profile.c b/libcrystfel/src/profile.c index ac76b8fa..5ca18f17 100644 --- a/libcrystfel/src/profile.c +++ b/libcrystfel/src/profile.c @@ -36,6 +36,7 @@ #include #include "profile.h" +#include "utils.h" #ifndef CLOCK_MONOTONIC_RAW #define CLOCK_MONOTONIC_RAW (CLOCK_MONOTONIC) @@ -70,12 +71,12 @@ static struct _profile_block *start_profile_block(const char *name) { struct _profile_block *b; - b = malloc(sizeof(struct _profile_block)); + b = cfmalloc(sizeof(struct _profile_block)); if ( b == NULL ) return NULL; - b->name = strdup(name); + b->name = cfstrdup(name); if ( b->name == NULL ) { - free(b); + cffree(b); return NULL; } b->n_children = 0; @@ -116,7 +117,7 @@ void profile_init() } if ( pd == NULL ) { - pd = malloc(sizeof(struct _profiledata)); + pd = cfmalloc(sizeof(struct _profiledata)); if ( pd == NULL ) return; } @@ -137,7 +138,7 @@ static char *format_profile_block(struct _profile_block *b) char **subbufs; char *full_buf; - subbufs = malloc(b->n_children * sizeof(char *)); + subbufs = cfmalloc(b->n_children * sizeof(char *)); if ( subbufs == NULL ) return NULL; total_len = 32 + strlen(b->name); @@ -147,16 +148,16 @@ static char *format_profile_block(struct _profile_block *b) total_len += 1 + strlen(subbufs[i]); } - full_buf = malloc(total_len); + full_buf = cfmalloc(total_len); snprintf(full_buf, 32, "(%s %.3f", b->name, b->total_time); for ( i=0; in_children; i++ ) { strcat(full_buf, " "); strcat(full_buf, subbufs[i]); - free(subbufs[i]); + cffree(subbufs[i]); } strcat(full_buf, ")"); - free(subbufs); + cffree(subbufs); return full_buf; } @@ -168,9 +169,9 @@ static void free_profile_block(struct _profile_block *b) for ( i=0; in_children; i++ ) { free_profile_block(b->children[i]); } - free(b->children); - free(b->name); - free(b); + cffree(b->children); + cffree(b->name); + cffree(b); } @@ -195,12 +196,12 @@ void profile_print_and_reset(int worker_id) stop_profile_block(pd->root); buf = format_profile_block(pd->root); - buf2 = malloc(8+strlen(buf)); + buf2 = cfmalloc(8+strlen(buf)); size_t len = 8+strlen(buf); snprintf(buf2, len, "%i %s\n", worker_id, buf); write(STDOUT_FILENO, buf2, strlen(buf2)); - free(buf); - free(buf2); + cffree(buf); + cffree(buf2); free_profile_block(pd->root); pd->root = start_profile_block("root"); @@ -218,7 +219,7 @@ void profile_start(const char *name) if ( pd->current->n_children >= pd->current->max_children ) { struct _profile_block **nblock; int nmax = pd->current->n_children + 64; - nblock = realloc(pd->current->children, nmax*sizeof(struct _profile_block *)); + nblock = cfrealloc(pd->current->children, nmax*sizeof(struct _profile_block *)); if ( nblock == NULL ) { fprintf(stderr, "Failed to allocate profiling record. " "Try again without --profile.\n"); diff --git a/libcrystfel/src/rational.c b/libcrystfel/src/rational.c index 800decf5..88294745 100644 --- a/libcrystfel/src/rational.c +++ b/libcrystfel/src/rational.c @@ -198,7 +198,7 @@ Rational rtnl_abs(Rational a) */ char *rtnl_format(Rational rt) { - char *v = malloc(32); + char *v = cfmalloc(32); if ( v == NULL ) return NULL; if ( rt.den == 1 ) { snprintf(v, 31, "%lli", rt.num); @@ -217,7 +217,7 @@ Rational *rtnl_list(signed int num_min, signed int num_max, Rational *list; int n = 0; - list = malloc((1+num_max-num_min)*(1+den_max-den_min)*sizeof(Rational)); + list = cfmalloc((1+num_max-num_min)*(1+den_max-den_min)*sizeof(Rational)); if ( list == NULL ) return NULL; for ( num=num_min; num<=num_max; num++ ) { @@ -263,12 +263,12 @@ RationalMatrix *rtnl_mtx_new(unsigned int rows, unsigned int cols) RationalMatrix *m; int i; - m = malloc(sizeof(RationalMatrix)); + m = cfmalloc(sizeof(RationalMatrix)); if ( m == NULL ) return NULL; - m->v = calloc(rows*cols, sizeof(Rational)); + m->v = cfcalloc(rows*cols, sizeof(Rational)); if ( m->v == NULL ) { - free(m); + cffree(m); return NULL; } @@ -372,8 +372,8 @@ IntegerMatrix *intmat_from_rtnl_mtx(const RationalMatrix *m) void rtnl_mtx_free(RationalMatrix *mtx) { if ( mtx == NULL ) return; - free(mtx->v); - free(mtx); + cffree(mtx->v); + cffree(mtx); } @@ -412,7 +412,7 @@ int transform_fractional_coords_rtnl(const RationalMatrix *P, cm = rtnl_mtx_copy(P); if ( cm == NULL ) return 1; - vec = malloc(cm->rows*sizeof(Rational)); + vec = cfmalloc(cm->rows*sizeof(Rational)); if ( vec == NULL ) return 1; for ( h=0; hrows; h++ ) vec[h] = ivec[h]; @@ -489,7 +489,7 @@ int transform_fractional_coords_rtnl(const RationalMatrix *P, ans[i] = rtnl_div(sum, rtnl_mtx_get(cm, i, i)); } - free(vec); + cffree(vec); rtnl_mtx_free(cm); return 0; @@ -517,7 +517,7 @@ void rtnl_mtx_print(const RationalMatrix *m) for ( j=0; jcols; j++ ) { char *v = rtnl_format(rtnl_mtx_get(m, i, j)); fprintf(stderr, "%4s ", v); - free(v); + cffree(v); } fprintf(stderr, "]\n"); } diff --git a/libcrystfel/src/reflist-utils.c b/libcrystfel/src/reflist-utils.c index 66a4996c..14e99d01 100644 --- a/libcrystfel/src/reflist-utils.c +++ b/libcrystfel/src/reflist-utils.c @@ -399,7 +399,7 @@ static RefList *read_reflections_from_file(FILE *fh, char **sym) if ( strncmp(line, "Symmetry: ", 10) != 0 ) return NULL; if ( sym != NULL ) { - *sym = strdup(line+10); + *sym = cfstrdup(line+10); } /* Read (and ignore) the header */ @@ -780,9 +780,9 @@ void free_contribs(RefList *list) { struct reflection_contributions *c; c = get_contributions(refl); - free(c->contribs); - free(c->contrib_crystals); - free(c); + cffree(c->contribs); + cffree(c->contrib_crystals); + cffree(c); } } @@ -793,13 +793,13 @@ static char *full_command_line(int argc, char *argv[]) size_t len = 1; char *cl; - if ( argc == 0 ) return strdup(""); + if ( argc == 0 ) return cfstrdup(""); for ( i=0; iin_list = 0; new->serial = serial; @@ -149,7 +149,7 @@ RefList *reflist_new() { RefList *new; - new = malloc(sizeof(struct _reflist)); + new = cfmalloc(sizeof(struct _reflist)); if ( new == NULL ) return NULL; new->head = NULL; @@ -184,7 +184,7 @@ Reflection *reflection_new(signed int h, signed int k, signed int l) void reflection_free(Reflection *refl) { pthread_mutex_destroy(&refl->lock); - free(refl); + cffree(refl); } @@ -212,8 +212,8 @@ void reflist_free(RefList *list) if ( list->head != NULL ) { recursive_free(list->head); } /* else empty list */ - if ( list->notes != NULL ) free(list->notes); - free(list); + if ( list->notes != NULL ) cffree(list->notes); + cffree(list); } @@ -994,9 +994,9 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) Reflection *refl; RefListIterator *iter; - iter = malloc(sizeof(struct _reflistiterator)); + iter = cfmalloc(sizeof(struct _reflistiterator)); iter->stack_size = 32; - iter->stack = malloc(iter->stack_size*sizeof(Reflection *)); + iter->stack = cfmalloc(iter->stack_size*sizeof(Reflection *)); iter->stack_ptr = 0; iter->is_const = 0; *piter = iter; @@ -1011,7 +1011,7 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) iter->stack[iter->stack_ptr++] = refl; if ( iter->stack_ptr == iter->stack_size ) { iter->stack_size += 32; - iter->stack = realloc(iter->stack, + iter->stack = cfrealloc(iter->stack, iter->stack_size*sizeof(Reflection *)); } refl = refl->child[0]; @@ -1019,8 +1019,8 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) } if ( iter->stack_ptr == 0 ) { - free(iter->stack); - free(iter); + cffree(iter->stack); + cffree(iter); return NULL; } @@ -1047,9 +1047,9 @@ const Reflection *first_refl_const(const RefList *list, RefListIterator **piter) const Reflection *refl; RefListIterator *iter; - iter = malloc(sizeof(struct _reflistiterator)); + iter = cfmalloc(sizeof(struct _reflistiterator)); iter->stack_size = 32; - iter->stack_const = malloc(iter->stack_size*sizeof(Reflection *)); + iter->stack_const = cfmalloc(iter->stack_size*sizeof(Reflection *)); iter->stack_ptr = 0; iter->is_const = 1; *piter = iter; @@ -1064,7 +1064,7 @@ const Reflection *first_refl_const(const RefList *list, RefListIterator **piter) iter->stack_const[iter->stack_ptr++] = refl; if ( iter->stack_ptr == iter->stack_size ) { iter->stack_size += 32; - iter->stack_const = realloc(iter->stack_const, + iter->stack_const = cfrealloc(iter->stack_const, iter->stack_size*sizeof(Reflection *)); } refl = refl->child[0]; @@ -1072,8 +1072,8 @@ const Reflection *first_refl_const(const RefList *list, RefListIterator **piter) } if ( iter->stack_ptr == 0 ) { - free(iter->stack_const); - free(iter); + cffree(iter->stack_const); + cffree(iter); return NULL; } @@ -1119,7 +1119,7 @@ Reflection *next_refl(Reflection *refl, RefListIterator *iter) iter->stack[iter->stack_ptr++] = refl; if ( iter->stack_ptr == iter->stack_size ) { iter->stack_size += 32; - iter->stack = realloc(iter->stack, + iter->stack = cfrealloc(iter->stack, iter->stack_size*sizeof(Reflection *)); } refl = refl->child[0]; @@ -1127,8 +1127,8 @@ Reflection *next_refl(Reflection *refl, RefListIterator *iter) } if ( iter->stack_ptr == 0 ) { - free(iter->stack); - free(iter); + cffree(iter->stack); + cffree(iter); return NULL; } @@ -1172,7 +1172,7 @@ const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter) iter->stack_const[iter->stack_ptr++] = refl; if ( iter->stack_ptr == iter->stack_size ) { iter->stack_size += 32; - iter->stack_const = realloc(iter->stack_const, + iter->stack_const = cfrealloc(iter->stack_const, iter->stack_size*sizeof(Reflection *)); } refl = refl->child[0]; @@ -1277,8 +1277,8 @@ void unlock_reflection(Reflection *refl) static void reflist_set_notes(RefList *reflist, const char *notes) { - free(reflist->notes); /* free(NULL) is OK */ - reflist->notes = strdup(notes); + cffree(reflist->notes); /* free(NULL) is OK */ + reflist->notes = cfstrdup(notes); } @@ -1315,7 +1315,7 @@ void reflist_add_notes(RefList *reflist, const char *notes_add) } len = strlen(notes_add) + strlen(reflist->notes) + 2; - nnotes = malloc(len); + nnotes = cfmalloc(len); if ( nnotes == NULL ) { ERROR("Failed to add notes to crystal.\n"); return; @@ -1324,6 +1324,6 @@ void reflist_add_notes(RefList *reflist, const char *notes_add) strcpy(nnotes, reflist->notes); strcat(nnotes, "\n"); strcat(nnotes, notes_add); - free(reflist->notes); + cffree(reflist->notes); reflist->notes = nnotes; } diff --git a/libcrystfel/src/spectrum.c b/libcrystfel/src/spectrum.c index 5f126cf0..58b822f8 100644 --- a/libcrystfel/src/spectrum.c +++ b/libcrystfel/src/spectrum.c @@ -71,7 +71,7 @@ Spectrum *spectrum_new() { Spectrum *s; - s = malloc(sizeof(Spectrum)); + s = cfmalloc(sizeof(Spectrum)); if ( s == NULL ) return NULL; s->rep = SPEC_GAUSSIANS; @@ -95,10 +95,10 @@ Spectrum *spectrum_new() void spectrum_free(Spectrum *s) { if ( s == NULL ) return; - free(s->gaussians); - free(s->k); - free(s->pdf); - free(s); + cffree(s->gaussians); + cffree(s->k); + cffree(s->pdf); + cffree(s); } @@ -292,11 +292,11 @@ static void normalise_gaussians(struct gaussian *gauss, int n_gauss) void spectrum_set_gaussians(Spectrum *s, struct gaussian *gs, int n_gauss) { /* Free old contents (if any - may be NULL) */ - free(s->gaussians); - free(s->k); - free(s->pdf); + cffree(s->gaussians); + cffree(s->k); + cffree(s->pdf); - s->gaussians = malloc(n_gauss * sizeof(struct gaussian)); + s->gaussians = cfmalloc(n_gauss * sizeof(struct gaussian)); if ( s->gaussians == NULL ) return; memcpy(s->gaussians, gs, n_gauss*sizeof(struct gaussian)); @@ -348,17 +348,17 @@ void spectrum_set_pdf(Spectrum *s, double *kvals, double *heights, int n) int i; /* Free old contents (if any - may be NULL) */ - free(s->gaussians); - free(s->k); - free(s->pdf); + cffree(s->gaussians); + cffree(s->k); + cffree(s->pdf); - s->k = malloc(n * sizeof(double)); + s->k = cfmalloc(n * sizeof(double)); if ( s->k == NULL ) return; - s->pdf = malloc(n * sizeof(double)); + s->pdf = cfmalloc(n * sizeof(double)); if ( s->pdf == NULL ) return; - perm = malloc(n * sizeof(size_t)); + perm = cfmalloc(n * sizeof(size_t)); if ( perm == NULL ) return; gsl_sort_index(perm, kvals, 1, n); @@ -367,7 +367,7 @@ void spectrum_set_pdf(Spectrum *s, double *kvals, double *heights, int n) s->k[i] = kvals[perm[i]]; s->pdf[i] = heights[perm[i]]; } - free(perm); + cffree(perm); s->n_samples = n; s->rep = SPEC_HISTOGRAM; @@ -393,8 +393,8 @@ static int read_esrf_spectrum(FILE *fh, Spectrum *s) k = srealloc(k, max_bins*sizeof(double)); samp = srealloc(samp, max_bins*sizeof(double)); if ( (k==NULL) || (samp==NULL) ) { - free(k); - free(samp); + cffree(k); + cffree(samp); return 1; } } @@ -406,8 +406,8 @@ static int read_esrf_spectrum(FILE *fh, Spectrum *s) } spectrum_set_pdf(s, k, samp, n_bins); - free(k); - free(samp); + cffree(k); + cffree(samp); return 0; } diff --git a/libcrystfel/src/stream.c b/libcrystfel/src/stream.c index 71dd7413..edbeb7af 100644 --- a/libcrystfel/src/stream.c +++ b/libcrystfel/src/stream.c @@ -453,7 +453,7 @@ int stream_write_chunk(Stream *st, const struct image *i, fprintf(st->fh, "hit = %i\n", i->hit); indexer = indexer_str(i->indexed_by); fprintf(st->fh, "indexed_by = %s\n", indexer); - free(indexer); + cffree(indexer); if ( i->indexed_by != INDEXING_NONE ) { fprintf(st->fh, "n_indexing_tries = %i\n", i->n_indexing_tries); } @@ -715,7 +715,7 @@ static void read_crystal(Stream *st, struct image *image, /* Add crystal to the list for this image */ n = image->n_crystals+1; - crystals_new = realloc(image->crystals, n*sizeof(Crystal *)); + crystals_new = cfrealloc(image->crystals, n*sizeof(Crystal *)); if ( crystals_new == NULL ) { ERROR("Failed to expand crystal list!\n"); @@ -733,7 +733,7 @@ static void parse_header(const char *line_in, struct image *image, char *line; char *pos; - line = strdup(line_in); + line = cfstrdup(line_in); chomp(line); pos = strchr(line, ' '); @@ -816,12 +816,12 @@ struct image *stream_read_chunk(Stream *st, StreamFlags srf) chomp(line); if ( strncmp(line, "Image filename: ", 16) == 0 ) { - image->filename = strdup(line+16); + image->filename = cfstrdup(line+16); have_filename = 1; } if ( strncmp(line, "Event: ", 7) == 0 ) { - image->ev = strdup(line+7); + image->ev = cfstrdup(line+7); } if ( strncmp(line, "hdf5/", 5) == 0 ) { @@ -928,7 +928,7 @@ struct image *stream_read_chunk(Stream *st, StreamFlags srf) char *stream_audit_info(Stream *st) { if ( st->audit_info == NULL ) return NULL; - return strdup(st->audit_info); + return cfstrdup(st->audit_info); } @@ -945,7 +945,7 @@ static int read_geometry_file(Stream *st) const size_t max_geom_len = 1024*1024; char *geom; - geom = malloc(max_geom_len); + geom = cfmalloc(max_geom_len); if ( geom == NULL ) { ERROR("Failed to allocate memory for geometry file\n"); return 1; @@ -962,7 +962,7 @@ static int read_geometry_file(Stream *st) if ( rval == NULL ) { ERROR("Failed to read stream geometry file.\n"); stream_close(st); - free(geom); + cffree(geom); return 1; } @@ -975,7 +975,7 @@ static int read_geometry_file(Stream *st) if ( len > max_geom_len-1 ) { ERROR("Stream's geometry file is too long (%li > %i).\n", (long)len, (int)max_geom_len); - free(geom); + cffree(geom); return 1; } else { strcat(geom, line); @@ -994,7 +994,7 @@ static int read_headers(Stream *st) int done = 0; size_t len = 0; - st->audit_info = malloc(4096); + st->audit_info = cfmalloc(4096); if ( st->audit_info == NULL ) { ERROR("Failed to allocate memory for audit information\n"); return 1; @@ -1041,7 +1041,7 @@ Stream *stream_open_for_read(const char *filename) { Stream *st; - st = malloc(sizeof(struct _stream)); + st = cfmalloc(sizeof(struct _stream)); if ( st == NULL ) return NULL; st->old_indexers = 0; st->audit_info = NULL; @@ -1058,7 +1058,7 @@ Stream *stream_open_for_read(const char *filename) } if ( st->fh == NULL ) { - free(st); + cffree(st); return NULL; } @@ -1108,7 +1108,7 @@ Stream *stream_open_fd_for_write(int fd, const DataTemplate *dtempl) { Stream *st; - st = malloc(sizeof(struct _stream)); + st = cfmalloc(sizeof(struct _stream)); if ( st == NULL ) return NULL; st->old_indexers = 0; st->audit_info = NULL; @@ -1120,7 +1120,7 @@ Stream *stream_open_fd_for_write(int fd, const DataTemplate *dtempl) st->fh = fdopen(fd, "w"); if ( st->fh == NULL ) { - free(st); + cffree(st); return NULL; } @@ -1165,7 +1165,7 @@ Stream *stream_open_for_write(const char *filename, { Stream *st; - st = malloc(sizeof(struct _stream)); + st = cfmalloc(sizeof(struct _stream)); if ( st == NULL ) return NULL; st->old_indexers = 0; st->audit_info = NULL; @@ -1178,7 +1178,7 @@ Stream *stream_open_for_write(const char *filename, st->fh = fopen(filename, "w"); if ( st->fh == NULL ) { ERROR("Failed to open stream.\n"); - free(st); + cffree(st); return NULL; } @@ -1209,11 +1209,11 @@ int stream_get_fd(Stream *st) void stream_close(Stream *st) { if ( st == NULL ) return; - free(st->audit_info); - free(st->geometry_file); + cffree(st->audit_info); + cffree(st->geometry_file); data_template_free(st->dtempl_read); fclose(st->fh); - free(st); + cffree(st); } @@ -1338,9 +1338,9 @@ struct _streamindex void stream_index_free(StreamIndex *index) { if ( index == NULL ) return; - free(index->keys); - free(index->ptrs); - free(index); + cffree(index->keys); + cffree(index->ptrs); + cffree(index); } @@ -1351,7 +1351,7 @@ static char *make_key(const char *filename, if ( ev == NULL ) ev = "//"; - key = malloc(strlen(filename)+strlen(ev)+2); + key = cfmalloc(strlen(filename)+strlen(ev)+2); if ( key == NULL ) return NULL; strcpy(key, filename); @@ -1398,14 +1398,14 @@ static void add_index_record(StreamIndex *index, char **new_keys; long int *new_ptrs; - new_keys = realloc(index->keys, - new_max_keys*sizeof(char *)); + new_keys = cfrealloc(index->keys, + new_max_keys*sizeof(char *)); if ( new_keys == NULL ) return; - new_ptrs = realloc(index->ptrs, - new_max_keys*sizeof(long int)); + new_ptrs = cfrealloc(index->ptrs, + new_max_keys*sizeof(long int)); if ( new_ptrs == NULL ) { - free(new_keys); + cffree(new_keys); return; } @@ -1436,7 +1436,7 @@ StreamIndex *stream_make_index(const char *filename) fh = fopen(filename, "r"); if ( fh == NULL ) return NULL; - index = malloc(sizeof(StreamIndex)); + index = cfmalloc(sizeof(StreamIndex)); if ( index == NULL ) { fclose(fh); return NULL; @@ -1467,11 +1467,11 @@ StreamIndex *stream_make_index(const char *filename) } if ( strncmp(line, "Image filename: ", 16) == 0 ) { - last_filename = strdup(line+16); + last_filename = cfstrdup(line+16); } if ( strncmp(line, "Event: ", 7) == 0 ) { - last_ev = strdup(line+7); + last_ev = cfstrdup(line+7); } if ( strcmp(line, STREAM_CHUNK_END_MARKER) == 0 ) { @@ -1483,8 +1483,8 @@ StreamIndex *stream_make_index(const char *filename) last_filename, last_ev); } - free(last_filename); - free(last_ev); + cffree(last_filename); + cffree(last_ev); last_start_pos = 0; last_filename = NULL; last_ev = NULL; diff --git a/libcrystfel/src/symmetry.c b/libcrystfel/src/symmetry.c index 6cda54a2..7568f2a1 100644 --- a/libcrystfel/src/symmetry.c +++ b/libcrystfel/src/symmetry.c @@ -66,7 +66,7 @@ struct _symopmask static void alloc_ops(SymOpList *ops) { - ops->ops = realloc(ops->ops, ops->max_ops*sizeof(IntegerMatrix *)); + ops->ops = cfrealloc(ops->ops, ops->max_ops*sizeof(IntegerMatrix *)); } @@ -82,13 +82,13 @@ SymOpMask *new_symopmask(const SymOpList *list) SymOpMask *m; int i; - m = malloc(sizeof(struct _symopmask)); + m = cfmalloc(sizeof(struct _symopmask)); if ( m == NULL ) return NULL; m->list = list; - m->mask = malloc(sizeof(int)*list->n_ops); + m->mask = cfmalloc(sizeof(int)*list->n_ops); if ( m->mask == NULL ) { - free(m); + cffree(m); return NULL; } @@ -104,7 +104,7 @@ SymOpMask *new_symopmask(const SymOpList *list) static SymOpList *new_symoplist() { SymOpList *new; - new = malloc(sizeof(SymOpList)); + new = cfmalloc(sizeof(SymOpList)); if ( new == NULL ) return NULL; new->max_ops = 16; new->n_ops = 0; @@ -129,9 +129,9 @@ void free_symoplist(SymOpList *ops) for ( i=0; in_ops; i++ ) { intmat_free(ops->ops[i]); } - if ( ops->ops != NULL ) free(ops->ops); - if ( ops->name != NULL ) free(ops->name); - free(ops); + if ( ops->ops != NULL ) cffree(ops->ops); + if ( ops->name != NULL ) cffree(ops->name); + cffree(ops); } /** @@ -142,8 +142,8 @@ void free_symoplist(SymOpList *ops) void free_symopmask(SymOpMask *m) { if ( m == NULL ) return; - free(m->mask); - free(m); + cffree(m->mask); + cffree(m); } @@ -186,9 +186,9 @@ static void add_symop_v(SymOpList *ops, for ( i=0; i<3; i++ ) intmat_set(m, i, 1, k[i]); for ( i=0; i<3; i++ ) intmat_set(m, i, 2, l[i]); - free(h); - free(k); - free(l); + cffree(h); + cffree(k); + cffree(l); add_symop(ops, m); } @@ -248,7 +248,7 @@ IntegerMatrix *get_symop(const SymOpList *ops, const SymOpMask *m, int idx) static signed int *v(signed int h, signed int k, signed int i, signed int l) { - signed int *vec = malloc(3*sizeof(signed int)); + signed int *vec = cfmalloc(3*sizeof(signed int)); if ( vec == NULL ) return NULL; /* Convert back to 3-index form now */ vec[0] = h-i; vec[1] = k-i; vec[2] = l; @@ -411,7 +411,7 @@ static SymOpList *make_1bar() { SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("-1"); + new->name = cfstrdup("-1"); expand_ops(new); return new; } @@ -420,7 +420,7 @@ static SymOpList *make_1bar() static SymOpList *make_1() { SymOpList *new = new_symoplist(); - new->name = strdup("1"); + new->name = cfstrdup("1"); expand_ops(new); return new; } @@ -433,7 +433,7 @@ static SymOpList *make_2m() SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("2/m"); + new->name = cfstrdup("2/m"); expand_ops(new); return new; } @@ -443,7 +443,7 @@ static SymOpList *make_2() { SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ - new->name = strdup("2"); + new->name = cfstrdup("2"); expand_ops(new); return new; } @@ -453,7 +453,7 @@ static SymOpList *make_m() { SymOpList *new = new_symoplist(); add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("m"); + new->name = cfstrdup("m"); expand_ops(new); return new; } @@ -467,7 +467,7 @@ static SymOpList *make_mmm() add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ add_symop_v(new, v(1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* m -| k */ - new->name = strdup("mmm"); + new->name = cfstrdup("mmm"); expand_ops(new); return new; } @@ -478,7 +478,7 @@ static SymOpList *make_222() SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ - new->name = strdup("222"); + new->name = cfstrdup("222"); expand_ops(new); return new; } @@ -489,7 +489,7 @@ static SymOpList *make_mm2() SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* m -| k */ - new->name = strdup("mm2"); + new->name = cfstrdup("mm2"); expand_ops(new); return new; } @@ -502,7 +502,7 @@ static SymOpList *make_4m() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("4/m"); + new->name = cfstrdup("4/m"); expand_ops(new); return new; } @@ -512,7 +512,7 @@ static SymOpList *make_4() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ - new->name = strdup("4"); + new->name = cfstrdup("4"); expand_ops(new); return new; } @@ -523,7 +523,7 @@ static SymOpList *make_4mm() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,1)); /* m -| l */ - new->name = strdup("4mm"); + new->name = cfstrdup("4mm"); expand_ops(new); return new; } @@ -534,7 +534,7 @@ static SymOpList *make_422() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ - new->name = strdup("422"); + new->name = cfstrdup("422"); expand_ops(new); return new; } @@ -544,7 +544,7 @@ static SymOpList *make_4bar() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* -4 // l */ - new->name = strdup("-4"); + new->name = cfstrdup("-4"); expand_ops(new); return new; } @@ -555,7 +555,7 @@ static SymOpList *make_4bar2m() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* -4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ - new->name = strdup("-42m"); + new->name = cfstrdup("-42m"); expand_ops(new); return new; } @@ -566,7 +566,7 @@ static SymOpList *make_4barm2() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* -4 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,-1)); /* 2 // h+k */ - new->name = strdup("-4m2"); + new->name = cfstrdup("-4m2"); expand_ops(new); return new; } @@ -578,7 +578,7 @@ static SymOpList *make_4mmm() add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,1)); /* m -| k */ add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("4/mmm"); + new->name = cfstrdup("4/mmm"); expand_ops(new); return new; } @@ -590,7 +590,7 @@ static SymOpList *make_3_R() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* 3 // h+k+l */ - new->name = strdup("3_R"); + new->name = cfstrdup("3_R"); expand_ops(new); return new; } @@ -601,7 +601,7 @@ static SymOpList *make_3bar_R() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* -3 // h+k+l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("-3_R"); + new->name = cfstrdup("-3_R"); expand_ops(new); return new; } @@ -612,7 +612,7 @@ static SymOpList *make_32_R() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* 3 // h+k+l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* 2 -| 3 */ - new->name = strdup("32_R"); + new->name = cfstrdup("32_R"); expand_ops(new); return new; } @@ -623,7 +623,7 @@ static SymOpList *make_3m_R() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* 3 // h+k+l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,1)); /* m */ - new->name = strdup("3m_R"); + new->name = cfstrdup("3m_R"); expand_ops(new); return new; } @@ -635,7 +635,7 @@ static SymOpList *make_3barm_R() add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* -3 // h+k+l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,1)); /* m */ - new->name = strdup("-3m_R"); + new->name = cfstrdup("-3m_R"); expand_ops(new); return new; } @@ -647,7 +647,7 @@ static SymOpList *make_3_H() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ - new->name = strdup("3_H"); + new->name = cfstrdup("3_H"); expand_ops(new); return new; } @@ -658,7 +658,7 @@ static SymOpList *make_3bar_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("-3_H"); + new->name = cfstrdup("-3_H"); expand_ops(new); return new; } @@ -669,7 +669,7 @@ static SymOpList *make_321_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,-1)); /* 2 // h */ - new->name = strdup("321_H"); + new->name = cfstrdup("321_H"); expand_ops(new); return new; } @@ -680,7 +680,7 @@ static SymOpList *make_312_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* 2 // h+k */ - new->name = strdup("312_H"); + new->name = cfstrdup("312_H"); expand_ops(new); return new; } @@ -691,7 +691,7 @@ static SymOpList *make_3m1_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,1)); /* m -| i */ - new->name = strdup("3m1_H"); + new->name = cfstrdup("3m1_H"); expand_ops(new); return new; } @@ -702,7 +702,7 @@ static SymOpList *make_31m_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,1)); /* m -| (k+i) */ - new->name = strdup("31m_H"); + new->name = cfstrdup("31m_H"); expand_ops(new); return new; } @@ -714,7 +714,7 @@ static SymOpList *make_3barm1_H() add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,-1)); /* 2 // h */ - new->name = strdup("-3m1_H"); + new->name = cfstrdup("-3m1_H"); expand_ops(new); return new; } @@ -726,7 +726,7 @@ static SymOpList *make_3bar1m_H() add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* 2 // h+k */ - new->name = strdup("-31m_H"); + new->name = cfstrdup("-31m_H"); expand_ops(new); return new; } @@ -738,7 +738,7 @@ static SymOpList *make_6() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,-1,0), v(-1,0,0,0), v(0,0,0,1)); /* 6 // l */ - new->name = strdup("6"); + new->name = cfstrdup("6"); expand_ops(new); return new; } @@ -748,7 +748,7 @@ static SymOpList *make_6bar() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,-1)); /* -6 // l */ - new->name = strdup("-6"); + new->name = cfstrdup("-6"); expand_ops(new); return new; } @@ -759,7 +759,7 @@ static SymOpList *make_6m() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,-1,0), v(-1,0,0,0), v(0,0,0,1)); /* 6 // l */ add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("6/m"); + new->name = cfstrdup("6/m"); expand_ops(new); return new; } @@ -770,7 +770,7 @@ static SymOpList *make_622() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,-1,0), v(-1,0,0,0), v(0,0,0,1)); /* 6 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,-1)); /* 2 // h */ - new->name = strdup("622"); + new->name = cfstrdup("622"); expand_ops(new); return new; } @@ -781,7 +781,7 @@ static SymOpList *make_6mm() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,-1,0), v(-1,0,0,0), v(0,0,0,1)); /* 6 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,1)); /* m -| i */ - new->name = strdup("6mm"); + new->name = cfstrdup("6mm"); expand_ops(new); return new; } @@ -792,7 +792,7 @@ static SymOpList *make_6barm2() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,-1)); /* -6 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,1)); /* m -| i */ - new->name = strdup("-6m2"); + new->name = cfstrdup("-6m2"); expand_ops(new); return new; } @@ -803,7 +803,7 @@ static SymOpList *make_6bar2m() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,-1)); /* -6 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,1)); /* m -| (k+i) */ - new->name = strdup("-62m"); + new->name = cfstrdup("-62m"); expand_ops(new); return new; } @@ -815,7 +815,7 @@ static SymOpList *make_6mmm() add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,-1)); /* -6 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,1)); /* m -| i */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("6/mmm"); + new->name = cfstrdup("6/mmm"); expand_ops(new); return new; } @@ -829,7 +829,7 @@ static SymOpList *make_23() add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ - new->name = strdup("23"); + new->name = cfstrdup("23"); expand_ops(new); return new; } @@ -842,7 +842,7 @@ static SymOpList *make_m3bar() add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("m-3"); + new->name = cfstrdup("m-3"); expand_ops(new); return new; } @@ -854,7 +854,7 @@ static SymOpList *make_432() add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1));/* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ - new->name = strdup("432"); + new->name = cfstrdup("432"); expand_ops(new); return new; } @@ -866,7 +866,7 @@ static SymOpList *make_4bar3m() add_symop_v(new, v(0,1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* -4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ - new->name = strdup("-43m"); + new->name = cfstrdup("-43m"); expand_ops(new); return new; } @@ -879,7 +879,7 @@ static SymOpList *make_m3barm() add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1));/* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("m-3m"); + new->name = cfstrdup("m-3m"); expand_ops(new); return new; } @@ -979,7 +979,7 @@ static SymOpList *getpg_arbitrary_ua(const char *sym, size_t s) return NULL; } - pg_type = strndup(sym, s-1); + pg_type = cfstrndup(sym, s-1); if ( pg_type == NULL ) { ERROR("Couldn't allocate string.\n"); return NULL; @@ -991,7 +991,7 @@ static SymOpList *getpg_arbitrary_ua(const char *sym, size_t s) pg_type); return NULL; } - free(pg_type); + cffree(pg_type); t = intmat_new(3, 3); if ( t == NULL ) return NULL; @@ -1027,14 +1027,14 @@ static SymOpList *getpg_arbitrary_ua(const char *sym, size_t s) transform_ops(pg, t); intmat_free(t); - new_name = malloc(64); + new_name = cfmalloc(64); if ( new_name == NULL ) { ERROR("Couldn't allocate space for PG name\n"); return NULL; } snprintf(new_name, 64, "%s_ua%c", pg->name, ua); - free(pg->name); + cffree(pg->name); pg->name = new_name; return pg; @@ -1115,7 +1115,7 @@ static void do_op(const IntegerMatrix *op, assert(ans != NULL); *he = ans[0]; *ke = ans[1]; *le = ans[2]; - free(ans); + cffree(ans); } @@ -1175,9 +1175,9 @@ void special_position(const SymOpList *ops, SymOpMask *m, assert(m->list == ops); n = num_equivs(ops, NULL); - htest = malloc(n*sizeof(signed int)); - ktest = malloc(n*sizeof(signed int)); - ltest = malloc(n*sizeof(signed int)); + htest = cfmalloc(n*sizeof(signed int)); + ktest = cfmalloc(n*sizeof(signed int)); + ltest = cfmalloc(n*sizeof(signed int)); for ( i=0; i %s", symmetry_name(source), symmetry_name(target)); twins->name = name; @@ -1716,7 +1716,7 @@ char *get_matrix_name(const IntegerMatrix *m, int col) int i; int printed = 0; - text = malloc(max_len+1); + text = cfmalloc(max_len+1); text[0] = '\0'; for ( i=0; i<3; i++ ) { @@ -1763,7 +1763,7 @@ static char *name_equiv(const IntegerMatrix *op) h = get_matrix_name(op, 0); k = get_matrix_name(op, 1); l = get_matrix_name(op, 2); - name = malloc(32); + name = cfmalloc(32); if ( strlen(h)+strlen(k)+strlen(l) == 3 ) { snprintf(name, 31, "%s%s%s", h, k, l); @@ -1794,7 +1794,7 @@ void describe_symmetry(const SymOpList *s) char *name = name_equiv(s->ops[i]); len = strlen(name); if ( len > max_len ) max_len = len; - free(name); + cffree(name); } if ( max_len < 8 ) max_len = 8; @@ -1810,7 +1810,7 @@ void describe_symmetry(const SymOpList *s) for ( j=0; jname = strdup(name); + ops->name = cfstrdup(name); } diff --git a/libcrystfel/src/thread-pool.c b/libcrystfel/src/thread-pool.c index 0951fcc6..fb17e7e4 100644 --- a/libcrystfel/src/thread-pool.c +++ b/libcrystfel/src/thread-pool.c @@ -88,11 +88,11 @@ static void *task_worker(void *pargsv) struct task_queue *q = w->tq; int *cookie_slot; - cookie_slot = malloc(sizeof(int)); + cookie_slot = cfmalloc(sizeof(int)); *cookie_slot = w->id; pthread_setspecific(status_label_key, cookie_slot); - free(w); + cffree(w); do { @@ -129,7 +129,7 @@ static void *task_worker(void *pargsv) } while ( 1 ); - free(cookie_slot); + cffree(cookie_slot); return NULL; } @@ -173,7 +173,7 @@ int run_threads(int n_threads, TPWorkFunc work, pthread_key_create(&status_label_key, NULL); - workers = malloc(n_threads * sizeof(pthread_t)); + workers = cfmalloc(n_threads * sizeof(pthread_t)); pthread_mutex_init(&q.lock, NULL); q.work = work; @@ -192,7 +192,7 @@ int run_threads(int n_threads, TPWorkFunc work, struct worker_args *w; - w = malloc(sizeof(struct worker_args)); + w = cfmalloc(sizeof(struct worker_args)); w->tq = &q; w->tqr = NULL; @@ -214,7 +214,7 @@ int run_threads(int n_threads, TPWorkFunc work, use_status_labels = 0; - free(workers); + cffree(workers); return q.n_completed; } diff --git a/libcrystfel/src/utils.c b/libcrystfel/src/utils.c index 04e028e9..7bfac487 100644 --- a/libcrystfel/src/utils.c +++ b/libcrystfel/src/utils.c @@ -436,9 +436,9 @@ char *cfstrndup(const char *s, size_t n) void *srealloc(void *arr, size_t new_size) { - void *new_arr = realloc(arr, new_size); + void *new_arr = cfrealloc(arr, new_size); if ( new_arr == NULL ) { - free(arr); + cffree(arr); return NULL; } else { return new_arr; @@ -448,7 +448,7 @@ void *srealloc(void *arr, size_t new_size) char *safe_strdup(const char *in) { if ( in == NULL ) return NULL; - return strdup(in); + return cfstrdup(in); } @@ -632,9 +632,9 @@ static int assplode_extract(char ***pbits, int n, size_t n_captured, size_t start, const char *a) { char **bits = *pbits; - bits = realloc(bits, sizeof(char *)*(n+1)); + bits = cfrealloc(bits, sizeof(char *)*(n+1)); assert(bits != NULL); - bits[n] = malloc(n_captured+1); + bits[n] = cfmalloc(n_captured+1); assert(bits[n] != NULL); memcpy(bits[n], a+start, n_captured); bits[n][n_captured] = '\0'; @@ -649,8 +649,8 @@ static int assplode_extract(char ***pbits, int n, size_t n_captured, * deliminators. * Store each segment in bits[0...n] where n is the number of segments and is * the return value. pbits = &bits - * Each segment needs to be freed with free() when finished with. - * The array of bits also needs to be freed with free() when finished with, + * Each segment needs to be freed with cffree() when finished with. + * The array of bits also needs to be freed with cffree() when finished with, * unless n=0 in which case bits==NULL */ int assplode(const char *a, const char *delims, char ***pbits, @@ -742,9 +742,9 @@ char *check_prefix(char *prefix) " with a slash. I'm going to add it for you.\n", prefix); STATUS("If this isn't what you want, run with --no-check-prefix.\n"); len = strlen(prefix)+2; - new = malloc(len); + new = cfmalloc(len); snprintf(new, len, "%s/", prefix); - free(prefix); + cffree(prefix); return new; } @@ -755,7 +755,7 @@ char *safe_basename(const char *in) char *cpy; char *res; - cpy = strdup(in); + cpy = cfstrdup(in); /* Get rid of any trailing slashes */ for ( i=strlen(cpy)-1; i>0; i-- ) { @@ -774,10 +774,10 @@ char *safe_basename(const char *in) } } - res = strdup(cpy+i); + res = cfstrdup(cpy+i); /* If we didn't find a previous slash, i==0 so res==cpy */ - free(cpy); + cffree(cpy); return res; } @@ -962,7 +962,7 @@ char *load_entire_file(const char *filename) return NULL; } - contents = malloc(statbuf.st_size+1); + contents = cfmalloc(statbuf.st_size+1); if ( contents == NULL ) { ERROR("Failed to allocate memory for file\n"); return NULL; @@ -971,14 +971,14 @@ char *load_entire_file(const char *filename) fh = fopen(filename, "r"); if ( fh == NULL ) { ERROR("Failed to open file '%s'\n", filename); - free(contents); + cffree(contents); return NULL; } if ( fread(contents, 1, statbuf.st_size, fh) != statbuf.st_size ) { ERROR("Failed to read file '%s'\n", filename); fclose(fh); - free(contents); + cffree(contents); return NULL; } contents[statbuf.st_size] = '\0'; -- cgit v1.2.3 From 513827a44d1ddd395f677a74617b42934ca9bc64 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 17 Jan 2024 16:43:32 +0100 Subject: Crystals shouldn't own RefLists (part 1) This is a terrible bit of API. A Crystal contains both the parameters for a calculation (e.g. prediction) and the results. Just look at post-refinement.c for an example of the mess this makes when trying to do calculations. This commit removes the reflection list from the Crystal structure. Future commits in this series will fix the resulting build carnage. This also gets rid of vestigial field pr_dud, and adds initialisers for all (remaining) fields. --- libcrystfel/src/crystal.c | 55 +++++++++++------------------------------------ libcrystfel/src/crystal.h | 25 +++++++-------------- libcrystfel/src/image.c | 1 - 3 files changed, 21 insertions(+), 60 deletions(-) diff --git a/libcrystfel/src/crystal.c b/libcrystfel/src/crystal.c index e5978795..a21283f9 100644 --- a/libcrystfel/src/crystal.c +++ b/libcrystfel/src/crystal.c @@ -3,11 +3,11 @@ * * A class representing a single crystal * - * Copyright © 2013-2021 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2013-2024 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: - * 2013-2020 Thomas White + * 2013-2024 Thomas White * 2016 Valerio Mariani * * This file is part of CrystFEL. @@ -31,7 +31,6 @@ #include "crystal.h" #include "utils.h" -#include "reflist-utils.h" /** @@ -41,30 +40,18 @@ struct _crystal { - /* Information about the crystal */ - UnitCell *cell; + UnitCell *cell; double m; /* Mosaicity in radians */ double osf; double Bfac; double profile_radius; - int pr_dud; double resolution_limit; - - /* Integrated (or about-to-be-integrated) reflections */ - RefList *reflections; - long long int n_saturated; /* Number of overloads */ - long long int n_implausible; /* Number of implausibly - * negative reflectionss */ - - /* User flag, e.g. for "this is a bad crystal". */ + long long int n_saturated; /* Number of overloads */ + long long int n_implausible; /* Number of implausibly negative reflectionss */ int user_flag; - - /* Text notes, which go in the stream */ - char *notes; - - /* Detector shift in metres */ - double det_shift_x; - double det_shift_y; + char *notes; /* Text notes, which go in the stream */ + double det_shift_x; /* Detector x-shift in metres */ + double det_shift_y; /* Detector y-shift in metres */ }; @@ -85,12 +72,15 @@ Crystal *crystal_new() if ( cryst == NULL ) return NULL; cryst->cell = NULL; - cryst->reflections = NULL; + cryst->m = 0.0; + cryst->osf = 1.0; + cryst->Bfac = 0.0; + cryst->profile_radius = 0.0; cryst->resolution_limit = INFINITY; cryst->n_saturated = 0; cryst->n_implausible = 0; - cryst->notes = NULL; cryst->user_flag = 0; + cryst->notes = NULL; cryst->det_shift_x = 0; cryst->det_shift_y = 0; @@ -149,13 +139,6 @@ Crystal *crystal_copy_deep(const Crystal *cryst) c->cell = cell; } - if ( cryst->reflections != NULL ) { - RefList *refls; - refls = copy_reflist(cryst->reflections); - if ( refls == NULL ) return NULL; - c->reflections = refls; - } - return c; } @@ -195,12 +178,6 @@ double crystal_get_profile_radius(const Crystal *cryst) } -RefList *crystal_get_reflections(Crystal *cryst) -{ - return cryst->reflections; -} - - double crystal_get_resolution_limit(Crystal *cryst) { return cryst->resolution_limit; @@ -272,12 +249,6 @@ void crystal_set_profile_radius(Crystal *cryst, double r) } -void crystal_set_reflections(Crystal *cryst, RefList *reflist) -{ - cryst->reflections = reflist; -} - - void crystal_set_resolution_limit(Crystal *cryst, double res) { cryst->resolution_limit = res; diff --git a/libcrystfel/src/crystal.h b/libcrystfel/src/crystal.h index 33764bc0..3f19386c 100644 --- a/libcrystfel/src/crystal.h +++ b/libcrystfel/src/crystal.h @@ -3,11 +3,11 @@ * * A class representing a single crystal * - * Copyright © 2013-2021 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2013-2024 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: - * 2013-2020 Thomas White + * 2013-2024 Thomas White * 2016 Valerio Mariani * * This file is part of CrystFEL. @@ -43,8 +43,6 @@ **/ typedef struct _crystal Crystal; -#include "reflist.h" - #ifdef __cplusplus extern "C" { #endif @@ -55,36 +53,29 @@ extern Crystal *crystal_copy_deep(const Crystal *cryst); extern void crystal_free(Crystal *cryst); extern UnitCell *crystal_get_cell(Crystal *cryst); -extern const UnitCell *crystal_get_cell_const(const Crystal *cryst); extern double crystal_get_profile_radius(const Crystal *cryst); -extern RefList *crystal_get_reflections(Crystal *cryst); extern double crystal_get_resolution_limit(Crystal *cryst); -extern long long int crystal_get_num_saturated_reflections(Crystal *cryst); -extern long long int crystal_get_num_implausible_reflections(Crystal *cryst); extern int crystal_get_user_flag(Crystal *cryst); extern double crystal_get_osf(Crystal *cryst); extern double crystal_get_Bfac(Crystal *cryst); extern double crystal_get_mosaicity(Crystal *cryst); extern const char *crystal_get_notes(Crystal *cryst); -extern void crystal_get_det_shift(Crystal *cryst, - double *shift_x, double* shift_y); +extern void crystal_get_det_shift(Crystal *cryst, double *shift_x, double *shift_y); +extern long long int crystal_get_num_saturated_reflections(Crystal *cryst); +extern long long int crystal_get_num_implausible_reflections(Crystal *cryst); extern void crystal_set_cell(Crystal *cryst, UnitCell *cell); extern void crystal_set_profile_radius(Crystal *cryst, double r); -extern void crystal_set_reflections(Crystal *cryst, RefList *reflist); extern void crystal_set_resolution_limit(Crystal *cryst, double res); -extern void crystal_set_num_saturated_reflections(Crystal *cryst, - long long int n); -extern void crystal_set_num_implausible_reflections(Crystal *cryst, - long long int n); extern void crystal_set_user_flag(Crystal *cryst, int flag); extern void crystal_set_osf(Crystal *cryst, double osf); extern void crystal_set_Bfac(Crystal *cryst, double B); extern void crystal_set_mosaicity(Crystal *cryst, double m); extern void crystal_set_notes(Crystal *cryst, const char *notes); -extern void crystal_set_det_shift(Crystal *cryst, - double shift_x, double shift_y); extern void crystal_add_notes(Crystal *cryst, const char *notes_add); +extern void crystal_set_det_shift(Crystal *cryst, double shift_x, double shift_y); +extern void crystal_set_num_saturated_reflections(Crystal *cryst, long long int n); +extern void crystal_set_num_implausible_reflections(Crystal *cryst, long long int n); #ifdef __cplusplus } diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 0789c6a3..9e9af85c 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -366,7 +366,6 @@ void free_all_crystals(struct image *image) if ( image->crystals == NULL ) return; for ( i=0; in_crystals; i++ ) { Crystal *cr = image->crystals[i]; - reflist_free(crystal_get_reflections(cr)); cell_free(crystal_get_cell(cr)); crystal_free(image->crystals[i]); } -- cgit v1.2.3 From 604c081d5f8dffc7a78cb07c245dae531342db04 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Jan 2024 09:46:26 +0100 Subject: Crystals shouldn't own RefLists (part 2) This commit replaces image.crystals with an array of small structs, each consisting of a Crystal-RefList pair. index.c and stream.c are updated, more to follow. --- libcrystfel/src/image.c | 28 ++++++++++++++++++++-------- libcrystfel/src/image.h | 12 ++++++++++-- libcrystfel/src/index.c | 9 ++++----- libcrystfel/src/stream.c | 48 +++++++++++++----------------------------------- 4 files changed, 47 insertions(+), 50 deletions(-) diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 9e9af85c..142598e3 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -317,35 +317,45 @@ void image_remove_feature(ImageFeatureList *flist, int idx) } -void image_add_crystal(struct image *image, Crystal *cryst) +void image_add_crystal_refls(struct image *image, + Crystal *cryst, + RefList *reflist) { - Crystal **crs; + struct crystal_refls *crs; int n; n = image->n_crystals; - crs = cfrealloc(image->crystals, (n+1)*sizeof(Crystal *)); + crs = cfrealloc(image->crystals, (n+1)*sizeof(struct crystal_refls)); if ( crs == NULL ) { ERROR("Failed to allocate memory for crystals.\n"); return; } - crs[n] = cryst; + crs[n].cr = cryst; + crs[n].refls = reflist; image->crystals = crs; image->n_crystals = n+1; } +void image_add_crystal(struct image *image, Crystal *cryst) +{ + image_add_crystal_refls(image, cryst, NULL); +} + + int remove_flagged_crystals(struct image *image) { int i; int n_bad = 0; for ( i=0; in_crystals; i++ ) { - if ( crystal_get_user_flag(image->crystals[i]) ) { + if ( crystal_get_user_flag(image->crystals[i].cr) ) { int j; - Crystal *deleteme = image->crystals[i]; + Crystal *deleteme = image->crystals[i].cr; cell_free(crystal_get_cell(deleteme)); crystal_free(deleteme); + reflist_free(image->crystals[i].refls); for ( j=i; jn_crystals-1; j++ ) { image->crystals[j] = image->crystals[j+1]; } @@ -365,11 +375,13 @@ void free_all_crystals(struct image *image) int i; if ( image->crystals == NULL ) return; for ( i=0; in_crystals; i++ ) { - Crystal *cr = image->crystals[i]; + Crystal *cr = image->crystals[i].cr; cell_free(crystal_get_cell(cr)); - crystal_free(image->crystals[i]); + crystal_free(image->crystals[i].cr); + reflist_free(image->crystals[i].refls); } cffree(image->crystals); + image->crystals = NULL; image->n_crystals = 0; } diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h index 7e4bad1f..beb66810 100644 --- a/libcrystfel/src/image.h +++ b/libcrystfel/src/image.h @@ -110,6 +110,12 @@ typedef enum } DataSourceType; +struct crystal_refls +{ + Crystal *cr; + RefList *refls; +}; + struct image { /** The image data, by panel */ @@ -124,8 +130,8 @@ struct image /** Non-zero if the frame was determined to be a "hit" */ int hit; - /**Array of crystals in the image */ - Crystal **crystals; + /** Array of crystals (with reflection lists) in the image */ + struct crystal_refls *crystals; /** The number of crystals in the image (size of \p crystals) */ int n_crystals; @@ -218,6 +224,8 @@ extern ImageFeatureList *sort_peaks(ImageFeatureList *flist); extern ImageFeatureList *image_feature_list_copy(const ImageFeatureList *flist); extern void image_add_crystal(struct image *image, Crystal *cryst); +extern void image_add_crystal_refls(struct image *image, + Crystal *cryst, RefList *reflist); extern int remove_flagged_crystals(struct image *image); extern void free_all_crystals(struct image *image); diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 4c35d2ca..7aea3b59 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -699,7 +699,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, int this_crystal = image->n_crystals - i - 1; /* ... starting at the end of the (complete) list ... */ - Crystal *cr = image->crystals[this_crystal]; + Crystal *cr = image->crystals[this_crystal].cr; crystal_set_profile_radius(cr, 0.02e9); crystal_set_mosaicity(cr, 0.0); @@ -756,7 +756,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, profile_start("cell-compare-to-others"); for ( j=0; jcrystals[j]; + Crystal *that_cr = image->crystals[j].cr; /* 'tols' is in frac (not %) and radians */ const double tols[] = {0.1, 0.1, 0.1, deg2rad(5.0), @@ -908,7 +908,7 @@ static int finished_retry(IndexingMethod indm, IndexingFlags flags, if ( flags & INDEXING_MULTI ) { /* Remove "used" spots and try for another lattice */ Crystal *cr; - cr = image->crystals[image->n_crystals-1]; + cr = image->crystals[image->n_crystals-1].cr; return delete_explained_peaks(image, cr); } else { return 1; @@ -945,8 +945,7 @@ void index_pattern_4(struct image *image, IndexingPrivate *ipriv, int *ping, if ( ipriv == NULL ) return; - image->crystals = NULL; - image->n_crystals = 0; + free_all_crystals(image); /* No peaks? */ if ( image->features == NULL ) return; diff --git a/libcrystfel/src/stream.c b/libcrystfel/src/stream.c index edbeb7af..ffe68162 100644 --- a/libcrystfel/src/stream.c +++ b/libcrystfel/src/stream.c @@ -338,11 +338,9 @@ static int num_integrated_reflections(RefList *list) } -static int write_crystal(Stream *st, Crystal *cr, - int include_reflections) +static int write_crystal(Stream *st, Crystal *cr, RefList *reflist) { UnitCell *cell; - RefList *reflist; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; @@ -389,7 +387,6 @@ static int write_crystal(Stream *st, Crystal *cr, fprintf(st->fh, "predict_refine/det_shift x = %.3f y = %.3f mm\n", det_shift_x*1e3, det_shift_y*1e3); - reflist = crystal_get_reflections(cr); if ( reflist != NULL ) { fprintf(st->fh, "diffraction_resolution_limit" @@ -406,20 +403,17 @@ static int write_crystal(Stream *st, Crystal *cr, } - if ( include_reflections ) { - - if ( reflist != NULL ) { + if ( reflist != NULL ) { - fprintf(st->fh, STREAM_REFLECTION_START_MARKER"\n"); - ret = write_stream_reflections(st->fh, reflist, - st->dtempl_write); - fprintf(st->fh, STREAM_REFLECTION_END_MARKER"\n"); + fprintf(st->fh, STREAM_REFLECTION_START_MARKER"\n"); + ret = write_stream_reflections(st->fh, reflist, + st->dtempl_write); + fprintf(st->fh, STREAM_REFLECTION_END_MARKER"\n"); - } else { + } else { - fprintf(st->fh, "No integrated reflections.\n"); + fprintf(st->fh, "No integrated reflections.\n"); - } } fprintf(st->fh, STREAM_CRYSTAL_END_MARKER"\n"); @@ -512,11 +506,11 @@ int stream_write_chunk(Stream *st, const struct image *i, } for ( j=0; jn_crystals; j++ ) { - if ( crystal_get_user_flag(i->crystals[j]) ) { + if ( crystal_get_user_flag(i->crystals[j].cr) ) { continue; } - ret = write_crystal(st, i->crystals[j], - srf & STREAM_REFLECTIONS); + ret = write_crystal(st, i->crystals[j].cr, + srf & STREAM_REFLECTIONS ? i->crystals[j].refls : NULL); } fprintf(st->fh, STREAM_CHUNK_END_MARKER"\n"); @@ -564,8 +558,7 @@ static void read_crystal(Stream *st, struct image *image, char unique_axis = '*'; LatticeType lattice_type = L_TRICLINIC; Crystal *cr; - int n; - Crystal **crystals_new; + RefList *reflist = NULL; double shift_x, shift_y; as.u = 0.0; as.v = 0.0; as.w = 0.0; @@ -664,8 +657,6 @@ static void read_crystal(Stream *st, struct image *image, if ( (strcmp(line, STREAM_REFLECTION_START_MARKER) == 0) && (srf & STREAM_REFLECTIONS) ) { - - RefList *reflist; reflist = read_stream_reflections_2_3(st); if ( reflist == NULL ) { ERROR("Failed while reading reflections\n"); @@ -673,9 +664,6 @@ static void read_crystal(Stream *st, struct image *image, ERROR("Event = %s\n", image->ev); break; } - - crystal_set_reflections(cr, reflist); - } if ( strcmp(line, STREAM_CRYSTAL_END_MARKER) == 0 ) break; @@ -713,17 +701,7 @@ static void read_crystal(Stream *st, struct image *image, /* Unused at the moment */ crystal_set_mosaicity(cr, 0.0); - /* Add crystal to the list for this image */ - n = image->n_crystals+1; - crystals_new = cfrealloc(image->crystals, n*sizeof(Crystal *)); - - if ( crystals_new == NULL ) { - ERROR("Failed to expand crystal list!\n"); - } else { - image->crystals = crystals_new; - image->crystals[image->n_crystals++] = cr; - } - + image_add_crystal_refls(image, cr, reflist); } -- cgit v1.2.3 From 8b51b44b1575a5e4c8d1c41924cebed93ff8d8cc Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Jan 2024 10:16:59 +0100 Subject: Crystals shouldn't own RefLists (part 3) This fixes integration.c, peaks.c and process_hkl.c. --- libcrystfel/src/integration.c | 36 ++++++++++++++++++------------------ libcrystfel/src/peaks.c | 12 ++++++------ src/process_hkl.c | 14 ++++++-------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/libcrystfel/src/integration.c b/libcrystfel/src/integration.c index cad0a75c..d2c06db7 100644 --- a/libcrystfel/src/integration.c +++ b/libcrystfel/src/integration.c @@ -1342,17 +1342,16 @@ static void setup_profile_boxes(struct intcontext *ic, RefList *list) void integrate_prof2d(IntegrationMethod meth, - Crystal *cr, struct image *image, IntDiag int_diag, + Crystal *cr, RefList *list, + struct image *image, IntDiag int_diag, signed int idh, signed int idk, signed int idl, double ir_inn, double ir_mid, double ir_out, pthread_mutex_t *term_lock, int **masks) { - RefList *list; UnitCell *cell; struct intcontext *ic; int i; - list = crystal_get_reflections(cr); cell = crystal_get_cell(cr); ic = intcontext_new(image, cell, meth, @@ -1593,12 +1592,12 @@ static double estimate_resolution(Crystal *cr, struct image *image) static void integrate_rings(IntegrationMethod meth, - Crystal *cr, struct image *image, IntDiag int_diag, + Crystal *cr, RefList *list, + struct image *image, IntDiag int_diag, signed int idh, signed int idk, signed int idl, double ir_inn, double ir_mid, double ir_out, pthread_mutex_t *term_lock, int **masks) { - RefList *list; Reflection *refl; RefListIterator *iter; UnitCell *cell; @@ -1606,7 +1605,6 @@ static void integrate_rings(IntegrationMethod meth, int n_rej = 0; int n_refl = 0; - list = crystal_get_reflections(cr); cell = crystal_get_cell(cr); ic = intcontext_new(image, cell, meth, @@ -1653,23 +1651,21 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, /* Predict all reflections */ for ( i=0; in_crystals; i++ ) { - RefList *list; double res; - double saved_R = crystal_get_profile_radius(image->crystals[i]); + double saved_R = crystal_get_profile_radius(image->crystals[i].cr); if ( overpredict ) { - crystal_set_profile_radius(image->crystals[i], + crystal_set_profile_radius(image->crystals[i].cr, saved_R * 5); } - res = estimate_resolution(image->crystals[i], image); - crystal_set_resolution_limit(image->crystals[i], res); + res = estimate_resolution(image->crystals[i].cr, image); + crystal_set_resolution_limit(image->crystals[i].cr, res); - list = predict_to_res(image->crystals[i], image, res+push_res); - crystal_set_reflections(image->crystals[i], list); + image->crystals[i].refls = predict_to_res(image->crystals[i].cr, image, res+push_res); if ( overpredict ) { - crystal_set_profile_radius(image->crystals[i], saved_R); + crystal_set_profile_radius(image->crystals[i].cr, saved_R); } } @@ -1681,22 +1677,26 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, for ( i=0; in_crystals; i++ ) { - Crystal *cr = image->crystals[i]; - switch ( meth & INTEGRATION_METHOD_MASK ) { case INTEGRATION_NONE : break; case INTEGRATION_RINGS : - integrate_rings(meth, cr, image, + integrate_rings(meth, + image->crystals[i].cr, + image->crystals[i].refls, + image, int_diag, idh, idk, idl, ir_inn, ir_mid, ir_out, term_lock, masks); break; case INTEGRATION_PROF2D : - integrate_prof2d(meth, cr, image, + integrate_prof2d(meth, + image->crystals[i].cr, + image->crystals[i].refls, + image, int_diag, idh, idk, idl, ir_inn, ir_mid, ir_out, term_lock, masks); diff --git a/libcrystfel/src/peaks.c b/libcrystfel/src/peaks.c index d56f6d03..63dd6966 100644 --- a/libcrystfel/src/peaks.c +++ b/libcrystfel/src/peaks.c @@ -62,15 +62,15 @@ /** \file peaks.h */ -static void add_crystal_to_mask(struct image *image, - struct detgeom_panel *p, int pn, - double ir_inn, int *mask, Crystal *cr) +static void add_reflections_to_mask(struct image *image, + struct detgeom_panel *p, int pn, + double ir_inn, int *mask, RefList *list) { Reflection *refl; RefListIterator *iter; /* Loop over all reflections */ - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -121,8 +121,8 @@ int *make_BgMask(struct image *image, struct detgeom_panel *p, if ( image->crystals == NULL ) return mask; for ( i=0; in_crystals; i++ ) { - add_crystal_to_mask(image, p, pn, ir_inn, - mask, image->crystals[i]); + add_reflections_to_mask(image, p, pn, ir_inn, + mask, image->crystals[i].refls); } return mask; diff --git a/src/process_hkl.c b/src/process_hkl.c index be1c95d4..31e4b1fc 100644 --- a/src/process_hkl.c +++ b/src/process_hkl.c @@ -271,7 +271,7 @@ static void apply_kpred(double k, RefList *list) static int merge_crystal(RefList *model, struct image *image, Crystal *cr, - RefList *reference, const SymOpList *sym, + RefList *new_refl, RefList *reference, const SymOpList *sym, double **hist_vals, signed int hist_h, signed int hist_k, signed int hist_l, int *hist_n, struct polarisation p, double min_snr, double max_adu, @@ -280,11 +280,8 @@ static int merge_crystal(RefList *model, struct image *image, Crystal *cr, { Reflection *refl; RefListIterator *iter; - RefList *new_refl; double scale; - new_refl = crystal_get_reflections(cr); - /* First, correct for polarisation */ apply_kpred(1.0/image->lambda, new_refl); polarisation_correction(new_refl, crystal_get_cell(cr), p); @@ -309,7 +306,7 @@ static int merge_crystal(RefList *model, struct image *image, Crystal *cr, scale = 1.0; } - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(new_refl, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -431,7 +428,8 @@ static int merge_stream(Stream *st, for ( i=0; in_crystals; i++ ) { - Crystal *cr = image->crystals[i]; + Crystal *cr = image->crystals[i].cr; + RefList *refls = image->crystals[i].refls; n_crystals_seen++; if ( (n_crystals_seen > start_after) @@ -440,8 +438,8 @@ static int merge_stream(Stream *st, { int r; n_crystals++; - r = merge_crystal(model, image, cr, reference, - sym, hist_vals, + r = merge_crystal(model, image, cr, refls, + reference, sym, hist_vals, hist_h, hist_k, hist_l, hist_i, p, min_snr, max_adu, push_res, -- cgit v1.2.3 From 36b79bb6f65018fe74f63291857263c6a14d5697 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Jan 2024 10:25:47 +0100 Subject: Crystals shouldn't own RefLists (part 4) This fixes the general prediction/partiality parts. --- libcrystfel/src/geometry.c | 50 ++++++++++++++++++---------------------- libcrystfel/src/geometry.h | 6 +++-- libcrystfel/src/predict-refine.c | 14 +++-------- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/libcrystfel/src/geometry.c b/libcrystfel/src/geometry.c index 32da348a..10a7fa19 100644 --- a/libcrystfel/src/geometry.c +++ b/libcrystfel/src/geometry.c @@ -512,13 +512,11 @@ RefList *predict_to_res(Crystal *cryst, struct image *image, double max_res) } -static void set_unity_partialities(Crystal *cryst) +static void set_unity_partialities(RefList *list) { - RefList *list; Reflection *refl; RefListIterator *iter; - list = crystal_get_reflections(cryst); if ( list == NULL ) { ERROR("No reflections for partiality calculation!\n"); return; @@ -533,13 +531,11 @@ static void set_unity_partialities(Crystal *cryst) } -static void set_random_partialities(Crystal *cryst, int image_serial) +static void set_random_partialities(RefList *list, int image_serial) { - RefList *list; Reflection *refl; RefListIterator *iter; - list = crystal_get_reflections(cryst); if ( list == NULL ) { ERROR("No reflections for partiality calculation!\n"); return; @@ -674,16 +670,14 @@ static double do_integral(double q2, double zl, double R, } -static void ginn_spectrum_partialities(Crystal *cryst, struct image *image) +static void ginn_spectrum_partialities(RefList *list, Crystal *cryst, struct image *image) { - RefList *list; Reflection *refl; RefListIterator *iter; double r0, m; UnitCell *cell; double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - list = crystal_get_reflections(cryst); if ( list == NULL ) { ERROR("No reflections for partiality calculation!\n"); return; @@ -701,7 +695,7 @@ static void ginn_spectrum_partialities(Crystal *cryst, struct image *image) r0 = fabs(crystal_get_profile_radius(cryst)); m = crystal_get_mosaicity(cryst); - for ( refl = first_refl(crystal_get_reflections(cryst), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -738,16 +732,14 @@ static void ginn_spectrum_partialities(Crystal *cryst, struct image *image) } -static void ewald_offset_partialities(Crystal *cryst, struct image *image) +static void ewald_offset_partialities(RefList *list, Crystal *cryst, struct image *image) { - RefList *list; Reflection *refl; RefListIterator *iter; double r0, m; UnitCell *cell; double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - list = crystal_get_reflections(cryst); if ( list == NULL ) { ERROR("No reflections for partiality calculation!\n"); return; @@ -765,7 +757,7 @@ static void ewald_offset_partialities(Crystal *cryst, struct image *image) r0 = fabs(crystal_get_profile_radius(cryst)); m = crystal_get_mosaicity(cryst); - for ( refl = first_refl(crystal_get_reflections(cryst), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -793,36 +785,40 @@ static void ewald_offset_partialities(Crystal *cryst, struct image *image) /** + * \param list A \ref RefList * \param cryst A \ref Crystal + * \param image An image structure * \param pmodel A \ref PartialityModel * - * Calculates the partialities for the reflections in \p cryst, given the current - * crystal and image parameters. The crystal's image and reflection lists - * must be set. The specified \ref PartialityModel will be used. + * Calculates the partialities for the reflections in \p list, given the current + * state of \p cryst and \p image. + * + * If \p pmodel is PMODEL_RANDOM or PMODEL_UNITY, then \p cryst can be NULL. + * If \p pmodel is PMODEL_UNITY, then \p image can also be NULL. * * You must not have changed the crystal or image parameters since you last * called \ref predict_to_res or \ref update_predictions, because this function * relies on the limiting wavelength values calculated by those functions. */ -void calculate_partialities(Crystal *cryst, struct image *image, +void calculate_partialities(RefList *list, Crystal *cryst, struct image *image, PartialityModel pmodel) { switch ( pmodel ) { case PMODEL_UNITY : - set_unity_partialities(cryst); + set_unity_partialities(list); break; case PMODEL_XSPHERE : - ginn_spectrum_partialities(cryst, image); + ginn_spectrum_partialities(list, cryst, image); break; case PMODEL_OFFSET : - ewald_offset_partialities(cryst, image); + ewald_offset_partialities(list, cryst, image); break; case PMODEL_RANDOM : - set_random_partialities(cryst, image->serial); + set_random_partialities(list, image->serial); break; case PMODEL_GGPM : @@ -839,18 +835,18 @@ void calculate_partialities(Crystal *cryst, struct image *image, /** + * \param list A \ref RefList * \param cryst A \ref Crystal * \param image An image structure * * Updates the predicted reflections (positions and excitation errors, but not - * the actual partialities) of \p cryst's reflections as seen in \p image, - * according to the current state of the crystal (e.g. its unit cell - * parameters). + * the actual partialities) in \p list, to match the current statea of + * \p crys as seen in \p image. * * If you need to update the partialities as well, call * \ref calculate_partialities afterwards. */ -void update_predictions(Crystal *cryst, struct image *image) +void update_predictions(RefList *list, Crystal *cryst, struct image *image) { Reflection *refl; RefListIterator *iter; @@ -861,7 +857,7 @@ void update_predictions(Crystal *cryst, struct image *image) cell_get_reciprocal(crystal_get_cell(cryst), &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); - for ( refl = first_refl(crystal_get_reflections(cryst), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { diff --git a/libcrystfel/src/geometry.h b/libcrystfel/src/geometry.h index b9f98694..217cb9ea 100644 --- a/libcrystfel/src/geometry.h +++ b/libcrystfel/src/geometry.h @@ -80,10 +80,12 @@ struct polarisation extern RefList *predict_to_res(Crystal *cryst, struct image *image, double max_res); -extern void calculate_partialities(Crystal *cryst, struct image *image, +extern void calculate_partialities(RefList *list, + Crystal *cryst, + struct image *image, PartialityModel pmodel); -extern void update_predictions(Crystal *cryst, struct image *image); +extern void update_predictions(RefList *list, Crystal *cryst, struct image *image); extern struct polarisation parse_polarisation(const char *text); extern void polarisation_correction(RefList *list, UnitCell *cell, struct polarisation p); diff --git a/libcrystfel/src/predict-refine.c b/libcrystfel/src/predict-refine.c index 4cd0e54e..5fb9b4cc 100644 --- a/libcrystfel/src/predict-refine.c +++ b/libcrystfel/src/predict-refine.c @@ -488,8 +488,7 @@ static int pair_peaks(struct image *image, Crystal *cr, /* Get the excitation errors and detector positions for the candidate * reflections */ - crystal_set_reflections(cr, all_reflist); - update_predictions(cr, image); + update_predictions(all_reflist, cr, image); /* Pass over the peaks again, keeping only the ones which look like * good pairings */ @@ -529,7 +528,6 @@ static int pair_peaks(struct image *image, Crystal *cr, } reflist_free(all_reflist); - crystal_set_reflections(cr, NULL); /* Sort the pairings by excitation error and look for a transition * between good pairings and outliers */ @@ -569,9 +567,7 @@ int refine_radius(Crystal *cr, struct image *image) reflist_free(reflist); return 1; } - crystal_set_reflections(cr, reflist); - update_predictions(cr, image); - crystal_set_reflections(cr, NULL); + update_predictions(reflist, cr, image); qsort(rps, n_acc, sizeof(struct reflpeak), cmpd2); n = (n_acc-1) - n_acc/50; @@ -820,7 +816,6 @@ int refine_prediction(struct image *image, Crystal *cr, reflist_free(reflist); return 1; } - crystal_set_reflections(cr, reflist); Minvs = make_panel_minvs(image->detgeom); @@ -833,7 +828,6 @@ int refine_prediction(struct image *image, Crystal *cr, if ( max_I <= 0.0 ) { ERROR("All peaks negative?\n"); cffree(rps); - crystal_set_reflections(cr, NULL); return 1; } for ( i=0; i Date: Thu, 18 Jan 2024 15:16:52 +0100 Subject: Crystals shouldn't own RefLists (part 5) This fixes the entire partialator/scaling/rejection part. --- src/merge.c | 34 ++++++++------ src/merge.h | 8 ++-- src/partialator.c | 125 ++++++++++++++++++++++++-------------------------- src/post-refinement.c | 98 +++++++++++++++++++-------------------- src/post-refinement.h | 7 +-- src/rejection.c | 43 +++++++++-------- src/rejection.h | 6 +-- src/scaling.c | 25 +++++----- src/scaling.h | 7 +-- 9 files changed, 178 insertions(+), 175 deletions(-) diff --git a/src/merge.c b/src/merge.c index 0a5c5f14..4a2dae66 100644 --- a/src/merge.c +++ b/src/merge.c @@ -55,7 +55,7 @@ struct merge_queue_args { RefList *full; pthread_rwlock_t full_lock; - Crystal **crystals; + struct crystal_refls *crystals; int n_started; double push_res; int use_weak; @@ -68,6 +68,7 @@ struct merge_worker_args { struct merge_queue_args *qargs; Crystal *crystal; + RefList *refls; int crystal_number; int n_reflections; }; @@ -81,7 +82,9 @@ static void *create_merge_job(void *vqargs) wargs = malloc(sizeof(struct merge_worker_args)); wargs->qargs = qargs; wargs->crystal_number = qargs->n_started; - wargs->crystal = qargs->crystals[qargs->n_started++]; + wargs->crystal = qargs->crystals[qargs->n_started].cr; + wargs->refls = qargs->crystals[qargs->n_started].refls; + qargs->n_started++; return wargs; } @@ -180,7 +183,7 @@ static void run_merge_job(void *vwargs, int cookie) G = crystal_get_osf(cr); B = crystal_get_Bfac(cr); - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(wargs->refls, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -262,8 +265,8 @@ static void finalise_merge_job(void *vqargs, void *vwargs) } -RefList *merge_intensities(Crystal **crystals, int n, int n_threads, - int min_meas, +RefList *merge_intensities(struct crystal_refls *crystals, int n, + int n_threads, int min_meas, double push_res, int use_weak, int ln_merge) { RefList *full; @@ -364,7 +367,7 @@ double correct_reflection(double val, Reflection *refl, double osf, double Bfac, } -double residual(Crystal *cr, const RefList *full, int free, +double residual(RefList *list, Crystal *cr, const RefList *full, int free, int *pn_used, const char *filename) { Reflection *refl; @@ -376,7 +379,7 @@ double residual(Crystal *cr, const RefList *full, int free, double B = crystal_get_Bfac(cr); UnitCell *cell = crystal_get_cell(cr); - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -420,7 +423,8 @@ double residual(Crystal *cr, const RefList *full, int free, } -double log_residual(Crystal *cr, const RefList *full, int free, +double log_residual(RefList *list, Crystal *cr, + const RefList *full, int free, int *pn_used, const char *filename) { double dev = 0.0; @@ -439,7 +443,7 @@ double log_residual(Crystal *cr, const RefList *full, int free, } } - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -487,7 +491,7 @@ double log_residual(Crystal *cr, const RefList *full, int free, /* Has to match run_merge_job to be useful */ -void write_unmerged(const char *fn, Crystal **crystals, int n_crystals) +void write_unmerged(const char *fn, struct crystal_refls *crystals, int n_crystals) { FILE *fh; int i; @@ -506,17 +510,17 @@ void write_unmerged(const char *fn, Crystal **crystals, int n_crystals) UnitCell *cell; fprintf(fh, "Crystal %i\n", i); - if ( crystal_get_user_flag(crystals[i]) ) { + if ( crystal_get_user_flag(crystals[i].cr) ) { fprintf(fh, "Flagged: yes\n"); } else { fprintf(fh, "Flagged: no\n"); } - G = crystal_get_osf(crystals[i]); - B = crystal_get_Bfac(crystals[i]); - cell = crystal_get_cell(crystals[i]); + G = crystal_get_osf(crystals[i].cr); + B = crystal_get_Bfac(crystals[i].cr); + cell = crystal_get_cell(crystals[i].cr); - for ( refl = first_refl(crystal_get_reflections(crystals[i]), &iter); + for ( refl = first_refl(crystals[i].refls, &iter); refl != NULL; refl = next_refl(refl, iter) ) { diff --git a/src/merge.h b/src/merge.h index 5f7e0e64..e304db78 100644 --- a/src/merge.h +++ b/src/merge.h @@ -43,7 +43,7 @@ #define MIN_PART_MERGE (0.3) -extern RefList *merge_intensities(Crystal **crystals, int n, int n_threads, +extern RefList *merge_intensities(struct crystal_refls *crystals, int n, int n_threads, int min_meas, double push_res, int use_weak, int ln_merge); @@ -53,12 +53,12 @@ extern double correct_reflection_nopart(double val, Reflection *refl, extern double correct_reflection(double val, Reflection *refl, double osf, double Bfac, double res); -extern double residual(Crystal *cr, const RefList *full, int free, +extern double residual(RefList *list, Crystal *cr, const RefList *full, int free, int *pn_used, const char *filename); -extern double log_residual(Crystal *cr, const RefList *full, int free, +extern double log_residual(RefList *list, Crystal *cr, const RefList *full, int free, int *pn_used, const char *filename); -extern void write_unmerged(const char *fn, Crystal **crystals, int n_crystals); +extern void write_unmerged(const char *fn, struct crystal_refls *crystals, int n_crystals); #endif /* MERGE */ diff --git a/src/partialator.c b/src/partialator.c index 6d362a01..659a12c5 100644 --- a/src/partialator.c +++ b/src/partialator.c @@ -169,14 +169,14 @@ static void add_to_csplit(struct custom_split *csplit, const char *id, /* Write two-way split results (i.e. for CC1/2 etc) for this list of crystals */ -static void write_split(Crystal **crystals, int n_crystals, const char *outfile, - int nthreads, PartialityModel pmodel, +static void write_split(struct crystal_refls *crystals, int n_crystals, + const char *outfile, int nthreads, PartialityModel pmodel, int min_measurements, SymOpList *sym, double push_res) { char tmp[1024]; RefList *split; - Crystal **crystals1; - Crystal **crystals2; + struct crystal_refls *crystals1; + struct crystal_refls *crystals2; int n_crystals1 = 0; int n_crystals2 = 0; int i; @@ -186,13 +186,12 @@ static void write_split(Crystal **crystals, int n_crystals, const char *outfile, return; } - crystals1 = malloc(n_crystals * sizeof(Crystal *)); + crystals1 = malloc(n_crystals * sizeof(struct crystal_refls)); if ( crystals1 == NULL ) return; - crystals2 = malloc(n_crystals * sizeof(Crystal *)); + crystals2 = malloc(n_crystals * sizeof(struct crystal_refls)); if ( crystals2 == NULL ) return; - for ( i=0; in_datasets; i++ ) { /* Try to find a crystal with dsn = i */ - if ( find_first_crystal(crystals, images, n_crystals, csplit, i) != -1 ) + if ( find_first_crystal(images, n_crystals, csplit, i) != -1 ) { n_cry++; } else { @@ -735,7 +735,7 @@ static void write_to_pgraph(FILE *fh, RefList *list, RefList *full, Crystal *cr, } -static void write_pgraph(RefList *full, Crystal **crystals, int n_crystals, +static void write_pgraph(RefList *full, struct crystal_refls *crystals, int n_crystals, signed int iter, const char *suff, const char *log_folder) { @@ -761,16 +761,16 @@ static void write_pgraph(RefList *full, Crystal **crystals, int n_crystals, } for ( i=0; icr = qargs->crystals[qargs->next]; + task->cr = qargs->crystals[qargs->next].cr; + task->refls = qargs->crystals[qargs->next].refls; task->image = qargs->images[qargs->next]; task->full = qargs->full; task->iter = qargs->iter; @@ -946,12 +948,13 @@ static void *get_log_task(void *vp) static void write_logs(void *vp, int cookie) { struct log_args *args = vp; - write_specgraph(args->cr, args->image, args->full, args->iter, args->cnum, - args->log_folder); - write_gridscan(args->cr, args->image, args->full, args->iter, args->cnum, - args->scaleflags, args->pmodel, args->log_folder); - write_test_logs(args->cr, args->image, args->full, args->iter, args->cnum, - args->log_folder); + write_specgraph(args->refls, args->cr, args->image, args->full, + args->iter, args->cnum, args->log_folder); + write_gridscan(args->refls, args->cr, args->image, args->full, + args->iter, args->cnum, args->scaleflags, args->pmodel, + args->log_folder); + write_test_logs(args->cr, args->image, args->full, args->iter, + args->cnum, args->log_folder); } @@ -965,7 +968,7 @@ static void done_log(void *vqargs, void *vp) } -static void write_logs_parallel(Crystal **crystals, struct image **images, +static void write_logs_parallel(struct crystal_refls *crystals, struct image **images, int n_crystals, RefList *full, int iter, int n_threads, int scaleflags, PartialityModel pmodel, @@ -1088,7 +1091,7 @@ int main(int argc, char *argv[]) int no_scale = 0; int no_Bscale = 0; int no_pr = 0; - Crystal **crystals; + struct crystal_refls *crystals; struct image **images; char *pmodel_str = NULL; PartialityModel pmodel = PMODEL_XSPHERE; @@ -1566,7 +1569,6 @@ int main(int argc, char *argv[]) do { struct image *image; - RefList *as; int i; image = stream_read_chunk(st, STREAM_REFLECTIONS); @@ -1580,41 +1582,39 @@ int main(int argc, char *argv[]) for ( i=0; in_crystals; i++ ) { Crystal *cr; - Crystal **crystals_new; + struct crystal_refls *crystals_new; struct image **images_new; RefList *cr_refl; - RefList *cr_refl_raw; struct image *image_for_crystal; double lowest_r; n_crystals_seen++; if ( n_crystals_seen <= start_after ) continue; - if ( crystal_get_resolution_limit(image->crystals[i]) < min_res ) continue; + if ( crystal_get_resolution_limit(image->crystals[i].cr) < min_res ) continue; - lowest_r = lowest_reflection(crystal_get_cell(image->crystals[i])); - if ( crystal_get_profile_radius(image->crystals[i]) > 0.5*lowest_r ) { + lowest_r = lowest_reflection(crystal_get_cell(image->crystals[i].cr)); + if ( crystal_get_profile_radius(image->crystals[i].cr) > 0.5*lowest_r ) { ERROR("Rejecting %s %s crystal %i because " "profile radius is obviously too big (%e %e).\n", image->filename, image->ev, i, - crystal_get_profile_radius(image->crystals[i]), + crystal_get_profile_radius(image->crystals[i].cr), lowest_r); continue; } crystals_new = realloc(crystals, - (n_crystals+1)*sizeof(Crystal *)); + (n_crystals+1)*sizeof(struct crystal_refls)); if ( crystals_new == NULL ) { ERROR("Failed to allocate memory for crystal " "list.\n"); return 1; } crystals = crystals_new; - crystals[n_crystals] = crystal_copy_deep(image->crystals[i]); - cr = crystals[n_crystals]; + cr = crystal_copy_deep(image->crystals[i].cr); + crystals[n_crystals].cr = cr; - images_new = realloc(images, - (n_crystals+1)*sizeof(struct image *)); + images_new = realloc(images, (n_crystals+1)*sizeof(struct image *)); if ( images_new == NULL ) { ERROR("Failed to allocate memory for image list\n"); return 1; @@ -1631,9 +1631,8 @@ int main(int argc, char *argv[]) *image_for_crystal = *image; images[n_crystals] = image_for_crystal; - image_for_crystal->n_crystals = 1; - image_for_crystal->crystals = malloc(sizeof(Crystal *)); - image_for_crystal->crystals[0] = cr; + image_for_crystal->n_crystals = 0; + image_for_crystal->crystals = NULL; image_for_crystal->filename = strdup(image->filename); image_for_crystal->ev = safe_strdup(image->ev); image_for_crystal->detgeom = NULL; @@ -1644,19 +1643,16 @@ int main(int argc, char *argv[]) image_for_crystal->bad = NULL; image_for_crystal->sat = NULL; - /* This is the raw list of reflections */ - cr_refl_raw = crystal_get_reflections(cr); - - cr_refl = apply_max_adu(cr_refl_raw, max_adu); - reflist_free(cr_refl_raw); - + cr_refl = apply_max_adu(image->crystals[i].refls, max_adu); if ( !no_free ) select_free_reflections(cr_refl, rng); - - as = asymmetric_indices(cr_refl, sym); - crystal_set_reflections(cr, as); - crystal_set_user_flag(cr, PRFLAG_OK); + image_add_crystal_refls(image_for_crystal, cr, + asymmetric_indices(cr_refl, sym)); reflist_free(cr_refl); + crystals[n_crystals].cr = image_for_crystal->crystals[0].cr; + crystals[n_crystals].refls = image_for_crystal->crystals[0].refls; + + crystal_set_user_flag(cr, PRFLAG_OK); if ( set_initial_params(cr, image_for_crystal, sparams_fh, force_bandwidth, force_radius, force_lambda) ) @@ -1697,14 +1693,13 @@ int main(int argc, char *argv[]) STATUS("Initial partiality calculation...\n"); for ( icryst=0; icrystcr_tgt, &pv->image_tgt); - calculate_partialities(pv->cr_tgt, &pv->image_tgt, pv->pmodel); + update_predictions(pv->refls, pv->cr_tgt, &pv->image_tgt); + calculate_partialities(pv->refls, pv->cr_tgt, &pv->image_tgt, pv->pmodel); - return residual(pv->cr_tgt, pv->full, free, NULL, NULL); + return residual(pv->refls, pv->cr_tgt, pv->full, free, NULL, NULL); } @@ -263,9 +264,9 @@ static void reindex_cell(UnitCell *cell, SymOpList *amb, int idx) } -static void try_reindex(Crystal *crin, struct image *image, const RefList *full, - SymOpList *sym, SymOpList *amb, int scaleflags, - PartialityModel pmodel) +static void try_reindex(RefList **prefls, Crystal *crin, struct image *image, + const RefList *full, SymOpList *sym, SymOpList *amb, + int scaleflags, PartialityModel pmodel) { Crystal *cr; double residual_original; @@ -273,8 +274,8 @@ static void try_reindex(Crystal *crin, struct image *image, const RefList *full, if ( sym == NULL || amb == NULL ) return; - if ( scale_one_crystal(crin, full, scaleflags) ) return; - residual_original = residual(crin, full, 0, NULL, NULL); + if ( scale_one_crystal(*prefls, crin, full, scaleflags) ) return; + residual_original = residual(*prefls, crin, full, 0, NULL, NULL); cr = crystal_copy(crin); @@ -291,23 +292,20 @@ static void try_reindex(Crystal *crin, struct image *image, const RefList *full, reindex_cell(cell, amb, idx); crystal_set_cell(cr, cell); - list = reindex_reflections(crystal_get_reflections(crin), - amb, sym, idx); - crystal_set_reflections(cr, list); - - update_predictions(cr, image); - calculate_partialities(cr, image, pmodel); - - if ( scale_one_crystal(cr, full, scaleflags) ) return; - residual_flipped = residual(cr, full, 0, NULL, NULL); + list = reindex_reflections(*prefls, amb, sym, idx); + update_predictions(list, cr, image); + calculate_partialities(list, cr, image, pmodel); + if ( scale_one_crystal(list, cr, full, scaleflags) ) return; + residual_flipped = residual(list, cr, full, 0, NULL, NULL); if ( residual_flipped < residual_original ) { crystal_set_cell(crin, cell); - crystal_set_reflections(crin, list); + reflist_free(*prefls); + *prefls = list; residual_original = residual_flipped; } else { cell_free(crystal_get_cell(cr)); - reflist_free(crystal_get_reflections(cr)); + reflist_free(list); } } @@ -365,7 +363,7 @@ void write_test_logs(Crystal *crystal, struct image *image, const RefList *full, } -void write_specgraph(Crystal *crystal, struct image *image, const RefList *full, +void write_specgraph(RefList *list, Crystal *crystal, struct image *image, const RefList *full, signed int cycle, int serial, const char *log_folder) { @@ -405,7 +403,7 @@ void write_specgraph(Crystal *crystal, struct image *image, const RefList *full, ins[1] = '\0'; } - for ( refl = first_refl(crystal_get_reflections(crystal), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -440,7 +438,8 @@ void write_specgraph(Crystal *crystal, struct image *image, const RefList *full, } -static void write_angle_grid(Crystal *cr, struct image *image, const RefList *full, +static void write_angle_grid(RefList *list_in, Crystal *cr, struct image *image, + const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) @@ -449,7 +448,6 @@ static void write_angle_grid(Crystal *cr, struct image *image, const RefList *fu char fn[64]; char ins[16]; struct rf_priv priv; - RefList *list; UnitCell *cell; Spectrum *spectrum; @@ -463,8 +461,7 @@ static void write_angle_grid(Crystal *cr, struct image *image, const RefList *fu priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - list = copy_reflist(crystal_get_reflections(cr)); - crystal_set_reflections(priv.cr_tgt, list); + priv.refls = copy_reflist(list_in); cell = cell_new_from_cell(crystal_get_cell(cr)); crystal_set_cell(priv.cr_tgt, cell); @@ -501,13 +498,14 @@ static void write_angle_grid(Crystal *cr, struct image *image, const RefList *fu fclose(fh); } - reflist_free(crystal_get_reflections(priv.cr_tgt)); + reflist_free(priv.refls); crystal_free(priv.cr_tgt); spectrum_free(spectrum); } -static void write_radius_grid(Crystal *cr, struct image *image, const RefList *full, +static void write_radius_grid(RefList *list_in, Crystal *cr, struct image *image, + const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) @@ -516,7 +514,6 @@ static void write_radius_grid(Crystal *cr, struct image *image, const RefList *f char fn[64]; char ins[16]; struct rf_priv priv; - RefList *list; UnitCell *cell; Spectrum *spectrum; @@ -530,8 +527,7 @@ static void write_radius_grid(Crystal *cr, struct image *image, const RefList *f priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - list = copy_reflist(crystal_get_reflections(cr)); - crystal_set_reflections(priv.cr_tgt, list); + priv.refls = copy_reflist(list_in); cell = cell_new_from_cell(crystal_get_cell(cr)); crystal_set_cell(priv.cr_tgt, cell); @@ -568,19 +564,20 @@ static void write_radius_grid(Crystal *cr, struct image *image, const RefList *f fclose(fh); } - reflist_free(crystal_get_reflections(priv.cr_tgt)); + reflist_free(priv.refls); crystal_free(priv.cr_tgt); spectrum_free(spectrum); } -void write_gridscan(Crystal *cr, struct image *image, const RefList *full, +void write_gridscan(RefList *list, + Crystal *cr, struct image *image, const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) { - write_angle_grid(cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); - write_radius_grid(cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); + write_angle_grid(list, cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); + write_radius_grid(list, cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); } @@ -646,7 +643,8 @@ static void zero_alter(struct rf_alteration *alter) } -static void do_pr_refine(Crystal *cr, struct image *image, const RefList *full, +static void do_pr_refine(RefList **plist_in, Crystal *cr, struct image *image, + const RefList *full, PartialityModel pmodel, int serial, int cycle, int write_logs, SymOpList *sym, SymOpList *amb, int scaleflags, @@ -656,12 +654,11 @@ static void do_pr_refine(Crystal *cr, struct image *image, const RefList *full, struct rf_alteration alter; int n_iter = 0; double fom, freefom; - RefList *list; FILE *fh = NULL; UnitCell *cell; Spectrum *spectrum; - try_reindex(cr, image, full, sym, amb, scaleflags, pmodel); + try_reindex(plist_in, cr, image, full, sym, amb, scaleflags, pmodel); zero_alter(&alter); @@ -675,8 +672,7 @@ static void do_pr_refine(Crystal *cr, struct image *image, const RefList *full, priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - list = copy_reflist(crystal_get_reflections(cr)); - crystal_set_reflections(priv.cr_tgt, list); + priv.refls = copy_reflist(*plist_in); cell = cell_new_from_cell(crystal_get_cell(cr)); crystal_set_cell(priv.cr_tgt, cell); @@ -722,13 +718,13 @@ static void do_pr_refine(Crystal *cr, struct image *image, const RefList *full, /* Apply the final shifts */ apply_parameters(cr, cr, image, image, alter); - update_predictions(cr, image); - calculate_partialities(cr, image, pmodel); + update_predictions(*plist_in, cr, image); + calculate_partialities(*plist_in, cr, image, pmodel); if ( write_logs ) { - write_gridscan(cr, image, full, cycle, serial, scaleflags, + write_gridscan(*plist_in, cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); - write_specgraph(cr, image, full, cycle, serial, log_folder); + write_specgraph(*plist_in, cr, image, full, cycle, serial, log_folder); write_test_logs(cr, image, full, cycle, serial, log_folder); } @@ -740,7 +736,7 @@ static void do_pr_refine(Crystal *cr, struct image *image, const RefList *full, fclose(fh); } - reflist_free(crystal_get_reflections(priv.cr_tgt)); + reflist_free(priv.refls); crystal_free(priv.cr_tgt); spectrum_free(spectrum); } @@ -750,6 +746,7 @@ struct refine_args { RefList *full; Crystal *crystal; + RefList **prefls; struct image *image; PartialityModel pmodel; int serial; @@ -766,7 +763,7 @@ struct pr_queue_args { int n_started; int n_done; - Crystal **crystals; + struct crystal_refls *crystals; struct image **images; int n_crystals; struct refine_args task_defaults; @@ -780,7 +777,8 @@ static void refine_image(void *task, int id) write_logs = !pargs->no_logs && (pargs->serial % 20 == 0); - do_pr_refine(pargs->crystal, pargs->image, pargs->full, pargs->pmodel, + do_pr_refine(pargs->prefls, pargs->crystal, pargs->image, + pargs->full, pargs->pmodel, pargs->serial, pargs->cycle, write_logs, pargs->sym, pargs->amb, pargs->scaleflags, pargs->log_folder); @@ -795,7 +793,8 @@ static void *get_image(void *vqargs) task = malloc(sizeof(struct refine_args)); memcpy(task, &qargs->task_defaults, sizeof(struct refine_args)); - task->crystal = qargs->crystals[qargs->n_started]; + task->crystal = qargs->crystals[qargs->n_started].cr; + task->prefls = &qargs->crystals[qargs->n_started].refls; task->image = qargs->images[qargs->n_started]; task->serial = qargs->n_started; @@ -816,7 +815,7 @@ static void done_image(void *vqargs, void *task) } -void refine_all(Crystal **crystals, struct image **images, int n_crystals, +void refine_all(struct crystal_refls *crystals, struct image **images, int n_crystals, RefList *full, int nthreads, PartialityModel pmodel, int cycle, int no_logs, SymOpList *sym, SymOpList *amb, int scaleflags, @@ -827,6 +826,7 @@ void refine_all(Crystal **crystals, struct image **images, int n_crystals, task_defaults.full = full; task_defaults.crystal = NULL; + task_defaults.prefls = NULL; task_defaults.image = NULL; task_defaults.pmodel = pmodel; task_defaults.cycle = cycle; diff --git a/src/post-refinement.h b/src/post-refinement.h index 7eb1fd0b..91c0f4f8 100644 --- a/src/post-refinement.h +++ b/src/post-refinement.h @@ -58,19 +58,20 @@ enum prflag extern const char *str_prflag(enum prflag flag); -extern void refine_all(Crystal **crystals, struct image **images, int n_crystals, +extern void refine_all(struct crystal_refls *crystals, struct image **images, + int n_crystals, RefList *full, int nthreads, PartialityModel pmodel, int cycle, int no_logs, SymOpList *sym, SymOpList *amb, int scaleflags, const char *log_folder); -extern void write_gridscan(Crystal *cr, struct image *image, +extern void write_gridscan(RefList *list, Crystal *cr, struct image *image, const RefList *full, int cycle, int serial, int scaleflags, PartialityModel model, const char *log_folder); -extern void write_specgraph(Crystal *crystal, struct image *image, +extern void write_specgraph(RefList *list, Crystal *crystal, struct image *image, const RefList *full, signed int cycle, int serial, const char *log_folder); diff --git a/src/rejection.c b/src/rejection.c index 4e3ff6ba..d3aa9b1f 100644 --- a/src/rejection.c +++ b/src/rejection.c @@ -63,7 +63,7 @@ static double mean_intensity(RefList *list) /* Reject really obvious outliers */ -void early_rejection(Crystal **crystals, int n) +void early_rejection(struct crystal_refls *crystals, int n) { int i; double m = 0.0; @@ -73,18 +73,16 @@ void early_rejection(Crystal **crystals, int n) for ( i=0; ifull = qargs->full; - wargs->crystal = qargs->crystals[qargs->n_started]; + wargs->crystal = qargs->crystals[qargs->n_started].cr; + wargs->refls = qargs->crystals[qargs->n_started].refls; wargs->crystal_number = qargs->n_started; wargs->non = 0; wargs->nan = 0; @@ -320,9 +320,8 @@ static void run_deltacchalf_job(void *vwargs, int cookie) double cchalf, cchalfi; struct deltacchalf_worker_args *wargs = vwargs; int nref = 0; - RefList *template = crystal_get_reflections(wargs->crystal); - cchalf = calculate_cchalf(template, wargs->full, NULL, &nref); - cchalfi = calculate_cchalf(template, wargs->full, wargs->crystal, &nref); + cchalf = calculate_cchalf(wargs->refls, wargs->full, NULL, &nref); + cchalfi = calculate_cchalf(wargs->refls, wargs->full, wargs->crystal, &nref); //STATUS("Frame %i:", i); //STATUS(" With = %f ", cchalf*100.0); //STATUS("Without = %f", cchalfi*100.0); @@ -355,8 +354,8 @@ static void finalise_deltacchalf_job(void *vqargs, void *vwargs) } -static void check_deltacchalf(Crystal **crystals, int n, RefList *full, - int n_threads) +static void check_deltacchalf(struct crystal_refls *crystals, int n, + RefList *full, int n_threads) { double cchalf; int i; @@ -409,7 +408,7 @@ static void check_deltacchalf(Crystal **crystals, int n, RefList *full, if ( isnan(vals[i]) || isinf(vals[i]) || ((vals[i]<0.0) && (vals[i] < mean-2.0*sd)) ) { - crystal_set_user_flag(crystals[i], PRFLAG_DELTACCHALF); + crystal_set_user_flag(crystals[i].cr, PRFLAG_DELTACCHALF); } } @@ -417,7 +416,7 @@ static void check_deltacchalf(Crystal **crystals, int n, RefList *full, } -static void show_duds(Crystal **crystals, int n_crystals) +static void show_duds(struct crystal_refls *crystals, int n_crystals) { int j; int bads[32]; @@ -427,7 +426,7 @@ static void show_duds(Crystal **crystals, int n_crystals) for ( j=0; j max_B ) { - crystal_set_user_flag(crystals[i], PRFLAG_BIGB); + if ( fabs(crystal_get_Bfac(crystals[i].cr)) > max_B ) { + crystal_set_user_flag(crystals[i].cr, PRFLAG_BIGB); } - if ( crystal_get_user_flag(crystals[i]) == 0 ) n_acc++; + if ( crystal_get_user_flag(crystals[i].cr) == 0 ) n_acc++; } show_duds(crystals, n); diff --git a/src/rejection.h b/src/rejection.h index 7dc2c92b..152c004e 100644 --- a/src/rejection.h +++ b/src/rejection.h @@ -35,10 +35,10 @@ #endif -#include "crystal.h" +#include "image.h" -extern void early_rejection(Crystal **crystals, int n); -extern void check_rejection(Crystal **crystals, int n, RefList *full, +extern void early_rejection(struct crystal_refls *crystals, int n); +extern void check_rejection(struct crystal_refls *crystals, int n, RefList *full, double max_B, int no_deltacchalf, int n_threads); #endif /* REJECTION_H */ diff --git a/src/scaling.c b/src/scaling.c index f007b757..52954f9a 100644 --- a/src/scaling.c +++ b/src/scaling.c @@ -53,6 +53,7 @@ struct scale_args { RefList *full; Crystal *crystal; + RefList *refls; int flags; }; @@ -61,7 +62,7 @@ struct scale_queue_args { int n_started; int n_done; - Crystal **crystals; + struct crystal_refls *crystals; int n_crystals; struct scale_args task_defaults; }; @@ -70,7 +71,7 @@ struct scale_queue_args static void scale_crystal(void *task, int id) { struct scale_args *pargs = task; - scale_one_crystal(pargs->crystal, pargs->full, pargs->flags); + scale_one_crystal(pargs->refls, pargs->crystal, pargs->full, pargs->flags); } @@ -82,7 +83,8 @@ static void *get_crystal(void *vqargs) task = malloc(sizeof(struct scale_args)); memcpy(task, &qargs->task_defaults, sizeof(struct scale_args)); - task->crystal = qargs->crystals[qargs->n_started]; + task->crystal = qargs->crystals[qargs->n_started].cr; + task->refls = qargs->crystals[qargs->n_started].refls; qargs->n_started++; @@ -99,8 +101,8 @@ static void done_crystal(void *vqargs, void *task) } -static double total_log_r(Crystal **crystals, int n_crystals, RefList *full, - int *ninc) +static double total_log_r(struct crystal_refls *crystals, int n_crystals, + RefList *full, int *ninc) { int i; double total = 0.0; @@ -108,8 +110,9 @@ static double total_log_r(Crystal **crystals, int n_crystals, RefList *full, for ( i=0; i Date: Thu, 18 Jan 2024 15:24:09 +0100 Subject: Crystals shouldn't own RefLists (part 6) This fixes the remaining programs. --- src/ambigator.c | 4 ++-- src/cell_explorer.c | 4 +--- src/crystfelimageview.c | 3 +-- src/gui_index.c | 10 +++++----- src/process_image.c | 14 +++++++------- src/whirligig.c | 11 +++++------ 6 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/ambigator.c b/src/ambigator.c index 3777cf0a..91e621ac 100644 --- a/src/ambigator.c +++ b/src/ambigator.c @@ -1287,7 +1287,8 @@ int main(int argc, char *argv[]) RefList *list; UnitCell *cell; - cr = image->crystals[i]; + cr = image->crystals[i].cr; + list = image->crystals[i].refls; cell = crystal_get_cell(cr); if ( n_crystals == max_crystals ) { @@ -1308,7 +1309,6 @@ int main(int argc, char *argv[]) } - list = crystal_get_reflections(cr); crystals[n_crystals] = asymm_and_merge(list, s_sym, cell, rmin, rmax, diff --git a/src/cell_explorer.c b/src/cell_explorer.c index 99cb284f..a92de347 100644 --- a/src/cell_explorer.c +++ b/src/cell_explorer.c @@ -2002,9 +2002,7 @@ static int add_stream(CellWindow *w, const char *stream_filename, for ( i=0; in_crystals; i++ ) { - Crystal *cr; - - cr = image->crystals[i]; + Crystal *cr = image->crystals[i].cr; if ( w->n_cells == max_cells ) { diff --git a/src/crystfelimageview.c b/src/crystfelimageview.c index 03350204..1659ae4f 100644 --- a/src/crystfelimageview.c +++ b/src/crystfelimageview.c @@ -707,9 +707,8 @@ static gint draw_sig(GtkWidget *window, cairo_t *cr, CrystFELImageView *iv) if ( iv->show_refls ) { int i; for ( i=0; iimage->n_crystals; i++ ) { - Crystal *cry = iv->image->crystals[i]; draw_refls(cr, iv, - crystal_get_reflections(cry), + iv->image->crystals[i].refls, iv->label_refls, crystal_cols[i % n_crystal_cols]); } diff --git a/src/gui_index.c b/src/gui_index.c index 2cc8e8db..218331eb 100644 --- a/src/gui_index.c +++ b/src/gui_index.c @@ -636,19 +636,19 @@ static void run_indexing_once(struct crystfelproject *proj) index_pattern(proj->cur_image, ipriv); for ( i=0; icur_image->n_crystals; i++ ) { - crystal_set_mosaicity(proj->cur_image->crystals[i], 0.0); + crystal_set_mosaicity(proj->cur_image->crystals[i].cr, 0.0); if ( proj->indexing_params.use_fix_profile_radius ) { /* Manual radius */ - crystal_set_profile_radius(proj->cur_image->crystals[i], + crystal_set_profile_radius(proj->cur_image->crystals[i].cr, proj->indexing_params.fix_profile_radius); } else { /* Auto radius determination */ - crystal_set_profile_radius(proj->cur_image->crystals[i], + crystal_set_profile_radius(proj->cur_image->crystals[i].cr, 0.02e9); - if ( refine_radius(proj->cur_image->crystals[i], + if ( refine_radius(proj->cur_image->crystals[i].cr, proj->cur_image) ) { ERROR("WARNING: Radius determination failed\n"); @@ -682,7 +682,7 @@ static void run_indexing_once(struct crystfelproject *proj) STATUS("Number of crystals: %i\n", proj->cur_image->n_crystals); for ( i=0; icur_image->n_crystals; i++ ) { - cell_print(crystal_get_cell(proj->cur_image->crystals[i])); + cell_print(crystal_get_cell(proj->cur_image->crystals[i].cr)); } } diff --git a/src/process_image.c b/src/process_image.c index 2f856594..782c97b9 100644 --- a/src/process_image.c +++ b/src/process_image.c @@ -434,20 +434,20 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, set_last_task(last_task, "prediction params"); if ( iargs->fix_profile_r >= 0.0 ) { for ( i=0; in_crystals; i++ ) { - crystal_set_profile_radius(image->crystals[i], + crystal_set_profile_radius(image->crystals[i].cr, iargs->fix_profile_r); - crystal_set_mosaicity(image->crystals[i], 0.0); + crystal_set_mosaicity(image->crystals[i].cr, 0.0); } } else { for ( i=0; in_crystals; i++ ) { - crystal_set_profile_radius(image->crystals[i], 0.02e9); - crystal_set_mosaicity(image->crystals[i], 0.0); + crystal_set_profile_radius(image->crystals[i].cr, 0.02e9); + crystal_set_mosaicity(image->crystals[i].cr, 0.0); } } if ( iargs->fix_profile_r < 0.0 ) { for ( i=0; in_crystals; i++ ) { - if ( refine_radius(image->crystals[i], image) ) { + if ( refine_radius(image->crystals[i].cr, image) ) { ERROR("WARNING: Radius determination failed\n"); } } @@ -479,7 +479,7 @@ streamwrite: int n = 0; for ( i=0; in_crystals; i++ ) { - n += crystal_get_num_implausible_reflections(image->crystals[i]); + n += crystal_get_num_implausible_reflections(image->crystals[i].cr); } if ( n > 0 ) { STATUS("WARNING: %i implausibly negative reflection%s in %s " @@ -495,7 +495,7 @@ out: pthread_mutex_lock(&sb_shared->totals_lock); any_crystals = 0; for ( i=0; in_crystals; i++ ) { - if ( crystal_get_user_flag(image->crystals[i]) == 0 ) { + if ( crystal_get_user_flag(image->crystals[i].cr) == 0 ) { sb_shared->n_crystals++; any_crystals = 1; } diff --git a/src/whirligig.c b/src/whirligig.c index 20fcfa40..aa2cf090 100644 --- a/src/whirligig.c +++ b/src/whirligig.c @@ -175,12 +175,11 @@ static void process_series(struct image *images, signed int *ser, fprintf(fh, "%i frames in series\n\n", len); fprintf(fh, " # Serial Filename EventID Crystal\n"); for ( i=0; in_crystals; i++ ) { for ( j=0; jn_crystals; j++ ) { - if ( compare_permuted_cell_parameters_and_orientation(crystal_get_cell(i1->crystals[i]), - crystal_get_cell(i2->crystals[j]), + if ( compare_permuted_cell_parameters_and_orientation(crystal_get_cell(i1->crystals[i].cr), + crystal_get_cell(i2->crystals[j].cr), tols, &m) ) { if ( !crystal_used(win, n1, i) @@ -377,12 +376,12 @@ static int try_join(struct window *win, int sn) /* Get the appropriately transformed cell from the last crystal in this * series */ - cr = win->img[sp].crystals[win->ser[sn][sp]]; + cr = win->img[sp].crystals[win->ser[sn][sp]].cr; ref = cell_transform_intmat(crystal_get_cell(cr), win->mat[sn][sp]); for ( j=0; jimg[win->join_ptr].n_crystals; j++ ) { Crystal *cr2; - cr2 = win->img[win->join_ptr].crystals[j]; + cr2 = win->img[win->join_ptr].crystals[j].cr; if ( compare_permuted_cell_parameters_and_orientation(ref, crystal_get_cell(cr2), tols, &win->mat[sn][win->join_ptr]) ) -- cgit v1.2.3 From a40db3a0a67914934f214d5ea9473ad3465235b5 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Jan 2024 15:35:35 +0100 Subject: Crystals shouldn't own RefLists (part 7) This fixes the test programs. --- tests/gradient_check.c | 8 ++++---- tests/gradient_check_utils.c | 3 +-- tests/prof2d_check.c | 21 +++++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/gradient_check.c b/tests/gradient_check.c index 48b8311b..0722b849 100644 --- a/tests/gradient_check.c +++ b/tests/gradient_check.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) #ifdef CHANGE_CELL double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - UnitCell *cell = crystal_get_cell(image.crystals[0]); + UnitCell *cell = crystal_get_cell(image.crystals[0].cr); step = 0.5e5; cell_get_reciprocal(cell, &asx, &asy, &asz, &bsx, &bsy, &bsz, @@ -115,7 +115,7 @@ int main(int argc, char *argv[]) return 1; } - update_predictions(image.crystals[0], &image); + update_predictions(image.crystals[0].refls, image.crystals[0].cr, &image); after = make_dev_list(rps, n_refls, image.detgeom); for ( i=0; ipanels[rps[i].peak->pn], panel_matrices[rps[i].peak->pn], cx, cy, cz, &calc[1], &calc[2]); diff --git a/tests/gradient_check_utils.c b/tests/gradient_check_utils.c index e217609f..8b9191cf 100644 --- a/tests/gradient_check_utils.c +++ b/tests/gradient_check_utils.c @@ -144,7 +144,6 @@ struct reflpeak *make_test_image(int *pn_refls, struct image *image) crystal_set_cell(cr, random_rotated_cell(rng)); refls = predict_to_res(cr, image, detgeom_max_resolution(image->detgeom, image->lambda)); - crystal_set_reflections(cr, refls); n_refls = num_reflections(refls); /* Associate a peak with every reflection */ @@ -174,7 +173,7 @@ struct reflpeak *make_test_image(int *pn_refls, struct image *image) i++; } - image_add_crystal(image, cr); + image_add_crystal_refls(image, cr, refls); gsl_rng_free(rng); diff --git a/tests/prof2d_check.c b/tests/prof2d_check.c index d2ff0bcd..4ea3cee5 100644 --- a/tests/prof2d_check.c +++ b/tests/prof2d_check.c @@ -38,11 +38,12 @@ #include "histogram.h" -extern void integrate_prof2d(IntegrationMethod meth, - Crystal *cr, struct image *image, IntDiag int_diag, - signed int idh, signed int idk, signed int idl, - double ir_inn, double ir_mid, double ir_out, - pthread_mutex_t *term_lock, int **masks); +void integrate_prof2d(IntegrationMethod meth, + Crystal *cr, RefList *list, + struct image *image, IntDiag int_diag, + signed int idh, signed int idk, signed int idl, + double ir_inn, double ir_mid, double ir_out, + pthread_mutex_t *term_lock, int **masks); #define ADD_PX(fs, ss, val) \ @@ -127,12 +128,12 @@ int main(int argc, char *argv[]) crystal_set_mosaicity(cr, 0.0); /* radians */ crystal_set_cell(cr, cell); - image.n_crystals = 1; - image.crystals = &cr; - + image.crystals = NULL; + image.n_crystals = 0; list = predict_to_res(cr, &image, detgeom_max_resolution(image.detgeom, image.lambda)); - crystal_set_reflections(cr, list); + + image_add_crystal_refls(&image, cr, list); for ( fs=0; fs Date: Fri, 19 Jan 2024 12:59:47 +0100 Subject: Fix incorrect uses of cell_free This also gets rid of crystal_copy_deep. From now on, all crystal_copy calls also copy the UnitCell. --- libcrystfel/src/crystal.c | 28 ++------------------------ libcrystfel/src/crystal.h | 1 - libcrystfel/src/image.c | 6 +----- libcrystfel/src/index.c | 1 - libcrystfel/src/indexers/fromfile.c | 2 +- src/partialator.c | 2 +- src/post-refinement.c | 39 ++++++++++++++++++------------------- 7 files changed, 24 insertions(+), 55 deletions(-) diff --git a/libcrystfel/src/crystal.c b/libcrystfel/src/crystal.c index a21283f9..f0022fcc 100644 --- a/libcrystfel/src/crystal.c +++ b/libcrystfel/src/crystal.c @@ -88,41 +88,17 @@ Crystal *crystal_new() } -/** - * \param cryst: A \ref Crystal to copy. - * - * Creates a new \ref Crystal which is a copy of \p cryst. The copy is a "shallow - * copy", which means that copies are NOT made of the data structures which - * \p cryst contains references to, for example its \ref RefList. - * - * \returns A (shallow) copy of \p cryst, or NULL on failure. - * - */ -Crystal *crystal_copy(const Crystal *cryst) -{ - Crystal *c; - - c = crystal_new(); - if ( c == NULL ) return NULL; - - memcpy(c, cryst, sizeof(Crystal)); - if ( c->notes != NULL ) c->notes = cfstrdup(c->notes); - - return c; -} - - /** * \param cryst: A \ref Crystal to copy. * * Creates a new \ref Crystal which is a copy of \p cryst. The copy is a "deep * copy", which means that copies ARE made of the data structures which - * \p cryst contains references to, for example its \ref RefList. + * \p cryst contains references to, for example its \ref UnitCell. * * \returns A (deep) copy of \p cryst, or NULL on failure. * */ -Crystal *crystal_copy_deep(const Crystal *cryst) +Crystal *crystal_copy(const Crystal *cryst) { Crystal *c; diff --git a/libcrystfel/src/crystal.h b/libcrystfel/src/crystal.h index 3f19386c..7147111f 100644 --- a/libcrystfel/src/crystal.h +++ b/libcrystfel/src/crystal.h @@ -49,7 +49,6 @@ extern "C" { extern Crystal *crystal_new(void); extern Crystal *crystal_copy(const Crystal *cryst); -extern Crystal *crystal_copy_deep(const Crystal *cryst); extern void crystal_free(Crystal *cryst); extern UnitCell *crystal_get_cell(Crystal *cryst); diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 142598e3..3b4e04df 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -352,9 +352,7 @@ int remove_flagged_crystals(struct image *image) for ( i=0; in_crystals; i++ ) { if ( crystal_get_user_flag(image->crystals[i].cr) ) { int j; - Crystal *deleteme = image->crystals[i].cr; - cell_free(crystal_get_cell(deleteme)); - crystal_free(deleteme); + crystal_free(image->crystals[i].cr); reflist_free(image->crystals[i].refls); for ( j=i; jn_crystals-1; j++ ) { image->crystals[j] = image->crystals[j+1]; @@ -375,8 +373,6 @@ void free_all_crystals(struct image *image) int i; if ( image->crystals == NULL ) return; for ( i=0; in_crystals; i++ ) { - Crystal *cr = image->crystals[i].cr; - cell_free(crystal_get_cell(cr)); crystal_free(image->crystals[i].cr); reflist_free(image->crystals[i].refls); } diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 7aea3b59..2a2542f5 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -552,7 +552,6 @@ static int check_cell(IndexingFlags flags, Crystal *cr, UnitCell *target, if ( out != NULL ) { /* Replace crystal's cell with new one */ - cell_free(crystal_get_cell(cr)); crystal_set_cell(cr, out); rtnl_mtx_free(rm); if ( !right_handed(out) ) STATUS("WARNING: left handed\n"); diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index c7f1d1ba..30305b21 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -337,7 +337,7 @@ int fromfile_index(struct image *image, void *mpriv) for ( i=0; in_crystals; i++ ) { Crystal *cr; - cr = crystal_copy_deep(p->crystals[i]); + cr = crystal_copy(p->crystals[i]); image_add_crystal(image, cr); } diff --git a/src/partialator.c b/src/partialator.c index 659a12c5..7d3f19f6 100644 --- a/src/partialator.c +++ b/src/partialator.c @@ -1611,7 +1611,7 @@ int main(int argc, char *argv[]) return 1; } crystals = crystals_new; - cr = crystal_copy_deep(image->crystals[i].cr); + cr = crystal_copy(image->crystals[i].cr); crystals[n_crystals].cr = cr; images_new = realloc(images, (n_crystals+1)*sizeof(struct image *)); diff --git a/src/post-refinement.c b/src/post-refinement.c index c67c0348..8a846b0f 100644 --- a/src/post-refinement.c +++ b/src/post-refinement.c @@ -268,7 +268,6 @@ static void try_reindex(RefList **prefls, Crystal *crin, struct image *image, const RefList *full, SymOpList *sym, SymOpList *amb, int scaleflags, PartialityModel pmodel) { - Crystal *cr; double residual_original; int idx, n; @@ -277,39 +276,39 @@ static void try_reindex(RefList **prefls, Crystal *crin, struct image *image, if ( scale_one_crystal(*prefls, crin, full, scaleflags) ) return; residual_original = residual(*prefls, crin, full, 0, NULL, NULL); - cr = crystal_copy(crin); - n = num_equivs(amb, NULL); for ( idx=0; idx Date: Sat, 20 Jan 2024 10:35:31 +0100 Subject: Crystal: Free UnitCell when setting a new one --- libcrystfel/src/crystal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libcrystfel/src/crystal.c b/libcrystfel/src/crystal.c index f0022fcc..e6ae4b09 100644 --- a/libcrystfel/src/crystal.c +++ b/libcrystfel/src/crystal.c @@ -215,6 +215,7 @@ void crystal_get_det_shift(Crystal *cryst, double* shift_x, double *shift_y) void crystal_set_cell(Crystal *cryst, UnitCell *cell) { + if ( cryst->owns_cell ) cell_free(cryst->cell); cryst->cell = cell; } -- cgit v1.2.3 From faf3f6b3a24de77d4eebfdc7fe2bc0f62c1e3df0 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 20 Jan 2024 10:36:02 +0100 Subject: Remove an unused variable --- src/post-refinement.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/post-refinement.c b/src/post-refinement.c index 8a846b0f..4a02ed08 100644 --- a/src/post-refinement.c +++ b/src/post-refinement.c @@ -281,7 +281,6 @@ static void try_reindex(RefList **prefls, Crystal *crin, struct image *image, for ( idx=0; idx Date: Thu, 25 Jan 2024 15:12:22 +0100 Subject: Peak search algorithms should not mutate image structure This changes all the peak search procedures into pure functions that return a new ImageFeatureList. This takes the management of image->features out of the hands of the peak search routines, and into the calling code's responsibility. In turn, this allows a load of stuff to become const. --- libcrystfel/src/index.c | 2 +- libcrystfel/src/peakfinder8.c | 38 +++++++----- libcrystfel/src/peakfinder8.h | 13 ++-- libcrystfel/src/peaks.c | 141 ++++++++++++++++-------------------------- libcrystfel/src/peaks.h | 43 ++++++------- src/gui_peaksearch.c | 72 +++++++++++---------- src/process_image.c | 93 +++++++++++++++------------- 7 files changed, 189 insertions(+), 213 deletions(-) diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 2a2542f5..12cd9190 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -742,7 +742,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, if ( ipriv->flags & INDEXING_CHECK_PEAKS ) { int mm = ipriv->flags & INDEXING_MULTI; - if ( !indexing_peak_check(image, &cr, 1, mm) ) { + if ( !indexing_peak_check(image, image->features, &cr, 1, mm) ) { crystal_set_user_flag(cr, 1); continue; } diff --git a/libcrystfel/src/peakfinder8.c b/libcrystfel/src/peakfinder8.c index 95153191..1def35d3 100644 --- a/libcrystfel/src/peakfinder8.c +++ b/libcrystfel/src/peakfinder8.c @@ -373,7 +373,7 @@ void free_pf8_private_data(struct pf8_private_data *data) } -static struct peakfinder_mask *create_peakfinder_mask(struct image *img, +static struct peakfinder_mask *create_peakfinder_mask(const struct image *img, struct radius_maps *rmps, int min_res, int max_res) @@ -1248,14 +1248,15 @@ static int peakfinder8_base(float *roffset, float *rthreshold, * \param max_res The maximum number of pixels out from the center * \param use_saturated Whether saturated peaks should be considered * - * Runs the peakfinder8 peak search algorithm + * Runs the peakfinder8 peak search algorithm, and returns an \ref ImageFeatureList, + * or NULL on error. */ -int peakfinder8(struct image *img, int max_n_peaks, - float threshold, float min_snr, - int min_pix_count, int max_pix_count, - int local_bg_radius, int min_res, - int max_res, int use_saturated, - int fast_mode, struct pf8_private_data *private_data) +ImageFeatureList *peakfinder8(const struct image *img, int max_n_peaks, + float threshold, float min_snr, + int min_pix_count, int max_pix_count, + int local_bg_radius, int min_res, + int max_res, int use_saturated, + int fast_mode, struct pf8_private_data *private_data) { struct pf8_private_data *geomdata; struct radius_maps *rmaps; @@ -1272,10 +1273,11 @@ int peakfinder8(struct image *img, int max_n_peaks, int remaining_max_num_peaks; int iterations; float max_r; + ImageFeatureList *peaks; iterations = 5; - if ( img->detgeom == NULL) return 1; + if ( img->detgeom == NULL) return NULL; profile_start("pf8-rmaps"); if ( private_data == NULL ) { @@ -1286,21 +1288,21 @@ int peakfinder8(struct image *img, int max_n_peaks, rmaps = geomdata->rmaps; rspixels = geomdata->rpixels; profile_end("pf8-rmaps"); - if (geomdata == NULL) return 1; + if (geomdata == NULL) return NULL; profile_start("pf8-mask"); pfmask = create_peakfinder_mask(img, rmaps, min_res, max_res); profile_end("pf8-mask"); if ( pfmask == NULL ) { if ( private_data == NULL ) free_pf8_private_data(geomdata); - return 1; + return NULL; } pfdata = allocate_panel_data(img->detgeom->n_panels); if ( pfdata == NULL) { if ( private_data == NULL ) free_pf8_private_data(geomdata); free_peakfinder_mask(pfmask); - return 1; + return NULL; } for ( pi=0 ; pidetgeom->n_panels ; pi++ ) { @@ -1327,7 +1329,7 @@ int peakfinder8(struct image *img, int max_n_peaks, if ( private_data == NULL ) free_pf8_private_data(geomdata); free_peakfinder_mask(pfmask); free_panel_data(pfdata); - return 1; + return NULL; } for ( i=0 ; in_rad_bins ; i++) { @@ -1389,10 +1391,11 @@ int peakfinder8(struct image *img, int max_n_peaks, free_peakfinder_mask(pfmask); free_panel_data(pfdata); free_radial_stats(rstats); - return 1; + return NULL; } remaining_max_num_peaks = max_n_peaks; + peaks = image_feature_list_new(); profile_start("pf8-search"); for ( pi=0 ; pidetgeom->n_panels ; pi++) { @@ -1430,8 +1433,9 @@ int peakfinder8(struct image *img, int max_n_peaks, free_peakfinder_mask(pfmask); free_panel_data(pfdata); free_radial_stats(rstats); + image_feature_list_free(peaks); profile_end("pf8-search"); - return 1; + return NULL; } peaks_to_add = num_found_peaks; @@ -1454,7 +1458,7 @@ int peakfinder8(struct image *img, int max_n_peaks, } } - image_add_feature(img->features, + image_add_feature(peaks, pkdata->com_fs[pki]+0.5, pkdata->com_ss[pki]+0.5, pi, pkdata->tot_i[pki], NULL); @@ -1467,5 +1471,5 @@ int peakfinder8(struct image *img, int max_n_peaks, free_panel_data(pfdata); free_radial_stats(rstats); free_peak_data(pkdata); - return 0; + return peaks; } diff --git a/libcrystfel/src/peakfinder8.h b/libcrystfel/src/peakfinder8.h index e5e86038..cf23bdbf 100644 --- a/libcrystfel/src/peakfinder8.h +++ b/libcrystfel/src/peakfinder8.h @@ -54,12 +54,13 @@ struct pf8_private_data *prepare_peakfinder8(struct detgeom *det, int fast_mode) void free_pf8_private_data(struct pf8_private_data *data); -extern int peakfinder8(struct image *img, int max_n_peaks, - float threshold, float min_snr, - int mix_pix_count, int max_pix_count, - int local_bg_radius, int min_res, - int max_res, int use_saturated, - int fast_mode, struct pf8_private_data *private_data); +extern ImageFeatureList *peakfinder8(const struct image *img, int max_n_peaks, + float threshold, float min_snr, + int mix_pix_count, int max_pix_count, + int local_bg_radius, int min_res, + int max_res, int use_saturated, + int fast_mode, + struct pf8_private_data *private_data); #ifdef __cplusplus } diff --git a/libcrystfel/src/peaks.c b/libcrystfel/src/peaks.c index 63dd6966..cb438683 100644 --- a/libcrystfel/src/peaks.c +++ b/libcrystfel/src/peaks.c @@ -131,7 +131,7 @@ int *make_BgMask(struct image *image, struct detgeom_panel *p, /* Returns non-zero if peak has been vetoed. * i.e. don't use result if return value is not zero. */ -int integrate_peak(struct image *image, +int integrate_peak(const struct image *image, int p_cfs, int p_css, int pn, double *pfs, double *pss, double *intensity, double *sigma, @@ -254,7 +254,8 @@ int integrate_peak(struct image *image, } -static void search_peaks_in_panel(struct image *image, float threshold, +static void search_peaks_in_panel(ImageFeatureList *peaklist, + const struct image *image, float threshold, float min_sq_gradient, float min_snr, int pn, double ir_inn, double ir_mid, double ir_out, int use_saturated) @@ -387,8 +388,7 @@ static void search_peaks_in_panel(struct image *image, float threshold, } /* Check for a nearby feature */ - image_feature_closest(image->features, f_fs, f_ss, pn, - &d, &idx); + image_feature_closest(peaklist, f_fs, f_ss, pn, &d, &idx); if ( d < 2.0*ir_inn ) { nrej_pro++; continue; @@ -400,8 +400,7 @@ static void search_peaks_in_panel(struct image *image, float threshold, } /* Add using "better" coordinates */ - image_add_feature(image->features, f_fs, f_ss, pn, - intensity, NULL); + image_add_feature(peaklist, f_fs, f_ss, pn, intensity, NULL); nacc++; if ( nacc > 10000 ) { @@ -422,69 +421,38 @@ static void search_peaks_in_panel(struct image *image, float threshold, } -void search_peaks(struct image *image, float threshold, float min_sq_gradient, - float min_snr, double ir_inn, double ir_mid, - double ir_out, int use_saturated) +ImageFeatureList *search_peaks(const struct image *image, + float threshold, float min_sq_gradient, + float min_snr, double ir_inn, double ir_mid, + double ir_out, int use_saturated) { int i; + ImageFeatureList *peaklist; - if ( image->features != NULL ) { - image_feature_list_free(image->features); - } - image->features = image_feature_list_new(); + peaklist = image_feature_list_new(); for ( i=0; idetgeom->n_panels; i++ ) { - search_peaks_in_panel(image, threshold, min_sq_gradient, + search_peaks_in_panel(peaklist, image, + threshold, min_sq_gradient, min_snr, i, ir_inn, ir_mid, ir_out, use_saturated); } -} - - -/** - * \param image An \ref image structure - * \param max_n_peaks The maximum number of peaks to be searched for - * \param threshold The image threshold value, in detector units - * \param min_snr The minimum signal to noise ratio for a peak - * \param min_pix_count The minimum number of pixels in a peak - * \param max_pix_count The maximum number of pixels in a peak - * \param local_bg_radius The averaging radius for background calculation - * \param min_res The minimum number of pixels out from the center - * \param max_res The maximum number of pixels out from the center - * \param use_saturated Whether saturated peaks should be considered - * - * Runs the peakfinder8 peak search algorithm. This is a thin wrapper which - * creates an empty \ref ImageFeatureList for \p image, then calls - * the actual \ref peakfinder8 function, found in \ref peakfinder8.h. - */ -int search_peaks_peakfinder8(struct image *image, int max_n_peaks, - float threshold, float min_snr, - int min_pix_count, int max_pix_count, - int local_bg_radius, int min_res, - int max_res, int use_saturated, - int fast_mode, void *private_data) -{ - if ( image->features != NULL ) { - image_feature_list_free(image->features); - } - image->features = image_feature_list_new(); - return peakfinder8(image, max_n_peaks, threshold, min_snr, - min_pix_count, max_pix_count, - local_bg_radius, min_res, - max_res, use_saturated, - fast_mode, private_data); + return peaklist; } #ifdef HAVE_FDIP -int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, - float min_snr_peak_pix, float min_snr_whole_peak, - float min_sig, float min_peak_over_neighbour, - int window_radius) +ImageFeatureList *search_peaks_peakfinder9(const struct image *image, + float min_snr_biggest_pix, + float min_snr_peak_pix, + float min_snr_whole_peak, + float min_sig, + float min_peak_over_neighbour, + int window_radius) { peakFinder9_accuracyConstants_t accuracy_consts; peakList_t peakList; @@ -492,11 +460,7 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, float *data_copy = NULL; float *data_copy_new; int panel_number; - - if ( image->features != NULL ) { - image_feature_list_free(image->features); - } - image->features = image_feature_list_new(); + ImageFeatureList *peaks; accuracy_consts.minSNR_biggestPixel = min_snr_biggest_pix; accuracy_consts.minSNR_peakPixel = min_snr_peak_pix; @@ -505,7 +469,9 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, accuracy_consts.minimumPeakOversizeOverNeighbours = min_peak_over_neighbour; accuracy_consts.windowRadius = window_radius; - if ( allocatePeakList(&peakList, NpeaksMax) ) return 1; + if ( allocatePeakList(&peakList, NpeaksMax) ) return NULL; + + peaks = image_feature_list_new(); for ( panel_number=0; panel_numberdetgeom->n_panels; panel_number++ ) { @@ -530,7 +496,7 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, cffree(data_copy); } freePeakList(peakList); - return 1; + return NULL; } else { data_copy = data_copy_new; } @@ -544,7 +510,7 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, &det_size_one_panel, &peakList); for ( peak_number=0; peak_numberfeatures, + image_add_feature(peaks, peakList.centerOfMass_rawX[peak_number], peakList.centerOfMass_rawY[peak_number], panel_number, @@ -556,18 +522,21 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, freePeakList(peakList); cffree(data_copy); - return 0; + return peaks; } #else -int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, - float min_snr_peak_pix, float min_snr_whole_peak, - float min_sig, float min_peak_over_neighbour, - int window_radius) +ImageFeatureList *search_peaks_peakfinder9(const struct image *image, + float min_snr_biggest_pix, + float min_snr_peak_pix, + float min_snr_whole_peak, + float min_sig, + float min_peak_over_neighbour, + int window_radius) { ERROR("This copy of CrystFEL was compiled without peakfinder9 support.\n"); - return 1; + return NULL; } #endif // HAVE_FDIP @@ -575,17 +544,20 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, /** * \param image An \ref image structure + * \param peaks An \ref ImageFeatureList * \param crystals Pointer to array of pointers to crystals * \param n_cryst The number of crystals * \param multi_mode Whether the thresholds should be set for multi-lattice indexing * - * Checks whether the peaks in \p image appear to be explained by the crystals + * Checks whether the peaks in \p peaks appear to be explained by the crystals * provided. * * Returns 1 if the peaks appear to be well-explained by the crystals. * Otherwise, if the indexing solutions appear to be "bad", returns 0. */ -int indexing_peak_check(struct image *image, Crystal **crystals, int n_cryst, +int indexing_peak_check(const struct image *image, + ImageFeatureList *peaks, + Crystal **crystals, int n_cryst, int multi_mode) { int n_feat = 0; @@ -593,7 +565,7 @@ int indexing_peak_check(struct image *image, Crystal **crystals, int n_cryst, int i; const double min_dist = 0.25; - for ( i=0; ifeatures); i++ ) { + for ( i=0; ifeatures, i); + f = image_get_feature(peaks, i); if ( f == NULL ) continue; n_feat++; @@ -664,27 +636,21 @@ int indexing_peak_check(struct image *image, Crystal **crystals, int n_cryst, } -/** - * Deprecated: use indexing_peak_check instead - */ -int peak_sanity_check(struct image *image, Crystal **crystals, int n_cryst) -{ - return indexing_peak_check(image, crystals, n_cryst, 1); -} - - -void validate_peaks(struct image *image, double min_snr, - int ir_inn, int ir_mid, int ir_out, int use_saturated, - int check_snr) +ImageFeatureList *validate_peaks(const struct image *image, ImageFeatureList *peaks, + double min_snr, + int ir_inn, int ir_mid, int ir_out, int use_saturated, + int check_snr) { int i, n; ImageFeatureList *flist; int n_wtf, n_int, n_snr, n_sat; + if ( peaks == NULL ) return NULL; + flist = image_feature_list_new(); - if ( flist == NULL ) return; + if ( flist == NULL ) return NULL; - n = image_feature_count(image->features); + n = image_feature_count(peaks); /* Loop over peaks, putting each one through the integrator */ n_wtf = 0; n_int = 0; n_snr = 0; n_sat = 0; @@ -696,7 +662,7 @@ void validate_peaks(struct image *image, double min_snr, double intensity, sigma; int saturated; - f = image_get_feature(image->features, i); + f = image_get_feature(peaks, i); if ( f == NULL ) { n_wtf++; continue; @@ -730,8 +696,7 @@ void validate_peaks(struct image *image, double min_snr, //STATUS("HDF5: %i peaks, validated: %i. WTF: %i, integration: %i, " // "SNR: %i, saturated: %i\n", // n, image_feature_count(flist), n_wtf, n_int, n_snr, n_sat); - image_feature_list_free(image->features); - image->features = flist; + return flist; } diff --git a/libcrystfel/src/peaks.h b/libcrystfel/src/peaks.h index 89634269..5a20574d 100644 --- a/libcrystfel/src/peaks.h +++ b/libcrystfel/src/peaks.h @@ -97,33 +97,26 @@ extern enum peak_search_method parse_peaksearch(const char *arg); extern int *make_BgMask(struct image *image, struct detgeom_panel *p, int pn, double ir_inn); -extern void search_peaks(struct image *image, float threshold, - float min_gradient, float min_snr, double ir_inn, - double ir_mid, double ir_out, int use_saturated); - -extern int search_peaks_peakfinder8(struct image *image, int max_n_peaks, - float threshold, float min_snr, - int mix_pix_count, int max_pix_count, - int local_bg_radius, int min_res, - int max_res, int use_saturated, - int fast_mode, void *private_data); - -extern int search_peaks_peakfinder9(struct image *image, - float min_snr_biggest_pix, - float min_snr_peak_pix, - float min_snr_whole_peak, float min_sig, - float min_peak_over_neighbour, - int window_radius); - -extern int indexing_peak_check(struct image *image, Crystal **crystals, +extern ImageFeatureList *search_peaks(const struct image *image, float threshold, + float min_gradient, float min_snr, double ir_inn, + double ir_mid, double ir_out, int use_saturated); + +extern ImageFeatureList *search_peaks_peakfinder9(const struct image *image, + float min_snr_biggest_pix, + float min_snr_peak_pix, + float min_snr_whole_peak, float min_sig, + float min_peak_over_neighbour, + int window_radius); + +extern int indexing_peak_check(const struct image *image, ImageFeatureList *peaks, + Crystal **crystals, int n_cryst, int multi_mode); -extern int peak_sanity_check(struct image *image, Crystal **crystals, - int n_cryst); - -extern void validate_peaks(struct image *image, double min_snr, - int ir_inn, int ir_mid, int ir_out, - int use_saturated, int check_snr); +extern ImageFeatureList *validate_peaks(const struct image *image, + ImageFeatureList *peaks, + double min_snr, + int ir_inn, int ir_mid, int ir_out, + int use_saturated, int check_snr); extern double estimate_peak_resolution(ImageFeatureList *peaks, double lambda, diff --git a/src/gui_peaksearch.c b/src/gui_peaksearch.c index 976e08ec..314fd5d4 100644 --- a/src/gui_peaksearch.c +++ b/src/gui_peaksearch.c @@ -41,6 +41,7 @@ #include #include +#include #include "crystfelimageview.h" #include "gui_project.h" @@ -60,52 +61,55 @@ void update_peaks(struct crystfelproject *proj) switch ( proj->peak_search_params.method ) { + ImageFeatureList *peaks; + case PEAK_ZAEF: - search_peaks(proj->cur_image, - proj->peak_search_params.threshold, - proj->peak_search_params.min_sq_gradient, - proj->peak_search_params.min_snr, - proj->peak_search_params.pk_inn, - proj->peak_search_params.pk_mid, - proj->peak_search_params.pk_out, - 1); + proj->cur_image->features = search_peaks(proj->cur_image, + proj->peak_search_params.threshold, + proj->peak_search_params.min_sq_gradient, + proj->peak_search_params.min_snr, + proj->peak_search_params.pk_inn, + proj->peak_search_params.pk_mid, + proj->peak_search_params.pk_out, + 1); break; case PEAK_PEAKFINDER8: - search_peaks_peakfinder8(proj->cur_image, 2048, - proj->peak_search_params.threshold, - proj->peak_search_params.min_snr, - proj->peak_search_params.min_pix_count, - proj->peak_search_params.max_pix_count, - proj->peak_search_params.local_bg_radius, - proj->peak_search_params.min_res, - proj->peak_search_params.max_res, - 1, 0, NULL); + proj->cur_image->features = peakfinder8(proj->cur_image, 2048, + proj->peak_search_params.threshold, + proj->peak_search_params.min_snr, + proj->peak_search_params.min_pix_count, + proj->peak_search_params.max_pix_count, + proj->peak_search_params.local_bg_radius, + proj->peak_search_params.min_res, + proj->peak_search_params.max_res, + 1, 0, NULL); break; case PEAK_PEAKFINDER9: - search_peaks_peakfinder9(proj->cur_image, - proj->peak_search_params.min_snr_biggest_pix, - proj->peak_search_params.min_snr_peak_pix, - proj->peak_search_params.min_snr, - proj->peak_search_params.min_sig, - proj->peak_search_params.min_peak_over_neighbour, - proj->peak_search_params.local_bg_radius); + proj->cur_image->features = search_peaks_peakfinder9(proj->cur_image, + proj->peak_search_params.min_snr_biggest_pix, + proj->peak_search_params.min_snr_peak_pix, + proj->peak_search_params.min_snr, + proj->peak_search_params.min_sig, + proj->peak_search_params.min_peak_over_neighbour, + proj->peak_search_params.local_bg_radius); break; case PEAK_HDF5: case PEAK_CXI: - proj->cur_image->features = image_read_peaks(proj->dtempl, - proj->cur_image->filename, - proj->cur_image->ev, - proj->peak_search_params.half_pixel_shift); + peaks = image_read_peaks(proj->dtempl, + proj->cur_image->filename, + proj->cur_image->ev, + proj->peak_search_params.half_pixel_shift); if ( proj->peak_search_params.revalidate ) { - validate_peaks(proj->cur_image, - proj->peak_search_params.min_snr, - proj->peak_search_params.pk_inn, - proj->peak_search_params.pk_mid, - proj->peak_search_params.pk_out, - 1, 0); + proj->cur_image->features = validate_peaks(proj->cur_image, peaks, + proj->peak_search_params.min_snr, + proj->peak_search_params.pk_inn, + proj->peak_search_params.pk_mid, + proj->peak_search_params.pk_out, + 1, 0); + image_feature_list_free(peaks); } break; diff --git a/src/process_image.c b/src/process_image.c index 782c97b9..c26842c3 100644 --- a/src/process_image.c +++ b/src/process_image.c @@ -57,6 +57,8 @@ #include "im-sandbox.h" #include "im-zmq.h" #include "im-asapo.h" +#include "peaks.h" +#include "peakfinder8.h" static float **backup_image_data(float **dp, struct detgeom *det) { @@ -292,35 +294,42 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, profile_start("peak-search"); switch ( iargs->peak_search.method ) { + ImageFeatureList *peaks; + case PEAK_HDF5: case PEAK_CXI: set_last_task(last_task, "peaksearch:hdf5orcxi"); - image->features = image_read_peaks(iargs->dtempl, - pargs->filename, - pargs->event, - iargs->peak_search.half_pixel_shift); - if ( image->features == NULL ) { - ERROR("Failed to get peaks from HDF5 file.\n"); - } + peaks = image_read_peaks(iargs->dtempl, + pargs->filename, + pargs->event, + iargs->peak_search.half_pixel_shift); if ( iargs->peak_search.revalidate ) { - validate_peaks(image, iargs->peak_search.min_snr, - iargs->peak_search.pk_inn, iargs->peak_search.pk_mid, - iargs->peak_search.pk_out, iargs->peak_search.use_saturated, - iargs->peak_search.check_hdf5_snr); + ImageFeatureList *npeaks = validate_peaks(image, peaks, + iargs->peak_search.min_snr, + iargs->peak_search.pk_inn, + iargs->peak_search.pk_mid, + iargs->peak_search.pk_out, + iargs->peak_search.use_saturated, + iargs->peak_search.check_hdf5_snr); + image_feature_list_free(peaks); + image->features = npeaks; } break; case PEAK_ZAEF: set_last_task(last_task, "peaksearch:zaef"); - search_peaks(image, iargs->peak_search.threshold, - iargs->peak_search.min_sq_gradient, iargs->peak_search.min_snr, - iargs->peak_search.pk_inn, iargs->peak_search.pk_mid, iargs->peak_search.pk_out, - iargs->peak_search.use_saturated); + image->features = search_peaks(image, iargs->peak_search.threshold, + iargs->peak_search.min_sq_gradient, + iargs->peak_search.min_snr, + iargs->peak_search.pk_inn, + iargs->peak_search.pk_mid, + iargs->peak_search.pk_out, + iargs->peak_search.use_saturated); break; case PEAK_PEAKFINDER8: set_last_task(last_task, "peaksearch:pf8"); - if ( search_peaks_peakfinder8(image, 2048, + image->features = peakfinder8(image, 2048, iargs->peak_search.threshold, iargs->peak_search.min_snr, iargs->peak_search.min_pix_count, @@ -329,40 +338,36 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, iargs->peak_search.min_res, iargs->peak_search.max_res, iargs->peak_search.use_saturated, - iargs->peak_search.peakfinder8_fast, - iargs->pf_private) ) { - ERROR("Failed to find peaks in image %s" - "(event %s).\n", - image->filename, image->ev); - } + iargs->peak_search.peakfinder8_fast, + iargs->pf_private); break; case PEAK_PEAKFINDER9: set_last_task(last_task, "peaksearch:pf9"); - if ( search_peaks_peakfinder9(image, - iargs->peak_search.min_snr_biggest_pix, - iargs->peak_search.min_snr_peak_pix, - iargs->peak_search.min_snr, - iargs->peak_search.min_sig, - iargs->peak_search.min_peak_over_neighbour, - iargs->peak_search.local_bg_radius) ) - { - ERROR("Failed to find peaks in image %s" - "(event %s).\n", - image->filename, image->ev); - } + image->features = search_peaks_peakfinder9(image, + iargs->peak_search.min_snr_biggest_pix, + iargs->peak_search.min_snr_peak_pix, + iargs->peak_search.min_snr, + iargs->peak_search.min_sig, + iargs->peak_search.min_peak_over_neighbour, + iargs->peak_search.local_bg_radius); break; case PEAK_MSGPACK: - image->features = image_msgpack_read_peaks(iargs->dtempl, - pargs->zmq_data, - pargs->zmq_data_size, - iargs->peak_search.half_pixel_shift); + peaks = image_msgpack_read_peaks(iargs->dtempl, + pargs->zmq_data, + pargs->zmq_data_size, + iargs->peak_search.half_pixel_shift); if ( iargs->peak_search.revalidate ) { - validate_peaks(image, iargs->peak_search.min_snr, - iargs->peak_search.pk_inn, iargs->peak_search.pk_mid, - iargs->peak_search.pk_out, iargs->peak_search.use_saturated, - iargs->peak_search.check_hdf5_snr); + ImageFeatureList *npeaks = validate_peaks(image, peaks, + iargs->peak_search.min_snr, + iargs->peak_search.pk_inn, + iargs->peak_search.pk_mid, + iargs->peak_search.pk_out, + iargs->peak_search.use_saturated, + iargs->peak_search.check_hdf5_snr); + image_feature_list_free(peaks); + image->features = npeaks; } break; @@ -371,6 +376,10 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, break; } + if ( image->features == NULL ) { + ERROR("Peaksearch failed for image %s" "(event %s).\n", + image->filename, image->ev); + } profile_end("peak-search"); image->peak_resolution = estimate_peak_resolution(image->features, -- cgit v1.2.3 From 967b72ba6e6243f1342232401f7109e4f225d2d3 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 30 Jan 2024 12:30:28 +0100 Subject: Add free_reflistiterator() This enables early exit from iteration over a RefList. --- libcrystfel/src/reflist.c | 17 +++++++++++++++-- libcrystfel/src/reflist.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/libcrystfel/src/reflist.c b/libcrystfel/src/reflist.c index 9ad41c5e..7a66bf9f 100644 --- a/libcrystfel/src/reflist.c +++ b/libcrystfel/src/reflist.c @@ -1180,8 +1180,7 @@ const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter) } if ( iter->stack_ptr == 0 ) { - free(iter->stack_const); - free(iter); + free_reflistiterator(iter); return NULL; } @@ -1190,6 +1189,20 @@ const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter) } while ( 1 ); } + +void free_reflistiterator(RefListIterator *iter) +{ + if ( iter != NULL ) { + if ( iter->is_const ) { + cffree(iter->stack_const); + } else { + cffree(iter->stack); + } + cffree(iter); + } +} + + /*********************************** Voodoo ***********************************/ static int recursive_depth(Reflection *refl) diff --git a/libcrystfel/src/reflist.h b/libcrystfel/src/reflist.h index 864e871d..5bba2e80 100644 --- a/libcrystfel/src/reflist.h +++ b/libcrystfel/src/reflist.h @@ -158,6 +158,7 @@ extern void add_refl_to_list(Reflection *refl, RefList *list); /* Iteration */ extern Reflection *first_refl(RefList *list, RefListIterator **piter); extern Reflection *next_refl(Reflection *refl, RefListIterator *iter); +extern void free_reflistiterator(RefListIterator *iter); extern const Reflection *first_refl_const(const RefList *list, RefListIterator **piter); extern const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter); -- cgit v1.2.3 From 5ac899bee2d033525410c8a69011f87933052eff Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 30 Jan 2024 12:29:07 +0100 Subject: Expose name_equiv --- libcrystfel/src/symmetry.c | 2 +- libcrystfel/src/symmetry.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libcrystfel/src/symmetry.c b/libcrystfel/src/symmetry.c index 7568f2a1..8afe675d 100644 --- a/libcrystfel/src/symmetry.c +++ b/libcrystfel/src/symmetry.c @@ -1755,7 +1755,7 @@ char *get_matrix_name(const IntegerMatrix *m, int col) } -static char *name_equiv(const IntegerMatrix *op) +char *name_equiv(const IntegerMatrix *op) { char *h, *k, *l; char *name; diff --git a/libcrystfel/src/symmetry.h b/libcrystfel/src/symmetry.h index b8780735..ba2c3742 100644 --- a/libcrystfel/src/symmetry.h +++ b/libcrystfel/src/symmetry.h @@ -83,6 +83,7 @@ extern int is_centrosymmetric(const SymOpList *s); extern const char *symmetry_name(const SymOpList *ops); extern void set_symmetry_name(SymOpList *ops, const char *name); extern void describe_symmetry(const SymOpList *s); +extern char *name_equiv(const IntegerMatrix *op); extern int is_centric(signed int h, signed int k, signed int l, const SymOpList *ops); -- cgit v1.2.3 From d216eda3fa9e5eb926c996c887e409d099f1ba02 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 14 Apr 2023 14:51:39 +0200 Subject: Julia: initial experimentation --- julia/CrystFEL/Project.toml | 4 ++++ julia/CrystFEL/src/CrystFEL.jl | 7 +++++++ julia/CrystFEL/src/datatemplates.jl | 29 +++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 julia/CrystFEL/Project.toml create mode 100644 julia/CrystFEL/src/CrystFEL.jl create mode 100644 julia/CrystFEL/src/datatemplates.jl diff --git a/julia/CrystFEL/Project.toml b/julia/CrystFEL/Project.toml new file mode 100644 index 00000000..2c6596b0 --- /dev/null +++ b/julia/CrystFEL/Project.toml @@ -0,0 +1,4 @@ +name = "CrystFEL" +uuid = "02864af1-98e3-4af5-94a7-a156d2a4edba" +authors = ["Thomas White "] +version = "0.1.0" diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl new file mode 100644 index 00000000..0ef197c0 --- /dev/null +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -0,0 +1,7 @@ +module CrystFEL + +include("datatemplates.jl") +using .DataTemplates +export DataTemplate, loaddatatemplate + +end # module CrystFEL diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl new file mode 100644 index 00000000..1357acb6 --- /dev/null +++ b/julia/CrystFEL/src/datatemplates.jl @@ -0,0 +1,29 @@ +module DataTemplates + +export DataTemplate, loaddatatemplate + +mutable struct InternalDataTemplate end + +mutable struct DataTemplate + internalptr::Ptr{InternalDataTemplate} +end + +function loaddatatemplate(filename::AbstractString) + + out = ccall((:data_template_new_from_file, :libcrystfel), + Ptr{InternalDataTemplate}, (Cstring,), filename) + if out == C_NULL + throw(OutOfMemoryError()) + end + + dt = DataTemplate(out) + + finalizer(dt) do x + ccall((:data_template_free, :libcrystfel), + Cvoid, (Ptr{InternalDataTemplate},), x.internalptr) + end + + return dt +end + +end -- cgit v1.2.3 From d5270938d73200979d43a830fd0ba81eca229779 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 14 Apr 2023 16:54:25 +0200 Subject: Julia: Switch to flat modules --- julia/CrystFEL/src/CrystFEL.jl | 2 -- julia/CrystFEL/src/datatemplates.jl | 4 ---- 2 files changed, 6 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 0ef197c0..e754a310 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -1,7 +1,5 @@ module CrystFEL include("datatemplates.jl") -using .DataTemplates -export DataTemplate, loaddatatemplate end # module CrystFEL diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index 1357acb6..c72a6c43 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -1,5 +1,3 @@ -module DataTemplates - export DataTemplate, loaddatatemplate mutable struct InternalDataTemplate end @@ -25,5 +23,3 @@ function loaddatatemplate(filename::AbstractString) return dt end - -end -- cgit v1.2.3 From ccbd7de6928f0bf6da0040734d98f339c70e8b01 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 18 Apr 2023 14:34:18 +0200 Subject: Julia: Implement SymOpList --- julia/CrystFEL/src/CrystFEL.jl | 1 + julia/CrystFEL/src/symmetry.jl | 109 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 julia/CrystFEL/src/symmetry.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index e754a310..7c342a15 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -1,5 +1,6 @@ module CrystFEL include("datatemplates.jl") +include("symmetry.jl") end # module CrystFEL diff --git a/julia/CrystFEL/src/symmetry.jl b/julia/CrystFEL/src/symmetry.jl new file mode 100644 index 00000000..00fb4f8c --- /dev/null +++ b/julia/CrystFEL/src/symmetry.jl @@ -0,0 +1,109 @@ +export SymOpList + +# Types for pointers returned by libcrystfel +mutable struct InternalSymOpList end +mutable struct InternalIntegerMatrix end + +# Exposed types +mutable struct SymOpList + internalptr::Ptr{InternalSymOpList} +end + +mutable struct SymOp + internalptr::Ptr{InternalIntegerMatrix} +end + + +function SymOpList(pointgroup::AbstractString) + + out = ccall((:get_pointgroup, :libcrystfel), + Ptr{InternalSymOpList}, (Cstring,), pointgroup) + if out == C_NULL + throw(OutOfMemoryError()) + end + + sym = SymOpList(out) + + finalizer(sym) do x + ccall((:free_symoplist, :libcrystfel), + Cvoid, (Ptr{InternalSymOpList},), x.internalptr) + end + + return sym + +end + + +function Base.getindex(sym::SymOpList, i::Int) + + if i >= length(sym) + throw(BoundsError()) + end + + out = ccall((:get_symop, :libcrystfel), + Ptr{InternalIntegerMatrix}, + (Ptr{InternalSymOpList},Ptr{Cvoid},Cint), + sym.internalptr,C_NULL,i) + + if out == C_NULL + throw(OutOfMemoryError()) + end + + return SymOp(out) + +end + + +function Base.length(sym::SymOpList) + return ccall((:num_equivs, :libcrystfel), + Cint, (Ptr{InternalSymOpList},Ptr{Cvoid}), + sym.internalptr, C_NULL) +end + + +function hkl_op(op::SymOp) + s = ccall((:name_equiv, :libcrystfel), + Cstring, + (Ptr{InternalIntegerMatrix},), + op.internalptr) + return unsafe_string(s) +end + + +function symmetry_name(sym::SymOpList) + s = ccall((:symmetry_name, :libcrystfel), + Cstring, + (Ptr{InternalSymOpList},), + sym.internalptr) + return unsafe_string(s) +end + + +function Base.iterate(sym::SymOpList) + return (sym[1], 1) +end + + +function Base.iterate(sym::SymOpList, i) + if i == length(sym) + return nothing + else + return (sym[i], i+1) + end +end + + +function Base.show(io::IO, sym::SymOpList) + println(io, length(sym), "-element SymOpList (\"", symmetry_name(sym), "\")") + for op in sym + println(io, hkl_op(op)) + end +end + + +function Base.show(io::IO, op::SymOp) + write(io, "SymOp(") + write(io, "\"") + write(io, hkl_op(op)) + write(io, "\")") +end -- cgit v1.2.3 From c98692e1bd29b43cc6ec5487abb2ccdd23297b40 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 18 Apr 2023 16:54:46 +0200 Subject: Julia: WIP on RefList --- julia/CrystFEL/src/CrystFEL.jl | 3 ++- julia/CrystFEL/src/reflists.jl | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 julia/CrystFEL/src/reflists.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 7c342a15..32ff6475 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -1,6 +1,7 @@ module CrystFEL -include("datatemplates.jl") include("symmetry.jl") +include("datatemplates.jl") +include("reflists.jl") end # module CrystFEL diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl new file mode 100644 index 00000000..9ecb1156 --- /dev/null +++ b/julia/CrystFEL/src/reflists.jl @@ -0,0 +1,22 @@ +export RefList, Reflection, loadreflist, savereflections + +mutable struct InternalRefList end + +mutable struct RefList + internalptr::Ptr{InternalRefList} + symmetry::SymOpList +end + +function loadreflist(filename::AbstractString) + + psym = Ptr{InternalSymOpList}() + out = ccall((:read_reflections_2, :libcrystfel), + Ptr{InternalRefList}, (Cstring,Ptr{InternalSymOpList}), + filename, psym) + if out == C_NULL + throw(OutOfMemoryError()) + end + + return RefList(out, SymOpList(psym)) + +end -- cgit v1.2.3 From fa8cb01b9f9f609d761574af18433aa39c18389a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 4 May 2023 16:14:06 +0200 Subject: Julia: SymOpList: fix iteration --- julia/CrystFEL/src/symmetry.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/julia/CrystFEL/src/symmetry.jl b/julia/CrystFEL/src/symmetry.jl index 00fb4f8c..9850fcb5 100644 --- a/julia/CrystFEL/src/symmetry.jl +++ b/julia/CrystFEL/src/symmetry.jl @@ -36,14 +36,14 @@ end function Base.getindex(sym::SymOpList, i::Int) - if i >= length(sym) + if i > length(sym) throw(BoundsError()) end out = ccall((:get_symop, :libcrystfel), Ptr{InternalIntegerMatrix}, (Ptr{InternalSymOpList},Ptr{Cvoid},Cint), - sym.internalptr,C_NULL,i) + sym.internalptr,C_NULL,i-1) if out == C_NULL throw(OutOfMemoryError()) @@ -80,12 +80,12 @@ end function Base.iterate(sym::SymOpList) - return (sym[1], 1) + return (sym[1], 2) end function Base.iterate(sym::SymOpList, i) - if i == length(sym) + if i > length(sym) return nothing else return (sym[i], i+1) -- cgit v1.2.3 From 355246a6197ad2fcd7a030eb4dd5890f0c32ce8e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 9 Oct 2023 10:47:36 +0200 Subject: Organise submodules hierarchically --- julia/CrystFEL/src/CrystFEL.jl | 21 ++++++++++++++++++++- julia/CrystFEL/src/datatemplates.jl | 4 ++++ julia/CrystFEL/src/reflists.jl | 6 ++++++ julia/CrystFEL/src/symmetry.jl | 6 +++++- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 32ff6475..6e72757a 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -1,7 +1,26 @@ +""" + CrystFEL + +Julia bindings for CrystFEL data structures and routines + +## Quick start +```julia + using CrystFEL + ... +``` +""" module CrystFEL include("symmetry.jl") +using .Symmetry +export SymOpList + include("datatemplates.jl") +using .DataTemplates +export DataTemplate, loaddatatemplate + include("reflists.jl") +using .RefLists +export RefList, Reflection, loadreflist, savereflections -end # module CrystFEL +end # of module diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index c72a6c43..00593286 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -1,3 +1,5 @@ +module DataTemplates + export DataTemplate, loaddatatemplate mutable struct InternalDataTemplate end @@ -23,3 +25,5 @@ function loaddatatemplate(filename::AbstractString) return dt end + +end # of module diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 9ecb1156..3931e40c 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -1,3 +1,7 @@ +module RefLists + +using ..Symmetry + export RefList, Reflection, loadreflist, savereflections mutable struct InternalRefList end @@ -20,3 +24,5 @@ function loadreflist(filename::AbstractString) return RefList(out, SymOpList(psym)) end + +end # of module diff --git a/julia/CrystFEL/src/symmetry.jl b/julia/CrystFEL/src/symmetry.jl index 9850fcb5..898b65a4 100644 --- a/julia/CrystFEL/src/symmetry.jl +++ b/julia/CrystFEL/src/symmetry.jl @@ -1,4 +1,6 @@ -export SymOpList +module Symmetry + +export SymOpList, InternalSymOpList, InternalIntegerMatrix # Types for pointers returned by libcrystfel mutable struct InternalSymOpList end @@ -107,3 +109,5 @@ function Base.show(io::IO, op::SymOp) write(io, hkl_op(op)) write(io, "\")") end + +end # of module -- cgit v1.2.3 From d84acbbb0cfdd8156f318fadf05c176f1922d28a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 9 Oct 2023 14:50:02 +0200 Subject: Add wrapper for detector panels --- julia/CrystFEL/src/CrystFEL.jl | 4 +++ julia/CrystFEL/src/detgeom.jl | 81 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 julia/CrystFEL/src/detgeom.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 6e72757a..859c8833 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -11,6 +11,10 @@ Julia bindings for CrystFEL data structures and routines """ module CrystFEL +include("detgeom.jl") +using .DetGeoms +export Panel, DetGeom + include("symmetry.jl") using .Symmetry export SymOpList diff --git a/julia/CrystFEL/src/detgeom.jl b/julia/CrystFEL/src/detgeom.jl new file mode 100644 index 00000000..b370b302 --- /dev/null +++ b/julia/CrystFEL/src/detgeom.jl @@ -0,0 +1,81 @@ +module DetGeoms +export Panel, DetGeom + +mutable struct Panel + name::Cstring + cx::Cdouble + cy::Cdouble + cz::Cdouble + pixel_pitch::Cdouble + adu_per_photon::Cdouble + max_adu::Cdouble + fsx::Cdouble + fsy::Cdouble + fsz::Cdouble + ssx::Cdouble + ssy::Cdouble + ssz::Cdouble + w::Cint + h::Cint + group::Ptr{Cvoid} +end + + +""" + Panel(name, width, height, (cnx, cny), clen, (fsx,fsy,fsz), (ssx,ssy,ssz), pixelsize, aduperphoton) + +Create a panel for a CrystFEL `DetGeom`. + +* `cnx` and `cny`: Corner position in pixel units +* `clen`: Corner z-position in meters +* `(fsx,fsy,fsz)`: Fast scan vector in pixel units +* `(ssx,ssy,ssz)`: Slow scan vector in pixel units +* `pixelsize`: Conversion factor from pixels to meters +* `aduperphoton`: Detector units per quantum, for error estimation + +Additional keyword arguments: + +* `max_adu`=Inf: Saturation value +* `group`: Panel group (for hierarchy) +""" +function Panel(name, width, height, corner::Tuple{Real, Real}, clen, + fs::Tuple{Real,Real,Real}, ss::Tuple{Real,Real,Real}, + pixel_pitch, adu_per_photon, + max_adu=Inf, group=C_NULL) + + @Base.GC.preserve name return Panel(pointer(name), + corner[1], corner[2], clen/pixel_pitch, + pixel_pitch, adu_per_photon, max_adu, + fs[1], fs[2], fs[3], + ss[1], ss[2], ss[3], + width, height, group) + +end + + +function Base.show(io::IO, p::Panel) + write(io, "Panel(") + write(io, "name=\"") + write(io, unsafe_string(p.name)) + write(io, "\", center=(") + show(io, p.cx); write(io, ", "); show(io, p.cy); write(io, ", "); show(io, p.cz) + write(io, "), fs=(") + show(io, p.fsx); write(io, ", "); show(io, p.fsy); write(io, ", "); show(io, p.fsz) + write(io, "), ss=(") + show(io, p.ssx); write(io, ", "); show(io, p.ssy); write(io, ", "); show(io, p.ssz) + write(io, "), size=(") + show(io, p.w); write(io, ", "); show(io, p.h) + write(io, "))") +end + + +""" + DetGeom(panels; topgroup=g) + +Create a CrystFEL `DetGeom` from a vector of `Panel`s. Optionally set the +panel group which should be the top of the hierarchy. +""" +function DetGeom(panels; topgroup=nothing) +end + +end # of module -- cgit v1.2.3 From 2324e4bf8166f5b9ae5efb468d4fd66ea7d3e697 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 9 Oct 2023 21:16:40 +0200 Subject: Add julia/alignment-test.jl --- julia/alignment-test.jl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 julia/alignment-test.jl diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl new file mode 100644 index 00000000..df1e1fbc --- /dev/null +++ b/julia/alignment-test.jl @@ -0,0 +1,14 @@ +using CrystFEL + +panels = [Panel("q1", 512, 512, (-530, -530), 0.1, (1, 0, 0), (0, 1, 0), 100e-6, 1), + Panel("q2", 512, 512, (28, -530), 0.1, (1, 0, 0), (0, 1, 0), 100e-6, 1), + Panel("q3", 512, 512, (-530, 28), 0.1, (1, 0, 0), (0, 1, 0), 100e-6, 1), + Panel("q4", 512, 512, (28, 28), 0.1, (1, 0, 0), (0, 1, 0), 100e-6, 1)] + +detgeom = DetGeom(panels) + +image = Image(detgeom) + +cell = UnitCell(123, 45, 80, 90, 97, 90) + +truth = predictreflections(image, cell) -- cgit v1.2.3 From 99be17bf7d70046c9ef67d52b200241e67d54dcc Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 12 Oct 2023 12:20:35 +0200 Subject: CrystFEL.DetGeoms.Panel(): Fix GC semantics --- julia/CrystFEL/src/detgeom.jl | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/julia/CrystFEL/src/detgeom.jl b/julia/CrystFEL/src/detgeom.jl index b370b302..622883ad 100644 --- a/julia/CrystFEL/src/detgeom.jl +++ b/julia/CrystFEL/src/detgeom.jl @@ -1,6 +1,22 @@ module DetGeoms export Panel, DetGeom +guardian = [] + +function protect(guardian, obj) + push!(guardian, obj) + obj +end + +function unprotect(guardian, obj) + let pos = findfirst(==(obj), guardian) + if pos !== nothing + deleteat!(guardian, pos) + end + end +end + + mutable struct Panel name::Cstring cx::Cdouble @@ -43,12 +59,18 @@ function Panel(name, width, height, corner::Tuple{Real, Real}, clen, pixel_pitch, adu_per_photon, max_adu=Inf, group=C_NULL) - @Base.GC.preserve name return Panel(pointer(name), - corner[1], corner[2], clen/pixel_pitch, - pixel_pitch, adu_per_photon, max_adu, - fs[1], fs[2], fs[3], - ss[1], ss[2], ss[3], - width, height, group) + myname = protect(guardian, deepcopy(name)) + + p = Panel(pointer(myname), + corner[1], corner[2], clen/pixel_pitch, + pixel_pitch, adu_per_photon, max_adu, + fs[1], fs[2], fs[3], + ss[1], ss[2], ss[3], + width, height, group) + + finalizer(p) do x + unprotect(guardian, myname) + end end -- cgit v1.2.3 From 87aa2caf1a226bfea9b6011412dd1a4e47330fa2 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 13 Oct 2023 09:09:50 +0200 Subject: WIP on images --- julia/CrystFEL/src/CrystFEL.jl | 4 ++++ julia/CrystFEL/src/detgeom.jl | 22 +++++++++++++++++++++- julia/CrystFEL/src/image.jl | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 julia/CrystFEL/src/image.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 859c8833..5afa9920 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -15,6 +15,10 @@ include("detgeom.jl") using .DetGeoms export Panel, DetGeom +include("image.jl") +using .Images +export Image + include("symmetry.jl") using .Symmetry export SymOpList diff --git a/julia/CrystFEL/src/detgeom.jl b/julia/CrystFEL/src/detgeom.jl index 622883ad..d394ee7b 100644 --- a/julia/CrystFEL/src/detgeom.jl +++ b/julia/CrystFEL/src/detgeom.jl @@ -37,6 +37,13 @@ mutable struct Panel end +mutable struct DetGeom + panels::Ptr{Panel} + n_panels::Cint + top_group::Ptr{Cvoid} +end + + """ Panel(name, width, height, (cnx, cny), clen, (fsx,fsy,fsz), (ssx,ssy,ssz), pixelsize, aduperphoton) @@ -97,7 +104,20 @@ end Create a CrystFEL `DetGeom` from a vector of `Panel`s. Optionally set the panel group which should be the top of the hierarchy. """ -function DetGeom(panels; topgroup=nothing) +function DetGeom(panels; topgroup=C_NULL) + + pmem = Base.Libc.malloc(sizeof(panels[1])*length(panels)) + + for (i,panel) in enumerate(panels) + Base.unsafe_copyto!(pmem, pointer(panel), 1) + end + + dg = DetGeom(pmem, length(panels), topgroup) + + finalize(dg) do x + Base.Libc.free(dg.panels) + end + end end # of module diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl new file mode 100644 index 00000000..e73e5f9a --- /dev/null +++ b/julia/CrystFEL/src/image.jl @@ -0,0 +1,34 @@ +module Images +export Image + +guardian = [] + +function protect(guardian, obj) + push!(guardian, obj) + obj +end + +function unprotect(guardian, obj) + let pos = findfirst(==(obj), guardian) + if pos !== nothing + deleteat!(guardian, pos) + end + end +end + + +mutable struct Image +end + + +""" + Image() + +Create a CrystFEL image structure +""" +function Image(panels) + + +end + +end # of module -- cgit v1.2.3 From f9fe0992b4f03eec44b51274a179aee64f172e5a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 26 Oct 2023 10:45:54 +0200 Subject: Julia: Add .so suffix to libcrystfel Something changed when I upgraded to Fedora 38, and now finding a library from Julia in a system location (no absolute path), without the suffix (see "dlext"), no longer works. "dlext" appears to work for an absolute path, though. I don't know whether it's a Julia thing or an ld thing. --- julia/CrystFEL/src/CrystFEL.jl | 2 ++ julia/CrystFEL/src/datatemplates.jl | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 5afa9920..cdb99979 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -11,6 +11,8 @@ Julia bindings for CrystFEL data structures and routines """ module CrystFEL +libcrystfel = "libcrystfel.so" + include("detgeom.jl") using .DetGeoms export Panel, DetGeom diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index 00593286..1030e2ef 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -1,5 +1,6 @@ module DataTemplates +import ..CrystFEL: libcrystfel export DataTemplate, loaddatatemplate mutable struct InternalDataTemplate end @@ -10,7 +11,7 @@ end function loaddatatemplate(filename::AbstractString) - out = ccall((:data_template_new_from_file, :libcrystfel), + out = ccall((:data_template_new_from_file, libcrystfel), Ptr{InternalDataTemplate}, (Cstring,), filename) if out == C_NULL throw(OutOfMemoryError()) -- cgit v1.2.3 From ef0611804113ae6dfb66ee4168f2a22f51f81920 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 26 Oct 2023 14:00:43 +0200 Subject: Julia: Get rid of DetGeom construction from panels It's theoretically possible, but rather complicated from Julia. It's not something that's really supported from the C API either, so I don't see much reason to bend over backwards to make it work from Julia. We will keep the access to the detgeom panel structure elements, though. --- julia/CrystFEL/src/detgeom.jl | 78 +------------------------------------------ julia/CrystFEL/src/image.jl | 30 ----------------- julia/alignment-test.geom | 49 +++++++++++++++++++++++++++ julia/alignment-test.jl | 10 ++---- 4 files changed, 52 insertions(+), 115 deletions(-) create mode 100644 julia/alignment-test.geom diff --git a/julia/CrystFEL/src/detgeom.jl b/julia/CrystFEL/src/detgeom.jl index d394ee7b..ba943d98 100644 --- a/julia/CrystFEL/src/detgeom.jl +++ b/julia/CrystFEL/src/detgeom.jl @@ -1,21 +1,5 @@ module DetGeoms -export Panel, DetGeom - -guardian = [] - -function protect(guardian, obj) - push!(guardian, obj) - obj -end - -function unprotect(guardian, obj) - let pos = findfirst(==(obj), guardian) - if pos !== nothing - deleteat!(guardian, pos) - end - end -end - +export Panel mutable struct Panel name::Cstring @@ -44,44 +28,6 @@ mutable struct DetGeom end -""" - Panel(name, width, height, (cnx, cny), clen, (fsx,fsy,fsz), (ssx,ssy,ssz), pixelsize, aduperphoton) - -Create a panel for a CrystFEL `DetGeom`. - -* `cnx` and `cny`: Corner position in pixel units -* `clen`: Corner z-position in meters -* `(fsx,fsy,fsz)`: Fast scan vector in pixel units -* `(ssx,ssy,ssz)`: Slow scan vector in pixel units -* `pixelsize`: Conversion factor from pixels to meters -* `aduperphoton`: Detector units per quantum, for error estimation - -Additional keyword arguments: - -* `max_adu`=Inf: Saturation value -* `group`: Panel group (for hierarchy) -""" -function Panel(name, width, height, corner::Tuple{Real, Real}, clen, - fs::Tuple{Real,Real,Real}, ss::Tuple{Real,Real,Real}, - pixel_pitch, adu_per_photon, - max_adu=Inf, group=C_NULL) - - myname = protect(guardian, deepcopy(name)) - - p = Panel(pointer(myname), - corner[1], corner[2], clen/pixel_pitch, - pixel_pitch, adu_per_photon, max_adu, - fs[1], fs[2], fs[3], - ss[1], ss[2], ss[3], - width, height, group) - - finalizer(p) do x - unprotect(guardian, myname) - end - -end - - function Base.show(io::IO, p::Panel) write(io, "Panel(") write(io, "name=\"") @@ -98,26 +44,4 @@ function Base.show(io::IO, p::Panel) end -""" - DetGeom(panels; topgroup=g) - -Create a CrystFEL `DetGeom` from a vector of `Panel`s. Optionally set the -panel group which should be the top of the hierarchy. -""" -function DetGeom(panels; topgroup=C_NULL) - - pmem = Base.Libc.malloc(sizeof(panels[1])*length(panels)) - - for (i,panel) in enumerate(panels) - Base.unsafe_copyto!(pmem, pointer(panel), 1) - end - - dg = DetGeom(pmem, length(panels), topgroup) - - finalize(dg) do x - Base.Libc.free(dg.panels) - end - -end - end # of module diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index e73e5f9a..3e4ff3a7 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -1,34 +1,4 @@ module Images export Image -guardian = [] - -function protect(guardian, obj) - push!(guardian, obj) - obj -end - -function unprotect(guardian, obj) - let pos = findfirst(==(obj), guardian) - if pos !== nothing - deleteat!(guardian, pos) - end - end -end - - -mutable struct Image -end - - -""" - Image() - -Create a CrystFEL image structure -""" -function Image(panels) - - -end - end # of module diff --git a/julia/alignment-test.geom b/julia/alignment-test.geom new file mode 100644 index 00000000..11668fca --- /dev/null +++ b/julia/alignment-test.geom @@ -0,0 +1,49 @@ +adu_per_photon = 1 +res = 10000 +clen = 100.0 mm +photon_energy = 9000 eV + +dim0 = % +dim1 = ss +dim2 = fs +data = /data/data + +q0/dim0 = 0 +q0/min_fs = 0 +q0/min_ss = 0 +q0/max_fs = 1024 +q0/max_ss = 1024 +q0/fs = x +q0/ss = y +q0/corner_x = -1054 +q0/corner_y = 30 + +q1/dim0 = 1 +q1/min_fs = 0 +q1/min_ss = 0 +q1/max_fs = 1024 +q1/max_ss = 1024 +q1/fs = x +q1/ss = y +q1/corner_x = 30 +q1/corner_y = 30 + +q2/dim0 = 2 +q2/min_fs = 0 +q2/min_ss = 0 +q2/max_fs = 1024 +q2/max_ss = 1024 +q2/fs = x +q2/ss = y +q2/corner_x = 30 +q2/corner_y = -1054 + +q3/dim0 = 3 +q3/min_fs = 0 +q3/min_ss = 0 +q3/max_fs = 1024 +q3/max_ss = 1024 +q3/fs = x +q3/ss = y +q3/corner_x = -1054 +q3/corner_y = -1054 diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index df1e1fbc..21aff531 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -1,13 +1,7 @@ using CrystFEL -panels = [Panel("q1", 512, 512, (-530, -530), 0.1, (1, 0, 0), (0, 1, 0), 100e-6, 1), - Panel("q2", 512, 512, (28, -530), 0.1, (1, 0, 0), (0, 1, 0), 100e-6, 1), - Panel("q3", 512, 512, (-530, 28), 0.1, (1, 0, 0), (0, 1, 0), 100e-6, 1), - Panel("q4", 512, 512, (28, 28), 0.1, (1, 0, 0), (0, 1, 0), 100e-6, 1)] - -detgeom = DetGeom(panels) - -image = Image(detgeom) +dtempl = loaddatatemplate("julia/alignment-test.geom") +image = Image(dtempl) cell = UnitCell(123, 45, 80, 90, 97, 90) -- cgit v1.2.3 From 1c84fcd33eb97b1151b34e7e19efeded6344f42f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 26 Oct 2023 15:13:58 +0200 Subject: Julia: Add image_create_for_simulation --- julia/CrystFEL/src/CrystFEL.jl | 8 +++--- julia/CrystFEL/src/datatemplates.jl | 4 +-- julia/CrystFEL/src/image.jl | 54 +++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index cdb99979..165b71eb 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -17,10 +17,6 @@ include("detgeom.jl") using .DetGeoms export Panel, DetGeom -include("image.jl") -using .Images -export Image - include("symmetry.jl") using .Symmetry export SymOpList @@ -29,6 +25,10 @@ include("datatemplates.jl") using .DataTemplates export DataTemplate, loaddatatemplate +include("image.jl") +using .Images +export Image + include("reflists.jl") using .RefLists export RefList, Reflection, loadreflist, savereflections diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index 1030e2ef..7aec0a1c 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -1,7 +1,7 @@ module DataTemplates import ..CrystFEL: libcrystfel -export DataTemplate, loaddatatemplate +export DataTemplate, InternalDataTemplate, loaddatatemplate mutable struct InternalDataTemplate end @@ -20,7 +20,7 @@ function loaddatatemplate(filename::AbstractString) dt = DataTemplate(out) finalizer(dt) do x - ccall((:data_template_free, :libcrystfel), + ccall((:data_template_free, libcrystfel), Cvoid, (Ptr{InternalDataTemplate},), x.internalptr) end diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 3e4ff3a7..0a8505d8 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -1,4 +1,58 @@ module Images + +import ..CrystFEL: libcrystfel +import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate +import ..CrystFEL.DetGeoms: DetGeom export Image +mutable struct InternalImage + dp::Ptr{Ptr{Cfloat}} + bad::Ptr{Ptr{Cint}} + sat::Ptr{Ptr{Cfloat}} + hit::Cint + crystals::Ptr{Ptr{Cvoid}} + n_crystals::Cint + indexed_by::Cint + n_indexing_tries::Cint + detgeom::Ptr{DetGeom} + data_source_type::Cint + filename::Cstring + ev::Cstring + data_block::Ptr{Cvoid} + data_block_size::Csize_t + meta_data::Cstring + header_cache::Ptr{Cvoid} + n_cached_headers::Cint + id::Cint + serial::Cint + spectrum::Ptr{Cvoid} + lambda::Cdouble + div::Cdouble + bw::Cdouble + peak_resolution::Cdouble + features::Ptr{Cvoid} + ida::Ptr{Cvoid} +end + +mutable struct Image + internalptr::Ptr{InternalImage} +end + +function Image(dtempl::DataTemplate) + + out = ccall((:image_create_for_simulation, libcrystfel), + Ptr{Image}, (Ref{InternalDataTemplate},), dtempl.internalptr) + if out == C_NULL + throw(OutOfMemoryError()) + end + + image = Image(out) + + finalizer(image) do x + ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) + end + + return image +end + end # of module -- cgit v1.2.3 From f81093eff4e5b546b5777446ab1bf21df00fb912 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 26 Oct 2023 16:26:09 +0200 Subject: WIP on image fields --- julia/CrystFEL/src/image.jl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 0a8505d8..a598edab 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -38,6 +38,19 @@ mutable struct Image internalptr::Ptr{InternalImage} end +function Base.getproperty(image::Image, name::Symbol) + if name === :internalptr + getfield(image, :internalptr) + else + idata = unsafe_load(image.internalptr) + getproperty(idata, name) + end +end + +function Base.propertynames(image::Image) + (:lambda, :internalptr) +end + function Image(dtempl::DataTemplate) out = ccall((:image_create_for_simulation, libcrystfel), -- cgit v1.2.3 From 9a1246bc041f9bcf2efc252ac0f0385598ce382e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 27 Oct 2023 15:57:16 +0200 Subject: Fix Image structure definition --- julia/CrystFEL/src/image.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index a598edab..263e7fa8 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -5,6 +5,8 @@ import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate import ..CrystFEL.DetGeoms: DetGeom export Image +const HEADER_CACHE_SIZE = 128 + mutable struct InternalImage dp::Ptr{Ptr{Cfloat}} bad::Ptr{Ptr{Cint}} @@ -21,7 +23,7 @@ mutable struct InternalImage data_block::Ptr{Cvoid} data_block_size::Csize_t meta_data::Cstring - header_cache::Ptr{Cvoid} + header_cache::NTuple{HEADER_CACHE_SIZE, Ptr{Cvoid}} n_cached_headers::Cint id::Cint serial::Cint -- cgit v1.2.3 From fb2251d6e7e80fa0a76727a5662bdfa9df765ba9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 27 Oct 2023 16:36:17 +0200 Subject: Julia: Add image loading, docstrings, formatting --- julia/CrystFEL/src/image.jl | 54 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 263e7fa8..37720e95 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -36,10 +36,12 @@ mutable struct InternalImage ida::Ptr{Cvoid} end + mutable struct Image internalptr::Ptr{InternalImage} end + function Base.getproperty(image::Image, name::Symbol) if name === :internalptr getfield(image, :internalptr) @@ -49,10 +51,25 @@ function Base.getproperty(image::Image, name::Symbol) end end -function Base.propertynames(image::Image) - (:lambda, :internalptr) + +function Base.propertynames(image::Image; private=false) + if private + fieldnames(InternalImage) + else + tuple(fieldnames(InternalImage)..., :internalptr) + end end + +""" + Image(dtempl::DataTemplate) + +Creates a CrystFEL image structure, not linked to any file or data block, +i.e. for simulation purposes. This will fail if `dtempl` contains any +references to metadata fields, e.g. `photon_energy = /LCLS/photon_energy eV`. + +Corresponds to CrystFEL C API function `image_create_for_simulation()`. +""" function Image(dtempl::DataTemplate) out = ccall((:image_create_for_simulation, libcrystfel), @@ -70,4 +87,37 @@ function Image(dtempl::DataTemplate) return image end + +""" + Image(dtempl::DataTemplate, filename::AbstractString, event::AbstractString, + no_image_data=false, no_mask_data=false) + +Loads an image from the filesystem. + +Corresponds to CrystFEL C API function `image_read()`. +""" +function Image(dtempl::DataTemplate, + filename::AbstractString, + event::AbstractString="//", + no_image_data=false, + no_mask_data=false) + + out = @ccall libcrystfel.image_read(dtempl.internalptr::Ptr{InternalDataTemplate}, + filename::Cstring, event::Cstring, + no_image_data::Cint, no_mask_data::Cint, + C_NULL::Ptr{Cvoid})::Ptr{Image} + if out == C_NULL + throw(OutOfMemoryError()) + end + + image = Image(out) + + finalizer(image) do x + ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) + end + + return image +end + + end # of module -- cgit v1.2.3 From b1a84a052ef18d91d053f95b6e8789889bd2d336 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 30 Oct 2023 16:00:06 +0100 Subject: Julia: Initial UnitCell implementation --- julia/CrystFEL/src/CrystFEL.jl | 6 ++++ julia/CrystFEL/src/cell.jl | 74 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 julia/CrystFEL/src/cell.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 165b71eb..007468ba 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -13,6 +13,12 @@ module CrystFEL libcrystfel = "libcrystfel.so" +include("cell.jl") +using .UnitCells +export UnitCell, LatticeType +export TriclinicLattice, MonoclinicLattice, OrthorhombicLattice +export TetragonalLattice, HexagonalLattice, RhombohedralLattice, CubicLattice + include("detgeom.jl") using .DetGeoms export Panel, DetGeom diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl new file mode 100644 index 00000000..3e34e9f8 --- /dev/null +++ b/julia/CrystFEL/src/cell.jl @@ -0,0 +1,74 @@ +module UnitCells + +import ..CrystFEL: libcrystfel +export UnitCell, LatticeType +export TriclinicLattice, MonoclinicLattice, OrthorhombicLattice +export TetragonalLattice, HexagonalLattice, RhombohedralLattice, CubicLattice + + +# Represents the real C-side (opaque) structure. +mutable struct InternalUnitCell end + +# The Julia-side structure, needed to house the pointer to the C structure +# Without this, we would only ever have a Ptr{DataTemplate}, not a DataTemplate. +mutable struct UnitCell + internalptr::Ptr{InternalUnitCell} +end + +@enum LatticeType begin + TriclinicLattice + MonoclinicLattice + OrthorhombicLattice + TetragonalLattice + HexagonalLattice + RhombohedralLattice + CubicLattice +end + +""" + UnitCell(a, b, c, α, β, γ, centering='P', latticetype=TriclinicLattice) + +Creates a CrystFEL UnitCell, in an undefined orientation, from the given +parameters. The angles (α, β, γ) should be in *degrees* - note that this is +different to the equivalent function in CrystFEL's C API. + +Corresponds to CrystFEL C API function `cell_new_from_parameters()`. +""" +function UnitCell(a, b, c, α, β, γ, + centering='P', + latticetype=TriclinicLattice, + uniqueaxis='*') + + out = ccall((:cell_new_from_parameters, libcrystfel), + Ptr{InternalUnitCell}, + (Cdouble,Cdouble,Cdouble,Cdouble,Cdouble,Cdouble), + a, b, c, deg2rad(α), deg2rad(β), deg2rad(γ)) + if out == C_NULL + throw(ArgumentError("Failed to create unit cell")) + end + + ccall((:cell_set_centering, libcrystfel), + Cvoid, (Ptr{InternalUnitCell},Cchar), + out, centering) + + ccall((:cell_set_unique_axis, libcrystfel), + Cvoid, (Ptr{InternalUnitCell},Cchar), + out, uniqueaxis) + + cell = UnitCell(out) + + finalizer(cell) do x + ccall((:cell_free, libcrystfel), + Cvoid, (Ptr{InternalUnitCell},), x.internalptr) + end + + return cell +end + + +function Base.show(io::IO, uc::UnitCell) + write(io, "UnitCell()") +end + + +end # of module -- cgit v1.2.3 From ddd00f0cf738541fb073cf180dc253ddd2eb2472 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 30 Oct 2023 16:00:20 +0100 Subject: Julia: Add some documentation and improve errors --- julia/CrystFEL/src/datatemplates.jl | 12 +++++++++++- julia/CrystFEL/src/image.jl | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index 7aec0a1c..cdb6c09b 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -3,18 +3,28 @@ module DataTemplates import ..CrystFEL: libcrystfel export DataTemplate, InternalDataTemplate, loaddatatemplate +# Represents the real C-side (opaque) structure. mutable struct InternalDataTemplate end +# The Julia-side structure, needed to house the pointer to the C structure +# Without this, we would only ever have a Ptr{DataTemplate}, not a DataTemplate. mutable struct DataTemplate internalptr::Ptr{InternalDataTemplate} end +""" + loaddatatemplate(filename) + +Creates a CrystFEL DataTemplate by loading a geometry file. + +Corresponds to CrystFEL C API function `data_template_new_from_file()`. +""" function loaddatatemplate(filename::AbstractString) out = ccall((:data_template_new_from_file, libcrystfel), Ptr{InternalDataTemplate}, (Cstring,), filename) if out == C_NULL - throw(OutOfMemoryError()) + throw(ArgumentError("Failed to load geometry file")) end dt = DataTemplate(out) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 37720e95..0f2d91d7 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -75,7 +75,7 @@ function Image(dtempl::DataTemplate) out = ccall((:image_create_for_simulation, libcrystfel), Ptr{Image}, (Ref{InternalDataTemplate},), dtempl.internalptr) if out == C_NULL - throw(OutOfMemoryError()) + throw(ArgumentError("Failed to create image")) end image = Image(out) @@ -107,7 +107,7 @@ function Image(dtempl::DataTemplate, no_image_data::Cint, no_mask_data::Cint, C_NULL::Ptr{Cvoid})::Ptr{Image} if out == C_NULL - throw(OutOfMemoryError()) + throw(ArgumentError("Failed to load image")) end image = Image(out) -- cgit v1.2.3 From 64410538e50883c3366bbbfcf67a0f72a5ea5f13 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 31 Oct 2023 15:16:41 +0100 Subject: Julia: Improve UnitCell implementation This adds Julian enums for lattice type, centering and unique axis, and a "show" method. --- julia/CrystFEL/src/CrystFEL.jl | 5 +- julia/CrystFEL/src/cell.jl | 109 +++++++++++++++++++++++++++++++++++++---- julia/alignment-test.jl | 3 +- 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 007468ba..66ad1176 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -15,9 +15,12 @@ libcrystfel = "libcrystfel.so" include("cell.jl") using .UnitCells -export UnitCell, LatticeType +export UnitCell, LatticeType, CenteringType, UniqueAxis export TriclinicLattice, MonoclinicLattice, OrthorhombicLattice export TetragonalLattice, HexagonalLattice, RhombohedralLattice, CubicLattice +export PrimitiveCell, ACenteredCell, BCenteredCell, CCenteredCell +export BodyCenteredCell, FaceCenteredCell, RhombohedralCell, RhombohedralCellOnHexagonalAxes +export NoUniqueAxis, UnknownUniqueAxis, UniqueAxisA, UniqueAxisB, UniqueAxisC include("detgeom.jl") using .DetGeoms diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl index 3e34e9f8..08204bbe 100644 --- a/julia/CrystFEL/src/cell.jl +++ b/julia/CrystFEL/src/cell.jl @@ -1,9 +1,12 @@ module UnitCells import ..CrystFEL: libcrystfel -export UnitCell, LatticeType +export UnitCell, LatticeType, CenteringType, UniqueAxis export TriclinicLattice, MonoclinicLattice, OrthorhombicLattice export TetragonalLattice, HexagonalLattice, RhombohedralLattice, CubicLattice +export PrimitiveCell, ACenteredCell, BCenteredCell, CCenteredCell +export BodyCenteredCell, FaceCenteredCell, RhombohedralCell, RhombohedralCellOnHexagonalAxes +export NoUniqueAxis, UnknownUniqueAxis, UniqueAxisA, UniqueAxisB, UniqueAxisC # Represents the real C-side (opaque) structure. @@ -15,29 +18,69 @@ mutable struct UnitCell internalptr::Ptr{InternalUnitCell} end + +""" +Enumeration of the seven Bravais lattice types: `TriclinicLattice`, +`MonoclinicLattice`, `OrthorhombicLattice`, `TetragonalLattice`, +`RhombohedralLattice`, `HexagonalLattice`, `CubicLattice`. +""" @enum LatticeType begin TriclinicLattice MonoclinicLattice OrthorhombicLattice TetragonalLattice - HexagonalLattice RhombohedralLattice + HexagonalLattice CubicLattice end + +""" +Enumeration of unit cell centering possibilities: `PrimitiveCell`, +`ACenteredCell`, `BCenteredCell`, `CCenteredCell`, `BodyCenteredCell` +(I-centering), `FaceCenteredCell` (F-centering), and `RhombohedralCell` +(R-centering, primitive rhombohedral cell). `RhombohedralCellOnHexagonalAxes` +indicates "H-centering" as used by the protein data bank, which is different +from the "triple hexagonal cell" described in the International Tables. +""" +@enum CenteringType begin + PrimitiveCell = Int('P') + ACenteredCell = Int('A') + BCenteredCell = Int('B') + CCenteredCell = Int('C') + BodyCenteredCell = Int('I') + FaceCenteredCell = Int('F') + RhombohedralCell = Int('R') + RhombohedralCellOnHexagonalAxes = Int('H') +end + + +""" +Enumeration of unique axis possibilities. The possibilities are `UniqueAxisA`, +`UniqueAxisB` and `UniqueAxisC`. Alternatively, use `NoUniqueAxis` if the type +of unit cell does not have a unique axis (triclinic, orthorhombic, cubic or +rhombohedral). `UnknownUniqueAxis` means that the unique axis is not known. +""" +@enum UniqueAxis begin + NoUniqueAxis = Int('*') + UnknownUniqueAxis = Int('?') + UniqueAxisA = Int('a') + UniqueAxisB = Int('b') + UniqueAxisC = Int('c') +end + + """ - UnitCell(a, b, c, α, β, γ, centering='P', latticetype=TriclinicLattice) + UnitCell(latticetype, centering, uniqueaxis, a, b, c, α, β, γ) Creates a CrystFEL UnitCell, in an undefined orientation, from the given parameters. The angles (α, β, γ) should be in *degrees* - note that this is different to the equivalent function in CrystFEL's C API. -Corresponds to CrystFEL C API function `cell_new_from_parameters()`. +Corresponds to CrystFEL C API function `cell_new_from_parameters` with follow-up +calls to `cell_set_centering`, `cell_set_lattice_type` and `cell_set_unique_axis`. """ -function UnitCell(a, b, c, α, β, γ, - centering='P', - latticetype=TriclinicLattice, - uniqueaxis='*') +function UnitCell(latticetype, centering, uniqueaxis, a, b, c, α, β, γ) out = ccall((:cell_new_from_parameters, libcrystfel), Ptr{InternalUnitCell}, @@ -55,6 +98,10 @@ function UnitCell(a, b, c, α, β, γ, Cvoid, (Ptr{InternalUnitCell},Cchar), out, uniqueaxis) + ccall((:cell_set_lattice_type, libcrystfel), + Cvoid, (Ptr{InternalUnitCell},Cint), + out, latticetype) + cell = UnitCell(out) finalizer(cell) do x @@ -65,9 +112,53 @@ function UnitCell(a, b, c, α, β, γ, return cell end +UnitCell(a, b, c, α, β, γ) = UnitCell(TriclinicLattice, PrimitiveCell, UnknownUniqueAxis, + a, b, c, α, β, γ) + + +function getlatticetype(cell) + lt = ccall((:cell_get_lattice_type, libcrystfel), + Cint, (Ptr{InternalUnitCell},), cell.internalptr) + cen = ccall((:cell_get_centering, libcrystfel), + Cchar, (Ptr{InternalUnitCell},), cell.internalptr) + ua = ccall((:cell_get_unique_axis, libcrystfel), + Cchar, (Ptr{InternalUnitCell},), cell.internalptr) + return LatticeType(lt),CenteringType(cen),UniqueAxis(ua) +end + + +function getcellparams(cell) + let a=Ref{Cdouble}(0), + b=Ref{Cdouble}(0), + c=Ref{Cdouble}(0), + α=Ref{Cdouble}(0), + β=Ref{Cdouble}(0), + γ=Ref{Cdouble}(0) + ccall((:cell_get_parameters, libcrystfel), + Cvoid, (Ptr{InternalUnitCell}, + Ref{Cdouble},Ref{Cdouble},Ref{Cdouble}, + Ref{Cdouble},Ref{Cdouble},Ref{Cdouble}), + cell.internalptr, a, b, c, α, β, γ) + return (a=a[], b=b[], c=c[], α=α[], β=β[], γ=γ[]) + end +end + function Base.show(io::IO, uc::UnitCell) - write(io, "UnitCell()") + write(io, "UnitCell(") + lt,cen,ua = getlatticetype(uc) + show(io, lt); write(io, ", ") + show(io, cen); write(io, ", ") + show(io, ua); write(io, ",\n ") + let cp = getcellparams(uc) + show(io, cp.a*1e10); write(io, " Å, ") + show(io, cp.b*1e10); write(io, " Å, ") + show(io, cp.c*1e10); write(io, " Å, ") + show(io, rad2deg(cp.α)); write(io, "°, ") + show(io, rad2deg(cp.β)); write(io, "°, ") + show(io, rad2deg(cp.γ)); write(io, "°") + end + write(io, ")") end diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 21aff531..c929634f 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -3,6 +3,7 @@ using CrystFEL dtempl = loaddatatemplate("julia/alignment-test.geom") image = Image(dtempl) -cell = UnitCell(123, 45, 80, 90, 97, 90) +cell = UnitCell(123, 45, 80, 90, 97, 90, + centering='P', latticetype=MonoclinicLattice, uniqueaxis='b') truth = predictreflections(image, cell) -- cgit v1.2.3 From 8b229d3472bcd5abadd0269b11977881aa49bff4 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 2 Nov 2023 12:57:11 +0100 Subject: Julia: Use Angstroms for UnitCell --- julia/CrystFEL/src/cell.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl index 08204bbe..aeec6e72 100644 --- a/julia/CrystFEL/src/cell.jl +++ b/julia/CrystFEL/src/cell.jl @@ -74,8 +74,14 @@ end UnitCell(latticetype, centering, uniqueaxis, a, b, c, α, β, γ) Creates a CrystFEL UnitCell, in an undefined orientation, from the given -parameters. The angles (α, β, γ) should be in *degrees* - note that this is -different to the equivalent function in CrystFEL's C API. +parameters. The axis lengths (a, b, c) should be in *Ångstroms*, and the +angles (α, β, γ) should be in *degrees* - note that this is different to the +equivalent function in CrystFEL's C API. + +See the documentation for `LatticeType`, `CenteringType` and `UniqueAxis` for +possible values. You can also use the characters `'a'`, `'b'` and `'c'` for +`uniqueaxis`, or `'P'`, `'A'`, `'B'`, `'C'`, `'I'`, `'F'`, `'R'` and `'H`' for +`centering. Corresponds to CrystFEL C API function `cell_new_from_parameters` with follow-up calls to `cell_set_centering`, `cell_set_lattice_type` and `cell_set_unique_axis`. @@ -85,7 +91,7 @@ function UnitCell(latticetype, centering, uniqueaxis, a, b, c, α, β, γ) out = ccall((:cell_new_from_parameters, libcrystfel), Ptr{InternalUnitCell}, (Cdouble,Cdouble,Cdouble,Cdouble,Cdouble,Cdouble), - a, b, c, deg2rad(α), deg2rad(β), deg2rad(γ)) + a/1e10, b/1e10, c/1e10, deg2rad(α), deg2rad(β), deg2rad(γ)) if out == C_NULL throw(ArgumentError("Failed to create unit cell")) end -- cgit v1.2.3 From adcee222e74b6ec5fd7f885d80f7641b4a285f5a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 2 Nov 2023 15:47:52 +0100 Subject: Julia: UnitCell: guess unique axis where possible --- julia/CrystFEL/src/cell.jl | 98 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl index aeec6e72..282572d0 100644 --- a/julia/CrystFEL/src/cell.jl +++ b/julia/CrystFEL/src/cell.jl @@ -88,6 +88,41 @@ calls to `cell_set_centering`, `cell_set_lattice_type` and `cell_set_unique_axis """ function UnitCell(latticetype, centering, uniqueaxis, a, b, c, α, β, γ) + ninety(a) = isapprox(a, 90, atol=0.1) + + if latticetype == OrthorhombicLattice + if !(ninety(α) && ninety(β) && ninety(γ)) + throw(ArgumentError("All angles must be 90°")) + end + + elseif latticetype == TetragonalLattice + if !(ninety(α) && ninety(β) && ninety(γ)) + throw(ArgumentError("All angles must be 90°")) + end + + elseif latticetype == CubicLattice + if !(ninety(α) && ninety(β) && ninety(γ)) + throw(ArgumentError("All angles must be 90°")) + end + + elseif latticetype == HexagonalLattice + if uniqueaxis == UniqueAxisA + if !isapprox(b, c, rtol=0.01) + throw(ArgumentError("b and c lengths should be equal")) + end + elseif uniqueaxis == UniqueAxisB + if !isapprox(a, c, rtol=0.01) + throw(ArgumentError("a and c lengths should be equal")) + end + elseif uniqueaxis == UniqueAxisC + if !isapprox(a, b, rtol=0.01) + throw(ArgumentError("a and b lengths should be equal")) + end + else + throw(ArgumentError("Hexagonal cell requires a unique axis")) + end + end + out = ccall((:cell_new_from_parameters, libcrystfel), Ptr{InternalUnitCell}, (Cdouble,Cdouble,Cdouble,Cdouble,Cdouble,Cdouble), @@ -118,8 +153,67 @@ function UnitCell(latticetype, centering, uniqueaxis, a, b, c, α, β, γ) return cell end -UnitCell(a, b, c, α, β, γ) = UnitCell(TriclinicLattice, PrimitiveCell, UnknownUniqueAxis, - a, b, c, α, β, γ) + + +""" + UnitCell(latticetype, centering, a, b, c, α, β, γ) + +A convenience constructor which attempts to determine the unique axis +automatically from the cell parameters. If the unique axis is not obvious, +an `ArgumentError` will be thrown. +""" +function UnitCell(latticetype, centering, a, b, c, α, β, γ) + + notninety(a) = !isapprox(a, 90, atol=0.5) + ninety(a) = isapprox(a, 90, atol=0.1) + onetwenty(a) = isapprox(a, 120, atol=0.1) + + if latticetype == TriclinicLattice + ua = NoUniqueAxis + elseif latticetype == OrthorhombicLattice + ua = NoUniqueAxis + elseif latticetype == RhombohedralLattice + ua = NoUniqueAxis + elseif latticetype == CubicLattice + ua = NoUniqueAxis + + elseif latticetype == MonoclinicLattice + if notninety(α) && ninety(β) && ninety(γ) + ua = UniqueAxisA + elseif ninety(α) && notninety(β) && ninety(γ) + ua = UniqueAxisB + elseif ninety(α) && ninety(β) && notninety(γ) + ua = UniqueAxisC + else + throw(ArgumentError("Can't determine unique axis")) + end + + elseif latticetype == TetragonalLattice + if isapprox(b, c, rtol=0.01) && !isapprox(a, b, rtol=0.05) + ua = UniqueAxisA + elseif isapprox(a, c, rtol=0.01) && !isapprox(a, b, rtol=0.05) + ua = UniqueAxisB + elseif isapprox(a, b, rtol=0.01) && !isapprox(c, b, rtol=0.05) + ua = UniqueAxisC + else + throw(ArgumentError("Can't determine unique axis")) + end + + elseif latticetype == HexagonalLattice + if onetwenty(α) && ninety(β) && ninety(γ) + ua = UniqueAxisA + elseif ninety(α) && onetwenty(β) && ninety(γ) + ua = UniqueAxisB + elseif ninety(α) && ninety(β) && onetwenty(γ) + ua = UniqueAxisC + else + throw(ArgumentError("Can't determine unique axis")) + end + end + + UnitCell(latticetype, centering, ua, a, b, c, α, β, γ) + +end function getlatticetype(cell) -- cgit v1.2.3 From 92fa163a5b6b31b541af8759fe1955283363b211 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 2 Nov 2023 16:00:00 +0100 Subject: Julia: UnitCell: Add some convenience constructors --- julia/CrystFEL/src/cell.jl | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl index 282572d0..b094770a 100644 --- a/julia/CrystFEL/src/cell.jl +++ b/julia/CrystFEL/src/cell.jl @@ -216,6 +216,49 @@ function UnitCell(latticetype, centering, a, b, c, α, β, γ) end +""" + UnitCell(latticetype, centering, a, b, c) + +Construct a `UnitCell` for an `OrthorhombicLattice`, `TetragonalLattice` or +`CubicLattice`. +""" +function UnitCell(latticetype::LatticeType, centering::CenteringType, a::Real, b::Real, c::Real) + if latticetype in (OrthorhombicLattice, TetragonalLattice, CubicLattice) + UnitCell(latticetype, centering, a, b, c, 90, 90, 90) + else + throw(ArgumentError("More parameters needed for this type of lattice")) + end +end + + +""" + UnitCell(CubicLattice, centering, a) + +Construct a `UnitCell` for a `CubicLattice`. +""" +function UnitCell(latticetype::LatticeType, centering::CenteringType, a::Real) + if latticetype == CubicLattice + UnitCell(latticetype, centering, a, a, a, 90, 90, 90) + else + throw(ArgumentError("More parameters needed for this type of lattice")) + end +end + + +""" + UnitCell(RhombohedralLattice, a, α) + +Construct a `UnitCell` for a `RhombohedralLattice`. +""" +function UnitCell(latticetype::LatticeType, a::Real, α::Real) + if latticetype == RhombohedralLattice + UnitCell(latticetype, RhombohedralCell, a, a, a, α, α, α) + else + throw(ArgumentError("More parameters needed for this type of lattice")) + end +end + + function getlatticetype(cell) lt = ccall((:cell_get_lattice_type, libcrystfel), Cint, (Ptr{InternalUnitCell},), cell.internalptr) -- cgit v1.2.3 From 703d42d7e80ead1a51f373b86289b7f8f891f4eb Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 2 Nov 2023 16:58:28 +0100 Subject: Julia: bring RefList and Symmetry up to date --- julia/CrystFEL/src/reflists.jl | 9 +++++---- julia/CrystFEL/src/symmetry.jl | 18 +++++++++++------- julia/alignment-test.jl | 3 +-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 3931e40c..2052e068 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -1,8 +1,9 @@ module RefLists -using ..Symmetry +import ..CrystFEL: libcrystfel +import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList -export RefList, Reflection, loadreflist, savereflections +export RefList, loadreflist mutable struct InternalRefList end @@ -14,11 +15,11 @@ end function loadreflist(filename::AbstractString) psym = Ptr{InternalSymOpList}() - out = ccall((:read_reflections_2, :libcrystfel), + out = ccall((:read_reflections_2, libcrystfel), Ptr{InternalRefList}, (Cstring,Ptr{InternalSymOpList}), filename, psym) if out == C_NULL - throw(OutOfMemoryError()) + throw(ArgumentError("Failed to load reflection list")) end return RefList(out, SymOpList(psym)) diff --git a/julia/CrystFEL/src/symmetry.jl b/julia/CrystFEL/src/symmetry.jl index 898b65a4..eddf9a18 100644 --- a/julia/CrystFEL/src/symmetry.jl +++ b/julia/CrystFEL/src/symmetry.jl @@ -1,16 +1,20 @@ module Symmetry +import ..CrystFEL: libcrystfel export SymOpList, InternalSymOpList, InternalIntegerMatrix + # Types for pointers returned by libcrystfel mutable struct InternalSymOpList end mutable struct InternalIntegerMatrix end + # Exposed types mutable struct SymOpList internalptr::Ptr{InternalSymOpList} end + mutable struct SymOp internalptr::Ptr{InternalIntegerMatrix} end @@ -18,7 +22,7 @@ end function SymOpList(pointgroup::AbstractString) - out = ccall((:get_pointgroup, :libcrystfel), + out = ccall((:get_pointgroup, libcrystfel), Ptr{InternalSymOpList}, (Cstring,), pointgroup) if out == C_NULL throw(OutOfMemoryError()) @@ -27,7 +31,7 @@ function SymOpList(pointgroup::AbstractString) sym = SymOpList(out) finalizer(sym) do x - ccall((:free_symoplist, :libcrystfel), + ccall((:free_symoplist, libcrystfel), Cvoid, (Ptr{InternalSymOpList},), x.internalptr) end @@ -38,11 +42,11 @@ end function Base.getindex(sym::SymOpList, i::Int) - if i > length(sym) + if (i<1) || (i > length(sym)) throw(BoundsError()) end - out = ccall((:get_symop, :libcrystfel), + out = ccall((:get_symop, libcrystfel), Ptr{InternalIntegerMatrix}, (Ptr{InternalSymOpList},Ptr{Cvoid},Cint), sym.internalptr,C_NULL,i-1) @@ -57,14 +61,14 @@ end function Base.length(sym::SymOpList) - return ccall((:num_equivs, :libcrystfel), + return ccall((:num_equivs, libcrystfel), Cint, (Ptr{InternalSymOpList},Ptr{Cvoid}), sym.internalptr, C_NULL) end function hkl_op(op::SymOp) - s = ccall((:name_equiv, :libcrystfel), + s = ccall((:name_equiv, libcrystfel), Cstring, (Ptr{InternalIntegerMatrix},), op.internalptr) @@ -73,7 +77,7 @@ end function symmetry_name(sym::SymOpList) - s = ccall((:symmetry_name, :libcrystfel), + s = ccall((:symmetry_name, libcrystfel), Cstring, (Ptr{InternalSymOpList},), sym.internalptr) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index c929634f..0adcfbe5 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -3,7 +3,6 @@ using CrystFEL dtempl = loaddatatemplate("julia/alignment-test.geom") image = Image(dtempl) -cell = UnitCell(123, 45, 80, 90, 97, 90, - centering='P', latticetype=MonoclinicLattice, uniqueaxis='b') +cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) truth = predictreflections(image, cell) -- cgit v1.2.3 From a6979502fec6d886db320db36b6e4e58bfb21ebc Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 3 Nov 2023 10:56:07 +0100 Subject: Julia: loadreflist: Fix symmetry --- julia/CrystFEL/src/reflists.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 2052e068..09e333b6 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -14,15 +14,16 @@ end function loadreflist(filename::AbstractString) - psym = Ptr{InternalSymOpList}() + psym = Ref{Cstring}() out = ccall((:read_reflections_2, libcrystfel), - Ptr{InternalRefList}, (Cstring,Ptr{InternalSymOpList}), + Ptr{InternalRefList}, (Cstring,Ref{Cstring}), filename, psym) if out == C_NULL throw(ArgumentError("Failed to load reflection list")) end - return RefList(out, SymOpList(psym)) + symmetryname = unsafe_string(psym[]) + return RefList(out, SymOpList(symmetryname)) end -- cgit v1.2.3 From 5d9308e7ded065be506f1bb32e49c073eac85686 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 3 Nov 2023 11:37:40 +0100 Subject: Julia: show/print/display methods for RefList and SymOpList --- julia/CrystFEL/src/reflists.jl | 14 ++++++++++++-- julia/CrystFEL/src/symmetry.jl | 12 +++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 09e333b6..65912e32 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -1,17 +1,21 @@ module RefLists import ..CrystFEL: libcrystfel -import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList - +import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name export RefList, loadreflist + +# The internal libcrystfel structure, not exposed directly mutable struct InternalRefList end + +# The Julian exposed type mutable struct RefList internalptr::Ptr{InternalRefList} symmetry::SymOpList end + function loadreflist(filename::AbstractString) psym = Ref{Cstring}() @@ -27,4 +31,10 @@ function loadreflist(filename::AbstractString) end + +function Base.show(io::IO, ::MIME"text/plain", reflist::RefList) + write(io, "Reflection list in point group ", symmetry_name(reflist.symmetry)) +end + + end # of module diff --git a/julia/CrystFEL/src/symmetry.jl b/julia/CrystFEL/src/symmetry.jl index eddf9a18..fd3ce7b2 100644 --- a/julia/CrystFEL/src/symmetry.jl +++ b/julia/CrystFEL/src/symmetry.jl @@ -2,6 +2,7 @@ module Symmetry import ..CrystFEL: libcrystfel export SymOpList, InternalSymOpList, InternalIntegerMatrix +export symmetry_name # Types for pointers returned by libcrystfel @@ -99,14 +100,19 @@ function Base.iterate(sym::SymOpList, i) end -function Base.show(io::IO, sym::SymOpList) - println(io, length(sym), "-element SymOpList (\"", symmetry_name(sym), "\")") +function Base.show(io::IO, ::MIME"text/plain", sym::SymOpList) + print(io, length(sym), "-element SymOpList (\"", symmetry_name(sym), "\")") for op in sym - println(io, hkl_op(op)) + print(io, "\n", hkl_op(op)) end end +function Base.show(io::IO, sym::SymOpList) + write(io, "SymOpList(\"", symmetry_name(sym), "\")") +end + + function Base.show(io::IO, op::SymOp) write(io, "SymOp(") write(io, "\"") -- cgit v1.2.3 From e1715b4d56c69140f3de93ad0db82f0c8a1deecd Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 5 Nov 2023 15:57:56 +0100 Subject: Julia: Add RefList iteration --- julia/CrystFEL/src/reflists.jl | 48 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 65912e32..09c23ccb 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -5,16 +5,58 @@ import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name export RefList, loadreflist -# The internal libcrystfel structure, not exposed directly +# The internal libcrystfel structures, not exposed directly +# We only ever have e.g. a Ptr{InternalRefList}, never a real InternalRefList mutable struct InternalRefList end +mutable struct InternalReflection end +mutable struct InternalRefListIterator end - -# The Julian exposed type +# The Julian exposed types mutable struct RefList internalptr::Ptr{InternalRefList} symmetry::SymOpList end +mutable struct Reflection + internalptr::Ptr{InternalReflection} +end + +mutable struct RefListIterator + lastrefl::Ptr{InternalReflection} + internalptr::Ptr{InternalRefListIterator} +end + + +function Base.iterate(a::RefList) + + ir = Ref{Ptr{InternalRefListIterator}}() + refl = ccall((:first_refl, libcrystfel), + Ptr{InternalReflection}, (Ptr{InternalRefList},Ref{Ptr{InternalRefListIterator}}), + a.internalptr, ir) + + if refl == C_NULL + throw(ArgumentError("Failed to find first reflection in list")) + end + + return Reflection(refl),RefListIterator(refl, ir[]) + +end + + +function Base.iterate(a::RefList, iter) + + refl = ccall((:next_refl, libcrystfel), + Ptr{InternalReflection}, (Ptr{InternalReflection},Ptr{InternalRefListIterator}), + iter.lastrefl, iter.internalptr) + + if refl == C_NULL + return nothing + end + + return Reflection(refl),RefListIterator(refl, iter.internalptr) + +end + function loadreflist(filename::AbstractString) -- cgit v1.2.3 From 94b29b9267795ec53534212907daaa09c0f3c696 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 5 Nov 2023 18:28:20 +0100 Subject: Julia: Better RefList iteration If the iteration ends early, the finalizer gives us a chance to free the RefListIterator. --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/reflists.jl | 33 ++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 66ad1176..5577ba7e 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -40,6 +40,6 @@ export Image include("reflists.jl") using .RefLists -export RefList, Reflection, loadreflist, savereflections +export RefList, Reflection, loadreflist, reflections end # of module diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 09c23ccb..96d2ec29 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -2,7 +2,7 @@ module RefLists import ..CrystFEL: libcrystfel import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name -export RefList, loadreflist +export RefList, loadreflist, reflections # The internal libcrystfel structures, not exposed directly @@ -22,38 +22,57 @@ mutable struct Reflection end mutable struct RefListIterator + reflist::RefList lastrefl::Ptr{InternalReflection} internalptr::Ptr{InternalRefListIterator} end -function Base.iterate(a::RefList) +function reflections(reflist::RefList) + iter = RefListIterator(reflist, C_NULL, C_NULL) + finalizer(iter) do x + if x.internalptr != C_NULL + ccall((:free_reflistiterator, libcrystfel), + Cvoid, (Ptr{InternalRefListIterator},), x.internalptr) + end + end + return iter +end + - ir = Ref{Ptr{InternalRefListIterator}}() +function Base.iterate(iter::RefListIterator) + + rli = Ref{Ptr{InternalRefListIterator}}(C_NULL) refl = ccall((:first_refl, libcrystfel), Ptr{InternalReflection}, (Ptr{InternalRefList},Ref{Ptr{InternalRefListIterator}}), - a.internalptr, ir) + iter.reflist.internalptr, rli) if refl == C_NULL throw(ArgumentError("Failed to find first reflection in list")) end - return Reflection(refl),RefListIterator(refl, ir[]) + iter.lastrefl = refl + iter.internalptr = rli[] + + return Reflection(refl),iter end -function Base.iterate(a::RefList, iter) +function Base.iterate(iter::RefListIterator, _) refl = ccall((:next_refl, libcrystfel), Ptr{InternalReflection}, (Ptr{InternalReflection},Ptr{InternalRefListIterator}), iter.lastrefl, iter.internalptr) if refl == C_NULL + iter.internalptr = C_NULL # libcrystfel already freed it return nothing end - return Reflection(refl),RefListIterator(refl, iter.internalptr) + iter.lastrefl = refl + + return Reflection(refl),iter end -- cgit v1.2.3 From 4f76cdc6230f901824131ba6566c845ca70aa1b6 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 5 Nov 2023 18:28:59 +0100 Subject: Julia: Add initial 'show' method for Reflection --- julia/CrystFEL/src/reflists.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 96d2ec29..e75939fb 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -98,4 +98,15 @@ function Base.show(io::IO, ::MIME"text/plain", reflist::RefList) end +function intensity(refl::Reflection) + ccall((:get_intensity, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) +end + +function Base.show(io::IO, refl::Reflection) + write(io, "Reflection(intensity=") + show(io, intensity(refl)) + write(io, ")") +end + end # of module -- cgit v1.2.3 From b18c4ccaa82068cd9979f9ea94f22c73dad7eb1d Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 6 Nov 2023 10:54:49 +0100 Subject: Julia: Implement Reflection fields --- julia/CrystFEL/src/reflists.jl | 108 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 5 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index e75939fb..c4f96e3d 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -98,14 +98,112 @@ function Base.show(io::IO, ::MIME"text/plain", reflist::RefList) end -function intensity(refl::Reflection) - ccall((:get_intensity, libcrystfel), - Cdouble, (Ptr{InternalReflection},), refl.internalptr) +function detectorpos(refl::Reflection) + pfs = Ref{Cdouble}(0) + pss = Ref{Cdouble}(0) + pn = ccall((:get_panel_number, libcrystfel), + Cint, (Ptr{InternalReflection},), refl.internalptr) + ccall((:get_detector_pos, libcrystfel), + Cint, (Ptr{InternalReflection},Ref{Cdouble},Ref{Cdouble}), + refl.internalptr, pfs, pss) + (fs=pfs[], ss=pss[], panelnumber=pn) end + +function indices(refl::Reflection) + h = Ref{Cint}(0) + k = Ref{Cint}(0) + l = Ref{Cint}(0) + ccall((:get_indices, libcrystfel), + Cint, (Ptr{InternalReflection},Ref{Cint},Ref{Cint},Ref{Cint}), + refl.internalptr, h, k, l) + (h[], k[], l[]) +end + + +function symmetricindices(refl::Reflection) + h = Ref{Cint}(0) + k = Ref{Cint}(0) + l = Ref{Cint}(0) + ccall((:get_symmetric_indices, libcrystfel), + Cint, (Ptr{InternalReflection},Ref{Cint},Ref{Cint},Ref{Cint}), + refl.internalptr, h, k, l) + (h[], k[], l[]) +end + + +function Base.getproperty(refl::Reflection, name::Symbol) + if name === :intensity + ccall((:get_intensity, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :sigintensity + ccall((:get_esd_intensity, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :partiality + ccall((:get_partiality, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :khalf + ccall((:get_khalf, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :kpred + ccall((:get_kpred, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :excitationerror + ccall((:get_exerr, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :lorentzfactor + ccall((:get_lorentz, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :phase + ccall((:get_phase, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :peak + ccall((:get_peak, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :meanbackground + ccall((:get_mean_bg, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :temp1 + ccall((:get_temp1, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :temp2 + ccall((:get_temp2, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :nmeasurements + ccall((:get_redundancy, libcrystfel), + Cint, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :flag + ccall((:get_flag, libcrystfel), + Cint, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :detectorposition + detectorpos(refl) + elseif name === :indices + indices(refl) + elseif name === :symmetricindices + symmetricindices(refl) + else + getfield(refl, name) + end +end + + +function Base.propertynames(::Reflection; private=false) + names = (:intensity,:sigintensity,:partiality,:khalf,:kpred,:lorentzfactor, + :excitationerror,:phase,:peak,:meanbackground,:temp1,:temp2, + :nmeasurements,:flag,:detectorposition,:indices,:symmetricindices) + if private + tuple(names..., :internalptr) + else + names + end +end + + function Base.show(io::IO, refl::Reflection) - write(io, "Reflection(intensity=") - show(io, intensity(refl)) + write(io, "Reflection(") + show(io, refl.indices) + write(io, ", intensity=") + show(io, refl.intensity) write(io, ")") end -- cgit v1.2.3 From 168202c140a1d6507e7c183983af39f62c472e64 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 6 Nov 2023 15:38:06 +0100 Subject: Julia: RefList: better pretty-printing --- julia/CrystFEL/Project.toml | 3 +++ julia/CrystFEL/src/reflists.jl | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/Project.toml b/julia/CrystFEL/Project.toml index 2c6596b0..6be52e40 100644 --- a/julia/CrystFEL/Project.toml +++ b/julia/CrystFEL/Project.toml @@ -2,3 +2,6 @@ name = "CrystFEL" uuid = "02864af1-98e3-4af5-94a7-a156d2a4edba" authors = ["Thomas White "] version = "0.1.0" + +[deps] +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index c4f96e3d..38232253 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -1,5 +1,6 @@ module RefLists +using Printf import ..CrystFEL: libcrystfel import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name export RefList, loadreflist, reflections @@ -94,7 +95,22 @@ end function Base.show(io::IO, ::MIME"text/plain", reflist::RefList) - write(io, "Reflection list in point group ", symmetry_name(reflist.symmetry)) + println(io, "Reflection list in point group ", symmetry_name(reflist.symmetry)) + print(io, " h k l intensity") + let n = 0 + for refl in Iterators.take(reflections(reflist), 11) + if n == 10 + # We have printed 10 already, and are here again. Truncate... + print(io, "\n ⋮ ⋮ ⋮ ⋮") + break + end + let ind = refl.indices + write(io, "\n") + @printf(io, "%4i %4i %4i %10.2f", ind[1], ind[2], ind[3], refl.intensity) + n += 1 + end + end + end end -- cgit v1.2.3 From 79304d62e3fc25ceae0268cf4e293fafd1b5a2b5 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 6 Nov 2023 15:38:14 +0100 Subject: Julia: RefListIterator: add more iteration methods --- julia/CrystFEL/src/reflists.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 38232253..0ac1e1f5 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -78,6 +78,11 @@ function Base.iterate(iter::RefListIterator, _) end +Base.IteratorEltype(::RefListIterator) = Reflection + +Base.isdone(iter::RefListIterator) = ((iter.internalptr == C_NULL) && (iter.lastrefl != C_NULL)) + + function loadreflist(filename::AbstractString) psym = Ref{Cstring}() -- cgit v1.2.3 From 92c95e86a747c661d755431a258bdecf25f819fd Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 6 Nov 2023 15:47:55 +0100 Subject: Julia: RefList: basic subscripting --- julia/CrystFEL/src/reflists.jl | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 0ac1e1f5..7905416d 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -13,15 +13,15 @@ mutable struct InternalReflection end mutable struct InternalRefListIterator end # The Julian exposed types -mutable struct RefList - internalptr::Ptr{InternalRefList} - symmetry::SymOpList -end - mutable struct Reflection internalptr::Ptr{InternalReflection} end +mutable struct RefList <: AbstractArray{Reflection, 3} + internalptr::Ptr{InternalRefList} + symmetry::SymOpList +end + mutable struct RefListIterator reflist::RefList lastrefl::Ptr{InternalReflection} @@ -79,10 +79,25 @@ end Base.IteratorEltype(::RefListIterator) = Reflection - Base.isdone(iter::RefListIterator) = ((iter.internalptr == C_NULL) && (iter.lastrefl != C_NULL)) +IndexStyle(::RefList) = IndexCartesian() + +function Base.getindex(reflist::RefList, h, k, l) + + refl = ccall((:find_refl, libcrystfel), + Ptr{InternalReflection}, (Ptr{InternalRefList},Cint,Cint,Cint), + reflist.internalptr, h, k, l) + + if refl == C_NULL + return nothing + else + return Reflection(refl) + end +end + + function loadreflist(filename::AbstractString) psym = Ref{Cstring}() -- cgit v1.2.3 From c490ab20dacb4a8ec327e172fd4fd48ebe947466 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 7 Nov 2023 17:28:35 +0100 Subject: Add Manifest.toml --- julia/CrystFEL/Manifest.toml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 julia/CrystFEL/Manifest.toml diff --git a/julia/CrystFEL/Manifest.toml b/julia/CrystFEL/Manifest.toml new file mode 100644 index 00000000..c59e01e9 --- /dev/null +++ b/julia/CrystFEL/Manifest.toml @@ -0,0 +1,12 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.9.2" +manifest_format = "2.0" +project_hash = "f604830d70fa58877def5710c5d1fa32dcb3f998" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" -- cgit v1.2.3 From 74081a5c3708b73daf29b40776562ff73c128b0b Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 7 Nov 2023 18:11:02 +0100 Subject: Julia: Remove explicit reflections() iterator creation This appears not to be necessary. I'd just got my thoughts into a twist. Either that, or I've forgotten the reason why this doesn't work. Let's see... --- julia/CrystFEL/src/reflists.jl | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 7905416d..f62bf010 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -3,7 +3,7 @@ module RefLists using Printf import ..CrystFEL: libcrystfel import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name -export RefList, loadreflist, reflections +export RefList, loadreflist # The internal libcrystfel structures, not exposed directly @@ -23,44 +23,34 @@ mutable struct RefList <: AbstractArray{Reflection, 3} end mutable struct RefListIterator - reflist::RefList lastrefl::Ptr{InternalReflection} internalptr::Ptr{InternalRefListIterator} end -function reflections(reflist::RefList) - iter = RefListIterator(reflist, C_NULL, C_NULL) - finalizer(iter) do x - if x.internalptr != C_NULL - ccall((:free_reflistiterator, libcrystfel), - Cvoid, (Ptr{InternalRefListIterator},), x.internalptr) - end - end - return iter -end - - -function Base.iterate(iter::RefListIterator) +function Base.iterate(reflist::RefList) rli = Ref{Ptr{InternalRefListIterator}}(C_NULL) refl = ccall((:first_refl, libcrystfel), Ptr{InternalReflection}, (Ptr{InternalRefList},Ref{Ptr{InternalRefListIterator}}), - iter.reflist.internalptr, rli) + reflist.internalptr, rli) if refl == C_NULL throw(ArgumentError("Failed to find first reflection in list")) end - iter.lastrefl = refl - iter.internalptr = rli[] + iter = RefListIterator(refl,rli[]) + finalizer(iter) do x + ccall((:free_reflistiterator, libcrystfel), + Cvoid, (Ptr{InternalRefListIterator},), x.internalptr) + end return Reflection(refl),iter end -function Base.iterate(iter::RefListIterator, _) +function Base.iterate(::RefList, iter) refl = ccall((:next_refl, libcrystfel), Ptr{InternalReflection}, (Ptr{InternalReflection},Ptr{InternalRefListIterator}), @@ -118,7 +108,7 @@ function Base.show(io::IO, ::MIME"text/plain", reflist::RefList) println(io, "Reflection list in point group ", symmetry_name(reflist.symmetry)) print(io, " h k l intensity") let n = 0 - for refl in Iterators.take(reflections(reflist), 11) + for refl in Iterators.take(reflist, 11) if n == 10 # We have printed 10 already, and are here again. Truncate... print(io, "\n ⋮ ⋮ ⋮ ⋮") -- cgit v1.2.3 From 25007d935f34186cc4bcdc0e73de6e4ecc0bd623 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 8 Nov 2023 09:43:50 +0100 Subject: RefList indexing details RefLists are a bit strange. They're logically Cartesian arrays with 3 indexes, but they're not really designed for indexing in this way. Rather, we always want to index them linearly, from start to finish. --- julia/CrystFEL/src/reflists.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index f62bf010..3c7d2d6a 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -68,12 +68,13 @@ function Base.iterate(::RefList, iter) end +Base.IndexStyle(::RefList) = IndexLinear() Base.IteratorEltype(::RefListIterator) = Reflection Base.isdone(iter::RefListIterator) = ((iter.internalptr == C_NULL) && (iter.lastrefl != C_NULL)) +Base.size(reflist::RefList) = ccall((:num_reflections, libcrystfel), + Cint, (Ptr{InternalRefList},), reflist.internalptr) -IndexStyle(::RefList) = IndexCartesian() - function Base.getindex(reflist::RefList, h, k, l) refl = ccall((:find_refl, libcrystfel), -- cgit v1.2.3 From 09cfb76007454cc5791e088675c4f458de240531 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 8 Nov 2023 10:16:03 +0100 Subject: Julia: Distinguish between merged and unmerged reflections An experiment. The C interface doesn't have this distinction, but it seems like it might be helpful. --- julia/CrystFEL/src/CrystFEL.jl | 3 +- julia/CrystFEL/src/reflists.jl | 76 ++++++++++++++++++++++++++++++++---------- 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 5577ba7e..0496897f 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -40,6 +40,7 @@ export Image include("reflists.jl") using .RefLists -export RefList, Reflection, loadreflist, reflections +export RefList, loadreflist +export Reflection, MergedReflection, UnmergedReflection end # of module diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 3c7d2d6a..362b53db 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -4,6 +4,7 @@ using Printf import ..CrystFEL: libcrystfel import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name export RefList, loadreflist +export Reflection, UnmergedReflection, MergedReflection # The internal libcrystfel structures, not exposed directly @@ -13,11 +14,9 @@ mutable struct InternalReflection end mutable struct InternalRefListIterator end # The Julian exposed types -mutable struct Reflection - internalptr::Ptr{InternalReflection} -end +abstract type Reflection end -mutable struct RefList <: AbstractArray{Reflection, 3} +mutable struct RefList{T<:Reflection} <: AbstractArray{T, 3} internalptr::Ptr{InternalRefList} symmetry::SymOpList end @@ -27,8 +26,16 @@ mutable struct RefListIterator internalptr::Ptr{InternalRefListIterator} end +mutable struct MergedReflection <: Reflection + internalptr::Ptr{InternalReflection} +end + +mutable struct UnmergedReflection <: Reflection + internalptr::Ptr{InternalReflection} +end -function Base.iterate(reflist::RefList) + +function Base.iterate(reflist::RefList{T}) where T rli = Ref{Ptr{InternalRefListIterator}}(C_NULL) refl = ccall((:first_refl, libcrystfel), @@ -45,12 +52,12 @@ function Base.iterate(reflist::RefList) Cvoid, (Ptr{InternalRefListIterator},), x.internalptr) end - return Reflection(refl),iter + return T(refl),iter end -function Base.iterate(::RefList, iter) +function Base.iterate(::RefList{T}, iter) where T refl = ccall((:next_refl, libcrystfel), Ptr{InternalReflection}, (Ptr{InternalReflection},Ptr{InternalRefListIterator}), @@ -63,19 +70,19 @@ function Base.iterate(::RefList, iter) iter.lastrefl = refl - return Reflection(refl),iter + return T(refl),iter end Base.IndexStyle(::RefList) = IndexLinear() -Base.IteratorEltype(::RefListIterator) = Reflection +Base.IteratorEltype(::RefList{T}) where T = T Base.isdone(iter::RefListIterator) = ((iter.internalptr == C_NULL) && (iter.lastrefl != C_NULL)) Base.size(reflist::RefList) = ccall((:num_reflections, libcrystfel), Cint, (Ptr{InternalRefList},), reflist.internalptr) -function Base.getindex(reflist::RefList, h, k, l) +function Base.getindex(reflist::RefList{T}, h, k, l) where T refl = ccall((:find_refl, libcrystfel), Ptr{InternalReflection}, (Ptr{InternalRefList},Cint,Cint,Cint), @@ -84,7 +91,7 @@ function Base.getindex(reflist::RefList, h, k, l) if refl == C_NULL return nothing else - return Reflection(refl) + return T(refl) end end @@ -100,13 +107,33 @@ function loadreflist(filename::AbstractString) end symmetryname = unsafe_string(psym[]) - return RefList(out, SymOpList(symmetryname)) + return RefList{MergedReflection}(out, SymOpList(symmetryname)) end -function Base.show(io::IO, ::MIME"text/plain", reflist::RefList) - println(io, "Reflection list in point group ", symmetry_name(reflist.symmetry)) +function Base.show(io::IO, ::MIME"text/plain", reflist::RefList{MergedReflection}) + println(io, "Merged reflection list in point group ", symmetry_name(reflist.symmetry)) + print(io, " h k l intensity") + let n = 0 + for refl in Iterators.take(reflist, 11) + if n == 10 + # We have printed 10 already, and are here again. Truncate... + print(io, "\n ⋮ ⋮ ⋮ ⋮") + break + end + let ind = refl.indices + write(io, "\n") + @printf(io, "%4i %4i %4i %10.2f", ind[1], ind[2], ind[3], refl.intensity) + n += 1 + end + end + end +end + + +function Base.show(io::IO, ::MIME"text/plain", reflist::RefList{UnmergedReflection}) + println(io, "Unmerged reflection list in point group ", symmetry_name(reflist.symmetry)) print(io, " h k l intensity") let n = 0 for refl in Iterators.take(reflist, 11) @@ -214,7 +241,7 @@ function Base.getproperty(refl::Reflection, name::Symbol) end -function Base.propertynames(::Reflection; private=false) +function Base.propertynames(::UnmergedReflection; private=false) names = (:intensity,:sigintensity,:partiality,:khalf,:kpred,:lorentzfactor, :excitationerror,:phase,:peak,:meanbackground,:temp1,:temp2, :nmeasurements,:flag,:detectorposition,:indices,:symmetricindices) @@ -226,11 +253,26 @@ function Base.propertynames(::Reflection; private=false) end -function Base.show(io::IO, refl::Reflection) - write(io, "Reflection(") +function Base.propertynames(::MergedReflection; private=false) + names = (:intensity,:sigintensity,:phase,:temp1,:temp2, + :nmeasurements,:flag,:indices,:symmetricindices) + if private + tuple(names..., :internalptr) + else + names + end +end + + +function Base.show(io::IO, refl::MergedReflection) + write(io, "MergedReflection(") show(io, refl.indices) write(io, ", intensity=") show(io, refl.intensity) + write(io, ", σ(intensity)=") + show(io, refl.sigintensity) + write(io, ", nmeasurements=") + show(io, refl.nmeasurements) write(io, ")") end -- cgit v1.2.3 From a117a52f03dbba5ac030f5256752b0f39613d4ba Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 8 Nov 2023 16:24:15 +0100 Subject: Update alignment-test.jl --- julia/alignment-test.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 0adcfbe5..a72c79c6 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -2,7 +2,6 @@ using CrystFEL dtempl = loaddatatemplate("julia/alignment-test.geom") image = Image(dtempl) - cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) - -truth = predictreflections(image, cell) +cr = Crystal(cell, image) +truth = predictreflections(cr, image) -- cgit v1.2.3 From d482752291dce86107bf97cda0e163db6fcc7b70 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 9 Nov 2023 11:07:25 +0100 Subject: Julia: add initial Crystal type and reflection prediction --- julia/CrystFEL/src/CrystFEL.jl | 8 ++++++++ julia/CrystFEL/src/crystal.jl | 40 ++++++++++++++++++++++++++++++++++++++++ julia/CrystFEL/src/diffcalc.jl | 21 +++++++++++++++++++++ julia/alignment-test.jl | 3 ++- 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 julia/CrystFEL/src/crystal.jl create mode 100644 julia/CrystFEL/src/diffcalc.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 0496897f..590b8973 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -43,4 +43,12 @@ using .RefLists export RefList, loadreflist export Reflection, MergedReflection, UnmergedReflection +include("crystal.jl") +using .Crystals +export Crystal, InternalCrystal + +include("diffcalc.jl") +using .DiffractionCalculations +export predictreflections + end # of module diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl new file mode 100644 index 00000000..9e222554 --- /dev/null +++ b/julia/CrystFEL/src/crystal.jl @@ -0,0 +1,40 @@ +module Crystals + +import ..CrystFEL: libcrystfel +import ..CrystFEL.RefLists: RefList, UnmergedReflection +import ..CrystFEL.UnitCells: UnitCell, InternalUnitCell +export Crystal, InternalCrystal + +# Represents the real C-side (opaque) structure. +mutable struct InternalCrystal end + +mutable struct Crystal + internalptr::Ptr{InternalCrystal} +end + + +function Crystal(cell::UnitCell) + + out = ccall((:crystal_new, libcrystfel), + Ptr{InternalCrystal}, ()) + + if out == C_NULL + throw(ArgumentError("Failed to create crystal")) + end + + ccall((:crystal_set_cell, libcrystfel), + Cvoid, (Ptr{InternalCrystal},Ptr{InternalUnitCell}), + out, cell.internalptr) + + cr = Crystal(out) + + finalizer(cr) do x + ccall((:crystal_free, libcrystfel), Cvoid, (Ptr{InternalCrystal},), + x.internalptr) + end + + return cr +end + + +end # of module diff --git a/julia/CrystFEL/src/diffcalc.jl b/julia/CrystFEL/src/diffcalc.jl new file mode 100644 index 00000000..2e039a20 --- /dev/null +++ b/julia/CrystFEL/src/diffcalc.jl @@ -0,0 +1,21 @@ +module DiffractionCalculations + +import ..CrystFEL: libcrystfel +import ..CrystFEL.Images: InternalImage +import ..CrystFEL.Crystals: InternalCrystal +import ..CrystFEL.RefLists: RefList, UnmergedReflection, InternalRefList +import ..CrystFEL.Symmetry: SymOpList +export predictreflections + + +function predictreflections(cr, image; maxres=1e10) + refls = ccall((:predict_to_res, libcrystfel), + Ptr{InternalRefList}, + (Ptr{InternalCrystal}, Ptr{InternalImage}, Cdouble), + cr.internalptr, image.internalptr, maxres) + sym = SymOpList("1") + return RefList{UnmergedReflection}(refls, sym) +end + + +end # of module diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index a72c79c6..397ed094 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -3,5 +3,6 @@ using CrystFEL dtempl = loaddatatemplate("julia/alignment-test.geom") image = Image(dtempl) cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) -cr = Crystal(cell, image) +cr = Crystal(cell) truth = predictreflections(cr, image) +println(truth) -- cgit v1.2.3 From dfdb8e50c49f7199ab43f5e92dcd16251055e4a0 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 9 Nov 2023 11:59:51 +0100 Subject: Julia: display methods for RefList{UnmergedReflection} --- julia/CrystFEL/src/reflists.jl | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 362b53db..9f8b7262 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -134,17 +134,20 @@ end function Base.show(io::IO, ::MIME"text/plain", reflist::RefList{UnmergedReflection}) println(io, "Unmerged reflection list in point group ", symmetry_name(reflist.symmetry)) - print(io, " h k l intensity") + print(io, " h k l intensity σ(intens) fs ss panel") let n = 0 for refl in Iterators.take(reflist, 11) if n == 10 # We have printed 10 already, and are here again. Truncate... - print(io, "\n ⋮ ⋮ ⋮ ⋮") + print(io, "\n ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮") break end - let ind = refl.indices + let ind = refl.indices, + pos = refl.detectorposition write(io, "\n") - @printf(io, "%4i %4i %4i %10.2f", ind[1], ind[2], ind[3], refl.intensity) + @printf(io, "%4i %4i %4i %10.2f %10.2f %7.2f %7.2f %6i", + ind[1], ind[2], ind[3], refl.intensity, refl.sigintensity, + pos.fs, pos.ss, pos.panelnumber) n += 1 end end @@ -276,4 +279,18 @@ function Base.show(io::IO, refl::MergedReflection) write(io, ")") end + +function Base.show(io::IO, refl::UnmergedReflection) + write(io, "UnmergedReflection(") + show(io, refl.indices) + write(io, " at "); + show(io, refl.detectorposition) + write(io, ", intensity=") + show(io, refl.intensity) + write(io, ", σ(intensity)=") + show(io, refl.sigintensity) + write(io, ")") +end + + end # of module -- cgit v1.2.3 From 4c1815e5c9d8ce2e0b7f596182e2d1736cb8cf2a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 9 Nov 2023 12:12:28 +0100 Subject: Add sigI and nmeas to show(::RefList{MergedReflection}) --- julia/CrystFEL/src/reflists.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 9f8b7262..5fb28b39 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -114,17 +114,18 @@ end function Base.show(io::IO, ::MIME"text/plain", reflist::RefList{MergedReflection}) println(io, "Merged reflection list in point group ", symmetry_name(reflist.symmetry)) - print(io, " h k l intensity") + print(io, " h k l intensity σ(intens) nmeas") let n = 0 for refl in Iterators.take(reflist, 11) if n == 10 # We have printed 10 already, and are here again. Truncate... - print(io, "\n ⋮ ⋮ ⋮ ⋮") + print(io, "\n ⋮ ⋮ ⋮ ⋮ ⋮ ⋮") break end let ind = refl.indices write(io, "\n") - @printf(io, "%4i %4i %4i %10.2f", ind[1], ind[2], ind[3], refl.intensity) + @printf(io, "%4i %4i %4i %10.2f %10.2f %5i", ind[1], ind[2], ind[3], + refl.intensity, refl.sigintensity, refl.nmeasurements) n += 1 end end -- cgit v1.2.3 From 8ad62271e568c6e80a7b69dccfd575007dca7946 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 10 Nov 2023 21:07:53 +0100 Subject: Julia: Remove AbstractArray bits from RefList --- julia/CrystFEL/src/reflists.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 5fb28b39..007f0f07 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -16,7 +16,7 @@ mutable struct InternalRefListIterator end # The Julian exposed types abstract type Reflection end -mutable struct RefList{T<:Reflection} <: AbstractArray{T, 3} +mutable struct RefList{T<:Reflection} internalptr::Ptr{InternalRefList} symmetry::SymOpList end @@ -75,11 +75,10 @@ function Base.iterate(::RefList{T}, iter) where T end -Base.IndexStyle(::RefList) = IndexLinear() Base.IteratorEltype(::RefList{T}) where T = T Base.isdone(iter::RefListIterator) = ((iter.internalptr == C_NULL) && (iter.lastrefl != C_NULL)) -Base.size(reflist::RefList) = ccall((:num_reflections, libcrystfel), - Cint, (Ptr{InternalRefList},), reflist.internalptr) +Base.length(reflist::RefList) = ccall((:num_reflections, libcrystfel), + Cint, (Ptr{InternalRefList},), reflist.internalptr) function Base.getindex(reflist::RefList{T}, h, k, l) where T -- cgit v1.2.3 From b22775e1e512a28c6918a3f77cc91e55ef8a1750 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 13 Nov 2023 08:56:03 +0100 Subject: Julia: Implement PeakList --- julia/CrystFEL/src/CrystFEL.jl | 4 +++ julia/CrystFEL/src/image.jl | 3 +- julia/CrystFEL/src/peaklist.jl | 82 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 julia/CrystFEL/src/peaklist.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 590b8973..76305e24 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -34,6 +34,10 @@ include("datatemplates.jl") using .DataTemplates export DataTemplate, loaddatatemplate +include("peaklist.jl") +using .PeakLists +export PeakList + include("image.jl") using .Images export Image diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 0f2d91d7..ca0a3da0 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -3,6 +3,7 @@ module Images import ..CrystFEL: libcrystfel import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate import ..CrystFEL.DetGeoms: DetGeom +import ..CrystFEL.PeakLists: PeakList, InternalPeakList export Image const HEADER_CACHE_SIZE = 128 @@ -32,7 +33,7 @@ mutable struct InternalImage div::Cdouble bw::Cdouble peak_resolution::Cdouble - features::Ptr{Cvoid} + peaks::Ptr{InternalPeakList} ida::Ptr{Cvoid} end diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl new file mode 100644 index 00000000..4814437f --- /dev/null +++ b/julia/CrystFEL/src/peaklist.jl @@ -0,0 +1,82 @@ +module PeakLists + +import ..CrystFEL: libcrystfel +export PeakList, InternalPeakList + +mutable struct InternalPeak + fs::Cdouble + ss::Cdouble + panelnumber::Cint + intensity::Cdouble + name::Cstring +end + +mutable struct InternalPeakList end + +struct PeakList + internalptr::Ptr{InternalPeakList} +end + + +function PeakList() + out = @ccall libcrystfel.image_feature_list_new()::Ptr{InternalPeakList} + if out == C_NULL + throw(ArgumentError("Failed to create peak list")) + end + PeakList(out) +end + + +function Base.length(peaklist::PeakList) + @ccall libcrystfel.image_feature_count(peaklist.internalptr::Ptr{InternalPeakList})::Cint +end + +Base.firstindex(peaklist::PeakList) = 1 +Base.lastindex(peaklist::PeakList) = length(peaklist) + + +function Base.push!(peaklist::PeakList, fs, ss, panelnumber, intensity, name=nothing) + + rname = isnothing(name) ? C_NULL : @ccall strdup(name::Cstring)::Cstring + + @ccall libcrystfel.image_add_feature(peaklist.internalptr::Ptr{InternalPeakList}, + fs::Cdouble, ss::Cdouble, panelnumber::Cint, + intensity::Cdouble, rname::Cstring)::Cvoid +end + + +function Base.getindex(peaklist::PeakList, n) + out = @ccall(libcrystfel.image_get_feature(peaklist.internalptr::Ptr{InternalPeakList}, + (n-1)::Cint)::Ptr{InternalPeak}) + if out == C_NULL + throw(BoundsError(peaklist, n)) + end + pdata = unsafe_load(out) + if pdata.name == C_NULL + nname = nothing + else + nname = unsafe_string(pdata.name) + end + return (fs=pdata.fs, ss=pdata.ss, panelnumber=pdata.panelnumber, + intensity=pdata.intensity, name=nname) +end + + +function Base.iterate(peaklist::PeakList) + return peaklist[1],(1,length(peaklist)) +end + + +function Base.iterate(peaklist::PeakList, state) + let nxt = state[1]+1 + len = state[2] + if nxt == len+1 + return nothing + else + return peaklist[nxt],(nxt,state[2]) + end + end +end + + +end # of module -- cgit v1.2.3 From 769915be06260591e2bdf5a04849dac269a2d3af Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 14 Nov 2023 10:52:46 +0100 Subject: Julia: Avoid segfault if image doesn't have a peak list --- julia/CrystFEL/src/image.jl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index ca0a3da0..0ffb8474 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -33,7 +33,7 @@ mutable struct InternalImage div::Cdouble bw::Cdouble peak_resolution::Cdouble - peaks::Ptr{InternalPeakList} + peaklist::Ptr{InternalPeakList} ida::Ptr{Cvoid} end @@ -48,7 +48,17 @@ function Base.getproperty(image::Image, name::Symbol) getfield(image, :internalptr) else idata = unsafe_load(image.internalptr) - getproperty(idata, name) + if name === :peaklist + let pl = getproperty(idata, :peaklist) + if pl == C_NULL + throw(ErrorException("Image doesn't have a peak list")) + else + PeakList(pl) + end + end + else + getproperty(idata, name) + end end end -- cgit v1.2.3 From 7513e4e2849a7a6c03bd5075ad579c2167c41ff5 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 15 Nov 2023 11:25:15 +0100 Subject: Setters for image struct --- julia/CrystFEL/src/image.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 0ffb8474..868afdc4 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -63,6 +63,23 @@ function Base.getproperty(image::Image, name::Symbol) end +function Base.setproperty!(image::Image, name::Symbol, val) + if name === :internalptr + setfield!(image, :internalptr, val) + else + idata = unsafe_load(image.internalptr) + if name === :peaklist + if val isa PeakList + setproperty!(idata, name, val.internalptr) + unsafe_store!(image.internalptr, idata) + else + throw(ArgumentError("Must be a PeakList")) + end + end + end +end + + function Base.propertynames(image::Image; private=false) if private fieldnames(InternalImage) -- cgit v1.2.3 From c752752fc4b7d477a8284a41c948b29e9bbe53e5 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 15 Nov 2023 11:25:25 +0100 Subject: Show method for PeakList --- julia/CrystFEL/src/peaklist.jl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl index 4814437f..0ca1fa4d 100644 --- a/julia/CrystFEL/src/peaklist.jl +++ b/julia/CrystFEL/src/peaklist.jl @@ -1,5 +1,6 @@ module PeakLists +using Printf import ..CrystFEL: libcrystfel export PeakList, InternalPeakList @@ -79,4 +80,22 @@ function Base.iterate(peaklist::PeakList, state) end +function Base.show(io::IO, ::MIME"text/plain", peaklist::PeakList) + println(io, "Peak list with ", length(peaklist), " peaks") + print(io, " fs ss panel intensity name") + let n = 0 + for pk in Iterators.take(peaklist, 11) + if n == 10 + # We have printed 10 already, and are here again. Truncate... + print(io, "\n ⋮ ⋮ ⋮ ⋮ ⋮") + break + end + write(io, "\n") + @printf(io, "%7.2f %7.2f %6i %10.2f %s", + pk.fs, pk.ss, pk.panelnumber, pk.intensity, pk.name) + n += 1 + end + end +end + end # of module -- cgit v1.2.3 From dd4229075833077eeb4e12eea06604cbf2e057a9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 15 Nov 2023 17:02:19 +0100 Subject: Julia: initial indexing framework --- julia/CrystFEL/src/CrystFEL.jl | 4 +++ julia/CrystFEL/src/indexing.jl | 61 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 julia/CrystFEL/src/indexing.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 76305e24..33ca75a8 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -55,4 +55,8 @@ include("diffcalc.jl") using .DiffractionCalculations export predictreflections +include("indexing.jl") +using .Indexing +export Indexer + end # of module diff --git a/julia/CrystFEL/src/indexing.jl b/julia/CrystFEL/src/indexing.jl new file mode 100644 index 00000000..a7798f6f --- /dev/null +++ b/julia/CrystFEL/src/indexing.jl @@ -0,0 +1,61 @@ +module Indexing + +import ..CrystFEL: libcrystfel +import ..CrystFEL.UnitCells: UnitCell, InternalUnitCell +export Indexer + +mutable struct IndexingPriv end + +mutable struct Indexer + indexingpriv::Ptr{IndexingPriv} +end + + +function Indexer(methods, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), + retry=true, multilattice=false, refine=true, peakcheck=true, cellcheck=true, + wavelength_estimate=0.0, clen_estimate=0.0, n_threads=1) + + taketwoopts = Ref{Ptr{Cvoid}}(C_NULL) + xgandalfopts = Ref{Ptr{Cvoid}}(C_NULL) + pinkindexeropts = Ref{Ptr{Cvoid}}(C_NULL) + felixopts = Ref{Ptr{Cvoid}}(C_NULL) + fromfileopts = Ref{Ptr{Cvoid}}(C_NULL) + asdfopts = Ref{Ptr{Cvoid}}(C_NULL) + + @ccall libcrystfel.default_method_options(taketwoopts::Ref{Ptr{Cvoid}}, + xgandalfopts::Ref{Ptr{Cvoid}}, + pinkindexeropts::Ref{Ptr{Cvoid}}, + felixopts::Ref{Ptr{Cvoid}}, + fromfileopts::Ref{Ptr{Cvoid}}, + asdfopts::Ref{Ptr{Cvoid}})::Cvoid + + out = @ccall libcrystfel.setup_indexing(methods::Cstring, + cell.internalptr::Ptr{InternalUnitCell}, + tolerances::Ref{NTuple{6,Cdouble}}, + 0::Cint, + wavelength_estimate::Cdouble, + clen_estimate::Cdouble, + n_threads::Cint, + taketwoopts[]::Ptr{Cvoid}, + xgandalfopts[]::Ptr{Cvoid}, + pinkindexeropts[]::Ptr{Cvoid}, + felixopts[]::Ptr{Cvoid}, + fromfileopts[]::Ptr{Cvoid}, + asdfopts[]::Ptr{Cvoid})::Ptr{IndexingPriv} + + if out == C_NULL + throw(ErrorException("Indexing setup failed")) + end + + indexer = Indexer(out) + + finalizer(indexer) do x + @ccall libcrystfel.cleanup_indexing(x.indexingpriv::Ptr{IndexingPriv})::Cvoid + end + + return indexer + +end + + +end # of module -- cgit v1.2.3 From ac750a6db8d663e49050d3f0335b413b00d74689 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 15 Nov 2023 17:02:30 +0100 Subject: Update alignment-test.jl --- julia/alignment-test.jl | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 397ed094..0e9ef170 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -1,8 +1,25 @@ using CrystFEL +using Random +# Create empty image for simulation purposes dtempl = loaddatatemplate("julia/alignment-test.geom") image = Image(dtempl) + +# Create a crystal and calculate its reflections cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) -cr = Crystal(cell) +cr = Crystal(cell) # FIXME: Random rotation truth = predictreflections(cr, image) -println(truth) + +# Sketch a diffraction pattern +image.peaklist = PeakList() +for refl in truth + if randn() > 3 + let dpos = refl.detectorposition + push!(image.peaklist, dpos.fs, dpos.ss, dpos.panelnumber, 100.0) + end + end +end + +# Index the pattern +indexer = Indexing("asdf-cell", cell, retry=false, multilattice=false, refine=true) +index(image, indexer) -- cgit v1.2.3 From 46077543748be731ea53d115cb26bc1c9e489914 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 16 Nov 2023 10:11:54 +0100 Subject: Julia: Implement indexing flags --- julia/CrystFEL/src/indexing.jl | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/indexing.jl b/julia/CrystFEL/src/indexing.jl index a7798f6f..862fdaec 100644 --- a/julia/CrystFEL/src/indexing.jl +++ b/julia/CrystFEL/src/indexing.jl @@ -11,6 +11,27 @@ mutable struct Indexer end +function indexflags(retry, multilattice, refine, peakcheck, cellcheck) + flags = 0 + if retry + flags |= 1 + end + if multilattice + flags |= 2 + end + if refine + flags |= 4 + end + if peakcheck + flags |= 32 + end + if cellcheck + flags |= 64 + end + return flags +end + + function Indexer(methods, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), retry=true, multilattice=false, refine=true, peakcheck=true, cellcheck=true, wavelength_estimate=0.0, clen_estimate=0.0, n_threads=1) @@ -29,10 +50,12 @@ function Indexer(methods, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), fromfileopts::Ref{Ptr{Cvoid}}, asdfopts::Ref{Ptr{Cvoid}})::Cvoid + flags = indexflags(retry, multilattice, refine, peakcheck, cellcheck) + out = @ccall libcrystfel.setup_indexing(methods::Cstring, cell.internalptr::Ptr{InternalUnitCell}, tolerances::Ref{NTuple{6,Cdouble}}, - 0::Cint, + flags::Cint, wavelength_estimate::Cdouble, clen_estimate::Cdouble, n_threads::Cint, -- cgit v1.2.3 From 2662f07afb9fbfe82c01cd110903d8afff3f8395 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 16 Nov 2023 10:12:07 +0100 Subject: Julia: Run the indexer pipeline --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/indexing.jl | 12 +++++++++++- julia/alignment-test.jl | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 33ca75a8..11de649a 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -57,6 +57,6 @@ export predictreflections include("indexing.jl") using .Indexing -export Indexer +export Indexer, index end # of module diff --git a/julia/CrystFEL/src/indexing.jl b/julia/CrystFEL/src/indexing.jl index 862fdaec..aad9847a 100644 --- a/julia/CrystFEL/src/indexing.jl +++ b/julia/CrystFEL/src/indexing.jl @@ -2,7 +2,8 @@ module Indexing import ..CrystFEL: libcrystfel import ..CrystFEL.UnitCells: UnitCell, InternalUnitCell -export Indexer +import ..CrystFEL.Images: Image, InternalImage +export Indexer, index mutable struct IndexingPriv end @@ -81,4 +82,13 @@ function Indexer(methods, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), end +function index(image::Image, idxr::Indexer) + @ccall libcrystfel.index_pattern_4(image.internalptr::Ptr{InternalImage}, + idxr.indexingpriv::Ptr{IndexingPriv}, + C_NULL::Ptr{Cvoid}, + C_NULL::Ptr{Cvoid}, + C_NULL::Ptr{Cvoid})::Cvoid +end + + end # of module diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 0e9ef170..df0bb03e 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -21,5 +21,5 @@ for refl in truth end # Index the pattern -indexer = Indexing("asdf-cell", cell, retry=false, multilattice=false, refine=true) +indexer = Indexer("asdf-cell", cell, retry=false, multilattice=false, refine=true) index(image, indexer) -- cgit v1.2.3 From 30ccd129a682afd067ee105e8d9de7486be16a47 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 16 Nov 2023 11:18:10 +0100 Subject: Use wavelength and clen from DataTemplate if possible --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/datatemplates.jl | 46 +++++++++++++++++++++++++++++++++++++ julia/CrystFEL/src/indexing.jl | 27 ++++++++++++++++++++-- julia/alignment-test.jl | 2 +- 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 11de649a..aa1b4518 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -32,7 +32,7 @@ export SymOpList include("datatemplates.jl") using .DataTemplates -export DataTemplate, loaddatatemplate +export DataTemplate, loaddatatemplate, wavelength, cameralength include("peaklist.jl") using .PeakLists diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index cdb6c09b..16433d9f 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -2,6 +2,7 @@ module DataTemplates import ..CrystFEL: libcrystfel export DataTemplate, InternalDataTemplate, loaddatatemplate +export wavelength, cameralength # Represents the real C-side (opaque) structure. mutable struct InternalDataTemplate end @@ -37,4 +38,49 @@ function loaddatatemplate(filename::AbstractString) return dt end + +""" + wavelength(datatemplate) + +Retrieves the radiation wavelength from a `DataTemplate`, if possible. + +It's not always possible to do this. Some geometry files declare the +wavelength as a parameter to be retrieved fom each image's metadata. A +program using this routine should take this possibility into account. + +Corresponds to CrystFEL C API function `data_template_get_wavelength_if_possible`. +""" +function wavelength(dtempl::DataTemplate) + wl = ccall((:data_template_get_wavelength_if_possible, libcrystfel), + Cdouble, (Ptr{InternalDataTemplate},), dtempl.internalptr) + if isnan(wl) + return nothing + else + return wl + end +end + + +""" + cameralength(datatemplate) + +Retrieves the camera length from a `DataTemplate`, if possible. + +It's not always possible to do this. Some geometry files declare the +detector position(s) as a parameter to be retrieved fom each image's metadata. A +program using this routine should take this possibility into account. + +Corresponds to CrystFEL C API function `data_template_get_clen_if_possible`. +""" +function cameralength(dtempl::DataTemplate) + clen = ccall((:data_template_get_clen_if_possible, libcrystfel), + Cdouble, (Ptr{InternalDataTemplate},), dtempl.internalptr) + if isnan(clen) + return nothing + else + return clen + end +end + + end # of module diff --git a/julia/CrystFEL/src/indexing.jl b/julia/CrystFEL/src/indexing.jl index aad9847a..3e4423a1 100644 --- a/julia/CrystFEL/src/indexing.jl +++ b/julia/CrystFEL/src/indexing.jl @@ -3,6 +3,7 @@ module Indexing import ..CrystFEL: libcrystfel import ..CrystFEL.UnitCells: UnitCell, InternalUnitCell import ..CrystFEL.Images: Image, InternalImage +import ..CrystFEL.DataTemplates: wavelength, cameralength export Indexer, index mutable struct IndexingPriv end @@ -33,9 +34,9 @@ function indexflags(retry, multilattice, refine, peakcheck, cellcheck) end -function Indexer(methods, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), +function Indexer(methods, dtempl, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), retry=true, multilattice=false, refine=true, peakcheck=true, cellcheck=true, - wavelength_estimate=0.0, clen_estimate=0.0, n_threads=1) + wavelength_estimate=nothing, clen_estimate=missing, n_threads=1) taketwoopts = Ref{Ptr{Cvoid}}(C_NULL) xgandalfopts = Ref{Ptr{Cvoid}}(C_NULL) @@ -53,6 +54,28 @@ function Indexer(methods, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), flags = indexflags(retry, multilattice, refine, peakcheck, cellcheck) + let wlfromdtempl = wavelength(dtempl) + if !isnothing(wlfromdtempl) + wavelength_estimate = wlfromdtempl + else + if isnothing(wavelength_estimate) + throw(ArgumentError("Wavelength cannot be determined from data template. "* + "Use Indexer(wavelength_estimate=...)")) + end + end + end + + let clenfromdtempl = cameralength(dtempl) + if !isnothing(clenfromdtempl) + clen_estimate = clenfromdtempl + else + if isnothing(clen_estimate) + throw(ArgumentError("Camera length cannot be determined from data template. "* + "Use Indexer(clen_estimate=...)")) + end + end + end + out = @ccall libcrystfel.setup_indexing(methods::Cstring, cell.internalptr::Ptr{InternalUnitCell}, tolerances::Ref{NTuple{6,Cdouble}}, diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index df0bb03e..0779b8db 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -21,5 +21,5 @@ for refl in truth end # Index the pattern -indexer = Indexer("asdf-cell", cell, retry=false, multilattice=false, refine=true) +indexer = Indexer("asdf-cell", dtempl, cell, retry=false, multilattice=false, refine=true) index(image, indexer) -- cgit v1.2.3 From 2381479b2a45ac4931c972d467f1face9fb55bb6 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 16 Nov 2023 14:04:48 +0100 Subject: Julia: Set profile radius and mosaicity for Crystal --- julia/CrystFEL/src/crystal.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index 9e222554..1c0143e2 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -13,7 +13,7 @@ mutable struct Crystal end -function Crystal(cell::UnitCell) +function Crystal(cell::UnitCell; profileradius=2e6, mosaicity=0) out = ccall((:crystal_new, libcrystfel), Ptr{InternalCrystal}, ()) @@ -26,6 +26,14 @@ function Crystal(cell::UnitCell) Cvoid, (Ptr{InternalCrystal},Ptr{InternalUnitCell}), out, cell.internalptr) + ccall((:crystal_set_profile_radius, libcrystfel), + Cvoid, (Ptr{InternalCrystal},Cdouble), + out, profileradius) + + ccall((:crystal_set_mosaicity, libcrystfel), + Cvoid, (Ptr{InternalCrystal},Cdouble), + out, mosaicity) + cr = Crystal(out) finalizer(cr) do x -- cgit v1.2.3 From 1fa4821361cb47e689f5622bb1e6f8ab9b17bf54 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 16 Nov 2023 14:05:02 +0100 Subject: PeakList: Handle zero-length lists better --- julia/CrystFEL/src/peaklist.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl index 0ca1fa4d..f8c9b407 100644 --- a/julia/CrystFEL/src/peaklist.jl +++ b/julia/CrystFEL/src/peaklist.jl @@ -64,7 +64,11 @@ end function Base.iterate(peaklist::PeakList) - return peaklist[1],(1,length(peaklist)) + if length(peaklist) > 0 + return peaklist[1],(1,length(peaklist)) + else + return nothing + end end -- cgit v1.2.3 From 3e467fb7f9ed331212ee2434eee8afd0355b96ff Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 16 Nov 2023 14:11:48 +0100 Subject: Update alignment-test.jl --- julia/alignment-test.jl | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 0779b8db..345c7d77 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -10,16 +10,35 @@ cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) cr = Crystal(cell) # FIXME: Random rotation truth = predictreflections(cr, image) -# Sketch a diffraction pattern -image.peaklist = PeakList() -for refl in truth - if randn() > 3 - let dpos = refl.detectorposition - push!(image.peaklist, dpos.fs, dpos.ss, dpos.panelnumber, 100.0) +# "Simulate" a diffraction pattern from the reflections +function sketch_pattern(reflist) + peaks = PeakList() + for refl in reflist + if randn() > 0 + let dpos = refl.detectorposition + push!(peaks, dpos.fs, dpos.ss, dpos.panelnumber, 100.0) + end end end + return peaks end +image.peaklist = sketch_pattern(truth) + # Index the pattern -indexer = Indexer("asdf-cell", dtempl, cell, retry=false, multilattice=false, refine=true) +indexer = Indexer("asdf", dtempl, cell, retry=false, multilattice=false, refine=true) index(image, indexer) + + +# Utility routine for visualising peaks +function plotpanel(image, pn) + x = [] + y = [] + for pk in image.peaklist + if pk.panelnumber == pn + push!(x, pk.fs) + push!(y, pk.ss) + end + end + scatter(x, y) +end -- cgit v1.2.3 From 793d4e1f725a9cf3a569ef95cdd8fdca080219d7 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 16 Nov 2023 16:36:02 +0100 Subject: Julia: CrystFEL.Indexing.Indexer: Fix tolerance parameter --- julia/CrystFEL/src/indexing.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/indexing.jl b/julia/CrystFEL/src/indexing.jl index 3e4423a1..60e293d9 100644 --- a/julia/CrystFEL/src/indexing.jl +++ b/julia/CrystFEL/src/indexing.jl @@ -76,9 +76,17 @@ function Indexer(methods, dtempl, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), end end + tols = Vector{Cfloat}(undef, 6) + tols[1] = tolerances[1] + tols[2] = tolerances[2] + tols[3] = tolerances[3] + tols[4] = deg2rad(tolerances[4]) + tols[5] = deg2rad(tolerances[5]) + tols[6] = deg2rad(tolerances[6]) + out = @ccall libcrystfel.setup_indexing(methods::Cstring, cell.internalptr::Ptr{InternalUnitCell}, - tolerances::Ref{NTuple{6,Cdouble}}, + tols::Ptr{Cfloat}, flags::Cint, wavelength_estimate::Cdouble, clen_estimate::Cdouble, -- cgit v1.2.3 From 371d46c0a9bc0ba1a279cfea561e389c755292ef Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 1 Dec 2023 14:18:22 +0100 Subject: Stub documentation for Julia bindings --- doc/articles/julia.rst | 178 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 doc/articles/julia.rst diff --git a/doc/articles/julia.rst b/doc/articles/julia.rst new file mode 100644 index 00000000..ac27873c --- /dev/null +++ b/doc/articles/julia.rst @@ -0,0 +1,178 @@ +========================== +Using libCrystFEL in Julia +========================== + +CrystFEL's shared library component, *libcrystfel*, can be accessed from +`Julia `_. This way, you can carry out almost any +process available in the CrystFEL tools, and much more besides. + +The Julia package for CrystFEL is found in the ``julia`` directory of the +CrystFEL source code package. The easiest way to get started is to use +``Pkg.develop``. Start Julia, press ``]``, then run the following command, +substituting the correct location of the CrystFEL package on your system:: + + (@v1.9) pkg> dev /home/twhite/crystfel/julia/CrystFEL + +Afterwards, import the CrystFEL package as follows:: + + julia> using CrystFEL + +It's imperative that the same version of the Julia package is used as CrystFEL +itself, otherwise you are likely to experience spontaneous crashes of the +whole Julia session. + +You only need to perform the ``pkg dev`` process once, not every session. Should +you ever need to, you can remove the CrystFEL package in the usual way:: + + (@v1.9) pkg> rm CrystFEL + +The Julia package for CrystFEL is a fairly thin wrapper around the +`libcrystfel C API `_, +so you can read the API documentation for some idea of the possibilities. +Below is a brief overview. + + +Unit cells +========== + +Create a ``UnitCell`` object as follows:: + + cell = UnitCell(MonoclinicLattice, PrimitiveCell, UniqueAxisB, 123, 45, 80, 90, 97, 90) + +The arguments are, in order: + +* Lattice type, one of ``TriclinicLattice``, ``MonoclinicLattice``, + ``OrthorhombicLattice``, ``TetragonalLattice``, ``HexagonalLattice``, + ``RhombohedralLattice`` or ``CubicLattice``. +* Centering, one of ``PrimitiveCell`` (P), ``ACenteredCell``, ``BCenteredCell``, + ``CCenteredCell``, ``BodyCenteredCell`` (I), ``FaceCenteredCell`` (F), + ``RhombohedralCell`` (R) or ``RhombohedralCellOnHexagonalAxes`` ("H"). +* Unique axis, one of ``UniqueAxisA``, ``UniqueAxisB``, ``UniqueAxisC``, + ``NoUniqueAxis`` (for lattice types that do not have a unique axis, e.g. cubic), + or ``UnknownUniqueAxis`` (which should be avoided, but is sometimes necessary). +* Cell axis lengths a,b,c, in Angstroms. +* Cell angles α,β,γ, in degrees. + +For many cases, you don't need to specify every parameter. Where possible, the +unique axis will be determined from the cell parameters, and can be omitted:: + + cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) + +Cell axis lengths, angles and centering types can be omitted if they are fixed +by the lattice type. For example:: + + julia> UnitCell(CubicLattice, FaceCenteredCell, 40) + UnitCell(CubicLattice, FaceCenteredCell, NoUniqueAxis, + 40.0 Å, 40.0 Å, 40.0 Å, 90.0°, 90.0°, 90.0°) + +or:: + + julia> UnitCell(RhombohedralLattice, 23, 75) + UnitCell(RhombohedralLattice, RhombohedralCell, NoUniqueAxis, + 23.0 Å, 23.0 Å, 23.0 Å, 75.0°, 75.0°, 75.0°) + + +Reflection lists +================ + +In Julia, a distinction is made between merged and unmerged reflections. No +such distinction exists in CrystFEL's C API. Merged reflections have +multiplicities (number of contributing measurements), whereas unmerged +reflections have detector locations, background levels and parameters related +to diffraction geometry such as excitation errors and Lorentz factors. In +reality, both types of reflection have all fields, just as for the C API. The +distinction controls how the objects are printed, and may help in writing +clearer programs. + +Load a reflection list from a data file (".hkl file") using +``loadreflist``:: + + julia> q = loadreflist("example.hkl") + Merged reflection list in point group mmm + h k l intensity σ(intens) nmeas + 0 0 5 23.45 124.51 11 + 0 0 6 32302.69 10091.34 8 + 0 0 7 -87.37 167.23 5 + 0 0 8 8051.75 3828.24 6 + 0 0 9 94.13 128.59 3 + 0 0 10 3703.07 1118.85 5 + 0 0 11 4.81 31.46 5 + 0 0 12 27287.94 14143.77 6 + 0 0 13 148.50 32.46 2 + 0 0 14 818.33 447.23 3 + ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ + +This produces a merged reflection list:: + + julia> typeof(q) + RefList{MergedReflection} + +Unmerged reflection lists (``RefList{UnmergedReflection}``) come from spot +prediction - see below. + +Reflection lists can be iterated over. For example:: + + julia> for refl in q + println(refl) + end + MergedReflection((0, 0, 5), intensity=23.450000762939453, σ(intensity)=124.51000213623047, nmeasurements=11) + MergedReflection((0, 0, 6), intensity=32302.689453125, σ(intensity)=10091.33984375, nmeasurements=8) + MergedReflection((0, 0, 7), intensity=-87.37000274658203, σ(intensity)=167.22999572753906, nmeasurements=5) + MergedReflection((0, 0, 8), intensity=8051.75, σ(intensity)=3828.239990234375, nmeasurements=6) + MergedReflection((0, 0, 9), intensity=94.12999725341797, σ(intensity)=128.58999633789062, nmeasurements=3) + MergedReflection((0, 0, 10), intensity=3703.070068359375, σ(intensity)=1118.8499755859375, nmeasurements=5) + MergedReflection((0, 0, 11), intensity=4.809999942779541, σ(intensity)=31.459999084472656, nmeasurements=5) + MergedReflection((0, 0, 12), intensity=27287.939453125, σ(intensity)=14143.76953125, nmeasurements=6) + MergedReflection((0, 0, 13), intensity=148.5, σ(intensity)=32.459999084472656, nmeasurements=2) + MergedReflection((0, 0, 14), intensity=818.3300170898438, σ(intensity)=447.2300109863281, nmeasurements=3) + ... + +You can subscript a RefList using Miller indices:: + + julia> q[1, 13, 43] + MergedReflection((1, 13, 43), intensity=-28.18000030517578, σ(intensity)=7.230000019073486, nmeasurements=6) + +Linear indexing is **not** supported, so you **can't** do things like +``q[10:end]``. + + +Symmetry +======== + +Symmetry operations are represented by ``SymOp`` objects, which are contained +within ``SymOpList`` objects. A point group is therefore represented by a +``SymOpList``. + +Create a point group from the Herman-Mauguin symbol as follows:: + + julia> s = SymOpList("2/m") + 4-element SymOpList ("2/m") + -h,-k,l + h,k,-l + hkl + -h,-k,-l + +The list can be subscripted linearly:: + + julia> s[1] + SymOp("-h,-k,l") + +Note that not all ``SymOpList`` objects represent a point group. One +counterexample is lists of indexing ambiguity operations. + + +Peak lists +========== + + +Crystals +======== + + +Indexing +======== + + +Prediction +========== + -- cgit v1.2.3 From 1340c96cc8af6df9a5d587649d5e2334fc94497d Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 14 Dec 2023 14:35:29 +0100 Subject: Prevent adding a PeakList to two different images This is kind-of-OK in C, but will break Julia's memory management. --- julia/CrystFEL/src/image.jl | 7 ++++++- julia/CrystFEL/src/peaklist.jl | 13 +++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 868afdc4..4f126c28 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -53,7 +53,7 @@ function Base.getproperty(image::Image, name::Symbol) if pl == C_NULL throw(ErrorException("Image doesn't have a peak list")) else - PeakList(pl) + PeakList(pl, true) end end else @@ -70,7 +70,12 @@ function Base.setproperty!(image::Image, name::Symbol, val) idata = unsafe_load(image.internalptr) if name === :peaklist if val isa PeakList + if val.in_image + throw(ArgumentError("PeakList is already in an image. "* + "Add a copy (use `deepcopy`) instead.")) + end setproperty!(idata, name, val.internalptr) + val.in_image = true unsafe_store!(image.internalptr, idata) else throw(ArgumentError("Must be a PeakList")) diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl index f8c9b407..1735de5e 100644 --- a/julia/CrystFEL/src/peaklist.jl +++ b/julia/CrystFEL/src/peaklist.jl @@ -14,8 +14,9 @@ end mutable struct InternalPeakList end -struct PeakList +mutable struct PeakList internalptr::Ptr{InternalPeakList} + in_image # if true, this PeakList belongs to an Image struct end @@ -24,10 +25,18 @@ function PeakList() if out == C_NULL throw(ArgumentError("Failed to create peak list")) end - PeakList(out) + PeakList(out, false) end +function Base.deepcopy(peaklist::PeakList) + out = @ccall libcrystfel.image_feature_list_copy(peaklist.internalptr::Ptr{InternalPeakList})::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Failed to copy peak list")) + end + PeakList(out, false) +end + function Base.length(peaklist::PeakList) @ccall libcrystfel.image_feature_count(peaklist.internalptr::Ptr{InternalPeakList})::Cint end -- cgit v1.2.3 From f9fa74c28a8b484cb4c268bcde4469c1b77ea3fe Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 14 Dec 2023 16:08:05 +0100 Subject: Detector alignment simulation (WIP) --- julia/CrystFEL/src/CrystFEL.jl | 1 + julia/CrystFEL/src/cell.jl | 18 ++++++++++++++ julia/alignment-test-moved.geom | 49 ++++++++++++++++++++++++++++++++++++ julia/alignment-test.jl | 55 +++++++++++++++++++++-------------------- 4 files changed, 96 insertions(+), 27 deletions(-) create mode 100644 julia/alignment-test-moved.geom diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index aa1b4518..47f09d41 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -21,6 +21,7 @@ export TetragonalLattice, HexagonalLattice, RhombohedralLattice, CubicLattice export PrimitiveCell, ACenteredCell, BCenteredCell, CCenteredCell export BodyCenteredCell, FaceCenteredCell, RhombohedralCell, RhombohedralCellOnHexagonalAxes export NoUniqueAxis, UnknownUniqueAxis, UniqueAxisA, UniqueAxisB, UniqueAxisC +export rotatecell include("detgeom.jl") using .DetGeoms diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl index b094770a..80250221 100644 --- a/julia/CrystFEL/src/cell.jl +++ b/julia/CrystFEL/src/cell.jl @@ -7,6 +7,7 @@ export TetragonalLattice, HexagonalLattice, RhombohedralLattice, CubicLattice export PrimitiveCell, ACenteredCell, BCenteredCell, CCenteredCell export BodyCenteredCell, FaceCenteredCell, RhombohedralCell, RhombohedralCellOnHexagonalAxes export NoUniqueAxis, UnknownUniqueAxis, UniqueAxisA, UniqueAxisB, UniqueAxisC +export rotatecell # Represents the real C-side (opaque) structure. @@ -305,4 +306,21 @@ function Base.show(io::IO, uc::UnitCell) end +mutable struct CrystFELQuaternion + w::Cdouble + x::Cdouble + y::Cdouble + z::Cdouble +end + +function rotatecell(uc, quat) + q = CrystFELQuaternion(quat...) + out = @ccall libcrystfel.cell_rotate(uc.internalptr::Ptr{InternalUnitCell}, + q::CrystFELQuaternion)::Ptr{InternalUnitCell} + if out == C_NULL + throw(ErrorException("Failed to rotate unit cell")) + end + UnitCell(out) +end + end # of module diff --git a/julia/alignment-test-moved.geom b/julia/alignment-test-moved.geom new file mode 100644 index 00000000..c1943056 --- /dev/null +++ b/julia/alignment-test-moved.geom @@ -0,0 +1,49 @@ +adu_per_photon = 1 +res = 10000 +clen = 100.0 mm +photon_energy = 9000 eV + +dim0 = % +dim1 = ss +dim2 = fs +data = /data/data + +q0/dim0 = 0 +q0/min_fs = 0 +q0/min_ss = 0 +q0/max_fs = 1024 +q0/max_ss = 1024 +q0/fs = x +q0/ss = y +q0/corner_x = -1056 +q0/corner_y = 30 + +q1/dim0 = 1 +q1/min_fs = 0 +q1/min_ss = 0 +q1/max_fs = 1024 +q1/max_ss = 1024 +q1/fs = x +q1/ss = y +q1/corner_x = 30 +q1/corner_y = 30 + +q2/dim0 = 2 +q2/min_fs = 0 +q2/min_ss = 0 +q2/max_fs = 1024 +q2/max_ss = 1024 +q2/fs = x +q2/ss = y +q2/corner_x = 30 +q2/corner_y = -1054 + +q3/dim0 = 3 +q3/min_fs = 0 +q3/min_ss = 0 +q3/max_fs = 1024 +q3/max_ss = 1024 +q3/fs = x +q3/ss = y +q3/corner_x = -1054 +q3/corner_y = -1054 diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 345c7d77..e6e1ab63 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -1,44 +1,45 @@ using CrystFEL using Random -# Create empty image for simulation purposes -dtempl = loaddatatemplate("julia/alignment-test.geom") -image = Image(dtempl) - -# Create a crystal and calculate its reflections -cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) -cr = Crystal(cell) # FIXME: Random rotation -truth = predictreflections(cr, image) - # "Simulate" a diffraction pattern from the reflections -function sketch_pattern(reflist) - peaks = PeakList() +function sketch_pattern(image, cr) + reflist = predictreflections(cr, image) + peaklist = PeakList() for refl in reflist if randn() > 0 let dpos = refl.detectorposition - push!(peaks, dpos.fs, dpos.ss, dpos.panelnumber, 100.0) + push!(peaklist, dpos.fs, dpos.ss, dpos.panelnumber, 100.0) end end end - return peaks + return peaklist end -image.peaklist = sketch_pattern(truth) -# Index the pattern -indexer = Indexer("asdf", dtempl, cell, retry=false, multilattice=false, refine=true) -index(image, indexer) +function randomrotation(cell) + rotatecell(cell, (1,0,0,0)) +end -# Utility routine for visualising peaks -function plotpanel(image, pn) - x = [] - y = [] - for pk in image.peaklist - if pk.panelnumber == pn - push!(x, pk.fs) - push!(y, pk.ss) - end +function simulate_and_index(cell, image_true, dtempl_moved, n) + + indexer = Indexer("asdf", dtempl_moved, cell, retry=false, multilattice=false, refine=true) + + for _ in 1:n + + cr = Crystal(randomrotation(cell)) + peaklist = sketch_pattern(image_true, cr) + image_moved = Image(dtempl_moved) + + image_moved.peaklist = peaklist + index(image_moved, indexer) + end - scatter(x, y) end + + +dtempl_true = loaddatatemplate("julia/alignment-test.geom") +image_true = Image(dtempl_true) +cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) +dtempl_moved = loaddatatemplate("julia/alignment-test-moved.geom") +simulate_and_index(cell, image_true, dtempl_moved, 100) -- cgit v1.2.3 From e532c6dd7f5344fcdacfdca54bd2810f05d87b65 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 20 Dec 2023 11:06:33 +0100 Subject: Julia: Stream opening --- julia/CrystFEL/src/CrystFEL.jl | 4 ++++ julia/CrystFEL/src/streams.jl | 48 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 julia/CrystFEL/src/streams.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 47f09d41..17ad2677 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -60,4 +60,8 @@ include("indexing.jl") using .Indexing export Indexer, index +include("streams.jl") +using .Streams +export Stream + end # of module diff --git a/julia/CrystFEL/src/streams.jl b/julia/CrystFEL/src/streams.jl new file mode 100644 index 00000000..afc23f4c --- /dev/null +++ b/julia/CrystFEL/src/streams.jl @@ -0,0 +1,48 @@ +module Streams + +import ..CrystFEL: libcrystfel +import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate +export Stream + +# Represents the real C-side (opaque) structure. +mutable struct InternalStream end + +# The Julia-side structure, needed to house the pointer to the C structure +mutable struct Stream + internalptr::Ptr{InternalStream} +end + + +function Stream(filename, mode::AbstractString, dtempl::DataTemplate) + if mode == "w" + out = @ccall libcrystfel.stream_open_for_write(filename::Cstring, + dtempl.internalptr::Ptr{InternalDataTemplate})::Ptr{InternalStream} + if out == C_NULL + throw(ErrorException("Failed to open stream for reading")) + end + return Stream(out) + elseif mode =="r" + throw(ArgumentError("To open a stream for reading, don't provide the DataTemplate")) + else + throw(ArgumentError("Unrecognised CrystFEL stream mode"*mode)) + end +end + + +function Stream(filename, mode::AbstractString) + if mode == "r" + out = @ccall libcrystfel.stream_open_for_read(filename::Cstring)::Ptr{InternalStream} + if out == C_NULL + throw(ErrorException("Failed to open stream for reading")) + end + return Stream(out) + elseif mode == "w" + throw(ArgumentError("To open a stream for writing, you must provide " + *"a DataTemplate: use Stream(filename, \"w\", dtempl)")) + else + throw(ArgumentError("Unrecognised CrystFEL stream mode"*mode)) + end +end + + +end # of module -- cgit v1.2.3 From e437e0465f07f66e188613da9568d7fa7f19dec5 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 18 Dec 2023 11:41:30 +0100 Subject: Julia: Add cell rotation --- julia/CrystFEL/Manifest.toml | 13 ++++++++++++- julia/CrystFEL/Project.toml | 1 + julia/CrystFEL/src/cell.jl | 28 ++++++++++++++++++++++++++++ julia/alignment-test.jl | 7 +------ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/julia/CrystFEL/Manifest.toml b/julia/CrystFEL/Manifest.toml index c59e01e9..e4ee3ce8 100644 --- a/julia/CrystFEL/Manifest.toml +++ b/julia/CrystFEL/Manifest.toml @@ -2,11 +2,22 @@ julia_version = "1.9.2" manifest_format = "2.0" -project_hash = "f604830d70fa58877def5710c5d1fa32dcb3f998" +project_hash = "4cf05e6854a627b02f001d01f38d3c0cbfcf00bd" [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +[[deps.Random]] +deps = ["SHA", "Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/julia/CrystFEL/Project.toml b/julia/CrystFEL/Project.toml index 6be52e40..8c81af0f 100644 --- a/julia/CrystFEL/Project.toml +++ b/julia/CrystFEL/Project.toml @@ -5,3 +5,4 @@ version = "0.1.0" [deps] Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl index 80250221..c098f8ca 100644 --- a/julia/CrystFEL/src/cell.jl +++ b/julia/CrystFEL/src/cell.jl @@ -1,5 +1,7 @@ module UnitCells +using Random + import ..CrystFEL: libcrystfel export UnitCell, LatticeType, CenteringType, UniqueAxis export TriclinicLattice, MonoclinicLattice, OrthorhombicLattice @@ -306,6 +308,8 @@ function Base.show(io::IO, uc::UnitCell) end +# This type is for talking to libcrystfel, and is named to avoid conflicting +# with other quaternion libraries. mutable struct CrystFELQuaternion w::Cdouble x::Cdouble @@ -313,6 +317,18 @@ mutable struct CrystFELQuaternion z::Cdouble end +function randomquat() + r = ()->2.0*rand(Float64)-1.0 + q = [r(), r(), r(), r()] + q ./ √(sum(q.^2)) +end + + +""" + rotatecell(uc::UnitCell, quaternion) + +Rotate a unit cell according to a quaternion (represented as a vector of 4 floats). +""" function rotatecell(uc, quat) q = CrystFELQuaternion(quat...) out = @ccall libcrystfel.cell_rotate(uc.internalptr::Ptr{InternalUnitCell}, @@ -323,4 +339,16 @@ function rotatecell(uc, quat) UnitCell(out) end + +""" + rotatecell(uc::UnitCell) + +Rotate a unit cell at random in three dimensions. Use this routine for +simulating serial crystallography datasets. + +Equivalent to CrystFEL routine `cell_rotate(uc, random_quaternion())`. +""" +rotatecell(uc) = rotatecell(uc, randomquat()) + + end # of module diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index e6e1ab63..6fec3256 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -16,18 +16,13 @@ function sketch_pattern(image, cr) end -function randomrotation(cell) - rotatecell(cell, (1,0,0,0)) -end - - function simulate_and_index(cell, image_true, dtempl_moved, n) indexer = Indexer("asdf", dtempl_moved, cell, retry=false, multilattice=false, refine=true) for _ in 1:n - cr = Crystal(randomrotation(cell)) + cr = Crystal(rotatecell(cell)) peaklist = sketch_pattern(image_true, cr) image_moved = Image(dtempl_moved) -- cgit v1.2.3 From 90132628f5f66836aebfd3c7c7daf583f5bf5d86 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 19 Dec 2023 11:30:33 +0100 Subject: Julia: Add Millepede output --- julia/CrystFEL/src/CrystFEL.jl | 4 ++++ julia/CrystFEL/src/indexing.jl | 11 +++++++++-- julia/alignment-test-moved.geom | 2 ++ julia/alignment-test.geom | 2 ++ julia/alignment-test.jl | 7 ++++--- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 17ad2677..017bd530 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -64,4 +64,8 @@ include("streams.jl") using .Streams export Stream +include("millepede.jl") +using .Millepede +export Mille + end # of module diff --git a/julia/CrystFEL/src/indexing.jl b/julia/CrystFEL/src/indexing.jl index 60e293d9..7dabd15c 100644 --- a/julia/CrystFEL/src/indexing.jl +++ b/julia/CrystFEL/src/indexing.jl @@ -113,12 +113,19 @@ function Indexer(methods, dtempl, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), end -function index(image::Image, idxr::Indexer) +function index(image::Image, idxr::Indexer; mille=nothing) + + if mille === nothing + imille = C_NULL + else + imille = mille.internalptr + end + @ccall libcrystfel.index_pattern_4(image.internalptr::Ptr{InternalImage}, idxr.indexingpriv::Ptr{IndexingPriv}, C_NULL::Ptr{Cvoid}, C_NULL::Ptr{Cvoid}, - C_NULL::Ptr{Cvoid})::Cvoid + imille::Ptr{Cvoid})::Cvoid end diff --git a/julia/alignment-test-moved.geom b/julia/alignment-test-moved.geom index c1943056..c834973b 100644 --- a/julia/alignment-test-moved.geom +++ b/julia/alignment-test-moved.geom @@ -47,3 +47,5 @@ q3/fs = x q3/ss = y q3/corner_x = -1054 q3/corner_y = -1054 + +group_all = q0,q1,q2,q3 diff --git a/julia/alignment-test.geom b/julia/alignment-test.geom index 11668fca..b2be83c6 100644 --- a/julia/alignment-test.geom +++ b/julia/alignment-test.geom @@ -47,3 +47,5 @@ q3/fs = x q3/ss = y q3/corner_x = -1054 q3/corner_y = -1054 + +group_all = q0,q1,q2,q3 diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 6fec3256..3948c6fb 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -16,7 +16,7 @@ function sketch_pattern(image, cr) end -function simulate_and_index(cell, image_true, dtempl_moved, n) +function simulate_and_index(cell, image_true, dtempl_moved, mille, n) indexer = Indexer("asdf", dtempl_moved, cell, retry=false, multilattice=false, refine=true) @@ -27,7 +27,7 @@ function simulate_and_index(cell, image_true, dtempl_moved, n) image_moved = Image(dtempl_moved) image_moved.peaklist = peaklist - index(image_moved, indexer) + index(image_moved, indexer, mille=mille) end end @@ -37,4 +37,5 @@ dtempl_true = loaddatatemplate("julia/alignment-test.geom") image_true = Image(dtempl_true) cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) dtempl_moved = loaddatatemplate("julia/alignment-test-moved.geom") -simulate_and_index(cell, image_true, dtempl_moved, 100) +mille = Mille("mille.dat") +simulate_and_index(cell, image_true, dtempl_moved, mille, 100) -- cgit v1.2.3 From 1d9460ed7876112aa229cff5fc4062402f78c169 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 19 Dec 2023 11:58:13 +0100 Subject: Reduce number of simulation runs and add some output --- julia/alignment-test.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 3948c6fb..aecd3435 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -29,7 +29,11 @@ function simulate_and_index(cell, image_true, dtempl_moved, mille, n) image_moved.peaklist = peaklist index(image_moved, indexer, mille=mille) + print(".") + end + println("") + end @@ -38,4 +42,4 @@ image_true = Image(dtempl_true) cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) dtempl_moved = loaddatatemplate("julia/alignment-test-moved.geom") mille = Mille("mille.dat") -simulate_and_index(cell, image_true, dtempl_moved, mille, 100) +simulate_and_index(cell, image_true, dtempl_moved, mille, 10) -- cgit v1.2.3 From ed473b7f099e949f189dcd41d69cfb33d945705a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 19 Dec 2023 16:30:31 +0100 Subject: Add plot routine for alignment test --- julia/alignment-test.jl | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index aecd3435..84e0f65d 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -1,5 +1,6 @@ using CrystFEL using Random +using Plots # "Simulate" a diffraction pattern from the reflections function sketch_pattern(image, cr) @@ -20,7 +21,7 @@ function simulate_and_index(cell, image_true, dtempl_moved, mille, n) indexer = Indexer("asdf", dtempl_moved, cell, retry=false, multilattice=false, refine=true) - for _ in 1:n + for i in 1:n cr = Crystal(rotatecell(cell)) peaklist = sketch_pattern(image_true, cr) @@ -29,7 +30,11 @@ function simulate_and_index(cell, image_true, dtempl_moved, mille, n) image_moved.peaklist = peaklist index(image_moved, indexer, mille=mille) - print(".") + if i % 100 == 0 + print("*") + else + print(".") + end end println("") @@ -41,5 +46,27 @@ dtempl_true = loaddatatemplate("julia/alignment-test.geom") image_true = Image(dtempl_true) cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) dtempl_moved = loaddatatemplate("julia/alignment-test-moved.geom") -mille = Mille("mille.dat") -simulate_and_index(cell, image_true, dtempl_moved, mille, 10) + + +function plotresiduals(filename) + + l = @layout([q0 q1; q2 q3]) + a = collect(Iterators.flatten(t)) + + function ploth(n, offs, label) + histogram(map(x->x.residual,filter(x->in(n, keys(x.globalgradients)), a[offs:3:end])), label=label) + end + + q0 = ploth(101, 1, "q0") + q1 = ploth(201, 1, "q1") + q2 = ploth(301, 1, "q2") + q3 = ploth(401, 1, "q3") + plot(q0, q1, q2, q3, layout=l, plot_title="Fast scan residual") + + #q0 = ploth(102, 2, "q0") + #q1 = ploth(202, 2, "q1") + #q2 = ploth(302, 2, "q2") + #q3 = ploth(402, 2, "q3") + #plot(q0, q1, q2, q3, layout=l, plot_title="Slow scan residual", reuse=false) + +end -- cgit v1.2.3 From a54740542de1610b63027e1224b89546b42278e3 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 20 Dec 2023 12:57:32 +0100 Subject: Add missing millepede.jl --- julia/CrystFEL/src/millepede.jl | 42 +++++++++++++++++++++++++++++++++++++++++ julia/alignment-test.jl | 4 ++++ 2 files changed, 46 insertions(+) create mode 100644 julia/CrystFEL/src/millepede.jl diff --git a/julia/CrystFEL/src/millepede.jl b/julia/CrystFEL/src/millepede.jl new file mode 100644 index 00000000..a65256dc --- /dev/null +++ b/julia/CrystFEL/src/millepede.jl @@ -0,0 +1,42 @@ +module Millepede + +import ..CrystFEL: libcrystfel +export Mille + +mutable struct InternalMille end + +mutable struct Mille + internalptr::Ptr{InternalMille} +end + + +""" + Mille(filename) + +Creates a new "Mille" object, which can be passed to `CrystFEL.Indexing.index()` +to accumulate detector geometry alignment information in the specified file. + +When you've finished adding data, call `close()` on the Mille object. This will +be done automatically when the object is freed by the garbage collector, but +that might not happen until Julia exits. + +Corresponds to CrystFEL C API routine `crystfel_mille_new`. +""" +function Mille(filename::AbstractString) + out = @ccall libcrystfel.crystfel_mille_new(filename::Cstring)::Ptr{InternalMille} + if out == C_NULL + throw(ArgumentError("Failed to create Millepede object")) + end + finalizer(close, Mille(out)) +end + + +function Base.close(x::Mille) + if x.internalptr != C_NULL + @ccall libcrystfel.crystfel_mille_free(x.internalptr::Ptr{InternalMille})::Cvoid + x.internalptr = C_NULL + end +end + + +end # of module diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 84e0f65d..9a7a7202 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -46,6 +46,10 @@ dtempl_true = loaddatatemplate("julia/alignment-test.geom") image_true = Image(dtempl_true) cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) dtempl_moved = loaddatatemplate("julia/alignment-test-moved.geom") +let mille = Mille("mille.dat") + simulate_and_index(cell, image_true, dtempl_true, mille, 100) + close(mille) +end function plotresiduals(filename) -- cgit v1.2.3 From dfa3ecf8c416470609f97b3b2eeafc5914fc4ba8 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 20 Dec 2023 12:57:50 +0100 Subject: Julia: Stream semantics --- julia/CrystFEL/src/streams.jl | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/streams.jl b/julia/CrystFEL/src/streams.jl index afc23f4c..94a1de17 100644 --- a/julia/CrystFEL/src/streams.jl +++ b/julia/CrystFEL/src/streams.jl @@ -13,36 +13,68 @@ mutable struct Stream end +""" + Stream(filename, "w", dtempl) + +Opens a CrystFEL stream for writing. Note that you must provide a `DataTemplate`, +which is needed to translate "panel coordinates" to "file coordinates". + +Corresponds to CrystFEL C API routine `stream_open_for_write`. +""" function Stream(filename, mode::AbstractString, dtempl::DataTemplate) + if mode == "w" out = @ccall libcrystfel.stream_open_for_write(filename::Cstring, - dtempl.internalptr::Ptr{InternalDataTemplate})::Ptr{InternalStream} + dtempl.internalptr::Ptr{InternalDataTemplate})::Ptr{InternalStream} if out == C_NULL throw(ErrorException("Failed to open stream for reading")) end - return Stream(out) + finalizer(close, Stream(out)) + elseif mode =="r" throw(ArgumentError("To open a stream for reading, don't provide the DataTemplate")) + else throw(ArgumentError("Unrecognised CrystFEL stream mode"*mode)) end end +""" + Stream(filename, "r") + +Opens a CrystFEL stream for reading. + +Close the stream with `close` when you've finished (this will happen +automatically when the `Stream` object is finalized). + +Corresponds to CrystFEL C API routine `stream_open_for_read`. +""" function Stream(filename, mode::AbstractString) + if mode == "r" out = @ccall libcrystfel.stream_open_for_read(filename::Cstring)::Ptr{InternalStream} if out == C_NULL throw(ErrorException("Failed to open stream for reading")) end - return Stream(out) + finalizer(close, Stream(out)) + elseif mode == "w" throw(ArgumentError("To open a stream for writing, you must provide " *"a DataTemplate: use Stream(filename, \"w\", dtempl)")) + else throw(ArgumentError("Unrecognised CrystFEL stream mode"*mode)) end end +function Base.close(st::Stream) + if st.internalptr != C_NULL + @ccall libcrystfel.stream_close(st.internalptr::Ptr{InternalStream})::Cvoid + st.internalptr = C_NULL + end +end + + end # of module -- cgit v1.2.3 From cbaf344d7716efb89e0edb6fbfedddf62d1fff65 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 20 Dec 2023 13:28:53 +0100 Subject: Julia: Add some docstrings --- julia/CrystFEL/src/indexing.jl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/julia/CrystFEL/src/indexing.jl b/julia/CrystFEL/src/indexing.jl index 7dabd15c..543246ec 100644 --- a/julia/CrystFEL/src/indexing.jl +++ b/julia/CrystFEL/src/indexing.jl @@ -34,6 +34,17 @@ function indexflags(retry, multilattice, refine, peakcheck, cellcheck) end +""" + Indexer(methods, dtempl, cell; + tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), + retry=true, multilattice=false, refine=true, + peakcheck=true, cellcheck=true, + wavelength_estimate=nothing, clen_estimate=missing, + n_threads=1) + +Creates a new CrystFEL indexing engine, which you can later apply to CrystFEL +`Image` structures using `index()`. +""" function Indexer(methods, dtempl, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), retry=true, multilattice=false, refine=true, peakcheck=true, cellcheck=true, wavelength_estimate=nothing, clen_estimate=missing, n_threads=1) @@ -113,6 +124,14 @@ function Indexer(methods, dtempl, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), end +""" + index(image::Image, indexer::Indexer; mille=nothing) + +Index `image` using `indexer`. + +If `mille` is a valid `Mille` object, detector geometry alignment data will +be written. +""" function index(image::Image, idxr::Indexer; mille=nothing) if mille === nothing -- cgit v1.2.3 From 6f801ee7d0823ad952ce2478a026a5059f13b380 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 20 Dec 2023 13:52:51 +0100 Subject: Julia: Add chunkwrite() --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/streams.jl | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 017bd530..7db1ba19 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -62,7 +62,7 @@ export Indexer, index include("streams.jl") using .Streams -export Stream +export Stream, chunkwrite include("millepede.jl") using .Millepede diff --git a/julia/CrystFEL/src/streams.jl b/julia/CrystFEL/src/streams.jl index 94a1de17..d0b98f5f 100644 --- a/julia/CrystFEL/src/streams.jl +++ b/julia/CrystFEL/src/streams.jl @@ -2,7 +2,8 @@ module Streams import ..CrystFEL: libcrystfel import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate -export Stream +import ..CrystFEL.Images: Image, InternalImage +export Stream, chunkwrite # Represents the real C-side (opaque) structure. mutable struct InternalStream end @@ -77,4 +78,27 @@ function Base.close(st::Stream) end +function streamflags(peaks, reflections, imagedata) + flags = 0 + if reflections + flags |= 2 + end + if peaks + flags |= 4 + end + if imagedata + flags |= 8 + end + return flags +end + + +function chunkwrite(st::Stream, image::Image; peaks=true, reflections=true) + flags = streamflags(peaks, reflections, false) + @ccall libcrystfel.stream_write_chunk(st.internalptr::Ptr{InternalStream}, + image.internalptr::Ptr{InternalImage}, + flags::Cint)::Cvoid +end + + end # of module -- cgit v1.2.3 From 713a1f382153cefe089c6eba0d7d8ec316055706 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 20 Dec 2023 13:53:06 +0100 Subject: Julia: Add example (partial_sim in Julia) --- julia/partial_sim.jl | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 julia/partial_sim.jl diff --git a/julia/partial_sim.jl b/julia/partial_sim.jl new file mode 100644 index 00000000..73fba066 --- /dev/null +++ b/julia/partial_sim.jl @@ -0,0 +1,13 @@ +using CrystFEL + +dtempl = loaddatatemplate("julia/alignment-test.geom") +cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) +let st = Stream("partials.stream", "w", dtempl) + for i in 1:10 + println("Writing image ", i) + image = Image(dtempl) + cr = Crystal(rotatecell(cell)) + reflist = predictreflections(cr, image) + chunkwrite(st, image) + end +end -- cgit v1.2.3 From 02b34871911a1b6c508e160a3ec5f0a1d602f8c9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 22 Dec 2023 14:04:27 +0100 Subject: Formatting --- julia/CrystFEL/src/image.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 4f126c28..22c18aa1 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -137,8 +137,8 @@ function Image(dtempl::DataTemplate, out = @ccall libcrystfel.image_read(dtempl.internalptr::Ptr{InternalDataTemplate}, filename::Cstring, event::Cstring, - no_image_data::Cint, no_mask_data::Cint, - C_NULL::Ptr{Cvoid})::Ptr{Image} + no_image_data::Cint, no_mask_data::Cint, + C_NULL::Ptr{Cvoid})::Ptr{Image} if out == C_NULL throw(ArgumentError("Failed to load image")) end -- cgit v1.2.3 From 5d23e6a5204dbef1260f744d6d42efbd1fcd1538 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 22 Dec 2023 11:47:44 +0100 Subject: Julia: Allow access to image.crystals image.crystals returns a vector of Crystal objects, while push!(image,crystal) can be used to add a new crystal. --- julia/CrystFEL/src/CrystFEL.jl | 8 ++++---- julia/CrystFEL/src/crystal.jl | 9 ++++++--- julia/CrystFEL/src/image.jl | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 7db1ba19..dbe31eae 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -39,10 +39,6 @@ include("peaklist.jl") using .PeakLists export PeakList -include("image.jl") -using .Images -export Image - include("reflists.jl") using .RefLists export RefList, loadreflist @@ -52,6 +48,10 @@ include("crystal.jl") using .Crystals export Crystal, InternalCrystal +include("image.jl") +using .Images +export Image + include("diffcalc.jl") using .DiffractionCalculations export predictreflections diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index 1c0143e2..97de0e78 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -10,6 +10,7 @@ mutable struct InternalCrystal end mutable struct Crystal internalptr::Ptr{InternalCrystal} + in_image # if true, this PeakList belongs to an Image struct end @@ -34,11 +35,13 @@ function Crystal(cell::UnitCell; profileradius=2e6, mosaicity=0) Cvoid, (Ptr{InternalCrystal},Cdouble), out, mosaicity) - cr = Crystal(out) + cr = Crystal(out, false) finalizer(cr) do x - ccall((:crystal_free, libcrystfel), Cvoid, (Ptr{InternalCrystal},), - x.internalptr) + if !x.in_image + ccall((:crystal_free, libcrystfel), Cvoid, (Ptr{InternalCrystal},), + x.internalptr) + end end return cr diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 22c18aa1..b5f4f8d8 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -4,6 +4,7 @@ import ..CrystFEL: libcrystfel import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate import ..CrystFEL.DetGeoms: DetGeom import ..CrystFEL.PeakLists: PeakList, InternalPeakList +import ..CrystFEL.Crystals: Crystal, InternalCrystal export Image const HEADER_CACHE_SIZE = 128 @@ -43,11 +44,30 @@ mutable struct Image end +function makecrystallist(listptr, n) + + crystals = Crystal[] + + if listptr == C_NULL + return crystals + end + + for i in 1:n + crystalptr = unsafe_load(listptr, i) + push!(crystals, Crystal(crystalptr, true)) + end + + crystals + +end + + function Base.getproperty(image::Image, name::Symbol) if name === :internalptr getfield(image, :internalptr) else idata = unsafe_load(image.internalptr) + if name === :peaklist let pl = getproperty(idata, :peaklist) if pl == C_NULL @@ -56,6 +76,11 @@ function Base.getproperty(image::Image, name::Symbol) PeakList(pl, true) end end + + elseif name === :crystals + return makecrystallist(getproperty(idata, :crystals), + getproperty(idata, :n_crystals)) + else getproperty(idata, name) end @@ -94,6 +119,17 @@ function Base.propertynames(image::Image; private=false) end +function Base.push!(image::Image, cr::Crystal) + if cr.in_image + throw(ErrorException("Crystal is already in an image")) + end + ccall((:image_add_crystal, libcrystfel), + Cvoid, (Ptr{InternalImage},Ptr{InternalCrystal}), + image.internalptr, cr.internalptr) + cr.in_image = true +end + + """ Image(dtempl::DataTemplate) -- cgit v1.2.3 From a08265b47bb25f8ac730641cf44659de660e814a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 22 Dec 2023 11:48:33 +0100 Subject: Julia: Implement setting of cr.reflections --- julia/CrystFEL/src/crystal.jl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index 97de0e78..1ab2a068 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -1,7 +1,7 @@ module Crystals import ..CrystFEL: libcrystfel -import ..CrystFEL.RefLists: RefList, UnmergedReflection +import ..CrystFEL.RefLists: RefList, InternalRefList, UnmergedReflection import ..CrystFEL.UnitCells: UnitCell, InternalUnitCell export Crystal, InternalCrystal @@ -48,4 +48,21 @@ function Crystal(cell::UnitCell; profileradius=2e6, mosaicity=0) end +function Base.setproperty!(cr::Crystal, name::Symbol, val) + if name === :internalptr + setfield!(cr, :internalptr, val) + else + if name === :reflections + if val isa RefList{UnmergedReflection} + ccall((:crystal_set_reflections, libcrystfel), + Cvoid, (Ptr{InternalCrystal},Ptr{InternalRefList}), + cr.internalptr, val.internalptr) + else + throw(ArgumentError("Must be a RefList{UnmergedReflection}")) + end + end + end +end + + end # of module -- cgit v1.2.3 From a3327d917c411a2b6f59475fb0c9b2b36589f1ae Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 22 Dec 2023 11:48:51 +0100 Subject: Julia: Add catch-all setproperty for image This allows e.g. image.serial to be set. --- julia/CrystFEL/src/image.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index b5f4f8d8..7a7ce76e 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -105,6 +105,9 @@ function Base.setproperty!(image::Image, name::Symbol, val) else throw(ArgumentError("Must be a PeakList")) end + else + setproperty!(idata, name, val) + unsafe_store!(image.internalptr, idata) end end end -- cgit v1.2.3 From f556b969f2c7147894a7a35a68440d522bfcd7c6 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 22 Dec 2023 11:49:12 +0100 Subject: Julia: Write the DataTemplate to the stream --- julia/CrystFEL/src/streams.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/julia/CrystFEL/src/streams.jl b/julia/CrystFEL/src/streams.jl index d0b98f5f..29f0de5d 100644 --- a/julia/CrystFEL/src/streams.jl +++ b/julia/CrystFEL/src/streams.jl @@ -30,6 +30,10 @@ function Stream(filename, mode::AbstractString, dtempl::DataTemplate) if out == C_NULL throw(ErrorException("Failed to open stream for reading")) end + + @ccall libcrystfel.stream_write_data_template(out::Ptr{InternalStream}, + dtempl.internalptr::Ptr{InternalDataTemplate})::Cvoid + finalizer(close, Stream(out)) elseif mode =="r" -- cgit v1.2.3 From adad37bb1f15aef265b6e9ac17fbc263e055311e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 22 Dec 2023 11:49:29 +0100 Subject: Update julia/partial_sim.jl --- julia/partial_sim.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/julia/partial_sim.jl b/julia/partial_sim.jl index 73fba066..4ddec347 100644 --- a/julia/partial_sim.jl +++ b/julia/partial_sim.jl @@ -6,8 +6,12 @@ let st = Stream("partials.stream", "w", dtempl) for i in 1:10 println("Writing image ", i) image = Image(dtempl) + image.serial = i + image.filename = "simulation_" * string(i) + image.ev = "//" cr = Crystal(rotatecell(cell)) - reflist = predictreflections(cr, image) + cr.reflections = predictreflections(cr, image) + push!(image, cr) chunkwrite(st, image) end end -- cgit v1.2.3 From 4799a7012e2d7bc482af4c4aafc0bb6927722eeb Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 22 Dec 2023 14:04:13 +0100 Subject: Julia: set filename and event ID for image --- julia/CrystFEL/src/image.jl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 7a7ce76e..3f74d8cd 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -88,6 +88,9 @@ function Base.getproperty(image::Image, name::Symbol) end +strdup(str) = @ccall strdup(str::Cstring)::Cstring + + function Base.setproperty!(image::Image, name::Symbol, val) if name === :internalptr setfield!(image, :internalptr, val) @@ -105,6 +108,23 @@ function Base.setproperty!(image::Image, name::Symbol, val) else throw(ArgumentError("Must be a PeakList")) end + + elseif name === :filename + if val isa AbstractString + setproperty!(idata, :filename, strdup(val)) + unsafe_store!(image.internalptr, idata) + else + throw(ArgumentError("Must be a string")) + end + + elseif name === :ev + if val isa AbstractString + setproperty!(idata, :ev, strdup(val)) + unsafe_store!(image.internalptr, idata) + else + throw(ArgumentError("Must be a string")) + end + else setproperty!(idata, name, val) unsafe_store!(image.internalptr, idata) -- cgit v1.2.3 From d34d4c16a1972cf7cd2be5b41d8f87d7ad22fb9f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 22 Dec 2023 17:03:43 +0100 Subject: Update docs --- doc/articles/julia.rst | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/doc/articles/julia.rst b/doc/articles/julia.rst index ac27873c..cbd22033 100644 --- a/doc/articles/julia.rst +++ b/doc/articles/julia.rst @@ -161,14 +161,59 @@ Note that not all ``SymOpList`` objects represent a point group. One counterexample is lists of indexing ambiguity operations. +Images and DataTemplates +======================== + +A ``DataTemplate`` represents the contents of a CrystFEL geometry file, which +describes the layout of information in the data, the physical positions of +parts of the detector, and the values of various items of metadata (or +information about where to get those values). Create a ``DataTemplate`` by +loading a geometry file:: + + dtempl = loaddatatemplate("/path/to/my.geom") + +An ``Image`` is an overall container structure representing one frame of a +serial crystallography dataset. Create one by loading an image from file:: + + image = Image(dtempl, "/path/to/mydata.cxi", "//32") + +You can use any kind of file supported by CrystFEL here. In the example, +``//32`` is the frame ID - leave it out if there is only one frame per file. + +If you're simulating data, you can create an empty image like this: + + image = Image(dtempl) + +However, several caveats apply to doing this. The ``DataTemplate`` must not +say that any metadata values (e.g. the wavelength) should be taken from file +headers, because there is no file in this case. An error will be thrown if +there is any problem. + + Peak lists ========== +A ``PeakList`` represents a list of positions on the detector surface. Create +it and add peaks like this:: + + peaklist = PeakList() + push!(peaklist, 10.0, 20.0, 1, 2000.0) + +The arguments to ``push!(::PeakList, ...)`` are, in order, the fast scan +coordinate, slow scan coordinate (both relative to the panel corner), panel +number (indexed from zero) and the spot intensity in detector units. + +You can assign your peaklist to an ``Image`` by setting ``image.peaklist``. +Note that any ``PeakList`` can only be assigned to a single ``Image``. An +error will be thrown if you try to add the same ``PeakList`` again (even to the +same ``Image``). If necessary, you can make a copy using ``deepcopy``. + Crystals ======== + Indexing ======== -- cgit v1.2.3 From e018c10216d79637f0bcb2915a00e9a744c58085 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 2 Jan 2024 10:49:33 +0100 Subject: Update docs --- doc/articles/julia.rst | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/articles/julia.rst b/doc/articles/julia.rst index cbd22033..0b6cabeb 100644 --- a/doc/articles/julia.rst +++ b/doc/articles/julia.rst @@ -75,17 +75,18 @@ or:: Reflection lists ================ -In Julia, a distinction is made between merged and unmerged reflections. No -such distinction exists in CrystFEL's C API. Merged reflections have +A ``RefList`` is a container for reflection data. In Julia, a distinction is +made between merged and unmerged reflections. Merged reflections have multiplicities (number of contributing measurements), whereas unmerged reflections have detector locations, background levels and parameters related -to diffraction geometry such as excitation errors and Lorentz factors. In -reality, both types of reflection have all fields, just as for the C API. The -distinction controls how the objects are printed, and may help in writing -clearer programs. +to diffraction geometry such as excitation errors and +Lorentz factors. -Load a reflection list from a data file (".hkl file") using -``loadreflist``:: +No such distinction exists in CrystFEL's C API, and in "reality", both types of +reflection have all fields. The distinction controls how the objects are +printed, and may help in writing clearer programs. + +Load a reflection list from a data file (".hkl file") using ``loadreflist``:: julia> q = loadreflist("example.hkl") Merged reflection list in point group mmm @@ -141,7 +142,9 @@ Symmetry Symmetry operations are represented by ``SymOp`` objects, which are contained within ``SymOpList`` objects. A point group is therefore represented by a -``SymOpList``. +``SymOpList``, but note that not all ``SymOpList`` objects represent a symmetry +group (in the sense of group theory). One counterexample is lists of indexing +ambiguity operations. Create a point group from the Herman-Mauguin symbol as follows:: @@ -157,9 +160,6 @@ The list can be subscripted linearly:: julia> s[1] SymOp("-h,-k,l") -Note that not all ``SymOpList`` objects represent a point group. One -counterexample is lists of indexing ambiguity operations. - Images and DataTemplates ======================== @@ -180,7 +180,7 @@ serial crystallography dataset. Create one by loading an image from file:: You can use any kind of file supported by CrystFEL here. In the example, ``//32`` is the frame ID - leave it out if there is only one frame per file. -If you're simulating data, you can create an empty image like this: +If you're simulating data, you can create an empty image like this:: image = Image(dtempl) -- cgit v1.2.3 From 8b67ec27c563d35fa8c5604b3475ff7b017abcb2 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 2 Jan 2024 10:49:43 +0100 Subject: Julia: Free old peak list on re-assignment --- julia/CrystFEL/src/image.jl | 64 ++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 3f74d8cd..de46af4b 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -91,44 +91,54 @@ end strdup(str) = @ccall strdup(str::Cstring)::Cstring +function assert_type(val, type) + if !(val isa type) + throw(ArgumentError("Must be a "*string(type)*" (have "*string(typeof(val))*" instead)")) + end +end + + +function set_peaklist(image, val) + assert_type(val, PeakList) + if val.in_image + throw(ArgumentError("PeakList is already in an image. "* + "Add a copy (use `deepcopy`) instead.")) + end + val.in_image = true + val = val.internalptr + idata = unsafe_load(image.internalptr) + old = swapproperty!(idata, :peaklist, val) + unsafe_store!(image.internalptr, idata) + + if old != C_NULL + @ccall libcrystfel.image_feature_list_free(old::Ptr{InternalPeakList})::Cvoid + end + +end + + function Base.setproperty!(image::Image, name::Symbol, val) if name === :internalptr setfield!(image, :internalptr, val) else - idata = unsafe_load(image.internalptr) + if name === :peaklist - if val isa PeakList - if val.in_image - throw(ArgumentError("PeakList is already in an image. "* - "Add a copy (use `deepcopy`) instead.")) - end - setproperty!(idata, name, val.internalptr) - val.in_image = true - unsafe_store!(image.internalptr, idata) - else - throw(ArgumentError("Must be a PeakList")) - end + return set_peaklist(image, val) elseif name === :filename - if val isa AbstractString - setproperty!(idata, :filename, strdup(val)) - unsafe_store!(image.internalptr, idata) - else - throw(ArgumentError("Must be a string")) - end + assert_type(val, AbstractString) + val = strdup(val) elseif name === :ev - if val isa AbstractString - setproperty!(idata, :ev, strdup(val)) - unsafe_store!(image.internalptr, idata) - else - throw(ArgumentError("Must be a string")) - end + assert_type(val, AbstractString) + val = strdup(val) - else - setproperty!(idata, name, val) - unsafe_store!(image.internalptr, idata) end + + idata = unsafe_load(image.internalptr) + setproperty!(idata, name, val) + unsafe_store!(image.internalptr, idata) + end end -- cgit v1.2.3 From 1f2185b46932d2a3c107a3f823b90a46a84ce202 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 3 Jan 2024 16:46:10 +0100 Subject: Julia: fix Image/PeakList memory semantics The previous commit 3bb46f49 was a mistake. We can't just free the old peak list, because there might still be a PeakList object around that refers to it. This new version keeps a record of the PeakList object itself, setting in_image=false if a new list is added, so that it can be freed by the GC. I made an attempt at making this thread-safe, but I think it's impossible to get it completely correct. One should simply avoid setting any Image fields in the same structure from different threads. --- julia/CrystFEL/src/image.jl | 44 +++++++++++++++++++++--------------------- julia/CrystFEL/src/peaklist.jl | 7 ++++++- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index de46af4b..24c1c923 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -41,6 +41,7 @@ end mutable struct Image internalptr::Ptr{InternalImage} + peaklist::Union{Nothing,PeakList} end @@ -65,19 +66,12 @@ end function Base.getproperty(image::Image, name::Symbol) if name === :internalptr getfield(image, :internalptr) + elseif name === :peaklist + getfield(image, :peaklist) else idata = unsafe_load(image.internalptr) - if name === :peaklist - let pl = getproperty(idata, :peaklist) - if pl == C_NULL - throw(ErrorException("Image doesn't have a peak list")) - else - PeakList(pl, true) - end - end - - elseif name === :crystals + if name === :crystals return makecrystallist(getproperty(idata, :crystals), getproperty(idata, :n_crystals)) @@ -98,20 +92,26 @@ function assert_type(val, type) end -function set_peaklist(image, val) - assert_type(val, PeakList) - if val.in_image +function set_peaklist(image, new_pl) + + assert_type(new_pl, PeakList) + + if new_pl.in_image throw(ArgumentError("PeakList is already in an image. "* "Add a copy (use `deepcopy`) instead.")) end - val.in_image = true - val = val.internalptr - idata = unsafe_load(image.internalptr) - old = swapproperty!(idata, :peaklist, val) - unsafe_store!(image.internalptr, idata) + new_pl.in_image = true + old_pl = swapfield!(image, :peaklist, new_pl) + if old_pl !== nothing + old_pl.in_image = false + # The old PeakList will now get GCed + end - if old != C_NULL - @ccall libcrystfel.image_feature_list_free(old::Ptr{InternalPeakList})::Cvoid + idata = unsafe_load(image.internalptr) + old_i = swapfield!(idata, :peaklist, new_pl.internalptr) + if old_pl === nothing || old_i == old_pl.internalptr + unsafe_store!(image.internalptr, idata) + # else someone else already set a new peaklist end end @@ -180,7 +180,7 @@ function Image(dtempl::DataTemplate) throw(ArgumentError("Failed to create image")) end - image = Image(out) + image = Image(out, nothing) finalizer(image) do x ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) @@ -212,7 +212,7 @@ function Image(dtempl::DataTemplate, throw(ArgumentError("Failed to load image")) end - image = Image(out) + image = Image(out, nothing) finalizer(image) do x ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl index 1735de5e..a676a7bf 100644 --- a/julia/CrystFEL/src/peaklist.jl +++ b/julia/CrystFEL/src/peaklist.jl @@ -25,7 +25,12 @@ function PeakList() if out == C_NULL throw(ArgumentError("Failed to create peak list")) end - PeakList(out, false) + finalizer(PeakList(out, false)) do pl + if !pl.in_image + @ccall libcrystfel.image_feature_list_free(pl.internalptr::Ptr{InternalPeakList})::Cvoid + # else it belongs to the image structure + end + end end -- cgit v1.2.3 From 0273eb0b50ff17feb12a0a1e0ac7ee5dc1233622 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 4 Jan 2024 10:50:40 +0100 Subject: Julia: Make a copy of the cell when creating a Crystal We could do some more reference tracking stuff here, but it seems a little excessive. --- julia/CrystFEL/src/crystal.jl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index 1ab2a068..129c028c 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -23,9 +23,14 @@ function Crystal(cell::UnitCell; profileradius=2e6, mosaicity=0) throw(ArgumentError("Failed to create crystal")) end + # We make a copy of the cell, to avoid memory model shenanigans + uccopy = ccall((:cell_new_from_cell, libcrystfel), + Ptr{InternalUnitCell}, (Ptr{InternalUnitCell},), + cell.internalptr) + ccall((:crystal_set_cell, libcrystfel), Cvoid, (Ptr{InternalCrystal},Ptr{InternalUnitCell}), - out, cell.internalptr) + out, uccopy) ccall((:crystal_set_profile_radius, libcrystfel), Cvoid, (Ptr{InternalCrystal},Cdouble), -- cgit v1.2.3 From d0787517583955eb0d9391b1bd14764198e83903 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 14 Jan 2024 10:37:10 +0100 Subject: Julia: Image/PeakList memory semantics (again) Previous commit a6462e1f0 was still not right. If the image gets freed, the PeakList can be left with a dangling reference. If the peak list gets replaced at the C level (e.g. by running a new peak search), Julia will have no way of knowing about it. Instead of having the PeakList know if it's associated with an image, it's better to have the Image know (at the C level) if it's responsible for freeing the ImageFeatureList. As soon as the ImageFeatureList is exposed to the Julia GC via a PeakList object, it becomes Julia's responsibility to free it. The Julia Image structure contains a reference to the Julia PeakList, to prevent this from happening until either the image is freed or a new PeakList is substituted. The two references (Julia image.peaklist and C image->features) have to be kept in sync, and we check image->features every time the peaklist is requested. --- julia/CrystFEL/src/image.jl | 39 +++++++++++++++++++++++---------------- julia/CrystFEL/src/peaklist.jl | 10 +++------- libcrystfel/src/image.c | 3 ++- libcrystfel/src/image.h | 4 ++++ 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 24c1c923..de79a556 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -36,6 +36,7 @@ mutable struct InternalImage peak_resolution::Cdouble peaklist::Ptr{InternalPeakList} ida::Ptr{Cvoid} + owns_peaklist::Cint end @@ -63,11 +64,27 @@ function makecrystallist(listptr, n) end +function getpeaklist(image) + idata = unsafe_load(image.internalptr) + if (image.peaklist === nothing) || (idata.peaklist != image.peaklist.internalptr) + if idata.peaklist != C_NULL + image.peaklist = PeakList(idata.peaklist) + # From now on, Julia is completely responsible for freeing the peaklist + idata.owns_peaklist = 0 + unsafe_store!(image.internalptr, idata) + else + image.peaklist = nothing + end + end + return image.peaklist +end + + function Base.getproperty(image::Image, name::Symbol) if name === :internalptr getfield(image, :internalptr) elseif name === :peaklist - getfield(image, :peaklist) + getpeaklist(image) else idata = unsafe_load(image.internalptr) @@ -96,23 +113,13 @@ function set_peaklist(image, new_pl) assert_type(new_pl, PeakList) - if new_pl.in_image - throw(ArgumentError("PeakList is already in an image. "* - "Add a copy (use `deepcopy`) instead.")) - end - new_pl.in_image = true - old_pl = swapfield!(image, :peaklist, new_pl) - if old_pl !== nothing - old_pl.in_image = false - # The old PeakList will now get GCed - end - idata = unsafe_load(image.internalptr) - old_i = swapfield!(idata, :peaklist, new_pl.internalptr) - if old_pl === nothing || old_i == old_pl.internalptr - unsafe_store!(image.internalptr, idata) - # else someone else already set a new peaklist + if (idata.owns_peaklist == 0) && (idata.peaklist != C_NULL) + @ccall libcrystfel.image_feature_list_free(idata.peaklist::Ptr{InternalPeakList})::Cvoid end + idata.peaklist = new_pl.internalptr + idata.owns_peaklist = 0 + unsafe_store!(image.internalptr, idata) end diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl index a676a7bf..d4354977 100644 --- a/julia/CrystFEL/src/peaklist.jl +++ b/julia/CrystFEL/src/peaklist.jl @@ -16,7 +16,6 @@ mutable struct InternalPeakList end mutable struct PeakList internalptr::Ptr{InternalPeakList} - in_image # if true, this PeakList belongs to an Image struct end @@ -25,11 +24,8 @@ function PeakList() if out == C_NULL throw(ArgumentError("Failed to create peak list")) end - finalizer(PeakList(out, false)) do pl - if !pl.in_image - @ccall libcrystfel.image_feature_list_free(pl.internalptr::Ptr{InternalPeakList})::Cvoid - # else it belongs to the image structure - end + finalizer(PeakList(out)) do pl + @ccall libcrystfel.image_feature_list_free(pl.internalptr::Ptr{InternalPeakList})::Cvoid end end @@ -39,7 +35,7 @@ function Base.deepcopy(peaklist::PeakList) if out == C_NULL throw(ErrorException("Failed to copy peak list")) end - PeakList(out, false) + PeakList(out) end function Base.length(peaklist::PeakList) diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 3b4e04df..ab4518a9 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -1394,7 +1394,7 @@ void image_free(struct image *image) int i, np; if ( image == NULL ) return; - image_feature_list_free(image->features); + if ( image->owns_peaklist ) image_feature_list_free(image->features); free_all_crystals(image); spectrum_free(image->spectrum); cffree(image->filename); @@ -1464,6 +1464,7 @@ struct image *image_new() image->bw = -1.0; image->peak_resolution = -1.0; image->features = NULL; + image->owns_peaklist = 1; return image; } diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h index beb66810..74ff6eee 100644 --- a/libcrystfel/src/image.h +++ b/libcrystfel/src/image.h @@ -190,6 +190,10 @@ struct image /** Re-usable data array structure, or NULL if not used */ ImageDataArrays *ida; + /** If set, then 'features' should be freed with the image. + * Otherwise, it is managed externally (e.g. by Julia) */ + int owns_peaklist; + }; #ifdef __cplusplus -- cgit v1.2.3 From 57ed401c57e8a7548cb21d16495495446e070e13 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 16 Jan 2024 10:33:06 +0100 Subject: Julia: Forbid non-deep copying of a PeakList We cannot have two PeakList objects pointing at the same underlying ImageFeatureList. --- julia/CrystFEL/src/peaklist.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl index d4354977..9eedad27 100644 --- a/julia/CrystFEL/src/peaklist.jl +++ b/julia/CrystFEL/src/peaklist.jl @@ -30,6 +30,8 @@ function PeakList() end +Base.copy(::PeakList) = throw(ErrorException("Cannot copy(::PeakList), must deepcopy")) + function Base.deepcopy(peaklist::PeakList) out = @ccall libcrystfel.image_feature_list_copy(peaklist.internalptr::Ptr{InternalPeakList})::Ptr{InternalPeakList} if out == C_NULL -- cgit v1.2.3 From e92d7d9a24f96549f5fb832efcb9e0f832d28beb Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 16 Jan 2024 12:11:09 +0100 Subject: Julia: Use jl_malloc etc for memory management --- julia/CrystFEL/src/CrystFEL.jl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index dbe31eae..27ee8b0b 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -13,6 +13,19 @@ module CrystFEL libcrystfel = "libcrystfel.so" +# Configure libcrystfel to use Julia's memory management. This is needed so +# that the Julia GC knows about the memory we allocate via libcrystfel +# routines. Otherwise, potentially very large objects will be kept hanging +# around in memory because Julia thinks it's using a very small amount of +# memory, and rarely runs the GC. In the case of image structures, the +# difference between apparent and true memory use can be a factor of a million! +function __init__() + @ccall libcrystfel.set_mm_funcs(cglobal(:jl_malloc)::Ptr{Cvoid}, + cglobal(:jl_free)::Ptr{Cvoid}, + cglobal(:jl_calloc)::Ptr{Cvoid}, + cglobal(:jl_realloc)::Ptr{Cvoid})::Cint +end + include("cell.jl") using .UnitCells export UnitCell, LatticeType, CenteringType, UniqueAxis -- cgit v1.2.3 From dd6aed228f47eb6bfc713b20e635e2bacfe1a6f9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 16 Jan 2024 16:48:12 +0100 Subject: Update alignment-test.jl --- julia/alignment-test.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 9a7a7202..ead812c3 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -1,6 +1,7 @@ using CrystFEL using Random using Plots +using MillepedeII # "Simulate" a diffraction pattern from the reflections function sketch_pattern(image, cr) @@ -54,6 +55,7 @@ end function plotresiduals(filename) + t = loadmille(filename) l = @layout([q0 q1; q2 q3]) a = collect(Iterators.flatten(t)) -- cgit v1.2.3 From ff89f33377133352838f27057525701e71c9df7c Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Jan 2024 17:25:20 +0100 Subject: Julia: Expose crystals and reflection lists from image The memory management isn't quite right here yet. --- julia/CrystFEL/src/crystal.jl | 9 +++------ julia/CrystFEL/src/image.jl | 23 +++++++++++++++++++---- julia/CrystFEL/src/reflists.jl | 1 + 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index 129c028c..eba7a615 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -10,7 +10,6 @@ mutable struct InternalCrystal end mutable struct Crystal internalptr::Ptr{InternalCrystal} - in_image # if true, this PeakList belongs to an Image struct end @@ -40,13 +39,11 @@ function Crystal(cell::UnitCell; profileradius=2e6, mosaicity=0) Cvoid, (Ptr{InternalCrystal},Cdouble), out, mosaicity) - cr = Crystal(out, false) + cr = Crystal(out) finalizer(cr) do x - if !x.in_image - ccall((:crystal_free, libcrystfel), Cvoid, (Ptr{InternalCrystal},), - x.internalptr) - end + ccall((:crystal_free, libcrystfel), Cvoid, (Ptr{InternalCrystal},), + x.internalptr) end return cr diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index de79a556..a9d9c28f 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -5,16 +5,23 @@ import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate import ..CrystFEL.DetGeoms: DetGeom import ..CrystFEL.PeakLists: PeakList, InternalPeakList import ..CrystFEL.Crystals: Crystal, InternalCrystal +import ..CrystFEL.RefLists: RefList, InternalRefList, UnmergedReflection +import ..CrystFEL.Symmetry: SymOpList export Image const HEADER_CACHE_SIZE = 128 +mutable struct CrystalRefListPair + crystal::Ptr{InternalCrystal} + reflist::Ptr{InternalRefList} +end + mutable struct InternalImage dp::Ptr{Ptr{Cfloat}} bad::Ptr{Ptr{Cint}} sat::Ptr{Ptr{Cfloat}} hit::Cint - crystals::Ptr{Ptr{Cvoid}} + crystals::Ptr{CrystalRefListPair} n_crystals::Cint indexed_by::Cint n_indexing_tries::Cint @@ -43,20 +50,28 @@ end mutable struct Image internalptr::Ptr{InternalImage} peaklist::Union{Nothing,PeakList} + crystals + reflists end function makecrystallist(listptr, n) - crystals = Crystal[] + crystals = [] if listptr == C_NULL return crystals end for i in 1:n - crystalptr = unsafe_load(listptr, i) - push!(crystals, Crystal(crystalptr, true)) + pairptr = unsafe_load(listptr, i) + cr = Crystal(pairptr.crystal) + if pairptr.reflist == C_NULL + reflist = nothing + else + reflist = RefList{UnmergedReflection}(pairptr.reflist, SymOpList("1")) + end + push!(crystals, (crystal=cr, reflections=reflist)) end crystals diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 007f0f07..d6b3a951 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -5,6 +5,7 @@ import ..CrystFEL: libcrystfel import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name export RefList, loadreflist export Reflection, UnmergedReflection, MergedReflection +export InternalRefList # The internal libcrystfel structures, not exposed directly -- cgit v1.2.3 From 1b4fdfa5cc1ab4fe9a1cdcbb0bf1602834eaec13 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Jan 2024 17:55:45 +0100 Subject: Julia: MM semantics for Image.crystals --- julia/CrystFEL/src/image.jl | 42 ++++++++++++++++++++++++++++++++++-------- julia/make-indexed.jl | 26 ++++++++++++++++++++++++++ libcrystfel/src/image.c | 10 ++++++++-- libcrystfel/src/image.h | 2 ++ 4 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 julia/make-indexed.jl diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index a9d9c28f..3384f0c9 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -14,6 +14,8 @@ const HEADER_CACHE_SIZE = 128 mutable struct CrystalRefListPair crystal::Ptr{InternalCrystal} reflist::Ptr{InternalRefList} + owns_crystal::Cint + owns_reflist::Cint end mutable struct InternalImage @@ -55,7 +57,7 @@ mutable struct Image end -function makecrystallist(listptr, n) +function makecrystallist(image, listptr, n) crystals = [] @@ -65,16 +67,33 @@ function makecrystallist(listptr, n) for i in 1:n pairptr = unsafe_load(listptr, i) - cr = Crystal(pairptr.crystal) + + # Re-use old Crystal if possible + n = findfirst(getfield(image, :crystals)) do x + x.internalptr == pairptr.crystal + end + + if n !== nothing + cr = getfield(image, :crystals)[n] + else + cr = Crystal(pairptr.crystal) + end + if pairptr.reflist == C_NULL reflist = nothing else reflist = RefList{UnmergedReflection}(pairptr.reflist, SymOpList("1")) + pairptr.owns_reflist = 0 end push!(crystals, (crystal=cr, reflections=reflist)) + pairptr.owns_crystal = 0 + unsafe_store!(listptr, pairptr, i) + # We are now responsible for freeing the Crystal and RefList end - crystals + image.crystals = map(x->x.crystal, crystals) + image.reflists = map(x->x.reflections, crystals) + return crystals end @@ -104,11 +123,12 @@ function Base.getproperty(image::Image, name::Symbol) idata = unsafe_load(image.internalptr) if name === :crystals - return makecrystallist(getproperty(idata, :crystals), - getproperty(idata, :n_crystals)) + return makecrystallist(image, + getfield(idata, :crystals), + getfield(idata, :n_crystals)) else - getproperty(idata, name) + getfield(idata, name) end end end @@ -155,6 +175,12 @@ function Base.setproperty!(image::Image, name::Symbol, val) assert_type(val, AbstractString) val = strdup(val) + elseif name === :crystals + return setfield!(image, :crystals, val) + + elseif name === :reflists + return setfield!(image, :reflists, val) + end idata = unsafe_load(image.internalptr) @@ -202,7 +228,7 @@ function Image(dtempl::DataTemplate) throw(ArgumentError("Failed to create image")) end - image = Image(out, nothing) + image = Image(out, nothing, [], []) finalizer(image) do x ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) @@ -234,7 +260,7 @@ function Image(dtempl::DataTemplate, throw(ArgumentError("Failed to load image")) end - image = Image(out, nothing) + image = Image(out, nothing, [], []) finalizer(image) do x ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) diff --git a/julia/make-indexed.jl b/julia/make-indexed.jl new file mode 100644 index 00000000..7a24f606 --- /dev/null +++ b/julia/make-indexed.jl @@ -0,0 +1,26 @@ +using CrystFEL +using Random + +# "Simulate" a diffraction pattern from the reflections +function sketch_pattern(image, cr) + reflist = predictreflections(cr, image) + peaklist = PeakList() + for refl in reflist + if randn() > 0 + let dpos = refl.detectorposition + push!(peaklist, dpos.fs, dpos.ss, dpos.panelnumber, 100.0) + end + end + end + return peaklist +end + + +dtempl = loaddatatemplate("julia/alignment-test.geom") +cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) +indexer = Indexer("asdf", dtempl, cell, retry=false, multilattice=false, refine=true) + +image = Image(dtempl) +cr = Crystal(rotatecell(cell)) +image.peaklist = sketch_pattern(image, cr) +index(image, indexer) diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index ab4518a9..e91c09d6 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -333,6 +333,8 @@ void image_add_crystal_refls(struct image *image, crs[n].cr = cryst; crs[n].refls = reflist; + crs[n].image_owns_crystal = 1; + crs[n].image_owns_refls = 1; image->crystals = crs; image->n_crystals = n+1; } @@ -373,8 +375,12 @@ void free_all_crystals(struct image *image) int i; if ( image->crystals == NULL ) return; for ( i=0; in_crystals; i++ ) { - crystal_free(image->crystals[i].cr); - reflist_free(image->crystals[i].refls); + if ( image->crystals[i].image_owns_crystal ) { + crystal_free(image->crystals[i].cr); + } + if ( image->crystals[i].image_owns_refls ) { + reflist_free(image->crystals[i].refls); + } } cffree(image->crystals); image->crystals = NULL; diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h index 74ff6eee..3db7de18 100644 --- a/libcrystfel/src/image.h +++ b/libcrystfel/src/image.h @@ -114,6 +114,8 @@ struct crystal_refls { Crystal *cr; RefList *refls; + int image_owns_crystal; + int image_owns_refls; }; struct image -- cgit v1.2.3 From 9a907d58a931472eb1178c42bfa1e7629e30ab00 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Jan 2024 09:52:01 +0100 Subject: Ownership for Crystal.Cell --- julia/CrystFEL/src/crystal.jl | 35 ++++++++++++++++++++++++++++++++++- julia/CrystFEL/src/image.jl | 2 +- libcrystfel/src/crystal.c | 11 +++++++++++ libcrystfel/src/crystal.h | 1 + 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index eba7a615..38204a62 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -10,6 +10,7 @@ mutable struct InternalCrystal end mutable struct Crystal internalptr::Ptr{InternalCrystal} + cell end @@ -39,7 +40,7 @@ function Crystal(cell::UnitCell; profileradius=2e6, mosaicity=0) Cvoid, (Ptr{InternalCrystal},Cdouble), out, mosaicity) - cr = Crystal(out) + cr = Crystal(out, nothing) finalizer(cr) do x ccall((:crystal_free, libcrystfel), Cvoid, (Ptr{InternalCrystal},), @@ -67,4 +68,36 @@ function Base.setproperty!(cr::Crystal, name::Symbol, val) end +function getcell(cr) + out = @ccall libcrystfel.crystal_relinquish_cell(cr.internalptr::Ptr{InternalCrystal})::Ptr{InternalUnitCell} + if getfield(cr, :cell) === nothing || getfield(cr, :cell).internalptr != out + if out != C_NULL + setfield!(cr, :cell, UnitCell(out)) + else + setfield!(cr, :cell, nothing) + end + end + return getfield(cr, :cell) +end + + +function Base.getproperty(cr::Crystal, name::Symbol) + if name === :internalptr + getfield(cr, :internalptr) + elseif name === :cell + return getcell(cr) + end +end + + +function Base.show(io::IO, cr::Crystal) + write(io, "Crystal(") + if cr.cell !== nothing + show(io, cr.cell) + else + write(io, "no cell") + end + write(io, ")") +end + end # of module diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 3384f0c9..5740dfaf 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -76,7 +76,7 @@ function makecrystallist(image, listptr, n) if n !== nothing cr = getfield(image, :crystals)[n] else - cr = Crystal(pairptr.crystal) + cr = Crystal(pairptr.crystal, nothing) end if pairptr.reflist == C_NULL diff --git a/libcrystfel/src/crystal.c b/libcrystfel/src/crystal.c index e6ae4b09..0cf246ae 100644 --- a/libcrystfel/src/crystal.c +++ b/libcrystfel/src/crystal.c @@ -41,6 +41,7 @@ struct _crystal { UnitCell *cell; + int owns_cell; double m; /* Mosaicity in radians */ double osf; double Bfac; @@ -72,6 +73,7 @@ Crystal *crystal_new() if ( cryst == NULL ) return NULL; cryst->cell = NULL; + cryst->owns_cell = 1; cryst->m = 0.0; cryst->osf = 1.0; cryst->Bfac = 0.0; @@ -128,6 +130,7 @@ Crystal *crystal_copy(const Crystal *cryst) void crystal_free(Crystal *cryst) { if ( cryst == NULL ) return; + if ( cryst->owns_cell ) cell_free(cryst->cell); cffree(cryst->notes); cffree(cryst); } @@ -142,6 +145,13 @@ UnitCell *crystal_get_cell(Crystal *cryst) } +UnitCell *crystal_relinquish_cell(Crystal *cryst) +{ + cryst->owns_cell = 0; + return cryst->cell; +} + + const UnitCell *crystal_get_cell_const(const Crystal *cryst) { return cryst->cell; @@ -217,6 +227,7 @@ void crystal_set_cell(Crystal *cryst, UnitCell *cell) { if ( cryst->owns_cell ) cell_free(cryst->cell); cryst->cell = cell; + cryst->owns_cell = 1; } diff --git a/libcrystfel/src/crystal.h b/libcrystfel/src/crystal.h index 7147111f..1804fa35 100644 --- a/libcrystfel/src/crystal.h +++ b/libcrystfel/src/crystal.h @@ -52,6 +52,7 @@ extern Crystal *crystal_copy(const Crystal *cryst); extern void crystal_free(Crystal *cryst); extern UnitCell *crystal_get_cell(Crystal *cryst); +extern UnitCell *crystal_relinquish_cell(Crystal *cryst); extern double crystal_get_profile_radius(const Crystal *cryst); extern double crystal_get_resolution_limit(Crystal *cryst); extern int crystal_get_user_flag(Crystal *cryst); -- cgit v1.2.3 From 93a6a827f115f27ed9e148aa635ec9400ffa700d Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Jan 2024 14:09:11 +0100 Subject: Julia: add translategroup() (and use it) --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/datatemplates.jl | 22 ++++++++++++++++ julia/alignment-test-moved.geom | 51 ------------------------------------- julia/alignment-test.jl | 5 ++-- 4 files changed, 26 insertions(+), 54 deletions(-) delete mode 100644 julia/alignment-test-moved.geom diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 27ee8b0b..63b636b1 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -46,7 +46,7 @@ export SymOpList include("datatemplates.jl") using .DataTemplates -export DataTemplate, loaddatatemplate, wavelength, cameralength +export DataTemplate, loaddatatemplate, wavelength, cameralength, translategroup include("peaklist.jl") using .PeakLists diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index 16433d9f..b76a272e 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -3,6 +3,7 @@ module DataTemplates import ..CrystFEL: libcrystfel export DataTemplate, InternalDataTemplate, loaddatatemplate export wavelength, cameralength +export translategroup # Represents the real C-side (opaque) structure. mutable struct InternalDataTemplate end @@ -83,4 +84,25 @@ function cameralength(dtempl::DataTemplate) end +""" + translategroup(datatemplate, groupname, xshift, yshift, zshift) + +Modifies `DataTemplate` by moving the specified panel group by the specified +amount (in metres). + +Corresponds to CrystFEL C API function `data_template_translate_group`. +""" +function translategroup(dtempl::DataTemplate, groupname, xshift, yshift, zshift) + r = @ccall libcrystfel.data_template_translate_group_m(dtempl.internalptr::Ptr{InternalDataTemplate}, + groupname::Cstring, + xshift::Cdouble, + yshift::Cdouble, + zshift::Cdouble)::Cint + if r != 0 + throw(ErrorException("Failed to shift DataTemplate")) + end + +end + + end # of module diff --git a/julia/alignment-test-moved.geom b/julia/alignment-test-moved.geom deleted file mode 100644 index c834973b..00000000 --- a/julia/alignment-test-moved.geom +++ /dev/null @@ -1,51 +0,0 @@ -adu_per_photon = 1 -res = 10000 -clen = 100.0 mm -photon_energy = 9000 eV - -dim0 = % -dim1 = ss -dim2 = fs -data = /data/data - -q0/dim0 = 0 -q0/min_fs = 0 -q0/min_ss = 0 -q0/max_fs = 1024 -q0/max_ss = 1024 -q0/fs = x -q0/ss = y -q0/corner_x = -1056 -q0/corner_y = 30 - -q1/dim0 = 1 -q1/min_fs = 0 -q1/min_ss = 0 -q1/max_fs = 1024 -q1/max_ss = 1024 -q1/fs = x -q1/ss = y -q1/corner_x = 30 -q1/corner_y = 30 - -q2/dim0 = 2 -q2/min_fs = 0 -q2/min_ss = 0 -q2/max_fs = 1024 -q2/max_ss = 1024 -q2/fs = x -q2/ss = y -q2/corner_x = 30 -q2/corner_y = -1054 - -q3/dim0 = 3 -q3/min_fs = 0 -q3/min_ss = 0 -q3/max_fs = 1024 -q3/max_ss = 1024 -q3/fs = x -q3/ss = y -q3/corner_x = -1054 -q3/corner_y = -1054 - -group_all = q0,q1,q2,q3 diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index ead812c3..4316755f 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -46,9 +46,10 @@ end dtempl_true = loaddatatemplate("julia/alignment-test.geom") image_true = Image(dtempl_true) cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) -dtempl_moved = loaddatatemplate("julia/alignment-test-moved.geom") +dtempl_moved = loaddatatemplate("julia/alignment-test.geom") +translategroup(dtempl_moved, "q0", 200e-6, 0, 0) let mille = Mille("mille.dat") - simulate_and_index(cell, image_true, dtempl_true, mille, 100) + simulate_and_index(cell, image_true, dtempl_moved, mille, 100) close(mille) end -- cgit v1.2.3 From 4e8625a7fd1a4a5b1c150cd388adae36757c1747 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Jan 2024 14:09:26 +0100 Subject: Julia: Fix stack overflow with image.peaklist --- julia/CrystFEL/src/image.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 5740dfaf..ce7b74d0 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -100,17 +100,18 @@ end function getpeaklist(image) idata = unsafe_load(image.internalptr) - if (image.peaklist === nothing) || (idata.peaklist != image.peaklist.internalptr) + if (getfield(image, :peaklist) === nothing) || + (idata.peaklist != getfield(image, :peaklist).internalptr) if idata.peaklist != C_NULL - image.peaklist = PeakList(idata.peaklist) + setfield!(image, :peaklist, PeakList(idata.peaklist)) # From now on, Julia is completely responsible for freeing the peaklist idata.owns_peaklist = 0 unsafe_store!(image.internalptr, idata) else - image.peaklist = nothing + setfield!(image, :peaklist, nothing) end end - return image.peaklist + return getfield(image, :peaklist) end -- cgit v1.2.3 From be377e728148605328d816516d0039b42efc214d Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Jan 2024 14:16:27 +0100 Subject: Julia: Crystal: Complain when requesting unrecognised field --- julia/CrystFEL/src/crystal.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index 38204a62..75124789 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -86,6 +86,8 @@ function Base.getproperty(cr::Crystal, name::Symbol) getfield(cr, :internalptr) elseif name === :cell return getcell(cr) + else + throw(ErrorException("Type Crystal has no field "*String(name))) end end -- cgit v1.2.3 From 3e63a502965b06b10259e8f29ce7f70b7f2550c9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Jan 2024 14:17:04 +0100 Subject: Julia: Remove leftover crystal.in_image --- julia/CrystFEL/src/image.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index ce7b74d0..494c5d27 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -202,13 +202,9 @@ end function Base.push!(image::Image, cr::Crystal) - if cr.in_image - throw(ErrorException("Crystal is already in an image")) - end ccall((:image_add_crystal, libcrystfel), Cvoid, (Ptr{InternalImage},Ptr{InternalCrystal}), image.internalptr, cr.internalptr) - cr.in_image = true end -- cgit v1.2.3 From ab4388d91a76841b4210840e17b94de826149b84 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Jan 2024 14:24:37 +0100 Subject: Julia: UnitCell: Fix spurious precision --- julia/CrystFEL/src/cell.jl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl index c098f8ca..bce39c50 100644 --- a/julia/CrystFEL/src/cell.jl +++ b/julia/CrystFEL/src/cell.jl @@ -1,6 +1,7 @@ module UnitCells using Random +using Printf import ..CrystFEL: libcrystfel export UnitCell, LatticeType, CenteringType, UniqueAxis @@ -297,12 +298,9 @@ function Base.show(io::IO, uc::UnitCell) show(io, cen); write(io, ", ") show(io, ua); write(io, ",\n ") let cp = getcellparams(uc) - show(io, cp.a*1e10); write(io, " Å, ") - show(io, cp.b*1e10); write(io, " Å, ") - show(io, cp.c*1e10); write(io, " Å, ") - show(io, rad2deg(cp.α)); write(io, "°, ") - show(io, rad2deg(cp.β)); write(io, "°, ") - show(io, rad2deg(cp.γ)); write(io, "°") + @printf(io, "%.3f Å, %.3f Å, %.3f Å, %.3f°, %.3f°, %.3f°", + cp.a*1e10, cp.b*1e10, cp.c*1e10, + rad2deg(cp.α), rad2deg(cp.β), rad2deg(cp.γ)) end write(io, ")") end -- cgit v1.2.3 From 66f11f47e070c265a00b36b9517229d7e40f040a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Jan 2024 15:11:02 +0100 Subject: Tweak alignment-test.jl --- julia/alignment-test.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 4316755f..f5abe334 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -3,7 +3,7 @@ using Random using Plots using MillepedeII -# "Simulate" a diffraction pattern from the reflections +# "Simulate" a diffraction pattern function sketch_pattern(image, cr) reflist = predictreflections(cr, image) peaklist = PeakList() @@ -24,11 +24,17 @@ function simulate_and_index(cell, image_true, dtempl_moved, mille, n) for i in 1:n + # Create a diffraction pattern for a random orientation cr = Crystal(rotatecell(cell)) peaklist = sketch_pattern(image_true, cr) - image_moved = Image(dtempl_moved) + # Make an image with the correct spot positions, + # but with an incorrect geometry + image_moved = Image(dtempl_moved) image_moved.peaklist = peaklist + + # Index the pattern (and store Mille data), + # based on the incorrect geometry index(image_moved, indexer, mille=mille) if i % 100 == 0 @@ -47,7 +53,7 @@ dtempl_true = loaddatatemplate("julia/alignment-test.geom") image_true = Image(dtempl_true) cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) dtempl_moved = loaddatatemplate("julia/alignment-test.geom") -translategroup(dtempl_moved, "q0", 200e-6, 0, 0) +translategroup(dtempl_moved, "q1", 200e-6, 0, 0) let mille = Mille("mille.dat") simulate_and_index(cell, image_true, dtempl_moved, mille, 100) close(mille) -- cgit v1.2.3 From eff54a2c23ee1d0d29f1af11af77881bd0c44b1e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 20 Jan 2024 10:34:48 +0100 Subject: Julia: translategroup: Add an exclamation point --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/datatemplates.jl | 6 +++--- julia/alignment-test.jl | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 63b636b1..431fb51e 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -46,7 +46,7 @@ export SymOpList include("datatemplates.jl") using .DataTemplates -export DataTemplate, loaddatatemplate, wavelength, cameralength, translategroup +export DataTemplate, loaddatatemplate, wavelength, cameralength, translategroup! include("peaklist.jl") using .PeakLists diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index b76a272e..7ede6843 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -3,7 +3,7 @@ module DataTemplates import ..CrystFEL: libcrystfel export DataTemplate, InternalDataTemplate, loaddatatemplate export wavelength, cameralength -export translategroup +export translategroup! # Represents the real C-side (opaque) structure. mutable struct InternalDataTemplate end @@ -85,14 +85,14 @@ end """ - translategroup(datatemplate, groupname, xshift, yshift, zshift) + translategroup!(datatemplate, groupname, xshift, yshift, zshift) Modifies `DataTemplate` by moving the specified panel group by the specified amount (in metres). Corresponds to CrystFEL C API function `data_template_translate_group`. """ -function translategroup(dtempl::DataTemplate, groupname, xshift, yshift, zshift) +function translategroup!(dtempl::DataTemplate, groupname, xshift, yshift, zshift) r = @ccall libcrystfel.data_template_translate_group_m(dtempl.internalptr::Ptr{InternalDataTemplate}, groupname::Cstring, xshift::Cdouble, diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index f5abe334..de4d284b 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -53,7 +53,7 @@ dtempl_true = loaddatatemplate("julia/alignment-test.geom") image_true = Image(dtempl_true) cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) dtempl_moved = loaddatatemplate("julia/alignment-test.geom") -translategroup(dtempl_moved, "q1", 200e-6, 0, 0) +translategroup!(dtempl_moved, "q1", 200e-6, 0, 0) let mille = Mille("mille.dat") simulate_and_index(cell, image_true, dtempl_moved, mille, 100) close(mille) -- cgit v1.2.3 From bb1bd3e18471d03cded733ff9b177c8fdeade0c8 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 20 Jan 2024 15:19:37 +0100 Subject: Julia: Add show method for Image --- julia/CrystFEL/src/image.jl | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 494c5d27..f858dfa7 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -1,5 +1,7 @@ module Images +using Printf + import ..CrystFEL: libcrystfel import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate import ..CrystFEL.DetGeoms: DetGeom @@ -267,4 +269,61 @@ function Image(dtempl::DataTemplate, end +function Base.show(io::IO, mime::MIME"text/plain", image::Image) + + idata = unsafe_load(image.internalptr) + @printf(io, "CrystFEL.Image(%p):\n\n", image.internalptr) + + println(io, " Serial number: ", idata.serial) + write(io, " Filename: ") + if idata.filename == C_NULL + write(io, "") + else + write(io, unsafe_string(idata.filename)) + end + write(io, "\n") + + write(io, " Frame ID: ") + if idata.ev == C_NULL + write(io, "") + else + write(io, unsafe_string(idata.ev)) + end + write(io, "\n") + + write(io, "\n") + println(io, " Wavelength: ", idata.lambda*1e10, " Å") + println(io, " Bandwidth: ", idata.bw*100, " %") + println(io, " Divergence: ", idata.div*1e3, " mrad") + + write(io, "\n") + if idata.peaklist != C_NULL + let npk = @ccall libcrystfel.image_feature_count(idata.peaklist::Ptr{InternalPeakList})::Cint + println(io, " Number of peaks: ", npk) + end + else + println(io, " Number of peaks: 0 (no peak list)") + end + + println(io, " Estimated resolution: ", 1e10/idata.peak_resolution, " Å") + write(io, " Hit flag: ") + if idata.hit != 0 + write(io, "set") + else + write(io, "not set") + end + write(io, "\n") + + write(io, "\n") + println(io, " Number of crystals: ", idata.n_crystals) + println(io, " Number of indexing attempts made: ", idata.n_crystals) + println(io, " Indexed by algorithm: ", idata.indexed_by) +end + + +function Base.show(io::IO, image::Image) + @printf(io, "CrystFEL.Image(%p)", image.internalptr) +end + + end # of module -- cgit v1.2.3 From 8fe6287bfc5335c47140fe7ba745de14b1376d2c Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 20 Jan 2024 15:37:03 +0100 Subject: Julia: predictreflections: add types This is to stop me from putting the image and crystal the wrong way round. --- julia/CrystFEL/src/diffcalc.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/diffcalc.jl b/julia/CrystFEL/src/diffcalc.jl index 2e039a20..d89376ce 100644 --- a/julia/CrystFEL/src/diffcalc.jl +++ b/julia/CrystFEL/src/diffcalc.jl @@ -1,14 +1,14 @@ module DiffractionCalculations import ..CrystFEL: libcrystfel -import ..CrystFEL.Images: InternalImage -import ..CrystFEL.Crystals: InternalCrystal +import ..CrystFEL.Images: InternalImage, Image +import ..CrystFEL.Crystals: InternalCrystal, Crystal import ..CrystFEL.RefLists: RefList, UnmergedReflection, InternalRefList import ..CrystFEL.Symmetry: SymOpList export predictreflections -function predictreflections(cr, image; maxres=1e10) +function predictreflections(cr::Crystal, image::Image; maxres=1e10) refls = ccall((:predict_to_res, libcrystfel), Ptr{InternalRefList}, (Ptr{InternalCrystal}, Ptr{InternalImage}, Cdouble), -- cgit v1.2.3 From 03612564815811e495a6b6a595defc834cd310e9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 20 Jan 2024 15:37:31 +0100 Subject: Julia: Fix image.peaklist memory management --- julia/CrystFEL/src/image.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index f858dfa7..5b443d05 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -152,12 +152,13 @@ function set_peaklist(image, new_pl) assert_type(new_pl, PeakList) idata = unsafe_load(image.internalptr) - if (idata.owns_peaklist == 0) && (idata.peaklist != C_NULL) + if (idata.owns_peaklist == 1) && (idata.peaklist != C_NULL) @ccall libcrystfel.image_feature_list_free(idata.peaklist::Ptr{InternalPeakList})::Cvoid end idata.peaklist = new_pl.internalptr idata.owns_peaklist = 0 unsafe_store!(image.internalptr, idata) + setfield!(image, :peaklist, new_pl) end -- cgit v1.2.3 From 24e81e00a1c36863b7e0f649bf7b3ec6ad3eb3c8 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 21 Jan 2024 11:21:11 +0100 Subject: Julia: Crystal: Improve show method, add accessors I'm not sure about these field names, yet. --- julia/CrystFEL/src/crystal.jl | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index 75124789..89aaf0fe 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -1,5 +1,7 @@ module Crystals +using Printf + import ..CrystFEL: libcrystfel import ..CrystFEL.RefLists: RefList, InternalRefList, UnmergedReflection import ..CrystFEL.UnitCells: UnitCell, InternalUnitCell @@ -86,20 +88,44 @@ function Base.getproperty(cr::Crystal, name::Symbol) getfield(cr, :internalptr) elseif name === :cell return getcell(cr) + elseif name === :Bfac + return @ccall libcrystfel.crystal_get_Bfac(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :osf + return @ccall libcrystfel.crystal_get_osf(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :mos + return @ccall libcrystfel.crystal_get_mosaicity(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :r + return @ccall libcrystfel.crystal_get_profile_radius(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :resolution + return @ccall libcrystfel.crystal_get_resolution_limit(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :flag + return @ccall libcrystfel.crystal_get_user_flag(cr.internalptr::Ptr{InternalCrystal})::Cint else throw(ErrorException("Type Crystal has no field "*String(name))) end end -function Base.show(io::IO, cr::Crystal) - write(io, "Crystal(") +function Base.show(io::IO, mime::MIME"text/plain", cr::Crystal) + @printf(io, "CrystFEL.Crystal(%p):\n\n", cr.internalptr) if cr.cell !== nothing show(io, cr.cell) + write(io, "\n\n") else - write(io, "no cell") + write(io, "Unit cell parameters not set\n\n") end - write(io, ")") + println(io, " Linear scale factor: ", cr.osf) + println(io, " Debye-Walle factor: ", cr.Bfac) + println(io, " Mosaicity: ", cr.mos) + println(io, " Profile radius: ", cr.r/1e9, " nm⁻¹") + println(io, " Resolution limit: ", cr.resolution) + println(io, " Flag: ", cr.flag) end + +function Base.show(io::IO, cr::Crystal) + @printf(io, "CrystFEL.Crystal(%p)", cr.internalptr) +end + + end # of module -- cgit v1.2.3 From 14c474465a497019383f16bdd12c09d3ed6069ea Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 21 Jan 2024 12:06:11 +0100 Subject: Julia: Get rid of crystal.reflections --- julia/CrystFEL/src/crystal.jl | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl index 89aaf0fe..f05f651f 100644 --- a/julia/CrystFEL/src/crystal.jl +++ b/julia/CrystFEL/src/crystal.jl @@ -56,16 +56,6 @@ end function Base.setproperty!(cr::Crystal, name::Symbol, val) if name === :internalptr setfield!(cr, :internalptr, val) - else - if name === :reflections - if val isa RefList{UnmergedReflection} - ccall((:crystal_set_reflections, libcrystfel), - Cvoid, (Ptr{InternalCrystal},Ptr{InternalRefList}), - cr.internalptr, val.internalptr) - else - throw(ArgumentError("Must be a RefList{UnmergedReflection}")) - end - end end end -- cgit v1.2.3 From f5925d65fe5d2fe7bf0293dc43e32ee48d8d4014 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 21 Jan 2024 12:06:32 +0100 Subject: Julia: Use cfstrdup (not strdup) --- julia/CrystFEL/src/image.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 5b443d05..e11b41c1 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -137,7 +137,7 @@ function Base.getproperty(image::Image, name::Symbol) end -strdup(str) = @ccall strdup(str::Cstring)::Cstring +strdup(str) = @ccall libcrystfel.cfstrdup(str::Cstring)::Cstring function assert_type(val, type) -- cgit v1.2.3 From 85a57decf6cafc353b792cd52f476eed4ade3915 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 21 Jan 2024 12:14:27 +0100 Subject: Julia: push!(image, crystal): Mark crystal as not to be freed The crystal must also be added to the image's list, so that it doesn't get GCed while the image is still around. --- julia/CrystFEL/src/image.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index e11b41c1..020117e7 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -205,9 +205,15 @@ end function Base.push!(image::Image, cr::Crystal) - ccall((:image_add_crystal, libcrystfel), - Cvoid, (Ptr{InternalImage},Ptr{InternalCrystal}), - image.internalptr, cr.internalptr) + @ccall libcrystfel.image_add_crystal(image.internalptr::Ptr{InternalImage}, + cr.internalptr::Ptr{InternalCrystal})::Cvoid + + idata = unsafe_load(image.internalptr) + ncryst = idata.n_crystals + pairptr = unsafe_load(idata.crystal_refls, ncryst) + pairptr.owns_crystal = 0 + unsafe_store!(idata.crystal_refls, pairptr, ncryst) + push!(getfield(image, :crystals), cr) end -- cgit v1.2.3 From d371a2b753fd20da36ec6a46f06e4bc8f058f1fa Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 21 Jan 2024 12:20:09 +0100 Subject: Julia: Add push!(image, crystal, reflections) New method needed following "Crystals shouldn't own RefLists" patch series. --- julia/CrystFEL/src/image.jl | 15 +++++++++++++++ julia/partial_sim.jl | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 020117e7..33af3252 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -217,6 +217,21 @@ function Base.push!(image::Image, cr::Crystal) end +function Base.push!(image::Image, cr::Crystal, reflections::RefList{UnmergedReflection}) + @ccall libcrystfel.image_add_crystal_refls(image.internalptr::Ptr{InternalImage}, + cr.internalptr::Ptr{InternalCrystal}, + reflections.internalptr::Ptr{InternalRefList})::Cvoid + idata = unsafe_load(image.internalptr) + ncryst = idata.n_crystals + pairptr = unsafe_load(idata.crystals, ncryst) + pairptr.owns_crystal = 0 + pairptr.owns_reflist = 0 + unsafe_store!(idata.crystals, pairptr, ncryst) + push!(getfield(image, :crystals), cr) + push!(getfield(image, :reflists), reflections) +end + + """ Image(dtempl::DataTemplate) diff --git a/julia/partial_sim.jl b/julia/partial_sim.jl index 4ddec347..11384f47 100644 --- a/julia/partial_sim.jl +++ b/julia/partial_sim.jl @@ -10,8 +10,8 @@ let st = Stream("partials.stream", "w", dtempl) image.filename = "simulation_" * string(i) image.ev = "//" cr = Crystal(rotatecell(cell)) - cr.reflections = predictreflections(cr, image) - push!(image, cr) + reflections = predictreflections(cr, image) + push!(image, cr, reflections) chunkwrite(st, image) end end -- cgit v1.2.3 From c2bbea9374aa940c6dc5f8102614470aab1baa8e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 22 Jan 2024 11:54:52 +0100 Subject: Julia: Expose partiality modelling --- julia/CrystFEL/src/CrystFEL.jl | 3 ++- julia/CrystFEL/src/diffcalc.jl | 33 ++++++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 431fb51e..1b1ee52b 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -67,7 +67,8 @@ export Image include("diffcalc.jl") using .DiffractionCalculations -export predictreflections +export predictreflections, calculatepartialities! +export PartialityModel, UnityModel, XSphereModel, OffsetModel, RandomModel, GeneralGaussianModel include("indexing.jl") using .Indexing diff --git a/julia/CrystFEL/src/diffcalc.jl b/julia/CrystFEL/src/diffcalc.jl index d89376ce..1c6aea9c 100644 --- a/julia/CrystFEL/src/diffcalc.jl +++ b/julia/CrystFEL/src/diffcalc.jl @@ -5,17 +5,40 @@ import ..CrystFEL.Images: InternalImage, Image import ..CrystFEL.Crystals: InternalCrystal, Crystal import ..CrystFEL.RefLists: RefList, UnmergedReflection, InternalRefList import ..CrystFEL.Symmetry: SymOpList -export predictreflections +export predictreflections, calculatepartialities! +export PartialityModel, UnityModel, XSphereModel, OffsetModel, RandomModel, GeneralGaussianModel + + +""" +Enumeration of the available partiality models. +""" +@enum PartialityModel begin + UnityModel + XSphereModel + OffsetModel + RandomModel + GeneralGaussianModel +end function predictreflections(cr::Crystal, image::Image; maxres=1e10) - refls = ccall((:predict_to_res, libcrystfel), - Ptr{InternalRefList}, - (Ptr{InternalCrystal}, Ptr{InternalImage}, Cdouble), - cr.internalptr, image.internalptr, maxres) + + refls = @ccall libcrystfel.predict_to_res(cr.internalptr::Ptr{InternalCrystal}, + image.internalptr::Ptr{InternalImage}, + maxres::Cdouble)::Ptr{InternalRefList} sym = SymOpList("1") return RefList{UnmergedReflection}(refls, sym) end +function calculatepartialities!(reflist::RefList{UnmergedReflection}, + cr::Crystal, image::Image; model=XSphereModel, maxres=1e10) + + @ccall libcrystfel.calculate_partialities(reflist.internalptr::Ptr{InternalRefList}, + cr.internalptr::Ptr{InternalCrystal}, + image.internalptr::Ptr{InternalImage}, + model::Cint)::Cvoid +end + + end # of module -- cgit v1.2.3 From 1b57489a6544042b7ae50383e636e311fe2f40d4 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 22 Jan 2024 13:56:36 +0100 Subject: Julia: Add Reflection setters --- julia/CrystFEL/src/reflists.jl | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index d6b3a951..1847b4cf 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -245,6 +245,65 @@ function Base.getproperty(refl::Reflection, name::Symbol) end +function Base.setproperty!(refl::Reflection, name::Symbol, val) + if name === :intensity + @ccall libcrystfel.set_intensity(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :sigintensity + @ccall libcrystfel.set_esd_intensity(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :partiality + @ccall libcrystfel.set_partiality(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :khalf + @ccall libcrystfel.set_khalf(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :kpred + @ccall libcrystfel.set_kpred(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :excitationerror + @ccall libcrystfel.set_exerr(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :lorentzfactor + @ccall libcrystfel.set_lorentz(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :phase + @ccall libcrystfel.set_phase(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :peak + @ccall libcrystfel.set_peak(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :meanbackground + @ccall libcrystfel.set_mean_bg(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :temp1 + @ccall libcrystfel.set_temp1(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :temp2 + @ccall libcrystfel.set_temp2(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :nmeasurements + @ccall libcrystfel.set_redundancy(refl.internalptr::Ptr{InternalReflection}, + val::Cint)::Cvoid + elseif name === :flag + @ccall libcrystfel.set_flag(refl.internalptr::Ptr{InternalReflection}, + val::Cint)::Cvoid + elseif name === :detectorposition + @ccall libcrystfel.set_detector_pos(refl.internalptr::Ptr{InternalReflection}, + val.fs::Cdouble, val.ss::Cdouble)::Cvoid + @ccall libcrystfel.set_panel_number(refl.internalptr::Ptr{InternalReflection}, + val.panelnumber::Cint)::Cvoid + elseif name === :indices + throw(ErrorException("Cannot set the indices of a Reflection")) + elseif name === :symmetricindices + @ccall libcrystfel.set_symmetric_indices(refl.internalptr::Ptr{InternalReflection}, + val[1]::Cint, val[2]::Cint, val[3]::Cint)::Cvoid + else + setfield!(refl, name, val) + end +end + + function Base.propertynames(::UnmergedReflection; private=false) names = (:intensity,:sigintensity,:partiality,:khalf,:kpred,:lorentzfactor, :excitationerror,:phase,:peak,:meanbackground,:temp1,:temp2, -- cgit v1.2.3 From 2e3591c6bb4aff4b54a69b9ca38542562f8069e2 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 22 Jan 2024 14:13:33 +0100 Subject: Julia: Add asymmetricindices() --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/symmetry.jl | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 1b1ee52b..daea5284 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -42,7 +42,7 @@ export Panel, DetGeom include("symmetry.jl") using .Symmetry -export SymOpList +export SymOpList, asymmetricindices include("datatemplates.jl") using .DataTemplates diff --git a/julia/CrystFEL/src/symmetry.jl b/julia/CrystFEL/src/symmetry.jl index fd3ce7b2..d6d2e477 100644 --- a/julia/CrystFEL/src/symmetry.jl +++ b/julia/CrystFEL/src/symmetry.jl @@ -2,7 +2,7 @@ module Symmetry import ..CrystFEL: libcrystfel export SymOpList, InternalSymOpList, InternalIntegerMatrix -export symmetry_name +export symmetry_name, asymmetricindices # Types for pointers returned by libcrystfel @@ -100,6 +100,17 @@ function Base.iterate(sym::SymOpList, i) end +function asymmetricindices(sym::SymOpList, h, k, l) + ho = Ref{Cint}(0) + ko = Ref{Cint}(0) + lo = Ref{Cint}(0) + @ccall libcrystfel.get_asymm(sym.internalptr::Ptr{InternalSymOpList}, + h::Cint, k::Cint, l::Cint, + ho::Ref{Cint}, ko::Ref{Cint}, lo::Ref{Cint})::Cvoid + (ho[], ko[], lo[]) +end + + function Base.show(io::IO, ::MIME"text/plain", sym::SymOpList) print(io, length(sym), "-element SymOpList (\"", symmetry_name(sym), "\")") for op in sym -- cgit v1.2.3 From f2829b1abb24be08a9f7214ec2d54ad9d142d7e7 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 22 Jan 2024 14:14:55 +0100 Subject: Julia: Finish implementing partial_sim.jl --- julia/partial_sim.jl | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/julia/partial_sim.jl b/julia/partial_sim.jl index 11384f47..efc621f9 100644 --- a/julia/partial_sim.jl +++ b/julia/partial_sim.jl @@ -1,7 +1,8 @@ using CrystFEL -dtempl = loaddatatemplate("julia/alignment-test.geom") -cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) +dtempl = loaddatatemplate("input.geom") +cell = UnitCell(OrthorhombicLattice, PrimitiveCell, 40.0, 50.0, 60.0) +full = loadreflist("input.hkl") let st = Stream("partials.stream", "w", dtempl) for i in 1:10 println("Writing image ", i) @@ -11,6 +12,18 @@ let st = Stream("partials.stream", "w", dtempl) image.ev = "//" cr = Crystal(rotatecell(cell)) reflections = predictreflections(cr, image) + calculatepartialities!(reflections, cr, image, model=XSphereModel) + for refl in reflections + f = full[asymmetricindices(full.symmetry, refl.indices...)...] + if f !== nothing + refl.intensity = f.intensity * refl.partiality * refl.lorentzfactor + else + # No matching "full" intensity - can't do anything + # Reflections with zero measurements won't be written to file + refl.nmeasurements = 0 + println("Not found: ", refl.indices) + end + end push!(image, cr, reflections) chunkwrite(st, image) end -- cgit v1.2.3 From caf4062de65c47146965a8d8caadbf9b642405b7 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 30 Jan 2024 15:39:15 +0100 Subject: Julia: Add peak search algorithms --- julia/CrystFEL/src/CrystFEL.jl | 4 +++ julia/CrystFEL/src/peaksearch.jl | 74 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 julia/CrystFEL/src/peaksearch.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index daea5284..230def00 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -82,4 +82,8 @@ include("millepede.jl") using .Millepede export Mille +include("peaksearch.jl") +using .PeakSearch +export zaefpeaks, peakfinder8, peakfinder9 + end # of module diff --git a/julia/CrystFEL/src/peaksearch.jl b/julia/CrystFEL/src/peaksearch.jl new file mode 100644 index 00000000..aaaee16c --- /dev/null +++ b/julia/CrystFEL/src/peaksearch.jl @@ -0,0 +1,74 @@ +module PeakSearch + +import ..CrystFEL: libcrystfel +import ..CrystFEL.Images: InternalImage +import ..CrystFEL.PeakLists: PeakList, InternalPeakList + +export zaefpeaks, peakfinder8, peakfinder9 + + +function tf10(val) + if val + return 1 + else + return 0 + end +end + + +function zaefpeaks(image; threshold=100, mingrad=100000, minsnr=5, + radiusinn=4, radiusmid=5, radiusout=7, usesaturated=true) + out = @ccall libcrystfel.search_peaks(image.internalptr::Ptr{InternalImage}, + threshold::Cfloat, + mingrad::Cfloat, + minsnr::Cfloat, + radiusinn::Cdouble, + radiusmid::Cdouble, + radiusout::Cdouble, + tf10(usesaturated)::Cint)::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Peak search failed")) + end + PeakList(out) +end + + + +function peakfinder8(image; threshold=100, minsnr=5, minpix=2, maxpix=200, + localbg=3, minres=0, maxres=5000, usesaturated=true, maxpeaks=2000) + out = @ccall libcrystfel.peakfinder8(image.internalptr::Ptr{InternalImage}, + maxpeaks::Cint, + threshold::Cfloat, + minsnr::Cfloat, + minpix::Cint, + maxpix::Cint, + localbg::Cint, + minres::Cint, + maxres::Cint, + tf10(usesaturated)::Cint, + 0::Cint, + C_NULL::Ptr{Cvoid})::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Peak search failed")) + end + PeakList(out) +end + + +function peakfinder9(image; minsnrbig=7, minsnrpeak=6, minsnrwhole=5, minbgsig=11, + brightpxcut=-Inf, window=5) + out = @ccall libcrystfel.search_peaks_peakfinder9(image.internalptr::Ptr{InternalImage}, + minsnrbig::Cfloat, + minsnrpeak::Cfloat, + minsnrwhole::Cfloat, + minbgsig::Cfloat, + brightpxcut::Cfloat, + window::Cint)::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Peak search failed")) + end + PeakList(out) +end + + +end # of module -- cgit v1.2.3 From c1cd21679686f59d8f3533145108118419b40356 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 31 Jan 2024 14:02:27 +0100 Subject: Julia: Add chunkread() --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/streams.jl | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 230def00..86637014 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -76,7 +76,7 @@ export Indexer, index include("streams.jl") using .Streams -export Stream, chunkwrite +export Stream, chunkwrite, chunkread include("millepede.jl") using .Millepede diff --git a/julia/CrystFEL/src/streams.jl b/julia/CrystFEL/src/streams.jl index 29f0de5d..d5c86464 100644 --- a/julia/CrystFEL/src/streams.jl +++ b/julia/CrystFEL/src/streams.jl @@ -3,7 +3,7 @@ module Streams import ..CrystFEL: libcrystfel import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate import ..CrystFEL.Images: Image, InternalImage -export Stream, chunkwrite +export Stream, chunkwrite, chunkread # Represents the real C-side (opaque) structure. mutable struct InternalStream end @@ -98,6 +98,7 @@ end function chunkwrite(st::Stream, image::Image; peaks=true, reflections=true) + st.internalptr == C_NULL && throw(ErrorException("Stream is closed")) flags = streamflags(peaks, reflections, false) @ccall libcrystfel.stream_write_chunk(st.internalptr::Ptr{InternalStream}, image.internalptr::Ptr{InternalImage}, @@ -105,4 +106,20 @@ function chunkwrite(st::Stream, image::Image; peaks=true, reflections=true) end +function chunkread(st::Stream; peaks=true, reflections=true) + + st.internalptr == C_NULL && throw(ErrorException("Stream is closed")) + + flags = streamflags(peaks, reflections, true) + out = @ccall libcrystfel.stream_read_chunk(st.internalptr::Ptr{InternalStream}, + flags::Cint)::Ptr{InternalImage} + out == C_NULL && return nothing + + finalizer(Image(out, nothing, [], [])) do x + ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) + end + +end + + end # of module -- cgit v1.2.3 From 85da29bd648334ddac81537c6309fefab68547a4 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 2 Feb 2024 15:10:12 +0100 Subject: Julia: Add 'rotategroup!' --- julia/CrystFEL/src/CrystFEL.jl | 3 ++- julia/CrystFEL/src/datatemplates.jl | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 86637014..91af5d19 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -46,7 +46,8 @@ export SymOpList, asymmetricindices include("datatemplates.jl") using .DataTemplates -export DataTemplate, loaddatatemplate, wavelength, cameralength, translategroup! +export DataTemplate, loaddatatemplate, wavelength, cameralength +export translategroup!, rotategroup! include("peaklist.jl") using .PeakLists diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index 7ede6843..9632346e 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -3,7 +3,7 @@ module DataTemplates import ..CrystFEL: libcrystfel export DataTemplate, InternalDataTemplate, loaddatatemplate export wavelength, cameralength -export translategroup! +export translategroup!, rotategroup! # Represents the real C-side (opaque) structure. mutable struct InternalDataTemplate end @@ -105,4 +105,23 @@ function translategroup!(dtempl::DataTemplate, groupname, xshift, yshift, zshift end +""" + rotategroup!(datatemplate, groupname, angle, axis) + +Modifies `DataTemplate` by rotating the specified panel group by the specified +amount (in degrees) about the specified xaxis (:x, :y or :z). + +Corresponds to CrystFEL C API function `data_template_rotate_group`. +""" +function rotategroup!(dtempl::DataTemplate, groupname, angle, axis) + r = @ccall libcrystfel.data_template_rotate_group(dtempl.internalptr::Ptr{InternalDataTemplate}, + groupname::Cstring, + deg2rad(angle)::Cdouble, + String(axis)[1]::Cchar)::Cint + if r != 0 + throw(ErrorException("Failed to rotate DataTemplate")) + end + +end + end # of module -- cgit v1.2.3 From 9f4a4750659732dbe7433fc61fe1d07b5aa05264 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 2 Feb 2024 15:10:40 +0100 Subject: Julia: Fix docs --- julia/CrystFEL/src/datatemplates.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl index 9632346e..b063aa90 100644 --- a/julia/CrystFEL/src/datatemplates.jl +++ b/julia/CrystFEL/src/datatemplates.jl @@ -90,7 +90,7 @@ end Modifies `DataTemplate` by moving the specified panel group by the specified amount (in metres). -Corresponds to CrystFEL C API function `data_template_translate_group`. +Corresponds to CrystFEL C API function `data_template_translate_group_m`. """ function translategroup!(dtempl::DataTemplate, groupname, xshift, yshift, zshift) r = @ccall libcrystfel.data_template_translate_group_m(dtempl.internalptr::Ptr{InternalDataTemplate}, -- cgit v1.2.3 From e40d5e6cd2d0b98d700bab42c614f27cfe725d97 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 2 Feb 2024 15:27:25 +0100 Subject: align_detector.jl: Show number of indexed frames --- julia/alignment-test.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index de4d284b..adaf399e 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -22,6 +22,7 @@ function simulate_and_index(cell, image_true, dtempl_moved, mille, n) indexer = Indexer("asdf", dtempl_moved, cell, retry=false, multilattice=false, refine=true) + nidx = 0 for i in 1:n # Create a diffraction pattern for a random orientation @@ -37,6 +38,10 @@ function simulate_and_index(cell, image_true, dtempl_moved, mille, n) # based on the incorrect geometry index(image_moved, indexer, mille=mille) + if image_moved.n_crystals > 0 + nidx += 1 + end + if i % 100 == 0 print("*") else @@ -46,6 +51,8 @@ function simulate_and_index(cell, image_true, dtempl_moved, mille, n) end println("") + println("Indexed ", nidx, " out of ", n, " frames") + end -- cgit v1.2.3 From 5398ff3bc10439b8e4642256b7d8b21e17ae7ce2 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 2 Feb 2024 16:39:30 +0100 Subject: Julia: Constructor for RefList{MergedReflection} --- julia/CrystFEL/src/reflists.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 1847b4cf..c5edb794 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -36,6 +36,17 @@ mutable struct UnmergedReflection <: Reflection end +function RefList{MergedReflection}(sym::SymOpList) + out = @ccall libcrystfel.reflist_new()::Ptr{InternalRefList} + if out == C_NULL + throw(ErrorException("Failed to create RefList")) + end + finalizer(RefList{MergedReflection}(out, sym)) do x + @ccall libcrystfel.reflist_free(x.internalptr::Ptr{InternalRefList})::Cvoid + end +end + + function Base.iterate(reflist::RefList{T}) where T rli = Ref{Ptr{InternalRefListIterator}}(C_NULL) -- cgit v1.2.3 From 55c02192fad40514a9dd8456aac9381561641cfe Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 6 Feb 2024 16:41:33 +0100 Subject: Julia: Add "savereflist!" --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/reflists.jl | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 91af5d19..95b2a61d 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -55,7 +55,7 @@ export PeakList include("reflists.jl") using .RefLists -export RefList, loadreflist +export RefList, loadreflist, savereflist! export Reflection, MergedReflection, UnmergedReflection include("crystal.jl") diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index c5edb794..e1766f83 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -3,7 +3,7 @@ module RefLists using Printf import ..CrystFEL: libcrystfel import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name -export RefList, loadreflist +export RefList, loadreflist, savereflist! export Reflection, UnmergedReflection, MergedReflection export InternalRefList @@ -123,6 +123,19 @@ function loadreflist(filename::AbstractString) end +function savereflist!(reflist::RefList{MergedReflection}, filename::AbstractString) + + r = @ccall libcrystfel.write_reflist_2(filename::Cstring, + reflist.internalptr::Ptr{InternalRefList}, + reflist.symmetry.internalptr::Ptr{InternalSymOpList})::Cint + + if r != 0 + throw(ErrorException("Failed to save reflection list")) + end + +end + + function Base.show(io::IO, ::MIME"text/plain", reflist::RefList{MergedReflection}) println(io, "Merged reflection list in point group ", symmetry_name(reflist.symmetry)) print(io, " h k l intensity σ(intens) nmeas") -- cgit v1.2.3 From 2710d085345f766afd885a41050b8d98ccab74d3 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 7 Feb 2024 11:14:23 +0100 Subject: Julia: RefList: index using tuple I realised that separate h k l parameters leads to a profusion of argument splatting. --- julia/CrystFEL/src/reflists.jl | 9 +++++---- julia/CrystFEL/src/symmetry.jl | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index e1766f83..6629b186 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -93,11 +93,12 @@ Base.length(reflist::RefList) = ccall((:num_reflections, libcrystfel), Cint, (Ptr{InternalRefList},), reflist.internalptr) -function Base.getindex(reflist::RefList{T}, h, k, l) where T +function Base.getindex(reflist::RefList{T}, indices) where T - refl = ccall((:find_refl, libcrystfel), - Ptr{InternalReflection}, (Ptr{InternalRefList},Cint,Cint,Cint), - reflist.internalptr, h, k, l) + refl = @ccall libcrystfel.find_refl(reflist.internalptr::Ptr{InternalRefList}, + indices[1]::Cint, + indices[2]::Cint, + indices[3]::Cint)::Ptr{InternalReflection} if refl == C_NULL return nothing diff --git a/julia/CrystFEL/src/symmetry.jl b/julia/CrystFEL/src/symmetry.jl index d6d2e477..4b4caa4d 100644 --- a/julia/CrystFEL/src/symmetry.jl +++ b/julia/CrystFEL/src/symmetry.jl @@ -100,12 +100,12 @@ function Base.iterate(sym::SymOpList, i) end -function asymmetricindices(sym::SymOpList, h, k, l) +function asymmetricindices(sym::SymOpList, indices) ho = Ref{Cint}(0) ko = Ref{Cint}(0) lo = Ref{Cint}(0) @ccall libcrystfel.get_asymm(sym.internalptr::Ptr{InternalSymOpList}, - h::Cint, k::Cint, l::Cint, + indices[1]::Cint, indices[2]::Cint, indices[3]::Cint, ho::Ref{Cint}, ko::Ref{Cint}, lo::Ref{Cint})::Cvoid (ho[], ko[], lo[]) end -- cgit v1.2.3 From bf126681d49c198dcec0e70e470a22d26dc31d55 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 7 Feb 2024 11:23:54 +0100 Subject: Julia: Add push!(::RefList, hkl) --- julia/CrystFEL/src/reflists.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 6629b186..89967d6f 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -108,6 +108,21 @@ function Base.getindex(reflist::RefList{T}, indices) where T end +function Base.push!(reflist::RefList{T}, indices) where T + + refl = @ccall libcrystfel.add_refl(reflist.internalptr::Ptr{InternalRefList}, + indices[1]::Cint, + indices[2]::Cint, + indices[3]::Cint)::Ptr{InternalReflection} + + if refl == C_NULL + return nothing + else + return T(refl) + end +end + + function loadreflist(filename::AbstractString) psym = Ref{Cstring}() -- cgit v1.2.3 From a4d8e53aa1969565c288b93ad36d1a7030ad19a3 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 7 Feb 2024 14:50:00 +0100 Subject: Julia: Add allcrystals() --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/streams.jl | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 95b2a61d..5ecfab91 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -77,7 +77,7 @@ export Indexer, index include("streams.jl") using .Streams -export Stream, chunkwrite, chunkread +export Stream, chunkwrite, chunkread, allcrystals include("millepede.jl") using .Millepede diff --git a/julia/CrystFEL/src/streams.jl b/julia/CrystFEL/src/streams.jl index d5c86464..798663e1 100644 --- a/julia/CrystFEL/src/streams.jl +++ b/julia/CrystFEL/src/streams.jl @@ -3,7 +3,7 @@ module Streams import ..CrystFEL: libcrystfel import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate import ..CrystFEL.Images: Image, InternalImage -export Stream, chunkwrite, chunkread +export Stream, chunkwrite, chunkread, allcrystals # Represents the real C-side (opaque) structure. mutable struct InternalStream end @@ -122,4 +122,17 @@ function chunkread(st::Stream; peaks=true, reflections=true) end +function allcrystals(st) + Channel() do ch + while true + image = chunkread(st) + image === nothing && break + for cr in image.crystals + put!(ch, (cr.crystal, cr.reflections)) + end + end + end +end + + end # of module -- cgit v1.2.3 From 93181e995bcae77e69d0b7eb3e32abfdd4d0d738 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 8 Feb 2024 16:34:21 +0100 Subject: Add julia/process_hkl.jl (example program) --- julia/process_hkl.jl | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 julia/process_hkl.jl diff --git a/julia/process_hkl.jl b/julia/process_hkl.jl new file mode 100644 index 00000000..ab2a6a20 --- /dev/null +++ b/julia/process_hkl.jl @@ -0,0 +1,41 @@ +using CrystFEL + +st = Stream("input.stream", "r") +sym = SymOpList("2/m_uab") +merged = RefList{MergedReflection}(sym) + +for (cr,reflections) in allcrystals(st) + + for refl in reflections + + indices = asymmetricindices(sym, refl.indices) + model_version = merged[indices] + if model_version === nothing + model_version = push!(merged, indices) + end + + w = 1.0 + mean = model_version.intensity + sumweight = model_version.temp1 + M2 = model_version.temp2 + temp = w + sumweight + delta = refl.intensity - mean + R = delta * w / temp + model_version.intensity = mean + R + model_version.temp1 = temp + model_version.temp2 = M2 + sumweight * delta * R + model_version.nmeasurements += 1 + + end + +end + +for refl in merged + if refl.nmeasurements > 1 + refl.sigintensity = sqrt(refl.temp2/refl.temp1)/sqrt(refl.nmeasurements) + else + refl.nmeasurements = 0 + end +end + +savereflist!(merged, "merged.hkl") -- cgit v1.2.3 From 0da7d9d1208f273aeb557adaed3f3e0f6dcdfe5a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 19 Feb 2024 17:11:58 +0100 Subject: Julia: Add Base.get!(::Reflist, indices) --- julia/CrystFEL/src/reflists.jl | 15 +++++++++++++++ julia/process_hkl.jl | 5 +---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 89967d6f..901162e8 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -108,6 +108,21 @@ function Base.getindex(reflist::RefList{T}, indices) where T end +function Base.get!(reflist::RefList{T}, indices) where T + + refl = @ccall libcrystfel.find_refl(reflist.internalptr::Ptr{InternalRefList}, + indices[1]::Cint, + indices[2]::Cint, + indices[3]::Cint)::Ptr{InternalReflection} + + if refl == C_NULL + return push!(reflist, indices) + else + return T(refl) + end +end + + function Base.push!(reflist::RefList{T}, indices) where T refl = @ccall libcrystfel.add_refl(reflist.internalptr::Ptr{InternalRefList}, diff --git a/julia/process_hkl.jl b/julia/process_hkl.jl index ab2a6a20..ac6ec662 100644 --- a/julia/process_hkl.jl +++ b/julia/process_hkl.jl @@ -9,10 +9,7 @@ for (cr,reflections) in allcrystals(st) for refl in reflections indices = asymmetricindices(sym, refl.indices) - model_version = merged[indices] - if model_version === nothing - model_version = push!(merged, indices) - end + model_version = get!(merged, indices) w = 1.0 mean = model_version.intensity -- cgit v1.2.3 From e1d77b345190f43eec2cc53684e0ded6b1939cd7 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 21 Feb 2024 11:02:13 +0100 Subject: julia/process_hkl.jl: Break into routines, add correction function --- julia/process_hkl.jl | 60 +++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/julia/process_hkl.jl b/julia/process_hkl.jl index ac6ec662..6d0dbd40 100644 --- a/julia/process_hkl.jl +++ b/julia/process_hkl.jl @@ -1,38 +1,46 @@ using CrystFEL -st = Stream("input.stream", "r") -sym = SymOpList("2/m_uab") -merged = RefList{MergedReflection}(sym) -for (cr,reflections) in allcrystals(st) +function mergereflections(correction, crystalrefls, sym) - for refl in reflections + merged = RefList{MergedReflection}(sym) - indices = asymmetricindices(sym, refl.indices) - model_version = get!(merged, indices) + for (cr,reflections) in crystalrefls - w = 1.0 - mean = model_version.intensity - sumweight = model_version.temp1 - M2 = model_version.temp2 - temp = w + sumweight - delta = refl.intensity - mean - R = delta * w / temp - model_version.intensity = mean + R - model_version.temp1 = temp - model_version.temp2 = M2 + sumweight * delta * R - model_version.nmeasurements += 1 + for refl in reflections - end + indices = asymmetricindices(sym, refl.indices) + model_version = get!(merged, indices) -end + w = 1.0 + mean = model_version.intensity + sumweight = model_version.temp1 + M2 = model_version.temp2 + temp = w + sumweight + delta = correction(refl.intensity, cr) - mean + R = delta * w / temp + model_version.intensity = mean + R + model_version.temp1 = temp + model_version.temp2 = M2 + sumweight * delta * R + model_version.nmeasurements += 1 + + end + end -for refl in merged - if refl.nmeasurements > 1 - refl.sigintensity = sqrt(refl.temp2/refl.temp1)/sqrt(refl.nmeasurements) - else - refl.nmeasurements = 0 + for refl in merged + if refl.nmeasurements > 1 + refl.sigintensity = sqrt(refl.temp2/refl.temp1)/sqrt(refl.nmeasurements) + else + refl.nmeasurements = 0 + end end + + return merged + end -savereflist!(merged, "merged.hkl") + +let st = Stream("input.stream", "r") + merged = mergereflections((i,cr)->i, allcrystals(st), SymOpList("2/m_uab")) + savereflist!(merged, "merged.hkl") +end -- cgit v1.2.3 From c75b2030b9c040c07c507f47822257879399e85d Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 21 Feb 2024 11:13:19 +0100 Subject: Julia: RefList: Return nothing if no reflections in list --- julia/CrystFEL/src/reflists.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index 901162e8..d922bdae 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -55,7 +55,7 @@ function Base.iterate(reflist::RefList{T}) where T reflist.internalptr, rli) if refl == C_NULL - throw(ArgumentError("Failed to find first reflection in list")) + return nothing # no reflections! end iter = RefListIterator(refl,rli[]) -- cgit v1.2.3 From fc78b43a4057be4216b55c3f8999f8f4296c04d9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 21 Feb 2024 14:11:46 +0100 Subject: Julia: chunkread: Expose option for reconstructing image data arrays/detgeom It makes a big performance difference to avoid creating these arrays. We will just need to deal with the fact that an Image might not have a DetGeom or data arrays. This commit also sets sensible chunkread options for allcrystals(). --- julia/CrystFEL/src/streams.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/julia/CrystFEL/src/streams.jl b/julia/CrystFEL/src/streams.jl index 798663e1..ce75c906 100644 --- a/julia/CrystFEL/src/streams.jl +++ b/julia/CrystFEL/src/streams.jl @@ -106,11 +106,11 @@ function chunkwrite(st::Stream, image::Image; peaks=true, reflections=true) end -function chunkread(st::Stream; peaks=true, reflections=true) +function chunkread(st::Stream; peaks=true, reflections=true, datageom=true) st.internalptr == C_NULL && throw(ErrorException("Stream is closed")) - flags = streamflags(peaks, reflections, true) + flags = streamflags(peaks, reflections, datageom) out = @ccall libcrystfel.stream_read_chunk(st.internalptr::Ptr{InternalStream}, flags::Cint)::Ptr{InternalImage} out == C_NULL && return nothing @@ -125,7 +125,7 @@ end function allcrystals(st) Channel() do ch while true - image = chunkread(st) + image = chunkread(st, peaks=false, reflections=true, datageom=false) image === nothing && break for cr in image.crystals put!(ch, (cr.crystal, cr.reflections)) -- cgit v1.2.3 From fa7c1e4aa507489f1c5ae9d9c107beaca5a705d3 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 21 Feb 2024 14:53:09 +0100 Subject: Julia: Set finalizers for RefList and Crystal when taken from image --- julia/CrystFEL/src/image.jl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 33af3252..4090dc61 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -86,11 +86,16 @@ function makecrystallist(image, listptr, n) else reflist = RefList{UnmergedReflection}(pairptr.reflist, SymOpList("1")) pairptr.owns_reflist = 0 + finalizer(reflist) do x + @ccall libcrystfel.reflist_free(x.internalptr::Ptr{InternalRefList})::Cvoid + end end push!(crystals, (crystal=cr, reflections=reflist)) pairptr.owns_crystal = 0 unsafe_store!(listptr, pairptr, i) - # We are now responsible for freeing the Crystal and RefList + finalizer(cr) do x + @ccall libcrystfel.crystal_free(x.internalptr::Ptr{InternalCrystal})::Cvoid + end end image.crystals = map(x->x.crystal, crystals) -- cgit v1.2.3 From 5e8c1b3f964432a16f180cb64f199f3d02218f3f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 22 Feb 2024 17:49:24 +0100 Subject: julia/process_hkl.jl: Abstract stable running mean/variance --- julia/process_hkl.jl | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/julia/process_hkl.jl b/julia/process_hkl.jl index 6d0dbd40..1d0bbdea 100644 --- a/julia/process_hkl.jl +++ b/julia/process_hkl.jl @@ -1,6 +1,21 @@ using CrystFEL +macro addmeasurement(measurement, weight, + mean, sumweight, wksp) + return quote + delta = $(esc(measurement)) - $(esc(mean)) + newsumweight = $(esc(sumweight)) + $(esc(weight)) + R = delta * $(esc(weight)) / newsumweight + $(esc(mean)) += R + $(esc(wksp)) += $(esc(sumweight)) * delta * R + $(esc(sumweight)) = newsumweight + end +end + +cstddev(nmeas, work1, work2) = sqrt(work2/work1)/sqrt(nmeas) + + function mergereflections(correction, crystalrefls, sym) merged = RefList{MergedReflection}(sym) @@ -11,17 +26,10 @@ function mergereflections(correction, crystalrefls, sym) indices = asymmetricindices(sym, refl.indices) model_version = get!(merged, indices) - - w = 1.0 - mean = model_version.intensity - sumweight = model_version.temp1 - M2 = model_version.temp2 - temp = w + sumweight - delta = correction(refl.intensity, cr) - mean - R = delta * w / temp - model_version.intensity = mean + R - model_version.temp1 = temp - model_version.temp2 = M2 + sumweight * delta * R + @addmeasurement(correction(refl.intensity, cr), 1.0, + model_version.intensity, + model_version.temp1, + model_version.temp2) model_version.nmeasurements += 1 end @@ -29,8 +37,11 @@ function mergereflections(correction, crystalrefls, sym) for refl in merged if refl.nmeasurements > 1 - refl.sigintensity = sqrt(refl.temp2/refl.temp1)/sqrt(refl.nmeasurements) + refl.sigintensity = cstddev(refl.nmeasurements, refl.temp1, refl.temp2) else + # Cannot delete a reflection from a list (especially not + # while iterating), but setting nmeasurements to zero + # prevents it from being written to the output file. refl.nmeasurements = 0 end end -- cgit v1.2.3 From 6156c2197b004479552c4507e936358b6a4ca6a6 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 26 Feb 2024 14:31:16 +0100 Subject: stream_read_chunk: Set kpred to nominal wavelength This avoids having to awkwardly pass the wavelength separately, e.g. to the polarisation correction. --- libcrystfel/src/stream.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libcrystfel/src/stream.c b/libcrystfel/src/stream.c index ffe68162..f1f2173c 100644 --- a/libcrystfel/src/stream.c +++ b/libcrystfel/src/stream.c @@ -199,7 +199,7 @@ static int write_peaks(const struct image *image, } -static RefList *read_stream_reflections_2_3(Stream *st) +static RefList *read_stream_reflections_2_3(Stream *st, double kpred) { char *rval = NULL; int first = 1; @@ -267,6 +267,7 @@ static RefList *read_stream_reflections_2_3(Stream *st) set_mean_bg(refl, bg); set_redundancy(refl, 1); set_symmetric_indices(refl, h, k, l); + set_kpred(refl, kpred); } } while ( rval != NULL ); @@ -657,7 +658,7 @@ static void read_crystal(Stream *st, struct image *image, if ( (strcmp(line, STREAM_REFLECTION_START_MARKER) == 0) && (srf & STREAM_REFLECTIONS) ) { - reflist = read_stream_reflections_2_3(st); + reflist = read_stream_reflections_2_3(st, 1.0/image->lambda); if ( reflist == NULL ) { ERROR("Failed while reading reflections\n"); ERROR("Filename = %s\n", image->filename); -- cgit v1.2.3 From b3b0a89f49a787bfe3ce5f9632832bc756cb2039 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 26 Feb 2024 15:34:11 +0100 Subject: Julia: UnitCell: Add accessors for cell parameters and basis vectors --- julia/CrystFEL/src/cell.jl | 90 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 6 deletions(-) diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl index bce39c50..a18810bb 100644 --- a/julia/CrystFEL/src/cell.jl +++ b/julia/CrystFEL/src/cell.jl @@ -291,17 +291,95 @@ function getcellparams(cell) end +# Returns the direct-space basis vectors as a Julia matrix +# See matrix-notation.pdf for information. This returns an "M-matrix". +function directcartesianmatrix(uc) + ax = Ref{Cdouble}(0) + ay = Ref{Cdouble}(0) + az = Ref{Cdouble}(0) + bx = Ref{Cdouble}(0) + by = Ref{Cdouble}(0) + bz = Ref{Cdouble}(0) + cx = Ref{Cdouble}(0) + cy = Ref{Cdouble}(0) + cz = Ref{Cdouble}(0) + out = @ccall libcrystfel.cell_get_cartesian(uc.internalptr::Ptr{InternalUnitCell}, + ax::Ref{Cdouble}, ay::Ref{Cdouble}, az::Ref{Cdouble}, + bx::Ref{Cdouble}, by::Ref{Cdouble}, bz::Ref{Cdouble}, + cx::Ref{Cdouble}, cy::Ref{Cdouble}, cz::Ref{Cdouble})::Cint + if out != 0 + throw(ErrorException("Failed to convert cell parameters")) + end + return [ax[] bx[] cx[]; ay[] by[] cy[]; az[] bz[] cz[]] +end + + +# Returns the reciprocal-space basis vectors as a Julia matrix +# See matrix-notation.pdf for information. This returns an "R-matrix". +function reciprocalcartesianmatrix(uc) + ax = Ref{Cdouble}(0) + ay = Ref{Cdouble}(0) + az = Ref{Cdouble}(0) + bx = Ref{Cdouble}(0) + by = Ref{Cdouble}(0) + bz = Ref{Cdouble}(0) + cx = Ref{Cdouble}(0) + cy = Ref{Cdouble}(0) + cz = Ref{Cdouble}(0) + out = @ccall libcrystfel.cell_get_reciprocal(uc.internalptr::Ptr{InternalUnitCell}, + ax::Ref{Cdouble}, ay::Ref{Cdouble}, az::Ref{Cdouble}, + bx::Ref{Cdouble}, by::Ref{Cdouble}, bz::Ref{Cdouble}, + cx::Ref{Cdouble}, cy::Ref{Cdouble}, cz::Ref{Cdouble})::Cint + if out != 0 + throw(ErrorException("Failed to convert cell parameters")) + end + return [ax[] ay[] az[]; bx[] by[] bz[]; cx[] cy[] cz[]] +end + + +function Base.propertynames(uc::UnitCell; private=false) + (:a, :b, :c, :α, :β, :γ, :latticetype, :cellparams, + :directcartesian, :reciprocalcartesian, + :internalptr) +end + + +function Base.getproperty(uc::UnitCell, name::Symbol) + if name === :internalptr + getfield(uc, :internalptr) + elseif name === :cellparams + return getcellparams(uc) + elseif name === :latticetype + return getlatticetype(uc) + elseif name === :a + return getcellparams(uc).a + elseif name === :b + return getcellparams(uc).b + elseif name === :c + return getcellparams(uc).c + elseif name === :α + return getcellparams(uc).α + elseif name === :β + return getcellparams(uc).β + elseif name === :γ + return getcellparams(uc).γ + elseif name === :directcartesian + return directcartesianmatrix(uc) + elseif name === :reciprocalcartesian + return reciprocalcartesianmatrix(uc) + end +end + + function Base.show(io::IO, uc::UnitCell) write(io, "UnitCell(") - lt,cen,ua = getlatticetype(uc) + lt,cen,ua = uc.latticetype show(io, lt); write(io, ", ") show(io, cen); write(io, ", ") show(io, ua); write(io, ",\n ") - let cp = getcellparams(uc) - @printf(io, "%.3f Å, %.3f Å, %.3f Å, %.3f°, %.3f°, %.3f°", - cp.a*1e10, cp.b*1e10, cp.c*1e10, - rad2deg(cp.α), rad2deg(cp.β), rad2deg(cp.γ)) - end + @printf(io, "%.3f Å, %.3f Å, %.3f Å, %.3f°, %.3f°, %.3f°", + uc.a*1e10, uc.b*1e10, uc.c*1e10, + rad2deg(uc.α), rad2deg(uc.β), rad2deg(uc.γ)) write(io, ")") end -- cgit v1.2.3 From 6a05f743abe8ab3091e287e22613adc3955c0897 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 26 Feb 2024 17:00:46 +0100 Subject: Julia: RefList: Return indices as vectors, not tuples We're going to be doing a lot of linear algebra with these numbers, so this makes more sense. --- julia/CrystFEL/src/reflists.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl index d922bdae..ba7311da 100644 --- a/julia/CrystFEL/src/reflists.jl +++ b/julia/CrystFEL/src/reflists.jl @@ -230,7 +230,7 @@ function indices(refl::Reflection) ccall((:get_indices, libcrystfel), Cint, (Ptr{InternalReflection},Ref{Cint},Ref{Cint},Ref{Cint}), refl.internalptr, h, k, l) - (h[], k[], l[]) + [h[], k[], l[]] end @@ -241,7 +241,7 @@ function symmetricindices(refl::Reflection) ccall((:get_symmetric_indices, libcrystfel), Cint, (Ptr{InternalReflection},Ref{Cint},Ref{Cint},Ref{Cint}), refl.internalptr, h, k, l) - (h[], k[], l[]) + [h[], k[], l[]] end -- cgit v1.2.3 From 92e4b1fcfedb9315bdd002fb5258ce67860519ae Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 26 Feb 2024 17:11:56 +0100 Subject: process_hkl.jl: Add polarisation correction --- julia/process_hkl.jl | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/julia/process_hkl.jl b/julia/process_hkl.jl index 1d0bbdea..d2cebc86 100644 --- a/julia/process_hkl.jl +++ b/julia/process_hkl.jl @@ -1,4 +1,5 @@ using CrystFEL +using LinearAlgebra macro addmeasurement(measurement, weight, @@ -26,7 +27,7 @@ function mergereflections(correction, crystalrefls, sym) indices = asymmetricindices(sym, refl.indices) model_version = get!(merged, indices) - @addmeasurement(correction(refl.intensity, cr), 1.0, + @addmeasurement(correction(refl, cr), 1.0, model_version.intensity, model_version.temp1, model_version.temp2) @@ -51,7 +52,28 @@ function mergereflections(correction, crystalrefls, sym) end -let st = Stream("input.stream", "r") - merged = mergereflections((i,cr)->i, allcrystals(st), SymOpList("2/m_uab")) +function anglebetween(v1, v2) + let v1n = norm(v1), v2n = norm(v2) + return 2*atan(norm(v1*v2n - v2*v1n), + norm(v1*v2n + v2*v1n)) + end +end + + +let st = Stream("/home/twhite/experiments/cxidb-193/short.stream", "r"), + merged = mergereflections(allcrystals(st), SymOpList("mmm")) do refl,crystal + + polfrac = 1.0 + polangle = 0.0 + + lp = transpose(crystal.cell.reciprocalcartesian) * refl.symmetricindices + tt = anglebetween([0,0,1], lp+[0,0,refl.kpred]) + phi = atan(lp[2], lp[1]) - polangle + pol = polfrac*(1.0 - cos(phi)*cos(phi)*sin(tt)*sin(tt)) + + (1.0-polfrac)*(1.0 - sin(phi)*sin(phi)*sin(tt)*sin(tt)) + + return refl.intensity / pol + + end savereflist!(merged, "merged.hkl") end -- cgit v1.2.3 From 0ebaf0eb0465be23d8fee4088271cb92154a606d Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 27 Feb 2024 11:35:46 +0100 Subject: Julia: Move merging utils to separate module --- julia/CrystFEL/src/CrystFEL.jl | 4 +++ julia/CrystFEL/src/mergeutils.jl | 57 ++++++++++++++++++++++++++++++++++++++++ julia/process_hkl.jl | 52 ------------------------------------ 3 files changed, 61 insertions(+), 52 deletions(-) create mode 100644 julia/CrystFEL/src/mergeutils.jl diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 5ecfab91..897d2614 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -87,4 +87,8 @@ include("peaksearch.jl") using .PeakSearch export zaefpeaks, peakfinder8, peakfinder9 +include("mergeutils.jl") +using .MergeUtils +export @addmeasurement, cstddev, mergereflections + end # of module diff --git a/julia/CrystFEL/src/mergeutils.jl b/julia/CrystFEL/src/mergeutils.jl new file mode 100644 index 00000000..b75bd2e8 --- /dev/null +++ b/julia/CrystFEL/src/mergeutils.jl @@ -0,0 +1,57 @@ +module MergeUtils + +using ..CrystFEL.RefLists +using ..CrystFEL.Symmetry +export @addmeasurement, cstddev, mergereflections + +macro addmeasurement(measurement, weight, + mean, sumweight, wksp) + return quote + delta = $(esc(measurement)) - $(esc(mean)) + newsumweight = $(esc(sumweight)) + $(esc(weight)) + R = delta * $(esc(weight)) / newsumweight + $(esc(mean)) += R + $(esc(wksp)) += $(esc(sumweight)) * delta * R + $(esc(sumweight)) = newsumweight + end +end + +cstddev(nmeas, work1, work2) = sqrt(work2/work1)/sqrt(nmeas) + + +function mergereflections(correction, crystalrefls, sym) + + merged = RefList{MergedReflection}(sym) + + for (cr,reflections) in crystalrefls + + for refl in reflections + + indices = asymmetricindices(sym, refl.indices) + model_version = get!(merged, indices) + @addmeasurement(correction(refl, cr), 1.0, + model_version.intensity, + model_version.temp1, + model_version.temp2) + model_version.nmeasurements += 1 + + end + end + + for refl in merged + if refl.nmeasurements > 1 + refl.sigintensity = cstddev(refl.nmeasurements, refl.temp1, refl.temp2) + else + # Cannot delete a reflection from a list (especially not + # while iterating), but setting nmeasurements to zero + # prevents it from being written to the output file. + refl.nmeasurements = 0 + end + end + + return merged + +end + + +end # of module diff --git a/julia/process_hkl.jl b/julia/process_hkl.jl index d2cebc86..80b78e52 100644 --- a/julia/process_hkl.jl +++ b/julia/process_hkl.jl @@ -1,57 +1,6 @@ using CrystFEL using LinearAlgebra - -macro addmeasurement(measurement, weight, - mean, sumweight, wksp) - return quote - delta = $(esc(measurement)) - $(esc(mean)) - newsumweight = $(esc(sumweight)) + $(esc(weight)) - R = delta * $(esc(weight)) / newsumweight - $(esc(mean)) += R - $(esc(wksp)) += $(esc(sumweight)) * delta * R - $(esc(sumweight)) = newsumweight - end -end - -cstddev(nmeas, work1, work2) = sqrt(work2/work1)/sqrt(nmeas) - - -function mergereflections(correction, crystalrefls, sym) - - merged = RefList{MergedReflection}(sym) - - for (cr,reflections) in crystalrefls - - for refl in reflections - - indices = asymmetricindices(sym, refl.indices) - model_version = get!(merged, indices) - @addmeasurement(correction(refl, cr), 1.0, - model_version.intensity, - model_version.temp1, - model_version.temp2) - model_version.nmeasurements += 1 - - end - end - - for refl in merged - if refl.nmeasurements > 1 - refl.sigintensity = cstddev(refl.nmeasurements, refl.temp1, refl.temp2) - else - # Cannot delete a reflection from a list (especially not - # while iterating), but setting nmeasurements to zero - # prevents it from being written to the output file. - refl.nmeasurements = 0 - end - end - - return merged - -end - - function anglebetween(v1, v2) let v1n = norm(v1), v2n = norm(v2) return 2*atan(norm(v1*v2n - v2*v1n), @@ -59,7 +8,6 @@ function anglebetween(v1, v2) end end - let st = Stream("/home/twhite/experiments/cxidb-193/short.stream", "r"), merged = mergereflections(allcrystals(st), SymOpList("mmm")) do refl,crystal -- cgit v1.2.3 From da9794d5775ca3af9bde78da830eaba5d71ffe2b Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 27 Feb 2024 11:56:24 +0100 Subject: Julia: Do polarisation correction via CrystFEL function The Julia-native correction was 50% slower. --- julia/CrystFEL/src/mergeutils.jl | 21 +++++++++++++++++++++ julia/process_hkl.jl | 22 +--------------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/julia/CrystFEL/src/mergeutils.jl b/julia/CrystFEL/src/mergeutils.jl index b75bd2e8..701992db 100644 --- a/julia/CrystFEL/src/mergeutils.jl +++ b/julia/CrystFEL/src/mergeutils.jl @@ -1,9 +1,12 @@ module MergeUtils +import ..CrystFEL: libcrystfel using ..CrystFEL.RefLists using ..CrystFEL.Symmetry +import ..CrystFEL.UnitCells: InternalUnitCell export @addmeasurement, cstddev, mergereflections + macro addmeasurement(measurement, weight, mean, sumweight, wksp) return quote @@ -19,12 +22,28 @@ end cstddev(nmeas, work1, work2) = sqrt(work2/work1)/sqrt(nmeas) +struct Polarisation + fraction::Cdouble + angle::Cdouble + disable::Cint +end + +function polarisation_correction!(reflist, cell, polfrac, polangle) + pol = Polarisation(polfrac, rad2deg(polangle), 0) + @ccall libcrystfel.polarisation_correction(reflist.internalptr::Ptr{InternalRefList}, + cell.internalptr::Ptr{InternalUnitCell}, + pol::Ref{Polarisation})::Cvoid +end + + function mergereflections(correction, crystalrefls, sym) merged = RefList{MergedReflection}(sym) for (cr,reflections) in crystalrefls + polarisation_correction!(reflections, cr.cell, 1.0, 0.0) + for refl in reflections indices = asymmetricindices(sym, refl.indices) @@ -53,5 +72,7 @@ function mergereflections(correction, crystalrefls, sym) end +mergereflections(crystalrefls, sym) = mergereflections((refl,cr)->refl.intensity, crystalrefls, sym) + end # of module diff --git a/julia/process_hkl.jl b/julia/process_hkl.jl index 80b78e52..34e6104e 100644 --- a/julia/process_hkl.jl +++ b/julia/process_hkl.jl @@ -1,27 +1,7 @@ using CrystFEL using LinearAlgebra -function anglebetween(v1, v2) - let v1n = norm(v1), v2n = norm(v2) - return 2*atan(norm(v1*v2n - v2*v1n), - norm(v1*v2n + v2*v1n)) - end -end - let st = Stream("/home/twhite/experiments/cxidb-193/short.stream", "r"), - merged = mergereflections(allcrystals(st), SymOpList("mmm")) do refl,crystal - - polfrac = 1.0 - polangle = 0.0 - - lp = transpose(crystal.cell.reciprocalcartesian) * refl.symmetricindices - tt = anglebetween([0,0,1], lp+[0,0,refl.kpred]) - phi = atan(lp[2], lp[1]) - polangle - pol = polfrac*(1.0 - cos(phi)*cos(phi)*sin(tt)*sin(tt)) + - (1.0-polfrac)*(1.0 - sin(phi)*sin(phi)*sin(tt)*sin(tt)) - - return refl.intensity / pol - - end + merged = mergereflections(allcrystals(st), SymOpList("mmm")) savereflist!(merged, "merged.hkl") end -- cgit v1.2.3 From 515bf55242c379f5ba4c0c6d15899e573ea08378 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 27 Feb 2024 17:10:14 +0100 Subject: alignment_test.jl: Break plotting routine into 3 --- julia/alignment-test.jl | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index adaf399e..43a22a23 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -67,26 +67,45 @@ let mille = Mille("mille.dat") end -function plotresiduals(filename) +function ploth(a, n, offs, label) + histogram(map(x->x.residual,filter(x->in(n, keys(x.globalgradients)), a[offs:3:end])), label=label) +end + + +function plotfs(filename) t = loadmille(filename) l = @layout([q0 q1; q2 q3]) a = collect(Iterators.flatten(t)) - function ploth(n, offs, label) - histogram(map(x->x.residual,filter(x->in(n, keys(x.globalgradients)), a[offs:3:end])), label=label) - end - - q0 = ploth(101, 1, "q0") - q1 = ploth(201, 1, "q1") - q2 = ploth(301, 1, "q2") - q3 = ploth(401, 1, "q3") + q0 = ploth(a, 101, 1, "q0") + q1 = ploth(a, 201, 1, "q1") + q2 = ploth(a, 301, 1, "q2") + q3 = ploth(a, 401, 1, "q3") plot(q0, q1, q2, q3, layout=l, plot_title="Fast scan residual") - #q0 = ploth(102, 2, "q0") - #q1 = ploth(202, 2, "q1") - #q2 = ploth(302, 2, "q2") - #q3 = ploth(402, 2, "q3") - #plot(q0, q1, q2, q3, layout=l, plot_title="Slow scan residual", reuse=false) +end + + +function plotss(filename) + t = loadmille(filename) + l = @layout([q0 q1; q2 q3]) + a = collect(Iterators.flatten(t)) + + q0 = ploth(a, 102, 2, "q0") + q1 = ploth(a, 202, 2, "q1") + q2 = ploth(a, 302, 2, "q2") + q3 = ploth(a, 402, 2, "q3") + plot(q0, q1, q2, q3, layout=l, plot_title="Slow scan residual") + +end + + +function plotr(filename) + t = loadmille(filename) + l = @layout([q0 q1; q2 q3]) + a = collect(Iterators.flatten(t)) + meas = histogram(map(x->x.residual, a[3:3:end])) + plot(meas, plot_title="Excitation error residual") end -- cgit v1.2.3 From fef45a2545c76c155f98149a262f671ca411e1b5 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 16 Apr 2024 09:53:20 +0200 Subject: alignment-test.jl: Round peak coordinates to one pixel, to get realistic errors --- julia/alignment-test.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index 43a22a23..e66547be 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -10,7 +10,7 @@ function sketch_pattern(image, cr) for refl in reflist if randn() > 0 let dpos = refl.detectorposition - push!(peaklist, dpos.fs, dpos.ss, dpos.panelnumber, 100.0) + push!(peaklist, round(dpos.fs), round(dpos.ss), dpos.panelnumber, 100.0) end end end -- cgit v1.2.3 From c7efe51eaf6ebc78b3406ca614e56dc08f824d78 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 16 Apr 2024 09:54:58 +0200 Subject: alignment-test.jl: Plot shift/sigma (pull value) --- julia/alignment-test.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl index e66547be..0c64a588 100644 --- a/julia/alignment-test.jl +++ b/julia/alignment-test.jl @@ -68,7 +68,10 @@ end function ploth(a, n, offs, label) - histogram(map(x->x.residual,filter(x->in(n, keys(x.globalgradients)), a[offs:3:end])), label=label) + histogram(map(x->x.residual/x.esd, + filter(x->in(n, keys(x.globalgradients)), + a[offs:3:end])), + label=label) end -- cgit v1.2.3 From 62a2fdee1b7e69a1fe1ecb58e286866c41b6bb81 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 16 Apr 2024 09:55:35 +0200 Subject: Tweak prediction refinement weightings --- libcrystfel/src/crystfel-mille.c | 6 +++--- libcrystfel/src/predict-refine.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libcrystfel/src/crystfel-mille.c b/libcrystfel/src/crystfel-mille.c index 381ee60a..3d02e527 100644 --- a/libcrystfel/src/crystfel-mille.c +++ b/libcrystfel/src/crystfel-mille.c @@ -266,17 +266,17 @@ void write_mille(Mille *mille, int n, UnitCell *cell, mille_add_measurement(mille, nl, local_gradients_fs, j, global_gradients_fs, labels, - fs_dev(&rps[i], image->detgeom), 0.22); + fs_dev(&rps[i], image->detgeom), 0.3); /* Add ss measurement */ mille_add_measurement(mille, nl, local_gradients_ss, j, global_gradients_ss, labels, - ss_dev(&rps[i], image->detgeom), 0.22); + ss_dev(&rps[i], image->detgeom), 0.3); /* Add excitation error "measurement" (local-only) */ mille_add_measurement(mille, nl, local_gradients_r, - 0, NULL, NULL, r_dev(&rps[i]), 1.0); + 0, NULL, NULL, r_dev(&rps[i]), 0.2); } } diff --git a/libcrystfel/src/predict-refine.c b/libcrystfel/src/predict-refine.c index 5fb9b4cc..6da0d3d1 100644 --- a/libcrystfel/src/predict-refine.c +++ b/libcrystfel/src/predict-refine.c @@ -46,7 +46,7 @@ /** \file predict-refine.h */ /* Weighting of excitation error term (m^-1) compared to position term (pixels) */ -#define EXC_WEIGHT (0.5e-7) +#define EXC_WEIGHT (1.0e-7) double r_dev(struct reflpeak *rp) -- cgit v1.2.3