/// <summary> /// Figures out what kind of data the file contains and passes it to parser. /// </summary> /// <param name="myStream">the file to parse</param> private void readFileData(Stream myStream) { // Make a new StreamReader to read the text input file. StreamReader reader = new StreamReader(myStream); // Check the first line of the file for its file type identifier. string fileType = reader.ReadLine().Trim(); // The new file data object will be stored here if successful. FileDataAbstract fileData; // Try to read the file data. if (fileType == "I0") { // TODO: Finish other data file types. fileData = new FileDataI0(reader.ReadToEnd(), this.currentTimeStep); } // Throw an exception if the format is not recognized. else { throw new Exception("The file format was not recognized; only files in 'I0' format work at this time."); } // If there are already other data files, make sure they are compatible. if (this.fileDataList.Count > 0) { FileDataAbstract tempData = this.fileDataList[0]; if (tempData.Xdim != fileData.Xdim || tempData.Ydim != fileData.Ydim || tempData.Zdim != fileData.Zdim) { throw new Exception("The file you are attempting to add has different dimensions than the previously added file(s). " + "If you would like to start over with new data, please clear the current data first."); } } // If we've gotten this far without Exception, we can // assume the file data will be added successfully. this.currentTimeStep++; this.fileDataList.Add(fileData); // Take the file data and turn it into a list of grid points. List<GridPoint> pointsList = fileData.GetSortedGridPointList(); // If there are already other file(s) in the program, clear out // the current trees and add their data to the points list. if (this.fileDataList.Count > 1) { // Clear the trees. this.joinTreeView.ClearTrees(); this.splitTreeView.ClearTrees(); this.contourTreeView.ClearTrees(); // Add the data. foreach (FileDataAbstract data in this.fileDataList) { pointsList = pointsList.Union(data.GetSortedGridPointList()).ToList(); pointsList.Sort(new Comparison<GridPoint>(GridPoint.Compare)); } } // Create the join tree and split tree from the file data. JoinTree joinTree = new JoinTree(pointsList[0].value, pointsList.Last().value, pointsList); SplitTree splitTree = new SplitTree(pointsList[0].value, pointsList.Last().value, pointsList); // Simplify the trees, except for the others' critical points. joinTree.SimplifyExceptFor(splitTree.GetCritical()); splitTree.SimplifyExceptFor( joinTree.GetCritical()); // Make the contour tree. ContourTree contourTree = new ContourTree(joinTree, splitTree); this.contourTreeView.AddTree(contourTree); this.topology.SetTree(contourTree); this.topology.AddTimeStep(); // Simplify trees the rest of the way. joinTree.Simplify(); splitTree.Simplify(); // Add trees to their views. this.joinTreeView.AddTree(joinTree); this.splitTreeView.AddTree(splitTree); // Dispose of unneeded resources. reader.Dispose(); myStream.Close(); }
//===================================================================// // Constructors // //===================================================================// /// <summary> /// Create a new ContourTree from the specified JoinTree and SplitTree. /// </summary> /// <remarks> /// A small warning: this will not work properly if there are only two /// nodes in both the split and join trees. /// </br></br> /// A different small warning: at present, the contour tree constructor /// does not actually fill the "merging" list with its merge nodes. /// I didn't need it filled out for my purposes, so I didn't make it work. /// </remarks> /// <param name="joinTree">the join tree</param> /// <param name="splitTree">the split tree</param> public ContourTree(JoinTree joinTree, SplitTree splitTree) { this.maxValue = joinTree.maxValue; this.minValue = joinTree.minValue; JoinTree cloneJoinTree = new JoinTree( joinTree); SplitTree cloneSplitTree = new SplitTree(splitTree); List<TreeNode> upLeaves = new List<TreeNode>( cloneJoinTree.GetParentless()); List<TreeNode> downLeaves = new List<TreeNode>(cloneSplitTree.GetChildless()); List<BlobOfContourNodes> blobList = new List<BlobOfContourNodes>(); //===============================================================// // Add parentless nodes from join tree. //===============================================================// // For each of the parentless nodes in the join tree, foreach (TreeNode upLeaf in upLeaves) { // copy the node and add it to the contour tree. ContourNode newNode = new ContourNode(upLeaf); if (this.topMostLeaf == null) { this.topMostLeaf = newNode; } // Check if the child of the parentless node has already been // added to the contour tree. bool matchFound = false; int tempIndex = 0; while (!matchFound && tempIndex < blobList.Count) { // If a match is found, if (blobList[tempIndex].ContainsMatch(upLeaf.GetChildren()[0])) { // set the flag, matchFound = true; // make the parentless node a branch of the match, blobList[tempIndex].GetMostRecentlyAddedNode().AddBranch(newNode); // make the match the trunk of the parentless node, newNode.SetTrunk(blobList[tempIndex].GetMostRecentlyAddedNode()); // and add the parentless node to the correct blob. ((List<ContourNode>)blobList[tempIndex]).Add(newNode); } tempIndex++; } // If a match was not found, make a new blob. if (!matchFound) { // Create a BlobOfContourNodesnew blob and a new node for the trunk. BlobOfContourNodes newBlob = new BlobOfContourNodes(newNode); ContourNode newTrunk = new ContourNode(upLeaf.GetChildren()[0]); // Set up branch / trunk relationships. newNode.SetTrunk(newTrunk); newTrunk.AddBranch(newNode); // Add the new node to the new blob. newBlob.Add(newTrunk); // Add the new blob to the blob list. blobList.Add(newBlob); } // Remove the parentless node from both the split tree and the join tree. cloneSplitTree.RemoveMatch(upLeaf); cloneJoinTree.RemoveMatch(upLeaf); } // end of adding parentless nodes to the contour tree //===============================================================// // Add childless nodes from split tree. //===============================================================// foreach (TreeNode downLeaf in downLeaves) { // Copy the node and add it to the contour tree. ContourNode newNode = new ContourNode(downLeaf); if (this.botMostLeaf == null) { this.botMostLeaf = newNode; } // Check if the parent of the childless node has already been // added to the contour tree. bool matchFound = false; int tempIndex = 0; while (!matchFound && tempIndex < blobList.Count) { // If a match is found, if (blobList[tempIndex].ContainsMatch(downLeaf.GetParents()[0])) { // set the flag, matchFound = true; // make the childless node a branch of the match, blobList[tempIndex].GetMostRecentlyAddedNode().AddBranch(newNode); // make the match the trunk of the childless node, newNode.SetTrunk(blobList[tempIndex].GetMostRecentlyAddedNode()); // and add the childless node to the correct blob. ((List<ContourNode>)blobList[tempIndex]).Add(newNode); } tempIndex++; } // If a match was not found, make a new blob. if (!matchFound) { // Create a new blob and a new node for the branch. BlobOfContourNodes newBlob = new BlobOfContourNodes(newNode); ContourNode newTrunk = new ContourNode(downLeaf.GetParents()[0]); // Set up trunk / branch relationships. newNode.SetTrunk(newTrunk); newTrunk.AddBranch(newNode); // Add the new node to the new blob. newBlob.Add(newTrunk); // Add the new blob to the blob list. blobList.Add(newBlob); } // Remove the childless node from both the split tree and the join tree. cloneSplitTree.RemoveMatch(downLeaf); cloneJoinTree.RemoveMatch(downLeaf); } // end of adding childless nodes to the contour tree //===============================================================// // Add additional nodes from join tree. //===============================================================// // Add nodes from the Join tree until the join tree has no more // branches to add and only the trunk remains. // Please note: this means the node currently being examined will // always have a valid, non-null child. while (cloneJoinTree.GetParentless().Count > 1) { // Store the nodes we'll be working with. List<TreeNode> oldLevel = cloneJoinTree.GetParentless(); foreach (TreeNode oldNode in oldLevel) { // Store the child of the node being worked with. TreeNode oldChild = oldNode.GetChildren()[0]; // The blob that contains the current node. BlobOfContourNodes containingBlob = null; // The blob that contains the current node's child. BlobOfContourNodes trunkBlob = null; // Look through the blobs until both the containingBlob and // trunkBlob are found, or all of the blobs have been examined. int index = 0; while ((containingBlob == null || trunkBlob == null) && index < blobList.Count) { // Store current blob and its most recently added node in // temporary variables to avoid extra function calls. BlobOfContourNodes currentBlob = blobList[index]; ContourNode mostRecent = currentBlob.GetMostRecentlyAddedNode(); // Check if current blob is containingBlob. if (mostRecent.Matches(oldNode)) { containingBlob = currentBlob; } // Check if current blob is childBlob. else if (oldChild.Matches(mostRecent)) { trunkBlob = currentBlob; } index++; } // If trunkBlob was not found, make a new node for the trunk // and add it to the contour tree and the containingBlob. if (trunkBlob == null) { ContourNode newNode = containingBlob.GetMostRecentlyAddedNode(); ContourNode newTrunk = new ContourNode(oldChild); // Set trunk / branch relations. newNode.SetTrunk(newTrunk); newTrunk.AddBranch(newNode); // Add newTrunk to the blob. containingBlob.Add(newTrunk); } // If the trunkBlob was found, merge the trunkBlob and // containingBlob blobs. else { ContourNode newNode = containingBlob.GetMostRecentlyAddedNode(); ContourNode newTrunk = trunkBlob.GetMostRecentlyAddedNode(); // Set branch / trunk relations. newNode.SetTrunk(newTrunk); newTrunk.AddBranch(newNode); // Make a list of the two blobs so the blob merge // constructor can be used. List<BlobOfContourNodes> paramList = new List<BlobOfContourNodes>(); paramList.Add(containingBlob); paramList.Add(trunkBlob); // This prevents the newTrunk from being double-listed // in the new blob. trunkBlob.Remove(newTrunk); // Make the new blob, containing all the nodes from the // trunk and containing blobs, with newTrunk as root. BlobOfContourNodes newBlob = new BlobOfContourNodes(newTrunk, paramList); // Update the blob list. blobList.Remove(containingBlob); blobList.Remove(trunkBlob); blobList.Add(newBlob); } // Either way, remove the node from both trees. cloneSplitTree.RemoveMatch(oldNode); cloneJoinTree.RemoveMatch(oldNode); } } // end of adding additional nodes from the join tree //===============================================================// // Add remaining nodes from split tree. //===============================================================// // Now just add all the remaining nodes in the split tree, from bottom to top. while (cloneSplitTree.GetChildless().Count > 0) { // Store the node we'll be working with. TreeNode oldNode = cloneSplitTree.GetChildless()[0]; // Also store the parent of the node being worked with, unless // it has no parent, in which case we do different stuff later. TreeNode oldParent = oldNode.GetParents().Count == 0 ? null : oldNode.GetParents()[0]; // The blob that contains the current node. BlobOfContourNodes containingBlob = null; // The blob that contains the current node's parent, // unless there was no parent. BlobOfContourNodes trunkBlob = null; // Look through the blobs until both the containingBlob and // trunkBlob are found, or all the blobs have been examined, // or containingBlob is found and there was no parent. int index = 0; while ((containingBlob == null || (trunkBlob == null && oldParent != null)) && index < blobList.Count) { // Store current blob and its most recently added node in // temporary variables to avoid extra function calls. BlobOfContourNodes currentBlob = blobList[index]; ContourNode mostRecent = currentBlob.GetMostRecentlyAddedNode(); // Check if current blob is containingBlob. if (mostRecent.Matches(oldNode)) { containingBlob = currentBlob; } // Check if current blob is trunkBlob. else if (oldParent != null && oldParent.Matches(mostRecent)){ trunkBlob = currentBlob; } index++; } // If trunkBlob was not found and a parent node exists, // make a new node for the parent and add it to the contour // tree and the containingBlob. if (trunkBlob == null && oldParent != null) { ContourNode newNode = containingBlob.GetMostRecentlyAddedNode(); ContourNode newTrunk = new ContourNode(oldParent); // Set trunk / branch relations. newNode.SetTrunk(newTrunk); newTrunk.AddBranch(newNode); // Add newParent to the blob. containingBlob.Add(newTrunk); } // If the trunkBlob was found, merge the trunkBlob and // containingBlob blobs. else if (trunkBlob != null) { ContourNode newNode = containingBlob.GetMostRecentlyAddedNode(); ContourNode newTrunk = trunkBlob.GetMostRecentlyAddedNode(); // Set branch / trunk relations. newNode.SetTrunk(newTrunk); newTrunk.AddBranch(newNode); // Make a list of the two blobs so the blob merge // constructor can be used. List<BlobOfContourNodes> paramList = new List<BlobOfContourNodes>(); paramList.Add(containingBlob); paramList.Add( trunkBlob); // This prevents the newParent from being double-listed // in the new blob. trunkBlob.Remove(newTrunk); // Make the new blob, containing all the nodes from the // trunk and containing blobs, with newTrunk as root. BlobOfContourNodes newBlob = new BlobOfContourNodes(newTrunk, paramList); // Update the blob list. blobList.Remove(containingBlob); blobList.Remove(trunkBlob); blobList.Add(newBlob); } // Otherwise, if there was no parent node, store the current // node as the "root" of the contour tree. else { this.root = containingBlob.GetMostRecentlyAddedNode(); } // No matter what, remove the node from both trees. cloneSplitTree.RemoveMatch(oldNode); cloneJoinTree.RemoveMatch(oldNode); } }
/// <summary> /// Add a new data file with formatting like the data file from Nathaniel. /// </summary> /// <param name="uselessParam1">required by C#</param> /// <param name="uselessParam2">required by C#</param> private void addNewNathanielDataFile(object uselessParam1, EventArgs uselessParam2) { // If opened properly, the file data will be stored here. Stream myStream = null; // This is a popup window that lets you pick a file to open. OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.InitialDirectory = "C:\\"; openFileDialog.Filter = "txt files (*.txt)|*.txt"; // Only look at text files. // If the file doesn't get opened / read / added properly, display an error message. if (openFileDialog.ShowDialog() == DialogResult.OK) { try { if ((myStream = openFileDialog.OpenFile()) != null) { // Make a new StreamReader to read the text input file. StreamReader reader = new StreamReader(myStream); // The new file data object will be stored here if successful. FileDataAbstract fileData; fileData = new FileDataNathaniel(reader.ReadToEnd(), this.currentTimeStep); // If there are already other data files, make sure they are compatible. if (this.fileDataList.Count > 0) { FileDataAbstract tempData = this.fileDataList[0]; if (tempData.Xdim != fileData.Xdim || tempData.Ydim != fileData.Ydim || tempData.Zdim != fileData.Zdim) { throw new Exception("The file you are attempting to add has different dimensions than the previously added file(s). " + "If you would like to start over with new data, please clear the current data first."); } } // If we've gotten this far without Exception, we can // assume the file data will be added successfully. this.currentTimeStep++; this.fileDataList.Add(fileData); // Take the file data and turn it into a list of grid points. List<GridPoint> pointsList = fileData.GetSortedGridPointList(); // If there are already other file(s) in the program, clear out // the current trees and add their data to the points list. if (this.fileDataList.Count > 1) { // Clear the trees. this.joinTreeView.ClearTrees(); this.splitTreeView.ClearTrees(); this.contourTreeView.ClearTrees(); // Add the data. foreach (FileDataAbstract data in this.fileDataList) { pointsList = pointsList.Union(data.GetSortedGridPointList()).ToList(); pointsList.Sort(new Comparison<GridPoint>(GridPoint.Compare)); } } // Create the join tree and split tree from the file data. JoinTree joinTree = new JoinTree(pointsList[0].value, pointsList.Last().value, pointsList); SplitTree splitTree = new SplitTree(pointsList[0].value, pointsList.Last().value, pointsList); // Simplify the trees, except for the others' critical points. joinTree.SimplifyExceptFor(splitTree.GetCritical()); splitTree.SimplifyExceptFor(joinTree.GetCritical()); // Make the contour tree. ContourTree contourTree = new ContourTree(joinTree, splitTree); this.contourTreeView.AddTree(contourTree); this.topology.SetTree(contourTree); this.topology.AddTimeStep(); // Simplify trees the rest of the way. joinTree.Simplify(); splitTree.Simplify(); // Add trees to their views. this.joinTreeView.AddTree(joinTree); this.splitTreeView.AddTree(splitTree); // Dispose of unneeded resources. reader.Dispose(); myStream.Close(); } } catch (Exception ex) { MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); } } }
/// <summary> /// This is a copy constructor for JoinTree. /// </summary> /// <param name="other">the JoinTree to copy</param> public JoinTree(JoinTree other) : base(other.maxValue, other.minValue) { other.Clone(this.parentless, this.merging, this.childless); }