Skip to content

Add detrending methods #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Jul 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 15 additions & 36 deletions .github/workflows/CompatHelper.yml
Original file line number Diff line number Diff line change
@@ -1,45 +1,24 @@
name: CompatHelper

on:
schedule:
- cron: 0 0 * * *
workflow_dispatch:
permissions:
contents: write
pull-requests: write
- cron: '00 * * * *'

jobs:
CompatHelper:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
julia-version: [1]
julia-arch: [x86]
os: [ubuntu-latest]
steps:
- name: Check if Julia is already available in the PATH
id: julia_in_path
run: which julia
continue-on-error: true
- name: Install Julia, but only if it is not already available in the PATH
uses: julia-actions/setup-julia@v1
- uses: julia-actions/setup-julia@latest
with:
version: '1'
arch: ${{ runner.arch }}
if: steps.julia_in_path.outcome != 'success'
- name: "Add the General registry via Git"
run: |
import Pkg
ENV["JULIA_PKG_SERVER"] = ""
Pkg.Registry.add("General")
shell: julia --color=yes {0}
- name: "Install CompatHelper"
run: |
import Pkg
name = "CompatHelper"
uuid = "aa819f21-2bde-4658-8897-bab36330d9b7"
version = "3"
Pkg.add(; name, uuid, version)
shell: julia --color=yes {0}
- name: "Run CompatHelper"
run: |
import CompatHelper
CompatHelper.main()
shell: julia --color=yes {0}
version: ${{ matrix.julia-version }}
- name: Pkg.add("CompatHelper")
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
- name: CompatHelper.main()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }}
# COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }}
run: julia -e 'using CompatHelper; CompatHelper.main()'
2 changes: 1 addition & 1 deletion .github/workflows/TagBot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
ssh: ${{ secrets.DOCUMENTER_KEY }}
ssh: ${{ secrets.DOCUMENTER_KEY }}
42 changes: 18 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ name: CI
on:
pull_request:
branches:
- master
- main
- '**' # matches every branch
push:
branches:
- master
- main
tags: '*'
jobs:
test:
Expand All @@ -15,17 +16,25 @@ jobs:
fail-fast: false
matrix:
version:
- '1' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
os: [ubuntu-latest]
- '1'
os: [ubuntu-latest] # adjust according to need, e.g. os: [ubuntu-latest] if testing only on linux
arch:
- x64
steps:
# Cancel ongoing CI test runs if pushing to branch again before the previous tests
# have finished
- name: Cancel ongoing test runs for previous commits
uses: styfle/cancel-workflow-action@0.6.0
with:
access_token: ${{ github.token }}

# Do tests
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: actions/cache@v1
- uses: actions/cache@v4
env:
cache-name: cache-artifacts
with:
Expand All @@ -36,24 +45,9 @@ jobs:
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@v1

- uses: julia-actions/julia-runtest@v1
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
with:
version: '1'
- name: Instantiate and install dependencies
run: |
julia --project=docs -e '
using Pkg
Pkg.develop(PackageSpec(path=pwd()))
Pkg.instantiate()'
- name: Generate documentation and deploy
env: # needed for pushing to gh-pages branch
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
run:
julia --project=docs docs/make.jl
file: lcov.info
26 changes: 26 additions & 0 deletions .github/workflows/doccleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Doc Preview Cleanup

on:
pull_request:
types: [closed]

jobs:
doc-preview-cleanup:
runs-on: ubuntu-latest
steps:
- name: Checkout gh-pages branch
uses: actions/checkout@v2
with:
ref: gh-pages
- name: Delete preview and history + push changes
run: |
if [ -d "previews/PR$PRNUM" ]; then
git config user.name "Documenter.jl"
git config user.email "documenter@juliadocs.github.io"
git rm -rf "previews/PR$PRNUM"
git commit -m "delete preview"
git branch gh-pages-new $(echo "delete history" | git commit-tree HEAD^{tree})
git push --force origin gh-pages-new:gh-pages
fi
env:
PRNUM: ${{ github.event.number }}
26 changes: 26 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Documentation

on:
push:
branches:
- main
tags: '*'
pull_request:

jobs:
build:
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: '1'
- name: Install dependencies
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # If authenticating with GitHub Actions token
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # If authenticating with SSH deploy key
run: julia --project=docs/ docs/make.jl
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ videos
plots
notebooks
_research
docs/build_docs_with_style.jl

################################################################################
# Julia #
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*changelog kept with respect to version 1.0*

# v1.2

- Add new functionality for the package: detrending
- Add new functionality for the package: smoothing
- Add new `Decompositions`: `PolynomialDetrending, NoDecomposition, MovingAverageSmoothing, LoessSmoothing, HodrickPrescott`.
- Package is now part of DynamicalSystems.jl as well under the category "Nonlinear Timeseries Analysis".

# v1.1

Update to Julia 1.9, and bump dependency compatibility versions to those of Julia 1.9+.
16 changes: 7 additions & 9 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "SignalDecomposition"
uuid = "11a47235-7b84-4c7c-b885-fc3e2a9cf955"
authors = ["Datseris <datseris.george@gmail.com>"]
version = "1.1.0"
version = "1.2.0"

[deps]
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
Expand All @@ -10,8 +10,11 @@ DelayEmbeddings = "5732040d-69e3-5649-938a-b6b4f237613f"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
LPVSpectral = "26dcc766-85df-5edc-b560-6076d5dbac63"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Loess = "4345ca2d-374a-55d4-8d30-97f9976e7612"
Neighborhood = "645ca80c-8b79-4109-87ea-e1f58159d116"
Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

