using System; using System.Collections.Generic; using System.Data.SqlTypes; using System.Data.SqlClient; using System.Text; namespace BrazilTimestampReconstruction { public class TimestampReconstruction { // Hashmap of the fits Dictionary brazilFit; // Queue for the fits. Queue segment; // connection SqlConnection conn; public TimestampReconstruction(string connString) { brazilFit = new Dictionary(); segment = new Queue(); conn = new SqlConnection(connString); } #region Reader public void ReadAnchorInformation() { AnchorReader rdr = new AnchorReader(conn, brazilFit, segment); rdr.ReadAnchorInformation(); } #endregion #region Build the fit tree public void BuildTimeFits() { DeleteRelativeFit(); BuildRelativeFits(); BuildInitialGlobalFits(); BuildSmallSegmentGlobalFits(); } public void BuildRelativeFits() { // For each relative fit, obtain // the alpha and beta parameters foreach (string cfKey in brazilFit.Keys) { ClockFit cf = brazilFit[cfKey]; Dictionary rfMap = cf.LocalAnchors; foreach (string rfKey in rfMap.Keys) { if (string.Compare(rfKey,cfKey) == 0) rfMap[rfKey].ComputeRelativeFit(Constants.MIN_ANCHORS, true); /* arg2 : global: true, local: false*/ else rfMap[rfKey].ComputeRelativeFit(2, false); // Store the fit if parent < child if (Utils.KeyGreater(cfKey, rfKey) == false) { InsertRelativeFitIntoDatabase(cfKey, rfKey, rfMap[rfKey].LocalFit); } // if GPS node then it its own child if (rfKey.CompareTo(cfKey) == 0) { cf.GlobalFit = rfMap[rfKey].LocalFit; } } } } public void BuildInitialGlobalFits() { // Put the BS nodes in the queue // Process until queue is empty while (segment.Count != 0) { string parKey = segment.Dequeue(); ClockFit cf = brazilFit[parKey]; LlseFit globalFit = cf.GlobalFit; foreach (string childKey in cf.LocalAnchors.Keys) { // Compute the global Fit using // the parent key's fit and the // child nodes mapping to the // parent node RelativeFit rf = cf.LocalAnchors[childKey]; LlseFit childGlobalFit; if (SegmentDoesNotNeedFit(parKey, childKey)) { continue; } else { LlseFit localFit = rf.LocalFit; if (Utils.KeyGreater(parKey, childKey)) { childGlobalFit = rf.ComputeGlobalFit(globalFit, localFit, true, Constants.MIN_ANCHORS); } else { childGlobalFit = rf.ComputeGlobalFit(globalFit, localFit, false, Constants.MIN_ANCHORS); } if (childGlobalFit == null) { continue; } } // update the child's global key and // add child to the queue if (BetterFit(childKey, parKey, childGlobalFit)) { UpdateFit(childKey, parKey, childGlobalFit); segment.Enqueue(childKey); } } } } public void BuildSmallSegmentGlobalFits() { Dictionary smallSegFit = new Dictionary(); List smallSegKeys = new List(); // Create a list of all the segments // that still need a fit foreach (string key in brazilFit.Keys) { LlseFit gf = brazilFit[key].GlobalFit; if (gf == null) { smallSegKeys.Add(key); smallSegFit.Add(key, true); // true represents needs a fit } } // At each iteration, try to find if you // can anchor the small segment fits // with ones that have already been fit for (int anchorCount = Constants.MIN_ANCHORS - 1; anchorCount >= 2; anchorCount--) { // Check all the segments that have no fits foreach (string needFit in smallSegKeys) { if (!(smallSegFit[needFit])) { continue; } ClockFit nf = brazilFit[needFit]; // Find a fit using one of its neighbors foreach (string parKey in nf.LocalAnchors.Keys) { # region Try to use an already established parent fit to obtain a fit if (brazilFit[parKey].GlobalFit != null) { // try using this route LlseFit globalFit = brazilFit[parKey].GlobalFit; LlseFit localFit = nf.LocalAnchors[parKey].LocalFit; LlseFit childGlobalFit; RelativeFit rf = nf.LocalAnchors[parKey]; if (Utils.KeyGreater(parKey, needFit)) { childGlobalFit = rf.ComputeGlobalFit(globalFit, localFit, true, anchorCount); } else { childGlobalFit = rf.ComputeGlobalFit(globalFit, localFit, false, anchorCount); } if (childGlobalFit == null) { continue; } // update the child's global key and // add child to the queue if (BetterFit(needFit, parKey, childGlobalFit)) { UpdateFit(needFit, parKey, childGlobalFit); } } #endregion } // remove this segment from the needFit set if (brazilFit[needFit].GlobalFit != null) { smallSegFit[needFit] = false; // does not need a fit anymore } } } } #endregion #region Book keeping functions public bool SegmentDoesNotNeedFit(string parKey, string childKey) { if (parKey.CompareTo(childKey) == 0) // If GPS node return true; if (childKey.Contains("-1")) return true; //if (brazilFit[childKey].GlobalFit != null) // return true; return false; } public void UpdateFit(string childKey, string parKey, LlseFit childGlobalFit) { brazilFit[childKey].GlobalFit = childGlobalFit; brazilFit[childKey].ParentSegment = parKey; Set fitset = brazilFit[parKey].Fitset; brazilFit[childKey].AddAncestors(fitset); brazilFit[childKey].AddToPath(brazilFit[parKey].Path); } public bool BetterFit(string childKey, string parKey, LlseFit newFit) { if (newFit.ChiSquare > Constants.HIGH_CHI) return false; LlseFit prevFit = brazilFit[childKey].GlobalFit; if (prevFit == null) return true; // Check for cycles in the fit path if (brazilFit[parKey].HasAncestor(childKey)) { return false; } // Check if the reduced chi square of the new fit is better if (newFit.ChiSquare < prevFit.ChiSquare) { return true; } return false; } #endregion #region Database Insert public void InsertIntoDatabase() { try { // Delete existing fits conn.Open(); SqlCommand cmd = new SqlCommand(Constants.DEL_FITS, conn); cmd.ExecuteNonQuery(); conn.Close(); // Insert new fits conn.Open(); foreach (string key in brazilFit.Keys) { ClockFit cf = brazilFit[key]; string[] nodeSegPair = key.Split ('_'); cmd = new SqlCommand(Constants.INSERT_FIT, conn); cmd.Parameters.AddWithValue("@boxid", nodeSegPair[0]); cmd.Parameters.AddWithValue("@segment", nodeSegPair[1]); /* cmd.Parameters.AddWithValue("@parNode", SqlString.Null); cmd.Parameters.AddWithValue("@parSegment", SqlString.Null); */ cmd.Parameters.AddWithValue("@alpha", SqlDouble.Null); cmd.Parameters.AddWithValue("@beta", SqlDouble.Null); cmd.Parameters.AddWithValue("@chi2", SqlDouble.Null); cmd.Parameters.AddWithValue("@points", SqlInt16.Null); cmd.Parameters.AddWithValue("@path", SqlString.Null); //cmd.Parameters["@alpha"].Value = SqlDouble.Null; //cmd.Parameters["@beta"].Value = SqlDouble.Null; if (cf.GlobalFit != null) { cmd.Parameters["@path"].Value = cf.Path; cmd.Parameters["@alpha"].Value = new SqlDouble(cf.GlobalFit.Alpha); cmd.Parameters["@beta"].Value = new SqlDouble(cf.GlobalFit.Beta); cmd.Parameters["@chi2"].Value = new SqlDouble(cf.GlobalFit.ChiSquare); cmd.Parameters["@points"].Value = new SqlInt16(cf.GlobalFit.NumPoints); } /* if (cf.ParentSegment != null) { string[] parNodeSegPair = cf.ParentSegment.Split('_'); cmd.Parameters["@parNode"].Value = parNodeSegPair[0]; cmd.Parameters["@parSegment"].Value = parNodeSegPair[1]; } */ cmd.ExecuteNonQuery(); } conn.Close(); } catch (SqlException ex) { //Console.Out.WriteLine(ex.ToString()); } } public void DeleteRelativeFit() { try { // Delete existing fits conn.Open(); SqlCommand cmd = new SqlCommand(Constants.DEL_REL_FITS, conn); cmd.ExecuteNonQuery(); conn.Close(); } catch (SqlException ex) { //Console.Out.WriteLine(ex.ToString()); } } public void InsertRelativeFitIntoDatabase(string parKey, string childKey, LlseFit llseFit) { if (llseFit == null) return; if (Double.IsNaN(llseFit.Alpha) || Double.IsNaN(llseFit.Beta)) return; try { // Insert new relative fits conn.Open(); string[] parentNodeSegPair = parKey.Split (Constants.KEY_SYMB_CHAR); string[] childNodeSegPair = childKey.Split(Constants.KEY_SYMB_CHAR); SqlCommand cmd = new SqlCommand(Constants.INSERT_REL_FIT, conn); cmd.Parameters.AddWithValue("@box1", parentNodeSegPair[0]); cmd.Parameters.AddWithValue("seg1", parentNodeSegPair[1]); cmd.Parameters.AddWithValue("@box2", childNodeSegPair[0]); cmd.Parameters.AddWithValue("@seg2", childNodeSegPair[1]); cmd.Parameters.AddWithValue("@alpha", llseFit.Alpha); cmd.Parameters.AddWithValue("@beta", llseFit.Beta); cmd.Parameters.AddWithValue("@chi2", llseFit.ChiSquare); cmd.Parameters.AddWithValue("@points", llseFit.NumPoints); cmd.ExecuteNonQuery(); } catch (SqlException ex) { //Console.Out.WriteLine(ex.ToString()); } finally { conn.Close(); } } #endregion } }