/// <summary> /// Look at everything we have in this tree and see if we can't generate a class correctly. /// </summary> /// <param name="tree"></param> /// <returns></returns> public IEnumerable<ROOTClassShell> GenerateClasses(ROOTNET.Interface.NTTree tree) { if (tree == null) throw new ArgumentNullException("tree must not be null"); /// /// The outlying class is going to be called by the name of the tree. /// var masterClass = new ROOTClassShell(tree.Name); var subClassesByName = from sc in ExtractClassesFromBranchList(masterClass, tree.ListOfBranches.Cast<ROOTNET.Interface.NTBranch>()) group sc by sc.Name; var subClasses = from scg in subClassesByName where scg.ClassesAreIdnetical() select scg.First(); foreach (var sc in subClasses) { yield return sc; } /// /// Last thing we need to do is create a proxy for the class. /// FileInfo f = MakeProxy(tree); masterClass.NtupleProxyPath = f.FullName; /// /// Work around a ROOT bug that doesn't allow for unloading of classes /// in the STL after a query is run. Actually, it will unload them, but somehow keeps /// references in memory. /// masterClass.ClassesToGenerate = ExtractSTLDictionaryReferences(f); /// /// Analyze the TTree arrays. /// var at = new ArrayAnalyzer(); var groupInfo = at.AnalyzeTTree(masterClass, tree, 100); /// /// Any item that isn't an array should be added to the list and /// put in the "ungrouped" array. /// AddNonArrays(masterClass, groupInfo, "ungrouped"); /// /// Write out the user info /// masterClass.UserInfoPath = WriteUserInfo(groupInfo, tree.SanitizedName()).FullName; /// /// Return the master class /// yield return masterClass; }
/// <summary> /// Generate a proxy for the tree. This involves making the proxy and then putting in the proper /// text substitutions for later processing by our framework. Some ugly text hacking! /// </summary> /// <param name="tree"></param> /// <returns></returns> private FileInfo MakeProxy(ROOTNET.Interface.NTTree tree) { /// /// First create the proxy. We have to create a darn temp macro name for that. /// var oldDir = Environment.CurrentDirectory; var createItDir = new DirectoryInfo(Environment.CurrentDirectory); if (ProxyGenerationLocation != null) createItDir = ProxyGenerationLocation; FileInfo macroFile = new FileInfo(createItDir + @"\junk_macro_parsettree_" + tree.SanitizedName() + ".C"); FileInfo result = null; try { /// /// We can only use local directories /// if (ProxyGenerationLocation != null) Environment.CurrentDirectory = ProxyGenerationLocation.FullName; using (var writer = macroFile.CreateText()) { writer.WriteLine("void {0} () {{}}", Path.GetFileNameWithoutExtension(macroFile.Name)); writer.Close(); } result = new FileInfo("ntuple_" + tree.SanitizedName() + ".h"); tree.MakeProxy(Path.GetFileNameWithoutExtension(result.Name), macroFile.Name, null, "nohist"); } finally { /// /// Go back to where we were /// Environment.CurrentDirectory = oldDir; } /// /// Next, add the proper things and remove some stuff /// /// /// Return the location of the cpp file /// return result; }