<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The sen2rts workflow • sen2rts</title>
<!-- jquery --><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script><!-- Bootstrap --><link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.4.0/yeti/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha256-nuL8/2cJ5NDSSwnKD8VqreErSWHtnEP9E7AySL+1ev4=" crossorigin="anonymous"></script><!-- bootstrap-toc --><link rel="stylesheet" href="../bootstrap-toc.css">
<script src="../bootstrap-toc.js"></script><!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
<!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- pkgdown --><link href="../pkgdown.css" rel="stylesheet">
<script src="../pkgdown.js"></script><meta property="og:title" content="The sen2rts workflow">
<meta property="og:description" content="sen2rts">
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body data-spy="scroll" data-target="#toc">
    

    <div class="container template-article">
      <header><div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <span class="navbar-brand">
        <a class="navbar-link" href="../index.html">sen2rts</a>
        <span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="">0.4.1</span>
      </span>
    </div>

    <div id="navbar" class="navbar-collapse collapse">
      <ul class="nav navbar-nav"></ul>
<ul class="nav navbar-nav navbar-right">
<li>
  <a href="../index.html">
    <span class="fa fa-home fa-lg"></span>
     
  </a>
</li>
<li>
  <a href="../reference/index.html">
    <span class="fa fa-file-code"></span>
     
     Reference
  </a>
</li>
<li>
  <a href="../articles/workflow.html">
    <span class="fa fa-book"></span>
     
     The sen2rts workflow
  </a>
</li>
<li>
  <a href="../news/index.html">
    <span class="fa fa-newspaper"></span>
     
     Changelog
  </a>
</li>
<li>
  <a href="http://luigi.ranghetti.info" class="external-link">
    <span class="fa fa-user"></span>
     
  </a>
</li>
<li>
  <a href="https://github.com/ranghetti/sen2rts/" class="external-link">
    <span class="fa fa-github fa-lg"></span>
     
  </a>
</li>
      </ul>
</div>
<!--/.nav-collapse -->
  </div>
<!--/.container -->
</div>
<!--/.navbar -->

      

      </header><div class="row">
  <div class="col-md-9 contents">
    <div class="page-header toc-ignore">
      <h1 data-toc-skip>The sen2rts workflow</h1>
            
      
      <small class="dont-index">Source: <a href="https://github.com/ranghetti/sen2rts/blob/HEAD/vignettes/workflow.Rmd" class="external-link"><code>vignettes/workflow.Rmd</code></a></small>
      <div class="hidden name"><code>workflow.Rmd</code></div>

    </div>

    
    
<p>This vignette describes a use case to process a sample Sentinel-2
time series and extract information about seasonality.</p>
<p>Functions developed in the package <a href="https://sen2rts.ranghetti.info" class="external-link">sen2rts</a> are run
sequentially, following this workflow:</p>
<ol style="list-style-type: decimal">
<li>
<a href="#produce-raster-archive-with-sen2r">produce raster archive
with sen2r</a>;</li>
<li>
<a href="#extract-time-series-over-spatial-features">extract time
series over spatial features</a>;</li>
<li>
<a href="#smooth-raw-time-series">smooth raw time series</a>;</li>
<li>
<a href="#fill-temporal-gaps">fill temporal gaps</a>;</li>
<li>
<a href="#cut-cycles">cut cycles</a>;</li>
<li>
<a href="#assign-cycles-to-specific-seasons">assign cycles to
specific seasons</a>;</li>
<li>
<a href="#interpolate-cycles">interpolate cycles</a>;</li>
<li>
<a href="#extract-phenological-metrics">extract phenological
metrics</a>;</li>
<li>
<a href="#aggregate-time-series-over-seasons">aggregate time series
over seasons</a>.</li>
</ol>
<div class="section level2">
<h2 id="produce-raster-archive-with-sen2r">Produce raster archive with <code>{sen2r}</code><a class="anchor" aria-label="anchor" href="#produce-raster-archive-with-sen2r"></a>
</h2>
<p>Package <a href="https://sen2r.ranghetti.info" class="external-link">sen2r</a> must be used to generate the local
raster data over the area of interest, since <a href="https://sen2rts.ranghetti.info" class="external-link">sen2rts</a> is
built to read a Sentinel-2 image archive in the <a href="https://sen2r.ranghetti.info/articles/outstructure.html" class="external-link">sen2r
output structure</a>. In this tutorial the following sample archive is
being used:</p>
<ul>
<li>
<strong>extent</strong>: some field crops of the farm <a href="https://bonificheferraresi.it/it/home" class="external-link"><em>Bonifiche
Ferraresi</em></a> located in the estate of Jolanda di Savoia (FE,
Italy);</li>
<li>
<strong>time window</strong>: 2-years time window (2019 to 2020),
which can be extended up to 5 years by the user;</li>
<li>
<strong>products</strong>: NDVI <a href="https://sen2r.ranghetti.info/articles/outstructure.html#spectral-indices" class="external-link">spectral
index</a> (main product) and <a href="https://sen2r.ranghetti.info/articles/outstructure.html#scene-classification-map" class="external-link">SCL</a>
(for quality metadata).</li>
</ul>
<p>The following code <em>could</em> be used to produce it (but see the
note below the code before launching it):</p>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://sen2r.ranghetti.info" class="external-link">sen2r</a></span><span class="op">)</span>
<span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://r-spatial.github.io/sf/" class="external-link">sf</a></span><span class="op">)</span>
<span class="co">## Define the directories to store SAFE archives and outputs</span>
<span class="va">samplecrops_dir</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/file.path.html" class="external-link">file.path</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/basename.html" class="external-link">dirname</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/attr.html" class="external-link">attr</a></span><span class="op">(</span><span class="fu"><a href="https://sen2r.ranghetti.info/reference/load_binpaths.html" class="external-link">load_binpaths</a></span><span class="op">(</span><span class="op">)</span>, <span class="st">"path"</span><span class="op">)</span><span class="op">)</span>, <span class="st">"samplecrops"</span><span class="op">)</span>
<span class="va">safe_dir</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/file.path.html" class="external-link">file.path</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/basename.html" class="external-link">dirname</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/attr.html" class="external-link">attr</a></span><span class="op">(</span><span class="fu"><a href="https://sen2r.ranghetti.info/reference/load_binpaths.html" class="external-link">load_binpaths</a></span><span class="op">(</span><span class="op">)</span>, <span class="st">"path"</span><span class="op">)</span><span class="op">)</span>, <span class="st">"safe"</span><span class="op">)</span>
<span class="co"># you can replace the previous lines with the paths of any desired folder</span>
<span class="co"># (in an existing parent directory)</span>
<span class="fu"><a href="https://rdrr.io/r/base/files2.html" class="external-link">dir.create</a></span><span class="op">(</span><span class="va">samplecrops_dir</span>, showWarnings <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span>
<span class="fu"><a href="https://rdrr.io/r/base/files2.html" class="external-link">dir.create</a></span><span class="op">(</span><span class="va">safe_dir</span>, showWarnings <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span>

<span class="co">## Define the output extent</span>
<span class="va">samplecrops_poly</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://r-spatial.github.io/sf/reference/sfc.html" class="external-link">st_sfc</a></span><span class="op">(</span><span class="fu"><a href="https://r-spatial.github.io/sf/reference/st.html" class="external-link">st_polygon</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/list.html" class="external-link">list</a></span><span class="op">(</span>
    <span class="fu"><a href="https://rdrr.io/r/base/matrix.html" class="external-link">matrix</a></span><span class="op">(</span>
      <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="fl">733500</span>, <span class="fl">4971600</span>,
        <span class="fl">733500</span>, <span class="fl">4973580</span>,
        <span class="fl">735480</span>, <span class="fl">4973580</span>,
        <span class="fl">735480</span>, <span class="fl">4971600</span>,
        <span class="fl">733500</span>, <span class="fl">4971600</span><span class="op">)</span>,
      ncol <span class="op">=</span> <span class="fl">2</span>, byrow <span class="op">=</span> <span class="cn">TRUE</span>
    <span class="op">)</span>
  <span class="op">)</span><span class="op">)</span>, crs <span class="op">=</span> <span class="fl">32632</span><span class="op">)</span>

