<a name="M000236"></a>
<div class="method-heading">
<span class="method-name">cell = [a, b, c, alpha, beta, gamma [, sig_a, sig_b, sig_c, sig_alpha, sig_beta, sig_gamma]]<br />
-set_cell([a, b, c, alpha, beta, gamma [, sig_a, sig_b, sig_c, sig_alpha, sig_beta, sig_gamma]], flag = nil)<br />
+set_cell([a, b, c, alpha, beta, gamma[, sig_a, sig_b, sig_c, sig_alpha, sig_beta, sig_gamma]], convert_coord = nil)<br />
</span>
</div>
<div class="method-description">
<p>
-Set the unit cell parameters. Alpha/beta/gamma are in degree. If the right-hand value (or the first argument) is nil, then clear the current unit cell. If the second argument is given as non-nil, then
-the coordinates are transformed so that the fractional coordinates remain the same. If the cell parameters are given as an array of 12 floats, then the second half of the array is to represent the sigma value (that are common in crystallographic data). This operation is undoable.
+Set the unit cell parameters. Alpha/beta/gamma are in degree. If the right-hand value (or the first argument) is nil, then clear the current unit cell. If the cell parameters are given as an array of 12 floats, then the second half of the array is to represent the sigma value (that are common in crystallographic data). Convert_coord is a flag to specify that the coordinates should be transformed so that the fractional coordinates remain the same. This operation is undoable.
</p>
<p>
<i>See Also:</i> <a href="Molecule.html#M000238">Molecule#box</a>, <a href="Molecule.html#M000239">Molecule#box=</a>, <a href="Molecule.html#M000235">Molecule#cell</a>
</div>
<div class="method-description">
<p>
-Returns whether the unit cell is flexible or not.
+Obsolete. Now the unit cell is always flexible (i.e. different frames can have different unit cell)
</p>
</div>
</div>
</div>
<div class="method-description">
<p>
-Set whether the unit cell is flexible or not.
+Obsolete. Now the unit cell is always flexible (i.e. different frames can have different unit cell)
+</p>
+</div>
+</div>
+
+<div id="method-M000237" class="method-detail">
+<a name="cell_periodicity"></a>
+<div class="method-heading">
+<span class="method-name">cell_periodicity → [n1, n2, n3] or nil<br />
+</span>
+</div>
+<div class="method-description">
+<p>
+Get flags denoting whether the cell is periodic along the a/b/c axes. If the cell is not defined, nil is returned.
+</p>
+</div>
+</div>
+
+<div id="method-M000237" class="method-detail">
+<a name="set_cell_periodicity"></a>
+<div class="method-heading">
+<span class="method-name">self.cell_periodicity = [n1, n2, n3] or Integer or nil<br />
+set_cell_periodicity([n1, n2, n3] or Integer or nil)
+</span>
+</div>
+<div class="method-description">
+<p>
+Set whether the cell is periodic along the a/b/c axes. If an integer is given as an argument, its bits 2/1/0 (from the lowest) correspond to the a/b/c axes. Nil is equivalent to [0, 0, 0].
+If cell is not defined, exception is raised.
+This operation is undoable.
</p>
</div>
</div>
void
md_set_cell(MDArena *arena)
{
- Molecule *mol = arena->mol;
+ Molecule *mol = arena->xmol;
if (mol == NULL)
return;
if (mol->cell != NULL) {
const char *gMolActionDeleteSymmetryOperation = "deleteSymop";
const char *gMolActionAddSymmetryOperation = "addSymop:t";
const char *gMolActionSetCell = "setCell:Di";
+const char *gMolActionSetCellPeriodicity = "setCellPeriodicity:i";
const char *gMolActionSetBox = "setBox:vvvvii";
const char *gMolActionClearBox = "clearBox";
-const char *gMolActionSetBoxForFrames = "setBoxForFrames:V";
-const char *gMolActionSetCellFlexibility = "setCellFlexibility:i";
+/*const char *gMolActionSetBoxForFrames = "setBoxForFrames:V"; */
+/*const char *gMolActionSetCellFlexibility = "setCellFlexibility:i"; */
const char *gMolActionAddParameters = "addParameters:iGU";
const char *gMolActionDeleteParameters = "deleteParameters:iG";
const char *gMolActionAmendBySymmetry = "amendBySymmetry:G;G";
{
double *dp, d[12];
Vector vecs[4];
- Int flags;
+ Int oflags;
Int convertCoord, n1, n2;
if (mol->cell == NULL) {
d[0] = 0.0;
n1 = 0;
+ oflags = 0;
} else {
for (n1 = 0; n1 < 6; n1++)
d[n1] = mol->cell->cell[n1];
}
memmove(vecs, mol->cell->axes, sizeof(Vector) * 3);
vecs[3] = mol->cell->origin;
- flags = (mol->cell->flags[0] != 0) * 4 + (mol->cell->flags[1] != 0) * 2 + (mol->cell->flags[2] != 0);
+ oflags = (mol->cell->flags[0] != 0) * 4 + (mol->cell->flags[1] != 0) * 2 + (mol->cell->flags[2] != 0);
}
convertCoord = action->args[1].u.ival;
dp = action->args[0].u.arval.ptr;
if (n1 == 0)
*actp = MolActionNew(gMolActionClearBox);
else {
- *actp = MolActionNew(gMolActionSetBox, &vecs[0], &vecs[1], &vecs[2], &vecs[3], flags, convertCoord);
+ *actp = MolActionNew(gMolActionSetBox, &vecs[0], &vecs[1], &vecs[2], &vecs[3], oflags, convertCoord);
if (n1 > 6) {
/* Two undo actions are needed: first is for restore the cell vectors, and second is for restore the sigmas */
MolAction *act2;
}
static int
+s_MolActionSetCellPeriodicity(Molecule *mol, MolAction *action, MolAction **actp)
+{
+ Int flags, oflags;
+ if (mol->cell == NULL)
+ return 0; /* Do nothing */
+ oflags = (mol->cell->flags[0] != 0) * 4 + (mol->cell->flags[1] != 0) * 2 + (mol->cell->flags[2] != 0);
+ flags = action->args[0].u.ival;
+ mol->cell->flags[0] = ((flags & 4) != 0);
+ mol->cell->flags[1] = ((flags & 2) != 0);
+ mol->cell->flags[2] = ((flags & 1) != 0);
+ *actp = MolActionNew(gMolActionSetCellPeriodicity, oflags);
+ return 0;
+}
+
+static int
s_MolActionSetBox(Molecule *mol, MolAction *action, MolAction **actp)
{
Int n1, n2;
}
/* This action is used for undoing "cell_flexibility = false" */
+/*
static int
s_MolActionSetBoxForFrames(Molecule *mol, MolAction *action, MolAction **actp)
{
Vector *vp1, *vp2;
n2 = MoleculeGetNumberOfFrames(mol);
if (n2 == 0 || mol->cell == NULL)
- return 0; /* Do nothing */
+ return 0; // Do nothing
n1 = action->args[0].u.arval.nitems / 4;
vp1 = (Vector *)(action->args[0].u.arval.ptr);
if (mol->nframe_cells < n2) {
- /* Expand the array before processing */
+ // Expand the array before processing
i = mol->nframe_cells * 4;
AssignArray(&(mol->frame_cells), &(mol->nframe_cells), sizeof(Vector) * 4, n2 - 1, NULL);
while (i < n2 * 4) {
- /* Copy the current cell */
+ // Copy the current cell
mol->frame_cells[i++] = mol->cell->axes[0];
mol->frame_cells[i++] = mol->cell->axes[1];
mol->frame_cells[i++] = mol->cell->axes[2];
*actp = MolActionNew(gMolActionSetBoxForFrames, n2 * 4, vp2);
free(vp2);
- /* Set the current cell (no change on the periodic flags) */
+ // Set the current cell (no change on the periodic flags)
vp2 = mol->frame_cells + mol->cframe * 4;
MoleculeSetPeriodicBox(mol, vp2, vp2 + 1, vp2 + 2, vp2 + 3, mol->cell->flags, 0);
return 0;
-}
+} */
+/*
static int
s_MolActionSetCellFlexibility(Molecule *mol, MolAction *action, MolAction **actp)
{
Int n1;
n1 = action->args[0].u.ival;
if ((n1 != 0) == (mol->useFlexibleCell != 0))
- return 0; /* Do nothing */
+ return 0; // Do nothing
mol->useFlexibleCell = (n1 != 0);
if (n1 == 0) {
- /* Clear the existing cells, and register undo */
+ // Clear the existing cells, and register undo
if (mol->nframe_cells > 0) {
MolAction *act2 = MolActionNew(gMolActionSetBoxForFrames, mol->nframe_cells * 4, mol->frame_cells);
MolActionSetFrame(act2, mol->cframe);
mol->frame_cells = NULL;
mol->nframe_cells = 0;
} else {
- /* Allocate cells for all frames and copy the current cell */
+ // Allocate cells for all frames and copy the current cell
Int i, nframes = MoleculeGetNumberOfFrames(mol);
if (nframes != 0 && mol->cell != NULL) {
if (mol->nframe_cells < nframes) {
- /* Expand the array */
+ // Expand the array
AssignArray(&(mol->frame_cells), &(mol->nframe_cells), sizeof(Vector) * 4, nframes - 1, NULL);
}
- /* Copy the current cell */
- /* (No undo action is registered; actually, the frame_cells array should be empty) */
+ // Copy the current cell
+ // (No undo action is registered; actually, the frame_cells array should be empty)
for (i = 0; i < nframes; i++) {
mol->frame_cells[i * 4] = mol->cell->axes[0];
mol->frame_cells[i * 4 + 1] = mol->cell->axes[1];
*actp = MolActionNew(gMolActionSetCellFlexibility, (n1 == 0));
return 0;
}
+*/
static int
s_MolActionAddParameters(Molecule *mol, MolAction *action, MolAction **actp)
return result;
if (mol->arena != NULL)
md_set_cell(mol->arena);
- needsRebuildMDArena = 1;
+ needsSymmetryAmendment = 1;
+ } else if (strcmp(action->name, gMolActionSetCellPeriodicity) == 0) {
+ if ((result = s_MolActionSetCellPeriodicity(mol, action, &act2)) != 0)
+ return result;
+ if (mol->arena != NULL)
+ md_set_cell(mol->arena);
+ needsSymmetryAmendment = 1;
} else if (strcmp(action->name, gMolActionSetBox) == 0) {
if ((result = s_MolActionSetBox(mol, action, &act2)) != 0)
return result;
if (mol->arena != NULL)
md_set_cell(mol->arena);
needsSymmetryAmendment = 1;
- } else if (strcmp(action->name, gMolActionSetBoxForFrames) == 0) {
+/* } else if (strcmp(action->name, gMolActionSetBoxForFrames) == 0) {
if ((result = s_MolActionSetBoxForFrames(mol, action, &act2)) != 0)
- return result;
- } else if (strcmp(action->name, gMolActionSetCellFlexibility) == 0) {
+ return result; */
+/* } else if (strcmp(action->name, gMolActionSetCellFlexibility) == 0) {
if ((result = s_MolActionSetCellFlexibility(mol, action, &act2)) != 0)
- return result;
+ return result; */
} else if (strcmp(action->name, gMolActionAddParameters) == 0) {
if ((result = s_MolActionAddParameters(mol, action, &act2)) != 0)
return result;
extern const char *gMolActionDeleteSymmetryOperation;
extern const char *gMolActionAddSymmetryOperation;
extern const char *gMolActionSetCell;
+extern const char *gMolActionSetCellPeriodicity;
extern const char *gMolActionSetBox;
extern const char *gMolActionClearBox;
-extern const char *gMolActionSetBoxForFrames;
-extern const char *gMolActionSetCellFlexibility;
+/*extern const char *gMolActionSetBoxForFrames; */
+/*extern const char *gMolActionSetCellFlexibility; */
extern const char *gMolActionAddParameters;
extern const char *gMolActionDeleteParameters;
extern const char *gMolActionAmendBySymmetry;
MoleculeInitWithMolecule(Molecule *mp2, const Molecule *mp)
{
int i;
+ MoleculeFlushFrames(mp);
MoleculeInitWithAtoms(mp2, mp->atoms, mp->natoms);
if (mp->nbonds > 0) {
if (NewArray(&mp2->bonds, &mp2->nbonds, sizeof(Int)*2, mp->nbonds) == NULL)
memmove(mp2->pibonds, mp->pibonds, sizeof(Int) * 4 * mp->npibonds);
}
- mp2->useFlexibleCell = mp->useFlexibleCell;
+/* mp2->useFlexibleCell = mp->useFlexibleCell; */
if (mp->nframe_cells > 0) {
if (NewArray(&mp2->frame_cells, &mp2->nframe_cells, sizeof(Vector) * 4, mp->nframe_cells) == NULL)
goto error;
} else if (strcmp(buf, "!:frame_periodic_boxes") == 0) {
Vector vs[5];
i = 0;
- mp->useFlexibleCell = 1; /* The presence of this block causes asserting this flag */
+ /* mp->useFlexibleCell = 1; *//* The presence of this block causes asserting this flag */
while (ReadLine(buf, sizeof buf, fp, &lineNumber) > 0) {
if (buf[0] == '!')
continue;
fprintf(fp, "\n");
}
- if (mp->useFlexibleCell != 0) {
+ if (mp->nframe_cells > 0) {
fprintf(fp, "!:frame_periodic_boxes\n");
fprintf(fp, "! ax ay az; bx by bz; cx cy cz; ox oy oz\n");
for (i = 0; i < mp->nframe_cells * 4; i++) {
vp[j] = ap->r;
ap->frames = vp;
}
- if (mp->cell != NULL && (mp->useFlexibleCell || inFrameCell != NULL)) {
- mp->useFlexibleCell = 1;
+ if (mp->cell != NULL && inFrameCell != NULL) {
+ /* mp->useFlexibleCell = 1; */
vp = mp->frame_cells;
AssignArray(&mp->frame_cells, &mp->nframe_cells, sizeof(Vector) * 4, n_new - 1, NULL);
if (vp == NULL) {
recalculated from the atoms if it is -1 */
Int cframe; /* The current frame number */
- Byte useFlexibleCell;
+/* Byte useFlexibleCell; *//* Obsolete (since 0.6.5; unit cell is frame dependent in all cases) */
Int nframe_cells;
Vector *frame_cells; /* The cell vectors for frames; (nframe_cells*4) array of Vectors */
/*
* call-seq:
* cell = [a, b, c, alpha, beta, gamma [, sig_a, sig_b, sig_c, sig_alpha, sig_beta, sig_gamma]]
- * set_cell([a, b, c, alpha, beta, gamma[, sig_a, sig_b, sig_c, sig_alpha, sig_beta, sig_gamma]], flag = nil)
+ * set_cell([a, b, c, alpha, beta, gamma[, sig_a, sig_b, sig_c, sig_alpha, sig_beta, sig_gamma]], convert_coord = nil)
*
* Set the unit cell parameters. If the cell value is nil, then clear the current cell.
- If the given argument has 12 members, then the second half of the parameters represents the sigma values.
- This operation is undoable. If the second argument is given as non-nil, then
- the coordinates are transformed so that the fractional coordinates remain the same.
+ If the given argument has 12 or more members, then the second half of the parameters represents the sigma values.
+ This operation is undoable.
+ Convert_coord is a flag to specify that the coordinates should be transformed so that the fractional coordinates remain the same.
*/
static VALUE
s_Molecule_SetCell(int argc, VALUE *argv, VALUE self)
{
Molecule *mol;
- VALUE val, fval;
- int i, flag, n;
+ VALUE val, cval;
+ int i, convert_coord, n;
double d[12];
Data_Get_Struct(self, Molecule, mol);
- rb_scan_args(argc, argv, "11", &val, &fval);
- flag = RTEST(fval);
+ rb_scan_args(argc, argv, "11", &val, &cval);
if (val == Qnil) {
- MolActionCreateAndPerform(mol, gMolActionSetCell, 0, d, flag);
- // MoleculeSetCell(mol, 1, 1, 1, 90, 90, 90);
- return Qnil;
+ n = 0;
+ } else {
+ int len;
+ val = rb_ary_to_ary(val);
+ len = RARRAY_LEN(val);
+ if (len >= 12) {
+ n = 12;
+ } else if (len >= 6) {
+ n = 6;
+ } else rb_raise(rb_eMolbyError, "too few members for cell parameters (6 or 12 required)");
+ for (i = 0; i < n; i++)
+ d[i] = NUM2DBL(rb_Float((RARRAY_PTR(val))[i]));
}
- val = rb_ary_to_ary(val);
- if (RARRAY_LEN(val) >= 12) {
- n = 12;
- } else if (RARRAY_LEN(val) >= 6) {
- n = 6;
- } else rb_raise(rb_eMolbyError, "too few members for cell parameters (6 or 12 required)");
- for (i = 0; i < n; i++)
- d[i] = NUM2DBL(rb_Float((RARRAY_PTR(val))[i]));
- MolActionCreateAndPerform(mol, gMolActionSetCell, n, d, flag);
+ convert_coord = (RTEST(cval) ? 1 : 0);
+ MolActionCreateAndPerform(mol, gMolActionSetCell, n, d, convert_coord);
return val;
}
/*
* call-seq:
- * cell_transform -> Transform
- *
- * Get the transform matrix that converts internal coordinates to cartesian coordinates.
- * If cell is not defined, nil is returned.
- */
-static VALUE
-s_Molecule_CellTransform(VALUE self)
-{
- Molecule *mol;
- Data_Get_Struct(self, Molecule, mol);
- if (mol == NULL || mol->cell == NULL)
- return Qnil;
- return ValueFromTransform(&(mol->cell->tr));
-}
-
-/*
- * call-seq:
* box -> [avec, bvec, cvec, origin, flags]
*
* Get the unit cell information in the form of a periodic bounding box.
* set_box
*
* Set the unit cell parameters. Avec, bvec, and cvec can be either a Vector3D or a number.
- If it is a number, the x/y/z axis vector is multiplied with the given number and used
- as the box vector.
- Flags, if present, is a 3-member array of Integers defining whether the system is
- periodic along the axis.
- If convert_coordinates is true, then the coordinates are converted so that the fractional coordinates remain the same.
- In the second form, an isotropic box with cell-length d is set.
- In the third form, the existing box is cleared.
- Note: the sigma of the cell parameters is not cleared unless the periodic box itself is cleared.
+ If it is a number, the x/y/z axis vector is multiplied with the given number and used
+ as the box vector.
+ Flags, if present, is a 3-member array of Integers defining whether the system is
+ periodic along the axis.
+ If convert_coordinates is true, then the coordinates are converted so that the fractional coordinates remain the same.
+ In the second form, an isotropic box with cell-length d is set.
+ In the third form, the existing box is cleared.
+ Note: the sigma of the cell parameters is not cleared unless the periodic box itself is cleared.
*/
static VALUE
s_Molecule_SetBox(VALUE self, VALUE aval)
Double d;
int i, convertCoordinates = 0;
Data_Get_Struct(self, Molecule, mol);
+ if (aval == Qnil) {
+ MolActionCreateAndPerform(mol, gMolActionClearBox);
+ return self;
+ }
+ aval = rb_ary_to_ary(aval);
for (i = 0; i < 6; i++) {
if (i < RARRAY_LEN(aval))
v[i] = (RARRAY_PTR(aval))[i];
/*
* call-seq:
+ * cell_periodicity -> [n1, n2, n3]
+ *
+ * Get flags denoting whether the cell is periodic along the a/b/c axes. If the cell is not defined
+ * nil is returned.
+ */
+static VALUE
+s_Molecule_CellPeriodicity(VALUE self)
+{
+ Molecule *mol;
+ Data_Get_Struct(self, Molecule, mol);
+ if (mol->cell == NULL)
+ return Qnil;
+ return rb_ary_new3(3, INT2FIX((int)mol->cell->flags[0]), INT2FIX((int)mol->cell->flags[1]), INT2FIX((int)mol->cell->flags[2]));
+}
+
+/*
+ * call-seq:
+ * self.cell_periodicity = [n1, n2, n3] or Integer or nil
+ * set_cell_periodicity = [n1, n2, n3] or Integer or nil
+ *
+ * Set whether the cell is periodic along the a/b/c axes. If an integer is given as an argument,
+ * its bits 2/1/0 (from the lowest) correspond to the a/b/c axes. Nil is equivalent to [0, 0, 0].
+ * If cell is not defined, exception is raised.
+ * This operation is undoable.
+ */
+static VALUE
+s_Molecule_SetCellPeriodicity(VALUE self, VALUE arg)
+{
+ Molecule *mol;
+ Int flag;
+ Data_Get_Struct(self, Molecule, mol);
+ if (mol->cell == NULL)
+ rb_raise(rb_eMolbyError, "periodic cell is not defined");
+ if (arg == Qnil)
+ flag = 0;
+ else if (rb_obj_is_kind_of(arg, rb_cNumeric))
+ flag = NUM2INT(rb_Integer(arg));
+ else {
+ Int i;
+ VALUE arg0;
+ arg = rb_ary_to_ary(arg);
+ for (i = 0; i < 3 && i < RARRAY_LEN(arg); i++) {
+ arg0 = RARRAY_PTR(arg)[i];
+ if (arg0 != Qnil && arg0 != Qfalse && arg0 != INT2FIX(0))
+ flag |= (1 << (2 - i));
+ }
+ }
+ MolActionCreateAndPerform(mol, gMolActionSetCellPeriodicity, flag);
+ return arg;
+}
+
+/*
+ * call-seq:
* cell_flexibility -> bool
*
* Returns the unit cell is flexible or not
static VALUE
s_Molecule_CellFlexibility(VALUE self)
{
- Molecule *mol;
+ rb_warn("cell_flexibility is obsolete (unit cell is always frame dependent)");
+ return Qtrue;
+/* Molecule *mol;
Data_Get_Struct(self, Molecule, mol);
if (mol->cell == NULL)
return Qfalse;
if (mol->useFlexibleCell)
return Qtrue;
- else return Qfalse;
+ else return Qfalse; */
}
/*
static VALUE
s_Molecule_SetCellFlexibility(VALUE self, VALUE arg)
{
- Molecule *mol;
+ rb_warn("set_cell_flexibility is obsolete (unit cell is always frame dependent)");
+ return self;
+/* Molecule *mol;
Data_Get_Struct(self, Molecule, mol);
MolActionCreateAndPerform(mol, gMolActionSetCellFlexibility, RTEST(arg) != 0);
- return self;
+ return self; */
+}
+
+/*
+ * call-seq:
+ * cell_transform -> Transform
+ *
+ * Get the transform matrix that converts internal coordinates to cartesian coordinates.
+ * If cell is not defined, nil is returned.
+ */
+static VALUE
+s_Molecule_CellTransform(VALUE self)
+{
+ Molecule *mol;
+ Data_Get_Struct(self, Molecule, mol);
+ if (mol == NULL || mol->cell == NULL)
+ return Qnil;
+ return ValueFromTransform(&(mol->cell->tr));
}
/*
rb_define_method(rb_cMolecule, "cell", s_Molecule_Cell, 0);
rb_define_method(rb_cMolecule, "cell=", s_Molecule_SetCell, -1);
rb_define_alias(rb_cMolecule, "set_cell", "cell=");
- rb_define_method(rb_cMolecule, "cell_transform", s_Molecule_CellTransform, 0);
rb_define_method(rb_cMolecule, "box", s_Molecule_Box, 0);
rb_define_method(rb_cMolecule, "box=", s_Molecule_SetBox, 1);
rb_define_method(rb_cMolecule, "set_box", s_Molecule_SetBox, -2);
+ rb_define_method(rb_cMolecule, "cell_transform", s_Molecule_CellTransform, 0);
+ rb_define_method(rb_cMolecule, "cell_periodicity", s_Molecule_CellPeriodicity, 0);
+ rb_define_method(rb_cMolecule, "cell_periodicity=", s_Molecule_SetCellPeriodicity, 1);
+ rb_define_alias(rb_cMolecule, "set_cell_periodicity", "cell_periodicity=");
rb_define_method(rb_cMolecule, "cell_flexibility", s_Molecule_CellFlexibility, 0);
rb_define_method(rb_cMolecule, "cell_flexibility=", s_Molecule_SetCellFlexibility, 1);
rb_define_alias(rb_cMolecule, "set_cell_flexibility", "cell_flexibility=");