private static void ComputeAndShowResult(string FileIn, int idTrack0, System.Collections.ArrayList InputData, SySal.Processing.MCSAnnecy.MomentumEstimator mcs) { MomentumResult finalResult = new MomentumResult(); #if !(DEBUG) try { #endif finalResult = mcs.ProcessData((SySal.Tracking.MIPEmulsionTrackInfo[])InputData.ToArray(typeof(SySal.Tracking.MIPEmulsionTrackInfo))); #if !(DEBUG) } catch (Exception x) { finalResult.Value = finalResult.ConfidenceLevel = finalResult.LowerBound = finalResult.UpperBound = 0.0; Console.WriteLine(x.ToString()); } #endif Console.WriteLine(FileIn + " " + idTrack0 + " " + finalResult.Value + " " + finalResult.LowerBound + " " + finalResult.UpperBound); }
/// <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); }
public static MomentumResult ProcessData(IMCSMomentumEstimator algo, Track tk) { int i, j; SySal.Tracking.MIPEmulsionTrackInfo[] tkinfo = new SySal.Tracking.MIPEmulsionTrackInfo[tk.Length]; if (algo is SySal.Processing.MCSLikelihood.MomentumEstimator) { Geometry geom = ((SySal.Processing.MCSLikelihood.Configuration)(((SySal.Management.IManageable)((object)algo)).Config)).Geometry; for (i = 0; i < tkinfo.Length; i++) { if (tk[i].LayerOwner.Side != 0) { throw new Exception("This functionality is only available for base-tracks.\r\nConsider using the interactive version, available in the interactive display."); } tkinfo[i] = tk[i].Info; for (j = 0; j < geom.Layers.Length && tk[i].LayerOwner.SheetId != geom.Layers[j].Plate; j++) { ; } if (j == geom.Layers.Length) { throw new Exception("Layer " + i + " Sheet " + tk[i].LayerOwner.SheetId + " does not map to any plate in momentum geometry.\r\nPlease check your geometry information."); } double z = (tkinfo[i].TopZ + tkinfo[i].BottomZ) * 0.5; if (z < tk[i].LayerOwner.UpstreamZ) { z = tk[i].LayerOwner.UpstreamZ; } else if (z > tk[i].LayerOwner.DownstreamZ) { z = tk[i].LayerOwner.DownstreamZ; } tkinfo[i].Intercept.X += tkinfo[i].Slope.X * (z - tkinfo[i].Intercept.Z); tkinfo[i].Intercept.Y += tkinfo[i].Slope.Y * (z - tkinfo[i].Intercept.Z); tkinfo[i].Intercept.Z = geom.Layers[j].ZMin + z - tk[i].LayerOwner.UpstreamZ; } } else if (algo is SySal.Processing.MCSAnnecy.MomentumEstimator) { for (i = 0; i < tkinfo.Length; i++) { if (tk[i].LayerOwner.Side != 0) { throw new Exception("This functionality is only available for base-tracks.\r\nConsider using the interactive version, available in the interactive display."); } tkinfo[i] = tk[i].Info; tkinfo[i].Field = (uint)tk[i].LayerOwner.Id; } } else { throw new Exception("Unsupported algorithm."); } MomentumResult res = algo.ProcessData(tkinfo); if (res.Value < 0.0) { throw new Exception("Invalid measurement"); } tk.SetAttribute(new SySal.TotalScan.NamedAttributeIndex("P"), res.Value); tk.SetAttribute(new SySal.TotalScan.NamedAttributeIndex("PMin" + (res.ConfidenceLevel * 100.0).ToString("F0", System.Globalization.CultureInfo.InvariantCulture)), res.LowerBound); tk.SetAttribute(new SySal.TotalScan.NamedAttributeIndex("PMax" + (res.ConfidenceLevel * 100.0).ToString("F0", System.Globalization.CultureInfo.InvariantCulture)), res.UpperBound); return(res); }
/// <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).</param> /// <param name="likelihood">the output variable that will contain the likelihood function.</param> /// <returns>the momentum and confidence limits.</returns> public MomentumResult ProcessData(SySal.Tracking.MIPEmulsionTrackInfo[] data, out NumericalTools.Likelihood likelihood) { MomentumResult myResult = new MomentumResult(); //ordiniamo gli elementi della geometria e dei dati inseriti per z Geometry gm = C.Geometry; data = orderElementData(data); //Controllo che la traccia sia contenuta in tutto il brick if (data[0].Intercept.Z <gm.Layers[0].ZMin || data[data.Length - 1].Intercept.Z> gm.Layers[gm.Layers.Length - 1].ZMin) { throw new Exception("Data span a Z interval that exceeds the geometry bounds."); } //Calcolo gli scattering ad ogni step e li scrivo nel file di dump se c'è!! scattDifference[] scatDif = calcScattDiff(gm, data); if (m_tkDumpFile != null) { writeInFileTK(scatDif); } //calcolo le differenze ArrayList resultDiff = new ArrayList(); ArrayList resultDiffL = new ArrayList(); double myRadiationLength = C.MinimumRadiationLengths; resultDiff = angularDifference(data, scatDif, myRadiationLength); resultDiffL = angularDifferenceL(data, scatDif, myRadiationLength); if (resultDiff.Count == 0) { throw new Exception("No slope difference available for computation."); } if (m_angularDiffDumpFile != null) { writeInFileAD(resultDiff); } //Calcolo elementi della matrice di covarianza e li scrivo nel file di dump se c'è!! ArrayList matrixFinal = new ArrayList(); matrixFinal = covMatrix(resultDiff, scatDif); if (m_cvDumpFile != null) { writeInFileCV(matrixFinal); } //Calcolo la probabilità totale e li scrivo nel file di dump se c'è!! int maxIndex = 0; ProbMomentum[] finalData = totalProbability(resultDiff, matrixFinal, C.MinimumMomentum, C.MaximumMomentum, C.MomentumStep, ref maxIndex); if (m_lkDumpFile != null) { writeInFileLK(finalData); } //Calcolo i limiti di confidenza double maxLike = finalData[maxIndex].probTot; double myCutLike; myCutLike = cutLike(maxLike); limit myLimit; myLimit = limitCalculation(finalData, myCutLike, maxIndex); //Scrivo i risultati myResult.Value = finalData[maxIndex].momValue; myResult.LowerBound = myLimit.lwLimit; myResult.UpperBound = myLimit.upLimit; myResult.ConfidenceLevel = 0.90; double[] lkval = new double[finalData.Length]; int i; for (i = 0; i < lkval.Length; i++) { lkval[i] = finalData[i].probTot; } likelihood = new NumericalTools.OneParamLogLikelihood(finalData[0].momValue, finalData[finalData.Length - 1].momValue, lkval, "P"); return(myResult); /* * finalData = totalProbability(resultDiffL, matrixFinal, C.MinimumMomentum, C.MaximumMomentum, C.MomentumStep, ref maxIndex); * for (i = 0; i < lkval.Length; i++) * lkval[i] = finalData[i].probTot; * likelihood = new NumericalTools.OneParamLogLikelihood(C.MomentumStep, likelihood, new NumericalTools.OneParamLogLikelihood(finalData[0].momValue, finalData[finalData.Length - 1].momValue, lkval, "P")); * myResult.Value = likelihood.Best(0); * double[] cr = likelihood.ConfidenceRegions(0, C.ConfidenceLevel); * myResult.LowerBound = cr[0]; * myResult.UpperBound = cr[1]; * return myResult; */ }