Ejemplo n.º 1
0
def task_runner(sa_engine, task):
    # Get crop_name and mgmt_code
    crop_no = task["crop_no"]
    lat = float(task["latitude"])
    lon = float(task["longitude"])
    year = 1900
    cip = None
    wdp = None

    # Get a crop info provider
    try:
        t1 = time.time()
        cropname, watersupply = select_crop(sa_engine, crop_no)
        cip = CropInfoProvider(cropname, watersupply, run_settings.data_dir)
        cropdata = cip.getCropData()
        msg = "Retrieving data for crop %s, %s took %6.1f seconds"
        print msg % (cropname, watersupply, time.time() - t1)

        # Everything seems to be set for the task now! Lon-lat combination is
        # checked in the call to the getSeasonDates method. We assume that the
        # landmask was checked. Also we assume that the data on the growing
        # season were checked. These are represented by day-of-year values.
        start_doy, end_doy = cip.getSeasonDates(lon, lat)

        # Get the weather data
        wdp = Hdf5WeatherDataProvider(run_settings.hdf5_meteo_file, lat, lon)

        # Loop over the years
        t2 = time.time()
        tsums = []
        for year in get_available_years(wdp):
            # Get timer data for the current year
            timerdata = cip.getTimerData(start_doy, end_doy, year)

            # Check that START_DATE does not fall before the first available
            # meteodata and END_DATE not beyond the last data with available
            # weather data.
            if timerdata['START_DATE'] < wdp.first_date: continue
            if timerdata['END_DATE'] > wdp.last_date: continue

            sitedata = {}
            soildata = {"SMFCF": 0.4}

            # Run simulation
            pheno = wofostEngine(sitedata,
                                 timerdata,
                                 soildata,
                                 cropdata,
                                 wdp,
                                 config="Wofost71_PhenoOnly.conf")
            pheno.run(days=366)

            sumresults = pheno.get_summary_output()
            if len(sumresults) > 0:
                tsums.append(sumresults[0]["TSUM"])
            else:
                msg = "No summary results for crop/year/lat/lon: %s/%s/%s/%s"
                logging.error(msg, crop_no, year, lat, lon)

        # end year

        # Insert average etc. into database
        if len(tsums) > 0:
            insert_tsum(sa_engine, 1, crop_no, lat, lon, mean(tsums),
                        std(tsums, ddof=1), min(tsums), max(tsums), len(tsums))
            msg = "Simulating for lat-lon (%s, %s) took %6.1f seconds"
            print msg % (str(lat), str(lon), time.time() - t2)
        else:
            msg = "Failed calculating TSUMs for lat-lon (%s, %s): no TSUMs calculated for 30 years"
            logging.error(msg, lat, lon)

    finally:
        # Clean up
        if wdp is not None:
            wdp.close()
        if cip is not None:
            cip.close()
Ejemplo n.º 2
0
def task_runner(sa_engine, task):
    # Get crop_name and mgmt_code
    crop_no = task["crop_no"]
    lat = float(task["latitude"])
    lon = float(task["longitude"])
    year = 1900
    cip = None
    wdp = None
    
    # Get a crop info provider
    try:
        t1 = time.time()
        cropname, watersupply = select_crop(sa_engine, crop_no)
        cip = CropInfoProvider(cropname, watersupply, run_settings.data_dir)
        cropdata = cip.getCropData()
        msg = "Retrieving data for crop %s, %s took %6.1f seconds" 
        print msg % (cropname, watersupply, time.time()-t1)

        # Everything seems to be set for the task now! Lon-lat combination is 
        # checked in the call to the getSeasonDates method. We assume that the
        # landmask was checked. Also we assume that the data on the growing
        # season were checked. These are represented by day-of-year values.
        start_doy, end_doy = cip.getSeasonDates(lon, lat)
        
        # Get the weather data
        wdp = Hdf5WeatherDataProvider(run_settings.hdf5_meteo_file, lat, lon)

        # Loop over the years
        t2 = time.time()
        tsums = []
        for year in get_available_years(wdp):
            # Get timer data for the current year
            timerdata = cip.getTimerData(start_doy, end_doy, year)

            # Check that START_DATE does not fall before the first available 
            # meteodata and END_DATE not beyond the last data with available
            # weather data.
            if timerdata['START_DATE'] < wdp.first_date: continue
            if timerdata['END_DATE'] > wdp.last_date: continue

            sitedata = {}
            soildata = {"SMFCF":0.4}

            # Run simulation
            pheno = wofostEngine(sitedata, timerdata, soildata, cropdata, wdp,
                        config="Wofost71_PhenoOnly.conf")
            pheno.run(days=366)

            sumresults = pheno.get_summary_output()
            if len(sumresults) > 0:
                tsums.append(sumresults[0]["TSUM"])
            else:
                msg = "No summary results for crop/year/lat/lon: %s/%s/%s/%s"
                logging.error(msg, crop_no, year, lat, lon)

        # end year

        # Insert average etc. into database
        if len(tsums) > 0:
            insert_tsum(sa_engine, 1, crop_no, lat, lon, mean(tsums), 
                std(tsums, ddof=1), min(tsums), max(tsums), len(tsums))
            msg = "Simulating for lat-lon (%s, %s) took %6.1f seconds" 
            print msg % (str(lat), str(lon), time.time()-t2)
        else:
            msg = "Failed calculating TSUMs for lat-lon (%s, %s): no TSUMs calculated for 30 years"
            logging.error(msg, lat, lon)

    finally:
        # Clean up
        if wdp is not None:
            wdp.close()
        if cip is not None:
            cip.close()
