Newer
Older
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ac.ed.lurg.country.Country;
import ac.ed.lurg.country.CountryAgent;
import ac.ed.lurg.country.CountryBoundaryItem;
import ac.ed.lurg.country.CountryBoundaryReader;
import ac.ed.lurg.demand.DemandManager;
import ac.ed.lurg.landuse.CropUsageData;
import ac.ed.lurg.landuse.IntensitiesItem;
import ac.ed.lurg.landuse.IrrigationCostItem;
import ac.ed.lurg.landuse.IrrigiationCostReader;
import ac.ed.lurg.landuse.LandCoverItem;
import ac.ed.lurg.landuse.LandCoverReader;
import ac.ed.lurg.output.LpjgOutputer;
import ac.ed.lurg.types.LandCoverType;
import ac.ed.lurg.types.ModelFitType;
import ac.ed.lurg.utils.LogWriter;
import ac.ed.lurg.yield.LPJYieldResponseMapReader;
import ac.ed.lurg.yield.YieldRaster;
import ac.sac.raster.RasterKey;
import ac.sac.raster.RasterOutputer;
public class ModelMain {
private Collection<CountryAgent> countryAgents;
private Map<Country, List<RasterKey>> countryToKeysMap;
private Map<CropType, Double> prevWorldPrices;
public static void main(String[] args) {
ModelMain theModel = new ModelMain();
theModel.setup();
theModel.run();
}
/* setup models, reading inputs, etc. */
private void setup() {
desiredProjection = RasterHeaderDetails.getGlobalHeaderFromCellSize(ModelConfig.CELL_SIZE_X, ModelConfig.CELL_SIZE_Y, "999");
countryToKeysMap = createCountryToKeysMap();
demandManager = new DemandManager(ModelFitType.LOGISTIC, ModelConfig.SSP_SCENARIO);
countryAgents = createCountryAgents();
// in first timestep we don't have this info, but ok as constrained to import/export specified amount
prevWorldPrices = new HashMap<CropType, Double>();
prevWorldPrices.put(c, 1.0);
for (int i = ModelConfig.START_TIMESTEP; i <= ModelConfig.END_TIMESTEP; i++) {
Timestep timestep = new Timestep(i);
LpjgOutputer.writeMarkerFile(timestep, true);
LogWriter.printlnError(e.getMessage());
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
// YieldResponsesItem yresp = yieldSurfaces.getFromCoordinates(-50.0, -4.0);
// LogWriter.printlnError("Test key: " + yresp.getYieldMax(CropType.CEREALS) + ", " + yresp.getYieldFertOnly(CropType.CEREALS) + ", " + yresp.getYieldIrrigOnly(CropType.CEREALS));
CropToDoubleMap totalImportCommodities = new CropToDoubleMap();
CropToDoubleMap totalExportCommodities = new CropToDoubleMap();
RasterSet<IntensitiesItem> globalIntensityRaster = new RasterSet<IntensitiesItem>(desiredProjection);
RasterSet<AreasItem> globalCropAreaRaster = new RasterSet<AreasItem>(desiredProjection);
RasterSet<IntegerRasterItem> globalLocationIdRaster = new RasterSet<IntegerRasterItem>(desiredProjection);
LogWriter.println("Country " + ca.getCountry());
Collection<RasterKey> countryKeys = countryToKeysMap.get(ca.getCountry());
YieldRaster countryYieldSurfaces = yieldSurfaces.getSubsetRasterForKeys(countryKeys);
GamsRasterOutput result = ca.determineProduction(timestep, countryYieldSurfaces, prevWorldPrices);
if (result == null) {
LogWriter.printlnError("No results for " + ca.getCountry());
continue;
}
// update global rasters
globalIntensityRaster.putAll(result.getIntensityRaster());
globalCropAreaRaster.putAll(result.getCropAreaRaster());
globalLocationIdRaster.putAll(result.getLocationIdRaster());
// Get values for world input costs
Map<CropType, CropUsageData> cropUsage = result.getCropUsageData();
for (Entry<CropType, CropUsageData> entry : cropUsage.entrySet()) {
CropType c = entry.getKey();
double countryNetImports = entry.getValue().getNetImports();
if (countryNetImports > 0)
totalImportCommodities.incrementValue(c, countryNetImports);
else
totalExportCommodities.incrementValue(c, -countryNetImports);
// Look at trade balance and adjust appropriately
for (CropType crop : CropType.getImportedTypes()) {
double imports = totalImportCommodities.get(crop);
double exports = totalExportCommodities.get(crop);
double prevPrice = prevWorldPrices.get(crop);
double adjustedPrice = updateMarketPrices(prevPrice, imports, exports);
LogWriter.println(String.format("Price for %s updated from %.3f (imports %.0f, exports %.0f) to %.3f ", crop.getGamsName(), prevPrice, imports, exports, adjustedPrice));
prevWorldPrices.put(crop, adjustedPrice);
}
outputTimestepResults(timestep, globalIntensityRaster, globalCropAreaRaster, globalLocationIdRaster, yieldSurfaces);
writeMarketFile(timestep, globalCropAreaRaster);
}
public double updateMarketPrices(double previousPrice, double demand, double supply) {
if (demand > 0 || supply > 0) {
double ratio;
if (demand > supply)
ratio = (demand-supply)/demand;
else
ratio = (demand-supply)/supply;
double adjustment = Math.exp(ratio * ModelConfig.MARKET_LAMBA);
return previousPrice * adjustment;
}
else {
return previousPrice;
}
}
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
private BufferedWriter getFileWriter(Timestep timestep, String file, String columnHeadings) throws IOException {
if (timestep.isInitialTimestep()) {
FileWriter fstream = new FileWriter(file,false);
BufferedWriter outputFile = new BufferedWriter(fstream);
outputFile.write(columnHeadings);
outputFile.newLine();
return outputFile;
}
else {
FileWriter fstream = new FileWriter(file,true);
return new BufferedWriter(fstream);
}
}
private double getTotalArea(LandCoverType lcType, RasterSet<AreasItem> globalCropAreaRaster) {
double totalArea = 0;
for (AreasItem item : globalCropAreaRaster.values()) {
totalArea += item.getLandCoverArea(lcType);
}
return totalArea;
}
private void writeMarketFile(Timestep timestep, RasterSet<AreasItem> cropAreaRaster) {
try {
StringBuffer sbHeadings = new StringBuffer("Year, Cropland (Mha), Pasture (Mha), Natural (Mha)");
for (CropType crop : CropType.getImportedTypes() )
sbHeadings.append(",Px_" + crop.getGamsName());
BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.TOTAL_LAND_COVER_FILE, sbHeadings.toString());
StringBuffer sbData = new StringBuffer();
sbData.append(String.format("%d,%.1f,%.1f,%.1f",
timestep.getYear(), getTotalArea(LandCoverType.CROPLAND, cropAreaRaster), getTotalArea(LandCoverType.PASTURE, cropAreaRaster), getTotalArea(LandCoverType.OTHER_NATURAL, cropAreaRaster)));
for (CropType crop : CropType.getImportedTypes() )
sbData.append(String.format(",%.3f", prevWorldPrices.get(crop)));
outputFile.write(sbData.toString());
outputFile.newLine();
outputFile.close();
}
catch (IOException e) {
e.printStackTrace();
}
private void outputTimestepResults(Timestep timestep, RasterSet<IntensitiesItem> intensityRaster, RasterSet<AreasItem> cropAreaRaster, RasterSet<IntegerRasterItem> locationIdRaster, YieldRaster yieldSurfaces) {
LpjgOutputer lpjOutputer = new LpjgOutputer(timestep, intensityRaster, cropAreaRaster, yieldSurfaces);
lpjOutputer.writeOutput();
/* new RasterOutputer<IntegerRasterItem>(locationIdRaster, "locId" + year) {
@Override
public Double getValue(RasterKey location) {
IntegerRasterItem locItem = results.get(location);
if (locItem == null)
return null;
return (double)locItem.getInt();
}
@Override
public int convertToPixelValue(double value) {
}
}.writeOutput(ModelConfig.WRITE_JPEG_IMAGES);
new RasterOutputer<IntensitiesItem>(intensityRaster, "wheatIntensity" + year) {
@Override
public Double getValue(RasterKey location) {
IntensitiesItem intensityItem = results.get(location);
if (intensityItem == null)
return null;
Intensity cropIntensity = intensityItem.getIntensity(CropType.WHEAT);
return cropIntensity == null ? 0 : cropIntensity.getFertiliserIntensity();
}
@Override
public int convertToPixelValue(double value) {
}
}.writeOutput(ModelConfig.WRITE_JPEG_IMAGES);
outputAreas(year, cropAreaRaster, CropType.MAIZE); */
outputLandCover(timestep.getYear(), cropAreaRaster, LandCoverType.CROPLAND);
outputLandCover(timestep.getYear(), cropAreaRaster, LandCoverType.PASTURE);
private void outputLandCover(int year, RasterSet<AreasItem> cropAreaRaster, final LandCoverType lcType) {
new RasterOutputer<AreasItem>(cropAreaRaster, lcType.getName() + "Area" + year) {
@Override
public Double getValue(RasterKey location) {
AreasItem area = results.get(location);
if (area == null)
return null;
}
@Override
public int convertToPixelValue(double value) {
}
}.writeOutput(ModelConfig.WRITE_JPEG_IMAGES);
}
public Map<Country, List<RasterKey>> createCountryToKeysMap() {
RasterSet<CountryBoundaryItem> countryBoundaries = new RasterSet<CountryBoundaryItem>(desiredProjection) {
private static final long serialVersionUID = -8449000692429399253L;
protected CountryBoundaryItem createRasterData() {
return new CountryBoundaryItem();
}
};
CountryBoundaryReader countryReader = new CountryBoundaryReader(countryBoundaries);
countryReader.getRasterDataFromFile(ModelConfig.COUNTRY_BOUNDARY_FILE);
Map<Country, List<RasterKey>> countryMap = new HashMap<Country, List<RasterKey>>();
for (Map.Entry<RasterKey, CountryBoundaryItem> entry : countryBoundaries.entrySet()) {
Country c = entry.getValue().getCountry();
if (c == null)
continue;
if (keys == null) {
keys = new ArrayList<RasterKey>();
}
keys.add(entry.getKey());
Collection<CountryAgent> countryAgents = new HashSet<CountryAgent>();
RasterSet<LandCoverItem> initLC = getInitialLandCover();
RasterSet<IrrigationCostItem> allIrrigationCosts = getIrrigationCosts();
Map<Country, Map<CropType, CropUsageData>> cropUsageDataMap = new CropUsageReader().getCommodityData();
HashSet<String> countryExclusionList = new HashSet<String>(Arrays.asList("Bangladesh", "Portugal", "Haiti", "Myanmar")); //"French Polynesia", "Cabo Verde", "Samoa", "Saint Vincent and the Grenadines"));
for (Map.Entry<Country, List<RasterKey>> entry : countryToKeysMap.entrySet()) {
Country country = entry.getKey();
List<RasterKey> keys = entry.getValue();
// if (!(country.getCountryName().equals("United States of Americaxx") || country.getCountryName().equals("Russian Federationxx") || country.getCountryName().equals("China")) ) { //|| country.getCountryName().equals("China")
// continue;
// }
if (demandManager.getPopulation(country, 2010) < 80 || countryExclusionList.contains(country.getCountryName())) {
LogWriter.printlnError("Skipping " + country);
continue;
}
RasterSet<LandCoverItem> initCountryLC = initLC.popSubsetForKeys(new RasterSet<LandCoverItem>(initLC.getHeaderDetails()), keys);
RasterSet<IrrigationCostItem> irrigationCosts = allIrrigationCosts.popSubsetForKeys(new RasterSet<IrrigationCostItem>(allIrrigationCosts.getHeaderDetails()), keys);
Map<CropType, CropUsageData> countryCommodityData = cropUsageDataMap.get(country);
if (countryCommodityData == null) {
LogWriter.printlnError("No commodities data for " +country + ", so skipping");
}
else if (initCountryLC.size() == 0) {
LogWriter.printlnError("No initial land cover for " +country + ", so skipping");
}
else {
CountryAgent ca = new CountryAgent(demandManager, country, initCountryLC, irrigationCosts, countryCommodityData);
countryAgents.add(ca);
}
LandCoverReader lcReader = new LandCoverReader(desiredProjection);
RasterSet<LandCoverItem> initLC = lcReader.getRasterDataFromFile(ModelConfig.INITAL_LAND_COVER_FILE);
private YieldRaster getYieldSurfaces(Timestep timestep) {
LPJYieldResponseMapReader yieldReader = new LPJYieldResponseMapReader(desiredProjection);
return yieldReader.getRasterData(timestep);
private RasterSet<IrrigationCostItem> getIrrigationCosts() {
RasterSet<IrrigationCostItem> irigCosts = new RasterSet<IrrigationCostItem>(desiredProjection) {
private static final long serialVersionUID = 8393130687550888654L;
protected IrrigationCostItem createRasterData() {
return new IrrigationCostItem();
}
};
IrrigiationCostReader irigCostReader = new IrrigiationCostReader(irigCosts);
irigCostReader.getRasterDataFromFile(ModelConfig.IRRIGATION_COST_FILE);