void quat_rotate(gdouble *vec, gdouble *quat) { gdouble rot[9]; quat_matrix(rot, quat); vecmat(rot, vec); }
void docking_project_create(GtkWidget *w, struct model_pak *model) { gint a, b, i, m, n, rx, ry, rz, size, rigid_save; gint a_max, b_max, rx_max, ry_max, rz_max; gchar *file, *dump, *dump_save, *rigid_move_save; gdouble dx, dy, dz, x[3], scale[3], mat[9], dock_centroid[3], q[4]; GString *name, *rigid; GSList *list, *core_list, *shell_list; struct dock_pak *dock; struct core_pak *core, *core2; struct shel_pak *shell, *shell2; FILE *fp; /* checks */ g_assert(model != NULL); size = g_slist_length(model->selection); if (!size) { gui_text_show(WARNING, "Please select the subset you wish to dock.\n"); return; } /* create new docking project */ dock = g_malloc(sizeof(struct dock_pak)); /* NEW - setup project path */ /* g_path_get_dirname(model->fullpath); g_get_current_dir(); */ /* seek a file name that doesn't exist (avoid background overwriting) */ name = g_string_new(NULL); i=0; do { g_string_sprintf(name, "project_%06d", i); i++; } while (g_file_test(name->str, G_FILE_TEST_EXISTS)); dock->path = g_build_path(sysenv.cwd, name->str, NULL); printf("creating new project: [%s]\n", dock->path); #if WIN32 if (mkdir(dock->path)) #else if (mkdir(dock->path, 0700)) #endif { gui_text_show(ERROR, "Failed to create project directory.\n"); g_free(dock->path); g_free(dock); return; } /* project control file */ g_string_sprintf(name, "%s%sproject.pcf", dock->path, DIR_SEP); fp = fopen(name->str, "wt"); /* save original variables */ dump_save = model->gulp.dump_file; model->gulp.dump_file = NULL; rigid_save = model->gulp.rigid; model->gulp.rigid = dock_rigid_on; rigid_move_save = model->gulp.rigid_move; model->gulp.rigid_move = NULL; if (model->gulp.rigid) { rigid = g_string_new(NULL); if (dock_rigid_x) g_string_sprintf(rigid, "x"); if (dock_rigid_y) g_string_sprintfa(rigid, "y"); if (dock_rigid_z) g_string_sprintfa(rigid, "z"); model->gulp.rigid_move = g_string_free(rigid, FALSE); } /* duplicate selection for docking */ core_list = NULL; shell_list = NULL; VEC3SET(dock_centroid, 0.0, 0.0, 0.0); for (list=model->selection ; list ; list=g_slist_next(list)) { core2 = dup_core(list->data); core_list = g_slist_prepend(core_list, core2); if (core2->shell) shell_list = g_slist_prepend(shell_list, core2->shell); /* compute centroid */ ARR3ADD(dock_centroid, core2->x); } /* NB: lists must have the same order as original selection */ core_list = g_slist_reverse(core_list); shell_list = g_slist_reverse(shell_list); VEC3MUL(dock_centroid, 1.0/(gdouble) size); /* fractional translation grid units */ scale[0] = dock_cell[0] / dock_grid[0]; scale[1] = dock_cell[1] / dock_grid[1]; /* rotational increments */ dx = PI/dock_rotate[0]; dy = PI/dock_rotate[1]; dz = PI/dock_rotate[2]; /* translational sampling */ if (dock_grid_on) { a_max = dock_grid[0]; b_max = dock_grid[1]; } else { a_max = 1; b_max = 1; } /* rotational sampling */ if (dock_rotate_on) { rx_max = dock_rotate[0]; ry_max = dock_rotate[1]; rz_max = dock_rotate[2]; } else { rx_max = 1; ry_max = 1; rz_max = 1; } /* project header */ fprintf(fp, "%%title solvent mapping project\n"); fprintf(fp, "%%set %d %d %f %f\n", a_max, b_max, dock_cell[0], dock_cell[1]); /* loop over all grid translations */ m = n = 0; for (a=0 ; a<a_max ; a++) { for (b=0 ; b<b_max ; b++) { VEC3SET(x, a, b, 0.0); x[0] *= scale[0]; x[1] *= scale[1]; /* loop over rotations */ VEC4SET(q, 1.0, 0.0, 0.0, 0.0); for (rx=0 ; rx<rx_max ; rx++) { if (rx) quat_concat_euler(q, PITCH, dx); for (ry=0 ; ry<ry_max ; ry++) { if (ry) quat_concat_euler(q, ROLL, dy); for (rz=0 ; rz<rz_max ; rz++) { if (rz) quat_concat_euler(q, YAW, dz); /* build total rotation matrix */ quat_matrix(mat, q); /* transform the cores and shells */ i = 0; for (list=model->selection ; list ; list=g_slist_next(list)) { core = list->data; /* FIXME - should we restore this after? how? */ core->region = 2; /* get original selection core coordinates */ core2 = g_slist_nth_data(core_list, i); ARR3SET(core->x, core2->x); /* perform the rotation (NB: must be done about origin in cartesian space) */ ARR3SUB(core->x, dock_centroid); vecmat(model->latmat, core->x); vecmat(mat, core->x); vecmat(model->ilatmat, core->x); ARR3ADD(core->x, dock_centroid); /* add the current translation offset */ ARR3ADD(core->x, x); /* as above, for the associated shell */ if (core->shell) { shell = core->shell; shell->region = 2; shell2 = core2->shell; g_assert(shell2 != NULL); ARR3SET(shell->x, shell2->x); ARR3SUB(shell->x, dock_centroid); vecmat(model->latmat, shell->x); vecmat(mat, shell->x); vecmat(model->ilatmat, shell->x); ARR3ADD(shell->x, dock_centroid); ARR3ADD(shell->x, x); } i++; } /* write docking configuration */ /* file = g_strdup_printf("%s_%06d.gin", model->basename, n); */ /* m identifies grid points (for later minimum check) */ fprintf(fp, "%s_%06d.gin %f %f %d\n", model->basename, n, x[0], x[1], m); file = g_strdup_printf("%s%s%s_%06d.gin", dock->path, DIR_SEP, model->basename, n); dump = g_strdup_printf("%s_%06d.res", model->basename, n); model->gulp.dump_file = dump; write_gulp(file, model); g_free(file); g_free(dump); n++; } } } m++; } } /* restore original variables */ model->gulp.dump_file = dump_save; model->gulp.rigid = rigid_save; g_free(model->gulp.rigid_move); model->gulp.rigid_move = rigid_move_save; /* restore original selection (delete, then concat saved list) */ i = 0; for (list=model->selection ; list ; list=g_slist_next(list)) { core = list->data; core2 = g_slist_nth_data(core_list, i); ARR3SET(core->x, core2->x); if (core->shell) { shell = core->shell; shell2 = core2->shell; g_assert(shell2 != NULL); ARR3SET(shell->x, shell2->x); } i++; } /* free docking core/shell lists */ free_slist(core_list); free_slist(shell_list); g_string_free(name, TRUE); fclose(fp); /* run docking in background unless told to stop after setup */ /* if (!dock_no_execute) submit_task("Docking", &docking_execute, dock, &docking_cleanup, dock, model); */ }