-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Full conversion #2
base: main
Are you sure you want to change the base?
Changes from 21 commits
cc321cd
2a6756d
b6dcade
1fe8fcb
0215c4f
4fd3bc1
38d5fbf
1963a27
8ac05be
31881f9
9d09b97
d56c302
4c194dd
75f7c3c
b996379
0cf2042
8dda039
49bdb02
f33a7aa
78bf31f
c262670
2e71168
027db15
a5a7979
a963223
568ed7b
4265929
ad6ddb8
0ff7ecd
c01dce2
b960abc
fdec236
06f886b
ed814ae
e683f9c
3bb8b87
68ad178
dca3085
97fd933
07b9d9b
391414b
07b2013
2699afa
fadf0d1
bfb540e
891e550
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,49 @@ | ||||||
|
||||||
import argparse | ||||||
import ROOT | ||||||
|
||||||
def main(): | ||||||
parser = argparse.ArgumentParser(description='Convert detector') | ||||||
parser.add_argument('-c', '--compact', help='Compact file location(s)', | ||||||
required=True, type=str, nargs='+') | ||||||
parser.add_argument('-o', '--out', help='Converted file path', | ||||||
default='nothing', type=str) | ||||||
parser.add_argument('-v', '--visibility', help='Level of layers in detector', | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Just to make it easier to understand |
||||||
default=9, type=int) | ||||||
|
||||||
args = parser.parse_args() | ||||||
|
||||||
convert(args.compact, args.out, args.visibility) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
To keep things working after the argparse changes |
||||||
|
||||||
|
||||||
def convert(compact_files, out_path, visibility): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be the same function as in |
||||||
print('INFO: Converting following compact file(s):') | ||||||
for cfile in compact_files: | ||||||
print(' ' + cfile) | ||||||
|
||||||
ROOT.gSystem.Load('libDDCore') | ||||||
description = ROOT.dd4hep.Detector.getInstance() | ||||||
for cfile in compact_files: | ||||||
description.fromXML(cfile) | ||||||
|
||||||
ROOT.gGeoManager.SetVisLevel(visibility) | ||||||
ROOT.gGeoManager.SetVisOption(0) | ||||||
|
||||||
if out_path == 'nothing': | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
to keep things working after the argparse changes |
||||||
|
||||||
counter = 0 | ||||||
slash_list = [] | ||||||
for cfile in compact_files: | ||||||
for i in cfile: | ||||||
counter += 1 | ||||||
if i == '/': | ||||||
slash_list.append(counter) | ||||||
|
||||||
last_slash = max(slash_list) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would move this into a function to declutter the conversion function. I am also not entirely sure I understand what the output will be yet if there are multiple compact files. The end result would look something like # ... all the rest from above
ROOT.gGeoManager.SetVisOption(0)
out_path = determine_outpath(out_path, compact_files) # to be implemented
ROOT.gGeoManager.Export(out_path) |
||||||
ROOT.gGeoManager.Export(f'{cfile[last_slash:len(cfile)-4]}.root') | ||||||
|
||||||
else: | ||||||
ROOT.gGeoManager.Export(out_path) | ||||||
|
||||||
if __name__ == '__main__': | ||||||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import argparse | ||
import subprocess | ||
|
||
parser = argparse.ArgumentParser(description='Convert detector (to .gltf)') | ||
parser.add_argument('root_file', help='Root file', | ||
type=str) | ||
parser.add_argument('-c', '--config_file', help='Json file of detector structure', | ||
default='a', type=str) | ||
parser.add_argument('-g', '--gltf_file', help='Gltf file', | ||
default='detector.gltf', type=str) | ||
|
||
args = parser.parse_args() | ||
|
||
subprocess.run(["node", ".", "-c", f'{args.config_file}', "-o", f'{args.gltf_file}', f'{args.root_file}']) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"childrenToHide": [], "subParts": {"BeamCal": [["BeamCal_(?!envelope)\\w+"], 0.8], "Coil": [["Coil_(?!envelope)\\w+"], 0.8], "EcalBarrel": [["EcalBarrel_(?!envelope)\\w+"], 0.8], "EcalEndcap": [["EcalEndcap_(?!envelope)\\w+"], 0.8], "EcalPlug": [["EcalPlug_(?!envelope)\\w+"], 0.8], "FTD": [["FTD_(?!envelope)\\w+", "FTDDisk_.*_negZ", "ftd_petal_negZ_.*_.*", "ftd_sensor_negZ_.*_.*_.*", "FTDDisk_.*_posZ", "ftd_petal_posZ_.*_.*", "ftd_sensor_posZ_.*_.*_.*", "FTD_support"], 0.8], "HcalBarrel": [["HcalBarrel_(?!envelope)\\w+"], 0.8], "HcalEndcap": [["HcalEndcap_(?!envelope)\\w+"], 0.8], "HcalRing": [["HcalRing_(?!envelope)\\w+"], 0.8], "LHCal": [["LHCal_(?!envelope)\\w+"], 0.8], "Lcal": [["Lcal_(?!envelope)\\w+"], 0.8], "QD0_cryostat": [["QD0_cryostat_(?!envelope)\\w+"], 0.8], "QD0_support": [["QD0_support_(?!envelope)\\w+"], 0.8], "SET": [["SET_(?!envelope)\\w+", "set_ladder_.*_.*", "set_ladder_.*_.*_.*"], 0.8], "SIT": [["SIT_(?!envelope)\\w+", "sit_ladder_.*_.*", "sit_ladder_.*_.*_.*"], 0.8], "SServices00": [["SServices00_(?!envelope)\\w+"], 0.8], "TPC": [["TPC_(?!envelope)\\w+", "tpc_endcap_bwd", "tpc_endcap_fwd", "tpc_sensGas_bwd", "tpc_row_bwd_.*", "tpc_sensGas_fwd", "tpc_row_fwd_.*"], 0.8], "Tube": [["Tube_(?!envelope)\\w+"], 0.8], "VXD": [["VXD_(?!envelope)\\w+", "BerylliumAnnulusBlock_.*_negZ_.*", "BerylliumAnnulusBlock_.*_posZ_.*", "ElectronicsEnd_.*_negZ_.*", "ElectronicsEnd_.*_posZ_.*", "SiActiveLayer_.*_negZ_.*", "SiActiveLayer_.*_posZ_.*", "VXD_support", "KaptonLines_.*_negZ", "KaptonLines_.*_posZ", "MetalLines_.*_negZ", "MetalLines_.*_posZ", "VXD_ExtKaptonCab_neg", "VXD_ExtKaptonCab_pos", "VXD_ExtMetalCab_neg", "VXD_ExtMetalCab_pos", "VXD_endplate_bwd", "VXD_endplate_fwd", "VXD_support_bwd_inner", "VXD_support_bwd_outer", "VXD_support_fwd_inner", "VXD_support_fwd_outer", "negShellCone", "posShellCone"], 0.8], "YokeBarrel": [["YokeBarrel_(?!envelope)\\w+"], 0.8], "YokeEndcap": [["YokeEndcap_(?!envelope)\\w+"], 0.8]}, "maxLevel": 3} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an auto-generated output? Very nice. If you want to make it more readable you can use the |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#!/usr/bin/env python | ||
# coding: utf-8 | ||
|
||
from dd4hep import Detector | ||
import re | ||
from argparse import ArgumentParser | ||
import pprint | ||
import json | ||
|
||
parser = ArgumentParser() | ||
|
||
parser.add_argument( | ||
"--compactFile", help="DD4hep compact description xml", required=True | ||
) | ||
parser.add_argument( | ||
"--maxDepth", | ||
help="Maximum traversal depth of the detector tree", | ||
default=10, | ||
type=int, | ||
) | ||
|
||
args = parser.parse_args() | ||
|
||
theDetector = Detector.getInstance() | ||
theDetector.fromXML(args.compactFile) | ||
start = theDetector.world() | ||
|
||
def process_name(raw_name): | ||
name = re.sub(r"\d+", ".*", raw_name) | ||
return name | ||
|
||
def tree(detElement, depth, maxDepth): | ||
nd = {} | ||
depth += 1 | ||
children = detElement.children() | ||
for raw_name, child in children: | ||
if depth > maxDepth: | ||
tree(child, depth, maxDepth) | ||
else: | ||
dictionary = tree(child, depth, maxDepth) | ||
nd.update({raw_name: dictionary}) | ||
return nd | ||
|
||
detector_dict = tree(start, 0, args.maxDepth) | ||
#pprint.pprint(detector_dict) | ||
|
||
def post_processing(obj, main_parts, subParts={}, sublist= []): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this also be made to take a list of subParts to ignore? That would make it possible to define a list that can be put into |
||
for k, v in obj.items(): | ||
if k in main_parts: | ||
sublist = [f'{k}_(?!envelope)\\w+'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the people who don't know regex by heart (like me). Could you put a comment here briefly explaining what |
||
outer_list = [] | ||
outer_list.append(sublist) | ||
outer_list.append(0.8) | ||
subParts.update({k: outer_list}) | ||
post_processing(v, main_parts, subParts, sublist) | ||
|
||
else: | ||
k_new = process_name(k) | ||
x = re.search("module|stave|layer|Calorimeter", k_new) | ||
if k_new not in sublist and x == None: | ||
sublist.append(k_new) | ||
post_processing(v, main_parts, subParts, sublist) | ||
return subParts | ||
|
||
subPart_processed = post_processing(detector_dict, list(detector_dict.keys())) | ||
|
||
final_dict = {"childrenToHide": [], | ||
"subParts": subPart_processed, | ||
"maxLevel": 3} | ||
|
||
pprint.pprint(final_dict) | ||
with open("config_automatic.json", "w") as outfile: | ||
json.dump(final_dict, outfile) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"childrenToHide": [ | ||
"SServices", | ||
"QDX_cryo", | ||
"QDX_support" | ||
], | ||
"subParts": { | ||
"EcalBarrel" : [["EcalBarrel_module\\w+"], 0.8], | ||
"Coil" : [["coil_vol_0"], 0.8], | ||
"Lcal" : [["Lcal_module_0", "Lcal_module_1"], 0.8], | ||
"EcalEndcap" : [["EcalEndcapQuadrant_."], 0.8], | ||
"EcalPlug" : [["ECRing_0", "ECRing_1"], 0.8], | ||
"BeamCal" : [["Beam_Cal_module_0", "Beam_Cal_module_1"], 0.8], | ||
"FTD" : [["FTDAirDiskLogicalPZ_._.", "FTDAirDiskLogicalNZ_._."], 0.8], | ||
"HcalEndcap" : [["HcalEndcap_EndcapModule._.", "Hcal_endcap_FEE_."], 0.8], | ||
"HcalRing" : [["HcalEndCapRingLogical_0", "HcalEndCapRingLogical_1"], 0.8], | ||
"LHCal" : [["LHCal_module_0", "LHCal_module_1"], 0.8], | ||
"HcalBarrel": [["HcalBarrel_module_.", "HcalBarrel_Module_lateral_plate_."], 0.8], | ||
"SIT": [["SIT_LadderLogical\\w+"], 0.8], | ||
"VXD": [["SiActiveLayer\\w+"], 0.8], | ||
"SET": [["SET_LadderLogical\\w+"], 0.8], | ||
"TPC": [["TPC\\w+"], 0.8], | ||
"Tube": [["tube\\w+"], 0.8], | ||
"YokeBarrel": [["YokeBarrel\\w+"], 0.8], | ||
"YokeEndcap": [["YokeEndcap\\w+"], 0.8] | ||
}, | ||
"maxLevel": 3 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
|
||
import argparse | ||
import ROOT | ||
import subprocess | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description='Convert detector') | ||
parser.add_argument('-cm', '--compact_file', help='Compact file location(s)', | ||
required=True, type=str, nargs='+') | ||
parser.add_argument('-cn', '--config_file', help='Json file of detector structure', | ||
default='nothing', type=str) | ||
parser.add_argument('-ro', '--out_root', help='Converted root file path', | ||
default='nothing', type=str) | ||
parser.add_argument('-ri', '--in_root', help='Input root file path (if a root file has already been obtained)', | ||
default='nothing', type=str) | ||
parser.add_argument('-g', '--out_gltf', help='Converted gltf file path', | ||
default='nothing', type=str) | ||
parser.add_argument('-d', '--depth', help='Level of layers in detector', | ||
default=9, type=int) | ||
|
||
args = parser.parse_args() | ||
|
||
#if args.in_root != 'nothing' and args.config_file != 'nothing': | ||
# gltf_convert(args.config_file, args.out_gltf, args.in_root) | ||
#else: | ||
print(args.compact_file) | ||
root_path = root_convert(args.compact_file, args.out_root, args.depth) | ||
|
||
if args.config_file == 'nothing': | ||
subprocess.run(["python", "configfile_generator.py", "--compactFile", f'{args.compact_file}']) | ||
else: | ||
config_file = args.config_file | ||
|
||
gltf_convert(config_file, args.out_gltf, root_path) | ||
|
||
|
||
def root_convert(compact_files, out_path, visibility): | ||
print('INFO: Converting following compact file(s):') | ||
for cfile in compact_files: | ||
print(' ' + cfile) | ||
|
||
ROOT.gSystem.Load('libDDCore') | ||
description = ROOT.dd4hep.Detector.getInstance() | ||
for cfile in compact_files: | ||
description.fromXML(cfile) | ||
|
||
ROOT.gGeoManager.SetVisLevel(visibility) | ||
ROOT.gGeoManager.SetVisOption(0) | ||
|
||
if out_path == 'nothing': | ||
counter = 0 | ||
slash_list = [] | ||
for cfile in compact_files: | ||
for i in cfile: | ||
counter += 1 | ||
if i == '/': | ||
slash_list.append(counter) | ||
|
||
last_slash = max(slash_list) | ||
root_path = f'{cfile[last_slash:len(cfile)-4]}.root' | ||
|
||
else: | ||
root_path = out_path | ||
|
||
ROOT.gGeoManager.Export(root_path) | ||
|
||
return root_path | ||
|
||
def gltf_convert(config, gltf, root): | ||
|
||
if gltf == 'nothing': | ||
gltf_path = f'{root[:len(root)-5]}.gltf' | ||
|
||
else: | ||
gltf_path = gltf | ||
|
||
subprocess.run(["node", ".", "-c", f'{config}', "-o", f'{gltf_path}', f'{root}']) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
|
||
import argparse | ||
import ROOT | ||
import subprocess | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description='Convert detector') | ||
parser.add_argument('-cm', '--compact', help='Compact file location(s)', | ||
required=True, type=str, nargs='+') | ||
parser.add_argument('-r', '--out_root', help='Converted root file path', | ||
default='nothing', type=str) | ||
parser.add_argument('-v', '--visibility', help='Level of layers in detector', | ||
default=9, type=int) | ||
parser.add_argument('-g', '--out_gltf', help='Converted gltf file path', | ||
default='nothing', type=str) | ||
parser.add_argument('-cn', '--config_file', help='Json file of detector structure', | ||
default='a', type=str) | ||
args = parser.parse_args() | ||
|
||
root_path = root_convert(args.compact, args.out_root, args.visibility) | ||
gltf_convert(args.config_file, args.out_gltf, root_path) | ||
|
||
def root_convert(compact_files, out_path, visibility): | ||
print('INFO: Converting following compact file(s):') | ||
for cfile in compact_files: | ||
print(' ' + cfile) | ||
|
||
ROOT.gSystem.Load('libDDCore') | ||
description = ROOT.dd4hep.Detector.getInstance() | ||
for cfile in compact_files: | ||
description.fromXML(cfile) | ||
|
||
ROOT.gGeoManager.SetVisLevel(visibility) | ||
ROOT.gGeoManager.SetVisOption(0) | ||
|
||
if out_path == 'nothing': | ||
counter = 0 | ||
slash_list = [] | ||
for cfile in compact_files: | ||
for i in cfile: | ||
counter += 1 | ||
if i == '/': | ||
slash_list.append(counter) | ||
|
||
last_slash = max(slash_list) | ||
root_path = f'{cfile[last_slash:len(cfile)-4]}.root' | ||
|
||
else: | ||
root_path = out_path | ||
|
||
ROOT.gGeoManager.Export(root_path) | ||
|
||
return root_path | ||
|
||
|
||
def gltf_convert(config, gltf, root): | ||
|
||
if gltf == 'nothing': | ||
gltf_path = f'{root[:len(root)-5]}.gltf' | ||
|
||
else: | ||
gltf_path = gltf | ||
|
||
subprocess.run(["node", ".", "-c", f'{config}', "-o", f'{gltf_path}', f'{root}']) | ||
|
||
if __name__ == '__main__': | ||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlikely in this case but people might want to use whatever magical string that you put here. You can then no longer differentiate between that magic string and an actual user value. It's easier to deal with an empty string here, because an empty output file doesn't make sense.