コード例 #1
0
        /// <summary>
        /// Builds a DCT-interpolated image.
        /// </summary>
        /// <param name="info">format of the image.</param>
        /// <param name="xwaves">number of X waves.</param>
        /// <param name="ywaves">number of Y waves.</param>
        /// <param name="pval">the values of a set of sampled points.</param>
        public DCTInterpolationImage(SySal.Imaging.ImageInfo info, int xwaves, int ywaves, PointValue[] pval)
            : base(info, new DCT(info.BitsPerPixel / 8, xwaves, ywaves, info.Width, info.Height, pval))
        {
            XWaves      = xwaves;
            YWaves      = ywaves;
            PointValues = pval;
            NumericalTools.AdvancedFitting.LeastSquares lsq = new NumericalTools.AdvancedFitting.LeastSquares();
            NumericalTools.Minimization.ITargetFunction dct = (NumericalTools.Minimization.ITargetFunction)Pixels;
            double[][] indep  = new double[pval.Length][];
            double[]   dep    = new double[pval.Length];
            double[]   deperr = new double[pval.Length];
            int        i;

            for (i = 0; i < indep.Length; i++)
            {
                indep[i] = new double[2] {
                    pval[i].X, pval[i].Y
                };
                dep[i]    = pval[i].Value;
                deperr[i] = 1.0;
            }
            double[] p = lsq.Fit(dct, xwaves * ywaves, indep, dep, deperr, 10);
            ((DCT)dct).ParamValues = p;
            ((DCT)dct).MakeCosValues();
            ((DCT)dct).m_CachedValues = new int[info.Width * info.Height];
            System.Threading.Thread[] hcomp_Threads = new System.Threading.Thread[info.Height];
            int iiy;

            for (iiy = 0; iiy < info.Height; iiy++)
            {
                hcomp_Threads[iiy] = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(delegate(object oiiiy)
                {
                    int iiiy = (int)oiiiy;
                    int iix, ix, iy;
                    for (iix = 0; iix < info.Width; iix++)
                    {
                        double dv = 0.0;
                        for (ix = 0; ix < XWaves; ix++)
                        {
                            for (iy = 0; iy < YWaves; iy++)
                            {
                                dv += ((DCT)dct).ParamValues[iy * XWaves + ix] * ((DCT)dct).XCosValues[ix, iix] * ((DCT)dct).YCosValues[iy, iiiy];
                            }
                        }
                        ((DCT)dct).m_CachedValues[iiiy * info.Width + iix] = (int)Math.Round(dv);
                    }
                }));
                hcomp_Threads[iiy].Start(iiy);
            }
            for (iiy = 0; iiy < info.Height; iiy++)
            {
                hcomp_Threads[iiy].Join();
                hcomp_Threads[iiy] = null;
            }
        }
