astro-subframe-organizer 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +737 -0
  4. data/exe/astro-subframe-organizer +8 -0
  5. data/lib/astro_subframe_organizer/astrophoto.rb +122 -0
  6. data/lib/astro_subframe_organizer/commands/cleanup/empty_directories.rb +27 -0
  7. data/lib/astro_subframe_organizer/commands/cleanup/thumbnails.rb +38 -0
  8. data/lib/astro_subframe_organizer/commands/cleanup/unorganize.rb +25 -0
  9. data/lib/astro_subframe_organizer/commands/equipment_options.rb +30 -0
  10. data/lib/astro_subframe_organizer/commands/init.rb +54 -0
  11. data/lib/astro_subframe_organizer/commands/inspect.rb +101 -0
  12. data/lib/astro_subframe_organizer/commands/organize/base.rb +43 -0
  13. data/lib/astro_subframe_organizer/commands/organize/bias.rb +13 -0
  14. data/lib/astro_subframe_organizer/commands/organize/darks.rb +12 -0
  15. data/lib/astro_subframe_organizer/commands/organize/flats.rb +14 -0
  16. data/lib/astro_subframe_organizer/commands/organize/lights.rb +14 -0
  17. data/lib/astro_subframe_organizer/commands/raw/rename_from_exif.rb +45 -0
  18. data/lib/astro_subframe_organizer/commands/raw/revert_name.rb +28 -0
  19. data/lib/astro_subframe_organizer/commands/run.rb +28 -0
  20. data/lib/astro_subframe_organizer/commands/shared_options.rb +29 -0
  21. data/lib/astro_subframe_organizer/commands/version.rb +15 -0
  22. data/lib/astro_subframe_organizer/commands.rb +64 -0
  23. data/lib/astro_subframe_organizer/config.rb +140 -0
  24. data/lib/astro_subframe_organizer/equipment/camera.rb +14 -0
  25. data/lib/astro_subframe_organizer/equipment/filter.rb +14 -0
  26. data/lib/astro_subframe_organizer/equipment/telescope.rb +14 -0
  27. data/lib/astro_subframe_organizer/equipment_selector.rb +103 -0
  28. data/lib/astro_subframe_organizer/file_metadata.rb +135 -0
  29. data/lib/astro_subframe_organizer/file_set.rb +107 -0
  30. data/lib/astro_subframe_organizer/filename_parser.rb +106 -0
  31. data/lib/astro_subframe_organizer/filename_parsers/cr2_filename_parser.rb +67 -0
  32. data/lib/astro_subframe_organizer/filename_parsers/fits_filename_parser.rb +67 -0
  33. data/lib/astro_subframe_organizer/filename_parsers/fits_header_parser.rb +120 -0
  34. data/lib/astro_subframe_organizer/fits_organizer.rb +154 -0
  35. data/lib/astro_subframe_organizer/logging.rb +10 -0
  36. data/lib/astro_subframe_organizer/organizer.rb +125 -0
  37. data/lib/astro_subframe_organizer/path_builder.rb +55 -0
  38. data/lib/astro_subframe_organizer/path_builders/base_path_builder.rb +33 -0
  39. data/lib/astro_subframe_organizer/path_builders/bias_path_builder.rb +38 -0
  40. data/lib/astro_subframe_organizer/path_builders/dark_path_builder.rb +61 -0
  41. data/lib/astro_subframe_organizer/path_builders/flat_path_builder.rb +48 -0
  42. data/lib/astro_subframe_organizer/path_builders/light_path_builder.rb +53 -0
  43. data/lib/astro_subframe_organizer/utils/empty_directory_cleaner.rb +36 -0
  44. data/lib/astro_subframe_organizer/utils/exif_renamer.rb +132 -0
  45. data/lib/astro_subframe_organizer/utils/exposure_format.rb +25 -0
  46. data/lib/astro_subframe_organizer/utils/file_utils.rb +10 -0
  47. data/lib/astro_subframe_organizer/utils/fits_stripper.rb +115 -0
  48. data/lib/astro_subframe_organizer/utils/raw_stripper.rb +47 -0
  49. data/lib/astro_subframe_organizer/utils/thumbnail_cleaner.rb +26 -0
  50. data/lib/astro_subframe_organizer/utils/unorganizer.rb +54 -0
  51. data/lib/astro_subframe_organizer/version.rb +5 -0
  52. data/lib/astro_subframe_organizer.rb +103 -0
  53. metadata +182 -0
