Seasonal mean AOD in Google Earth Engine - google-earth-engine

I want to plot the spatial map of the average annual and winter seasons MODIS Aerosol Optical Depth for each year from 2003 to 2022 in Google Earth Engine. For the annual mean, I think the following script gives the result
//-------------------------MODIS AOD Analysis--------------------------
// import modis AOD image collection
var modisAOD = ee.ImageCollection("MODIS/006/MCD19A2_GRANULES")
.filterBounds(aoi)
.select("Optical_Depth_055");
//annual AOD
// set start and end year
var startyear = 2003;
var endyear = 2022;
// make a date object
var startdate = ee.Date.fromYMD(startyear,1, 1);
var enddate = ee.Date.fromYMD(endyear , 12, 31);
// make a list with years
var years = ee.List.sequence(startyear, endyear);
var annualAOD = ee.ImageCollection.fromImages(
years.map(function (year) {
var annual = modisAOD
.filter(ee.Filter.calendarRange(year, year, 'year'))
.mean();
return annual
.set('year', year)
.set('system:time_start', ee.Date.fromYMD(year, 1, 1));
}));
How can I do the same for the winter season? In my case winter season AOD for this year is defined as the mean AOD of the previous year's December and this year's January and February.Thank you in advance for your support.

Related

Filter specific months in several years

var x1= ee.ImageCollection('LANDSAT/LC08/C01/T1_SR').filterBounds(geometry)
.filterDate('2019-07-01', '2019-10-30')
.sort('CLOUD_COVER');
How could I filter the dates in Sep, Oct, and Nov between 2014 and 2020?
Here is an example of how to filter by year, then specific months within those years.
// Create image collection of S-2 imagery for the perdiod 2015-2020
var S2 = ee.ImageCollection('COPERNICUS/S2')
//filter start and end date
.filterDate('2015-07-01', '2020-10-31')
.filter(ee.Filter.calendarRange(9, 11,'month'))

DateTime Series Issue PineScript

I'm working to fill an array with High/Low pivot points of the "Previous Trading Day", but I'm facing an issue in terms of the time series (second section below!). I'm not sure if that PineScript's bug or my misunderstanding of how are the time-series functions working!! Please Help, very organize details.
Calling for current Trading Day, then selected the regular session ( No issues in this part )
//------------------ Selected Day of Trading
//Start Day
Start_Period= timestamp(syminfo.timezone, 2020, 12, 09, 00, 00, 00)
//End Day
End_Period = timestamp(syminfo.timezone, 2020, 12, 09, 23, 59, 59)
//------------------ Filtring Session
// Regular Session
t_reg = time("1440", session.regular)
The issue only in this coding box.
Pine script would not recognize the result of Change_Time
// Detect the change of time between selected day trading and most recent day trading (t-t[1])
Change_Time = security(syminfo.tickerid, "1440", change(time))
FunYesterday()=>
if time >= Start_Period-Change_Time and time <= End_Period-Change_Time and t_reg
[pivothigh(close, 3, 2), pivotlow(close, 3, 2)]
However, if I substitute the security function of Change_time= 60*60*24*1000will work fine!!, but I tried to avoid this method because of time deference on weekends, and other holidays.
Final Section find Pivot and Create Array ( No issues in this part )
//------------------ Pivot point at 15 min.
[ph2, pl2] = security(syminfo.tickerid, "15", FunYesterday(), lookahead = barmerge.lookahead_off)
ph2_filter= ph2 == ph2[1]?na:ph2
pl2_filter= pl2 == pl2[1]?na:pl2
//------------------ Array Part
var a = array.new_float()
if (not na(ph2_filter))
array.push(a,ph2_filter)
else if (not na(pl2_filter))
array.push(a,pl2_filter)
if barstate.islast and array.size(a)>0
y=label.new(bar_index, close, "Initial\na: " + tostring(a))
label.delete(y[1])
I'm very open if you have any other idea to import data from the most recent trading day only!!. Thank you

Issue with date formatting and time zone change

