/* * image.c * * Handle images and image features * * Copyright © 2012-2014 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: * 2014 Kenneth Beyerlein * 2011-2014 Thomas White * * 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 . * */ #define _ISOC99_SOURCE #include #include #include #include #include "image.h" #include "utils.h" /** * SECTION:image * @short_description: Data structure representing an image * @title: Image * @section_id: * @see_also: * @include: "image.h" * @Image: * * The image structure represents an image, usually one * frame from a large series of diffraction patterns, which might be from the * same or different crystals. */ struct _imagefeaturelist { struct imagefeature *features; int n_features; }; void image_add_feature(ImageFeatureList *flist, double fs, double ss, struct image *parent, double intensity, const char *name) { if ( flist->features ) { flist->features = realloc(flist->features, (flist->n_features+1) *sizeof(struct imagefeature)); } else { assert(flist->n_features == 0); flist->features = malloc(sizeof(struct imagefeature)); } flist->features[flist->n_features].fs = fs; flist->features[flist->n_features].ss = ss; flist->features[flist->n_features].intensity = intensity; flist->features[flist->n_features].parent = parent; flist->features[flist->n_features].name = name; flist->features[flist->n_features].valid = 1; flist->n_features++; } ImageFeatureList *image_feature_list_new() { ImageFeatureList *flist; flist = malloc(sizeof(ImageFeatureList)); flist->n_features = 0; flist->features = NULL; return flist; } static int comp(const void *a, const void *b) { const struct imagefeature *ap = a; const struct imagefeature *bp = b; return ap->intensity < bp->intensity; } /* Strongest first. Returned list is guaranteed not to have any holes * (feature->valid = 0) */ ImageFeatureList *sort_peaks(ImageFeatureList *flist) { ImageFeatureList *n = image_feature_list_new(); int nf, i; if ( n == NULL ) return NULL; n->features = malloc(flist->n_features*sizeof(struct imagefeature)); if ( n->features == NULL ) { free(n); return NULL; } nf = 0; for ( i=0; in_features; i++ ) { struct imagefeature *f; f = image_get_feature(flist, i); if ( f == NULL ) continue; n->features[nf++] = flist->features[i]; } n->n_features = nf; qsort(n->features, nf, sizeof(struct imagefeature), comp); return n; } void image_feature_list_free(ImageFeatureList *flist) { if ( !flist ) return; if ( flist->features ) free(flist->features); free(flist); } struct imagefeature *image_feature_closest(ImageFeatureList *flist, double fs, double ss, double *d, int *idx, struct detector *det) { int i; double dmin = +HUGE_VAL; int closest = 0; struct panel *p1; p1 = find_panel(det, fs, ss); for ( i=0; in_features; i++ ) { double ds; struct panel *p2; p2 = find_panel(det, flist->features[i].fs, flist->features[i].ss); if ( p1 != p2 ) { continue; } ds = distance(flist->features[i].fs, flist->features[i].ss, fs, ss); if ( ds < dmin ) { dmin = ds; closest = i; } } if ( dmin < +HUGE_VAL ) { *d = dmin; *idx = closest; return &flist->features[closest]; } *d = +INFINITY; return NULL; } Reflection *image_reflection_closest(RefList *rlist, double fs, double ss, struct detector *det, double *d) { double dmin = HUGE_VAL; Reflection *closest = NULL; struct panel *p1; Reflection *refl; RefListIterator *iter; p1 = find_panel(det, fs, ss); for ( refl = first_refl(rlist, &iter); refl != NULL; refl = next_refl(refl, iter) ) { double ds; struct panel *p2; double rfs, rss; get_detector_pos(refl, &rfs, &rss); p2 = find_panel(det, rfs, rss); if ( p1 != p2 ) { continue; } ds = distance(rfs, rss, fs, ss); if ( ds < dmin ) { dmin = ds; closest = refl; } } if ( dmin < +HUGE_VAL ) { *d = dmin; return closest; } *d = +INFINITY; return NULL; } int image_feature_count(ImageFeatureList *flist) { if ( flist == NULL ) return 0; return flist->n_features; } struct imagefeature *image_get_feature(ImageFeatureList *flist, int idx) { /* Sanity check */ if ( flist == NULL ) return NULL; if ( idx >= flist->n_features ) return NULL; if ( flist->features[idx].valid == 0 ) return NULL; return &flist->features[idx]; } void image_remove_feature(ImageFeatureList *flist, int idx) { flist->features[idx].valid = 0; } void image_add_crystal(struct image *image, Crystal *cryst) { Crystal **crs; int n; n = image->n_crystals; crs = realloc(image->crystals, (n+1)*sizeof(Crystal *)); if ( crs == NULL ) { ERROR("Failed to allocate memory for crystals.\n"); return; } crs[n] = cryst; image->crystals = crs; image->n_crystals = n+1; } /* Free all crystals, including their RefLists and UnitCells */ void free_all_crystals(struct image *image) { int i; if ( image->crystals == NULL ) return; for ( i=0; in_crystals; i++ ) { Crystal *cr = image->crystals[i]; reflist_free(crystal_get_reflections(cr)); cell_free(crystal_get_cell(cr)); crystal_free(image->crystals[i]); } free(image->crystals); image->n_crystals = 0; }