Author: [log in to unmask] Date: Tue Oct 27 10:23:54 2015 New Revision: 3891 Log: Added utility to combine multiple AIDA files with the same plots. Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/AddPlots.java Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/AddPlots.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/AddPlots.java (added) +++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/AddPlots.java Tue Oct 27 10:23:54 2015 @@ -0,0 +1,254 @@ +package org.hps.users.kmccarty.plots; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.lcsim.util.aida.AIDA; + +import hep.aida.IAnalysisFactory; +import hep.aida.IHistogram1D; +import hep.aida.IHistogram2D; +import hep.aida.IManagedObject; +import hep.aida.ITree; + +public class AddPlots { + + public static void main(String[] args) throws IllegalArgumentException, IOException { + // Define the root directory for the plots. + String rootDir = null; + + // Get the option identifier from the command arguments. + boolean isHelp = false; + boolean isFileList = false; + boolean isDirectory = false; + if(args.length > 0) { + if(args[0].compareTo("-h") == 0) { isHelp = true; } + else if(args[0].compareTo("-f") == 0) { isFileList = true; } + else if(args[0].compareTo("-d") == 0) { isDirectory = true; } + } else { + System.err.println("Insufficient arguments. See \"AddPlots -h\""); + System.exit(1); + } + + // Process the command line argument. + List<File> plotFiles = new ArrayList<File>(); + if(isHelp) { + System.out.println("Usage:"); + System.out.println("\tAddPlots -d [PLOT_DIRECTORY]"); + System.out.println("\tAddPlots -f [PLOT_FILE] [PLOT_FILE] ..."); + System.exit(0); + } else if(isDirectory) { + // Make sure that a directory is specified. + if(args.length < 2) { + System.err.println("Insufficient arguments. Must specify at least two files."); + System.exit(1); + } + + // Get the plot directory from the second argument. + File plotDirectory = new File(args[1]); + + // Verify that it exists and is a directory. + if(!plotDirectory.exists()) { + System.err.println("File path does not exist."); + System.exit(1); + } if(!plotDirectory.isDirectory()) { + System.err.println("Indicated path must be a directory."); + System.exit(1); + } + + // Store the root directory. + rootDir = plotDirectory.getAbsolutePath() + "\\"; + + // Extract the AIDA files from the directory. + for(File file : plotDirectory.listFiles()) { + System.out.println(file.getName()); + int indexOfExtension = file.getName().lastIndexOf('.'); + if(indexOfExtension == -1) { continue; } + if(file.getName().substring(indexOfExtension).compareToIgnoreCase(".aida") == 0) { + plotFiles.add(file); + } + } + + // Debug status print. + System.out.println("Processing plots in directory \"" + plotDirectory.getAbsolutePath() + "\""); + } else if(isFileList) { + // Make sure that at least one file was specified. + if(args.length < 3) { + System.err.println("Insufficient arguments. Must specify at least two files."); + System.exit(1); + } + + // Get the root directory. + rootDir = System.getProperty("user.dir") + "\\"; + + // Create and verify the specified files. + for(int i = 1; i < args.length; i++) { + // Create the file object and make sure that it exists. + File file = new File(args[i]); + if(!file.exists()) { + System.err.println("Specified file does not exist: " + args[i]); + System.exit(1); + } + + // Add it to the file list. + plotFiles.add(file); + } + } else { + System.err.println("Option \"" + args[0] + "\" is not recognized."); + System.exit(1); + } + + // Make sure that there are actually files. + if(plotFiles.isEmpty()) { + System.err.println("No AIDA files found!"); + System.exit(1); + } + + // Get the plots file and open it. + IAnalysisFactory af = IAnalysisFactory.create(); + ITree tree = af.createTreeFactory().create(plotFiles.get(0).getAbsolutePath()); + if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); } + + // Get the histograms names. + List<String> objectNameList = getTreeFiles(tree); + + // Separate the plots into 1D and 2D plots and extract their + // bin sizes and other properties. + List<Integer> xBins1D = new ArrayList<Integer>(); + List<Double> xBins1DMin = new ArrayList<Double>(); + List<Double> xBins1DMax = new ArrayList<Double>(); + List<Integer> xBins2D = new ArrayList<Integer>(); + List<Double> xBins2DMin = new ArrayList<Double>(); + List<Double> xBins2DMax = new ArrayList<Double>(); + List<Integer> yBins2D = new ArrayList<Integer>(); + List<Double> yBins2DMin = new ArrayList<Double>(); + List<Double> yBins2DMax = new ArrayList<Double>(); + List<String> histogramNames1D = new ArrayList<String>(); + List<String> histogramNames2D = new ArrayList<String>(); + for(String objectName : objectNameList) { + // Get the object. + IManagedObject object = tree.find(objectName); + + // If it is a 1D histogram, process it. + if(object instanceof IHistogram1D) { + // Add the object to the 1D histogram list. + histogramNames1D.add(objectName); + + // Get the bin size. + IHistogram1D plot = (IHistogram1D) object; + xBins1D.add(plot.axis().bins()); + xBins1DMin.add(plot.axis().lowerEdge()); + xBins1DMax.add(plot.axis().upperEdge()); + } + + // If it is a 1D histogram, process it. + else if(object instanceof IHistogram2D) { + // Add the object to the 2D histogram list. + histogramNames2D.add(objectName); + + // Get the bin size. + IHistogram2D plot = (IHistogram2D) object; + xBins2D.add(plot.xAxis().bins()); + xBins2DMin.add(plot.xAxis().lowerEdge()); + xBins2DMax.add(plot.xAxis().upperEdge()); + yBins2D.add(plot.yAxis().bins()); + yBins2DMin.add(plot.yAxis().lowerEdge()); + yBins2DMax.add(plot.yAxis().upperEdge()); + } + } + + // Create plots corresponding to each of the plot objects. + AIDA aida = AIDA.defaultInstance(); + List<IHistogram1D> histograms1D = new ArrayList<IHistogram1D>(histogramNames1D.size()); + List<IHistogram2D> histograms2D = new ArrayList<IHistogram2D>(histogramNames2D.size()); + for(int i = 0; i < histogramNames1D.size(); i++) { + IHistogram1D histogram = aida.histogram1D(histogramNames1D.get(i), xBins1D.get(i), xBins1DMin.get(i), xBins1DMax.get(i)); + histograms1D.add(histogram); + } + for(int i = 0; i < histogramNames2D.size(); i++) { + IHistogram2D histogram = aida.histogram2D(histogramNames2D.get(i), xBins2D.get(i), xBins2DMin.get(i), xBins2DMax.get(i), yBins2D.get(i), yBins2DMin.get(i), yBins2DMax.get(i)); + histograms2D.add(histogram); + } + + // Iterate over each file and add their entries to the compiled + // plots. + for(File file : plotFiles) { + // Open the file. + ITree fileTree = af.createTreeFactory().create(file.getAbsolutePath()); + + // For each plot, get the equivalent plot from the file + // and add each bin entry to the compiled plot. + for(int i = 0; i < histogramNames1D.size(); i++) { + // Get the histogram object. + IHistogram1D histogram = (IHistogram1D) fileTree.find(histogramNames1D.get(i)); + + // Iterate over the bins. + for(int x = 0; x < xBins1D.get(i); x++) { + // Get the entries in this bin and the bin average. + int entries = histogram.binEntries(x); + double average = histogram.binMean(x); + + // Add the entries to the compiled plot. + for(int j = 0; j < entries; j++) { + histograms1D.get(i).fill(average); + } + } + } + for(int i = 0; i < histogramNames2D.size(); i++) { + // Get the histogram object. + IHistogram2D histogram = (IHistogram2D) fileTree.find(histogramNames2D.get(i)); + + // Iterate over the bins. + for(int x = 0; x < xBins2D.get(i); x++) { + for(int y = 0; y < yBins2D.get(i); y++) { + // Get the entries in this bin and the bin average. + int entries = histogram.binEntries(x, y); + double averageX = histogram.binMeanX(x, y); + double averageY = histogram.binMeanY(x, y); + + // Add the entries to the compiled plot. + for(int j = 0; j < entries; j++) { + histograms2D.get(i).fill(averageX, averageY); + } + } + } + } + } + + // Save the compiled plots to a new file. + aida.saveAs(rootDir + "compiled-plots.aida"); + System.out.println("Plots written to path " + rootDir + "compiled-plots.aida"); + } + + private static final List<String> getTreeFiles(ITree tree) { + return getTreeFiles(tree, "/"); + } + + private static final List<String> getTreeFiles(ITree tree, String rootDir) { + // Make a list to contain the plot names. + List<String> list = new ArrayList<String>(); + + // Iterate over the objects at the indicated directory of the tree. + String objectNames[] = tree.listObjectNames(rootDir); + for(String objectName : objectNames) { + // Convert the object name to a char array and check the + // last character. Directories end in '/'. + char[] plotChars = objectName.toCharArray(); + + // If the object is a directory, process any objects inside + // of it as well. + if(plotChars[plotChars.length - 1] == '/') { + List<String> dirList = getTreeFiles(tree, objectName); + list.addAll(dirList); + } + + // Otherwise, just add the object to the list. + else { list.add(objectName); } + } + + // Return the compiled list. + return list; + } +}