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/indexers/fromfile.c | 389 ++++++++++++++++++++++++++++++++++++ libcrystfel/src/indexers/fromfile.h | 47 +++++ 2 files changed, 436 insertions(+) create mode 100644 libcrystfel/src/indexers/fromfile.c create mode 100644 libcrystfel/src/indexers/fromfile.h (limited to 'libcrystfel/src/indexers') 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 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/indexers') 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/indexers') 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/indexers') 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/indexers') 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/indexers') 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/indexers') 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/indexers/fromfile.c | 10 ++++++++++ libcrystfel/src/indexers/fromfile.h | 2 ++ 2 files changed, 12 insertions(+) (limited to 'libcrystfel/src/indexers') 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/indexers/fromfile.c | 96 ++++++++++++++++++++++++++++++------- libcrystfel/src/indexers/fromfile.h | 18 ++----- 2 files changed, 83 insertions(+), 31 deletions(-) (limited to 'libcrystfel/src/indexers') 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 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/indexers') 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/indexers') 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/indexers') 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