コード例 #2
0
        /// <summary>
        /// Computes the momentum and confidence limits using positions and slopes provided.
        /// </summary>
        /// <param name="data">the position and slopes of the track (even Z-unordered). The <c>Field</c> member is used to define the plate.</param>
        /// <returns>the momentum and confidence limits.</returns>
        public MomentumResult ProcessData(SySal.Tracking.MIPEmulsionTrackInfo[] data)
        {
            int            i;
            MomentumResult result = new MomentumResult();

            System.Collections.ArrayList tr = new System.Collections.ArrayList();
            tr.AddRange(data);
            tr.Sort(new DataSorter());

            int nseg = tr.Count;
            int npl  = (int)(((SySal.Tracking.MIPEmulsionTrackInfo)tr[tr.Count - 1]).Field - ((SySal.Tracking.MIPEmulsionTrackInfo)tr[0]).Field) + 1;

            if (nseg < 2)
            {
                throw new Exception("PMSang - Warning! nseg < 2 (" + nseg + ")- impossible to estimate momentum!");
            }
            if (npl < nseg)
            {
                throw new Exception("PMSang - Warning! npl < nseg (" + npl + ", " + nseg + ")");
            }

            int plmax = (int)((SySal.Tracking.MIPEmulsionTrackInfo)tr[tr.Count - 1]).Field + 1;

            if (plmax < 1 || plmax > 1000)
            {
                throw new Exception("PMSang - Warning! plmax = " + plmax + " - correct the segments PID's!");
            }

            float xmean, ymean, zmean, txmean, tymean, wmean;
            float xmean0, ymean0, zmean0, txmean0, tymean0, wmean0;

            FitTrackLine(tr, out xmean0, out ymean0, out zmean0, out txmean0, out tymean0, out wmean0);
            float tmean = (float)Math.Sqrt(txmean0 * txmean0 + tymean0 * tymean0);

            SySal.Tracking.MIPEmulsionTrackInfo aas;
            float sigmax = 0, sigmay = 0;

            for (i = 0; i < tr.Count; i++)
            {
                aas     = (SySal.Tracking.MIPEmulsionTrackInfo)tr[i];
                sigmax += (float)((txmean0 - aas.Slope.X) * (txmean0 - aas.Slope.X));
                sigmay += (float)((tymean0 - aas.Slope.Y) * (tymean0 - aas.Slope.Y));
            }
            sigmax = (float)(Math.Sqrt(sigmax / tr.Count));
            sigmay = (float)(Math.Sqrt(sigmay / tr.Count));
            for (i = 0; i < tr.Count; i++)
            {
                aas = (SySal.Tracking.MIPEmulsionTrackInfo)tr[i];
                if (Math.Abs(aas.Slope.X - txmean0) > 3 * sigmax || Math.Abs(aas.Slope.Y - tymean0) > 3 * sigmay)
                {
                    aas.Slope.X = 0; aas.Slope.Y = 0;
                }
            }

            FitTrackLine(tr, out xmean0, out ymean0, out zmean0, out txmean0, out tymean0, out wmean0);

            float PHI = (float)Math.Atan2(txmean0, tymean0);

            for (i = 0; i < tr.Count; i++)
            {
                aas = (SySal.Tracking.MIPEmulsionTrackInfo)tr[i];
                float slx = (float)(aas.Slope.Y * Math.Cos(-PHI) - aas.Slope.X * Math.Sin(-PHI));
                float sly = (float)(aas.Slope.X * Math.Cos(-PHI) + aas.Slope.Y * Math.Sin(-PHI));
                aas.Slope.X = slx;
                aas.Slope.Y = sly;
            }

            FitTrackLine(tr, out xmean, out ymean, out zmean, out txmean, out tymean, out wmean);



            // -- start calcul --

            int minentr = C.MinEntries; // min number of entries in the cell to accept the cell for fitting
            int stepmax = npl - 1;      //npl/minentr;     // max step
            int size    = stepmax + 1;  // vectors size

            int maxcell = 14;

            double[] da  = new double[Math.Min(size, maxcell)];
            double[] dax = new double[Math.Min(size, maxcell)];
            double[] day = new double[Math.Min(size, maxcell)];

            int[] nentr  = new int[Math.Min(size, maxcell)];
            int[] nentrx = new int[Math.Min(size, maxcell)];
            int[] nentry = new int[Math.Min(size, maxcell)];

            SySal.Tracking.MIPEmulsionTrackInfo s1, s2;
            int ist;

            for (ist = 1; ist <= stepmax; ist++)         // cycle by the step size
            {
                int i1;
                for (i1 = 0; i1 < nseg - 1; i1++)          // cycle by the first seg
                {
                    s1 = (SySal.Tracking.MIPEmulsionTrackInfo)tr[i1];
                    /* ???? KRYSS: how could this be null ???? if(!s1) continue; */
                    int i2;
                    for (i2 = i1 + 1; i2 < nseg; i2++)      // cycle by the second seg
                    {
                        s2 = (SySal.Tracking.MIPEmulsionTrackInfo)tr[i2];
                        /* ???? KRYSS: how could this be null ???? if(!s2) continue; */
                        int icell = (int)Math.Abs(s2.Field - s1.Field);
                        if (icell > maxcell)
                        {
                            continue;
                        }
                        if (icell == ist)
                        {
                            if (s2.Slope.X != 0 && s1.Slope.X != 0)
                            {
                                dax[icell - 1]    += (float)((Math.Atan(s2.Slope.X) - Math.Atan(s1.Slope.X)) * (Math.Atan(s2.Slope.X) - Math.Atan(s1.Slope.X)));
                                nentrx[icell - 1] += 1;
                            }
                            if (s2.Slope.Y != 0 && s1.Slope.Y != 0)
                            {
                                day[icell - 1]    += (float)((Math.Atan(s2.Slope.Y) - Math.Atan(s1.Slope.Y)) * (Math.Atan(s2.Slope.Y) - Math.Atan(s1.Slope.Y)));
                                nentry[icell - 1] += 1;
                            }
                            if (s2.Slope.X != 0.0 && s1.Slope.X != 0.0 && s2.Slope.Y != 0.0 && s1.Slope.Y != 0.0)
                            {
                                da[icell - 1] += (float)(((Math.Atan(s2.Slope.X) - Math.Atan(s1.Slope.X)) * (Math.Atan(s2.Slope.X) - Math.Atan(s1.Slope.X)))
                                                         + ((Math.Atan(s2.Slope.Y) - Math.Atan(s1.Slope.Y)) * (Math.Atan(s2.Slope.Y) - Math.Atan(s1.Slope.Y))));
                                nentr[icell - 1] += 1;
                            }
                        }
                    }
                }
            }

            if (m_DiffLog != null)
            {
                m_DiffLog.WriteLine("Entries: " + da.Length);
                int u;
                m_DiffLog.WriteLine("3D");
                for (u = 0; u < nentr.Length; u++)
                {
                    m_DiffLog.WriteLine(u + " " + nentr[u] + " " + da[u]);
                }
                m_DiffLog.WriteLine("Longitudinal");
                for (u = 0; u < nentrx.Length; u++)
                {
                    m_DiffLog.WriteLine(u + " " + nentrx[u] + " " + dax[u]);
                }
                m_DiffLog.WriteLine("Transverse");
                for (u = 0; u < nentry.Length; u++)
                {
                    m_DiffLog.WriteLine(u + " " + nentry[u] + " " + day[u]);
                }
                m_DiffLog.Flush();
            }

            float Zcorr = (float)Math.Sqrt(1 + txmean0 * txmean0 + tymean0 * tymean0); // correction due to non-zero track angle and crossed lead thickness

            int maxX = 0, maxY = 0, max3D = 0;                                         // maximum value for the function fit

            double[][] vindx     = new double[Math.Min(size, maxcell)][];
            double[][] errvindx  = new double[Math.Min(size, maxcell)][];
            double[][] vindy     = new double[Math.Min(size, maxcell)][];
            double[][] errvindy  = new double[Math.Min(size, maxcell)][];
            double[][] vind3d    = new double[Math.Min(size, maxcell)][];
            double[][] errvind3d = new double[Math.Min(size, maxcell)][];
            double[]   errda     = new double[Math.Min(size, maxcell)];
            double[]   errdax    = new double[Math.Min(size, maxcell)];
            double[]   errday    = new double[Math.Min(size, maxcell)];

            System.Collections.ArrayList ar_vindx     = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_errvindx  = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_vindy     = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_errvindy  = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_vind3d    = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_errvind3d = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_da        = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_dax       = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_day       = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_errda     = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_errdax    = new System.Collections.ArrayList();
            System.Collections.ArrayList ar_errday    = new System.Collections.ArrayList();



            ist = 0;
            int ist1 = 0, ist2 = 0;                          // use the counter for case of missing cells

            for (i = 0; i < vind3d.Length /* size */; i++)
            {
                if (nentrx[i] >= minentr && Math.Abs(dax[i]) < 0.1)
                {
                    if (ist >= vindx.Length)
                    {
                        continue;
                    }

                    ar_vindx.Add(new double[1] {
                        i + 1
                    });
                    ar_errvindx.Add(new double[1] {
                        .25
                    });
                    ar_dax.Add(Math.Sqrt(dax[i] / (nentrx[i] * Zcorr)));
                    ar_errdax.Add((double)ar_dax[ar_dax.Count - 1] / Math.Sqrt(2 * nentrx[i]));
                    ist++;
                    maxX = ist;
                }
                if (nentry[i] >= minentr && Math.Abs(day[i]) < 0.1)
                {
                    if (ist1 >= vindy.Length)
                    {
                        continue;
                    }

                    ar_vindy.Add(new double[1] {
                        i + 1
                    });
                    ar_errvindy.Add(new double[1] {
                        .25
                    });
                    ar_day.Add(Math.Sqrt(day[i] / (nentry[i] * Zcorr)));
                    ar_errday.Add((double)ar_day[ar_day.Count - 1] / Math.Sqrt(2 * nentry[i]));
                    ist1++;
                    maxY = ist1;
                }
                if (nentr[i] >= minentr / 2 && Math.Abs(da[i]) < 0.1)
                {
                    if (ist2 >= vind3d.Length)
                    {
                        continue;
                    }

                    ar_vind3d.Add(new double[1] {
                        i + 1
                    });
                    ar_errvind3d.Add(new double[1] {
                        .25
                    });
                    ar_da.Add(Math.Sqrt(da[i] / (2 * nentr[i] * Zcorr)));
                    ar_errda.Add((double)ar_da[ar_da.Count - 1] / Math.Sqrt(4 * nentr[i]));
                    ist2++;
                    max3D = ist2;
                }
            }

            vindx     = (double[][])ar_vindx.ToArray(typeof(double[]));
            vindy     = (double[][])ar_vindy.ToArray(typeof(double[]));
            vind3d    = (double[][])ar_vind3d.ToArray(typeof(double[]));
            errvindx  = (double[][])ar_errvindx.ToArray(typeof(double[]));
            errvindy  = (double[][])ar_errvindy.ToArray(typeof(double[]));
            errvind3d = (double[][])ar_errvind3d.ToArray(typeof(double[]));
            da        = (double[])ar_da.ToArray(typeof(double));
            dax       = (double[])ar_dax.ToArray(typeof(double));
            day       = (double[])ar_day.ToArray(typeof(double));
            errda     = (double[])ar_errda.ToArray(typeof(double));
            errdax    = (double[])ar_errdax.ToArray(typeof(double));
            errday    = (double[])ar_errday.ToArray(typeof(double));

            float dt = (float)(C.SlopeError3D_0 + C.SlopeError3D_1 * Math.Abs(tmean) + C.SlopeError3D_2 * tmean * tmean);  // measurements errors parametrization

            dt *= dt;
            float dtx = (float)(C.SlopeErrorLong_0 + C.SlopeErrorLong_1 * Math.Abs(txmean) + C.SlopeErrorLong_2 * txmean * txmean);  // measurements errors parametrization

            dtx *= dtx;
            float dty = (float)(C.SlopeErrorTransv_0 + C.SlopeErrorTransv_1 * Math.Abs(tymean) + C.SlopeErrorTransv_2 * tymean * tymean);  // measurements errors parametrization

            dty *= dty;

            float x0 = (float)(C.RadiationLength / 1000);


            // the fit results
            float ePx = 0.0f, ePy = 0.0f;            // the estimated momentum
            float eDPx = 0.0f, eDPy = 0.0f;          // the fit error

            float ePXmin = 0.0f, ePXmax = 0.0f;      // momentum 90% errors range
            float ePYmin = 0.0f, ePYmax = 0.0f;      // momentum 90% errors range

            // the output of PMSang
            float eP = 0.0f, eDP = 0.0f;
            float ePmin = 0.0f, ePmax = 0.0f;         // momentum 90% errors range

            /*
             * eF1X = MCSErrorFunction("eF1X",x0,dtx);    eF1X->SetRange(0,14);
             * eF1X->SetParameter(0,2000.);                             // starting value for momentum in GeV
             * eF1Y = MCSErrorFunction("eF1Y",x0,dty);    eF1Y->SetRange(0,14);
             * eF1Y->SetParameter(0,2000.);                             // starting value for momentum in GeV
             * eF1 = MCSErrorFunction("eF1",x0,dt);     eF1->SetRange(0,14);
             * eF1->SetParameter(0,2000.);                             // starting value for momentum in GeV
             */

            NumericalTools.AdvancedFitting.LeastSquares LSF = new NumericalTools.AdvancedFitting.LeastSquares();
            LSF.Logger = m_FitLog;
            float chi2_3D = -1.0f;
            float chi2_T  = -1.0f;
            float chi2_L  = -1.0f;

            if (max3D > 0)
            {
                try
                {
                    LSF.Fit(new MyNF(x0, dt), 1, vind3d, da, errvind3d, errda, 100);
                    eP  = (float)(1.0f / 1000.0f * Math.Abs(LSF.BestFit[0]));
                    eDP = (float)(1.0f / 1000.0f * LSF.StandardErrors[0]);
                    EstimateMomentumError(eP, npl, tymean, out ePmin, out ePmax);
                    chi2_3D = (float)LSF.EstimatedVariance;
                }
                catch (Exception)
                {
                    ePmin = ePmax = eP = -99;
                }
            }
            if (maxX > 0)
            {
                try
                {
                    LSF.Fit(new MyNF(x0, dtx), 1, vindx, dax, errvindx, errdax, 100);
                    ePx  = (float)(1.0f / 1000.0f * Math.Abs(LSF.BestFit[0]));
                    eDPx = (float)(1.0f / 1000.0f * LSF.StandardErrors[0]);
                    EstimateMomentumError(ePx, npl, txmean, out ePXmin, out ePXmax);
                    chi2_L = (float)LSF.EstimatedVariance;
                }
                catch (Exception)
                {
                    ePXmin = ePXmax = ePx = -99;
                }
            }
            if (maxY > 0)
            {
                try
                {
                    LSF.Fit(new MyNF(x0, dty), 1, vindy, day, errvindy, errday, 100);
                    ePy  = (float)(1.0f / 1000.0f * Math.Abs(LSF.BestFit[0]));
                    eDPy = (float)(1.0f / 1000.0f * LSF.StandardErrors[0]);
                    EstimateMomentumError(ePy, npl, tmean, out ePYmin, out ePYmax);
                    chi2_T = (float)LSF.EstimatedVariance;
                }
                catch (Exception)
                {
                    ePYmin = ePYmax = ePy = -99;
                }
            }

            result.ConfidenceLevel = 0.90;
            if (!C.IgnoreLongitudinal && !C.IgnoreTransverse)
            {
                result.Value      = Math.Round(eP / 0.01) * 0.01;
                result.LowerBound = Math.Round(ePmin / 0.01) * 0.01;
                result.UpperBound = Math.Round(ePmax / 0.01) * 0.01;
                if (tmean > 0.2 && ((chi2_T >= 0.0 && chi2_T < chi2_3D) || (chi2_3D < 0.0 && chi2_T >= 0.0)))
                {
                    result.Value      = Math.Round(ePy / 0.01) * 0.01;
                    result.LowerBound = Math.Round(ePYmin / 0.01) * 0.01;
                    result.UpperBound = Math.Round(ePYmax / 0.01) * 0.01;
                }
            }
            else if (!C.IgnoreTransverse && C.IgnoreLongitudinal)
            {
                result.Value      = Math.Round(ePy / 0.01) * 0.01;
                result.LowerBound = Math.Round(ePYmin / 0.01) * 0.01;
                result.UpperBound = Math.Round(ePYmax / 0.01) * 0.01;
            }
            else if (!C.IgnoreLongitudinal && C.IgnoreTransverse)
            {
                result.Value      = Math.Round(ePx / 0.01) * 0.01;
                result.LowerBound = Math.Round(ePXmin / 0.01) * 0.01;
                result.UpperBound = Math.Round(ePXmax / 0.01) * 0.01;
            }
            else
            {
                result.Value = result.LowerBound = result.UpperBound = -99;
                throw new Exception("Both projections are disabled in scattering estimation!");
            }
            return(result);
        }