64 void write_eulers(
char *eu_file,
unsigned long eu_count,
float *eu_store,
65 double eu_range[3][2],
double delta)
68 const char *program =
"lib_eul";
71 if ((out = fopen(eu_file,
"w")) == NULL) {
75 for (i = 0; i < eu_count; i++)
76 fprintf(out,
"%10.4f%10.4f%10.4f\n",
83 void read_eulers(
char *in_file,
unsigned long *eu_count,
float **eu_store)
88 const char *program =
"lib_eul";
92 if ((in = fopen(in_file,
"r")) == NULL) {
97 if (fscanf(in,
"%lf %lf %lf\n", &psi, &theta, &phi) != 3)
break;
103 *eu_store = (
float *)
alloc_vect(i * 3,
sizeof(
float));
104 if ((in = fopen(in_file,
"r")) == NULL) {
109 if (fscanf(in,
"%lf %lf %lf\n", &psi, &theta, &phi) != 3)
break;
111 *(*eu_store + i * 3 + 0) = psi *
ROT_CONV;
112 *(*eu_store + i * 3 + 1) = theta *
ROT_CONV;
113 *(*eu_store + i * 3 + 2) = phi *
ROT_CONV;
119 printf(
"lib_eul> %lu Euler angles read from file %s\n", i, in_file);
133 double psi_in,
double theta_in,
double phi_in,
134 double psi_ref,
double theta_ref,
double phi_ref)
136 double curr_psi, curr_theta, curr_phi;
137 double new_psi, new_theta, new_phi;
140 curr_psi = psi_in - psi_ref;
141 if (curr_psi >= 0) new_psi = fmod(curr_psi, 2 *
PI) + psi_ref;
142 else new_psi = 2 *
PI - fmod(-curr_psi, 2 *
PI) + psi_ref;
144 curr_theta = theta_in - theta_ref;
145 if (curr_theta >= 0) new_theta = fmod(curr_theta, 2 *
PI) + theta_ref;
146 else new_theta = 2 *
PI - fmod(-curr_theta, 2 *
PI) + theta_ref;
148 curr_phi = phi_in - phi_ref;
149 if (curr_phi >= 0) new_phi = fmod(curr_phi, 2 *
PI) + phi_ref;
150 else new_phi = 2 *
PI - fmod(-curr_phi, 2 *
PI) + phi_ref;
155 if (new_theta - theta_ref >
PI) {
157 if (new_theta >= 0) curr_theta = fmod(new_theta, 2 *
PI);
158 else curr_theta = 2 *
PI - fmod(-new_theta, 2 *
PI);
159 new_theta -= 2 * curr_theta;
162 curr_theta = new_theta - theta_ref;
163 if (curr_theta >= 0) new_theta = fmod(curr_theta, 2 *
PI) + theta_ref;
164 else new_theta = 2 *
PI - fmod(-curr_theta, 2 *
PI) + theta_ref;
169 if (new_psi - psi_ref >
PI) new_psi -=
PI;
173 if (new_phi - phi_ref >
PI) new_phi -=
PI;
178 *theta_out = new_theta;
186 double sin_psi = sin(psi);
187 double cos_psi = cos(psi);
188 double sin_theta = sin(theta);
189 double cos_theta = cos(theta);
190 double sin_phi = sin(phi);
191 double cos_phi = cos(phi);
194 dump[0][0] = cos_psi * cos_phi - cos_theta * sin_phi * sin_psi;
195 dump[0][1] = cos_psi * sin_phi + cos_theta * cos_phi * sin_psi;
196 dump[0][2] = sin_psi * sin_theta;
197 dump[1][0] = -sin_psi * cos_phi - cos_theta * sin_phi * cos_psi;
198 dump[1][1] = -sin_psi * sin_phi + cos_theta * cos_phi * cos_psi;
199 dump[1][2] = cos_psi * sin_theta;
200 dump[2][0] = sin_theta * sin_phi;
201 dump[2][1] = -sin_theta * cos_phi;
202 dump[2][2] = cos_theta;
220 unsigned long *eu_count,
float **eu_store)
224 double phi, phi_tmp, psi_old, psi_new, psi_tmp,
theta, theta_tmp, h;
225 const char *program =
"lib_eul";
229 n = (int)ceil(360.0 * 360.0 / (delta * delta *
PI));
232 phi_steps = (int)ceil((eu_range[2][1] - eu_range[2][0]) /
delta);
242 psi_new = (eu_range[0][1] + eu_range[0][0]) * 0.5 *
ROT_CONV;
243 remap_eulers(&psi_new, &theta, &phi_tmp, psi_new, theta, 0.0,
244 eu_range[0][0]*
ROT_CONV, eu_range[1][0]*ROT_CONV, eu_range[2][0]*ROT_CONV);
245 if (eu_range[1][0]*ROT_CONV <= theta && eu_range[1][1]*ROT_CONV >= theta) j++;
250 for (k = 1; k < n - 1; k++) {
251 h = -1 + 2 * k / (n - 1.0);
253 psi_new = psi_old + 3.6 / (
sqrt((
double)n * (1 - h * h)));
256 remap_eulers(&psi_new, &theta, &phi_tmp, psi_new, theta, 0.0,
257 eu_range[0][0]*ROT_CONV, eu_range[1][0]*ROT_CONV, eu_range[2][0]*ROT_CONV);
259 if (eu_range[0][0]*ROT_CONV <= psi_new && eu_range[0][1]*ROT_CONV >= psi_new && eu_range[1][0]*ROT_CONV <= theta && eu_range[1][1]*ROT_CONV >= theta) j++;
264 psi_new = (eu_range[0][1] + eu_range[0][0]) * 0.5 * ROT_CONV;
265 remap_eulers(&psi_new, &theta, &phi_tmp, psi_new, theta, 0.0,
266 eu_range[0][0]*ROT_CONV, eu_range[1][0]*ROT_CONV, eu_range[2][0]*ROT_CONV);
267 if (eu_range[1][0]*ROT_CONV <= theta && eu_range[1][1]*ROT_CONV >= theta) j++;
271 printf(
"lib_eul> Spiral Euler angle distribution, total number %lu (delta = %f deg.)\n", i, delta);
275 *eu_store = (
float *)
alloc_vect(i * 3,
sizeof(
float));
280 psi_new = (eu_range[0][1] + eu_range[0][0]) * 0.5 * ROT_CONV;
281 remap_eulers(&psi_new, &theta, &phi_tmp, psi_new, theta, 0.0,
282 eu_range[0][0]*ROT_CONV, eu_range[1][0]*ROT_CONV, eu_range[2][0]*ROT_CONV);
283 if (eu_range[1][0]*ROT_CONV <= theta && eu_range[1][1]*ROT_CONV >= theta) {
284 for (phi = eu_range[2][0]; phi <= eu_range[2][1]; phi +=
delta) {
285 if (phi >= 360)
break;
286 remap_eulers(&psi_tmp, &theta_tmp, &phi_tmp, psi_new, theta, phi * ROT_CONV,
288 *(*eu_store + j + 0) = psi_tmp;
289 *(*eu_store + j + 1) = theta_tmp;
290 *(*eu_store + j + 2) = phi_tmp;
297 for (k = 1; k < n - 1; k++) {
298 h = -1 + 2 * k / (n - 1.0);
300 psi_new = psi_old + 3.6 / (
sqrt((
double)n * (1 - h * h)));
302 remap_eulers(&psi_new, &theta, &phi_tmp, psi_new, theta, 0.0,
303 eu_range[0][0]*ROT_CONV, eu_range[1][0]*ROT_CONV, eu_range[2][0]*ROT_CONV);
304 if (eu_range[0][0]*ROT_CONV <= psi_new && eu_range[0][1]*ROT_CONV >= psi_new && eu_range[1][0]*ROT_CONV <= theta && eu_range[1][1]*ROT_CONV >= theta) {
305 for (phi = eu_range[2][0]; phi <= eu_range[2][1]; phi +=
delta) {
306 if (phi >= 360)
break;
307 remap_eulers(&psi_tmp, &theta_tmp, &phi_tmp, psi_new, theta, phi * ROT_CONV,
309 *(*eu_store + j + 0) = psi_tmp;
310 *(*eu_store + j + 1) = theta_tmp;
311 *(*eu_store + j + 2) = phi_tmp;
319 psi_new = (eu_range[0][1] + eu_range[0][0]) * 0.5 * ROT_CONV;
320 remap_eulers(&psi_new, &theta, &phi_tmp, psi_new, theta, 0.0,
321 eu_range[0][0]*ROT_CONV, eu_range[1][0]*ROT_CONV, eu_range[2][0]*ROT_CONV);
322 if (eu_range[1][0]*ROT_CONV <= theta && eu_range[1][1]*ROT_CONV >= theta) {
323 for (phi = eu_range[2][0]; phi <= eu_range[2][1]; phi +=
delta) {
324 if (phi >= 360)
break;
325 remap_eulers(&psi_tmp, &theta_tmp, &phi_tmp, psi_new, theta, phi * ROT_CONV,
327 *(*eu_store + j + 0) = psi_tmp;
328 *(*eu_store + j + 1) = theta_tmp;
329 *(*eu_store + j + 2) = phi_tmp;
341 unsigned long *eu_count,
float **eu_store)
343 double psi, psi_tmp,
theta, theta_tmp, phi, phi_tmp;
345 int psi_steps, theta_steps, phi_steps;
347 unsigned long i,
j,
n,
k;
348 unsigned long partial_count, curr_count;
350 const char *program =
"lib_eul";
355 psi_steps = (int)ceil((eu_range[0][1] - eu_range[0][0]) /
delta);
356 theta_steps = (int)ceil((eu_range[1][1] - eu_range[1][0]) /
delta);
357 phi_steps = (int)ceil((eu_range[2][1] - eu_range[2][0]) /
delta);
359 if (psi_steps < 1 || theta_steps < 1 || phi_steps < 1) {
363 partial_count = (psi_steps + 1) * (theta_steps + 1);
366 curr_eulers = (
float *)
alloc_vect(partial_count * 3,
sizeof(
float));
367 degenerate = (
char *)
alloc_vect(partial_count,
sizeof(
char));
379 for (psi = 0; (float)psi <= psi_steps * delta && (
float)psi < 360 ; psi +=
delta) {
380 for (theta = 0; (float)theta <= theta_steps * delta && (
float)theta < 360 ; theta +=
delta) {
383 (eu_range[1][0] + theta)*ROT_CONV,
384 (eu_range[2][0] + phi)*ROT_CONV,
386 *(curr_eulers + j + 0) = psi_tmp;
387 *(curr_eulers + j + 1) = theta_tmp;
388 *(curr_eulers + j + 2) = phi_tmp;
396 printf(
"lib_eul> Euler angles, initial combinations of psi and phi angles %lu (delta = %f deg.)\n", partial_count, delta);
398 for (j = 0; j < partial_count; j++) *(degenerate + j) = 0;
401 printf(
"lib_eul> Searching for redundant orientations ");
402 for (j = 0; j < partial_count; j++)
if (*(degenerate + j) == 0) {
403 if (fmod(j + 1, 1000) == 0.0)printf(
".");
404 rot_euler(pdb1, pdb2, 1, *(curr_eulers + j * 3 + 0), *(curr_eulers + j * 3 + 1), *(curr_eulers + j * 3 + 2));
405 for (i = j + 1; i < partial_count; i++)
if (*(degenerate + i) == 0) {
406 rot_euler(pdb1, pdb3, 1, *(curr_eulers + i * 3 + 0), *(curr_eulers + i * 3 + 1), *(curr_eulers + i * 3 + 2));
407 if ((pdb2[0].
x - pdb3[0].
x) * (pdb2[0].x - pdb3[0].x) + (pdb2[0].
y - pdb3[0].
y) * (pdb2[0].y - pdb3[0].y) +
408 (pdb2[0].
z - pdb3[0].
z) * (pdb2[0].z - pdb3[0].z) < ((2.0 * sin(0.7 * delta *
ROT_CONV / 2.0)) * (2.0 * sin(0.7 * delta *
ROT_CONV / 2.0)))) {
410 *(degenerate +
i) = 1;
416 *eu_count = (partial_count -
k) * (phi_steps + 1);
417 curr_count = (partial_count -
k) * (phi_steps + 1);
420 *eu_store = (
float *)
alloc_vect(curr_count * phi_steps * 3,
sizeof(
float));
422 printf(
"lib_eul> Adding psi angle to reduced set...\n");
423 for (j = 0; j < partial_count; j++) {
424 if (*(degenerate + j) != 1) {
425 for (phi = 0; (float)phi <= phi_steps * delta && (
float)phi < 360 ; phi +=
delta) {
426 *(*eu_store + h * 3 + 0) = *(curr_eulers + j * 3 + 0);
427 *(*eu_store + h * 3 + 1) = *(curr_eulers + j * 3 + 1);
428 *(*eu_store + h * 3 + 2) = phi *
ROT_CONV;
436 printf(
"lib_eul> Euler angles, final number %lu (delta = %f deg.)\n", *eu_count, delta);
454 for (i = 0; i < 3; ++
i)
for (j = 0; j < 3; ++
j) trace += matrix1[i][j] * matrix2[i][j];
455 return (trace - 1.0) / 2.0;
461 char similar_eulers(
double a1,
double a2,
double a3,
double b1,
double b2,
double b3)
466 double matrix1[3][3], matrix2[3][3];
472 for (i = 0; i < 3; ++
i)
for (j = 0; j < 3; ++
j) trace += matrix2[i][j] * matrix1[i][j];
473 deviation_cosine = (trace - 1.0) / 2.0;
474 if (deviation_cosine <= 0.9998477)
return 0;
490 unsigned long *eu_count,
float **eu_store)
493 double psi_ang_dist, psi_real_dist;
494 double theta_real_dist, phi_real_dist;
495 double psi_steps, theta_steps, phi_steps;
496 double psi_range, theta_range, phi_range;
498 const char *program =
"lib_eul";
500 if ((eu_range[0][1] - eu_range[0][0]) / delta < -1 ||
501 (eu_range[1][1] - eu_range[1][0]) / delta < -1 ||
502 (eu_range[2][1] - eu_range[2][0]) / delta < -1) {
506 psi_range = eu_range[0][1] - eu_range[0][0];
507 theta_range = eu_range[1][1] - eu_range[1][0];
508 phi_range = eu_range[2][1] - eu_range[2][0];
512 phi_steps = rint((phi_range / delta) + 0.499);
513 phi_real_dist = phi_range / phi_steps;
515 theta_steps = rint((theta_range / delta) + 0.499);
516 theta_real_dist = theta_range / theta_steps;
521 for (phi = eu_range[2][0]; phi < 360.0 &&
522 phi <= eu_range[2][1]; phi += phi_real_dist) {
523 for (theta = eu_range[1][0]; theta <= 180.0 &&
524 theta <= eu_range[1][1]; theta += theta_real_dist) {
525 if (theta == 0.0 || theta == 180.0) {
528 psi_steps = rint(360.0 * cos((90.0 - theta) *
ROT_CONV) / delta);
530 psi_ang_dist = 360.0 / psi_steps;
531 psi_real_dist = psi_range / (ceil(psi_range / psi_ang_dist));
532 for (psi = eu_range[0][0]; psi < 360.0 &&
533 psi <= eu_range[0][1]; psi += psi_real_dist) {
542 *eu_store = (
float *)
alloc_vect(*eu_count * 3,
sizeof(
float));
545 for (phi = eu_range[2][0]; phi < 360.0 &&
546 phi <= eu_range[2][1]; phi += phi_real_dist) {
547 for (theta = eu_range[1][0]; theta <= 180.0 &&
548 theta <= eu_range[1][1]; theta += theta_real_dist) {
549 if (theta == 0.0 || theta == 180.0) {
552 psi_steps = rint(360.0 * cos((90.0 - theta) *
ROT_CONV) / delta);
554 psi_ang_dist = 360.0 / psi_steps;
555 psi_real_dist = psi_range / (ceil(psi_range / psi_ang_dist));
556 for (psi = eu_range[0][0]; psi < 360.0 &&
557 psi <= eu_range[0][1]; psi += psi_real_dist) {
559 *(*eu_store + j * 3 + 0) = (
float)psi *
ROT_CONV;
560 *(*eu_store + j * 3 + 1) = (
float)theta *
ROT_CONV;
561 *(*eu_store + j * 3 + 2) = (
float)phi *
ROT_CONV;
568 printf(
"lib_eul> Proportional Euler angles distribution, total number %lu (delta = %f deg.)\n", *eu_count, delta);
void rot_euler(PDB *pdb_original, PDB *pdb_rotate, unsigned num_atoms, double psi, double theta, double phi)
void free_vect_and_zero_ptr(void **pvect)
void read_eulers(char *in_file, unsigned long *eu_count, float **eu_store)
void sqrt(Image< double > &op)
void eu_spiral(double eu_range[3][2], double delta, unsigned long *eu_count, float **eu_store)
double deviation_cosine(double matrix1[3][3], double matrix2[3][3])
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void error_open_filename(int error_number, const char *program, char *argv)
void remap_eulers(double *psi_out, double *theta_out, double *phi_out, double psi_in, double theta_in, double phi_in, double psi_ref, double theta_ref, double phi_ref)
void error_negative_euler(int error_number, const char *program)
void write_eulers(char *eu_file, unsigned long eu_count, float *eu_store, double eu_range[3][2], double delta)
void get_rot_matrix(double dump[3][3], double psi, double theta, double phi)
double psi(const double x)
char similar_eulers(double a1, double a2, double a3, double b1, double b2, double b3)
void * alloc_vect(unsigned int n, size_t elem_size)
fprintf(glob_prnt.io, "\)
void eu_sparsed(double eu_range[3][2], double delta, unsigned long *eu_count, float **eu_store)
void eu_proportional(double eu_range[3][2], double delta, unsigned long *eu_count, float **eu_store)