/* * utils.h * * Utility stuff * * (c) 2006-2010 Thomas White * * Part of CrystFEL - crystallography with a FEL * */ #ifndef UTILS_H #define UTILS_H #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "thread-pool.h" /* -------------------------- Fundamental constants ------------------------ */ /* Electron charge in C */ #define ELECTRON_CHARGE (1.6021773e-19) /* Planck's constant (Js) */ #define PLANCK (6.62606896e-34) /* Speed of light in vacuo (m/s) */ #define C_VACUO (299792458) /* Thomson scattering length (m) */ #define THOMSON_LENGTH (2.81794e-15) /* ------------------------------ Quaternions ------------------------------- */ struct quaternion { double w; double x; double y; double z; }; extern struct quaternion normalise_quaternion(struct quaternion q); extern double quaternion_modulus(struct quaternion q); extern struct quaternion random_quaternion(void); extern int quaternion_valid(struct quaternion q); extern struct rvec quat_rot(struct rvec q, struct quaternion z); /* --------------------------- Useful functions ----------------------------- */ extern void show_matrix_eqn(gsl_matrix *M, gsl_vector *v, int r); extern size_t notrail(char *s); extern void chomp(char *s); typedef enum { ASSPLODE_NONE = 0, ASSPLODE_DUPS = 1<<0 } AssplodeFlag; extern int assplode(const char *a, const char *delims, char ***pbits, AssplodeFlag flags); extern void progress_bar(int val, int total, const char *text); extern int poisson_noise(double expected); /* Keep these ones inline, to avoid function call overhead */ static inline struct quaternion invalid_quaternion(void) { struct quaternion quat; quat.w = 0.0; quat.x = 0.0; quat.y = 0.0; quat.z = 0.0; return quat; } static inline double distance(double x1, double y1, double x2, double y2) { return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); } static inline double modulus(double x, double y, double z) { return sqrt(x*x + y*y + z*z); } static inline double modulus_squared(double x, double y, double z) { return x*x + y*y + z*z; } static inline double distance3d(double x1, double y1, double z1, double x2, double y2, double z2) { return modulus(x1-x2, y1-y2, z1-z2); } /* Answer in radians */ static inline double angle_between(double x1, double y1, double z1, double x2, double y2, double z2) { double mod1 = modulus(x1, y1, z1); double mod2 = modulus(x2, y2, z2); double cosine = (x1*x2 + y1*y2 + z1*z2) / (mod1*mod2); /* Fix domain if outside due to rounding */ if ( cosine > 1.0 ) cosine = 1.0; if ( cosine < -1.0 ) cosine = -1.0; return acos(cosine); } /* ----------------------------- Useful macros ------------------------------ */ #define rad2deg(a) ((a)*180/M_PI) #define deg2rad(a) ((a)*M_PI/180) #define is_odd(a) ((a)%2==1) #define biggest(a,b) ((a>b) ? (a) : (b)) #define smallest(a,b) ((a= 0 ) { \ fprintf(stderr, "%3i: ", error_print_val); \ } \ fprintf(stderr, __VA_ARGS__); \ pthread_mutex_unlock(&stderr_lock); \ } #define STATUS(...) { \ int status_print_val = get_status_label(); \ pthread_mutex_lock(&stderr_lock); \ if ( status_print_val >= 0 ) { \ fprintf(stderr, "%3i: ", status_print_val); \ } \ fprintf(stderr, __VA_ARGS__); \ pthread_mutex_unlock(&stderr_lock); \ } /* ------------------------------ File handling ----------------------------- */ extern char *check_prefix(char *prefix); extern char *safe_basename(const char *in); #endif /* UTILS_H */