public static double[] Smooth([NotNull] double[] spectrum, double cutOff, IntRegion region) { if (spectrum == null) throw new ArgumentNullException("spectrum"); if (cutOff <= 0) throw new ArgumentException("cutOff"); var result = FFT_smoothing(spectrum, cutOff, region); return result; }
void build(CGVMesh vmesh, CGVolume vol, IntRegion subset) { // Because each Material ID forms a submesh // Do we need to calculate localU? if (GenerateUV) { System.Array.Resize <Vector2>(ref vmesh.UV, vmesh.Count); } // Prepare Submeshes prepareSubMeshes(vmesh, groupsByMatID, subset.Length, ref m_Material); //prepareSubMeshes(vmesh, groupsByMatID, vol.Count - 1, ref m_Material); SamplePointsMaterialGroupCollection col; SamplePointsMaterialGroup grp; int vtIdx = 0; int[] triIdx = new int[groupsByMatID.Count]; // triIdx for each submesh // for all sample segments (except the last) along the path, create Triangles to the next segment for (int sample = subset.From; sample < subset.To; sample++) { // for each submesh (collection) for (int subMeshIdx = 0; subMeshIdx < groupsByMatID.Count; subMeshIdx++) { col = groupsByMatID[subMeshIdx]; // create UV and triangles for all groups in submesh for (int g = 0; g < col.Count; g++) { grp = col[g]; if (GenerateUV) { createMaterialGroupUV(ref vmesh, ref vol, ref grp, col.MaterialID, col.AspectCorrection, sample, vtIdx); } for (int p = 0; p < grp.Patches.Count; p++) { createPatchTriangles(ref vmesh.SubMeshes[subMeshIdx].Triangles, ref triIdx[subMeshIdx], vtIdx + grp.Patches[p].Start, grp.Patches[p].Count, vol.CrossSize, ReverseTriOrder); } } } vtIdx += vol.CrossSize; } // UV for last path segment if (GenerateUV) { // for each submesh (collection) for (int subMeshIdx = 0; subMeshIdx < groupsByMatID.Count; subMeshIdx++) { col = groupsByMatID[subMeshIdx]; // create triangles for (int g = 0; g < col.Count; g++) { grp = col[g]; createMaterialGroupUV(ref vmesh, ref vol, ref grp, col.MaterialID, col.AspectCorrection, subset.To, vtIdx); } } } }
public static double[] FFT_smoothing([NotNull] double[] x, double cutOff, IntRegion tr) { if (x == null) throw new ArgumentNullException("x"); var n = tr.Width; var nn = GetNn(n); var chH = tr.Max; var chL = tr.Min; var br = new double[8192]; var y = new double[x.Length]; var window = GetWindow(nn, n); var offset = Convert.ToInt32((2*nn - chL - chH - 1)/2); var chLo = chL + offset; var chHo = chH + offset; //Extend Left side var points = from i in Enumerable.Range(chL, Convert.ToInt32(cutOff)) select new Point(i, x[i]); var func = Statistics.GetLeastSquaresLine(points).Function; for (var i = 0; i <= chLo - 1; i++) br[i] = func(i - offset)*window[i]; //Spectrum Main Body for (var i = chLo; i <= chHo; i++) br[i] = x[i - offset]*window[i]; //Extend Right side points = from i in Enumerable.Range(Convert.ToInt32(chH - cutOff + 1), Convert.ToInt32(cutOff)) select new Point(i, x[i]); func = Statistics.GetLeastSquaresLine(points).Function; for (var i = chHo; i <= nn*2 - 1; i++) br[i] = func(i - offset)*window[i]; //FFT var z = ArrayFactory.ByFunc(i => new Complex(br[i], 0), 4096); z = CalcFft(z, false); //High Frequency Cutoff var fc = Convert.ToInt32(nn*2/cutOff); var i0 = fc*2; for (var i = 1; i <= nn; i++) { var f = i > i0 ? 0 : (Math.Cos(Math.PI*i/fc/2) + 1)/2; z[i] = f*z[i]; z[nn*2 - i] = f*z[nn*2 - i]; } //IFFT z = CalcFft(z, true); var y1 = z.Select(Complex.Abs).ToArray(); foreach (var i in tr) y[i] = y1[i + offset]/window[i + offset]; return y; }
public static double[] Calculate([NotNull] double[] spectrum, [CanBeNull] double[] model, double param1, double param2, IntRegion target) { if (spectrum == null) throw new ArgumentException("spectrum"); model = model ?? ArrayFactory.Repeat(1.0, spectrum.Length); var background = ArrayFactory.Repeat(1.0, spectrum.Length); Calculate(spectrum, model, ref background, param1, param2, target); return background; }
private static void Calculate([NotNull] double[] spectrumInCount, [NotNull] double[] model, [NotNull] ref double[] backGround, double bgParm1, double bgParm2, IntRegion tr) { if (spectrumInCount == null) throw new ArgumentNullException("spectrumInCount"); if (backGround == null) throw new ArgumentNullException("backGround"); if (model == null) throw new ArgumentNullException("model"); var buffer = new double[4096]; var background0 = new double[4096]; var statisticalError = new double[4096]; //Initialization double b1 = 0; var ch0 = model.FirstIndex(d => d > 0); for (var ch = ch0; ch <= Convert.ToInt32(ch0 + bgParm1); ch++) { if (spectrumInCount[ch] > b1 & !model[ch].IsZero()) b1 = spectrumInCount[ch]/model[ch]; } foreach (var ch in tr) { if (model[ch].IsZero()) { backGround[ch] = b1; statisticalError[ch] = 0; } else { backGround[ch] = spectrumInCount[ch]/model[ch]; statisticalError[ch] = Math.Sqrt(spectrumInCount[ch])/model[ch]*bgParm2; } } var count = 0; var stage = 1; double multiplier = 3; //Loop do { foreach (var ch in tr) background0[ch] = backGround[ch]; foreach (var ch in tr) { var x = spectrumInCount[ch]/model[ch]; var b = backGround[ch]; if (model[ch].IsZero() | x > b + (statisticalError[ch]*multiplier)) buffer[ch] = b; else buffer[ch] = x; } backGround = Smoothing.FFT_smoothing(buffer, bgParm1, tr); var isConverged = false; foreach (var ch in tr.Where(ch => !background0[ch].IsZero())) { if (backGround[ch].IsNear(background0[ch], background0[ch]*0.005)) isConverged = true; } count++; switch (stage) { case 1: if (count == 100 || !isConverged) { stage = 2; multiplier = 1; count = 0; } break; case 2: if (count == 100 || !isConverged) stage = 0; break; } } while (stage != 0); foreach (var ch in tr) backGround[ch] *= model[ch]; }
public void DoPeakFitting(double liveTime) { if (Input == null) throw new InvalidOperationException(); var region = new IntRegion((int) DataProcessRegion.X1, (int) DataProcessRegion.X2); Smoothed = Smoothing.Smooth(Input, SmoothingCutoffFrequency, region); Background = PeakFitting.Background.Calculate( Smoothed, null, BackgroundParameter0, BackgroundParameter1, region); var pf = new PeakFitting.PeakFitting {Calibration = Calibration, LineInfo = LineInfo}; var result = pf.PeakFit(Input, Background, region, liveTime); Calibration = pf.Calibration; PeakFit = pf.PeakFitSpectrum; FittingResult = result.ToArray(); }
private static bool PeakFittingMain( [NotNull] IEnumerable<PeakCollection> peakGroups, [NotNull] double[] spectrum1, [NotNull] double[] spectrum2, [NotNull] double[] netSpectrum, IntRegion tr) { if (peakGroups == null) throw new ArgumentNullException("peakGroups"); if (spectrum1 == null) throw new ArgumentNullException("spectrum1"); if (spectrum2 == null) throw new ArgumentNullException("spectrum2"); if (netSpectrum == null) throw new ArgumentNullException("netSpectrum"); var pg = peakGroups.ToArray(); var paramCount = pg.Length; if (paramCount >= tr.Width) return false; try { foreach (var i in Enumerable.Range(0, 20)) { var a = new double[paramCount, paramCount]; var b = new double[paramCount]; foreach (var ch in tr) { // ピークを重ねあわせて、スペクトルを作る。 spectrum2[ch] = 0; var da = new double[paramCount]; foreach (var l in Enumerable.Range(0, paramCount)) { da[l] = PeaksForSingleElement(ch, pg[l]); //FDH spectrum2[ch] += pg[l].Height*da[l]; } foreach (var l in Enumerable.Range(0, paramCount)) { for (var m = l; m <= paramCount - 1; m++) a[l, m] += da[l]*da[m]; b[l] += da[l]*(netSpectrum[ch] - spectrum2[ch]); } } a = a.Synmetric(); var ans = Matrix.GaussJordanMethod(a, b); foreach (var l in Enumerable.Range(0, paramCount)) pg[l].Height += ans[l]; var canContinue = Enumerable.Range(0, paramCount).Any(l => Math.Abs(ans[l]) > pg[l].Height*0.0001); if (!canContinue) break; } foreach (var ch in tr) spectrum2[ch] += spectrum1[ch]; return true; } catch (Exception) { return false; } }
public IEnumerable<LineIntensity> PeakFit( [NotNull] double[] input, [NotNull] double[] background, IntRegion targetRegion, double liveTime) { if (input == null) throw new ArgumentNullException("input"); if (background == null) throw new ArgumentNullException("background"); if (Calibration == null) throw new InvalidOperationException("Calibration is null"); if (LineInfo == null) throw new InvalidOperationException("LineInfo is null"); var net = new double[input.Length]; foreach (var i in Enumerable.Range(0, Math.Min(input.Length, background.Length))) net[i] = input[i] - background[i]; var peakCollections = ToPeakCollections(LineInfo, Calibration, net); var result = PeakFittingMain(peakCollections, input, background, net, targetRegion); var list = new List<LineIntensity>(); if (result) { foreach (var p in peakCollections) { var ph = p.Height > 0 ? p.Height : 0; var pii = ph > 0 ? ph*Math.Sqrt(Math.PI/p.First().Height) : 0; var lic = LineInfo.First(li => li.Name == p.Name); list.Add(new LineIntensity(lic, pii/liveTime)); } } PeakFitSpectrum = background; return list; }
void build(CGVMesh vmesh, CGVolume vol, IntRegion subset) { // Because each Material ID forms a submesh // Do we need to calculate localU? if (GenerateUV) { System.Array.Resize<Vector2>(ref vmesh.UV, vmesh.Count); } // Prepare Submeshes prepareSubMeshes(vmesh, groupsByMatID, subset.Length, ref m_Material); //prepareSubMeshes(vmesh, groupsByMatID, vol.Count - 1, ref m_Material); SamplePointsMaterialGroupCollection col; SamplePointsMaterialGroup grp; int vtIdx = 0; int[] triIdx = new int[groupsByMatID.Count]; // triIdx for each submesh // for all sample segments (except the last) along the path, create Triangles to the next segment for (int sample = subset.From; sample < subset.To; sample++) { // for each submesh (collection) for (int subMeshIdx = 0; subMeshIdx < groupsByMatID.Count; subMeshIdx++) { col = groupsByMatID[subMeshIdx]; // create UV and triangles for all groups in submesh for (int g = 0; g < col.Count; g++) { grp = col[g]; if (GenerateUV) createMaterialGroupUV(ref vmesh, ref vol, ref grp, col.MaterialID, col.AspectCorrection, sample, vtIdx); for (int p = 0; p < grp.Patches.Count; p++) createPatchTriangles(ref vmesh.SubMeshes[subMeshIdx].Triangles, ref triIdx[subMeshIdx], vtIdx+grp.Patches[p].Start, grp.Patches[p].Count, vol.CrossSize, ReverseTriOrder); } } vtIdx += vol.CrossSize; } // UV for last path segment if (GenerateUV) { // for each submesh (collection) for (int subMeshIdx = 0; subMeshIdx < groupsByMatID.Count; subMeshIdx++) { col = groupsByMatID[subMeshIdx]; // create triangles for (int g = 0; g < col.Count; g++) { grp = col[g]; createMaterialGroupUV(ref vmesh, ref vol, ref grp, col.MaterialID, col.AspectCorrection, subset.To, vtIdx); } } } }