private static void HandleMeshCollider(MeshCollider c, ref AlignmentData data) { // TODO: I don't think there's an efficient solution for those. // The convex collider mesh doesn't seem accessible by script. // We could access the original mesh, but that all is pretty inefficient. // Best solution for now probably is to just restrict ourselves to the other colliders. }
private void ExportAlignmentData(AlignmentData data, DatasetInformation baselineDatasetInformation, DatasetInformation alignDatasetInformation, IEnumerable <UMCLight> baselineFeatures, IEnumerable <UMCLight> aligneeFeatures) { var netValues = new List <double>(); var massValues = new List <double>(); var anchorPoints = data.Matches; foreach (var match in anchorPoints) { netValues.Add(match.AnchorPointX.Net - match.AnchorPointY.Net); massValues.Add(match.AnchorPointX.Mass - match.AnchorPointY.Mass); } var netHist = MatchCountHistogramBuilder.CreateResidualHistogram(-.05, .05, .01, netValues); var netHistogram = new Dictionary <double, int>(); Console.WriteLine(); for (var i = 0; i < netHist.Bins.Count; i++) { netHistogram.Add(netHist.Bins[i], Convert.ToInt32(netHist.Data[i])); Console.WriteLine("{0}\t{1}", netHist.Bins[i], netHist.Data[i]); } }
/// <summary> /// Arguments that hold alignment information when a dataset is aligned. /// </summary> public FeaturesAlignedEventArgs(DatasetInformation datasetInfo, IEnumerable <UMCLight> baselineFeatures, IEnumerable <UMCLight> aligneeFeatures, AlignmentData alignmentData) { m_datasetInformation = datasetInfo; BaselineFeatures = baselineFeatures; AligneeFeatures = aligneeFeatures; AlignmentData = alignmentData; }
public new AlignmentData Align(MassTagDatabase database, IEnumerable <UMCLight> alignee, IProgress <ProgressData> progress = null) { var matches = base.Align(database, alignee); var data = new AlignmentData { Matches = matches }; Matches = matches; return(data); }
public AlignmentViewModel(AlignmentData alignment) { this.WindowTitle = string.Format("{0} Alignment Data", alignment.AligneeDataset); var plots = new AlignmentPlotCreator(alignment); this.HeatmapImage = ImageConverter.ConvertImage(PlotImageUtility.CreateImage(plots.Heatmap)); this.NetScanImage = ImageConverter.ConvertImage(PlotImageUtility.CreateImage(plots.NetResidual)); this.MassHistogram = ImageConverter.ConvertImage(PlotImageUtility.CreateImage(plots.MassHistogram)); this.NetHistogram = ImageConverter.ConvertImage(PlotImageUtility.CreateImage(plots.NetHistogram)); this.MassMzImage = ImageConverter.ConvertImage(PlotImageUtility.CreateImage(plots.MassMzResidual)); this.MassScanImage = ImageConverter.ConvertImage(PlotImageUtility.CreateImage(plots.MassScanResidual)); }
public AlignmentPlotCreator(AlignmentData alignment) { var residuals = alignment.ResidualData; Heatmap = HeatmapFactory.CreateAlignedHeatmap(alignment.HeatScores, alignment.BaselineIsAmtDB); NetResidual = ScatterPlotFactory.CreateResidualPlot(residuals.Net, residuals.LinearCustomNet, residuals.LinearNet, "NET Residuals", "Scans", "NET"); MassHistogram = HistogramFactory.CreateHistogram(alignment.MassErrorHistogram, "Mass Error", "Mass Error (ppm)"); NetHistogram = HistogramFactory.CreateHistogram(alignment.NetErrorHistogram, "NET Error", "NET Error"); MassMzResidual = ScatterPlotFactory.CreateResidualPlot(residuals.Mz, residuals.MzMassError, residuals.MzMassErrorCorrected, "Mass Residuals", "m/z", "Mass Errors"); MassScanResidual = ScatterPlotFactory.CreateResidualPlot(residuals.Net, residuals.MzMassError, residuals.MzMassErrorCorrected, "Mass Residuals", "Scan", "Mass Errors"); }
/// <summary> /// Creates an empty layer. /// </summary> /// <param name="id">the order number in the FlexiVolume.</param> /// <param name="brickid">the brick id.</param> /// <param name="sheet">the sheet in the brick.</param> /// <param name="side">the side (0 for base tracks, 1 for downstream, 2 for upstream).</param> public Layer(int id, long brickid, int sheet, short side) : base() { m_BrickId = brickid; m_SheetId = sheet; m_Side = side; m_Id = id; m_DownstreamZ_Updated = false; m_UpstreamZ_Updated = false; AlignmentData al = new AlignmentData(); al.AffineMatrixXX = al.AffineMatrixYY = 1.0; al.AffineMatrixXY = al.AffineMatrixYX = 0.0; al.TranslationX = al.TranslationY = al.TranslationZ = 0.0; al.DShrinkX = al.DShrinkY = 1.0; al.SAlignDSlopeX = al.SAlignDSlopeY = 0.0; SetAlignmentData(al); Segments = new Segment[0]; }
private static void HandleCapsuleCollider(CapsuleCollider c, ref AlignmentData data) { /* * var m = c.transform.localToWorldMatrix; * switch(c.direction) { * case 0: // aligned along x-axis * list.Add(m.MultiplyVector(Vector3.right)); * list.Add(m.MultiplyVector(Vector3.left)); * break; * case 1: // aligned along y-axis * list.Add(m.MultiplyVector(Vector3.up)); * list.Add(m.MultiplyVector(Vector3.down)); * break; * case 2: // aligned along z-axis * list.Add(m.MultiplyVector(Vector3.forward)); * list.Add(m.MultiplyVector(Vector3.back)); * break; * }*/ }
public static AlignmentData Scan(Vector3 pos, float radius, GameObject ignore = null) { var data = new AlignmentData(); foreach (var collider in Physics.OverlapSphere(pos, radius)) { if (ignore != null && ignore.GetComponentsInChildren <Collider>().Contains(collider)) { continue; } switch (collider) { case BoxCollider b: HandleBoxCollider(b, ref data); break; case SphereCollider s: HandleSphereCollider(s, ref data); break; case CapsuleCollider c: HandleCapsuleCollider(c, ref data); break; case MeshCollider m: HandleMeshCollider(m, ref data); break; } } /* * Dictionary<Vector3, int> histogram = new Dictionary<Vector3, int>(new DirectionComparer()); * foreach(var dir in orientations) { * if(histogram.TryGetValue(dir, out int count)) { * histogram[dir] = count + 1; * } else { * histogram[dir] = 1; * } * }*/ return(data); }
/// <summary> /// Align a set of features to a set of baseline features. /// </summary> /// <param name="baseline">The baseline features to align to.</param> /// <param name="alignee">The features to align.</param> /// <param name="progress">The progress reporter for the alignment process.</param> /// <returns>Information about the alignment.</returns> public AlignmentData Align(IEnumerable <UMCLight> baseline, IEnumerable <UMCLight> alignee, IProgress <ProgressData> progress = null) { // Enumerate features to lists. // Perform a deep copy of the LCMS features so that the original features are unaffected by the warp. var aligneeFeatures = alignee.Select(feature => new UMCLight(feature)).ToList(); var baselineFeatures = baseline.ToList(); // Warp mass if NET_MASS_WARP, otherwise only warp NET. var netMassWarp = this.options.AlignType == LcmsWarpAlignmentType.NET_MASS_WARP; var alignmentData = netMassWarp ? this.WarpNetMass(aligneeFeatures, baselineFeatures) : this.WarpNet(aligneeFeatures, baselineFeatures, true); // TODO: Change this to return the new alignment data object. var aData = new AlignmentData { AlignmentFunctions = new Dictionary <FeatureLight.SeparationTypes, LcmsWarpResults>() }; return(aData); }
private static void HandleBoxCollider(BoxCollider c, ref AlignmentData data) { var m = c.transform.localToWorldMatrix; data.AddOrientation(m.MultiplyVector(Vector3.forward)); data.AddOrientation(m.MultiplyVector(Vector3.back)); data.AddOrientation(m.MultiplyVector(Vector3.up)); data.AddOrientation(m.MultiplyVector(Vector3.down)); data.AddOrientation(m.MultiplyVector(Vector3.right)); data.AddOrientation(m.MultiplyVector(Vector3.left)); var cornerA = m.MultiplyPoint(c.center + 0.5f * c.size); var cornerB = m.MultiplyPoint(c.center - 0.5f * c.size); data.AddLevelX(cornerA.x); data.AddLevelX(cornerB.x); data.AddLevelY(cornerA.y); data.AddLevelY(cornerB.y); data.AddLevelZ(cornerA.z); data.AddLevelZ(cornerB.z); }
private static void HandleSphereCollider(SphereCollider c, ref AlignmentData data) { }
/// <summary> /// Aligns the dataset to the data stored in the alignment processor. /// </summary> /// <param name="alignmentProcessor">Aligner</param> /// <param name="features">LC-MS Features to align to the baseline</param> /// <param name="alignmentOptions">Options</param> /// <param name="progress"></param> /// <returns></returns> private AlignmentData AlignFeatures(LcmsWarpAlignmentProcessor alignmentProcessor, IEnumerable <UMCLight> features, LcmsWarpAlignmentOptions alignmentOptions, IProgress <ProgressData> progress = null) { var progData = new ProgressData(progress); var localProgress = new Progress <ProgressData>(p => progData.Report(p.Percent, p.Status)); var alignmentData = new AlignmentData(); OnStatus("Starting alignment of features."); // Set minMtdbnet and maxMtdbnet to 0 alignmentData.MinMTDBNET = 0; alignmentData.MaxMTDBNET = 0; var umcLights = features as List <UMCLight> ?? features.ToList(); progData.StepRange(5, "Starting alignment of features."); var filteredFeatures = FilterFeaturesByAbundance(umcLights, alignmentOptions); // Convert the features, and make a map, so that we can re-adjust the aligned values later. var map = FeatureDataConverters.MapFeature(umcLights); progData.StepRange(10, "Setting alignee features."); // Set features OnStatus("Setting alignee features."); alignmentProcessor.SetAligneeDatasetFeatures(filteredFeatures); progData.StepRange(90, "Performing alignment warping."); // Find alignment OnStatus("Performing alignment warping."); alignmentProcessor.PerformAlignmentToMsFeatures(localProgress); progData.StepRange(95); // Extract alignment function alignmentData.AlignmentFunction = alignmentProcessor.GetAlignmentFunction(); progData.StepRange(100); // Extract the NET value for every scan _scanToNETMap = alignmentProcessor.GetScanToNETMapping(); // Correct the features (updates NetAligned and MassMonoisotopicAligned) OnStatus("Applying alignment function to all features."); progData.Status = "Applying alignment function to all features."; umcLights = alignmentProcessor.ApplyNetMassFunctionToAligneeDatasetFeatures(umcLights); progData.Report(100); // Find min/max scan for meta-data var minScanBaseline = int.MaxValue; var maxScanBaseline = int.MinValue; foreach (var feature in umcLights) { maxScanBaseline = Math.Max(maxScanBaseline, feature.Scan); minScanBaseline = Math.Min(minScanBaseline, feature.Scan); } // Update the scan and NET ranges alignmentData.MinScanBaseline = minScanBaseline; alignmentData.MaxScanBaseline = maxScanBaseline; alignmentData.MinMTDBNET = (float)alignmentProcessor.MinReferenceNet; alignmentData.MaxMTDBNET = (float)alignmentProcessor.MaxReferenceNet; // Cache the matching features alignmentData.FeatureMatches = alignmentProcessor.FeatureMatches; // Pull out the heat maps... OnStatus("Retrieving alignment data."); progData.Status = "Retrieving alignment data."; alignmentData.HeatScores = alignmentProcessor.GetAlignmentHeatMap(alignmentOptions.StandardizeHeatScores); // Mass and net error histograms! alignmentData.MassErrorHistogram = alignmentProcessor.GetMassErrorHistogram(alignmentOptions.MassBinSize); alignmentData.NetErrorHistogram = alignmentProcessor.GetNetErrorHistogram(alignmentOptions.NetBinSize); alignmentData.DriftErrorHistogram = alignmentProcessor.GetDriftErrorHistogram(alignmentOptions.DriftTimeBinSize); // Get the residual data from the warp. alignmentData.ResidualData = alignmentProcessor.GetResidualData(); alignmentData.NETIntercept = alignmentProcessor.NetIntercept; alignmentData.NETRsquared = alignmentProcessor.NetRsquared; alignmentData.NETSlope = alignmentProcessor.NetSlope; alignmentData.MassMean = alignmentProcessor.MassMu; alignmentData.MassStandardDeviation = alignmentProcessor.MassStd; alignmentData.NETMean = alignmentProcessor.NetMu; alignmentData.NETStandardDeviation = alignmentProcessor.NetStd; alignmentData.BaselineIsAmtDB = _options.AlignToMassTagDatabase; return(alignmentData); }
/// <summary> /// Main Edlib method. /// </summary> /// <param name="originalQuery">String a</param> /// <param name="originalTarget">String b</param> /// <param name="config">Configuration</param> /// <returns>Result of the alignment</returns> public static AlignmentResult Align(string originalQuery, string originalTarget, AlignmentConfig config) { // NOTE: Is other mode useful? If so, why? if (config.Mode == AlignmentMode.Hw || config.Mode == AlignmentMode.Shw) { throw new NotImplementedException(); } AlignmentResult result = new AlignmentResult { Status = (int)AlignmentStatus.Ok, EditDistance = -1, EndLocations = null, StartingLocations = null, NumberOfLocations = 0, Alignment = null, AlignmentLength = 0, AlphabetLength = 0, }; // Transform sequences and recognize alphabet byte[] query, target; string alphabet = TransformSequences(originalQuery, originalTarget, out query, out target); result.AlphabetLength = alphabet.Length; // Initialization int queryLength = originalQuery.Length; int targetLength = originalTarget.Length; int maxBlocks = CeilDivision(queryLength, WordSize); int w = maxBlocks * WordSize - queryLength; EqualityDefinition equalityDefinition = new EqualityDefinition(alphabet, config.AdditionalEqualities, config.AdditionalEqualitiesLength); ulong[] peq = BuildPeq(alphabet.Length, query, queryLength, ref equalityDefinition); // Main Calculation int positionNw = -1; AlignmentData alignmentData = new AlignmentData(); bool dynamicK = false; int k = config.K; if (k < 0) // If valid k is not given, auto-adjust k until solution is found. { dynamicK = true; k = WordSize; // Gives better results than smaller k. } do { MyersEditDistanceNw(peq, w, maxBlocks, queryLength, target, targetLength, k, false, -1, ref result.EditDistance, ref positionNw, ref alignmentData); k *= 2; } while (dynamicK && result.EditDistance == -1); // NOTE: Do we need this block code? We only care about editing distance // Since we only care about the editing distance score, this is where we stop if (result.EditDistance >= 0) { // If NW mode, set end location explicitly. if (config.Mode == AlignmentMode.Nw) { result.EndLocations = new int[sizeof(int) * 1]; result.EndLocations[0] = targetLength - 1; result.NumberOfLocations = 1; } // if (!(config.Task == AlignmentTask.TaskLocate || config.Task == AlignmentTask.TaskPath)) // { // for (int i = 0; i < result.NumberOfLocations; i++) { // result.StartingLocations[i] = 0; // } // } } return(result); }
/// <summary> /// Uses Myers' bit-vector algorithm to find edit distance for global(NW) alignment method. /// </summary> /// <param name="peq"></param> /// <param name="w"></param> /// <param name="maxBlocks"></param> /// <param name="queryLength"></param> /// <param name="target"></param> /// <param name="targetLength"></param> /// <param name="k"></param> /// <param name="findAlignment"></param> /// <param name="targetStopPosition"></param> /// <param name="bestScore"></param> /// <param name="position"></param> /// <param name="alignmentData"></param> /// <returns>Status code.</returns> private static int MyersEditDistanceNw(ulong[] peq, int w, int maxBlocks, int queryLength, byte[] target, int targetLength, int k, bool findAlignment, int targetStopPosition, ref int bestScore, ref int position, ref AlignmentData alignmentData) { if (targetStopPosition > -1 && findAlignment) { return((int)AlignmentStatus.Error); } // Each STRONG_REDUCE_NUM column is reduced in more expensive way. const int strongReduceNum = 2048; if (k < Math.Abs(targetLength - queryLength)) { bestScore = position = -1; return((int)AlignmentStatus.Ok); } k = Math.Min(k, Math.Max(queryLength, targetLength)); int firstBlock = 0; int lastBlock = Math.Min(maxBlocks, CeilDivision(Math.Min(k, (k + queryLength - targetLength) / 2) + 1, WordSize)) - 1; Block[] bl; // Current block Block[] blocks = new Block[maxBlocks]; for (int i = 0; i < maxBlocks; i++) { blocks[i] = new Block(); } // Initialize p, m, and score bl = blocks; for (int b = 0; b <= lastBlock; b++) { bl[b].Score = (b + 1) * WordSize; bl[b].P = UInt64.MaxValue; bl[b].M = 0; } if (findAlignment) { alignmentData = new AlignmentData(maxBlocks, targetLength); } else if (targetStopPosition > -1) { alignmentData = new AlignmentData(maxBlocks, 1); } for (int c = 0; c < targetLength; c++) { ulong[] peqC = peq; // Get offset for the character peq // peq + *targetChar * maxBlocks int startPeqC = target[c] * maxBlocks; // Calculate column int hout = 1; // Get first block offset for (int b = firstBlock; b <= lastBlock; b++) { ulong pout, mout; hout = CalculateBlock(bl[b].P, bl[b].M, peqC[startPeqC + b], hout, out pout, out mout); bl[b].P = pout; bl[b].M = mout; bl[b].Score += hout; } k = Math.Min(k, bl[lastBlock].Score + Math.Max(targetLength - c - 1, queryLength - ((1 + lastBlock) * WordSize - 1) - 1) + (lastBlock == maxBlocks - 1 ? w : 0)); // Adjust number of blocks using Ukkonen algorithm if (lastBlock + 1 < maxBlocks && ! ( //score[lastBlock] >= k + Constants.WORDSIZE || // NOTICE: this condition could be satisfied if above block also! ((lastBlock + 1) * WordSize - 1 > k - bl[lastBlock].Score + 2 * WordSize - 2 - targetLength + c + queryLength))) { lastBlock++; bl[lastBlock].P = UInt64.MaxValue; bl[lastBlock].M = 0; ulong pout, mout; int newHout = CalculateBlock(bl[lastBlock].P, bl[lastBlock].M, peqC[startPeqC + lastBlock], hout, out pout, out mout); bl[lastBlock].Score = bl[lastBlock - 1].Score - hout + WordSize + newHout; bl[lastBlock].P = pout; bl[lastBlock].M = mout; hout = newHout; } // While block is out of band, move one block up. // NOTE: Condition used here is more loose than the one from the article, since I simplified the max() part of it. // I could consider adding that max part, for optimal performance. while (lastBlock >= firstBlock && (bl[lastBlock].Score >= k + WordSize || ((lastBlock + 1) * WordSize - 1 > // TODO: Does not work if do not put +1! Why??? k - bl[lastBlock].Score + 2 * WordSize - 2 - targetLength + c + queryLength + 1))) { lastBlock--; } // While outside of band, advance block while (firstBlock <= lastBlock && (bl[firstBlock].Score >= k + WordSize || ((firstBlock + 1) * WordSize - 1 < bl[firstBlock].Score - k - targetLength + queryLength + c))) { firstBlock++; } if (c % strongReduceNum == 0) { while (lastBlock >= firstBlock) { int[] scores = GetBlockCellValues(bl[lastBlock]); int numCells = lastBlock == maxBlocks - 1 ? WordSize - w : WordSize; int r = lastBlock * WordSize + numCells - 1; bool reduce = true; for (int i = WordSize - numCells; i < WordSize; i++) { // TODO: Does not work if do not put +1! Why??? if (scores[i] <= k && r <= k - scores[i] - targetLength + c + queryLength + 1) { reduce = false; break; } r--; } if (!reduce) { break; } lastBlock--; } while (firstBlock <= lastBlock) { int[] scores = GetBlockCellValues(bl[firstBlock]); int numCells = firstBlock == maxBlocks - 1 ? WordSize - w : WordSize; int r = firstBlock * WordSize + numCells - 1; bool reduce = true; for (int i = WordSize - numCells; i < WordSize; i++) { if (scores[i] <= k && r >= scores[i] - k - targetLength + c + queryLength) { reduce = false; break; } r--; } if (!reduce) { break; } firstBlock++; } } if (lastBlock < firstBlock) { bestScore = position = -1; return((int)AlignmentStatus.Ok); } if (findAlignment && c < targetLength) { for (int b = firstBlock; b <= lastBlock; b++) { alignmentData.Ps[maxBlocks * c + b] = bl[b].P; alignmentData.Ms[maxBlocks * c + b] = bl[b].M; alignmentData.Scores[maxBlocks * c + b] = bl[b].Score; alignmentData.FirstBlocks[c] = firstBlock; alignmentData.LastBlocks[c] = lastBlock; } } if (c == targetStopPosition) { for (int b = firstBlock; b <= lastBlock; b++) { alignmentData.Ps[b] = blocks[b].P; alignmentData.Ms[b] = blocks[b].M; alignmentData.Scores[b] = blocks[b].Score; alignmentData.FirstBlocks[0] = firstBlock; alignmentData.LastBlocks[0] = lastBlock; } bestScore = -1; position = targetStopPosition; return((int)AlignmentStatus.Ok); } } if (lastBlock == maxBlocks - 1) { int bs = GetBlockCellValues(bl[lastBlock])[w]; if (bs <= k) { bestScore = bs; position = targetLength - 1; return((int)AlignmentStatus.Ok); } } bestScore = position = -1; return((int)AlignmentStatus.Ok); }
public Quaternion TryMatchOrientation(AlignmentData other) { return(AlignmentEstimator.GetRotation(Orientations, other.Orientations)); }
/// <summary> /// Sets the alignment data for this layer, also recomputing the inverse matrix. /// </summary> /// <param name="a">the new alignment data to be used.</param> public void SetAlignment(AlignmentData a) { SetAlignmentData(a); }
void Update() { radius = transform.localScale.Average(); data = AlignmentQuery.Scan(transform.position, radius); }