data/README.md ADDED
@@ -0,0 +1,737 @@
1
+ # Organize Astrophotography Data
2
+
3
+ This is a Ruby gem command line tool to help organize astrophotography data into folders using keywords to assist in grouping and matching subframes for preprocessing and calibration. Subframe organization is compatible with keyword grouping in PixInsight using `WeightedBatchPreProcessing`.
4
+
5
+ The tool can quickly rename raw (CR2) files based on EXIF metadata and manual user input, which can then be used to group for preprocessing and calibration.
6
+
7
+ AstroSubframeOrganizer has been adapted from a standalone [Ruby Script](https://gist.github.com/shekibobo/b8e853bf70d787b55a87f7a4cf7ed248) to a customizable gem, with more features, customizability, and improved usability and safeguards.
8
+
9
+ This version of the gem was written to organize or reorganize the data collected to match my current workflow.
10
+
11
+ ## Table of Contents
12
+
13
+ - [Organize Astrophotography Data](#organize-astrophotography-data)
14
+ - [Table of Contents](#table-of-contents)
15
+ - [Installation](#installation)
16
+ - [Getting Started](#getting-started)
17
+ - [Initialize your equipment set](#initialize-your-equipment-set)
18
+ - [Configuration](#configuration)
19
+ - [Creating a Config File](#creating-a-config-file)
20
+ - [Advanced Configuration](#advanced-configuration)
21
+ - [Temperature Tolerance](#temperature-tolerance)
22
+ - [Telescope Ignore Patterns](#telescope-ignore-patterns)
23
+ - [Custom Metadata Mappings](#custom-metadata-mappings)
24
+ - [Custom File Extensions](#custom-file-extensions)
25
+ - [Using a Custom Config File](#using-a-custom-config-file)
26
+ - [Organization Tools](#organization-tools)
27
+ - [Interactive Menu](#interactive-menu)
28
+ - [Global Options](#global-options)
29
+ - [Equipment Options](#equipment-options)
30
+ - [Command Mode](#command-mode)
31
+ - [Darks](#darks)
32
+ - [Flat Darks](#flat-darks)
33
+ - [Flats](#flats)
34
+ - [FlatSet](#flatset)
35
+ - [Lights](#lights)
36
+ - [Biases](#biases)
37
+ - [Unorganize](#unorganize)
38
+ - [Raw Tools](#raw-tools)
39
+ - [Rename From EXIF](#rename-from-exif)
40
+ - [Revert Rename](#revert-rename)
41
+ - [Cleanup Tools](#cleanup-tools)
42
+ - [Delete Thumbnails](#delete-thumbnails)
43
+ - [Delete Empty Directories](#delete-empty-directories)
44
+ - [Utils](#utils)
45
+ - [Organized Directory Structure](#organized-directory-structure)
46
+ - [Light Frames](#light-frames)
47
+ - [Flat Frames](#flat-frames)
48
+ - [Dark Frames](#dark-frames)
49
+ - [Bias Frames](#bias-frames)
50
+ - [Flat Darks (DarkFlats)](#flat-darks-darkflats)
51
+ - [PixInsight - Saved WBPP Process Icons](#pixinsight---saved-wbpp-process-icons)
52
+ - [WBPP\_Darks](#wbpp_darks)
53
+ - [WBPP\_Flats](#wbpp_flats)
54
+ - [WBPP\_Integration](#wbpp_integration)
55
+ - [Historical Development Notes](#historical-development-notes)
56
+ - [Pre-ASIAir Image Data](#pre-asiair-image-data)
57
+ - [Exposure Time](#exposure-time)
58
+ - [Renaming Previously Renamed Files](#renaming-previously-renamed-files)
59
+ - [Contributing](#contributing)
60
+ - [Get Started Coding](#get-started-coding)
61
+ - [Disclaimer](#disclaimer)
62
+
63
+ ## Installation
64
+
65
+ Install the gem:
66
+
67
+ ```bash
68
+ gem install astro-subframe-organizer
69
+ ```
70
+
71
+ Or clone the repository and run:
72
+
73
+ ```bash
74
+ bundle install
75
+ bundle exec rake install
76
+ ```
77
+
78
+ ## Getting Started
79
+
80
+ ### Initialize your equipment set
81
+
82
+ Create a default config file with sample equipment and settings (~/astro-subframe-organizer-config.yml) and edit it to include your equipment:
83
+
84
+ ```bash
85
+ astro-subframe-organizer init
86
+ ```
87
+
88
+ Or create it with your equipment list directly:
89
+
90
+ ```bash
91
+ astro-subframe-organizer init --telescope CarbonStar200 --filter NBZ --camera 'ZWO ASI183MC Pro'
92
+ ```
93
+
94
+ Run the organizer:
95
+
96
+ ```bash
97
+ astro-subframe-organizer run
98
+ ```
99
+
100
+ Follow the interactive prompts to organize your files.
101
+
102
+ ### Configuration
103
+
104
+ The gem supports customizable lists of telescopes, filters, and cameras. By default, it uses built-in lists, but you can create a personal configuration file.
105
+
106
+ #### Creating a Config File
107
+
108
+ To create a default configuration file:
109
+
110
+ ```bash
111
+ astro-subframe-organizer init
112
+ ```
113
+
114
+ This creates `~/astro-subframe-organizer-config.yml` with default values. Edit this file to customize your equipment or change configurations:
115
+
116
+ ```yaml
117
+ telescopes:
118
+ - RedCat51
119
+ - ZhumellZ130
120
+ - YourTelescope
121
+ filters:
122
+ - BaaderMoon
123
+ - NBZ
124
+ - YourFilter
125
+ cameras:
126
+ - T7
127
+ - 183MC
128
+ - ZWO ASI183MC Pro
129
+ - Canon EOS 1500D
130
+ - YourCamera
131
+ temperature_tolerance: 5.0
132
+ ```
133
+
134
+ If you only use one set of equipment, you can create and update the config file in one shot:
135
+
136
+ ```bash
137
+ astro-subframe-organizer init --telescope CarbonStar200 --filter NBZ --camera 'ZWO ASI183MC Pro'
138
+ ```
139
+
140
+ When you run the organizer with only one option in each equipment category, the interactive organizer will automatically select the equipment unless there's a mismatch in the available metadata (FITS headers or EXIF data), so it may be useful to create multiple config files that include your common equipment configurations:
141
+
142
+ ```bash
143
+ astro-subframe-organizer init --config ~/galaxy-season.yml --telescope CarbonStar200 --filter BaaderMoon --camera 'ZWO ASI533MC Pro'
144
+ ```
145
+
146
+ ```bash
147
+ astro-subframe-organizer init --config ~/nightscape.yml --telescope Rokinon135 --filter BaaderMoon --camera 'Canon T7'
148
+ ```
149
+
150
+ ```bash
151
+ astro-subframe-organizer init --config ~/dual-narrowband.yml --telescope Redcat51 --filter NBZ --camera 'ZWO ASI183MC Pro'
152
+ ```
153
+
154
+ If you shoot with multiple filters, you can add additional filters in the config file:
155
+
156
+ ```yaml
157
+ telescopes:
158
+ - Redcat71
159
+ filters:
160
+ - L
161
+ - R
162
+ - G
163
+ - B
164
+ cameras:
165
+ - ZWO ASI2600MM Pro
166
+ temperature_tolerance: 5.0
167
+ ```
168
+
169
+ Note: if you have an automatic filter wheel and your software records the filter name in FITS headers, ASO will automatically select the assigned filter for organization.
170
+
171
+ ### Advanced Configuration
172
+
173
+ You can further customize how metadata is extracted and how equipment is identified and grouped by adding these optional sections to your configuration file.
174
+
175
+ #### Temperature Tolerance
176
+
177
+ By default, all image types that get grouped by `CCD-TEMP` will be grouped together with the temperature rounded to the nearest 5°C. See the following example table for rounding ranges:
178
+
179
+ | Actual Temp | Rounded Temp | Notes |
180
+ | --- | --- | --- |
181
+ | -10.0C | -10. | exactly on boundary |
182
+ | -9.5C | -10. | 0.5 below boundary, rounds to -10 |
183
+ | -10.5C | -10. | 0.5 above boundary, rounds to -10 |
184
+ | -7.5C | -10. | equidistant between -5 and -10, rounds toward -10 |
185
+ | -12.5C | -15. | equidistant between -10 and -15, rounds toward -15 |
186
+ | -13.0C | -15. | closer to -15 |
187
+ | -8.0C | -10. | closer to -10 |
188
+ | 0.0C | 0. | zero |
189
+ | 36.0C | 35. | warm DSLR, rounds to 35 |
190
+ | 37.0C | 35. | closer to 35 |
191
+ | 38.0C | 40. | closer to 40 |
192
+ | -20.0C | -20. | colder target, exactly on boundary |
193
+ | -18.0C | -20. | closer to -20 |
194
+
195
+ Override `temperature_tolerance` in your config files to change the rounding.
196
+
197
+ This is especially useful if you're using CMOS/DSLR or otherwise uncooled cameras, and will help you build a Darks library when you can't control the temperature.
198
+
199
+ #### Telescope Ignore Patterns
200
+
201
+ ASIAir and other software often populate the `TELESCOP` header with the name of your mount rather than your telescope. You can define partial match strings to ignore these values. These patterns are **case-insensitive** and will force a manual selection or use a CLI override if matched.
202
+
203
+ ```yaml
204
+ telescope_ignore_patterns:
205
+ - Mount
206
+ - EQMod
207
+ - AM5
208
+ - AM3
209
+ - RST-135
210
+ ```
211
+
212
+ #### Custom Metadata Mappings
213
+
214
+ If your capture software uses non-standard FITS headers or your DSLR uses unusual EXIF tags, you can map them to the fields the organizer expects. The tool uses a fallback mechanism: it checks the tags in the order they are listed and uses the first one that contains a value.
215
+
216
+ ```yaml
217
+ fits_header_mappings:
218
+ temperature:
219
+ - CCD-TEMP
220
+ - SET-TEMP
221
+ - SENSOR-TEMP
222
+ exposure:
223
+ - EXPOSURE
224
+ - EXPTIME
225
+ target:
226
+ - OBJECT
227
+ - TARGET
228
+ exif_tag_mappings:
229
+ temperature:
230
+ - camera_temperature
231
+ - sensor_temperature
232
+ iso:
233
+ - iso
234
+ - base_iso
235
+ ```
236
+
237
+ #### Custom File Extensions
238
+
239
+ If you use file extensions not supported by default, you can add them here:
240
+
241
+ ```yaml
242
+ fits_extensions:
243
+ - .fit
244
+ - .fits
245
+ - .fts
246
+ raw_extensions:
247
+ - .cr2
248
+ - .cr3
249
+ - .nef
250
+ - .arw
251
+ - .dng
252
+ ```
253
+
254
+ #### Using a Custom Config File
255
+
256
+ You can specify a custom config file in all subcommands, and that config will be used for the duration of that run session:
257
+
258
+ ```bash
259
+ astro-subframe-organizer run --config ~/galaxy-season.yml # All interactive menus will use equipment from galaxy-season.yml until you quit
260
+ ```
261
+
262
+ ## Organization Tools
263
+
264
+ There are several ways to use `astro-subframe-organizer`.
265
+
266
+ ### Interactive Menu
267
+
268
+ To run the interactive organizer:
269
+
270
+ ```bash
271
+ astro-subframe-organizer run # aliases: -i, --interactive
272
+ ```
273
+
274
+ This will present you with a series of interactive menus to walk you through organizating each subframe type. Each subframe type has its own set of required inputs, which it will try to gather from FITS headers or filename patterns. If the information can't be detected automatically, the you will be prompted to choose, typically from the equipment in your [configuration file](#configuration).
275
+
276
+ ```stdout
277
+ $ astro-subframe-organizer run --dry-run
278
+ Using config file at /Users/joshkovach/.astro_subframe_organizer.yml
279
+ What are we organizing? (Dry Run)
280
+ 1) Darks
281
+ 2) Flats
282
+ 3) Lights
283
+ 4) Biases
284
+ 5) Remove empty directories
285
+ 6) Remove jpg thumbnails
286
+ 7) Rename files from EXIF data
287
+ 8) Quit
288
+ Choose 1-8 [1]:
289
+ ```
290
+
291
+ Selecting a given tool will lead you through an interactive set of prompts and confirmation steps to help organize your data, for example:
292
+
293
+ ```stdout
294
+ What are we organizing? (Dry Run) Lights
295
+ Using config file at ~/.astro_subframe_organizer.yml
296
+ Preparing to move 330 Light files from 14 groups...
297
+ Preparing to move 1 Light file(s)
298
+ FROM spec/fixtures/cr2
299
+ TO spec/fixtures/cr2/Light_Aurora_FLATSET_20210418_ISO_6400_EXP_4.0s_Bin_1_CCD-TEMP_20._TELESCOPE_????_FILTER_????_CAMERA_????
300
+ Continue? (Y/n)
301
+ ```
302
+
303
+ Note the `????` in the target path name – these are the fields that were not able to be detected automatically, and you will be prompted to select from a series of options to pick the missing fields from your configured equipment:
304
+
305
+ ```stdout
306
+ For Light set Light_Aurora_4.0s_Bin1_ISO6400_20210418-025606_20.0C_0441.CR2..Light_Aurora_4.0s_Bin1_ISO6400_20210418-025606_20.0C_0441.CR2:
307
+ ⚠ Telescope auto-detect failed.
308
+ What telescope is this set for?
309
+ 1) RedCat51
310
+ 2) ZhumellZ130
311
+ 3) AperturaAD8
312
+ 4) MeadeDS90
313
+ 5) CanonEFS1855
314
+ Choose 1-5 [1]:
315
+
316
+ Selected Telescope: RedCat51
317
+
318
+ ⚠ Filter auto-detect failed.
319
+ What filter is used with this set?
320
+ 1) BaaderMoon
321
+ 2) NBZ
322
+ 3) NoFilter
323
+ Choose 1-3 [1]:
324
+
325
+ Selected Filter: NBZ
326
+
327
+ ⚠ Camera auto-detect failed.
328
+ What camera is used with this set?
329
+ 1) T7
330
+ 2) 183MC
331
+ Choose 1-2 [1]:
332
+
333
+ Selected Camera: 183MC
334
+
335
+ mv /Users/joshkovach/astrophotography/ruby-scripts/astro-subframe-organizer/spec/fixtures/cr2/Light_Aurora_4.0s_Bin1_ISO6400_20210418-025606_20.0C_0441.CR2 /Users/joshkovach/astrophotography/ruby-scripts/astro-subframe-organizer/spec/fixtures/cr2/Light_Aurora_FLATSET_20210418_ISO_6400_EXP_4.0s_Bin_1_CCD-TEMP_20._TELESCOPE_RedCat51_FILTER_NBZ_CAMERA_183MC/Light_Aurora_4.0s_Bin1_ISO6400_20210418-025606_20.0C_0441.CR2
336
+ Done
337
+
338
+ Preparing to move 62 Light file(s)
339
+ FROM spec/fixtures/fits/light-blanks
340
+ TO spec/fixtures/fits/light-blanks/Light_C 1_FLATSET_20260411_ROTATION_108deg_GAIN_111_EXP_300.0s_Bin_1_TELESCOPE_EQMod Mount_FILTER_????_CAMERA_ZWO ASI183MC Pro
341
+ Continue? (Y/n)
342
+ ```
343
+
344
+ For each new set of files (split by index number overflow or when detected equipment changes) within the target directory, you'll be guided through the same set of prompts until all files have been organized into descriptive, keyword-based directories.
345
+
346
+ ### Global Options
347
+
348
+ **`--dry-run`**
349
+
350
+ Great way to start experimenting with the tool. It will display all the `mv` commands that would happen, but without actually moving anything. Experiment without any risk, and to get a feel for how it will work with your files.
351
+
352
+ **`--skip-confirm`**
353
+
354
+ After you've become comfortable with how the tools work, you can pass override options to any command to make your workflow quicker. Passing the `--skip-confirm` option to any command will skip the `Continue?` prompts, and just assume that you know what you're doing. Especially helpful when you're using [command mode](#command-mode), where you can skip all interactions completely.
355
+
356
+ ```stdout
357
+ $ astro-subframe-organizer run --dry-run --skip-confirm
358
+ Using config file at /Users/joshkovach/.astro_subframe_organizer.yml
359
+ What are we organizing? (Dry Run) Lights
360
+ ⚠ Unprocessed raw images detected, but will be ignored. Raw images must be renamed before organizing. Run `astro-subframe-organizer raw rename_from_exif`, then try again.
361
+ Using config file at ~/.astro_subframe_organizer.yml
362
+ Preparing to move 330 Light files from 14 groups...
363
+ For Light set Light_Aurora_4.0s_Bin1_ISO6400_20210418-025606_20.0C_0441.CR2..Light_Aurora_4.0s_Bin1_ISO6400_20210418-025606_20.0C_0441.CR2:
364
+ ⚠ Telescope auto-detect failed.
365
+ What telescope is this set for?
366
+ 1) RedCat51
367
+ 2) ZhumellZ130
368
+ 3) AperturaAD8
369
+ 4) MeadeDS90
370
+ 5) CanonEFS1855
371
+ Choose 1-5 [1]:
372
+ ```
373
+
374
+ **`--verbose`**
375
+
376
+ Prints all logs, including debug messages. Every file moved will display its `mv` command.
377
+
378
+ **`--path`**
379
+
380
+ By default, ASO will operate on the working directory (where the command is called from), and works on all sub-directories. Alternatively, you can specify a `--path` to operate on. Again, this will run recursively by default.
381
+
382
+ ```bash
383
+ astro-subframe-organizer light --path staged/Plan/Lights/NGC\ 2264/
384
+ ```
385
+
386
+ The above command will organize only the light files in the `NGC 2264` directory.
387
+
388
+ ### Equipment Options
389
+
390
+ > [!TIP]
391
+ >
392
+ > Use the [`unorganize`](#unorganize) command if you need to undo an organization that didn't work as you expected.
393
+
394
+ **`--telescope`**
395
+
396
+ Automatically sets the telescope field for any command that uses it. When using `--telescope`, it will override the `TELESCOP` FITS header, and does not need to be one of the telescopes in your config file. If the auto-detected telescope is different from the `--telescope` value, a warning will be logged (e.g., `Using telescope RedCat51, but detected EQMod Mount`), but the move will continue using your override.
397
+
398
+ > [!NOTE]
399
+ >
400
+ > ASIAir sets the `TELESCOP` header to your *mount*, not your telescope, so you will likely see the warning a lot if your capture software does the same.
401
+
402
+ **`--camera`**
403
+
404
+ Automatically sets the camera field for any command that uses it. When using `--camera`, it will override the `INSTRUME` FITS header. If the auto-detected camera differs from your override, a warning will be logged, but the move will continue.
405
+
406
+ **`--filter`**
407
+
408
+ Automatically sets the filter field for any command that uses it. When using `--filter`, it will override the `FILTER` FITS header. If the auto-detected filter differs from your override, a warning will be logged, but the move will continue.
409
+
410
+ ### Command Mode
411
+
412
+ If you want to skip the interactive menu, or you know what you're doing without it, you can directly call each of the available commands (and a few more) using the commands directly.
413
+
414
+ #### Darks
415
+
416
+ Darks will be grouped in a folder by `CCD-TEMP` (rounded to nearest 5°C), `ISO` or `GAIN`, `EXP`, `CAMERA` and `MONTH` (e.g. 2022-06).
417
+
418
+ ```bash
419
+ # run without interactive steps
420
+ astro-subframe-organizer darks --camera 'ZWO ASI183MC Pro' --skip-confirm
421
+ ```
422
+
423
+ > [!TIP]
424
+ > When shooting with an uncooled camera, you can get a good idea what temperatures you need, and allows me to create master darks with combined temperatures of +/- 5°C if I need more darks at a certain temperature.
425
+
426
+ ##### Flat Darks
427
+
428
+ The `darks` command will also check for possible flat darks, and will ask for confirmation when the exposure time is 10.0s or less. In the case of a flat dark set, it will organize them into a folder with `ISO` or `GAIN`, `EXP`, and `FLATSET` (the date of the darks and flats). These don't take `CCD-TEMP` into account, assuming the flats and flat darks are taken at roughly the same time and under the same conditions. 1°C variation is not going to make enough of a difference for me to care, and I only want one master flat from this `FLATSET`.
429
+
430
+ These files will be grouped into a folder prefixed with `DarkFlat` instead of just `Dark`. When moving off the ASIAir, I put this folder inside a `FLATSET_<date>` folder with the accompanying flats folder so I can load all the necessary files by directory in one shot in WBPP.
431
+
432
+ > [!NOTE]
433
+ > I don't actually use the DarkFlat capability anymore. This is a relic of when I had less control over operating conditions, so I've left it for beginners who may find it useful. The keywords used make it easier to match flats to flat-darks when dumping raw subframes into WBPP instead of using masters from a calibration library.
434
+ >
435
+ > Instead, I always shoot my flats at a fixed exposure time (5.0s), adjusting my flat panel to give the desired brightness for the equipment and exposure time I'm using. Whenever I create my Dark library for the season, I capture a set matching the exposure time of my flats. I use that master dark to separately calibrate my flats for the season.
436
+
437
+ #### Flats
438
+
439
+ Flats need to be taken with the same image train conditions as your lights, which typically includes:
440
+
441
+ - `ROTATION`
442
+ - `ISO` or `GAIN`
443
+ - `EXP`
444
+ - `TELESCOPE`
445
+ - `FILTER`
446
+ - `CAMERA`
447
+
448
+ Ideally, they are taken during or right after your session, so that any variation in the image train (dust, focus, ice, etc.) don't have a chance to change before you capture the frames that are meant to remove those variations.
449
+
450
+ > [!TIP]
451
+ > For this reason, I always take my flats in the morning after my imaging session, and before shutting off the camera to prevent any moisture that might be present on the sensor from melting and freezing in a different position.
452
+
453
+ In order to match lights, flats will be grouped using the [`FLATSET`](#flatset) keyword along with the keywords listed above.
454
+
455
+ ```bash
456
+ # run without interactive steps
457
+ astro-subframe-organizer flats --telescope Redcat51 --filter NBZ --camera 'ZWO ASI183MC Pro' --skip-confirm
458
+ ```
459
+
460
+ All of the aforementioned keywords are used in WBPP when doing the lights calibration and integration.
461
+
462
+ > [!TIP]
463
+ > Calibrate your flats after each session with a matching master dark from your darks library, and use the master flat in WBPP instead of the raw subframes. If you calibrate your flats with darks, you don't need to take bias frames.
464
+
465
+ ##### FlatSet
466
+
467
+ The `FLATSET` value is just the date in format `YYYYMMdd`. Because I always take my flats in the morning after my session, the `FLATSET` for lights is calculated as the *end date* of the session. Any subframe taken after noon will use the `FLATSET` of the following day, and anything before noon will use the same date.
468
+
469
+ In the rare event that I can't take flats for a session, as long as I didn't change the image train significantly, I can usually still calibrate with a `FLATSET` taken on another date close to the missed session.
470
+
471
+ #### Lights
472
+
473
+ Similar to flats, organizing lights will prompt to select the telescope and filter used for this data set, and will organize into a folder with most of the same keywords as the flats.
474
+
475
+ ```bash
476
+ # run without interactive steps
477
+ astro-subframe-organizer lights --telescope Redcat51 --filter BaaderMoon --camera 'ZWO ASI183MC Pro' --skip-confirm
478
+ ```
479
+
480
+ #### Biases
481
+
482
+ Biases are taken at the fastest shutter speed available to your camera to remove the latent electrical noise on the camera sensor. When using flats without flat-darks, the flats and lights both need to be calibrated with bias frames. These frames are grouped primarily by `EXP`, `CAMERA`, and `MONTH` (to help match appropriate darks).
483
+
484
+ ```bash
485
+ # run without interactive steps
486
+ astro-subframe-organizer biases --camera 'ZWO ASI183MC Pro' --skip-confirm
487
+ ```
488
+
489
+ > [!TIP]
490
+ > If you take darks to calibrate your flats (a.k.a. flat-darks, a.k.a. dark-flats) and use the master flat calibrated with those darks, you don't need to use bias frames at all.
491
+
492
+ #### Unorganize
493
+
494
+ If you find that the organization didn't go as you hoped, you can easily ungroup those subframes, which just takes them out of their grouped directory, and removes the empty directory after the move.
495
+
496
+ ```bash
497
+ # run without interactive steps
498
+ astro-subframe-organizer unorganize --skip-confirm
499
+ ```
500
+
501
+ ### Raw Tools
502
+
503
+ If you're shooting RAW without any software to wrap them with FITS headers, you'll end up getting an image named something like `IMG_00001.CR2` (that's what my Canon T7 does, anyway). This doesn't really help you be an organized astrophotographer, so I built a tool to help!
504
+
505
+ To use this tool uses [`exiftool`](https://exiftool.org/) for working with RAW files. For Mac and Linux users, the tool is included with the gem, but Windows users will need to install it separately.
506
+
507
+ **Windows**
508
+
509
+ Follow instructions at <https://exiftool.org/>, or install using Chocolatey on Windows 10. I don't use Windows, so if anyone uses it and wants to update this to be more specific, please submit a pull request.
510
+
511
+ ```bash
512
+ choco install exiftool
513
+ ```
514
+
515
+ **OSX**
516
+
517
+ ```bash
518
+ brew install exiftool
519
+ ```
520
+
521
+ **Ubuntu Linux**
522
+
523
+ ```bash
524
+ sudo apt install exiftool
525
+ ```
526
+
527
+ #### Rename From EXIF
528
+
529
+ I first wrote this tool after I had started using an ASIAir with my Canon T7, and my original organization script used a filename parser to capture metadata and group accordingly. So for historical reasons, this tool renames RAW files to match the naming scheme used by ASIAir, which allowed me to group data from before and after getting my ASIAir.
530
+
531
+ > [!TIP]
532
+ > If you are starting out in astrophotography, and are just using a DSLR, I recommend starting here. Rename your unhelpful raw files, then run them through the organizer tools.
533
+
534
+ Use `raw rename` to rename `IMG_****.CR2` files to something helpful based on the embedded EXIF data and your own knowledge about what's in those photos.
535
+
536
+ ```bash
537
+ # run without interactive steps
538
+ astro-subframe-organizer raw rename --type light --target 'NGC 2264' --telescope Redcat51 --filter BaaderMoon --skip-confirm
539
+ astro-subframe-organizer raw rename --type flat --target 'NGC 2264' --telescope Redcat51 --filter BaaderMoon --skip-confirm
540
+ astro-subframe-organizer raw rename --type dark --skip-confirm
541
+ astro-subframe-organizer raw rename --type bias --skip-confirm
542
+ ```
543
+
544
+ You should do this on files that are already grouped in separate directories to help keep them separate. There's currently no auto-detection set up for the type of subframe you're organizing, so you have to specify it. If you leave off any of the options, you will be prompted to fill in or select the required values for the subframe type.
545
+
546
+ #### Revert Rename
547
+
548
+ The `raw rename` tool will only work on images that match the prefix `IMG_`, so if you messed up the rename on the first pass, you can revert them and have another go.
549
+
550
+ ```bash
551
+ # run without interactive steps
552
+ astro-subframe-organizer raw revert --skip-confirm
553
+ ```
554
+
555
+ This will rename each image back to `IMG_****.CR2` as Canon intended.
556
+
557
+ ### Cleanup Tools
558
+
559
+ #### Delete Thumbnails
560
+
561
+ ASIAir, and maybe other capturing software, includes a thumbnail for each FITS files so that it can display preview images on your phone. Outside of that context, they are a nuisance and are completely unnecessary. This tool will delete all those annoying jpgs in a snap!
562
+
563
+ ```bash
564
+ # run without interactive steps
565
+ astro-subframe-organizer cleanup thumbnails --skip-confirm
566
+ ```
567
+
568
+ It can't be undone, but why would you want to?
569
+
570
+ #### Delete Empty Directories
571
+
572
+ After reorganizing my photos and moving them to a better place, I'm often left with a bunch of deeply nested empty directories, with some not-so-empty ones mixed in, and I'd rather not have to dig through each one to figure out what to delete. So I made a tool for that!
573
+
574
+ ```bash
575
+ astro-subframe-organizer cleanup empty
576
+ ```
577
+
578
+ This will remove any directory that completely empty, recursively. Mac users may be familiar with the infamous hidden `.DS_Store` file - I don't count that as content. If the directory contains *only* `.DS_Store`, it still counts as empty. You can run this at the top-level of wherever you're working to make it easier to find what matters.
579
+
580
+ ### Utils
581
+
582
+ If you want to see FITS headers or EXIF data that's on your images, use `inspect`:
583
+
584
+ ```bash
585
+ astro-subframe-organizer inspect dark/IMG_0001.CR2
586
+ ```
587
+
588
+ This will print out all the metadata on your RAW images, or all the FITS headers on a `.fit` image.
589
+
590
+ ## Organized Directory Structure
591
+
592
+ The organizer moves files into specific directory structures based on the image type. These structures are designed to be compatible with PixInsight's `WeightedBatchPreProcessing` (WBPP) script by using standard keywords.
593
+
594
+ ### Light Frames
595
+
596
+ Organized to match with flats from a specific session and darks of the same exposure/gain/temp.
597
+ `Light_<target>_FLATSET_<date>_GAIN_<gain>_EXP_<exp>_Bin_<bin>_CCD-TEMP_<temp>_TELESCOPE_<tel>_FILTER_<fil>_CAMERA_<cam>`
598
+
599
+ ### Flat Frames
600
+
601
+ Organized to match with Light frames from the same session.
602
+ `Flat_FLATSET_<date>_GAIN_<gain>_EXP_<exp>_Bin_<bin>_TELESCOPE_<tel>_FILTER_<fil>_CAMERA_<cam>`
603
+
604
+ ### Dark Frames
605
+
606
+ Organized to facilitate a library of master darks.
607
+ `Dark_ISO_<iso>_EXP_<exp>_CCD-TEMP_<temp>_CAMERA_<cam>_MONTH_<month>`
608
+
609
+ ### Bias Frames
610
+
611
+ `Bias_GAIN_<gain>_EXP_<exp>_Bin_<bin>_CAMERA_<cam>_MONTH_<month>`
612
+
613
+ ### Flat Darks (DarkFlats)
614
+
615
+ Used specifically to calibrate flats when bias frames aren't used. These are especially useful if you are using an uncooled camera, and you take your flat darks at the same time as your flats.
616
+ `DarkFlat_FLATSET_<date>_ISO_<iso>_EXP_<exp>_Bin_<bin>_CAMERA_<cam>`
617
+
618
+ ## PixInsight - Saved WBPP Process Icons
619
+
620
+ All of this organization is to facilitate a standardized workflow in PixInsight using WBPP with predefined process icons for generating each of master darks, master flats, and the master lights.
621
+
622
+ > [!TIP]
623
+ > By including `MONTH` in Dark and Bias paths, you can maintain a rolling library of calibration frames, allowing you to easily identify and use the most recent masters for your current data.
624
+
625
+ ### WBPP_Darks
626
+
627
+ This process icon is preloaded with appropriate master biases, uses the following grouping keywords on the Calibration tab:
628
+
629
+ | Keyword | Pre | Post |
630
+ | -------- | --- | ---- |
631
+ | CCD-TEMP | x | x |
632
+ | GAIN | x | x |
633
+ | ISO | x | x |
634
+ | EXP | x | x |
635
+ | MONTH | x | x |
636
+ | CAMERA | x | x |
637
+
638
+ The generated darks are then able to be used in the `WBPP_Integration` process icon.
639
+
640
+ ### WBPP_Flats
641
+
642
+ This process icon is also preloaded with appropriate master biases, and uses the following grouping keywords on the Calibration tab:
643
+
644
+ | Keyword | Pre | Post | Notes |
645
+ | -------- | --- | ---- | ----- |
646
+ | FLATSET | x | x | |
647
+ | ROTATION | x | x | |
648
+ | ISO | x | x | |
649
+ | GAIN | x | x | |
650
+ | CAMERA | x | x | |
651
+ | BIN | x | x | |
652
+ | EXP | x | | Match for Darks, but not for Lights |
653
+ | CCD-TEMP | x | | Match for Darks, but not for Lights |
654
+
655
+ Since my flats and darkflats are together in the same directory, I can load them into WBPP using the `Directory` button in one step, and then click the run button.
656
+
657
+ > [!IMPORTANT]
658
+ > Manually remove the `EXP_*` segment from the new master flat's file name if present. Flats should ignore exposure time when matching to lights.
659
+ >
660
+ > If you don't do this, the next step, `WBPP_Integration` will not automatically match your flats to your lights, since `EXP` is a required grouping keyword in that step to automatically match darks to lights. **If the property exists on the filename, they must match.** If keywords on one file don't exist on another, they are ignored in keyword grouping in WBPP.
661
+
662
+ ### WBPP_Integration
663
+
664
+ This process icon is preloaded with appropriate biases, but shouldn't be necessary at this point if you followed the process described so far. This step uses the following grouping keywords on the Calibration tab:
665
+
666
+ | Keyword | Pre | Post | Notes |
667
+ | -------- | --- | ---- | ----- |
668
+ | PANE | x | x | |
669
+ | FLATSET | x | | |
670
+ | ROTATION | x | x | |
671
+ | BIN | x | x | |
672
+ | EXP | x | | |
673
+ | CCD-TEMP | x | | |
674
+ | ISO | x | x | |
675
+ | GAIN | x | x | |
676
+ | TELESCOPE| x | x | |
677
+ | FILTER | x | x | |
678
+ | CAMERA | x | x | |
679
+
680
+ If you are working on multiple targets, you'll want to make sure you choose the `Registration Reference Image -> Mode -> auto by LIGHT (or PANE)` setting under the Calibration tab.
681
+
682
+ This final step is relatively easy. Simply load your master darks (not darkflats), your master flats, and all your lights. The script should automatically detect and group all the files for calibration. You may have to manually select a few of the darks and flats for calibration if you reuse the same FLATSET for multiple nights. Other than that, just check your other settings and output directory for this run and you should be good to go.
683
+
684
+ ## Historical Development Notes
685
+
686
+ This was based on a script written a long time ago, so here's some historical information that may be relevant for new astrophotographers.
687
+
688
+ ### Pre-ASIAir Image Data
689
+
690
+ With the Canon T7 data captured before I started using an ASIAir Plus, the images were captured in RAW format as `CR2` files, with the name `IMG_0001.CR2`, which is pretty useless for AP photo organization. However, I've found that these RAW files do include most of the necessary data in EXIF tags to allow renaming to match my newer data generated by the ASIAir Plus, including exposure time, camera temperature, iso, etc. Using [exiftool](https://exiftool.org), these files can be renamed (with some extra parsing work in Ruby and some user input) to match the same file name pattern with actual data from the original source files.
691
+
692
+ To rename your older `IMG_XXXX.CR2` files, you can use the `Rename files with EXIF data` option. You will then be prompted to choose which type of file you are organizing. If you are organizing a `Light` file, you'll also be prompted to enter the target name.
693
+
694
+ > [!IMPORTANT]
695
+ > You must have `exiftool` installed and in your system path in order to run this renaming process.
696
+
697
+ #### Exposure Time
698
+
699
+ When the EXIF data includes `ExposureTime` less than 1 second, the value is formatted as a fraction, e.g. `1/250`, which then gets interpreted by most file systems as a directory separator. In order to handle this appropriately to match the decimal exposure formatting that the ASIAir generates, we need to do a few workarounds. First, we need to replace the `/` character with `-` so that the files don't get misplaced in a new directory. Second, we need to take the file that `exiftool` generates and parse it to recalculate that fraction value as a decimal at an appropriate time scale. So we parse the `1-250`, convert that to a `Rational` in Ruby, `Rational(1, 250)`, and then change the scale from seconds to milliseconds to nanoseconds until we have the exposure time represented as a number equal to or greater than 1.0.
700
+
701
+ #### Renaming Previously Renamed Files
702
+
703
+ This operation also lets you rename files that you renamed with an older naming format and convert it automatically to use the consistent naming pattern. If the script finds files that are not named `IMG_XXXX.CR2`, it will prompt you to choose whether to skip or rename them. It will then rename them all to `IMG_XXXX.CR2`, where `XXXX` is the last 4 characters of the filename (usually the sequence number). It will then run the script as normal on the now normallized files.
704
+
705
+ Once all of the files are renamed, they can then be organized into folders just as we do with the FITS files that we get from the ASIAir.
706
+
707
+ ## Contributing
708
+
709
+ This is a tool I've been using for several years now, and I'm excited to get it into a place I feel comfortable sharing it with other people to use. That said, it's *alpha* and has only been used *by me*. If you use this and have any problems with it, or would like better support for your equipment or workflows, please drop a friendly issue, and we can discuss it. If you have ideas for improvement, I'm also happy to consider pull requests.
710
+
711
+ Contributions are welcome from astrophotographers and developers alike — you don't need to write code to help. You can test the organizer with your own equipment and report what works or doesn't, validate the organization structure for your stacking software workflow, improve documentation, or help other users.
712
+
713
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for full details, including development setup, fixture file guidelines, and pull request expectations.
714
+
715
+ This project follows the [Contributor Covenant](https://www.contributor-covenant.org/) [Code of Conduct](CODE_OF_CONDUCT.MD).
716
+
717
+ ### Get Started Coding
718
+
719
+ ```bash
720
+ git clone https://github.com/your-username/astro-subframe-organizer
721
+ cd astro-subframe-organizer
722
+ bin/setup
723
+ bundle exec rake spec
724
+ ```
725
+
726
+ The test suite uses real stripped FITS fixture files. If you're working on a bug that
727
+ requires a new fixture, strip it first to remove image data and location headers:
728
+
729
+ ```bash
730
+ bundle exec bin/strip_fits -o spec/fixtures/fits/your-set/ your_file.fit
731
+ ```
732
+
733
+ ## Disclaimer
734
+
735
+ I make no claims about the reliability of Astro Subframe Organizer under your circumstances. Please test and verify the code and the conditions you will run this script through before running it on your data. Dry runs are your friend. While Astro Subframe Organizer is relatively well tested, it may behave unexpectedly if your data capture is significantly different from mine. **I am not responsible for lost or corrupted data or damaged devices resulting from the use of this Astro Subframe Organizer**. Just be careful, **make backups**, test things out before you fully rely on any part of this tool. If you find an issue while using this tool, please report it on the [issue tracker](https://github.com/shekibobo/astro-subframe-organizer/issues).
736
+
737
+ Clear skies!