I am having a weird issue with dates formatting in Google Sheets and Google Script.
I am developing a script that reads a list of dates in a Google sheet and then sends automatic emails to a list of recipients. I have a cell in the spreadsheet with a date formatted as "dd/mm/yyyy" and then I use the following formulas (cell + 7, cell + 14, cell + 21, cell + 28, etc...) to generate all the other dates in the spreadsheet.
I use the following code to read the dates in the spreadsheet:
var sheet = SpreadsheetApp.getActiveSheet();
var drng = sheet.getDataRange();
var rng = sheet.getRange(4, 2, drng.getLastRow()-3, drng.getLastColumn());
var rngData = rng.getValues();
var todayDate = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy");
// CYCLE THROUGH DATA
for (var i = 0; i < rngData.length; i++) { // cycle through the rows in the spreadsheet
var ptLastName = rngData[i][0]; // fixed patient data used to email customization
var ptFirstName = rngData[i][1];
var ptDoB = Utilities.formatDate(rngData[i][2], "GMT+1", "dd/MM/yyyy");
var ptSex = rngData[i][3];
var ptEmail = rngData[i][4];
var ptDoS = Utilities.formatDate(rngData[i][5], "GMT+1", "dd/MM/yyyy");
var ptDoD = Utilities.formatDate(rngData[i][6], "GMT+1", "dd/MM/yyyy");
for (var j = 7; j <= 14; j++) { // cycle through follow-up data for the current patient
var currentDate = Utilities.formatDate(rngData[i][j], "GMT+1", "dd/MM/yyyy");
if (currentDate == todayDate) { // send email with the questionnaire
writeEmail(ptFirstName, ptLastName, ptSex, ptDoD, ptEmail);
rng.getCell(i+1, j+1).setBackground("yellow");
}
}
}
The issue is that when I try for read and format some of the dates they are not corresponding to the ones listed in the spreadsheet. I have noted that the wrong dates in the code are systematically 1 day earlier than the ones listed in the spreadsheet. On a closer look I have noted that some of the dates read from the spreadsheet at GMT+2 while others are GMT+1.
That's weird because I have checked my system settings (it GMT+1) as well as the spreadsheet settings (GMT+1). So I don't understand why some dates are automatically converted to GMT+2.
I tried it this way and it works okay:
function dattest() {
const ss=SpreadsheetApp.getActive();
const sh=ss.getActiveSheet();
const rg=sh.getDataRange();
const vs=rg.getValues()[0];
vs.forEach(function(d){
Logger.log(Utilities.formatDate(new Date(d),Session.getScriptTimeZone(),"dd/MM/yyyy"));
});
}
Display Values:
8/1/2020,8/8/2020,8/15/2020,8/22/2020
Formulas:
,=A1+7,=A1+14,=a1+21
The output from view Executions:
Aug 1, 2020, 2:52:37 PM Info 01/08/2020
Aug 1, 2020, 2:52:37 PM Info 08/08/2020
Aug 1, 2020, 2:52:37 PM Info 15/08/2020
Aug 1, 2020, 2:52:37 PM Info 22/08/2020
Seems correct to me
thank you for your help.
I finally found out what the problem was.
The dates in the spreadsheet were stored as dd/mm/yyyy, and the system automatically added 00.00.00 as time to them. As a result, when I was trying to read some of the dates with the code some of them were converted as the day before because of the daylight saving time adjustment. I have managed to solve the issue adding 1/3 of a day to all the dates. This way they are stored as dd/mm/yyyy 8.00.000 am and they remain the same day all year long.

Add a decimal year to a moment.js date

How can I add a decimal/float value to a moment.js date object?
moment('2017-09-20').add(1.234, 'years');
does only change the year and month, not the day. I was expecting that moment will calculate the correct date of '2017-09-20' plus one year plus the nearest day of the 0.234th of the year 2018. But instead it prints out '2017-11-20'.
You can create a moment.duration for 1.234 years and then add using moment().add(Duration);.
EDIT:
1.234 years is equal to 1 year and 2.808 months as you can see using toISOString(). The same duration is equal to 451 days. As the asDays() states:
moment.duration().asDays() gets the length of the duration in days.
So you can use asDays() output as input of add(Number, String);.
Here a live example:
// Create moment duration for 1.234 years
var dur = moment.duration(1.234, 'years');
// 1.234 years is equal to 1 year and 2.808 months
console.log(dur.toISOString()); // P1Y2.808M
// 1.234 years is also equal to 451 days
console.log(dur.asDays()); // 451
// Add duration using moment().add(Duration);
var m1 = moment('2017-09-20').add(dur);
console.log(m1.format()); // 2018-12-20T00:00:00+01:00
// Add number of days
var m2 = moment('2017-09-20').add(dur.asDays(), 'd');
console.log(m2.format()); // 2018-12-15T00:00:00+01:00
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

D3.js xAxis tickformat week number

The ISO week numbers are not right when trying to display them on the x-axis using tickformat.
var parseDate = d3.time.format("%Y%W").parse;
var x = d3.time.scale().range([0, width]);
x.domain([parseDate("201552"), parseDate("201602")]);
var xAxis = d3.svg.axis().scale(x)
.orient("bottom")
.ticks(d3.time.monday,1)
.tickFormat(d3.time.format("%W"))
This works fine with most of the scenario except with years that have 53 weeks.
Example: from week 201552 to week 201602. In this scenario it always skips week 53 so the the tick I get are [52, 01, 02]. although the expected output is [52,53,01,02]. Here is my code
I also tried parsing the date string using momentjs since I face this problem skip week in d3.time.format
This is the modified code using momentjs to parse the date:
var parseDate = function(d){
return moment(d, "YYYYWW").toDate();
}
x.domain([parseDate("201552"), parseDate("201602")]);
var MultiFormat = d3.time.format.multi([
["%W", function(d) {
return moment(d).isoWeek();
}],
]);
var xAxis_weeks = d3.svg.axis().scale(x)
.orient("bottom")
.ticks(d3.time.monday,1)
.tickFormat( function(d) {return MultiFormat(d);})
Now the output is [51,52,01,02] which also should have been [52,53,01,02]

Resources