Beispiel #1
0
        /// <summary>
        /// Extract info for a sub-class from a branch! The last one is the top level class we are currently parsing!
        /// </summary>
        /// <param name="branch"></param>
        /// <returns></returns>
        private IEnumerable <ROOTClassShell> ExtractClass(ROOTClassShell container, ROOTNET.Interface.NTBranch branch)
        {
            ///
            /// First, figure out what kind of class this is. For example, might it be a stl vector? If so,
            /// then we need to parse that up!
            ///

            if (branch.GetClassName().Contains("<"))
            {
                return(ExtractROOTTemplateClass(container, branch));
            }
            else
            {
                return(ExtractROOTPlainClass(container, branch));
            }
        }
Beispiel #2
0
        /// <summary>
        /// A class has been defined only in the local tree. We need to parse through it and extract
        /// enough into to build a class on our own so that it can be correctly referenced in LINQ.
        /// </summary>
        /// <param name="container"></param>
        /// <param name="branch"></param>
        /// <param name="cls"></param>
        /// <returns></returns>
        private IEnumerable <ROOTClassShell> BuildMetadataForTTreeClassFromBranches(ROOTClassShell container, ROOTNET.Interface.NTBranch branch, ROOTNET.Interface.NTClass cls)
        {
            //
            // Get a unique classname. Attempt to do "the right thing". In particular, if this is a clones array of some
            // struct, it is not a "named" class, so use the name of the clones array instead.
            //

            string className          = cls.Name;
            bool   mightBeClonesArray = false;

            if (branch is ROOTNET.Interface.NTBranchElement)
            {
                var cn = (branch as ROOTNET.Interface.NTBranchElement).ClonesName.SanitizedName();
                if (!string.IsNullOrWhiteSpace(cn))
                {
                    className          = cn;
                    mightBeClonesArray = true;
                }
            }

            if (_classNameCounter.ContainsKey(className))
            {
                _classNameCounter[className] += 1;
                className = string.Format("{0}_{1}", className, _classNameCounter[className]);
            }
            else
            {
                _classNameCounter[className] = 0;
            }

            //
            // We will define the class, and it will be exactly what is given to use by the
            // tree.
            //

            var varName = branch.Name.SanitizedName();

            container.Add(new ItemSimpleType(varName, className)
            {
                NotAPointer = true
            });

            //
            // We are going to build our own class type here.
            //

            var treeClass = new ROOTClassShell(className)
            {
                IsTopLevelClass = false
            };

            //
            // Now, loop over the branches and add them in, returning any classes we had to generate.
            //

            foreach (var c in ExtractClassesFromBranchList(treeClass, branch.ListOfBranches.Cast <ROOTNET.Interface.NTBranch>()))
            {
                yield return(c);
            }

            //
            // The arrays in a tclones arrays are funny. The proxy generated parses them as seperate arrays, but their length is
            // basically the size of the tclonesarray. So we have to use that as the length. This is implied be cause we've marked
            // this class as a tclones array class already (above - the IsTTreeSubClass). So for the index we mark it as an index,
            // but we just marked the bound as "implied" - this will be picked up by the code when it is generated later on.
            //

            if (mightBeClonesArray)
            {
                var cBoundName          = string.Format("{0}_", varName);
                var cstyleArrayIndicies = from item in treeClass.Items
                                          where item is ItemCStyleArray
                                          let citem = item as ItemCStyleArray
                                                      from index in citem.Indicies
                                                      where !index.indexConst && index.indexBoundName == cBoundName
                                                      select index;
                bool foundTClonesArray = false;
                foreach (var item in cstyleArrayIndicies)
                {
                    item.indexBoundName = "implied";
                    foundTClonesArray   = true;
                }
                treeClass.IsTClonesArrayClass = foundTClonesArray;
            }

            //
            // If this is a tclones array - and it is a real array, then we don't want to de-reference anything.
            //

            if (treeClass.IsTClonesArrayClass)
            {
                foreach (var item in treeClass.Items)
                {
                    item.NotAPointer = true;
                }
            }

            //
            // Finally, the one we just built!
            //

            yield return(treeClass);
        }
Beispiel #3
0
        /// <summary>
        /// There is a plain class that needs to be extracted. We usually end up here becuase it is a split class of
        /// some sort. For now, we will assume it is a real root class.
        /// </summary>
        /// <param name="branch"></param>
        /// <returns></returns>
        private IEnumerable <ROOTClassShell> ExtractROOTPlainClass(ROOTClassShell container, ROOTNET.Interface.NTBranch branch)
        {
            //
            // Double chekc that this is a root class. Since we are looking at the Tree, ROOT's system would certianly have declared it
            // internally. If we can't find the cls info, then we are in trouble.
            //

            var cls = ROOTNET.NTClass.GetClass(branch.GetClassName());

            if (cls == null)
            {
                throw new NotImplementedException("The class '" + branch.GetClassName() + "' is not known to ROOT's type systems - and I can't proceed unless it is");
            }
            if (cls.Name == "string")
            {
                throw new NotImplementedException("The class 'string' is not translated yet!");
            }

            //
            // There are several ways this class can be encoded in the file. They broadly break down
            // into two classes:
            //
            //  1) A class that is fully defined by ROOT. TLorentzVector would be such a thing.
            //      Custom classes that ROOT has a full dictionary for are equivalent and that
            //      we have a good wrapper for.
            //  2) A class that is only defined by the contents of the ROOT file. This could be
            //      as a series of leaves in the TTree (this would be the case of a split class)
            //      or in the streamer, which is a non-split class' case.
            //

            //
            // If it has some public data members, then it is a real ROOT class, and whatever was done to define it and make it known
            // to ROOT here we assume will also be done when the full blown LINQ interface is run (i.e. some loaded C++ files).
            //

            if (!cls.IsShellTClass())
            {
                container.Add(new ItemROOTClass(branch.Name, branch.GetClassName()));
                return(Enumerable.Empty <ROOTClassShell>());
            }

            //
            // If we are here, then we are dealing with a locally defined class. One that ROOT made up on the fly. In short, not one
            // that we are going to have a translation for. So, we have to build the meta data for it. This
            // meta data can come from the tree branch list or from the streamer.
            //

            return(BuildMetadataForTTreeClassFromBranches(container, branch, cls));
        }
Beispiel #4
0
 /// <summary>
 /// Given a branch that is a template, parse it and add to the class hierarchy.
 /// </summary>
 /// <param name="branch"></param>
 /// <returns></returns>
 private IEnumerable <ROOTClassShell> ExtractROOTTemplateClass(ROOTClassShell container, ROOTNET.Interface.NTBranch branch)
 {
     return(ExtractROOTTemplateClass(container, branch.Name, branch.GetClassName()));
 }