<span class="co">## Install Sen2Cor (used to process SAFE L1C archives)</span>
<span class="fu"><a href="https://sen2r.ranghetti.info/reference/install_sen2cor.html" class="external-link">install_sen2cor</a></span><span class="op">(</span><span class="op">)</span>

<span class="co">## Launch sen2r() to download Sentinel-2 data and produce the archive</span>
<span class="fu"><a href="https://sen2r.ranghetti.info/reference/sen2r.html" class="external-link">sen2r</a></span><span class="op">(</span>
  gui <span class="op">=</span> <span class="cn">FALSE</span>,
  extent <span class="op">=</span> <span class="va">samplecrops_poly</span>,
  extent_name <span class="op">=</span> <span class="st">"samplecrops"</span>,
  timewindow <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"2019-01-01"</span>, <span class="st">"2020-12-31"</span><span class="op">)</span>,
  list_prods <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"SCL"</span><span class="op">)</span>, <span class="co"># you can add "BOA" for eventual future usage</span>
  list_indices <span class="op">=</span> <span class="st">"NDVI"</span>,
  sen2cor_use_dem <span class="op">=</span> <span class="cn">TRUE</span>,
  path_l1c <span class="op">=</span> <span class="va">safe_dir</span>,
  path_l2a <span class="op">=</span> <span class="va">safe_dir</span>,
  path_out <span class="op">=</span> <span class="va">samplecrops_dir</span>
<span class="op">)</span></code></pre></div>
<p><em>NOTE:</em> producing the output archive with this command
requires a lot of patience, since most of the required SAFE archives
must be ordered from <a href="https://scihub.copernicus.eu/userguide/LongTermArchive" class="external-link">ESA Long
Term Archive</a> and Level-1C archives must be processed to obtain the
corresponding Level-2A ones.</p>
<p>In order to speed-up this step, the archive can be downloaded from
this <a href="https://doi.org/10.5281/zenodo.4620934" class="external-link">Zenodo
repository</a> using the following code instead than the previous
chunk:</p>
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="co">## Define the directory to store outputs</span>
<span class="va">samplecrops_dir</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/file.path.html" class="external-link">file.path</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/basename.html" class="external-link">dirname</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/attr.html" class="external-link">attr</a></span><span class="op">(</span><span class="fu"><a href="https://sen2r.ranghetti.info/reference/load_binpaths.html" class="external-link">load_binpaths</a></span><span class="op">(</span><span class="op">)</span>, <span class="st">"path"</span><span class="op">)</span><span class="op">)</span>, <span class="st">"samplecrops"</span><span class="op">)</span>
<span class="co"># you can replace the previous line with the paths of any desired folder</span>
<span class="co"># (in an existing parent directory)</span>

<span class="co">## Download and extract the sample archives</span>
<span class="kw">if</span> <span class="op">(</span><span class="op">!</span><span class="fu"><a href="https://rdrr.io/r/base/files2.html" class="external-link">dir.exists</a></span><span class="op">(</span><span class="va">samplecrops_dir</span><span class="op">)</span><span class="op">)</span> <span class="op">{</span>
  <span class="fu"><a href="https://rdrr.io/r/base/files2.html" class="external-link">dir.create</a></span><span class="op">(</span><span class="va">samplecrops_dir</span>, showWarnings <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span>
  <span class="va">samplecrops_url</span> <span class="op">&lt;-</span> <span class="st">"https://zenodo.org/record/4620934/files"</span>
  <span class="kw">for</span> <span class="op">(</span><span class="va">sel_y</span> <span class="kw">in</span> <span class="fl">2019</span><span class="op">:</span><span class="fl">2020</span><span class="op">)</span> <span class="op">{</span> <span class="co"># can be extended up to 2015:2020</span>
    <span class="kw">for</span> <span class="op">(</span><span class="va">sel_p</span> <span class="kw">in</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"SCL"</span>, <span class="st">"NDVI"</span><span class="op">)</span><span class="op">)</span> <span class="op">{</span>
      <span class="fu"><a href="https://rdrr.io/r/utils/download.file.html" class="external-link">download.file</a></span><span class="op">(</span>
        <span class="fu"><a href="https://rdrr.io/r/base/file.path.html" class="external-link">file.path</a></span><span class="op">(</span><span class="va">samplecrops_url</span>, <span class="fu"><a href="https://rdrr.io/r/base/paste.html" class="external-link">paste0</a></span><span class="op">(</span><span class="st">"S2X2A_"</span>,<span class="va">sel_y</span>,<span class="st">"_022_samplecrops_"</span>,<span class="va">sel_p</span>,<span class="st">"_10.zip"</span><span class="op">)</span><span class="op">)</span>,
        <span class="va">temp_zip_path</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/tempfile.html" class="external-link">tempfile</a></span><span class="op">(</span>fileext <span class="op">=</span> <span class="st">".zip"</span><span class="op">)</span>
      <span class="op">)</span>
      <span class="fu"><a href="https://rdrr.io/r/utils/unzip.html" class="external-link">unzip</a></span><span class="op">(</span><span class="va">temp_zip_path</span>, exdir <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/file.path.html" class="external-link">file.path</a></span><span class="op">(</span><span class="va">samplecrops_dir</span>, <span class="va">sel_p</span><span class="op">)</span><span class="op">)</span>
      <span class="fu"><a href="https://rdrr.io/r/base/files.html" class="external-link">file.remove</a></span><span class="op">(</span><span class="va">temp_zip_path</span><span class="op">)</span>
    <span class="op">}</span>
  <span class="op">}</span>
<span class="op">}</span></code></pre></div>
</div>
<div class="section level2">
<h2 id="extract-time-series-over-spatial-features">Extract time series over spatial features<a class="anchor" aria-label="anchor" href="#extract-time-series-over-spatial-features"></a>
</h2>
<p>“Raw” time series can be extracted from the data archive using the
function <code><a href="../reference/extract_s2ts.html">extract_s2ts()</a></code>. Required inputs are:</p>
<ol style="list-style-type: decimal">
<li>the paths of the rasters to be used;</li>
<li>a spatial file of class <code>sf</code> or <code>sfc</code>
containing the features over which extracting the time series.</li>
</ol>
<p>The function <code><a href="../reference/load_s2paths.html">load_s2paths()</a></code> can be used to easily obtain
the required paths passing it the main path of the <a href="https://sen2r.ranghetti.info" class="external-link">sen2r</a>
archive, the product type to read and some other additional parameters
which can be used to filter the existing rasters (time window,
Sentinel-2 orbits or a specific sensor). See <a href="../reference/load_s2paths.html">the documentation</a> for additional
details.</p>
<p>The spatial file can contain point or polygon features. In the first
case, raster values overlayed by points are used; in the second case,
cells covered by each polygon are averaged, additionally using a quality
data (SCL and/or CLD) to compute a weighted average. Moreover, in both
the cases the additional quality layers can be used to assign a quality
flag to each time series value (see <a href="../reference/extract_sen2rts.html">the function documentation</a>
for details). In the case of SCL, each surface class can be assigned to
a weight value using the function <code><a href="../reference/scl_weights.html">scl_weights()</a></code>.</p>
<p>In this example, SCL archive is used both to weight averages over
polygons and to assign quality flags to time series. The default SCL
weights are used, with the exception of class “snow” (since snow is a
rare event in the area of interest, pixels classified as snow are more
often errors of classification; so, value “0” is used).</p>
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://sen2rts.ranghetti.info" class="external-link">sen2rts</a></span><span class="op">)</span>
<span class="co">## Read image paths</span>
<span class="va">sen2r_ndvi_paths</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/load_s2paths.html">load_s2paths</a></span><span class="op">(</span>
  <span class="va">samplecrops_dir</span>, 
  prod_type <span class="op">=</span> <span class="st">"NDVI"</span>,
  time_window <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"2019-01-01"</span>, <span class="st">"2020-12-31"</span><span class="op">)</span> 
