001 package org.wdssii.polarmerger; 002 003 import java.util.ArrayList; 004 import java.util.Date; 005 import java.util.List; 006 007 import org.apache.commons.logging.Log; 008 import org.apache.commons.logging.LogFactory; 009 import org.wdssii.core.PolarGrid; 010 import org.wdssii.polarmerger.PolarMerger.MergerStrategy; 011 012 /** 013 * Stores all the observations and provides operations on them. 014 * 015 * @author lakshman 016 * 017 */ 018 public class MergeableObservations { 019 private static Log log = LogFactory.getLog(MergeableObservations.class); 020 021 private static final int EXPECTED_MAX_OBSERVATIONS = 1000 * 1000 * 1; 022 023 private List<Observation> observations; 024 025 private ObservationMerger merger = null; 026 027 private PowerDensityLookup lookup = null; 028 029 public MergeableObservations(MergerStrategy mergerStrategy, 030 PowerDensityLookup lookup) { 031 if (log.isDebugEnabled()) { 032 log.debug("Creating observation list of capacity " 033 + EXPECTED_MAX_OBSERVATIONS); 034 } 035 observations = new ArrayList<Observation>(EXPECTED_MAX_OBSERVATIONS); 036 if (log.isInfoEnabled()) { 037 log.info("Finished creating observation list of capacity " 038 + EXPECTED_MAX_OBSERVATIONS); 039 } 040 041 this.lookup = lookup; 042 043 if (mergerStrategy == MergerStrategy.DistanceWeighted) { 044 merger = new DistanceWeightedObservationMerger(); 045 } else if (mergerStrategy == MergerStrategy.NearestNeighbor) { 046 merger = new NearestNeighborObservationMerger(); 047 } else { 048 merger = new LatestObservationMerger(); 049 } 050 051 } 052 053 public int pruneBefore(Date date) { 054 int capacity = Math.max(observations.size(), EXPECTED_MAX_OBSERVATIONS); 055 if (log.isInfoEnabled()) { 056 log.info("Creating observation list: capacity=" + capacity + " current=" + observations.size()); 057 } 058 059 List<Observation> keep = new ArrayList<Observation>(capacity); 060 if (log.isDebugEnabled()) { 061 log.debug("Finished creating observation list"); 062 } 063 064 for (Observation o : observations) { 065 if (o.getTime().after(date)) { 066 keep.add(o); 067 } 068 } 069 070 int pruned = (observations.size() - keep.size()); 071 observations = keep; 072 return pruned; 073 } 074 075 public void fillMergedValues(PolarGrid[] mergedGrids) { 076 if (observations.size() == 0) { 077 return; 078 } 079 080 float[][][] values = new float[mergedGrids.length][][]; 081 for (int i = 0; i < values.length; ++i) { 082 values[i] = mergedGrids[i].getValues(); 083 } 084 085 int numElev = values.length; 086 int numAz = values[0].length; 087 int numRn = values[0][0].length; 088 089 merger.init(values); 090 091 for (Observation obs : observations) { 092 int e = obs.getEIndex(); 093 int az = obs.getAzIndex(); 094 int rn = obs.getRnIndex(); 095 float[][][] weights = lookup.getWeights(); 096 for (int i = 0; i < weights.length; ++i) { 097 int w_e = e + i - weights.length / 2; 098 if (w_e < 0 || w_e >= numElev) 099 continue; 100 for (int j = 0; j < weights[i].length; ++j) { 101 int w_az = az + j - weights[i].length / 2; 102 // azimuth wraps around 103 if (w_az < 0) 104 w_az += numAz; 105 else if (w_az >= numAz) 106 w_az -= numAz; 107 108 for (int k = 0; k < weights[i][j].length; ++k) { 109 int w_rn = rn + k - weights[i][j].length / 2; 110 if (w_rn < 0 || w_rn >= numRn) 111 continue; 112 merger.update(values, w_e, w_az, w_rn, obs, 113 weights[i][j][k]); 114 } 115 } 116 } 117 } 118 119 merger.finishComputation(values); 120 } 121 122 public void add(Observation obs) { 123 observations.add(obs); 124 } 125 }