package hep.aida.ref; import hep.aida.IAnnotation; import hep.aida.IBaseHistogram; import hep.aida.IDataPointSet; import hep.aida.IFunction; import hep.aida.IManagedObject; import hep.aida.ITree; import hep.aida.ITuple; import hep.aida.ref.tree.Tree; import hep.aida.ref.xml.AidaXMLWriter; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.freehep.util.FreeHEPLookup; /** * * @author turri * @version $Id: AidaUtils.java 10700 2007-04-19 21:13:38Z serbo $ */ public abstract class AidaUtils { private static Pattern stringPattern = Pattern.compile("\\s*((\"(.*?)\")|([^,;$]*))\\s*?(,|;|$)"); private static Pattern pattern = Pattern.compile("([\\w|\\.]+)\\s*((=\\s*(\"(.*?)\"|([^,;$]*)))\\s*)?(,|;|$)"); public static void fillPath(ITree tree, IManagedObject mo) { if (tree != null && mo != null) { IAnnotation an = null; if (mo instanceof IBaseHistogram) { an = ((IBaseHistogram) mo).annotation(); } else if (mo instanceof IDataPointSet) { an = ((IDataPointSet) mo).annotation(); } else if (mo instanceof IFunction) { an = ((IFunction) mo).annotation(); } else if (mo instanceof ITuple) { an = ((ITuple) mo).annotation(); } String path = tree.findPath(mo); if (an == null) return; try { if (an.hasKey(Annotation.aidaPathKey)) { an.setValue(Annotation.aidaPathKey, path); } else { an.addItem(Annotation.aidaPathKey, path, true); } } catch (Exception e) { e.printStackTrace(); } String name = tree.name(); if (name == null || name.trim().equals("")) name = tree.storeName(); String fullPath = "/"+name+path; try { Tree aidaMasterTree = ( (Tree) FreeHEPLookup.instance().lookup(ITree.class) ); if (aidaMasterTree != null) fullPath = aidaMasterTree.findPath(mo); if (an.hasKey(Annotation.fullPathKey)) { an.setValue(Annotation.fullPathKey, fullPath); } else { an.addItem(Annotation.fullPathKey, fullPath, true); } } catch (Exception e) { e.printStackTrace(); } } } /** * Parse AIDA options. Accepts values of the form: * <pre> * a=b;c=d * a="Some Options",c="My , Funny Value" * testCase (equivalent to testCase=true) * </pre> * @param options The options string to be parsed * @return A map containing all the found options * @throws IllegalArgumentException if the options string is invalid */ public static Map parseOptions(String options) { if (options == null || options.trim().length() == 0) return Collections.EMPTY_MAP; Map hashValues = new HashMap(); Matcher matcher = pattern.matcher(options); while (matcher.find()) { String key = matcher.group(1); String value = matcher.group(5); if (value == null) { value = matcher.group(6); //This is to remove the trailing spaces in group(6) if ( value != null ) value = value.trim(); } if (value == null) value = "true"; hashValues.put(key,value); if (matcher.end() == options.length()) return hashValues; } throw new IllegalArgumentException("Invalid options: "+options); } public static String createOptionsString(Map options) { String tmp = ""; if (options == null || options.size() == 0) return tmp; Iterator it = options.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); Object value = options.get(key); tmp += ", "+key.toString()+"=\""+value.toString()+"\""; } return tmp; } public static String[] parseString(String options) { if (options == null || options.trim().length() == 0) return new String[0]; ArrayList list = new ArrayList(); Matcher matcher =stringPattern.matcher(options); while (matcher.find()) { int g = matcher.groupCount(); String value = matcher.group(3); if (value == null) value = matcher.group(1); if (value != null) { list.add(value.trim()); } if (matcher.end() == options.length()) { String[] array = new String[list.size()]; if (list.size() > 0) array = (String[]) list.toArray(array); return array; } } throw new IllegalArgumentException("Invalid options: "+options); } // Creates path array from String. Path should start with "/" // Does not take escaped "/" ("\\/") as a path element separator public static String[] stringToArray(String path) { String[] result = null; if ( path == null || path.equals("")) return result; StringTokenizer tokenizer = new StringTokenizer(path, "/"); ArrayList list = new ArrayList(tokenizer.countTokens()); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); while (token.endsWith("\\")) { token = token.substring(0, token.length()-1)+ "/"; if (tokenizer.hasMoreTokens()) token = token + tokenizer.nextToken(); } list.add(token); } result = new String[list.size()]; list.toArray(result); return result; } // Escape all "/" -> "\\/" public static String modifyName(String name) { if (name.indexOf('/') < 0) return name; String newName = ""; int index = -1; for (int i=0; i<name.length(); i++) { if (name.charAt(i) == '/') { if (i > 0 && name.charAt(i-1) == '\\') continue; if (i > index) { newName = newName + name.substring(index+1, i) + "\\/"; index = i; } else if (i == index) { newName = newName + "\\/"; } } } newName += name.substring(index+1); return newName; } public static String parseName(String pathString) { if (pathString == null || pathString.equals("/") || pathString.endsWith("/")) return ""; if (pathString.indexOf("/") < 0) return pathString; String[] path = stringToArray(pathString); String name = path[path.length-1]; return name; } public static String parseDirName(String pathString) { if (pathString == null || pathString.equals("/") || pathString.endsWith("/")) return pathString; if (pathString.indexOf("/") < 0) return ""; String dirName = ""; if (pathString.startsWith("/")) dirName = "/"; String[] path = stringToArray(pathString); if (path.length <= 1) { return dirName; } else { for (int i=0; i<path.length-1; i++) { dirName += path[i] + "/"; } } return dirName; } // returns -1 if nothing was found public static int findInArray(String string, String[] array) { int index = -1; if (string == null || array == null || array.length == 0) return index; for (int i=0; i<array.length; i++) { if (string.equals(array[i])) { index = i; break; } } return index; } // Determines if "path" is direct child of "dir" public static boolean isPathInDir(String dir, String path) { if (dir.indexOf("//") >= 0) dir.replaceAll("//", "/"); if (path.indexOf("//") >= 0) path.replaceAll("//", "/"); if (path.equals(dir)) return false; if (!path.startsWith(dir)) return false; String tmp = path.substring(dir.length()); if (tmp.startsWith("/")) tmp = tmp.substring(1); if (tmp.trim().equals("")) return false; int index = tmp.indexOf("/"); if (index >= 0 && index < (tmp.length()-1)) return false; else return true; } /** * Round number down (closer to Negative Infinity): * "order" defines which significant digit is rounded, order >= 0 * * roundDown(234.5, 0) -> 200.0 * roundDown(234.5, 1) -> 230.0 * roundDown(234.5, 2) -> 234.0 * */ public static double roundDown(double x, int order) { if (Double.isNaN(x) || Double.isInfinite(x) || x == Double.MIN_VALUE) return x; else if (x < 0) { return (-1.)*roundUp(Math.abs(x), order); } else if (x == 0) return x; double mant = Math.floor(Math.log(x)/Math.log(10.)); double factor = Math.pow(10., (order-mant)); double tmp = Math.floor(x*factor)/factor; return tmp; } /** * Round number up (closer to Positive Infinity), * "order" defines which significant digit is rounded, order >= 0 * * roundUp(234.5, 0) -> 300.0 * roundUp(234.5, 1) -> 240.0 * roundUp(234.5, 2) -> 235.0 * */ public static double roundUp(double x, int order) { if (Double.isNaN(x) || Double.isInfinite(x) || x == Double.MAX_VALUE) return x; else if (x < 0) { return (-1.)*roundDown(Math.abs(x), order); } else if (x == 0) return x; double mant = Math.floor(Math.log(x)/Math.log(10.)); double factor = Math.pow(10., (order-mant)); double tmp = Math.ceil(x*factor)/factor; return tmp; } }