0

I want to calculate hourly temperatures from daily temperatures based on formulas I have from Goudrian and Laar. My daily temperatures come from the Image Collection for Daymet.

// Raster of boundary of lower U.S. 48
var us = ee.Image("users/japolo/us_bounds");

var usbound = us.geometry();

// Set up Daymet collection from 2009 to 2020
var daymetb = ee.ImageCollection("NASA/ORNL/DAYMET_V4")
.filterDate('2009-01-01', '2020-12-31')
.map(function(im){return im.clip(usbound)});

// Set a threshold of temps for use in a later calculation
var threshold = function(im) {
  return im.where(im.lt(-5.0), -5)
};

// Get mean temp. over collection
var daymean = daymet.map(function (image) {
  var dayx = image.select('tmax')
  var dayn = image.select('tmin')
  // Apply threshold
  var dayxt = threshold(dayx)
  var daynt = threshold(dayn)
  // Calculate mean temp.
  return daynt.add(dayxt).divide(2)
})

This Image Collection has daily means for 12 years: 4380 Images. I don't know what the function is to do what I want. I'm still learning to use GEE and have no background in JavaScript, but I know that GEE has the .reduce function when one wants to go from, say daily to weekly values, but I want to go in the reverse direction. I think that I may need to map() something over the Image Collection, but I have no idea what kind of function will increase the number of Image, especially in a way that uses time to go from 1 day to 24 hours.

For example, if I have a 7 images in an Image Collection, say 2020-01-08 to 2020-01-14, to start, I want to finish with 168 images, where every 24 images are the seven 24 hours periods for 8 Jan. through 14 Jan.

This is the code I have for the hourly temperatures. I added this after the comment from xunilk. It doesn't create Images, it assigns values to Images, so it won't help me with expanding the Image Collection.

var daylen_cal = function(image) {
    // Constants
    var pi = 3.141593
    var rad = pi/180
    // Latitude of pixel
    var imla = ee.Image.pixelLonLat().select('latitude');
    // Date --- THIS COULD CHANGE FOR ImageCollection vs. Image
    //var imgda = ee.Date(image);
    var magda = ee.ImageCollection(image).toList(3);
    var imgda = ee.Image(ee.List(magda).get(0));
    var imgd2 = imgda.date();
    print(imgd2)
    // Day of year
    var doy = imgd2.getRelative('day', 'year').add(1);
    // Sine of latitude
    var latsn = imla.multiply(rad).sin();
    // Cosine of latitude
    var latcs = imla.multiply(rad).cos();
    // Max of sine of declination
    var xsindecl = ee.Number(rad).multiply(23.45).sin();
    // Sine of declination
    var sndl1 = doy.add(10).divide(365).multiply(pi).multiply(2).cos()
    var sindecl = xsindecl.multiply(-1).multiply(sndl1)
    // Cosine of declination
    var cosf = function(image) {
        return ee.Image().expression(
          '(1 - im * im)**0.5', {
          'im' : sindecl
      })
    };
    var cosdecl = cosf();
    // Parts for the day length equation
    var p_a = latsn.multiply(sindecl);
    var p_b = latcs.multiply(cosdecl);
    var p_c = p_a.divide(p_b);
    // Daylength equation
    var dayeq = function(image) {
      return ee.Image().expression(
        '12 * (1 + (2 / pi) * atan(im / (im*im+1)**0.5))', {
        'pi' : pi,
        'im' : p_c
      })
    };
    var daylen = dayeq();
    return ee.Image(daylen)
}

EDIT #2: I wonder if I can add the additional layers as bands? I don't know what the different is between an Image and a band in GEE. I see there is the .addBands function, so I tried this, but it doesn't work, mostly because I don't know how to iterate the addBands part. I know GEE doesn't like for loops, but I have not idea how to approach this otherwise.

var usbounds = ee.Image("users/japolo/us_bounds"),
    dec0112 = ee.Image("users/japolo/time_raster_2012_01_01");
    
var us = usbounds.geometry();

var dec0112 = dec0112.clip(us);

//1 hr = 3600000 ms; 8760 steps in one year

var startdate = ee.Date('2009-01-01T00:00:00').millis();

var timelist = ee.List.sequence(1230768000000, null, 3600000, 8760)

var n = timelist.size().getInfo();

for (var i = 0; i < n; i++) {
  print(timelist.get(i));
  var col2 = dec0112.addBands(dec0112);
}
2
  • Apply Goudrian and Laar formulas to dayly image collection for converting it in hourly image collection.
    – xunilk
    Commented Feb 19, 2022 at 1:26
  • @xunilk, the code for the formulas was added. The code does not create Images, it assigns values.
    – John Polo
    Commented Feb 19, 2022 at 18:59

1 Answer 1

0

I tried using the code in this answer. It seems close, but I didn't know how to use it with the list of dates I made.

As a matter of luck, I was searching for something else related to this work and came across this answer. I modified the code a little and this is the code that creates an Image Collection with a specified number of Images.

var usbounds = ee.Image("users/japolo/us_bounds"),
    dec0112 = ee.Image("users/japolo/time_raster_2012_01_01");
    
var us = usbounds.geometry();

// My starting image
var dec0112 = dec0112.clip(us);

//1 hr = 3600000 ms; 8760 steps in one year; ~720 / month

var startdate = ee.Date('2009-01-01T00:00:00').millis();

var timelist = ee.List.sequence(1230768000000, null, 3600000, 8760)

var Date_Start = ee.Date('2009-01-01T00:00:00');
// Wanted a year's worth. The ImageCollection in last step won't create more
// than 5000 Images, so I cut back.
var Date_End = ee.Date('2009-06-30T23:00:00');
// Was originally 8760
var num_in_interval = 4343;

// Create list of dates for time series
var n_units = Date_End.difference(Date_Start,'hour').round();
var dates = ee.List.sequence(0, n_units, null, num_in_interval);
var make_datelist = function(n) {
  return Date_Start.advance(n,'hour');
};
var dates = dates.map(make_datelist);

var addmoreims = function(image) {
  return ee.Image(dec0112);
};

var CreateCol = function(d1) {
  var start = ee.Date(d1);
  var end = ee.Date(d1).advance(num_in_interval, 'hour');
  var name = start.format('YYYY-MM-dd H:00:ss');
  var intCol = ee.ImageCollection(dec0112)
    .map(addmoreims)
    .toList(2);
  // Change the ImageCollection to an Image
  // otherwise, the list created will be a list 
  // of ImageCollections and that can't be 
  // turned into an ImageCollection
  return ee.Image(ee.List(intCol).get(0)).set({name: name});
};

// A list of images that has the length I need
var list_of_images = dates.map(CreateCol);

// Create an ImageCollection from the list I made in previous step
var ims_l = ee.ImageCollection(list_of_images);

I reused my starting image each time, but I don't think that will be a problem, since this is supposed to be a skeleton for other code that I hope will assign the new values I intend to use.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.