<span class="op">)</span>
<span class="va">sen2r_scl_paths</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/load_s2paths.html">load_s2paths</a></span><span class="op">(</span>
  <span class="va">samplecrops_dir</span>, 
  prod_type <span class="op">=</span> <span class="st">"SCL"</span>,
  time_window <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"2019-01-01"</span>, <span class="st">"2020-12-31"</span><span class="op">)</span>
<span class="op">)</span>
<span class="co"># time_window can be extended up to c("2015-07-01", "2020-12-31")</span>

<span class="co">## Read sample polygons</span>
<span class="fu"><a href="https://rdrr.io/r/utils/data.html" class="external-link">data</a></span><span class="op">(</span><span class="va">samplecrops</span><span class="op">)</span>
<span class="co"># first 4 polygons are used: skip the following line to use all the 12 ones.</span>
<span class="va">samplecrops</span> <span class="op">&lt;-</span> <span class="va">samplecrops</span><span class="op">[</span><span class="fl">1</span><span class="op">:</span><span class="fl">4</span>,<span class="op">]</span>

<span class="co">## Extract TS</span>
<span class="va">ts_raw</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/extract_s2ts.html">extract_s2ts</a></span><span class="op">(</span>
  <span class="va">sen2r_ndvi_paths</span>, 
  <span class="va">samplecrops</span>, 
  scl_paths <span class="op">=</span> <span class="va">sen2r_scl_paths</span>,
  scl_w <span class="op">=</span> <span class="fu"><a href="../reference/scl_weights.html">scl_weights</a></span><span class="op">(</span>snow <span class="op">=</span> <span class="fl">0</span><span class="op">)</span>,
  in_sf_id <span class="op">=</span> <span class="st">"fid"</span>
<span class="op">)</span>

