From 194d63d064e776e22e32e451fe2a7a1c86bcfc7b Mon Sep 17 00:00:00 2001 From: Peter Alexander <peter@blackhillock.co.uk> Date: Wed, 30 Aug 2017 15:00:23 +0100 Subject: [PATCH] Changes to aggregate FPUs into basins --- data/halfdeg/fpuGrouping.txt | 12 ++ hind1970/data/halfdeg/fpuGrouping.txt | 12 ++ hind1970/hind_config.properties | 2 +- src/ac/ed/lurg/ModelConfig.java | 3 +- src/ac/ed/lurg/ModelMain.java | 110 ++------------- src/ac/ed/lurg/landuse/FPUManager.java | 127 ++++++++++++++---- src/ac/ed/lurg/landuse/Fpu.java | 45 +++++++ .../ed/lurg/landuse/IrrigationRasterSet.java | 15 +-- src/ac/ed/lurg/landuse/WaterBasin.java | 44 ++++++ src/ac/sac/raster/AbstractRasterReader.java | 6 +- 10 files changed, 234 insertions(+), 142 deletions(-) create mode 100644 data/halfdeg/fpuGrouping.txt create mode 100644 hind1970/data/halfdeg/fpuGrouping.txt create mode 100644 src/ac/ed/lurg/landuse/Fpu.java create mode 100644 src/ac/ed/lurg/landuse/WaterBasin.java diff --git a/data/halfdeg/fpuGrouping.txt b/data/halfdeg/fpuGrouping.txt new file mode 100644 index 00000000..201cb948 --- /dev/null +++ b/data/halfdeg/fpuGrouping.txt @@ -0,0 +1,12 @@ +fpu,basin +70,Nile, +72,Nile +74,Nile +146,Nile +149,Nile +150,Nile +203,Nile +9,Amazon +10,Amazon +12,Amazon +13,Amazon diff --git a/hind1970/data/halfdeg/fpuGrouping.txt b/hind1970/data/halfdeg/fpuGrouping.txt new file mode 100644 index 00000000..201cb948 --- /dev/null +++ b/hind1970/data/halfdeg/fpuGrouping.txt @@ -0,0 +1,12 @@ +fpu,basin +70,Nile, +72,Nile +74,Nile +146,Nile +149,Nile +150,Nile +203,Nile +9,Amazon +10,Amazon +12,Amazon +13,Amazon diff --git a/hind1970/hind_config.properties b/hind1970/hind_config.properties index 5c457f5f..afdb8964 100644 --- a/hind1970/hind_config.properties +++ b/hind1970/hind_config.properties @@ -11,7 +11,7 @@ YIELD_DIR=/Users/peteralexander/Documents/LURG/LPJ/Aug2017/LPJG_PLUM_expt1.1_196 # irritatingly the gams file is also found under the BASE_DIR, and don't want to duplicate so need to specify exactly GAMS_MODEL=/Users/peteralexander/Documents/R_Workspace/UNPLUM/GAMS/IntExtOpt.gms -DEBUG_LIMIT_COUNTRIES=false +DEBUG_LIMIT_COUNTRIES=true DEBUG_COUNTRY_NAME=India & Sri Lanka DEBUG_JUST_DEMAND_OUTPUT=false IS_CALIBRATION_RUN = false diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java index 2e7a69cd..bf6b97ac 100644 --- a/src/ac/ed/lurg/ModelConfig.java +++ b/src/ac/ed/lurg/ModelConfig.java @@ -153,6 +153,7 @@ public class ModelConfig { public static final String IRRIGATION_COST_FILE = SPATIAL_DATA_DIR + File.separator + "irrigation_cost.asc"; public static final String IRRIGATION_CONSTRAINT_FILE = SPATIAL_DATA_DIR + File.separator + "blue_water_available_pseudoCRU_rcp8p5_2004_2013_grid_allhdyro_mm.txt"; public static final String FPU_BOUNDARIES_FILE = SPATIAL_DATA_DIR + File.separator + "FPU.asc"; + public static final String FPU_GROUPING_FILE = SPATIAL_DATA_DIR + File.separator + "fpuGrouping.txt"; public static final String IRRIG_MAX_WATER_FILENAME = getProperty("IRRIG_MAX_WATER_FILENAME", "gsirrigation.out"); public static final String IRRIG_RUNOFF_FILE = getProperty("IRRIG_RUNOFF_FILE", "tot_runoff.out"); public static final String PROTECTED_AREAS_FILE = SPATIAL_DATA_DIR + File.separator + "protected_areas.txt"; @@ -205,7 +206,7 @@ public class ModelConfig { public static final double PASTURE_HARVEST_FRACTION = getDoubleProperty("PASTURE_HARVEST_FRACTION", 0.5); public static final double MEAT_EFFICIENCY = getDoubleProperty("MEAT_EFFICIENCY", 1.0); // 'meat' is includes feed conversion ratio already, this is tech. change or similar public static final double IRRIGIATION_EFFICIENCY = getDoubleProperty("IRRIGIATION_EFFICIENCY", 0.5); - public static final double ENVIRONMENTAL_WATER_CONSTRAINT = getDoubleProperty("ENVIRONMENTAL_WATER_CONSTRAINT", 0.4); + public static final double ENVIRONMENTAL_WATER_CONSTRAINT = getDoubleProperty("ENVIRONMENTAL_WATER_CONSTRAINT", 0.5); public static final double WATER_AVAILIBILITY_RATE_OF_CHANGE = IS_CALIBRATION_RUN ? 0.0 : getDoubleProperty("WATER_AVAILIBILITY_RATE_OF_CHANGE", 0.0); public static final boolean USE_BLUE_WATER_FILE_IRRIG_CONSTRAINT = getBooleanProperty("USE_BLUE_WATER_FILE_IRRIG_CONSTRAINT", false);; diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java index 7e24e6b0..2079c879 100644 --- a/src/ac/ed/lurg/ModelMain.java +++ b/src/ac/ed/lurg/ModelMain.java @@ -121,34 +121,8 @@ public class ModelMain { prevWorldPrices.put(CropType.PULSES, GlobalPrice.createInitial(0.4 * ModelConfig.INITIAL_PRICE_SHIFT)); prevWorldPrices.put(CropType.STARCHY_ROOTS, GlobalPrice.createInitial(0.1 * ModelConfig.INITIAL_PRICE_SHIFT)); - prevWorldPrices.put(CropType.MONOGASTRICS, - GlobalPrice.createInitial(0.4 * 0.5 * ModelConfig.INITIAL_PRICE_SHIFT)); // quantities - // is - // in - // feed - // equivalent - // term - // (0.4 - // is - // weighted - // average - // price - // per - // feed, - // and - // 0.5 - // accounts - // for - // mark-up - // for - // additional - // processing) - prevWorldPrices.put(CropType.RUMINANTS, GlobalPrice.createInitial(0.1 * 0.6 * ModelConfig.INITIAL_PRICE_SHIFT)); // quantities - // is - // in - // feed - // equivalent - // term + prevWorldPrices.put(CropType.MONOGASTRICS, GlobalPrice.createInitial(0.4 * 0.5 * ModelConfig.INITIAL_PRICE_SHIFT)); // quantities is in feed equivalent term (0.4 is weighted average price per feed, and 0.5 accounts for mark-up for additional processing) + prevWorldPrices.put(CropType.RUMINANTS, GlobalPrice.createInitial(0.1 * 0.6 * ModelConfig.INITIAL_PRICE_SHIFT)); // quantities is in feed equivalent term prevWorldPrices.put(CropType.ENERGY_CROPS, GlobalPrice.createInitial(0.04 * ModelConfig.INITIAL_PRICE_SHIFT)); prevStockLevel = getInitialStockLevels(); } @@ -169,12 +143,7 @@ public class ModelMain { private void doTimestep(Timestep timestep) { LogWriter.println(timestep.toString()); - YieldRaster yieldSurfaces = getYieldSurfaces(timestep); // this will - // wait for the - // marker file - // from LPJ if - // configured to - // do so + YieldRaster yieldSurfaces = getYieldSurfaces(timestep); // this will wait for the marker file from LPJ if configured to do so RasterSet<IrrigationItem> allIrrigData = getUpdateIrrigationData(timestep, yieldSurfaces); YieldResponsesItem yresp = yieldSurfaces.getFromCoordinates(-90.5, 45.5); @@ -250,8 +219,7 @@ public class ModelMain { } } - // energycrops are a special case where demand in global and exogenously - // specified + // energycrops are a special case where demand in global and exogenously specified totalImportCommodities.incrementValue(CropType.ENERGY_CROPS, gen2EcDDemand); // Look at trade balance and adjust appropriately @@ -300,17 +268,7 @@ public class ModelMain { private void writeLandCoverFile(Timestep timestep, RasterSet<LandUseItem> landUseRaster) { try { StringBuffer sbHeadings = new StringBuffer( - "Year,Cropland,Pasture,ManForest,UnmanForest,Natural,EnergyCrop,FertCrop,IrrigCrop"); // Year,Cropland - // (Mha),Pasture - // (Mha),Managed_Forest - // (Mha),Unmanaged_Forest - // (Mha),Natural - // (Mha),Energycrops - // (Mha),Fert - // crop - // (Mt),,Irrig - // crop - // (km3)"); + "Year,Cropland,Pasture,ManForest,UnmanForest,Natural,EnergyCrop,FertCrop,IrrigCrop"); BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.LAND_COVER_OUTPUT_FILE, sbHeadings.toString()); @@ -326,14 +284,8 @@ public class ModelMain { LandUseItem.getTotalCropArea(landUseRaster.values(), CropType.ENERGY_CROPS))); sbData.append(String.format(",%.1f", LandUseItem.getFertiliserTotal(landUseRaster.values(), CropType.getCropsLessPasture()) / 1000)); - // sbData.append(String.format(",%.1f", - // LandUseItem.getFertiliserTotal(landUseRaster.values(), - // CropType.PASTURE)/1000)); sbData.append(String.format(",%.1f", LandUseItem.getIrrigationTotal(landUseRaster.values(), CropType.getCropsLessPasture()))); - // sbData.append(String.format(",%.1f", - // LandUseItem.getIrrigationTotal(landUseRaster.values(), - // CropType.PASTURE))); outputFile.write(sbData.toString()); outputFile.newLine(); @@ -438,21 +390,20 @@ public class ModelMain { if (timestep.isInitialTimestep()) { outputClusters(clusterIdRaster); - outputWaterAvailablity(currentIrrigationData); } } + + if (timestep.isInitialTimestep()) + outputWaterAvailablity(currentIrrigationData); // Output LandUses to tabular file, for analysis (perhaps) LogWriter.println("Outputing land uses Year: " + timestep.getYear()); LandUseOutputer landuseOutputer = new LandUseOutputer(timestep.getYear(), landUseRaster); landuseOutputer.writeOutput(); - // don't really need this a LPJ outputs have same data, although in a - // slightly different format - // outputLandCover(timestep.getYear(), landUseRaster, - // LandCoverType.CROPLAND); - // outputLandCover(timestep.getYear(), landUseRaster, - // LandCoverType.PASTURE); + // don't really need this a LPJ outputs have same data, although in a slightly different format + // outputLandCover(timestep.getYear(), landUseRaster, LandCoverType.CROPLAND); + // outputLandCover(timestep.getYear(), landUseRaster, LandCoverType.PASTURE); } private void outputWaterAvailablity(IrrigationRasterSet irrigiationRS) { @@ -510,13 +461,7 @@ public class ModelMain { Collection<CountryAgent> countryAgents = new HashSet<CountryAgent>(); Map<CompositeCountry, Map<CropType, CropUsageData>> cropUsageDataMap = new CropUsageReader( compositeCountryManager).getCommodityData(); - RasterSet<LandUseItem> initLU = getInitialLandUse(); // read in all land - // use data - // saved from - // previous - // state, e.g. - // calibrations - // run + RasterSet<LandUseItem> initLU = getInitialLandUse(); for (CompositeCountry cc : countryGrouping) { @@ -593,22 +538,9 @@ public class ModelMain { c.printStackTrace(); return null; } - - // alternative to deserialization is to use tabular data - /* - * RasterSet<LandUseItem> initLU = new - * RasterSet<LandUseItem>(desiredProjection) { private static final long - * serialVersionUID = 1317102740312961042L; protected LandUseItem - * createRasterData() { return new LandUseItem(); } }; new - * LandUseReader(initLU).getRasterDataFromFile(ModelConfig. - * INITAL_LAND_USE_FILE); return initLU; - */ } - /** - * this is if we are starting from Hurtt of other initial land covers (so we - * don't have land uses and intensity data) - */ + /** this is if we are starting from Hurtt of other initial land covers (so we don't have land uses and intensity data) */ private RasterSet<LandUseItem> getLandUseFromBaseline() { RasterSet<LandCoverItem> initialLC = new RasterSet<LandCoverItem>(desiredProjection) { private static final long serialVersionUID = 4642550777741425501L; @@ -622,14 +554,6 @@ public class ModelMain { new MaxCropAreaReader(initialLC).getRasterDataFromFile(ModelConfig.HIGH_SLOPE_AREAS_FILE); new LandCoverReader(initialLC).getRasterDataFromFile(ModelConfig.INITAL_LAND_COVER_FILE); - /* - * new RasterOutputer<LandCoverItem>(initLC, "InitialCropland") { - * - * @Override public Double getValue(RasterKey location) { LandCoverItem - * item = results.get(location); if (item == null) return null; return - * item.getLandCoverFract(LandCoverType.CROPLAND); } }.writeOutput(); - */ - RasterSet<LandUseItem> landUseRaster = new RasterSet<LandUseItem>(initialLC.getHeaderDetails()); for (Map.Entry<RasterKey, LandCoverItem> entry : initialLC.entrySet()) { @@ -637,13 +561,7 @@ public class ModelMain { RasterKey key = entry.getKey(); LandCoverItem landCover = entry.getValue(); areasItem.setLandCoverAreas(landCover); - areasItem.setCropFraction(CropType.WHEAT, 0.5); // random start, - // better if we - // could get data, - // but free - // substitution - // between crops so - // not critical + areasItem.setCropFraction(CropType.WHEAT, 0.5); // random start as don't have better data areasItem.setCropFraction(CropType.MAIZE, 0.5); areasItem.setProtectedArea(landCover.getProtectedArea()); landUseRaster.put(key, areasItem); diff --git a/src/ac/ed/lurg/landuse/FPUManager.java b/src/ac/ed/lurg/landuse/FPUManager.java index 3fa2d967..6ca11ee3 100644 --- a/src/ac/ed/lurg/landuse/FPUManager.java +++ b/src/ac/ed/lurg/landuse/FPUManager.java @@ -4,14 +4,14 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import ac.ed.lurg.ModelConfig; -import ac.ed.lurg.utils.CollectionHelper; -import ac.ed.lurg.utils.LazyHashMap; import ac.ed.lurg.utils.LogWriter; +import ac.ed.lurg.utils.StringTabularReader; import ac.sac.raster.IntegerRasterItem; import ac.sac.raster.RasterHeaderDetails; import ac.sac.raster.RasterKey; @@ -22,40 +22,100 @@ public class FPUManager { private static final int YEAR_COL = 1; private static final int USAGE_COL = 2; - RasterSet<IntegerRasterItem> fpuBoundaries; // better if these were private - Map<IntegerRasterItem, List<RasterKey>> fpuMap; - private Map<Integer, Map<Integer, Double>> fpuOtherUses; + private StringTabularReader fpuGroups; + private Map<WaterBasin, List<RasterKey>> basinToRasterKeysMap = new HashMap<WaterBasin, List<RasterKey>>(); + private Map<WaterBasin, Map<Integer, Double>> basinToOtherUses = new HashMap<WaterBasin, Map<Integer, Double>>(); + + public FPUManager(RasterHeaderDetails desiredProjection) { + fpuGroups = new StringTabularReader(",", new String[]{"fpu", "basin"}); + fpuGroups.read(ModelConfig.FPU_GROUPING_FILE); + + // Handle rasterkeys + Map<Fpu, List<RasterKey>> fpuToRasterKeys = getMapFpuToKeys(desiredProjection); + for (Map.Entry<Fpu, List<RasterKey>> entry : fpuToRasterKeys.entrySet()) { + WaterBasin basin = getBasin(entry.getKey()); + + List<RasterKey> basinRasterKeys = basinToRasterKeysMap.get(basin); + if (basinRasterKeys == null) { + basinRasterKeys = new ArrayList<RasterKey>(); + basinToRasterKeysMap.put(basin, basinRasterKeys); + } + basinRasterKeys.addAll(entry.getValue()); + } + + // Handle other water uses + Map<Fpu, Map<Integer, Double>> fpuToOtherUses = getFpuToOtherUses(); + for (Map.Entry<Fpu, Map<Integer, Double>> entry : fpuToOtherUses.entrySet()) { + WaterBasin basin = getBasin(entry.getKey()); + + Map<Integer, Double> basinOtherUses = basinToOtherUses.get(basin); + if (basinOtherUses == null) { + basinOtherUses = new HashMap<Integer, Double>(); + basinToOtherUses.put(basin, basinOtherUses); + } + + for (Map.Entry<Integer, Double> fpuOuEntry : entry.getValue().entrySet()) { + Integer year = fpuOuEntry.getKey(); + Double newOtherUse = fpuOuEntry.getValue(); + if (basinOtherUses.containsKey(year)) + newOtherUse += basinOtherUses.get(year); + + basinOtherUses.put(year, newOtherUse); + } + } + } + + private WaterBasin getBasin(Fpu fpu) { + Map<String, String> queryMap = new HashMap<String, String>(); + queryMap.put("fpu", Integer.toString(fpu.getId())); + String basin; + try { + Map<String, String> row = fpuGroups.querySingle(queryMap); + basin = row.get("basin"); + } catch (Exception e) { + basin = fpu.toString(); // this happens whenever an FPU is not grouped explicitly into a basin + } + return new WaterBasin(basin); + } - public FPUManager(RasterHeaderDetails desiredProjection) { - fpuBoundaries = new RasterSet<IntegerRasterItem>(desiredProjection) { + private Map<Fpu, List<RasterKey>> getMapFpuToKeys(RasterHeaderDetails desiredProjection) { + RasterSet<IntegerRasterItem> fpuBoundaries = new RasterSet<IntegerRasterItem>(desiredProjection) { private static final long serialVersionUID = -8620255271155259176L; protected IntegerRasterItem createRasterData() { return new IntegerRasterItem(0); } }; - + + // read FPU boundary raster FPUBoundaryReader fpuReader = new FPUBoundaryReader(fpuBoundaries); fpuReader.getRasterDataFromFile(ModelConfig.FPU_BOUNDARIES_FILE); + + Map<Fpu, List<RasterKey>> invertedBoundaries = new HashMap<Fpu, List<RasterKey>>(); + + for (Map.Entry<RasterKey, IntegerRasterItem> entry : fpuBoundaries.entrySet()) { + Fpu fpu = new Fpu(entry.getValue().getInt()); + List<RasterKey> rasterKeys = invertedBoundaries.get(fpu); + if (rasterKeys == null) { + rasterKeys = new ArrayList<RasterKey>(); + invertedBoundaries.put(fpu, rasterKeys); + } + + rasterKeys.add(entry.getKey()); + } - fpuMap = CollectionHelper.invertMap(fpuBoundaries); - readOtherUses(); + return invertedBoundaries; } - @SuppressWarnings("serial") - private void readOtherUses() { - - LazyHashMap<Integer, Map<Integer, Double>> usageMap = new LazyHashMap<Integer, Map<Integer, Double>>() { - protected Map<Integer, Double> createValue() { - return new HashMap<Integer, Double>(); - } - }; + private Map<Fpu, Map<Integer, Double>> getFpuToOtherUses() { + Map<Fpu, Map<Integer, Double>> otherUsesMap = new HashMap<Fpu, Map<Integer, Double>>(); String filename = ModelConfig.OTHER_WATER_USES_FILE; try { BufferedReader reader = new BufferedReader(new FileReader(filename)); String line; - int fpu, year; + int fpuId, year; double waterUsage; + Fpu fpu; reader.readLine(); // read header @@ -65,11 +125,17 @@ public class FPUManager { if (tokens.length < 3) LogWriter.printlnError("Too few columns in " + filename + ", " + line); - fpu = Integer.parseInt(tokens[FPU_COL]); + fpuId = Integer.parseInt(tokens[FPU_COL]); + fpu = new Fpu(fpuId); year = Integer.parseInt(tokens[YEAR_COL]); waterUsage = Double.parseDouble(tokens[USAGE_COL]); - Map<Integer, Double> fpuData = usageMap.lazyGet(fpu); + Map<Integer, Double> fpuData = otherUsesMap.get(fpu); + if (fpuData == null) { + fpuData = new HashMap<Integer, Double>(); + otherUsesMap.put(fpu, fpuData); + } + fpuData.put(year, waterUsage); } reader.close(); @@ -78,21 +144,24 @@ public class FPUManager { LogWriter.printlnError("Failed in reading water usage"); LogWriter.print(e); } - LogWriter.println("Processed " + filename + ", create " + usageMap.size() + " water usage maps values"); - - fpuOtherUses = usageMap; + LogWriter.println("Processed " + filename + ", create " + otherUsesMap.size() + " water usage maps values"); + return otherUsesMap; } - List<RasterKey> getKeysFor(IntegerRasterItem fpu) { - List<RasterKey> keys = fpuMap.get(fpu); + public List<RasterKey> getKeysFor(WaterBasin basin) { + List<RasterKey> keys = basinToRasterKeysMap.get(basin); if (keys == null) keys = new ArrayList<RasterKey>(); return keys; } - public double getOtherWaterUse(Integer fpuId, Integer year) { + public double getOtherWaterUse(WaterBasin basin, Integer year) { //LogWriter.println(fpuId + " " + year); - Double d = fpuOtherUses.get(fpuId).get(year); + Double d = basinToOtherUses.get(basin).get(year); return d; } -} + + public Collection<WaterBasin> getWaterBasins() { + return basinToRasterKeysMap.keySet(); + } +} \ No newline at end of file diff --git a/src/ac/ed/lurg/landuse/Fpu.java b/src/ac/ed/lurg/landuse/Fpu.java new file mode 100644 index 00000000..5164b04a --- /dev/null +++ b/src/ac/ed/lurg/landuse/Fpu.java @@ -0,0 +1,45 @@ +package ac.ed.lurg.landuse; + +/** This is currently really just a marker class to aid type safety, using Integer directly would have worked, but been less clear*/ + +public class Fpu { + private Integer id; + + Fpu(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Fpu" + id; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Fpu other = (Fpu) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } +} diff --git a/src/ac/ed/lurg/landuse/IrrigationRasterSet.java b/src/ac/ed/lurg/landuse/IrrigationRasterSet.java index 62bfd403..e9f06067 100644 --- a/src/ac/ed/lurg/landuse/IrrigationRasterSet.java +++ b/src/ac/ed/lurg/landuse/IrrigationRasterSet.java @@ -5,8 +5,6 @@ import java.util.Map; import ac.ed.lurg.ModelConfig; import ac.ed.lurg.Timestep; -import ac.ed.lurg.utils.LogWriter; -import ac.sac.raster.IntegerRasterItem; import ac.sac.raster.RasterHeaderDetails; import ac.sac.raster.RasterKey; import ac.sac.raster.RasterSet; @@ -28,14 +26,14 @@ public class IrrigationRasterSet extends RasterSet<IrrigationItem> { public void updateConstraintByFPU(Timestep timestep) { Collection<RasterKey> fpuKeys; - Collection<IntegerRasterItem> keyset = fpuManager.fpuMap.keySet(); + Collection<WaterBasin> keyset = fpuManager.getWaterBasins(); int yearsOfIrrigChange = (timestep.getTimestep() - ModelConfig.START_TIMESTEP) * ModelConfig.TIMESTEP_SIZE; double waterAvailabilityAdj = 1.0 + yearsOfIrrigChange * ModelConfig.WATER_AVAILIBILITY_RATE_OF_CHANGE; int year = timestep.getYear(); if (year < 2001) year = 2001; // we don't have other water use before this date - for (IntegerRasterItem fpu : keyset) { + for (WaterBasin fpu : keyset) { fpuKeys = fpuManager.getKeysFor(fpu); RasterSet<IrrigationItem> irrigData = createSubsetForKeys(fpuKeys); @@ -48,15 +46,13 @@ public class IrrigationRasterSet extends RasterSet<IrrigationItem> { for (Map.Entry<RasterKey, IrrigationItem> entry : irrigData.entrySet()) { if (entry.getValue() != null) { - fpuRunOff += entry.getValue().getRunOff() * fpuManager.fpuBoundaries.getAreaMha(entry.getKey())* 0.01; + fpuRunOff += entry.getValue().getRunOff() * irrigData.getAreaMha(entry.getKey())* 0.01; cellCount++; } } - Double fpuRunOffAvailable = fpuRunOff * ModelConfig.ENVIRONMENTAL_WATER_CONSTRAINT; - - otherUses = fpuManager.getOtherWaterUse(fpu.getInt(), year) * waterAvailabilityAdj; + otherUses = fpuManager.getOtherWaterUse(fpu, year) * waterAvailabilityAdj; if (fpuRunOffAvailable - otherUses < 0){ waterAvailForIrrigPerCell = 0; @@ -64,10 +60,9 @@ public class IrrigationRasterSet extends RasterSet<IrrigationItem> { else waterAvailForIrrigPerCell = (fpuRunOffAvailable - otherUses) / cellCount; - for (Map.Entry<RasterKey, IrrigationItem> entry : irrigData.entrySet()) { if (entry.getValue() != null){ - waterAvailabileMm = waterAvailForIrrigPerCell/fpuManager.fpuBoundaries.getAreaMha(entry.getKey())/0.01; + waterAvailabileMm = waterAvailForIrrigPerCell/irrigData.getAreaMha(entry.getKey())/0.01; entry.getValue().setIrrigConstraint(waterAvailabileMm); } } diff --git a/src/ac/ed/lurg/landuse/WaterBasin.java b/src/ac/ed/lurg/landuse/WaterBasin.java new file mode 100644 index 00000000..2d4a5c73 --- /dev/null +++ b/src/ac/ed/lurg/landuse/WaterBasin.java @@ -0,0 +1,44 @@ +package ac.ed.lurg.landuse; + +public class WaterBasin { + + private String basinId; + + public WaterBasin (String basinId) { + this.basinId = basinId; + } + + public String getId() { + return basinId; + } + + @Override + public String toString() { + return "WaterBasin " + basinId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((basinId == null) ? 0 : basinId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + WaterBasin other = (WaterBasin) obj; + if (basinId == null) { + if (other.basinId != null) + return false; + } else if (!basinId.equals(other.basinId)) + return false; + return true; + } +} diff --git a/src/ac/sac/raster/AbstractRasterReader.java b/src/ac/sac/raster/AbstractRasterReader.java index a1560b22..d4507a1b 100755 --- a/src/ac/sac/raster/AbstractRasterReader.java +++ b/src/ac/sac/raster/AbstractRasterReader.java @@ -101,13 +101,9 @@ public abstract class AbstractRasterReader<D extends RasterItem> { int row = 0, col = 0; try { - BufferedReader in = new BufferedReader(new FileReader(filename)); RasterHeaderDetails header = handleHeader(in); - - String line; - - + String line; while ((line=in.readLine()) != null) { -- GitLab