angles = {
const results = []
const allDistances = []
const twistedAngles = []
const distWithinChain = []
for (const carbChains of chainData.results) {
const leadingVectors = leadingVector.filter(d => d.carbIndex === carbChains.carb.carbIndex)
const N = leadingVectors.length
if (N > params.minNumberOfChains) {
const rubs = allDataWithVectors.filter(d => d.reg === carbChains.carb.carbIndex)
for (let i = 0; i < N - 1; i++) {
const chain1 = leadingVectors[i].leadVector
const chain1Normed = math.dotDivide(chain1, math.norm(chain1))
const chainData = leadingVectors[i].chain
.map(d => rubs.find( r => r.tag === d))
.map(r => {
const pos = math.matrix([r.x, r.y, r.z])
const posUnit = math.dotDivide(pos, math.norm(pos))
const p = math.dot(pos, chain1Normed)
return {
...r,
p
}
})
.sort((a, b) => a.p - b.p)
.map(r => {
const narot = math.dot(chain1, r.vec) > 0 ? r.narot : -r.narot
return {
...carbChains.carb,
narot: narot < 0 ? (90 + (narot % 90) ) % 90 : narot % 90,
originalNarot: narot,
tag: r.tag,
p: r.p,
pos: math.matrix([r.x, r.y, r.z]),
vec: r.vec
}
})//
twistedAngles.push(chainData)
const distsInChain = []
for (let z = 0; z < chainData.length - 1; z++) {
const rub1Orientation = math.dotDivide(chainData[z].vec, math.norm(chainData[z].vec))
const rub2Orientation = math.dotDivide(chainData[z+1].vec, math.norm(chainData[z+1].vec))
const tmpBend = math.dot(rub1Orientation, rub2Orientation)
const bend = tmpBend > 0 ? tmpBend : math.dot(rub1Orientation, math.dotMultiply(rub2Orientation, -1))
const dAngle = chainData[z+1].narot - chainData[z].narot
distsInChain.push({
d: math.norm(math.subtract(chainData[z].pos, chainData[z+1].pos)),
rub1: chainData[z+1],
rub2: chainData[z],
bend: 180 * math.acos(bend) /Math.PI,
twist: dAngle > 45 ? 90 - dAngle : (dAngle < -45 ? 90 + dAngle : dAngle),
l: chainData.length,
...carbChains.carb
})
}
distWithinChain.push(distsInChain)
for (let j = i + 1; j < N; j++) {
const comDist = math.norm(math.subtract(leadingVectors[i].centerOfMass, leadingVectors[j].centerOfMass))
const distance = distBetweenChains(leadingVectors[i], leadingVectors[j])
distance.allDists.forEach(d => {
allDistances.push({
i: leadingVectors[i].chainId,
j: leadingVectors[j].chainId,
minDist: distance.dist,
dist: d
})
})
const chain2 = leadingVectors[j].leadVector
const chain2Contrary = math.dotMultiply(-1, chain2)
const chain2Normed = math.dotDivide(chain2, math.norm(chain2))
const chain2ContraryNormed = math.dotMultiply(-1, chain2Normed)
const dot1 = math.dot(chain1Normed, chain2Normed)
const dot2 = math.dot(chain1Normed, chain2ContraryNormed)
const c2 = dot1 > dot2 ? chain2Normed : chain2ContraryNormed
const dot = Math.max(dot1, dot2)
const cross = math.cross(chain1Normed, c2)
const theta = math.dot(cross, distance.direction)
results.push(
{
...carbChains.carb,
dot,
angle: 180 * math.acos(dot) /Math.PI,
comDist,
dist: distance.dist,
direction: distance.direction,
theta,
chainId1: leadingVectors[i].chainId,
chainId2: leadingVectors[j].chainId,
chain1: leadingVectors[i],
chain2: leadingVectors[j]
}
)
}
}
}
}
return { results, allDistances, twistedAngles, distWithinChain }
}