UNPKG

biojs-vis-pdbviewer

Version:

A BioJS 2.0 component to view protein structures

352 lines (347 loc) 12.8 kB
Clazz.declarePackage ("J.geodesic"); Clazz.load (["J.api.JmolEnvCalc", "JU.P3", "J.atomdata.AtomData"], "J.geodesic.EnvelopeCalculation", ["JU.AU", "$.BS", "$.V3", "J.atomdata.RadiusData", "JU.BSUtil", "$.Geodesic", "$.Normix"], function () { c$ = Clazz.decorateAsClass (function () { this.geodesicMap = null; this.mapT = null; this.mads = null; this.atomData = null; this.vwr = null; this.ac = 0; this.maxRadius = 0; this.modelZeroBased = false; this.disregardNeighbors = false; this.bsMySelected = null; this.dotsConvexMaps = null; this.dotsConvexMax = 0; this.geodesicCount = 0; this.bsSurface = null; this.radiusP = 0; this.diameterP = 0; this.bsTemp = null; this.bsIgnore = null; this.onlySelectedDots = false; this.isSurface = false; this.multiModel = false; this.currentPoints = null; this.indexI = 0; this.centerI = null; this.radiusI = 0; this.radiiIP2 = 0; this.pointT = null; this.centerT = null; this.vertexTest = null; this.neighborCount = 0; this.neighborIndices = null; this.neighborCenters = null; this.neighborPlusProbeRadii2 = null; this.neighborRadii2 = null; Clazz.instantialize (this, arguments); }, J.geodesic, "EnvelopeCalculation", null, J.api.JmolEnvCalc); Clazz.prepareFields (c$, function () { this.atomData = new J.atomdata.AtomData (); this.pointT = new JU.P3 (); this.vertexTest = new Array (12); { for (var i = 0; i < 12; i++) this.vertexTest[i] = new JU.P3 (); }this.neighborIndices = Clazz.newIntArray (16, 0); this.neighborCenters = new Array (16); this.neighborPlusProbeRadii2 = Clazz.newFloatArray (16, 0); this.neighborRadii2 = Clazz.newFloatArray (16, 0); }); Clazz.makeConstructor (c$, function () { }); Clazz.overrideMethod (c$, "set", function (vwr, ac, mads) { this.vwr = vwr; this.ac = ac; this.mads = mads; this.geodesicCount = JU.Geodesic.getVertexCount (3); this.geodesicMap = JU.BS.newN (this.geodesicCount); this.mapT = JU.BS.newN (this.geodesicCount); J.geodesic.EnvelopeCalculation.EMPTY_SET = JU.BSUtil.emptySet; return this; }, "J.atomdata.AtomDataServer,~N,~A"); Clazz.defineMethod (c$, "getDotsConvexMaps", function () { return this.dotsConvexMaps; }); Clazz.defineMethod (c$, "getDotsConvexMax", function () { return this.dotsConvexMax; }); Clazz.defineMethod (c$, "allocDotsConvexMaps", function (max) { if (this.dotsConvexMax >= max) return; this.dotsConvexMax = max; this.dotsConvexMaps = new Array (max); }, "~N"); Clazz.overrideMethod (c$, "getBsSurfaceClone", function () { return JU.BSUtil.copy (this.bsSurface); }); Clazz.defineMethod (c$, "setMads", function (mads) { this.mads = mads; }, "~A"); Clazz.defineMethod (c$, "setFromBits", function (index, bs) { this.geodesicMap.setBits (0, this.geodesicCount); for (var iDot = this.geodesicCount; --iDot >= 0; ) if (!bs.get (iDot)) this.geodesicMap.clear (iDot); if (this.dotsConvexMaps == null) this.dotsConvexMaps = new Array (this.ac); var map; if (this.geodesicMap.isEmpty ()) map = J.geodesic.EnvelopeCalculation.EMPTY_SET; else map = JU.BSUtil.copy (this.geodesicMap); if (index >= this.dotsConvexMaps.length) return; this.dotsConvexMaps[index] = map; this.dotsConvexMax = Math.max (this.dotsConvexMax, index); }, "~N,JU.BS"); Clazz.defineMethod (c$, "newSet", function () { this.dotsConvexMax = 0; this.dotsConvexMaps = null; this.radiusP = this.diameterP = 0; this.mads = null; }); Clazz.defineMethod (c$, "reCalculate", function (bs, m) { if (this.atomData.radiusData != null) { this.calculate (null, this.maxRadius, bs, this.bsIgnore, this.disregardNeighbors, this.onlySelectedDots, this.isSurface, this.multiModel); return; }if (this.dotsConvexMaps == null || this.dotsConvexMax == 0) return; var pt = new JU.V3 (); if (this.bsTemp == null) this.bsTemp = JU.Normix.newVertexBitSet (); for (var i = bs.nextSetBit (0); i >= 0; i = bs.nextSetBit (i + 1)) { if (i >= this.dotsConvexMax) return; var map = this.dotsConvexMaps[i]; if (map == null || map.isEmpty ()) continue; var bsNew = new JU.BS (); for (var j = map.nextSetBit (0); j >= 0; j = map.nextSetBit (j + 1)) { pt.setT (JU.Geodesic.getVertexVector (j)); m.rotate (pt); bsNew.set (JU.Normix.getNormixV (pt, this.bsTemp)); } this.dotsConvexMaps[i] = bsNew; } }, "JU.BS,JU.M3"); Clazz.overrideMethod (c$, "calculate", function (rd, maxRadius, bsSelected, bsIgnore, disregardNeighbors, onlySelectedDots, isSurface, multiModel) { if (rd == null) { rd = this.atomData.radiusData; if (rd == null) return; } else { this.atomData.radiusData = rd; this.bsIgnore = bsIgnore; this.onlySelectedDots = onlySelectedDots; this.multiModel = multiModel; this.isSurface = isSurface; }if (rd.value == 3.4028235E38) rd.value = 3.0; this.atomData.modelIndex = (multiModel ? -1 : 0); this.modelZeroBased = !multiModel; this.vwr.fillAtomData (this.atomData, 1 | (this.mads == null ? 2 : 0)); this.ac = this.atomData.ac; if (this.mads != null) for (var i = 0; i < this.ac; i++) this.atomData.atomRadius[i] = this.mads[i] / 1000; this.bsMySelected = (onlySelectedDots && bsSelected != null ? JU.BSUtil.copy (bsSelected) : bsIgnore != null ? JU.BSUtil.setAll (this.ac) : null); JU.BSUtil.andNot (this.bsMySelected, bsIgnore); this.disregardNeighbors = disregardNeighbors; this.maxRadius = maxRadius; this.bsSurface = new JU.BS (); var isAll = (bsSelected == null); var iter = this.vwr.getSelectedAtomIterator (this.bsMySelected, false, this.modelZeroBased, false); var i0 = (isAll ? this.ac - 1 : bsSelected.nextSetBit (0)); for (var i = i0; i >= 0; i = (isAll ? i - 1 : bsSelected.nextSetBit (i + 1))) if (bsIgnore == null || !bsIgnore.get (i)) { this.setAtomI (i); this.getNeighbors (iter); this.calcConvexMap (isSurface); } iter.release (); this.currentPoints = null; this.setDotsConvexMax (); }, "J.atomdata.RadiusData,~N,JU.BS,JU.BS,~B,~B,~B,~B"); Clazz.defineMethod (c$, "getRadius", function (atomIndex) { return this.atomData.atomRadius[atomIndex]; }, "~N"); Clazz.overrideMethod (c$, "getPoints", function () { if (this.dotsConvexMaps == null) { this.calculate ( new J.atomdata.RadiusData (null, 3.0, J.atomdata.RadiusData.EnumType.ABSOLUTE, null), 3.4028235E38, this.bsMySelected, null, false, false, false, false); }if (this.currentPoints != null) return this.currentPoints; var nPoints = 0; var dotCount = 42; for (var i = this.dotsConvexMax; --i >= 0; ) if (this.dotsConvexMaps[i] != null) nPoints += this.dotsConvexMaps[i].cardinalityN (dotCount); var points = new Array (nPoints); if (nPoints == 0) return points; nPoints = 0; for (var i = this.dotsConvexMax; --i >= 0; ) if (this.dotsConvexMaps[i] != null) { var iDot = this.dotsConvexMaps[i].size (); if (iDot > dotCount) iDot = dotCount; while (--iDot >= 0) if (this.dotsConvexMaps[i].get (iDot)) { var pt = new JU.P3 (); pt.scaleAdd2 (this.atomData.atomRadius[i], JU.Geodesic.getVertexVector (iDot), this.atomData.atomXyz[i]); points[nPoints++] = pt; } } this.currentPoints = points; return points; }); Clazz.defineMethod (c$, "setDotsConvexMax", function () { if (this.dotsConvexMaps == null) this.dotsConvexMax = 0; else { var i; for (i = this.ac; --i >= 0 && this.dotsConvexMaps[i] == null; ) { } this.dotsConvexMax = i + 1; }}); Clazz.defineMethod (c$, "getAppropriateRadius", function (atomIndex) { return (this.mads != null ? (atomIndex >= this.mads.length ? 0 : this.mads[atomIndex] / 1000) : this.atomData.atomRadius[atomIndex]); }, "~N"); Clazz.defineMethod (c$, "setAtomI", function (indexI) { this.indexI = indexI; this.centerI = this.atomData.atomXyz[indexI]; this.radiusI = this.atomData.atomRadius[indexI]; this.radiiIP2 = this.radiusI + this.radiusP; this.radiiIP2 *= this.radiiIP2; }, "~N"); Clazz.defineMethod (c$, "calcConvexMap", function (isSurface) { if (this.dotsConvexMaps == null) this.dotsConvexMaps = new Array (this.ac); this.calcConvexBits (); var map; if (this.geodesicMap.isEmpty ()) map = J.geodesic.EnvelopeCalculation.EMPTY_SET; else { this.bsSurface.set (this.indexI); if (isSurface) { this.addIncompleteFaces (this.geodesicMap); this.addIncompleteFaces (this.geodesicMap); }map = JU.BSUtil.copy (this.geodesicMap); }this.dotsConvexMaps[this.indexI] = map; }, "~B"); Clazz.defineMethod (c$, "addIncompleteFaces", function (points) { this.mapT.clearAll (); var faces = JU.Geodesic.getFaceVertexes (3); var len = faces.length; var maxPt = -1; for (var f = 0; f < len; ) { var p1 = faces[f++]; var p2 = faces[f++]; var p3 = faces[f++]; var ok1 = points.get (p1); var ok2 = points.get (p2); var ok3 = points.get (p3); if (!(ok1 || ok2 || ok3) || ok1 && ok2 && ok3) continue; if (!ok1) { this.mapT.set (p1); if (maxPt < p1) maxPt = p1; }if (!ok2) { this.mapT.set (p2); if (maxPt < p2) maxPt = p2; }if (!ok3) { this.mapT.set (p3); if (maxPt < p3) maxPt = p3; }} for (var i = 0; i <= maxPt; i++) { if (this.mapT.get (i)) points.set (i); } }, "JU.BS"); Clazz.defineMethod (c$, "calcConvexBits", function () { this.geodesicMap.setBits (0, this.geodesicCount); var combinedRadii = this.radiusI + this.radiusP; if (this.neighborCount == 0) return; var faceTest; var p1; var p2; var p3; var faces = JU.Geodesic.getFaceVertexes (3); var p4 = J.geodesic.EnvelopeCalculation.power4[2]; var ok1; var ok2; var ok3; this.mapT.clearAll (); for (var i = 0; i < 12; i++) { this.vertexTest[i].scaleAdd2 (combinedRadii, JU.Geodesic.getVertexVector (i), this.centerI); } for (var f = 0; f < 20; f++) { faceTest = 0; p1 = faces[3 * p4 * (4 * f + 0)]; p2 = faces[3 * p4 * (4 * f + 1)]; p3 = faces[3 * p4 * (4 * f + 2)]; for (var j = 0; j < this.neighborCount; j++) { var maxDist = this.neighborPlusProbeRadii2[j]; this.centerT = this.neighborCenters[j]; ok1 = this.vertexTest[p1].distanceSquared (this.centerT) >= maxDist; ok2 = this.vertexTest[p2].distanceSquared (this.centerT) >= maxDist; ok3 = this.vertexTest[p3].distanceSquared (this.centerT) >= maxDist; if (!ok1) this.geodesicMap.clear (p1); if (!ok2) this.geodesicMap.clear (p2); if (!ok3) this.geodesicMap.clear (p3); if (!ok1 && !ok2 && !ok3) { faceTest = -1; break; }} var kFirst = f * 12 * p4; var kLast = kFirst + 12 * p4; for (var k = kFirst; k < kLast; k++) { var vect = faces[k]; if (this.mapT.get (vect) || !this.geodesicMap.get (vect)) continue; switch (faceTest) { case -1: this.geodesicMap.clear (vect); break; case 0: for (var j = 0; j < this.neighborCount; j++) { var maxDist = this.neighborPlusProbeRadii2[j]; this.centerT = this.neighborCenters[j]; this.pointT.scaleAdd2 (combinedRadii, JU.Geodesic.getVertexVector (vect), this.centerI); if (this.pointT.distanceSquared (this.centerT) < maxDist) this.geodesicMap.clear (vect); } break; case 1: } this.mapT.set (vect); } } }); Clazz.defineMethod (c$, "getNeighbors", function (iter) { this.neighborCount = 0; if (this.disregardNeighbors) return null; this.vwr.setIteratorForAtom (iter, this.indexI, this.radiusI + this.diameterP + this.maxRadius); while (iter.hasNext ()) { var indexN = iter.next (); var neighborRadius = this.atomData.atomRadius[indexN]; if (this.centerI.distance (this.atomData.atomXyz[indexN]) > this.radiusI + this.radiusP + this.radiusP + neighborRadius) continue; if (this.neighborCount == this.neighborIndices.length) { this.neighborIndices = JU.AU.doubleLengthI (this.neighborIndices); this.neighborCenters = JU.AU.doubleLength (this.neighborCenters); this.neighborPlusProbeRadii2 = JU.AU.doubleLengthF (this.neighborPlusProbeRadii2); this.neighborRadii2 = JU.AU.doubleLengthF (this.neighborRadii2); }this.neighborCenters[this.neighborCount] = this.atomData.atomXyz[indexN]; this.neighborIndices[this.neighborCount] = indexN; var r = neighborRadius + this.radiusP; this.neighborPlusProbeRadii2[this.neighborCount] = r * r; this.neighborRadii2[this.neighborCount] = neighborRadius * neighborRadius; ++this.neighborCount; } return iter; }, "J.api.AtomIndexIterator"); Clazz.defineMethod (c$, "deleteAtoms", function (firstAtomDeleted, nAtomsDeleted) { this.dotsConvexMaps = JU.AU.deleteElements (this.dotsConvexMaps, firstAtomDeleted, nAtomsDeleted); this.dotsConvexMax = this.dotsConvexMaps.length; if (this.mads != null) this.mads = JU.AU.deleteElements (this.mads, firstAtomDeleted, nAtomsDeleted); this.atomData.atomRadius = JU.AU.deleteElements (this.atomData.atomRadius, firstAtomDeleted, nAtomsDeleted); this.atomData.atomXyz = JU.AU.deleteElements (this.atomData.atomXyz, firstAtomDeleted, nAtomsDeleted); this.atomData.ac -= nAtomsDeleted; this.ac = this.atomData.ac; }, "~N,~N"); Clazz.defineStatics (c$, "EMPTY_SET", null); Clazz.defineStatics (c$, "power4", [1, 4, 16, 64, 256]); });