From 4573b716ec78a2bbd1348bc4a2a027d1d796cd2f Mon Sep 17 00:00:00 2001 From: Wouter Deconinck <wouter.deconinck@umanitoba.ca> Date: Sun, 17 Oct 2021 18:45:50 +0000 Subject: [PATCH] CI job to automatically generate ACTS material scans --- .gitlab-ci.yml | 1 + benchmarks/material_maps/config.yml | 22 ++++ .../material_maps/scripts/configureMap.py | 101 ++++++++++++++ .../material_maps/scripts/writeMapConfig.py | 123 ++++++++++++++++++ 4 files changed, 247 insertions(+) create mode 100644 benchmarks/material_maps/config.yml create mode 100644 benchmarks/material_maps/scripts/configureMap.py create mode 100644 benchmarks/material_maps/scripts/writeMapConfig.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 25d1fa03..7b56a51f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -110,6 +110,7 @@ include: - local: 'benchmarks/roman_pots/config.yml' - local: 'benchmarks/zdc/config.yml' - local: 'benchmarks/crystal_calorimeter/config.yml' + - local: 'benchmarks/material_maps/config.yml' - local: 'benchmarks/pid/config.yml' - local: 'benchmarks/timing/config.yml' - local: 'benchmarks/b0_tracker/config.yml' diff --git a/benchmarks/material_maps/config.yml b/benchmarks/material_maps/config.yml new file mode 100644 index 00000000..0d1104d1 --- /dev/null +++ b/benchmarks/material_maps/config.yml @@ -0,0 +1,22 @@ +material_maps: + extends: .det_benchmark + stage: simulate + script: + - ActsExampleGeometryDD4hep -j 1 -n 1 --dd4hep-input ${DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml --output-json --output-root --mat-output-file geometry-map --mat-output-allmaterial true --mat-output-sensitives false + - test -f geometry-map.json + - python3 benchmarks/material_maps/scripts/writeMapConfig.py geometry-map.json config-map.json + - test -f config-map.json + - python3 benchmarks/material_maps/scripts/configureMap.py geometry-map.json config-map.json + - test -f config-map.json + - ActsExampleMaterialRecordingDD4hep -j 1 -n ${JUGGLER_N_EVENTS} --dd4hep-input ${DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml --output-root + - test -f geant4_material_tracks.root + - root -l -b -q -e "TChain T(\"material-tracks\"); T.Add(\"geant4_material_tracks.root\"); cout << T.GetEntries() << \" entries\" << endl; gApplication->Terminate(T.GetEntries()-${JUGGLER_N_EVENTS});" + - ActsExampleMaterialMappingDD4hep -j 1 -n ${JUGGLER_N_EVENTS} --dd4hep-input ${DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml --input-root true --input-files geant4_material_tracks.root --mat-input-type file --mat-input-file geometry-map.json --output-root --output-json --output-cbor --mat-output-file material-maps --mat-mapping-surfaces true --mat-mapping-volumes true --mat-mapping-volume-stepsize 1 + - test -f material-maps.json + - ActsExampleMaterialValidationDD4hep -j 1 -n ${JUGGLER_N_EVENTS} --dd4hep-input ${DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml --mat-input-type file --mat-input-file material-maps.json --output-root --mat-output-file val-mat-map --prop-z0-sigma 0.0 --prop-d0-sigma 0.0 + - ls -al + - mkdir -p results/material_maps + - cp *.root *.json *.cbor results/material_maps/ + artifacts: + paths: + - results/material_maps diff --git a/benchmarks/material_maps/scripts/configureMap.py b/benchmarks/material_maps/scripts/configureMap.py new file mode 100644 index 00000000..1ebf729d --- /dev/null +++ b/benchmarks/material_maps/scripts/configureMap.py @@ -0,0 +1,101 @@ +# This file is part of the Acts project. +# +# Copyright (C) 2020-2021 CERN for the benefit of the Acts project +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import json +import sys + +# Should be run with Python 3 if possible +# Script that use the json config file to configure the Json surfaces map for the material mapping +# Take two arguments in input : The path to the surfaces map and the path of the json config file +# By default the input is : 'surfaces-map.json' and the output is : 'config-map.json' +# The config file can be used to define a binning for all the surfaces in a given volume +# It can also be used to define the binning for volume mapping + +if sys.version_info[0] < 3: + print('Using Python 2') + print('To obtain the proper ordering in the Json files Python 3 is recomanded') + +if len(sys.argv) < 2 : + inFileName = 'geometry-maps.json' + confFileName = 'config-map.json' + +if len(sys.argv) < 3 : + confFileName = 'config-map.json' + +else : + inFileName = sys.argv[1] + confFileName = sys.argv[2] + + +with open(inFileName,'r+') as json_file: + with open(confFileName,'r') as config_file: + + config = json.load(config_file) + data = json.load(json_file) + + for entry in data['Surfaces']['entries']: + + if 'type' not in entry['value']['bounds']: + entry['value']['bounds']['type'] = '' + + if 'layer' in entry: + if 'approach' not in entry: + if 'sensitive' not in entry: + for conf in config['Surfaces'][str(entry['volume'])]: + if 'layer' in conf and conf['layer'] == 'X' and conf['value']['bounds']['type'] == entry['value']['bounds']['type']: + entry['value']['material']['mapMaterial'] = conf['value']['material']['mapMaterial'] + entry['value']['material']['mappingType'] = conf['value']['material']['mappingType'] + ibin = 0 + for bin in entry['value']['material']['binUtility']['binningdata']: + bin['bins'] = conf['value']['material']['binUtility']['binningdata'][ibin]['bins'] + ibin = ibin+1 + continue + continue + + if 'boundary' in entry: + if 'layer' not in entry: + for conf in config['Surfaces'][str(entry['volume'])]: + if 'boundary' in conf and conf['boundary'] == entry['boundary'] and conf['value']['bounds']['type'] == entry['value']['bounds']['type']: + entry['value']['material']['mapMaterial'] = conf['value']['material']['mapMaterial'] + entry['value']['material']['mappingType'] = conf['value']['material']['mappingType'] + ibin = 0 + for bin in entry['value']['material']['binUtility']['binningdata']: + bin['bins'] = conf['value']['material']['binUtility']['binningdata'][ibin]['bins'] + ibin = ibin+1 + continue + continue + + if 'approach' in entry: + if 'sensitive' not in entry: + for conf in config['Surfaces'][str(entry['volume'])]: + if 'approach' in conf and conf['approach'] == entry['approach'] and conf['value']['bounds']['type'] == entry['value']['bounds']['type']: + entry['value']['material']['mapMaterial'] = conf['value']['material']['mapMaterial'] + entry['value']['material']['mappingType'] = conf['value']['material']['mappingType'] + ibin = 0 + for bin in entry['value']['material']['binUtility']['binningdata']: + bin['bins'] = conf['value']['material']['binUtility']['binningdata'][ibin]['bins'] + ibin = ibin+1 + continue + continue + + if 'sensitive' in entry: + if 'approach' not in entry: + for conf in config['Surfaces'][str(entry['volume'])]: + if 'sensitive' in conf and conf['sensitive'] == 'X' and conf['layer'] == entry['layer'] and conf['value']['bounds']['type'] == entry['value']['bounds']['type']: + entry['value']['material']['mapMaterial'] = conf['value']['material']['mapMaterial'] + entry['value']['material']['mappingType'] = conf['value']['material']['mappingType'] + ibin = 0 + for bin in entry['value']['material']['binUtility']['binningdata']: + bin['bins'] = conf['value']['material']['binUtility']['binningdata'][ibin]['bins'] + ibin = ibin+1 + continue + continue + data['Volumes'] = config['Volumes'] + json_file.seek(0) + json.dump(data, json_file, indent=4) + json_file.truncate() diff --git a/benchmarks/material_maps/scripts/writeMapConfig.py b/benchmarks/material_maps/scripts/writeMapConfig.py new file mode 100644 index 00000000..6c32a22d --- /dev/null +++ b/benchmarks/material_maps/scripts/writeMapConfig.py @@ -0,0 +1,123 @@ +# This file is part of the Acts project. +# +# Copyright (C) 2020-2021 CERN for the benefit of the Acts project +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import json +import sys + +# Should be run with Python 3 if possible +# Script that parse a Json surfaces map to create an easy to use json config file for the mapping +# Take two arguments in input : The path to the surfaces map and the path of the json config file +# By default the input is : 'surfaces-map.json' and the output is : 'config-map.json' +# The config file can be used to define a binning for all the surfaces in a given volume +# It can also be used to define the binning for volume mapping + +def getSurfaceMateral(mat): + outputmat = {} + value = {} + material = {} + bound = {} + outputmat['volume'] = mat['volume'] + if 'boundary' in mat: + outputmat['boundary'] = mat['boundary'] + if 'layer' in mat: + if 'approach' not in entry: + if 'sensitive' not in entry: + outputmat['layer'] = 'X' + if 'approach' in mat: + outputmat['approach'] = mat['approach'] + if 'sensitive' in mat: + outputmat['layer'] = mat['layer'] + outputmat['sensitive'] = 'X' + material['binUtility'] = mat['value']['material']['binUtility'] + material['mapMaterial'] = False + material['mappingType'] = mat['value']['material']['type'] + bound['type'] = mat['value']['bounds']['type'] + value['material'] = material + value['bounds'] = bound + outputmat['value'] = value + return outputmat + +if sys.version_info[0] < 3: + print('Using Python 2') + print('To obtain the proper ordering in the Json files Python 3 is recomanded') + +if len(sys.argv) < 2 : + inFileName = 'geometry-maps.json' +else : + inFileName = sys.argv[1] + + +with open(inFileName,'r') as json_file: + config = {} + config['Surfaces'] = {} + data = json.load(json_file) + lastVol = -1 + for entry in data['Surfaces']['entries']: + if lastVol != entry['volume']: + if lastVol != -1: + config['Surfaces'][lastVol] = vconfig + vconfig = [] + lastVol = entry['volume'] + typeLayer = [] + createdApproach1 = False + createdApproach2 = False + typeSensitive = {} + + if 'type' not in entry['value']['bounds']: + entry['value']['bounds']['type'] = '' + + if 'layer' in entry: + if 'approach' not in entry: + if 'sensitive' not in entry: + if entry['value']['bounds']['type'] not in typeLayer: + typeLayer.append(entry['value']['bounds']['type']) + surface = getSurfaceMateral(entry) + vconfig.append(surface) + continue + + if 'boundary' in entry: + if 'layer' not in entry: + surface = getSurfaceMateral(entry) + vconfig.append(surface) + continue + + if 'approach' in entry: + if 'sensitive' not in entry: + if entry['approach'] == 1 and createdApproach1 == False: + createdApproach1 = True + surface = getSurfaceMateral(entry) + vconfig.append(surface) + continue + if entry['approach'] == 2 and createdApproach2 == False: + createdApproach2 = True + surface = getSurfaceMateral(entry) + vconfig.append(surface) + continue + + if 'sensitive' in entry: + if 'approach' not in entry: + if entry['value']['material']['binUtility']['binningdata'] != None: + if not entry['layer'] in typeSensitive: + typeSensitive[entry['layer']]=[] + if entry['value']['bounds']['type'] not in typeSensitive[entry['layer']]: + typeSensitive[entry['layer']].append(entry['value']['bounds']['type']) + surface = getSurfaceMateral(entry) + vconfig.append(surface) + continue + + if lastVol != -1: + config['Surfaces'][lastVol] = vconfig + config['Volumes'] = data['Volumes'] + +if len(sys.argv) < 3 : + outFileName = 'config-map.json' +else : + outFileName = sys.argv[2] + +with open(outFileName, 'w') as outfile: + json.dump(config, outfile, indent=4) -- GitLab