public void Execute() { SySal.Processing.QuickMapping.QuickMapper QM = new SySal.Processing.QuickMapping.QuickMapper(); SySal.Processing.QuickMapping.Configuration C = QM.Config as SySal.Processing.QuickMapping.Configuration; C.FullStatistics = false; C.Name = ""; C.PosTol = m_PosTol; C.SlopeTol = m_SlopeTol; C.UseAbsoluteReference = true; m_Pairs = QM.Match(m_rinfo, m_winfo, m_DZ, m_PosSweep, m_PosSweep); }
private void Compute(bool comp_x, bool comp_y, object btn) { m_Running = true; EnableButtons(btn); m_Stop = false; pbProgress.Value = 0.0; System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate() { try { SySal.Processing.QuickMapping.QuickMapper QM = new SySal.Processing.QuickMapping.QuickMapper(); SySal.Processing.QuickMapping.Configuration qmc = (SySal.Processing.QuickMapping.Configuration)QM.Config; qmc.FullStatistics = false; qmc.UseAbsoluteReference = true; qmc.PosTol = S.PosTolerance; qmc.SlopeTol = 1.0; QM.Config = qmc; System.Collections.ArrayList xconv = new System.Collections.ArrayList(); System.Collections.ArrayList yconv = new System.Collections.ArrayList(); int sfi; for (sfi = 0; sfi < SummaryFiles.Length; sfi++) { QuasiStaticAcquisition Q = new QuasiStaticAcquisition(SummaryFiles[sfi]); foreach (QuasiStaticAcquisition.Sequence seq in Q.Sequences) { int ly; SySal.Imaging.Cluster[] prevC = FilterClusters(seq.Layers[0].ReadClusters()); SySal.Imaging.Cluster[] nextC = null; SySal.BasicTypes.Vector prevP = seq.Layers[0].Position; SySal.BasicTypes.Vector nextP = new SySal.BasicTypes.Vector(); for (ly = 1; ly < seq.Layers.Length; ly++) { if (m_Stop) { throw new Exception("Stopped."); } nextC = FilterClusters(seq.Layers[ly].ReadClusters()); nextP = seq.Layers[ly].Position; this.Invoke(new dSetValue(SetValue), 100.0 * (((double)seq.Id + (double)(ly - 1) / (double)(seq.Layers.Length - 1)) / (double)(Q.Sequences.Length) + sfi) / SummaryFiles.Length); SySal.BasicTypes.Vector2 dp = new SySal.BasicTypes.Vector2(seq.Layers[ly].Position - seq.Layers[ly - 1].Position); SySal.BasicTypes.Vector2 dp1 = dp; dp1.X /= S.MinConv; dp1.Y /= S.MinConv; SySal.BasicTypes.Vector2 dp2 = dp; dp2.X /= S.MaxConv; dp2.Y /= S.MaxConv; SySal.BasicTypes.Vector2 da = new SySal.BasicTypes.Vector2(); da.X = 0.5 * (dp1.X + dp2.X); da.Y = 0.5 * (dp1.Y + dp2.Y); SySal.BasicTypes.Vector2 dext = new SySal.BasicTypes.Vector2(); dext.X = Math.Abs(dp1.X - dp2.X); dext.Y = Math.Abs(dp1.Y - dp2.Y); SySal.Tracking.MIPEmulsionTrackInfo[] prevmap = new SySal.Tracking.MIPEmulsionTrackInfo[prevC.Length]; int i; for (i = 0; i < prevC.Length; i++) { SySal.Tracking.MIPEmulsionTrackInfo info = new SySal.Tracking.MIPEmulsionTrackInfo(); info.Intercept.X = prevC[i].X; info.Intercept.Y = prevC[i].Y; prevmap[i] = info; } SySal.Tracking.MIPEmulsionTrackInfo[] nextmap = new SySal.Tracking.MIPEmulsionTrackInfo[nextC.Length]; for (i = 0; i < nextC.Length; i++) { nextmap[i] = new SySal.Tracking.MIPEmulsionTrackInfo(); } double[,] convopt = new double[, ] { { 1.0, 1.0 }, { -1.0, 1.0 }, { -1.0, -1.0 }, { 1.0, -1.0 } }; int o; SySal.Scanning.PostProcessing.PatternMatching.TrackPair[] bestpairs = new SySal.Scanning.PostProcessing.PatternMatching.TrackPair[0]; SySal.BasicTypes.Vector2 bestda = new SySal.BasicTypes.Vector2(); for (o = 0; o < convopt.GetLength(0); o++) { try { for (i = 0; i < nextC.Length; i++) { SySal.Tracking.MIPEmulsionTrackInfo info = nextmap[i]; info.Intercept.X = nextC[i].X + da.X * convopt[o, 0]; info.Intercept.Y = nextC[i].Y + da.Y * convopt[o, 1]; nextmap[i] = info; } SySal.Scanning.PostProcessing.PatternMatching.TrackPair[] prs = QM.Match(prevmap, nextmap, 0.0, dext.X, dext.Y); if (prs.Length > bestpairs.Length) { bestda.X = da.X * convopt[o, 0]; bestda.Y = da.Y * convopt[o, 1]; bestpairs = prs; } } catch (Exception xc) { } } if (bestpairs.Length >= S.MinMatches) { double[] deltas = new double[bestpairs.Length]; for (i = 0; i < bestpairs.Length; i++) { deltas[i] = bestpairs[i].First.Info.Intercept.X - nextC[bestpairs[i].Second.Index].X; } bestda.X = NumericalTools.Fitting.Quantiles(deltas, new double[] { 0.5 })[0]; if (bestda.X != 0.0) { double v = dp.X / bestda.X; int pos = xconv.BinarySearch(v); if (pos < 0) { pos = ~pos; } xconv.Insert(pos, v); } for (i = 0; i < bestpairs.Length; i++) { deltas[i] = bestpairs[i].First.Info.Intercept.Y - nextC[bestpairs[i].Second.Index].Y; } bestda.Y = NumericalTools.Fitting.Quantiles(deltas, new double[] { 0.5 })[0]; if (bestda.Y != 0.0) { double v = dp.Y / bestda.Y; int pos = yconv.BinarySearch(v); if (pos < 0) { pos = ~pos; } yconv.Insert(pos, v); } if (comp_x && xconv.Count > 0) { int bmin, bmax; bmin = (int)Math.Ceiling(xconv.Count * 0.16); bmax = (int)Math.Floor(xconv.Count * 0.84); if (bmax < bmin) { bmin = bmax; } double[] sample1s = (double[])xconv.GetRange(bmin, bmax - bmin + 1).ToArray(typeof(double)); XConv = NumericalTools.Fitting.Average(sample1s); this.Invoke(new dSetConv(SetConv), new object[] { true, XConv, 0.5 * (sample1s[sample1s.Length - 1] - sample1s[0]) / Math.Sqrt(sample1s.Length) }); } if (comp_y && yconv.Count > 0) { int bmin, bmax; bmin = (int)Math.Ceiling(yconv.Count * 0.16); bmax = (int)Math.Floor(yconv.Count * 0.84); if (bmax < bmin) { bmin = bmax; } double[] sample1s = (double[])yconv.GetRange(bmin, bmax - bmin + 1).ToArray(typeof(double)); YConv = NumericalTools.Fitting.Average(sample1s); this.Invoke(new dSetConv(SetConv), new object[] { false, YConv, 0.5 * (sample1s[sample1s.Length - 1] - sample1s[0]) / Math.Sqrt(sample1s.Length) }); } } prevP = nextP; prevC = nextC; } } } } catch (Exception xc1) { iLog.Log("Compute", xc1.ToString()); } m_Running = false; this.Invoke(new dEnableButtons(EnableButtons), btn); })); thread.Start(); }
public SySal.Imaging.Grain3D[] MakeGrainsFromClusters(SySal.Imaging.Cluster3D[][] cls, SySal.BasicTypes.Vector[] positions) { this.DemagCoefficients = new double[0]; this.MatchDX = new double[0]; this.MatchDY = new double[0]; System.Collections.ArrayList adx = new System.Collections.ArrayList(); System.Collections.ArrayList ady = new System.Collections.ArrayList(); int i; int halfw = (int)(C.ImageWidth / 2); int halfh = (int)(C.ImageHeight / 2); ChainCluster[][] planes = new ChainCluster[positions.Length][]; System.Collections.ArrayList demags = new System.Collections.ArrayList(); int plane; double c2x, c2y; double px0 = positions[0].X; double py0 = positions[0].Y; double pz0 = positions[0].Z; for (plane = 0; plane < planes.Length; plane++) { if (Progress != null) { Progress((double)plane / (double)planes.Length * 0.5); } if (ShouldStop != null && ShouldStop()) { return(null); } planes[plane] = new ChainCluster[cls[plane].Length]; SySal.Imaging.Cluster3D [] cplanes = cls[plane]; double px = positions[plane].X; double py = positions[plane].Y; double pz = positions[plane].Z; double pxd = px - px0; double pyd = py - py0; double pzd = pz - pz0; double dmz = OptimizeDemagCoefficient ? 1 : Math.Pow(1.0 + C.DMagDZ, pzd); for (i = 0; i < planes[plane].Length; i++) { ChainCluster cc = new ChainCluster(); cc.Cluster = cplanes[i].Cluster; cc.Id = i; cc.Plane = plane; cc.Z = pz; cc.Cluster.X = (cc.Cluster.X - halfw) * C.Pixel2Micron.X * dmz; // +px; cc.Cluster.Y = (cc.Cluster.Y - halfh) * C.Pixel2Micron.Y * dmz; // +py; c2y = cc.Cluster.X * cc.Cluster.X * C.XYCurvature * cc.Cluster.Y; c2x = cc.Cluster.Y * cc.Cluster.Y * C.XYCurvature * cc.Cluster.X; cc.Cluster.X += c2x; cc.Cluster.Y += c2y; cc.Z += C.ZCurvature * (cc.Cluster.X * cc.Cluster.X + cc.Cluster.Y * cc.Cluster.Y); cc.Cluster.X += pxd; cc.Cluster.Y += pyd; planes[plane][i] = cc; } } if (Progress != null) { Progress(0.5); } for (i = 0; i < planes.Length - 1; i++) { if (Progress != null) { Progress(0.5 + 0.5 * (double)i / (double)(planes.Length - 1)); } if (ShouldStop != null && ShouldStop()) { return(null); } SySal.Tracking.MIPEmulsionTrackInfo[] t1 = new SySal.Tracking.MIPEmulsionTrackInfo[planes[i].Length]; SySal.Tracking.MIPEmulsionTrackInfo[] t2 = new SySal.Tracking.MIPEmulsionTrackInfo[planes[i + 1].Length]; int j; for (j = 0; j < t1.Length; j++) { ChainCluster cc = planes[i][j]; SySal.Tracking.MIPEmulsionTrackInfo info = new SySal.Tracking.MIPEmulsionTrackInfo(); info.Count = (ushort)cc.Cluster.Area; info.AreaSum = (uint)j; info.Intercept.X = cc.Cluster.X; info.Intercept.Y = cc.Cluster.Y; info.Intercept.Z = 0.0; info.Slope.X = info.Slope.Y = info.Slope.Z = 0.0; t1[j] = info; } for (j = 0; j < t2.Length; j++) { ChainCluster cc = planes[i + 1][j]; SySal.Tracking.MIPEmulsionTrackInfo info = new SySal.Tracking.MIPEmulsionTrackInfo(); info.Count = (ushort)cc.Cluster.Area; info.AreaSum = (ushort)j;// cls.Id; info.Intercept.X = cc.Cluster.X + 2.0 * (C.ClusterMatchMaxOffset + C.ClusterMatchPositionTolerance); info.Intercept.Y = cc.Cluster.Y + 2.0 * (C.ClusterMatchMaxOffset + C.ClusterMatchPositionTolerance); info.Intercept.Z = 0.0; info.Slope.X = info.Slope.Y = info.Slope.Z = 0.0; t2[j] = info; } try { SySal.Processing.QuickMapping.Configuration qmc = (SySal.Processing.QuickMapping.Configuration)QM.Config; qmc.FullStatistics = false; qmc.UseAbsoluteReference = true; qmc.PosTol = C.ClusterMatchPositionTolerance * 0.5; qmc.SlopeTol = 1.0; QM.Config = qmc; int bkg = QM.Match(t1, t2, 0.0, C.ClusterMatchPositionTolerance * 0.25, C.ClusterMatchPositionTolerance * 0.25).Length; for (j = 0; j < t2.Length; j++) { ChainCluster cc = planes[i + 1][j]; t2[j].Intercept.X = cc.Cluster.X; t2[j].Intercept.Y = cc.Cluster.Y; } qmc.PosTol = C.ClusterMatchMaxOffset * 0.5; QM.Config = qmc; SySal.Scanning.PostProcessing.PatternMatching.TrackPair[] tp = QM.Match(t1, t2, 0.0, C.ClusterMatchMaxOffset * 0.25, C.ClusterMatchMaxOffset * 0.25); double deltax = 0.0, deltay = 0.0, demagx = 0.0, demagy = 0.0; double dummy = 0.0; double q = (1.0 - (double)bkg / (double)tp.Length) * 0.25; double[,] deltas = new double[tp.Length, 4]; for (j = 0; j < tp.Length; j++) { deltas[j, 0] = tp[j].Second.Info.Intercept.X; deltas[j, 1] = tp[j].Second.Info.Intercept.Y; deltas[j, 2] = tp[j].First.Info.Intercept.X - tp[j].Second.Info.Intercept.X; deltas[j, 3] = tp[j].First.Info.Intercept.Y - tp[j].Second.Info.Intercept.Y; } int[] ids = NumericalTools.Fitting.PeakDataSel(deltas, new double[] { Math.Abs(halfw * C.Pixel2Micron.X) * 0.25, Math.Abs(halfh * C.Pixel2Micron.Y) * 0.25, C.ClusterMatchPositionTolerance * 0.5, C.ClusterMatchPositionTolerance * 0.5 }, -1.0, q); double[] ws = new double[ids.Length]; double[] dws = new double[ids.Length]; for (j = 0; j < ids.Length; j++) { ws[j] = deltas[ids[j], 0]; dws[j] = deltas[ids[j], 2]; } NumericalTools.ComputationResult resx = NumericalTools.Fitting.LinearFitSE(ws, dws, ref demagx, ref deltax, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy); for (j = 0; j < ids.Length; j++) { ws[j] = deltas[ids[j], 1]; dws[j] = deltas[ids[j], 3]; } double dmagdeltaz = positions[i + 1].Z - positions[i].Z; NumericalTools.ComputationResult resy = NumericalTools.Fitting.LinearFitSE(ws, dws, ref demagy, ref deltay, ref dummy, ref dummy, ref dummy, ref dummy, ref dummy); if (resx == NumericalTools.ComputationResult.OK && resy == NumericalTools.ComputationResult.OK) { demags.Add(Math.Log(1.0 + demagx) / dmagdeltaz); demags.Add(Math.Log(1.0 + demagy) / dmagdeltaz); } for (j = 0; j < t2.Length; j++) { ChainCluster cc = planes[i + 1][j]; t2[j].Intercept.X += deltax; t2[j].Intercept.Y += deltay; cc.Cluster.X += deltax; cc.Cluster.Y += deltay; } qmc.PosTol = C.ClusterMatchPositionTolerance * 0.5; QM.Config = qmc; tp = QM.Match(t1, t2, 0.0, C.ClusterMatchPositionTolerance * 0.25, C.ClusterMatchPositionTolerance * 0.25); foreach (SySal.Scanning.PostProcessing.PatternMatching.TrackPair tp1 in tp) { if (planes[i][tp1.First.Info.AreaSum].Next == null && planes[i + 1][tp1.Second.Info.AreaSum].PreviousSize == 0 && (planes[i][tp1.First.Info.AreaSum].Cluster.Area < planes[i + 1][tp1.Second.Info.AreaSum].Cluster.Area && planes[i][tp1.First.Info.AreaSum].Cluster.Area < planes[i][tp1.First.Info.AreaSum].PreviousSize) == false) { planes[i][tp1.First.Info.AreaSum].Next = planes[i + 1][tp1.Second.Info.AreaSum]; planes[i + 1][tp1.Second.Info.AreaSum].PreviousSize = planes[i][tp1.First.Info.AreaSum].Cluster.Area; adx.Add(tp1.First.Info.Intercept.X - tp1.Second.Info.Intercept.X); ady.Add(tp1.First.Info.Intercept.Y - tp1.Second.Info.Intercept.Y); } } } catch (Exception) { } } System.Collections.ArrayList achains = new System.Collections.ArrayList(); System.Collections.ArrayList grains = new System.Collections.ArrayList(); foreach (ChainCluster[] cplane in planes) { foreach (ChainCluster cc in cplane) { if (cc.Next != null) { cc.Next.Id = -1; } if (cc.Id >= 0) { achains.Add(cc); } } } foreach (ChainCluster cc in achains) { int totalc = 1; ChainCluster cc1 = cc.Next; while (cc1 != null) { cc1 = cc1.Next; totalc++; } SySal.Imaging.Cluster3D[] cl3d = new SySal.Imaging.Cluster3D[totalc]; totalc = 0; cc1 = cc; uint gvolume = 0; while (cc1 != null) { double dmz = OptimizeDemagCoefficient ? 1 : Math.Pow(1.0 + C.DMagDZ, positions[cc1.Plane].Z - positions[0].Z); cl3d[totalc].Cluster = cc1.Cluster; cl3d[totalc].Cluster.X = cl3d[totalc].Cluster.X / dmz + positions[0].X; cl3d[totalc].Cluster.Y = cl3d[totalc].Cluster.Y / dmz + positions[0].Y; cl3d[totalc].Layer = (uint)cc1.Plane; cl3d[totalc].Z = cc1.Z; gvolume += cc1.Cluster.Area; cc1 = cc1.Next; totalc++; } if (gvolume < C.MinGrainVolume) { continue; } grains.Add(SySal.Imaging.Grain3D.FromClusterCenters(cl3d)); } this.DemagCoefficients = (double[])demags.ToArray(typeof(double)); this.MatchDX = (double[])adx.ToArray(typeof(double)); this.MatchDY = (double[])ady.ToArray(typeof(double)); if (Progress != null) { Progress(1.0); } return((SySal.Imaging.Grain3D[])grains.ToArray(typeof(SySal.Imaging.Grain3D))); }
private static void OneZoneIntercalibration(string [] args, ref SySal.DAQSystem.Scanning.IntercalibrationInfo intercal, bool rewrite) { int i, j, n; int MinMatches = Convert.ToInt32(args[8]); SySal.Scanning.Plate.IO.OPERA.LinkedZone reflz = (SySal.Scanning.Plate.IO.OPERA.LinkedZone)SySal.OperaPersistence.Restore(args[1], typeof(SySal.Scanning.Plate.IO.OPERA.LinkedZone)); SySal.Tracking.MIPEmulsionTrackInfo [] refzone = new SySal.Tracking.MIPEmulsionTrackInfo[reflz.Length]; for (i = 0; i < refzone.Length; i++) { refzone[i] = reflz[i].Info; } reflz = null; GC.Collect(); SySal.Scanning.Plate.IO.OPERA.LinkedZone caliblz = (SySal.Scanning.Plate.IO.OPERA.LinkedZone)SySal.OperaPersistence.Restore(args[2], typeof(SySal.Scanning.Plate.IO.OPERA.LinkedZone)); SySal.Tracking.MIPEmulsionTrackInfo [] calibzone = new SySal.Tracking.MIPEmulsionTrackInfo[caliblz.Length]; for (i = 0; i < calibzone.Length; i++) { calibzone[i] = caliblz[i].Info; } if (!rewrite) { caliblz = null; } GC.Collect(); SySal.Processing.QuickMapping.QuickMapper QMap = new SySal.Processing.QuickMapping.QuickMapper(); SySal.Processing.QuickMapping.Configuration C = (SySal.Processing.QuickMapping.Configuration)QMap.Config; double postol = Convert.ToDouble(args[4], System.Globalization.CultureInfo.InvariantCulture); double leverarm = Convert.ToDouble(args[6], System.Globalization.CultureInfo.InvariantCulture); C.PosTol = postol + leverarm; C.SlopeTol = Convert.ToDouble(args[5], System.Globalization.CultureInfo.InvariantCulture); QMap.Config = C; double ZProj = Convert.ToDouble(args[3], System.Globalization.CultureInfo.InvariantCulture); double maxoffset = Convert.ToDouble(args[7], System.Globalization.CultureInfo.InvariantCulture); SySal.Scanning.PostProcessing.PatternMatching.TrackPair [] pairs = QMap.Match(refzone, calibzone, ZProj, maxoffset, maxoffset); if (pairs.Length < MinMatches) { Console.Error.WriteLine("Too few matching tracks: " + MinMatches.ToString() + " required, " + pairs.Length + " obtained. Aborting."); return; } Console.WriteLine("Matches: " + pairs.Length); n = pairs.Length; double [,] indep = new double[2, n]; double [] dep = new double[n]; double [] res = new double[3]; double dummy = 0.0; for (i = 0; i < n; i++) { indep[0, i] = ((SySal.Tracking.MIPEmulsionTrackInfo)(pairs[i].Second.Track)).Intercept.X - intercal.RX; indep[1, i] = ((SySal.Tracking.MIPEmulsionTrackInfo)(pairs[i].Second.Track)).Intercept.Y - intercal.RY; dep[i] = pairs[i].First.Info.Intercept.X - intercal.RX; } NumericalTools.Fitting.MultipleLinearRegression(indep, dep, ref res, ref dummy); Console.WriteLine("{0}\t{1}\t{2}\t{3}", res[0], res[1], res[2], dummy); intercal.TX = res[0]; intercal.MXX = res[1]; intercal.MXY = res[2]; for (i = 0; i < n; i++) { indep[0, i] = ((SySal.Tracking.MIPEmulsionTrackInfo)(pairs[i].Second.Track)).Intercept.X - intercal.RX; indep[1, i] = ((SySal.Tracking.MIPEmulsionTrackInfo)(pairs[i].Second.Track)).Intercept.Y - intercal.RY; dep[i] = pairs[i].First.Info.Intercept.Y - intercal.RY; } NumericalTools.Fitting.MultipleLinearRegression(indep, dep, ref res, ref dummy); Console.WriteLine("{0}\t{1}\t{2}\t{3}", res[0], res[1], res[2], dummy); intercal.TY = res[0]; intercal.MYX = res[1]; intercal.MYY = res[2]; System.Collections.ArrayList a_goodpairs = new System.Collections.ArrayList(); foreach (SySal.Scanning.PostProcessing.PatternMatching.TrackPair p in pairs) { dummy = Math.Abs(intercal.TX + intercal.MXX * (p.Second.Info.Intercept.X - intercal.RX) + intercal.MXY * (p.Second.Info.Intercept.Y - intercal.RY) - p.First.Info.Intercept.X + intercal.RX); if (dummy > postol) { continue; } dummy = Math.Abs(intercal.TY + intercal.MYX * (p.Second.Info.Intercept.X - intercal.RX) + intercal.MYY * (p.Second.Info.Intercept.Y - intercal.RY) - p.First.Info.Intercept.Y + intercal.RY); if (dummy > postol) { continue; } a_goodpairs.Add(p); } Console.WriteLine("remaining " + a_goodpairs.Count); SySal.Scanning.PostProcessing.PatternMatching.TrackPair [] goodpairs = (SySal.Scanning.PostProcessing.PatternMatching.TrackPair [])a_goodpairs.ToArray(typeof(SySal.Scanning.PostProcessing.PatternMatching.TrackPair)); n = goodpairs.Length; indep = new double[2, n]; dep = new double[n]; for (i = 0; i < n; i++) { indep[0, i] = ((SySal.Tracking.MIPEmulsionTrackInfo)(goodpairs[i].Second.Track)).Intercept.X - intercal.RX; indep[1, i] = ((SySal.Tracking.MIPEmulsionTrackInfo)(goodpairs[i].Second.Track)).Intercept.Y - intercal.RY; dep[i] = goodpairs[i].First.Info.Intercept.X - intercal.RX; } NumericalTools.Fitting.MultipleLinearRegression(indep, dep, ref res, ref dummy); Console.WriteLine("{0}\t{1}\t{2}\t{3}", res[0], res[1], res[2], dummy); intercal.TX = res[0]; intercal.MXX = res[1]; intercal.MXY = res[2]; for (i = 0; i < n; i++) { indep[0, i] = ((SySal.Tracking.MIPEmulsionTrackInfo)(goodpairs[i].Second.Track)).Intercept.X - intercal.RX; indep[1, i] = ((SySal.Tracking.MIPEmulsionTrackInfo)(goodpairs[i].Second.Track)).Intercept.Y - intercal.RY; dep[i] = goodpairs[i].First.Info.Intercept.Y - intercal.RY; } NumericalTools.Fitting.MultipleLinearRegression(indep, dep, ref res, ref dummy); Console.WriteLine("{0}\t{1}\t{2}\t{3}", res[0], res[1], res[2], dummy); intercal.TY = res[0]; intercal.MYX = res[1]; intercal.MYY = res[2]; CheckIntercalibration(intercal); if (rewrite) { MyTransformation.Transformation = intercal; SySal.OperaPersistence.Persist(args[2], new LinkedZone(caliblz)); } }
private static void ThreeZoneIntercalibration(string [] args, ref SySal.DAQSystem.Scanning.IntercalibrationInfo intercal, bool rewrite) { int i, n; int MinMatches = Convert.ToInt32(args[11]); SySal.Processing.QuickMapping.QuickMapper QMap = new SySal.Processing.QuickMapping.QuickMapper(); SySal.Processing.QuickMapping.Configuration C = (SySal.Processing.QuickMapping.Configuration)QMap.Config; C.PosTol = Convert.ToDouble(args[8], System.Globalization.CultureInfo.InvariantCulture); C.SlopeTol = Convert.ToDouble(args[9], System.Globalization.CultureInfo.InvariantCulture); QMap.Config = C; double ZProj = Convert.ToDouble(args[7], System.Globalization.CultureInfo.InvariantCulture); double maxoffset = Convert.ToDouble(args[10], System.Globalization.CultureInfo.InvariantCulture); MapPos [] mappositions = new MapPos[3]; SySal.Scanning.Plate.IO.OPERA.LinkedZone [] savezones = new SySal.Scanning.Plate.IO.OPERA.LinkedZone[3]; for (n = 0; n < 3; n++) { SySal.Scanning.Plate.IO.OPERA.LinkedZone reflz = (SySal.Scanning.Plate.IO.OPERA.LinkedZone)SySal.OperaPersistence.Restore(args[1 + n * 2], typeof(SySal.Scanning.Plate.IO.OPERA.LinkedZone)); SySal.Tracking.MIPEmulsionTrackInfo [] refzone = new SySal.Tracking.MIPEmulsionTrackInfo[reflz.Length]; for (i = 0; i < refzone.Length; i++) { refzone[i] = reflz[i].Info; } reflz = null; SySal.Scanning.Plate.IO.OPERA.LinkedZone caliblz = (SySal.Scanning.Plate.IO.OPERA.LinkedZone)SySal.OperaPersistence.Restore(args[2 + n * 2], typeof(SySal.Scanning.Plate.IO.OPERA.LinkedZone)); if (rewrite) { savezones[n] = caliblz; } SySal.Tracking.MIPEmulsionTrackInfo [] calibzone = new SySal.Tracking.MIPEmulsionTrackInfo[caliblz.Length]; for (i = 0; i < calibzone.Length; i++) { calibzone[i] = caliblz[i].Info; } caliblz = null; GC.Collect(); Console.Write("Zone #" + n.ToString() + " "); SySal.Scanning.PostProcessing.PatternMatching.TrackPair [] pairs = QMap.Match(refzone, calibzone, ZProj, maxoffset, maxoffset); if (pairs.Length < MinMatches) { Console.Error.WriteLine("Too few matching tracks: " + MinMatches.ToString() + " required, " + pairs.Length + " obtained. Aborting."); return; } Console.WriteLine("Matches: " + pairs.Length); mappositions[n].SetFromPairs(pairs); mappositions[n].X -= intercal.RX; mappositions[n].Y -= intercal.RY; } double x20 = mappositions[2].X - mappositions[0].X; double x10 = mappositions[1].X - mappositions[0].X; double y20 = mappositions[2].Y - mappositions[0].Y; double y10 = mappositions[1].Y - mappositions[0].Y; double det = 1.0 / (x10 * y20 - x20 * y10); double u20 = mappositions[2].DX - mappositions[0].DX; double v20 = mappositions[2].DY - mappositions[0].DY; double u10 = mappositions[1].DX - mappositions[0].DX; double v10 = mappositions[1].DY - mappositions[0].DY; intercal.MXX = (u10 * y20 - u20 * y10) * det; intercal.MXY = (u20 * x10 - u10 * x20) * det; intercal.MYX = (v10 * y20 - v20 * y10) * det; intercal.MYY = (v20 * x10 - v10 * x20) * det; intercal.TX = mappositions[0].DX - intercal.MXX * mappositions[0].X - intercal.MXY * mappositions[0].Y; intercal.TY = mappositions[0].DY - intercal.MYX * mappositions[0].X - intercal.MYY * mappositions[0].Y; intercal.MXX += 1.0; intercal.MYY += 1.0; CheckIntercalibration(intercal); if (rewrite) { MyTransformation.Transformation = intercal; for (n = 0; n < 3; n++) { SySal.OperaPersistence.Persist(args[2 + n * 2], new LinkedZone(savezones[n])); } } }
static void Main(string[] args) { if (args.Length != 13 && args.Length != 4 && args.Length != 2) { Console.WriteLine("usage: FlattenTLG.exe <cell map> <TLG to be flattened> <output TLG> <min matches>"); Console.WriteLine(" or"); Console.WriteLine("usage: FlattenTLG.exe <cell map> <min matches>"); Console.WriteLine(" (opens a console to query the transformation map generator)"); Console.WriteLine(" or"); Console.WriteLine("usage: FlattenTLG.exe <reference TLG (supposed flat)> <TLG to be flattened> <output TLG> <cell size> <slope tol> <pos tol> <pos sweep> <z projection> <selection string> <min matches> <z adjust> <z step> <parallel (true|false)>"); Console.WriteLine("Selection function variables:"); foreach (SelFunc sf in KnownFunctions) { Console.WriteLine(sf.Name + " -> " + sf.Desc); } return; } bool usereadymap = (args.Length < 13); bool useconsole = (args.Length == 2); string reftlg = args[0]; string worktlg = useconsole ? "" : args[1]; string outtlg = useconsole ? "" : args[2]; uint MinMatches = 0; int xcells = 0; int ycells = 0; double cellsize = 0.0; int ix, iy; int i, j, k; SySal.BasicTypes.Vector2 Center = new SySal.BasicTypes.Vector2(); SySal.BasicTypes.Rectangle WorkRect; SySal.Scanning.Plate.IO.OPERA.LinkedZone worklz = null; if (useconsole == false) { worklz = SySal.DataStreams.OPERALinkedZone.FromFile(worktlg); WorkRect = worklz.Extents; } else { WorkRect = new SySal.BasicTypes.Rectangle(); } SySal.BasicTypes.Rectangle RefRect = new SySal.BasicTypes.Rectangle(); RTrackCell[,] WorkCells; if (usereadymap) { MinMatches = Convert.ToUInt32(args[useconsole ? 1 : 3]); System.IO.StreamReader cr = new System.IO.StreamReader(args[0]); while (cr.EndOfStream == false) { System.Text.RegularExpressions.Match m = rx_CellMap.Match(cr.ReadLine()); if (m.Success) { RefRect.MinX = Convert.ToDouble(m.Groups[1].Value); RefRect.MaxX = Convert.ToDouble(m.Groups[2].Value); RefRect.MinY = Convert.ToDouble(m.Groups[3].Value); RefRect.MaxY = Convert.ToDouble(m.Groups[4].Value); cellsize = Convert.ToDouble(m.Groups[5].Value); xcells = Convert.ToInt32(m.Groups[6].Value); ycells = Convert.ToInt32(m.Groups[7].Value); break; } } Center.X = 0.5 * (RefRect.MinX + RefRect.MaxX); Center.Y = 0.5 * (RefRect.MinY + RefRect.MaxY); WorkCells = new RTrackCell[xcells, ycells]; for (ix = 0; ix < xcells; ix++) { for (iy = 0; iy < ycells; iy++) { SySal.BasicTypes.Rectangle rect = new SySal.BasicTypes.Rectangle(); rect.MinX = RefRect.MinX + ix * cellsize; rect.MaxX = rect.MinX + cellsize; rect.MinY = RefRect.MinY + iy * cellsize; rect.MaxY = rect.MinY + cellsize; WorkCells[ix, iy] = new RTrackCell(rect, Center); WorkCells[ix, iy].Result = NumericalTools.ComputationResult.InvalidInput; } } while (cr.EndOfStream == false) { System.Text.RegularExpressions.Match m = rx_Cell.Match(cr.ReadLine()); if (m.Success) { ix = Convert.ToInt32(m.Groups[1].Value); iy = Convert.ToInt32(m.Groups[2].Value); WorkCells[ix, iy].Result = NumericalTools.ComputationResult.OK; WorkCells[ix, iy].Matches = Convert.ToInt32(m.Groups[3].Value); WorkCells[ix, iy].Average.X = Convert.ToDouble(m.Groups[4].Value); WorkCells[ix, iy].Average.Y = Convert.ToDouble(m.Groups[5].Value); WorkCells[ix, iy].AlignInfo.MXX = Convert.ToDouble(m.Groups[6].Value); WorkCells[ix, iy].AlignInfo.MXY = Convert.ToDouble(m.Groups[7].Value); WorkCells[ix, iy].AlignInfo.MYX = Convert.ToDouble(m.Groups[8].Value); WorkCells[ix, iy].AlignInfo.MYY = Convert.ToDouble(m.Groups[9].Value); WorkCells[ix, iy].AlignInfo.TX = Convert.ToDouble(m.Groups[10].Value); WorkCells[ix, iy].AlignInfo.TY = Convert.ToDouble(m.Groups[11].Value); WorkCells[ix, iy].AlignInfo.TZ = Convert.ToDouble(m.Groups[12].Value); WorkCells[ix, iy].SlopeAlignInfo.X = Convert.ToDouble(m.Groups[13].Value); WorkCells[ix, iy].SlopeAlignInfo.Y = Convert.ToDouble(m.Groups[14].Value); } } cr.Close(); if (useconsole) { GridInterpolation G1 = new GridInterpolation(WorkCells, cellsize, RefRect, (int)MinMatches); Console.WriteLine("Type a pair of coordinates ( X Y ) to get the transformation map.\r\nEOF (CTRL+Z to exit)."); double x, y; string line; while ((line = Console.ReadLine()) != null) { System.Text.RegularExpressions.Match m = rx_XY.Match(line); x = Convert.ToDouble(m.Groups[1].Value); y = Convert.ToDouble(m.Groups[2].Value); SySal.BasicTypes.Vector dslope = new SySal.BasicTypes.Vector(); SySal.DAQSystem.Scanning.IntercalibrationInfo dpos = new SySal.DAQSystem.Scanning.IntercalibrationInfo(); bool result = G1.Evaluate(x, y, ref dslope, ref dpos); Console.WriteLine(x + " " + y + " -> " + (result ? "OK" : "FAILED") + " " + dpos.RX + " " + dpos.RY + " " + dpos.MXX + " " + dpos.MXY + " " + dpos.MYX + " " + dpos.MYY + " " + dpos.TX + " " + dpos.TY + " " + dpos.TZ + " " + dslope.X + " " + dslope.Y); } return; } } else { cellsize = Convert.ToDouble(args[3]); double slopetol = Convert.ToDouble(args[4]); double postol = Convert.ToDouble(args[5]); double possweep = Convert.ToDouble(args[6]); double DZ = Convert.ToDouble(args[7]); string selstring = args[8]; MinMatches = Convert.ToUInt32(args[9]); double ZAdj = Convert.ToDouble(args[10]); double ZStep = Convert.ToDouble(args[11]); bool IsParallel = Convert.ToBoolean(args[12]); NumericalTools.CStyleParsedFunction S = new NumericalTools.CStyleParsedFunction(selstring); dSel[] pMap = new dSel[S.ParameterList.Length]; for (j = 0; j < S.ParameterList.Length; j++) { string sp = S.ParameterList[j]; for (i = 0; i < KnownFunctions.Length && String.Compare(sp, KnownFunctions[i].Name, true) != 0; i++) { ; } if (i == KnownFunctions.Length) { throw new Exception("Unknown parameter \"" + sp + "\"."); } pMap[j] = KnownFunctions[i].Evaluate; } SySal.Scanning.Plate.IO.OPERA.LinkedZone reflz = SySal.DataStreams.OPERALinkedZone.FromFile(reftlg); RefRect = reflz.Extents; if (WorkRect.MinX > RefRect.MinX) { RefRect.MinX = WorkRect.MinX; } if (WorkRect.MaxX < RefRect.MaxX) { RefRect.MaxX = WorkRect.MaxX; } if (WorkRect.MinY > RefRect.MinY) { RefRect.MinY = WorkRect.MinY; } if (WorkRect.MaxY < RefRect.MaxY) { RefRect.MaxY = WorkRect.MaxY; } Center.X = 0.5 * (RefRect.MinX + RefRect.MaxX); Center.Y = 0.5 * (RefRect.MinY + RefRect.MaxY); xcells = (int)Math.Ceiling((RefRect.MaxX - RefRect.MinX) / cellsize); ycells = (int)Math.Ceiling((RefRect.MaxY - RefRect.MinY) / cellsize); Console.WriteLine("X/Y Cells: " + xcells + "/" + ycells); if (xcells <= 0 || ycells <= 0) { throw new Exception("Null working area."); } RTrackCell[,] RefCells = new RTrackCell[xcells, ycells]; WorkCells = new RTrackCell[xcells, ycells]; for (ix = 0; ix < xcells; ix++) { for (iy = 0; iy < ycells; iy++) { SySal.BasicTypes.Rectangle rect = new SySal.BasicTypes.Rectangle(); rect.MinX = RefRect.MinX + ix * cellsize; rect.MaxX = rect.MinX + cellsize; rect.MinY = RefRect.MinY + iy * cellsize; rect.MaxY = rect.MinY + cellsize; RefCells[ix, iy] = new RTrackCell(rect, Center); WorkCells[ix, iy] = new RTrackCell(rect, Center); } } SySal.Scanning.Plate.IO.OPERA.LinkedZone lz; RTrackCell[,] rtc; for (i = 0; i < 2; i++) { if (i == 0) { lz = reflz; rtc = RefCells; } else { lz = worklz; rtc = WorkCells; } for (j = 0; j < lz.Length; j++) { SySal.Scanning.MIPBaseTrack tk = lz[j] as SySal.Scanning.MIPBaseTrack; for (k = 0; k < pMap.Length; k++) { S[k] = pMap[k](tk); } if (S.Evaluate() != 0.0) { ix = (int)((tk.Info.Intercept.X - RefRect.MinX) / cellsize); iy = (int)((tk.Info.Intercept.Y - RefRect.MinY) / cellsize); if (ix >= 0 && ix < xcells && iy >= 0 && iy < ycells) { RTrack rtr = new RTrack(); rtr.Slope.X = tk.Info.Slope.X; rtr.Slope.Y = tk.Info.Slope.Y; rtr.Position.X = tk.Info.Intercept.X; rtr.Position.Y = tk.Info.Intercept.Y; rtc[ix, iy].Add(rtr); } } } } for (ix = 0; ix < xcells; ix++) { for (iy = 0; iy < ycells; iy++) { Console.WriteLine("Ref " + RefCells[ix, iy].Average.X + " " + RefCells[ix, iy].Average.Y + " " + RefCells[ix, iy].Count); Console.WriteLine("Work " + WorkCells[ix, iy].Average.X + " " + WorkCells[ix, iy].Average.Y + " " + WorkCells[ix, iy].Count); } } SySal.Processing.QuickMapping.QuickMapper QM = new SySal.Processing.QuickMapping.QuickMapper(); SySal.Processing.QuickMapping.Configuration qmc = QM.Config as SySal.Processing.QuickMapping.Configuration; qmc.FullStatistics = false; qmc.UseAbsoluteReference = true; qmc.PosTol = postol; qmc.SlopeTol = slopetol; for (ix = 0; ix < xcells; ix++) { for (iy = 0; iy < ycells; iy++) { SySal.Tracking.MIPEmulsionTrackInfo[] rinfo = new SySal.Tracking.MIPEmulsionTrackInfo[RefCells[ix, iy].Count]; SySal.Tracking.MIPEmulsionTrackInfo[] winfo = new SySal.Tracking.MIPEmulsionTrackInfo[WorkCells[ix, iy].Count]; for (i = 0; i < 2; i++) { SySal.Tracking.MIPEmulsionTrackInfo[] inf = (i == 0) ? rinfo : winfo; RTrackCell[,] cells = (i == 0) ? RefCells : WorkCells; double dz = (i == 0) ? 0.0 : DZ; for (j = 0; j < inf.Length; j++) { RTrack r = cells[ix, iy].Get(j); inf[j] = new SySal.Tracking.MIPEmulsionTrackInfo(); inf[j].Slope.X = r.Slope.X; inf[j].Slope.Y = r.Slope.Y; inf[j].Intercept.X = r.Position.X; inf[j].Intercept.Y = r.Position.Y; inf[j].Intercept.Z = dz; } } SySal.Scanning.PostProcessing.PatternMatching.TrackPair[] pairs = new SySal.Scanning.PostProcessing.PatternMatching.TrackPair[0]; double bestdz = 0.0; if (rinfo.Length >= 2 && winfo.Length >= 2) { double dz1; if (IsParallel) { System.Collections.ArrayList thrarr = new System.Collections.ArrayList(); for (dz1 = -ZAdj; dz1 <= ZAdj; dz1 += ZStep) { MapThread mthr = new MapThread(); mthr.m_rinfo = rinfo; mthr.m_winfo = winfo; mthr.m_DZ = DZ + dz1; mthr.m_PosSweep = possweep; mthr.m_PosTol = postol; mthr.m_SlopeTol = slopetol; mthr.m_Thread = new System.Threading.Thread(new System.Threading.ThreadStart(mthr.Execute)); mthr.m_Thread.Start(); thrarr.Add(mthr); } foreach (MapThread mt in thrarr) { mt.m_Thread.Join(); if (mt.m_Pairs.Length > pairs.Length) { bestdz = mt.m_DZ - DZ; pairs = mt.m_Pairs; } } } else { for (dz1 = -ZAdj; dz1 <= ZAdj; dz1 += ZStep) { SySal.Scanning.PostProcessing.PatternMatching.TrackPair[] qairs = QM.Match(rinfo, winfo, DZ + dz1, possweep, possweep); if (qairs.Length > pairs.Length) { bestdz = dz1; pairs = qairs; } } } } double[] alignpars = new double[7]; SySal.BasicTypes.Vector2 slopedelta = new SySal.BasicTypes.Vector2(); SySal.BasicTypes.Vector2 slopetolv = new SySal.BasicTypes.Vector2(); double[] dslx = new double[pairs.Length]; double[] dsly = new double[pairs.Length]; for (j = 0; j < pairs.Length; j++) { dslx[j] = pairs[j].First.Info.Slope.X - pairs[j].Second.Info.Slope.X; } PeakFit(dslx, slopetol, out slopedelta.X, out slopetolv.X); for (j = 0; j < pairs.Length; j++) { dsly[j] = pairs[j].First.Info.Slope.Y - pairs[j].Second.Info.Slope.Y; } PeakFit(dsly, slopetol, out slopedelta.Y, out slopetolv.Y); int gooddslopes = 0; for (j = 0; j < pairs.Length; j++) { if ((slopedelta.X - slopetolv.X) < dslx[j] && dslx[j] < (slopedelta.X + slopetolv.X) && (slopedelta.Y - slopetolv.Y) < dsly[j] && dsly[j] < (slopedelta.Y + slopetolv.Y)) { gooddslopes++; } } if (gooddslopes > 0) { double[] DX = new double[gooddslopes]; double[] DY = new double[gooddslopes]; double[] X = new double[gooddslopes]; double[] Y = new double[gooddslopes]; double[] SX = new double[gooddslopes]; double[] SY = new double[gooddslopes]; for (j = i = 0; j < pairs.Length; j++) { if ((slopedelta.X - slopetolv.X) < dslx[j] && dslx[j] < (slopedelta.X + slopetolv.X) && (slopedelta.Y - slopetolv.Y) < dsly[j] && dsly[j] < (slopedelta.Y + slopetolv.Y)) { X[i] = pairs[j].Second.Info.Intercept.X - WorkCells[ix, iy].AlignInfo.RX; Y[i] = pairs[j].Second.Info.Intercept.Y - WorkCells[ix, iy].AlignInfo.RY; SX[i] = pairs[j].Second.Info.Slope.X; SY[i] = pairs[j].Second.Info.Slope.Y; DX[i] = pairs[j].First.Info.Intercept.X - pairs[j].Second.Info.Intercept.X; DY[i] = pairs[j].First.Info.Intercept.Y - pairs[j].Second.Info.Intercept.Y; //System.IO.File.AppendAllText(@"c:\flattentlg.txt", "\r\n" + ix + " " + iy + " " + i + " " + j + " " + pairs.Length + " " + gooddslopes + " " + WorkCells[ix, iy].AlignInfo.RX + " " + WorkCells[ix, iy].AlignInfo.RY + " " + X[i] + " " + Y[i] + " " + SX[i] + " " + SY[i] + " " + DX[i] + " " + DY[i] + " " + bestdz); i++; } } WorkCells[ix, iy].Result = IteratedAffineFocusing(DX, DY, X, Y, SX, SY, postol, ref alignpars); } else { WorkCells[ix, iy].Result = NumericalTools.ComputationResult.InvalidInput; } WorkCells[ix, iy].Matches = pairs.Length; WorkCells[ix, iy].AlignInfo.TZ = alignpars[6] + bestdz; WorkCells[ix, iy].AlignInfo.TX = alignpars[4]; WorkCells[ix, iy].AlignInfo.TY = alignpars[5]; WorkCells[ix, iy].AlignInfo.MXX = 1.0 + alignpars[0]; WorkCells[ix, iy].AlignInfo.MXY = 0.0 + alignpars[1]; WorkCells[ix, iy].AlignInfo.MYX = 0.0 + alignpars[2]; WorkCells[ix, iy].AlignInfo.MYY = 1.0 + alignpars[3]; WorkCells[ix, iy].SlopeAlignInfo = slopedelta; Console.WriteLine("Fit " + WorkCells[ix, iy].Result + " " + WorkCells[ix, iy].AlignInfo.MXX + " " + WorkCells[ix, iy].AlignInfo.MXY + " " + WorkCells[ix, iy].AlignInfo.MYX + " " + WorkCells[ix, iy].AlignInfo.MYY + " " + WorkCells[ix, iy].AlignInfo.TX + " " + WorkCells[ix, iy].AlignInfo.TY + " " + WorkCells[ix, iy].AlignInfo.TZ + " " + WorkCells[ix, iy].SlopeAlignInfo.X + " " + WorkCells[ix, iy].SlopeAlignInfo.Y); } } int goodcells = 0; for (ix = 0; ix < xcells; ix++) { for (iy = 0; iy < ycells; iy++) { if (WorkCells[ix, iy].Result == NumericalTools.ComputationResult.OK && WorkCells[ix, iy].Matches >= MinMatches) { goodcells++; } } } Console.WriteLine("Good cells: " + goodcells); Console.WriteLine("--------CELLS"); Console.WriteLine("CELLMAP " + RefRect.MinX + " " + RefRect.MaxX + " " + RefRect.MinY + " " + RefRect.MaxY + " " + cellsize + " " + xcells + " " + ycells); Console.WriteLine("IX\tIY\tN\tX\tY\tMXX\tMXY\tMYX\tMYY\tTX\tTY\tTZ\tTDSX\tTDSY"); for (ix = 0; ix < xcells; ix++) { for (iy = 0; iy < ycells; iy++) { if (WorkCells[ix, iy].Result == NumericalTools.ComputationResult.OK && WorkCells[ix, iy].Matches >= MinMatches) { Console.WriteLine(ix + "\t" + iy + "\t" + WorkCells[ix, iy].Matches + "\t" + WorkCells[ix, iy].Average.X + "\t" + WorkCells[ix, iy].Average.Y + "\t" + WorkCells[ix, iy].AlignInfo.MXX + "\t" + WorkCells[ix, iy].AlignInfo.MXY + "\t" + WorkCells[ix, iy].AlignInfo.MYX + "\t" + WorkCells[ix, iy].AlignInfo.MYY + "\t" + WorkCells[ix, iy].AlignInfo.TX + "\t" + WorkCells[ix, iy].AlignInfo.TY + "\t" + WorkCells[ix, iy].AlignInfo.TZ + "\t" + WorkCells[ix, iy].SlopeAlignInfo.X + "\t" + WorkCells[ix, iy].SlopeAlignInfo.Y); } } } Console.WriteLine("--------ENDCELLS"); } SySal.DataStreams.OPERALinkedZone.Writer outlzw = new SySal.DataStreams.OPERALinkedZone.Writer(outtlg, worklz.Id, worklz.Extents, worklz.Center, worklz.Transform); outlzw.SetZInfo(worklz.Top.TopZ, worklz.Top.BottomZ, worklz.Bottom.TopZ, worklz.Bottom.BottomZ); for (i = 0; i < ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.Side)worklz.Top).ViewCount; i++) { outlzw.AddView(((SySal.Scanning.Plate.IO.OPERA.LinkedZone.Side)worklz.Top).View(i), true); } for (i = 0; i < ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.Side)worklz.Bottom).ViewCount; i++) { outlzw.AddView(((SySal.Scanning.Plate.IO.OPERA.LinkedZone.Side)worklz.Bottom).View(i), false); } SySal.BasicTypes.Vector proj = new SySal.BasicTypes.Vector(); Console.WriteLine("Writing flattened TLG..."); GridInterpolation G = new GridInterpolation(WorkCells, cellsize, RefRect, (int)MinMatches); System.DateTime start = System.DateTime.Now; for (i = 0; i < worklz.Length; i++) { if (i % 1000 == 0) { System.DateTime nw = System.DateTime.Now; if ((nw - start).TotalMilliseconds >= 10000) { Console.WriteLine((i * 100 / worklz.Length) + "%"); start = nw; } } SySal.Tracking.MIPEmulsionTrackInfo baseinfo = worklz[i].Info; SySal.DAQSystem.Scanning.IntercalibrationInfo transforminfo = new SySal.DAQSystem.Scanning.IntercalibrationInfo(); transforminfo.RX = Center.X; transforminfo.RY = Center.Y; SySal.BasicTypes.Vector tds = new SySal.BasicTypes.Vector(); G.Evaluate(baseinfo.Intercept.X, baseinfo.Intercept.Y, ref tds, ref transforminfo); proj.X = -baseinfo.Slope.X * transforminfo.TZ; proj.Y = -baseinfo.Slope.Y * transforminfo.TZ; proj.Z = 0.0; baseinfo.Intercept = transforminfo.Transform(baseinfo.Intercept) + proj; baseinfo.Slope = transforminfo.Deform(baseinfo.Slope) + tds; SySal.Scanning.MIPIndexedEmulsionTrack toptk = worklz[i].Top; SySal.Tracking.MIPEmulsionTrackInfo topinfo = toptk.Info; SySal.Scanning.MIPIndexedEmulsionTrack bottomtk = worklz[i].Bottom; SySal.Tracking.MIPEmulsionTrackInfo bottominfo = bottomtk.Info; topinfo.Intercept = transforminfo.Transform(topinfo.Intercept) + proj; topinfo.Slope = transforminfo.Deform(topinfo.Slope) + tds; bottominfo.Intercept = transforminfo.Transform(bottominfo.Intercept) + proj; bottominfo.Slope = transforminfo.Deform(bottominfo.Slope) + tds; outlzw.AddMIPEmulsionTrack(topinfo, i, ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)toptk).View.Id, ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)toptk).OriginalRawData, true); outlzw.AddMIPEmulsionTrack(bottominfo, i, ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)bottomtk).View.Id, ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)bottomtk).OriginalRawData, false); outlzw.AddMIPBasetrack(baseinfo, i, i, i); } outlzw.Complete(); Console.WriteLine("Written \"" + outtlg + "\"."); }