<span class="co"># Rescale values (this is needed since rasters were saved as Int16 </span>
<span class="co"># with a scale factor of 10000)</span>
<span class="va">ts_raw</span><span class="op">$</span><span class="va">value</span> <span class="op">&lt;-</span> <span class="va">ts_raw</span><span class="op">$</span><span class="va">value</span> <span class="op">/</span> <span class="fl">1E4</span></code></pre></div>
<p>The output is an object of class <code>s2ts</code>, which basically
is a <code>data.table</code> associated with specific methods for
printing and plotting. Print method shows a preview of the
<code>data.table</code>, with first 4 ID and first/last 5 dates; values
are accompanied by symbols which summarises the value of the quality
flag.</p>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="https://rdrr.io/r/base/print.html" class="external-link">print</a></span><span class="op">(</span><span class="va">ts_raw</span>, topn <span class="op">=</span> <span class="fl">5</span><span class="op">)</span> <span class="co"># standard visualisation</span></code></pre></div>
<pre><code><span class="co">## A raw s2ts time series with 141 dates and 4 IDs.</span>
<span class="co">##            Date Orbit Sensor           01                     02                     03          </span>
<span class="co">##   1: 2019-01-04   022     2A  0.198677164 &lt;U+25CB&gt;   0.275262139 &lt;U+25CB&gt;   0.348486523 &lt;U+25CB&gt; </span>
<span class="co">##   2: 2019-01-09   022     2B  0.007140325 &lt;U+25CB&gt;   0.009556043 &lt;U+25CB&gt;   0.005936018 &lt;U+25CB&gt; </span>
<span class="co">##   3: 2019-01-14   022     2A  0.124776814 &lt;U+25CB&gt;   0.177525636 &lt;U+25CB&gt;   0.228511524 &lt;U+25CB&gt; </span>
<span class="co">##   4: 2019-01-19   022     2B  0.038714396 &lt;U+25CB&gt;   0.042100174 &lt;U+25CB&gt;   0.049539241 &lt;U+25CB&gt; </span>
<span class="co">##   5: 2019-01-24   022     2A  0.154739921 &lt;U+25CB&gt;   0.163076289 &lt;U+25CB&gt;   0.196441886 &lt;U+25CB&gt; </span>
<span class="co">##  ---                                                                                             </span>
<span class="co">## 137: 2020-12-04   022     2A  0.007280689 &lt;U+25CB&gt;   0.008712644 &lt;U+25CB&gt;   0.006281991 &lt;U+25CB&gt; </span>
<span class="co">## 138: 2020-12-09   022     2B -0.029473375 &lt;U+25CB&gt;  -0.032747440 &lt;U+25CB&gt;  -0.026344074 &lt;U+25CB&gt; </span>
<span class="co">## 139: 2020-12-19   022     2B  0.082687887 &lt;U+25CB&gt;   0.245273945 &lt;U+25CB&gt;   0.217815478 &lt;U+25CB&gt; </span>
<span class="co">## 140: 2020-12-24   022     2A  0.005621169 &lt;U+25CB&gt;   0.005258656 &lt;U+25CB&gt;   0.002072325 &lt;U+25CB&gt; </span>
<span class="co">## 141: 2020-12-29   022     2B  0.017024807 &lt;U+25CB&gt;   0.026785510 &lt;U+25CB&gt;   0.023719102 &lt;U+25CB&gt; </span>
<span class="co">##                04          </span>
<span class="co">##   1:  0.304735257 &lt;U+25CB&gt; </span>
<span class="co">##   2:  0.006098119 &lt;U+25CB&gt; </span>
<span class="co">##   3:  0.208502085 &lt;U+25CB&gt; </span>
<span class="co">##   4:  0.049726541 &lt;U+25CB&gt; </span>
<span class="co">##   5:  0.214882679 &lt;U+25CB&gt; </span>
<span class="co">##  ---                       </span>
<span class="co">## 137:  0.004105747 &lt;U+25CB&gt; </span>
<span class="co">## 138: -0.022775444 &lt;U+25CB&gt; </span>
<span class="co">## 139:  0.576268384 &lt;U+25CB&gt; </span>
<span class="co">## 140:  0.002197806 &lt;U+25CB&gt; </span>
<span class="co">## 141:  0.025177011 &lt;U+25CB&gt; </span>
<span class="co">## </span>
<span class="co">## Quality flags:  &lt;U+25CF&gt; [1]  &lt;U+25D5&gt; [0.9,1)  &lt;U+25D1&gt; [0.75,0.9)  &lt;U+25D4&gt; [0.5,0.75)  &lt;U+25CB&gt; [0,0.5)</span></code></pre>
<div class="sourceCode" id="cb6"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu">data.table</span><span class="fu">::</span><span class="fu"><a href="https://Rdatatable.gitlab.io/data.table/reference/as.data.table.html" class="external-link">as.data.table</a></span><span class="op">(</span><span class="va">ts_raw</span><span class="op">)</span> <span class="co"># conversion in data.table allows showing all attributes</span></code></pre></div>
<pre><code><span class="co">##      id       date orbit sensor        value        qa</span>
<span class="co">##   1: 01 2019-01-04   022     2A  0.198677164 0.2849574</span>
<span class="co">##   2: 01 2019-01-09   022     2B  0.007140325 0.0000000</span>
<span class="co">##   3: 01 2019-01-14   022     2A  0.124776814 0.3341486</span>
<span class="co">##   4: 01 2019-01-19   022     2B  0.038714396 0.0000000</span>
<span class="co">##   5: 01 2019-01-24   022     2A  0.154739921 0.3212616</span>
<span class="co">##  ---                                                  </span>
<span class="co">## 560: 04 2020-12-04   022     2A  0.004105747 0.0000000</span>
<span class="co">## 561: 04 2020-12-09   022     2B -0.022775444 0.0000000</span>
<span class="co">## 562: 04 2020-12-19   022     2B  0.576268384 0.4434169</span>
<span class="co">## 563: 04 2020-12-24   022     2A  0.002197806 0.0000000</span>
<span class="co">## 564: 04 2020-12-29   022     2B  0.025177011 0.0000000</span></code></pre>
<div class="sourceCode" id="cb8"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="../reference/plot.html">plot</a></span><span class="op">(</span><span class="va">ts_raw</span><span class="op">)</span></code></pre></div>
<p><img src="workflow_files/figure-html/print_extract-1.png" width="100%" style="display: block; margin: auto;"></p>
<p>The <code>plot</code> method for class <code>s2ts</code> calls
<code><a href="https://ggplot2.tidyverse.org/reference/ggplot.html" class="external-link">ggplot2::ggplot()</a></code>. Raw values are shown using a colour
scale which depends on the quality flag associated to each value. In
this case, it was determined from SCL values, using the following
correspondence between SCL classes and 0-1 values:</p>
<div class="sourceCode" id="cb9"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="../reference/scl_weights.html">scl_weights</a></span><span class="op">(</span>snow <span class="op">=</span> <span class="fl">0</span><span class="op">)</span></code></pre></div>
<pre><code><span class="co">##                  no_data   saturated_or_defective         dark_area_pixels            cloud_shadows </span>
<span class="co">##                     0.00                     0.00                     0.33                     0.17 </span>
<span class="co">##               vegetation            not_vegetated                    water             unclassified </span>
<span class="co">##                     1.00                     1.00                     1.00                     0.33 </span>
<span class="co">## cloud_medium_probability   cloud_high_probability              thin_cirrus                     snow </span>
<span class="co">##                     0.00                     0.00                     0.33                     0.00</span></code></pre>
</div>
<div class="section level2">
<h2 id="smooth-raw-time-series">Smooth raw time series<a class="anchor" aria-label="anchor" href="#smooth-raw-time-series"></a>
</h2>
<p>This step allows removing evident temporal discontinuities like
drops, usually due to low quality points or points with a wrong
associated quality flag (misclassification), by applying a
Savitzky-Golay low-pass filter.</p>
<p>Function <code><a href="../reference/smooth_s2ts.html">smooth_s2ts()</a></code> is used for the first step. It
takes as input a <code>s2ts</code> object created with
<code><a href="../reference/extract_s2ts.html">extract_s2ts()</a></code> (raw time series) and optional parameter
values which can be used to adjust the output (see the documentation for
details), returning a <code>s2ts</code> object (the same class of the
input) containing both raw and smoothed values.</p>
<p>In the following example <code>smooth_ts()</code> is launched
increasing the default value of the low-pass filter.</p>
<div class="sourceCode" id="cb11"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="va">ts_smoothed</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/smooth_s2ts.html">smooth_s2ts</a></span><span class="op">(</span><span class="va">ts_raw</span>, sg_daywindow <span class="op">=</span> <span class="fl">30</span><span class="op">)</span>
<span class="fu"><a href="https://rdrr.io/r/base/print.html" class="external-link">print</a></span><span class="op">(</span><span class="va">ts_smoothed</span>, topn <span class="op">=</span> <span class="fl">5</span><span class="op">)</span></code></pre></div>
<pre><code><span class="co">## A smoothed s2ts time series with 141 dates and 4 IDs.</span>
<span class="co">##            Date Orbit Sensor        01                  02                  03                  04</span>
<span class="co">##   1: 2019-01-04   022     2A 0.2015220 &lt;U+25CB&gt;  0.2817340 &lt;U+25CB&gt;  0.3593622 &lt;U+25CB&gt;  0.3132747</span>
<span class="co">##   2: 2019-01-09   022     2B        NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">##   3: 2019-01-14   022     2A 0.2186216 &lt;U+25CB&gt;  0.2905136 &lt;U+25CB&gt;  0.3084582 &lt;U+25CB&gt;  0.2964681</span>
<span class="co">##   4: 2019-01-19   022     2B        NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">##   5: 2019-01-24   022     2A 0.2225528 &lt;U+25CB&gt;  0.2832968 &lt;U+25CB&gt;  0.2719021 &lt;U+25CB&gt;  0.2741441</span>
<span class="co">##  ---                                                                                              </span>
<span class="co">## 137: 2020-12-04   022     2A        NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">## 138: 2020-12-09   022     2B        NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">## 139: 2020-12-19   022     2B 0.1731419 &lt;U+25CB&gt;  0.3511046 &lt;U+25CB&gt;  0.2431572 &lt;U+25CB&gt;  0.8050031</span>
<span class="co">## 140: 2020-12-24   022     2A        NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">## 141: 2020-12-29   022     2B        NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">##               </span>
<span class="co">##   1: &lt;U+25CB&gt; </span>
<span class="co">##   2: &lt;U+25CB&gt; </span>
<span class="co">##   3: &lt;U+25CB&gt; </span>
<span class="co">##   4: &lt;U+25CB&gt; </span>
<span class="co">##   5: &lt;U+25CB&gt; </span>
<span class="co">##  ---          </span>
<span class="co">## 137: &lt;U+25CB&gt; </span>
<span class="co">## 138: &lt;U+25CB&gt; </span>
<span class="co">## 139: &lt;U+25CB&gt; </span>
<span class="co">## 140: &lt;U+25CB&gt; </span>
<span class="co">## 141: &lt;U+25CB&gt; </span>
<span class="co">## </span>
<span class="co">## Quality flags:  &lt;U+25CF&gt; [1]  &lt;U+25D5&gt; [0.9,1)  &lt;U+25D1&gt; [0.75,0.9)  &lt;U+25D4&gt; [0.5,0.75)  &lt;U+25CB&gt; [0,0.5)</span></code></pre>
<div class="sourceCode" id="cb13"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="../reference/plot.html">plot</a></span><span class="op">(</span><span class="va">ts_smoothed</span><span class="op">)</span></code></pre></div>
<p><img src="workflow_files/figure-html/smooth_s2ts-1.png" width="100%" style="display: block; margin: auto;"></p>
<p>Plotting output time series allows raw values (points joined by a
light-grey line) together with smoothed values (joined by a dark line).
Points can be hidden with <code>plot(..., plot_points = FALSE)</code>
(see the <a href="../reference/plot.s2ts.html"><code>plot.s2ts</code></a>
documentation for details about the plotting method).</p>
<p>At this stage, a manual inspection can help to refine optional
arguments in order to better suit the smoothing to the user real case.
In this example, overestimations occur when seasonal cycles starts and
ends. Moreover, a specific date is causing the presence of an artifact
in fields 01, 02 and 04 (the reason can be understood visualising the
corresponding image: some clouds were marked as bare soil, causing a
higher index value not correctly labelled with a low quality flag).</p>
<p>Editing function arguments can help to avoid this problem:</p>
<div class="sourceCode" id="cb14"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="va">ts_smoothed2</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/smooth_s2ts.html">smooth_s2ts</a></span><span class="op">(</span>
  <span class="va">ts_raw</span>, 
  noise_dir <span class="op">=</span> <span class="st">"undefined"</span>, spike <span class="op">=</span> <span class="fl">0.1</span>, spike_window <span class="op">=</span> <span class="fl">3</span>
