public void VolumeAsExpected() { var aa1 = new ApproximatedAminoAcid(AminoAcidName.Alanine, 1); var aa2 = new ApproximatedAminoAcid(AminoAcidName.Alanine, 2); var aa3 = new ApproximatedAminoAcid(AminoAcidName.Alanine, 3); var peptide = new ApproximatePeptide(new List <ApproximatedAminoAcid> { aa1, aa2, aa3 }); // Set positions aa1.NitrogenPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 0, 0, 0); aa1.CarbonAlphaPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 1, 0, 0); aa1.CarbonPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 1, 1, 0); aa2.NitrogenPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 0, 1, 0); aa2.CarbonAlphaPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 0, 1, 1); aa2.CarbonPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 1, 1, 1); aa3.NitrogenPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 1, 0, 1); aa3.CarbonAlphaPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 0, 0, 1); aa3.CarbonPosition = new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 0.5, 0.5, 0.5); var result = CompactnessMeasurer.Measure(peptide); var volume = result.Volume.Value; var picoMultiplier = SIPrefix.Pico.GetMultiplier(); var cubicPicoMultiplier = picoMultiplier * picoMultiplier * picoMultiplier; Assert.That(volume / cubicPicoMultiplier, Is.EqualTo(1).Within(1e-6)); }
public static ApproximatePeptide FromPeptide(Peptide peptide) { var dihedralAngles = AminoAcidAngleMeasurer.MeasureAngles(peptide); var approximateAminoAcids = new List <ApproximatedAminoAcid>(); foreach (var aminoAcid in peptide.AminoAcids) { PdbAminoAcidAtomNamer.AssignNames(aminoAcid); var nitrogen = aminoAcid.GetAtomFromName("N"); var carbonAlpha = aminoAcid.GetAtomFromName("CA"); var carbon = aminoAcid.GetAtomFromName("C"); var aminoAcidDihedralAngles = dihedralAngles[aminoAcid]; var approximateAminoAcid = new ApproximatedAminoAcid(aminoAcid.Name, aminoAcid.SequenceNumber) { NitrogenPosition = nitrogen.Position, CarbonAlphaPosition = carbonAlpha.Position, CarbonPosition = carbon.Position, OmegaAngle = aminoAcidDihedralAngles.Omega, PhiAngle = aminoAcidDihedralAngles.Phi, PsiAngle = aminoAcidDihedralAngles.Psi, IsFrozen = true }; approximateAminoAcids.Add(approximateAminoAcid); } return(new ApproximatePeptide(approximateAminoAcids)); }
private void CalculateBondLengthForces(ApproximatedAminoAcid previousAminoAcid, ApproximatedAminoAcid aminoAcid, Dictionary <ApproximatedAminoAcid, ApproximateAminoAcidForces> bondForces) { var nitrogenCarbonBondLength = BondLengthCalculator.CalculateApproximate(ElementName.Nitrogen, ElementName.Carbon); var carbonCarbonBondLength = BondLengthCalculator.CalculateApproximate(ElementName.Carbon, ElementName.Carbon); var aminoAcidForces = bondForces[aminoAcid]; // Carbon - nitrogen bond if (previousAminoAcid != null) { var carbonNitrogenForceVector = CalculateBondLengthForce(previousAminoAcid.CarbonPosition, aminoAcid.NitrogenPosition, nitrogenCarbonBondLength); var previousAminoAcidForces = bondForces[previousAminoAcid]; previousAminoAcidForces.CarbonForce += carbonNitrogenForceVector; aminoAcidForces.NitrogenForce += -carbonNitrogenForceVector; } // Nitrogen - carbon alpha bond var nitrogenCarbonAlphaForceVector = CalculateBondLengthForce(aminoAcid.NitrogenPosition, aminoAcid.CarbonAlphaPosition, nitrogenCarbonBondLength); aminoAcidForces.NitrogenForce += nitrogenCarbonAlphaForceVector; aminoAcidForces.CarbonAlphaForce += -nitrogenCarbonAlphaForceVector; // Carbon alpha - carbon bond var carbonAlphaCarbonForceVector = CalculateBondLengthForce(aminoAcid.CarbonAlphaPosition, aminoAcid.CarbonPosition, carbonCarbonBondLength); aminoAcidForces.CarbonAlphaForce += carbonAlphaCarbonForceVector; aminoAcidForces.CarbonForce += -carbonAlphaCarbonForceVector; }
private void CalculateBondAngleForces(ApproximatedAminoAcid previousAminoAcid, ApproximatedAminoAcid aminoAcid, Dictionary <ApproximatedAminoAcid, ApproximateAminoAcidForces> bondForces) { const double RestoreForceScaling = 1e-10; var aminoAcidForces = bondForces[aminoAcid]; var nitrogenCarbonAlphaVector = aminoAcid.NitrogenPosition.VectorTo(aminoAcid.CarbonAlphaPosition); if (previousAminoAcid != null) { var previousAminoAcidForces = bondForces[previousAminoAcid]; // Carbon alpha - carbon - nitrogen bond pair var carbonAlphaCarbonVector = previousAminoAcid.CarbonAlphaPosition .VectorTo(previousAminoAcid.CarbonPosition); var carbonNitrogenVector = previousAminoAcid.CarbonPosition .VectorTo(aminoAcid.NitrogenPosition); var cacnAngle = 180.To(Unit.Degree) - carbonAlphaCarbonVector.AngleWith(carbonNitrogenVector); var cacnPlaneNormal = carbonAlphaCarbonVector.CrossProduct(carbonNitrogenVector); var cacnForceMagnitude = RestoreForceScaling * (cacnAngle.In(Unit.Degree) - AminoAcidBondAngles.CaCNAngle.In(Unit.Degree)) .To(Unit.Newton); var carbonAlpha1ForceDirection = -carbonAlphaCarbonVector.CrossProduct(cacnPlaneNormal).Normalize().ToVector3D(); var nitrogenForceDirection = -carbonNitrogenVector.CrossProduct(cacnPlaneNormal).Normalize().ToVector3D(); previousAminoAcidForces.CarbonAlphaForce += cacnForceMagnitude * carbonAlpha1ForceDirection; previousAminoAcidForces.CarbonForce += -(cacnForceMagnitude * carbonAlpha1ForceDirection + cacnForceMagnitude * nitrogenForceDirection); aminoAcidForces.NitrogenForce += cacnForceMagnitude * nitrogenForceDirection; // Carbon - nitrogen - carbon alpha bond pair var cncaAngle = 180.To(Unit.Degree) - carbonNitrogenVector.AngleWith(nitrogenCarbonAlphaVector); var cncaPlaneNormal = carbonNitrogenVector.CrossProduct(nitrogenCarbonAlphaVector); var cncaForceMagnitude = RestoreForceScaling * (cncaAngle.In(Unit.Degree) - AminoAcidBondAngles.CNCaAngle.In(Unit.Degree)) .To(Unit.Newton); var carbonForceDirection = -carbonNitrogenVector.CrossProduct(cncaPlaneNormal).Normalize().ToVector3D(); var carbonAlpha2ForceDirection = -nitrogenCarbonAlphaVector.CrossProduct(cncaPlaneNormal).Normalize().ToVector3D(); previousAminoAcidForces.CarbonForce += cncaForceMagnitude * carbonForceDirection; aminoAcidForces.NitrogenForce += -(cncaForceMagnitude * carbonForceDirection + cncaForceMagnitude * carbonAlpha2ForceDirection); aminoAcidForces.CarbonAlphaForce += cncaForceMagnitude * carbonAlpha2ForceDirection; } // Nitrogen - carbon alpha - carbon bond pair var carbonAlphaCarbon2Vector = aminoAcid.CarbonAlphaPosition.VectorTo(aminoAcid.CarbonPosition); var ncacAngle = 180.To(Unit.Degree) - nitrogenCarbonAlphaVector.AngleWith(carbonAlphaCarbon2Vector); var ncacPlaneNormal = nitrogenCarbonAlphaVector.CrossProduct(carbonAlphaCarbon2Vector); var ncacForceMagnitude = RestoreForceScaling * (ncacAngle.In(Unit.Degree) - AminoAcidBondAngles.NCaCAngle.In(Unit.Degree)) .To(Unit.Newton); var nitrogenForceDirection2 = -nitrogenCarbonAlphaVector.CrossProduct(ncacPlaneNormal).Normalize().ToVector3D(); var carbonForceDirection2 = -carbonAlphaCarbon2Vector.CrossProduct(ncacPlaneNormal).Normalize().ToVector3D(); aminoAcidForces.NitrogenForce += ncacForceMagnitude * nitrogenForceDirection2; aminoAcidForces.CarbonAlphaForce += -(ncacForceMagnitude * nitrogenForceDirection2 + ncacForceMagnitude * carbonForceDirection2); aminoAcidForces.CarbonForce += ncacForceMagnitude * carbonForceDirection2; }
public static void Position(IList <ApproximatedAminoAcid> aminoAcids, UnitPoint3D startPosition) { ApproximatedAminoAcid lastAminoAcid = null; foreach (var aminoAcid in aminoAcids) { PositionAminoAcid(aminoAcid, lastAminoAcid, startPosition); lastAminoAcid = aminoAcid; } }
public ApproximateAminoAcidVertex3D(ApproximatedAminoAcid aminoAcid) { AminoAcid = aminoAcid; Id = Interlocked.Increment(ref lastId); var carbonAlphaPosition = aminoAcid.CarbonAlphaPosition.In(SIPrefix.Pico, Unit.Meter); var x = carbonAlphaPosition.X; var y = carbonAlphaPosition.Y; var z = carbonAlphaPosition.Z; Position = new[] { x, y, z }; Point = new Point3D(x, y, z); }
private static void ApplyOmegaDeviationForce(ApproximatedAminoAcid lastAminoAcid, ApproximatedAminoAcid aminoAcid, AminoAcidAngles aminoAcidAngles, Dictionary <ApproximatedAminoAcid, ApproximateAminoAcidForces> forceDictionary) { if (lastAminoAcid == null) { return; } var omegaDeviation = aminoAcidAngles.Omega.In(Unit.Degree) < 0 ? -180 - aminoAcidAngles.Omega.In(Unit.Degree) : 180 - aminoAcidAngles.Omega.In(Unit.Degree); if (!forceDictionary.ContainsKey(aminoAcid)) { forceDictionary.Add(aminoAcid, new ApproximateAminoAcidForces()); } var aminoAcidForces = forceDictionary[aminoAcid]; if (!forceDictionary.ContainsKey(lastAminoAcid)) { forceDictionary.Add(lastAminoAcid, new ApproximateAminoAcidForces()); } var lastAminoAcidForces = forceDictionary[lastAminoAcid]; var carbonNitrogenVector = lastAminoAcid.CarbonPosition .VectorTo(aminoAcid.NitrogenPosition) .In(SIPrefix.Pico, Unit.Meter); var previousCarbonCarbonAlphaVector = lastAminoAcid.CarbonPosition .VectorTo(lastAminoAcid.CarbonAlphaPosition) .In(SIPrefix.Pico, Unit.Meter); var forceMagnitude1 = forceScaling * omegaDeviation * 1.0.To(Unit.Newton); var forceDirection1 = previousCarbonCarbonAlphaVector .CrossProduct(carbonNitrogenVector) .Normalize() .ToVector3D(); lastAminoAcidForces.CarbonAlphaForce += forceMagnitude1 * forceDirection1; var nitrogenCarbonAlphaVector = aminoAcid.NitrogenPosition .VectorTo(aminoAcid.CarbonAlphaPosition) .In(SIPrefix.Pico, Unit.Meter); var forceMagnitude2 = forceScaling * omegaDeviation * 1.0.To(Unit.Newton); var forceDirection2 = -nitrogenCarbonAlphaVector .CrossProduct(carbonNitrogenVector) .Normalize() .ToVector3D(); aminoAcidForces.CarbonAlphaForce += forceMagnitude2 * forceDirection2; }
private void RecursiveAddAndPositionNewAminoAcid( ApproximatePeptide peptide, Stack <AminoAcidName> aminoAcidQueue, MultiLevelGrowingFoldingSimulatorSettings settings) { var aminoAcidName = aminoAcidQueue.Pop(); var lastAminoAcid = peptide.AminoAcids.LastOrDefault(); var lastPosition = lastAminoAcid?.CarbonAlphaPosition ?? new UnitPoint3D(Unit.Meter, 0, 0, 0); var influencingAminoAcids = peptide.AminoAcids .Where(x => x.CarbonAlphaPosition.DistanceTo(lastPosition) < settings.InfluenceHorizont) .ToList(); var ramachandranPlot = ramachandranPlotSource.Get(aminoAcidName); var sequenceNumber = lastAminoAcid?.SequenceNumber + 1 ?? 0; var isTimeForSecondaryStructureFolding = sequenceNumber % settings.SecondaryStructureFoldingFrequency == 0; if (isTimeForSecondaryStructureFolding) { FoldSecondaryStructure(peptide); } var remainingPositionAttempts = settings.PositioningAttempts; do { try { var aminoAcid = new ApproximatedAminoAcid(aminoAcidName, sequenceNumber); PositionAminoAcid(aminoAcid, lastAminoAcid, ramachandranPlot, influencingAminoAcids, settings); peptide.Add(aminoAcid); RecursiveAddAndPositionNewAminoAcid(peptide, aminoAcidQueue, settings); return; } catch (AminoAcidCannotBePositionedException) { remainingPositionAttempts--; } } while (remainingPositionAttempts > 0); aminoAcidQueue.Push(aminoAcidName); throw new AminoAcidCannotBePositionedException(aminoAcidName, sequenceNumber); }
private void ApplyForce(ApproximatedAminoAcid aminoAcid, ApproximateAminoAcidForces resultingForces, UnitValue timeStepSize, UnitValue reservoirTemperature) { var scaling = 1e0; var nitrogenForce = scaling * resultingForces.NitrogenForce; var nitrogenMass = PeriodicTable.GetSingleAtomMass(ElementName.Nitrogen); var nitrogenAcceleration = nitrogenForce / nitrogenMass; var nitrogenVelocityChange = nitrogenAcceleration * timeStepSize; aminoAcid.NitrogenVelocity += nitrogenVelocityChange; aminoAcid.NitrogenVelocity = InteractWithReservoir(aminoAcid.NitrogenVelocity, nitrogenMass, reservoirTemperature); aminoAcid.NitrogenPosition += aminoAcid.NitrogenVelocity * timeStepSize; if (simulationSettings.ResetAtomVelocityAfterEachTimestep) { aminoAcid.NitrogenVelocity = new UnitVector3D(Unit.MetersPerSecond, 0, 0, 0); } var carbonAlphaForce = scaling * resultingForces.CarbonAlphaForce; var carbonAlphaMass = PeriodicTable.GetSingleAtomMass(ElementName.Carbon) + AminoAcidSideChainMassLookup.SideChainMasses[aminoAcid.Name]; var carbonAlphaAcceleration = carbonAlphaForce / carbonAlphaMass; var carbonAlphaVelocityChange = carbonAlphaAcceleration * timeStepSize; aminoAcid.CarbonAlphaVelocity += carbonAlphaVelocityChange; aminoAcid.CarbonAlphaVelocity = InteractWithReservoir(aminoAcid.CarbonAlphaVelocity, carbonAlphaMass, reservoirTemperature); aminoAcid.CarbonAlphaPosition += aminoAcid.CarbonAlphaVelocity * timeStepSize; if (simulationSettings.ResetAtomVelocityAfterEachTimestep) { aminoAcid.CarbonAlphaVelocity = new UnitVector3D(Unit.MetersPerSecond, 0, 0, 0); } var carbonForce = scaling * resultingForces.CarbonForce; var carbonMass = PeriodicTable.GetSingleAtomMass(ElementName.Carbon); var carbonAcceleration = carbonForce / carbonMass; var carbonVelocityChange = carbonAcceleration * timeStepSize; aminoAcid.CarbonVelocity += carbonVelocityChange; aminoAcid.CarbonVelocity = InteractWithReservoir(aminoAcid.CarbonVelocity, carbonMass, reservoirTemperature); aminoAcid.CarbonPosition += aminoAcid.CarbonVelocity * timeStepSize; if (simulationSettings.ResetAtomVelocityAfterEachTimestep) { aminoAcid.CarbonVelocity = new UnitVector3D(Unit.MetersPerSecond, 0, 0, 0); } }
private void ApplyPsiDeviationForce(ApproximatedAminoAcid aminoAcid, ApproximatedAminoAcid nextAminoAcid, Dictionary <ApproximatedAminoAcid, ApproximateAminoAcidForces> forceDictionary, double psiDeviation) { var carbonAlphaCarbonVector = aminoAcid.CarbonAlphaPosition .VectorTo(aminoAcid.CarbonPosition) .In(SIPrefix.Pico, Unit.Meter); if (!forceDictionary.ContainsKey(aminoAcid)) { forceDictionary.Add(aminoAcid, new ApproximateAminoAcidForces()); } var aminoAcidForces = forceDictionary[aminoAcid]; var carbonAlphaNitrogenVector = aminoAcid.CarbonAlphaPosition .VectorTo(aminoAcid.NitrogenPosition) .In(SIPrefix.Pico, Unit.Meter); var forceMagnitude1 = -forceScaling * psiDeviation * 1.0.To(Unit.Newton); var forceDirection1 = carbonAlphaCarbonVector .CrossProduct(carbonAlphaNitrogenVector) .Normalize() .ToVector3D(); aminoAcidForces.NitrogenForce += forceMagnitude1 * forceDirection1; if (nextAminoAcid != null) // Should be redundant, because psi is undefined if no next amino acid { if (!forceDictionary.ContainsKey(nextAminoAcid)) { forceDictionary.Add(nextAminoAcid, new ApproximateAminoAcidForces()); } var nextAminoAcidForces = forceDictionary[nextAminoAcid]; var carbonNitrogenVector = aminoAcid.CarbonPosition .VectorTo(nextAminoAcid.NitrogenPosition) .In(SIPrefix.Pico, Unit.Meter); var forceMagnitude2 = forceScaling * psiDeviation * 1.0.To(Unit.Newton); var forceDirection2 = carbonAlphaCarbonVector .CrossProduct(carbonNitrogenVector) .Normalize() .ToVector3D(); nextAminoAcidForces.NitrogenForce += forceMagnitude2 * forceDirection2; } }
private void PositionAminoAcid( ApproximatedAminoAcid aminoAcid, ApproximatedAminoAcid lastAminoAcid, RamachandranPlot ramachandranPlot, List <ApproximatedAminoAcid> influencingAminoAcids, MultiLevelGrowingFoldingSimulatorSettings settings) { var influencingCenter = CalculateCenter(influencingAminoAcids); var positionAttempt = 1; do { var aminoAcidAngles = ramachandranPlot.GetRandomPhiPsi(); aminoAcid.OmegaAngle = aminoAcidAngles.Omega; aminoAcid.PhiAngle = aminoAcidAngles.Phi; aminoAcid.PsiAngle = aminoAcidAngles.Psi; ApproximateAminoAcidPositioner.PositionAminoAcid(aminoAcid, lastAminoAcid, new UnitPoint3D(Unit.Meter, 0, 0, 0)); // Note: Clashing distance was determined using MultiLevelGrowingFoldingSimulatorStudy.MeasureAverageAminoAcidDistance var isClashingWithAnyInfluencingAminoAcid = influencingAminoAcids .Any(otherAminoAcid => otherAminoAcid.CarbonAlphaPosition.DistanceTo(aminoAcid.CarbonAlphaPosition).In(SIPrefix.Nano, Unit.Meter) < 1.0); if (isClashingWithAnyInfluencingAminoAcid) { positionAttempt++; continue; } if (lastAminoAcid != null && influencingAminoAcids.Count > 0) { var isTooFarAway = aminoAcid.CarbonAlphaPosition.DistanceTo(influencingCenter) > lastAminoAcid.CarbonAlphaPosition.DistanceTo(influencingCenter) && aminoAcid.CarbonAlphaPosition.DistanceTo(influencingCenter) > 0.8 * settings.InfluenceHorizont; if (isTooFarAway) { positionAttempt++; continue; } } return; } while (positionAttempt < settings.PositioningAttempts); throw new AminoAcidCannotBePositionedException(aminoAcid.Name, aminoAcid.SequenceNumber); }
public void AminoAcidPositioningTest() { var aminoAcid1 = new ApproximatedAminoAcid(AminoAcidName.Glycine, 1) { OmegaAngle = 0.To(Unit.Degree), PhiAngle = 0.To(Unit.Degree), PsiAngle = -120.To(Unit.Degree) }; var aminoAcid2 = new ApproximatedAminoAcid(AminoAcidName.Glycine, 2) { OmegaAngle = 10.To(Unit.Degree), PhiAngle = -70.To(Unit.Degree), PsiAngle = 0.To(Unit.Degree) }; var peptide = new ApproximatePeptide(new [] { aminoAcid1, aminoAcid2 }); var angles = AminoAcidAngleMeasurer.MeasureAngles(peptide); var aminoAcid1Angles = angles[aminoAcid1]; var aminoAcid2Angles = angles[aminoAcid2]; Assert.That(aminoAcid1Angles.Psi.In(Unit.Radians), Is.EqualTo(aminoAcid1.PsiAngle.In(Unit.Radians)).Within(1e-9)); Assert.That(aminoAcid2Angles.Omega.In(Unit.Radians), Is.EqualTo(aminoAcid2.OmegaAngle.In(Unit.Radians)).Within(1e-9)); Assert.That(aminoAcid2Angles.Phi.In(Unit.Radians), Is.EqualTo(aminoAcid2.PhiAngle.In(Unit.Radians)).Within(1e-9)); }
public void CarbonAlphaDistancesMatchRealMeasurements() { var aminoAcid1 = new ApproximatedAminoAcid(AminoAcidName.Valine, 90) { OmegaAngle = 179.9.To(Unit.Degree), PhiAngle = -35.9.To(Unit.Degree), PsiAngle = -52.0.To(Unit.Degree) }; var aminoAcid2 = new ApproximatedAminoAcid(AminoAcidName.Alanine, 91) { OmegaAngle = 179.9.To(Unit.Degree), PhiAngle = -63.5.To(Unit.Degree), PsiAngle = -59.7.To(Unit.Degree) }; var peptide = new[] { aminoAcid1, aminoAcid2 }; ApproximateAminoAcidPositioner.Position(peptide, new UnitPoint3D(Unit.Meter, 0, 0, 0)); var carbonAlphaCarbonDistance = aminoAcid1.CarbonAlphaPosition .DistanceTo(aminoAcid1.CarbonPosition); Assert.That(carbonAlphaCarbonDistance.In(SIPrefix.Pico, Unit.Meter), Is.EqualTo(154).Within(0.1)); var carbonNitrogenDistance = aminoAcid1.CarbonPosition .DistanceTo(aminoAcid2.NitrogenPosition); Assert.That(carbonNitrogenDistance.In(SIPrefix.Pico, Unit.Meter), Is.EqualTo(152).Within(0.1)); var aminoAcidAngles = AminoAcidAngleMeasurer.MeasureAngles(new ApproximatePeptide(peptide)); Assert.That(aminoAcidAngles[aminoAcid1].Psi.Value - aminoAcid1.PsiAngle.Value, Is.EqualTo(0).Within(0.1)); Assert.That(aminoAcidAngles[aminoAcid2].Phi.Value - aminoAcid2.PhiAngle.Value, Is.EqualTo(0).Within(0.1)); // The bond length vary because we use theoretical bond length, which do not exactly match real bond lengths //Assert.That( // aminoAcid1.CarbonAlphaPosition.DistanceTo(aminoAcid2.CarbonAlphaPosition).In(SIPrefix.Pico, Unit.Meter), // Is.EqualTo(380.3).Within(0.1)); }
public void AtomPositionsAsExpected() { var aminoAcid1 = new ApproximatedAminoAcid(AminoAcidName.Valine, 90) { OmegaAngle = 45.To(Unit.Degree), PhiAngle = -60.To(Unit.Degree), PsiAngle = 90.To(Unit.Degree) }; var aminoAcid2 = new ApproximatedAminoAcid(AminoAcidName.Alanine, 91) { OmegaAngle = 0.To(Unit.Degree), PhiAngle = -90.To(Unit.Degree), PsiAngle = 90.To(Unit.Degree) }; var peptide = new ApproximatePeptide(new[] { aminoAcid1, aminoAcid2 }); ApproximateAminoAcidPositioner.Position(peptide.AminoAcids, new UnitPoint3D(Unit.Meter, 0, 0, 0)); var angles = AminoAcidAngleMeasurer.MeasureAngles(peptide); Assert.That(angles[aminoAcid1].Psi.In(Unit.Degree), Is.EqualTo(aminoAcid1.PsiAngle.In(Unit.Degree)).Within(1)); Assert.That(angles[aminoAcid2].Omega.In(Unit.Degree), Is.EqualTo(aminoAcid2.OmegaAngle.In(Unit.Degree)).Within(1)); Assert.That(angles[aminoAcid2].Phi.In(Unit.Degree), Is.EqualTo(aminoAcid2.PhiAngle.In(Unit.Degree)).Within(1)); //Assert.That( // aminoAcid1.NitrogenPosition.DistanceTo(new UnitPoint3D(Unit.Meter, 0, 0, 0)).In(SIPrefix.Pico, Unit.Meter), // Is.EqualTo(0).Within(1e-3)); //Assert.That( // aminoAcid1.CarbonAlphaPosition.DistanceTo(new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 152, 0, 0)).In(SIPrefix.Pico, Unit.Meter), // Is.EqualTo(0).Within(1e-3)); //Assert.That( // aminoAcid1.CarbonPosition.DistanceTo(new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 152, 154, 0)).In(SIPrefix.Pico, Unit.Meter), // Is.EqualTo(0).Within(1e-3)); //Assert.That( // aminoAcid2.NitrogenPosition.DistanceTo(new UnitPoint3D(SIPrefix.Pico, Unit.Meter, 152, 154, 152)).In(SIPrefix.Pico, Unit.Meter), // Is.EqualTo(0).Within(1e-3)); }
public static void PositionAminoAcid(ApproximatedAminoAcid aminoAcid, ApproximatedAminoAcid lastAminoAcid = null, UnitPoint3D startPosition = null) { if (lastAminoAcid == null && startPosition == null) { throw new ArgumentNullException("Either last amino acid or start position must be non-null"); } var nitrogenCarbonDistance = PeriodicTable.GetCovalentRadius(ElementName.Nitrogen) + PeriodicTable.GetCovalentRadius(ElementName.Carbon); var CaCDistance = 2 * PeriodicTable.GetCovalentRadius(ElementName.Carbon); UnitPoint3D carbonPosition; UnitPoint3D carbonAlphaPosition; Vector3D carbonAlphaCarbonBondDirection; Vector3D nitrogenCarbonAlphaBondDirection; if (lastAminoAcid == null) { carbonPosition = startPosition; carbonAlphaPosition = startPosition + new UnitPoint3D(SIPrefix.Pico, Unit.Meter, -CaCDistance.In(SIPrefix.Pico, Unit.Meter), 0, 0); carbonAlphaCarbonBondDirection = carbonAlphaPosition.VectorTo(carbonPosition); nitrogenCarbonAlphaBondDirection = new Vector3D(0, 1, 0); } else { carbonPosition = lastAminoAcid.CarbonPosition; carbonAlphaPosition = lastAminoAcid.CarbonAlphaPosition; carbonAlphaCarbonBondDirection = carbonAlphaPosition .VectorTo(carbonPosition); nitrogenCarbonAlphaBondDirection = lastAminoAcid.NitrogenPosition .VectorTo(carbonAlphaPosition); } var omega = aminoAcid.OmegaAngle ?? Math.PI.To(Unit.Radians); var phi = aminoAcid.PhiAngle ?? 0.To(Unit.Radians); var psi = lastAminoAcid?.PsiAngle ?? 0.To(Unit.Radians); var nitrogenPosition = CalculateAtomPosition(carbonPosition, carbonAlphaCarbonBondDirection, nitrogenCarbonAlphaBondDirection, nitrogenCarbonDistance, AminoAcidBondAngles.CaCNAngle, psi); carbonAlphaPosition = CalculateAtomPosition(nitrogenPosition, carbonPosition.VectorTo(nitrogenPosition), carbonAlphaCarbonBondDirection, nitrogenCarbonDistance, AminoAcidBondAngles.CNCaAngle, omega); carbonPosition = CalculateAtomPosition(carbonAlphaPosition, nitrogenPosition.VectorTo(carbonAlphaPosition), carbonPosition.VectorTo(nitrogenPosition), CaCDistance, AminoAcidBondAngles.NCaCAngle, phi); aminoAcid.NitrogenPosition = nitrogenPosition; aminoAcid.CarbonAlphaPosition = carbonAlphaPosition; aminoAcid.CarbonPosition = carbonPosition; if (aminoAcid.OmegaAngle == null) { aminoAcid.OmegaAngle = omega; } if (aminoAcid.PhiAngle == null) { aminoAcid.PhiAngle = phi; } if (lastAminoAcid != null && lastAminoAcid.PsiAngle == null) { lastAminoAcid.PsiAngle = psi; } }