Expand All @@ -20,15 +23,10 @@ BandedMatrices = "1"
DelayEmbeddings = "2"
FFTW = "1.2"
LPVSpectral = "0.3"
Loess = "0.6"
Neighborhood = "0.2"
Polynomials = "4"
SparseArrays = "1.11"
StaticArrays = "1"
Statistics = "1"
julia = "1.9"

[extras]
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
DynamicalSystemsBase = "6e36e845-645a-534a-86f2-f5d4aa5a06b4"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "DelimitedFiles", "DynamicalSystemsBase"]
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
![SignalDecomposition.jl](https://github.com/JuliaDynamics/JuliaDynamics/blob/master/videos/other/signaldecomposition.gif?raw=true)
[![docsdev](https://img.shields.io/badge/docs-dev-lightblue.svg)](https://juliadynamics.github.io/DynamicalSystemsDocs.jl/signaldecomposition/dev/)
[![docsstable](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliadynamics.github.io/DynamicalSystemsDocs.jl/signaldecomposition/stable/)
[![CI](https://github.com/JuliaDynamics/SignalDecomposition.jl/workflows/CI/badge.svg)](https://github.com/JuliaDynamics/SignalDecomposition.jl/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/JuliaDynamics/SignalDecomposition.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/JuliaDynamics/SignalDecomposition.jl)

| **Documentation** | **Tests** | **Chat** |
|:--------:|:---------------:|:-----:|
|[![](https://img.shields.io/badge/docs-online-blue.svg)](https://JuliaDynamics.github.io/SignalDecomposition.jl/dev)| [![CI](https://github.com/juliadynamics/SignalDecomposition.jl/workflows/CI/badge.svg)](https://github.com/JuliaDynamics/SignalDecomposition.jl/actions) | [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/JuliaDynamics/Lobby)
SignalDecomposition.jl is a Julia package providing an interface and dozens of algorithm implementations for signal decomposition.
Given a signal (or timeseries), the function `decompose` splits it into two components.
These may be:

- structure and noise (de-noising or smoothing)
- seasonal and residual (climatologies or anomalies)
- trend and residual (de-trending)

Decompose a signal/timeseries into structure and noise or seasonal and residual components.
Further info in the docs!
It can be used as a standalone package, or as part of
[DynamicalSystems.jl](https://juliadynamics.github.io/DynamicalSystemsDocs.jl/dynamicalsystems/stable/).

To install it, run `import Pkg; Pkg.add("SignalDecomposition")`.

All further information is provided in the documentation, which you can either find [online](https://juliadynamics.github.io/DynamicalSystemsDocs.jl/signaldecomposition/stable/) or build locally by running the `docs/make.jl` file.
7 changes: 5 additions & 2 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8"
DynamicalSystems = "61744808-ddfa-5f27-97ff-6e42cc95d634"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PredefinedDynamicalSystems = "31e2f376-db9e-427a-b76e-a14f56347a14"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
SignalDecomposition = "11a47235-7b84-4c7c-b885-fc3e2a9cf955"
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"

[compat]
PredefinedDynamicalSystems = "1.4"
62 changes: 17 additions & 45 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,49 +1,21 @@
using Pkg
Pkg.activate(@__DIR__)
CI = get(ENV, "CI", nothing) == "true" || get(ENV, "GITHUB_TOKEN", nothing) !== nothing
CI && Pkg.instantiate()
CI && (ENV["GKSwstype"] = "100")
cd(@__DIR__)
using SignalDecomposition
decompose = SignalDecomposition.decompose
using PredefinedDynamicalSystems

using SignalDecomposition, Documenter, DocumenterTools
using DocumenterTools: Themes
using Plots

# %%
# download the themes
for file in ("juliadynamics-lightdefs.scss", "juliadynamics-darkdefs.scss", "juliadynamics-style.scss")
download("https://raw.githubusercontent.com/JuliaDynamics/doctheme/master/$file", joinpath(@__DIR__, file))
end
# create the themes
for w in ("light", "dark")
header = read(joinpath(@__DIR__, "juliadynamics-style.scss"), String)
theme = read(joinpath(@__DIR__, "juliadynamics-$(w)defs.scss"), String)
write(joinpath(@__DIR__, "juliadynamics-$(w).scss"), header*"\n"*theme)
end
# compile the themes
Themes.compile(joinpath(@__DIR__, "juliadynamics-light.scss"), joinpath(@__DIR__, "src/assets/themes/documenter-light.css"))
Themes.compile(joinpath(@__DIR__, "juliadynamics-dark.scss"), joinpath(@__DIR__, "src/assets/themes/documenter-dark.css"))

makedocs(modules = [SignalDecomposition],
sitename= "SignalDecomposition.jl",
authors = "George Datseris and contributors.",
doctest = false,
format = Documenter.HTML(
prettyurls = CI,
assets = [
"assets/logo.ico",
asset("https://fonts.googleapis.com/css?family=Quicksand|Montserrat|Source+Code+Pro|Lora&display=swap", class=:css),
],
),
pages = [
"Documentation" => "index.md",
"Examples" => "examples.md",
],
"index.md",
"examples.md",
]

import Downloads
Downloads.download(
"https://raw.githubusercontent.com/JuliaDynamics/doctheme/master/build_docs_with_style.jl",
joinpath(@__DIR__, "build_docs_with_style.jl")
)
include("build_docs_with_style.jl")

if CI
deploydocs(
repo = "github.com/JuliaDynamics/SignalDecomposition.jl.git",
target = "build",
push_preview = true
)
end
build_docs_with_style(pages, SignalDecomposition;
authors = "George Datseris <datseris.george@gmail.com>",
expandfirst = ["index.md"], # this is the first script that loads colorscheme
)
Loading