diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 91e8c86..6bf7533 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,36 +1,63 @@ -# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs - -name: Node.js CI +name: Poto-Siril on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] jobs: build: - runs-on: ubuntu-latest - strategy: matrix: node-version: [18.x, 20.x, 22.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - run: npm install + - run: npm run check-types + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 + with: + node-version: 22.x + cache: "npm" + - run: npm install + - run: npm run lint + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 + with: + node-version: 22.x + cache: "npm" + - run: npm install + - run: npm run test -- --coverage + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + + test-cli: + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm install - - run: npm run lint - - run: npm run check-types - - run: npm run test -- --coverage - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} + - uses: actions/checkout@v4 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 + with: + node-version: 22.x + cache: "npm" + - run: npm install + - run: npm run test-cli \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index b4c6b4e..0ce8f8b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,24 +1,22 @@ { - "version": "0.2.0", + "version": "0.4.0", "configurations": [ { - "name": "dispatch-dump", + "name": "dev-prepare-dataset1", "type": "node", "request": "launch", "runtimeExecutable": "node", "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"], - "args": [ "src/poto-siril.ts", - "dispatch", - "-p", - "src/tests/data/project1", - "-a", - "src/tests/data/asiair-dump1", - "-b", - "src/tests/data/bank", + "prepare", + "-i", + "tmp/asiair-dump", + "-i", + "tmp/bank", + "tmp/project" ], - + "preLaunchTask": "npm: dev-prepare-ds1", "cwd": "${workspaceRoot}", "internalConsoleOptions": "openOnSessionStart", "skipFiles": ["/**", "node_modules/**"] diff --git a/README.md b/README.md index b577400..4a91c91 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ![logo](./img/poto-siril_logo.png) -Automatization around Siril () and ASIAIR for deep sky astrophotography. +Automatization around Siril () for deep sky astrophotography. [![codecov](https://codecov.io/gh/TomyCesaille/poto-siril/graph/badge.svg?token=RCF9ZV8JZ9)](https://codecov.io/gh/TomyCesaille/poto-siril) @@ -8,28 +8,41 @@ Automatization around Siril () and ASIAIR for deep sky astro **Poto-Siril is a CLI tool to automate the pre-processing of astrophotography images on top of Siril.** -Poto-Siril's primary goal is to **overcome the repetitive and tedious** work when pre-processing multiple layers before compositing a (L)RGB image (e.g. narrowband filters with monochrome camera or color camera with dual-band filters). It works with images captured by a ZWO ASIAIR device out of the box or with any `fit` files that follows the same [naming convention and directory structure](#poto-siril-project-architecture). +Poto-Siril aims to **overcome the repetitive and tedious** work when pre-processing multiple layers before compositing an (L)RGB image (e.g. narrowband filters with a monochrome camera or a color camera with dual-band filters). + +It works with images captured by a ZWO ASIAIR device out of the box or with any `fit` files that follow the same [file naming convention](#file-naming-convention) and [directory structure](#asiair-directory-structure-for-reference) (more support to come, help is welcomed 👋). ### Workflow 🚀 +The essence of Poto-Siril is about: + +- Organizing the raw data by grouping the multiple light sequences together in small groups (of the same filter, bulb, gain, etc...) tagged with the appropriate flats, darks, and biases. +- Running Siril script(s) on each group of lights to retrieve the calibrated lights, following: + +```math +Calibrated\_Light = \frac{Light\_Frame - Dark\_Frame}{Flat\_Frame} +``` + +- Stacking the calibrated lights to get a master light for each layer/filter. + ![workflow](./img/poto-siril_workflow.png) ### In detail -- **Easy import lights and flats from ASIAIR and search for associated darks and biases in bank folder** - Import one or several night sessions (lights and flats from `Autorun` or `Plan` mode with ASIAIR) and automatically pick the darks and bias from the bank folder (matching bulb, gain, binning, ...). +- **Easy import of lights and flats from night session(s) and search for associated darks and biases in a bank folder** + Import one or several night sessions (e.g. lights and flats from `Autorun` or `Plan` mode with ASIAIR) and automatically pick the darks and biases from the bank folder (matching bulb, gain, binning, ...). A summary resumes the light sequence(s) and the calibration files associated. - ![dispatch](./img/poto-siril_dispatch.png) + ![dispatch](./img/poto-siril_prepare_summary.png) - **Complex Light - Flat matching** - The project consists of multiple night sessions where the flats changed over the time? e.g., a significant date gap between shooting sessions and the lights aren't coming with the same collimation and/or dust in the optical train. - Poto-Siril will auto-detect that and help you to associate the right flats to the right lights. + Poto-Siril helps to associate the right flats with the right lights when the project consists of multiple night sessions where the flats changed over time, e.g., a significant date gap between shooting sessions having a new collimation tuning and/or new dust in the optical train. + ![flat_matching](./img/poto-siril_prepare_advanced-flats-matching.png) - **Multi-layers project structure** - The imported files ☝️ are organized by filters and light sets (bulb, gain & binning, if there's multiple combinations). Each light set will map to a light sequence in Siril that you preprocess separately. - 👉 You can easily work on a LRGB or LRGBHaOIIISII project. + The imported files ☝️ are organized by filters and light sets (bulb, gain & binning, if there are multiple combinations). Each light set will map to a light sequence in Siril to be pre-processed separately. + 👉 You can easily work on an LRGB or LRGBHaOIIISII project. - **Batch Siril script execution to pre-process the data** - Generates and run a Siril script (`.ssl` file) for each light set to preprocess the images based on a ssl file template that can be customized. + (Generates and) Runs a Siril script (`.ssl` file) to calibrate the lights for each light set, based on a customizable ssl file template. - **A/B testing** (PLANNED) - Run the (generated ☝️) Siril script with different parameters (e.g. rejection algo, sigma low/high thresholds) and compare the results. + Run the (generated ☝️) Siril script with different parameters (e.g. rejection algorithm, sigma low/high thresholds) and compare the results. Or run several different pre-processing scripts and compare the results. ### What it is not doing @@ -47,6 +60,10 @@ npm i # For Unix based systems: chmod +x ./poto.sh + +# Test the CLI: +./poto.sh -v +# Should print `poto-siril 0.3.0`. ``` Make sure to have `siril` registered in your PATH. @@ -56,35 +73,59 @@ siril -v # Should print `siril 1.2.3`. ``` -### Poto-Siril project architecture +### CLI commands -The ASIAIR directory structure is as follows: +```bash +$POTO_PROJECT=jorislacance/deepsky/poto_2024_08_10_veil-nebula + +# Prepare a Poto project by importing imaging data session(s) and "static" calibration files (darks, biases). +./poto.sh prepare \ + # e.g. ASIAIR dump folder with Autorun directory filled with lights and corresponding flats. + -i jorislacance/deepsky/sessions/asiair_2024_08_10_veil-nebula \ + # e.g. Bank folder where poto-siril will cherry-pick darks and biases as needed. + -i jorislacance/deepsky/_bank \ + # 🎉 poto project directory destination. + $POTO_PROJECT + +# Batch pre-process all the lights, set by set (filter, bulb, gain, binning...) based on a Siril script template. +export POTO_SCRIPT_TEMPLATE=src/process/mono_processing_process/1_preprocessing.ssf +./poto.sh preprocess \ + -t $POTO_SCRIPT_TEMPLATE \ + $POTO_PROJECT -```text -# Root dump directory of an ASIAIR session -├── Autorun -│ ├── Light -| | └── M42 -| | ├── Light_M42_10.0s_Bin1_S_gain360_20240320-203324_-10.0C_0001.fit -│ | ├── ... -| | ├── Light_M42_10.0s_Bin1_S_gain100_20240321-223159_-10.0C_0001.fit -| | └── ... -│ └── Flat -| ├── Flat_1.0ms_Bin1_S_gain100_20240320-233122_-10.5C_0001.fit -│ └── ... -├── Plan -│ # Same structure as Autorun. -├── Live -│ # Ignored in poto-siril -├── Preview -│ # Ignored in poto-siril -├── Video -│ # Ignored in poto-siril -└── log - # Ignored in poto-siril +# BONUS: Drop thumbnails and empty directories generated by ASIAIR. +./poto.sh clear jorislacance/deepsky/sessions/asiair_2024_08_10_veil-nebula ``` -Poto project, once imported from the ASIAIR dump via the `dispatch` command, will be broke down into the following directory structure: +### Pre-processing pipeline + +Usually, the pre-processing is a multi-step journey. The most usual case is to pre-process lights, eliminate bad ones in Siril directly, and go back to Poto-Siril to batch-run the stacking. + +You can chain multiple scripts to achieve the desired result. +See [src/process/mono_processing_process/README.md](src/process/mono_processing_process/README.md) for a full example of a pre-processing pipeline. + +#### Create your own + +You can easily create your own by following the [mono_processing_process](src/process/mono_processing_process) example. + +Some remarks about **Poto-Siril script templates**: + +- `.ssf` extension like regular Siril scripts. +- Poto-Siril dynamically overwrites the `{{poto-dir}}`, `{{lights}}`, `{{flats}}`, `{{darks}}`, `{{biases}}`, `{{process}}` & `{{masters}}` variables to the current light set to pre-process. + +### File naming convention + +Poto-Siril expects the files to follow the ASIAIR file naming convention `{Light|Flat|Dark|Bias}_{TARGET}_{EXPOSURE_TIME}{s|ms}_Bin{BINNING}_{FILTER}_gain{GAIN}_{DATE}-{TIME}_{TEMPERATURE}C_{SEQUENCE_NUMBER}.fit`. + +For example: + +- `Light_10.0s_Bin1_S_gain360_20240320-203324_-10.0C_0001.fit` +- `Light_FOV_60.0s_Bin1_S_gain100_20240624-010840_-10.1C_0001.fit` +- `Flat_1.0ms_Bin1_S_gain100_20240320-233122_-10.5C_0001.fit` +- `Dark_300.0s_Bin1_S_gain100_20240320-233122_-10.5C_0001.fit` +- `Bias_1.0ms_Bin1_S_gain100_20240320-233122_-10.5C_0001.fit` + +### Poto-Siril project architecture ```text # Poto project root directory @@ -101,16 +142,16 @@ Poto project, once imported from the ASIAIR dump via the `dispatch` command, wil ├── H ├── O ├── ... -└── any 👈 Biases & darks falls here. lights & flats too if no filter. +└── any 👈 Biases & darks fall here. lights & flats too if no filter. ``` -> 💡 `S`, `H`, `O` are the filters names defined in ASIAIR (cf Filter Wheel settings). +> 💡 `S`, `H`, `O` are the filter names defined in ASIAIR (cf Filter Wheel settings). -### The bank folder +### The bank folder (for reference) -The bank folder is where you store your **darks** and **biases** files. The bank folder does not expect a specific structure as long as files are following the ASIAIR file naming convention. +It's common to store the **darks** and **biases** in a 'bank folder' since they are quite static. Poto-siril doesn't expect any precise directory structure for a directory to act like a bank folder as long as the [file naming convention](#file-naming-convention) is respected. -A good organization could be as follows: +Example of structure: ```text # Bank directory @@ -125,41 +166,32 @@ A good organization could be as follows: └── ... ``` -### CLI commands - -```bash -# The location of your raw ASIAIR root folder (also named dump folder). -export POTO_ASIAIR_DUMP=/Users/jorislacance/deepsky/dump_2024_08_10_veil-nebula - -# Drop thumbnails and empty directories from the ASIAIR dump folder. -./poto.sh clean -a $POTO_ASIAIR_DUMP - -# Import lights to project, grouped per filter, and then light sets (bulb, gain & binning) -# with the related calibration files (flats, darks and biases). -export POTO_BANK=/Users/jorislacance/deepsky/_bank -export POTO_PROJECT=/Users/jorislacance/deepsky/poto_2024_08_10_veil-nebula - -./poto.sh dispatch -a $POTO_ASIAIR_DUMP -b $POTO_BANK -p $POTO_PROJECT - -# Process each light set based on a Siril script template. -export POTO_SCRIPT_TEMPLATE=src/process/mono_processing_process/1_preprocessing.ssf +### ASIAIR directory structure (for reference) -./poto.sh preprocess -p $POTO_PROJECT -s $POTO_SCRIPT_TEMPLATE +```text +# Root dump directory of an ASIAIR session +├── Autorun +│ ├── Light +| | └── M42 +| | ├── Light_M42_10.0s_Bin1_S_gain360_20240320-203324_-10.0C_0001.fit +│ | ├── ... +| | ├── Light_M42_10.0s_Bin1_S_gain100_20240321-223159_-10.0C_0001.fit +| | └── ... +│ └── Flat +| ├── Flat_1.0ms_Bin1_S_gain100_20240320-233122_-10.5C_0001.fit +│ └── ... +├── Plan +│ # Same structure as Autorun. +├── Live +│ # Ignored in poto-siril +├── Preview +│ # Ignored in poto-siril +├── Video +│ # Ignored in poto-siril +└── log + # Ignored in poto-siril ``` -### Full pre-processing - -See [src/process/mono_processing_process/README.md](src/process/mono_processing_process/README.md) for a full example of a pre-processing process. - -#### Create your own process - -You can easily create your own process by following the example of the [mono_processing_process](src/process/mono_processing_process) process. - -Some remarks about **Poto-Siril script templates**: - -- `.ssf` extension like regular Siril scripts. -- Poto-Siril overwrite the `{{lights}}`, `{{flats}}`, `{{darks}}`, `{{biases}}`, `{{process}}`, `{{masters}}` variables to the current light set to pre-process. - ## Development ```bash @@ -175,12 +207,10 @@ npm run check-types # Generate dataset 1 for development npm run dev-spawn-ds1 -# Run the CLI dispatch-dump with the development dataset 1 -npm run dev-dispatch-ds1 +# Run the prepare command with the development dataset 1 +npm run dev-prepare-ds1 ``` ## Side Notes -[Sirilic and Sirilot](https://siril.org/2018/11/sirilic-and-sirilot-two-very-useful-utilities-for-siril/) are two alternatives to automate Siril. This project is another take that emphasize lazyness of manipulating files in the file system, the love of Siril Scripting and A/B testing. - -"assembling the composition, making the pre-groups of lights with the right flats (days, filderss...) +[Sirilic and Sirilot](https://siril.org/2018/11/sirilic-and-sirilot-two-very-useful-utilities-for-siril/) are two alternatives to automate Siril. This project is another take that emphasizes the laziness of manipulating files in the file system, the love of Siril Scripting, and A/B testing. diff --git a/img/poto-siril_dispatch.png b/img/poto-siril_dispatch.png deleted file mode 100644 index 22dd0bb..0000000 Binary files a/img/poto-siril_dispatch.png and /dev/null differ diff --git a/img/poto-siril_prepare_advanced-flats-matching.png b/img/poto-siril_prepare_advanced-flats-matching.png new file mode 100644 index 0000000..184acc6 Binary files /dev/null and b/img/poto-siril_prepare_advanced-flats-matching.png differ diff --git a/img/poto-siril_prepare_summary.png b/img/poto-siril_prepare_summary.png new file mode 100644 index 0000000..5bc717f Binary files /dev/null and b/img/poto-siril_prepare_summary.png differ diff --git a/jest.config.ts b/jest.config.ts index a152749..a8e4f08 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -13,7 +13,7 @@ const jestConfig: JestConfigWithTsJest = { transformIgnorePatterns: [ "/node_modules/(?!chalk|ansi-escapes)", // Ensure node_modules are transformed correctly ], - setupFilesAfterEnv: ["/jest.setup.js"], + setupFilesAfterEnv: ["/jest.setup.ts"], // Add custom matcher setup file }; export default jestConfig; diff --git a/jest.d.ts b/jest.d.ts new file mode 100644 index 0000000..586f2dd --- /dev/null +++ b/jest.d.ts @@ -0,0 +1,12 @@ +import "jest"; + +declare global { + namespace jest { + interface Matchers { + /** + * Custom Jest matcher to compare snapshots with mocked path.resolve(). + */ + toMatchSnapshotWithNormalizedPaths(): R; + } + } +} \ No newline at end of file diff --git a/jest.setup.js b/jest.setup.js deleted file mode 100644 index 4a9c7e4..0000000 --- a/jest.setup.js +++ /dev/null @@ -1,3 +0,0 @@ -// Disable chalk colors since GitHub Actions doesn't support them (would conflict with e2e snapshosts). -// eslint-disable-next-line no-undef -process.env.FORCE_COLOR = "0"; diff --git a/jest.setup.ts b/jest.setup.ts new file mode 100644 index 0000000..0d4fd0e --- /dev/null +++ b/jest.setup.ts @@ -0,0 +1,42 @@ +// Disable chalk colors since GitHub Actions doesn't support them (would conflict with e2e snapshots). + +process.env.FORCE_COLOR = "0"; + +import path from "path"; +import process from "process"; +import { expect } from "@jest/globals"; // Import Jest globals +import { toMatchSnapshot } from "jest-snapshot"; // Import Jest snapshot matcher + +// TODO. Find some courage some day to refactor this properly to jest snapshotSerializers. If jest+ESM+typescript is less a burden by then. + +expect.extend({ + toMatchSnapshotWithNormalizedPaths(received) { + return toMatchSnapshot.call( + this, + normalizeReceived(received), + "", + ); + }, +}); + +const normalizeReceived = (received: string | string[]) => { + let normalized: string | string[] = received; + if (typeof received === "string") { + normalized = received.replaceAll( + new RegExp(path.resolve(process.cwd()), "gm"), + "", + ); + } else if ( + Array.isArray(received) && + received.every(item => typeof item === "string") + ) { + normalized = received.map(item => + item.replaceAll( + new RegExp(path.resolve(process.cwd()), "gm"), + "", + ), + ); + } + + return normalized; +}; diff --git a/package.json b/package.json index 0559513..f314ac3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "poto-siril", - "version": "0.2.0", + "version": "0.4.0", "description": "Automatization around Siril () and ASIAIR for deep sky astrophotography.", "main": "poto.sh", "type": "module", @@ -8,9 +8,11 @@ "lint": "eslint .", "check-types": "tsc", "test": "TZ=UTC node --experimental-vm-modules node_modules/.bin/jest --coverage src", + "test-cli": "./poto.sh --version", "dev-test": "TZ=UTC node --experimental-vm-modules node_modules/.bin/jest --coverage --watch src", "dev-spawn-ds1": "tsx ./scripts/dev-spawn-ds1.ts", - "dev-dispatch-ds1": "npm run dev-spawn-ds1 && TZ=UTC ./poto.sh dispatch -a ./tmp/asiair-dump -b ./tmp/bank -p ./tmp/project" + "dev-prepare-ds1": "npm run dev-spawn-ds1 && TZ=UTC ./poto.sh prepare -i tmp/asiair-dump -i tmp/bank tmp/project", + "dev-preprocess-ds1": "TZ=UTC ./poto.sh preprocess -t src/process/mono_processing_process/1_preprocessing.ssf tmp/project" }, "keywords": [ "siril", diff --git a/scripts-ref/Mono_Preprocessing.ssf b/scripts-ref/Mono_Preprocessing.ssf deleted file mode 100644 index 6e44a02..0000000 --- a/scripts-ref/Mono_Preprocessing.ssf +++ /dev/null @@ -1,73 +0,0 @@ -############################################ -# -# Script for Siril 1.2 -# February 2023 -# (C) Cyril Richard -# Mono_Preprocessing v1.3 -# -########### PREPROCESSING SCRIPT ########### -# -# Script for mono camera preprocessing -# -# Needs 4 sets of RAW images in the working -# directory, within 4 directories: -# biases/ -# flats/ -# darks/ -# lights/ -# Saves masters to ./masters/ -# -############################################ - -requires 1.2.0 - -# Convert Bias Frames to .fit files -cd biases -convert bias -out=../process -cd ../process - -# Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=../masters/bias_stacked -cd .. - -# Convert Flat Frames to .fit files -cd flats -convert flat -out=../process -cd ../process - -# Calibrate Flat Frames -calibrate flat -bias=../masters/bias_stacked - -# Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=../masters/pp_flat_stacked -cd .. - -# Convert Dark Frames to .fit files -cd darks -convert dark -out=../process -cd ../process - -# Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=../masters/dark_stacked -cd .. - -# Convert Light Frames to .fit files -cd lights -convert light -out=../process -cd ../process - -# Calibrate Light Frames -calibrate light -dark=../masters/dark_stacked -flat=../masters/pp_flat_stacked -cc=dark - -# Align Lights -register pp_light - -# Stack calibrated lights to result.fit -stack r_pp_light rej 3 3 -norm=addscale -output_norm -out=result - -# and flipping if required -load result -mirrorx -bottomup -save ../result_$FILTER:%s$_$LIVETIME:%d$s - -close diff --git a/scripts-ref/OSC_Extract_Ha.ssf b/scripts-ref/OSC_Extract_Ha.ssf deleted file mode 100644 index 1544766..0000000 --- a/scripts-ref/OSC_Extract_Ha.ssf +++ /dev/null @@ -1,77 +0,0 @@ -############################################ -# -# Script for Siril 1.2 -# February 2023 -# (C) Cyril Richard -# ExtractHa v1.3 -# -########### PREPROCESSING SCRIPT ########### -# -# Script for color camera preprocessing that -# extracts Ha -# -# Needs 4 sets of RAW images in the working -# directory, within 4 directories: -# biases/ -# flats/ -# darks/ -# lights/ -# Saves masters to ./masters/ -# -############################################ - -requires 1.2.0 - -# Convert Bias Frames to .fit files -cd biases -convert bias -out=../process -cd ../process - -# Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=../masters/bias_stacked -cd .. - -# Convert Flat Frames to .fit files -cd flats -convert flat -out=../process -cd ../process - -# Calibrate Flat Frames -calibrate flat -bias=../masters/bias_stacked - -# Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=../masters/pp_flat_stacked -cd .. - -# Convert Dark Frames to .fit files -cd darks -convert dark -out=../process -cd ../process - -# Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=../masters/dark_stacked -cd .. - -# Convert Light Frames to .fit files -cd lights -convert light -out=../process -cd ../process - -# Calibrate Light Frames -calibrate light -dark=../masters/dark_stacked -flat=../masters/pp_flat_stacked -cc=dark -cfa -equalize_cfa - -# Extract Ha -seqextract_Ha pp_light - -# Align lights -register Ha_pp_light -drizzle - -# Stack calibrated lights to Ha_stack -stack r_Ha_pp_light rej 3 3 -norm=addscale -output_norm -out=Ha_stack - -# and flipping if required -load Ha_stack -mirrorx -bottomup -save ../result_Ha_$LIVETIME:%d$s - -close \ No newline at end of file diff --git a/scripts-ref/OSC_Extract_HaOIII.ssf b/scripts-ref/OSC_Extract_HaOIII.ssf deleted file mode 100644 index 6a6d433..0000000 --- a/scripts-ref/OSC_Extract_HaOIII.ssf +++ /dev/null @@ -1,96 +0,0 @@ -############################################ -# -# Script for Siril 1.2 -# February 2023 -# (C) Cyril Richard -# ExtractHaOIII v1.4 -# -########### PREPROCESSING SCRIPT ########### -# -# Script for color camera preprocessing that -# extracts Ha and OIII -# -# Needs 4 sets of RAW images in the working -# directory, within 4 directories: -# biases/ -# flats/ -# darks/ -# lights/ -# Saves masters to ./masters/ -# -############################################ - -requires 1.2.0 - -# Convert Bias Frames to .fit files -cd biases -convert bias -out=../process -cd ../process - -# Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=../masters/bias_stacked -cd .. - -# Convert Flat Frames to .fit files -cd flats -convert flat -out=../process -cd ../process - -# Calibrate Flat Frames -calibrate flat -bias=../masters/bias_stacked - -# Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=../masters/pp_flat_stacked -cd .. - -# Convert Dark Frames to .fit files -cd darks -convert dark -out=../process -cd ../process - -# Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=../masters/dark_stacked -cd .. - -# Convert Light Frames to .fit files -cd lights -convert light -out=../process -cd ../process - -# Calibrate Light Frames -calibrate light -dark=../masters/dark_stacked -flat=../masters/pp_flat_stacked -cc=dark -cfa -equalize_cfa - -# Extract Ha and OIII -seqextract_HaOIII pp_light - -# Align Ha lights -register Ha_pp_light -drizzle - -# Stack calibrated Ha lights to Ha_stack (temporary) -stack r_Ha_pp_light rej 3 3 -norm=addscale -output_norm -out=results_00001 - -# and flip if required -mirrorx_single results_00001 - - -# Align OIII lights -register OIII_pp_light - -# Stack calibrated OIII lights to OIII_stack (temporary) -stack r_OIII_pp_light rej 3 3 -norm=addscale -output_norm -out=results_00002 - -# and flip if required -mirrorx_single results_00002 - -# Align the result images, small shifts and chromatic aberrations can occur -register results -transf=shift -interp=none - -# Renorm OIII to Ha using PixelMath -pm $r_results_00002$*mad($r_results_00001$)/mad($r_results_00002$)-mad($r_results_00001$)/mad($r_results_00002$)*median($r_results_00002$)+median($r_results_00001$) -save ../results/result_OIII_$LIVETIME:%d$s - -# Save Ha final result -load r_results_00001 -save ../results/result_Ha_$LIVETIME:%d$s - -close diff --git a/scripts-ref/OSC_Preprocessing.ssf b/scripts-ref/OSC_Preprocessing.ssf deleted file mode 100644 index 897a00c..0000000 --- a/scripts-ref/OSC_Preprocessing.ssf +++ /dev/null @@ -1,74 +0,0 @@ -############################################ -# -# Script for Siril 1.2 -# February 2023 -# (C) Cyril Richard -# Preprocessing v1.3 -# -########### PREPROCESSING SCRIPT ########### -# -# Script for color camera preprocessing -# -# Needs 4 sets of RAW images in the working -# directory, within 4 directories: -# biases/ -# flats/ -# darks/ -# lights/ -# Saves masters to ./masters/ -# -############################################ - -requires 1.2.0 - -# Convert Bias Frames to .fit files -cd biases -convert bias -out=../process -cd ../process - -# Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=../masters/bias_stacked -cd .. - -# Convert Flat Frames to .fit files -cd flats -convert flat -out=../process -cd ../process - -# Calibrate Flat Frames -calibrate flat -bias=../masters/bias_stacked - -# Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=../masters/pp_flat_stacked -cd .. - -# Convert Dark Frames to .fit files -cd darks -convert dark -out=../process -cd ../process - -# Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=../masters/dark_stacked -cd .. - -# Convert Light Frames to .fit files -cd lights -convert light -out=../process -cd ../process - -# Calibrate Light Frames -calibrate light -dark=../masters/dark_stacked -flat=../masters/pp_flat_stacked -cc=dark -cfa -equalize_cfa -debayer - -# Align lights -register pp_light - -# Stack calibrated lights to result.fit -stack r_pp_light rej 3 3 -norm=addscale -output_norm -rgb_equal -out=result - -# flip if required -load result -mirrorx -bottomup -save ../result_$LIVETIME:%d$s - -cd .. -close \ No newline at end of file diff --git a/scripts-ref/OSC_Preprocessing_WithDrizzle.ssf b/scripts-ref/OSC_Preprocessing_WithDrizzle.ssf deleted file mode 100644 index 65addf7..0000000 --- a/scripts-ref/OSC_Preprocessing_WithDrizzle.ssf +++ /dev/null @@ -1,75 +0,0 @@ -############################################ -# -# Script for Siril 1.2 -# February 2023 -# (C) Cyril Richard -# OSC_Preprocessing_WithDrizzle v1.3 -# -########### PREPROCESSING SCRIPT ########### -# -# Script for color camera preprocessing -# aligning using Drizzle 2x -# -# Needs 4 sets of RAW images in the working -# directory, within 4 directories: -# biases/ -# flats/ -# darks/ -# lights/ -# Saves masters to ./masters/ -# -############################################ - -requires 1.2.0 - -# Convert Bias Frames to .fit files -cd biases -convert bias -out=../process -cd ../process - -# Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=../masters/bias_stacked -cd .. - -# Convert Flat Frames to .fit files -cd flats -convert flat -out=../process -cd ../process - -# Calibrate Flat Frames -calibrate flat -bias=../masters/bias_stacked - -# Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=../masters/pp_flat_stacked -cd .. - -# Convert Dark Frames to .fit files -cd darks -convert dark -out=../process -cd ../process - -# Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=../masters/dark_stacked -cd .. - -# Convert Light Frames to .fit files -cd lights -convert light -out=../process -cd ../process - -# Calibrate Light Frames -calibrate light -dark=../masters/dark_stacked -flat=../masters/pp_flat_stacked -cc=dark -cfa -equalize_cfa -debayer - -# Align lights with Drizzle 2x -register pp_light -drizzle - -# Stack calibrated lights to result.fit -stack r_pp_light rej 3 3 -norm=addscale -output_norm -rgb_equal -out=result - -# and flipping if required -load result -mirrorx -bottomup -save ../result_drizzle_$LIVETIME:%d$s - -cd .. -close diff --git a/scripts-ref/RGB_Composition.ssf b/scripts-ref/RGB_Composition.ssf deleted file mode 100644 index 10ba76e..0000000 --- a/scripts-ref/RGB_Composition.ssf +++ /dev/null @@ -1,27 +0,0 @@ -############################################ -# -# Script for Siril 1.2 -# February 2023 -# (C) Vincent Hourdin -# RGB_compositing v1.0 -# -########### SIMPLE RGB COMPOSTION ########### -# In an empty directory, put images named R, G and B (or any naming that -# respects this order alphanumerically) -# They will get aligned, cropped and combined into a color image - -requires 1.2.0 - -# Convert 3 input images to a sequence -convert colors -out=process -cd process - -# Make a 2pass registration -register colors -2pass - -# Crop the 3 images to their common area -seqapplyreg colors -framing=min - -# Compose the 3 layers -rgbcomp r_colors_00003 r_colors_00002 r_colors_00001 -out=../rgb - diff --git a/src/commands/asiair-dump-cleaning.ts b/src/commands/clear.ts similarity index 85% rename from src/commands/asiair-dump-cleaning.ts rename to src/commands/clear.ts index f70986e..379b440 100644 --- a/src/commands/asiair-dump-cleaning.ts +++ b/src/commands/clear.ts @@ -8,14 +8,14 @@ import path from "path"; import { logger } from "../utils/logger"; -export const cleanThumbnails = (dir: string, isRecursive: boolean = false) => { +export const dropThumbnails = (dir: string, isRecursiveCall: boolean = false) => { // Default parameter set to current directory const files = fs.readdirSync(dir); files.forEach(file => { const filePath = path.join(dir, file); const stat = fs.statSync(filePath); if (stat.isDirectory()) { - cleanThumbnails(filePath, true); + dropThumbnails(filePath, true); } else { if (file.endsWith("_thn.jpg")) { fs.unlinkSync(filePath); @@ -23,10 +23,10 @@ export const cleanThumbnails = (dir: string, isRecursive: boolean = false) => { } } }); - if (!isRecursive) logger.info("Asiair dump cleaning - Thumbnails deleted ✅"); + if (!isRecursiveCall) logger.info("Asiair dump cleaning - Thumbnails deleted ✅"); }; -export const removeEmptyDirectories = (dir: string) => { +export const dropEmptyDirectories = (dir: string) => { const isDirEmpty = (directory: string): boolean => { const files = fs.readdirSync(directory); if (files.length === 0) { diff --git a/src/commands/dispatch-dump.ts b/src/commands/prepare.ts similarity index 89% rename from src/commands/dispatch-dump.ts rename to src/commands/prepare.ts index b9597ff..2736f8e 100644 --- a/src/commands/dispatch-dump.ts +++ b/src/commands/prepare.ts @@ -1,9 +1,3 @@ -// Dispatch ASIAIR dump data from ASIAIR tree structure to the SIRIL process structure. - -// TODO allow filtering a range of data, for lights and flats. This will ease the process of selecting the frames -// regroup per night session (so split at noon and consider after midnight part of the previon night). this is also easing out the process. -// pre select those that are burned (daylight started to appear), probably by checking the date of the frame and location. - import fs from "fs"; import Enquirer from "enquirer"; @@ -22,34 +16,46 @@ import { } from "../utils/types"; import { POTO_JSON, POTO_VERSION } from "../utils/const"; -export type DispatchOptions = { +export type PrepareProps = { + inputDirectories: string[]; projectDirectory: string; - asiAirDirectory: string; - bankDirectory: string; }; const enquirer = new Enquirer(); -const dispatch = async ({ +const prepare = async ({ + inputDirectories, projectDirectory, - asiAirDirectory, - bankDirectory, -}: DispatchOptions) => { +}: PrepareProps) => { +// TODO. logger.command("prepare"); to introduce the command in the logs. + await ensureProjectDirectoryExists(projectDirectory); logger.step("Reading input directories"); - const inputFiles = await getAllFitsInInputDirectories( - asiAirDirectory, - projectDirectory, - ); + const inputFiles : FileImageSpec[] = []; + for (const inputDirectory of inputDirectories){ + logger.debug(`Reading input directory ${inputDirectory}`); + const files = await getAllFitsInInputDirectory( + inputDirectory, + projectDirectory, + ); + inputFiles.push(...files); + } const allLights = inputFiles.filter(file => file.type === "Light"); + const allLightsFlats = inputFiles.filter(file => file.type === "Light" || file.type === "Flat"); + const allDarksBiases = inputFiles.filter(file => file.type === "Dark" || file.type === "Bias"); + + logger.info( + `Found ${inputFiles.length} .fit files in input directories 🌋.`, + ); + logger.info(`Including ${allLights.length} lights 🌟.`); logger.step("Matching lights and flats (early stage)"); const allFlatsMatchingLights = getFlatsMatchingLightsNaive( - inputFiles, + allLightsFlats, allLights, ); @@ -68,12 +74,11 @@ const dispatch = async ({ logger.step("Tagging darks and biases"); - const bankFiles = getAllFitsInBankDirectories( - bankDirectory, - projectDirectory, - ); + logger.info(`Found ${allDarksBiases.length} darks+baises files.`); + + layerSets = AssignDarksBiasesToLayerSets(layerSets, allDarksBiases); - layerSets = AssignDarksBiasesToLayerSets(layerSets, bankFiles); + // TODO. Create a summary just like `👉 Light - Flat matching summary:` logger.step("Preview before dispatching"); @@ -99,7 +104,7 @@ const dispatch = async ({ // TODO. custom sort if LRGBSHO filter names to ease reading. }; -export default dispatch; +export default prepare; /** * Ensure that the project directory exists. @@ -129,18 +134,42 @@ export const selectedInputSubDirectoryChoices: SelectedInputSubDirectoryChoices[ ["Use Autorun directory", "Use Plan directory", "Use both directory"]; /** - * Retrieve all FITS files from the input directories. + * Retrieve all FITS files from the input directory. * - * @param asiAirDirectory - The directory where ASIAIR files are stored. + * @param inputDirectory - The directory to scan. * @param projectDirectory - The directory of the current project. * @returns An array of FileImageSpec objects representing the FITS files. */ -const getAllFitsInInputDirectories = async ( - asiAirDirectory: string, +const getAllFitsInInputDirectory = async ( + inputDirectory: string, projectDirectory: string, ): Promise => { - // ASIAIR stores the lights+flats files in either the Autorun or Plan directories. - const autorunDirectory = `${asiAirDirectory}/Autorun`; + // if ASIAIR used, may stores the lights+flats files in either the Autorun or Plan directories. + + const autorunDirectory = `${inputDirectory}/Autorun`; + const planDirectory = `${inputDirectory}/Plan`; + + const isAsiAirDump = fs.existsSync(autorunDirectory) || fs.existsSync(planDirectory); + + const logFiles = (files: unknown[]) => { + logger.info(`Found ${files.length} files in input dir(s) to dispatch.`); + }; + + if (!isAsiAirDump) { + const allFiles = getFitsFromDirectory({ + directory: inputDirectory, + projectDirectory, + }); + if (allFiles.length === 0) { + logger.errorThrow(`No FITS files found in ${inputDirectory}.`); + } + + logFiles(allFiles); + return allFiles; + } + + logger.debug(`ASIAIR dump detected in ${inputDirectory}.`); + const autorunFiles = fs.existsSync(autorunDirectory) ? getFitsFromDirectory({ directory: autorunDirectory, @@ -148,7 +177,6 @@ const getAllFitsInInputDirectories = async ( }) : []; - const planDirectory = `${asiAirDirectory}/Plan`; const planFiles = fs.existsSync(planDirectory) ? getFitsFromDirectory({ directory: planDirectory, @@ -156,12 +184,8 @@ const getAllFitsInInputDirectories = async ( }) : []; - const logFiles = (files: unknown[]) => { - logger.info(`Found ${files.length} files in input dir(s) to dispatch.`); - }; - if (autorunFiles.length === 0 && planFiles.length === 0) { - logger.errorThrow("No FITS files found in the input directories."); + logger.errorThrow("No FITS files found in Autorun nor Plan folders."); } if (autorunFiles.length > 0 && planFiles.length === 0) { @@ -179,7 +203,7 @@ const getAllFitsInInputDirectories = async ( type: "select", name: "selectedInputSubDirectory", message: - "Files found in both Autorun and Plan directories. How to do we proceed?", + "Files found in both Autorun and Plan directories. How do we proceed?", choices: selectedInputSubDirectoryChoices, })) as { selectedInputSubDirectory: SelectedInputSubDirectoryChoices }; @@ -450,25 +474,6 @@ const initLayerSetsWithLightsnFlats = ( return layerSets; }; -/** - * Retrieve all FITS files from the input directories. - * - * @param bankDirectory - The directory where ASIAIR files are stored. - * @param projectDirectory - The directory of the current project. - * @returns An array of FileImageSpec objects representing the FITS files. - */ -const getAllFitsInBankDirectories = ( - bankDirectory: string, - projectDirectory: string, -): FileImageSpec[] => { - const files = getFitsFromDirectory({ - directory: bankDirectory, - projectDirectory, - }); - logger.info(`Found ${files.length} files in the bank.`); - return files; -}; - /** * Assign darks and biases to the layer sets. * We darks are assigned to lights, and biases are assigned to flats. diff --git a/src/commands/run-scripts.ts b/src/commands/preprocess.exec-scripts.ts similarity index 75% rename from src/commands/run-scripts.ts rename to src/commands/preprocess.exec-scripts.ts index 4fbcef7..eda349e 100644 --- a/src/commands/run-scripts.ts +++ b/src/commands/preprocess.exec-scripts.ts @@ -6,7 +6,7 @@ import { GENERATED_SCRIPT_PREFIX } from "../utils/const"; export const runScripts = async ( projectDirectory: string, - scriptPath: string, + scriptTemplatePath: string, ) => { const scripts = fs .readdirSync(projectDirectory, { @@ -17,17 +17,23 @@ export const runScripts = async ( .filter( f => path.basename(f) === - `${GENERATED_SCRIPT_PREFIX}${path.basename(scriptPath)}`, + `${GENERATED_SCRIPT_PREFIX}${path.basename(scriptTemplatePath)}`, ) .map(f => path.join(projectDirectory, f)); logger.debug(`${scripts.length} scripts found to run.`); + const cwd = path.resolve(projectDirectory); + logger.debug("Siril CWD:", cwd); + + for (const script of scripts) { logger.info(`Running script ${script}`); - const child = execa("siril", ["-s", script], { - cwd: path.dirname(script), + const scriptRelativeToCwD = path.relative(cwd, script); + + const child = execa("siril", ["-s", scriptRelativeToCwD], { + cwd, }); child.stdout?.pipe(process.stdout); diff --git a/src/commands/generate-scripts.ts b/src/commands/preprocess.generate-scripts.ts similarity index 72% rename from src/commands/generate-scripts.ts rename to src/commands/preprocess.generate-scripts.ts index 8849d6c..91876ac 100644 --- a/src/commands/generate-scripts.ts +++ b/src/commands/preprocess.generate-scripts.ts @@ -10,9 +10,9 @@ import { export const generateScripts = async ( projectDirectory: string, - scriptPath: string, + scriptTemplatePath: string, ) => { - const scriptTemplate = fs.readFileSync(scriptPath, { + const scriptTemplate = fs.readFileSync(scriptTemplatePath, { encoding: "utf8", }); @@ -31,7 +31,7 @@ export const generateScripts = async ( generateScriptForLightSet( projectDirectory, set, - path.basename(scriptPath), + path.basename(scriptTemplatePath), scriptTemplate, ); }); @@ -47,7 +47,6 @@ const generateScriptForLightSet = ( ) => { const filter = set.filter; const filterDirectory = path.join(projectDirectory, filter); - const anyDirectory = path.join(projectDirectory, "any"); const processDirectory = path.join( filterDirectory, `${set.layerSetId}_process`, @@ -63,14 +62,6 @@ const generateScriptForLightSet = ( fs.mkdirSync(mastersDirectory, { recursive: false }); } - logger.debug("directories", { - anyDirectory, - filterDirectory, - processDirectory, - mastersDirectory, - }); - - // TODO. Move checkers to dispatch-dump. const lightsdirs = [...new Set(set.lights.map(x => x.projectDirectory))]; if (lightsdirs.length === 0) { throw new Error("No lights found for filter " + set.layerSetId); @@ -78,7 +69,7 @@ const generateScriptForLightSet = ( if (lightsdirs.length > 1) { logger.errorThrow("Multiple sets of light for ", lightsdirs); } - const lightsDir = lightsdirs[0]; + const lightsDir = path.resolve(lightsdirs[0]); const flatsDirs = [...new Set(set.flats.map(x => x.projectDirectory))]; if (flatsDirs.length === 0) { @@ -87,7 +78,7 @@ const generateScriptForLightSet = ( if (flatsDirs.length > 1) { throw new Error("Multiple sets of flat for " + set.layerSetId); } - const flatsDir = flatsDirs[0]; + const flatsDir = path.resolve(flatsDirs[0]); const darksDirs = [...new Set(set.darks.map(x => x.projectDirectory))]; if (darksDirs.length === 0) { @@ -96,7 +87,7 @@ const generateScriptForLightSet = ( if (darksDirs.length > 1) { throw new Error("Multiple sets of darks for " + set.layerSetId); } - const darksDir = darksDirs[0]; + const darksDir = path.resolve(darksDirs[0]); const biasesDirs = [...new Set(set.biases.map(x => x.projectDirectory))]; if (biasesDirs.length === 0) { @@ -105,32 +96,34 @@ const generateScriptForLightSet = ( if (biasesDirs.length > 1) { throw new Error("Multiple sets of biases for " + set.layerSetId); } - const biasesDir = biasesDirs[0]; + const biasesDir = path.resolve(biasesDirs[0]); - logger.info("dirs", { - lightDir: lightsDir, - flatsdir: flatsDir, - darksdir: darksDir, - biasesdir: biasesDir, - }); + const projectDirectoryAbs = path.resolve(projectDirectory); + const processDirAbs = path.resolve(processDirectory); + const masterDirAbs = path.resolve(mastersDirectory); + + // TODO. Check that the script has the variables, warn if none. const script = scriptTemplate + .replaceAll("{{poto-dir}}", projectDirectoryAbs) .replaceAll("{{biases}}", biasesDir) .replaceAll("{{darks}}", darksDir) .replaceAll("{{flats}}", flatsDir) .replaceAll("{{lights}}", lightsDir) - .replaceAll("{{process}}", processDirectory) - .replaceAll("{{masters}}", mastersDirectory); + .replaceAll("{{process}}", processDirAbs) + .replaceAll("{{masters}}", masterDirAbs); const processingScriptPath = path.join( processDirectory, `${GENERATED_SCRIPT_PREFIX}${scriptName}`, ); fs.writeFileSync(processingScriptPath, script); - logger.info(`Generated ${processingScriptPath}`, { - biasesDir, - darksDir, - flatsDir, - lightsDir, - }); + logger.info(`Generated ${processingScriptPath}`); + logger.debug(`- {{poto-dir}} 👉 ${projectDirectoryAbs}`); + logger.debug(`- {{lights}} 👉 ${lightsDir}`); + logger.debug(`- {{flats}} 👉 ${flatsDir}`); + logger.debug(`- {{darks}} 👉 ${darksDir}`); + logger.debug(`- {{biases}} 👉 ${biasesDir}`); + logger.debug(`- {{process}} 👉 ${processDirAbs}`); + logger.debug(`- {{masters}} 👉 ${masterDirAbs}`); }; diff --git a/src/poto-siril.ts b/src/poto-siril.ts index 4a1f07b..6ff1746 100644 --- a/src/poto-siril.ts +++ b/src/poto-siril.ts @@ -1,67 +1,56 @@ import { Command } from "commander"; -import dispatch from "./commands/dispatch-dump"; +import prepare, { PrepareProps } from "./commands/prepare"; import { - cleanThumbnails, - removeEmptyDirectories, -} from "./commands/asiair-dump-cleaning"; -import { generateScripts } from "./commands/generate-scripts"; -import { runScripts } from "./commands/run-scripts"; + dropThumbnails, + dropEmptyDirectories, +} from "./commands/clear"; +import { generateScripts } from "./commands/preprocess.generate-scripts"; +import { runScripts } from "./commands/preprocess.exec-scripts"; import { POTO_VERSION } from "./utils/const"; const program = new Command(); program .name("poto-siril") - .description("CLI to some ASIAIR import and SIRIL processing") - .version(POTO_VERSION); - -// const parseMode = (value: string, previous: string) => { -// if (value != "autorun" && value != "plan") { -// throw new InvalidArgumentError("Unknown mode. Use `autorun` or `plan`."); -// } -// return value; -// }; + .description("CLI tool to automate the pre-processing of astrophotography images on top of Siril.") + .version(POTO_VERSION, "-v, --version", "output the current version"); program - .command("clean") + .command("clear") .description( - "prepare the ASIAIR dump directory for import by dropping thumbnails and empty directories", + "Drop thumbnails and empty directories from an ASIAIR dump.", ) - .option("-a, --asiair ", "ASIAIR directory") + .argument("", "directory to clear") .allowExcessArguments(false) - .action(option => { - cleanThumbnails(option.asiair); - removeEmptyDirectories(option.asiair); + .action(directory => { + dropThumbnails(directory); + dropEmptyDirectories(directory); }); program - .command("dispatch") - .description("Dispatch ASIAIR files and bank data to a project directory") - // .argument("[path]", "project directory", ".") - .option("-p, --project ", "project directory") - .option("-a, --asiair ", "ASIAIR directory") - .option("-b, --bank ", "Biases & Darks bank directory") - .action(options => { - dispatch({ - projectDirectory: options.project, - asiAirDirectory: options.asiair, - bankDirectory: options.bank, - }); + .command("prepare") + .description("Prepare a poto project importing the light frames, and the calibration frames more or less picked automatically.") + .option("-i, --input ", "directory(ies) to pick from. Will take all lights files. Flats, darks, and biases based on lights.", (value, previous) => previous.concat([value]), []) + .argument("", "poto project directory destination") + .allowExcessArguments(false) + .action((projectDirectory, options) => { + prepare({ + inputDirectories: options.input, + projectDirectory, + } as PrepareProps); }); program .command("preprocess") - .description("Preprocess the project directory") - .option("-p, --project ", "project directory") + .description("Preprocess using a Siril script (Poto-Siril's Siril script template).") .option( - "-s, --script ", - "ssl script path", - "./process/mono_processing_process/1_preprocessing.ssf", + "-t, --template ", "path to the (Poto-)Siril script template", ) + .argument("", "poto project directory") .allowExcessArguments(false) - .action(options => { - generateScripts(options.project, options.script).then(() => { - runScripts(options.project, options.script); + .action((projectDirectory, options) => { + generateScripts(projectDirectory, options.template).then(() => { + runScripts(projectDirectory, options.template); }); }); diff --git a/src/process/mono_processing_process/1_preprocessing.ssf b/src/process/mono_processing_process/1_preprocessing.ssf index e007800..9544987 100644 --- a/src/process/mono_processing_process/1_preprocessing.ssf +++ b/src/process/mono_processing_process/1_preprocessing.ssf @@ -11,6 +11,7 @@ ############################################ # # Variables: +# poto-dir: {{poto-dir}}/ # biases: {{biases}}/ # flats: {{flats}}/ # darks: {{darks}}/ diff --git a/src/process/mono_processing_process/3_stack_lights.ssf b/src/process/mono_processing_process/3_stack_lights.ssf index fc66c20..278a6c7 100644 --- a/src/process/mono_processing_process/3_stack_lights.ssf +++ b/src/process/mono_processing_process/3_stack_lights.ssf @@ -11,6 +11,7 @@ ############################################ # # Variables: +# poto-dir: {{poto-dir}}/ # biases: {{biases}}/ # flats: {{flats}}/ # darks: {{darks}}/ diff --git a/src/tests/data-sample/Bias_1.0ms_Bin1_gain0_20240807-142905_-9.6C_0001.fit b/src/tests/data-sample/Bias_1.0ms_Bin1_gain0_20240807-142905_-9.6C_0001.fit new file mode 100755 index 0000000..1ad1f21 Binary files /dev/null and b/src/tests/data-sample/Bias_1.0ms_Bin1_gain0_20240807-142905_-9.6C_0001.fit differ diff --git a/src/tests/data-sample/Dark_60.0s_Bin1_gain0_20240807-162149_-10.0C_0001.fit b/src/tests/data-sample/Dark_60.0s_Bin1_gain0_20240807-162149_-10.0C_0001.fit new file mode 100755 index 0000000..9e2d306 Binary files /dev/null and b/src/tests/data-sample/Dark_60.0s_Bin1_gain0_20240807-162149_-10.0C_0001.fit differ diff --git a/src/tests/data-sample/Flat_1.2s_Bin1_H_gain0_20240811-025058_-9.8C_0001.fit b/src/tests/data-sample/Flat_1.2s_Bin1_H_gain0_20240811-025058_-9.8C_0001.fit new file mode 100755 index 0000000..32ad2f9 Binary files /dev/null and b/src/tests/data-sample/Flat_1.2s_Bin1_H_gain0_20240811-025058_-9.8C_0001.fit differ diff --git a/src/tests/data-sample/Light_NGC6992_60.0s_Bin1_H_gain100_20240811-010756_-10.2C_0001.fit b/src/tests/data-sample/Light_NGC6992_60.0s_Bin1_H_gain100_20240811-010756_-10.2C_0001.fit new file mode 100755 index 0000000..92bc6d4 --- /dev/null +++ b/src/tests/data-sample/Light_NGC6992_60.0s_Bin1_H_gain100_20240811-010756_-10.2C_0001.fit @@ -0,0 +1,2 @@ +SIMPLE = T / file does conform to FITS standard BITPIX = 16 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 3008 / length of data axis 1 NAXIS2 = 3008 / length of data axis 2 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H BZERO = 32768 / offset data range to that of unsigned short BSCALE = 1 / default scaling factor CREATOR = 'ZWO ASIAIR Mini' / Capture software OFFSET = 70 / camera offset XORGSUBF= 0 / Subframe X position in binned pixels YORGSUBF= 0 / Subframe Y position in binned pixels FOCALLEN= 1007 / Focal length of telescope in mm SET-TEMP= -10 / CCD temperature setpoint in degrees C EGAIN = 1.00560426712036 / Electronic gain in e-/ADU XBINNING= 1 / Camera X Bin YBINNING= 1 / Camera Y Bin CCDXBIN = 1 / Camera X Bin CCDYBIN = 1 / Camera Y Bin XPIXSZ = 3.75999999046326 / pixel size in microns (with binning) YPIXSZ = 3.75999999046326 / pixel size in microns (with binning) IMAGETYP= 'Light ' / Type of image EXPOSURE= 60. / Exposure time in seconds EXPTIME = 60. / Exposure time in seconds CCD-TEMP= -10.1999998092651 / sensor temperature in C RA = 314.22525 / Object Right Ascension in degrees DEC = 31.940627 / Object Declination in degrees DATE-OBS= '2024-08-10T23:06:54.826010' / Image exposure start time FILTER = 'H ' / Filter used when taking image INSTRUME= 'ZWO ASI533MM Pro' / Camera model GUIDECAM= 'ZWO ASI224MC' / Guide camera model GAIN = 100 / Gain Value FOCUSPOS= 5127 / Focuser position in steps TELESCOP= 'EQMod Mount' / Telescope name CTYPE1 = 'RA---TAN-SIP' / TAN (gnomic) projection + SIP distortions CTYPE2 = 'DEC--TAN-SIP' / TAN (gnomic) projection + SIP distortions CRVAL1 = 313.784038285 / RA of reference point CRVAL2 = 31.6333028979 / DEC of reference point CRPIX1 = 2386.75680542 / X reference pixel CRPIX2 = 2328.60321045 / Y reference pixel CD1_1 = -0.000210392249782 / Transformation matrix CD1_2 = 3.75209072702E-05 / no comment CD2_1 = -3.74096005855E-05 / no comment CD2_2 = -0.000210350468404 / no comment A_ORDER = 2 / Polynomial order, axis 1 B_ORDER = 2 / Polynomial order, axis 2 AP_ORDER= 2 / Inv polynomial order, axis 1 BP_ORDER= 2 / Inv polynomial order, axis 2 A_0_0 = 0 / no comment A_0_1 = 0 / no comment A_0_2 = 4.44835287928E-09 / no comment A_1_0 = 0 / no comment A_1_1 = 1.54168169723E-08 / no comment A_2_0 = -1.87407502794E-07 / no comment B_0_0 = 0 / no comment B_0_1 = 0 / no comment B_0_2 = 3.22861210756E-08 / no comment B_1_0 = 0 / no comment B_1_1 = -3.00221338939E-07 / no comment B_2_0 = -1.11152412133E-07 / no comment AP_0_0 = 3.9979712674E-05 / no comment AP_0_1 = 4.66102223414E-09 / no comment AP_0_2 = -4.44604836415E-09 / no comment AP_1_0 = -4.06085401138E-08 / no comment AP_1_1 = -1.53856819928E-08 / no comment AP_2_0 = 1.87237879955E-07 / no comment BP_0_0 = 4.38488355694E-05 / no comment BP_0_1 = 5.36112100262E-08 / no comment BP_0_2 = -3.22573682205E-08 / no comment BP_1_0 = -2.68687717057E-07 / no comment BP_1_1 = 3.00038837054E-07 / no comment BP_2_0 = 1.10842010157E-07 / no comment IMAGEW = 3008 / Image width, in pixels. IMAGEH = 3008 / Image height, in pixels. END ܊ ؊\ȊĊ̊܊܊ @h؍<,Ȏp,p0 ؊܊܋@܊(؊ ܊Њ ̊芬Њ ܊Њ܊  ,܊Ԋ0 8TD؊P8$ȑH,܊܊̊܊(܊Њ ܊Њ$܋슼슴<؊Ԋ܊܊Њ܊܊܊ЊԊ܊ Tdt0l|8( ؊܊芬܊ ȊȊĊȊ܊Њ $܋Њ,܊$̊Ċ܊\L܊( L`8\XXPȋt<($ȊЊԊ$؊܊8ȊԊ(ԊԊ؊,܊܊􊨊 ܊܊Њ܊؊ $܊܊܊Ԋ H ܊Ԋ؊8 hh܋t<8 슰؊ ܊  ܊ЊȊ؊$Њ8܊PЊԊ̊ ܊؊ pp|0@<܊Њ܊ĊX؊܊؊؊܋ 4܊؊ (؊ ؊ ܊܊ 0Ȋ ܊܊lppX@܊ Ԋ܊؋̊ ؊ ܊ ܊ ؊$Ԋ$܊$Ԋ  Њ,܊ $(0(Ԋ؊ ؊̊Ԋ܊܊؊؊슼؊܊` 䊼܊ ̊܊0 ܊ЊԊ܊Ċ0؊̊؊8,؊܊(܊܊$ ؊̊8܊܋ȋԊЊ8Ԋ$$(؊L ̊܊  ؊Њ ܊؊슠 ܊ Њ܊$Ȋ(,,؊ 슰؊Њ ܊ ȋ ܊ 슼 슸܊܊䊔,8Њ܊ԊЊ ؊ $܊̊䊰܊̊Њ܊؊ ؊؊ ܊Ԋ؊܊ԊT, ؊Ԋ$܊Ȋ,̊  Ȋ( ؊ԊȊ ؊܊ ,LT ؊܊ ؊؊D (̊$؊܊؊ ܊ L슰܊܊(܊؊芤؊Ċ̊܊ Ԋ܊܊؊8,슼􊸊܊  ĊD芰Ԋ(T(Ԋ̊ЊԊ܊(\4 ЊЊЊĊЊ$t@D܊܊؊芤܊ԊЊĊ܊ ,@PP,؊,,<$؊Њ܊􊤊,0ԊȊ스܋슬Hx@Ԋ芸􊴊̊؊܊슼Ԋ܊ $̊4X(48$Ԋ܊芰܊܊Њ܊􊴊L4  ԊԊ̊܊ ܊슴܋ĊȊ4؊Ԋ슬( ܊ 芼ԊȊ,؊ȊԊ ܊܊ Ȋ Ȋ܊芼Ԋ܊ԊЊ܊l؊܊Ћ$܊܊؊ @ Ċ Ċ  ܊Ԋ܊ԊЊ Ԋ܊܊؊ ,ԋ ܊܊Ċ􊼊 芸܊Њ(Ȋ؊ ܊ 슴 ܊Ԋ䊼܊Ԋ$(܊􊸊Њ슠܊䊤܊Ԋ ؊(؊؊܊̊ h$ԊH܊؊ Ȋ܊@<؊ 􊴊4Ԋ ( ܊Ԋ܋ 0؊܊ 􊜊 Ȋ(܊؊܊̊܊܊XȊ܊ԊH؊܊܊ԊЊ  ؊Њ܊܊Њ؊􊤊Њ̊ Ȋ4($؊Њ슰܊ ȊЊ4Ԋ ܊ ̊L؊Ԋ؊44 ؊܊Ȋ܊(( ܊ ̊Њ$܊܊$܊܋̊؊܊8܊ ̊,􊤊̊؊芨 Pt\$܊܊ԊЊ؊ ܊܊܊슸܊ЊԊ؊ ܊܊܊(Td؊ ؊$ ̊Ԋ  ܊ (؊؊؊؊܊؊  Ċ ԊЊX <Ȋ@܊܊ЊԊȊ Ԋ􊨊 ؊܊ Ȋ$؊̊0<0 Ȋ܊̊Ԋ܊< $(D<؊̊Њ؊芘ȊpL`@0p ̊؊ ܊$Ԋ䊼̊܊ ܊ ܊܊܊ Ԋ؊܊܊Ԋ ؊܊8܊THXԊ Њ0܊Ȋ􊴊܊܊؊(܊슼(ЊĊ܊܊Ԋ̊4`Ȍ(t Ȋ܊܊ԊȊ܊ L܊ԊdH؊$芼8􊬊܊܊؊<@DԊԊȊ슰ԊԊ ܊ 8 􊠊ЊЊ܊܊Ԋ܊܊܊؊ ܊Ԋ Ċ ܊Ԋ$Ċ芸 Ċ܊Њ<􊤊    ܊ԊDȊ芤 Њ Ċ ̊$܊Ȋ܊܊8 ܊ȋ ĊЊԊ ԋ܊ЊĊ ȊԊ ̊  􊸊؊ Ċ܊ ܊Ċ܊ Ԋ$ Њ܊܊Ȋ 芤ЊĊ $܊ Ȋ̊ 8슼܊$$܊ ̊ ܊( ܊ЊȊ؊؊4 ؊̊$܊$Ċ ܊ 04 ,ԊԊԊ 0ЊȊ؊,؊܊<H  Ԋ܊􊤋̊܊( <,܊<8$芨,܊ D؊̊܊ Ԋ܊  ܊ 8 @`\ Ȋ8ԊЊ,܊܊̊܊$  $$܊(̊܊؊ Ԋ܊ |̋D ܊ ЊЋ܊Ԋ ,􊬊H؊ ܊,؊HĊ $Њ􊼊@ċԋHP4̊܊܊ĊĊ̊ Ԋ Ċ Ԋ̊Ȋ܊􊰊؊ ؊ (@`D ؊܊܊ ܊ ԊԊȊ̊ЊԊ܊̊D  ؊  ܊Ԋ 􊰊܊ HԊ4Ԋ ̊܊(܊ ܊ Њ܊ ܊$Њ  ȊЊ ,8؊슘؊ ܊Њ Ċ؊܊ ܊PĊ  T Њ܊ d@ ܊  ؊l܊0؊̊  Ԋ0$܊ ؊Ԋ܊ ܊ 芰܊<\d􊬊؊ȊĊԊ܊Ȋ ܊<<Њ ,܊슸 ܊Њ,Ԋ܊܊4 ̊܊Ԋ؊   芸ЊЊ؊ ̊Ԋ܊܊$t܊D@ ܊Ԋ؊܊Ȋ܊؊܊܊܊ ؊܋ ܊؊؊Њ􊴊t􊰊  L܊܊   ܊Њ܊܊Ԋ􊸊(܊Њ̊ d Ԋ(؊$Ԋ 4Ċ؋( ؊܊Ċ8 ܋܊؊Ԋ Ȋ,܊Ԋ ؊ ܊̊8܊؊Ȋ܊؊$؊܊Њ܊$44܊܊ ȊЊ܊܊Ȋ4Ԋ܊܊Њ܊؊Ȋ܊  ̊؊܋܊Ȋ؊؊$􊼊Њ  (<4 Ċ܊؊̊܊􊸋  ܊Ԋ܊Њ؊ $Њ Њ܊ԊP܊H؊Њ0Pp̌ h Ȋ܊؊܋Ȋ,܊Ԋ Ԋ܊슼 P ԋ Ԋ408슨̊DXp\0|8 Ċ܊܊܊ ܊ ԋ  Њ؊܊스܊ЊdhD@< ԋ܊x܊Ԋ  8̊܊ȊĊ  Ԋ Ȋ슴؊Њ@܊Њ8lh<`, 0 ЊЊԊ슨܊ ؊  ܊؊$܊ԋ Ћ ,Њ4ЊPȐܐ苘HԊԊ8܊ @ Ċ܊܊؊܊,Ċ ܊ ܊슰̊܊$܊(܊(p،xLHD0 ܊ԊȊ(؊܊Њ̊̊ ȊԊ؊܊Њ ؊4܊܊ЋDth0$̊܊Ȋ؊Pxd,Њ܊Ԋ܊̊Ԋ؊$ Њ 4̊ ؊ D@8(܊ 4|܌@@Ћ ,Ԋ ԊԊ ܊@$, ,؊   $ (( H4 $ Hl`4h$  $܊(ȊĊ,@Њ,܊܊ Њ < Ԋ 8xЋ0$܊$Њ܊܊슼Ԋ x88Ȋ̊ Ċ܊̊(؊Ԋ 슼$ ,Ԋ܊ Ȋ܊Ċ Ȋ܊؊ ܊Њ܊@܊܊,ԊԊ܊芸 ܊@,(؊$0 ؊Ċ (Ԋ4( ؊ , ЊЊ̊  Ċ؊ 8芸܊$܊ ,ȊԊ dЊ <<8 ̊܊Ԋ܊܊0($Њ ܋Ċ܊̊0$ @D܊,؊̊ Њ ܊؊̊  8xT($P؊؊܊܊̊̊܊܊슴 LX,܊Ċ܊8 Њ ܊Ċ芼؊؊ (@0@ ܊܊ 芰܊Ċ4Њ$<$ЊĊ܊(܊􊴊܊؊􊴊܊( ܊Њ<8< D,dl؊Ԋ(H Ԋ Ȋ؊؊ ̊؊ԊԊȊ,܊Ԋ؊܊􊼊슴$P (Њ (,,܊` Hċ, ̊Њ܊Њ$܊ ̊܊ȊԊĊЊ؊؊Њ܊ ܊ Ԋ@(,$Ԋ܊ ؊܊Ȋ Њ ,܊ ̊؊ ܊̊슰(4܊؊8ԊȊ̊ЊȊ܊؊ ؊܊ ܊ԋ ܊؊􊼊􊤊܊Ԋ؊̊(,̊  Њ܊؊芼Ȋ芬܊؊܊܊Ċ    ܊􊼊,؊܊؊؊슰0 ܋܊ԋ ЊԊ슼Ċ؊,4܊Ԋ ЊԊЊ܊ ܊ < @̊̊܊슴 $܊ ܊4(,܊؊܊$ԊЊ  Ԋ؊Ԋ􊬊؊Ȋ ؊̊ ܊Њ܊4܊Ԋ\4؊L,<8܊$ԊԊ؊̋DԊ  ԊȊ􊴊Ċ܊􊰊4Ԋ܊܊ ̊􊨊؊ЊȊ4̊ԊԊ ؊Ԋ؊0 ؊ ؊ЊԊ؊ĊD؊Ԋ 4ԊȊ$Ԋ؊ ,0ԊĊ$؊ ̊@ ܊ ܊$؊, ܊؊ ܊܊<ЋT􊰊܊Ԋ܊܊芬(܊ ܊Ċ؊܊  ܊Ċ܊܊Ԋ Њ܊ ؊H܊܊ Ԋ܋,d@,؊؊Ȋ܊$؊؊ Ԋ$ȊԊ̊̊Ȋ؊܊   DHhЊT,܊􊰊   ,HԊЊ܊܊4܊􊼊8 Њ܊ $H$ Њ ,܊  Ԋ ܊ ؊Ԋ  4؊$ԊЊ̊܊܊؊̊Њ (܊؊Ћ  @D84 슸Ԋ؊Ԋ $ ܊؊̊$܊܊؊؊8؊܊Ԋ 0hL ؊ 0؊,Њ4, Ԋ؊Њ4Ԋ܊Ԋ Ċ؊,ċ\؊Ԋ슰􊰊ĊԊ؊؊Њ ܊܊܊  ̊슔 4 L܊ ؊؊ 0؋p l܊؊d؊؊Њ Ԋ ܊܊LЊ̊Ȋ ܊Њ܊4HD<  ؊܊ $<<܊$ hd̊Ċ,Ċ 􊼊Ċ􊰊 ؊ЊĊ؊ Ċ܊؊Њ̋$|LX,܊܊̊؊Ԋ Ld8 @\h  D؊0\,􊬊؊D܊Ȋ܊܊ ܊ (Ԋ Њ܊ȊԊ؊PD\< L\4 0  lt|$Ȋ ؊Ԋ̊Ԋ܊؊؊ ̊܊ Ԋ܊$Њ ĊЊ (L؊؊$ Њ؊8xl܊؊Њ ܋8슔Њ,tT ؊ ܊Ċ,Ċ؊ Ċ4<Ԋ Ȋ  , Ԋ܊܊Њ Ԋ4t 슼 ̊Ԋ؊܊􊸊 ̊ , ؊Њ 0  Ԋ܊܊ Ԋ܊܊܊ ̊(8D ̊LLl`0܊Ċ؊Ȋ܊܊ ؊,܊Ȋ܊܊؊ԊԊ ܊@L܊,   $Ċ Њ܊$$܊  ؋,L,(̊؊Ԋ̊؊Ȋ0p\lԊĊ܊ԋ( ȊԊ0؊Ԋ@܊스܊Ԋ ؊؊܊ȊԊ ܊Ċ܊܊܊4,4Њ؊؊܊܊Ċ܊܊܊܊؊(܊芼P슸܊܊܊܊ЊЊ؊Ċ  Њ0܊؊؊܊܊̊܋$ ܊܊$슸܊܊Ԋ ؊ ܊Ԋ܊܊܊슠芰  Ċ܋ Њ Њ( 8슸 Ԋ쌰@Њ 슜 ؊   Ћ ܊DЊ ܊0( ܊0 ؊؊ȊԊ܊܊Ċ؋ЊԊ  ؊܊Ċ؊̊DXX@4܊Ȋ؊􊠊$<ԋ, d؊Ȋ܊܊$   ؊@ ܊슸 ؊̊̊dXԊ04  $܊ ܊܊ ̊$슴؊8̊< 芸( 䊐܊4܊$,tT8 ܊0 ȊԊЊ 䊴 ̊Ȋ$܊ ؊ D  ܊ ċЊ܊Њ$T48<Ԋ 0􊴊0 (؊ȊȊ (܊܊  ܊Ċ Ċ؊Ԋ ܊̊8̊ ĊԊ܋܊(($􊼊Њ 슨Ԋ ܊􊴊Ȋ Њ􊴊܊D􊸊܊؊Ȋ8؊$Ԋ ܊$ 4ĊP؊Ԋ(,D Ԋ슼܊4܊̊؊؊􊨊̊D ̊܊Њ܊؊؊ Ԋ $܋    Ȋ􊼊 ȊĊ؊芠@pL؊܊̊ Ȋ􊼊Ȋ؊̊܊؊ԊԊ4 @p` ܊ ܊؊؊܊$Њ Ԋ  ؊Њ܊܊  ̊܊Ȋ؊ȊD@LX  Њ􊨊슴̊Њ ܊Ċ|  Ȋ$؊܊܊Ȋ 00܊̊ЊĊ܊܊슼(؊܊܊܊܊4Њ􊸊؊Њ0l8؊ЊЊ ܊̊؊ Њ̊ Њ􊴊Ԋh ܊ Њ܊܊  Ԋ Ԋ܊ Ԋ `XH􊸊P Ԋ d 4,4슠(Ȋ􊰊((<<܊Ȋ؊<ȊЊ܊̊܊܊D`P܊ ܊܊Ԋ̊Ċ@Ċ (\t,H܊􊴊4؊/tmp/project/ +# biases: /tmp/project/any/Bias_1.0ms_Bin1_gain100/ +# flats: /tmp/project/H/Flat_1.0ms_Bin1_H_gain100/ +# darks: /tmp/project/any/Dark_60.0s_Bin1_gain0/ +# lights: /tmp/project/H/Light_60.0s_Bin1_H_gain0/ +# process: /tmp/project/H/Light_60.0s_Bin1_H_gain0_process/ +# masters: /tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/ # ############################################ requires 1.2.0 # Convert Bias Frames to .fit files -cd tmp/project/any/Bias_1.0ms_Bin1_gain100 -convert bias -out=tmp/project/H/Light_60.0s_Bin1_H_gain0_process -cd tmp/project/H/Light_60.0s_Bin1_H_gain0_process +cd /tmp/project/any/Bias_1.0ms_Bin1_gain100 +convert bias -out=/tmp/project/H/Light_60.0s_Bin1_H_gain0_process +cd /tmp/project/H/Light_60.0s_Bin1_H_gain0_process # Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/bias_stacked +stack bias rej 3 3 -nonorm -out=/tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/bias_stacked # Convert Flat Frames to .fit files -cd tmp/project/H/Flat_1.0ms_Bin1_H_gain100 -convert flat -out=tmp/project/H/Light_60.0s_Bin1_H_gain0_process -cd tmp/project/H/Light_60.0s_Bin1_H_gain0_process +cd /tmp/project/H/Flat_1.0ms_Bin1_H_gain100 +convert flat -out=/tmp/project/H/Light_60.0s_Bin1_H_gain0_process +cd /tmp/project/H/Light_60.0s_Bin1_H_gain0_process # Calibrate Flat Frames -calibrate flat -bias=tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/bias_stacked +calibrate flat -bias=/tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/bias_stacked # Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/pp_flat_stacked +stack pp_flat rej 3 3 -norm=mul -out=/tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/pp_flat_stacked # Convert Dark Frames to .fit files -cd tmp/project/any/Dark_60.0s_Bin1_gain0 -convert dark -out=tmp/project/H/Light_60.0s_Bin1_H_gain0_process -cd tmp/project/H/Light_60.0s_Bin1_H_gain0_process +cd /tmp/project/any/Dark_60.0s_Bin1_gain0 +convert dark -out=/tmp/project/H/Light_60.0s_Bin1_H_gain0_process +cd /tmp/project/H/Light_60.0s_Bin1_H_gain0_process # Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/dark_stacked +stack dark rej 3 3 -nonorm -out=/tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/dark_stacked # Convert Light Frames to .fit files -cd tmp/project/H/Light_60.0s_Bin1_H_gain0 -convert light -out=tmp/project/H/Light_60.0s_Bin1_H_gain0_process -cd tmp/project/H/Light_60.0s_Bin1_H_gain0_process +cd /tmp/project/H/Light_60.0s_Bin1_H_gain0 +convert light -out=/tmp/project/H/Light_60.0s_Bin1_H_gain0_process +cd /tmp/project/H/Light_60.0s_Bin1_H_gain0_process # Calibrate Light Frames -calibrate light -dark=tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/dark_stacked -flat=tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/pp_flat_stacked -cc=dark +calibrate light -dark=/tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/dark_stacked -flat=/tmp/project/H/Light_60.0s_Bin1_H_gain0_masters/pp_flat_stacked -cc=dark # Align Lights register pp_light @@ -970,51 +971,52 @@ exports[`E2E should be neat 5`] = ` ############################################ # # Variables: -# biases: tmp/project/any/Bias_1.0ms_Bin1_gain100/ -# flats: tmp/project/S/Flat_1.0ms_Bin1_S_gain100/ -# darks: tmp/project/any/Dark_120.0s_Bin1_gain0/ -# lights: tmp/project/S/Light_120.0s_Bin1_S_gain0/ -# process: tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process/ -# masters: tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/ +# poto-dir: /tmp/project/ +# biases: /tmp/project/any/Bias_1.0ms_Bin1_gain100/ +# flats: /tmp/project/S/Flat_1.0ms_Bin1_S_gain100/ +# darks: /tmp/project/any/Dark_120.0s_Bin1_gain0/ +# lights: /tmp/project/S/Light_120.0s_Bin1_S_gain0/ +# process: /tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process/ +# masters: /tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/ # ############################################ requires 1.2.0 # Convert Bias Frames to .fit files -cd tmp/project/any/Bias_1.0ms_Bin1_gain100 -convert bias -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process -cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd /tmp/project/any/Bias_1.0ms_Bin1_gain100 +convert bias -out=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd /tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process # Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/bias_stacked +stack bias rej 3 3 -nonorm -out=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/bias_stacked # Convert Flat Frames to .fit files -cd tmp/project/S/Flat_1.0ms_Bin1_S_gain100 -convert flat -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process -cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd /tmp/project/S/Flat_1.0ms_Bin1_S_gain100 +convert flat -out=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd /tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process # Calibrate Flat Frames -calibrate flat -bias=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/bias_stacked +calibrate flat -bias=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/bias_stacked # Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/pp_flat_stacked +stack pp_flat rej 3 3 -norm=mul -out=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/pp_flat_stacked # Convert Dark Frames to .fit files -cd tmp/project/any/Dark_120.0s_Bin1_gain0 -convert dark -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process -cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd /tmp/project/any/Dark_120.0s_Bin1_gain0 +convert dark -out=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd /tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process # Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/dark_stacked +stack dark rej 3 3 -nonorm -out=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/dark_stacked # Convert Light Frames to .fit files -cd tmp/project/S/Light_120.0s_Bin1_S_gain0 -convert light -out=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process -cd tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd /tmp/project/S/Light_120.0s_Bin1_S_gain0 +convert light -out=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process +cd /tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process # Calibrate Light Frames -calibrate light -dark=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/dark_stacked -flat=tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/pp_flat_stacked -cc=dark +calibrate light -dark=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/dark_stacked -flat=/tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters/pp_flat_stacked -cc=dark # Align Lights register pp_light @@ -1037,51 +1039,52 @@ exports[`E2E should be neat 6`] = ` ############################################ # # Variables: -# biases: tmp/project/any/Bias_1.0ms_Bin1_gain100/ -# flats: tmp/project/S/Flat_1.0ms_Bin1_S_gain100/ -# darks: tmp/project/any/Dark_60.0s_Bin1_gain100/ -# lights: tmp/project/S/Light_60.0s_Bin1_S_gain100/ -# process: tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process/ -# masters: tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/ +# poto-dir: /tmp/project/ +# biases: /tmp/project/any/Bias_1.0ms_Bin1_gain100/ +# flats: /tmp/project/S/Flat_1.0ms_Bin1_S_gain100/ +# darks: /tmp/project/any/Dark_60.0s_Bin1_gain100/ +# lights: /tmp/project/S/Light_60.0s_Bin1_S_gain100/ +# process: /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process/ +# masters: /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/ # ############################################ requires 1.2.0 # Convert Bias Frames to .fit files -cd tmp/project/any/Bias_1.0ms_Bin1_gain100 -convert bias -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd /tmp/project/any/Bias_1.0ms_Bin1_gain100 +convert bias -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process # Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/bias_stacked +stack bias rej 3 3 -nonorm -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/bias_stacked # Convert Flat Frames to .fit files -cd tmp/project/S/Flat_1.0ms_Bin1_S_gain100 -convert flat -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd /tmp/project/S/Flat_1.0ms_Bin1_S_gain100 +convert flat -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process # Calibrate Flat Frames -calibrate flat -bias=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/bias_stacked +calibrate flat -bias=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/bias_stacked # Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/pp_flat_stacked +stack pp_flat rej 3 3 -norm=mul -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/pp_flat_stacked # Convert Dark Frames to .fit files -cd tmp/project/any/Dark_60.0s_Bin1_gain100 -convert dark -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd /tmp/project/any/Dark_60.0s_Bin1_gain100 +convert dark -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process # Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/dark_stacked +stack dark rej 3 3 -nonorm -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/dark_stacked # Convert Light Frames to .fit files -cd tmp/project/S/Light_60.0s_Bin1_S_gain100 -convert light -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100 +convert light -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process # Calibrate Light Frames -calibrate light -dark=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/dark_stacked -flat=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/pp_flat_stacked -cc=dark +calibrate light -dark=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/dark_stacked -flat=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters/pp_flat_stacked -cc=dark # Align Lights register pp_light @@ -1104,51 +1107,52 @@ exports[`E2E should be neat 7`] = ` ############################################ # # Variables: -# biases: tmp/project/any/Bias_1.0ms_Bin1_gain100/ -# flats: tmp/project/S/Flat_1.0ms_Bin1_S_gain100/ -# darks: tmp/project/any/Dark_60.0s_Bin1_gain100/ -# lights: tmp/project/S/Light_60.0s_Bin1_S_gain100/ -# process: tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process/ -# masters: tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/ +# poto-dir: /tmp/project/ +# biases: /tmp/project/any/Bias_1.0ms_Bin1_gain100/ +# flats: /tmp/project/S/Flat_1.0ms_Bin1_S_gain100/ +# darks: /tmp/project/any/Dark_60.0s_Bin1_gain100/ +# lights: /tmp/project/S/Light_60.0s_Bin1_S_gain100/ +# process: /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process/ +# masters: /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/ # ############################################ requires 1.2.0 # Convert Bias Frames to .fit files -cd tmp/project/any/Bias_1.0ms_Bin1_gain100 -convert bias -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process +cd /tmp/project/any/Bias_1.0ms_Bin1_gain100 +convert bias -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process # Stack Bias Frames to bias_stacked.fit -stack bias rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/bias_stacked +stack bias rej 3 3 -nonorm -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/bias_stacked # Convert Flat Frames to .fit files -cd tmp/project/S/Flat_1.0ms_Bin1_S_gain100 -convert flat -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process +cd /tmp/project/S/Flat_1.0ms_Bin1_S_gain100 +convert flat -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process # Calibrate Flat Frames -calibrate flat -bias=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/bias_stacked +calibrate flat -bias=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/bias_stacked # Stack Flat Frames to pp_flat_stacked.fit -stack pp_flat rej 3 3 -norm=mul -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/pp_flat_stacked +stack pp_flat rej 3 3 -norm=mul -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/pp_flat_stacked # Convert Dark Frames to .fit files -cd tmp/project/any/Dark_60.0s_Bin1_gain100 -convert dark -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process +cd /tmp/project/any/Dark_60.0s_Bin1_gain100 +convert dark -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process # Stack Dark Frames to dark_stacked.fit -stack dark rej 3 3 -nonorm -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/dark_stacked +stack dark rej 3 3 -nonorm -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/dark_stacked # Convert Light Frames to .fit files -cd tmp/project/S/Light_60.0s_Bin1_S_gain100 -convert light -out=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process -cd tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100 +convert light -out=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process +cd /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process # Calibrate Light Frames -calibrate light -dark=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/dark_stacked -flat=tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/pp_flat_stacked -cc=dark +calibrate light -dark=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/dark_stacked -flat=/tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters/pp_flat_stacked -cc=dark # Align Lights register pp_light @@ -1174,12 +1178,14 @@ exports[`E2E should be neat 8`] = ` } ]", "step: Reading input directories", + "debug: Reading input directory tmp/asiair-dump", + "debug: ASIAIR dump detected in tmp/asiair-dump.", "debug: Skipping unknown file (Flat_1.0ms_Bin1_S_gain100_20240511-094306_-10.5C_0001.fot)", "prompt: [ { "type": "select", "name": "selectedInputSubDirectory", - "message": "Files found in both Autorun and Plan directories. How to do we proceed?", + "message": "Files found in both Autorun and Plan directories. How do we proceed?", "choices": [ "Use Autorun directory", "Use Plan directory", @@ -1188,6 +1194,10 @@ exports[`E2E should be neat 8`] = ` } ]", "info: Found 19 files in input dir(s) to dispatch.", + "debug: Reading input directory tmp/bank", + "info: Found 14 files in input dir(s) to dispatch.", + "info: Found 33 .fit files in input directories 🌋.", + "info: Including 8 lights 🌟.", "step: Matching lights and flats (early stage)", "warning: No matching light for Flat_1.0ms_Bin1_O_gain100 (seq 20240511-094306). Skipping.", "warning: No matching light for Flat_1.0ms_Bin2_S_gain100 (seq 20240511-094304). Skipping.", @@ -1256,7 +1266,7 @@ exports[`E2E should be neat 8`] = ` "debug: - Light_120.0s_Bin1_S_gain0 20240626-010853 🏹 Flat_1.0ms_Bin1_S_gain100 20240626-094304", "debug: - Light_60.0s_Bin1_S_gain100 20240627-010820 🏹 Flat_1.0ms_Bin1_S_gain100 20240626-094304", "step: Tagging darks and biases", - "info: Found 14 files in the bank.", + "info: Found 14 darks+baises files.", "step: Preview before dispatching", "info: 🔭 Cumulated light integration: 9 minutes.", "info: 📦 Project size: 8 lights, 10 darks, 12 flats, 12 biases.", @@ -1318,18 +1328,38 @@ exports[`E2E should be neat 8`] = ` "debug: - Bias_1.0ms_Bin1_gain100_20230910-101132_-9.8C_0002.fit dispatched.", "debug: - Bias_1.0ms_Bin1_gain100_20230910-101133_-9.8C_0003.fit dispatched.", "success: Dispatch complete.", - "debug: directories [object Object]", - "info: dirs [object Object]", - "info: Generated tmp/project/H/Light_60.0s_Bin1_H_gain0_process/poto_1_preprocessing.ssf [object Object]", - "debug: directories [object Object]", - "info: dirs [object Object]", - "info: Generated tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process/poto_1_preprocessing.ssf [object Object]", - "debug: directories [object Object]", - "info: dirs [object Object]", - "info: Generated tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process/poto_1_preprocessing.ssf [object Object]", - "debug: directories [object Object]", - "info: dirs [object Object]", - "info: Generated tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process/poto_1_preprocessing.ssf [object Object]", + "info: Generated tmp/project/H/Light_60.0s_Bin1_H_gain0_process/poto_1_preprocessing.ssf", + "debug: - {{poto-dir}} 👉 /tmp/project", + "debug: - {{lights}} 👉 /tmp/project/H/Light_60.0s_Bin1_H_gain0", + "debug: - {{flats}} 👉 /tmp/project/H/Flat_1.0ms_Bin1_H_gain100", + "debug: - {{darks}} 👉 /tmp/project/any/Dark_60.0s_Bin1_gain0", + "debug: - {{biases}} 👉 /tmp/project/any/Bias_1.0ms_Bin1_gain100", + "debug: - {{process}} 👉 /tmp/project/H/Light_60.0s_Bin1_H_gain0_process", + "debug: - {{masters}} 👉 /tmp/project/H/Light_60.0s_Bin1_H_gain0_masters", + "info: Generated tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process/poto_1_preprocessing.ssf", + "debug: - {{poto-dir}} 👉 /tmp/project", + "debug: - {{lights}} 👉 /tmp/project/S/Light_60.0s_Bin1_S_gain100", + "debug: - {{flats}} 👉 /tmp/project/S/Flat_1.0ms_Bin1_S_gain100", + "debug: - {{darks}} 👉 /tmp/project/any/Dark_60.0s_Bin1_gain100", + "debug: - {{biases}} 👉 /tmp/project/any/Bias_1.0ms_Bin1_gain100", + "debug: - {{process}} 👉 /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_process", + "debug: - {{masters}} 👉 /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240624-010840_masters", + "info: Generated tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process/poto_1_preprocessing.ssf", + "debug: - {{poto-dir}} 👉 /tmp/project", + "debug: - {{lights}} 👉 /tmp/project/S/Light_120.0s_Bin1_S_gain0", + "debug: - {{flats}} 👉 /tmp/project/S/Flat_1.0ms_Bin1_S_gain100", + "debug: - {{darks}} 👉 /tmp/project/any/Dark_120.0s_Bin1_gain0", + "debug: - {{biases}} 👉 /tmp/project/any/Bias_1.0ms_Bin1_gain100", + "debug: - {{process}} 👉 /tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_process", + "debug: - {{masters}} 👉 /tmp/project/S/Light_120.0s_Bin1_S_gain0__20240626-010853_masters", + "info: Generated tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process/poto_1_preprocessing.ssf", + "debug: - {{poto-dir}} 👉 /tmp/project", + "debug: - {{lights}} 👉 /tmp/project/S/Light_60.0s_Bin1_S_gain100", + "debug: - {{flats}} 👉 /tmp/project/S/Flat_1.0ms_Bin1_S_gain100", + "debug: - {{darks}} 👉 /tmp/project/any/Dark_60.0s_Bin1_gain100", + "debug: - {{biases}} 👉 /tmp/project/any/Bias_1.0ms_Bin1_gain100", + "debug: - {{process}} 👉 /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_process", + "debug: - {{masters}} 👉 /tmp/project/S/Light_60.0s_Bin1_S_gain100__20240627-010820_masters", "success: Scripts were generated ✅.", ] `; diff --git a/src/tests/e2e/e2e-testing.spec.ts b/src/tests/e2e/e2e-testing.spec.ts index a5fe6a2..1054abf 100644 --- a/src/tests/e2e/e2e-testing.spec.ts +++ b/src/tests/e2e/e2e-testing.spec.ts @@ -3,15 +3,15 @@ import path from "path"; import fs from "fs"; import Enquirer from "enquirer"; -import dispatch, { +import prepare, { SelectedInputSubDirectoryChoices, -} from "../../commands/dispatch-dump"; +} from "../../commands/prepare"; import { POTO_JSON } from "../../utils/const"; import { - cleanThumbnails, - removeEmptyDirectories, -} from "../../commands/asiair-dump-cleaning"; -import { generateScripts } from "../../commands/generate-scripts"; + dropThumbnails, + dropEmptyDirectories, +} from "../../commands/clear"; +import { generateScripts } from "../../commands/preprocess.generate-scripts"; import { spawnMockedDatasetToFs_dataset_1 } from "../fixtures"; import { logger } from "../../utils/logger"; @@ -104,7 +104,7 @@ describe("E2E", () => { }); expect(files.filter(f => f.endsWith("_thn.jpg"))).toHaveLength(3); - cleanThumbnails(asiAirDirectory); + dropThumbnails(asiAirDirectory); files = fs.readdirSync(asiAirDirectory, { recursive: true, @@ -122,17 +122,16 @@ describe("E2E", () => { true, ); - removeEmptyDirectories(asiAirDirectory); + dropEmptyDirectories(asiAirDirectory); expect(fs.existsSync(path.join(asiAirDirectory, "empty", "empty"))).toBe( false, ); expect(fs.existsSync(path.join(asiAirDirectory, "empty"))).toBe(false); - await dispatch({ + await prepare({ projectDirectory, - asiAirDirectory, - bankDirectory, + inputDirectories: [asiAirDirectory, bankDirectory], }); files = fs.readdirSync(projectDirectory, { @@ -145,8 +144,8 @@ describe("E2E", () => { [ "H", "S", + "_poto_siril.json", "any", - "poto.json", "H/Flat_1.0ms_Bin1_H_gain100", "H/Light_60.0s_Bin1_H_gain0", "S/Flat_1.0ms_Bin1_S_gain100", @@ -220,10 +219,11 @@ describe("E2E", () => { encoding: "utf8", }, ); - expect(scriptContent).toMatchSnapshot(); + + expect(scriptContent).toMatchSnapshotWithNormalizedPaths(); } - expect(logMessages).toMatchSnapshot(); + expect(logMessages).toMatchSnapshotWithNormalizedPaths(); }); describe("returns all fits in the input directories", () => { @@ -242,12 +242,34 @@ describe("E2E", () => { } as never); await expect( - dispatch({ + prepare({ + projectDirectory, + inputDirectories: [asiAirDirectory, bankDirectory], + }), + ).rejects.toThrow(`No FITS files found in ${asiAirDirectory}`); + }); + + it("should warn if no files (ASIAIR version)", async () => { + const autorunDirectory = `${asiAirDirectory}/Autorun`; + if (fs.existsSync(autorunDirectory)) { + fs.rmSync(autorunDirectory, { recursive: true }); + } + const planDirectory = `${asiAirDirectory}/Plan`; + if (fs.existsSync(planDirectory)) { + fs.rmSync(planDirectory, { recursive: true }); + } + fs.mkdirSync(planDirectory); + + promptMock.mockResolvedValueOnce({ + createProjectDirectory: true, + } as never); + + await expect( + prepare({ projectDirectory, - asiAirDirectory, - bankDirectory, + inputDirectories: [asiAirDirectory, bankDirectory], }), - ).rejects.toThrow("No FITS files found in the input directories."); + ).rejects.toThrow("No FITS files found in Autorun nor Plan folders."); }); it("should auto pick Autorun files", async () => { @@ -273,10 +295,9 @@ describe("E2E", () => { go: true, } as never); - await dispatch({ + await prepare({ projectDirectory, - asiAirDirectory, - bankDirectory, + inputDirectories: [asiAirDirectory, bankDirectory], }); const files = fs.readdirSync(projectDirectory, { @@ -304,10 +325,9 @@ describe("E2E", () => { go: true, } as never); - await dispatch({ + await prepare({ projectDirectory, - asiAirDirectory, - bankDirectory, + inputDirectories: [asiAirDirectory, bankDirectory], }); expect(logMessages).toContain( @@ -345,10 +365,9 @@ describe("E2E", () => { go: true, } as never); - await dispatch({ + await prepare({ projectDirectory, - asiAirDirectory, - bankDirectory, + inputDirectories: [asiAirDirectory, bankDirectory], }); expect(logMessages).toContain( @@ -369,10 +388,9 @@ describe("E2E", () => { go: true, } as never); - await dispatch({ + await prepare({ projectDirectory, - asiAirDirectory, - bankDirectory, + inputDirectories: [asiAirDirectory, bankDirectory], }); expect(logMessages).toContain( diff --git a/src/tests/fixtures.ts b/src/tests/fixtures.ts index 18b88aa..16bb37c 100644 --- a/src/tests/fixtures.ts +++ b/src/tests/fixtures.ts @@ -1,6 +1,7 @@ import path from "path"; import fs from "fs"; import { logger } from "../utils/logger"; +import { imageType } from "src/utils/types"; const tmpDir = "tmp"; @@ -26,8 +27,15 @@ const spawnMockedDatasetToFs = ( dataset.forEach(file => { const filePath = path.join(tmpDir, file); + + const fileType = file.includes("Light") ? "Light" : + file.includes("Dark") ? "Dark" : + file.includes("Bias") ? "Bias" : + file.includes("Flat") ? "Flat" : + null; + fs.mkdirSync(path.dirname(filePath), { recursive: true }); - fs.writeFileSync(filePath, "mocked content"); + fs.writeFileSync(filePath, fileType ? getRealDataFromSample(fileType) : "mocked content"); }); const asiAirDirectory = path.join(tmpDir, "asiair-dump"); @@ -121,3 +129,16 @@ const dataset_1 = [ // 1 file from Plan directory to test the choice selection. Bin2 to not match with the rest. "asiair-dump/Plan/Flat/Flat_1.0ms_Bin2_H_gain100_20240512-124300_-10.5C_0001.fit", ]; + +const getRealDataFromSample = (type: imageType): Buffer => { + switch (type) { + case "Light": + return fs.readFileSync("src/tests/data-sample/Light_NGC6992_60.0s_Bin1_H_gain100_20240811-010756_-10.2C_0001.fit"); + case "Dark": + return fs.readFileSync("src/tests/data-sample/Dark_60.0s_Bin1_gain0_20240807-162149_-10.0C_0001.fit"); + case "Bias": + return fs.readFileSync("src/tests/data-sample/Bias_1.0ms_Bin1_gain0_20240807-142905_-9.6C_0001.fit"); + case "Flat": + return fs.readFileSync("src/tests/data-sample/Flat_1.2s_Bin1_H_gain0_20240811-025058_-9.8C_0001.fit"); + } +}; \ No newline at end of file diff --git a/src/utils/const.ts b/src/utils/const.ts index b979f2e..53ce05d 100644 --- a/src/utils/const.ts +++ b/src/utils/const.ts @@ -1,5 +1,5 @@ -export const POTO_VERSION = "0.2.0"; +export const POTO_VERSION = "poto-siril 0.4.0"; -export const POTO_JSON = "poto.json"; +export const POTO_JSON = "_poto_siril.json"; export const GENERATED_SCRIPT_PREFIX = "poto_"; diff --git a/src/utils/types.ts b/src/utils/types.ts index c4977a1..544e8b9 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -1,4 +1,4 @@ -type imageType = "Light" | "Dark" | "Bias" | "Flat"; +export type imageType = "Light" | "Dark" | "Bias" | "Flat"; export type ImageSpec = { /** diff --git a/tsconfig.json b/tsconfig.json index 285a49f..9e2688d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,5 +14,5 @@ "baseUrl": "./" }, "exclude": ["node_modules"], - "include": ["src/**/*.ts", "bin/*.ts"] + "include": ["src/**/*.ts", "jest.config.ts", "jest.d.ts"] }