Clazz.declarePackage("J.adapter.readers.quantum");
Clazz.load(["J.adapter.readers.quantum.MopacSlaterReader", "JU.BS"], "J.adapter.readers.quantum.MoldenReader", ["java.util.Arrays", "$.Hashtable", "JU.AU", "$.Lst", "$.PT", "J.adapter.readers.quantum.BasisFunctionReader", "JU.Logger"], function(){
var c$ = Clazz.decorateAsClass(function(){
this.loadGeometries = false;
this.loadVibrations = false;
this.vibOnly = false;
this.optOnly = false;
this.doSort = true;
this.orbitalType = "";
this.modelAtomCount = 0;
this.lineBuffer = null;
this.bsAtomOK = null;
this.bsBadIndex = null;
this.nSPDF = null;
this.haveEnergy = true;
this.ptLineBuf = 0;
this.bufLen = 0;
Clazz.instantialize(this, arguments);}, J.adapter.readers.quantum, "MoldenReader", J.adapter.readers.quantum.MopacSlaterReader);
Clazz.prepareFields (c$, function(){
this.bsAtomOK =  new JU.BS();
this.bsBadIndex =  new JU.BS();
});
Clazz.overrideMethod(c$, "initializeReader", 
function(){
this.vibOnly = this.checkFilterKey("VIBONLY");
this.optOnly = this.checkFilterKey("OPTONLY");
this.doSort = !this.checkFilterKey("NOSORT");
this.loadGeometries = !this.vibOnly && this.desiredVibrationNumber < 0 && !this.checkFilterKey("NOOPT");
this.loadVibrations = !this.optOnly && this.desiredModelNumber < 0 && !this.checkFilterKey("NOVIB");
if (this.checkFilterKey("ALPHA")) this.filter = "alpha";
 else if (this.checkFilterKey("BETA")) this.filter = "beta";
 else this.filter = this.getFilter("SYM=");
});
Clazz.overrideMethod(c$, "checkLine", 
function(){
if (!this.line.contains("[")) return true;
this.line = this.line.toUpperCase().trim();
if (!this.line.startsWith("[")) return true;
JU.Logger.info(this.line);
if (this.line.indexOf("[ATOMS]") == 0) {
this.readAtoms();
this.modelAtomCount = this.asc.getAtomSetAtomCount(0);
if (this.asc.atomSetCount == 1 && this.moData != null) this.finalizeMOData(this.moData);
return false;
}if (this.line.indexOf("[GTO]") == 0) return this.readGaussianBasis();
if (this.line.indexOf("[STO]") == 0) return this.readSlaterBasis();
if (this.line.indexOf("[MO]") == 0) return (!this.doReadMolecularOrbitals || this.readMolecularOrbitals());
if (this.line.indexOf("[FREQ]") == 0) return (!this.loadVibrations || this.readFreqsAndModes());
if (this.line.indexOf("[GEOCONV]") == 0) return (!this.loadGeometries || this.readGeometryOptimization());
if (this.checkOrbitalType(this.line)) return true;
if (this.checkSymmetry()) return false;
return true;
});
Clazz.defineMethod(c$, "checkSymmetry", 
function(){
if (this.line.startsWith("[SPACEGROUP]")) {
this.setSpaceGroupName(this.rd());
this.rd();
return true;
}if (this.line.startsWith("[OPERATORS]")) {
while (this.rd() != null && this.line.indexOf("[") < 0) if (this.line.length > 0) {
JU.Logger.info("adding operator " + this.line);
this.setSymmetryOperator(this.line);
}
return true;
}if (this.line.startsWith("[CELL]")) {
this.rd();
JU.Logger.info("setting cell dimensions " + this.line);
this.next[0] = 0;
for (var i = 0; i < 6; i++) this.setUnitCellItem(i, this.parseFloat());

this.rd();
return true;
}if (this.line.startsWith("[CELLAXES]")) {
var f =  Clazz.newFloatArray (9, 0);
this.fillFloatArray(null, 0, f);
this.addExplicitLatticeVector(0, f, 0);
this.addExplicitLatticeVector(1, f, 3);
this.addExplicitLatticeVector(2, f, 6);
return true;
}return false;
});
Clazz.overrideMethod(c$, "finalizeSubclassReader", 
function(){
if (!this.bsBadIndex.isEmpty()) try {
var ilast = 0;
var atoms = this.asc.atoms;
var nAtoms = this.asc.ac;
this.bsAtomOK.set(nAtoms);
var n = this.shells.size();
for (var i = 0; i < n; i++) {
var iatom = this.shells.get(i)[0];
if (iatom != 2147483647) {
ilast = atoms[iatom - 1].elementNumber;
continue;
}for (var j = this.bsAtomOK.nextClearBit(0); j >= 0; j = this.bsAtomOK.nextClearBit(j + 1)) {
if (atoms[j].elementNumber == ilast) {
this.shells.get(i)[0] = j + 1;
JU.Logger.info("MoldenReader assigning shells starting with " + i + " for ** to atom " + (j + 1) + " z " + ilast);
for (; ++i < n && !this.bsBadIndex.get(i) && this.shells.get(i)[0] == 2147483647; ) this.shells.get(i)[0] = j + 1;

i--;
this.bsAtomOK.set(j);
break;
}}
}
} catch (e) {
if (Clazz.exceptionOf(e, Exception)){
JU.Logger.error("Molden reader could not assign shells -- abandoning MOs");
this.asc.setCurrentModelInfo("moData", null);
} else {
throw e;
}
}
this.finalizeReaderASCR();
});
Clazz.defineMethod(c$, "readAtoms", 
function(){
var coordUnit = JU.PT.getTokens(this.line.$replace(']', ' '))[1];
var isFractional = (coordUnit.indexOf("FRACTIONAL") >= 0);
var isAU = (!isFractional && coordUnit.indexOf("ANGS") < 0);
if (isAU && coordUnit.indexOf("AU") < 0) JU.Logger.error("Molden atom line does not indicate units ANGS, AU, or FRACTIONAL -- AU assumed: " + this.line);
this.setFractionalCoordinates(isFractional);
var f = (isAU ? 0.5291772 : 1);
while (this.rd() != null && this.line.indexOf('[') < 0) {
var tokens = this.getTokens();
if (tokens.length < 6) continue;
var atom = this.setAtomCoordScaled(null, tokens, 3, f);
atom.atomName = tokens[0];
atom.elementNumber = this.parseIntStr(tokens[2]);
}
});
Clazz.defineMethod(c$, "readSlaterBasis", 
function(){
var stoFactor = (this.line.indexOf("ANGS") >= 0 ? 0.5291772 : 1);
this.scaleSlaters = (this.line.indexOf("MOPAC") >= 0);
this.nCoef = 0;
while (this.rd() != null && this.line.indexOf("[") < 0) {
var tokens = this.getTokens();
if (tokens.length < 7) continue;
var zeta = this.parseFloatStr(tokens[5]) * stoFactor;
this.addSlater(this.parseIntStr(tokens[0]), this.parseIntStr(tokens[1]), this.parseIntStr(tokens[2]), this.parseIntStr(tokens[3]), this.parseIntStr(tokens[4]), zeta, this.parseFloatStr(tokens[6]));
this.nCoef++;
}
this.setSlaters(false);
return false;
});
Clazz.defineMethod(c$, "readGaussianBasis", 
function(){
this.shells =  new JU.Lst();
var gdata =  new JU.Lst();
var atomIndex = 0;
var gaussianPtr = 0;
this.nCoef = 0;
this.nSPDF =  Clazz.newIntArray (12, 0);
this.discardLinesUntilNonBlank();
while (this.line != null && !((this.line = this.line.trim()).length == 0 || this.line.charAt(0) == '[')) {
var tokens = this.getTokens();
atomIndex = this.parseIntStr(tokens[0]) - 1;
if (atomIndex == 2147483647) {
this.bsBadIndex.set(this.shells.size());
} else {
this.bsAtomOK.set(atomIndex);
}while (this.rd() != null && (this.line = this.line.trim()).length > 0 && this.line.charAt(0) != '[') {
tokens = this.getTokens();
var shellLabel = tokens[0].toUpperCase();
var type = J.adapter.readers.quantum.BasisFunctionReader.getQuantumShellTagID(shellLabel);
var nPrimitives = this.parseIntStr(tokens[1]);
var slater =  Clazz.newIntArray (4, 0);
this.nSPDF[type]++;
slater[0] = atomIndex + 1;
slater[1] = type;
slater[2] = gaussianPtr + 1;
slater[3] = nPrimitives;
var n = this.getDfCoefMaps()[type].length;
if (!this.haveCoefs) {
System.out.println(this.nCoef + " adding " + n + " coefficients type " + J.adapter.readers.quantum.BasisFunctionReader.getQuantumShellTag(type) + " for atom " + atomIndex);
this.nCoef += n;
}for (var ip = nPrimitives; --ip >= 0; ) {
var primTokens = JU.PT.getTokens(this.rd());
var nTokens = primTokens.length;
var orbData =  Clazz.newFloatArray (nTokens, 0);
for (var d = 0; d < nTokens; d++) orbData[d] = this.parseFloatStr(primTokens[d]);

gdata.addLast(orbData);
gaussianPtr++;
}
this.shells.addLast(slater);
}
if (this.line.length > 0 && this.line.charAt(0) == '[') break;
this.rd();
}
var garray = JU.AU.newFloat2(gaussianPtr);
for (var i = 0; i < gaussianPtr; i++) {
garray[i] = gdata.get(i);
}
this.moData.put("shells", this.shells);
this.moData.put("gaussians", garray);
JU.Logger.info(this.shells.size() + " slater shells read");
JU.Logger.info(garray.length + " gaussian primitives read");
this.asc.setCurrentModelInfo("moData", this.moData);
return false;
});
Clazz.defineMethod(c$, "readMolecularOrbitals", 
function(){
while (this.checkOrbitalType(this.rd())) {
}
if (this.orbitalType === "") {
this.createLineBuffer();
}this.fixOrbitalType();
JU.Logger.info(this.nCoef + " MO coefficients expected for orbital type " + this.orbitalType);
var tokens = this.getMoTokens(this.line);
while (tokens != null && tokens.length > 0 && tokens[0].indexOf('[') < 0) {
var mo =  new java.util.Hashtable();
var data =  new JU.Lst();
var energy = NaN;
var occupancy = NaN;
var symmetry = null;
var key;
while (this.parseIntStr(key = tokens[0]) == -2147483648) {
if (key.startsWith("Ene")) {
energy = this.parseFloatStr(tokens[1]);
} else if (key.startsWith("Occup")) {
occupancy = this.parseFloatStr(tokens[1]);
} else if (key.startsWith("Sym")) {
symmetry = tokens[1];
} else if (key.startsWith("Spin")) {
this.alphaBeta = tokens[1].toLowerCase();
}tokens = this.getMoTokens(null);
}
var pt = 0;
var offset = 0;
while (tokens != null && tokens.length > 0 && this.parseIntStr(tokens[0]) != -2147483648) {
if (tokens.length != 2) throw  new Exception("invalid MO coefficient specification");
var i = this.parseIntStr(tokens[0]);
if (pt == 0 && i == this.nCoef + 1 && "beta".equals(this.alphaBeta)) {
offset = -this.nCoef;
}i += offset;
while (i > ++pt) data.addLast("0");

data.addLast(tokens[1]);
tokens = this.getMoTokens(null);
}
if (this.orbitalType.equals("") && data.size() < this.nCoef) {
JU.Logger.info("too few orbital coefficients for 6D");
this.checkOrbitalType("[5D]");
}while (++pt <= this.nCoef) {
data.addLast("0");
}
var coefs =  Clazz.newFloatArray (this.nCoef, 0);
for (var i = data.size(); --i >= 0; ) coefs[i] = this.parseFloatStr(data.get(i));

var l = this.line;
this.line = "" + symmetry;
if (this.filterMO()) {
mo.put("coefficients", coefs);
if (Float.isNaN(energy)) {
this.haveEnergy = false;
} else {
mo.put("energy", Float.$valueOf(energy));
}if (!Float.isNaN(occupancy)) mo.put("occupancy", Float.$valueOf(occupancy));
if (symmetry != null) mo.put("symmetry", symmetry);
if (this.alphaBeta.length > 0) mo.put("type", this.alphaBeta);
this.setMO(mo);
if (this.debugging) {
JU.Logger.debug(coefs.length + " coefficients in MO " + this.orbitals.size());
}}this.line = l;
}
if (this.debugging) JU.Logger.debug("read " + this.orbitals.size() + " MOs");
this.setMOs("");
if (this.haveEnergy && this.doSort) this.sortMOs();
return false;
});
Clazz.defineMethod(c$, "rd", 
function(){
if (++this.ptLineBuf < this.bufLen) {
return this.line = this.lineBuffer.get(this.ptLineBuf);
}if (this.bufLen > 0) {
this.lineBuffer = null;
this.bufLen = -1;
return null;
}return Clazz.superCall(this, J.adapter.readers.quantum.MoldenReader, "rd", []);
});
Clazz.defineMethod(c$, "createLineBuffer", 
function(){
if (this.lineBuffer != null) return;
this.lineBuffer =  new JU.Lst();
var l0 = this.line;
while (Clazz.superCall(this, J.adapter.readers.quantum.MoldenReader, "rd", []) != null) {
if (!this.line.contains("[") || !this.checkOrbitalType(this.line)) {
this.lineBuffer.addLast(this.line);
}}
this.bufLen = this.lineBuffer.size();
this.ptLineBuf = -1;
this.line = l0;
});
Clazz.defineMethod(c$, "sortMOs", 
function(){
var list = this.orbitals.toArray( new Array(this.orbitals.size()));
java.util.Arrays.sort(list, Clazz.innerTypeInstance(J.adapter.readers.quantum.BasisFunctionReader.MOEnergySorter, this, null));
this.orbitals.clear();
for (var i = 0; i < list.length; i++) this.orbitals.addLast(list[i]);

});
Clazz.defineMethod(c$, "getMoTokens", 
function(line){
return (line == null && (line = this.rd()) == null ? null : JU.PT.getTokens(line.$replace('=', ' ')));
}, "~S");
Clazz.defineMethod(c$, "checkOrbitalType", 
function(line){
if (line.length > 3 && "5D 6D 7F 10 9G 15 11 21".indexOf(line.substring(1, 3)) >= 0) {
if (this.orbitalType.indexOf(line) >= 0) return true;
if (line.indexOf("G") >= 0 || line.indexOf("H") >= 0 || line.indexOf("I") >= 0) this.appendLoadNote("Unsupported orbital type ignored: " + line);
this.orbitalType += line;
JU.Logger.info("Orbital type set to " + this.orbitalType);
this.fixOrbitalType();
return true;
}return false;
}, "~S");
Clazz.defineMethod(c$, "fixOrbitalType", 
function(){
if (this.orbitalType.contains("5D")) {
this.fixSlaterTypes(4, 3);
this.fixSlaterTypes(6, 5);
this.fixSlaterTypes(8, 7);
this.fixSlaterTypes(10, 9);
}if (this.orbitalType.contains("10F")) {
this.fixSlaterTypes(5, 6);
this.fixSlaterTypes(7, 8);
this.fixSlaterTypes(9, 10);
}if (this.orbitalType.contains("15G")) {
this.fixSlaterTypes(7, 8);
this.fixSlaterTypes(9, 10);
}});
Clazz.defineMethod(c$, "readFreqsAndModes", 
function(){
var tokens;
var frequencies =  new JU.Lst();
while (this.rd() != null && this.line.indexOf('[') < 0) {
var f = this.getTokens()[0];
frequencies.addLast(f);
}
var nFreqs = frequencies.size();
this.skipTo("[FR-COORD]");
if (!this.vibOnly) this.readAtomSet("frequency base geometry", true, true);
this.skipTo("[FR-NORM-COORD]");
var haveVib = false;
for (var nFreq = 0; nFreq < nFreqs; nFreq++) {
this.skipTo("vibration");
this.doGetVibration(++this.vibrationNumber);
if (haveVib) this.asc.cloneLastAtomSet();
haveVib = true;
this.asc.setAtomSetFrequency(this.vibrationNumber, null, null, "" + Double.$valueOf(frequencies.get(nFreq)), null);
var i0 = this.asc.getLastAtomSetAtomIndex();
for (var i = 0; i < this.modelAtomCount; i++) {
tokens = JU.PT.getTokens(this.rd());
this.asc.addVibrationVector(i + i0, this.parseFloatStr(tokens[0]) * 0.5291772, this.parseFloatStr(tokens[1]) * 0.5291772, this.parseFloatStr(tokens[2]) * 0.5291772);
}
}
return true;
});
Clazz.defineMethod(c$, "readGeometryOptimization", 
function(){
var energies =  new JU.Lst();
this.rd();
while (this.rd() != null && this.line.indexOf("force") < 0) energies.addLast("" + Double.$valueOf(this.line.trim()));

this.skipTo("[GEOMETRIES] XYZ");
var nGeom = energies.size();
var firstModel = (this.optOnly || this.desiredModelNumber >= 0 ? 0 : 1);
this.modelNumber = firstModel;
var haveModel = false;
if (this.desiredModelNumber == 0 || this.desiredModelNumber == nGeom) this.desiredModelNumber = nGeom;
 else if (this.asc.atomSetCount > 0) this.finalizeMOData(this.moData);
for (var i = 0; i < nGeom; i++) {
this.readLines(2);
if (this.doGetModel(++this.modelNumber, null)) {
this.readAtomSet("Step " + (this.modelNumber - firstModel) + "/" + nGeom + ": " + energies.get(i), false, !this.optOnly || haveModel);
haveModel = true;
} else {
this.readLines(this.modelAtomCount);
}}
return true;
});
Clazz.defineMethod(c$, "skipTo", 
function(key){
key = key.toUpperCase();
if (this.line == null || !this.line.toUpperCase().contains(key)) while (this.rd() != null && this.line.toUpperCase().indexOf(key) < 0) {
}
}, "~S");
Clazz.defineMethod(c$, "readAtomSet", 
function(atomSetName, isBohr, asClone){
if (asClone && this.desiredModelNumber < 0) this.asc.cloneFirstAtomSet(0);
var f = (isBohr ? 0.5291772 : 1);
this.asc.setAtomSetName(atomSetName);
if (this.asc.ac == 0) {
while (this.rd() != null && this.line.indexOf('[') < 0) {
var tokens = this.getTokens();
if (tokens.length == 4) this.setAtomCoordScaled(null, tokens, 1, f).atomName = tokens[0];
}
this.modelAtomCount = this.asc.getLastAtomSetAtomCount();
return;
}var atoms = this.asc.atoms;
var i0 = this.asc.getLastAtomSetAtomIndex();
for (var i = 0; i < this.modelAtomCount; i++) this.setAtomCoordScaled(atoms[i + i0], JU.PT.getTokens(this.rd()), 1, f);

}, "~S,~B,~B");
});
;//5.0.1-v7 Mon Aug 17 10:07:10 MDT 2026
