var exports={};var changeDetectionLib=exports;if(getImagesLib===undefined||getImagesLib===null){var getImagesLib=require("users/aaronkamoske/GTAC-Modules:getImagesLib.js");}
var lossYearPalette="ffffe5,fff7bc,fee391,fec44f,fe9929,ec7014,cc4c02";var lossMagPalette="D00,F5DEB3";var gainYearPalette="AFDEA8,80C476,308023,145B09";var gainMagPalette="F5DEB3,006400";var changeDurationPalette="BD1600,E2F400,0C2780";exports.lossYearPalette=lossYearPalette;exports.lossMagPalette=lossMagPalette;exports.gainYearPalette=gainYearPalette;exports.gainMagPalette=gainMagPalette;exports.changeDurationPalette=changeDurationPalette;function getR2(collection,coefficients,dependent,independents){var meanImage=collection.select(dependent).mean();var squaredErrors=collection.map(function(image){var prediction=image.select(independents).multiply(coefficients).reduce("sum");var actual=image.select(dependent);var diffPrediction=actual.subtract(prediction);var diffMean=actual.subtract(meanImage);var sqError=diffPrediction.multiply(diffPrediction).rename("sqError");var sqTotal=diffMean.multiply(diffMean).rename("sqTotal");return image.addBands(sqError).addBands(sqTotal);});var ssError=squaredErrors.select("sqError").sum();var ssTotal=squaredErrors.select("sqTotal").sum();var R2=ee.Image(1).subtract(ssError.divide(ssTotal));return R2;}
function thresholdChange(changeCollection,changeThresh,changeDir){if(changeDir===undefined||changeDir===null){changeDir=1;}
var bandNames=ee.Image(changeCollection.first()).bandNames();bandNames=bandNames.map(function(bn){return ee.String(bn).cat("_change");});var change=changeCollection.map(function(img){var yr=ee.Date(img.get("system:time_start")).get("year");var changeYr=img.multiply(changeDir).gt(changeThresh);var yrImage=img.where(img.mask(),yr);changeYr=yrImage.updateMask(changeYr).rename(bandNames).int16();return img.mask(ee.Image(1)).addBands(changeYr);});return change;}
function thresholdSubtleChange(changeCollection,changeThreshLow,changeThreshHigh,changeDir){if(changeDir===undefined||changeDir===null){changeDir=1;}
var bandNames=ee.Image(changeCollection.first()).bandNames();bandNames=bandNames.map(function(bn){return ee.String(bn).cat("_change");});var change=changeCollection.map(function(img){var yr=ee.Date(img.get("system:time_start")).get("year");var changeYr=img.multiply(changeDir).gt(changeThreshLow).and(img.multiply(changeDir).lt(changeThreshHigh));var yrImage=img.where(img.mask(),yr);changeYr=yrImage.updateMask(changeYr).rename(bandNames).int16();return img.mask(ee.Image(1)).addBands(changeYr);});return change;}
function getExistingChangeData(changeThresh,showLayers){if(showLayers===undefined||showLayers===null){showLayers=true;}
if(changeThresh===undefined||changeThresh===null){changeThresh=50;}
var startYear=1985;var endYear=2023;var hansen=ee.Image("UMD/hansen/global_forest_change_2022_v1_10").select(["lossyear"]).add(2000).int16();hansen=hansen.updateMask(hansen.neq(2000).and(hansen.gte(startYear)).and(hansen.lte(endYear)));if(showLayers){Map.addLayer(hansen,{min:startYear,max:endYear,palette:"FF0,F00"},"Hansen Change Year",false);}
return hansen;}
var getLTvertStack=function(LTresult,run_params){var emptyArray=[];var vertLabels=[];var iString;for(var i=1;i<=run_params.maxSegments+1;i++){iString=i.toString();vertLabels.push("vert_"+iString);emptyArray.push(-32768);}
var zeros=ee.Image(ee.Array([emptyArray,emptyArray,emptyArray,]));var lbls=[["yrs_","src_","fit_"],vertLabels];var vmask=LTresult.arraySlice(0,3,4);var ltVertStack=LTresult.arrayMask(vmask).arraySlice(0,0,3).addBands(zeros).toArray(1).arraySlice(1,0,run_params.maxSegments+1).arrayFlatten(lbls,"");return ltVertStack;};function getLTStack(LTresult,maxVertices,bandNames){var nBands=bandNames.length;var emptyArray=[];var vertLabels=[];var iString;for(var i=1;i<=maxVertices;i++){iString=i.toString();vertLabels.push(iString);emptyArray.push(-32768);}
var emptyArrayList=[];range(1,nBands+1).map(function(i){emptyArrayList.push(emptyArray);});var zeros=ee.Image(ee.Array(emptyArrayList));var lbls=[bandNames,vertLabels];var ltVertStack=LTresult.addBands(zeros).toArray(1).arraySlice(1,0,maxVertices).arrayFlatten(lbls,"");return ltVertStack.updateMask(ltVertStack.neq(-32768));}
function rawLTToVertices(rawLT,indexName,multBy,vertexNoData){if(multBy===undefined||multBy===null){multBy=10000;}
if(vertexNoData===undefined||vertexNoData===null){vertexNoData=-32768;}
var distDir;if(indexName!==undefined&&indexName!==null){try{distDir=getImagesLib.changeDirDict[indexName];}catch(err){distDir=-1;}}else{distDir=-1;}
var ltArray=rawLT.select(["LandTrendr"]);var rmse=rawLT.select(["rmse"]).multiply(multBy);var vertices=ltArray.arraySlice(0,3,4);ltArray=ltArray.arrayMask(vertices);ltArray=ltArray.arrayMask(ee.Image(ee.Array([[1],[0],[1],[0]])));var l=ltArray.arrayLength(1);var minObservationsNeededMask=ltArray.arraySlice(0,1,2).arraySlice(1,0,1).neq(vertexNoData).arrayProject([0]).arrayFlatten([["test"]]);var multImg=ee.Image(ee.Array([[1],[distDir*multBy]])).arrayRepeat(1,l);ltArray=ltArray.multiply(multImg);return ltArray.addBands(rmse).updateMask(minObservationsNeededMask);}
var extractDisturbance=function(lt,distDir,params,mmu){var vertexMask=lt.arraySlice(0,3,4);var vertices=lt.arrayMask(vertexMask);var left=vertices.arraySlice(1,0,-1);var right=vertices.arraySlice(1,1,null);var startYear=left.arraySlice(0,0,1);var startVal=left.arraySlice(0,2,3);var endYear=right.arraySlice(0,0,1);var endVal=right.arraySlice(0,2,3);var dur=endYear.subtract(startYear);var mag=endVal.subtract(startVal);var distImg=ee.Image.cat([startYear.add(1),mag,dur,startVal.multiply(-1),]).toArray(0);var distImgSorted=distImg.arraySort(mag.multiply(-1));var tempDistImg1=distImgSorted.arraySlice(1,0,1).unmask(ee.Image(ee.Array([[0],[0],[0],[0]])));var tempDistImg2=distImgSorted.arraySlice(1,1,2).unmask(ee.Image(ee.Array([[0],[0],[0],[0]])));var tempDistImg3=distImgSorted.arraySlice(1,2,3).unmask(ee.Image(ee.Array([[0],[0],[0],[0]])));var finalDistImg1=tempDistImg1.arrayProject([0]).arrayFlatten([["yod","mag","dur","preval"]]);var finalDistImg2=tempDistImg2.arrayProject([0]).arrayFlatten([["yod","mag","dur","preval"]]);var finalDistImg3=tempDistImg3.arrayProject([0]).arrayFlatten([["yod","mag","dur","preval"]]);function filterDisturbances(finalDistImg){var longTermDisturbance=finalDistImg.select(["dur"]).gte(15);var longTermThreshold=finalDistImg.select(["mag"]).gte(params.tree_loss20).and(longTermDisturbance);var threshold=finalDistImg.select(["mag"]).gte(params.tree_loss1);return finalDistImg.updateMask(threshold.or(longTermThreshold));}
finalDistImg1=filterDisturbances(finalDistImg1);finalDistImg2=filterDisturbances(finalDistImg2);finalDistImg3=filterDisturbances(finalDistImg3);function applyMMU(finalDistImg){var mmuPatches=finalDistImg.select(["yod.*"]).int16().connectedPixelCount(mmu,true).gte(mmu);return finalDistImg.updateMask(mmuPatches);}
if(mmu>1){print("Applying mmu:",mmu,"to LANDTRENDR heuristic outputs");finalDistImg1=applyMMU(finalDistImg1);finalDistImg2=applyMMU(finalDistImg2);finalDistImg3=applyMMU(finalDistImg3);}
return finalDistImg1.addBands(finalDistImg2).addBands(finalDistImg3);};function multBands(img,distDir,by){var out=img.multiply(ee.Image(distDir).multiply(by));out=out.copyProperties(img,["system:time_start"]).copyProperties(img);return out;}
function addToImage(img,howMuch){var out=img.add(ee.Image(howMuch));out=out.copyProperties(img,["system:time_start"]).copyProperties(img);return out;}
function nullFinder(img,countMask){var m=img.mask();m=m.or(countMask.not());img=img.mask(m);img=img.where(countMask.not(),-32768);return img;}
function arrayToTimeSeries(tsArray,yearsArray,possibleYears,bandName){var noDateValue=-32768;var dummyImage=ee.Image(noDateValue).toArray();var tsC=possibleYears.map(function(yr){yr=ee.Number(yr);var yrMask=yearsArray.eq(yr);var masked=tsArray.arrayMask(yrMask);var l=masked.arrayLength(0);masked=masked.where(l.eq(0),dummyImage).arrayGet([-1]);masked=masked.updateMask(masked.neq(noDateValue)).rename([bandName]).set("system:time_start",ee.Date.fromYMD(yr,6,1).millis());return masked;});return ee.ImageCollection(tsC);}
function landtrendrWrapper(processedComposites,startYear,endYear,indexName,distDir,run_params,distParams,mmu){var noDataValue=32768;if(distDir===1){noDataValue=-noDataValue;}
var ltCollection=processedComposites.select([indexName]).map(function(img){return ee.Image(multBands(img,distDir,1));});run_params.timeSeries=ltCollection;var lt=ee.Algorithms.TemporalSegmentation.LandTrendr(run_params);var distImg=extractDisturbance(lt.select("LandTrendr"),distDir,distParams,mmu);var distImgBandNames=distImg.bandNames();distImgBandNames=distImgBandNames.map(function(bn){return ee.String(indexName).cat("_").cat(bn);});distImg=distImg.rename(distImgBandNames);var rawLT=lt.select([0]);var ltYear=rawLT.arraySlice(0,0,1).arrayProject([1]);var ltFitted=rawLT.arraySlice(0,2,3).arrayProject([1]);if(distDir===-1){ltFitted=ltFitted.multiply(-1);}
var fittedCollection=arrayToTimeSeries(ltFitted,ltYear,ee.List.sequence(startYear,endYear),"LT_Fitted_"+indexName);var vertStack=getLTvertStack(rawLT,run_params);return[lt,distImg,fittedCollection,vertStack];}
function getRawAndFittedLT(rawTs,lt,startYear,endYear,indexName,distDir){if(indexName===undefined||indexName===null){indexName="Band";}
if(distDir===undefined||distDir===null){distDir=-1;}
var ltYear=lt.arraySlice(0,0,1).arrayProject([1]);var ltFitted=lt.arraySlice(0,2,3).arrayProject([1]);if(distDir==-1){ltFitted=ltFitted.multiply(-1);}
var fittedCollection=arrayToTimeSeries(ltFitted,ltYear,ee.List.sequence(startYear,endYear),"LT_Fitted_"+indexName);var joinedTS=getImagesLib.joinCollections(rawTs,fittedCollection);return joinedTS;}
var default_lt_run_params={maxSegments:6,spikeThreshold:0.9,vertexCountOvershoot:3,preventOneYearRecovery:true,recoveryThreshold:0.25,pvalThreshold:0.05,bestModelProportion:0.75,minObservationsNeeded:6,};function simpleRawLTToVertices(rawLT){var rmse=rawLT.select(["rmse"]);var ltArray=rawLT.select(["LandTrendr"]);var vertices=ltArray.arraySlice(0,3,4);ltArray=ltArray.arrayMask(vertices);return ltArray.arrayMask(ee.Image(ee.Array([[1],[0],[1],[0]]))).addBands(rmse);}
function multLT(rawLT,multBy){var rmse=rawLT.select(["rmse"]).multiply(multBy).abs();var ltArray=rawLT.select(["LandTrendr"]);var l=ltArray.arrayLength(1);var multImg=ee.Image(ee.Array([[1],[multBy]])).arrayRepeat(1,l);return ltArray.multiply(multImg).addBands(rmse);}
function LTExportPrep(rawLT,multBy){multBy=multBy||10000;rawLT=simpleRawLTToVertices(rawLT);rawLT=multLT(rawLT,multBy);return rawLT;}
function runLANDTRENDR(ts,bandName,run_params){ts=ts.select([bandName]);var distDir;try{distDir=getImagesLib.changeDirDict[bandName];}catch(err){distDir=-1;}
ts=ts.map(function(img){return multBands(img,1,distDir);});run_params=run_params||default_lt_run_params;run_params["timeSeries"]=ts;var rawLT=ee.Algorithms.TemporalSegmentation.LandTrendr(run_params);return LTExportPrep(rawLT,distDir).set("band",bandName).set("run_params",run_params);}
function LTLossGainExportPrep(lossGainDict,indexName,multBy){indexName=indexName||"Bn";multBy=multBy||10000;var lossStack=lossGainDict["lossStack"];var gainStack=lossGainDict["gainStack"];var lossThematic=lossStack.select([".*_yr_.*"]).int16().addBands(lossStack.select([".*_dur_.*"]).byte());var lossContinuous=lossStack.select([".*_mag_.*",".*_slope_.*"]).multiply(multBy);if(Math.abs(multBy)===10000){lossContinuous=lossContinuous.int16();}
lossStack=lossThematic.addBands(lossContinuous);var gainThematic=gainStack.select([".*_yr_.*"]).int16().addBands(gainStack.select([".*_dur_.*"]).byte());var gainContinuous=gainStack.select([".*_mag_.*",".*_slope_.*"]).multiply(multBy);if(Math.abs(multBy)===10000){gainContinuous=gainContinuous.int16();}
gainStack=gainThematic.addBands(gainContinuous);var outStack=lossStack.addBands(gainStack);var bns=outStack.bandNames();var outBns=bns.map(function(bn){return ee.String(indexName).cat("_LT_").cat(bn);});return outStack.rename(outBns);}
function addLossGainToMap(lossGainStack,startYear,endYear,lossMagMin,lossMagMax,gainMagMin,gainMagMax,indexName,howManyToPull){lossMagMin=lossMagMin||-8000;lossMagMax=lossMagMax||-2000;gainMagMin=gainMagMin||1000;gainMagMax=gainMagMax||8000;var vizParamsLossYear={min:startYear,max:endYear,palette:lossYearPalette,};var vizParamsLossMag={min:lossMagMin,max:lossMagMax,palette:lossMagPalette,};var vizParamsGainYear={min:startYear,max:endYear,palette:gainYearPalette,};var vizParamsGainMag={min:gainMagMin,max:gainMagMax,palette:gainMagPalette,};var vizParamsDuration={min:1,max:5,palette:changeDurationPalette,layerType:"geeImage",};range(1,howManyToPull+1).map(function(i){var lossStackI=lossGainStack.select([".*_loss_.*_"+i.toString()]);var gainStackI=lossGainStack.select([".*_gain_.*_"+i.toString()]);var showLossYear=false;if(i==1){showLossYear=true;}
console.log(getObjType(lossStackI));Map.addLayer(lossStackI.select([".*_loss_yr.*"]),vizParamsLossYear,i.toString()+" "+indexName+" Loss Year",showLossYear);Map.addLayer(lossStackI.select([".*_loss_mag.*"]),vizParamsLossMag,i.toString()+" "+indexName+" Loss Magnitude",false);Map.addLayer(lossStackI.select([".*_loss_dur.*"]),vizParamsDuration,i.toString()+" "+indexName+" Loss Duration",false);Map.addLayer(gainStackI.select([".*_gain_yr.*"]),vizParamsGainYear,i.toString()+" "+indexName+" Gain Year",false);Map.addLayer(gainStackI.select([".*_gain_mag.*"]),vizParamsGainMag,i.toString()+" "+indexName+" Gain Magnitude",false);Map.addLayer(gainStackI.select([".*_gain_dur.*"]),vizParamsDuration,i.toString()+" "+indexName+" Gain Duration",false);});}
function simpleLANDTRENDR(ts,startYear,endYear,indexName,run_params,lossMagThresh,lossSlopeThresh,gainMagThresh,gainSlopeThresh,slowLossDurationThresh,chooseWhichLoss,chooseWhichGain,addToMap,howManyToPull,multBy){indexName=indexName||"NBR";run_params=run_params||default_lt_run_params;lossMagThresh=lossMagThresh||-0.15;lossSlopeThresh=lossSlopeThresh||-0.1;gainMagThresh=gainMagThresh||0.1;gainSlopeThresh=gainSlopeThresh||0.1;slowLossDurationThresh=slowLossDurationThresh||3;chooseWhichLoss=chooseWhichLoss||"largest";chooseWhichGain=chooseWhichGain||"largest";addToMap=addToMap||true;howManyToPull=howManyToPull||2;multBy=multBy||10000;ts=ts.select(indexName);var lt=runLANDTRENDR(ts,indexName,run_params);var distDir;try{distDir=getImagesLib.changeDirDict[indexName];}catch(err){distDir=-1;}
var ltTS=simpleLTFit(lt,startYear,endYear,indexName,true,run_params["maxSegments"]);var joinedTS=getImagesLib.joinCollections(ts,ltTS.select([".*_LT_fitted"]));var ltRawPositiveForChange=multLT(lt,distDir);var lossGainDict=convertToLossGain(ltRawPositiveForChange,"arrayLandTrendr",lossMagThresh,lossSlopeThresh,gainMagThresh,gainSlopeThresh,slowLossDurationThresh,chooseWhichLoss,chooseWhichGain,howManyToPull);var lossGainStack=LTLossGainExportPrep(lossGainDict,indexName,multBy);if(addToMap){addLossGainToMap(lossGainStack,startYear,endYear,(lossMagThresh-0.7)*multBy,lossMagThresh*multBy,gainMagThresh*multBy,(gainMagThresh+0.7)*multBy,indexName,howManyToPull);}
return[multLT(lt,multBy),lossGainStack];}
function prepTimeSeriesForLandTrendr(ts,indexName,run_params){var maxSegments=ee.Number(run_params.maxSegments);var minObservationsNeeded=ee.Number(run_params.minObservationsNeeded);ts=ts.select([indexName]);var distDir=getImagesLib.changeDirDict[indexName];var tsT=ts.map(function(img){return multBands(img,1,distDir);});var countMask=tsT.count().unmask().gte(minObservationsNeeded);tsT=tsT.map(function(img){return nullFinder(img,countMask);});run_params.timeSeries=tsT;var runMask=countMask.rename("insufficientDataMask");var prepDict={run_params:run_params,runMask:runMask,distDir:distDir,};return prepDict;}
function LANDTRENDRVertStack(composites,indexName,run_params,startYear,endYear){var creationDate=ee.Date(Date.now()).format("YYYYMMdd");var prepDict=prepTimeSeriesForLandTrendr(composites,indexName,run_params);run_params=prepDict.run_params;var countMask=prepDict.runMask;var rawLt=ee.Algorithms.TemporalSegmentation.LandTrendr(run_params);var lt=rawLt.select([0]);var ltStack=ee.Image(getLTvertStack(lt,run_params)).updateMask(countMask);ltStack=ltStack.select("yrs.*").addBands(ltStack.select("fit.*"));var rmse=rawLt.select([1]).rename("rmse");ltStack=ltStack.addBands(rmse);ltStack=applyDistDir_vertStack(ltStack,getImagesLib.changeDirDict[indexName],"landtrendr");ltStack=ltStack.set({startYear:startYear,endYear:endYear,band:indexName,creationDate:creationDate,maxSegments:run_params.maxSegments,spikeThreshold:run_params.spikeThreshold,vertexCountOvershoot:run_params.vertexCountOvershoot,recoveryThreshold:run_params.recoveryThreshold,pvalThreshold:run_params.pvalThreshold,bestModelProportion:run_params.bestModelProportion,minObservationsNeeded:run_params.minObservationsNeeded,});return ee.Image(ltStack);}
function LANDTRENDRFitMagSlopeDiffCollection(ts,indexName,run_params){var startYear=ee.Date(ts.first().get("system:time_start")).get("year");var endYear=ee.Date(ts.sort("system:time_start",false).first().get("system:time_start")).get("year");var landtrendrOut=LANDTRENDRVertStack(ts,indexName,run_params,startYear,endYear);var ltStack=ee.Image(landtrendrOut.ltStack);var durFitMagSlope=convertStack_To_DurFitMagSlope(ltStack,"LT");durFitMagSlope=durFitMagSlope.map(function(img){return LT_VT_multBands(img,10000);});durFitMagSlope=durFitMagSlope.map(function(img){return img.int16();});return durFitMagSlope;}
function multiBandLANDTRENDRFitMagSlopeDiffCollection(ts,indexNames,run_params){var startYear=ee.Date(ts.first().get("system:time_start")).get("year");var endYear=ee.Date(ts.sort("system:time_start",false).first().get("system:time_start")).get("year");var landtrendrOut=ee.ImageCollection(indexNames.map(function(indexName){return LANDTRENDRVertStack(ts,indexName,run_params,startYear,endYear);}));var durFitMagSlope=convertStack_To_DurFitMagSlope(landtrendrOut,"LT");return durFitMagSlope;}
function LT_VT_multBands(img,multBy){var fitted=img.select(".*_fitted").multiply(multBy);var slope=img.select(".*_slope").multiply(multBy);var diff=img.select(".*_diff").multiply(multBy);var mag=img.select(".*_mag").multiply(multBy);var dur=img.select(".*_dur");var out=dur.addBands(fitted).addBands(slope).addBands(diff).addBands(mag);out=out.copyProperties(img,["system:time_start"]).copyProperties(img);return ee.Image(out);}
function applyDistDir_vertStack(stack,distDir,verdet_or_landtrendr){var years=stack.select("yrs.*");var fitted=stack.select("fit.*").multiply(distDir);var out=years.addBands(fitted);out=ee.Algorithms.If(ee.String(verdet_or_landtrendr).compareTo("landtrendr").eq(0),out.addBands(stack.select("rmse")),out);out=ee.Image(out);out=out.copyProperties(stack,["system:time_start"]).copyProperties(stack);return ee.Image(out);}
function LT_VT_vertStack_multBands(img,verdet_or_landtrendr,multBy){var years=img.select("yrs.*");var fitted=img.select("fit.*").multiply(multBy);var out=years.addBands(fitted);if(verdet_or_landtrendr=="landtrendr"){var rmse=img.select("rmse").multiply(multBy);out=out.addBands(rmse);}
out=out.copyProperties(img,["system:time_start"]).copyProperties(img);return ee.Image(out);}
function fitStackToCollection(stack,maxSegments,startYear,endYear){var yrDurMagSlope=ee.FeatureCollection(ee.List.sequence(1,maxSegments).map(function(i){i=ee.Number(i);var stringSelectLeft=ee.String(".*_").cat(i.byte().format());var stringSelectRight=ee.String(".*_").cat(i.add(1).byte().format());var stackLeft=stack.select([stringSelectLeft]);var stackRight=stack.select([stringSelectRight]);var segYearsLeft=stackLeft.select(["yrs_.*"]).rename(["year_left"]);var segYearsRight=stackRight.select(["yrs_.*"]).rename(["year_right"]);var segFitLeft=stackLeft.select(["fit_.*"]).rename(["fitted"]);var segFitRight=stackRight.select(["fit_.*"]).rename(["fitted"]);var segDur=segYearsRight.subtract(segYearsLeft).rename(["dur"]);var segMag=segFitRight.subtract(segFitLeft).rename(["mag"]);var segSlope=segMag.divide(segDur).rename(["slope"]);var annualizedCollection=ee.FeatureCollection(ee.List.sequence(startYear,endYear).map(function(yr){yr=ee.Number(yr);var yrImage=ee.Image(yr);yrImage=ee.Algorithms.If(yr.eq(startYear),yrImage.updateMask(segYearsLeft.lte(yr).and(segYearsRight.gte(yr))),yrImage.updateMask(segYearsLeft.lt(yr).and(segYearsRight.gte(yr))));yrImage=ee.Image(yrImage).rename(["yr"]).int16();var yrDur=segDur.updateMask(yrImage);var yrMag=segMag.updateMask(yrImage);var yrSlope=segSlope.updateMask(yrImage);var yrFit=segFitRight.subtract(yrSlope.multiply(segYearsRight.subtract(yr))).updateMask(yrImage);var diffFromLeft=yrFit.subtract(segFitLeft).updateMask(yrImage).rename(["diff"]);var out=yrDur.addBands(yrFit).addBands(yrMag).addBands(yrSlope).addBands(diffFromLeft);out=out.set("system:time_start",ee.Date.fromYMD(yr,6,1).millis());return out;}));return annualizedCollection;}));yrDurMagSlope=ee.ImageCollection(yrDurMagSlope.flatten());var yrDurMagSlopeCleaned=ee.ImageCollection.fromImages(ee.List.sequence(startYear,endYear).map(function(yr){var yrDurMagSlopeT=yrDurMagSlope.filter(ee.Filter.calendarRange(yr,yr,"year")).mosaic();return yrDurMagSlopeT.set("system:time_start",ee.Date.fromYMD(yr,6,1).millis());}));return yrDurMagSlopeCleaned;}
function convertStack_To_DurFitMagSlope(stackCollection,VTorLT){stackCollection=ee.ImageCollection(stackCollection);var stackList=stackCollection.first().bandNames();if(stackList.getInfo().indexOf("rmse")>=0){stackList=stackList.remove("rmse");stackCollection=stackCollection.select(stackList);}
var maxSegments=stackCollection.first().get("maxSegments");var startYear=stackCollection.first().get("startYear");var endYear=stackCollection.first().get("endYear");var indexList=ee.Dictionary(stackCollection.aggregate_histogram("band")).keys().getInfo();var outputCollection;var stack;indexList.map(function(indexName){stack=stackCollection.filter(ee.Filter.eq("band",indexName)).mosaic();var yrDurMagSlopeCleaned=fitStackToCollection(stack,maxSegments,startYear,endYear);var bns=ee.Image(yrDurMagSlopeCleaned.first()).bandNames();var outBns=bns.map(function(bn){return ee.String(indexName).cat("_"+VTorLT+"_").cat(bn);});yrDurMagSlopeCleaned=yrDurMagSlopeCleaned.select(bns,outBns);if(outputCollection===undefined){outputCollection=yrDurMagSlopeCleaned;}else{outputCollection=getImagesLib.joinCollections(outputCollection,yrDurMagSlopeCleaned,false);}});return outputCollection;}
function simpleLTFit(ltStack,startYear,endYear,indexName,arrayMode,maxSegs,multBy){if(indexName===undefined||indexName===null){indexName="";}
if(arrayMode===undefined||arrayMode===null){arrayMode=true;}
if(maxSegs===undefined||maxSegs===null){maxSegs=6;}
multBy=multBy||1;if(arrayMode){ltStack=ltStack.select([0]);var zeros=ee.Image(ee.Array([0]).repeat(0,maxSegs+2));var yrBns=[];var fitBns=[];var emptyArray=[];var iString;for(var i=1;i<maxSegs+2;i++){iString=i.toString();yrBns.push("yrs_"+iString);fitBns.push("fit_"+iString);}
var yrs=ltStack.arraySlice(0,0,1).arrayProject([1]).arrayCat(zeros,0).arraySlice(0,0,maxSegs+1).arrayFlatten([yrBns]).selfMask();var fit=ltStack.arraySlice(0,1,2).arrayProject([1]).arrayCat(zeros,0).arraySlice(0,0,maxSegs+1).arrayFlatten([fitBns]).updateMask(yrs.mask());}else{var yrs=ltStack.select("yrs_.*").selfMask();var fit=ltStack.select("fit_.*").updateMask(yrs.mask());}
fit=fit.multiply(multBy);var isStartYear=yrs.reduce(ee.Reducer.firstNonNull());var isEndYear=yrs.reduce(ee.Reducer.lastNonNull());var blankMask=yrs.gte(100000);var out=ee.ImageCollection(ee.List.sequence(startYear,endYear).map(function(yr){yr=ee.Number(yr);var startYrMask=blankMask;startYrMask=startYrMask.where(isStartYear.eq(yr),yrs.lte(yr));startYrMask=startYrMask.where(isStartYear.lt(yr),yrs.lt(yr));var endYrMask=blankMask;endYrMask=endYrMask.where(isStartYear.eq(yr),yrs.gt(yr));endYrMask=endYrMask.where(isStartYear.lt(yr),yrs.gte(yr));var fitStart=fit.updateMask(startYrMask).reduce(ee.Reducer.lastNonNull());var fitEnd=fit.updateMask(endYrMask).reduce(ee.Reducer.firstNonNull());var yearStart=yrs.updateMask(startYrMask).reduce(ee.Reducer.lastNonNull());var yearEnd=yrs.updateMask(endYrMask).reduce(ee.Reducer.firstNonNull());var segDiff=fitEnd.subtract(fitStart);var segDur=yearEnd.subtract(yearStart);var tDiff=ee.Image(yr).subtract(yearStart);var segSlope=segDiff.divide(segDur);var fitDiff=segSlope.multiply(tDiff);var fitted=fitStart.add(fitDiff);return segDur.addBands(fitted).addBands(segDiff).addBands(segSlope).addBands(fitDiff).rename([indexName+"_LT_dur",indexName+"_LT_fitted",indexName+"_LT_mag",indexName+"_LT_slope",indexName+"_LT_diff",]).set("system:time_start",ee.Date.fromYMD(yr,6,1).millis());}));return out;}
function batchSimpleLTFit(ltStacks,startYear,endYear,indexNames,bandPropertyName,arrayMode,maxSegs,multBy,mosaicReducer){if(bandPropertyName===null||bandPropertyName===undefined){bandPropertyName="band";}
if(indexNames===null||indexNames===undefined){indexNames=ltStacks.aggregate_histogram(bandPropertyName).keys().getInfo();}
arrayMode=arrayMode||true;maxSegs=maxSegs||6;multBy=multBy||1;mosaicReducer=mosaicReducer||ee.Reducer.lastNonNull();var lt_fit;indexNames.map(function(bn){var ltt=ltStacks.filter(ee.Filter.eq(bandPropertyName,bn));var bns=ltt.first().bandNames();ltt=ltt.reduce(mosaicReducer).rename(bns);if(lt_fit===undefined){lt_fit=simpleLTFit(ltt,startYear,endYear,bn,arrayMode,maxSegs,multBy);}else{lt_fit=getImagesLib.joinCollections(lt_fit,simpleLTFit(ltt,startYear,endYear,bn,arrayMode,maxSegs,multBy),false);}});return lt_fit;}
function convertToLossGain(ltStack,format,lossMagThresh,lossSlopeThresh,gainMagThresh,gainSlopeThresh,slowLossDurationThresh,chooseWhichLoss,chooseWhichGain,howManyToPull){if(lossMagThresh===undefined||lossMagThresh===null){lossMagThresh=-0.15;}
if(lossSlopeThresh===undefined||lossSlopeThresh===null){lossSlopeThresh=-0.1;}
if(gainMagThresh===undefined||gainMagThresh===null){gainMagThresh=0.1;}
if(gainSlopeThresh===undefined||gainSlopeThresh===null){gainSlopeThresh=0.1;}
if(slowLossDurationThresh===undefined||slowLossDurationThresh===null){slowLossDurationThresh=3;}
if(chooseWhichLoss===undefined||chooseWhichLoss===null){chooseWhichLoss="largest";}
if(chooseWhichGain===undefined||chooseWhichGain===null){chooseWhichGain="largest";}
if(howManyToPull===undefined||howManyToPull===null){howManyToPull=2;}
if(format===undefined||format===null){format="rawLandTrendr";}
if(format==="rawLandTrendr"){ltStack=simpleRawLTToVertices(ltStack);}
if(format=="rawLandTrendr"||format=="arrayLandTrendr"){ltStack=ltStack.select([0]);print("Converting LandTrendr from array output to Gain & Loss");var left=ltStack.arraySlice(1,0,-1);var right=ltStack.arraySlice(1,1,null);var diff=left.subtract(right);var slopes=diff.arraySlice(0,1,2).divide(diff.arraySlice(0,0,1)).multiply(-1);var duration=diff.arraySlice(0,0,1).multiply(-1);var fittedMag=diff.arraySlice(0,1,2);var forSorting=right.arraySlice(0,0,1).arrayCat(duration,0).arrayCat(fittedMag,0).arrayCat(slopes,0);}else if(format=="vertStack"){print("Converting LandTrendr OR Verdet from vertStack format to Gain & Loss");var baseMask=ltStack.select([0]).mask();var ltStack=ltStack.unmask(255);var yrs=ltStack.select("yrs.*").toArray();var yrMask=yrs.eq(-32768).or(yrs.eq(32767)).or(yrs.eq(0)).not();yrs=yrs.arrayMask(yrMask);var fit=ltStack.select("fit.*").toArray().arrayMask(yrMask);var both=yrs.arrayCat(fit,1).matrixTranspose();var left=both.arraySlice(1,0,-1);var right=both.arraySlice(1,1,null);var diff=left.subtract(right);var fittedMag=diff.arraySlice(0,1,2);var duration=diff.arraySlice(0,0,1).multiply(-1);var slopes=fittedMag.divide(duration);var forSorting=right.arraySlice(0,0,1).arrayCat(duration,0).arrayCat(fittedMag,0).arrayCat(slopes,0);forSorting=forSorting.updateMask(baseMask);}
var magLossMask=forSorting.arraySlice(0,2,3).lte(lossMagThresh);var slopeLossMask=forSorting.arraySlice(0,3,4).lte(lossSlopeThresh);var lossMask=magLossMask.or(slopeLossMask);var magGainMask=forSorting.arraySlice(0,2,3).gte(gainMagThresh);var slopeGainMask=forSorting.arraySlice(0,3,4).gte(gainSlopeThresh);var gainMask=magGainMask.or(slopeGainMask);var forLossSorting=forSorting.arrayMask(lossMask);var forGainSorting=forSorting.arrayMask(gainMask);var lossColumnDict={newest:[0,-1],oldest:[0,1],largest:[2,1],smallest:[2,-1],steepest:[3,1],mostGradual:[3,-1],shortest:[1,1],longest:[1,-1],};var gainColumnDict={newest:[0,-1],oldest:[0,1],largest:[2,-1],smallest:[2,1],steepest:[3,-1],mostGradual:[3,1],shortest:[1,1],longest:[1,-1],};var lossSortValue=lossColumnDict[chooseWhichLoss];var gainSortValue=gainColumnDict[chooseWhichGain];var lossSortBy=forLossSorting.arraySlice(0,lossSortValue[0],lossSortValue[0]+1).multiply(lossSortValue[1]);var gainSortBy=forGainSorting.arraySlice(0,gainSortValue[0],gainSortValue[0]+1).multiply(gainSortValue[1]);var lossAfterForSorting=forLossSorting.arraySort(lossSortBy);var gainAfterForSorting=forGainSorting.arraySort(gainSortBy);var lossStack=getLTStack(lossAfterForSorting,howManyToPull,["loss_yr_","loss_dur_","loss_mag_","loss_slope_",]);var gainStack=getLTStack(gainAfterForSorting,howManyToPull,["gain_yr_","gain_dur_","gain_mag_","gain_slope_",]);var lossGainDict={lossStack:lossStack,gainStack:gainStack};return lossGainDict;}
function replace_mask(img,newimg,nodata){nodata=nodata||0;var mask=img.mask();img=img.unmask(nodata);img=img.where(mask.not(),newimg);img=img.updateMask(img.neq(nodata));return img;}
function addMillisecondsTimeBand(img){var mask=img.mask().reduce(ee.Reducer.min());var time=img.metadata("system:time_start").rename("time").mask(mask);return img.addBands(time);}
function linearInterp(imgcol,frame,nodata){frame=frame||32;nodata=nodata||0;var bns=ee.Image(imgcol.first()).bandNames();var time="system:time_start";imgcol=imgcol.map(addMillisecondsTimeBand);var maxDiff=ee.Filter.maxDifference(frame*(1000*60*60*24),time,null,time);var cond={leftField:time,rightField:time};var f1=ee.Filter.and(maxDiff,ee.Filter.lessThanOrEquals(cond));var c1=ee.Join.saveAll({matchesKey:"after",ordering:time,ascending:false,}).apply(imgcol,imgcol,f1);var f2=ee.Filter.and(maxDiff,ee.Filter.greaterThanOrEquals(cond));var c2=ee.Join.saveAll({matchesKey:"before",ordering:time,ascending:true,}).apply(c1,imgcol,f2);var interpolated=ee.ImageCollection(c2.map(function(img){img=ee.Image(img);var before=ee.ImageCollection.fromImages(ee.List(img.get("before"))).mosaic();var after=ee.ImageCollection.fromImages(ee.List(img.get("after"))).mosaic();img=img.set("before",null).set("after",null);before=replace_mask(before,after,nodata);after=replace_mask(after,before,nodata);var x1=before.select("time").double();var x2=after.select("time").double();var now=ee.Image.constant(img.date().millis()).double();var ratio=now.subtract(x1).divide(x2.subtract(x1));before=before.select(bns);after=after.select(bns);img=img.select(bns);var interp=after.subtract(before).multiply(ratio).add(before);var qc=img.mask().not();interp=replace_mask(img,interp,nodata);return interp.copyProperties(img,img.propertyNames());}));return interpolated;}
function applyLinearInterp(composites,nYearsInterpolate){composites=composites.select(["red","green","blue","nir","swir1","swir2",]);var masks=composites.map(function(img){return img.mask().reduce(ee.Reducer.min()).byte().copyProperties(img,img.propertyNames());}).select([0]);masks=masks.map(function(img){return img.rename([ee.Date(img.get("system:time_start")).format("YYYY")]);});masks=masks.toBands();var origNames=masks.bandNames();var newNames=origNames.map(function(bandName){return ee.String(bandName).replace("null","mask");});masks=masks.select(origNames,newNames).set("creationDate",ee.Date(Date.now()).format("YYYYMMdd")).set("mask",true);composites=linearInterp(composites,365*nYearsInterpolate,-32768).map(getImagesLib.simpleAddIndices).map(getImagesLib.getTasseledCap).map(getImagesLib.simpleAddTCAngles);var outDict={composites:composites,masks:masks};return outDict;}
function applyVerdetScaling(ts,indexName,correctionFactor){var distDir=getImagesLib.changeDirDict[indexName];var tsT=ts.map(function(img){return ee.Image(multBands(img,1,-distDir));});tsT=tsT.map(function(img){return ee.Image(addToImage(img,1));});tsT=tsT.map(function(img){return ee.Image(multBands(img,1,correctionFactor));});return tsT;}
function undoVerdetScaling(fitted,indexName,correctionFactor){var distDir=getImagesLib.changeDirDict[indexName];fitted=ee.Image(multBands(fitted,1,1.0/correctionFactor));fitted=ee.Image(addToImage(fitted,-1));fitted=ee.Image(multBands(fitted,1,-distDir));return fitted;}
function updateVerdetMasks(img,linearInterpMasks){var thisYear=ee.Date(img.get("system:time_start")).format("YYYY");var thisYear_maskName=ee.String(".*_").cat(thisYear);var thisMask=linearInterpMasks.select(thisYear_maskName);img=img.updateMask(thisMask);return img;}
function prepTimeSeriesForVerdet(ts,indexName,run_params,correctionFactor){var startYear=ee.Date(ts.first().get("system:time_start")).get("year");var endYear=ee.Date(ts.sort("system:time_start",false).first().get("system:time_start")).get("year");ts=ts.select([indexName]);var tsT=applyVerdetScaling(ts,indexName,correctionFactor);var countMask=tsT.count().unmask().gte(endYear.subtract(startYear).add(1));tsT=tsT.map(function(img){return nullFinder(img,countMask);});run_params.timeSeries=tsT;countMask=countMask.rename("insufficientDataMask");var prepDict={run_params:run_params,countMask:countMask,startYear:startYear,endYear:endYear,};return prepDict;}
function VERDETVertStack(ts,indexName,run_params,maxSegments,correctionFactor,doLinearInterp){if(!run_params){run_params={tolerance:0.0001,alpha:0.1};}
if(!maxSegments){maxSegments=10;}
if(!correctionFactor){correctionFactor=1;}
if(!doLinearInterp){doLinearInterp=false;}
var creationDate=ee.Date(Date.now()).format("YYYYMMdd");var prepDict=prepTimeSeriesForVerdet(ts,indexName,run_params,correctionFactor);run_params=prepDict.run_params;var countMask=prepDict.countMask;var startYear=prepDict.startYear;var endYear=prepDict.endYear;var verdet=ee.Algorithms.TemporalSegmentation.Verdet(run_params).arraySlice(0,1,null);var tsYearRight=ee.Image(ee.Array.cat([ee.Array([startYear]),ee.Array(ee.List.sequence(startYear.add(2),endYear)),]));var vLeft=verdet.arraySlice(0,1,-1);var vRight=verdet.arraySlice(0,2,null);var vCurvature=vLeft.subtract(vRight);var vVertices=vCurvature.abs().gte(0.00001);vVertices=ee.Image(ee.Array([1])).arrayCat(vVertices,0).arrayCat(ee.Image(ee.Array([1])),0);tsYearRight=tsYearRight.arrayMask(vVertices);var dur=tsYearRight.arraySlice(0,1,null).subtract(tsYearRight.arraySlice(0,0,-1));dur=ee.Image(ee.Array([0])).arrayCat(dur,0);verdet=verdet.arrayMask(vVertices);var mag=verdet.multiply(dur);var fitted=ee.Image(run_params.timeSeries.limit(3).mean()).toArray().arrayCat(mag,0);fitted=fitted.arrayAccum(0,ee.Reducer.sum()).arraySlice(0,1,null);fitted=undoVerdetScaling(fitted,indexName,correctionFactor);var forStack=tsYearRight.addBands(fitted).toArray(1);var stack=getLTStack(forStack.arrayTranspose(),maxSegments+1,["yrs_","fit_",]).updateMask(countMask);stack=stack.set({startYear:startYear,endYear:endYear,band:indexName,creationDate:creationDate,maxSegments:maxSegments,correctionFactor:correctionFactor,tolerance:run_params.tolerance,alpha:run_params.alpha,linearInterpApplied:doLinearInterp,});return ee.Image(stack);}
function VERDETFitMagSlopeDiffCollection(composites,indexName,run_params,maxSegments,correctionFactor,doLinearInterp,masks){if(doLinearInterp===null||doLinearInterp===undefined){doLinearInterp=false;}
var vtStack=VERDETVertStack(composites,indexName,run_params,maxSegments,correctionFactor,doLinearInterp);var durFitMagSlope=convertStack_To_DurFitMagSlope(vtStack,"VT");durFitMagSlope=durFitMagSlope.map(function(img){return LT_VT_multBands(img,10000);});durFitMagSlope=durFitMagSlope.map(function(img){return img.int16();});if(doLinearInterp===true){durFitMagSlope=durFitMagSlope.map(function(img){var thisYear=ee.Date(img.get("system:time_start")).format("YYYY");var thisMask=masks.select(ee.String(".*_").cat(thisYear));img=img.updateMask(thisMask);return img;});}
return durFitMagSlope;}
function verdetAnnualSlope(tsIndex,indexName,startYear,endYear,alpha,tolerance){var verdet=ee.Algorithms.TemporalSegmentation.Verdet({timeSeries:tsIndex,tolerance:tolerance,alpha:alpha,}).arraySlice(0,1,null);print("indexName",indexName);print("verdet",verdet);Map.addLayer(verdet,{},"verdet "+indexName);var tsYear=tsIndex.map(getImagesLib.addYearBand).select([1]).toArray().arraySlice(0,1,null).arrayProject([0]);var possibleYears=ee.List.sequence(startYear,endYear);print("possibleYears",possibleYears);print("tsYear",tsYear);var verdetC=arrayToTimeSeries(verdet,tsYear,possibleYears,"VERDET_fitted_"+indexName+"_slope");return verdetC;}
function getEWMA(lsIndex,trainingStartYear,trainingEndYear,harmonicCount){if(harmonicCount===null||harmonicCount===undefined){harmonicCount=1;}
var ewmacd=ee.Algorithms.TemporalSegmentation.Ewmacd({timeSeries:lsIndex,vegetationThreshold:-1,trainingStartYear:trainingStartYear,trainingEndYear:trainingEndYear,harmonicCount:harmonicCount,});var ewma=ewmacd.select(["ewma"]);return ewma;}
function annualizeEWMA(ewma,indexName,lsYear,startYear,endYear,annualReducer,remove2012){if(annualReducer===null||annualReducer===undefined){annualReducer=ee.Reducer.min();}
if(remove2012===null||remove2012===undefined){remove2012=true;}
var years=ee.List.sequence(startYear,endYear);var replace2012=ee.Number(ee.List([years.indexOf(2011),years.indexOf(2012),years.indexOf(2013)]).reduce(ee.Reducer.min())).neq(-1).getInfo();print("2012 needs replaced:",replace2012);if(remove2012){years=years.removeAll([2012]);}
var noDateValue=-32768;var dummyImage=ee.Image(noDateValue).toArray();var annualEWMA=years.map(function(yr){yr=ee.Number(yr);var yrMask=lsYear.int16().eq(yr);var ewmacdYr=ewma.arrayMask(yrMask);var ewmacdYearYr=lsYear.arrayMask(yrMask);var ewmacdYrSorted=ewmacdYr.arraySort(ewmacdYr);var ewmacdYearYrSorted=ewmacdYearYr.arraySort(ewmacdYr);var yrData=ewmacdYrSorted.arrayCat(ewmacdYearYrSorted,1);var yrReduced=ewmacdYrSorted.arrayReduce(annualReducer,[0]);var l=yrReduced.arrayLength(0);yrReduced=yrReduced.where(l.eq(0),dummyImage).arrayGet([-1]);yrReduced=yrReduced.updateMask(yrReduced.neq(noDateValue)).rename(["EWMA_"+indexName]).set("system:time_start",ee.Date.fromYMD(yr,6,1).millis()).int16();return yrReduced;});annualEWMA=ee.ImageCollection.fromImages(annualEWMA);if(remove2012&&replace2012==1){print("Replacing EWMA 2012 with mean of 2011 and 2013");var value2011=ee.Image(annualEWMA.filter(ee.Filter.calendarRange(2011,2011,"year")).first());var value2013=ee.Image(annualEWMA.filter(ee.Filter.calendarRange(2013,2013,"year")).first());var value2012=value2013.add(value2011);value2012=value2012.divide(2).rename(["EWMA_"+indexName]).set("system:time_start",ee.Date.fromYMD(2012,6,1).millis()).int16();annualEWMA=ee.ImageCollection(ee.FeatureCollection([annualEWMA,ee.ImageCollection([value2012])]).flatten()).sort("system:time_start");}
return annualEWMA;}
function runEWMACD(lsIndex,indexName,startYear,endYear,trainingStartYear,trainingEndYear,harmonicCount,annualReducer,remove2012){var ewma=getEWMA(lsIndex,trainingStartYear,trainingEndYear,harmonicCount);var lsYear=lsIndex.map(function(img){return getImagesLib.addDateBand(img,true);}).select(["year"]).toArray().arrayProject([0]);var annualEWMA=annualizeEWMA(ewma,indexName,lsYear,startYear,endYear,annualReducer,remove2012);return[ewma.arrayCat(lsYear,1),annualEWMA];}
function CCDCFitMagSlopeCollection(ccdc_output,studyArea){var startYear=ee.Number.parse(ccdc_output.first().get("startYear"));var endYear=ee.Number.parse(ccdc_output.first().get("endYear"));var maxSegments=ee.Number.parse(ccdc_output.first().get("nSegments"));var create_date=ccdc_output.first().get("create_date");var bandNames=ee.List(["blue","green","red","nir","swir1","temp","swir2",]);var ccdc_raw=ccdc_output.filterBounds(studyArea).mosaic().clip(studyArea);var yrDurMagSlope=ee.FeatureCollection(ee.List.sequence(1,maxSegments).map(function(i){i=ee.Number(i);var stringSelect=ee.String("S").cat(i.byte().format());var segAll=ccdc_raw.select([stringSelect.cat("_.*")]);var segStartDay=segAll.select([stringSelect.cat("_tStart")]).rename(["startDay"]);var segEndDay=segAll.select([stringSelect.cat("_tEnd")]).rename(["endDay"]);var segBreakDay=segAll.select([stringSelect.cat("_tBreak")]).rename(["breakDay"]);var effEndDay=segEndDay.max(segBreakDay).rename(["effEndDay"]);var segDur=effEndDay.subtract(segStartDay).divide(365).rename(["CCDC_dur"]);var segChangeProb=segAll.select([stringSelect.cat("_changeProb")]).rename(["changeProb"]);var segBands=ee.ImageCollection(ee.List.sequence(1,7).map(function(bandNum){bandNum=ee.Number(bandNum).int();var thisBand=ee.String(bandNames.get(bandNum.subtract(1)));var bandString=ee.String("_B").cat(bandNum.format());var segSlope=segAll.select([stringSelect.cat(bandString.cat("_coef_SLP"))]).rename(["slope"]);var segIntp=segAll.select([stringSelect.cat(bandString.cat("_coef_INTP"))]).rename(["intercept"]);var segMag=segSlope.multiply(segDur).rename(["mag"]);return segSlope.addBands(segIntp).addBands(segMag).set("system:index",thisBand);}));var output=ee.FeatureCollection(ee.List.sequence(startYear,endYear).map(function(yr){yr=ee.Number(yr).int();var cutoffday=ee.Date.parse("yyyy-D",yr.format().cat("-250")).difference(ee.Date.fromYMD(0,1,1),"day");var lastYrCutoffday=ee.Date.parse("yyyy-D",yr.subtract(1).format().cat("-250")).difference(ee.Date.fromYMD(0,1,1),"day");var yearDay=ee.Date.fromYMD(yr,6,1).difference(ee.Date.fromYMD(0,1,1),"day");var yrImage=ee.Image(yr).rename(["yr"]).int16();var yrMask=segStartDay.lt(cutoffday).and(segEndDay.gte(lastYrCutoffday));var yrBands=ee.ImageCollection(segBands.map(function(band){var yrSlope=ee.Image(band.select([".*slope"])).rename(["CCDC_slope"]);var yrIntp=ee.Image(band.select([".*intercept"])).rename(["CCDC_intercept"]);var yrMag=ee.Image(band.select([".*mag"])).rename(["CCDC_mag"]);var yrFit=yrSlope.multiply(yearDay).add(yrIntp).rename(["CCDC_fitted"]);var yrDur=segDur.rename(["CCDC_dur"]);return yrSlope.addBands(yrIntp).addBands(yrMag).addBands(yrFit).addBands(yrDur).updateMask(yrMask);})).toBands();yrBands=ee.Image(multBands(yrBands,1,0.0001));var yrDur=segDur.updateMask(yrMask);var yrProb=segChangeProb.updateMask(yrMask);var yrSegStart=segStartDay.updateMask(yrMask);var yrSegEnd=segEndDay.updateMask(yrMask);var yrSegBreak=segBreakDay.updateMask(yrMask);var yrEffEnd=effEndDay.updateMask(yrMask);var out=yrBands;return out.set("system:time_start",ee.Date.fromYMD(yr,6,1).millis()).set("year",yr);}));return output;}));yrDurMagSlope=ee.ImageCollection(yrDurMagSlope.flatten());var ccdc=ee.ImageCollection.fromImages(ee.List.sequence(startYear,endYear).map(function(yr){var yrDurMagSlopeT=yrDurMagSlope.filter(ee.Filter.calendarRange(yr,yr,"year")).mosaic();return yrDurMagSlopeT.set("system:time_start",ee.Date.fromYMD(yr,6,1).millis()).set("create_date",create_date).set("startYear",startYear).set("endYear",endYear).set("nSegments",maxSegments);}));return ccdc;}
function pairwiseSlope(c){c=c.sort("system:time_start");var bandNames=ee.Image(c.first()).bandNames();var years=c.toList(10000).map(function(i){i=ee.Image(i);return ee.Date(i.get("system:time_start")).get("year");});var yearsLeft=years.slice(0,-1);var yearsRight=years.slice(1,null);var yearPairs=yearsLeft.zip(yearsRight);var slopeCollection=yearPairs.map(function(yp){yp=ee.List(yp);var yl=ee.Number(yp.get(0));var yr=ee.Number(yp.get(1));var yd=yr.subtract(yl);var l=ee.Image(c.filter(ee.Filter.calendarRange(yl,yl,"year")).first()).add(0.000001);var r=ee.Image(c.filter(ee.Filter.calendarRange(yr,yr,"year")).first());var slope=r.subtract(l).rename(bandNames);slope=slope.set("system:time_start",ee.Date.fromYMD(yr,6,1).millis());return slope;});return ee.ImageCollection.fromImages(slopeCollection);}
function toAnnualMedian(images,startYear,endYear){var dummyImmage=ee.Image(images.first());var out=ee.List.sequence(startYear,endYear).map(function(yr){var imagesT=images.filter(ee.Filter.calendarRange(yr,yr,"year"));imagesT=getImagesLib.fillEmptyCollections(imagesT,dummyImmage);return imagesT.median().set("system:time_start",ee.Date.fromYMD(yr,6,1));});return ee.ImageCollection.fromImages(out);}
function predictModel(c,model,bandNames){var intercepts=model.select("intercept_.*");var slopes=model.select("slope_.*");if(bandNames===null||bandNames===undefined){bandNames=slopes.bandNames().map(function(bn){return ee.String(bn).split("_").get(1);});}
var predictedBandNames=bandNames.map(function(bn){return ee.String(bn).cat("_trend");});var predicted=c.map(function(img){var cActual=img.select(bandNames);var out=img.select(["year"]).multiply(slopes).add(img.select(["constant"]).multiply(intercepts)).rename(predictedBandNames);return cActual.addBands(out).copyProperties(img,["system:time_start"]);});return predicted;}
function getLinearFit(c,bandNames){if(bandNames===null||bandNames===undefined){bandNames=ee.Image(c.first()).bandNames();}else{bandNames=ee.List(bandNames);c=c.select(bandNames);}
c=c.map(function(img){return img.addBands(ee.Image(1));});c=c.map(getImagesLib.addDateBand);var selectOrder=ee.List([["constant","year"],bandNames]).flatten();var model=c.select(selectOrder).reduce(ee.Reducer.linearRegression(2,bandNames.length())).select([0]);model=model.arrayTranspose().arrayFlatten([bandNames,["intercept","slope"]]);var predicted=predictModel(c,model,bandNames);return[model,predicted];}
function zAndTrendChangeDetection(allScenes,indexNames,nDays,startYear,endYear,startJulian,endJulian,baselineLength,baselineGap,epochLength,zReducer,useAnnualMedianForTrend,exportImages,exportPathRoot,studyArea,scale,crs,transform,minBaselineObservationsNeeded){if(minBaselineObservationsNeeded===null||minBaselineObservationsNeeded===undefined){minBaselineObservationsNeeded=30;}
allScenes=allScenes.select(indexNames);var dummyScene=ee.Image(allScenes.first());var outNames=indexNames.map(function(bn){return ee.String(bn).cat("_Z");});var analysisStartYear=Math.max(startYear+baselineLength+baselineGap,startYear+epochLength-1);var years=ee.List.sequence(analysisStartYear,endYear,1).getInfo();var julians=ee.List.sequence(startJulian,endJulian-nDays,nDays).getInfo();var zAndTrendCollection=years.map(function(yr){yr=ee.Number(yr);var blStartYear=yr.subtract(baselineLength).subtract(baselineGap);var blEndYear=yr.subtract(1).subtract(baselineGap);var trendStartYear=yr.subtract(epochLength).add(1);return ee.FeatureCollection(julians.map(function(jd){jd=ee.Number(jd);var jdStart=jd;var jdEnd=jd.add(nDays);var blImages=allScenes.filter(ee.Filter.calendarRange(blStartYear,blEndYear,"year")).filter(ee.Filter.calendarRange(jdStart,jdEnd));blImages=getImagesLib.fillEmptyCollections(blImages,dummyScene);var blCounts=blImages.count();blImages=blImages.map(function(img){return img.updateMask(blCounts.gte(minBaselineObservationsNeeded));});var analysisImages=allScenes.filter(ee.Filter.calendarRange(yr,yr,"year")).filter(ee.Filter.calendarRange(jdStart,jdEnd));analysisImages=getImagesLib.fillEmptyCollections(analysisImages,dummyScene);var trendImages=allScenes.filter(ee.Filter.calendarRange(trendStartYear,yr,"year")).filter(ee.Filter.calendarRange(jdStart,jdEnd));trendImages=getImagesLib.fillEmptyCollections(trendImages,dummyScene);if(useAnnualMedianForTrend){trendImages=toAnnualMedian(trendImages,trendStartYear,yr);}
var linearTrend=getLinearFit(trendImages,indexNames);var linearTrendModel=ee.Image(linearTrend[0]).select([".*_slope"]).multiply(10000);var blMean=blImages.mean();var blStd=blImages.reduce(ee.Reducer.stdDev());var analysisImagesZ=analysisImages.map(function(img){return img.subtract(blMean).divide(blStd);}).reduce(zReducer).rename(outNames).multiply(10);var outName=ee.String("Z_and_Trend_b").cat(ee.String(blStartYear.int16())).cat(ee.String("_")).cat(ee.String(blEndYear.int16())).cat(ee.String("_epoch")).cat(ee.String(ee.Number(epochLength))).cat(ee.String("_y")).cat(ee.String(yr.int16())).cat(ee.String("_jd")).cat(ee.String(jdStart.int16())).cat(ee.String("_")).cat(ee.String(jdEnd.int16()));var imageStartDate=ee.Date.fromYMD(yr,1,1).advance(jdStart,"day").millis();var out=analysisImagesZ.addBands(linearTrendModel).int16().set({"system:time_start":imageStartDate,"system:time_end":ee.Date.fromYMD(yr,1,1).advance(jdEnd,"day").millis(),baselineYrs:baselineLength,baselineStartYear:blStartYear,baselineEndYear:blEndYear,epochLength:epochLength,trendStartYear:trendStartYear,year:yr,startJulian:jdStart,endJulian:jdEnd,"system:index":outName,});if(exportImages){outName=outName.getInfo();var outPath=exportPathRoot+"/"+outName;getImagesLib.exportToAssetWrapper(out.clip(studyArea),outName,outPath,"mean",studyArea.bounds(),scale,crs,transform);}
return out;}));});zAndTrendCollection=ee.ImageCollection(ee.FeatureCollection(zAndTrendCollection).flatten());return zAndTrendCollection;}
function thresholdZAndTrend(zAndTrendCollection,zThresh,slopeThresh,startYear,endYear,negativeOrPositiveChange){if(negativeOrPositiveChange===null||negativeOrPositiveChange===undefined){negativeOrPositiveChange="negative";}
var dir;if(negativeOrPositiveChange==="negative"){dir=-1;}else{dir=1;}
zAndTrendCollection=zAndTrendCollection.filter(ee.Filter.calendarRange(startYear,endYear,"year"));var zCollection=zAndTrendCollection.select(".*_Z");var trendCollection=zAndTrendCollection.select(".*_slope");var zChange=thresholdChange(zCollection,-zThresh,dir).select(".*_change");var trendChange=thresholdChange(trendCollection,-slopeThresh,dir).select(".*_change");Map.addLayer(zChange.max().select([0]),{min:startYear,max:endYear,palette:"FF0,F00"},"Z Most Recent Change Year "+negativeOrPositiveChange,true);Map.addLayer(trendChange.max().select([0]),{min:startYear,max:endYear,palette:"FF0,F00"},"Trend Most Recent Change Year "+negativeOrPositiveChange,false);return{zChange:zChange,trendChange:trendChange};}
function thresholdZAndTrendSubtle(zAndTrendCollection,zThreshLow,zThreshHigh,slopeThreshLow,slopeThreshHigh,startYear,endYear,negativeOrPositiveChange){if(negativeOrPositiveChange===null||negativeOrPositiveChange===undefined){negativeOrPositiveChange="negative";}
var dir;var colorRamp;if(negativeOrPositiveChange==="negative"){dir=-1;colorRamp="FF0,F00";}else{dir=1;colorRamp="BBB,080";}
var zCollection=zAndTrendCollection.select(".*_Z");var trendCollection=zAndTrendCollection.select(".*_slope");var zChange=thresholdSubtleChange(zCollection,-zThreshLow,-zThreshHigh,dir).select(".*_change");var trendChange=thresholdSubtleChange(trendCollection,-slopeThreshLow,-slopeThreshHigh,dir).select(".*_change");Map.addLayer(zChange.max().select([0]),{min:startYear,max:endYear,palette:colorRamp},"Z Most Recent Change Year "+negativeOrPositiveChange,false);Map.addLayer(trendChange.max().select([0]),{min:startYear,max:endYear,palette:colorRamp},"Trend Most Recent Change Year "+negativeOrPositiveChange,false);}
function simpleCCDCPrediction(img,timeBandName,whichHarmonics,whichBands){var omega=ee.Number(2.0).multiply(Math.PI);var tBand=img.select([timeBandName]);var intercepts=img.select([".*_INTP"]);var slopes=img.select([".*_SLP"]).multiply(tBand);var tOmega=ee.Image(whichHarmonics).multiply(omega).multiply(tBand);var cosHarm=tOmega.cos();var sinHarm=tOmega.sin();var harmSelect=whichHarmonics.map(function(n){return ee.String(".*").cat(ee.Number(n).format());});var sins=img.select([".*_SIN.*"]);sins=sins.select(harmSelect);var coss=img.select([".*_COS.*"]);coss=coss.select(harmSelect);var outBns=whichBands.map(function(bn){return ee.String(bn).cat("_CCDC_fitted");});var predicted=ee.ImageCollection(whichBands.map(function(bn){bn=ee.String(bn);return ee.Image([intercepts.select(bn.cat("_.*")),slopes.select(bn.cat("_.*")),sins.select(bn.cat("_.*")).multiply(sinHarm),coss.select(bn.cat("_.*")).multiply(cosHarm),]).reduce(ee.Reducer.sum());})).toBands().rename(outBns);return img.addBands(predicted);}
function simpleCCDCPredictionWrapper(c,timeBandName,whichHarmonics){var whichBands=ee.Image(c.first()).select([".*_INTP"]).bandNames().map(function(bn){return ee.String(bn).split("_").get(0);});whichBands=ee.Dictionary(whichBands.reduce(ee.Reducer.frequencyHistogram())).keys().getInfo();var out=c.map(function(img){return simpleCCDCPrediction(img,timeBandName,whichHarmonics,whichBands);});return out;}
function getCCDCSegCoeffs(timeImg,ccdcImg,fillGaps){var coeffKeys=[".*_coefs"];var tStartKeys=["tStart"];var tEndKeys=["tEnd"];var tBreakKeys=["tBreak"];var coeffs=ccdcImg.select(coeffKeys);var bns=coeffs.bandNames();var nBns=bns.length();var harmonicTag=ee.List(["INTP","SLP","COS1","SIN1","COS2","SIN2","COS3","SIN3",]);coeffs=coeffs.toArray(2);var tStarts=ccdcImg.select(tStartKeys);var tEnds=ccdcImg.select(tEndKeys);var tBreaks=ccdcImg.select(tBreakKeys);tStarts=ee.Image(ee.Algorithms.If(fillGaps,tStarts.arraySlice(0,0,1).arrayCat(tBreaks.arraySlice(0,0,-1),0),tStarts));tEnds=ee.Image(ee.Algorithms.If(fillGaps,tBreaks.arraySlice(0,0,-1).arrayCat(tEnds.arraySlice(0,-1,null),0),tEnds));var tMask=tStarts.lt(timeImg).and(tEnds.gte(timeImg)).arrayRepeat(1,1).arrayRepeat(2,1);coeffs=coeffs.arrayMask(tMask).arrayProject([2,1]).arrayTranspose(1,0).arrayFlatten([bns,harmonicTag]);coeffs=coeffs.updateMask(coeffs.reduce(ee.Reducer.max()).neq(0));return timeImg.addBands(coeffs);}
function annualizeCCDC(ccdcImg,startYear,endYear,startJulian,endJulian,tEndExtrapolationPeriod,yearStartMonth,yearStartDay,annualizeWithCompositeDates,compositeCollection){if(annualizeWithCompositeDates===undefined||annualizeWithCompositeDates===null){annualizeWithCompositeDates=false;}
var timeImgs;if(annualizeWithCompositeDates===true){timeImgs=getTimeImageCollectionFromComposites(startJulian,endJulian,compositeCollection);}else{timeImgs=getTimeImageCollection(startYear,endYear,startJulian,endJulian,1,yearStartMonth,yearStartDay);}
var finalTEnd=ccdcImg.select("tEnd");finalTEnd=finalTEnd.arraySlice(0,-1,null).rename("tEnd").arrayGet(0).add(tEndExtrapolationPeriod).toArray(0);var tEnds=ccdcImg.select("tEnd");tEnds=tEnds.arraySlice(0,0,-1).arrayCat(finalTEnd,0).rename("tEnd");var keepBands=ccdcImg.bandNames().remove("tEnd");ccdcImg=ccdcImg.select(keepBands).addBands(tEnds);var annualSegCoeffs=timeImgs.map(function(img){return getCCDCSegCoeffs(img,ccdcImg,true);});return annualSegCoeffs;}
function getFitSlopeCCDC(annualSegCoeffs,startYear,endYear){var whichBands=ee.Image(annualSegCoeffs.first()).select([".*_INTP"]).bandNames().map(function(bn){return ee.String(bn).split("_").get(0);});whichBands=ee.Dictionary(whichBands.reduce(ee.Reducer.frequencyHistogram())).keys().getInfo();var fitted=annualSegCoeffs.map(function(img){return simpleCCDCPredictionAnnualized(img,"year",whichBands);});var diff=ee.ImageCollection(ee.List.sequence(ee.Number(startYear).add(1),endYear).map(function(rightYear){var leftYear=ee.Number(rightYear).subtract(1);var rightFitted=ee.Image(fitted.filter(ee.Filter.calendarRange(rightYear,rightYear,"year")).first());var leftFitted=ee.Image(fitted.filter(ee.Filter.calendarRange(leftYear,leftYear,"year")).first());var slopeNames=rightFitted.select([".*_fitted"]).bandNames().map(function(name){return ee.String(ee.String(name).split("_fitted").get(0)).cat(ee.String("_fitSlope"));});var slope=rightFitted.select([".*_fitted"]).subtract(leftFitted.select([".*_fitted"])).rename(slopeNames);return rightFitted.addBands(slope);}));var bandNames=diff.first().bandNames();var newBandNames=bandNames.map(function(name){return ee.String(name).replace("coefs","CCDC");});diff=diff.select(bandNames,newBandNames);return diff;}
function simpleCCDCPredictionAnnualized(img,timeBandName,whichBands){var tBand=img.select([timeBandName]);var intercepts=img.select([".*_INTP"]);var slopes=img.select([".*_SLP"]).multiply(tBand);var outBns=whichBands.map(function(bn){return ee.String(bn).cat("_CCDC_fitted");});var predicted=ee.ImageCollection(whichBands.map(function(bn){bn=ee.String(bn);return ee.Image([intercepts.select(bn.cat("_.*")),slopes.select(bn.cat("_.*")),]).reduce(ee.Reducer.sum());})).toBands().rename(outBns);return img.addBands(predicted);}
function predictCCDC(ccdcImg,timeImgs,fillGaps,whichHarmonics){var timeBandName=ee.Image(timeImgs.first()).select([0]).bandNames().get(0);timeImgs=timeImgs.map(function(img){return getCCDCSegCoeffs(img,ccdcImg,fillGaps);});return simpleCCDCPredictionWrapper(timeImgs,timeBandName,whichHarmonics);}
function simpleGetTimeImageCollection(startYear,endYear,step){var yearImages=ee.ImageCollection(ee.List.sequence(startYear,endYear,step).map(function(n){n=ee.Number(n);var img=ee.Image(n).float().rename(["year"]);var y=n.int16();var fraction=n.subtract(y);var d=ee.Date.fromYMD(y,1,1).advance(fraction,"year").millis();return img.set("system:time_start",d);}));return yearImages;}
function getTimeImageCollection(startYear,endYear,startJulian,endJulian,step,yearStartMonth,yearStartDay){if(startJulian===undefined||startJulian===null){startJulian=1;}
if(endJulian===undefined||endJulian===null){endJulian=365;}
if(step===undefined||step===null){step=0.1;}
if(yearStartMonth===undefined||yearStartMonth===null){yearStartMonth=1;}
if(yearStartDay===undefined||yearStartDay===null){yearStartDay=1;}
var monthDayFraction=ee.Number.parse(ee.Date.fromYMD(startYear,yearStartMonth,yearStartDay).format("DDD")).divide(365);var yearImages=ee.ImageCollection(ee.List.sequence(ee.Number(startYear).add(monthDayFraction),ee.Number(endYear).add(monthDayFraction),step).map(function(n){n=ee.Number(n);var img=ee.Image(n).float().rename(["year"]);var y=n.int16();var fraction=n.subtract(y);var d=ee.Date.fromYMD(y.subtract(ee.Number(1)),12,31).advance(fraction,"year").millis();return img.set("system:time_start",d);}));return yearImages.filter(ee.Filter.calendarRange(startYear,endYear,"year")).filter(ee.Filter.calendarRange(startJulian,endJulian));}
function getTimeImageCollectionFromComposites(startJulian,endJulian,compositeCollection){var medianFraction=compositeCollection.select("julianDay").map(function(jDay){var fraction=jDay.divide(365);var nextYearMask=jDay.lte(ee.Image.constant(startJulian));var thisYearMask=nextYearMask.not();var nextYearFraction=fraction.updateMask(nextYearMask).add(1);var thisYearFraction=fraction.updateMask(thisYearMask);fraction=nextYearFraction.addBands(thisYearFraction).reduce(ee.Reducer.max());return fraction;}).reduce(ee.Reducer.median());var yearImages=compositeCollection.map(function(dateImg){var newDateImg=ee.Image(dateImg.select("year").add(dateImg.select("julianDay").divide(365))).copyProperties(dateImg,["system:time_start"]);var imgYear=dateImg.date().get("year");var medianValues=ee.Image.constant(imgYear).float().add(ee.Image(medianFraction)).rename("median_values");var compositeMask=ee.Image(newDateImg).mask();var out=ee.Image(newDateImg).addBands(medianValues.updateMask(compositeMask.not())).reduce(ee.Reducer.max()).rename("year").copyProperties(dateImg,["system:time_start"]);return out;});return yearImages;}
function ccdcChangeDetection(ccdcImg,bandName){var magKeys=[".*_magnitude"];var tBreakKeys=["tBreak"];var changeProbKeys=["changeProb"];var changeProbThresh=1;var magnitudes=ccdcImg.select(magKeys);var breaks=ccdcImg.select(tBreakKeys);var changeProbs=ccdcImg.select(changeProbKeys);print(changeProbs,"changeProbs");var changeMask=changeProbs.gte(changeProbThresh);magnitudes=magnitudes.select(bandName+".*");var breaksSortedByMag=breaks.arraySort(magnitudes);var magnitudesSortedByMag=magnitudes.arraySort();var changeMaskSortedByMag=changeMask.arraySort(magnitudes);var breaksSortedByYear=breaks.arraySort();var magnitudesSortedByYear=magnitudes.arraySort(breaks);var changeMaskSortedByYear=changeMask.arraySort(breaks);var highestMagLossYear=breaksSortedByMag.arraySlice(0,0,1).arrayFlatten([["loss_year"]]);var highestMagLossMag=magnitudesSortedByMag.arraySlice(0,0,1).arrayFlatten([["loss_mag"]]);var highestMagLossMask=changeMaskSortedByMag.arraySlice(0,0,1).arrayFlatten([["loss_mask"]]);highestMagLossYear=highestMagLossYear.updateMask(highestMagLossMag.lt(0).and(highestMagLossMask));highestMagLossMag=highestMagLossMag.updateMask(highestMagLossMag.lt(0).and(highestMagLossMask));var highestMagGainYear=breaksSortedByMag.arraySlice(0,-1,null).arrayFlatten([["gain_year"]]);var highestMagGainMag=magnitudesSortedByMag.arraySlice(0,-1,null).arrayFlatten([["gain_mag"]]);var highestMagGainMask=changeMaskSortedByMag.arraySlice(0,-1,null).arrayFlatten([["gain_mask"]]);highestMagGainYear=highestMagGainYear.updateMask(highestMagGainMag.gt(0).and(highestMagGainMask));highestMagGainMag=highestMagGainMag.updateMask(highestMagGainMag.gt(0).and(highestMagGainMask));var mostRecentLossYear=breaksSortedByYear.arrayMask(magnitudesSortedByYear.lt(0)).arrayPad([1]).arraySlice(0,-1,null).arrayFlatten([["loss_year"]]);var mostRecentLossMag=magnitudesSortedByYear.arrayMask(magnitudesSortedByYear.lt(0)).arrayPad([1]).arraySlice(0,-1,null).arrayFlatten([["loss_mag"]]);var mostRecentLossMask=changeMaskSortedByYear.arrayMask(magnitudesSortedByYear.lt(0)).arrayPad([1]).arraySlice(0,-1,null).arrayFlatten([["loss_mask"]]);mostRecentLossYear=mostRecentLossYear.updateMask(mostRecentLossMag.lt(0).and(mostRecentLossMask));mostRecentLossMag=mostRecentLossMag.updateMask(mostRecentLossMag.lt(0).and(mostRecentLossMask));var mostRecentGainYear=breaksSortedByYear.arrayMask(magnitudesSortedByYear.gt(0)).arrayPad([1]).arraySlice(0,-1,null).arrayFlatten([["gain_year"]]);var mostRecentGainMag=magnitudesSortedByYear.arrayMask(magnitudesSortedByYear.gt(0)).arrayPad([1]).arraySlice(0,-1,null).arrayFlatten([["gain_mag"]]);var mostRecentGainMask=changeMaskSortedByYear.arrayMask(magnitudesSortedByYear.gt(0)).arrayPad([1]).arraySlice(0,-1,null).arrayFlatten([["gain_mask"]]);mostRecentGainYear=mostRecentGainYear.updateMask(mostRecentGainMag.gt(0).and(mostRecentGainMask));mostRecentGainMag=mostRecentGainMag.updateMask(mostRecentGainMag.gt(0).and(mostRecentGainMask));return{mostRecent:{loss:{year:mostRecentLossYear,mag:mostRecentLossMag},gain:{year:mostRecentGainYear,mag:mostRecentGainMag},},highestMag:{loss:{year:highestMagLossYear,mag:highestMagLossMag},gain:{year:highestMagGainYear,mag:highestMagGainMag},},};}
exports.getR2=getR2;exports.extractDisturbance=extractDisturbance;exports.landtrendrWrapper=landtrendrWrapper;exports.multBands=multBands;exports.LT_VT_multBands=LT_VT_multBands;exports.addToImage=addToImage;exports.getExistingChangeData=getExistingChangeData;exports.arrayToTimeSeries=arrayToTimeSeries;exports.getRawAndFittedLT=getRawAndFittedLT;exports.getLTStack=getLTStack;exports.getLTvertStack=getLTvertStack;exports.simpleLANDTRENDR=simpleLANDTRENDR;exports.default_lt_run_params=default_lt_run_params;exports.multLT=multLT;exports.convertToLossGain=convertToLossGain;exports.LTLossGainExportPrep=LTLossGainExportPrep;exports.addLossGainToMap=addLossGainToMap;exports.simpleLTFit=simpleLTFit;exports.batchSimpleLTFit=batchSimpleLTFit;exports.prepTimeSeriesForLandTrendr=prepTimeSeriesForLandTrendr;exports.LANDTRENDRVertStack=LANDTRENDRVertStack;exports.rawLTToVertices=rawLTToVertices;exports.applyDistDir_vertStack=applyDistDir_vertStack;exports.LT_VT_vertStack_multBands=LT_VT_vertStack_multBands;exports.fitStackToCollection=fitStackToCollection;exports.convertStack_To_DurFitMagSlope=convertStack_To_DurFitMagSlope;exports.LANDTRENDRFitMagSlopeDiffCollection=LANDTRENDRFitMagSlopeDiffCollection;exports.multiBandLANDTRENDRFitMagSlopeDiffCollection=multiBandLANDTRENDRFitMagSlopeDiffCollection;exports.applyLinearInterp=applyLinearInterp;exports.updateVerdetMasks=updateVerdetMasks;exports.VERDETVertStack=VERDETVertStack;exports.VERDETFitMagSlopeDiffCollection=VERDETFitMagSlopeDiffCollection;exports.verdetAnnualSlope=verdetAnnualSlope;exports.annualizeEWMA=annualizeEWMA;exports.getEWMA=getEWMA;exports.runEWMACD=runEWMACD;exports.CCDCFitMagSlopeCollection=CCDCFitMagSlopeCollection;exports.pairwiseSlope=pairwiseSlope;exports.thresholdChange=thresholdChange;exports.predictModel=predictModel;exports.getLinearFit=getLinearFit;exports.toAnnualMedian=toAnnualMedian;exports.zAndTrendChangeDetection=zAndTrendChangeDetection;exports.thresholdZAndTrend=thresholdZAndTrend;exports.thresholdZAndTrendSubtle=thresholdZAndTrendSubtle;exports.thresholdSubtleChange=thresholdSubtleChange;exports.simpleCCDCPrediction=simpleCCDCPrediction;exports.simpleCCDCPredictionWrapper=simpleCCDCPredictionWrapper;exports.getCCDCSegCoeffs=getCCDCSegCoeffs;exports.annualizeCCDC=annualizeCCDC;exports.getFitSlopeCCDC=getFitSlopeCCDC;exports.simpleCCDCPredictionAnnualized=simpleCCDCPredictionAnnualized;exports.predictCCDC=predictCCDC;exports.getTimeImageCollection=getTimeImageCollection;exports.simpleGetTimeImageCollection=simpleGetTimeImageCollection;exports.getTimeImageCollectionFromComposites=getTimeImageCollectionFromComposites;exports.ccdcChangeDetection=ccdcChangeDetection;