Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/firebird-ng/src/app/data-pipelines/three-geometry.processor.ts is written in an unsupported language. File is not indexed.

0001 import * as THREE from "three";
0002 import {wildCardCheck} from "../utils/wildcard";
0003 import {CalorimetryGeometryPrettifier} from "./calorimetry.prettifier";
0004 import {editThreeNodeContent, EditThreeNodeRule} from "../utils/three-geometry-editor";
0005 import {Subdetector} from "../model/subdetector";
0006 
0007 /**
0008  * A typed object that associates a name (or multiple names) with an array of edit rules.
0009  * E.g. { name: "DIRC_14", rules: [ { patterns: [...], ... } ] }
0010  */
0011 export interface DetectorThreeRuleSet {
0012   names?: string[];
0013   name?: string;
0014   rules: EditThreeNodeRule[];
0015 }
0016 
0017 /**
0018  * Converts a raw JSON/JSONC array into typed DetectorThreeRuleSet objects.
0019  * If an EditThreeNodeRule has "materialJson", we parse it using THREE.MaterialLoader.
0020  */
0021 export function ruleSetsFromObj(obj: any): DetectorThreeRuleSet[] {
0022   // Not an array => return empty
0023   if (!Array.isArray(obj)) {
0024     console.warn('ruleSetsFromObj: top-level object is not an array. Returning empty.');
0025     return [];
0026   }
0027 
0028   // Create a single MaterialLoader we can reuse for all materialJson objects
0029   const materialLoader = new THREE.MaterialLoader();
0030 
0031   return obj.map((item: any) => {
0032     // Ensure we have a rules array
0033     if (!item.rules || !Array.isArray(item.rules)) {
0034       console.warn('ruleSetsFromObj: missing or invalid "rules" array in item:', item);
0035       return { rules: [] };
0036     }
0037 
0038     // Convert each rule
0039     const convertedRules: EditThreeNodeRule[] = item.rules.map((r: any) => {
0040       const rule: EditThreeNodeRule = { ...r };
0041 
0042       // 1) Convert a color from string hex "0xabcdef" => number
0043       if (typeof rule.color === 'string') {
0044         rule.color = parseInt(rule.color, 16);
0045       }
0046 
0047       // 2) If there's "materialJson", parse it using THREE.MaterialLoader
0048       if (r.materialJson && typeof r.materialJson === 'object') {
0049         try {
0050           // Convert raw JSON to real material
0051           const loadedMaterial = materialLoader.parse(r.materialJson);
0052           rule.material = loadedMaterial;
0053         } catch (err) {
0054           console.error('Failed to parse materialJson:', err, r.materialJson);
0055         }
0056       }
0057 
0058       return rule;
0059     });
0060 
0061     return {
0062       names: item.names,
0063       name: item.name,
0064       rules: convertedRules,
0065     };
0066   });
0067 }
0068 
0069 
0070 /**
0071  * Matches which set of rules should be applied to which detectors
0072  *
0073  * - Detectors are matched based on their `sourceGeometryName` against the names specified in the rulesets.
0074  * - Rule lists are matched to detectors in the order they appear in the rulesets
0075  * - Once a rule is applied to a detector, that detector is excluded from further rule matching, ensuring each detector is processed only once.
0076  * - If both `names` and `name` are provided in a ruleset, the function treats it as a user error in JSON rule editing but processes both without raising an exception.
0077  * - If a ruleset contains a wildcard name (`"*"`), it will apply its rules to any detectors not already matched by previous rulesets. So it should be placed in
0078  *
0079  * @param {Subdetector[]} detectors - The list of detectors to which the rules will be applied.
0080  * @param {DetectorThreeRuleSet[]} ruleSets - The set of rules to be applied, processed sequentially.
0081  * @return {Map<Subdetector, EditThreeNodeRule[]>} - A map associating each detector with an array of the rules applied to it.
0082  */
0083 export function matchRulesToDetectors(ruleSets: DetectorThreeRuleSet[], detectors: Subdetector[]): Map<Subdetector, EditThreeNodeRule[]> {
0084   const unassignedDetectors = new Set(detectors);
0085   const detectorRulesMap = new Map<Subdetector, EditThreeNodeRule[]>();
0086 
0087   for(let ruleSet of ruleSets) {
0088     const targets = new Set<Subdetector>();
0089     let names = new Set<string>(ruleSet.names || []);
0090 
0091     // Handle possible user error where both 'name' and 'names' are provided.
0092     if (ruleSet.name) {
0093       names.add(ruleSet.name);
0094     }
0095 
0096     for(let name of names) {
0097       for(let det of unassignedDetectors) {
0098         if (wildCardCheck(det.sourceGeometryName, name)) {
0099           targets.add(det);
0100           detectorRulesMap.set(det, ruleSet.rules || []);
0101           unassignedDetectors.delete(det);  // Move deletion here to optimize
0102         }
0103       }
0104     }
0105   }
0106 
0107   return detectorRulesMap;
0108 }
0109 
0110 export class ThreeGeometryProcessor {
0111 
0112 
0113   constructor() {
0114 
0115   }
0116 
0117   public processRuleSets(ruleSets: DetectorThreeRuleSet[], detectors: Subdetector[]) {
0118     let detRulesMap = matchRulesToDetectors(ruleSets, detectors);
0119     for (let [detector, ruleSet] of detRulesMap) {
0120       for(let rule of ruleSet) {
0121         editThreeNodeContent(detector.geometry, rule);
0122       }
0123     }
0124   }
0125 }