package ucar.coord; import ucar.nc2.util.Misc; import java.util.*; /** * Create shared coordinates across variables in the same group, * to form the set of group coordinates. * Use object.equals() to find unique coordinates. * * @author caron * @since 12/10/13 */ public class CoordinateUniquify { static private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CoordinateUniquify.class); HashMap<Coordinate, Coordinate> runtimeBuilders = new HashMap<>(); HashMap<Coordinate, Coordinate> timeBuilders = new HashMap<>(); HashMap<Coordinate, Coordinate> timeIntvBuilders = new HashMap<>(); HashMap<Coordinate, Coordinate> vertBuilders = new HashMap<>(); HashMap<Coordinate, Coordinate> ensBuilders = new HashMap<>(); HashMap<Coordinate, Coordinate> time2DBuilders = new HashMap<>(); HashMap<Coordinate, Coordinate> swap = new HashMap<>(); List<Coordinate> unionCoords; Map<Coordinate, Integer> indexMap; public void addCoordinates(List<Coordinate> coords) { for (Coordinate coord : coords) addCoordinate(coord); } public void addCoordinate(Coordinate coord) { Coordinate already; switch (coord.getType()) { case runtime: already = runtimeBuilders.get(coord); if (already == null) runtimeBuilders.put(coord, coord); else swap.put(coord, already); // keep track of substitutes break; case time: already = timeBuilders.get(coord); if (already == null) timeBuilders.put(coord, coord); else swap.put(coord, already); break; case timeIntv: already = timeIntvBuilders.get(coord); if (already == null) timeIntvBuilders.put(coord, coord); else swap.put(coord, already); break; case time2D: already = time2DBuilders.get(coord); if (already == null) time2DBuilders.put(coord, coord); else swap.put(coord, already); break; case vert: already = vertBuilders.get(coord); if (already == null) vertBuilders.put(coord, coord); else swap.put(coord, already); break; case ens: already = ensBuilders.get(coord); if (already == null) ensBuilders.put(coord, coord); else swap.put(coord, already); break; } } public List<Coordinate> finish() { unionCoords = new ArrayList<>(20); for (Coordinate coord : runtimeBuilders.keySet()) unionCoords.add(coord); for (Coordinate coord : time2DBuilders.keySet()) unionCoords.add(coord); for (Coordinate coord : timeBuilders.keySet()) unionCoords.add(coord); for (Coordinate coord : timeIntvBuilders.keySet()) unionCoords.add(coord); for (Coordinate coord : vertBuilders.keySet()) unionCoords.add(coord); for (Coordinate coord : ensBuilders.keySet()) unionCoords.add(coord); indexMap = new HashMap<>(); for (int i = 0; i < this.unionCoords.size(); i++) { indexMap.put(this.unionCoords.get(i), i); } return unionCoords; } // redo the variables against the shared coordinates public List<Integer> reindex(List<Coordinate> coords) { List<Integer> result = new ArrayList<>(); for (Coordinate coord : coords) { Coordinate sub = swap.get(coord); Coordinate use = (sub == null) ? coord : sub; Integer idx = indexMap.get(use); // index into unionCoords if (idx == null) { throw new IllegalStateException(); } result.add(idx); } return result; } }