コード例 #1
0
ファイル: Exe.cs プロジェクト: kryssb/SySal.NET
        /// <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.");
        }
コード例 #2
0
ファイル: MapMerge.cs プロジェクト: kryssb/SySal.NET
        /// <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);
        }
コード例 #3
0
ファイル: MapMerge.cs プロジェクト: kryssb/SySal.NET
        /// <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);
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: kryssb/SySal.NET
        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;
            }
        }
コード例 #5
0
ファイル: Exe.cs プロジェクト: kryssb/SySal.NET
        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);
            }
        }
コード例 #6
0
ファイル: Exe.cs プロジェクト: kryssb/SySal.NET
        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));
            }
        }
コード例 #7
0
ファイル: Exe.cs プロジェクト: kryssb/SySal.NET
        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]));
                }
            }
        }
コード例 #8
0
        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) + "%");
                }
            }
        }
コード例 #9
0
ファイル: MapMerge.cs プロジェクト: kryssb/SySal.NET
        /// <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
        }
コード例 #10
0
ファイル: MapMerge.cs プロジェクト: kryssb/SySal.NET
        /// <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);
        }
コード例 #11
0
ファイル: MapMerge.cs プロジェクト: kryssb/SySal.NET
        /// <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 + ".");
                }
            }
        }
コード例 #12
0
ファイル: DataStreams.cs プロジェクト: kryssb/SySal.NET
            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);
            }
コード例 #13
0
ファイル: Program.cs プロジェクト: kryssb/SySal.NET
            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);
            }
コード例 #14
0
ファイル: Program.cs プロジェクト: kryssb/SySal.NET
            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);
            }
コード例 #15
0
ファイル: Program.cs プロジェクト: kryssb/SySal.NET
        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 + "\".");
        }