<span class="op">)</span>
<span class="fu"><a href="https://rdrr.io/r/base/print.html" class="external-link">print</a></span><span class="op">(</span><span class="va">ts_smoothed2</span>, topn <span class="op">=</span> <span class="fl">5</span><span class="op">)</span></code></pre></div>
<pre><code><span class="co">## A smoothed s2ts time series with 141 dates and 4 IDs.</span>
<span class="co">##            Date Orbit Sensor         01                  02                  03                  04</span>
<span class="co">##   1: 2019-01-04   022     2A 0.19853684 &lt;U+25CB&gt;  0.2750062 &lt;U+25CB&gt;  0.3480647 &lt;U+25CB&gt;  0.3034821</span>
<span class="co">##   2: 2019-01-09   022     2B         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">##   3: 2019-01-14   022     2A 0.12731438 &lt;U+25CB&gt;  0.1815165 &lt;U+25CB&gt;  0.2313612 &lt;U+25CB&gt;  0.2246652</span>
<span class="co">##   4: 2019-01-19   022     2B         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">##   5: 2019-01-24   022     2A 0.21829625 &lt;U+25CB&gt;  0.1618919 &lt;U+25CB&gt;  0.2899842 &lt;U+25CB&gt;  0.2123145</span>
<span class="co">##  ---                                                                                               </span>
<span class="co">## 137: 2020-12-04   022     2A         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">## 138: 2020-12-09   022     2B         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">## 139: 2020-12-19   022     2B 0.07806048 &lt;U+25CB&gt;  0.2414399 &lt;U+25CB&gt;  0.2187567 &lt;U+25CB&gt;  0.5682294</span>
<span class="co">## 140: 2020-12-24   022     2A         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">## 141: 2020-12-29   022     2B         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA &lt;U+25CB&gt;         NA</span>
<span class="co">##               </span>
<span class="co">##   1: &lt;U+25CB&gt; </span>
<span class="co">##   2: &lt;U+25CB&gt; </span>
<span class="co">##   3: &lt;U+25CB&gt; </span>
<span class="co">##   4: &lt;U+25CB&gt; </span>
<span class="co">##   5: &lt;U+25CB&gt; </span>
<span class="co">##  ---          </span>
<span class="co">## 137: &lt;U+25CB&gt; </span>
<span class="co">## 138: &lt;U+25CB&gt; </span>
<span class="co">## 139: &lt;U+25CB&gt; </span>
<span class="co">## 140: &lt;U+25CB&gt; </span>
<span class="co">## 141: &lt;U+25CB&gt; </span>
<span class="co">## </span>
<span class="co">## Quality flags:  &lt;U+25CF&gt; [1]  &lt;U+25D5&gt; [0.9,1)  &lt;U+25D1&gt; [0.75,0.9)  &lt;U+25D4&gt; [0.5,0.75)  &lt;U+25CB&gt; [0,0.5)</span></code></pre>
<div class="sourceCode" id="cb16"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="../reference/plot.html">plot</a></span><span class="op">(</span><span class="va">ts_smoothed2</span><span class="op">)</span></code></pre></div>
<p><img src="workflow_files/figure-html/fix_smooth_s2ts-1.png" width="100%" style="display: block; margin: auto;"></p>
<p>Here an explanation: the high <code>sg_daywindow = 30</code> value
was determining the use of too many images in the smoothing filter,
causing overestimations in correspondence of high slopes; so, the
default window of 15 days was restored. Regarding the specific date: by
default only spikes with a <code>"low</code>” direction are removed,
while the problematic spikes have a <code>"high"</code> direction, so
<code>noise_dir = "undefined"</code> was used to remove both.
<code>spike = 0.1</code> was then used to reduce the relative “y”
difference for spike determination, because the default one
(<code>0.25</code>) is too high for spikes with a <code>"high"</code>
direction (correct values would be removed). For the same reason,
<code>spike_window</code> was reduced from 5 to 3 (only isolated values
are removed).</p>
</div>
<div class="section level2">
<h2 id="fill-temporal-gaps">Fill temporal gaps<a class="anchor" aria-label="anchor" href="#fill-temporal-gaps"></a>
</h2>
<p>In order to obtain temporally homogeneous time series by filling gaps
(missing dates, or dates characterised by a quality flag = 0), function
<code><a href="../reference/fill_s2ts.html">fill_s2ts()</a></code> can be used. Inputs are similar to
<code><a href="../reference/smooth_s2ts.html">smooth_s2ts()</a></code>: function takes a smoothed <code>s2ts</code>
object and additional optional parameters, producing an output
<code>s2ts</code> filled time series.</p>
<div class="sourceCode" id="cb17"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="op">(</span> <span class="va">ts_filled</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/fill_s2ts.html">fill_s2ts</a></span><span class="op">(</span><span class="va">ts_smoothed2</span><span class="op">)</span> <span class="op">)</span></code></pre></div>
<pre><code><span class="co">## An interpolated s2ts time series with 726 dates and 4 IDs.</span>
<span class="co">##            Date Orbit Sensor        01                  02                  03                  04</span>
<span class="co">##   1: 2019-01-04   022     2A 0.1985368 &lt;U+25CB&gt;  0.2750062 &lt;U+25CB&gt;  0.3480647 &lt;U+25CB&gt;  0.3034821</span>
<span class="co">##   2: 2019-01-05  &lt;NA&gt;   &lt;NA&gt; 0.1762664        ~  0.2612186        ~  0.3193624        ~  0.2903388</span>
<span class="co">##   3: 2019-01-06  &lt;NA&gt;   &lt;NA&gt; 0.1580937        ~  0.2485234        ~  0.2952760        ~  0.2785395</span>
<span class="co">##   4: 2019-01-07  &lt;NA&gt;   &lt;NA&gt; 0.1437444        ~  0.2368810        ~  0.2754940        ~  0.2680186</span>
<span class="co">##   5: 2019-01-08  &lt;NA&gt;   &lt;NA&gt; 0.1329442        ~  0.2262514        ~  0.2597046        ~  0.2587107</span>
<span class="co">##  ---                                                                                              </span>
<span class="co">## 722: 2020-12-25  &lt;NA&gt;   &lt;NA&gt;        NA        ~         NA        ~         NA        ~         NA</span>
<span class="co">## 723: 2020-12-26  &lt;NA&gt;   &lt;NA&gt;        NA        ~         NA        ~         NA        ~         NA</span>
<span class="co">## 724: 2020-12-27  &lt;NA&gt;   &lt;NA&gt;        NA        ~         NA        ~         NA        ~         NA</span>
<span class="co">## 725: 2020-12-28  &lt;NA&gt;   &lt;NA&gt;        NA        ~         NA        ~         NA        ~         NA</span>
<span class="co">## 726: 2020-12-29   022     2B        NA        ~         NA        ~         NA        ~         NA</span>
<span class="co">##               </span>
<span class="co">##   1: &lt;U+25CB&gt; </span>
<span class="co">##   2:        ~ </span>
<span class="co">##   3:        ~ </span>
<span class="co">##   4:        ~ </span>
<span class="co">##   5:        ~ </span>
<span class="co">##  ---          </span>
<span class="co">## 722:        ~ </span>
<span class="co">## 723:        ~ </span>
<span class="co">## 724:        ~ </span>
<span class="co">## 725:        ~ </span>
<span class="co">## 726:        ~ </span>
<span class="co">## </span>
<span class="co">## Quality flags:  &lt;U+25CF&gt; [1]  &lt;U+25D5&gt; [0.9,1)  &lt;U+25D1&gt; [0.75,0.9)  &lt;U+25D4&gt; [0.5,0.75)  &lt;U+25CB&gt; [0,0.5)</span>
<span class="co">## Interpolated values are marked with "~".</span></code></pre>
<p>Filled values can be discriminated by smoothed ones because of the
<code>~</code> symbol used instead of the quality symbol.</p>
<p>Plotting method (here not shown) is equivalent to the one used for
smoothed <code>s2ts</code> objects.</p>
</div>
<div class="section level2">
<h2 id="cut-cycles">Cut cycles<a class="anchor" aria-label="anchor" href="#cut-cycles"></a>
</h2>
<p><em>Note: here and in the whole package a phenological time window
characterised by a begin (low index value), a peak (high value) and an
end (low value) is called “cycle”. The term “phenological season” is
never used in order to avoid confusion with the word “season”, used in
the package to identify specific portions of the year (like in function
<code><a href="../reference/assign_season.html">assign_season()</a></code>). The only exception is in the definitions
of some phenological metrics (e.g.  Start of Season and End of Season),
which are inherited from package {phenopix} and maintained with the same
names.</em></p>
<p>Next step is the partition of each time series in specific cycles,
basing on the position of drops (considered as cycle cuts) and peaks.
This is done using the function <code><a href="../reference/cut_cycles.html">cut_cycles()</a></code> and properly
setting arguments <code>min_win</code>, <code>min_peakvalue</code>,
<code>max_dropvalue</code> and <code>min_rel_thresh</code>: depending on
values of these parameters, each time series is cut in in a higher or
smaller number of cycles. Moreover, each cycle is associated to a
specific year. Arguments <code>n_cycles</code>, <code>newyearday</code>
and <code>weight_metric</code> allows determining which year should be
associated to each cycle and how many (and which) cycles should be
maintained for each year. The selection of cycles to be maintained can
be done on the basis of different metrics, like the maximum value
reached in each cycle (see the <a href="../reference/cut_cycles.html">function documentation</a> for
details). The output is a data table in which each record is a cycle,
with associated dates of begin, end and maximum value; a field
<code>weight</code> represents the cycle weight as computed by the
function.</p>
<p>In this example, cycles are cut with default parameters with the
exception of the minimum length of the cycle (30 days).</p>
<div class="sourceCode" id="cb19"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="va">dt_cycles</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/cut_cycles.html">cut_cycles</a></span><span class="op">(</span><span class="va">ts_filled</span>, min_win <span class="op">=</span> <span class="fl">30</span><span class="op">)</span>
<span class="fu"><a href="https://rdrr.io/r/utils/head.html" class="external-link">head</a></span><span class="op">(</span><span class="va">dt_cycles</span><span class="op">)</span></code></pre></div>
<pre><code><span class="co">##    id year cycle      begin        end     maxval    weight</span>
<span class="co">## 1: 01 2019     1 2019-01-11 2019-09-07 2019-07-03  65.12355</span>
<span class="co">## 2: 01 2019     2 2019-09-07 2019-12-09 2019-10-27  20.61482</span>
<span class="co">## 3: 01 2020     1 2019-12-09 2020-11-05 2020-08-03 113.15489</span>
<span class="co">## 4: 02 2019     1 2019-06-21 2019-11-14 2019-08-17  77.66607</span>
<span class="co">## 5: 02 2020     1 2019-11-14 2020-11-02 2020-04-23 135.43469</span>
<span class="co">## 6: 03 2019     1 2019-02-11 2019-10-26 2019-04-03  74.24240</span></code></pre>
</div>
<div class="section level2">
<h2 id="assign-cycles-to-specific-seasons">Assign cycles to specific seasons<a class="anchor" aria-label="anchor" href="#assign-cycles-to-specific-seasons"></a>
</h2>
<p>For a finer selection of cycles to be maintained, function
<code><a href="../reference/assign_season.html">assign_season()</a></code> can be used. In this case, cycles can be
associated not only to a specific year, but also to a season
(e.g. summer or winter); this is useful for example in case of multiple
crop seasons. For each season, the user can define a time windows in
which maximum values must occur, and/or an expected date of the peak to
select the nearest cycles. The function can be also used after having
retrieved phenological metrics, so to filter on the basis of dates of
start or end of season.</p>
<p>In this example the <code>data.table</code> produced by
<code><a href="../reference/cut_cycles.html">cut_cycles()</a></code> is filtered to keep a single, summer cycle: in
this case, the output data table includes the same fields of the
input.</p>
<div class="sourceCode" id="cb21"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="op">(</span> <span class="va">dt_cycles_seas</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/assign_season.html">assign_season</a></span><span class="op">(</span>
  <span class="va">dt_cycles</span>, max_n_cycles <span class="op">=</span> <span class="fl">1</span>, 
  pop_win <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"04-01"</span>, <span class="st">"08-31"</span><span class="op">)</span>, pop_name <span class="op">=</span> <span class="st">"maxval"</span>
<span class="op">)</span> <span class="op">)</span></code></pre></div>
<pre><code><span class="co">##    id year cycle      begin        end     maxval    weight</span>
<span class="co">## 1: 01 2019     1 2019-01-11 2019-09-07 2019-07-03  65.12355</span>
<span class="co">## 2: 01 2020     1 2019-12-09 2020-11-05 2020-08-03 113.15489</span>
<span class="co">## 3: 02 2019     1 2019-06-21 2019-11-14 2019-08-17  77.66607</span>
<span class="co">## 4: 02 2020     1 2019-11-14 2020-11-02 2020-04-23 135.43469</span>
<span class="co">## 5: 03 2019     1 2019-02-11 2019-10-26 2019-04-03  74.24240</span>
<span class="co">## 6: 03 2020     1 2019-10-26 2020-11-06 2020-07-14 112.19395</span>
<span class="co">## 7: 04 2019     1 2019-05-10 2019-09-14 2019-07-30  79.64547</span>
<span class="co">## 8: 04 2020     1 2019-12-14 2020-06-21 2020-04-22  89.06280</span></code></pre>
<p>If the user had asked to keep more than one season (or to assign a
name to the season), the output would have included an additional field
with the season name (see the example below).</p>
<div class="sourceCode" id="cb23"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="va">dt_cycles_seas2</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/assign_season.html">assign_season</a></span><span class="op">(</span>
  <span class="va">dt_cycles</span>, max_n_cycles <span class="op">=</span> <span class="fl">1</span>, 
  seasons <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"winter"</span>, <span class="st">"summer"</span><span class="op">)</span>,
  pop_win <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/list.html" class="external-link">list</a></span><span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"12-01"</span>, <span class="st">"03-31"</span><span class="op">)</span>, <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"04-01"</span>, <span class="st">"08-31"</span><span class="op">)</span><span class="op">)</span>, 
  pop_name <span class="op">=</span> <span class="st">"maxval"</span>
