// Merge two patterns to one. private void convolute_basic(Pattern target, Pattern source1, Pattern source2) { target.Clear(); int g_n = source1.Count; int f_n = source2.Count; if (g_n == 0 || f_n == 0) { return; } for (int k = 0; k < g_n + f_n - 1; k++) { double sumweight = 0, summass = 0; int start = k < (f_n - 1) ? 0 : k - f_n + 1; // max(0, k-f_n+1) int end = k < (g_n - 1) ? k : g_n - 1; // min(g_n - 1, k) for (int i = start; i <= end; i++) { double weight = source1[i].Intensity * source2[k - i].Intensity; double mass = source1[i].Mz + source2[k - i].Mz; sumweight += weight; summass += weight * mass; } Peak p = new Peak(); if (sumweight == 0) { p.Mz = DUMMY_MASS; } else { p.Mz = summass / sumweight; } p.Intensity = sumweight; target.Add(p); } }
public Pattern Calculate(FormMap fm, double limit, long charge) { Pattern tmp = new Pattern(); Pattern result = new Pattern(); result.Add(new Peak() { Mz = 0.0, Intensity = 1.0 }); foreach (var i in fm) { int atom_index = i.Key; SuperAtomList sal = sad[atom_index]; int n = i.Value; int j = 0; while (n > 0) { int sz = sal.Count; if (j == sz) { sal.Add(new Pattern()); convolute_basic(sal[j], sal[j - 1], sal[j - 1]); Prune(sal[j], limit); } if ((n & 1) == 1) { // digit is 1, convolute result convolute_basic(tmp, result, sal[j]); Prune(tmp, limit); result.Clear(); result.AddRange(tmp); } n >>= 1; j++; } } // take charge into account foreach (var p in result) { if (charge > 0) { p.Mz = p.Mz / Math.Abs(charge) - ELECTRON_MASS; } else if (charge < 0) { p.Mz = p.Mz / Math.Abs(charge) + ELECTRON_MASS; } } if (result.Count == 0) { throw new Exception("Calculate profile failed"); } return(result); }
/// <summary> /// Generates a hold note alongside normal notes. /// </summary> /// <param name="startTime">The start time of notes.</param> /// <returns>The <see cref="Pattern"/> containing the hit objects.</returns> private Pattern generateHoldAndNormalNotes(double startTime) { // - - - - // ■ x x - // ■ - x x // ■ x - x // ■ - x x var pattern = new Pattern(); int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns) holdColumn = FindAvailableColumn(holdColumn, PreviousPattern); // Create the hold note addToPattern(pattern, holdColumn, startTime, EndTime); int nextColumn = GetRandomColumn(); int noteCount; if (ConversionDifficulty > 6.5) noteCount = GetRandomNoteCount(0.63, 0); else if (ConversionDifficulty > 4) noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0.12 : 0.45, 0); else if (ConversionDifficulty > 2.5) noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0 : 0.24, 0); else noteCount = 0; noteCount = Math.Min(TotalColumns - 1, noteCount); bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == HitSampleInfo.HIT_WHISTLE || s.Name == HitSampleInfo.HIT_FINISH || s.Name == HitSampleInfo.HIT_CLAP); var rowPattern = new Pattern(); for (int i = 0; i <= spanCount; i++) { if (!(ignoreHead && startTime == HitObject.StartTime)) { for (int j = 0; j < noteCount; j++) { nextColumn = FindAvailableColumn(nextColumn, validation: c => c != holdColumn, patterns: rowPattern); addToPattern(rowPattern, nextColumn, startTime, startTime); } } pattern.Add(rowPattern); rowPattern.Clear(); startTime += SegmentDuration; } return pattern; }
public void CalculateSteps() { var cols = 16; var rows = MathUtil.CeilToInt(totalFlags / (float)cols); var w = cols * tileSize.x; var h = rows * tileSize.y; var canvas = new Pattern(w, h); canvas.Clear(); var totalPixels = tileSize.x * tileSize.y; var brush = new int[totalPixels]; IColor[] colors = new IColor[totalFlags]; var flagColors = flagColorChip.colors; for (int i = 0; i < totalFlags; i++) { colors[i] = flagColors[i]; var pos = gameChip.CalculatePosition(i, w); pos.x *= tileSize.x; pos.y *= tileSize.y; // Update the brush for (int j = 0; j < totalPixels; j++) { brush[j] = i; } canvas.SetPixels(pos.x, pos.y, tileSize.x, tileSize.y, brush); } var imageExporter = new PNGWriter(); exporter = new PixelDataExporter(fullFileName, canvas.pixels, w, h, colors, imageExporter); exporter.CalculateSteps(); }
/// <summary> /// Generates a hold note alongside normal notes. /// </summary> /// <param name="startTime">The start time of notes.</param> /// <returns>The <see cref="Pattern"/> containing the hit objects.</returns> private Pattern generateHoldAndNormalNotes(double startTime) { // - - - - // ■ x x - // ■ - x x // ■ x - x // ■ - x x var pattern = new Pattern(); int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns) { while (PreviousPattern.ColumnHasObject(holdColumn)) { holdColumn = Random.Next(RandomStart, TotalColumns); } } // Create the hold note addToPattern(pattern, holdColumn, startTime, endTime); int nextColumn = Random.Next(RandomStart, TotalColumns); int noteCount; if (ConversionDifficulty > 6.5) { noteCount = GetRandomNoteCount(0.63, 0); } else if (ConversionDifficulty > 4) { noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0.12 : 0.45, 0); } else if (ConversionDifficulty > 2.5) { noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0 : 0.24, 0); } else { noteCount = 0; } noteCount = Math.Min(TotalColumns - 1, noteCount); bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP); var rowPattern = new Pattern(); for (int i = 0; i <= spanCount; i++) { if (!(ignoreHead && startTime == HitObject.StartTime)) { for (int j = 0; j < noteCount; j++) { while (rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn) { nextColumn = Random.Next(RandomStart, TotalColumns); } addToPattern(rowPattern, nextColumn, startTime, startTime); } } pattern.Add(rowPattern); rowPattern.Clear(); startTime += segmentDuration; } return(pattern); }