static void apply_cell_shift(UnitCell *cell, int k, double shift) { double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; cell_get_reciprocal(cell, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); switch ( k ) { case GPARAM_ASX : asx += shift; break; case GPARAM_ASY : asy += shift; break; case GPARAM_ASZ : asz += shift; break; case GPARAM_BSX : bsx += shift; break; case GPARAM_BSY : bsy += shift; break; case GPARAM_BSZ : bsz += shift; break; case GPARAM_CSX : csx += shift; break; case GPARAM_CSY : csy += shift; break; case GPARAM_CSZ : csz += shift; break; } cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); }
static UnitCell *new_shifted_cell(UnitCell *input, int k, double shift) { UnitCell *cell; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; cell = cell_new(); cell_get_reciprocal(input, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); switch ( k ) { case REF_ASX : asx += shift; break; case REF_ASY : asy += shift; break; case REF_ASZ : asz += shift; break; case REF_BSX : bsx += shift; break; case REF_BSY : bsy += shift; break; case REF_BSZ : bsz += shift; break; case REF_CSX : csx += shift; break; case REF_CSY : csy += shift; break; case REF_CSZ : csz += shift; break; } cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); return cell; }
struct prdata pr_refine(Crystal *cr, const RefList *full, PartialityModel pmodel) { double dev; int i; const int verbose = 0; struct prdata prdata; double mean_p_change = 0.0; prdata.refined = 0; prdata.n_filtered = 0; /* Don't refine crystal if scaling was bad */ if ( crystal_get_user_flag(cr) != 0 ) return prdata; if ( verbose ) { dev = guide_dev(cr, full); STATUS("\n"); /* Deal with progress bar */ STATUS("Before iteration: dev = %10.5e\n", dev); } i = 0; do { double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; double dev; cell_get_reciprocal(crystal_get_cell(cr), &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); pr_iterate(cr, full, pmodel, &prdata.n_filtered); update_partialities(cr, pmodel); if ( verbose ) { dev = guide_dev(cr, full); STATUS("PR Iteration %2i: dev = %10.5e\n", i+1, dev); } i++; } while ( (mean_p_change > 0.01) && (i < MAX_CYCLES) ); if ( crystal_get_user_flag(cr) == 0 ) { prdata.refined = 1; } return prdata; }
int main(int argc, char *argv[]) { struct image image; const double incr_frac = 1.0/1000000.0; double incr_val; double ax, ay, az; double bx, by, bz; double cx, cy, cz; UnitCell *cell; Crystal *cr; struct quaternion orientation; int i; int fail = 0; int quiet = 0; int plot = 0; int c; gsl_rng *rng; const struct option longopts[] = { {"quiet", 0, &quiet, 1}, {"plot", 0, &plot, 1}, {0, 0, NULL, 0} }; while ((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) { switch (c) { case 0 : break; case '?' : break; default : ERROR("Unhandled option '%c'\n", c); break; } } image.width = 1024; image.height = 1024; image.det = simple_geometry(&image); image.det->panels[0].res = 13333.3; image.det->panels[0].clen = 80e-3; image.det->panels[0].coffset = 0.0; image.lambda = ph_en_to_lambda(eV_to_J(8000.0)); image.div = 1e-3; image.bw = 0.01; image.filename = malloc(256); cr = crystal_new(); if ( cr == NULL ) { ERROR("Failed to allocate crystal.\n"); return 1; } crystal_set_mosaicity(cr, 0.0); crystal_set_profile_radius(cr, 0.005e9); crystal_set_image(cr, &image); cell = cell_new_from_parameters(10.0e-9, 10.0e-9, 10.0e-9, deg2rad(90.0), deg2rad(90.0), deg2rad(90.0)); rng = gsl_rng_alloc(gsl_rng_mt19937); for ( i=0; i<2; i++ ) { UnitCell *rot; double val; PartialityModel pmodel; if ( i == 0 ) { pmodel = PMODEL_SCSPHERE; STATUS("Testing SCSphere model:\n"); } else if ( i == 1 ) { pmodel = PMODEL_SCGAUSSIAN; STATUS("Testing SCGaussian model.\n"); } else { ERROR("WTF?\n"); return 1; } orientation = random_quaternion(rng); rot = cell_rotate(cell, orientation); crystal_set_cell(cr, rot); cell_get_reciprocal(rot, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); incr_val = incr_frac * image.div; val = test_gradients(cr, incr_val, REF_DIV, "div", "div", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * crystal_get_profile_radius(cr); val = test_gradients(cr, incr_val, REF_R, "R", "R", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * ax; val = test_gradients(cr, incr_val, REF_ASX, "ax*", "x", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * bx; val = test_gradients(cr, incr_val, REF_BSX, "bx*", "x", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * cx; val = test_gradients(cr, incr_val, REF_CSX, "cx*", "x", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * ay; val = test_gradients(cr, incr_val, REF_ASY, "ay*", "y", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * by; val = test_gradients(cr, incr_val, REF_BSY, "by*", "y", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * cy; val = test_gradients(cr, incr_val, REF_CSY, "cy*", "y", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * az; val = test_gradients(cr, incr_val, REF_ASZ, "az*", "z", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * bz; val = test_gradients(cr, incr_val, REF_BSZ, "bz*", "z", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; incr_val = incr_frac * cz; val = test_gradients(cr, incr_val, REF_CSZ, "cz*", "z", pmodel, quiet, plot); if ( val < 0.99 ) fail = 1; } gsl_rng_free(rng); return fail; }
static int check_centering(double a, double b, double c, double al, double be, double ga, LatticeType latt, char cen, char ua, gsl_rng *rng) { UnitCell *cell, *cref; UnitCell *n; UnitCellTransformation *t; int fail = 0; int i; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; double ax, ay, az; double bx, by, bz; double cx, cy, cz; STATUS(" ---------------> " "Checking %s %c (ua %c) %5.2e %5.2e %5.2e %5.2f %5.2f %5.2f\n", str_lattice(latt), cen, ua, a, b, c, al, be, ga); cref = cell_new_from_parameters(a, b, c, deg2rad(al), deg2rad(be), deg2rad(ga)); cell_set_lattice_type(cref, latt); cell_set_centering(cref, cen); cell_set_unique_axis(cref, ua); cell = cell_rotate(cref, random_quaternion(rng)); if ( cell == NULL ) return 1; cell_free(cref); check_cell(cell, "Input"); n = uncenter_cell(cell, &t); if ( n != NULL ) { STATUS("Transformation was:\n"); tfn_print(t); if ( check_cell(n, "Output") ) fail = 1; if ( !fail ) cell_print(n); } else { fail = 1; } cell_get_reciprocal(cell, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); cell_get_cartesian(n, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); fesetround(1); /* Round towards nearest */ for ( i=0; i<100; i++ ) { signed int h, k, l; double x, y, z; double nh, nk, nl; double dh, dk, dl; int f = 0; do { h = gsl_rng_uniform_int(rng, 30); k = gsl_rng_uniform_int(rng, 30); l = gsl_rng_uniform_int(rng, 30); } while ( forbidden_reflection(cell, h, k, l) ); x = h*asx + k*bsx + l*csx; y = h*asy + k*bsy + l*csy; z = h*asz + k*bsz + l*csz; nh = x*ax + y*ay + z*az; nk = x*bx + y*by + z*bz; nl = x*cx + y*cy + z*cz; dh = nh - lrint(nh); dk = nk - lrint(nk); dl = nl - lrint(nl); if ( fabs(dh) > 0.1 ) f++; if ( fabs(dk) > 0.1 ) f++; if ( fabs(dl) > 0.1 ) f++; if ( f ) { STATUS("Centered %3i %3i %3i -> " "Primitive %7.2f %7.2f %7.2f\n", h, k, l, nh, nk, nl); fail = 1; } } cell_get_reciprocal(n, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); for ( i=0; i<100; i++ ) { signed int h, k, l; double x, y, z; double nh, nk, nl; double dh, dk, dl; int f = 0; long int ih, ik, il; h = gsl_rng_uniform_int(rng, 30); k = gsl_rng_uniform_int(rng, 30); l = gsl_rng_uniform_int(rng, 30); x = h*asx + k*bsx + l*csx; y = h*asy + k*bsy + l*csy; z = h*asz + k*bsz + l*csz; nh = x*ax + y*ay + z*az; nk = x*bx + y*by + z*bz; nl = x*cx + y*cy + z*cz; dh = nh - lrint(nh); dk = nk - lrint(nk); dl = nl - lrint(nl); if ( fabs(dh) > 0.1 ) f++; if ( fabs(dk) > 0.1 ) f++; if ( fabs(dl) > 0.1 ) f++; ih = lrint(nh); ik = lrint(nk); il = lrint(nl); if ( forbidden_reflection(cell, ih, ik, il) ) { STATUS("Primitive %3i %3i %3i -> " "Centered %3li %3li %3li, " "which is forbidden\n", h, k, l, ih, ik, il); fail = 1; } if ( f ) { STATUS("Primitive %3i %3i %3i -> " "Centered %7.2f %7.2f %7.2f\n", h, k, l, nh, nk, nl); fail = 1; } } return fail; }
int main(int argc, char *argv[]) { int fail = 0; struct quaternion orientation; UnitCell *cell; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; double asmag, bsmag, csmag; double als, bes, gas; double ax, ay, az; double bx, by, bz; double cx, cy, cz; gsl_rng *rng; rng = gsl_rng_alloc(gsl_rng_mt19937); cell = cell_new_from_parameters(27.155e-9, 28.155e-9, 10.987e-9, deg2rad(90.0), deg2rad(90.0), deg2rad(120.0)); if ( cell == NULL ) return 1; orientation = random_quaternion(rng); cell = cell_rotate(cell, orientation); cell_get_reciprocal(cell, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); asmag = sqrt(pow(asx, 2.0) + pow(asy, 2.0) + pow(asz, 2.0)); bsmag = sqrt(pow(bsx, 2.0) + pow(bsy, 2.0) + pow(bsz, 2.0)); csmag = sqrt(pow(csx, 2.0) + pow(csy, 2.0) + pow(csz, 2.0)); als = angle_between(bsx, bsy, bsz, csx, csy, csz); bes = angle_between(asx, asy, asz, csx, csy, csz); gas = angle_between(asx, asy, asz, bsx, bsy, bsz); STATUS("Separation between (100) planes = %5.2f nm\n", 1e9/asmag); STATUS("Separation between (010) planes = %5.2f nm\n", 1e9/bsmag); STATUS("Separation between (001) planes = %5.2f nm\n", 1e9/csmag); STATUS("Angle between (100) and (010) planes = %5.2f deg\n", rad2deg(gas)); STATUS("Angle between (100) and (001) planes = %5.2f deg\n", rad2deg(bes)); STATUS("Angle between (010) and (001) planes = %5.2f deg\n", rad2deg(als)); cell_free(cell); cell = cell_new(); if ( cell == NULL ) return 1; cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); cell_print(cell); cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); STATUS("Cell choice 1:\n"); cell_set_cartesian(cell, ax, ay, az, bx, by, bz, cx, cy, cz); cell_print(cell); STATUS("Cell choice 2:\n"); cell_set_cartesian(cell, bx, by, bz, -ax-bx, -ay-by, -az-bz, cx, cy, cz); cell_print(cell); STATUS("Cell choice 3:\n"); cell_set_cartesian(cell, -ax-bx, -ay-by, -az-bz, ax, ay, az, cx, cy, cz); cell_print(cell); gsl_rng_free(rng); return fail; }
static void write_crystal(Stream *st, Crystal *cr, int include_reflections) { UnitCell *cell; RefList *reflist; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; double a, b, c, al, be, ga; double rad; fprintf(st->fh, CRYSTAL_START_MARKER"\n"); cell = crystal_get_cell(cr); assert(cell != NULL); cell_get_parameters(cell, &a, &b, &c, &al, &be, &ga); fprintf(st->fh, "Cell parameters %7.5f %7.5f %7.5f nm," " %7.5f %7.5f %7.5f deg\n", a*1.0e9, b*1.0e9, c*1.0e9, rad2deg(al), rad2deg(be), rad2deg(ga)); cell_get_reciprocal(cell, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); fprintf(st->fh, "astar = %+9.7f %+9.7f %+9.7f nm^-1\n", asx/1e9, asy/1e9, asz/1e9); fprintf(st->fh, "bstar = %+9.7f %+9.7f %+9.7f nm^-1\n", bsx/1e9, bsy/1e9, bsz/1e9); fprintf(st->fh, "cstar = %+9.7f %+9.7f %+9.7f nm^-1\n", csx/1e9, csy/1e9, csz/1e9); fprintf(st->fh, "lattice_type = %s\n", str_lattice(cell_get_lattice_type(cell))); fprintf(st->fh, "centering = %c\n", cell_get_centering(cell)); fprintf(st->fh, "unique_axis = %c\n", cell_get_unique_axis(cell)); rad = crystal_get_profile_radius(cr); fprintf(st->fh, "profile_radius = %.5f nm^-1\n", rad/1e9); reflist = crystal_get_reflections(cr); if ( reflist != NULL ) { fprintf(st->fh, "diffraction_resolution_limit" " = %.2f nm^-1 or %.2f A\n", crystal_get_resolution_limit(cr)/1e9, 1e10 / crystal_get_resolution_limit(cr)); fprintf(st->fh, "num_reflections = %i\n", num_reflections(reflist)); fprintf(st->fh, "num_saturated_reflections = %lli\n", crystal_get_num_saturated_reflections(cr)); } if ( include_reflections ) { if ( reflist != NULL ) { fprintf(st->fh, REFLECTION_START_MARKER"\n"); if ( AT_LEAST_VERSION(st, 2, 2) ) { write_stream_reflections(st->fh, reflist); } else { /* This function writes like a normal reflection * list was written in stream 2.1 */ write_stream_reflections_2_1(st->fh, reflist); } fprintf(st->fh, REFLECTION_END_MARKER"\n"); } else { fprintf(st->fh, "No integrated reflections.\n"); } } fprintf(st->fh, CRYSTAL_END_MARKER"\n"); }