Ejemplo n.º 3
0
def task_runner(sa_engine, task):
    # Get crop_name and mgmt_code
    crop_no = task["crop_no"]
    lat = float(task["latitude"])
    lon = float(task["longitude"])
    year = 1900
    cip = None
    wdp = None
    logger = logging.getLogger("GGCMI Task Runner")
    logger.info("Starting task runner for task %i" % task["task_id"])

    # Get a crop info provider
    try:
        t1 = time.time()
        cropname, watersupply = select_crop(sa_engine, crop_no)
        cip = CropInfoProvider(
            cropname,
            watersupply,
        )
        cropdata = cip.getCropData()
        if (not task.has_key("tsum1")) or (not task.has_key("tsum2")):
            msg = "Location specific values for crop parameter(s) missing: TSUM1 and/or TSUM2"
            raise PCSEError(msg)
        else:
            cropdata["TSUM1"] = float(task["tsum1"])
            cropdata["TSUM2"] = float(task["tsum2"])
        start_doy, end_doy = cip.getSeasonDates(lon, lat)
        msg = "Retrieving data for crop %s, %s took %6.1f seconds"
        logger.info(msg % (cropname, watersupply, time.time() - t1))

        # Everything seems to be set for the task now! Lon-lat combination is
        # checked in the call to the getSeasonDates method. We assume that the
        # landmask was checked. Also we assume that the data on the growing
        # season were checked. These are represented by day-of-year values.

        # Get the weather data
        t2 = time.time()
        wdp = Hdf5WeatherDataProvider(run_settings.hdf5_meteo_file, lat, lon)
        available_years = get_available_years(wdp)
        msg = "Retrieving weather data for lat-lon %s, %s took %6.1f seconds"
        logger.debug(msg % (str(lat), str(lon), time.time() - t2))

        # Loop over the years
        t3 = time.time()
        allresults = []
        msg = None
        for year in available_years:
            # Get timer data for the current year
            timerdata = cip.getTimerData(start_doy, end_doy, year)

            # Check that START_DATE does not fall before the first available
            # meteodata and END_DATE not beyond the last data with available
            # weather data.
            if timerdata['START_DATE'] < wdp.first_date:
                continue
            if timerdata['END_DATE'] > wdp.last_date:
                continue
            # Get soil and site data

            soildata = run_settings.get_soil_data(lon, lat)
            sitedata = run_settings.get_site_data(soildata)

            # Run simulation
            if watersupply == 'ir':
                configFile = 'GGCMI_PP.conf'
            else:
                configFile = 'GGCMI_WLP.conf'

            if msg is None:
                msg = "Starting simulation for %s-%s (%5.2f, %5.2f), planting " \
                      "at: %s, final harvest at: %s"
                msg = msg % (cropname, watersupply, lon, lat,
                             timerdata['CROP_START_DATE'],
                             timerdata['CROP_END_DATE'])
                logger.info(msg)

            wofost = wofostEngine(sitedata,
                                  timerdata,
                                  soildata,
                                  cropdata,
                                  wdp,
                                  config=configFile)
            wofost.run_till_terminate()
            results = wofost.get_output()
            sumresults = wofost.get_summary_output()
            if (len(results) > 0) and (len(sumresults) > 0):
                allresults.append({
                    "year": year,
                    "summary": sumresults,
                    "results": results
                })
            else:
                msg = "Insufficient results for crop/year/lat/lon: %s/%s/%s/%s"
                logger.error(msg, crop_no, year, lat, lon)
        # end year

        if len(allresults) > 0:
            # pickle all results
            task_id = task["task_id"]
            obj = {
                "task_id": task_id,
                "crop_no": crop_no,
                "longitude": lon,
                "latitude": lat
            }
            obj["allresults"] = allresults

            # Write results to pickle file. First to .tmp then rename to .pkl
            # to avoid read/write collisions with ggcmi_processsor
            pickle_fname = run_settings.output_file_template % task_id
            if os.path.splitext(pickle_fname)[1] == ".pkl":
                pickle_fname += ".tmp"
            else:
                pickle_fname += ".pkl.tmp"

            pickle_fname_fp = os.path.join(run_settings.output_folder,
                                           pickle_fname)
            with open(pickle_fname_fp, 'wb') as f:
                cPickle.dump(obj, f, cPickle.HIGHEST_PROTOCOL)
            final_fname_fp = os.path.splitext(pickle_fname_fp)[0]
            os.rename(pickle_fname_fp, final_fname_fp)

            msg = "Simulating for lat-lon (%s, %s) took %6.1f seconds"
            logger.info(msg % (str(lat), str(lon), time.time() - t3))
        else:
            msg = "Failed simulating for lon,lat,crop, watersupply (%s, %s, " \
                  "%s, %s): no output available."
            msg = msg % (lon, lat, cropname, watersupply)
            raise PCSEError(msg)

    finally:
        if wdp is not None:
            wdp.close()
        if cip is not None:
            cip.close()
