From: Toshi Nagata Date: Tue, 15 Nov 2022 15:07:54 +0000 (+0900) Subject: Support load/save of NBO info X-Git-Url: http://git.osdn.net/view?p=molby%2FMolby.git;a=commitdiff_plain;h=c2d61cd83654d565a405b7a8aa19d8a9abeee133 Support load/save of NBO info --- diff --git a/MolLib/Molecule.c b/MolLib/Molecule.c index 5b80f62..0ff5985 100755 --- a/MolLib/Molecule.c +++ b/MolLib/Molecule.c @@ -859,11 +859,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* idx symop symbase */ if (sscanf(buf, "%d %d %d", &ibuf[0], &ibuf[1], &ibuf[2]) < 3) { s_append_asprintf(errbuf, "line %d: symmetry operations cannot be read for atom %d", lineNumber, i + 1); - goto err_exit; + goto skip_section; } if (i >= mp->natoms) { s_append_asprintf(errbuf, "line %d: too many atomic symmetry info\n", lineNumber); - goto err_exit; + goto skip_section; } ap = ATOM_AT_INDEX(mp->atoms, i); ap->symop.sym = ibuf[1] / 1000000; @@ -884,11 +884,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* idx fix_force fix_pos */ if (sscanf(buf, "%d %lf %lf %lf %lf", &ibuf[0], &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3]) < 5) { s_append_asprintf(errbuf, "line %d: fix atom info cannot be read for atom %d", lineNumber, i + 1); - goto err_exit; + goto skip_section; } if (i >= mp->natoms) { s_append_asprintf(errbuf, "line %d: too many fix atom info\n", lineNumber); - goto err_exit; + goto skip_section; } ap = ATOM_AT_INDEX(mp->atoms, i); ap->fix_force = dbuf[0]; @@ -908,11 +908,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* idx uff_type */ if (sscanf(buf, "%d %6s", &ibuf[0], cbuf[0]) < 2) { s_append_asprintf(errbuf, "line %d: uff type info cannot be read for atom %d", lineNumber, i + 1); - goto err_exit; + goto skip_section; } if (i >= mp->natoms) { s_append_asprintf(errbuf, "line %d: too many uff type info\n", lineNumber); - goto err_exit; + goto skip_section; } ap = ATOM_AT_INDEX(mp->atoms, i); strncpy(ap->uff_type, cbuf[0], 5); @@ -929,11 +929,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* idx mm_exclude periodic_exclude */ if (sscanf(buf, "%d %d %d", &ibuf[0], &ibuf[1], &ibuf[2]) < 3) { s_append_asprintf(errbuf, "line %d: mm_exclude flags cannot be read for atom %d", lineNumber, i + 1); - goto err_exit; + goto skip_section; } if (i >= mp->natoms) { s_append_asprintf(errbuf, "line %d: too many mm_exclude flags\n", lineNumber); - goto err_exit; + goto skip_section; } ap = ATOM_AT_INDEX(mp->atoms, i); ap->mm_exclude = (ibuf[1] != 0); @@ -950,7 +950,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* idx count */ if ((j = sscanf(buf, "%d %d", &ibuf[0], &ibuf[1])) < 2) { s_append_asprintf(errbuf, "line %d: bad format for pi_anchor", lineNumber); - goto err_exit; + goto skip_section; } i = ibuf[0]; ap = ATOM_AT_INDEX(mp->atoms, i); @@ -963,7 +963,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) ap->anchor = (PiAnchor *)calloc(sizeof(PiAnchor), 1); if (ibuf[1] < 2 || ibuf[1] >= mp->natoms) { s_append_asprintf(errbuf, "line %d: bad number of components for pi_anchor", lineNumber); - goto err_exit; + goto skip_section; } AtomConnectResize(&ap->anchor->connect, ibuf[1]); ip = AtomConnectData(&ap->anchor->connect); @@ -976,15 +976,15 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) } if (sscanf(buf, "%d %lf", &ibuf[0], &dbuf[0]) < 2) { s_append_asprintf(errbuf, "line %d: bad format for pi_anchor", lineNumber); - goto err_exit; + goto skip_section; } if (ibuf[0] < 0 || ibuf[0] >= mp->natoms) { s_append_asprintf(errbuf, "line %d: atom index out of range", lineNumber); - goto err_exit; + goto skip_section; } if (dbuf[0] <= 0.0) { s_append_asprintf(errbuf, "line %d: the pi anchor weights should be positive", lineNumber); - goto err_exit; + goto skip_section; } ip[i] = ibuf[0]; ap->anchor->coeffs[i] = dbuf[0]; @@ -1005,11 +1005,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) } if (j > 4 && nframes != 0) { s_append_asprintf(errbuf, "line %d: atom position sigma can only be given for frame 0", lineNumber); - goto err_exit; + goto skip_section; } if (j > 4 && j != 7) { s_append_asprintf(errbuf, "line %d: atom position sigma cannot be read for atom %d frame %d", lineNumber, i + 1, nframes); - goto err_exit; + goto skip_section; } if (i >= mp->natoms) { s_append_asprintf(errbuf, "line %d: too many atom position records\n", lineNumber); @@ -1050,7 +1050,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) i = sscanf(buf, "%d %d %d %d %d %d %d %d", &ibuf[0], &ibuf[1], &ibuf[2], &ibuf[3], &ibuf[4], &ibuf[5], &ibuf[6], &ibuf[7]); if (i < 2 || i % 2 != 0) { s_append_asprintf(errbuf, "line %d: bad bond format", lineNumber); - goto err_exit; + goto skip_section; } for (j = 0; j < i; j += 2) { iibuf[0] = ibuf[j]; @@ -1079,7 +1079,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) i = sscanf(buf, "%lf %lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3]); if (i == 0) { s_append_asprintf(errbuf, "line %d: bad bond order format", lineNumber); - goto err_exit; + goto skip_section; } for (j = 0; j < i; j++) { AssignArray(&mp->bondOrders, &mp->nbondOrders, sizeof(Double), mp->nbondOrders, &dbuf[j]); @@ -1109,7 +1109,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) i = sscanf(buf, "%d %d %d %d %d %d %d %d %d", &ibuf[0], &ibuf[1], &ibuf[2], &ibuf[3], &ibuf[4], &ibuf[5], &ibuf[6], &ibuf[7], &ibuf[8]); if (i == 0 || i % 3 != 0) { s_append_asprintf(errbuf, "line %d: bad angle format", lineNumber); - goto err_exit; + goto skip_section; } for (j = 0; j < i; j += 3) { iibuf[0] = ibuf[j]; @@ -1140,7 +1140,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) i = sscanf(buf, "%d %d %d %d %d %d %d %d", &ibuf[0], &ibuf[1], &ibuf[2], &ibuf[3], &ibuf[4], &ibuf[5], &ibuf[6], &ibuf[7]); if (i == 0 || i % 4 != 0) { s_append_asprintf(errbuf, "line %d: bad dihedral format", lineNumber); - goto err_exit; + goto skip_section; } for (j = 0; j < i; j += 4) { iibuf[0] = ibuf[j]; @@ -1172,7 +1172,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) i = sscanf(buf, "%d %d %d %d %d %d %d %d", &ibuf[0], &ibuf[1], &ibuf[2], &ibuf[3], &ibuf[4], &ibuf[5], &ibuf[6], &ibuf[7]); if (i == 0 || i % 4 != 0) { s_append_asprintf(errbuf, "line %d: bad improper format", lineNumber); - goto err_exit; + goto skip_section; } for (j = 0; j < i; j += 4) { iibuf[0] = ibuf[j]; @@ -1203,17 +1203,17 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* a b c alpha beta gamma [sigmaflag] */ if ((j = sscanf(buf, "%lf %lf %lf %lf %lf %lf %d", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3], &dbuf[4], &dbuf[5], &ibuf[0])) < 6) { s_append_asprintf(errbuf, "line %d: bad xtalcell format", lineNumber); - goto err_exit; + goto skip_section; } MoleculeSetCell(mp, dbuf[0], dbuf[1], dbuf[2], dbuf[3], dbuf[4], dbuf[5], 0); if (j == 7 && ibuf[0] != 0) { if (ReadLine(buf, sizeof buf, fp, &lineNumber) <= 0) { s_append_asprintf(errbuf, "line %d: sigma for xtalcell are missing", lineNumber); - goto err_exit; + goto skip_section; } if (sscanf(buf, "%lf %lf %lf %lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3], &dbuf[4], &dbuf[5]) < 6) { s_append_asprintf(errbuf,"line %d: bad xtalcell sigma format", lineNumber); - goto err_exit; + goto skip_section; } if (mp->cell != NULL) { mp->cell->has_sigma = 1; @@ -1237,7 +1237,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* a11 a12 a13; a21 a22 a23; a31 a32 a33; t1 t2 t3 */ if (sscanf(buf, "%lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2]) < 3) { s_append_asprintf(errbuf, "line %d: bad symmetry_operation format", lineNumber); - goto err_exit; + goto skip_section; } if (i < 3) { tr[i] = dbuf[0]; @@ -1265,11 +1265,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* b11 b22 b33 b12 b13 b23 [has_sigma] */ if ((j = sscanf(buf, "%lf %lf %lf %lf %lf %lf %d", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3], &dbuf[4], &dbuf[5], &ibuf[0])) < 6) { s_append_asprintf(errbuf, "line %d: anisotropic thermal parameters cannot be read for atom %d", lineNumber, i + 1); - goto err_exit; + goto skip_section; } if (i >= mp->natoms) { s_append_asprintf(errbuf, "line %d: too many anisotropic thermal parameters\n", lineNumber); - goto err_exit; + goto skip_section; } if (dbuf[0] == 0.0 && dbuf[1] == 0.0 && dbuf[2] == 0.0 && dbuf[3] == 0.0 && dbuf[4] == 0.0 && dbuf[5] == 0.0) { /* Skip it */ @@ -1279,16 +1279,16 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) if (j == 7 && ibuf[0] != 0) { if (ReadLine(buf, sizeof buf, fp, &lineNumber) <= 0) { s_append_asprintf(errbuf, "line %d: anisotropic thermal parameters sigma missing", lineNumber); - goto err_exit; + goto skip_section; } if (sscanf(buf, "%lf %lf %lf %lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3], &dbuf[4], &dbuf[5]) < 6) { s_append_asprintf(errbuf, "line %d: anisotropic thermal parameters sigma cannot be read for atom %d", lineNumber, i + 1); - goto err_exit; + goto skip_section; } ap = ATOM_AT_INDEX(mp->atoms, i); if (ap->aniso == NULL) { s_append_asprintf(errbuf, "line %d: anisotropic thermal parameters sigma are given while the parameters are not given", lineNumber); - goto err_exit; + goto skip_section; } ap->aniso->has_bsig = 1; for (j = 0; j < 6; j++) @@ -1320,7 +1320,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) } if ((j = sscanf(buf, "%d %d %d %d", &ibuf[0], &ibuf[1], &ibuf[2], &ibuf[3])) < 3) { s_append_asprintf(errbuf, "line %d: bad periodic_box format", lineNumber); - goto err_exit; + goto skip_section; } if (j == 4 && ibuf[3] != 0) has_sigma = 1; @@ -1331,11 +1331,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) if (has_sigma) { if (ReadLine(buf, sizeof buf, fp, &lineNumber) <= 0) { s_append_asprintf(errbuf, "line %d: sigma for cell parameters are missing", lineNumber); - goto err_exit; + goto skip_section; } if (sscanf(buf, "%lf %lf %lf %lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3], &dbuf[4], &dbuf[5]) < 6) { s_append_asprintf(errbuf, "line %d: bad periodic_box sigma format", lineNumber); - goto err_exit; + goto skip_section; } if (mp->cell != NULL) { mp->cell->has_sigma = 1; @@ -1360,7 +1360,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) break; if (sscanf(buf, "%lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2]) < 3) { s_append_asprintf(errbuf, "line %d: bad frame_periodic_box format", lineNumber); - goto err_exit; + goto skip_section; } vs[i].x = dbuf[0]; vs[i].y = dbuf[1]; @@ -1406,7 +1406,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) if (k < '0' || k > '9') { s_append_asprintf(errbuf, "line %d: too few flags in alchem_flags block", lineNumber + 1); free(valp); - goto err_exit; + goto skip_section; } ReadLine(buf, sizeof buf, fp, &lineNumber); bufp = buf; @@ -1415,13 +1415,13 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) if (i >= j) { s_append_asprintf(errbuf, "line %d: too many flags in alchem_flags block", lineNumber); free(valp); - goto err_exit; + goto skip_section; } valp[i++] = *bufp - '0'; } else if (*bufp != ' ' && *bufp != '\t' && *bufp != '\n') { s_append_asprintf(errbuf, "line %d: strange character (0x%02x) in alchem_flags block", lineNumber, (int)*bufp); free(valp); - goto err_exit; + goto skip_section; } bufp++; } @@ -1503,14 +1503,14 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) if (strcmp(comp, "pressure") == 0) { if (sscanf(valp, "%lf %lf %lf %lf %lf %lf %lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3], &dbuf[4], &dbuf[5], &dbuf[6], &dbuf[7], &dbuf[8]) < 9) { s_append_asprintf(errbuf, "line %d: bad format", lineNumber); - goto err_exit; + goto skip_section; } for (i = 0; i < 9; i++) pressure->apply[i] = dbuf[i]; } else if (strcmp(comp, "pressure_cell_flexibility") == 0) { if (sscanf(valp, "%lf %lf %lf %lf %lf %lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3], &dbuf[4], &dbuf[5], &dbuf[6], &dbuf[7]) < 8) { s_append_asprintf(errbuf, "line %d: bad format", lineNumber); - goto err_exit; + goto skip_section; } for (i = 0; i < 8; i++) pressure->cell_flexibility[i] = dbuf[i]; @@ -1533,11 +1533,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* idx vx vy vz */ if (sscanf(buf, "%d %lf %lf %lf", &ibuf[0], &dbuf[0], &dbuf[1], &dbuf[2]) < 4) { s_append_asprintf(errbuf, "line %d: atom velocity cannot be read for atom %d", lineNumber, i + 1); - goto err_exit; + goto skip_section; } if (i >= mp->natoms) { s_append_asprintf(errbuf, "line %d: too many atom velocity records\n", lineNumber); - goto err_exit; + goto skip_section; } ap = ATOM_AT_INDEX(mp->atoms, i); ap->v.x = dbuf[0]; @@ -1556,11 +1556,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* idx fx fy fz */ if (sscanf(buf, "%d %lf %lf %lf", &ibuf[0], &dbuf[0], &dbuf[1], &dbuf[2]) < 4) { s_append_asprintf(errbuf, "line %d: atom force cannot be read for atom %d", lineNumber, i + 1); - goto err_exit; + goto skip_section; } if (i >= mp->natoms) { s_append_asprintf(errbuf, "line %d: too many atom force records\n", lineNumber); - goto err_exit; + goto skip_section; } ap = ATOM_AT_INDEX(mp->atoms, i); ap->f.x = dbuf[0]; @@ -1586,7 +1586,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) if (j < 0) { s_append_asprintf(errbuf, "%s", bufp); free(bufp); - goto err_exit; + goto skip_section; } i += j; } @@ -1611,7 +1611,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) || (i == 2 && sscanf(buf, "%lf %lf %lf %lf", &dbuf[4], &dbuf[5], &dbuf[6], &dbuf[7]) < 4)) { s_append_asprintf(errbuf, "line %d: bad trackball format", lineNumber); - goto err_exit; + goto skip_section; } if (i == 0) TrackballSetScale(mp->mview->track, dbuf[0]); @@ -1722,11 +1722,14 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) continue; if (buf[0] == '\n') break; - /* sym nprims a_idx */ - if (sscanf(buf, "%6s %d %d", cbuf[0], &ibuf[0], &ibuf[1]) < 3) { + /* sym nprims a_idx [add_exp] */ + i = sscanf(buf, "%6s %d %d %d", cbuf[0], &ibuf[0], &ibuf[1], &ibuf[3]); + if (i < 3) { s_append_asprintf(errbuf, "line %d: the gaussian primitive info cannot be read", lineNumber); - goto err_exit; + goto skip_section; } + if (i == 3) + ibuf[3] = 0; /* Additional exponent (JANPA extension) */ if (strcasecmp(cbuf[0], "S") == 0) { ibuf[2] = 0; } else if (strcasecmp(cbuf[0], "P") == 0) { @@ -1747,17 +1750,17 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) ibuf[2] = -4; } else { s_append_asprintf(errbuf, "line %d: the gaussian primitive type %s is unknown", lineNumber, cbuf[0]); - goto err_exit; + goto skip_section; } if (ibuf[0] <= 0) { s_append_asprintf(errbuf, "line %d: the number of primitive (%d) must be positive", lineNumber, ibuf[0]); - goto err_exit; + goto skip_section; } if (ibuf[1] < 0 || ibuf[1] >= mp->natoms) { s_append_asprintf(errbuf, "line %d: the atom index (%d) is out of range", lineNumber, ibuf[1]); - goto err_exit; + goto skip_section; } - MoleculeAddGaussianOrbitalShell(mp, ibuf[1], ibuf[2], ibuf[0], 0); + MoleculeAddGaussianOrbitalShell(mp, ibuf[1], ibuf[2], ibuf[0], ibuf[3]); i = ibuf[0]; while (ReadLine(buf, sizeof buf, fp, &lineNumber) > 0) { if (buf[0] == '!') @@ -1766,7 +1769,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) break; if (sscanf(buf, "%lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2]) < 3) { s_append_asprintf(errbuf, "line %d: cannot read gaussian primitive coefficients", lineNumber); - goto err_exit; + goto skip_section; } MoleculeAddGaussianPrimitiveCoefficients(mp, dbuf[0], dbuf[1], dbuf[2]); if (--i == 0) @@ -1784,7 +1787,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) break; if (sscanf(buf, "%6s %d %d", cbuf[0], &ibuf[0], &ibuf[1]) < 3) { s_append_asprintf(errbuf, "line %d: the MO info cannot be correctly read", lineNumber); - goto err_exit; + goto skip_section; } if (strcasecmp(cbuf[0], "RHF") == 0) { ibuf[2] = 1; @@ -1794,11 +1797,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) ibuf[2] = 0; } else { s_append_asprintf(errbuf, "line %d: unknown HF type: %s", lineNumber, cbuf[0]); - goto err_exit; + goto skip_section; } if (ibuf[0] < 0 || ibuf[1] < 0) { s_append_asprintf(errbuf, "line %d: incorrect number of electrons", lineNumber); - goto err_exit; + goto skip_section; } MoleculeSetMOInfo(mp, ibuf[2], ibuf[0], ibuf[1]); } @@ -1806,7 +1809,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) } else if (strcmp(buf, "!:mo_coefficients") == 0) { if (mp->bset == NULL || mp->bset->nshells == 0) { s_append_asprintf(errbuf, "line %d: the :gaussian_primitive section must come before :mo_coefficients", lineNumber); - goto err_exit; + goto skip_section; } /* Count the number of components */ dp = (Double *)malloc(sizeof(Double) * mp->bset->ncomps); @@ -1818,11 +1821,11 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) break; if (sscanf(buf, "MO %d %lf", &ibuf[0], &dbuf[6]) < 2) { s_append_asprintf(errbuf, "line %d: cannot read the MO index or energy", lineNumber); - goto err_exit; + goto skip_section; } if (ibuf[0] != i) { s_append_asprintf(errbuf, "line %d: the MO index (%d) must be in ascending order", lineNumber, ibuf[0]); - goto err_exit; + goto skip_section; } i = 0; while (ReadLine(buf, sizeof buf, fp, &lineNumber) > 0) { @@ -1844,7 +1847,7 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) i = MoleculeSetMOCoefficients(mp, ibuf[0], dbuf[6], mp->bset->ncomps, dp); if (i != 0) { s_append_asprintf(errbuf, "line %d: cannot set MO coefficients", lineNumber); - goto err_exit; + goto skip_section; } i = ibuf[0] + 1; /* For next entry */ } @@ -1883,14 +1886,14 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) if (i == 0) { if (sscanf(buf, "%d %d", &ibuf[0], &ibuf[1]) < 2) { s_append_asprintf(errbuf, "line %d: the closed/visible flags cannot be read for graphic object", lineNumber); - goto err_exit; + goto skip_section; } gp->closed = ibuf[0]; gp->visible = ibuf[1]; } else if (i == 1) { if (sscanf(buf, "%lf %lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2], &dbuf[3]) < 4) { s_append_asprintf(errbuf, "line %d: the color cannot be read for graphic object", lineNumber); - goto err_exit; + goto skip_section; } for (j = 0; j < 4; j++) gp->rgba[j] = dbuf[j]; @@ -1898,14 +1901,14 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) j = atoi(buf); if (j < 0) { s_append_asprintf(errbuf, "line %d: the number of control points must be non-negative", lineNumber); - goto err_exit; + goto skip_section; } if (j > 0) NewArray(&gp->points, &gp->npoints, sizeof(GLfloat) * 3, j); } else if (i >= 3 && i < gp->npoints + 3) { if (sscanf(buf, "%lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2]) < 3) { s_append_asprintf(errbuf, "line %d: the control point cannot be read for graphic object", lineNumber); - goto err_exit; + goto skip_section; } j = (i - 3) * 3; gp->points[j++] = dbuf[0]; @@ -1915,14 +1918,14 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) j = atoi(buf); if (j < 0) { s_append_asprintf(errbuf, "line %d: the number of normals must be non-negative", lineNumber); - goto err_exit; + goto skip_section; } if (j > 0) NewArray(&gp->normals, &gp->nnormals, sizeof(GLfloat) * 3, j); } else if (i >= gp->npoints + 4 && i < gp->npoints + gp->nnormals + 4) { if (sscanf(buf, "%lf %lf %lf", &dbuf[0], &dbuf[1], &dbuf[2]) < 3) { s_append_asprintf(errbuf, "line %d: the normal vector cannot be read for graphic object", lineNumber); - goto err_exit; + goto skip_section; } j = (i - gp->npoints - 4) * 3; gp->normals[j++] = dbuf[0]; @@ -1938,6 +1941,34 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) goto redo; } continue; + } else if (strcmp(buf, "!:nbo") == 0) { + Int stringLen; + char *stringBuf, *returnString; + i = strlen(buf) + 1; /* Including \n */ + NewArray(&stringBuf, &stringLen, sizeof(char), i + 1); + strcpy(stringBuf, buf); + strcat(stringBuf, "\n"); + k = lineNumber; + while (ReadLine(buf, sizeof buf, fp, &lineNumber) > 0) { + /* The comment lines are _not_ skipped */ + if (buf[0] == '\n') + break; + j = strlen(buf); + AssignArray(&stringBuf, &stringLen, sizeof(char), i + j, NULL); + strncpy(stringBuf + i, buf, j); + i += j; + } + if (MolActionCreateAndPerform(mp, SCRIPT_ACTION("si;s"), + "proc { |s,i| mbsfstring2nbo(s,i) }", + stringBuf, k, &returnString) != 0) { + s_append_asprintf(errbuf, "line %d: cannot call mbsfstring2nbo at line ", lineNumber); + goto skip_section; + } else if (returnString[0] != 0) { + s_append_asprintf(errbuf, "%s", returnString); + goto skip_section; + } + free(stringBuf); + continue; } else if (strncmp(buf, "!:@", 3) == 0) { /* Plug-in implemented in the ruby world */ Int stringLen; @@ -1959,15 +1990,16 @@ MoleculeLoadMbsfFile(Molecule *mp, const char *fname, char **errbuf) "proc { |i| loadmbsf_plugin(i) rescue \"line #{i}: #{$i.to_s}\" }", stringBuf, k, &returnString) != 0) { s_append_asprintf(errbuf, "line %d: cannot invoke Ruby plugin", lineNumber); - goto err_exit; + goto skip_section; } else if (returnString[0] != 0) { s_append_asprintf(errbuf, "%s", returnString); - goto err_exit; + goto skip_section; } free(stringBuf); continue; } /* Unknown sections are silently ignored */ + skip_section:; } MoleculeCleanUpResidueTable(mp); @@ -2778,9 +2810,10 @@ MoleculeAddGaussianPrimitiveCoefficients(Molecule *mol, Double exponent, Double } /* Get the shell information from the component index */ -/* The outLabel must have space for at least 23 non-Null characters */ +/* The outLabel must have space for at least 31 non-Null characters */ +/* See also: sub load_janpa_log in loadsave.rb */ int -MoleculeGetGaussianComponentInfo(Molecule *mol, Int comp_idx, Int *outAtomIdx, char *outLabel, Int *outShellIdx) +MoleculeGetGaussianComponentInfo(Molecule *mol, Int comp_idx, Int *outAtomIdx, char outLabel[32], Int *outShellIdx) { BasisSet *bset; ShellInfo *shellp; @@ -2800,8 +2833,8 @@ MoleculeGetGaussianComponentInfo(Molecule *mol, Int comp_idx, Int *outAtomIdx, c static const char *type_f = "xxxyyyzzzxxyxxzxyyyyzxzzyzzxyz"; static const char *type_f7[] = {"z3-zr2", "xz2-xr2", "yz2-yr2", "x2z-y2z", "xyz", "x3-xy2", "x2y-y3"}; static const char *type_g[] = {"x4", "y4", "z4", "x3y", "x3z", "xy3", "y3z", "xz3", "yz3", "x2y2", "x2z2", "y2z2", "x2yz", "xy2z", "xyz2"}; - static const char *type_g9[] = {"z4-z2r2+r4", "xz3-xzr2", "yz3-yzr2", "(x2-y2)(z2-r2)", "xyz2-xyr2", "x3z-xy2z", "x2yz-y3z", "x4-x2y2+y4", "x3y-xy3"}; - *outAtomIdx = shellp->a_idx; + static const char *type_g9[] = {"z4-z2r2+r4", "xz3-xzr2", "yz3-yzr2", "x2z2-y2z2", "xyz2-xyr2", "x3z-xy2z", "x2yz-y3z", "x4-x2y2+y4", "x3y-xy3"}; + *outAtomIdx = shellp->a_idx; *outShellIdx = si; switch (shellp->sym) { case kGTOType_S: @@ -2828,7 +2861,8 @@ MoleculeGetGaussianComponentInfo(Molecule *mol, Int comp_idx, Int *outAtomIdx, c break; case kGTOType_D5: outLabel[0] = 'D'; - strcpy(outLabel + 1, type_d5[comp_idx]); + strncpy(outLabel + 1, type_d5[comp_idx], 30); + outLabel[31] = 0; break; case kGTOType_F: outLabel[0] = 'F'; @@ -2837,19 +2871,30 @@ MoleculeGetGaussianComponentInfo(Molecule *mol, Int comp_idx, Int *outAtomIdx, c break; case kGTOType_F7: outLabel[0] = 'F'; - strcpy(outLabel + 1, type_f7[comp_idx]); + strncpy(outLabel + 1, type_f7[comp_idx], 30); + outLabel[31] = 0; break; case kGTOType_G: outLabel[0] = 'G'; - strcpy(outLabel + 1, type_g[comp_idx]); + strncpy(outLabel + 1, type_g[comp_idx], 30); + outLabel[31] = 0; break; case kGTOType_G9: outLabel[0] = 'G'; - strcpy(outLabel + 1, type_g9[comp_idx]); + strncpy(outLabel + 1, type_g9[comp_idx], 30); + outLabel[31] = 0; break; default: return -3; /* Unsupported orbital type (internal error) */ } + if (shellp->add_exp > 0) { + /* Additional exponent (JANPA extension): like "s*r2", "dxx-yy*r4", etc. */ + int len = strlen(outLabel); + if (len < 28) { + snprintf(outLabel + len, 32 - len, "*r%d", shellp->add_exp); + } + outLabel[31] = 0; + } return 0; } } @@ -4770,7 +4815,7 @@ MoleculeWriteToMbsfFile(Molecule *mp, const char *fname, char **errbuf) ShellInfo *sp; PrimInfo *pp; fprintf(fp, "!:gaussian_primitives\n"); - fprintf(fp, "! sym nprims a_idx; A C Csp\n"); + fprintf(fp, "! sym nprims a_idx [add_exp]; A C Csp\n"); for (i = 0, sp = mp->bset->shells; i < mp->bset->nshells; i++, sp++) { switch (sp->sym) { case kGTOType_S: p = "S"; break; @@ -4784,7 +4829,10 @@ MoleculeWriteToMbsfFile(Molecule *mp, const char *fname, char **errbuf) case kGTOType_G9: p = "G9"; break; default: snprintf(bufs[0], 8, "X%d", sp->sym); p = bufs[0]; break; } - fprintf(fp, "%s %d %d\n", p, sp->nprim, sp->a_idx); + if (sp->add_exp == 0) + fprintf(fp, "%s %d %d\n", p, sp->nprim, sp->a_idx); + else + fprintf(fp, "%s %d %d %d\n", p, sp->nprim, sp->a_idx, sp->add_exp); pp = mp->bset->priminfos + sp->p_idx; for (j = 0; j < sp->nprim; j++, pp++) { fprintf(fp, "%.18g %.18g %.18g\n", pp->A, pp->C, pp->Csp); @@ -4843,10 +4891,20 @@ MoleculeWriteToMbsfFile(Molecule *mp, const char *fname, char **errbuf) /* Plug-in in the Ruby world */ { char *outMessage; + /* Save NBO information */ + if (MolActionCreateAndPerform(mp, SCRIPT_ACTION(";s"), + "proc { nbo2msbfstring rescue \"Plug-in error: #{$!.to_s}\" }", &outMessage) == 0) { + if (strncmp(outMessage, "Plug-in error", 13) == 0) { + s_append_asprintf(errbuf, "%s", outMessage); + } + fputs(outMessage, fp); + free(outMessage); + } + /* Other Plug-in */ if (MolActionCreateAndPerform(mp, SCRIPT_ACTION(";s"), "proc { savembsf_plugin rescue \"Plug-in error: #{$!.to_s}\" }", &outMessage) == 0) { if (outMessage[0] != 0) { - if (strncmp(outMessage, "Plug-in", 7) == 0) { + if (strncmp(outMessage, "Plug-in error", 13) == 0) { s_append_asprintf(errbuf, "%s", outMessage); } else { fprintf(fp, "%s\n", outMessage); diff --git a/MolLib/Molecule.h b/MolLib/Molecule.h index b7da244..3edd403 100755 --- a/MolLib/Molecule.h +++ b/MolLib/Molecule.h @@ -414,7 +414,7 @@ void MoleculeExchange(Molecule *mp1, Molecule *mp2); int MoleculeAddGaussianOrbitalShell(Molecule *mol, Int a_idx, Int sym, Int nprims, Int add_exp); int MoleculeAddGaussianPrimitiveCoefficients(Molecule *mol, Double exponent, Double contraction, Double contraction_sp); -int MoleculeGetGaussianComponentInfo(Molecule *mol, Int comp_idx, Int *outAtomIdx, char *outLabel, Int *outShellIdx); +int MoleculeGetGaussianComponentInfo(Molecule *mol, Int comp_idx, Int *outAtomIdx, char outLabel[32], Int *outShellIdx); int MoleculeSetMOCoefficients(Molecule *mol, Int idx, Double energy, Int ncomps, Double *coeffs); int MoleculeGetMOCoefficients(Molecule *mol, Int idx, Double *energy, Int *ncoeffs, Double **coeffs); int MoleculeSetMOInfo(Molecule *mol, Int rflag, Int ne_alpha, Int ne_beta); diff --git a/Scripts/loadsave.rb b/Scripts/loadsave.rb index 738beb2..fc03f43 100755 --- a/Scripts/loadsave.rb +++ b/Scripts/loadsave.rb @@ -817,6 +817,7 @@ class Molecule # and load from it (i.e. use the basis set converted by molden2molden) def sub_load_janpa_log(inppath) begin + # See also: MoleculeGetGaussianComponentInfo() in Molecule.c m2name_p = {0=>"x", 1=>"y", -1=>"z"} m2name_d = {0=>"zz-rr", 1=>"xz", -1=>"yz", 2=>"xx-yy", -2=>"xy"} m2name_f = {0=>"z3-zr2", 1=>"xz2-xr2", -1=>"yz2-yr2", 2=>"x2z-y2z", -2=>"xyz", 3=>"x3-xy2", -3=>"x2y-y3"} @@ -1208,6 +1209,119 @@ class Molecule end end + # Convert @nbo info to an msbf string (multiline) + # !:nbo + # [XXX] (NAO, LHO, etc.) + # nn (number of components) + # (nao_labels)*nn, one per line + # XXX n + # (%.18g)*nn, at most 6 per line + def nbo2msbfstring + unless @nbo + return "" + end + keys = @nbo.keys.grep(/AO\/\w+/) + s = "!:nbo\n" + keys.each { |k| + k =~ /AO\/(\w+)/ + key = $1 + labels = @nbo[key + "_L"] + m = @nbo[k] + nc = m.column_size + s += "[#{key}]\n#{nc}\n" + nc.times { |i| + l = (labels ? labels[i] : "") + s += "#{key} #{i+1} #{l}\n" + nc.times { |j| + s += sprintf("%.18g%s", m[i, j], ((j == nc - 1 || j % 6 == 5) ? "\n" : " ")) + } + } + } + s += "\n" + s + end + + # Read @nbo info from a multiline string and set to @nbo + def mbsfstring2nbo(s, first_lineno) + h = Hash.new + lineno = first_lineno - 1 + errmsg = "Error reading NBO section: " + key = nil + nc = nil + labels = nil + mo_matrix = nil + mo = nil + s.each_line { |ln| + lineno += 1 + next if lineno == first_lineno + ln.chomp! + if key == nil + if ln =~ /\[(\w+)\]/ + key = $1 + else + return errmsg + "keyword (like NBO, NHO, ...) is expected at line #{lineno}" + end + next + end + if nc == nil + nc = ln.to_i + labels = nil + mo_matrix = [] + mo = [] + next + end + if ln[0, key.length] == key + if mo == nil + return errmsg + "number of components is missing" + end + if mo.length > 0 + return errmsg + "too few coefficients at line #{lineno}" + end + ln =~ /^(\w+) +(\d+) *(.*)$/ + l = $3 + if l != "" + labels ||= [] + labels[mo_matrix.length] = l.strip + end + next + end + m = ln.split + begin + m = m.map { |c| Float(c) } + rescue + return errmsg + "cannot convert to number at line #{lineno}" + end + mo += m + if mo.length > nc + return errmsg + "too many coefficients at line #{lineno}" + end + if mo.length == nc + mo_matrix.push(mo) + mo = [] + if mo_matrix.length == nc + # All components are correctly read + if labels + # Set the label if not specified + nc.times { |i| + if !labels[i] || labels[i] == "" + labels[i] = "#{key}#{i+1}" + end + } + h["#{key}_L"] = labels + end + h["AO/#{key}"] = LAMatrix.new(mo_matrix) + mo = nil + mo_matrix = nil + labels = nil + key = nil + nc = nil + end + end + } # end each_line + @nbo = h + return "" + end + def loadout(filename) retval = false fp = open(filename, "rb") diff --git a/wxSources/MyApp.cpp b/wxSources/MyApp.cpp index ab495a9..1cdab83 100755 --- a/wxSources/MyApp.cpp +++ b/wxSources/MyApp.cpp @@ -1465,7 +1465,7 @@ MyApp::CallSubProcess(const char **argv, const char *procname, int (*callback)(v pid = ::wxExecute(argv[0], flag, m_process); } else { // Array of arguments - pid = ::wxExecute(argv, flag, m_process); + pid = ::wxExecuteArgv(argv, flag, m_process); } if (pid == 0) { if (progress_panel) @@ -2411,7 +2411,7 @@ void MyAppCallback_endUndoGrouping(void) int MyAppCallback_callSubProcess(const char **argv, const char *procname, int (*callback)(void *), void *callback_data, FILE *output, FILE *errout, int *exitstatus_p, int *pid_p) { if (!gUseGUI) - return ::wxExecute(argv, wxEXEC_SYNC | wxEXEC_HIDE_CONSOLE); + return ::wxExecuteArgv(argv, wxEXEC_SYNC | wxEXEC_HIDE_CONSOLE, NULL); else return wxGetApp().CallSubProcess(argv, procname, callback, callback_data, output, errout, exitstatus_p, pid_p); } diff --git a/wxSources/MyApp.h b/wxSources/MyApp.h index df27e1e..3052287 100755 --- a/wxSources/MyApp.h +++ b/wxSources/MyApp.h @@ -175,6 +175,11 @@ protected: wxMemoryBuffer m_stdin; }; +#if wxCHECK_VERSION(3,1,0) +#define wxExecuteArgv(_argv, _flags, _process) wxExecute(_argv, _flags, _process) +#else +#define wxExecuteArgv(_argv, _flags, _process) wxExecute((char **)(_argv), _flags, _process) +#endif // Define a new application class MyApp: public wxApp diff --git a/wxSources/MyDocument.cpp b/wxSources/MyDocument.cpp index 1bbc49f..b4ad7b2 100755 --- a/wxSources/MyDocument.cpp +++ b/wxSources/MyDocument.cpp @@ -230,7 +230,10 @@ MyDocument::DoOpenDocument(const wxString& file) return false; } - /* Does this document have multiple representation of molecules? */ + if (gLoadSaveErrorMessage != NULL) + MyAppCallback_showScriptMessage("On loading %s:\n%s\n", p, gLoadSaveErrorMessage); + + /* Does this document have multiple representation of molecules? */ if (MolActionCreateAndPerform(newmol, SCRIPT_ACTION(";i"), "lambda { @aux_mols ? @aux_mols.count : 0 }", &len) == 0 && len > 0) { wxCommandEvent myEvent(MyDocumentEvent, MyDocumentEvent_openAuxiliaryDocuments); wxPostEvent(this, myEvent); @@ -1151,7 +1154,7 @@ MyDocument::RunSubProcess(const char **argv, int (*callback)(Molecule *, int), i subProcessPID = ::wxExecute(argv[0], wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER, subProcess); } else { // Array of arguments - subProcessPID = ::wxExecute(argv, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER, subProcess); + subProcessPID = ::wxExecuteArgv(argv, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER, subProcess); } if (subProcessPID == 0) { subProcess->Detach();