{"_id":"@dexvis/root-geo-tree-editor","_rev":"2-eff11b4ad3ecb29767e63b60ba42c539","name":"@dexvis/root-geo-tree-editor","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@dexvis/root-geo-tree-editor","version":"0.1.0","keywords":["root","geometry","cern","tgeo","tree","editor"],"author":{"name":"dexvis"},"license":"MIT","_id":"@dexvis/root-geo-tree-editor@0.1.0","maintainers":[{"name":"eicdev","email":"romanovda@gmail.com"},{"name":"sqrd.max","email":"sqrd.max@gmail.com"}],"homepage":"https://github.com/dexvis/root-geo-tree-editor#readme","bugs":{"url":"https://github.com/dexvis/root-geo-tree-editor/issues"},"dist":{"shasum":"a18b0e17cb6e4ef165683470863853824f528984","tarball":"https://registry.npmjs.org/@dexvis/root-geo-tree-editor/-/root-geo-tree-editor-0.1.0.tgz","fileCount":2,"integrity":"sha512-EBKwZJrC4OsADTOXzpH/GFy1lOySCcw8GYcBJRgQ4uZNA3LGpyPbtCPbgMlwCQtU7p/xXCUGtWBphkI2G8iI0A==","signatures":[{"sig":"MEUCIQCgDkSzlisbreRGQaZKHKmKfQVvBkExXK4vIVoN9qXDegIgFJ8ymY5InYWuJLINJy7uBjG2CuRsC4MLRGQnman3NP4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":8944},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"0d36ce0e5ff247624e9b8489ea98a24c97c67d07","scripts":{"dev":"tsup --watch","test":"vitest","build":"tsup"},"_npmUser":{"name":"eicdev","email":"romanovda@gmail.com"},"repository":{"url":"git+https://github.com/dexvis/root-geo-tree-editor.git","type":"git"},"_npmVersion":"10.9.4","description":"Utility functions for navigating and manipulating TGeo nodes within the CERN ROOT framework. Includes functionalities to walk through geometric nodes with customizable callbacks, find nodes matching specific patterns, and analyze nodes based on provided c","directories":{},"_nodeVersion":"22.21.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^4.0.18","typescript":"^5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/root-geo-tree-editor_0.1.0_1771218192461_0.32601343947415296","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@dexvis/root-geo-tree-editor","version":"0.1.1","description":"Utility functions for navigating and manipulating TGeo nodes within the CERN ROOT framework. Includes functionalities to walk through geometric nodes with customizable callbacks, find nodes matching specific patterns, and analyze nodes based on provided c","type":"module","publishConfig":{"access":"public"},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs","types":"./dist/index.d.ts"}},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest"},"repository":{"type":"git","url":"git+https://github.com/dexvis/root-geo-tree-editor.git"},"keywords":["root","geometry","cern","tgeo","tree","editor"],"author":{"name":"dexvis"},"license":"MIT","bugs":{"url":"https://github.com/dexvis/root-geo-tree-editor/issues"},"homepage":"https://github.com/dexvis/root-geo-tree-editor#readme","devDependencies":{"tsup":"^8.5.1","typescript":"^5.9.3","vitest":"^4.0.18"},"_id":"@dexvis/root-geo-tree-editor@0.1.1","gitHead":"0d36ce0e5ff247624e9b8489ea98a24c97c67d07","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-psaXPvcfzArDKuVAt//c3/uXGpehKbw2e1aeo1ywBLF9bW5Y1O+qOF6ucw7G/J6DNpDMHGnSZNuoeiBKJBjIgg==","shasum":"87fbc14fe07dbddc05261838a5dff752b79e0576","tarball":"https://registry.npmjs.org/@dexvis/root-geo-tree-editor/-/root-geo-tree-editor-0.1.1.tgz","fileCount":8,"unpackedSize":89574,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDq6bPzq8v4GD13f/oI3KYBVFqFus9Ose0Sl7Kdf24srgIhAPlZ4AzKKAZyIRLQecRDNnhYHM6Acz8AVpfSW0NqbaBL"}]},"_npmUser":{"name":"eicdev","email":"romanovda@gmail.com"},"directories":{},"maintainers":[{"name":"eicdev","email":"romanovda@gmail.com"},{"name":"sqrd.max","email":"sqrd.max@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/root-geo-tree-editor_0.1.1_1771218324552_0.8809060224107768"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-16T05:03:12.358Z","modified":"2026-02-16T05:05:24.891Z","0.1.0":"2026-02-16T05:03:12.615Z","0.1.1":"2026-02-16T05:05:24.709Z"},"bugs":{"url":"https://github.com/dexvis/root-geo-tree-editor/issues"},"author":{"name":"dexvis"},"license":"MIT","homepage":"https://github.com/dexvis/root-geo-tree-editor#readme","keywords":["root","geometry","cern","tgeo","tree","editor"],"repository":{"type":"git","url":"git+https://github.com/dexvis/root-geo-tree-editor.git"},"description":"Utility functions for navigating and manipulating TGeo nodes within the CERN ROOT framework. Includes functionalities to walk through geometric nodes with customizable callbacks, find nodes matching specific patterns, and analyze nodes based on provided c","maintainers":[{"name":"eicdev","email":"romanovda@gmail.com"},{"name":"sqrd.max","email":"sqrd.max@gmail.com"}],"readme":"# root-geo-tree-editor\r\n\r\nNavigate, search, and edit [CERN ROOT](https://root.cern/) TGeo geometry trees in JavaScript/TypeScript. Works with geometry structures produced by [JSROOT](https://root.cern/js/).\r\n\r\n## Install\r\n\r\n```bash\r\nnpm install @dexvis/root-geo-tree-editor\r\n```\r\n\r\n## Node structure\r\n\r\nThe library operates on ROOT TGeo node objects with this shape:\r\n\r\n```\r\nnode.fName           — node name\r\nnode.fVolume         — associated volume (contains fNodes, fGeoAtt)\r\nnode.fMasterVolume   — master volume (used instead of fVolume when present)\r\nnode.fMother         — parent volume\r\nnode.fVolume.fNodes.arr — child nodes array\r\nnode.fVolume.fGeoAtt    — visibility attribute bitmask\r\n```\r\n\r\nFull paths are built as `\"Root/Child/GrandChild\"` during traversal.\r\n\r\n## API\r\n\r\n### Navigation\r\n\r\n#### `walkGeoNodes(node, callback, maxLevel?, level?, path?, pattern?)`\r\n\r\nRecursively traverses the geometry tree. The callback receives each node, its full path, and depth level. Return `false` from the callback to stop descending into children.\r\n\r\n```ts\r\nimport { walkGeoNodes } from '@dexvis/root-geo-tree-editor';\r\n\r\n// Count all nodes up to depth 3\r\nlet count = walkGeoNodes(topNode, null, 3);\r\n\r\n// Walk with a callback\r\nwalkGeoNodes(topNode, (node, fullPath, level) => {\r\n  console.log(`${fullPath} (level ${level})`);\r\n  return true; // continue into children\r\n}, Infinity);\r\n\r\n// Walk only nodes matching a wildcard pattern\r\nwalkGeoNodes(topNode, (node, fullPath, level) => {\r\n  console.log('Matched:', fullPath);\r\n  return true;\r\n}, Infinity, 0, \"\", \"*Tracker*\");\r\n```\r\n\r\n#### `findGeoNodes(node, pattern, maxLevel?)`\r\n\r\nFinds all nodes whose full path matches a wildcard pattern. Returns `{ geoNode, fullPath }[]`.\r\n\r\n```ts\r\nimport { findGeoNodes } from '@dexvis/root-geo-tree-editor';\r\n\r\nconst results = findGeoNodes(topNode, \"*Calorimeter*\");\r\nresults.forEach(r => console.log(r.fullPath));\r\n\r\n// Limit search depth\r\nconst shallow = findGeoNodes(topNode, \"*Child*\", 2);\r\n```\r\n\r\n#### `findSingleGeoNode(topNode, pattern, maxLevel?)`\r\n\r\nReturns a single matching node or `null`. Throws if more than one node matches.\r\n\r\n```ts\r\nimport { findSingleGeoNode } from '@dexvis/root-geo-tree-editor';\r\n\r\nconst node = findSingleGeoNode(topNode, \"*InnerTracker*\");\r\n```\r\n\r\n#### `getGeoNodesByLevel(topNode, selectLevel?)`\r\n\r\nCollects all nodes at a specific depth. Returns `{ geoNode, fullPath }[]`.\r\n\r\n```ts\r\nimport { getGeoNodesByLevel } from '@dexvis/root-geo-tree-editor';\r\n\r\n// Get all level-1 (direct children) nodes\r\nconst children = getGeoNodesByLevel(topNode, 1);\r\n```\r\n\r\n#### `analyzeGeoNodes(node)`\r\n\r\nLogs a summary of top-level subcomponents and their total descendant counts.\r\n\r\n```ts\r\nimport { analyzeGeoNodes } from '@dexvis/root-geo-tree-editor';\r\n\r\nanalyzeGeoNodes(geoManager.fMasterVolume);\r\n// Output:\r\n//   --- Detector subcomponents [num]-[name]: 5\r\n//     12034: Root/Tracker\r\n//     8921: Root/Calorimeter\r\n//     ...\r\n//   --- End of analysis --- Total elements: 34210\r\n```\r\n\r\n#### `findGeoManager(file)`\r\n\r\nFinds and reads the `TGeoManager` object from a ROOT file.\r\n\r\n```ts\r\nimport { findGeoManager } from '@dexvis/root-geo-tree-editor';\r\n\r\nconst geoManager = await findGeoManager(file);\r\nconst topNode = geoManager.fMasterVolume;\r\n```\r\n\r\n### Editing\r\n\r\n#### `EditActions` enum\r\n\r\n| Action | Description |\r\n|---|---|\r\n| `Nothing` | No action |\r\n| `Remove` | Remove the matched node from its parent |\r\n| `RemoveSiblings` | Keep only the matched node, remove its siblings |\r\n| `RemoveChildren` | Remove all children of the matched node |\r\n| `RemoveBySubLevel` | Remove descendants below N levels (set `pruneSubLevel`) |\r\n| `SetGeoBit` | Set a visibility bit on the node's volume |\r\n| `UnsetGeoBit` | Clear a visibility bit |\r\n| `ToggleGeoBit` | Toggle a visibility bit |\r\n\r\n#### `GeoNodeEditRule`\r\n\r\n```ts\r\nclass GeoNodeEditRule {\r\n  pattern: string;                    // wildcard pattern to match node paths\r\n  action?: EditActions;               // action to perform\r\n  pruneSubLevel?: number;             // depth for RemoveBySubLevel\r\n  geoBit?: GeoAttBits;               // bit for Set/Unset/ToggleGeoBit actions\r\n  childrenRules?: GeoNodeEditRule[];  // rules applied to children first\r\n  childrenRulesMaxLevel?: number;     // max depth for children rules\r\n}\r\n```\r\n\r\n#### `editGeoNodes(topNode, rules, maxLevel?)`\r\n\r\nApplies edit rules to matching nodes in the geometry tree.\r\n\r\n```ts\r\nimport { editGeoNodes, EditActions, GeoNodeEditRule } from '@dexvis/root-geo-tree-editor';\r\nimport { GeoAttBits } from '@dexvis/root-geo-tree-editor';\r\n\r\n// Remove specific nodes\r\neditGeoNodes(topNode, [\r\n  { pattern: \"*/SupportStructure*\", action: EditActions.Remove }\r\n]);\r\n\r\n// Keep only one subdetector, remove its siblings\r\neditGeoNodes(topNode, [\r\n  { pattern: \"*/Tracker\", action: EditActions.RemoveSiblings }\r\n]);\r\n\r\n// Remove all children of a node\r\neditGeoNodes(topNode, [\r\n  { pattern: \"*/Beampipe\", action: EditActions.RemoveChildren }\r\n]);\r\n\r\n// Set visibility on matched nodes\r\neditGeoNodes(topNode, [\r\n  {\r\n    pattern: \"*/Tracker\",\r\n    action: EditActions.SetGeoBit,\r\n    geoBit: GeoAttBits.kVisThis\r\n  }\r\n]);\r\n\r\n// Nested rules: apply children rules before the main action\r\neditGeoNodes(topNode, [\r\n  {\r\n    pattern: \"*/Calorimeter\",\r\n    action: EditActions.Nothing,\r\n    childrenRules: [\r\n      { pattern: \"*/Absorber*\", action: EditActions.Remove }\r\n    ],\r\n    childrenRulesMaxLevel: 3\r\n  }\r\n]);\r\n```\r\n\r\n#### `removeGeoNode(node)` / `removeChildren(node)`\r\n\r\nLow-level helpers to remove a single node from its parent or clear all children.\r\n\r\n```ts\r\nimport { removeGeoNode, removeChildren } from '@dexvis/root-geo-tree-editor';\r\n\r\nremoveGeoNode(someNode);   // splices node out of parent's array\r\nremoveChildren(someNode);  // empties node's children array\r\n```\r\n\r\n### Attribute Bits\r\n\r\n#### `GeoAttBits` enum\r\n\r\nMaps to ROOT's [TGeoAtt](https://root.cern/doc/master/classTGeoAtt.html) visibility flags:\r\n\r\n| Flag | Description |\r\n|---|---|\r\n| `kVisOverride` | Volume's visibility attributes are overwritten |\r\n| `kVisNone` | Volume and daughters are invisible |\r\n| `kVisThis` | This volume is visible |\r\n| `kVisDaughters` | All leaves are visible |\r\n| `kVisOneLevel` | First-level daughters are visible |\r\n| `kVisContainers` | All containers visible |\r\n| `kVisOnly` | Only this volume visible |\r\n| `kVisBranch` | Only a given branch visible |\r\n| `kVisRaytrace` | Raytracing flag |\r\n\r\n#### `testGeoBit(volume, flag)` / `setGeoBit(volume, flag, value)` / `toggleGeoBit(volume, flag)`\r\n\r\nRead, set, or toggle individual visibility bits on a volume's `fGeoAtt`.\r\n\r\n```ts\r\nimport { GeoAttBits, testGeoBit, setGeoBit, toggleGeoBit } from '@dexvis/root-geo-tree-editor';\r\n\r\nif (!testGeoBit(volume, GeoAttBits.kVisThis)) {\r\n  setGeoBit(volume, GeoAttBits.kVisThis, 1);  // make visible\r\n}\r\n\r\ntoggleGeoBit(volume, GeoAttBits.kVisDaughters);\r\n\r\nsetGeoBit(volume, GeoAttBits.kVisNone, 0);  // clear \"invisible\" flag\r\n```\r\n\r\n#### `printAllGeoBitsStatus(volume)`\r\n\r\nLogs the state of all visibility flags for a volume.\r\n\r\n```ts\r\nimport { printAllGeoBitsStatus } from '@dexvis/root-geo-tree-editor';\r\n\r\nprintAllGeoBitsStatus(volume);\r\n// kVisOverride  : No\r\n// kVisNone      : No\r\n// kVisThis      : Yes\r\n// ...\r\n```\r\n\r\n## Wildcard patterns\r\n\r\nPattern matching uses `*` (any characters) and `?` (single character) against full node paths.\r\n\r\n| Pattern | Matches |\r\n|---|---|\r\n| `*Tracker*` | Any path containing \"Tracker\" |\r\n| `*/Child1` | Direct or nested node named \"Child1\" |\r\n| `Root/*/Sensor?` | \"Sensor\" + one char, two levels below Root |\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}