/// <summary> /// Checks the intercalibration. /// </summary> /// <param name="info">the intercalibration to be checked.</param> public static void CheckIntercalibration(SySal.DAQSystem.Scanning.IntercalibrationInfo info) { double det = info.MXX * info.MYY - info.MXY * info.MYX; Console.WriteLine(); System.Xml.Serialization.XmlSerializer xmls = new System.Xml.Serialization.XmlSerializer(typeof(SySal.DAQSystem.Scanning.IntercalibrationInfo)); xmls.Serialize(Console.Out, info); // if (Math.Abs(det - 1.0) > 0.1) throw new Exception("Transformation is a reflection or requires excessive contraction/expansion."); // if (Math.Abs(info.MXY + info.MYX) / det > 0.005) throw new Exception("Transformation has excessive shear."); }
/// <summary> /// Computes the transformation parameters for a rototranslation with expansion. /// </summary> /// <param name="xypairs">the set of x,y pairs where displacements are known.</param> /// <param name="dxdypairs">the set of deltax,deltay pairs measured.</param> /// <returns>the transformation parameters.</returns> public static SySal.DAQSystem.Scanning.IntercalibrationInfo FindRototranslation(double[,] xypairs, double[,] dxdypairs) { double[,] cmat = new double[4, 4]; double[] v = new double[4]; int i, n; n = dxdypairs.GetLength(0); double avgx = 0.0, avgy = 0.0, x, y; for (i = 0; i < n; i++) { avgx += xypairs[i, 0]; avgy += xypairs[i, 1]; } avgx /= n; avgy /= n; SySal.DAQSystem.Scanning.IntercalibrationInfo cal = new SySal.DAQSystem.Scanning.IntercalibrationInfo(); cal.RX = avgx; cal.RY = avgy; for (i = 0; i < n; i++) { x = xypairs[i, 0] - avgx; y = xypairs[i, 1] - avgy; cmat[0, 0] += x * x + y * y; cmat[0, 2] += x; cmat[0, 3] += y; v[0] += dxdypairs[i, 0] * x + dxdypairs[i, 1] * y; cmat[1, 1] += x * x + y * y; cmat[1, 2] += y; cmat[1, 3] -= x; v[1] += dxdypairs[i, 0] * y - dxdypairs[i, 1] * x; cmat[2, 0] += x; cmat[2, 1] += y; cmat[2, 2] += 1.0; v[2] += dxdypairs[i, 0]; cmat[3, 0] += y; cmat[3, 1] -= x; cmat[3, 3] += 1.0; v[3] += dxdypairs[i, 1]; } NumericalTools.Cholesky ch = new NumericalTools.Cholesky(cmat, 1.0e-8); v = ch.Solve(v); cal.MXX = cal.MYY = 1.0 + v[0]; cal.MXY = v[1]; cal.MYX = -v[1]; cal.TX = v[2]; cal.TY = v[3]; return(cal); }
/// <summary> /// Computes the transformation parameters for a translation. /// </summary> /// <param name="xypairs">the set of x,y pairs where displacements are known.</param> /// <param name="dxdypairs">the set of deltax,deltay pairs measured.</param> /// <returns>the transformation parameters.</returns> public static SySal.DAQSystem.Scanning.IntercalibrationInfo FindTranslation(double[,] xypairs, double[,] dxdypairs) { double dx = 0.0, dy = 0.0; int i, n; n = dxdypairs.GetLength(0); for (i = 0; i < n; i++) { dx += dxdypairs[i, 0]; dy += dxdypairs[i, 1]; } SySal.DAQSystem.Scanning.IntercalibrationInfo cal = new SySal.DAQSystem.Scanning.IntercalibrationInfo(); cal.MXX = cal.MYY = 1.0; cal.MXY = cal.MYX = 0.0; cal.TX = dx / n; cal.TY = dy / n; return(cal); }
private static long DumpZone(string tlgpath, SySal.Scanning.Plate.IO.OPERA.LinkedZone lz, long db_brick_id, long db_plate_id, long db_procop_id, long series, string rawdatapath, DateTime starttime, DateTime endtime, SySal.OperaDb.OperaDbConnection conn, SySal.OperaDb.OperaDbTransaction trans) { try { long db_id_zone = 0; int s, i, n; double dz, basez; SySal.Scanning.Plate.Side side; SySal.DAQSystem.Scanning.IntercalibrationInfo transform = lz.Transform; double TDX = transform.TX - transform.MXX * transform.RX - transform.MXY * transform.RY; double TDY = transform.TY - transform.MYX * transform.RX - transform.MYY * transform.RY; //zone db_id_zone = SySal.OperaDb.Schema.TB_ZONES.Insert(db_brick_id, db_plate_id, db_procop_id, db_id_zone, lz.Extents.MinX, lz.Extents.MaxX, lz.Extents.MinY, lz.Extents.MaxY, tlgpath, starttime, endtime, series, transform.MXX, transform.MXY, transform.MYX, transform.MYY, TDX, TDY); if (FullZoneDump == false) { return(db_id_zone); } //views for (s = 0; s < 2; s++) { if (s == 0) { side = lz.Top; basez = lz.Top.BottomZ; } else { side = lz.Bottom; basez = lz.Bottom.TopZ; } n = ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.Side)side).ViewCount; for (i = 0; i < n; i++) { SySal.Scanning.Plate.IO.OPERA.LinkedZone.View vw = ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.Side)side).View(i); SySal.OperaDb.Schema.TB_VIEWS.Insert(db_brick_id, db_id_zone, s + 1, //i + 1, vw.Id + 1, vw.TopZ, vw.BottomZ, vw.Position.X, vw.Position.Y); } } SySal.OperaDb.Schema.TB_VIEWS.Flush(); int TrackId = 0; int UpTrackId = 0; int DownTrackId = 0; SySal.Tracking.MIPEmulsionTrackInfo info = null; SySal.Tracking.MIPEmulsionTrackInfo tinfo = null; SySal.Tracking.MIPEmulsionTrackInfo binfo = null; //Basetracks for (i = 0; i < lz.Length; i++) { if (lz[i].Info.Sigma >= 0) { info = lz[i].Info; tinfo = lz[i].Top.Info; binfo = lz[i].Bottom.Info; } else { continue; } DownTrackId++; basez = lz.Top.BottomZ; dz = (basez - tinfo.Intercept.Z); SySal.OperaDb.Schema.TB_MIPMICROTRACKS.Insert(db_brick_id, db_id_zone, 1, DownTrackId, tinfo.Intercept.X + tinfo.Slope.X * dz, tinfo.Intercept.Y + tinfo.Slope.Y * dz, tinfo.Slope.X, tinfo.Slope.Y, tinfo.Count, tinfo.AreaSum, System.DBNull.Value, tinfo.Sigma, ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)(lz.Top[i])).View.Id + 1); UpTrackId++; basez = lz.Bottom.TopZ; dz = (basez - binfo.Intercept.Z); SySal.OperaDb.Schema.TB_MIPMICROTRACKS.Insert(db_brick_id, db_id_zone, 2, UpTrackId, binfo.Intercept.X + binfo.Slope.X * dz, binfo.Intercept.Y + binfo.Slope.Y * dz, binfo.Slope.X, binfo.Slope.Y, binfo.Count, binfo.AreaSum, System.DBNull.Value, binfo.Sigma, ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)(lz.Bottom[i])).View.Id + 1); TrackId++; basez = ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)(lz[i].Top)).View.BottomZ; dz = 0; //TODO (basez - info.Intercept.Z); SySal.OperaDb.Schema.TB_MIPBASETRACKS.Insert(db_brick_id, db_id_zone, TrackId, info.Intercept.X + info.Slope.X * dz, info.Intercept.Y + info.Slope.Y * dz, info.Slope.X, info.Slope.Y, info.Count, info.AreaSum, System.DBNull.Value, info.Sigma, 1, DownTrackId, 2, UpTrackId); } //Microtracks for (i = 0; i < lz.Length; i++) { if (lz[i].Info.Sigma >= 0) { continue; } else if (lz[i].Top.Info.Sigma >= 0) { tinfo = lz[i].Top.Info; DownTrackId++; basez = lz.Top.BottomZ; dz = (basez - tinfo.Intercept.Z); SySal.OperaDb.Schema.TB_MIPMICROTRACKS.Insert(db_brick_id, db_id_zone, 1, DownTrackId, tinfo.Intercept.X + tinfo.Slope.X * dz, tinfo.Intercept.Y + tinfo.Slope.Y * dz, tinfo.Slope.X, tinfo.Slope.Y, tinfo.Count, tinfo.AreaSum, System.DBNull.Value, tinfo.Sigma, ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)(lz.Top[i])).View.Id + 1); } else if (lz[i].Bottom.Info.Sigma >= 0) { binfo = lz[i].Bottom.Info; UpTrackId++; basez = lz.Bottom.TopZ; dz = (basez - binfo.Intercept.Z); SySal.OperaDb.Schema.TB_MIPMICROTRACKS.Insert(db_brick_id, db_id_zone, 2, UpTrackId, binfo.Intercept.X + binfo.Slope.X * dz, binfo.Intercept.Y + binfo.Slope.Y * dz, binfo.Slope.X, binfo.Slope.Y, binfo.Count, binfo.AreaSum, System.DBNull.Value, binfo.Sigma, ((SySal.Scanning.Plate.IO.OPERA.LinkedZone.MIPIndexedEmulsionTrack)(lz.Bottom[i])).View.Id + 1); } } SySal.OperaDb.Schema.TB_MIPMICROTRACKS.Flush(); SySal.OperaDb.Schema.TB_MIPBASETRACKS.Flush(); return(db_id_zone); } catch (Exception x) { throw x; } }
static void Main(string[] args) { // // TODO: Add code to start application here // try { int nzones = 0; bool rewrite = false; if (args.Length < 1) { ShowUsage(); return; } if (args[0] == "1" || args[0].ToLower() == "1r") { nzones = 1; if (args[0].ToLower() == "1r") { rewrite = true; } } else if (args[0] == "3" || args[0].ToLower() == "3r") { nzones = 3; if (args[0].ToLower() == "3r") { rewrite = true; } } else { ShowUsage(); return; } string [] oldargs = args; args = new string[oldargs.Length - 1]; int i; for (i = 1; i < oldargs.Length; i++) { args[i - 1] = oldargs[i]; } if ((nzones == 1 && (args.Length != 9 && args.Length != 11)) || (nzones == 3 && (args.Length != 12 && args.Length != 14))) { ShowUsage(); return; } SySal.DAQSystem.Scanning.IntercalibrationInfo intercal = new SySal.DAQSystem.Scanning.IntercalibrationInfo(); if (nzones == 1 && args.Length == 11) { intercal.RX = Convert.ToDouble(args[9], System.Globalization.CultureInfo.InvariantCulture); intercal.RY = Convert.ToDouble(args[10], System.Globalization.CultureInfo.InvariantCulture); } else if (nzones == 3 && args.Length == 14) { intercal.RX = Convert.ToDouble(args[12], System.Globalization.CultureInfo.InvariantCulture); intercal.RY = Convert.ToDouble(args[13], System.Globalization.CultureInfo.InvariantCulture); } if (nzones == 1) { OneZoneIntercalibration(args, ref intercal, rewrite); } else { ThreeZoneIntercalibration(args, ref intercal, rewrite); } System.IO.StreamWriter wr = new System.IO.StreamWriter(args[0]); System.Xml.Serialization.XmlSerializer xmls = new System.Xml.Serialization.XmlSerializer(typeof(SySal.DAQSystem.Scanning.IntercalibrationInfo)); xmls.Serialize(wr, intercal); wr.Flush(); wr.Close(); } catch (Exception x) { Console.Error.WriteLine(x); } }
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])); } } }
internal void Check(CheckMode mode, string textout, NumericalTools.Function slf, bool dumpfound, bool dumpnotfound) { Mode = mode; SelectionFunction = slf; string [] pars = new string[0]; if (slf != null) { pars = slf.ParameterList; if (pars.Length == 0) { throw new Exception("The selection function must have parameters."); } } System.IO.StreamWriter wr = null; int Searched = 0, Found = 0; SySal.DAQSystem.Scanning.IntercalibrationInfo Inv = new SySal.DAQSystem.Scanning.IntercalibrationInfo(); try { wr = new System.IO.StreamWriter(textout); wr.WriteLine("ID\tPX\tPY\tSX\tSY\tN"); SySal.TotalScan.Layer lay = null; switch (Mode) { case CheckMode.Center: lay = Vol.Layers[1]; break; case CheckMode.Upstream: lay = Vol.Layers[Vol.Layers.Length - 1]; break; case CheckMode.Downstream: lay = Vol.Layers[0]; break; default: throw new Exception("Unsupported mode"); } Inv.RX = Vol.RefCenter.X + lay.AlignData.TranslationX; Inv.RY = Vol.RefCenter.Y + lay.AlignData.TranslationY; double iden = 1.0 / (lay.AlignData.AffineMatrixXX * lay.AlignData.AffineMatrixYY - lay.AlignData.AffineMatrixXY * lay.AlignData.AffineMatrixYX); Inv.MXX = lay.AlignData.AffineMatrixYY * iden; Inv.MXY = -lay.AlignData.AffineMatrixXY * iden; Inv.MYX = -lay.AlignData.AffineMatrixYX * iden; Inv.MYY = lay.AlignData.AffineMatrixXX * iden; Inv.TX = -lay.AlignData.TranslationX; Inv.TY = -lay.AlignData.TranslationY; int tkn = Vol.Tracks.Length; int t, p; SySal.TotalScan.Track tk; string ps; double ipx, ipy, isx, isy; for (t = 0; t < tkn; t++) { tk = Vol.Tracks[t]; if (SelectionFunction != null) { for (p = 0; p < pars.Length; p++) { ps = pars[p].ToUpper(); switch (ps) { case "N": SelectionFunction[p] = tk.Length; break; case "DZ": SelectionFunction[p] = tk.Downstream_Z; break; case "UZ": SelectionFunction[p] = tk.Upstream_Z; break; case "DSX": SelectionFunction[p] = tk.Downstream_SlopeX; break; case "DSY": SelectionFunction[p] = tk.Downstream_SlopeY; break; case "USX": SelectionFunction[p] = tk.Upstream_SlopeX; break; case "USY": SelectionFunction[p] = tk.Upstream_SlopeY; break; case "D0X": SelectionFunction[p] = tk.Downstream_PosX - tk.Downstream_SlopeX * tk.Downstream_PosZ; break; case "D0Y": SelectionFunction[p] = tk.Downstream_PosY - tk.Downstream_SlopeY * tk.Downstream_PosZ; break; case "U0X": SelectionFunction[p] = tk.Upstream_PosX - tk.Upstream_SlopeX * tk.Upstream_PosZ; break; case "U0Y": SelectionFunction[p] = tk.Upstream_PosY - tk.Upstream_SlopeY * tk.Upstream_PosZ; break; case "DPX": SelectionFunction[p] = tk.Downstream_PosX + tk.Downstream_SlopeX * (tk.Downstream_Z - tk.Downstream_PosZ); break; case "DPY": SelectionFunction[p] = tk.Downstream_PosY + tk.Downstream_SlopeY * (tk.Downstream_Z - tk.Downstream_PosZ); break; case "UPX": SelectionFunction[p] = tk.Upstream_PosX + tk.Upstream_SlopeX * (tk.Upstream_Z - tk.Upstream_PosZ); break; case "UPY": SelectionFunction[p] = tk.Upstream_PosY + tk.Upstream_SlopeY * (tk.Upstream_Z - tk.Upstream_PosZ); break; default: throw new Exception("Unknown parameter " + ps); } } if (SelectionFunction.Evaluate() == 0) { continue; } } switch (Mode) { case CheckMode.Center: { if (tk.UpstreamLayerId == 2 && tk.DownstreamLayerId == 0) { Searched++; if (tk.Length == 3) { Found++; if (dumpfound) { SySal.Tracking.MIPEmulsionTrackInfo info = tk[1].Info; ipx = Inv.MXX * (info.Intercept.X - Inv.RX) + Inv.MXY * (info.Intercept.Y - Inv.RY) + Inv.TX + Inv.RX; ipy = Inv.MYX * (info.Intercept.X - Inv.RX) + Inv.MYY * (info.Intercept.Y - Inv.RY) + Inv.TY + Inv.RY; isx = Inv.MXX * info.Slope.X + Inv.MXY * info.Slope.Y; isy = Inv.MYX * info.Slope.X + Inv.MYY * info.Slope.Y; wr.WriteLine(tk.Id + "\t" + ipx.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + ipy.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isx.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isy.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + tk.Length); } } else { if (dumpnotfound) { SySal.Tracking.MIPEmulsionTrackInfo info = new SySal.Tracking.MIPEmulsionTrackInfo(); info.Intercept.X = tk.Downstream_PosX + tk.Downstream_SlopeX * (lay.RefCenter.Z - tk.Downstream_PosZ); info.Intercept.Y = tk.Downstream_PosY + tk.Downstream_SlopeY * (lay.RefCenter.Z - tk.Downstream_PosZ); info.Slope.X = tk.Downstream_SlopeX; info.Slope.Y = tk.Downstream_SlopeY; ipx = Inv.MXX * (info.Intercept.X - Inv.RX) + Inv.MXY * (info.Intercept.Y - Inv.RY) + Inv.TX + Inv.RX; ipy = Inv.MYX * (info.Intercept.X - Inv.RX) + Inv.MYY * (info.Intercept.Y - Inv.RY) + Inv.TY + Inv.RY; isx = Inv.MXX * info.Slope.X + Inv.MXY * info.Slope.Y; isy = Inv.MYX * info.Slope.X + Inv.MYY * info.Slope.Y; wr.WriteLine(tk.Id + "\t" + ipx.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + ipy.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isx.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isy.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + tk.Length); } } } } break; case CheckMode.Upstream: { if (tk.DownstreamLayerId == 0 && tk.Length >= (Vol.Layers.Length - 1)) { Searched++; if (tk.Length == Vol.Layers.Length) { Found++; if (dumpfound) { SySal.Tracking.MIPEmulsionTrackInfo info = tk[tk.Length - 1].Info; ipx = Inv.MXX * (info.Intercept.X - Inv.RX) + Inv.MXY * (info.Intercept.Y - Inv.RY) + Inv.TX + Inv.RX; ipy = Inv.MYX * (info.Intercept.X - Inv.RX) + Inv.MYY * (info.Intercept.Y - Inv.RY) + Inv.TY + Inv.RY; isx = Inv.MXX * info.Slope.X + Inv.MXY * info.Slope.Y; isy = Inv.MYX * info.Slope.X + Inv.MYY * info.Slope.Y; wr.WriteLine(tk.Id + "\t" + ipx.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + ipy.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isx.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isy.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + tk.Length); } } else { if (dumpnotfound) { SySal.Tracking.MIPEmulsionTrackInfo info = new SySal.Tracking.MIPEmulsionTrackInfo(); info.Intercept.X = tk.Upstream_PosX + tk.Upstream_SlopeX * (lay.RefCenter.Z - tk.Upstream_PosZ); info.Intercept.Y = tk.Upstream_PosY + tk.Upstream_SlopeY * (lay.RefCenter.Z - tk.Upstream_PosZ); info.Slope.X = tk.Upstream_SlopeX; info.Slope.Y = tk.Upstream_SlopeY; ipx = Inv.MXX * (info.Intercept.X - Inv.RX) + Inv.MXY * (info.Intercept.Y - Inv.RY) + Inv.TX + Inv.RX; ipy = Inv.MYX * (info.Intercept.X - Inv.RX) + Inv.MYY * (info.Intercept.Y - Inv.RY) + Inv.TY + Inv.RY; isx = Inv.MXX * info.Slope.X + Inv.MXY * info.Slope.Y; isy = Inv.MYX * info.Slope.X + Inv.MYY * info.Slope.Y; wr.WriteLine(tk.Id + "\t" + ipx.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + ipy.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isx.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isy.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + tk.Length); } } } } break; case CheckMode.Downstream: { if (tk.UpstreamLayerId == (Vol.Layers.Length - 1) && tk.Length >= (Vol.Layers.Length - 1)) { Searched++; if (tk.Length == Vol.Layers.Length) { Found++; if (dumpfound) { SySal.Tracking.MIPEmulsionTrackInfo info = tk[0].Info; ipx = Inv.MXX * (info.Intercept.X - Inv.RX) + Inv.MXY * (info.Intercept.Y - Inv.RY) + Inv.TX + Inv.RX; ipy = Inv.MYX * (info.Intercept.X - Inv.RX) + Inv.MYY * (info.Intercept.Y - Inv.RY) + Inv.TY + Inv.RY; isx = Inv.MXX * info.Slope.X + Inv.MXY * info.Slope.Y; isy = Inv.MYX * info.Slope.X + Inv.MYY * info.Slope.Y; wr.WriteLine(tk.Id + "\t" + ipx.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + ipy.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isx.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isy.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + tk.Length); } } else { if (dumpnotfound) { SySal.Tracking.MIPEmulsionTrackInfo info = new SySal.Tracking.MIPEmulsionTrackInfo(); info.Intercept.X = tk.Downstream_PosX + tk.Downstream_SlopeX * (lay.RefCenter.Z - tk.Downstream_PosZ); info.Intercept.Y = tk.Downstream_PosY + tk.Downstream_SlopeY * (lay.RefCenter.Z - tk.Downstream_PosZ); info.Slope.X = tk.Downstream_SlopeX; info.Slope.Y = tk.Downstream_SlopeY; ipx = Inv.MXX * (info.Intercept.X - Inv.RX) + Inv.MXY * (info.Intercept.Y - Inv.RY) + Inv.TX + Inv.RX; ipy = Inv.MYX * (info.Intercept.X - Inv.RX) + Inv.MYY * (info.Intercept.Y - Inv.RY) + Inv.TY + Inv.RY; isx = Inv.MXX * info.Slope.X + Inv.MXY * info.Slope.Y; isy = Inv.MYX * info.Slope.X + Inv.MYY * info.Slope.Y; wr.WriteLine(tk.Id + "\t" + ipx.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + ipy.ToString("F1", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isx.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + isy.ToString("F4", System.Globalization.CultureInfo.InvariantCulture) + "\t" + tk.Length); } } } } break; } } wr.Flush(); } catch (Exception x) { Console.WriteLine("Unrecoverable error:\n" + x.Message); } finally { if (wr != null) { wr.Close(); } Console.WriteLine("Searched: " + Searched); Console.WriteLine("Found: " + Found); if (Searched > 1) { double p = (double)Found / (double)Searched; Console.WriteLine("Efficiency: " + (p * 100.0).ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "% \xb1" + (Math.Sqrt(p * (1.0 - p) / Searched) * 100.0).ToString("F2", System.Globalization.CultureInfo.InvariantCulture) + "%"); } } }
/// <summary> /// Adds segments, tracks and vertices of a volume to another one. /// </summary> /// <param name="refvol">the volume to be augmented with the content of the other.</param> /// <param name="addvol">segments, tracks and vertices from this volume are added to the other.</param> /// <param name="ds">the dataset that should be assigned to imported tracks.</param> /// <param name="fds">the dataset that should be imported; if this parameter is <c>null</c>, all datasets are imported.</param> /// <param name="flt">track mapping filter function.</param> /// <param name="logstrw">the stream where logging information is to be dumped; set to <c>null</c> to disable logging.</param> public void AddToVolume(SySal.TotalScan.Flexi.Volume refvol, SySal.TotalScan.Flexi.Volume addvol, SySal.TotalScan.Flexi.DataSet ds, SySal.TotalScan.Flexi.DataSet fds, MapManager.dMapFilter flt, System.IO.TextWriter logstrw) { if (logstrw != null) { logstrw.WriteLine("Begin AddToVolume."); } #if !DEBUG try { #endif int i, j, n; SySal.DAQSystem.Scanning.IntercalibrationInfo[] calinfo = new SySal.DAQSystem.Scanning.IntercalibrationInfo[addvol.Layers.Length]; for (i = 0; i < addvol.Layers.Length; i++) { for (j = 0; j < refvol.Layers.Length && (refvol.Layers[j].BrickId != addvol.Layers[i].BrickId || refvol.Layers[j].SheetId != addvol.Layers[i].SheetId || refvol.Layers[j].Side != addvol.Layers[i].Side); j++) { ; } if (j == refvol.Layers.Length) { throw new Exception("No reference layer found for Brick/Sheet/Side = " + addvol.Layers[i].BrickId + "/" + addvol.Layers[i].SheetId + "/" + addvol.Layers[i].Side); } if (logstrw != null) { logstrw.WriteLine("Seeking mapping for layer " + i + " Brick/Sheet/Side " + refvol.Layers[i].BrickId + "/" + refvol.Layers[i].SheetId + "/" + refvol.Layers[i].Side); } calinfo[i] = MapTransform(MapManager.ExtractMap(refvol.Layers[j], (MapSide)refvol.Layers[j].Side, flt, true), MapManager.ExtractMap(addvol.Layers[i], (MapSide)refvol.Layers[j].Side, flt, true), null, logstrw); } for (i = 0; i < addvol.Layers.Length; i++) { SySal.TotalScan.Layer lay = addvol.Layers[i]; n = lay.Length; SySal.DAQSystem.Scanning.IntercalibrationInfo cinfo = calinfo[i]; SySal.DAQSystem.Scanning.IntercalibrationInfo alinfo = new SySal.DAQSystem.Scanning.IntercalibrationInfo(); SySal.TotalScan.AlignmentData al = lay.AlignData; alinfo.MXX = al.AffineMatrixXX * cinfo.MXX + al.AffineMatrixXY * cinfo.MYX; alinfo.MXY = al.AffineMatrixXX * cinfo.MXY + al.AffineMatrixXY * cinfo.MYY; alinfo.MYX = al.AffineMatrixYX * cinfo.MXX + al.AffineMatrixYY * cinfo.MYX; alinfo.MYY = al.AffineMatrixYX * cinfo.MXY + al.AffineMatrixYY * cinfo.MYY; double rx = lay.RefCenter.X - cinfo.RX; double ry = lay.RefCenter.Y - cinfo.RY; alinfo.RX = lay.RefCenter.X; alinfo.RY = lay.RefCenter.Y; double dx = cinfo.MXX * rx + cinfo.MXY * ry - rx + cinfo.TX; double dy = cinfo.MYX * rx + cinfo.MYY * ry - ry + cinfo.TY; alinfo.TX = al.AffineMatrixXX * dx + al.AffineMatrixXY * dy + al.TranslationX; alinfo.TY = al.AffineMatrixYX * dx + al.AffineMatrixYY * dy + al.TranslationY; for (j = 0; j < n; j++) { SySal.TotalScan.Flexi.Segment seg = (SySal.TotalScan.Flexi.Segment)lay[j]; SySal.Tracking.MIPEmulsionTrackInfo info = seg.OriginalInfo; info.Slope = alinfo.Deform(info.Slope); info.Intercept = alinfo.Transform(info.Intercept); seg.SetInfo(info); } } if (logstrw != null) { logstrw.Write("Importing volume..."); } refvol.ImportVolume(ds, addvol, fds); if (logstrw != null) { logstrw.WriteLine("Done."); } #if !DEBUG } catch (Exception x) { if (logstrw != null) { logstrw.WriteLine("Error:\r\n" + x.ToString()); } } finally { if (logstrw != null) { logstrw.WriteLine("End AddToVolume."); } } #endif }
/// <summary> /// Adds segments to an existing layer with a specified mapping transformation. /// </summary> /// <param name="lay">the layer that is to receive the new segments.</param> /// <param name="addsegs">the segments to be added.</param> /// <param name="calinfo">the mapping transformation to be used.</param> public void AddToLayer(SySal.TotalScan.Flexi.Layer lay, SySal.TotalScan.Flexi.Segment [] addsegs, SySal.DAQSystem.Scanning.IntercalibrationInfo calinfo) { int i; SySal.TotalScan.Segment [] segs = new SySal.TotalScan.Segment[addsegs.Length]; for (i = 0; i < addsegs.Length; i++) { SySal.Tracking.MIPEmulsionTrackInfo info = addsegs[i].Info; info.Slope = calinfo.Deform(info.Slope); info.Intercept = calinfo.Transform(info.Intercept); addsegs[i].SetInfo(info); segs[i] = addsegs[i]; } lay.AddSegments(segs); }
/// <summary> /// Maps a pattern of tracks onto another one. /// </summary> /// <param name="refpattern">the reference pattern.</param> /// <param name="mappattern">the pattern to be mapped.</param> /// <param name="flt">the filter function for mapping.</param> /// <param name="logstrw">the output stream where logging information is written; set to <c>null</c> to disable logging.</param> /// <returns>the transformation obtained.</returns> public SySal.DAQSystem.Scanning.IntercalibrationInfo MapTransform(SySal.Tracking.MIPEmulsionTrackInfo[] refpattern, SySal.Tracking.MIPEmulsionTrackInfo[] mappattern, MapManager.dMapFilter flt, System.IO.TextWriter logstrw) { SySal.DAQSystem.Scanning.IntercalibrationInfo calinfo = new SySal.DAQSystem.Scanning.IntercalibrationInfo(); try { if (logstrw != null) { logstrw.WriteLine("Begin pattern mapping."); } calinfo.MXX = calinfo.MYY = 1.0; calinfo.MXY = calinfo.MYX = 0.0; calinfo.RX = calinfo.RY = calinfo.TX = calinfo.TY = calinfo.TZ = 0.0; int nr = refpattern.Length; int na = mappattern.Length; if (logstrw != null) { logstrw.WriteLine("Ref tracks: " + nr); logstrw.WriteLine("Add tracks: " + na); } if (nr == 0 || na == 0) { return(calinfo); } SySal.BasicTypes.Rectangle refrect = new SySal.BasicTypes.Rectangle(); SySal.BasicTypes.Rectangle addrect = new SySal.BasicTypes.Rectangle(); SySal.Tracking.MIPEmulsionTrackInfo refinfo = refpattern[0]; SySal.Tracking.MIPEmulsionTrackInfo addinfo = mappattern[0]; refrect.MinX = refrect.MaxX = refinfo.Intercept.X; refrect.MinY = refrect.MaxY = refinfo.Intercept.Y; addrect.MinX = addrect.MaxX = addinfo.Intercept.X; addrect.MinY = addrect.MaxY = addinfo.Intercept.Y; int i; for (i = 1; i < nr; i++) { refinfo = refpattern[i]; if (refinfo.Intercept.X < refrect.MinX) { refrect.MinX = refinfo.Intercept.X; } else if (refinfo.Intercept.X > refrect.MaxX) { refrect.MaxX = refinfo.Intercept.X; } if (refinfo.Intercept.Y < refrect.MinY) { refrect.MinY = refinfo.Intercept.Y; } else if (refinfo.Intercept.Y > refrect.MaxY) { refrect.MaxY = refinfo.Intercept.Y; } } for (i = 1; i < na; i++) { addinfo = mappattern[i]; if (addinfo.Intercept.X < addrect.MinX) { addrect.MinX = addinfo.Intercept.X; } else if (addinfo.Intercept.X > addrect.MaxX) { addrect.MaxX = addinfo.Intercept.X; } if (addinfo.Intercept.Y < addrect.MinY) { addrect.MinY = addinfo.Intercept.Y; } else if (addinfo.Intercept.Y > addrect.MaxY) { addrect.MaxY = addinfo.Intercept.Y; } } SySal.BasicTypes.Rectangle maprect = new SySal.BasicTypes.Rectangle(); maprect.MinX = Math.Max(refrect.MinX, addrect.MinX); maprect.MaxX = Math.Min(refrect.MaxX, addrect.MaxX); maprect.MinY = Math.Max(refrect.MinY, addrect.MinY); maprect.MaxY = Math.Min(refrect.MaxY, addrect.MaxY); int xcells = (int)Math.Ceiling((maprect.MaxX - maprect.MinX) / m_Config.MapSize); int ycells = (int)Math.Ceiling((maprect.MaxY - maprect.MinY) / m_Config.MapSize); if (logstrw != null) { logstrw.WriteLine("Ref rect: " + refrect.MinX + " " + refrect.MaxX + " " + refrect.MinY + " " + refrect.MaxY); logstrw.WriteLine("Map rect: " + addrect.MinX + " " + addrect.MaxX + " " + addrect.MinY + " " + addrect.MaxY); logstrw.WriteLine("Common rect: " + maprect.MinX + " " + maprect.MaxX + " " + maprect.MinY + " " + maprect.MaxY); logstrw.WriteLine("X cells: " + xcells + " Y cells: " + ycells); } if (xcells <= 0 || ycells <= 0) { return(calinfo); } int ix, iy; System.Collections.ArrayList[,] rmaps = new System.Collections.ArrayList[ycells, xcells]; System.Collections.ArrayList[,] amaps = new System.Collections.ArrayList[ycells, xcells]; for (ix = 0; ix < xcells; ix++) { for (iy = 0; iy < ycells; iy++) { rmaps[iy, ix] = new System.Collections.ArrayList(); amaps[iy, ix] = new System.Collections.ArrayList(); } } for (i = 0; i < nr; i++) { refinfo = refpattern[i]; ix = (int)((refinfo.Intercept.X - maprect.MinX) / m_Config.MapSize); if (ix < 0 || ix >= xcells) { continue; } iy = (int)((refinfo.Intercept.Y - maprect.MinY) / m_Config.MapSize); if (iy < 0 || iy >= ycells) { continue; } if (flt == null || flt(refinfo)) { rmaps[iy, ix].Add(refinfo); } } for (i = 0; i < na; i++) { addinfo = mappattern[i]; ix = (int)((addinfo.Intercept.X - maprect.MinX) / m_Config.MapSize); if (ix < 0 || ix >= xcells) { continue; } iy = (int)((addinfo.Intercept.Y - maprect.MinY) / m_Config.MapSize); if (iy < 0 || iy >= ycells) { continue; } if (flt == null || flt(addinfo)) { amaps[iy, ix].Add(addinfo); } } System.Collections.ArrayList mres = new System.Collections.ArrayList(); for (ix = 0; ix < xcells; ix++) { for (iy = 0; iy < ycells; iy++) { SySal.Tracking.MIPEmulsionTrackInfo[] ri = (SySal.Tracking.MIPEmulsionTrackInfo[])rmaps[iy, ix].ToArray(typeof(SySal.Tracking.MIPEmulsionTrackInfo)); if (ri.Length <= 0) { continue; } SySal.Tracking.MIPEmulsionTrackInfo[] ai = (SySal.Tracking.MIPEmulsionTrackInfo[])amaps[iy, ix].ToArray(typeof(SySal.Tracking.MIPEmulsionTrackInfo)); if (ai.Length <= 0) { continue; } MapResult mr = Map(ri, ai)[0]; if (mr.Valid) { SySal.BasicTypes.Vector2 p = new SySal.BasicTypes.Vector2(); p.X = maprect.MinX + m_Config.MapSize * (ix + 0.5); p.Y = maprect.MinY + m_Config.MapSize * (iy + 0.5); mres.Add(new object[] { p, mr }); logstrw.WriteLine("Z ix " + ix + " iy " + iy + " matches " + mr.Matches + " X " + p.X + " Y " + p.Y + " DeltaX/Y " + mr.DeltaPos.X + "/" + mr.DeltaPos.Y + " RMSX/Y " + mr.DeltaPosRMS.X + "/" + mr.DeltaPosRMS.Y + " DeltaSX/Y " + mr.DeltaSlope.X + "/" + mr.DeltaSlope.Y + " RMSX/Y " + mr.DeltaSlopeRMS.X + "/" + mr.DeltaSlopeRMS.Y); } else if (logstrw != null) { logstrw.WriteLine("Z ix " + ix + " iy " + iy + " matches " + mr.Matches); } } } double[,] inXY = new double[mres.Count, 2]; double[,] dXY = new double[mres.Count, 2]; for (i = 0; i < mres.Count; i++) { object[] o = (object[])mres[i]; inXY[i, 0] = ((SySal.BasicTypes.Vector2)o[0]).X; inXY[i, 1] = ((SySal.BasicTypes.Vector2)o[0]).Y; dXY[i, 0] = -((MapResult)o[1]).DeltaPos.X; dXY[i, 1] = -((MapResult)o[1]).DeltaPos.Y; if (logstrw != null) { logstrw.WriteLine("Zone " + i + " matches " + ((MapResult)o[1]).Matches + " " + inXY[i, 0] + " " + inXY[i, 1] + " " + dXY[i, 0] + " " + dXY[i, 1]); } } switch (mres.Count) { case 0: return(calinfo); case 1: return(calinfo = TransformFitter.FindTranslation(inXY, dXY)); case 2: return(calinfo = TransformFitter.FindRototranslation(inXY, dXY)); default: try { return(calinfo = TransformFitter.FindAffineTransformation(inXY, dXY)); } catch (Exception) { return(calinfo = TransformFitter.FindRototranslation(inXY, dXY)); } } } finally { if (logstrw != null) { logstrw.WriteLine("End mapping with RX/Y " + calinfo.RX + "/" + calinfo.RY + " MXX/XY/YX/YY " + calinfo.MXX + "/" + calinfo.MXY + "/" + calinfo.MYX + "/" + calinfo.MYY + " TX/Y " + calinfo.TX + "/" + calinfo.TY + "."); } } }
public Writer(string filepath, SySal.BasicTypes.Identifier id, SySal.BasicTypes.Rectangle extents, SySal.BasicTypes.Vector2 center, SySal.DAQSystem.Scanning.IntercalibrationInfo transform) { guid = System.Environment.ExpandEnvironmentVariables("%TEMP%\\" + System.Guid.NewGuid().ToString() + ".tlgs."); m_FilePath = filepath; w_tlg = new System.IO.BinaryWriter(new System.IO.FileStream(filepath, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None)); b_toptk = new System.IO.BinaryWriter(t_toptk = new System.IO.FileStream(guid + "ttk", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None)); b_bottk = new System.IO.BinaryWriter(t_bottk = new System.IO.FileStream(guid + "btk", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None)); b_topvw = new System.IO.BinaryWriter(t_topvw = new System.IO.FileStream(guid + "tvw", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None)); b_botvw = new System.IO.BinaryWriter(t_botvw = new System.IO.FileStream(guid + "bvw", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None)); b_topix = new System.IO.BinaryWriter(t_topix = new System.IO.FileStream(guid + "tix", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None)); b_botix = new System.IO.BinaryWriter(t_botix = new System.IO.FileStream(guid + "bix", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None)); b_linked = new System.IO.BinaryWriter(t_linked = new System.IO.FileStream(guid + "lk", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None)); w_tlg.Write((byte)0x41); w_tlg.Write((ushort)0x7); w_tlg.Write(SectionTag); Section_Tracks_pos = w_tlg.BaseStream.Position; w_tlg.Write((long)0); w_tlg.Write(id.Part0); w_tlg.Write(id.Part1); w_tlg.Write(id.Part2); w_tlg.Write(id.Part3); w_tlg.Write(center.X); w_tlg.Write(center.Y); w_tlg.Write(extents.MinX); w_tlg.Write(extents.MaxX); w_tlg.Write(extents.MinY); w_tlg.Write(extents.MaxY); w_tlg.Write(transform.MXX); w_tlg.Write(transform.MXY); w_tlg.Write(transform.MYX); w_tlg.Write(transform.MYY); w_tlg.Write(transform.TX); w_tlg.Write(transform.TY); w_tlg.Write(transform.RX); w_tlg.Write(transform.RY); }
public bool Evaluate(double x, double y, ref SySal.BasicTypes.Vector sloped, ref SySal.DAQSystem.Scanning.IntercalibrationInfo posd) { double tx = (x - RefRect.MinX) / CellSize - 0.5; double ty = (y - RefRect.MinY) / CellSize - 0.5; int ix = (int)tx; int iy = (int)ty; double mux = tx - ix; double muy = ty - iy; double[,] w = new double[, ] { { (1.0 - muy) * (1.0 - mux), (1.0 - muy) * mux }, { muy *(1.0 - mux), muy *mux } }; int itx, ity; posd.MXX = posd.MXY = posd.MYX = posd.MYY = posd.TX = posd.TY = posd.TZ = 0.0; sloped.X = sloped.Y = 0; for (itx = 0; itx <= 1; itx++) { int iix = ix + itx; if (iix < 0) { iix = 0; } else if (iix >= XCells) { iix = XCells - 1; } for (ity = 0; ity <= 1; ity++) { int iiy = iy + ity; if (iiy < 0) { iiy = 0; } else if (iiy >= YCells) { iiy = YCells - 1; } double tw = w[ity, itx]; RTrackCell g = m_Grid2[iix, iiy]; posd.MXX += g.AlignInfo.MXX * tw; posd.MXY += g.AlignInfo.MXY * tw; posd.MYX += g.AlignInfo.MYX * tw; posd.MYY += g.AlignInfo.MYY * tw; posd.TX += (g.AlignInfo.TX + g.AlignInfo.MXX * (x - g.AlignInfo.RX) + g.AlignInfo.MXY * (y - g.AlignInfo.RY) + (g.AlignInfo.RX - x)) * tw; posd.TY += (g.AlignInfo.TY + g.AlignInfo.MYX * (x - g.AlignInfo.RX) + g.AlignInfo.MYY * (y - g.AlignInfo.RY) + (g.AlignInfo.RY - y)) * tw; posd.TZ += g.AlignInfo.TZ * tw; sloped.X += g.SlopeAlignInfo.X * tw; sloped.Y += g.SlopeAlignInfo.Y * tw; } } sloped.Z = 0.0; posd.RX = x; posd.RY = y; return(true); }
public bool EvaluateW(double x, double y, ref SySal.BasicTypes.Vector sloped, ref SySal.DAQSystem.Scanning.IntercalibrationInfo posd) { int ix = (int)((x - RefRect.MinX) / CellSize - 0.5); int iy = (int)((y - RefRect.MinY) / CellSize - 0.5); int iix, iiy; int i, j; double dx, dy; System.Collections.ArrayList arr = new System.Collections.ArrayList(); if (ix >= 0 && ix < XCells && iy >= 0 && iy < YCells && m_Grid[ix, iy].Result == NumericalTools.ComputationResult.OK && m_Grid[ix, iy].Matches >= MinMatches) { arr.Add(m_Grid[ix, iy]); } foreach (int [] dv in dirs) { for (i = 0; i < MaxXYCells; i++) { iix = ix + dv[0] + i * dv[2]; if (iix < 0 || iix >= XCells) { continue; } iiy = iy + dv[1] + i * dv[3]; if (iiy < 0 || iiy >= YCells) { continue; } if (m_Grid[iix, iiy].Result == NumericalTools.ComputationResult.OK && m_Grid[iix, iiy].Matches >= MinMatches) { arr.Add(m_Grid[iix, iiy]); break; } } } RTrackCell[] activecells = (RTrackCell[])arr.ToArray(typeof(RTrackCell)); if (activecells.Length == 0) { return(false); } double[] w = new double[activecells.Length]; double[] mw = new double[activecells.Length]; double w_all = 0.0; for (i = 0; i < activecells.Length; i++) { dx = x - activecells[i].Average.X; dy = y - activecells[i].Average.Y; mw[i] = dx * dx + dy * dy; } for (i = 0; i < w.Length; i++) { w[i] = 1.0; for (j = 0; j < mw.Length; j++) { if (i != j) { w[i] *= mw[j]; } } } for (i = 0; i < w.Length; i++) { w_all += w[i]; } for (i = 0; i < w.Length; i++) { w[i] /= w_all; } posd.MXX = posd.MXY = posd.MYX = posd.MYY = posd.TX = posd.TY = posd.TZ = 0.0; sloped.X = sloped.Y = 0; for (i = 0; i < w.Length; i++) { posd.MXX += activecells[i].AlignInfo.MXX * w[i]; posd.MXY += activecells[i].AlignInfo.MXY * w[i]; posd.MYX += activecells[i].AlignInfo.MYX * w[i]; posd.MYY += activecells[i].AlignInfo.MYY * w[i]; posd.TX += (activecells[i].AlignInfo.TX + activecells[i].AlignInfo.MXX * (x - activecells[i].AlignInfo.RX) + activecells[i].AlignInfo.MXY * (y - activecells[i].AlignInfo.RY) + (activecells[i].AlignInfo.RX - x)) * w[i]; posd.TY += (activecells[i].AlignInfo.TY + activecells[i].AlignInfo.MYX * (x - activecells[i].AlignInfo.RX) + activecells[i].AlignInfo.MYY * (y - activecells[i].AlignInfo.RY) + (activecells[i].AlignInfo.RY - y)) * w[i]; posd.TZ += activecells[i].AlignInfo.TZ * w[i]; sloped.X += activecells[i].SlopeAlignInfo.X * w[i]; sloped.Y += activecells[i].SlopeAlignInfo.Y * w[i]; } sloped.Z = 0.0; posd.RX = x; posd.RY = y; return(true); }
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 + "\"."); }