Example #1
0
void coords_confine_cores(GSList *cores, struct model_pak *model)
{
gint dummy[3];
gdouble x[3];
GSList *list;
struct core_pak *core;
struct shel_pak *shell;

g_assert(model != NULL);

if (!model->periodic)
  return;

/* translate cores to within the cell */
for (list=cores ; list ; list=g_slist_next(list))
  {
  core = list->data;
  fractional_clamp(core->x, dummy, model->periodic);

/* move shell */
  if (core->shell)
    {
    shell = core->shell;

/* want core-shell distance to be smallest possible */
    ARR3SET(x, shell->x);
    ARR3SUB(x, core->x);
    fractional_min(x, model->periodic);
    ARR3SET(shell->x, core->x);
    ARR3ADD(shell->x, x);
    }
  }
}
Example #2
0
gint region_move_atom(struct core_pak *core, gint direction,
                                    struct model_pak *data)
{
gint flag, primary, secondary, mov[2];
gdouble vec[3], tmp[3], d[3];
GSList *list;
struct core_pak *comp;

#if DEBUG_REGION_SWITCH_ATOM
printf("       model: %s\n", data->basename);
printf(" periodicity: %d\n", data->periodic);
printf("         hkl: %f %f %f\n", data->surface.miller[0],
          data->surface.miller[1], data->surface.miller[2]);
printf("        dhkl: %f\n", data->surface.dspacing);
printf("region sizes: %f %f\n", data->surface.region[0], data->surface.region[1]);
printf("      moving: ");
if (direction == UP)
  printf("UP\n");
else
  printf("DOWN\n");
#endif

/* checks */
g_return_val_if_fail(data != NULL, 1);
g_return_val_if_fail(data->periodic == 2, 1);
if (data->surface.region[0] < 1)
  {
  gui_text_show(ERROR, "region 1 is empty.\n");
  return(1);
  }

/* setup region switching labels */
if (direction == UP)
  {
  primary = REGION1A;
  secondary = REGION2A;
  }
else
  {
  primary = REGION2A;
  secondary = REGION1A;
  }

/* get fractional depth translation vector */
ARR3SET(vec, data->surface.depth_vec);
vecmat(data->ilatmat, vec);

/* calculate offset to region boundary */
ARR3SET(tmp, vec);
if (direction == DOWN)
  {
  VEC3MUL(tmp, data->surface.region[0]);
  VEC3MUL(tmp, -1.0);
  }
else
  {
  if (data->surface.region[1] == 0)
    {
    VEC3MUL(tmp, data->surface.region[0]);
    }
  else
    {
    VEC3MUL(tmp, data->surface.region[1]);
    }
  }

/* if region 2 is empty, just move core to the bottom */
if (data->surface.region[1] == 0.0)
  {
  ARR3ADD(core->x, tmp);
  if (core->shell)
    {
    ARR3ADD((core->shell)->x, tmp);
    }
  atom_colour_scheme(data->colour_scheme, core, data);
  return(0);
  }

/* get coordinates of target atom */
ARR3ADD(tmp, core->x);

#if DEBUG_REGION_SWITCH_ATOM
P3VEC("    translation: ", vec);
P3VEC("  target coords: ", tmp);
#endif

/* find the target */
flag=0;
for (list=data->cores ; list ; list=g_slist_next(list))
  {
  comp = list->data;

/* only atoms of the same type need apply */
  if (core->atom_code != comp->atom_code)
    continue;

/* get difference vector */
  ARR3SET(d, comp->x);
  ARR3SUB(d, tmp);

/* pbc constraint */
  while(d[0] < -FRACTION_TOLERANCE)
    d[0] += 1.0;
  while(d[0] > 0.5)
    d[0] -= 1.0;
  while(d[1] < -FRACTION_TOLERANCE)
    d[1] += 1.0;
  while(d[1] > 0.5)
    d[1] -= 1.0;

/* test difference vector's magnitude */
  if (VEC3MAGSQ(d) < FRACTION_TOLERANCE)
    {
/* change its labelling */
#if DEBUG_REGION_SWITCH_ATOM
printf("Matched core: %p\n", comp);
#endif
    comp->region = secondary;
    if (comp->shell)
      {
      (comp->shell)->region = secondary;
      }
    atom_colour_scheme(data->colour_scheme, comp, data);
    flag++;
    break;
    }
  }

if (!flag)
  {
  gui_text_show(ERROR, "Failed to find a boundary image.\n");
  return(1);
  }

/* now move selected atom to bottom of region 2 */
ARR3SET(tmp, vec);
VEC3MUL(tmp, (data->surface.region[0] + data->surface.region[1]));
if (direction == UP)
  VEC3MUL(tmp, -1.0);
ARR3SUB(core->x, tmp);
core->region = primary;
/* pbc constrain */
fractional_clamp(core->x, mov, 2);

if (core->shell)
  {
  ARR3SUB((core->shell)->x, tmp);
  ARR2ADD((core->shell)->x, mov);
  (core->shell)->region = primary;
  }

atom_colour_scheme(data->colour_scheme, core, data);

return(0);
}
Example #3
0
void camera_waypoint_animate(gint frames, gint overwrite, struct model_pak *model)
{
gint i;
gdouble a, af, v[3], e[3], o[3], tmp[3];
gdouble jf, jv[3], x[3], mat[9];
GSList *list, *journey;
struct camera_pak *cam, *cam1, *cam2;

/* checks */
g_assert(model != NULL);
g_assert(frames > 0);
if (g_slist_length(model->waypoint_list) < 2)
  {
  gui_text_show(ERROR, "You need to make at least 2 waypoint.\n");
  return;
  }

/* close any active animation dialog */
dialog_destroy_type(ANIM);

#if DEBUG_CAMERA_ANIMATE
printf("frames for each traversal: %d\n", frames);
#endif

list = model->waypoint_list;
cam1 = list->data;
list = g_slist_next(list);

/* create the camera journey */
journey = NULL;
while (list)
  {
  cam2 = list->data;

/* setup camera journey vector */
  ARR3SET(jv, cam2->x);
  ARR3SUB(jv, cam1->x);

/* add starting camera over journey leg */
  for (i=0 ; i<frames ; i++)
    {
/* journey fraction */
    jf = i;
    jf /= frames;

    ARR3SET(x, jv);
    VEC3MUL(x, jf);    

    cam = camera_dup(cam1);
    ARR3ADD(cam->x, x);

    journey = g_slist_prepend(journey, cam);
    }
 
/* approx 5 degrees */
#define ROTATION_INCREMENT 0.08727
/* (v x e plane alignment) */
proj_vop(v, cam2->v, cam1->o);
a = via(v, cam1->v, 3);

/* compute rotation increment */
af = (gint) nearest_int(a / ROTATION_INCREMENT);
if (!af)
  af = 1.0;

/* test rotation sense */
matrix_v_rotation(mat, cam1->o, a);
ARR3SET(tmp, cam1->v);
vecmat(mat, tmp);
if (via(tmp, v, 3) > 0.1)
  a *= -1.0;

/* build rotaton */
matrix_v_rotation(mat, cam1->o, a/af);

/* apply to camera */
ARR3SET(v, cam1->v);
ARR3SET(e, cam1->e);
for (i=af ; i-- ; )
  {
  cam = camera_dup(cam1);
  ARR3SET(cam->x, cam2->x);

  vecmat(mat, v);
  vecmat(mat, e);

  ARR3SET(cam->v, v);
  ARR3SET(cam->e, e);

  journey = g_slist_prepend(journey, cam);
  }

/* TODO - apply elevation to get v in complete coincidence */
/* rotate about e to achieve coincidence */
a = via(v, cam2->v, 3);

/* compute rotation increment */
af = (gint) nearest_int(a / ROTATION_INCREMENT);
if (!af)
  af = 1.0;

/* test rotation sense */
matrix_v_rotation(mat, e, a);
ARR3SET(tmp, v);
vecmat(mat, tmp);
if (via(tmp, cam2->v, 3) > 0.1)
  a *= -1.0;

/* build rotaton */
matrix_v_rotation(mat, e, a/af);

/* apply to camera */
ARR3SET(o, cam1->o);
for (i=af ; i-- ; )
  {
  cam = camera_dup(cam1);
  ARR3SET(cam->x, cam2->x);

  vecmat(mat, v);
  vecmat(mat, o);

  ARR3SET(cam->v, v);
  ARR3SET(cam->o, o);
  ARR3SET(cam->e, e);

  journey = g_slist_prepend(journey, cam);
  }

/* endpoint camera */
  journey = g_slist_prepend(journey, camera_dup(cam2));

/* get next journey leg */
  cam1 = cam2;
  list = g_slist_next(list);
  }
journey = g_slist_reverse(journey);

if (overwrite)
  {
  free_slist(model->transform_list);
  model->transform_list = journey;
  }
else
  model->transform_list = g_slist_concat(model->transform_list, journey);

model->num_frames = g_slist_length(model->transform_list);
model->animation = TRUE;

redraw_canvas(SINGLE);
}
Example #4
0
void delete_duplicate_cores(struct model_pak *model)
{
gdouble vec[3];
GSList *list1, *list2, *za_list;
gpointer zone;
struct core_pak *core1, *core2;
struct shel_pak *s1, *s2;

/* checks */
g_assert(model != NULL);
g_assert(model->zone_array != NULL);

#if DEBUG_REMOVE_DUPLICATES
printf("Initial cores: %d\n", g_slist_length(model->cores));
printf("Initial shels: %d\n", g_slist_length(model->shels));
#endif

/* enumerate all cores */
for (list1=model->cores ; list1 ; list1=g_slist_next(list1))
  {
  core1 = list1->data;
  if (core1->status & DELETED)
    continue;

/* enumerate cores in current locality */
  zone = zone_get(core1->x, model->zone_array);

#if DEBUG_REMOVE_DUPLICATES_MORE
printf(" + %s [%p] : [%p] :", core1->atom_label, core1, zone);
P3VEC(" ", core1->x);
#endif
/* should use zone_area_cores() as a very small coord difference */
/* can result in cores being put in different (neighbouring) zones */
/*
  for (list2=zone_cores(zone) ; list2 ; list2=g_slist_next(list2))
*/

  za_list = zone_area_cores(1, zone, model->zone_array);
  for (list2=za_list ; list2 ; list2=g_slist_next(list2))
    {
    core2 = list2->data;
    if (core2->status & DELETED)
      continue;

/* avoid double counting */
    if (core1 >= core2)
      continue;

    if (core1->atom_code != core2->atom_code)
      continue;

#if DEBUG_REMOVE_DUPLICATES_MORE
printf(" - %s :", core2->atom_label);
P3VEC(" ", core2->x);
#endif

/* compute and test the minimum separation */
    ARR3SET(vec, core1->x);
    ARR3SUB(vec, core2->x);

    fractional_min(vec, model->periodic);

    if (VEC3MAGSQ(vec) < FRACTION_TOLERANCE)
      {
/* delete core2, unless primary AND core1 is non primary */
      if (core2->primary && !core1->primary)
        {
        core1->status |= DELETED;

/* FIXME - this may be a problem since we start the core2 loop */
/* requiring that core1 be undeleted */
#if DEBUG_REMOVE_DUPLICATES_MORE
printf(" * rm 1\n");
#endif
        }
      else
        {
        core2->status |= DELETED;

#if DEBUG_REMOVE_DUPLICATES_MORE
printf(" * rm 2\n");
#endif
        }
      }
    }
  g_slist_free(za_list);
  }

/* commit before searching for duplicate shells, as a commit */
/* will delete some attached shells */
delete_commit(model);

for (list1=model->shels ; list1 ; list1=g_slist_next(list1))
  {
  s1 = list1->data;
  if (s1->status & DELETED)
    continue;

/* NEW - enumerate shells in the current locality */
  zone = zone_get(s1->x, model->zone_array); 
  for (list2=zone_shells(zone) ; list2 ; list2=g_slist_next(list2))
    {
    s2 = list2->data;

    if (s2->status & DELETED)
      continue;
    if (s1 == s2)
      continue;

    ARR3SET(vec, s1->x);
    ARR3SUB(vec, s2->x);

/* adjust for periodicity */
    fractional_min(vec, model->periodic);

    if (VEC3MAGSQ(vec) < FRACTION_TOLERANCE)
      {
/* delete shell2, unless primary AND shell1 is non primary */
      if (s2->primary && !s1->primary)
        s1->status |= DELETED;
      else
        s2->status |= DELETED;
      }
    }
  }
delete_commit(model);

#if DEBUG_REMOVE_DUPLICATES
printf("Final cores: %d\n", g_slist_length(model->cores));
printf("Final shels: %d\n", g_slist_length(model->shels));
#endif
}
Example #5
0
void povray_hdr(FILE *fp, struct model_pak *data)
{
gdouble xvec, yvec, amb, pos[3], colour[3];
gdouble x[3], o[3], v[3], e[3];
GSList *list;
struct light_pak *light;
struct camera_pak *camera;

g_assert(data != NULL);
g_assert(data->camera != NULL);

fprintf(fp,"#include \"colors.inc\" \n");
fprintf(fp,"#include \"finish.inc\" \n");
fprintf(fp,"#include \"glass.inc\" \n");
fprintf(fp,"#include \"metals.inc\" \n");
fprintf(fp,"#include \"textures.inc\" \n");

/* background colour (except for glass morphologies) */
fprintf(fp,"background { color rgb<%f,%f,%f0> }\n", sysenv.render.bg_colour[0],
                        sysenv.render.bg_colour[1], sysenv.render.bg_colour[2]);  

/* pixel to angstrom conversion, with yet another magic number... */
p2a = 0.565 * (gdouble) sysenv.render.width / data->rmax;

/* preserve model aspect ratio for the given image size */
xvec = yvec = 2.0*sysenv.rsize;
if (sysenv.render.width > sysenv.render.height)
  xvec *= sysenv.render.width/sysenv.render.height;
if (sysenv.render.height > sysenv.render.width)
  yvec *= sysenv.render.height/sysenv.render.width;

/* compute camera position and orientation */
camera = data->camera;
ARR3SET(x, camera->x);
ARR3SET(o, camera->o);
ARR3SET(v, camera->v);

switch (camera->mode)
  {
  case FREE:
    break;

  default:
  case LOCKED:
    quat_rotate(x, camera->q);
    quat_rotate(o, camera->q);
    quat_rotate(v, camera->q);
    break;
  }
/* convert viewing vector to a location */
ARR3ADD(v, x);

/* camera zoom */
xvec *= camera->zoom;
yvec *= camera->zoom;

/* NEW - enable movies of left/right eye to be produced */
if (sysenv.stereo)
  {
/* get axis for eye translation (view x up vector) */
  crossprod(e, v, o);
  normalize(e, 3);

/* the old 2% rule ... */
  VEC3MUL(e, 0.02 * sysenv.rsize); 

/* default is left eye only */
  if (sysenv.render.stereo_right)
    {
    ARR3ADD(x, e);
    ARR3ADD(v, e);
    }
  else
    {
    ARR3SUB(x, e);
    ARR3SUB(v, e);
    }
  }

/* sky is the orientation vector */
/* right and up give the perspective */
if (camera->perspective)
  {
  fprintf(fp,"camera { location <%f,%f,%f>\n", x[0], x[1], x[2]);
  fprintf(fp,"    sky <%f,%f,%f>\n", o[0], o[1], o[2]);
  fprintf(fp,"    right <%f,0,0> up <%f,0,0>\n", xvec, yvec);
  fprintf(fp,"    look_at <%f,%f,%f>\n", v[0], v[1], v[2]);
  fprintf(fp,"    angle %f }\n", camera->fov);
  }
else
  {
  fprintf(fp,"camera { orthographic location <%f,%f,%f>\n", x[0], x[1], x[2]);
  fprintf(fp,"    sky <%f,%f,%f>\n", o[0], o[1], o[2]);
  fprintf(fp,"    right <%f,0,0> up <%f,0,0>\n", xvec, yvec);
  fprintf(fp,"    look_at <%f,%f,%f> }\n", v[0], v[1], v[2]);
  }

/* create light sources */
for (list=sysenv.render.light_list ; list ; list=g_slist_next(list))
  {
  light = list->data;
  ARR3SET(pos, light->x);

/* OpenGL -> POVRay axes */
  pos[0] *= -1.0;
  pos[1] *= -1.0;
  pos[2] *= -1.0;

  quat_rotate(pos, camera->q);

  switch (light->type)
    {
    case POSITIONAL:
      fprintf(fp,"light_source\n  {\n <%f,%f,%f>\n", pos[0], pos[1], pos[2]);
      break;

    case DIRECTIONAL:
/* move away far enough so the rays are ~ // */
      VEC3MUL(pos, 100.0*data->rmax);
      fprintf(fp,"light_source\n  {\n <%f,%f,%f>\n", pos[0], pos[1], pos[2]);
      break;

    default:
      continue;
    }

/* simulate OpenGL style lights */
  ARR3SET(colour, light->colour);
  VEC3MUL(colour, light->specular);

  if (sysenv.render.shadowless)
    fprintf(fp,"  color rgb<%f,%f,%f> shadowless }\n", colour[0], colour[1], colour[2]);
  else
    {
/* old style lighting */
/*
    fprintf(fp,"  color rgb<%f,%f,%f> }\n", colour[0], colour[1], colour[2]);
*/
    fprintf (fp,"color White\n");
    fprintf (fp,"   area_light <5, 0, 0,>, <0, 0, 5>, 5, 5\n");
    fprintf (fp,"   adaptive 1\n   jitter\n}\n");
    }
  }

/* fill-light to bring out the shadows */
fprintf(fp,"light_source{<%f,%f,%f> color Gray80 shadowless}\n", pos[0], pos[1], pos[2]);

/* morph is too dark with just the above, sky_sphere is *nice* */
/* TODO - choice of colour eg white/grey/light blue */
/* NB: white is a bit too bright (even with 0 ambience) */
if (data->id == MORPH)
  {
  if (!sysenv.render.wire_surface && !sysenv.render.shadowless)
    {
    fprintf(fp,"sky_sphere { pigment {gradient y  color_map "
               "{[0, 1 color Gray20 color White]} rotate x*45}}\n");
    }
  }

/* POVRay is a bit darker than OpenGL */
amb = 20.0*sysenv.render.ambience;

fprintf(fp,"global_settings { ambient_light rgb<%f, %f, %f> assumed_gamma 2.2}\n",amb,amb,amb);
}
Example #6
0
gint surf_sysabs(struct model_pak *data, gint h, gint k, gint l)
{
gint i, flag;
gint f1[3] /*, f2[3]*/;
gdouble dp, dummy, vec[3], df[3];

#if DEBUG_FACET_ABSENT
printf("testing %d %d %d\n", h, k, l);
#endif

/* apply the symmetry matrices (skip identity) */
VEC3SET(f1, h, k, l);
for (i=1 ; i<data->sginfo.order ; i++)
  {
/* NEW - identity + translation alone is insufficent */
  if (matrix_is_identity(*(data->sginfo.matrix+i)))
    continue;

  VEC3SET(vec, h, k, l);

  vecmat(*(data->sginfo.matrix+i), vec);
  flag = 0;

/* not needed - we've expanded all symmetry operations (incl. inversion) */
/* test f1 . m = -f1 */
/*
  ARR3SET(df, f1);
  ARR3ADD(df, vec);
  if (VEC3MAGSQ(df) < FRACTION_TOLERANCE)
    if (data->sginfo.inversion)
      flag++;
*/
 
/* test f1 . m = f1 */
  ARR3SET(df, f1);
  ARR3SUB(df, vec);
  if (VEC3MAGSQ(df) < POSITION_TOLERANCE)
    flag++;

  if (flag)
    {
#if DEBUG_FACET_ABSENT
printf("symop [%d] satisfies 1st absence condition.\n", i);
P3MAT("matrix:", *(data->sginfo.matrix+i));
P3VEC("offset:", *(data->sginfo.offset+i));
#endif

/* test if <f1,t> = non-integer */
    ARR3SET(vec, *(data->sginfo.offset+i));
    ARR3MUL(vec, f1);
    dp = fabs(vec[0] + vec[1] + vec[2]);
    if (modf(dp, &dummy) > POSITION_TOLERANCE)
      {
#if DEBUG_FACET_ABSENT
printf("symop [%d] [%f %f %f] satisfies 2nd absence condition.\n",
       i, *(*(data->sginfo.offset+i)+0), *(*(data->sginfo.offset+i)+1),
          *(*(data->sginfo.offset+i)+2));
printf("facet is extinct.\n");
#endif
      return(TRUE);
      }
    }
  }

#if DEBUG_FACET_ABSENT
printf(">>> Not absent\n");
#endif

return(FALSE);
}
Example #7
0
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);
*/
}
Example #8
0
void zmat_build(void)
{
gint i, j, k, n, type;
gdouble r, a, d, x[4][3], v[3];
gdouble  zaxis[3] = {0.0, 0.0, 1.0};
gchar *line;
GSList *list, *species;
struct zmat_pak *zmat;
struct core_pak *core[4] = {NULL, NULL, NULL, NULL};
struct model_pak *model;

model = sysenv.active_model;
if (!model)
  return;

/* CURRENT - using selection as our list of cores to generate a zmatrix from */
if (!model->selection)
  {
  gui_text_show(WARNING, "ZMATRIX: please select a molecule.\n");
  return;
  }

/* destroy old zmatrix */
/* TODO - prompt if non null */
zmat_free(model->zmatrix);
zmat = model->zmatrix = zmat_new();
zmat_angle_units_set(model->zmatrix, DEGREES);

/* setup SIESTA species type */
species = fdf_species_build(model);

/* sort the list so it follows molecular connectivity */
model->selection = zmat_connect_sort(model->selection);

n=0;
for (list=model->selection ; list ; list=g_slist_next(list))
  {
/* current atom/zmatrix line init */
  core[0] = list->data;
  type = fdf_species_index(core[0]->atom_label, species);
  line = NULL;

  zmat->zcores = g_slist_append(zmat->zcores, core[0]);

/* build a ZMATRIX line for processing */
  switch (n)
    {
    case 0:
      if (core[0])
        {
        ARR3SET(x[0], core[0]->x);
        vecmat(model->latmat, x[0]);
        }
      line = g_strdup_printf("%d  0 0 0  %f %f %f  0 0 0\n", type, x[0][0], x[0][1], x[0][2]);
      break;

    case 1:
      if (core[0])
        {
        ARR3SET(x[0], core[0]->x);
        vecmat(model->latmat, x[0]);
        }
      if (core[1])
        {
        ARR3SET(x[1], core[1]->x);
        vecmat(model->latmat, x[1]);
        }

      r = measure_distance(x[0], x[1]);

/* angle with z axis */
      ARR3SET(v, x[0]);
      ARR3SUB(v, x[1]);
      a = R2D * via(v, zaxis, 3);

/* angle between xy projection and x axis */
      d = R2D * angle_x_compute(v[0], v[1]);

      line = g_strdup_printf("%d  1 0 0  %f %f %f 0 0 0\n", type, r, a, d);
      break;

    case 2:
/* coords init */
  for (i=3 ; i-- ; )
    {
    if (core[i])
      {
      ARR3SET(x[i], core[i]->x);
      vecmat(model->latmat, x[i]);
      }
    else
      g_assert_not_reached();
    }

      r = measure_distance(x[0], x[1]);
      a = measure_angle(x[0], x[1], x[2]);

/* create a fake core -> 1 unit displaced in the z direction */
      g_assert(core[3] == NULL);
      core[3] = core_new("x", NULL, model);
      ARR3SET(core[3]->rx, core[2]->rx);
      ARR3ADD(core[3]->rx, zaxis); 
      d = measure_torsion(core);
      core_free(core[3]);

      line = g_strdup_printf("%d  2 1 0  %f %f %f 0 0 0\n", type,r,a,d);
      break;

    default:

/* connectivity test */
      if (!zmat_bond_check(core[0], core[1]))
        {
#if DEBUG_ZMAT_BUILD
printf("[%d] non-connected atoms [%f]\n", n, measure_distance(x[0], x[1]));
#endif
/* need to build a new connectivity chain starting from core[0] */
        core[1] = core[2] = core[3] = NULL;
        if (!zmat_connect_find(n, core, zmat))
          {
          gui_text_show(WARNING, "ZMATRIX: bad connectivity (molecule will be incomplete)\n");
          goto zmat_build_done;
          }
        }

/* coords init */
      for (i=3 ; i-- ; )
        {
        if (core[i])
          {
          ARR3SET(x[i], core[i]->x);
          vecmat(model->latmat, x[i]);
          }
        else
          g_assert_not_reached();
        }

      r = measure_distance(x[0], x[1]);
      a = measure_angle(x[0], x[1], x[2]);
      d = measure_torsion(core);

/* NB: indexing starts from 0, siesta starts from 1 (naturally) */
      i = 1+g_slist_index(zmat->zcores, core[1]);
      j = 1+g_slist_index(zmat->zcores, core[2]);
      k = 1+g_slist_index(zmat->zcores, core[3]);

      line = g_strdup_printf("%d  %d %d %d  %f %f %f 0 0 0\n", type,i,j,k,r,a,d);
    }

/* process a successfully constructed ZMATRIX line */
  if (line)
    {
    zmat_core_add(line, model->zmatrix);
    g_free(line);
    }

/* shuffle */
  core[3] = core[2];
  core[2] = core[1];
  core[1] = core[0];

  n++;
  }

zmat_build_done:

/* do the species typing */
zmat_type(model->zmatrix, species);

free_slist(species);
}
Example #9
0
void zmat_process(gpointer data, struct model_pak *model)
{
gint i, n;
gdouble r, a, d;
gdouble v1[3], v2[3], v3[3], m1[9], m2[9];
gpointer tmp;
GSList *list;
struct zmat_pak *zmat = data;
struct zval_pak *zval;
struct core_pak *core[4] = {NULL, NULL, NULL, NULL};

/* checks */
if (!zmat)
  return;

matrix_lattice_init(model);

#if ZMAT_PROCESS_DEBUG
printf("distance scale = %f\n", zmat->distance_scale);
printf("angle scale = %f\n", zmat->angle_scale);
#endif

/* track the core # - 1st 3 items in zmatrix are exceptions */
n = 0;
for (list=zmat->zlines ; list ; list=g_slist_next(list))
  {
  zval = list->data;

/* check for variable names */
  for (i=3 ; i-- ; )
    {
    if (zval->name[i])
      {
/* hash table lookup for variable value */
      zval->value[i] = zmat_table_lookup(zval->name[i], zmat);
      }
    }

/* create the core */
#if ZMAT_PROCESS_DEBUG
printf("[%d = %s] [%d %d %d]", zval->type, zval->elem,
                               zval->connect[0], zval->connect[1], zval->connect[2]);
P3VEC(" x: ", zval->value);

#endif

/* TODO - need to mark zmatrix generated cores as special */
/* probably have another list in the zmat struct that contains */
/* all the cores created below */

  switch (n)
    {
    case 0:
/* TODO - convert to cartesian if fractional and enforce cart model */
      core[0] = new_core(zval->elem, model);
      model->cores = g_slist_prepend(model->cores, core[0]);
      zmat->zcores = g_slist_prepend(zmat->zcores, core[0]);
      ARR3SET(core[0]->x, zval->value);
      if (zmat->fractional)
        vecmat(model->latmat, core[0]->x);
      else
        {
        VEC3MUL(core[0]->x, zmat->distance_scale);
        }
      break;

    case 1:
      core[1] = new_core(zval->elem, model);
      model->cores = g_slist_prepend(model->cores, core[1]);
      zmat->zcores = g_slist_prepend(zmat->zcores, core[1]);

      r = zmat->distance_scale * zval->value[0];
/*
      a = zmat->angle_scale * zval->value[1];
      d = zmat->angle_scale * zval->value[2];
*/

/* SIESTA hack : z-axis angle is 2nd, and theta is 3rd (last) */
      a = zmat->angle_scale * zval->value[2];
      d = zmat->angle_scale * zval->value[1];

      v1[0] = v1[1] = r * sin(d);
      v1[0] *= cos(a);
      v1[1] *= sin(a);
      v1[2] = r * cos(d);

      ARR3SET(core[1]->x, core[0]->x);
      ARR3ADD(core[1]->x, v1);
      break;

    case 2:
/* check the connection order */
      if (zval->connect[0] == 2)
        {
        tmp = core[0];
        core[0] = core[1];
        core[1] = tmp;
        }

      r = zmat->distance_scale * zval->value[0];
      a = zmat->angle_scale * zval->value[1];
      d = zmat->angle_scale * zval->value[2];

      ARR3SET(v2, core[1]->x);
      ARR3SUB(v2, core[0]->x);

/* get rotation axis for bond angle */
      VEC3SET(v3, 0.0, 0.0, 1.0);
      crossprod(v1, v3, v2);

/* rotate bondlength scaled vector into position */
      matrix_v_rotation(m2, v1, a);
      ARR3SET(v3, v2);
      normalize(v3, 3);
      VEC3MUL(v3, r);
      vecmat(m2, v3);

/* rotate to give required dihedral */
      matrix_v_rotation(m1, v2, d);
      vecmat(m1, v3);

/* generate the atom position */
      core[2] = new_core(zval->elem, model);
      model->cores = g_slist_prepend(model->cores, core[2]);
      zmat->zcores = g_slist_prepend(zmat->zcores, core[2]);

      ARR3SET(core[2]->x, core[0]->x);
      ARR3ADD(core[2]->x, v3);
      break;

    default:
/* get core connectivity (NB: prepending cores - hence n - number) */
      core[0] = g_slist_nth_data(zmat->zcores, n-zval->connect[0]); 
      core[1] = g_slist_nth_data(zmat->zcores, n-zval->connect[1]); 
      core[2] = g_slist_nth_data(zmat->zcores, n-zval->connect[2]); 
g_assert(core[0] != NULL);
g_assert(core[1] != NULL);
g_assert(core[2] != NULL);

      r = zmat->distance_scale * zval->value[0];
      a = zmat->angle_scale * zval->value[1];
      d = zmat->angle_scale * zval->value[2];

/* setup vectors */
      ARR3SET(v2, core[1]->x);
      ARR3SUB(v2, core[0]->x);
      ARR3SET(v3, core[2]->x);
      ARR3SUB(v3, core[1]->x);

/* rotate v3 about v2 to give dihedral */
      matrix_v_rotation(m1, v2, d);
      vecmat(m1, v3);

/* get rotation axis and matrix for bond angle */
      crossprod(v1, v3, v2);
      matrix_v_rotation(m2, v1, a);
      normalize(v2, 3);
      VEC3MUL(v2, r);
      vecmat(m2, v2);

/* generate the atom position */
      core[3] = new_core(zval->elem, model);
      model->cores = g_slist_prepend(model->cores, core[3]);
      zmat->zcores = g_slist_prepend(zmat->zcores, core[3]);

      ARR3SET(core[3]->x, core[0]->x);
      ARR3ADD(core[3]->x, v2);

/* TODO (maybe) - some zmatrix constructions implicitly assume */
/* some checking for duplicate atoms & reversing the torsional */
/* angle sense to accomodate this. */

      break;
    }
  n++;
  }

/* zmatrix cores are created in cartesians - revert to fractional if required */
if (model->fractional)
  {
  for (list=zmat->zcores ; list ; list=g_slist_next(list))
    {
    core[0] = list->data;
    vecmat(model->ilatmat, core[0]->x);
    }
  }
}