Skip to content
Snippets Groups Projects

add_handler_remove_hashcode

Merged Xueting Yang requested to merge xueting_add_handler_pattern_matching into master
1 unresolved thread
Files
3
+ 89
0
import ROOT
import re
import tempfile
import os
import shutil
class HashRemoveHandler:
"""This class is used to remove the hash code at the end of the directory names of a rootfile.
Hash code is judged by an underline and 8 random characters e.g."_(\w{8})$".
If both input_file_path and output_file_path are provided, modified file will be saved in output_file_path;
If only input_file_path is provided, modified file will replace the old file"""
# Example usage
# modifier = HashRemoveHandler("old_file.root", "new_file.root") or modifier = HashRemoveHandler("old_file.root")
# modifier.modify_root_file()
def __init__(self, input_file_path, output_file_path=None):
self.input_file_path = input_file_path
self.output_file_path = output_file_path
def process_directory(self, old_dir, new_parent_dir, subdir_counts=None, parent_path=""):
if subdir_counts is None:
subdir_counts = {}
directory_path = "/".join(filter(None, [parent_path, old_dir.GetName()]))
new_dir_name = self.remove_hashcode(old_dir.GetName())
complete_dir_name = self.remove_hashcode(directory_path)
subdir_counts[complete_dir_name] = subdir_counts.get(complete_dir_name, 0) + 1
variant = subdir_counts[complete_dir_name]
if variant > 1:
new_dir_name += "_variant" + str(variant)
if new_dir_name != self.input_file_path:
new_dir = new_parent_dir.mkdir(new_dir_name)
if new_dir_name == self.input_file_path:
new_dir = new_parent_dir
for key in old_dir.GetListOfKeys():
obj = key.ReadObj()
if isinstance(obj, ROOT.TDirectory):
self.process_directory(obj, new_dir, subdir_counts, parent_path=directory_path)
elif isinstance(obj, ROOT.TH1):
new_dir.cd()
histogram = obj.Clone()
histogram.Write()
def remove_hashcode(self, directory_name):
# Remove hash code at the end of the directory name
pattern = r"_(\w{8})$"
match = re.search(pattern, directory_name)
if match:
return directory_name[:match.start()]
return directory_name
def modify_root_file(self):
ROOT.gROOT.SetBatch(True) # Enable batch mode to suppress graphics
# Open the original ROOT file
input_file = ROOT.TFile.Open(self.input_file_path)
if input_file is None or input_file.IsZombie():
print("Error: Failed to open the original file '{}'".format(self.input_file_path))
return
if self.output_file_path is None:
# If the output_file_path is not provided, create a temporary file
tmp_output_file_path = os.path.join(tempfile.gettempdir(), "tmp_modified_file.root")
output_file = ROOT.TFile(tmp_output_file_path, "RECREATE")
else:
# If the output_file_path is provided, create a new ROOT file
output_file = ROOT.TFile(self.output_file_path, "RECREATE")
if output_file.IsZombie():
print("Error: Failed to create the new file '{}'".format(self.output_file_path))
return
# Process the directories recursively
root_dir = input_file.GetDirectory("/")
self.process_directory(root_dir, output_file)
# Write and close the new ROOT file
output_file.Write()
output_file.Close()
# Close the original ROOT file
input_file.Close()
if self.output_file_path is None:
# If the output_file_path is not provided, replace the original file with the temporary one
shutil.move(tmp_output_file_path, self.input_file_path)
ROOT.gROOT.SetBatch(False) # Disable batch mode
Loading