diff options
author | Thomas White <taw@physics.org> | 2011-11-15 13:59:17 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2012-02-22 15:27:40 +0100 |
commit | 25c3d29ed7701cadbb3813878f25b633a7cd7c2d (patch) | |
tree | 2efd3bd84ee6948543b0bc89053f7654047b8542 /src | |
parent | fb9df2f18def2d0b8fbdbc854c8a8c10e39ce6d9 (diff) |
Move indexing and rendering to libcrystfel
Diffstat (limited to 'src')
-rw-r--r-- | src/dirax.c | 529 | ||||
-rw-r--r-- | src/dirax.h | 26 | ||||
-rw-r--r-- | src/index-priv.h | 29 | ||||
-rw-r--r-- | src/index.c | 274 | ||||
-rw-r--r-- | src/index.h | 63 | ||||
-rw-r--r-- | src/mosflm.c | 609 | ||||
-rw-r--r-- | src/mosflm.h | 27 | ||||
-rw-r--r-- | src/reax.c | 728 | ||||
-rw-r--r-- | src/reax.h | 27 | ||||
-rw-r--r-- | src/render.c | 442 | ||||
-rw-r--r-- | src/render.h | 55 |
11 files changed, 0 insertions, 2809 deletions
diff --git a/src/dirax.c b/src/dirax.c deleted file mode 100644 index bb1cb808..00000000 --- a/src/dirax.c +++ /dev/null @@ -1,529 +0,0 @@ -/* - * dirax.c - * - * Invoke the DirAx auto-indexing program - * - * (c) 2006-2010 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <string.h> -#include <unistd.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <assert.h> -#include <sys/ioctl.h> -#include <errno.h> - -#if HAVE_FORKPTY_LINUX -#include <pty.h> -#elif HAVE_FORKPTY_BSD -#include <util.h> -#endif - - -#include "image.h" -#include "dirax.h" -#include "utils.h" -#include "peaks.h" - - -#define DIRAX_VERBOSE 0 - -#define MAX_DIRAX_CELL_CANDIDATES (5) - - -typedef enum { - DIRAX_INPUT_NONE, - DIRAX_INPUT_LINE, - DIRAX_INPUT_PROMPT, - DIRAX_INPUT_ACL -} DirAxInputType; - - -struct dirax_data { - - /* DirAx auto-indexing low-level stuff */ - int pty; - pid_t pid; - char *rbuffer; - int rbufpos; - int rbuflen; - - /* DirAx auto-indexing high-level stuff */ - int step; - int finished_ok; - int read_cell; - int best_acl; - int best_acl_nh; - int acls_tried[MAX_CELL_CANDIDATES]; - int n_acls_tried; - -}; - - -static void dirax_parseline(const char *line, struct image *image, - struct dirax_data *dirax) -{ - int rf, i, di, acl, acl_nh; - float d; - - #if DIRAX_VERBOSE - char *copy; - - copy = strdup(line); - for ( i=0; i<strlen(copy); i++ ) { - if ( copy[i] == '\r' ) copy[i]='r'; - if ( copy[i] == '\n' ) copy[i]='\0'; - } - STATUS("DirAx: %s\n", copy); - free(copy); - #endif - - if ( strstr(line, "reflections from file") ) { - ERROR("DirAx can't understand this data.\n"); - return; - } - - /* Is this the first line of a unit cell specification? */ - rf = 0; i = 0; - while ( (i<strlen(line)) && ((line[i] == 'R') - || (line[i] == 'D') || (line[i] == ' ')) ) { - if ( line[i] == 'R' ) rf = 1; - if ( (line[i] == 'D') && rf ) { - dirax->read_cell = 1; - image->candidate_cells[image->ncells] = cell_new(); - return; - } - i++; - } - - /* Parse unit cell vectors as appropriate */ - if ( dirax->read_cell == 1 ) { - /* First row of unit cell values */ - float ax, ay, az; - int r; - r = sscanf(line, "%f %f %f %f %f %f", - &d, &d, &d, &ax, &ay, &az); - if ( r != 6 ) { - ERROR("Couldn't understand cell line:\n"); - ERROR("'%s'\n", line); - dirax->read_cell = 0; - cell_free(image->candidate_cells[image->ncells]); - return; - } - cell_set_cartesian_a(image->candidate_cells[image->ncells], - ax*1e-10, ay*1e-10, az*1e-10); - dirax->read_cell++; - return; - } else if ( dirax->read_cell == 2 ) { - /* Second row of unit cell values */ - float bx, by, bz; - int r; - r = sscanf(line, "%f %f %f %f %f %f", - &d, &d, &d, &bx, &by, &bz); - if ( r != 6 ) { - ERROR("Couldn't understand cell line:\n"); - ERROR("'%s'\n", line); - dirax->read_cell = 0; - cell_free(image->candidate_cells[image->ncells]); - return; - } - cell_set_cartesian_b(image->candidate_cells[image->ncells], - bx*1e-10, by*1e-10, bz*1e-10); - dirax->read_cell++; - return; - } else if ( dirax->read_cell == 3 ) { - /* Third row of unit cell values */ - float cx, cy, cz; - int r; - r = sscanf(line, "%f %f %f %f %f %f", - &d, &d, &d, &cx, &cy, &cz); - if ( r != 6 ) { - ERROR("Couldn't understand cell line:\n"); - ERROR("'%s'\n", line); - dirax->read_cell = 0; - cell_free(image->candidate_cells[image->ncells]); - return; - } - cell_set_cartesian_c(image->candidate_cells[image->ncells++], - cx*1e-10, cy*1e-10, cz*1e-10); - dirax->read_cell = 0; - return; - } - - dirax->read_cell = 0; - - if ( sscanf(line, "%i %i %f %f %f %f %f %f %i", &acl, &acl_nh, - &d, &d, &d, &d, &d, &d, &di) == 9 ) { - if ( acl_nh > dirax->best_acl_nh ) { - - int i, found = 0; - - for ( i=0; i<dirax->n_acls_tried; i++ ) { - if ( dirax->acls_tried[i] == acl ) found = 1; - } - - if ( !found ) { - dirax->best_acl_nh = acl_nh; - dirax->best_acl = acl; - } - - } - } -} - - -static void dirax_sendline(const char *line, struct dirax_data *dirax) -{ - #if DIRAX_VERBOSE - char *copy; - int i; - - copy = strdup(line); - for ( i=0; i<strlen(copy); i++ ) { - if ( copy[i] == '\r' ) copy[i]='\0'; - if ( copy[i] == '\n' ) copy[i]='\0'; - } - STATUS("To DirAx: '%s'\n", copy); - free(copy); - #endif - - write(dirax->pty, line, strlen(line)); -} - - -static void dirax_send_next(struct image *image, struct dirax_data *dirax) -{ - char tmp[32]; - - switch ( dirax->step ) { - - case 1 : - dirax_sendline("\\echo off\n", dirax); - break; - - case 2 : - snprintf(tmp, 31, "read xfel-%i.drx\n", image->id); - dirax_sendline(tmp, dirax); - break; - - case 3 : - dirax_sendline("dmax 1000\n", dirax); - break; - - case 4 : - dirax_sendline("indexfit 2\n", dirax); - break; - - case 5 : - dirax_sendline("levelfit 1000\n", dirax); - break; - - case 6 : - dirax_sendline("go\n", dirax); - dirax->finished_ok = 1; - break; - - case 7 : - dirax_sendline("acl\n", dirax); - break; - - case 8 : - if ( dirax->best_acl_nh == 0 ) { - /* At this point, DirAx is presenting its ACL prompt - * and waiting for a single number. Use an extra - * newline to choose automatic ACL selection before - * exiting. */ - dirax_sendline("\nexit\n", dirax); - break; - } - snprintf(tmp, 31, "%i\n", dirax->best_acl); - dirax->acls_tried[dirax->n_acls_tried++] = dirax->best_acl; - dirax_sendline(tmp, dirax); - break; - - case 9 : - dirax_sendline("cell\n", dirax); - break; - - case 10 : - if ( dirax->n_acls_tried == MAX_DIRAX_CELL_CANDIDATES ) { - dirax_sendline("exit\n", dirax); - } else { - /* Go back round for another cell */ - dirax->best_acl_nh = 0; - dirax->step = 7; - dirax_sendline("acl\n", dirax); - } - break; - - default: - dirax_sendline("exit\n", dirax); - return; - - } - - dirax->step++; -} - - -static int dirax_readable(struct image *image, struct dirax_data *dirax) -{ - int rval; - int no_string = 0; - - rval = read(dirax->pty, dirax->rbuffer+dirax->rbufpos, - dirax->rbuflen-dirax->rbufpos); - - if ( (rval == -1) || (rval == 0) ) return 1; - - dirax->rbufpos += rval; - assert(dirax->rbufpos <= dirax->rbuflen); - - while ( (!no_string) && (dirax->rbufpos > 0) ) { - - int i; - int block_ready = 0; - DirAxInputType type = DIRAX_INPUT_NONE; - - /* See if there's a full line in the buffer yet */ - for ( i=0; i<dirax->rbufpos-1; i++ ) { - /* Means the last value looked at is rbufpos-2 */ - - /* Is there a prompt in the buffer? */ - if ( (i+7 <= dirax->rbufpos) - && (!strncmp(dirax->rbuffer+i, "Dirax> ", 7)) ) { - block_ready = 1; - type = DIRAX_INPUT_PROMPT; - break; - } - - /* How about an ACL prompt? */ - if ( (i+10 <= dirax->rbufpos) - && (!strncmp(dirax->rbuffer+i, "acl/auto [", 10)) ) { - block_ready = 1; - type = DIRAX_INPUT_ACL; - break; - } - - if ( (dirax->rbuffer[i] == '\r') - && (dirax->rbuffer[i+1] == '\n') ) { - block_ready = 1; - type = DIRAX_INPUT_LINE; - break; - } - - } - - if ( block_ready ) { - - unsigned int new_rbuflen; - unsigned int endbit_length; - char *block_buffer = NULL; - - switch ( type ) { - - case DIRAX_INPUT_LINE : - - block_buffer = malloc(i+1); - memcpy(block_buffer, dirax->rbuffer, i); - block_buffer[i] = '\0'; - - if ( block_buffer[0] == '\r' ) { - memmove(block_buffer, block_buffer+1, i); - } - - dirax_parseline(block_buffer, image, dirax); - free(block_buffer); - endbit_length = i+2; - break; - - case DIRAX_INPUT_PROMPT : - - dirax_send_next(image, dirax); - endbit_length = i+7; - break; - - case DIRAX_INPUT_ACL : - - dirax_send_next(image,dirax ); - endbit_length = i+10; - break; - - default : - - /* Obviously, this never happens :) */ - ERROR("Unrecognised DirAx input mode! " - "I don't know how to understand DirAx\n"); - return 1; - - } - - /* Now the block's been parsed, it should be - * forgotten about */ - memmove(dirax->rbuffer, - dirax->rbuffer + endbit_length, - dirax->rbuflen - endbit_length); - - /* Subtract the number of bytes removed */ - dirax->rbufpos = dirax->rbufpos - - endbit_length; - new_rbuflen = dirax->rbuflen - endbit_length; - if ( new_rbuflen == 0 ) new_rbuflen = 256; - dirax->rbuffer = realloc(dirax->rbuffer, - new_rbuflen); - dirax->rbuflen = new_rbuflen; - - } else { - - if ( dirax->rbufpos==dirax->rbuflen ) { - - /* More buffer space is needed */ - dirax->rbuffer = realloc( - dirax->rbuffer, - dirax->rbuflen + 256); - dirax->rbuflen = dirax->rbuflen - + 256; - /* The new space gets used at the next - * read, shortly... */ - - } - no_string = 1; - - } - - } - - return 0; -} - - -static void write_drx(struct image *image) -{ - FILE *fh; - int i; - char filename[1024]; - - snprintf(filename, 1023, "xfel-%i.drx", image->id); - - fh = fopen(filename, "w"); - if ( !fh ) { - ERROR("Couldn't open temporary file '%s'\n", filename); - return; - } - fprintf(fh, "%f\n", 0.5); /* Lie about the wavelength. */ - - for ( i=0; i<image_feature_count(image->features); i++ ) { - - struct imagefeature *f; - - f = image_get_feature(image->features, i); - if ( f == NULL ) continue; - - fprintf(fh, "%10f %10f %10f %8f\n", - f->rx/1e10, f->ry/1e10, f->rz/1e10, 1.0); - - } - fclose(fh); -} - - -void run_dirax(struct image *image) -{ - unsigned int opts; - int status; - int rval; - struct dirax_data *dirax; - - write_drx(image); - - dirax = malloc(sizeof(struct dirax_data)); - if ( dirax == NULL ) { - ERROR("Couldn't allocate memory for DirAx data.\n"); - return; - } - - dirax->pid = forkpty(&dirax->pty, NULL, NULL, NULL); - if ( dirax->pid == -1 ) { - ERROR("Failed to fork for DirAx\n"); - return; - } - if ( dirax->pid == 0 ) { - - /* Child process: invoke DirAx */ - struct termios t; - - /* Turn echo off */ - tcgetattr(STDIN_FILENO, &t); - t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); - tcsetattr(STDIN_FILENO, TCSANOW, &t); - - execlp("dirax", "", (char *)NULL); - ERROR("Failed to invoke DirAx.\n"); - _exit(0); - - } - - dirax->rbuffer = malloc(256); - dirax->rbuflen = 256; - dirax->rbufpos = 0; - - /* Set non-blocking */ - opts = fcntl(dirax->pty, F_GETFL); - fcntl(dirax->pty, F_SETFL, opts | O_NONBLOCK); - - dirax->step = 1; /* This starts the "initialisation" procedure */ - dirax->finished_ok = 0; - dirax->read_cell = 0; - dirax->n_acls_tried = 0; - dirax->best_acl_nh = 0; - - do { - - fd_set fds; - struct timeval tv; - int sval; - - FD_ZERO(&fds); - FD_SET(dirax->pty, &fds); - - tv.tv_sec = 10; - tv.tv_usec = 0; - - sval = select(dirax->pty+1, &fds, NULL, NULL, &tv); - - if ( sval == -1 ) { - int err = errno; - ERROR("select() failed: %s\n", strerror(err)); - rval = 1; - } else if ( sval != 0 ) { - rval = dirax_readable(image, dirax); - } else { - ERROR("No response from DirAx..\n"); - rval = 1; - } - - } while ( !rval ); - - close(dirax->pty); - free(dirax->rbuffer); - waitpid(dirax->pid, &status, 0); - - if ( dirax->finished_ok == 0 ) { - ERROR("DirAx doesn't seem to be working properly.\n"); - } - - free(dirax); -} diff --git a/src/dirax.h b/src/dirax.h deleted file mode 100644 index 8c429710..00000000 --- a/src/dirax.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * dirax.h - * - * Invoke the DirAx auto-indexing program - * - * (c) 2006-2010 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifndef DIRAX_H -#define DIRAX_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "utils.h" - - -extern void run_dirax(struct image *image); - - -#endif /* DIRAX_H */ diff --git a/src/index-priv.h b/src/index-priv.h deleted file mode 100644 index 3d8c8a22..00000000 --- a/src/index-priv.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * index-priv.h - * - * Indexing private data - * - * (c) 2006-2010 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifndef INDEXPRIV_H -#define INDEXPRIV_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -#include "index.h" - -struct _indexingprivate -{ - IndexingMethod indm; -}; - - -#endif /* INDEXPRIV_H */ diff --git a/src/index.c b/src/index.c deleted file mode 100644 index d5e76c50..00000000 --- a/src/index.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * index.c - * - * Perform indexing (somehow) - * - * (c) 2006-2011 Thomas White <taw@physics.org> - * (c) 2010 Richard Kirian <rkirian@asu.edu> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <string.h> -#include <assert.h> - -#include "image.h" -#include "utils.h" -#include "peaks.h" -#include "dirax.h" -#include "mosflm.h" -#include "detector.h" -#include "index.h" -#include "index-priv.h" -#include "reax.h" -#include "geometry.h" - - -/* Base class constructor for unspecialised indexing private data */ -IndexingPrivate *indexing_private(IndexingMethod indm) -{ - struct _indexingprivate *priv; - priv = calloc(1, sizeof(struct _indexingprivate)); - priv->indm = indm; - return priv; -} - - -static const char *maybes(int n) -{ - if ( n == 1 ) return ""; - return "s"; -} - - -IndexingPrivate **prepare_indexing(IndexingMethod *indm, UnitCell *cell, - const char *filename, struct detector *det, - double nominal_photon_energy) -{ - int n; - int nm = 0; - IndexingPrivate **iprivs; - - while ( indm[nm] != INDEXING_NONE ) nm++; - STATUS("Preparing %i indexing method%s.\n", nm, maybes(nm)); - iprivs = malloc((nm+1) * sizeof(IndexingPrivate *)); - - for ( n=0; n<nm; n++ ) { - - switch ( indm[n] ) { - case INDEXING_NONE : - ERROR("Tried to prepare INDEXING_NONE!\n"); - break; - case INDEXING_DIRAX : - iprivs[n] = indexing_private(indm[n]); - break; - case INDEXING_MOSFLM : - iprivs[n] = indexing_private(indm[n]); - break; - case INDEXING_REAX : - iprivs[n] = reax_prepare(); - break; - } - - } - iprivs[n] = NULL; - - return iprivs; -} - - -void cleanup_indexing(IndexingPrivate **priv) -{ - int n = 0; - - if ( priv == NULL ) return; /* Nothing to do */ - - while ( priv[n] != NULL ) { - - switch ( priv[n]->indm ) { - case INDEXING_NONE : - free(priv[n]); - break; - case INDEXING_DIRAX : - free(priv[n]); - break; - case INDEXING_MOSFLM : - free(priv[n]); - break; - case INDEXING_REAX : - reax_cleanup(priv[n]); - break; - } - - n++; - - } -} - - -void map_all_peaks(struct image *image) -{ - int i, n; - - n = image_feature_count(image->features); - - /* Map positions to 3D */ - for ( i=0; i<n; i++ ) { - - struct imagefeature *f; - struct rvec r; - - f = image_get_feature(image->features, i); - if ( f == NULL ) continue; - - r = get_q(image, f->fs, f->ss, NULL, 1.0/image->lambda); - f->rx = r.u; f->ry = r.v; f->rz = r.w; - - } -} - - -void index_pattern(struct image *image, UnitCell *cell, IndexingMethod *indm, - int cellr, int verbose, IndexingPrivate **ipriv, - int config_insane) -{ - int i; - int n = 0; - - if ( indm == NULL ) return; - - map_all_peaks(image); - image->indexed_cell = NULL; - - while ( indm[n] != INDEXING_NONE ) { - - image->ncells = 0; - - /* Index as appropriate */ - switch ( indm[n] ) { - case INDEXING_NONE : - return; - case INDEXING_DIRAX : - run_dirax(image); - break; - case INDEXING_MOSFLM : - run_mosflm(image, cell); - break; - case INDEXING_REAX : - reax_index(ipriv[n], image, cell); - break; - } - if ( image->ncells == 0 ) { - n++; - continue; - } - - for ( i=0; i<image->ncells; i++ ) { - - UnitCell *new_cell = NULL; - UnitCell *cand = image->candidate_cells[i]; - - if ( verbose ) { - STATUS("--------------------\n"); - STATUS("Candidate cell %i (before matching):\n", - i); - cell_print(image->candidate_cells[i]); - STATUS("--------------------\n"); - } - - /* Match or reduce the cell as appropriate */ - switch ( cellr ) { - case CELLR_NONE : - new_cell = cell_new_from_cell(cand); - break; - case CELLR_REDUCE : - new_cell = match_cell(cand, cell, verbose, 1); - break; - case CELLR_COMPARE : - new_cell = match_cell(cand, cell, verbose, 0); - break; - case CELLR_COMPARE_AB : - new_cell = match_cell_ab(cand, cell); - break; - } - - /* No cell? Move on to the next candidate */ - if ( new_cell == NULL ) continue; - - /* Sanity check */ - image->reflections = find_intersections(image, new_cell); - image->indexed_cell = new_cell; - - if ( !config_insane && !peak_sanity_check(image) ) { - cell_free(new_cell); - image->indexed_cell = NULL; - continue; - } - - goto done; /* Success */ - - } - - for ( i=0; i<image->ncells; i++ ) { - cell_free(image->candidate_cells[i]); - image->candidate_cells[i] = NULL; - } - - /* Move on to the next indexing method */ - n++; - - } - -done: - for ( i=0; i<image->ncells; i++ ) { - /* May free(NULL) if all algorithms were tried and no success */ - cell_free(image->candidate_cells[i]); - } -} - - -IndexingMethod *build_indexer_list(const char *str, int *need_cell) -{ - int n, i; - char **methods; - IndexingMethod *list; - int tmp; - - if ( need_cell == NULL ) need_cell = &tmp; - *need_cell = 0; - - n = assplode(str, ",", &methods, ASSPLODE_NONE); - list = malloc((n+1)*sizeof(IndexingMethod)); - - for ( i=0; i<n; i++ ) { - - if ( strcmp(methods[i], "dirax") == 0) { - list[i] = INDEXING_DIRAX; - } else if ( strcmp(methods[i], "mosflm") == 0) { - list[i] = INDEXING_MOSFLM; - } else if ( strcmp(methods[i], "reax") == 0) { - list[i] = INDEXING_REAX; - *need_cell = 1; - } else { - ERROR("Unrecognised indexing method '%s'\n", - methods[i]); - return NULL; - } - - free(methods[i]); - - } - free(methods); - list[i] = INDEXING_NONE; - - return list; -} diff --git a/src/index.h b/src/index.h deleted file mode 100644 index 9d4b69bd..00000000 --- a/src/index.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * index.h - * - * Perform indexing (somehow) - * - * (c) 2006-2010 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifndef INDEX_H -#define INDEX_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -#include "cell.h" -#include "image.h" -#include "detector.h" - - -/* Indexing methods */ -typedef enum { - INDEXING_NONE, - INDEXING_DIRAX, - INDEXING_MOSFLM, - INDEXING_REAX, -} IndexingMethod; - - -/* Cell reduction methods */ -enum { - CELLR_NONE, - CELLR_REDUCE, - CELLR_COMPARE, - CELLR_COMPARE_AB, -}; - - -typedef struct _indexingprivate IndexingPrivate; - -extern IndexingPrivate *indexing_private(IndexingMethod indm); - -extern IndexingPrivate **prepare_indexing(IndexingMethod *indm, UnitCell *cell, - const char *filename, - struct detector *det, - double nominal_photon_energy); - -extern void map_all_peaks(struct image *image); - -extern void index_pattern(struct image *image, UnitCell *cell, - IndexingMethod *indm, int cellr, int verbose, - IndexingPrivate **priv, int config_insane); - -extern void cleanup_indexing(IndexingPrivate **priv); - -extern IndexingMethod *build_indexer_list(const char *str, int *need_cell); - -#endif /* INDEX_H */ diff --git a/src/mosflm.c b/src/mosflm.c deleted file mode 100644 index 5df5af21..00000000 --- a/src/mosflm.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * mosflm.c - * - * Invoke the DPS auto-indexing algorithm through MOSFLM - * - * (c) 2010 Richard Kirian <rkirian@asu.edu> - * (c) 2006-2010 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - -/* TODO: - * - * Properly read the newmat file (don't use fscanf-- spaces between numers - * are not guaranteed) - * - * "Success" is indicated by existence of NEWMAT file written by mosflm. - * Better to interact with mosflm directly in order to somehow verify success. - * - * Investigate how these keywords affect mosflms behavior: - * - * MOSAICITY - * DISPERSION - * DIVERGENCE - * POLARISATION - * POSTREF BEAM - * POSTREF USEBEAM OFF - * PREREFINE ON - * EXTRA ON - * POSTREF ON - * - * These did not seem to affect the results by my (Rick's) experience, probably - * because they are only used conjunction with image intensity data, but it's - * worth another look at the documentation. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <assert.h> -#include <fcntl.h> -#include <errno.h> - -#if HAVE_FORKPTY_LINUX -#include <pty.h> -#elif HAVE_FORKPTY_BSD -#include <util.h> -#endif - - -#include "image.h" -#include "mosflm.h" -#include "utils.h" -#include "peaks.h" - - -#define MOSFLM_VERBOSE 0 - - -typedef enum { - MOSFLM_INPUT_NONE, - MOSFLM_INPUT_LINE, - MOSFLM_INPUT_PROMPT -} MOSFLMInputType; - - -struct mosflm_data { - - /* MOSFLM auto-indexing low-level stuff */ - int pty; - pid_t pid; - char *rbuffer; - int rbufpos; - int rbuflen; - - /* MOSFLM high-level stuff */ - char newmatfile[128]; - char imagefile[128]; - char sptfile[128]; - int step; - int finished_ok; - UnitCell *target_cell; - -}; - - -static void mosflm_parseline(const char *line, struct image *image, - struct mosflm_data *dirax) -{ - #if MOSFLM_VERBOSE - char *copy; - int i; - - copy = strdup(line); - for ( i=0; i<strlen(copy); i++ ) { - if ( copy[i] == '\r' ) copy[i]='r'; - if ( copy[i] == '\n' ) copy[i]='\0'; - } - STATUS("MOSFLM: %s\n", copy); - free(copy); - #endif -} - - -static int read_newmat(const char *filename, struct image *image) -{ - FILE * fh; - float asx, asy, asz; - float bsx, bsy, bsz; - float csx, csy, csz; - int n; - double c; - - fh = fopen(filename, "r"); - if ( fh == NULL ) { - return 1; - } - n = fscanf(fh, "%f %f %f\n", &asx, &bsx, &csx); - n += fscanf(fh, "%f %f %f\n", &asy, &bsy, &csy); - n += fscanf(fh, "%f %f %f\n", &asz, &bsz, &csz); - if ( n != 9 ) { - STATUS("Fewer than 9 parameters found in NEWMAT file.\n"); - return 1; - } - fclose(fh); - - /* MOSFLM "A" matrix is multiplied by lambda, so fix this */ - c = 1/image->lambda; - - image->candidate_cells[0] = cell_new(); - - cell_set_reciprocal(image->candidate_cells[0], - asz*c, asy*c, asx*c, - bsz*c, bsy*c, bsx*c, - csz*c, csy*c, csx*c); - - image->ncells = 1; - - return 0; -} - - -/* Need to sort mosflm peaks by intensity... */ -struct sptline { - double x; /* x coordinate of peak */ - double y; /* y coordinate of peak */ - double h; /* height of peak */ - double s; /* sigma of peak */ -}; - - -static int compare_vals(const void *ap, const void *bp) -{ - const struct sptline a = *(struct sptline *)ap; - const struct sptline b = *(struct sptline *)bp; - - if ( a.h < b.h ) return 1; - if ( a.h > b.h ) return -1; - return 0; -} - - -/* Write .spt file for mosflm */ -static void write_spt(struct image *image, const char *filename) -{ - FILE *fh; - int i; - double fclen = 67.8; /* fake camera length in mm */ - double fpix = 0.075; /* fake pixel size in mm */ - double pix; - double height = 100.0; - double sigma = 1.0; - int nPeaks = image_feature_count(image->features); - struct sptline *sptlines; - - fh = fopen(filename, "w"); - if ( !fh ) { - ERROR("Couldn't open temporary file '%s'\n", filename); - return; - } - - fprintf(fh, "%10d %10d %10.8f %10.6f %10.6f\n", 1, 1, fpix, 1.0, 0.0); - fprintf(fh, "%10d %10d\n", 1, 1); - fprintf(fh, "%10.5f %10.5f\n", 0.0, 0.0); - - sptlines = malloc(sizeof(struct sptline)*nPeaks); - - for ( i=0; i<nPeaks; i++ ) { - - struct imagefeature *f; - struct panel *p; - double xs, ys, rx, ry; - - f = image_get_feature(image->features, i); - if ( f == NULL ) continue; - - p = find_panel(image->det, f->fs, f->ss); - if ( p == NULL ) continue; - - pix = 1000.0/p->res; /* pixel size in mm */ - height = f->intensity; - - xs = (f->fs-p->min_fs)*p->fsx + (f->ss-p->min_ss)*p->ssx; - ys = (f->ss-p->min_fs)*p->fsy + (f->ss-p->min_ss)*p->ssy; - rx = xs + p->cnx; - ry = ys + p->cny; - - sptlines[i].x = ry*pix*fclen/p->clen/1000.0; - sptlines[i].y = -rx*pix*fclen/p->clen/1000.0; - sptlines[i].h = height; - sptlines[i].s = sigma/1000.0; - - } - - qsort(sptlines, nPeaks, sizeof(struct sptline), compare_vals); - - for ( i=0; i<nPeaks; i++ ) { - - fprintf(fh, "%10.2f %10.2f %10.2f %10.2f %10.2f %10.2f\n", - sptlines[i].x, sptlines[i].y, - 0.0, 0.0, - sptlines[i].h, sptlines[i].s); - - } - - free(sptlines); - - fprintf(fh,"%10.2f %10.2f %10.2f %10.2f %10.2f %10.2f\n", - -999.0,-999.0,-999.0,-999.0,-999.0,-999.0); - fclose(fh); -} - - -/* Write a dummy 1x1 pixel image file for MOSFLM. Without post refinement, - * MOSFLM will ignore this, but it must be present. */ -static void write_img(struct image *image, const char *filename) -{ - FILE *fh; - unsigned short int *intimage; - - intimage = malloc(sizeof(unsigned short int)); - intimage[0] = 1; - - fh = fopen(filename, "w"); - if ( !fh ) { - ERROR("Couldn't open temporary file '%s'\n", filename); - return; - } - - /* Write header */ - fprintf(fh, "{\nHEADER_BYTES=512;\n"); - fprintf(fh, "BYTE_ORDER=little_endian;\n"); - fprintf(fh, "TYPE=unsigned_short;\n"); - fprintf(fh, "DIM=2;\n"); - fprintf(fh, "SIZE1=1;\n"); - fprintf(fh, "SIZE2=1;\n"); - fprintf(fh, "}\n"); - - /* Header padding */ - while ( ftell(fh) < 512 ) fprintf(fh," "); - - fwrite(intimage, sizeof(unsigned short int), 1, fh); - free(intimage); - fclose(fh); -} - - -static void mosflm_sendline(const char *line, struct mosflm_data *mosflm) -{ - #if MOSFLM_VERBOSE - char *copy; - int i; - - copy = strdup(line); - for ( i=0; i<strlen(copy); i++ ) { - if ( copy[i] == '\r' ) copy[i]='\0'; - if ( copy[i] == '\n' ) copy[i]='\0'; - } - STATUS("To MOSFLM: '%s'\n", copy); - free(copy); - #endif - - write(mosflm->pty, line, strlen(line)); -} - - -static void mosflm_send_next(struct image *image, struct mosflm_data *mosflm) -{ - char tmp[256]; - char symm[32]; - const char *sg; - double wavelength; - double a, b, c, alpha, beta, gamma; - int i, j; - - switch ( mosflm->step ) { - - case 1 : - mosflm_sendline("DETECTOR ROTATION HORIZONTAL" - " ANTICLOCKWISE ORIGIN LL FAST HORIZONTAL" - " RECTANGULAR\n", mosflm); - break; - - case 2 : - if ( mosflm->target_cell != NULL ) { - cell_get_parameters(mosflm->target_cell, &a, &b, &c, - &alpha, &beta, &gamma); - snprintf(tmp, 255, - "CELL %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n", - a*1e10, b*1e10, c*1e10, - rad2deg(alpha), rad2deg(beta), rad2deg(gamma)); - mosflm_sendline(tmp, mosflm); - } else { - mosflm_sendline("# Do nothing\n", mosflm); - } - break; - - case 3 : - if ( mosflm->target_cell != NULL ) { - sg = cell_get_spacegroup(mosflm->target_cell); - /* Remove white space from space group */ - j = 0; - for ( i=0; i<strlen(sg); i++ ) { - if (sg[i] != ' ') { - symm[j++] = sg[i]; - } - } - symm[j] = '\0'; - snprintf(tmp, 255, "SYMM %s\n", symm); - mosflm_sendline(tmp, mosflm); - } else { - mosflm_sendline("SYMM P1\n", mosflm); - } - break; - - case 4 : - mosflm_sendline("DISTANCE 67.8\n", mosflm); - break; - - case 5 : - mosflm_sendline("BEAM 0.0 0.0\n", mosflm); - break; - - case 6 : - wavelength = image->lambda*1e10; - snprintf(tmp, 255, "WAVELENGTH %10.5f\n", wavelength); - mosflm_sendline(tmp, mosflm); - break; - - case 7 : - snprintf(tmp, 255, "NEWMAT %s\n", mosflm->newmatfile); - mosflm_sendline(tmp, mosflm); - break; - - case 8 : - snprintf(tmp, 255, "IMAGE %s phi 0 0\n", mosflm->imagefile); - mosflm_sendline(tmp, mosflm); - break; - - case 9 : - snprintf(tmp, 255, "AUTOINDEX DPS FILE %s" - " IMAGE 1 MAXCELL 1000 REFINE\n", - mosflm->sptfile); - - /* "This option is only available if you e-mail Andrew Leslie - * and ask for it." - MOSFLM - * snprintf(tmp, 255, "AUTOINDEX NODISPLAY IMAGE 1 FILE %s\n", - * mosflm->sptfile); */ - mosflm_sendline(tmp, mosflm); - break; - - case 10 : - mosflm_sendline("GO\n", mosflm); - mosflm->finished_ok = 1; - break; - - default: - mosflm_sendline("exit\n", mosflm); - return; - - } - - mosflm->step++; -} - - -static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) -{ - int rval; - int no_string = 0; - - rval = read(mosflm->pty, mosflm->rbuffer+mosflm->rbufpos, - mosflm->rbuflen-mosflm->rbufpos); - - if ( (rval == -1) || (rval == 0) ) return 1; - - mosflm->rbufpos += rval; - assert(mosflm->rbufpos <= mosflm->rbuflen); - - while ( (!no_string) && (mosflm->rbufpos > 0) ) { - - int i; - int block_ready = 0; - MOSFLMInputType type = MOSFLM_INPUT_NONE; - - /* See if there's a full line in the buffer yet */ - for ( i=0; i<mosflm->rbufpos-1; i++ ) { - /* Means the last value looked at is rbufpos-2 */ - - /* Is there a prompt in the buffer? */ - if ( (i+10 <= mosflm->rbufpos) - && (!strncmp(mosflm->rbuffer+i, "MOSFLM => ", 10)) ) { - block_ready = 1; - type = MOSFLM_INPUT_PROMPT; - break; - } - - if ( (mosflm->rbuffer[i] == '\r') - && (mosflm->rbuffer[i+1] == '\n') ) { - block_ready = 1; - type = MOSFLM_INPUT_LINE; - break; - } - - } - - if ( block_ready ) { - - unsigned int new_rbuflen; - unsigned int endbit_length; - char *block_buffer = NULL; - - switch ( type ) { - - case MOSFLM_INPUT_LINE : - - block_buffer = malloc(i+1); - memcpy(block_buffer, mosflm->rbuffer, i); - block_buffer[i] = '\0'; - - if ( block_buffer[0] == '\r' ) { - memmove(block_buffer, block_buffer+1, i); - } - - mosflm_parseline(block_buffer, image, mosflm); - free(block_buffer); - endbit_length = i+2; - break; - - case MOSFLM_INPUT_PROMPT : - - mosflm_send_next(image, mosflm); - endbit_length = i+7; - break; - - default : - - /* Obviously, this never happens :) */ - ERROR("Unrecognised MOSFLM input mode! " - "I don't know how to understand MOSFLM\n"); - return 1; - - } - - /* Now the block's been parsed, it should be - * forgotten about */ - memmove(mosflm->rbuffer, - mosflm->rbuffer + endbit_length, - mosflm->rbuflen - endbit_length); - - /* Subtract the number of bytes removed */ - mosflm->rbufpos = mosflm->rbufpos - - endbit_length; - new_rbuflen = mosflm->rbuflen - endbit_length; - if ( new_rbuflen == 0 ) new_rbuflen = 256; - mosflm->rbuffer = realloc(mosflm->rbuffer, - new_rbuflen); - mosflm->rbuflen = new_rbuflen; - - } else { - - if ( mosflm->rbufpos==mosflm->rbuflen ) { - - /* More buffer space is needed */ - mosflm->rbuffer = realloc( - mosflm->rbuffer, - mosflm->rbuflen + 256); - mosflm->rbuflen = mosflm->rbuflen + 256; - /* The new space gets used at the next - * read, shortly... */ - - } - no_string = 1; - - } - - } - - return 0; -} - - -void run_mosflm(struct image *image, UnitCell *cell) -{ - struct mosflm_data *mosflm; - unsigned int opts; - int status; - int rval; - - mosflm = malloc(sizeof(struct mosflm_data)); - if ( mosflm == NULL ) { - ERROR("Couldn't allocate memory for MOSFLM data.\n"); - return; - } - - mosflm->target_cell = cell; - - snprintf(mosflm->imagefile, 127, "xfel-%i_001.img", image->id); - write_img(image, mosflm->imagefile); /* Dummy image */ - - snprintf(mosflm->sptfile, 127, "xfel-%i_001.spt", image->id); - write_spt(image, mosflm->sptfile); - - snprintf(mosflm->newmatfile, 127, "xfel-%i.newmat", image->id); - remove(mosflm->newmatfile); - - mosflm->pid = forkpty(&mosflm->pty, NULL, NULL, NULL); - if ( mosflm->pid == -1 ) { - ERROR("Failed to fork for MOSFLM\n"); - free(mosflm); - return; - } - if ( mosflm->pid == 0 ) { - - /* Child process: invoke MOSFLM */ - struct termios t; - - /* Turn echo off */ - tcgetattr(STDIN_FILENO, &t); - t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); - tcsetattr(STDIN_FILENO, TCSANOW, &t); - - execlp("ipmosflm", "", (char *)NULL); - ERROR("Failed to invoke MOSFLM.\n"); - _exit(0); - - } - - mosflm->rbuffer = malloc(256); - mosflm->rbuflen = 256; - mosflm->rbufpos = 0; - - /* Set non-blocking */ - opts = fcntl(mosflm->pty, F_GETFL); - fcntl(mosflm->pty, F_SETFL, opts | O_NONBLOCK); - - mosflm->step = 1; /* This starts the "initialisation" procedure */ - mosflm->finished_ok = 0; - - do { - - fd_set fds; - struct timeval tv; - int sval; - - FD_ZERO(&fds); - FD_SET(mosflm->pty, &fds); - - tv.tv_sec = 10; - tv.tv_usec = 0; - - sval = select(mosflm->pty+1, &fds, NULL, NULL, &tv); - - if ( sval == -1 ) { - int err = errno; - ERROR("select() failed: %s\n", strerror(err)); - rval = 1; - } else if ( sval != 0 ) { - rval = mosflm_readable(image, mosflm); - } else { - ERROR("No response from MOSFLM..\n"); - rval = 1; - } - - } while ( !rval ); - - close(mosflm->pty); - free(mosflm->rbuffer); - waitpid(mosflm->pid, &status, 0); - - if ( mosflm->finished_ok == 0 ) { - ERROR("MOSFLM doesn't seem to be working properly.\n"); - } else { - /* Read the mosflm NEWMAT file and get cell if found */ - read_newmat(mosflm->newmatfile, image); - } - - free(mosflm); -} diff --git a/src/mosflm.h b/src/mosflm.h deleted file mode 100644 index 82b80a44..00000000 --- a/src/mosflm.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * mosflm.h - * - * Invoke the DPS auto-indexing algorithm through MOSFLM - * - * (c) 2010 Richard Kirian <rkirian@asu.edu> - * (c) 2006-2010 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifndef MOSFLM_H -#define MOSFLM_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "utils.h" - - -extern void run_mosflm(struct image *image, UnitCell *cell); - - -#endif /* MOSFLM_H */ diff --git a/src/reax.c b/src/reax.c deleted file mode 100644 index ff1ea582..00000000 --- a/src/reax.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * reax.c - * - * A new auto-indexer - * - * (c) 2011 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <assert.h> -#include <fftw3.h> -#include <fenv.h> -#include <gsl/gsl_matrix.h> -#include <gsl/gsl_vector.h> -#include <gsl/gsl_linalg.h> -#include <gsl/gsl_eigen.h> -#include <gsl/gsl_blas.h> - -#include "image.h" -#include "utils.h" -#include "peaks.h" -#include "cell.h" -#include "index.h" -#include "index-priv.h" - - -struct dvec -{ - double x; - double y; - double z; - double th; - double ph; -}; - - -struct reax_private -{ - IndexingPrivate base; - struct dvec *directions; - int n_dir; - double angular_inc; - - double *fft_in; - fftw_complex *fft_out; - fftw_plan plan; - int nel; - - fftw_complex *r_fft_in; - fftw_complex *r_fft_out; - fftw_plan r_plan; - int ch; - int cw; -}; - - -static double check_dir(struct dvec *dir, ImageFeatureList *flist, - int nel, double pmax, double *fft_in, - fftw_complex *fft_out, fftw_plan plan, - int smin, int smax, - const char *rg, struct detector *det) -{ - int n, i; - double tot; - - for ( i=0; i<nel; i++ ) { - fft_in[i] = 0.0; - } - - n = image_feature_count(flist); - for ( i=0; i<n; i++ ) { - - struct imagefeature *f; - double val; - int idx; - - f = image_get_feature(flist, i); - if ( f == NULL ) continue; - - if ( rg != NULL ) { - - struct panel *p; - - p = find_panel(det, f->fs, f->ss); - assert(p != NULL); - - if ( p->rigid_group != rg ) continue; - - } - - val = f->rx*dir->x + f->ry*dir->y + f->rz*dir->z; - - idx = nel/2 + nel*val/(2.0*pmax); - fft_in[idx]++; - - } - - fftw_execute_dft_r2c(plan, fft_in, fft_out); - - tot = 0.0; - for ( i=smin; i<=smax; i++ ) { - double re, im; - re = fft_out[i][0]; - im = fft_out[i][1]; - tot += sqrt(re*re + im*im); - } - - return tot; -} - - -/* Refine a direct space vector. From Clegg (1984) */ -static double iterate_refine_vector(double *x, double *y, double *z, - ImageFeatureList *flist) -{ - int fi, n, err; - gsl_matrix *C; - gsl_vector *A; - gsl_vector *t; - gsl_matrix *s_vec; - gsl_vector *s_val; - double dtmax; - - A = gsl_vector_calloc(3); - C = gsl_matrix_calloc(3, 3); - - n = image_feature_count(flist); - fesetround(1); - for ( fi=0; fi<n; fi++ ) { - - struct imagefeature *f; - double val; - double kn, kno; - double xv[3]; - int i, j; - - f = image_get_feature(flist, fi); - if ( f == NULL ) continue; - - kno = f->rx*(*x) + f->ry*(*y) + f->rz*(*z); /* Sorry ... */ - kn = nearbyint(kno); - if ( kn - kno > 0.3 ) continue; - - xv[0] = f->rx; xv[1] = f->ry; xv[2] = f->rz; - - for ( i=0; i<3; i++ ) { - - val = gsl_vector_get(A, i); - gsl_vector_set(A, i, val+xv[i]*kn); - - for ( j=0; j<3; j++ ) { - val = gsl_matrix_get(C, i, j); - gsl_matrix_set(C, i, j, val+xv[i]*xv[j]); - } - - } - - } - - s_val = gsl_vector_calloc(3); - s_vec = gsl_matrix_calloc(3, 3); - err = gsl_linalg_SV_decomp_jacobi(C, s_vec, s_val); - if ( err ) { - ERROR("SVD failed: %s\n", gsl_strerror(err)); - gsl_matrix_free(s_vec); - gsl_vector_free(s_val); - gsl_matrix_free(C); - gsl_vector_free(A); - return 0.0; - } - - t = gsl_vector_calloc(3); - err = gsl_linalg_SV_solve(C, s_vec, s_val, A, t); - if ( err ) { - ERROR("Matrix solution failed: %s\n", gsl_strerror(err)); - gsl_matrix_free(s_vec); - gsl_vector_free(s_val); - gsl_matrix_free(C); - gsl_vector_free(A); - gsl_vector_free(t); - return 0.0; - } - - gsl_matrix_free(s_vec); - gsl_vector_free(s_val); - - dtmax = fabs(*x - gsl_vector_get(t, 0)); - dtmax += fabs(*y - gsl_vector_get(t, 1)); - dtmax += fabs(*z - gsl_vector_get(t, 2)); - - *x = gsl_vector_get(t, 0); - *y = gsl_vector_get(t, 1); - *z = gsl_vector_get(t, 2); - - gsl_matrix_free(C); - gsl_vector_free(A); - - return dtmax; -} - - -static void refine_cell(struct image *image, UnitCell *cell, - ImageFeatureList *flist) -{ - double ax, ay, az; - double bx, by, bz; - double cx, cy, cz; - int i; - double sm; - - cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); - i = 0; - do { - - sm = iterate_refine_vector(&ax, &ay, &az, flist); - sm += iterate_refine_vector(&bx, &by, &bz, flist); - sm += iterate_refine_vector(&cx, &cy, &cz, flist); - i++; - - } while ( (sm > 0.001e-9) && (i<10) ); - - cell_set_cartesian(cell, ax, ay, az, bx, by, bz, cx, cy, cz); - - if ( i == 10 ) { - cell_free(image->indexed_cell); - image->indexed_cell = NULL; - } -} - - -static void fine_search(struct reax_private *p, ImageFeatureList *flist, - int nel, double pmax, double *fft_in, - fftw_complex *fft_out, fftw_plan plan, - int smin, int smax, double th_cen, double ph_cen, - double *x, double *y, double *z) -{ - double fom = 0.0; - double th, ph; - double inc; - struct dvec dir; - int i, s; - double max, modv; - - inc = p->angular_inc / 100.0; - - for ( th=th_cen-p->angular_inc; th<=th_cen+p->angular_inc; th+=inc ) { - for ( ph=ph_cen-p->angular_inc; ph<=ph_cen+p->angular_inc; ph+=inc ) { - - double new_fom; - - dir.x = cos(ph) * sin(th); - dir.y = sin(ph) * sin(th); - dir.z = cos(th); - - new_fom = check_dir(&dir, flist, nel, pmax, fft_in, fft_out, - plan, smin, smax, NULL, NULL); - - if ( new_fom > fom ) { - fom = new_fom; - *x = dir.x; *y = dir.y; *z = dir.z; - } - - } - } - - s = -1; - max = 0.0; - for ( i=smin; i<=smax; i++ ) { - - double re, im, m; - - re = fft_out[i][0]; - im = fft_out[i][1]; - m = sqrt(re*re + im*im); - if ( m > max ) { - max = m; - s = i; - } - - } - assert(s>0); - - modv = (double)s / (2.0*pmax); - *x *= modv; *y *= modv; *z *= modv; -} - - -static double get_model_phase(double x, double y, double z, ImageFeatureList *f, - int nel, double pmax, double *fft_in, - fftw_complex *fft_out, fftw_plan plan, - int smin, int smax, const char *rg, - struct detector *det) -{ - struct dvec dir; - int s, i; - double max; - double re, im; - - dir.x = x; dir.y = y; dir.z = z; - - check_dir(&dir, f, nel, pmax, fft_in,fft_out, plan, smin, smax, - rg, det); - - s = -1; - max = 0.0; - for ( i=smin; i<=smax; i++ ) { - - double re, im, m; - - re = fft_out[i][0]; - im = fft_out[i][1]; - m = sqrt(re*re + im*im); - if ( m > max ) { - max = m; - s = i; - } - - } - - re = fft_out[s][0]; - im = fft_out[s][1]; - - return atan2(im, re); -} - - -static void refine_rigid_group(struct image *image, UnitCell *cell, - const char *rg, int nel, double pmax, - double *fft_in, fftw_complex *fft_out, - fftw_plan plan, int smin, int smax, - struct detector *det, struct reax_private *pr) -{ - double ax, ay, az, ma; - double bx, by, bz, mb; - double cx, cy, cz, mc; - double pha, phb, phc; - struct panel *p; - int i, j; - fftw_complex *r_fft_in; - fftw_complex *r_fft_out; - double m2m; - signed int aix, aiy; - signed int bix, biy; - signed int cix, ciy; - double max; - int max_i, max_j; - - cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); - - ma = modulus(ax, ay, az); - mb = modulus(bx, by, bz); - mc = modulus(cx, cy, cz); - - pha = get_model_phase(ax/ma, ay/ma, az/ma, image->features, nel, pmax, - fft_in, fft_out, plan, smin, smax, rg, det); - phb = get_model_phase(bx/mb, by/mb, bz/mb, image->features, nel, pmax, - fft_in, fft_out, plan, smin, smax, rg, det); - phc = get_model_phase(cx/mc, cy/mc, cz/mc, image->features, nel, pmax, - fft_in, fft_out, plan, smin, smax, rg, det); - - for ( i=0; i<det->n_panels; i++ ) { - if ( det->panels[i].rigid_group == rg ) { - p = &det->panels[i]; - break; - } - } - - r_fft_in = fftw_malloc(pr->cw*pr->ch*sizeof(fftw_complex)); - r_fft_out = fftw_malloc(pr->cw*pr->ch*sizeof(fftw_complex)); - for ( i=0; i<pr->cw; i++ ) { - for ( j=0; j<pr->ch; j++ ) { - r_fft_in[i+pr->cw*j][0] = 0.0; - r_fft_in[i+pr->cw*j][1] = 0.0; - } - } - - ma = modulus(ax, ay, 0.0); - mb = modulus(bx, by, 0.0); - mc = modulus(cx, cy, 0.0); - m2m = ma; - if ( mb > m2m ) m2m = mb; - if ( mc > m2m ) m2m = mc; - - aix = (pr->cw/2)*ax/m2m; aiy = (pr->ch/2)*ay/m2m; - bix = (pr->cw/2)*bx/m2m; biy = (pr->ch/2)*by/m2m; - cix = (pr->cw/2)*cx/m2m; ciy = (pr->ch/2)*cy/m2m; - - if ( aix < 0 ) aix += pr->cw/2; - if ( bix < 0 ) bix += pr->cw/2; - if ( cix < 0 ) cix += pr->cw/2; - - if ( aiy < 0 ) aiy += pr->ch/2; - if ( biy < 0 ) biy += pr->ch/2; - if ( ciy < 0 ) ciy += pr->ch/2; - - r_fft_in[aix + pr->cw*aiy][0] = cos(pha); - r_fft_in[aix + pr->cw*aiy][1] = sin(pha); - r_fft_in[pr->cw-aix + pr->cw*(pr->ch-aiy)][0] = cos(pha); - r_fft_in[pr->cw-aix + pr->cw*(pr->ch-aiy)][1] = -sin(pha); - - r_fft_in[bix + pr->cw*biy][0] = cos(phb); - r_fft_in[bix + pr->cw*biy][1] = sin(phb); - r_fft_in[pr->cw-bix + pr->cw*(pr->ch-biy)][0] = cos(phb); - r_fft_in[pr->cw-bix + pr->cw*(pr->ch-biy)][1] = -sin(phb); - - r_fft_in[cix + pr->cw*ciy][0] = cos(phc); - r_fft_in[cix + pr->cw*ciy][1] = sin(phc); - r_fft_in[pr->cw-cix + pr->cw*(pr->ch-ciy)][0] = cos(phc); - r_fft_in[pr->cw-cix + pr->cw*(pr->ch-ciy)][1] = -sin(phc); - - const int tidx = 1; - r_fft_in[tidx][0] = 1.0; - r_fft_in[tidx][1] = 0.0; - -// STATUS("%i %i\n", aix, aiy); -// STATUS("%i %i\n", bix, biy); -// STATUS("%i %i\n", cix, ciy); - - fftw_execute_dft(pr->r_plan, r_fft_in, r_fft_out); - -// max = 0.0; -// FILE *fh = fopen("centering.dat", "w"); -// for ( i=0; i<pr->cw; i++ ) { -// for ( j=0; j<pr->ch; j++ ) { -// -// double re, im, am, ph; -// -// re = r_fft_out[i + pr->cw*j][0]; -// im = r_fft_out[i + pr->cw*j][1]; -// am = sqrt(re*re + im*im); -// ph = atan2(im, re); -// -// if ( am > max ) { -// max = am; -// max_i = i; -// max_j = j; -// } -// -// fprintf(fh, "%f ", am); -// -// } -// fprintf(fh, "\n"); -// } -// STATUS("Max at %i, %i\n", max_i, max_j); -// fclose(fh); -// exit(1); - -// STATUS("Offsets for '%s': %.2f, %.2f pixels\n", rg, dx, dy); -} - - -static void refine_all_rigid_groups(struct image *image, UnitCell *cell, - int nel, double pmax, - double *fft_in, fftw_complex *fft_out, - fftw_plan plan, int smin, int smax, - struct detector *det, - struct reax_private *p) -{ - int i; - - for ( i=0; i<image->det->num_rigid_groups; i++ ) { - refine_rigid_group(image, cell, image->det->rigid_groups[i], - nel, pmax, fft_in, fft_out, plan, smin, smax, - det, p); - } -} - - -void reax_index(IndexingPrivate *pp, struct image *image, UnitCell *cell) -{ - int i; - struct reax_private *p; - double fom; - double ax, ay, az; - double bx, by, bz; - double cx, cy, cz; - double mod_a, mod_b, mod_c; - double al, be, ga; - double th, ph; - double *fft_in; - fftw_complex *fft_out; - int smin, smax; - double amin, amax; - double bmin, bmax; - double cmin, cmax; - double pmax; - int n; - const double ltol = 5.0; /* Direct space axis length - * tolerance in percent */ - const double angtol = deg2rad(1.5); /* Direct space angle tolerance - * in radians */ - - assert(pp->indm == INDEXING_REAX); - p = (struct reax_private *)pp; - - fft_in = fftw_malloc(p->nel*sizeof(double)); - fft_out = fftw_malloc((p->nel/2 + 1)*sizeof(fftw_complex)); - - cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); - mod_a = modulus(ax, ay, az); - amin = mod_a * (1.0-ltol/100.0); - amax = mod_a * (1.0+ltol/100.0); - - mod_b = modulus(bx, by, bz); - bmin = mod_b * (1.0-ltol/100.0); - bmax = mod_b * (1.0+ltol/100.0); - - mod_c = modulus(cx, cy, cz); - cmin = mod_c * (1.0-ltol/100.0); - cmax = mod_c * (1.0+ltol/100.0); - - al = angle_between(bx, by, bz, cx, cy, cz); - be = angle_between(ax, ay, az, cx, cy, cz); - ga = angle_between(ax, ay, az, bx, by, bz); - - pmax = 0.0; - n = image_feature_count(image->features); - for ( i=0; i<n; i++ ) { - - struct imagefeature *f; - double val; - - f = image_get_feature(image->features, i); - if ( f == NULL ) continue; - - val = modulus(f->rx, f->ry, f->rz); - if ( val > pmax ) pmax = val; - - } - - /* Sanity check */ - if ( pmax < 1e4 ) return; - - /* Search for a */ - smin = 2.0*pmax * amin; - smax = 2.0*pmax * amax; - fom = 0.0; th = 0.0; ph = 0.0; - for ( i=0; i<p->n_dir; i++ ) { - - double new_fom; - - new_fom = check_dir(&p->directions[i], image->features, - p->nel, pmax, fft_in, fft_out, p->plan, - smin, smax, NULL, NULL); - if ( new_fom > fom ) { - fom = new_fom; - th = p->directions[i].th; - ph = p->directions[i].ph; - } - - } - fine_search(p, image->features, p->nel, pmax, fft_in, fft_out, - p->plan, smin, smax, th, ph, &ax, &ay, &az); - - /* Search for b */ - smin = 2.0*pmax * bmin; - smax = 2.0*pmax * bmax; - fom = 0.0; th = 0.0; ph = 0.0; - for ( i=0; i<p->n_dir; i++ ) { - - double new_fom, ang; - - ang = angle_between(p->directions[i].x, p->directions[i].y, - p->directions[i].z, ax, ay, az); - if ( fabs(ang-ga) > angtol ) continue; - - new_fom = check_dir(&p->directions[i], image->features, - p->nel, pmax, fft_in, fft_out, p->plan, - smin, smax, NULL, NULL); - if ( new_fom > fom ) { - fom = new_fom; - th = p->directions[i].th; - ph = p->directions[i].ph; - } - - } - fine_search(p, image->features, p->nel, pmax, fft_in, fft_out, - p->plan, smin, smax, th, ph, &bx, &by, &bz); - - /* Search for c */ - smin = 2.0*pmax * cmin; - smax = 2.0*pmax * cmax; - fom = 0.0; th = 0.0; ph = 0.0; - for ( i=0; i<p->n_dir; i++ ) { - - double new_fom, ang; - - ang = angle_between(p->directions[i].x, p->directions[i].y, - p->directions[i].z, ax, ay, az); - if ( fabs(ang-be) > angtol ) continue; - - ang = angle_between(p->directions[i].x, p->directions[i].y, - p->directions[i].z, bx, by, bz); - if ( fabs(ang-al) > angtol ) continue; - - new_fom = check_dir(&p->directions[i], image->features, - p->nel, pmax, fft_in, fft_out, p->plan, - smin, smax, NULL, NULL); - if ( new_fom > fom ) { - fom = new_fom; - th = p->directions[i].th; - ph = p->directions[i].ph; - } - - } - fine_search(p, image->features, p->nel, pmax, fft_in, fft_out, - p->plan, smin, smax, th, ph, &cx, &cy, &cz); - - image->candidate_cells[0] = cell_new(); - cell_set_cartesian(image->candidate_cells[0], - ax, ay, az, bx, by, bz, cx, cy, cz); - - refine_all_rigid_groups(image, image->candidate_cells[0], p->nel, pmax, - fft_in, fft_out, p->plan, smin, smax, - image->det, p); - map_all_peaks(image); - refine_cell(image, image->candidate_cells[0], image->features); - - fftw_free(fft_in); - fftw_free(fft_out); - - image->ncells = 1; -} - - -IndexingPrivate *reax_prepare() -{ - struct reax_private *p; - int samp; - double th; - - p = calloc(1, sizeof(*p)); - if ( p == NULL ) return NULL; - - p->base.indm = INDEXING_REAX; - - p->angular_inc = deg2rad(1.7); /* From Steller (1997) */ - - /* Reserve memory, over-estimating the number of directions */ - samp = 2.0*M_PI / p->angular_inc; - p->directions = malloc(samp*samp*sizeof(struct dvec)); - if ( p == NULL) { - free(p); - return NULL; - } - STATUS("Allocated space for %i directions\n", samp*samp); - - /* Generate vectors for 1D Fourier transforms */ - fesetround(1); /* Round to nearest */ - p->n_dir = 0; - for ( th=0.0; th<M_PI_2; th+=p->angular_inc ) { - - double ph, phstep, n_phstep; - - n_phstep = 2.0*M_PI*sin(th)/p->angular_inc; - n_phstep = nearbyint(n_phstep); - phstep = 2.0*M_PI/n_phstep; - - for ( ph=0.0; ph<2.0*M_PI; ph+=phstep ) { - - struct dvec *dir; - - assert(p->n_dir<samp*samp); - - dir = &p->directions[p->n_dir++]; - - dir->x = cos(ph) * sin(th); - dir->y = sin(ph) * sin(th); - dir->z = cos(th); - dir->th = th; - dir->ph = ph; - - } - - } - STATUS("Generated %i directions (angular increment %.3f deg)\n", - p->n_dir, rad2deg(p->angular_inc)); - - p->nel = 1024; - - /* These arrays are not actually used */ - p->fft_in = fftw_malloc(p->nel*sizeof(double)); - p->fft_out = fftw_malloc((p->nel/2 + 1)*sizeof(fftw_complex)); - - p->plan = fftw_plan_dft_r2c_1d(p->nel, p->fft_in, p->fft_out, - FFTW_MEASURE); - - p->cw = 128; p->ch = 128; - - /* Also not used */ - p->r_fft_in = fftw_malloc(p->cw*p->ch*sizeof(fftw_complex)); - p->r_fft_out = fftw_malloc(p->cw*p->ch*sizeof(fftw_complex)); - - p->r_plan = fftw_plan_dft_2d(p->cw, p->ch, p->r_fft_in, p->r_fft_out, - 1, FFTW_MEASURE); - - return (IndexingPrivate *)p; -} - - -void reax_cleanup(IndexingPrivate *pp) -{ - struct reax_private *p; - - assert(pp->indm == INDEXING_REAX); - p = (struct reax_private *)pp; - - fftw_destroy_plan(p->plan); - fftw_free(p->fft_in); - fftw_free(p->fft_out); - - fftw_destroy_plan(p->r_plan); - fftw_free(p->r_fft_in); - fftw_free(p->r_fft_out); - - free(p); -} diff --git a/src/reax.h b/src/reax.h deleted file mode 100644 index 543cd0d5..00000000 --- a/src/reax.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * reax.h - * - * A new auto-indexer - * - * (c) 2011 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifndef REAX_H -#define REAX_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "cell.h" - -extern IndexingPrivate *reax_prepare(void); -extern void reax_cleanup(IndexingPrivate *pp); - -extern void reax_index(IndexingPrivate *p, struct image *image, UnitCell *cell); - -#endif /* REAX_H */ diff --git a/src/render.c b/src/render.c deleted file mode 100644 index dbaca2fd..00000000 --- a/src/render.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * render.c - * - * Render a high dynamic range buffer in some sensible way - * - * (c) 2006-2011 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -#ifdef HAVE_GTK -#include <gdk-pixbuf/gdk-pixbuf.h> -#endif - -#include <stdlib.h> -#include <math.h> -#include <stdint.h> - -#ifdef HAVE_TIFF -#include <tiffio.h> -#endif - - -#include "hdf5-file.h" -#include "render.h" -#include "peaks.h" -#include "filters.h" -#include "utils.h" - - -static void render_rgb(double val, double max, - double *rp, double *gp, double *bp) -{ - int s; - double p; - double r, g, b; - - s = val / (max/6); - p = fmod(val, max/6.0); - p /= (max/6.0); - - r = 0.0; g = 0.0; b = 0.0; - - if ( (val < 0.0) ) { - s = 0; - p = 0; - } - if ( (val > max) ) { - s = 6; - } - switch ( s ) { - case 0 : { /* Black to blue */ - r = 0; g = 0; b = p; - break; - } - case 1 : { /* Blue to pink */ - r = p; g = 0; b = 1.0; - break; - } - case 2 : { /* Pink to red */ - r = 1.0; g = 0; b = (1.0-p)*1.0; - break; - } - case 3 : { /* Red to Orange */ - r = 1.0; g = 0.5*p; b = 0; - break; - } - case 4 : { /* Orange to Yellow */ - r = 1.0; g = 0.5 + 0.5*p; b = 0; - break; - } - case 5 : { /* Yellow to White */ - r = 1.0; g = 1.0; b = 1.0*p; - break; - } - case 6 : { /* Pixel has hit the maximum value */ - r = 1.0; g = 1.0; b = 1.0; - break; - } - } - - *rp = r; - *gp = g; - *bp = b; -} - - -static void render_ratio(double val, double max, - double *rp, double *gp, double *bp) -{ - if ( val <= 1.0 ) { - render_rgb(val, 2.0, rp, gp, bp); - } else { - /* Your homework is to simplify this expression */ - val = ((val-1.0)/(max-1.0)) * (max/2.0) + max/2.0; - render_rgb(val, max, rp, gp, bp); - } -} - - -static void render_mono(double val, double max, - double *rp, double *gp, double *bp) -{ - double p; - p = val / max; - if ( val < 0.0 ) p = 0.0; - if ( val > max ) p = 1.0; - *rp = p; - *gp = p; - *bp = p; -} - - -static void render_invmono(double val, double max, - double *rp, double *gp, double *bp) -{ - double p; - p = val / max; - p = 1.0 - p; - if ( val < 0.0 ) p = 1.0; - if ( val > max ) p = 0.0; - *rp = p; - *gp = p; - *bp = p; -} - - -void render_scale(double val, double max, int scale, - double *rp, double *gp, double *bp) -{ - switch ( scale ) { - case SCALE_COLOUR : - render_rgb(val, max, rp, gp, bp); - break; - case SCALE_MONO : - render_mono(val, max, rp, gp, bp); - break; - case SCALE_INVMONO : - render_invmono(val, max, rp, gp, bp); - break; - case SCALE_RATIO : - render_ratio(val, max, rp, gp, bp); - break; - } -} - - -#ifdef HAVE_GTK - -static float *get_binned_panel(struct image *image, int binning, - int min_fs, int max_fs, int min_ss, int max_ss) -{ - float *data; - int x, y; - int w, h; - int fw; - float *in; - - fw = image->width; - in = image->data; - - /* Some pixels might get discarded */ - w = (max_fs - min_fs + 1) / binning; - h = (max_ss - min_ss + 1) / binning; - - data = malloc(w*h*sizeof(float)); - - for ( x=0; x<w; x++ ) { - for ( y=0; y<h; y++ ) { - - double total; - size_t xb, yb; - - total = 0; - for ( xb=0; xb<binning; xb++ ) { - for ( yb=0; yb<binning; yb++ ) { - - double v; - v = in[binning*x+xb+min_fs + (binning*y+yb+min_ss)*fw]; - total += v; - - } - } - - data[x+w*y] = total / ((double)binning * (double)binning); - - } - } - - return data; -} - - -/* NB This function is shared between render_get_image() and - * render_get_colour_scale() */ -static void render_free_data(guchar *data, gpointer p) -{ - free(data); -} - - -static GdkPixbuf *render_panel(struct image *image, - int binning, int scale, double boost, - int min_fs, int max_fs, int min_ss, int max_ss) -{ - int w, h; - guchar *data; - float *hdr; - int x, y; - double max; - int pw, ph; - int i; - - /* Calculate panel width and height - * (add one because min and max are inclusive) */ - pw = max_fs - min_fs + 1; - ph = max_ss - min_ss + 1; - w = pw / binning; - h = ph / binning; - - /* High dynamic range version */ - max = 0.0; - for ( i=0; i<image->width*image->height; i++ ) { - if ( image->data[i] > max ) max = image->data[i]; - } - hdr = get_binned_panel(image, binning, min_fs, max_fs, min_ss, max_ss); - if ( hdr == NULL ) return NULL; - - /* Rendered (colourful) version */ - data = malloc(3*w*h); - if ( data == NULL ) { - free(hdr); - return NULL; - } - - max /= boost; - if ( max <= 6 ) { max = 10; } - /* These x,y coordinates are measured relative to the bottom-left - * corner */ - for ( y=0; y<h; y++ ) { - for ( x=0; x<w; x++ ) { - - double val; - double r, g, b; - - val = hdr[x+w*y]; - render_scale(val, max, scale, &r, &g, &b); - - /* Stuff inside square brackets makes this pixel go to - * the expected location in the pixbuf (which measures - * from the top-left corner */ - data[3*( x+w*y )+0] = 255*r; - data[3*( x+w*y )+1] = 255*g; - data[3*( x+w*y )+2] = 255*b; - - } - } - - /* Finished with this */ - free(hdr); - - /* Create the pixbuf from the 8-bit display data */ - return gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, FALSE, 8, - w, h, w*3, render_free_data, NULL); - -} - - -/* Render an image into multiple pixbufs according to geometry */ -GdkPixbuf **render_panels(struct image *image, - int binning, int scale, double boost, - int *n_pixbufs) -{ - int i; - int np = image->det->n_panels; - GdkPixbuf **pixbufs; - - pixbufs = calloc(np, sizeof(GdkPixbuf*)); - if ( pixbufs == NULL ) { - *n_pixbufs = 0; - return NULL; - } - - for ( i=0; i<np; i++ ) { - - pixbufs[i] = render_panel(image, binning, scale, boost, - image->det->panels[i].min_fs, - image->det->panels[i].max_fs, - image->det->panels[i].min_ss, - image->det->panels[i].max_ss); - - } - - *n_pixbufs = np; - - return pixbufs; -} - - -GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int scale) -{ - guchar *data; - size_t x, y; - int max; - - data = malloc(3*w*h); - if ( data == NULL ) return NULL; - - max = h; - - for ( y=0; y<h; y++ ) { - - double r, g, b; - int val; - - val = y; - - render_scale(val, max, scale, &r, &g, &b); - - data[3*( 0+w*(h-1-y) )+0] = 0; - data[3*( 0+w*(h-1-y) )+1] = 0; - data[3*( 0+w*(h-1-y) )+2] = 0; - for ( x=1; x<w; x++ ) { - data[3*( x+w*(h-1-y) )+0] = 255*r; - data[3*( x+w*(h-1-y) )+1] = 255*g; - data[3*( x+w*(h-1-y) )+2] = 255*b; - } - - } - - return gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, FALSE, 8, - w, h, w*3, render_free_data, NULL); -} - - -int render_tiff_fp(struct image *image, const char *filename) -{ -#ifdef HAVE_TIFF - TIFF *th; - float *line; - int y; - - th = TIFFOpen(filename, "w"); - if ( th == NULL ) return 1; - - TIFFSetField(th, TIFFTAG_IMAGEWIDTH, image->width); - TIFFSetField(th, TIFFTAG_IMAGELENGTH, image->height); - TIFFSetField(th, TIFFTAG_SAMPLESPERPIXEL, 1); - TIFFSetField(th, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); - TIFFSetField(th, TIFFTAG_BITSPERSAMPLE, 32); - TIFFSetField(th, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); - TIFFSetField(th, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(th, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(th, TIFFTAG_ROWSPERSTRIP, - TIFFDefaultStripSize(th, image->width*4)); - - line = _TIFFmalloc(TIFFScanlineSize(th)); - for ( y=0; y<image->height; y++ ) { - memcpy(line, &image->data[(image->height-1-y)*image->width], - image->width*4); - TIFFWriteScanline(th, line, y, 0); - } - _TIFFfree(line); - - TIFFClose(th); - -#else - STATUS("No TIFF support.\n"); -#endif - return 0; -} - - -int render_tiff_int16(struct image *image, const char *filename, double boost) -{ -#ifdef HAVE_TIFF - TIFF *th; - int16_t *line; - int x, y; - double max; - - th = TIFFOpen(filename, "w"); - if ( th == NULL ) return 1; - - TIFFSetField(th, TIFFTAG_IMAGEWIDTH, image->width); - TIFFSetField(th, TIFFTAG_IMAGELENGTH, image->height); - TIFFSetField(th, TIFFTAG_SAMPLESPERPIXEL, 1); - TIFFSetField(th, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); /* (signed) */ - TIFFSetField(th, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(th, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); - TIFFSetField(th, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(th, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(th, TIFFTAG_ROWSPERSTRIP, - TIFFDefaultStripSize(th, image->width*4)); - - line = _TIFFmalloc(TIFFScanlineSize(th)); - max = 0.0; - for ( y=0; y<image->height; y++ ) { - for ( x=0;x<image->width; x++ ) { - double val; - val = image->data[x+image->height*y]; - if ( val > max ) max = val; - } - } - max /= 32767.0; - - for ( y=0; y<image->height; y++ ) { - for ( x=0;x<image->width; x++ ) { - - double val; - - val = image->data[x+(image->height-1-y)*image->width]; - val *= ((double)boost/max); - - /* Clamp to 16-bit range, - * and work round inability of most readers to deal - * with signed integers. */ - val += 1000.0; - if ( val > 32767.0 ) val = 32767.0; - if ( val < 0.0 ) val = 0.0; - - line[x] = val; - } - - TIFFWriteScanline(th, line, y, 0); - } - _TIFFfree(line); - - TIFFClose(th); -#else - STATUS("No TIFF support.\n"); -#endif - return 0; -} - -#endif /* HAVE_GTK */ diff --git a/src/render.h b/src/render.h deleted file mode 100644 index fbfbbdb2..00000000 --- a/src/render.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * render.h - * - * Render a high dynamic range buffer in some sensible way - * - * (c) 2006-2011 Thomas White <taw@physics.org> - * - * Part of CrystFEL - crystallography with a FEL - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifndef RENDER_H -#define RENDER_H - - -#include <stddef.h> - -#include "image.h" - -enum { - SCALE_COLOUR, - SCALE_MONO, - SCALE_INVMONO, - SCALE_RATIO -}; - -/* Colour scale lookup */ -extern void render_scale(double val, double max, int scale, - double *rp, double *gp, double *bp); - - -#ifdef HAVE_GTK - -#include <gdk-pixbuf/gdk-pixbuf.h> - -extern GdkPixbuf **render_panels(struct image *image, - int binning, int scale, double boost, - int *n_pixbufs); - -extern GdkPixbuf *render_get_colour_scale(size_t w, size_t h, int scale); - -extern int render_tiff_fp(struct image *image, const char *filename); -extern int render_tiff_int16(struct image *image, const char *filename, - double boost); - -#endif /* HAVE_GTK */ - - - -#endif /* RENDER_H */ |