Commit 844947d1 authored by Thomas White's avatar Thomas White
Browse files

Add more options, including random orientations

parent 3d22f282
......@@ -35,35 +35,84 @@ static void show_help(const char *s)
{
printf("Syntax: %s\n\n", s);
printf("Simulate diffraction patterns from small crystals\n");
printf(" probed with femosecond pulses from a free electron laser\n\n");
printf(" -h, --help Display this help message\n");
printf(" --simulation-details Show details of the simulation\n");
printf(" probed with femosecond pulses from a free electron laser.\n\n");
printf(" -h, --help Display this help message\n");
printf(" --simulation-details Show details of the simulation\n");
printf(" --near-bragg Output h,k,l,I near Bragg conditions\n");
printf(" -r, --random-orientation Use a randomly generated orientation\n");
printf(" (a new orientation will be used for each image)\n");
printf(" -n, --number=<N> Generate N images. Default 1\n");
}
static void show_details(const char *s)
static void show_details()
{
printf("%s: Simulation Details\n\n", s);
printf("Simulates diffraction patterns from small crystals\n");
printf("probed with femtosecond pulses from a free electron laser\n\n");
printf("This program simulates diffraction patterns from small crystals illuminated\n");
printf("with femtosecond X-ray pulses from a free electron laser.\n\n");
printf("Scattering Factors\n");
printf("------------------\n");
printf("Scattering factors\n");
}
static struct quaternion read_quaternion()
{
do {
int r;
float w, x, y, z;
char line[1024];
char *rval;
printf("Please input quaternion: w x y z\n");
rval = fgets(line, 1023, stdin);
if ( rval == NULL ) return invalid_quaternion();
chomp(line);
r = sscanf(line, "%f %f %f %f", &w, &x, &y, &z);
if ( r == 4 ) {
struct quaternion quat;
quat.w = w;
quat.x = x;
quat.y = y;
quat.z = z;
return quat;
} else {
fprintf(stderr, "Invalid rotation '%s'\n", line);
}
} while ( 1 );
}
int main(int argc, char *argv[])
{
int c, done;
int c;
struct image image;
char filename[1024];
int number = 1;
int config_simdetails = 0;
int config_nearbragg = 0;
int config_randomquat = 0;
int number = 1; /* Index for the current image */
int n_images = 1; /* Generate one image by default */
int done = 0;
/* Long options */
const struct option longopts[] = {
{"help", 0, NULL, 'h'},
{"simulation-details", 0, &config_simdetails, 1},
{0, 0, NULL, 0}
{"help", 0, NULL, 'h'},
{"simulation-details", 0, &config_simdetails, 1},
{"near-bragg", 0, &config_nearbragg, 1},
{"random-orientation", 0, NULL, 'r'},
{"number", 1, NULL, 'n'},
{0, 0, NULL, 0}
};
while ((c = getopt_long(argc, argv, "h", longopts, NULL)) != -1) {
/* Short options */
while ((c = getopt_long(argc, argv, "hrn:", longopts, NULL)) != -1) {
switch (c) {
case 'h' : {
......@@ -71,6 +120,16 @@ int main(int argc, char *argv[])
return 0;
}
case 'r' : {
config_randomquat = 1;
break;
}
case 'n' : {
n_images = atoi(optarg);
break;
}
case 0 : {
break;
}
......@@ -83,7 +142,7 @@ int main(int argc, char *argv[])
}
if ( config_simdetails ) {
show_details(argv[0]);
show_details();
return 0;
}
......@@ -102,64 +161,44 @@ int main(int argc, char *argv[])
/* Splurge a few useful numbers */
printf("Wavelength is %f nm\n", image.lambda/1.0e-9);
again:
/* Read quaternion from stdin */
done = 0;
do {
int r;
float w, x, y, z;
char line[1024];
char *rval;
printf("Please input quaternion: w x y z\n");
rval = fgets(line, 1023, stdin);
if ( rval == NULL ) return 0;
chomp(line);
r = sscanf(line, "%f %f %f %f", &w, &x, &y, &z);
if ( r == 4 ) {
printf("Rotation is: %f %f %f %f (modulus=%f)\n",
w, x, y, z, sqrtf(w*w + x*x + y*y + z*z));
image.orientation.w = w;
image.orientation.x = x;
image.orientation.y = y;
image.orientation.z = z;
done = 1;
/* Read quaternion from stdin */
if ( config_randomquat ) {
image.orientation = random_quaternion();
} else {
fprintf(stderr, "Invalid rotation '%s'\n", line);
image.orientation = read_quaternion();
}
} while ( !done );
if ( quaternion_valid(image.orientation) ) {
fprintf(stderr, "Orientation modulus is not zero!\n");
return 1;
}
/* Ensure no residual information */
image.qvecs = NULL;
image.sfacs = NULL;
image.data = NULL;
image.twotheta = NULL;
image.hdr = NULL;
/* Ensure no residual information */
image.qvecs = NULL;
image.sfacs = NULL;
image.data = NULL;
image.twotheta = NULL;
image.hdr = NULL;
get_diffraction(&image);
record_image(&image);
get_diffraction(&image);
record_image(&image);
snprintf(filename, 1023, "results/sim-%i.h5", number);
number++;
snprintf(filename, 1023, "results/sim-%i.h5", number);
number++;
/* Write the output file */
hdf5_write(filename, image.data, image.width, image.height);
/* Write the output file */
hdf5_write(filename, image.data, image.width, image.height);
/* Clean up */
free(image.data);
free(image.qvecs);
free(image.hdr);
free(image.sfacs);
free(image.twotheta);
/* Clean up */
free(image.data);
free(image.qvecs);
free(image.hdr);
free(image.sfacs);
free(image.twotheta);
if ( n_images && (number >= n_images) ) done = 1;
/* Do it all again */
goto again;
} while ( !done );
}
......@@ -94,3 +94,53 @@ double poisson_noise(double expected)
return k - 1;
}
double quaternion_modulus(struct quaternion q)
{
return sqrt(q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z);
}
struct quaternion normalise_quaternion(struct quaternion q)
{
double mod;
struct quaternion r;
mod = quaternion_modulus(q);
r.w = q.w / mod;
r.x = q.x / mod;
r.y = q.y / mod;
r.z = q.z / mod;
return r;
}
struct quaternion random_quaternion()
{
struct quaternion q;
q.w = (double)random()/RAND_MAX;
q.x = (double)random()/RAND_MAX;
q.y = (double)random()/RAND_MAX;
q.z = (double)random()/RAND_MAX;
normalise_quaternion(q);
return q;
}
int quaternion_valid(struct quaternion q)
{
double qmod;
qmod = quaternion_modulus(q);
/* Modulus = 1 to within some tolerance?
* Nasty allowance for floating-point accuracy follows... */
if ( (qmod > 0.999) && (qmod < 1.001) ) return 1;
return 0;
}
......@@ -56,6 +56,11 @@ struct quaternion
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);
/* --------------------------- Useful functions ----------------------------- */
......@@ -67,6 +72,16 @@ extern void progress_bar(int val, int total, const char *text);
extern double 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));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment