Esempio n. 1
0
        /// <summary>
        /// Performs multiple matching.
        /// </summary>
        /// <param name="refmap">the reference map.</param>
        /// <param name="mmaps">the list of track maps to be merged.</param>
        /// <returns>the result of pattern matching with each track pattern.</returns>
        public MapResult[] Map(SySal.Tracking.MIPEmulsionTrackInfo[] refmap, params SySal.Tracking.MIPEmulsionTrackInfo[][] mmaps)
        {
            SySal.Processing.QuickMapping.Configuration qmc = (SySal.Processing.QuickMapping.Configuration)m_QM.Config;
            qmc.FullStatistics       = !m_Config.FavorSpeedOverAccuracy;
            qmc.UseAbsoluteReference = true;
            qmc.PosTol   = m_Config.PosTol;
            qmc.SlopeTol = m_Config.SlopeTol;
            MapResult[] mres = new MapResult[mmaps.Length];

            int i;

            for (i = 0; i < mmaps.Length; i++)
            {
                SySal.Scanning.PostProcessing.PatternMatching.TrackPair [] pairs = m_QM.Match(refmap, mmaps[i], 0.0, m_Config.MaxPosOffset, m_Config.MaxPosOffset);
                mres[i].Valid = (mres[i].Matches = pairs.Length) >= m_Config.MinMatches;
                if (pairs.Length <= 0)
                {
                    mres[i].Valid = false;
                    continue;
                }
                SySal.BasicTypes.Vector2 dp = new SySal.BasicTypes.Vector2();
                SySal.BasicTypes.Vector2 dp2 = new SySal.BasicTypes.Vector2();
                SySal.BasicTypes.Vector2 ds = new SySal.BasicTypes.Vector2();
                SySal.BasicTypes.Vector2 ds2 = new SySal.BasicTypes.Vector2();
                double dx, dy;
                foreach (SySal.Scanning.PostProcessing.PatternMatching.TrackPair p in pairs)
                {
                    dx     = (p.First.Info.Intercept.X - p.Second.Info.Intercept.X);
                    dy     = (p.First.Info.Intercept.Y - p.Second.Info.Intercept.Y);
                    dp.X  += dx;
                    dp.Y  += dy;
                    dp2.X += (dx * dx);
                    dp2.Y += (dy * dy);
                    dx     = (p.First.Info.Slope.X - p.Second.Info.Slope.X);
                    dy     = (p.First.Info.Slope.Y - p.Second.Info.Slope.Y);
                    ds.X  += dx;
                    ds.Y  += dy;
                    ds2.X += (dx * dx);
                    ds2.Y += (dy * dy);
                }
                dp.X                 /= pairs.Length;
                dp.Y                 /= pairs.Length;
                dp2.X                 = Math.Sqrt(dp2.X / pairs.Length - dp.X * dp.X);
                dp2.Y                 = Math.Sqrt(dp2.Y / pairs.Length - dp.Y * dp.Y);
                ds.X                 /= pairs.Length;
                ds.Y                 /= pairs.Length;
                ds2.X                 = Math.Sqrt(ds2.X / pairs.Length - ds.X * ds.X);
                ds2.Y                 = Math.Sqrt(ds2.Y / pairs.Length - ds.Y * ds.Y);
                mres[i].DeltaPos      = dp;
                mres[i].DeltaPosRMS   = dp2;
                mres[i].DeltaSlope    = ds;
                mres[i].DeltaSlopeRMS = ds2;
            }
            return(mres);
        }
Esempio n. 2
0
        /// <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 + ".");
                }
            }
        }