Molecular Modeling Software
リビジョン | d36e14f18952caec63b23b00de4d35d7e1f57796 (tree) |
---|---|
日時 | 2010-02-20 15:40:58 |
作者 | toshinagata1964 <toshinagata1964@a2be...> |
コミッター | toshinagata1964 |
Ruby commands find_angles and find_dihedrals are made obsolete. remove_bonds is implemented. create_bond (create_bonds) now returns the number of newly added bonds instead of self.
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@12 a2be9bc6-48de-4e38-9406-05402d4bc13c
@@ -589,7 +589,7 @@ MolActionPerform(Molecule *mol, MolAction *action) | ||
589 | 589 | int n1, result, natoms; |
590 | 590 | Molecule *mol2; |
591 | 591 | IntGroup *ig; |
592 | - MolAction *act2; | |
592 | + MolAction *act2 = NULL; | |
593 | 593 | int needsSymmetryAmendment = 0; |
594 | 594 | int needsRebuildMDArena = 0; |
595 | 595 | Int *ip; |
@@ -775,9 +775,14 @@ MolActionPerform(Molecule *mol, MolAction *action) | ||
775 | 775 | } else if (strcmp(action->name, gMolActionAddBonds) == 0) { |
776 | 776 | ip = (Int *)action->args[0].u.arval.ptr; |
777 | 777 | n1 = action->args[0].u.arval.nitems / 2; |
778 | - if ((result = MoleculeAddBonds(mol, n1, ip)) < 0) | |
778 | + if ((result = MoleculeAddBonds(mol, n1, ip)) <= 0) | |
779 | 779 | return result; |
780 | - act2 = MolActionNew(gMolActionDeleteBonds, n1 * 2, ip); | |
780 | + ip = (Int *)malloc(sizeof(Int) * 2 * result); | |
781 | + if (ip == NULL) | |
782 | + return -4; | |
783 | + memmove(ip, mol->bonds - result * 2, sizeof(Int) * 2 * result); | |
784 | + act2 = MolActionNew(gMolActionDeleteBonds, result * 2, ip); | |
785 | + free(ip); | |
781 | 786 | needsRebuildMDArena = 1; |
782 | 787 | } else if (strcmp(action->name, gMolActionDeleteBonds) == 0) { |
783 | 788 | ip = (Int *)action->args[0].u.arval.ptr; |
@@ -5792,14 +5792,20 @@ MoleculeExtract(Molecule *src, Molecule **dstp, IntGroup *where, int dummyFlag) | ||
5792 | 5792 | int |
5793 | 5793 | MoleculeAddBonds(Molecule *mp, Int nbonds, const Int *bonds) |
5794 | 5794 | { |
5795 | - int i, j, n1, n2; | |
5795 | + int i, j, n1, n2, n; | |
5796 | 5796 | Atom *ap; |
5797 | + Int *bonds_tmp; | |
5798 | + | |
5797 | 5799 | if (mp == NULL || bonds == NULL || nbonds <= 0) |
5798 | 5800 | return 0; |
5799 | 5801 | if (mp->noModifyTopology) |
5800 | 5802 | return -4; /* Prohibited operation */ |
5801 | 5803 | |
5802 | 5804 | /* Check the bonds */ |
5805 | + bonds_tmp = (Int *)malloc(sizeof(Int) * nbonds * 2); | |
5806 | + if (bonds_tmp == NULL) | |
5807 | + return -4; /* Out of memory */ | |
5808 | + n = 0; | |
5803 | 5809 | for (i = 0; i < nbonds; i++) { |
5804 | 5810 | n1 = bonds[i * 2]; |
5805 | 5811 | n2 = bonds[i * 2 + 1]; |
@@ -5808,18 +5814,29 @@ MoleculeAddBonds(Molecule *mp, Int nbonds, const Int *bonds) | ||
5808 | 5814 | ap = ATOM_AT_INDEX(mp->atoms, n1); |
5809 | 5815 | if (ap->nconnects >= ATOMS_MAX_CONNECTS - 1 || ATOM_AT_INDEX(mp->atoms, n2)->nconnects >= ATOMS_MAX_CONNECTS - 1) |
5810 | 5816 | return -2; /* Too many bonds */ |
5817 | + /* Check duplicates */ | |
5811 | 5818 | for (j = 0; j < ap->nconnects; j++) { |
5812 | 5819 | if (ap->connects[j] == n2) |
5813 | - return -3; /* Duplicate bond */ | |
5820 | + break; | |
5814 | 5821 | } |
5822 | + if (j == ap->nconnects) { | |
5823 | + bonds_tmp[n * 2] = n1; | |
5824 | + bonds_tmp[n * 2 + 1] = n2; | |
5825 | + n++; | |
5826 | + } | |
5827 | + } | |
5828 | + if (n == 0) { | |
5829 | + /* No bonds to add */ | |
5830 | + free(bonds_tmp); | |
5831 | + return 0; | |
5815 | 5832 | } |
5816 | 5833 | |
5817 | 5834 | __MoleculeLock(mp); |
5818 | 5835 | |
5819 | 5836 | /* Add connects[] */ |
5820 | - for (i = 0; i < nbonds; i++) { | |
5821 | - n1 = bonds[i * 2]; | |
5822 | - n2 = bonds[i * 2 + 1]; | |
5837 | + for (i = 0; i < n; i++) { | |
5838 | + n1 = bonds_tmp[i * 2]; | |
5839 | + n2 = bonds_tmp[i * 2 + 1]; | |
5823 | 5840 | ap = ATOM_AT_INDEX(mp->atoms, n1); |
5824 | 5841 | ap->connects[ap->nconnects++] = n2; |
5825 | 5842 | ap = ATOM_AT_INDEX(mp->atoms, n2); |
@@ -5830,9 +5847,9 @@ MoleculeAddBonds(Molecule *mp, Int nbonds, const Int *bonds) | ||
5830 | 5847 | n1 = mp->nbonds; |
5831 | 5848 | /* if (AssignArray(&(mp->bonds), &(mp->nbonds), sizeof(Int) * 2, mp->nbonds + nb - 1, NULL) == NULL |
5832 | 5849 | || sInsertElementsToArrayAtPositions(mp->bonds, n1, bonds, nb, sizeof(Int) * 2, where) != 0) */ |
5833 | - if (AssignArray(&(mp->bonds), &(mp->nbonds), sizeof(Int) * 2, mp->nbonds + nbonds - 1, NULL) == NULL) | |
5850 | + if (AssignArray(&(mp->bonds), &(mp->nbonds), sizeof(Int) * 2, mp->nbonds + n - 1, NULL) == NULL) | |
5834 | 5851 | goto panic; |
5835 | - memmove(mp->bonds + n1 * 2, bonds, sizeof(Int) * 2 * nbonds); | |
5852 | + memmove(mp->bonds + n1 * 2, bonds_tmp, sizeof(Int) * 2 * n); | |
5836 | 5853 | |
5837 | 5854 | /* Add angles, dihedrals, impropers */ |
5838 | 5855 | { |
@@ -5846,9 +5863,9 @@ MoleculeAddBonds(Molecule *mp, Int nbonds, const Int *bonds) | ||
5846 | 5863 | angles = dihedrals = impropers = NULL; |
5847 | 5864 | nangles = ndihedrals = nimpropers = 0; |
5848 | 5865 | |
5849 | - for (i = 0; i < nbonds; i++) { | |
5850 | - n1 = bonds[i * 2]; | |
5851 | - n2 = bonds[i * 2 + 1]; | |
5866 | + for (i = 0; i < n; i++) { | |
5867 | + n1 = bonds_tmp[i * 2]; | |
5868 | + n2 = bonds_tmp[i * 2 + 1]; | |
5852 | 5869 | ap1 = ATOM_AT_INDEX(mp->atoms, n1); |
5853 | 5870 | ap2 = ATOM_AT_INDEX(mp->atoms, n2); |
5854 | 5871 | /* Angles X-n1-n2 */ |
@@ -5930,7 +5947,8 @@ MoleculeAddBonds(Molecule *mp, Int nbonds, const Int *bonds) | ||
5930 | 5947 | mp->needsMDRebuild = 1; |
5931 | 5948 | __MoleculeUnlock(mp); |
5932 | 5949 | |
5933 | - return nbonds; | |
5950 | + free(bonds_tmp); | |
5951 | + return n; | |
5934 | 5952 | |
5935 | 5953 | panic: |
5936 | 5954 | __MoleculeUnlock(mp); |
@@ -4728,6 +4728,7 @@ s_Molecule_SetPsPerStep(VALUE self, VALUE val) | ||
4728 | 4728 | * |
4729 | 4729 | * Find the angles from the bonds. Returns the number of angles newly created. |
4730 | 4730 | */ |
4731 | +/* | |
4731 | 4732 | static VALUE |
4732 | 4733 | s_Molecule_FindAngles(VALUE self) |
4733 | 4734 | { |
@@ -4758,13 +4759,14 @@ s_Molecule_FindAngles(VALUE self) | ||
4758 | 4759 | } |
4759 | 4760 | return INT2NUM(nip); |
4760 | 4761 | } |
4761 | - | |
4762 | +*/ | |
4762 | 4763 | /* |
4763 | 4764 | * call-seq: |
4764 | 4765 | * find_dihedrals -> Integer |
4765 | 4766 | * |
4766 | 4767 | * Find the dihedrals from the bonds. Returns the number of dihedrals newly created. |
4767 | 4768 | */ |
4769 | +/* | |
4768 | 4770 | static VALUE |
4769 | 4771 | s_Molecule_FindDihedrals(VALUE self) |
4770 | 4772 | { |
@@ -4806,6 +4808,7 @@ s_Molecule_FindDihedrals(VALUE self) | ||
4806 | 4808 | } |
4807 | 4809 | return INT2NUM(nip); |
4808 | 4810 | } |
4811 | +*/ | |
4809 | 4812 | |
4810 | 4813 | /* |
4811 | 4814 | * call-seq: |
@@ -5438,16 +5441,17 @@ s_Molecule_DuplicateAnAtom(int argc, VALUE *argv, VALUE self) | ||
5438 | 5441 | |
5439 | 5442 | /* |
5440 | 5443 | * call-seq: |
5441 | - * create_bond(n1, n2, ...) -> Molecule | |
5444 | + * create_bond(n1, n2, ...) -> Integer | |
5442 | 5445 | * |
5443 | - * Create bonds between atoms n1 and n2, n3 and n4, and so on. Returns self. | |
5446 | + * Create bonds between atoms n1 and n2, n3 and n4, and so on. If the corresponding bond is already present for a particular pair, | |
5447 | + * do nothing for that pair. Returns the number of bonds actually created. | |
5444 | 5448 | * This operation is undoable. |
5445 | 5449 | */ |
5446 | 5450 | static VALUE |
5447 | 5451 | s_Molecule_CreateBond(int argc, VALUE *argv, VALUE self) |
5448 | 5452 | { |
5449 | 5453 | Molecule *mol; |
5450 | - Int i, *ip; | |
5454 | + Int i, *ip, old_nbonds; | |
5451 | 5455 | if (argc == 0) |
5452 | 5456 | rb_raise(rb_eMolbyError, "missing arguments"); |
5453 | 5457 | if (argc % 2 != 0) |
@@ -5457,7 +5461,7 @@ s_Molecule_CreateBond(int argc, VALUE *argv, VALUE self) | ||
5457 | 5461 | for (i = 0; i < argc; i++) |
5458 | 5462 | ip[i] = s_Molecule_AtomIndexFromValue(mol, argv[i]); |
5459 | 5463 | ip[argc] = kInvalidIndex; |
5460 | -// i = MoleculeAddBonds(mol, ip, NULL); | |
5464 | + old_nbonds = mol->nbonds; | |
5461 | 5465 | i = MolActionCreateAndPerform(mol, gMolActionAddBonds, argc, ip); |
5462 | 5466 | if (i == -1) |
5463 | 5467 | rb_raise(rb_eMolbyError, "atom index out of range"); |
@@ -5467,7 +5471,34 @@ s_Molecule_CreateBond(int argc, VALUE *argv, VALUE self) | ||
5467 | 5471 | rb_raise(rb_eMolbyError, "duplicate bonds"); |
5468 | 5472 | else if (i != 0) |
5469 | 5473 | rb_raise(rb_eMolbyError, "error in creating bonds"); |
5470 | - return self; | |
5474 | + return INT2NUM(mol->nbonds - old_nbonds); | |
5475 | +} | |
5476 | + | |
5477 | +/* | |
5478 | + * call-seq: | |
5479 | + * molecule.remove_bonds(n1, n2, ...) -> Integer | |
5480 | + * | |
5481 | + * Remove bonds between atoms n1 and n2, n3 and n4, and so on. If the corresponding bond is not present for | |
5482 | + * a particular pair, do nothing for that pair. Returns the number of bonds actually removed. | |
5483 | + * This operation is undoable. | |
5484 | + */ | |
5485 | +static VALUE | |
5486 | +s_Molecule_RemoveBond(int argc, VALUE *argv, VALUE self) | |
5487 | +{ | |
5488 | + Molecule *mol; | |
5489 | + Int i, *ip, old_nbonds; | |
5490 | + if (argc == 0) | |
5491 | + rb_raise(rb_eMolbyError, "missing arguments"); | |
5492 | + if (argc % 2 != 0) | |
5493 | + rb_raise(rb_eMolbyError, "bonds should be specified by pairs of atom indices"); | |
5494 | + Data_Get_Struct(self, Molecule, mol); | |
5495 | + ip = ALLOC_N(Int, argc + 1); | |
5496 | + for (i = 0; i < argc; i++) | |
5497 | + ip[i] = s_Molecule_AtomIndexFromValue(mol, argv[i]); | |
5498 | + ip[argc] = kInvalidIndex; | |
5499 | + old_nbonds = mol->nbonds; | |
5500 | + MolActionCreateAndPerform(mol, gMolActionDeleteBonds, argc, ip); | |
5501 | + return INT2NUM(old_nbonds - mol->nbonds); | |
5471 | 5502 | } |
5472 | 5503 | |
5473 | 5504 | /* |
@@ -7491,8 +7522,8 @@ Init_Molby(void) | ||
7491 | 7522 | rb_define_method(rb_cMolecule, "ps_per_step", s_Molecule_PsPerStep, 0); |
7492 | 7523 | rb_define_method(rb_cMolecule, "ps_per_step=", s_Molecule_SetPsPerStep, 1); |
7493 | 7524 | |
7494 | - rb_define_method(rb_cMolecule, "find_angles", s_Molecule_FindAngles, 0); | |
7495 | - rb_define_method(rb_cMolecule, "find_dihedrals", s_Molecule_FindDihedrals, 0); | |
7525 | +/* rb_define_method(rb_cMolecule, "find_angles", s_Molecule_FindAngles, 0); | |
7526 | + rb_define_method(rb_cMolecule, "find_dihedrals", s_Molecule_FindDihedrals, 0); */ | |
7496 | 7527 | rb_define_method(rb_cMolecule, "nresidues", s_Molecule_Nresidues, 0); |
7497 | 7528 | rb_define_method(rb_cMolecule, "nresidues=", s_Molecule_ChangeNresidues, 1); |
7498 | 7529 | rb_define_method(rb_cMolecule, "max_residue_number", s_Molecule_MaxResSeq, -1); |
@@ -7520,6 +7551,9 @@ Init_Molby(void) | ||
7520 | 7551 | rb_define_method(rb_cMolecule, "create_atom", s_Molecule_CreateAnAtom, -1); |
7521 | 7552 | rb_define_method(rb_cMolecule, "duplicate_atom", s_Molecule_DuplicateAnAtom, -1); |
7522 | 7553 | rb_define_method(rb_cMolecule, "create_bond", s_Molecule_CreateBond, -1); |
7554 | + rb_define_alias(rb_cMolecule, "create_bonds", "create_bond"); | |
7555 | + rb_define_method(rb_cMolecule, "remove_bond", s_Molecule_RemoveBond, -1); | |
7556 | + rb_define_alias(rb_cMolecule, "remove_bonds", "remove_bond"); | |
7523 | 7557 | rb_define_method(rb_cMolecule, "add_angle", s_Molecule_AddAngle, 3); |
7524 | 7558 | rb_define_method(rb_cMolecule, "remove_angle", s_Molecule_RemoveAngle, 3); |
7525 | 7559 | rb_define_method(rb_cMolecule, "add_dihedral", s_Molecule_AddDihedral, 4); |