<span class="op">)</span>
<span class="fu"><a href="https://rdrr.io/r/utils/head.html" class="external-link">head</a></span><span class="op">(</span><span class="va">dt_cycles_seas2</span><span class="op">)</span></code></pre></div>
<pre><code><span class="co">##    id year cycle season      begin        end     maxval    weight</span>
<span class="co">## 1: 01 2019     1 summer 2019-01-11 2019-09-07 2019-07-03  65.12355</span>
<span class="co">## 2: 01 2020     1 summer 2019-12-09 2020-11-05 2020-08-03 113.15489</span>
<span class="co">## 3: 02 2019     1 summer 2019-06-21 2019-11-14 2019-08-17  77.66607</span>
<span class="co">## 4: 02 2020     1 summer 2019-11-14 2020-11-02 2020-04-23 135.43469</span>
<span class="co">## 5: 03 2019     1 summer 2019-02-11 2019-10-26 2019-04-03  74.24240</span>
<span class="co">## 6: 03 2020     1 summer 2019-10-26 2020-11-06 2020-07-14 112.19395</span></code></pre>
<p>The retrieved cycles can be plotted together with time series passing
the data table of cycles with the argument <code>pheno</code>: in this
case, vertical black lines are drawn to discriminate cycles, and yellow
bars highlight existing cycles (unless
<code>plot_cycles = FALSE</code>). Adding the argument
<code>plot_dates = TRUE</code> allows printing dates of cuts.</p>
<div class="sourceCode" id="cb25"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="../reference/plot.html">plot</a></span><span class="op">(</span><span class="va">ts_filled</span>, pheno <span class="op">=</span> <span class="va">dt_cycles_seas</span>, plot_dates <span class="op">=</span> <span class="cn">TRUE</span>, plot_points <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></code></pre></div>
<p><img src="workflow_files/figure-html/plot_assign-1.png" width="100%" style="display: block; margin: auto;"></p>
<p>Notice also that, when <code>pheno</code> or <code>fitted</code>
arguments are passed to the plot, printing raw points is disabled by
default; <code>plot_points = TRUE</code> is required to plot them.</p>
</div>
<div class="section level2">
<h2 id="interpolate-cycles">Interpolate cycles<a class="anchor" aria-label="anchor" href="#interpolate-cycles"></a>
</h2>
<p>In order to retrieve phenological metrics, time series have to be
interpolated using a known function.</p>
<p>To perform this step, <a href="https://sen2rts.ranghetti.info" class="external-link">sen2rts</a> makes use of double
logistic functions implemented in package <code>{phenopix}</code>:
<code><a href="https://rdrr.io/pkg/phenopix/man/PhenoTrs.html" class="external-link">phenopix::PhenoTrs()</a></code>, <code><a href="https://rdrr.io/pkg/phenopix/man/PhenoDeriv.html" class="external-link">phenopix::PhenoDeriv()</a></code>,
<code>phenopix::PhenoKlosterman()</code> and
<code><a href="https://rdrr.io/pkg/phenopix/man/PhenoGu.html" class="external-link">phenopix::PhenoGu()</a></code> (see documentations for details).
Required inputs are a <code>s2ts</code> object generated with
<code><a href="../reference/fill_s2ts.html">fill_s2ts()</a></code> and a data table of cycles generated with
<code><a href="../reference/cut_cycles.html">cut_cycles()</a></code>. Argument <code>fit</code> allows choosing the
fitting method (multiple methods can be passed: in case of failure of
the first one, the second is used). Output is a list containing the
interpolations. since this output is not intended to be visualised by
the user but to be passed to <code><a href="../reference/extract_pheno.html">extract_pheno()</a></code>, it can not be
easily explored by the user (there are not printing methods); instead, a
plotting method exist, so interpolations can be plotted passing this
object to the argument <code>fitted</code> (the example below shows it).
Interpolations are shown with red curves.</p>
<div class="sourceCode" id="cb26"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="va">cf</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/fit_curve.html">fit_curve</a></span><span class="op">(</span><span class="va">ts_filled</span>, <span class="va">dt_cycles_seas</span>, fit <span class="op">=</span> <span class="st">"gu"</span><span class="op">)</span>
<span class="fu"><a href="../reference/plot.html">plot</a></span><span class="op">(</span><span class="va">ts_filled</span>, fitted <span class="op">=</span> <span class="va">cf</span><span class="op">)</span></code></pre></div>
<p><img src="workflow_files/figure-html/fit_curve-1.png" width="100%" style="display: block; margin: auto;"></p>
<p>This function can require a large amount of time. To speed up it,
<code>method = "no"</code> can be chosen: in this case interpolation is
not performed, and the function simply convert the smoothed and filled
time series in a list in the format accepted by
<code><a href="../reference/extract_pheno.html">extract_pheno()</a></code>. User must be aware that extracting
phenological metrics from non interpolated series can lead to errors
(generally, only <code>method = "trs"</code> works) or wrong
estimations.</p>
</div>
<div class="section level2">
<h2 id="extract-phenological-metrics">Extract phenological metrics<a class="anchor" aria-label="anchor" href="#extract-phenological-metrics"></a>
</h2>
<p>As for fitting methods, also methods to extract phenological metrics
are inherited from package {phenopix}:
<code><a href="https://rdrr.io/pkg/phenopix/man/PhenoTrs.html" class="external-link">phenopix::PhenoTrs()</a></code>, <code><a href="https://rdrr.io/pkg/phenopix/man/PhenoDeriv.html" class="external-link">phenopix::PhenoDeriv()</a></code>,
<code><a href="https://rdrr.io/pkg/phenopix/man/PhenoKl.html" class="external-link">phenopix::PhenoKl()</a></code> and <code><a href="https://rdrr.io/pkg/phenopix/man/PhenoGu.html" class="external-link">phenopix::PhenoGu()</a></code>.
Function <code><a href="../reference/extract_pheno.html">extract_pheno()</a></code> can be used to do it: it accepts
as input a list of fitted cycles as produced by <code><a href="../reference/fit_curve.html">fit_curve()</a></code>
and a method among the available ones. Output is a
<code>data.table</code> in a format similar to the one produced by
<code>extract_cycles()</code>, but containing phenological metrics in
addition to dates of begin and end of cycles.</p>
<div class="sourceCode" id="cb27"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="op">(</span> <span class="va">dt_pheno</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/extract_pheno.html">extract_pheno</a></span><span class="op">(</span><span class="va">cf</span>, method <span class="op">=</span> <span class="st">"trs"</span>, trs <span class="op">=</span> <span class="fl">0.25</span><span class="op">)</span> <span class="op">)</span></code></pre></div>
<pre><code><span class="co">##    id year cycle      begin        end     maxval    weight        sos        eos los        pop</span>
<span class="co">## 1: 01 2019     1 2019-01-11 2019-09-06 2019-07-03  65.12355 2019-06-08 2019-08-17  70 2019-07-06</span>
<span class="co">## 2: 01 2020     1 2019-12-09 2020-11-04 2020-08-03 113.15489 2020-05-26 2020-09-01  98 2020-07-31</span>
<span class="co">## 3: 02 2019     1 2019-06-21 2019-11-13 2019-08-17  77.66607 2019-07-05 2019-10-10  97 2019-08-30</span>
<span class="co">## 4: 02 2020     1 2019-11-14 2020-11-01 2020-04-23 135.43469 2019-12-09 2020-06-11 185 2020-04-25</span>
<span class="co">## 5: 03 2019     1 2019-02-11 2019-10-25 2019-04-03  74.24240 2019-02-20 2019-06-20 120 2019-04-01</span>
<span class="co">## 6: 03 2020     1 2019-10-26 2020-11-05 2020-07-14 112.19395 2020-05-16 2020-09-01 108 2020-07-10</span>
<span class="co">## 7: 04 2019     1 2019-05-10 2019-09-13 2019-07-30  79.64547 2019-06-02 2019-09-08  98 2019-08-16</span>
<span class="co">## 8: 04 2020     1 2019-12-14 2020-06-20 2020-04-22  89.06280 2020-02-29 2020-06-13 105 2020-05-14</span>
<span class="co">##          mgs rsp rau      peak       msp       mau</span>
<span class="co">## 1: 0.5177695  NA  NA 0.6820822 0.3038994 0.2911377</span>
<span class="co">## 2: 0.7002851  NA  NA 0.8364063 0.2840135 0.3339171</span>
<span class="co">## 3: 0.6339211  NA  NA 0.8125181 0.2799478 0.2586716</span>
<span class="co">## 4: 0.5610319  NA  NA 0.8033260 0.2881567 0.2865726</span>
<span class="co">## 5: 0.4963164  NA  NA 0.6045332 0.2568708 0.2598417</span>
<span class="co">## 6: 0.7432974  NA  NA 0.8748075 0.2807313 0.3247225</span>
<span class="co">## 7: 0.6655245  NA  NA 0.7712665 0.3006362 0.3854653</span>
<span class="co">## 8: 0.6383665  NA  NA 0.7805908 0.3327761 0.3463545</span></code></pre>
<div class="sourceCode" id="cb29"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="fu"><a href="../reference/plot.html">plot</a></span><span class="op">(</span><span class="va">ts_filled</span>, fitted <span class="op">=</span> <span class="va">cf</span>, pheno <span class="op">=</span> <span class="va">dt_pheno</span><span class="op">)</span></code></pre></div>
<p><img src="workflow_files/figure-html/extract_pheno-1.png" width="100%" style="display: block; margin: auto;"></p>
<p>Here phenological metrics based on threshold at 10% of relative
values is used, printed and plotted. Metrics are plotted using segments
of different colours. Different methods produce different metrics; for
examples, using <code>method = "klosterman"</code>:</p>
<div class="sourceCode" id="cb30"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="va">dt_pheno2</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/extract_pheno.html">extract_pheno</a></span><span class="op">(</span><span class="va">cf</span>, method <span class="op">=</span> <span class="st">"klosterman"</span><span class="op">)</span>
<span class="fu"><a href="../reference/plot.html">plot</a></span><span class="op">(</span><span class="va">ts_filled</span>, pheno <span class="op">=</span> <span class="va">dt_pheno2</span><span class="op">)</span></code></pre></div>
<p><img src="workflow_files/figure-html/extract_pheno2-1.png" width="100%" style="display: block; margin: auto;"></p>
<p>As stated in paragraph <a href="#cut-cycles-and-assign-them-to-specific-seasons">Assign
season</a>, season assignment can be also performed after the extraction
of metrics. In the example below, late-seeded crops are extracted basing
on dates of Start of Season:</p>
<div class="sourceCode" id="cb31"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="op">(</span> <span class="va">dt_pheno_seas</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/assign_season.html">assign_season</a></span><span class="op">(</span>
  <span class="va">dt_pheno</span>, max_n_cycles <span class="op">=</span> <span class="fl">1</span>, 
  sos_win <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"05-01"</span>, <span class="st">"06-15"</span><span class="op">)</span>,
<span class="op">)</span> <span class="op">)</span></code></pre></div>
<pre><code><span class="co">##    id year cycle      begin        end     maxval    weight        sos        eos los        pop</span>
<span class="co">## 1: 01 2019     1 2019-01-11 2019-09-06 2019-07-03  65.12355 2019-06-08 2019-08-17  70 2019-07-06</span>
<span class="co">## 2: 01 2020     1 2019-12-09 2020-11-04 2020-08-03 113.15489 2020-05-26 2020-09-01  98 2020-07-31</span>
<span class="co">## 3: 03 2020     1 2019-10-26 2020-11-05 2020-07-14 112.19395 2020-05-16 2020-09-01 108 2020-07-10</span>
<span class="co">## 4: 04 2019     1 2019-05-10 2019-09-13 2019-07-30  79.64547 2019-06-02 2019-09-08  98 2019-08-16</span>
<span class="co">##          mgs rsp rau      peak       msp       mau</span>
<span class="co">## 1: 0.5177695  NA  NA 0.6820822 0.3038994 0.2911377</span>
<span class="co">## 2: 0.7002851  NA  NA 0.8364063 0.2840135 0.3339171</span>
<span class="co">## 3: 0.7432974  NA  NA 0.8748075 0.2807313 0.3247225</span>
<span class="co">## 4: 0.6655245  NA  NA 0.7712665 0.3006362 0.3854653</span></code></pre>
</div>
<div class="section level2">
<h2 id="aggregate-time-series-over-seasons">Aggregate time series over seasons<a class="anchor" aria-label="anchor" href="#aggregate-time-series-over-seasons"></a>
</h2>
<p>This additional step can be performed to aggregate time series on the
basis of the information extracted from the seasonal analysis.</p>
<p>The function accepts as inputs a time series (in the
<code>s2ts</code> format) and a data table produced by
<code><a href="../reference/cut_cycles.html">cut_cycles()</a></code>, <code><a href="../reference/assign_season.html">assign_season()</a></code> or
<code><a href="../reference/extract_pheno.html">extract_pheno()</a></code>. The aggregation can be defined setting
arguments <code>metrics</code> (the two phenological metrics to be used
as lower and upper limit) and <code>fun</code> (the aggregation
function). Output is a <code>data.table</code> with the same length of
<code>pheno</code>, in which each record contains the aggregate value of
the time series over the specified cycle.</p>
<p>In the example below, 95% percentiles among the dates of Start and
End of Season (used as quasi-maximum values) are extracted.</p>
<div class="sourceCode" id="cb33"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span class="op">(</span> <span class="va">dt_aggr</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/aggregate_pheno.html">aggregate_pheno</a></span><span class="op">(</span>
  <span class="va">ts_filled</span>, <span class="va">dt_pheno_seas</span>, 
  metrics <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"sos"</span>, <span class="st">"eos"</span><span class="op">)</span>, fun <span class="op">=</span> <span class="st">"quantile"</span>, probs <span class="op">=</span> <span class="fl">0.95</span>, na.rm <span class="op">=</span> <span class="cn">TRUE</span>
<span class="op">)</span> <span class="op">)</span></code></pre></div>
<pre><code><span class="co">##    id year cycle     value</span>
<span class="co">## 1: 01 2019     1 0.6810734</span>
<span class="co">## 2: 01 2020     1 0.8401771</span>
<span class="co">## 3: 03 2020     1 0.8863815</span>
<span class="co">## 4: 04 2019     1 0.7802313</span></code></pre>
</div>
  </div>

  <div class="col-md-3 hidden-xs hidden-sm" id="pkgdown-sidebar">

        <nav id="toc" data-toggle="toc"><h2 data-toc-skip>Contents</h2>
    </nav>
</div>

</div>



      <footer><div class="copyright">
  <p></p>
<p>Developed by Luigi Ranghetti.</p>
</div>

<div class="pkgdown">
  <p></p>
<p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a>
2.0.2.</p>
</div>

      </footer>
</div>

  


  

  </body>
</html>
