Newer
Older
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.Map;
import ac.ed.lurg.country.CompositeCountry;
import ac.ed.lurg.country.CompositeCountryManager;
import ac.ed.lurg.country.CountryAgent;
import ac.ed.lurg.country.CountryBoundaryRaster;
import ac.ed.lurg.country.CountryBoundaryReader;
import ac.ed.lurg.country.GlobalPrice;
import ac.ed.lurg.country.SubsidyRateManager;
import ac.ed.lurg.demand.AbstractDemandManager;
import ac.ed.lurg.demand.BaseConsumpManager;
import ac.ed.lurg.demand.DemandManagerFromFile;
import ac.ed.lurg.demand.DemandManagerSSP;
import ac.ed.lurg.landuse.CropUsageData;
import ac.ed.lurg.landuse.FPUManager;
import ac.ed.lurg.landuse.IrrigationConstraintReader;
import ac.ed.lurg.landuse.IrrigationItem;
import ac.ed.lurg.landuse.IrrigationMaxAmountReader;
import ac.ed.lurg.landuse.IrrigationRasterSet;
import ac.ed.lurg.landuse.LandCoverItem;
import ac.ed.lurg.landuse.LandCoverReader;
import ac.ed.lurg.landuse.LandUseItem;
import ac.ed.lurg.landuse.ProtectedAreasReader;
import ac.ed.lurg.output.LandUseOutputer;
import ac.ed.lurg.output.LpjgOutputer;
import ac.ed.lurg.types.LandCoverType;
import ac.ed.lurg.utils.LogWriter;
import ac.ed.lurg.yield.LPJYieldResponseMapReader;
import ac.ed.lurg.yield.YieldRaster;
import ac.sac.raster.IntegerRasterReader;
import ac.sac.raster.RasterKey;
import ac.sac.raster.RasterOutputer;
public class ModelMain {
private Collection<CountryAgent> countryAgents;
private CountryBoundaryRaster countryBoundaryRaster;
private AbstractDemandManager demandManager;
private SubsidyRateManager subsidyRateManager;
private CompositeCountryManager compositeCountryManager;
LPJYieldResponseMapReader lpjYieldReader;
Peter Alexander
committed
private InternationalMarket internationalMarket;
private IrrigationRasterSet currentIrrigationData;
private RasterSet<LandUseItem> globalLandUseRaster;
private RasterSet<IntegerRasterItem> clusterIdRaster;
ModelMain theModel = new ModelMain();
System.out.println("Working Directory = " + System.getProperty("user.dir"));
theModel.setup();
theModel.run();
}
/* setup models, reading inputs, etc. */
private void setup() {
desiredProjection = RasterHeaderDetails.getGlobalHeaderFromCellSize(ModelConfig.CELL_SIZE_X, ModelConfig.CELL_SIZE_Y, "999");
BaseConsumpManager baseConsumpManager = new BaseConsumpManager();
compositeCountryManager = new CompositeCountryManager(baseConsumpManager);
subsidyRateManager = new SubsidyRateManager(compositeCountryManager);
lpjYieldReader = new LPJYieldResponseMapReader(desiredProjection);
if (ModelConfig.DEMAND_FROM_FILE)
demandManager = new DemandManagerFromFile(compositeCountryManager);
else
demandManager = new DemandManagerSSP(ModelConfig.SSP_SCENARIO, baseConsumpManager, compositeCountryManager);
if (ModelConfig.SHOCKS_POSSIBLE) ModelConfig.readInShocksFile();
tradeManager = new TradeManager(compositeCountryManager);
countryBoundaryRaster = getCountryBoundaryRaster();
clusterIdRaster = ModelConfig.GENERATE_NEW_YIELD_CLUSTERS ? new RasterSet<IntegerRasterItem>(desiredProjection) : getClusterRaster();
countryAgents = createCountryAgents(compositeCountryManager.getAll());
globalLandUseRaster = new RasterSet<LandUseItem>(desiredProjection);
Peter Alexander
committed
internationalMarket = new InternationalMarket();
for (int i = ModelConfig.START_TIMESTEP; i <= ModelConfig.END_TIMESTEP; i++) {
Timestep timestep = new Timestep(i);
LpjgOutputer.writeMarkerFile(timestep.getYear(), true);
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
getUpdateIrrigationData(timestep, yieldSurfaces); // updating currentIrrigationData
double previousGen2EcDDemand = (timestep.isInitialTimestep() || ModelConfig.IS_CALIBRATION_RUN ) ? 0: demandManager.getSecondGenBioenergyDemand(timestep.getPreviousTimestep());
double gen2EcDDemand = demandManager.getSecondGenBioenergyDemand(ModelConfig.IS_CALIBRATION_RUN ? new Timestep(1) : timestep);
double gen2Increase = (gen2EcDDemand>previousGen2EcDDemand) ? gen2EcDDemand - previousGen2EcDDemand : 0.0;
Collection<RasterKey> countryKeys = countryBoundaryRaster.getKeysFor(ca.getCountry());
YieldRaster countryYieldSurfaces = yieldSurfaces.createSubsetForKeys(countryKeys);
RasterSet<IrrigationItem> irrigData = currentIrrigationData.createSubsetForKeys(countryKeys);
Peter Alexander
committed
Peter Alexander
committed
ca.determineProduction(timestep, countryYieldSurfaces, irrigData, internationalMarket.getWorldPrices(), gen2Increase);
LogWriter.printlnError("Exception processing " + ca.getCountry() + " will continue with other countries");
// some hacky code for debug purposes that keeps each gams gdx file
// for one country
if (ModelConfig.GAMS_COUNTRY_TO_SAVE != null && ca.getCountry().getName().equals(ModelConfig.GAMS_COUNTRY_TO_SAVE)) {
FileSystems.getDefault().getPath(ModelConfig.TEMP_DIR + File.separator + "_gams_java_gdb1.gdx"),
FileSystems.getDefault().getPath(ModelConfig.TEMP_DIR + File.separator + ModelConfig.GAMS_COUNTRY_TO_SAVE + timestep.getYear() + ".gdx"),
Peter Alexander
committed
globalLandUseRaster.putAll(ca.getLandUses());
// if first timestep and calibration get the clustering info, which
// doesn't change through time
if (ModelConfig.GENERATE_NEW_YIELD_CLUSTERS && timestep.isInitialTimestep())
clusterIdRaster.putAll(ca.getYieldClusters());
Peter Alexander
committed
internationalMarket.determineInternationalTrade(countryAgents, gen2EcDDemand, timestep);
outputTimestepResults(timestep, globalLandUseRaster);
private BufferedWriter getFileWriter(Timestep timestep, String file, String columnHeadings) throws IOException {
if (timestep.isInitialTimestep()) {
BufferedWriter outputFile = new BufferedWriter(fstream);
outputFile.write(columnHeadings);
outputFile.newLine();
return outputFile;
return new BufferedWriter(fstream);
}
}
private void writeLandCoverFile(Timestep timestep, RasterSet<LandUseItem> landUseRaster) {
StringBuffer sbHeadings = new StringBuffer("Year,Cropland,Pasture,ManForest,UnmanForest,Natural,AbPasture,EnergyCrop,FertCrop,IrrigCrop");
BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.LAND_COVER_OUTPUT_FILE, sbHeadings.toString());
StringBuffer sbData = new StringBuffer();
sbData.append(String.format("%d,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f", timestep.getYear(),
LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.CROPLAND),
LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.PASTURE),
Peter Alexander
committed
LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.MANAGED_FOREST),
LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.UNMANAGED_FOREST),
LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.OTHER_NATURAL),
LandUseItem.getAbandonedPasture(landUseRaster.values()))
sbData.append(String.format(",%.1f", 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.getIrrigationTotal(landUseRaster.values(), CropType.getCropsLessPasture())));
outputFile.write(sbData.toString());
outputFile.newLine();
outputFile.close();
private void writeGlobalMarketFile(Timestep timestep) {
try {
Peter Alexander
committed
BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.PRICES_OUTPUT_FILE, "Year,Crop,Imports (Mt),Exports (Mt),New export price, Stock Levels (Mt)");
internationalMarket.writeGlobalMarketFile(timestep, outputFile);
private void writeGlobalFoodBalanceSheet(Timestep timestep, RasterSet<LandUseItem> landUseRaster) {
try {
BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.FOOD_BALANCE_SHEET_FILE, "Year,Crop,Production,Imports,Export,TransportLosses,StockVar,Supply,MonogastricsFeed,RuminantsFeed,SeedAndOtherLosses,FoodAnd1stGen,ProdArea");
Map<CropType, GlobalPrice> worldPrices = internationalMarket.getWorldPrices();
double harvestedAndFallowArea = 0;
for (CropType crop : CropType.getCropsLessPasture()) {
GlobalPrice priceQuantity = worldPrices.get(crop); // some specific logic for import/exports and this has been aggregated already, so best to use it
double prod=0, prodArea=0, feedMonogastrics=0, feedRuminants=0;
double exportsBeforeTL=0, imports=0, transportloss=0, stockChange=0;
if (priceQuantity != null) {
exportsBeforeTL = priceQuantity.getExportsBeforeTransportLoss();
imports = priceQuantity.getImportAmount();
transportloss = priceQuantity.getTransportLosses();
stockChange = priceQuantity.getStockChange();
}
for (CountryAgent ca : countryAgents) {
Map<CropType, CropUsageData> allCropUsage = ca.getCropUsageData();
CropUsageData cropUsage = allCropUsage.get(crop);
if (cropUsage != null) {
prod += cropUsage.getProduction();
prodArea += cropUsage.getArea();
feedMonogastrics += cropUsage.getMonogastricFeed();
feedRuminants += cropUsage.getRuminantFeed();
}
double seedAndWaste = (prod * (1/(1-crop.getSeedAndWasteRate())))-prod;
double netSupply = prod - exportsBeforeTL + imports;
double foodAnd1stGen = netSupply - feedMonogastrics - feedRuminants;
if (!crop.equals(CropType.SETASIDE))
prodArea *= (1-ModelConfig.UNHANDLED_CROP_RATE); // remove unhandled crop area
harvestedAndFallowArea += prodArea;
StringBuffer sbData = new StringBuffer();
sbData.append(String.format("%d,%s", timestep.getYear(), crop.getGamsName()));
sbData.append(String.format(",%.2f", prod));
sbData.append(String.format(",%.2f,%.2f,%.2f,%.2f", imports, exportsBeforeTL, transportloss, stockChange));
sbData.append(String.format(",%.2f,%.2f,%.2f,%.2f,%.2f", netSupply, feedMonogastrics, feedRuminants, seedAndWaste, foodAnd1stGen));
sbData.append(String.format(",%.2f", prodArea));
outputFile.write(sbData.toString());
outputFile.newLine();
}
double cropLandArea = LandUseItem.getTotalLandCover(landUseRaster.values(), LandCoverType.CROPLAND);
double unhandledArea = cropLandArea - harvestedAndFallowArea;
outputFile.write(String.format("%d,%s,,,,,,,,,,,%.2f", timestep.getYear(), "unhandled", unhandledArea));
outputFile.newLine();
outputFile.close();
} catch (IOException e) {
LogWriter.print(e);
}
}
private void writeDemandFile(Timestep timestep) {
try {
Peter Alexander
committed
BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.DEMAND_OUTPUT_FILE, "Year,Commodity,Amount (Mt)");
for (CountryAgent country : countryAgents) {
Double d = country.getCurrentProjectedDemand().get(comm);
LogWriter.println(String.format("%s,%s,%.4f", country.getCountry(), comm.getGamsName(), d));
}
sbData.append(String.format("%d,%s", timestep.getYear(), comm.getGamsName()));
sbData.append(String.format(",%.1f", demandAmount));
LogWriter.println("Global demand " + timestep.getYear() + " " + comm.getGamsName() + " " + demandAmount + "\n");
outputFile.write(sbData.toString());
outputFile.newLine();
}
outputFile.close();
private void writeDomesticProductionFile(Timestep timestep) {
StringBuffer sbHeadings = new StringBuffer("Year, Country, Crop, Area, Production, Production_cost, Import_price, Export_price, Net_imports, Rum_feed_amount, Mon_feed_amount");
BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.DOMESTIC_OUTPUT_FILE, sbHeadings.toString());
for (CropType crop : CropType.getAllItems()) {
for (CountryAgent country : countryAgents) {
R0slyn
committed
Map<CropType, CropUsageData> cropUsageAllCrops = country.getCropUsageData();
CropUsageData cropUsage = cropUsageAllCrops.get(crop);
R0slyn
committed
if (cropUsage == null)
continue;
Double prodCosts = cropUsage.getProdCost();
Double prod = cropUsage.getProduction();
Double area = cropUsage.getArea();
Double rumFeedAmount = cropUsage.getRuminantFeed();
Double monFeedAmount = cropUsage.getMonogastricFeed();
R0slyn
committed
Double importPrice = null;
Double exportPrice = null;
Double netImports = null;
CountryPrice px = country.getCurrentCountryPrices().get(crop);
netImports = cropUsage.getNetImports(); //this isn't accounting for transport losses in exports
sbData.append(String.format("%d,%s,%s", timestep.getYear(), country.getCountry(), crop.getGamsName()));
sbData.append(String.format(",%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f", area, prod, prodCosts, importPrice, exportPrice, netImports, rumFeedAmount, monFeedAmount));
outputFile.write(sbData.toString());
outputFile.newLine();
}
}
outputFile.close();
} catch (IOException e) {
LogWriter.print(e);
}
}
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
private void writeCountryDemandFile(Timestep timestep){
try {
StringBuffer sbHeadings = new StringBuffer("Year, Country, Commodity, Demand");
BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.COUNTRY_DEMAND_FILE, sbHeadings.toString());
for (CountryAgent country : countryAgents) {
for (CommodityType commodity : CommodityType.getAllItems()) {
double demand = country.getCurrentProjectedDemand().get(commodity);
StringBuffer sbData = new StringBuffer();
sbData.append(String.format("%d,%s,%s", timestep.getYear(), country.getCountry(), commodity.getGamsName()));
sbData.append(String.format(",%.3f", demand));
outputFile.write(sbData.toString());
outputFile.newLine();
}
}
outputFile.close();
} catch (IOException e) {
LogWriter.print(e);
}
}
private void outputTimestepResults(Timestep timestep, RasterSet<LandUseItem> landUseRaster) {
writeLandCoverFile(timestep, landUseRaster);
writeGlobalMarketFile(timestep);
writeCountryDemandFile(timestep);
writeGlobalFoodBalanceSheet(timestep, landUseRaster);
if (ModelConfig.OUTPUT_FOR_LPJG) {
for (int outputYear : timestep.getYearsFromLast()) {
Peter Alexander
committed
LogWriter.println("Outputing Year: " + outputYear);
RasterSet<LandUseItem> landUseToOutput = null;
landUseToOutput = landUseRaster;
}
else if (ModelConfig.INTERPOLATE_OUTPUT_YEARS) {
InterpolatingRasterSet<LandUseItem> intermediateLandUse = new InterpolatingRasterSet<LandUseItem>( landUseRaster.getHeaderDetails()) {
private static final long serialVersionUID = 1306045141011047760L;
protected LandUseItem createRasterData() {
return new LandUseItem();
Peter Alexander
committed
intermediateLandUse.setup(globalLandUseRaster, landUseRaster, timestep.getPreviousTimestep().getYear(), timestep.getYear(), outputYear);
landUseToOutput = intermediateLandUse;
if (landUseToOutput != null) {
LpjgOutputer lpjOutputer = new LpjgOutputer(outputYear, landUseToOutput);
lpjOutputer.writeOutput();
}
outputWaterAvailablity(timestep, currentIrrigationData); // uses the year directory structure created above
if (ModelConfig.IS_CALIBRATION_RUN)
if (timestep.isInitialTimestep() && ModelConfig.GENERATE_NEW_YIELD_CLUSTERS)
outputClusters(clusterIdRaster);
// 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);
private void outputWaterAvailablity(Timestep timestep, IrrigationRasterSet irrigiationRS) {
new RasterOutputer<Double, IrrigationItem>(irrigiationRS, ModelConfig.OUTPUT_DIR + File.separator + timestep.getYear() + File.separator + "IrrigConstraint.asc") {
@Override
public Double getValue(RasterKey location) {
IrrigationItem item = results.get(location);
if (item == null)
return null;
return item.getIrrigConstraint();
}
}.writeOutput();
}
private void outputClusters(RasterSet<IntegerRasterItem> landUseRaster) {
new RasterOutputer<Integer, IntegerRasterItem>(landUseRaster, ModelConfig.CLUSTERED_YIELD_FILE) {
public Integer getValue(RasterKey location) {
IntegerRasterItem item = results.get(location);
}.writeOutput();
public RasterSet<IntegerRasterItem> getClusterRaster() {
RasterSet<IntegerRasterItem> clusters = new RasterSet<IntegerRasterItem>(desiredProjection) {
private static final long serialVersionUID = 2467452274591854417L;
@Override
protected IntegerRasterItem createRasterData() {
return new IntegerRasterItem(0);
}
};
IntegerRasterReader clusterReader = new IntegerRasterReader(clusters);
clusterReader.getRasterDataFromFile(ModelConfig.CLUSTERED_YIELD_FILE);
return clusters;
}
public CountryBoundaryRaster getCountryBoundaryRaster() {
CountryBoundaryRaster countryBoundaries = new CountryBoundaryRaster(desiredProjection, compositeCountryManager);
CountryBoundaryReader countryReader = new CountryBoundaryReader(countryBoundaries);
countryReader.getRasterDataFromFile(ModelConfig.COUNTRY_BOUNDARY_FILE);
public Collection<CountryAgent> createCountryAgents(Collection<CompositeCountry> countryGrouping) {
Collection<CountryAgent> countryAgents = new HashSet<CountryAgent>();
Map<CompositeCountry, Map<CropType, CropUsageData>> cropUsageDataMap = new CropUsageReader(compositeCountryManager).getCommodityData();
RasterSet<LandUseItem> initLU = getInitialLandUse();
for (CompositeCountry cc : countryGrouping) {
if (!(cc.getName().equals(ModelConfig.DEBUG_COUNTRY_NAME)))
List<RasterKey> keys = countryBoundaryRaster.getKeysFor(cc);
Map<CropType, CropUsageData> countryCommodityData = cropUsageDataMap.get(cc);
Map<CropType, Double> countryTradeBarriers = tradeManager.getTradeBarriers(cc);
LogWriter.printlnError("No commodities data for " + cc + ", so skipping");
RasterSet<LandUseItem> initCountryLandUse = initLU.createSubsetForKeys(keys);
RasterSet<IntegerRasterItem> yieldClusters = ModelConfig.GENERATE_NEW_YIELD_CLUSTERS ? null : clusterIdRaster.createSubsetForKeys(keys);
if (initCountryLandUse.size() == 0) {
LogWriter.printlnError("No initial land use for " + cc + ", so skipping");
Map<CropType, Double> subsidyRates = subsidyRateManager.getSubsidyRates(cc);
CountryAgent ca = new CountryAgent(demandManager, cc, initCountryLandUse, countryCommodityData, countryTradeBarriers, yieldClusters, subsidyRates);
private RasterSet<LandUseItem> getInitialLandUse() {
if (ModelConfig.IS_CALIBRATION_RUN)
return getLandUseFromBaseline();
else
return deserializeLandUse();
}
private void serializeLandUse(RasterSet<LandUseItem> landUseRaster) {
try {
LogWriter.println("Starting serializing LandUse to " + ModelConfig.SERIALIZED_LAND_USE_FILE);
FileOutputStream fileOut = new FileOutputStream(ModelConfig.SERIALIZED_LAND_USE_FILE);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(landUseRaster);
out.close();
fileOut.close();
LogWriter.println("Serialized data is saved");
@SuppressWarnings("unchecked")
private RasterSet<LandUseItem> deserializeLandUse() {
try {
RasterSet<LandUseItem> initLU;
FileInputStream fileIn = new FileInputStream(ModelConfig.SERIALIZED_LAND_USE_FILE);
ObjectInputStream in = new ObjectInputStream(fileIn);
initLU = (RasterSet<LandUseItem>) in.readObject();
in.close();
fileIn.close();
LogWriter.println("Deserialized " + ModelConfig.SERIALIZED_LAND_USE_FILE);
return initLU;
LogWriter.printlnError("Problem deserializing " + ModelConfig.SERIALIZED_LAND_USE_FILE);
LogWriter.print(i);
return null;
LogWriter.printlnError("RasterSet<LandUseItem> class not found");
c.printStackTrace();
return null;
}
/** 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;
protected LandCoverItem createRasterData() {
return new LandCoverItem();
}
new ProtectedAreasReader(initialLC).getRasterDataFromFile(ModelConfig.PROTECTED_AREAS_FILE);
new MaxCropAreaReader(initialLC).getRasterDataFromFile(ModelConfig.HIGH_SLOPE_AREAS_FILE);
new LandCoverReader(initialLC).getRasterDataFromFile(ModelConfig.INITAL_LAND_COVER_FILE);
RasterSet<LandUseItem> landUseRaster = new RasterSet<LandUseItem>(initialLC.getHeaderDetails());
for (Map.Entry<RasterKey, LandCoverItem> entry : initialLC.entrySet()) {
LandUseItem areasItem = new LandUseItem();
RasterKey key = entry.getKey();
LandCoverItem landCover = entry.getValue();
areasItem.setLandCoverAreas(landCover);
areasItem.setCropFraction(CropType.WHEAT, 0.5); // random start as don't have better data
areasItem.setCropFraction(CropType.MAIZE, 0.5);
areasItem.setProtectedArea(landCover.getProtectedArea());
areasItem.setUnavailableFract(landCover.getUnavailableFract());
landUseRaster.put(key, areasItem);
}
private YieldRaster getYieldSurfaces(Timestep timestep) {
return lpjYieldReader.getShockedRasterData(timestep);
/** Get irrigation data that does not change with time, should only be called once */
IrrigationRasterSet fixedIrrigData = new IrrigationRasterSet(desiredProjection, new FPUManager(desiredProjection));
new IrrigiationCostReader(fixedIrrigData).getRasterDataFromFile(ModelConfig.IRRIGATION_COST_FILE);
new IrrigationConstraintReader(fixedIrrigData).getRasterDataFromFile(ModelConfig.IRRIGATION_CONSTRAINT_FILE);
String baseTimestepRootDir = Timestep.getYearSubDir(ModelConfig.YIELD_DIR, ModelConfig.ELLIOTT_BASEYEAR); // needs to be Elliott base timestep
new RunOffReader(fixedIrrigData, true).getRasterDataFromFile(baseTimestepRootDir + File.separator + ModelConfig.IRRIG_RUNOFF_FILE);
fixedIrrigData.calcIrrigConstraintOffsets(); // should have everything we need to calc offset between Elliott and LPJ data
/** Ugly in situ update of currentIrrigationData, better if IrrigationRasterSets were handled more immutably */
private void getUpdateIrrigationData(Timestep timestep, YieldRaster yieldSurfaces) {
String rootDir = timestep.getYearSubDir(ModelConfig.YIELD_DIR);
new IrrigationMaxAmountReader(currentIrrigationData).getRasterDataFromFile(rootDir + File.separator + ModelConfig.IRRIG_MAX_WATER_FILENAME);
if (!ModelConfig.USE_BLUE_WATER_FILE_IRRIG_CONSTRAINT) {
new RunOffReader(currentIrrigationData, false).getRasterDataFromFile(rootDir + File.separator + ModelConfig.IRRIG_RUNOFF_FILE);
currentIrrigationData.updateIrrigConstraints(timestep);