From f1a24d0e4c32735fa016cbb262b61a1cce5960fc Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Thu, 9 Jul 2020 14:38:19 +0200 Subject: unit cell vectors are correct, space group missing --- libcrystfel/src/index.c | 288 ++++++++++-- libcrystfel/src/index.h | 5 +- libcrystfel/src/uthash.h | 1150 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1413 insertions(+), 30 deletions(-) create mode 100755 libcrystfel/src/uthash.h (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index dc689df2..ab451c41 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -60,9 +60,31 @@ #include "xgandalf.h" #include "pinkindexer.h" +#include "uthash.h" + /** \file index.h */ +struct skip_private +{ + char path_to_sol[50]; + float solutions[]; +}; + +struct record_key_t{ //added + char filename[100]; + char event_path[35]; + int event_dim; +}; + +struct record_t{ //added + struct record_key_t key; + int line; + UT_hash_handle hh; +}; + +//declared as global variable +struct record_t *line_hash = NULL; //added struct _indexingprivate { @@ -75,6 +97,24 @@ struct _indexingprivate void **engine_private; }; +void delete_all() { + struct record_t *current_line, *tmp; + + HASH_ITER(hh, line_hash, current_line, tmp) { + HASH_DEL(line_hash, current_line); + free(current_line); + } +} + +void print_struct() { + struct record_t *s; + s = (struct record_t *)malloc(sizeof *s); + memset(s, 0, sizeof *s); + + for(s=line_hash; s != NULL; s=(struct record_t*)(s->hh.next)) { + printf("The line is event_path %s and event_dim %d in file %s \n", s->key.event_path, s->key.event_dim, s->key.filename); + } +} static const char *onoff(int a) { @@ -113,37 +153,225 @@ static void show_indexing_flags(IndexingFlags flags) } -static int debug_index(struct image *image) -{ +void *skip_prepare(char *solution_filename) +{ FILE *fh; - Crystal *cr; - UnitCell *cell; - float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; + int nlines; + int nparams_in_solution; + int nparams_per_line; + int nparams; + char *filename[35]; //??? is that correct + char *event_path[35]; //??? is that correct + int event_dim; + int current_line; + int position_in_current_line; + struct record_t *item; + + //Assembling solution file name from input file name to crystfel + char path_to_sol[50],extension[10]; + strcpy(path_to_sol,"../"); + strcpy(extension,".sol"); + strtok(solution_filename, "."); //Takes the first part of the list name (before the .) + strcat(path_to_sol, strtok(solution_filename, ".") ); //Add .sol at the previously splitted name + strcat(path_to_sol, extension ); + + char cwd[PATH_MAX]; + if (getcwd(cwd, sizeof(cwd)) != NULL) { + //printf("Path where skip_prepare is ran: %s\n", cwd); + } + + fh = fopen(path_to_sol, "r"); - fh = fopen("../../indexing.debug", "r"); if ( fh == NULL ) { - ERROR("indexing.debug not found\n"); + ERROR("indexing.sol not found by skip_prepare\n"); return 0; } - if ( fscanf(fh, "%e %e %e", &asx, &asy, &asz) != 3 ) { - ERROR("Failed to read a* from indexing.debug\n"); - return 0; + nlines = ncrystals_in_sol(path_to_sol); + nparams_per_line = 11; //There are 9 vector component and 2 detector shifts excluding filename and event + nparams_in_solution = nlines*nparams_per_line; + nparams = nlines*(nparams_per_line+3); + + float *params = malloc(nparams_in_solution * sizeof( float)); + + //Reads indexing solutions + int j = 0; //index that follows the solution parameter + for(int i = 0; i < nparams; i++) + { + + current_line = i/(nparams_per_line+3); + + position_in_current_line = (i)%(nparams_per_line+3); + + if (position_in_current_line == 0){ + + if ( fscanf(fh, "%s", filename) != 1 ) { + if (current_line == (nlines-1)){ + break; + } + else{ + printf("Failed to read a filename from indexing.sol with skip_prepare\n"); + return 0; + } + } + } + + if (position_in_current_line == 1){ + + if ( fscanf(fh, "%s", event_path) != 1 ) { + printf("Failed to read an event_path from indexing.sol with skip_prepare\n"); + return 0; + } + } + + if (position_in_current_line == 2){ + if ( fscanf(fh, "%d", &event_dim) != 1 ) { + printf("Failed to read an event from indexing.sol with skip_prepare\n"); + return 0; + } + + //Prepare to add to the hash table once an event is read + item = (struct record_t *)malloc(sizeof *item); + memset(item, 0, sizeof *item); + strcpy(item->key.filename, filename); + strcpy(item->key.event_path, event_path); + item->key.event_dim = event_dim; + item->line=current_line; + + //Verify the uniqueness of the key + struct record_t *uniqueness_test; + HASH_FIND(hh, line_hash, &item->key, sizeof(struct record_key_t), uniqueness_test); /* id already in the hash? */ + if (uniqueness_test==NULL) { + //If not in the table, add + HASH_ADD(hh, line_hash, key, sizeof(struct record_key_t), item); + } + else{ + //If already in the table, break with error + printf("Keys to the data must be unique! Verify the combination filename, event_path, event_dim"); + return 0; + } + + + + } + + if (position_in_current_line > 2){ + if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { + printf("Failed to read a parameter from indexing.sol with skip_prepare\n"); + return 0; + } + j+=1; + } + } + + fclose(fh); + + struct skip_private *dp; + dp = (struct skip_private *) malloc( sizeof(struct skip_private) + nparams * sizeof( float) ); + + if ( dp == NULL ) return NULL; + + memcpy(dp->path_to_sol, path_to_sol, sizeof path_to_sol); + + for (int k = 0; k < nparams; k++) + { + dp->solutions[k] = params[k]; } - if ( fscanf(fh, "%e %e %e", &bsx, &bsy, &bsz) != 3 ) { - ERROR("Failed to read b* from indexing.debug\n"); + + free(params); + + return (void *)dp; +} + +int ncrystals_in_sol(char *path) +{ + FILE *fh; + int count = 0; // Line counter (result) + char c; // To store a character read from file + + fh = fopen(path, "r"); + + if ( fh == NULL ) { + ERROR("%s not found by ncrystals_in_sol\n",path); return 0; } - if ( fscanf(fh, "%e %e %e", &csx, &csy, &csz) != 3 ) { - ERROR("Failed to read c* from indexing.debug\n"); + + for (c = getc(fh); c != EOF; c = getc(fh)) + if (c == '\n') // Increment count if this character is newline + count = count + 1; + + //For the last line, which has no \n at the end + count = count + 1; + + // Close the file + fclose(fh); + + return count; + +} + +//Fonction from pinkindexer.c to update the detector center of individual crystals +//hack for electron crystallography while crystal_set_det_shift is not working approprietly +static void update_detector(struct detector *det, double xoffs, double yoffs) +{ + int i; + + for (i = 0; i < det->n_panels; i++) { + struct panel *p = &det->panels[i]; + p->cnx += xoffs * p->res; + p->cny += yoffs * p->res; + } +} + +static int skip_index(struct image *image, void *mpriv) +{ + Crystal *cr; + UnitCell *cell; + float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz, xshift, yshift; + int serial; + int nparams_per_line; + struct record_t *item, *p; + int line_number; + + struct skip_private *dp = (struct skip_private *)mpriv; + + //Look up the hash table + item = (struct record_t *)malloc(sizeof *item); + memset(item, 0, sizeof *item); + strcpy(item->key.filename, image->filename); + strcpy(item->key.event_path, *image->event->path_entries); + item->key.event_dim = *image->event->dim_entries; + + HASH_FIND(hh, line_hash, &item->key, sizeof(struct record_key_t), p); /* id already in the hash? */ + if (p==NULL) { + printf("Not indexing file %s, event %s %d \n", image->filename, *image->event->path_entries, *image->event->dim_entries); return 0; } + line_number = p->line; + nparams_per_line = 11; + + asx = dp->solutions[(line_number * nparams_per_line) + 0]; + asy = dp->solutions[(line_number * nparams_per_line) + 1]; + asz = dp->solutions[(line_number * nparams_per_line) + 2]; + bsx = dp->solutions[(line_number * nparams_per_line) + 3]; + bsy = dp->solutions[(line_number * nparams_per_line) + 4]; + bsz = dp->solutions[(line_number * nparams_per_line) + 5]; + csx = dp->solutions[(line_number * nparams_per_line) + 6]; + csy = dp->solutions[(line_number * nparams_per_line) + 7]; + csz = dp->solutions[(line_number * nparams_per_line) + 8]; + xshift = dp->solutions[(line_number * nparams_per_line) + 9]; + yshift = dp->solutions[(line_number * nparams_per_line) + 10]; + cr = crystal_new(); cell = cell_new(); - cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); + cell_set_reciprocal(cell, asx * 1e9, asy * 1e9, asz* 1e9, bsx * 1e9, bsy * 1e9, bsz * 1e9, csx * 1e9, csy * 1e9, csz* 1e9); + crystal_set_cell(cr, cell); + crystal_set_det_shift(cr, xshift * 1e-3, yshift * 1e-3); + update_detector(image->det, xshift * 1e-3, yshift * 1e-3); image_add_crystal(image, cr); + return 1; } @@ -201,8 +429,8 @@ static char *base_indexer_str(IndexingMethod indm) strcpy(str, "simulation"); break; - case INDEXING_DEBUG : - strcpy(str, "debug"); + case INDEXING_FILE : + strcpy(str, "file"); break; default : @@ -238,7 +466,8 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, struct xgandalf_options *xgandalf_opts, struct pinkIndexer_options* pinkIndexer_opts, struct felix_options *felix_opts, - struct taketwo_options *taketwo_opts) + struct taketwo_options *taketwo_opts, + char *filename) { char *str; IndexingMethod in = *m; @@ -266,8 +495,8 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, priv = xds_prepare(m, cell); break; - case INDEXING_DEBUG : - priv = (IndexingPrivate *)strdup("Hello!"); + case INDEXING_FILE : + priv = skip_prepare(filename); break; case INDEXING_FELIX : @@ -320,7 +549,8 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell, struct taketwo_options *ttopts, struct xgandalf_options *xgandalf_opts, struct pinkIndexer_options *pinkIndexer_opts, - struct felix_options *felix_opts) + struct felix_options *felix_opts, + char *filename) { int i, n; char **method_strings; @@ -417,7 +647,8 @@ IndexingPrivate *setup_indexing(const char *method_list, UnitCell *cell, xgandalf_opts, pinkIndexer_opts, felix_opts, - ttopts); + ttopts, + filename); if ( ipriv->engine_private[i] == NULL ) return NULL; @@ -518,8 +749,9 @@ void cleanup_indexing(IndexingPrivate *ipriv) felix_cleanup(ipriv->engine_private[n]); break; - case INDEXING_DEBUG : + case INDEXING_FILE : free(ipriv->engine_private[n]); + delete_all(); break; case INDEXING_TAKETWO : @@ -645,9 +877,9 @@ static int try_indexer(struct image *image, IndexingMethod indm, r = run_xds(image, mpriv); break; - case INDEXING_DEBUG : - set_last_task(last_task, "indexing:debug"); - r = debug_index(image); + case INDEXING_FILE : + set_last_task(last_task, "indexing:file"); + r = skip_index(image,mpriv); break; case INDEXING_FELIX : @@ -1080,9 +1312,9 @@ IndexingMethod get_indm_from_string_2(const char *str, int *err) method = INDEXING_SIMULATION; return method; - } else if ( strcmp(bits[i], "debug") == 0) { + } else if ( strcmp(bits[i], "file") == 0) { if ( have_method ) return warn_method(str); - method = INDEXING_DEBUG; + method = INDEXING_FILE; return method; } else if ( strcmp(bits[i], "latt") == 0) { diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h index 0c899199..bd5be68e 100644 --- a/libcrystfel/src/index.h +++ b/libcrystfel/src/index.h @@ -77,7 +77,7 @@ typedef enum { INDEXING_FELIX = 4, /**< Invoke Felix program */ INDEXING_XDS = 5, /**< Invoke XDS program (NB not nXDS) */ INDEXING_SIMULATION = 6, /**< Dummy value for simulated data */ - INDEXING_DEBUG = 7, /**< Results injector for debugging */ + INDEXING_FILE = 7, /**< Results injector for debugging */ INDEXING_ASDF = 8, /**< Use built-in ASDF algorithm */ INDEXING_TAKETWO = 9, /**< Use built-in TakeTwo algorithm */ INDEXING_XGANDALF = 10, /**< Use XGANDALF (via optional library) */ @@ -159,7 +159,8 @@ extern IndexingPrivate *setup_indexing(const char *methods, UnitCell *cell, struct taketwo_options *ttopts, struct xgandalf_options *xgandalf_opts, struct pinkIndexer_options *pinkIndexer_opts, - struct felix_options *felix_opts); + struct felix_options *felix_opts, + char *filename); extern const IndexingMethod *indexing_methods(IndexingPrivate *p, int *n); diff --git a/libcrystfel/src/uthash.h b/libcrystfel/src/uthash.h new file mode 100755 index 00000000..5e5866a3 --- /dev/null +++ b/libcrystfel/src/uthash.h @@ -0,0 +1,1150 @@ +/* +Copyright (c) 2003-2018, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.1.0 + +#include /* memcmp, memset, strlen */ +#include /* ptrdiff_t */ +#include /* exit */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE(x) +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif + +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_bzero +#define uthash_bzero(a,n) memset(a,'\0',n) +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif + +#ifdef uthash_memcmp +/* This warning will not catch programs that define uthash_memcmp AFTER including uthash.h. */ +#warning "uthash_memcmp is deprecated; please use HASH_KEYCMP instead" +#else +#define uthash_memcmp(a,b,n) memcmp(a,b,n) +#endif + +#ifndef HASH_KEYCMP +#define HASH_KEYCMP(a,b,n) uthash_memcmp(a,b,n) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +#ifndef HASH_NONFATAL_OOM +#define HASH_NONFATAL_OOM 0 +#endif + +#if HASH_NONFATAL_OOM +/* malloc failures can be recovered from */ + +#ifndef uthash_nonfatal_oom +#define uthash_nonfatal_oom(obj) do {} while (0) /* non-fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0) +#define IF_HASH_NONFATAL_OOM(x) x + +#else +/* malloc failures result in lost memory, hash tables are unusable */ + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") +#define IF_HASH_NONFATAL_OOM(x) + +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle*)(void*)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_item = (itemptrhh); \ + unsigned _hd_bkt; \ + HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + (head)->hh.tbl->buckets[_hd_bkt].count++; \ + _hd_hh_item->hh_next = NULL; \ + _hd_hh_item->hh_prev = NULL; \ +} while (0) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FCN(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl,oomed) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!(tbl)->bloom_bv) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ + } \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl,oomed) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head,oomed) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ + if (!(head)->hh.tbl) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ + if (!(head)->hh.tbl->buckets) { \ + HASH_RECORD_OOM(oomed); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } else { \ + uthash_bzero((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + uthash_free((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } \ + ) \ + } \ + } \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ + break; \ + } \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#if HASH_NONFATAL_OOM + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + if (!(oomed)) { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + if (oomed) { \ + HASH_ROLLBACK_BKT(hh, head, &(add)->hh); \ + HASH_DELETE_HH(hh, head, &(add)->hh); \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } else { \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + } \ + } else { \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } \ +} while (0) + +#else + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ +} while (0) + +#endif + + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ + HASH_DELETE_HH(hh, head, &(delptr)->hh) + +#define HASH_DELETE_HH(hh,head,delptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } else { \ + unsigned _hd_bkt; \ + if (_hd_hh_del == (head)->hh.tbl->tail) { \ + (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ + } \ + if (_hd_hh_del->prev != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ + } else { \ + DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ + } \ + HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh, head, "HASH_DELETE_HH"); \ +} while (0) + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ +do { \ + unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \ + HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \ +} while (0) +#define HASH_ADD_STR(head,strfield,add) \ +do { \ + unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \ +} while (0) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ +do { \ + unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \ +} while (0) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#include /* fprintf, stderr */ +#define HASH_OOPS(...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head,where) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count = 0; \ + char *_prev; \ + for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ + (where), (void*)_thh->hh_prev, (void*)_prev); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ + (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev != (char*)_thh->prev) { \ + HASH_OOPS("%s: invalid prev %p, actual %p\n", \ + (where), (void*)_thh->prev, (void*)_prev); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head,where) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen = (unsigned)keylen; \ + const unsigned char *_hb_key = (const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key = (const unsigned char*)(key); \ + hashv = 0; \ + for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key = (const unsigned char*)(key); \ + (hashv) = 2166136261U; \ + for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,hh,addhh,oomed) \ +do { \ + UT_hash_bucket *_ha_head = &(head); \ + _ha_head->count++; \ + (addhh)->hh_next = _ha_head->hh_head; \ + (addhh)->hh_prev = NULL; \ + if (_ha_head->hh_head != NULL) { \ + _ha_head->hh_head->hh_prev = (addhh); \ + } \ + _ha_head->hh_head = (addhh); \ + if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ + && !(addhh)->tbl->noexpand) { \ + HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + HASH_DEL_IN_BKT(head,addhh); \ + } \ + ) \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(head,delhh) \ +do { \ + UT_hash_bucket *_hd_head = &(head); \ + _hd_head->count--; \ + if (_hd_head->hh_head == (delhh)) { \ + _hd_head->hh_head = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_prev) { \ + (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_next) { \ + (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ + } \ +} while (0) + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(hh,tbl,oomed) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero(_he_new_buckets, \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->ideal_chain_maxlen = \ + ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ + ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + (tbl)->nonideal_items = 0; \ + for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ + _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[_he_bkt]); \ + if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ + (tbl)->nonideal_items++; \ + if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \ + _he_newbkt->expand_mult++; \ + } \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { \ + _he_newbkt->hh_head->hh_prev = _he_thh; \ + } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->num_buckets *= 2U; \ + (tbl)->log2_num_buckets++; \ + (tbl)->buckets = _he_new_buckets; \ + (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ + ((tbl)->ineff_expands+1U) : 0U; \ + if ((tbl)->ineff_expands > 1U) { \ + (tbl)->noexpand = 1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ + } \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ + _hs_psize++; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + if (_hs_q == NULL) { \ + break; \ + } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else if ((cmpfcn( \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ + )) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL) { \ + _hs_tail->next = NULL; \ + } \ + if (_hs_nmerges <= 1U) { \ + _hs_looping = 0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh, head, "HASH_SRT"); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt = NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if ((src) != NULL) { \ + for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \ + _dst_hh = (UT_hash_handle*)(void*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { \ + _last_elt_hh->next = _elt; \ + } \ + if ((dst) == NULL) { \ + DECLTYPE_ASSIGN(dst, _elt); \ + HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + uthash_nonfatal_oom(_elt); \ + (dst) = NULL; \ + continue; \ + } \ + ) \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \ + (dst)->hh_dst.tbl->num_items++; \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh); \ + HASH_DELETE_HH(hh_dst, dst, _dst_hh); \ + _dst_hh->tbl = NULL; \ + uthash_nonfatal_oom(_elt); \ + continue; \ + } \ + ) \ + HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if ((head) != NULL) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + (((head) != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ -- cgit v1.2.3 From f34c46f087108a293d471eec4235b292a13daa69 Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Sun, 19 Jul 2020 21:27:02 +0200 Subject: last minute changes --- libcrystfel/src/index.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index ab451c41..3ac3dad5 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -68,6 +68,7 @@ struct skip_private { char path_to_sol[50]; + UnitCell *cellTemplate; float solutions[]; }; @@ -153,7 +154,7 @@ static void show_indexing_flags(IndexingFlags flags) } -void *skip_prepare(char *solution_filename) +void *skip_prepare(char *solution_filename, UnitCell *cell) { FILE *fh; int nlines; @@ -277,6 +278,9 @@ void *skip_prepare(char *solution_filename) { dp->solutions[k] = params[k]; } + + + dp->cellTemplate = cell; free(params); @@ -366,6 +370,9 @@ static int skip_index(struct image *image, void *mpriv) cr = crystal_new(); cell = cell_new(); cell_set_reciprocal(cell, asx * 1e9, asy * 1e9, asz* 1e9, bsx * 1e9, bsy * 1e9, bsz * 1e9, csx * 1e9, csy * 1e9, csz* 1e9); + cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); + cell_set_centering(cell, cell_get_centering(dp->cellTemplate)); + cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); crystal_set_cell(cr, cell); crystal_set_det_shift(cr, xshift * 1e-3, yshift * 1e-3); @@ -496,7 +503,7 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, break; case INDEXING_FILE : - priv = skip_prepare(filename); + priv = skip_prepare(filename, cell); break; case INDEXING_FELIX : -- cgit v1.2.3 From 0b6ce92886424133a6a61bc0613fe89c2d359fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Bu=CC=88cker?= Date: Wed, 5 Aug 2020 11:18:04 +0200 Subject: adding some versbosity to file indexer --- libcrystfel/src/index.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 3ac3dad5..ddd25a4b 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -184,9 +184,12 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) fh = fopen(path_to_sol, "r"); if ( fh == NULL ) { - ERROR("indexing.sol not found by skip_prepare\n"); + ERROR("%s not found by skip_prepare in %s\n", path_to_sol, cwd); return 0; } + else { + fprintf("Reading solution file %s from %s\n", path_to_sol, cwd); + } nlines = ncrystals_in_sol(path_to_sol); nparams_per_line = 11; //There are 9 vector component and 2 detector shifts excluding filename and event @@ -310,6 +313,8 @@ int ncrystals_in_sol(char *path) // Close the file fclose(fh); + printf("Found indexing file %s containing %d lines. \n", path, count); + return count; } -- cgit v1.2.3 From 8aa94ecb8179de2e38ce2a7f135df1eb97eb0b80 Mon Sep 17 00:00:00 2001 From: Robert Buecker Date: Wed, 5 Aug 2020 12:53:29 +0200 Subject: hotfix for from-file indexer --- libcrystfel/src/index.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index ddd25a4b..1e8820d7 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -160,7 +160,7 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) int nlines; int nparams_in_solution; int nparams_per_line; - int nparams; + int nentries; char *filename[35]; //??? is that correct char *event_path[35]; //??? is that correct int event_dim; @@ -188,19 +188,21 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) return 0; } else { - fprintf("Reading solution file %s from %s\n", path_to_sol, cwd); + STATUS("Found solution file %s at %s\n", path_to_sol, cwd); } nlines = ncrystals_in_sol(path_to_sol); - nparams_per_line = 11; //There are 9 vector component and 2 detector shifts excluding filename and event - nparams_in_solution = nlines*nparams_per_line; - nparams = nlines*(nparams_per_line+3); + nparams_per_line = 11; /* There are 9 vector components and 2 detector shifts */ + nparams_in_solution = nlines*nparams_per_line; /* total crystal parameters in solution file */ + nentries = nlines*(nparams_per_line+3); /* total entries in solution file */ float *params = malloc(nparams_in_solution * sizeof( float)); + STATUS("Parsing solution file containing %d lines...\n", nlines); + //Reads indexing solutions int j = 0; //index that follows the solution parameter - for(int i = 0; i < nparams; i++) + for(int i = 0; i < nentries; i++) { current_line = i/(nparams_per_line+3); @@ -270,15 +272,20 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) fclose(fh); + STATUS("Solution file parsing done. Have %d parameters and %d total entries.\n", nparams_in_solution, nentries) + struct skip_private *dp; - dp = (struct skip_private *) malloc( sizeof(struct skip_private) + nparams * sizeof( float) ); + dp = (struct skip_private *) malloc( sizeof(struct skip_private) + nentries * sizeof( float) ); if ( dp == NULL ) return NULL; memcpy(dp->path_to_sol, path_to_sol, sizeof path_to_sol); - for (int k = 0; k < nparams; k++) + for (int k = 0; k < nparams_in_solution; k++) { + if ( (k % 1000) == 0 ){ + STATUS("Read %d parameters.\n", k); + } dp->solutions[k] = params[k]; } @@ -287,6 +294,8 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) free(params); + STATUS("Solution lookup table initialized!\n"); + return (void *)dp; } @@ -313,7 +322,7 @@ int ncrystals_in_sol(char *path) // Close the file fclose(fh); - printf("Found indexing file %s containing %d lines. \n", path, count); + // STATUS("Found indexing file %s containing %d lines. \n", path, count); return count; -- cgit v1.2.3 From a4b8e131cd253f947148eae96c311edf532e9a37 Mon Sep 17 00:00:00 2001 From: Robert Buecker Date: Thu, 6 Aug 2020 10:52:47 +0200 Subject: changed status messages for file indexer --- libcrystfel/src/index.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 1e8820d7..2b5907ba 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -184,7 +184,7 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) fh = fopen(path_to_sol, "r"); if ( fh == NULL ) { - ERROR("%s not found by skip_prepare in %s\n", path_to_sol, cwd); + ERROR("%s not found by skip_prepare in %s\n", path_to_sol, cwd); return 0; } else { @@ -283,9 +283,6 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) for (int k = 0; k < nparams_in_solution; k++) { - if ( (k % 1000) == 0 ){ - STATUS("Read %d parameters.\n", k); - } dp->solutions[k] = params[k]; } @@ -362,7 +359,9 @@ static int skip_index(struct image *image, void *mpriv) HASH_FIND(hh, line_hash, &item->key, sizeof(struct record_key_t), p); /* id already in the hash? */ if (p==NULL) { - printf("Not indexing file %s, event %s %d \n", image->filename, *image->event->path_entries, *image->event->dim_entries); + /* + STATUS("Not indexing file %s, event %s %d \n", image->filename, *image->event->path_entries, *image->event->dim_entries); + */ return 0; } -- cgit v1.2.3 From 3926cfee958f2b3687997f22881c6d2593bbd3b7 Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Mon, 14 Sep 2020 23:58:00 -0400 Subject: Removed global variable, include profile_radius and diff_limit in sol file, cleaned up warning messages, not working yet for multi-crystals --- libcrystfel/src/index.c | 265 ++++++++++++++++++++++++++---------------------- 1 file changed, 145 insertions(+), 120 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 2b5907ba..0150787a 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "image.h" #include "utils.h" @@ -65,28 +66,28 @@ /** \file index.h */ +#define NPARAMS_PER_LINE 13 // There are 9 vector components, 2 detector shifts, 1 profile radius, 1 resolution limit +#define NKEYS_PER_LINE 4 // The keys are the filename, event path, event dim and crystal number + struct skip_private { - char path_to_sol[50]; - UnitCell *cellTemplate; - float solutions[]; + UnitCell *cellTemplate; + struct record_t *sol_hash; }; -struct record_key_t{ //added +struct record_key_t{ //Hash table keys char filename[100]; - char event_path[35]; + char event_path[100]; int event_dim; + int crystal_number; }; -struct record_t{ //added +struct record_t{ //Hash table struct record_key_t key; - int line; + float solution[NPARAMS_PER_LINE]; UT_hash_handle hh; }; -//declared as global variable -struct record_t *line_hash = NULL; //added - struct _indexingprivate { IndexingFlags flags; @@ -98,22 +99,24 @@ struct _indexingprivate void **engine_private; }; -void delete_all() { - struct record_t *current_line, *tmp; +void print_struct(struct record_t *sol_hash) { + struct record_t *s; + s = (struct record_t *)malloc(sizeof *s); + memset(s, 0, sizeof *s); - HASH_ITER(hh, line_hash, current_line, tmp) { - HASH_DEL(line_hash, current_line); - free(current_line); - } + for(s=sol_hash; s != NULL; s=(struct record_t*)(s->hh.next)) { + printf("This entry corresponds to event %s//%d and crystal_number %d in file %s \n", s->key.event_path, s->key.event_dim, s->key.crystal_number, s->key.filename); + } } -void print_struct() { +void full_print_struct(struct record_t *sol_hash) { struct record_t *s; s = (struct record_t *)malloc(sizeof *s); memset(s, 0, sizeof *s); - for(s=line_hash; s != NULL; s=(struct record_t*)(s->hh.next)) { - printf("The line is event_path %s and event_dim %d in file %s \n", s->key.event_path, s->key.event_dim, s->key.filename); + for(s=sol_hash; s != NULL; s=(struct record_t*)(s->hh.next)) { + printf("This entry corresponds to event %s//%d and crystal_number %d in file %s \n", s->key.event_path, s->key.event_dim, s->key.crystal_number, s->key.filename); + printf("The solution parameters are %e %e %e %e %e %e %e %e %e %e %e %e %e \n", s->solution[0], s->solution[1], s->solution[2], s->solution[3], s->solution[4], s->solution[5], s->solution[6], s->solution[7], s->solution[8], s->solution[9], s->solution[10], s->solution[11], s->solution[12]); } } @@ -137,7 +140,6 @@ static void set_last_task(char *lt, const char *task) strcpy(lt, task); } - static void show_indexing_flags(IndexingFlags flags) { STATUS("Indexing parameters:\n"); @@ -153,30 +155,60 @@ static void show_indexing_flags(IndexingFlags flags) onoff(flags & INDEXING_RETRY)); } +int ncrystals_in_sol(char *path) +{ + FILE *fh; + int count = 0; // Line counter (result) + char c; // To store a character read from file + + fh = fopen(path, "r"); + + if ( fh == NULL ) { + ERROR("%s not found by ncrystals_in_sol\n",path); + return 0; + } + + for (c = getc(fh); c != EOF; c = getc(fh)) + if (c == '\n') // Increment count if this character is newline + count = count + 1; + + //For the last line, which has no \n at the end + count = count + 1; + + // Close the file + fclose(fh); + + // STATUS("Found indexing file %s containing %d lines. \n", path, count); + + return count; + +} + void *skip_prepare(char *solution_filename, UnitCell *cell) { FILE *fh; int nlines; int nparams_in_solution; - int nparams_per_line; int nentries; - char *filename[35]; //??? is that correct - char *event_path[35]; //??? is that correct - int event_dim; + char filename[100]; + char event_path[100]; + int event_dim; + int crystal_number; int current_line; int position_in_current_line; - struct record_t *item; + struct record_t *sol_hash = NULL; + struct record_t *item = NULL; + float params[NPARAMS_PER_LINE]; + char path_to_sol[50],extension[10]; + char cwd[PATH_MAX]; //Assembling solution file name from input file name to crystfel - char path_to_sol[50],extension[10]; strcpy(path_to_sol,"../"); strcpy(extension,".sol"); - strtok(solution_filename, "."); //Takes the first part of the list name (before the .) strcat(path_to_sol, strtok(solution_filename, ".") ); //Add .sol at the previously splitted name strcat(path_to_sol, extension ); - char cwd[PATH_MAX]; if (getcwd(cwd, sizeof(cwd)) != NULL) { //printf("Path where skip_prepare is ran: %s\n", cwd); } @@ -192,22 +224,19 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) } nlines = ncrystals_in_sol(path_to_sol); - nparams_per_line = 11; /* There are 9 vector components and 2 detector shifts */ - nparams_in_solution = nlines*nparams_per_line; /* total crystal parameters in solution file */ - nentries = nlines*(nparams_per_line+3); /* total entries in solution file */ + nparams_in_solution = nlines*NPARAMS_PER_LINE; /* total crystal parameters in solution file */ + nentries = nlines*(NPARAMS_PER_LINE+NKEYS_PER_LINE); /* total entries in solution file */ - float *params = malloc(nparams_in_solution * sizeof( float)); - STATUS("Parsing solution file containing %d lines...\n", nlines); //Reads indexing solutions - int j = 0; //index that follows the solution parameter + int j = 0; //index that follows the solution parameter [0,NPARAMS_PER_LINE] for(int i = 0; i < nentries; i++) { - current_line = i/(nparams_per_line+3); + current_line = i/(NPARAMS_PER_LINE+NKEYS_PER_LINE); - position_in_current_line = (i)%(nparams_per_line+3); + position_in_current_line = (i)%(NPARAMS_PER_LINE+NKEYS_PER_LINE); if (position_in_current_line == 0){ @@ -225,106 +254,84 @@ void *skip_prepare(char *solution_filename, UnitCell *cell) if (position_in_current_line == 1){ if ( fscanf(fh, "%s", event_path) != 1 ) { - printf("Failed to read an event_path from indexing.sol with skip_prepare\n"); + printf("Failed to read an event path from indexing.sol with skip_prepare\n"); return 0; } } - + if (position_in_current_line == 2){ + if ( fscanf(fh, "%d", &event_dim) != 1 ) { - printf("Failed to read an event from indexing.sol with skip_prepare\n"); + printf("Failed to read an event dim from indexing.sol with skip_prepare\n"); + return 0; + } + } + + if (position_in_current_line == 3){ + if ( fscanf(fh, "%d", &crystal_number) != 1 ) { + printf("Failed to read a crystal number from indexing.sol with skip_prepare\n"); + return 0; + } + } + + if (position_in_current_line > 3){ + if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { + printf("Failed to read a parameter from indexing.sol with skip_prepare\n"); return 0; } + j+=1; + + + } + + if (j == (NPARAMS_PER_LINE) ){ - //Prepare to add to the hash table once an event is read + //Prepare to add to the hash table item = (struct record_t *)malloc(sizeof *item); memset(item, 0, sizeof *item); strcpy(item->key.filename, filename); strcpy(item->key.event_path, event_path); item->key.event_dim = event_dim; - item->line=current_line; + item->key.crystal_number = crystal_number; + for (int k = 0; k < NPARAMS_PER_LINE; k++){ + item->solution[k] = params[k]; + } //Verify the uniqueness of the key struct record_t *uniqueness_test; - HASH_FIND(hh, line_hash, &item->key, sizeof(struct record_key_t), uniqueness_test); /* id already in the hash? */ + HASH_FIND(hh, sol_hash, &item->key, sizeof(struct record_key_t), uniqueness_test); // id already in the hash? if (uniqueness_test==NULL) { //If not in the table, add - HASH_ADD(hh, line_hash, key, sizeof(struct record_key_t), item); + HASH_ADD(hh, sol_hash, key, sizeof(struct record_key_t), item); } else{ //If already in the table, break with error - printf("Keys to the data must be unique! Verify the combination filename, event_path, event_dim"); + printf("Keys to the data must be unique! Verify the combination filename, event, crystal_number"); return 0; } + j=0; - - } - - if (position_in_current_line > 2){ - if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { - printf("Failed to read a parameter from indexing.sol with skip_prepare\n"); - return 0; - } - j+=1; } } fclose(fh); - + STATUS("Solution file parsing done. Have %d parameters and %d total entries.\n", nparams_in_solution, nentries) struct skip_private *dp; - dp = (struct skip_private *) malloc( sizeof(struct skip_private) + nentries * sizeof( float) ); + dp = (struct skip_private *) malloc( sizeof(struct skip_private)); if ( dp == NULL ) return NULL; - - memcpy(dp->path_to_sol, path_to_sol, sizeof path_to_sol); - - for (int k = 0; k < nparams_in_solution; k++) - { - dp->solutions[k] = params[k]; - } - dp->cellTemplate = cell; - - free(params); + dp->sol_hash = sol_hash; STATUS("Solution lookup table initialized!\n"); return (void *)dp; } -int ncrystals_in_sol(char *path) -{ - FILE *fh; - int count = 0; // Line counter (result) - char c; // To store a character read from file - - fh = fopen(path, "r"); - - if ( fh == NULL ) { - ERROR("%s not found by ncrystals_in_sol\n",path); - return 0; - } - - for (c = getc(fh); c != EOF; c = getc(fh)) - if (c == '\n') // Increment count if this character is newline - count = count + 1; - - //For the last line, which has no \n at the end - count = count + 1; - - // Close the file - fclose(fh); - - // STATUS("Found indexing file %s containing %d lines. \n", path, count); - - return count; - -} - //Fonction from pinkindexer.c to update the detector center of individual crystals //hack for electron crystallography while crystal_set_det_shift is not working approprietly static void update_detector(struct detector *det, double xoffs, double yoffs) @@ -338,15 +345,13 @@ static void update_detector(struct detector *det, double xoffs, double yoffs) } } -static int skip_index(struct image *image, void *mpriv) +static int skip_index(struct image *image, void *mpriv, int crystal_number) { Crystal *cr; UnitCell *cell; - float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz, xshift, yshift; - int serial; - int nparams_per_line; - struct record_t *item, *p; - int line_number; + float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz, xshift, yshift, profile_radius, resolution_limit; + struct record_t *item, *p, *pprime; + float *sol; struct skip_private *dp = (struct skip_private *)mpriv; @@ -356,29 +361,29 @@ static int skip_index(struct image *image, void *mpriv) strcpy(item->key.filename, image->filename); strcpy(item->key.event_path, *image->event->path_entries); item->key.event_dim = *image->event->dim_entries; + item->key.crystal_number = crystal_number; - HASH_FIND(hh, line_hash, &item->key, sizeof(struct record_key_t), p); /* id already in the hash? */ + HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct record_key_t), p); //id already in the hash? if (p==NULL) { - /* - STATUS("Not indexing file %s, event %s %d \n", image->filename, *image->event->path_entries, *image->event->dim_entries); - */ + //STATUS("Not indexing file %s, event %s %d \n", image->filename, *image->event->path_entries, *image->event->dim_entries); return 0; } - line_number = p->line; - nparams_per_line = 11; - - asx = dp->solutions[(line_number * nparams_per_line) + 0]; - asy = dp->solutions[(line_number * nparams_per_line) + 1]; - asz = dp->solutions[(line_number * nparams_per_line) + 2]; - bsx = dp->solutions[(line_number * nparams_per_line) + 3]; - bsy = dp->solutions[(line_number * nparams_per_line) + 4]; - bsz = dp->solutions[(line_number * nparams_per_line) + 5]; - csx = dp->solutions[(line_number * nparams_per_line) + 6]; - csy = dp->solutions[(line_number * nparams_per_line) + 7]; - csz = dp->solutions[(line_number * nparams_per_line) + 8]; - xshift = dp->solutions[(line_number * nparams_per_line) + 9]; - yshift = dp->solutions[(line_number * nparams_per_line) + 10]; + sol = &(p->solution)[0]; + + asx = sol[0]; + asy = sol[1]; + asz = sol[2]; + bsx = sol[3]; + bsy = sol[4]; + bsz = sol[5]; + csx = sol[6]; + csy = sol[7]; + csz = sol[8]; + xshift = sol[9]; + yshift = sol[10]; + profile_radius = sol[11]; + resolution_limit = sol[12]; cr = crystal_new(); cell = cell_new(); @@ -390,9 +395,29 @@ static int skip_index(struct image *image, void *mpriv) crystal_set_cell(cr, cell); crystal_set_det_shift(cr, xshift * 1e-3, yshift * 1e-3); update_detector(image->det, xshift * 1e-3, yshift * 1e-3); + crystal_set_profile_radius(cr, profile_radius*1e9); + crystal_set_resolution_limit(cr, resolution_limit*1e9); image_add_crystal(image, cr); + //Look for additional crystals + item->key.crystal_number = crystal_number+1; + HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct record_key_t), pprime); //id already in the hash? + if (pprime==NULL) { + + //If no more crystal, done + return 1; + } + else{ + //If more crystals, recursive call for next crystal in line + skip_index(image,mpriv,crystal_number+1); + } + + + dp->sol_hash = NULL; //Clean up local copy of the hash table + + return 1; + } @@ -771,7 +796,6 @@ void cleanup_indexing(IndexingPrivate *ipriv) case INDEXING_FILE : free(ipriv->engine_private[n]); - delete_all(); break; case INDEXING_TAKETWO : @@ -899,7 +923,8 @@ static int try_indexer(struct image *image, IndexingMethod indm, case INDEXING_FILE : set_last_task(last_task, "indexing:file"); - r = skip_index(image,mpriv); + int crystal_number = 0; + r = skip_index(image,mpriv,crystal_number); break; case INDEXING_FELIX : -- cgit v1.2.3 From b11033a649afff30254804d9035ee9ccb67f044d Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Wed, 16 Sep 2020 02:31:58 -0400 Subject: fromfile indexer in a separate file --- libcrystfel/src/fromfile.c | 364 +++++++++++++++++++++++++++++++++++++++++++++ libcrystfel/src/fromfile.h | 73 +++++++++ libcrystfel/src/index.c | 314 +------------------------------------- 3 files changed, 440 insertions(+), 311 deletions(-) create mode 100644 libcrystfel/src/fromfile.c create mode 100644 libcrystfel/src/fromfile.h (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/fromfile.c b/libcrystfel/src/fromfile.c new file mode 100644 index 00000000..8dcb92c1 --- /dev/null +++ b/libcrystfel/src/fromfile.c @@ -0,0 +1,364 @@ +/* + * fromfile.c + * + * Perform indexing from solution file + * + * + * Authors: + * 2020 Pascal Hogan-Lamarre + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see . + * + */ + +#include "image.h" +#include "detector.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "uthash.h" + +/** \file fromfile.h */ + +/* There are 9 vector components, + * 2 detector shifts, 1 profile radius, + * 1 resolution limit */ +#define NPARAMS_PER_LINE 13 +/* The keys are the filename, + * event path, event dim and crystal number */ +#define NKEYS_PER_LINE 4 + +struct fromfile_private +{ + UnitCell *cellTemplate; + struct fromfile_entries *sol_hash; +}; + +struct fromfile_keys +{ + char filename[100]; + char event_path[100]; + int event_dim; + int crystal_number; +}; + +struct fromfile_entries +{ + struct fromfile_keys key; + float solution[NPARAMS_PER_LINE]; + UT_hash_handle hh; +}; + +void print_struct(struct fromfile_entries *sol_hash) +{ + struct fromfile_entries *s; + s = (struct fromfile_entries *)malloc(sizeof *s); + memset(s, 0, sizeof *s); + + for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { + printf("File %s, event %s//%d and crystal_number %d \n", + s->key.filename, s->key.event_path, + s->key.event_dim, s->key.crystal_number); + } +} + +void full_print_struct(struct fromfile_entries *sol_hash) +{ + struct fromfile_entries *s; + s = (struct fromfile_entries *)malloc(sizeof *s); + memset(s, 0, sizeof *s); + + for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { + printf("File %s, event %s//%d and crystal_number %d \n", + s->key.filename, s->key.event_path, + s->key.event_dim, s->key.crystal_number); + + printf("Solution parameters:\n"); + for( int i = 0; i < NPARAMS_PER_LINE; i++ ){ + printf("%e", s->solution[i]); + } + printf("\n"); + } +} + +int ncrystals_in_sol(char *path) +{ + FILE *fh; + int count = 0; /* Line counter (result) */ + char c; /* To store a character read from file */ + + fh = fopen(path, "r"); + + if ( fh == NULL ) { + ERROR("%s not found by ncrystals_in_sol\n",path); + return 0; + } + + for ( c = getc(fh); c != EOF; c = getc(fh) ){ + if ( c == '\n' ){ + count = count + 1; + } + } + + /* For the last line, which has no \n at the end*/ + count = count + 1; + + fclose(fh); + + return count; + +} + +void *fromfile_prepare(char *solution_filename, UnitCell *cell) +{ + FILE *fh; + int nlines; + int nparams_in_solution; + int nentries; + char filename[100]; + char event_path[100]; + int event_dim; + int crystal_number; + int current_line; + int position_in_current_line; + struct fromfile_entries *sol_hash = NULL; + struct fromfile_entries *item = NULL; + float params[NPARAMS_PER_LINE]; + char path_to_sol[50],extension[10]; + char cwd[PATH_MAX]; + + /* Assembling solution file name from input file name*/ + strcpy(path_to_sol, "../"); + strcpy(extension, ".sol"); + strcat(path_to_sol, strtok(solution_filename, ".")); + strcat(path_to_sol, extension); + + if (getcwd(cwd, sizeof(cwd)) != NULL) { + ERROR("Cannot identify current directory\n"); + } + + fh = fopen(path_to_sol, "r"); + + if ( fh == NULL ) { + ERROR("%s not found by fromfile_prepare in %s\n", path_to_sol, cwd); + return 0; + } + else { + STATUS("Found solution file %s at %s\n", path_to_sol, cwd); + } + + nlines = ncrystals_in_sol(path_to_sol); + /* Total crystal parameters in solution file */ + nparams_in_solution = nlines*NPARAMS_PER_LINE; + /* Total entries in solution file */ + nentries = nlines*(NPARAMS_PER_LINE+NKEYS_PER_LINE); + + STATUS("Parsing solution file containing %d lines...\n", nlines); + + /* Reads indexing solutions */ + int j = 0; /* follows the solution parameter [0,NPARAMS_PER_LINE] */ + for(int i = 0; i < nentries; i++) + { + + current_line = i/(NPARAMS_PER_LINE+NKEYS_PER_LINE); + + position_in_current_line = (i)%(NPARAMS_PER_LINE+NKEYS_PER_LINE); + + if ( position_in_current_line == 0 ){ + if ( fscanf(fh, "%s", filename) != 1 ) { + if ( current_line == (nlines-1) ){ + break; + } + else{ + printf("Failed to read a filename\n"); + return 0; + } + } + } + + if ( position_in_current_line == 1 ){ + + if ( fscanf(fh, "%s", event_path) != 1 ) { + printf("Failed to read an event path\n"); + return 0; + } + } + + if ( position_in_current_line == 2 ){ + + if ( fscanf(fh, "%d", &event_dim) != 1 ) { + printf("Failed to read an event dim\n"); + return 0; + } + } + + if ( position_in_current_line == 3 ){ + if ( fscanf(fh, "%d", &crystal_number) != 1 ) { + printf("Failed to read a crystal number\n"); + return 0; + } + } + + if ( position_in_current_line > 3 ){ + if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { + printf("Failed to read a parameter\n"); + return 0; + } + j+=1; + } + + if ( j == (NPARAMS_PER_LINE) ){ + + /* Prepare to add to the hash table */ + item = (struct fromfile_entries *)malloc(sizeof *item); + memset(item, 0, sizeof *item); + strcpy(item->key.filename, filename); + strcpy(item->key.event_path, event_path); + item->key.event_dim = event_dim; + item->key.crystal_number = crystal_number; + for ( int k = 0; k < NPARAMS_PER_LINE; k++){ + item->solution[k] = params[k]; + } + + /* Verify the uniqueness of the key */ + struct fromfile_entries *uniqueness_test; + HASH_FIND(hh, sol_hash, &item->key, + sizeof(struct fromfile_keys), uniqueness_test); + if (uniqueness_test==NULL) { + HASH_ADD(hh, sol_hash, key, sizeof(struct fromfile_keys), item); + } + else{ + printf("Keys must be unique! Verify the combinations"); + return 0; + } + + j=0; + + } + } + + fclose(fh); + + STATUS("Solution parsing done. Have %d parameters and %d total entries.\n", + nparams_in_solution, nentries); + + struct fromfile_private *dp; + dp = (struct fromfile_private *) malloc( sizeof(struct fromfile_private)); + + if ( dp == NULL ){ + return NULL; + } + + dp->cellTemplate = cell; + dp->sol_hash = sol_hash; + + STATUS("Solution lookup table initialized!\n"); + + return (void *)dp; +} + +static void update_detector(struct detector *det, double xoffs, double yoffs) +{ + int i; + + for ( i = 0; i < det->n_panels; i++ ) { + struct panel *p = &det->panels[i]; + p->cnx += xoffs * p->res; + p->cny += yoffs * p->res; + } +} + +int fromfile_index(struct image *image, void *mpriv, int crystal_number) +{ + Crystal *cr; + UnitCell *cell; + float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; + float xshift, yshift, profile_radius, resolution_limit; + struct fromfile_entries *item, *p, *pprime; + float *sol; + + struct fromfile_private *dp = (struct fromfile_private *)mpriv; + + /* Look up the hash table */ + item = (struct fromfile_entries *)malloc(sizeof *item); + memset(item, 0, sizeof *item); + strcpy(item->key.filename, image->filename); + strcpy(item->key.event_path, *image->event->path_entries); + item->key.event_dim = *image->event->dim_entries; + item->key.crystal_number = crystal_number; + + /* key already in the hash? */ + HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), p); + if ( p == NULL ) { + return 0; + } + + sol = &(p->solution)[0]; + + asx = sol[0] * 1e9; + asy = sol[1] * 1e9; + asz = sol[2] * 1e9; + bsx = sol[3] * 1e9; + bsy = sol[4] * 1e9; + bsz = sol[5] * 1e9; + csx = sol[6] * 1e9; + csy = sol[7] * 1e9; + csz = sol[8] * 1e9; + xshift = sol[9] * 1e-3; + yshift = sol[10] * 1e-3; + profile_radius = sol[11] * 1e9; + resolution_limit = sol[12] * 1e9; + + cr = crystal_new(); + cell = cell_new(); + cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); + cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); + cell_set_centering(cell, cell_get_centering(dp->cellTemplate)); + cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); + + crystal_set_cell(cr, cell); + crystal_set_det_shift(cr, xshift , yshift); + update_detector(image->det, xshift , yshift); + crystal_set_profile_radius(cr, profile_radius); + crystal_set_resolution_limit(cr, resolution_limit); + image_add_crystal(image, cr); + + /*Look for additional crystals*/ + item->key.crystal_number = crystal_number+1; + HASH_FIND(hh, dp->sol_hash, &item->key, + sizeof(struct fromfile_keys), pprime); + + if ( pprime == NULL ) { + + /* If no more crystal, done */ + return 1; + } + else{ + /* If more crystals, recursive call for next crystal in line */ + fromfile_index(image, mpriv, crystal_number+1); + } + + dp->sol_hash = NULL; /* Clean up local copy */ + + return 1; + +} \ No newline at end of file diff --git a/libcrystfel/src/fromfile.h b/libcrystfel/src/fromfile.h new file mode 100644 index 00000000..dda976b5 --- /dev/null +++ b/libcrystfel/src/fromfile.h @@ -0,0 +1,73 @@ +/* + * fromfile.h + * + * Perform indexing from solution file + * + * + * Authors: + * 2020 Pascal Hogan-Lamarre + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see . + * + */ + +#ifndef FROMFILE_H +#define FROMFILE_H + + +#include "image.h" +#include "cell.h" +#include "uthash.h" + +/* There are 9 vector components, + * 2 detector shifts, 1 profile radius, + * 1 resolution limit */ +#define NPARAMS_PER_LINE 13 +/* The keys are the filename, + * event path, event dim and crystal number */ +#define NKEYS_PER_LINE 4 + +struct fromfile_private +{ + UnitCell *cellTemplate; + struct fromfile_entries *sol_hash; +}; + +struct fromfile_keys +{ + char filename[100]; + char event_path[100]; + int event_dim; + int crystal_number; +}; + +struct fromfile_entries +{ + struct fromfile_keys key; + float solution[NPARAMS_PER_LINE]; + UT_hash_handle hh; +}; + +extern void print_struct(struct fromfile_entries *sol_hash); + +extern void full_print_struct(struct fromfile_entries *sol_hash); + +extern void *fromfile_prepare(char *solution_filename, UnitCell *cell); + +extern int fromfile_index(struct image *image, void *mpriv, int crystal_number); + + +#endif /* FROMFILE_H */ \ No newline at end of file diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 0150787a..c8e34b23 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -60,34 +60,13 @@ #include "taketwo.h" #include "xgandalf.h" #include "pinkindexer.h" +#include "fromfile.h" #include "uthash.h" /** \file index.h */ -#define NPARAMS_PER_LINE 13 // There are 9 vector components, 2 detector shifts, 1 profile radius, 1 resolution limit -#define NKEYS_PER_LINE 4 // The keys are the filename, event path, event dim and crystal number - -struct skip_private -{ - UnitCell *cellTemplate; - struct record_t *sol_hash; -}; - -struct record_key_t{ //Hash table keys - char filename[100]; - char event_path[100]; - int event_dim; - int crystal_number; -}; - -struct record_t{ //Hash table - struct record_key_t key; - float solution[NPARAMS_PER_LINE]; - UT_hash_handle hh; -}; - struct _indexingprivate { IndexingFlags flags; @@ -99,27 +78,6 @@ struct _indexingprivate void **engine_private; }; -void print_struct(struct record_t *sol_hash) { - struct record_t *s; - s = (struct record_t *)malloc(sizeof *s); - memset(s, 0, sizeof *s); - - for(s=sol_hash; s != NULL; s=(struct record_t*)(s->hh.next)) { - printf("This entry corresponds to event %s//%d and crystal_number %d in file %s \n", s->key.event_path, s->key.event_dim, s->key.crystal_number, s->key.filename); - } -} - -void full_print_struct(struct record_t *sol_hash) { - struct record_t *s; - s = (struct record_t *)malloc(sizeof *s); - memset(s, 0, sizeof *s); - - for(s=sol_hash; s != NULL; s=(struct record_t*)(s->hh.next)) { - printf("This entry corresponds to event %s//%d and crystal_number %d in file %s \n", s->key.event_path, s->key.event_dim, s->key.crystal_number, s->key.filename); - printf("The solution parameters are %e %e %e %e %e %e %e %e %e %e %e %e %e \n", s->solution[0], s->solution[1], s->solution[2], s->solution[3], s->solution[4], s->solution[5], s->solution[6], s->solution[7], s->solution[8], s->solution[9], s->solution[10], s->solution[11], s->solution[12]); - } -} - static const char *onoff(int a) { if ( a ) return "on"; @@ -155,272 +113,6 @@ static void show_indexing_flags(IndexingFlags flags) onoff(flags & INDEXING_RETRY)); } -int ncrystals_in_sol(char *path) -{ - FILE *fh; - int count = 0; // Line counter (result) - char c; // To store a character read from file - - fh = fopen(path, "r"); - - if ( fh == NULL ) { - ERROR("%s not found by ncrystals_in_sol\n",path); - return 0; - } - - for (c = getc(fh); c != EOF; c = getc(fh)) - if (c == '\n') // Increment count if this character is newline - count = count + 1; - - //For the last line, which has no \n at the end - count = count + 1; - - // Close the file - fclose(fh); - - // STATUS("Found indexing file %s containing %d lines. \n", path, count); - - return count; - -} - - -void *skip_prepare(char *solution_filename, UnitCell *cell) -{ - FILE *fh; - int nlines; - int nparams_in_solution; - int nentries; - char filename[100]; - char event_path[100]; - int event_dim; - int crystal_number; - int current_line; - int position_in_current_line; - struct record_t *sol_hash = NULL; - struct record_t *item = NULL; - float params[NPARAMS_PER_LINE]; - char path_to_sol[50],extension[10]; - char cwd[PATH_MAX]; - - //Assembling solution file name from input file name to crystfel - strcpy(path_to_sol,"../"); - strcpy(extension,".sol"); - strcat(path_to_sol, strtok(solution_filename, ".") ); //Add .sol at the previously splitted name - strcat(path_to_sol, extension ); - - if (getcwd(cwd, sizeof(cwd)) != NULL) { - //printf("Path where skip_prepare is ran: %s\n", cwd); - } - - fh = fopen(path_to_sol, "r"); - - if ( fh == NULL ) { - ERROR("%s not found by skip_prepare in %s\n", path_to_sol, cwd); - return 0; - } - else { - STATUS("Found solution file %s at %s\n", path_to_sol, cwd); - } - - nlines = ncrystals_in_sol(path_to_sol); - nparams_in_solution = nlines*NPARAMS_PER_LINE; /* total crystal parameters in solution file */ - nentries = nlines*(NPARAMS_PER_LINE+NKEYS_PER_LINE); /* total entries in solution file */ - - STATUS("Parsing solution file containing %d lines...\n", nlines); - - //Reads indexing solutions - int j = 0; //index that follows the solution parameter [0,NPARAMS_PER_LINE] - for(int i = 0; i < nentries; i++) - { - - current_line = i/(NPARAMS_PER_LINE+NKEYS_PER_LINE); - - position_in_current_line = (i)%(NPARAMS_PER_LINE+NKEYS_PER_LINE); - - if (position_in_current_line == 0){ - - if ( fscanf(fh, "%s", filename) != 1 ) { - if (current_line == (nlines-1)){ - break; - } - else{ - printf("Failed to read a filename from indexing.sol with skip_prepare\n"); - return 0; - } - } - } - - if (position_in_current_line == 1){ - - if ( fscanf(fh, "%s", event_path) != 1 ) { - printf("Failed to read an event path from indexing.sol with skip_prepare\n"); - return 0; - } - } - - if (position_in_current_line == 2){ - - if ( fscanf(fh, "%d", &event_dim) != 1 ) { - printf("Failed to read an event dim from indexing.sol with skip_prepare\n"); - return 0; - } - } - - if (position_in_current_line == 3){ - if ( fscanf(fh, "%d", &crystal_number) != 1 ) { - printf("Failed to read a crystal number from indexing.sol with skip_prepare\n"); - return 0; - } - } - - if (position_in_current_line > 3){ - if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { - printf("Failed to read a parameter from indexing.sol with skip_prepare\n"); - return 0; - } - j+=1; - - - } - - if (j == (NPARAMS_PER_LINE) ){ - - //Prepare to add to the hash table - item = (struct record_t *)malloc(sizeof *item); - memset(item, 0, sizeof *item); - strcpy(item->key.filename, filename); - strcpy(item->key.event_path, event_path); - item->key.event_dim = event_dim; - item->key.crystal_number = crystal_number; - for (int k = 0; k < NPARAMS_PER_LINE; k++){ - item->solution[k] = params[k]; - } - - //Verify the uniqueness of the key - struct record_t *uniqueness_test; - HASH_FIND(hh, sol_hash, &item->key, sizeof(struct record_key_t), uniqueness_test); // id already in the hash? - if (uniqueness_test==NULL) { - //If not in the table, add - HASH_ADD(hh, sol_hash, key, sizeof(struct record_key_t), item); - } - else{ - //If already in the table, break with error - printf("Keys to the data must be unique! Verify the combination filename, event, crystal_number"); - return 0; - } - - j=0; - - } - } - - fclose(fh); - - STATUS("Solution file parsing done. Have %d parameters and %d total entries.\n", nparams_in_solution, nentries) - - struct skip_private *dp; - dp = (struct skip_private *) malloc( sizeof(struct skip_private)); - - if ( dp == NULL ) return NULL; - - dp->cellTemplate = cell; - dp->sol_hash = sol_hash; - - STATUS("Solution lookup table initialized!\n"); - - return (void *)dp; -} - -//Fonction from pinkindexer.c to update the detector center of individual crystals -//hack for electron crystallography while crystal_set_det_shift is not working approprietly -static void update_detector(struct detector *det, double xoffs, double yoffs) -{ - int i; - - for (i = 0; i < det->n_panels; i++) { - struct panel *p = &det->panels[i]; - p->cnx += xoffs * p->res; - p->cny += yoffs * p->res; - } -} - -static int skip_index(struct image *image, void *mpriv, int crystal_number) -{ - Crystal *cr; - UnitCell *cell; - float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz, xshift, yshift, profile_radius, resolution_limit; - struct record_t *item, *p, *pprime; - float *sol; - - struct skip_private *dp = (struct skip_private *)mpriv; - - //Look up the hash table - item = (struct record_t *)malloc(sizeof *item); - memset(item, 0, sizeof *item); - strcpy(item->key.filename, image->filename); - strcpy(item->key.event_path, *image->event->path_entries); - item->key.event_dim = *image->event->dim_entries; - item->key.crystal_number = crystal_number; - - HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct record_key_t), p); //id already in the hash? - if (p==NULL) { - //STATUS("Not indexing file %s, event %s %d \n", image->filename, *image->event->path_entries, *image->event->dim_entries); - return 0; - } - - sol = &(p->solution)[0]; - - asx = sol[0]; - asy = sol[1]; - asz = sol[2]; - bsx = sol[3]; - bsy = sol[4]; - bsz = sol[5]; - csx = sol[6]; - csy = sol[7]; - csz = sol[8]; - xshift = sol[9]; - yshift = sol[10]; - profile_radius = sol[11]; - resolution_limit = sol[12]; - - cr = crystal_new(); - cell = cell_new(); - cell_set_reciprocal(cell, asx * 1e9, asy * 1e9, asz* 1e9, bsx * 1e9, bsy * 1e9, bsz * 1e9, csx * 1e9, csy * 1e9, csz* 1e9); - cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); - cell_set_centering(cell, cell_get_centering(dp->cellTemplate)); - cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); - - crystal_set_cell(cr, cell); - crystal_set_det_shift(cr, xshift * 1e-3, yshift * 1e-3); - update_detector(image->det, xshift * 1e-3, yshift * 1e-3); - crystal_set_profile_radius(cr, profile_radius*1e9); - crystal_set_resolution_limit(cr, resolution_limit*1e9); - image_add_crystal(image, cr); - - //Look for additional crystals - item->key.crystal_number = crystal_number+1; - HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct record_key_t), pprime); //id already in the hash? - if (pprime==NULL) { - - //If no more crystal, done - return 1; - } - else{ - //If more crystals, recursive call for next crystal in line - skip_index(image,mpriv,crystal_number+1); - } - - - dp->sol_hash = NULL; //Clean up local copy of the hash table - - - return 1; - -} - - static char *base_indexer_str(IndexingMethod indm) { char *str; @@ -541,7 +233,7 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, break; case INDEXING_FILE : - priv = skip_prepare(filename, cell); + priv = fromfile_prepare(filename, cell); break; case INDEXING_FELIX : @@ -924,7 +616,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, case INDEXING_FILE : set_last_task(last_task, "indexing:file"); int crystal_number = 0; - r = skip_index(image,mpriv,crystal_number); + r = fromfile_index(image, mpriv, crystal_number); break; case INDEXING_FELIX : -- cgit v1.2.3 From 689d86d0937332aa8577329d007b0dd31a2b73c4 Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Wed, 16 Sep 2020 02:45:55 -0400 Subject: cleaning, remove double statements --- libcrystfel/src/fromfile.c | 21 ++++++++++----------- libcrystfel/src/fromfile.h | 32 +++----------------------------- 2 files changed, 13 insertions(+), 40 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/fromfile.c b/libcrystfel/src/fromfile.c index 8dcb92c1..eff997b5 100644 --- a/libcrystfel/src/fromfile.c +++ b/libcrystfel/src/fromfile.c @@ -45,13 +45,7 @@ #define NPARAMS_PER_LINE 13 /* The keys are the filename, * event path, event dim and crystal number */ -#define NKEYS_PER_LINE 4 - -struct fromfile_private -{ - UnitCell *cellTemplate; - struct fromfile_entries *sol_hash; -}; +#define NKEYS_PER_LINE 4 struct fromfile_keys { @@ -68,6 +62,12 @@ struct fromfile_entries UT_hash_handle hh; }; +struct fromfile_private +{ + UnitCell *cellTemplate; + struct fromfile_entries *sol_hash; +}; + void print_struct(struct fromfile_entries *sol_hash) { struct fromfile_entries *s; @@ -328,18 +328,18 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) profile_radius = sol[11] * 1e9; resolution_limit = sol[12] * 1e9; - cr = crystal_new(); cell = cell_new(); cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); cell_set_centering(cell, cell_get_centering(dp->cellTemplate)); cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); + cr = crystal_new(); crystal_set_cell(cr, cell); - crystal_set_det_shift(cr, xshift , yshift); - update_detector(image->det, xshift , yshift); crystal_set_profile_radius(cr, profile_radius); crystal_set_resolution_limit(cr, resolution_limit); + crystal_set_det_shift(cr, xshift , yshift); + update_detector(image->det, xshift , yshift); image_add_crystal(image, cr); /*Look for additional crystals*/ @@ -348,7 +348,6 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) sizeof(struct fromfile_keys), pprime); if ( pprime == NULL ) { - /* If no more crystal, done */ return 1; } diff --git a/libcrystfel/src/fromfile.h b/libcrystfel/src/fromfile.h index dda976b5..29d31aee 100644 --- a/libcrystfel/src/fromfile.h +++ b/libcrystfel/src/fromfile.h @@ -27,40 +27,14 @@ #ifndef FROMFILE_H #define FROMFILE_H +struct fromfile_keys; +struct fromfile_entries; +struct fromfile_private; #include "image.h" #include "cell.h" #include "uthash.h" -/* There are 9 vector components, - * 2 detector shifts, 1 profile radius, - * 1 resolution limit */ -#define NPARAMS_PER_LINE 13 -/* The keys are the filename, - * event path, event dim and crystal number */ -#define NKEYS_PER_LINE 4 - -struct fromfile_private -{ - UnitCell *cellTemplate; - struct fromfile_entries *sol_hash; -}; - -struct fromfile_keys -{ - char filename[100]; - char event_path[100]; - int event_dim; - int crystal_number; -}; - -struct fromfile_entries -{ - struct fromfile_keys key; - float solution[NPARAMS_PER_LINE]; - UT_hash_handle hh; -}; - extern void print_struct(struct fromfile_entries *sol_hash); extern void full_print_struct(struct fromfile_entries *sol_hash); -- cgit v1.2.3 From 5963ae8133473b5957f607cbc6fd9a5ccefa34f9 Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Wed, 16 Sep 2020 21:09:40 -0400 Subject: modified the keys to use an event string --- libcrystfel/src/fromfile.c | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/fromfile.c b/libcrystfel/src/fromfile.c index eff997b5..c87d5cbe 100644 --- a/libcrystfel/src/fromfile.c +++ b/libcrystfel/src/fromfile.c @@ -44,14 +44,13 @@ * 1 resolution limit */ #define NPARAMS_PER_LINE 13 /* The keys are the filename, - * event path, event dim and crystal number */ -#define NKEYS_PER_LINE 4 + * event, and crystal number */ +#define NKEYS_PER_LINE 3 struct fromfile_keys { char filename[100]; - char event_path[100]; - int event_dim; + char event[100]; int crystal_number; }; @@ -75,9 +74,9 @@ void print_struct(struct fromfile_entries *sol_hash) memset(s, 0, sizeof *s); for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { - printf("File %s, event %s//%d and crystal_number %d \n", - s->key.filename, s->key.event_path, - s->key.event_dim, s->key.crystal_number); + printf("File %s, event %s, and crystal_number %d \n", + s->key.filename, s->key.event, + s->key.crystal_number); } } @@ -88,9 +87,9 @@ void full_print_struct(struct fromfile_entries *sol_hash) memset(s, 0, sizeof *s); for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { - printf("File %s, event %s//%d and crystal_number %d \n", - s->key.filename, s->key.event_path, - s->key.event_dim, s->key.crystal_number); + printf("File %s, event %s, and crystal_number %d \n", + s->key.filename, s->key.event, + s->key.crystal_number); printf("Solution parameters:\n"); for( int i = 0; i < NPARAMS_PER_LINE; i++ ){ @@ -135,8 +134,7 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) int nparams_in_solution; int nentries; char filename[100]; - char event_path[100]; - int event_dim; + char event[100]; int crystal_number; int current_line; int position_in_current_line; @@ -197,28 +195,20 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) if ( position_in_current_line == 1 ){ - if ( fscanf(fh, "%s", event_path) != 1 ) { - printf("Failed to read an event path\n"); - return 0; - } - } - - if ( position_in_current_line == 2 ){ - - if ( fscanf(fh, "%d", &event_dim) != 1 ) { - printf("Failed to read an event dim\n"); + if ( fscanf(fh, "%s", event) != 1 ) { + printf("Failed to read an event\n"); return 0; } } - if ( position_in_current_line == 3 ){ + if ( position_in_current_line == 2 ){ if ( fscanf(fh, "%d", &crystal_number) != 1 ) { printf("Failed to read a crystal number\n"); return 0; } } - if ( position_in_current_line > 3 ){ + if ( position_in_current_line > 2 ){ if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { printf("Failed to read a parameter\n"); return 0; @@ -232,8 +222,7 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) item = (struct fromfile_entries *)malloc(sizeof *item); memset(item, 0, sizeof *item); strcpy(item->key.filename, filename); - strcpy(item->key.event_path, event_path); - item->key.event_dim = event_dim; + strcpy(item->key.event, event); item->key.crystal_number = crystal_number; for ( int k = 0; k < NPARAMS_PER_LINE; k++){ item->solution[k] = params[k]; @@ -302,8 +291,7 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) item = (struct fromfile_entries *)malloc(sizeof *item); memset(item, 0, sizeof *item); strcpy(item->key.filename, image->filename); - strcpy(item->key.event_path, *image->event->path_entries); - item->key.event_dim = *image->event->dim_entries; + strcpy(item->key.event, get_event_string(image->event)); item->key.crystal_number = crystal_number; /* key already in the hash? */ -- cgit v1.2.3 From c97685fbeca127373ffb0a6cc1f2222e12a91f1e Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Wed, 16 Sep 2020 22:35:42 -0400 Subject: if-conditions that prevent modification of the profile_radius read from file --- libcrystfel/src/index.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index c8e34b23..e0e8ff05 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -664,7 +664,9 @@ static int try_indexer(struct image *image, IndexingMethod indm, Crystal *cr = image->crystals[this_crystal]; crystal_set_image(cr, image); - crystal_set_profile_radius(cr, 0.02e9); + if ( indm != INDEXING_FILE){ + crystal_set_profile_radius(cr, 0.02e9); + } crystal_set_mosaicity(cr, 0.0); /* Pre-refinement unit cell check if requested */ -- cgit v1.2.3 From 5c50243916af143a0d7c10792eacdfb97608a107 Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Wed, 16 Sep 2020 22:45:56 -0400 Subject: if-conditions to prevent modifying the resolution limit value read in the solution file --- libcrystfel/src/integration.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/integration.c b/libcrystfel/src/integration.c index 3d8258c1..8a3c581e 100644 --- a/libcrystfel/src/integration.c +++ b/libcrystfel/src/integration.c @@ -1687,9 +1687,14 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, saved_R * 5); } - res = estimate_resolution(crystal_get_cell(image->crystals[i]), + if ( image->indexed_by != INDEXING_FILE ){ + res = estimate_resolution(crystal_get_cell(image->crystals[i]), image->features); - crystal_set_resolution_limit(image->crystals[i], res); + crystal_set_resolution_limit(image->crystals[i], res); + } + else{ + res = crystal_get_resolution_limit(image->crystals[i]); + } list = predict_to_res(image->crystals[i], res+push_res); crystal_set_reflections(image->crystals[i], list); -- cgit v1.2.3 From 07787a409f8c152bf5ce224b67ae2ca8f99fb1d5 Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Thu, 17 Sep 2020 00:29:28 -0400 Subject: multiple crystal per shot implemented (to be tested) --- libcrystfel/src/fromfile.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/fromfile.c b/libcrystfel/src/fromfile.c index c87d5cbe..f79bc0d1 100644 --- a/libcrystfel/src/fromfile.c +++ b/libcrystfel/src/fromfile.c @@ -283,6 +283,7 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; float xshift, yshift, profile_radius, resolution_limit; struct fromfile_entries *item, *p, *pprime; + int ncryst = 0; float *sol; struct fromfile_private *dp = (struct fromfile_private *)mpriv; @@ -323,6 +324,7 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); cr = crystal_new(); + ncryst += 1; crystal_set_cell(cr, cell); crystal_set_profile_radius(cr, profile_radius); crystal_set_resolution_limit(cr, resolution_limit); @@ -335,17 +337,10 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), pprime); - if ( pprime == NULL ) { - /* If no more crystal, done */ - return 1; + if ( pprime != NULL ) { + ncryst += fromfile_index(image, mpriv, crystal_number+1); } - else{ - /* If more crystals, recursive call for next crystal in line */ - fromfile_index(image, mpriv, crystal_number+1); - } - - dp->sol_hash = NULL; /* Clean up local copy */ - - return 1; + + return ncryst; } \ No newline at end of file -- cgit v1.2.3 From 4489ee99f7b75d43e2c098822cfcb916847b47e1 Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Thu, 17 Sep 2020 21:39:41 -0400 Subject: removed the crystal number key from the solution file, deduced during reading --- libcrystfel/src/fromfile.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/fromfile.c b/libcrystfel/src/fromfile.c index f79bc0d1..8555e0f4 100644 --- a/libcrystfel/src/fromfile.c +++ b/libcrystfel/src/fromfile.c @@ -43,9 +43,9 @@ * 2 detector shifts, 1 profile radius, * 1 resolution limit */ #define NPARAMS_PER_LINE 13 -/* The keys are the filename, - * event, and crystal number */ -#define NKEYS_PER_LINE 3 +/* The keys read from file + * are the filename, event */ +#define NKEYS_PER_LINE 2 struct fromfile_keys { @@ -176,6 +176,7 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) int j = 0; /* follows the solution parameter [0,NPARAMS_PER_LINE] */ for(int i = 0; i < nentries; i++) { + crystal_number = 0; current_line = i/(NPARAMS_PER_LINE+NKEYS_PER_LINE); @@ -200,15 +201,8 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) return 0; } } - - if ( position_in_current_line == 2 ){ - if ( fscanf(fh, "%d", &crystal_number) != 1 ) { - printf("Failed to read a crystal number\n"); - return 0; - } - } - if ( position_in_current_line > 2 ){ + if ( position_in_current_line > 1 ){ if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { printf("Failed to read a parameter\n"); return 0; @@ -231,13 +225,25 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) /* Verify the uniqueness of the key */ struct fromfile_entries *uniqueness_test; HASH_FIND(hh, sol_hash, &item->key, - sizeof(struct fromfile_keys), uniqueness_test); - if (uniqueness_test==NULL) { - HASH_ADD(hh, sol_hash, key, sizeof(struct fromfile_keys), item); + sizeof(struct fromfile_keys), uniqueness_test); + + if ( uniqueness_test == NULL ) { + HASH_ADD(hh, sol_hash, key, + sizeof(struct fromfile_keys), item); } else{ - printf("Keys must be unique! Verify the combinations"); - return 0; + do + { + uniqueness_test = NULL; + crystal_number += 1; + item->key.crystal_number = crystal_number; + HASH_FIND(hh, sol_hash, &item->key, + sizeof(struct fromfile_keys), uniqueness_test); + } + while ( uniqueness_test != NULL ); + + HASH_ADD(hh, sol_hash, key, + sizeof(struct fromfile_keys), item); } j=0; -- cgit v1.2.3 From abbba986d43b1fa9d7107101d7b5432d6796009b Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Thu, 17 Sep 2020 23:25:25 -0400 Subject: read filename and event with dynamical allocation --- libcrystfel/src/fromfile.c | 63 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 12 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/fromfile.c b/libcrystfel/src/fromfile.c index 8555e0f4..05262458 100644 --- a/libcrystfel/src/fromfile.c +++ b/libcrystfel/src/fromfile.c @@ -127,27 +127,62 @@ int ncrystals_in_sol(char *path) } +char *read_unknown_string(FILE *fh){ + /* Source: "https://stackoverflow.com/questions/16870485/ + * how-can-i-read-an-input-string-of-unknown-length" */ + + char *str = NULL; + int ch; + size_t len = 0; + size_t size = 1; + + str = realloc(NULL, sizeof(char)*size); //size is start size + if ( !str ){ + ERROR("Can't reallocate string size") + } + + while( ( ch = fgetc(fh) ) != ' ' && ch != EOF ){ + if (ch != '\n'){ + str[len++]=ch; + } + if(len==size){ + size+=64; + str = realloc(str, sizeof(char)*(size)); + if ( !str ){ + ERROR("Can't reallocate string size") + } + } + } + + return realloc(str, sizeof(char)*len); + +} + void *fromfile_prepare(char *solution_filename, UnitCell *cell) { FILE *fh; int nlines; int nparams_in_solution; int nentries; - char filename[100]; - char event[100]; + char *filename; + char *event; int crystal_number; int current_line; int position_in_current_line; struct fromfile_entries *sol_hash = NULL; struct fromfile_entries *item = NULL; float params[NPARAMS_PER_LINE]; - char path_to_sol[50],extension[10]; char cwd[PATH_MAX]; /* Assembling solution file name from input file name*/ + char *path_to_sol; + size_t path_len; + char *core_name = strtok(solution_filename, "."); + char *extension = ".sol"; + path_len = sizeof(core_name) + sizeof(extension) + sizeof("../"); + path_to_sol = realloc(NULL, sizeof(char)*path_len); strcpy(path_to_sol, "../"); - strcpy(extension, ".sol"); - strcat(path_to_sol, strtok(solution_filename, ".")); + strcat(path_to_sol, core_name); strcat(path_to_sol, extension); if (getcwd(cwd, sizeof(cwd)) != NULL) { @@ -183,23 +218,26 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) position_in_current_line = (i)%(NPARAMS_PER_LINE+NKEYS_PER_LINE); if ( position_in_current_line == 0 ){ - if ( fscanf(fh, "%s", filename) != 1 ) { + + filename = read_unknown_string(fh); + + if ( !filename ){ if ( current_line == (nlines-1) ){ break; } - else{ printf("Failed to read a filename\n"); return 0; - } } + } if ( position_in_current_line == 1 ){ - - if ( fscanf(fh, "%s", event) != 1 ) { - printf("Failed to read an event\n"); + event = read_unknown_string(fh); + if ( !event ){ + printf("Failed to read a event\n"); return 0; } + } if ( position_in_current_line > 1 ){ @@ -232,6 +270,7 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) sizeof(struct fromfile_keys), item); } else{ + /* Look for the next available set of keys */ do { uniqueness_test = NULL; @@ -246,7 +285,7 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) sizeof(struct fromfile_keys), item); } - j=0; + j=0; } } -- cgit v1.2.3 From f937b91c7c9016665efd0c38af1e0a5d21d41c99 Mon Sep 17 00:00:00 2001 From: Pascal Hogan-Lamarre Date: Sun, 4 Oct 2020 20:57:30 -0400 Subject: Solved problem concerning prof_radius and diff_lim calculation, prof_radius and diff_lim removed from sol file --- libcrystfel/src/fromfile.c | 10 ++++------ libcrystfel/src/index.c | 28 +++++++++++++++++++--------- libcrystfel/src/integration.c | 9 ++------- 3 files changed, 25 insertions(+), 22 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/fromfile.c b/libcrystfel/src/fromfile.c index 05262458..13044ebe 100644 --- a/libcrystfel/src/fromfile.c +++ b/libcrystfel/src/fromfile.c @@ -42,7 +42,7 @@ /* There are 9 vector components, * 2 detector shifts, 1 profile radius, * 1 resolution limit */ -#define NPARAMS_PER_LINE 13 +#define NPARAMS_PER_LINE 11 /* The keys read from file * are the filename, event */ #define NKEYS_PER_LINE 2 @@ -326,7 +326,7 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) Crystal *cr; UnitCell *cell; float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - float xshift, yshift, profile_radius, resolution_limit; + float xshift, yshift; struct fromfile_entries *item, *p, *pprime; int ncryst = 0; float *sol; @@ -359,8 +359,6 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) csz = sol[8] * 1e9; xshift = sol[9] * 1e-3; yshift = sol[10] * 1e-3; - profile_radius = sol[11] * 1e9; - resolution_limit = sol[12] * 1e9; cell = cell_new(); cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); @@ -371,8 +369,6 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) cr = crystal_new(); ncryst += 1; crystal_set_cell(cr, cell); - crystal_set_profile_radius(cr, profile_radius); - crystal_set_resolution_limit(cr, resolution_limit); crystal_set_det_shift(cr, xshift , yshift); update_detector(image->det, xshift , yshift); image_add_crystal(image, cr); @@ -382,6 +378,8 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), pprime); + /* If a similar tag exist, + * recursive call increasing the crystal_number by 1 */ if ( pprime != NULL ) { ncryst += fromfile_index(image, mpriv, crystal_number+1); } diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index e0e8ff05..7b03ba3e 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -664,9 +664,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, Crystal *cr = image->crystals[this_crystal]; crystal_set_image(cr, image); - if ( indm != INDEXING_FILE){ - crystal_set_profile_radius(cr, 0.02e9); - } + crystal_set_profile_radius(cr, 0.02e9); crystal_set_mosaicity(cr, 0.0); /* Pre-refinement unit cell check if requested */ @@ -877,12 +875,14 @@ void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, if ( ipriv == NULL ) return; - map_all_peaks(image); + if ( ipriv->methods[0] != INDEXING_FILE){ + map_all_peaks(image); + orig = image->features; + } + image->crystals = NULL; image->n_crystals = 0; - orig = image->features; - for ( n=0; nn_methods; n++ ) { int done = 0; @@ -890,7 +890,9 @@ void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, int ntry = 0; int success = 0; - image->features = sort_peaks(orig); + if ( ipriv->methods[0] != INDEXING_FILE){ + image->features = sort_peaks(orig); + } do { @@ -906,7 +908,9 @@ void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, } while ( !done ); - image_feature_list_free(image->features); + if ( ipriv->methods[0] != INDEXING_FILE){ + image_feature_list_free(image->features); + } /* Stop now if the pattern is indexed (don't try again for more * crystals with a different indexing method) */ @@ -917,13 +921,19 @@ void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, } + if ( ipriv->methods[0] == INDEXING_FILE){ + map_all_peaks(image); + } + else{ + image->features = orig; + } + if ( n < ipriv->n_methods ) { image->indexed_by = ipriv->methods[n]; } else { image->indexed_by = INDEXING_NONE; } - image->features = orig; } diff --git a/libcrystfel/src/integration.c b/libcrystfel/src/integration.c index 8a3c581e..3d8258c1 100644 --- a/libcrystfel/src/integration.c +++ b/libcrystfel/src/integration.c @@ -1687,14 +1687,9 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, saved_R * 5); } - if ( image->indexed_by != INDEXING_FILE ){ - res = estimate_resolution(crystal_get_cell(image->crystals[i]), + res = estimate_resolution(crystal_get_cell(image->crystals[i]), image->features); - crystal_set_resolution_limit(image->crystals[i], res); - } - else{ - res = crystal_get_resolution_limit(image->crystals[i]); - } + crystal_set_resolution_limit(image->crystals[i], res); list = predict_to_res(image->crystals[i], res+push_res); crystal_set_reflections(image->crystals[i], list); -- cgit v1.2.3 From 87d60b8110e68ab42052588f275506eaca4f521f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 10:16:37 +0100 Subject: FromFile indexer: Move to libcrystfel/src/indexers Also adds to meson.build --- libcrystfel/src/fromfile.c | 389 ------------------------------------ libcrystfel/src/fromfile.h | 47 ----- libcrystfel/src/index.c | 2 +- libcrystfel/src/indexers/fromfile.c | 389 ++++++++++++++++++++++++++++++++++++ libcrystfel/src/indexers/fromfile.h | 47 +++++ 5 files changed, 437 insertions(+), 437 deletions(-) delete mode 100644 libcrystfel/src/fromfile.c delete mode 100644 libcrystfel/src/fromfile.h create mode 100644 libcrystfel/src/indexers/fromfile.c create mode 100644 libcrystfel/src/indexers/fromfile.h (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/fromfile.c b/libcrystfel/src/fromfile.c deleted file mode 100644 index 13044ebe..00000000 --- a/libcrystfel/src/fromfile.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * fromfile.c - * - * Perform indexing from solution file - * - * - * Authors: - * 2020 Pascal Hogan-Lamarre - * - * This file is part of CrystFEL. - * - * CrystFEL is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CrystFEL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CrystFEL. If not, see . - * - */ - -#include "image.h" -#include "detector.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "uthash.h" - -/** \file fromfile.h */ - -/* There are 9 vector components, - * 2 detector shifts, 1 profile radius, - * 1 resolution limit */ -#define NPARAMS_PER_LINE 11 -/* The keys read from file - * are the filename, event */ -#define NKEYS_PER_LINE 2 - -struct fromfile_keys -{ - char filename[100]; - char event[100]; - int crystal_number; -}; - -struct fromfile_entries -{ - struct fromfile_keys key; - float solution[NPARAMS_PER_LINE]; - UT_hash_handle hh; -}; - -struct fromfile_private -{ - UnitCell *cellTemplate; - struct fromfile_entries *sol_hash; -}; - -void print_struct(struct fromfile_entries *sol_hash) -{ - struct fromfile_entries *s; - s = (struct fromfile_entries *)malloc(sizeof *s); - memset(s, 0, sizeof *s); - - for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { - printf("File %s, event %s, and crystal_number %d \n", - s->key.filename, s->key.event, - s->key.crystal_number); - } -} - -void full_print_struct(struct fromfile_entries *sol_hash) -{ - struct fromfile_entries *s; - s = (struct fromfile_entries *)malloc(sizeof *s); - memset(s, 0, sizeof *s); - - for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { - printf("File %s, event %s, and crystal_number %d \n", - s->key.filename, s->key.event, - s->key.crystal_number); - - printf("Solution parameters:\n"); - for( int i = 0; i < NPARAMS_PER_LINE; i++ ){ - printf("%e", s->solution[i]); - } - printf("\n"); - } -} - -int ncrystals_in_sol(char *path) -{ - FILE *fh; - int count = 0; /* Line counter (result) */ - char c; /* To store a character read from file */ - - fh = fopen(path, "r"); - - if ( fh == NULL ) { - ERROR("%s not found by ncrystals_in_sol\n",path); - return 0; - } - - for ( c = getc(fh); c != EOF; c = getc(fh) ){ - if ( c == '\n' ){ - count = count + 1; - } - } - - /* For the last line, which has no \n at the end*/ - count = count + 1; - - fclose(fh); - - return count; - -} - -char *read_unknown_string(FILE *fh){ - /* Source: "https://stackoverflow.com/questions/16870485/ - * how-can-i-read-an-input-string-of-unknown-length" */ - - char *str = NULL; - int ch; - size_t len = 0; - size_t size = 1; - - str = realloc(NULL, sizeof(char)*size); //size is start size - if ( !str ){ - ERROR("Can't reallocate string size") - } - - while( ( ch = fgetc(fh) ) != ' ' && ch != EOF ){ - if (ch != '\n'){ - str[len++]=ch; - } - if(len==size){ - size+=64; - str = realloc(str, sizeof(char)*(size)); - if ( !str ){ - ERROR("Can't reallocate string size") - } - } - } - - return realloc(str, sizeof(char)*len); - -} - -void *fromfile_prepare(char *solution_filename, UnitCell *cell) -{ - FILE *fh; - int nlines; - int nparams_in_solution; - int nentries; - char *filename; - char *event; - int crystal_number; - int current_line; - int position_in_current_line; - struct fromfile_entries *sol_hash = NULL; - struct fromfile_entries *item = NULL; - float params[NPARAMS_PER_LINE]; - char cwd[PATH_MAX]; - - /* Assembling solution file name from input file name*/ - char *path_to_sol; - size_t path_len; - char *core_name = strtok(solution_filename, "."); - char *extension = ".sol"; - path_len = sizeof(core_name) + sizeof(extension) + sizeof("../"); - path_to_sol = realloc(NULL, sizeof(char)*path_len); - strcpy(path_to_sol, "../"); - strcat(path_to_sol, core_name); - strcat(path_to_sol, extension); - - if (getcwd(cwd, sizeof(cwd)) != NULL) { - ERROR("Cannot identify current directory\n"); - } - - fh = fopen(path_to_sol, "r"); - - if ( fh == NULL ) { - ERROR("%s not found by fromfile_prepare in %s\n", path_to_sol, cwd); - return 0; - } - else { - STATUS("Found solution file %s at %s\n", path_to_sol, cwd); - } - - nlines = ncrystals_in_sol(path_to_sol); - /* Total crystal parameters in solution file */ - nparams_in_solution = nlines*NPARAMS_PER_LINE; - /* Total entries in solution file */ - nentries = nlines*(NPARAMS_PER_LINE+NKEYS_PER_LINE); - - STATUS("Parsing solution file containing %d lines...\n", nlines); - - /* Reads indexing solutions */ - int j = 0; /* follows the solution parameter [0,NPARAMS_PER_LINE] */ - for(int i = 0; i < nentries; i++) - { - crystal_number = 0; - - current_line = i/(NPARAMS_PER_LINE+NKEYS_PER_LINE); - - position_in_current_line = (i)%(NPARAMS_PER_LINE+NKEYS_PER_LINE); - - if ( position_in_current_line == 0 ){ - - filename = read_unknown_string(fh); - - if ( !filename ){ - if ( current_line == (nlines-1) ){ - break; - } - printf("Failed to read a filename\n"); - return 0; - } - - } - - if ( position_in_current_line == 1 ){ - event = read_unknown_string(fh); - if ( !event ){ - printf("Failed to read a event\n"); - return 0; - } - - } - - if ( position_in_current_line > 1 ){ - if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { - printf("Failed to read a parameter\n"); - return 0; - } - j+=1; - } - - if ( j == (NPARAMS_PER_LINE) ){ - - /* Prepare to add to the hash table */ - item = (struct fromfile_entries *)malloc(sizeof *item); - memset(item, 0, sizeof *item); - strcpy(item->key.filename, filename); - strcpy(item->key.event, event); - item->key.crystal_number = crystal_number; - for ( int k = 0; k < NPARAMS_PER_LINE; k++){ - item->solution[k] = params[k]; - } - - /* Verify the uniqueness of the key */ - struct fromfile_entries *uniqueness_test; - HASH_FIND(hh, sol_hash, &item->key, - sizeof(struct fromfile_keys), uniqueness_test); - - if ( uniqueness_test == NULL ) { - HASH_ADD(hh, sol_hash, key, - sizeof(struct fromfile_keys), item); - } - else{ - /* Look for the next available set of keys */ - do - { - uniqueness_test = NULL; - crystal_number += 1; - item->key.crystal_number = crystal_number; - HASH_FIND(hh, sol_hash, &item->key, - sizeof(struct fromfile_keys), uniqueness_test); - } - while ( uniqueness_test != NULL ); - - HASH_ADD(hh, sol_hash, key, - sizeof(struct fromfile_keys), item); - } - - j=0; - - } - } - - fclose(fh); - - STATUS("Solution parsing done. Have %d parameters and %d total entries.\n", - nparams_in_solution, nentries); - - struct fromfile_private *dp; - dp = (struct fromfile_private *) malloc( sizeof(struct fromfile_private)); - - if ( dp == NULL ){ - return NULL; - } - - dp->cellTemplate = cell; - dp->sol_hash = sol_hash; - - STATUS("Solution lookup table initialized!\n"); - - return (void *)dp; -} - -static void update_detector(struct detector *det, double xoffs, double yoffs) -{ - int i; - - for ( i = 0; i < det->n_panels; i++ ) { - struct panel *p = &det->panels[i]; - p->cnx += xoffs * p->res; - p->cny += yoffs * p->res; - } -} - -int fromfile_index(struct image *image, void *mpriv, int crystal_number) -{ - Crystal *cr; - UnitCell *cell; - float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - float xshift, yshift; - struct fromfile_entries *item, *p, *pprime; - int ncryst = 0; - float *sol; - - struct fromfile_private *dp = (struct fromfile_private *)mpriv; - - /* Look up the hash table */ - item = (struct fromfile_entries *)malloc(sizeof *item); - memset(item, 0, sizeof *item); - strcpy(item->key.filename, image->filename); - strcpy(item->key.event, get_event_string(image->event)); - item->key.crystal_number = crystal_number; - - /* key already in the hash? */ - HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), p); - if ( p == NULL ) { - return 0; - } - - sol = &(p->solution)[0]; - - asx = sol[0] * 1e9; - asy = sol[1] * 1e9; - asz = sol[2] * 1e9; - bsx = sol[3] * 1e9; - bsy = sol[4] * 1e9; - bsz = sol[5] * 1e9; - csx = sol[6] * 1e9; - csy = sol[7] * 1e9; - csz = sol[8] * 1e9; - xshift = sol[9] * 1e-3; - yshift = sol[10] * 1e-3; - - cell = cell_new(); - cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); - cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); - cell_set_centering(cell, cell_get_centering(dp->cellTemplate)); - cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); - - cr = crystal_new(); - ncryst += 1; - crystal_set_cell(cr, cell); - crystal_set_det_shift(cr, xshift , yshift); - update_detector(image->det, xshift , yshift); - image_add_crystal(image, cr); - - /*Look for additional crystals*/ - item->key.crystal_number = crystal_number+1; - HASH_FIND(hh, dp->sol_hash, &item->key, - sizeof(struct fromfile_keys), pprime); - - /* If a similar tag exist, - * recursive call increasing the crystal_number by 1 */ - if ( pprime != NULL ) { - ncryst += fromfile_index(image, mpriv, crystal_number+1); - } - - return ncryst; - -} \ No newline at end of file diff --git a/libcrystfel/src/fromfile.h b/libcrystfel/src/fromfile.h deleted file mode 100644 index 29d31aee..00000000 --- a/libcrystfel/src/fromfile.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * fromfile.h - * - * Perform indexing from solution file - * - * - * Authors: - * 2020 Pascal Hogan-Lamarre - * - * This file is part of CrystFEL. - * - * CrystFEL is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CrystFEL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CrystFEL. If not, see . - * - */ - -#ifndef FROMFILE_H -#define FROMFILE_H - -struct fromfile_keys; -struct fromfile_entries; -struct fromfile_private; - -#include "image.h" -#include "cell.h" -#include "uthash.h" - -extern void print_struct(struct fromfile_entries *sol_hash); - -extern void full_print_struct(struct fromfile_entries *sol_hash); - -extern void *fromfile_prepare(char *solution_filename, UnitCell *cell); - -extern int fromfile_index(struct image *image, void *mpriv, int crystal_number); - - -#endif /* FROMFILE_H */ \ No newline at end of file diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 58e90437..c2f79eff 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -59,7 +59,7 @@ #include "indexers/taketwo.h" #include "indexers/xgandalf.h" #include "indexers/pinkindexer.h" -#include "fromfile.h" +#include "indexers/fromfile.h" #include "uthash.h" diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c new file mode 100644 index 00000000..13044ebe --- /dev/null +++ b/libcrystfel/src/indexers/fromfile.c @@ -0,0 +1,389 @@ +/* + * fromfile.c + * + * Perform indexing from solution file + * + * + * Authors: + * 2020 Pascal Hogan-Lamarre + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see . + * + */ + +#include "image.h" +#include "detector.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "uthash.h" + +/** \file fromfile.h */ + +/* There are 9 vector components, + * 2 detector shifts, 1 profile radius, + * 1 resolution limit */ +#define NPARAMS_PER_LINE 11 +/* The keys read from file + * are the filename, event */ +#define NKEYS_PER_LINE 2 + +struct fromfile_keys +{ + char filename[100]; + char event[100]; + int crystal_number; +}; + +struct fromfile_entries +{ + struct fromfile_keys key; + float solution[NPARAMS_PER_LINE]; + UT_hash_handle hh; +}; + +struct fromfile_private +{ + UnitCell *cellTemplate; + struct fromfile_entries *sol_hash; +}; + +void print_struct(struct fromfile_entries *sol_hash) +{ + struct fromfile_entries *s; + s = (struct fromfile_entries *)malloc(sizeof *s); + memset(s, 0, sizeof *s); + + for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { + printf("File %s, event %s, and crystal_number %d \n", + s->key.filename, s->key.event, + s->key.crystal_number); + } +} + +void full_print_struct(struct fromfile_entries *sol_hash) +{ + struct fromfile_entries *s; + s = (struct fromfile_entries *)malloc(sizeof *s); + memset(s, 0, sizeof *s); + + for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { + printf("File %s, event %s, and crystal_number %d \n", + s->key.filename, s->key.event, + s->key.crystal_number); + + printf("Solution parameters:\n"); + for( int i = 0; i < NPARAMS_PER_LINE; i++ ){ + printf("%e", s->solution[i]); + } + printf("\n"); + } +} + +int ncrystals_in_sol(char *path) +{ + FILE *fh; + int count = 0; /* Line counter (result) */ + char c; /* To store a character read from file */ + + fh = fopen(path, "r"); + + if ( fh == NULL ) { + ERROR("%s not found by ncrystals_in_sol\n",path); + return 0; + } + + for ( c = getc(fh); c != EOF; c = getc(fh) ){ + if ( c == '\n' ){ + count = count + 1; + } + } + + /* For the last line, which has no \n at the end*/ + count = count + 1; + + fclose(fh); + + return count; + +} + +char *read_unknown_string(FILE *fh){ + /* Source: "https://stackoverflow.com/questions/16870485/ + * how-can-i-read-an-input-string-of-unknown-length" */ + + char *str = NULL; + int ch; + size_t len = 0; + size_t size = 1; + + str = realloc(NULL, sizeof(char)*size); //size is start size + if ( !str ){ + ERROR("Can't reallocate string size") + } + + while( ( ch = fgetc(fh) ) != ' ' && ch != EOF ){ + if (ch != '\n'){ + str[len++]=ch; + } + if(len==size){ + size+=64; + str = realloc(str, sizeof(char)*(size)); + if ( !str ){ + ERROR("Can't reallocate string size") + } + } + } + + return realloc(str, sizeof(char)*len); + +} + +void *fromfile_prepare(char *solution_filename, UnitCell *cell) +{ + FILE *fh; + int nlines; + int nparams_in_solution; + int nentries; + char *filename; + char *event; + int crystal_number; + int current_line; + int position_in_current_line; + struct fromfile_entries *sol_hash = NULL; + struct fromfile_entries *item = NULL; + float params[NPARAMS_PER_LINE]; + char cwd[PATH_MAX]; + + /* Assembling solution file name from input file name*/ + char *path_to_sol; + size_t path_len; + char *core_name = strtok(solution_filename, "."); + char *extension = ".sol"; + path_len = sizeof(core_name) + sizeof(extension) + sizeof("../"); + path_to_sol = realloc(NULL, sizeof(char)*path_len); + strcpy(path_to_sol, "../"); + strcat(path_to_sol, core_name); + strcat(path_to_sol, extension); + + if (getcwd(cwd, sizeof(cwd)) != NULL) { + ERROR("Cannot identify current directory\n"); + } + + fh = fopen(path_to_sol, "r"); + + if ( fh == NULL ) { + ERROR("%s not found by fromfile_prepare in %s\n", path_to_sol, cwd); + return 0; + } + else { + STATUS("Found solution file %s at %s\n", path_to_sol, cwd); + } + + nlines = ncrystals_in_sol(path_to_sol); + /* Total crystal parameters in solution file */ + nparams_in_solution = nlines*NPARAMS_PER_LINE; + /* Total entries in solution file */ + nentries = nlines*(NPARAMS_PER_LINE+NKEYS_PER_LINE); + + STATUS("Parsing solution file containing %d lines...\n", nlines); + + /* Reads indexing solutions */ + int j = 0; /* follows the solution parameter [0,NPARAMS_PER_LINE] */ + for(int i = 0; i < nentries; i++) + { + crystal_number = 0; + + current_line = i/(NPARAMS_PER_LINE+NKEYS_PER_LINE); + + position_in_current_line = (i)%(NPARAMS_PER_LINE+NKEYS_PER_LINE); + + if ( position_in_current_line == 0 ){ + + filename = read_unknown_string(fh); + + if ( !filename ){ + if ( current_line == (nlines-1) ){ + break; + } + printf("Failed to read a filename\n"); + return 0; + } + + } + + if ( position_in_current_line == 1 ){ + event = read_unknown_string(fh); + if ( !event ){ + printf("Failed to read a event\n"); + return 0; + } + + } + + if ( position_in_current_line > 1 ){ + if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { + printf("Failed to read a parameter\n"); + return 0; + } + j+=1; + } + + if ( j == (NPARAMS_PER_LINE) ){ + + /* Prepare to add to the hash table */ + item = (struct fromfile_entries *)malloc(sizeof *item); + memset(item, 0, sizeof *item); + strcpy(item->key.filename, filename); + strcpy(item->key.event, event); + item->key.crystal_number = crystal_number; + for ( int k = 0; k < NPARAMS_PER_LINE; k++){ + item->solution[k] = params[k]; + } + + /* Verify the uniqueness of the key */ + struct fromfile_entries *uniqueness_test; + HASH_FIND(hh, sol_hash, &item->key, + sizeof(struct fromfile_keys), uniqueness_test); + + if ( uniqueness_test == NULL ) { + HASH_ADD(hh, sol_hash, key, + sizeof(struct fromfile_keys), item); + } + else{ + /* Look for the next available set of keys */ + do + { + uniqueness_test = NULL; + crystal_number += 1; + item->key.crystal_number = crystal_number; + HASH_FIND(hh, sol_hash, &item->key, + sizeof(struct fromfile_keys), uniqueness_test); + } + while ( uniqueness_test != NULL ); + + HASH_ADD(hh, sol_hash, key, + sizeof(struct fromfile_keys), item); + } + + j=0; + + } + } + + fclose(fh); + + STATUS("Solution parsing done. Have %d parameters and %d total entries.\n", + nparams_in_solution, nentries); + + struct fromfile_private *dp; + dp = (struct fromfile_private *) malloc( sizeof(struct fromfile_private)); + + if ( dp == NULL ){ + return NULL; + } + + dp->cellTemplate = cell; + dp->sol_hash = sol_hash; + + STATUS("Solution lookup table initialized!\n"); + + return (void *)dp; +} + +static void update_detector(struct detector *det, double xoffs, double yoffs) +{ + int i; + + for ( i = 0; i < det->n_panels; i++ ) { + struct panel *p = &det->panels[i]; + p->cnx += xoffs * p->res; + p->cny += yoffs * p->res; + } +} + +int fromfile_index(struct image *image, void *mpriv, int crystal_number) +{ + Crystal *cr; + UnitCell *cell; + float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; + float xshift, yshift; + struct fromfile_entries *item, *p, *pprime; + int ncryst = 0; + float *sol; + + struct fromfile_private *dp = (struct fromfile_private *)mpriv; + + /* Look up the hash table */ + item = (struct fromfile_entries *)malloc(sizeof *item); + memset(item, 0, sizeof *item); + strcpy(item->key.filename, image->filename); + strcpy(item->key.event, get_event_string(image->event)); + item->key.crystal_number = crystal_number; + + /* key already in the hash? */ + HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), p); + if ( p == NULL ) { + return 0; + } + + sol = &(p->solution)[0]; + + asx = sol[0] * 1e9; + asy = sol[1] * 1e9; + asz = sol[2] * 1e9; + bsx = sol[3] * 1e9; + bsy = sol[4] * 1e9; + bsz = sol[5] * 1e9; + csx = sol[6] * 1e9; + csy = sol[7] * 1e9; + csz = sol[8] * 1e9; + xshift = sol[9] * 1e-3; + yshift = sol[10] * 1e-3; + + cell = cell_new(); + cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); + cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); + cell_set_centering(cell, cell_get_centering(dp->cellTemplate)); + cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); + + cr = crystal_new(); + ncryst += 1; + crystal_set_cell(cr, cell); + crystal_set_det_shift(cr, xshift , yshift); + update_detector(image->det, xshift , yshift); + image_add_crystal(image, cr); + + /*Look for additional crystals*/ + item->key.crystal_number = crystal_number+1; + HASH_FIND(hh, dp->sol_hash, &item->key, + sizeof(struct fromfile_keys), pprime); + + /* If a similar tag exist, + * recursive call increasing the crystal_number by 1 */ + if ( pprime != NULL ) { + ncryst += fromfile_index(image, mpriv, crystal_number+1); + } + + return ncryst; + +} \ No newline at end of file diff --git a/libcrystfel/src/indexers/fromfile.h b/libcrystfel/src/indexers/fromfile.h new file mode 100644 index 00000000..29d31aee --- /dev/null +++ b/libcrystfel/src/indexers/fromfile.h @@ -0,0 +1,47 @@ +/* + * fromfile.h + * + * Perform indexing from solution file + * + * + * Authors: + * 2020 Pascal Hogan-Lamarre + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see . + * + */ + +#ifndef FROMFILE_H +#define FROMFILE_H + +struct fromfile_keys; +struct fromfile_entries; +struct fromfile_private; + +#include "image.h" +#include "cell.h" +#include "uthash.h" + +extern void print_struct(struct fromfile_entries *sol_hash); + +extern void full_print_struct(struct fromfile_entries *sol_hash); + +extern void *fromfile_prepare(char *solution_filename, UnitCell *cell); + +extern int fromfile_index(struct image *image, void *mpriv, int crystal_number); + + +#endif /* FROMFILE_H */ \ No newline at end of file -- cgit v1.2.3 From 0cc8a3db1a6e57f64275deab0da2b31a15fdbb69 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 11:26:01 +0100 Subject: Clean up after merge --- libcrystfel/src/index.c | 14 ++++++++------ libcrystfel/src/index.h | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index c2f79eff..341abf58 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -63,9 +63,9 @@ #include "uthash.h" - /** \file index.h */ + struct _indexingprivate { IndexingFlags flags; @@ -79,6 +79,7 @@ struct _indexingprivate void **engine_private; }; + static const char *onoff(int a) { if ( a ) return "on"; @@ -99,6 +100,7 @@ static void set_last_task(char *lt, const char *task) strcpy(lt, task); } + static void show_indexing_flags(IndexingFlags flags) { STATUS("Indexing parameters:\n"); @@ -404,7 +406,7 @@ IndexingPrivate *setup_indexing(const char *method_list, pinkIndexer_opts, felix_opts, ttopts, - filename); + filename); if ( ipriv->engine_private[i] == NULL ) return NULL; @@ -639,8 +641,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, case INDEXING_FILE : set_last_task(last_task, "indexing:file"); - int crystal_number = 0; - r = fromfile_index(image, mpriv, crystal_number); + r = fromfile_index(image, mpriv, 0); break; case INDEXING_FELIX : @@ -942,7 +943,7 @@ void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, int ntry = 0; int success = 0; - if ( ipriv->methods[0] != INDEXING_FILE){ + if ( ipriv->methods[0] != INDEXING_FILE ) { image->features = sort_peaks(orig); } @@ -960,7 +961,7 @@ void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, } while ( !done ); - if ( ipriv->methods[0] != INDEXING_FILE){ + if ( ipriv->methods[0] != INDEXING_FILE ) { image_feature_list_free(image->features); } @@ -979,6 +980,7 @@ void index_pattern_3(struct image *image, IndexingPrivate *ipriv, int *ping, image->indexed_by = INDEXING_NONE; } + image->features = orig; } diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h index 92406604..5cee29b2 100644 --- a/libcrystfel/src/index.h +++ b/libcrystfel/src/index.h @@ -73,7 +73,7 @@ typedef enum { INDEXING_FELIX = 4, /**< Invoke Felix program */ INDEXING_XDS = 5, /**< Invoke XDS program (NB not nXDS) */ INDEXING_SIMULATION = 6, /**< Dummy value for simulated data */ - INDEXING_FILE = 7, /**< Results injector for debugging */ + INDEXING_FILE = 7, /**< Results injector for debugging */ INDEXING_ASDF = 8, /**< Use built-in ASDF algorithm */ INDEXING_TAKETWO = 9, /**< Use built-in TakeTwo algorithm */ INDEXING_XGANDALF = 10, /**< Use XGANDALF (via optional library) */ -- cgit v1.2.3 From 640a9c4aa44f58acc40108ac2ae84269117fd84a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 12:02:32 +0100 Subject: FromFile indexer: Strip trailing whitespace and sort out formatting --- libcrystfel/src/indexers/fromfile.c | 234 ++++++++++++++++++------------------ libcrystfel/src/indexers/fromfile.h | 3 +- 2 files changed, 117 insertions(+), 120 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index 13044ebe..c5ea0e56 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -3,7 +3,6 @@ * * Perform indexing from solution file * - * * Authors: * 2020 Pascal Hogan-Lamarre * @@ -24,9 +23,6 @@ * */ -#include "image.h" -#include "detector.h" - #include #include #include @@ -35,137 +31,145 @@ #include #include +#include "image.h" +#include "detector.h" #include "uthash.h" /** \file fromfile.h */ -/* There are 9 vector components, +/* There are 9 vector components, * 2 detector shifts, 1 profile radius, * 1 resolution limit */ -#define NPARAMS_PER_LINE 11 -/* The keys read from file +#define NPARAMS_PER_LINE 11 +/* The keys read from file * are the filename, event */ #define NKEYS_PER_LINE 2 + struct fromfile_keys -{ - char filename[100]; - char event[100]; - int crystal_number; +{ + char filename[100]; + char event[100]; + int crystal_number; }; + struct fromfile_entries -{ - struct fromfile_keys key; - float solution[NPARAMS_PER_LINE]; - UT_hash_handle hh; +{ + struct fromfile_keys key; + float solution[NPARAMS_PER_LINE]; + UT_hash_handle hh; }; + struct fromfile_private { UnitCell *cellTemplate; struct fromfile_entries *sol_hash; }; -void print_struct(struct fromfile_entries *sol_hash) + +void print_struct(struct fromfile_entries *sol_hash) { - struct fromfile_entries *s; - s = (struct fromfile_entries *)malloc(sizeof *s); - memset(s, 0, sizeof *s); - - for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { - printf("File %s, event %s, and crystal_number %d \n", - s->key.filename, s->key.event, - s->key.crystal_number); - } + struct fromfile_entries *s; + s = (struct fromfile_entries *)malloc(sizeof *s); + memset(s, 0, sizeof *s); + + for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { + printf("File %s, event %s, and crystal_number %d \n", + s->key.filename, s->key.event, s->key.crystal_number); + } } + void full_print_struct(struct fromfile_entries *sol_hash) { - struct fromfile_entries *s; - s = (struct fromfile_entries *)malloc(sizeof *s); - memset(s, 0, sizeof *s); - - for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { - printf("File %s, event %s, and crystal_number %d \n", - s->key.filename, s->key.event, - s->key.crystal_number); - + struct fromfile_entries *s; + s = (struct fromfile_entries *)malloc(sizeof *s); + memset(s, 0, sizeof *s); + + for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { + printf("File %s, event %s, and crystal_number %d \n", + s->key.filename, s->key.event, + s->key.crystal_number); + printf("Solution parameters:\n"); - for( int i = 0; i < NPARAMS_PER_LINE; i++ ){ - printf("%e", s->solution[i]); - } - printf("\n"); - } + for( int i = 0; i < NPARAMS_PER_LINE; i++ ){ + printf("%e", s->solution[i]); + } + printf("\n"); + } } + int ncrystals_in_sol(char *path) { FILE *fh; int count = 0; /* Line counter (result) */ - char c; /* To store a character read from file */ + char c; /* To store a character read from file */ fh = fopen(path, "r"); if ( fh == NULL ) { - ERROR("%s not found by ncrystals_in_sol\n",path); + ERROR("%s not found by ncrystals_in_sol\n", path); return 0; } - for ( c = getc(fh); c != EOF; c = getc(fh) ){ - if ( c == '\n' ){ - count = count + 1; + for ( c = getc(fh); c != EOF; c = getc(fh) ) { + if ( c == '\n' ) { + count = count + 1; } } - + /* For the last line, which has no \n at the end*/ count = count + 1; - - fclose(fh); - return count; + fclose(fh); + return count; } -char *read_unknown_string(FILE *fh){ + +char *read_unknown_string(FILE *fh) +{ /* Source: "https://stackoverflow.com/questions/16870485/ * how-can-i-read-an-input-string-of-unknown-length" */ char *str = NULL; - int ch; - size_t len = 0; + int ch; + size_t len = 0; size_t size = 1; - str = realloc(NULL, sizeof(char)*size); //size is start size - if ( !str ){ + str = realloc(NULL, sizeof(char)*size); //size is start size + if ( !str ) { ERROR("Can't reallocate string size") } - - while( ( ch = fgetc(fh) ) != ' ' && ch != EOF ){ + + while( ( ch = fgetc(fh) ) != ' ' && ch != EOF ){ if (ch != '\n'){ str[len++]=ch; } - if(len==size){ + if(len==size){ size+=64; - str = realloc(str, sizeof(char)*(size)); + str = realloc(str, sizeof(char)*(size)); if ( !str ){ ERROR("Can't reallocate string size") } - } - } - - return realloc(str, sizeof(char)*len); + } + } + return realloc(str, sizeof(char)*len); } + void *fromfile_prepare(char *solution_filename, UnitCell *cell) -{ +{ FILE *fh; int nlines; int nparams_in_solution; int nentries; - char *filename; - char *event; + char *filename; + char *event; int crystal_number; int current_line; int position_in_current_line; @@ -192,46 +196,44 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) fh = fopen(path_to_sol, "r"); if ( fh == NULL ) { - ERROR("%s not found by fromfile_prepare in %s\n", path_to_sol, cwd); + ERROR("%s not found by fromfile_prepare in %s\n", + path_to_sol, cwd); return 0; - } - else { + } else { STATUS("Found solution file %s at %s\n", path_to_sol, cwd); } nlines = ncrystals_in_sol(path_to_sol); /* Total crystal parameters in solution file */ - nparams_in_solution = nlines*NPARAMS_PER_LINE; + nparams_in_solution = nlines*NPARAMS_PER_LINE; /* Total entries in solution file */ - nentries = nlines*(NPARAMS_PER_LINE+NKEYS_PER_LINE); - + nentries = nlines*(NPARAMS_PER_LINE+NKEYS_PER_LINE); + STATUS("Parsing solution file containing %d lines...\n", nlines); /* Reads indexing solutions */ int j = 0; /* follows the solution parameter [0,NPARAMS_PER_LINE] */ - for(int i = 0; i < nentries; i++) - { + for(int i = 0; i < nentries; i++) { + crystal_number = 0; current_line = i/(NPARAMS_PER_LINE+NKEYS_PER_LINE); - + position_in_current_line = (i)%(NPARAMS_PER_LINE+NKEYS_PER_LINE); - if ( position_in_current_line == 0 ){ + if ( position_in_current_line == 0 ) { filename = read_unknown_string(fh); if ( !filename ){ - if ( current_line == (nlines-1) ){ - break; - } + if ( current_line == nlines-1 ) break; printf("Failed to read a filename\n"); return 0; } - + } - if ( position_in_current_line == 1 ){ + if ( position_in_current_line == 1 ) { event = read_unknown_string(fh); if ( !event ){ printf("Failed to read a event\n"); @@ -240,15 +242,15 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) } - if ( position_in_current_line > 1 ){ + if ( position_in_current_line > 1 ) { if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { printf("Failed to read a parameter\n"); return 0; } - j+=1; + j+=1; } - if ( j == (NPARAMS_PER_LINE) ){ + if ( j == (NPARAMS_PER_LINE) ) { /* Prepare to add to the hash table */ item = (struct fromfile_entries *)malloc(sizeof *item); @@ -257,41 +259,39 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) strcpy(item->key.event, event); item->key.crystal_number = crystal_number; for ( int k = 0; k < NPARAMS_PER_LINE; k++){ - item->solution[k] = params[k]; + item->solution[k] = params[k]; } /* Verify the uniqueness of the key */ struct fromfile_entries *uniqueness_test; - HASH_FIND(hh, sol_hash, &item->key, + HASH_FIND(hh, sol_hash, &item->key, sizeof(struct fromfile_keys), uniqueness_test); - - if ( uniqueness_test == NULL ) { - HASH_ADD(hh, sol_hash, key, + + if ( uniqueness_test == NULL ) { + HASH_ADD(hh, sol_hash, key, sizeof(struct fromfile_keys), item); - } - else{ + } else { /* Look for the next available set of keys */ - do - { + do { uniqueness_test = NULL; crystal_number += 1; item->key.crystal_number = crystal_number; - HASH_FIND(hh, sol_hash, &item->key, - sizeof(struct fromfile_keys), uniqueness_test); - } - while ( uniqueness_test != NULL ); - - HASH_ADD(hh, sol_hash, key, + HASH_FIND(hh, sol_hash, &item->key, + sizeof(struct fromfile_keys), + uniqueness_test); + } while ( uniqueness_test != NULL ); + + HASH_ADD(hh, sol_hash, key, sizeof(struct fromfile_keys), item); } - j=0; + j=0; } } - + fclose(fh); - + STATUS("Solution parsing done. Have %d parameters and %d total entries.\n", nparams_in_solution, nentries); @@ -301,15 +301,16 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) if ( dp == NULL ){ return NULL; } - - dp->cellTemplate = cell; + + dp->cellTemplate = cell; dp->sol_hash = sol_hash; - + STATUS("Solution lookup table initialized!\n"); return (void *)dp; } + static void update_detector(struct detector *det, double xoffs, double yoffs) { int i; @@ -321,16 +322,16 @@ static void update_detector(struct detector *det, double xoffs, double yoffs) } } + int fromfile_index(struct image *image, void *mpriv, int crystal_number) { Crystal *cr; UnitCell *cell; float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - float xshift, yshift; + float xshift, yshift; struct fromfile_entries *item, *p, *pprime; int ncryst = 0; float *sol; - struct fromfile_private *dp = (struct fromfile_private *)mpriv; /* Look up the hash table */ @@ -341,13 +342,11 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) item->key.crystal_number = crystal_number; /* key already in the hash? */ - HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), p); - if ( p == NULL ) { - return 0; - } + HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), p); + if ( p == NULL ) return 0; sol = &(p->solution)[0]; - + asx = sol[0] * 1e9; asy = sol[1] * 1e9; asz = sol[2] * 1e9; @@ -362,10 +361,10 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) cell = cell_new(); cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); - cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); + cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); cell_set_centering(cell, cell_get_centering(dp->cellTemplate)); cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); - + cr = crystal_new(); ncryst += 1; crystal_set_cell(cr, cell); @@ -373,17 +372,16 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) update_detector(image->det, xshift , yshift); image_add_crystal(image, cr); - /*Look for additional crystals*/ + /* Look for additional crystals */ item->key.crystal_number = crystal_number+1; - HASH_FIND(hh, dp->sol_hash, &item->key, + HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), pprime); /* If a similar tag exist, * recursive call increasing the crystal_number by 1 */ - if ( pprime != NULL ) { + if ( pprime != NULL ) { ncryst += fromfile_index(image, mpriv, crystal_number+1); } - + return ncryst; - -} \ No newline at end of file +} diff --git a/libcrystfel/src/indexers/fromfile.h b/libcrystfel/src/indexers/fromfile.h index 29d31aee..b91f10ae 100644 --- a/libcrystfel/src/indexers/fromfile.h +++ b/libcrystfel/src/indexers/fromfile.h @@ -3,7 +3,6 @@ * * Perform indexing from solution file * - * * Authors: * 2020 Pascal Hogan-Lamarre * @@ -44,4 +43,4 @@ extern void *fromfile_prepare(char *solution_filename, UnitCell *cell); extern int fromfile_index(struct image *image, void *mpriv, int crystal_number); -#endif /* FROMFILE_H */ \ No newline at end of file +#endif /* FROMFILE_H */ -- cgit v1.2.3 From 1a92ce3723861478e48a9c4875b9fcd0e6589ad3 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 12:32:01 +0100 Subject: FromFile indexer: Add missing semicolons --- libcrystfel/src/indexers/fromfile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index c5ea0e56..969477b8 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -142,7 +142,7 @@ char *read_unknown_string(FILE *fh) str = realloc(NULL, sizeof(char)*size); //size is start size if ( !str ) { - ERROR("Can't reallocate string size") + ERROR("Can't reallocate string size"); } while( ( ch = fgetc(fh) ) != ' ' && ch != EOF ){ @@ -152,8 +152,8 @@ char *read_unknown_string(FILE *fh) if(len==size){ size+=64; str = realloc(str, sizeof(char)*(size)); - if ( !str ){ - ERROR("Can't reallocate string size") + if ( !str ) { + ERROR("Can't reallocate string size"); } } } -- cgit v1.2.3 From 1862584055980608d10d4a3708351b0c8ff034b7 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 12:35:25 +0100 Subject: FromFile indexer: Remove update_detector Everything should use the per-crystal detector shift now. --- libcrystfel/src/indexers/fromfile.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index 969477b8..4da01d78 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -32,7 +32,6 @@ #include #include "image.h" -#include "detector.h" #include "uthash.h" /** \file fromfile.h */ @@ -311,18 +310,6 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) } -static void update_detector(struct detector *det, double xoffs, double yoffs) -{ - int i; - - for ( i = 0; i < det->n_panels; i++ ) { - struct panel *p = &det->panels[i]; - p->cnx += xoffs * p->res; - p->cny += yoffs * p->res; - } -} - - int fromfile_index(struct image *image, void *mpriv, int crystal_number) { Crystal *cr; @@ -369,7 +356,6 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) ncryst += 1; crystal_set_cell(cr, cell); crystal_set_det_shift(cr, xshift , yshift); - update_detector(image->det, xshift , yshift); image_add_crystal(image, cr); /* Look for additional crystals */ -- cgit v1.2.3 From 9edd14304236313e458dc920570ca6aeee6e5b10 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 13:27:25 +0100 Subject: FromFile indexer: Remove getcwd() It's only used for some error messages, and it doesn't compile anyway. --- libcrystfel/src/indexers/fromfile.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index 4da01d78..cb1fb150 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -175,7 +175,6 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) struct fromfile_entries *sol_hash = NULL; struct fromfile_entries *item = NULL; float params[NPARAMS_PER_LINE]; - char cwd[PATH_MAX]; /* Assembling solution file name from input file name*/ char *path_to_sol; @@ -188,18 +187,13 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) strcat(path_to_sol, core_name); strcat(path_to_sol, extension); - if (getcwd(cwd, sizeof(cwd)) != NULL) { - ERROR("Cannot identify current directory\n"); - } - fh = fopen(path_to_sol, "r"); if ( fh == NULL ) { - ERROR("%s not found by fromfile_prepare in %s\n", - path_to_sol, cwd); + ERROR("%s not found by fromfile_prepare\n", path_to_sol); return 0; } else { - STATUS("Found solution file %s at %s\n", path_to_sol, cwd); + STATUS("Found solution file %s\n", path_to_sol); } nlines = ncrystals_in_sol(path_to_sol); -- cgit v1.2.3 From df469d21c20e655d66712f78b8054c9e110b62f3 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 15:25:48 +0100 Subject: FromFile indexer: Remove unnecessary casting/memset --- libcrystfel/src/indexers/fromfile.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index cb1fb150..040b35e5 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -71,10 +71,11 @@ struct fromfile_private void print_struct(struct fromfile_entries *sol_hash) { struct fromfile_entries *s; - s = (struct fromfile_entries *)malloc(sizeof *s); - memset(s, 0, sizeof *s); - for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { + s = calloc(1, sizeof(struct fromfile_entries)); + if ( s == NULL ) return; + + for( s=sol_hash; s != NULL; s=s->hh.next ) { printf("File %s, event %s, and crystal_number %d \n", s->key.filename, s->key.event, s->key.crystal_number); } @@ -84,10 +85,10 @@ void print_struct(struct fromfile_entries *sol_hash) void full_print_struct(struct fromfile_entries *sol_hash) { struct fromfile_entries *s; - s = (struct fromfile_entries *)malloc(sizeof *s); - memset(s, 0, sizeof *s); + s = calloc(1, sizeof(struct fromfile_entries)); + if ( s == NULL ) return; - for( s=sol_hash; s != NULL; s=(struct fromfile_entries*)(s->hh.next) ) { + for( s=sol_hash; s != NULL; s=s->hh.next ) { printf("File %s, event %s, and crystal_number %d \n", s->key.filename, s->key.event, s->key.crystal_number); @@ -313,11 +314,10 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) struct fromfile_entries *item, *p, *pprime; int ncryst = 0; float *sol; - struct fromfile_private *dp = (struct fromfile_private *)mpriv; + struct fromfile_private *dp = mpriv; /* Look up the hash table */ - item = (struct fromfile_entries *)malloc(sizeof *item); - memset(item, 0, sizeof *item); + item = calloc(1, sizeof(struct fromfile_entries)); strcpy(item->key.filename, image->filename); strcpy(item->key.event, get_event_string(image->event)); item->key.crystal_number = crystal_number; -- cgit v1.2.3 From 618aa72a9771faad60ae1ec9f7357bdd29736b4a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 15:38:43 +0100 Subject: FromFile indexer: Update for new event ID in image structure --- libcrystfel/src/indexers/fromfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index 040b35e5..d43b17c5 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -319,7 +319,7 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) /* Look up the hash table */ item = calloc(1, sizeof(struct fromfile_entries)); strcpy(item->key.filename, image->filename); - strcpy(item->key.event, get_event_string(image->event)); + strcpy(item->key.event, image->ev); item->key.crystal_number = crystal_number; /* key already in the hash? */ -- cgit v1.2.3 From fdfa088f97aa2525b9b19e9383cbc203b354b61d Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 12 Mar 2021 16:21:35 +0100 Subject: FromFile indexer: Add skeleton cleanup procedure --- libcrystfel/src/index.c | 2 +- libcrystfel/src/indexers/fromfile.c | 10 ++++++++++ libcrystfel/src/indexers/fromfile.h | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index 341abf58..f9001968 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -510,7 +510,7 @@ void cleanup_indexing(IndexingPrivate *ipriv) break; case INDEXING_FILE : - free(ipriv->engine_private[n]); + fromfile_cleanup(ipriv->engine_private[n]); break; case INDEXING_TAKETWO : diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index d43b17c5..73cee547 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -365,3 +365,13 @@ int fromfile_index(struct image *image, void *mpriv, int crystal_number) return ncryst; } + + +void fromfile_cleanup(void *mpriv) +{ + struct fromfile_private *dp = mpriv; + + /* FIXME: Implementation */ + + free(dp); +} diff --git a/libcrystfel/src/indexers/fromfile.h b/libcrystfel/src/indexers/fromfile.h index b91f10ae..deb7b105 100644 --- a/libcrystfel/src/indexers/fromfile.h +++ b/libcrystfel/src/indexers/fromfile.h @@ -42,5 +42,7 @@ extern void *fromfile_prepare(char *solution_filename, UnitCell *cell); extern int fromfile_index(struct image *image, void *mpriv, int crystal_number); +extern void fromfile_cleanup(void *mpriv); + #endif /* FROMFILE_H */ -- cgit v1.2.3 From dcdce375c16c709161d57cbae551feb7b842db34 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Mar 2021 12:00:22 +0100 Subject: FromFile indexer: Option processing This give FromFile its own private command-lien option processing, like the other indexers. It removes the ability to auto-generate the solution filename, but I don't think there's a way to do that without breaking abstractions. --- libcrystfel/src/index.c | 12 +++-- libcrystfel/src/index.h | 7 ++- libcrystfel/src/indexers/fromfile.c | 96 ++++++++++++++++++++++++++++++------- libcrystfel/src/indexers/fromfile.h | 18 ++----- 4 files changed, 95 insertions(+), 38 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index f9001968..0ce9e2a2 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -208,7 +208,7 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, struct pinkIndexer_options* pinkIndexer_opts, struct felix_options *felix_opts, struct taketwo_options *taketwo_opts, - char *filename) + struct fromfile_options *fromfile_opts) { char *str; IndexingMethod in = *m; @@ -237,7 +237,7 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, break; case INDEXING_FILE : - priv = fromfile_prepare(filename, cell); + priv = fromfile_prepare(m, fromfile_opts); break; case INDEXING_FELIX : @@ -336,7 +336,7 @@ IndexingPrivate *setup_indexing(const char *method_list, struct xgandalf_options *xgandalf_opts, struct pinkIndexer_options *pinkIndexer_opts, struct felix_options *felix_opts, - char *filename) + struct fromfile_options *fromfile_opts) { IndexingPrivate *ipriv; IndexingMethod *methods; @@ -406,7 +406,7 @@ IndexingPrivate *setup_indexing(const char *method_list, pinkIndexer_opts, felix_opts, ttopts, - filename); + fromfile_opts); if ( ipriv->engine_private[i] == NULL ) return NULL; @@ -1213,10 +1213,12 @@ char *detect_indexing_methods(UnitCell *cell) void default_method_options(TakeTwoOptions **ttopts, XGandalfOptions **xgandalf_opts, PinkIndexerOptions **pinkIndexer_opts, - FelixOptions **felix_opts) + FelixOptions **felix_opts, + FromFileOptions **fromfile_opts) { taketwo_default_options(ttopts); xgandalf_default_options(xgandalf_opts); pinkIndexer_default_options(pinkIndexer_opts); felix_default_options(felix_opts); + fromfile_default_options(fromfile_opts); } diff --git a/libcrystfel/src/index.h b/libcrystfel/src/index.h index 5cee29b2..88b9b67e 100644 --- a/libcrystfel/src/index.h +++ b/libcrystfel/src/index.h @@ -152,16 +152,19 @@ typedef struct felix_options FelixOptions; typedef struct taketwo_options TakeTwoOptions; typedef struct xgandalf_options XGandalfOptions; typedef struct pinkIndexer_options PinkIndexerOptions; +typedef struct fromfile_options FromFileOptions; extern struct argp felix_argp; extern struct argp pinkIndexer_argp; extern struct argp taketwo_argp; extern struct argp xgandalf_argp; +extern struct argp fromfile_argp; extern void default_method_options(TakeTwoOptions **ttopts, XGandalfOptions **xgandalf_opts, PinkIndexerOptions **pinkIndexer_opts, - FelixOptions **felix_opts); + FelixOptions **felix_opts, + FromFileOptions **fromfile_opts); extern IndexingPrivate *setup_indexing(const char *methods, UnitCell *cell, @@ -173,7 +176,7 @@ extern IndexingPrivate *setup_indexing(const char *methods, struct xgandalf_options *xgandalf_opts, struct pinkIndexer_options *pinkIndexer_opts, struct felix_options *felix_opts, - char *filename); + struct fromfile_options *fromfile_opts); extern const IndexingMethod *indexing_methods(IndexingPrivate *p, int *n); diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index 73cee547..400683ae 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -5,6 +5,7 @@ * * Authors: * 2020 Pascal Hogan-Lamarre + * 2021 Thomas White * * This file is part of CrystFEL. * @@ -30,6 +31,7 @@ #include #include #include +#include #include "image.h" #include "uthash.h" @@ -45,6 +47,12 @@ #define NKEYS_PER_LINE 2 +struct fromfile_options +{ + char *filename; +}; + + struct fromfile_keys { char filename[100]; @@ -162,7 +170,7 @@ char *read_unknown_string(FILE *fh) } -void *fromfile_prepare(char *solution_filename, UnitCell *cell) +void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) { FILE *fh; int nlines; @@ -177,27 +185,15 @@ void *fromfile_prepare(char *solution_filename, UnitCell *cell) struct fromfile_entries *item = NULL; float params[NPARAMS_PER_LINE]; - /* Assembling solution file name from input file name*/ - char *path_to_sol; - size_t path_len; - char *core_name = strtok(solution_filename, "."); - char *extension = ".sol"; - path_len = sizeof(core_name) + sizeof(extension) + sizeof("../"); - path_to_sol = realloc(NULL, sizeof(char)*path_len); - strcpy(path_to_sol, "../"); - strcat(path_to_sol, core_name); - strcat(path_to_sol, extension); - - fh = fopen(path_to_sol, "r"); - + fh = fopen(opts->filename, "r"); if ( fh == NULL ) { - ERROR("%s not found by fromfile_prepare\n", path_to_sol); - return 0; + ERROR("%s not found by fromfile_prepare\n", opts->filename); + return NULL; } else { - STATUS("Found solution file %s\n", path_to_sol); + STATUS("Found solution file %s\n", opts->filename); } - nlines = ncrystals_in_sol(path_to_sol); + nlines = ncrystals_in_sol(opts->filename); /* Total crystal parameters in solution file */ nparams_in_solution = nlines*NPARAMS_PER_LINE; /* Total entries in solution file */ @@ -375,3 +371,67 @@ void fromfile_cleanup(void *mpriv) free(dp); } + + +static void fromfile_show_help() +{ + printf("Parameters for 'fromfile' indexing:\n" +" --fromfile-input-file\n" +" Filename of indexing solution file\n" +); +} + + +int fromfile_default_options(FromFileOptions **opts_ptr) +{ + FromFileOptions *opts; + opts = malloc(sizeof(struct fromfile_options)); + if ( opts == NULL ) return ENOMEM; + opts->filename = NULL; + *opts_ptr = opts; + return 0; +} + + +static error_t fromfile_parse_arg(int key, char *arg, + struct argp_state *state) +{ + struct fromfile_options **opts_ptr = state->input; + int r; + + switch ( key ) { + + case ARGP_KEY_INIT : + r = fromfile_default_options(opts_ptr); + if ( r ) return r; + break; + + case 1 : + fromfile_show_help(); + return EINVAL; + + case 2 : + (*opts_ptr)->filename = strdup(arg); + break; + + default : + return ARGP_ERR_UNKNOWN; + + } + + return 0; +} + + +static struct argp_option fromfile_options[] = { + + {"help-fromfile", 1, NULL, OPTION_NO_USAGE, + "Show options for 'from file' indexing", 99}, + + {"fromfile-input-file", 2, "filename", OPTION_HIDDEN, NULL}, + {0} +}; + + +struct argp fromfile_argp = { fromfile_options, fromfile_parse_arg, + NULL, NULL, NULL, NULL, NULL }; diff --git a/libcrystfel/src/indexers/fromfile.h b/libcrystfel/src/indexers/fromfile.h index deb7b105..ba7e1ee4 100644 --- a/libcrystfel/src/indexers/fromfile.h +++ b/libcrystfel/src/indexers/fromfile.h @@ -5,6 +5,7 @@ * * Authors: * 2020 Pascal Hogan-Lamarre + * 2021 Thomas White * * This file is part of CrystFEL. * @@ -26,23 +27,14 @@ #ifndef FROMFILE_H #define FROMFILE_H -struct fromfile_keys; -struct fromfile_entries; -struct fromfile_private; +#include #include "image.h" -#include "cell.h" -#include "uthash.h" - -extern void print_struct(struct fromfile_entries *sol_hash); - -extern void full_print_struct(struct fromfile_entries *sol_hash); - -extern void *fromfile_prepare(char *solution_filename, UnitCell *cell); +extern int fromfile_default_options(FromFileOptions **opts_ptr); +extern void *fromfile_prepare(IndexingMethod *indm, + struct fromfile_options *opts); extern int fromfile_index(struct image *image, void *mpriv, int crystal_number); - extern void fromfile_cleanup(void *mpriv); - #endif /* FROMFILE_H */ -- cgit v1.2.3 From d551cdbf3395b92d1542f6bcab07b9203054ce3b Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Mar 2021 12:09:29 +0100 Subject: Fix mode of uthash.h --- libcrystfel/src/uthash.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 libcrystfel/src/uthash.h (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/uthash.h b/libcrystfel/src/uthash.h old mode 100755 new mode 100644 -- cgit v1.2.3 From 42727512dc46459b349de68be835735ed26e186b Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Mar 2021 12:03:24 +0100 Subject: FromFile indexer: New parser and simplification of code Significant change: the solution file must now come with the lattice type, centering and (if applicable) unique axis information at the end of each line, e.g. 'cI' (cubic I), 'mAb' (monoclinic A, unique axis b). --- libcrystfel/src/indexers/fromfile.c | 436 ++++++++++++++++-------------------- 1 file changed, 198 insertions(+), 238 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index 400683ae..aa2c8999 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -38,336 +38,296 @@ /** \file fromfile.h */ -/* There are 9 vector components, - * 2 detector shifts, 1 profile radius, - * 1 resolution limit */ -#define NPARAMS_PER_LINE 11 -/* The keys read from file - * are the filename, event */ -#define NKEYS_PER_LINE 2 - - struct fromfile_options { char *filename; }; +#define MAX_KEY_LEN (256) +#define MAX_CRYSTALS (16) -struct fromfile_keys +struct fromfile_key { - char filename[100]; - char event[100]; - int crystal_number; + char filename[MAX_KEY_LEN]; + char event[MAX_KEY_LEN]; }; -struct fromfile_entries +struct fromfile_entry { - struct fromfile_keys key; - float solution[NPARAMS_PER_LINE]; + struct fromfile_key key_field; + Crystal *crystals[MAX_CRYSTALS]; + int n_crystals; UT_hash_handle hh; }; struct fromfile_private { - UnitCell *cellTemplate; - struct fromfile_entries *sol_hash; + struct fromfile_entry *sol_hash; }; -void print_struct(struct fromfile_entries *sol_hash) +static int make_key(struct fromfile_key *key, + const char *filename, const char *ev) { - struct fromfile_entries *s; + if ( (strlen(filename) > MAX_KEY_LEN) || (strlen(ev) > MAX_KEY_LEN) ) { + ERROR("Filename/event too long: %s %s\n", filename, ev); + return 1; + } - s = calloc(1, sizeof(struct fromfile_entries)); - if ( s == NULL ) return; + /* The entire structure is used as a key, not just the pre-terminator + * parts of the strings. Therefore it must be initialised to zero */ + memset(key, 0, sizeof(struct fromfile_key)); - for( s=sol_hash; s != NULL; s=s->hh.next ) { - printf("File %s, event %s, and crystal_number %d \n", - s->key.filename, s->key.event, s->key.crystal_number); - } + strcpy(key->filename, filename); + strcpy(key->event, ev); + + return 0; } -void full_print_struct(struct fromfile_entries *sol_hash) +struct fromfile_entry *add_unique(struct fromfile_entry **phead, + struct fromfile_key key) { - struct fromfile_entries *s; - s = calloc(1, sizeof(struct fromfile_entries)); - if ( s == NULL ) return; - - for( s=sol_hash; s != NULL; s=s->hh.next ) { - printf("File %s, event %s, and crystal_number %d \n", - s->key.filename, s->key.event, - s->key.crystal_number); - - printf("Solution parameters:\n"); - for( int i = 0; i < NPARAMS_PER_LINE; i++ ){ - printf("%e", s->solution[i]); - } - printf("\n"); + struct fromfile_entry *p; + struct fromfile_entry *head = *phead; + + HASH_FIND(hh, head, &key, sizeof(struct fromfile_key), p); + if ( p == NULL ) { + + struct fromfile_entry *item; + + item = malloc(sizeof(struct fromfile_entry)); + if ( item == NULL ) return NULL; + + item->n_crystals = 0; + item->key_field = key; + + HASH_ADD(hh, head, key_field, sizeof(struct fromfile_key), item); + *phead = head; + return item; + + } else { + return p; } } -int ncrystals_in_sol(char *path) +static int set_ua(UnitCell *cell, const char *ltsym) { - FILE *fh; - int count = 0; /* Line counter (result) */ - char c; /* To store a character read from file */ + if ( strlen(ltsym) != 3 ) return 1; + cell_set_unique_axis(cell, ltsym[2]); + return 0; +} - fh = fopen(path, "r"); - if ( fh == NULL ) { - ERROR("%s not found by ncrystals_in_sol\n", path); - return 0; - } +static int set_lattice(UnitCell *cell, const char *ltsym) +{ + if ( (strlen(ltsym) != 2) && (strlen(ltsym) != 3) ) return 1; + + switch ( ltsym[1] ) { + case 'P': + case 'A': + case 'B': + case 'C': + case 'I': + case 'F': + case 'R': + case 'H': + break; - for ( c = getc(fh); c != EOF; c = getc(fh) ) { - if ( c == '\n' ) { - count = count + 1; - } + default: + return 1; } + cell_set_centering(cell, ltsym[1]); - /* For the last line, which has no \n at the end*/ - count = count + 1; + switch ( ltsym[0] ) { - fclose(fh); + case 'a' : + cell_set_lattice_type(cell, L_TRICLINIC); + break; - return count; -} + case 'm' : + cell_set_lattice_type(cell, L_MONOCLINIC); + return set_ua(cell, ltsym); + case 'o' : + cell_set_lattice_type(cell, L_ORTHORHOMBIC); + break; -char *read_unknown_string(FILE *fh) -{ - /* Source: "https://stackoverflow.com/questions/16870485/ - * how-can-i-read-an-input-string-of-unknown-length" */ + case 't' : + cell_set_lattice_type(cell, L_TETRAGONAL); + return set_ua(cell, ltsym); - char *str = NULL; - int ch; - size_t len = 0; - size_t size = 1; + case 'c' : + cell_set_lattice_type(cell, L_CUBIC); + break; - str = realloc(NULL, sizeof(char)*size); //size is start size - if ( !str ) { - ERROR("Can't reallocate string size"); - } + case 'r' : + cell_set_lattice_type(cell, L_RHOMBOHEDRAL); + break; - while( ( ch = fgetc(fh) ) != ' ' && ch != EOF ){ - if (ch != '\n'){ - str[len++]=ch; - } - if(len==size){ - size+=64; - str = realloc(str, sizeof(char)*(size)); - if ( !str ) { - ERROR("Can't reallocate string size"); - } - } + case 'h' : + cell_set_lattice_type(cell, L_HEXAGONAL); + return set_ua(cell, ltsym); + + default : + return 1; } - return realloc(str, sizeof(char)*len); + return 0; } void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) { FILE *fh; - int nlines; - int nparams_in_solution; - int nentries; - char *filename; - char *event; - int crystal_number; - int current_line; - int position_in_current_line; - struct fromfile_entries *sol_hash = NULL; - struct fromfile_entries *item = NULL; - float params[NPARAMS_PER_LINE]; + struct fromfile_private *dp; - fh = fopen(opts->filename, "r"); - if ( fh == NULL ) { - ERROR("%s not found by fromfile_prepare\n", opts->filename); + if ( opts->filename == NULL ) { + ERROR("Please try again with --fromfile-input-file\n"); return NULL; - } else { - STATUS("Found solution file %s\n", opts->filename); } - nlines = ncrystals_in_sol(opts->filename); - /* Total crystal parameters in solution file */ - nparams_in_solution = nlines*NPARAMS_PER_LINE; - /* Total entries in solution file */ - nentries = nlines*(NPARAMS_PER_LINE+NKEYS_PER_LINE); - - STATUS("Parsing solution file containing %d lines...\n", nlines); - - /* Reads indexing solutions */ - int j = 0; /* follows the solution parameter [0,NPARAMS_PER_LINE] */ - for(int i = 0; i < nentries; i++) { - - crystal_number = 0; - - current_line = i/(NPARAMS_PER_LINE+NKEYS_PER_LINE); - - position_in_current_line = (i)%(NPARAMS_PER_LINE+NKEYS_PER_LINE); - - if ( position_in_current_line == 0 ) { + dp = malloc(sizeof(struct fromfile_private)); + if ( dp == NULL ) return NULL; - filename = read_unknown_string(fh); - - if ( !filename ){ - if ( current_line == nlines-1 ) break; - printf("Failed to read a filename\n"); - return 0; - } + fh = fopen(opts->filename, "r"); + if ( fh == NULL ) { + ERROR("Couldn't find solution file '%s'\n", opts->filename); + return NULL; + } + dp->sol_hash = NULL; + + /* Read indexing solutions */ + do { + + char *rval; + char line[1024]; + int i, n; + char **bits; + float vals[11]; + struct fromfile_key key; + Crystal *cr; + UnitCell *cell; + struct fromfile_entry *item = NULL; + + rval = fgets(line, 1023, fh); + if ( rval == NULL ) break; + + /* FIXME: Replace this with something that can handle quoted + * filenames with possible spaces */ + chomp(line); + notrail(line); + n = assplode(line, " \t,", &bits, ASSPLODE_NONE); + if ( n < 14 ) { + ERROR("Badly formatted line '%s'\n", line); + return NULL; } - if ( position_in_current_line == 1 ) { - event = read_unknown_string(fh); - if ( !event ){ - printf("Failed to read a event\n"); - return 0; + /* filename, event, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz, + * det_shift_x, det_shift_y, latticetype+centering */ + for ( i=2; i<13; i++ ) { + if (sscanf(bits[i], "%f", &vals[i-2]) != 1) + { + ERROR("Invalid value for number %i\n", i); + return NULL; } + } + if ( make_key(&key, bits[0], bits[1]) ) { + ERROR("Failed to make key for %s %s\n", + bits[0], bits[1]); + continue; } - if ( position_in_current_line > 1 ) { - if ( fscanf(fh, "%e", ¶ms[j]) != 1 ) { - printf("Failed to read a parameter\n"); - return 0; - } - j+=1; + item = add_unique(&dp->sol_hash, key); + if ( item == NULL ) { + ERROR("Failed to add/find entry for %s %s\n", + bits[0], bits[1]); + continue; } - if ( j == (NPARAMS_PER_LINE) ) { + if ( item->n_crystals == MAX_CRYSTALS ) { - /* Prepare to add to the hash table */ - item = (struct fromfile_entries *)malloc(sizeof *item); - memset(item, 0, sizeof *item); - strcpy(item->key.filename, filename); - strcpy(item->key.event, event); - item->key.crystal_number = crystal_number; - for ( int k = 0; k < NPARAMS_PER_LINE; k++){ - item->solution[k] = params[k]; - } + ERROR("Too many crystals for %s %s\n", bits[0], bits[1]); - /* Verify the uniqueness of the key */ - struct fromfile_entries *uniqueness_test; - HASH_FIND(hh, sol_hash, &item->key, - sizeof(struct fromfile_keys), uniqueness_test); + } else { - if ( uniqueness_test == NULL ) { - HASH_ADD(hh, sol_hash, key, - sizeof(struct fromfile_keys), item); + cr = crystal_new(); + + /* mm -> m */ + crystal_set_det_shift(cr, vals[9]*1e-3, vals[10]*1e-3); + + cell = cell_new(); + cell_set_reciprocal(cell, vals[0]*1e9, vals[1]*1e9, vals[2]*1e9, + vals[3]*1e9, vals[4]*1e9, vals[5]*1e9, + vals[6]*1e9, vals[7]*1e9, vals[8]*1e9); + if ( set_lattice(cell, bits[13]) ) { + ERROR("Invalid lattice type '%s'\n", bits[13]); } else { - /* Look for the next available set of keys */ - do { - uniqueness_test = NULL; - crystal_number += 1; - item->key.crystal_number = crystal_number; - HASH_FIND(hh, sol_hash, &item->key, - sizeof(struct fromfile_keys), - uniqueness_test); - } while ( uniqueness_test != NULL ); - - HASH_ADD(hh, sol_hash, key, - sizeof(struct fromfile_keys), item); + crystal_set_cell(cr, cell); + item->crystals[item->n_crystals++] = cr; } - j=0; - } - } - fclose(fh); + for ( i=0; icellTemplate = cell; - dp->sol_hash = sol_hash; + fclose(fh); - STATUS("Solution lookup table initialized!\n"); + STATUS("Read %i crystals from %s\n", + HASH_CNT(hh, dp->sol_hash), opts->filename); - return (void *)dp; + return dp; } -int fromfile_index(struct image *image, void *mpriv, int crystal_number) +int fromfile_index(struct image *image, void *mpriv) { - Crystal *cr; - UnitCell *cell; - float asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - float xshift, yshift; - struct fromfile_entries *item, *p, *pprime; - int ncryst = 0; - float *sol; + struct fromfile_entry *p; struct fromfile_private *dp = mpriv; + struct fromfile_key key; + int i; + + make_key(&key, image->filename, image->ev); - /* Look up the hash table */ - item = calloc(1, sizeof(struct fromfile_entries)); - strcpy(item->key.filename, image->filename); - strcpy(item->key.event, image->ev); - item->key.crystal_number = crystal_number; - - /* key already in the hash? */ - HASH_FIND(hh, dp->sol_hash, &item->key, sizeof(struct fromfile_keys), p); - if ( p == NULL ) return 0; - - sol = &(p->solution)[0]; - - asx = sol[0] * 1e9; - asy = sol[1] * 1e9; - asz = sol[2] * 1e9; - bsx = sol[3] * 1e9; - bsy = sol[4] * 1e9; - bsz = sol[5] * 1e9; - csx = sol[6] * 1e9; - csy = sol[7] * 1e9; - csz = sol[8] * 1e9; - xshift = sol[9] * 1e-3; - yshift = sol[10] * 1e-3; - - cell = cell_new(); - cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); - cell_set_lattice_type(cell, cell_get_lattice_type(dp->cellTemplate)); - cell_set_centering(cell, cell_get_centering(dp->cellTemplate)); - cell_set_unique_axis(cell, cell_get_unique_axis(dp->cellTemplate)); - - cr = crystal_new(); - ncryst += 1; - crystal_set_cell(cr, cell); - crystal_set_det_shift(cr, xshift , yshift); - image_add_crystal(image, cr); - - /* Look for additional crystals */ - item->key.crystal_number = crystal_number+1; - HASH_FIND(hh, dp->sol_hash, &item->key, - sizeof(struct fromfile_keys), pprime); - - /* If a similar tag exist, - * recursive call increasing the crystal_number by 1 */ - if ( pprime != NULL ) { - ncryst += fromfile_index(image, mpriv, crystal_number+1); + HASH_FIND(hh, dp->sol_hash, &key, sizeof(struct fromfile_key), p); + if ( p == NULL ) { + STATUS("WARNING: No solution for %s %s\n", + image->filename, image->ev); + return 0; } - return ncryst; + for ( i=0; in_crystals; i++ ) { + Crystal *cr; + cr = crystal_copy_deep(p->crystals[i]); + image_add_crystal(image, cr); + } + + return p->n_crystals; } void fromfile_cleanup(void *mpriv) { struct fromfile_private *dp = mpriv; - - /* FIXME: Implementation */ + struct fromfile_entry *item, *tmp; + + HASH_ITER(hh, dp->sol_hash, item, tmp) { + int i; + HASH_DEL(dp->sol_hash, item); + for ( i=0; in_crystals; i++ ) { + Crystal *cr = item->crystals[i]; + cell_free(crystal_get_cell(cr)); + crystal_free(cr); + } + } free(dp); } -- cgit v1.2.3 From 4084ac4ad8d745b12f97c9881e0fb50a0ac21da4 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Mar 2021 14:08:28 +0100 Subject: FromFile indexer: Take account of working directory --- libcrystfel/src/indexers/fromfile.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index aa2c8999..f39a717b 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -190,15 +190,26 @@ void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) return NULL; } - dp = malloc(sizeof(struct fromfile_private)); - if ( dp == NULL ) return NULL; + /* If filename is not absolute, jump out of working directory */ + if ( opts->filename[0] == '/' ) { + fh = fopen(opts->filename, "r"); + } else { + char *prefixed_fn = malloc(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); + } - fh = fopen(opts->filename, "r"); if ( fh == NULL ) { ERROR("Couldn't find solution file '%s'\n", opts->filename); return NULL; } + dp = malloc(sizeof(struct fromfile_private)); + if ( dp == NULL ) return NULL; + dp->sol_hash = NULL; /* Read indexing solutions */ -- cgit v1.2.3 From b49baa8da32331cf1880d3eeab0d51560a0efca3 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 19 Mar 2021 14:09:26 +0100 Subject: FromFile indexer: add copyright notice There is presumably an MPSD that also needs to be added. --- libcrystfel/src/indexers/fromfile.c | 3 +++ libcrystfel/src/indexers/fromfile.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'libcrystfel/src') diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index f39a717b..782934d7 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -3,6 +3,9 @@ * * Perform indexing from solution file * + * Copyright © 2021 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * * Authors: * 2020 Pascal Hogan-Lamarre * 2021 Thomas White diff --git a/libcrystfel/src/indexers/fromfile.h b/libcrystfel/src/indexers/fromfile.h index ba7e1ee4..5f1d24d9 100644 --- a/libcrystfel/src/indexers/fromfile.h +++ b/libcrystfel/src/indexers/fromfile.h @@ -3,6 +3,9 @@ * * Perform indexing from solution file * + * Copyright © 2021 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * * Authors: * 2020 Pascal Hogan-Lamarre * 2021 Thomas White -- cgit v1.2.3