Ejemplo n.º 4
0
def task_runner(sa_engine, task):

    # Get crop_name and mgmt_code
    crop_no = task["crop_no"]
    cropname, watersupply = select_crop(sa_engine, crop_no)
    msg = "Starting to simulate for %s (%s)" % (cropname, watersupply)
    print msg

    # Get a crop info provider
    t1 = time.time()
    cip = CropInfoProvider(cropname, watersupply, run_settings.datadir)
    extent = cip.getExtent()
    cropdata = cip.getCropData()
    msg = ("Retrieving data for crop %s, %s took %6.1f seconds" % (cropname, watersupply, time.time()-t1))
    print msg

    # Everything seems to be set for the task now!
    # Make sure we can loop over the grid cells from UL down to LR corner
    nvlp = extent
    x_range = arange(nvlp.getMinX() + 0.5*nvlp.dx, nvlp.getMaxX() + 0.5*nvlp.dy, nvlp.dx)
    y_range = arange(nvlp.getMinY() + 0.5*nvlp.dy, nvlp.getMaxY() + 0.5*nvlp.dx, nvlp.dy)
    if nvlp.xcoords_sort != 'ASC':
        x_range = reversed(x_range)
    if nvlp.ycoords_sort != 'DESC':
        y_range = reversed(y_range)

    # Find out whether maybe another process already calculated TSUMs for this crop
    minlat, maxlon = get_resumption_point(sa_engine, crop_no)

    # Loop but make sure not to waste time on pixels that are not interesting
    for lat in y_range:
        if (lat > minlat):
            continue
        eps = 0.0000001
        for lon in x_range:
            try:
                if abs(lat - minlat) < eps and (lon - maxlon) < eps:
                    continue
                # Check the landmask
                if not cip.get_landmask(lon, lat):
                    continue

                # Check the data on the growing season represented by day-of-year
                # values. If start_doy or end_doy return nodata value (-99), then
                # continue with next grid directly.
                start_doy, end_doy = cip.getSeasonDates(lon, lat)
                if (start_doy == -99) or (end_doy == -99):
                    continue

                wdp = Hdf5WeatherDataProvider(run_settings.hdf5_meteo_file, lat, lon)

                # Loop over the years
                t2 = time.time()
                tsums = []
                for year in get_available_years(wdp):
                    # Get timer data for the current year
                    timerdata = cip.getTimerData(start_doy, end_doy, year)

                    # Check that START_DATE does not fall before the first
                    # available meteodata and END_DATE not beyond the
                    # last data with available weather data.
                    if timerdata['START_DATE'] < wdp.first_date or \
                       timerdata['END_DATE'] > wdp.last_date:
                        continue

                    sitedata = {}
                    soildata = {"SMFCF":0.4}

                    # Run simulation
                    pheno = wofostEngine(sitedata, timerdata, soildata, cropdata,
                                         wdp, config="Wofost71_PhenoOnly.conf")
                    pheno.run(days=366)

                    sumresults = pheno.get_summary_output()
                    if len(sumresults) > 0:
                        tsums.append(sumresults[0]["TSUM"])
                    else:
                        msg = "No summary results for crop/year/lat/lon: %s/%s/%s/%s"
                        logging.error(msg, crop_no, year, lat, lon)

                # end year

                # Insert average etc. into database
                if len(tsums) > 0:
                    insert_tsum(sa_engine, 1, crop_no, lat, lon, mean(tsums), std(tsums, ddof=1),
                                min(tsums), max(tsums), len(tsums))
                    msg = ("Simulating for lat-lon (%s, %s) took %6.1f seconds" % (str(lat), str(lon), time.time()-t2))
                    print msg
                else:
                    msg = "Failed calculating TSUMs for lat-lon (%s, %s): no TSUMs calculated for 30 years"
                    logging.error(msg, lat, lon)

                if wdp is not None:
                    wdp.close()

            except tables.NoSuchNodeError:
                msg = "No weather data found for lat/lon: %s/%s"
                logging.error(msg, lat, lon)
            except PCSEError:
                msg = "Error in PCSE for crop/year/lat/lon: %s/%s/%s/%s"
                logging.exception(msg, crop_no, year, lat, lon)

    print "Finished simulating for " + cropname + " (" + watersupply + ")"
    cip.close()