espada-astro 1.0.0__tar.gz

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 (40) hide show
  1. espada_astro-1.0.0/PKG-INFO +593 -0
  2. espada_astro-1.0.0/README.md +574 -0
  3. espada_astro-1.0.0/adplib/__init__.py +0 -0
  4. espada_astro-1.0.0/adplib/config.py +479 -0
  5. espada_astro-1.0.0/adplib/config.yaml +63 -0
  6. espada_astro-1.0.0/adplib/doc/info_docs.yaml +620 -0
  7. espada_astro-1.0.0/adplib/espada.py +1895 -0
  8. espada_astro-1.0.0/adplib/exceptions.py +15 -0
  9. espada_astro-1.0.0/adplib/group.py +360 -0
  10. espada_astro-1.0.0/adplib/logger.py +351 -0
  11. espada_astro-1.0.0/adplib/sip/__init__.py +0 -0
  12. espada_astro-1.0.0/adplib/sip/sip_args.yaml +19 -0
  13. espada_astro-1.0.0/adplib/sip/sipargs.py +1544 -0
  14. espada_astro-1.0.0/adplib/sofia/__init__.py +0 -0
  15. espada_astro-1.0.0/adplib/sofia/region.py +180 -0
  16. espada_astro-1.0.0/adplib/sofia/sofia_abs_default.par +157 -0
  17. espada_astro-1.0.0/adplib/sofia/sofia_default.par +157 -0
  18. espada_astro-1.0.0/adplib/sofia/sofia_emi_default.par +157 -0
  19. espada_astro-1.0.0/adplib/sofia/sofia_test_datacube.fits +0 -0
  20. espada_astro-1.0.0/adplib/sofia/sopar.py +1818 -0
  21. espada_astro-1.0.0/adplib/tap/__init__.py +0 -0
  22. espada_astro-1.0.0/adplib/tap/datap.py +1669 -0
  23. espada_astro-1.0.0/adplib/tap/download_par.yaml +82 -0
  24. espada_astro-1.0.0/adpweb/__init__.py +0 -0
  25. espada_astro-1.0.0/adpweb/images/ESPADA_logo.png +0 -0
  26. espada_astro-1.0.0/adpweb/images/Workflow_v2-1.png +0 -0
  27. espada_astro-1.0.0/adpweb/report.py +1040 -0
  28. espada_astro-1.0.0/adpweb/resources/base.css +92 -0
  29. espada_astro-1.0.0/adpweb/resources/collapsible.css +299 -0
  30. espada_astro-1.0.0/adpweb/resources/dataset_tab.css +302 -0
  31. espada_astro-1.0.0/adpweb/templates/report.html +663 -0
  32. espada_astro-1.0.0/espada_astro.egg-info/PKG-INFO +593 -0
  33. espada_astro-1.0.0/espada_astro.egg-info/SOURCES.txt +38 -0
  34. espada_astro-1.0.0/espada_astro.egg-info/dependency_links.txt +1 -0
  35. espada_astro-1.0.0/espada_astro.egg-info/entry_points.txt +2 -0
  36. espada_astro-1.0.0/espada_astro.egg-info/requires.txt +11 -0
  37. espada_astro-1.0.0/espada_astro.egg-info/top_level.txt +2 -0
  38. espada_astro-1.0.0/pyproject.toml +52 -0
  39. espada_astro-1.0.0/setup.cfg +4 -0
  40. espada_astro-1.0.0/setup.py +3 -0
@@ -0,0 +1,593 @@
1
+ Metadata-Version: 2.4
2
+ Name: espada-astro
3
+ Version: 1.0.0
4
+ Summary: ESPADA either downloads data via the TAP service or uses ALMA's own data and performs source searches using SOFIA software and produces images for publication or quick inspection using SIP software.
5
+ Author-email: Borja Montoro Molina <borjamomo96@gmail.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: numpy>=2.1.2
9
+ Requires-Dist: pandas>=2.2.3
10
+ Requires-Dist: pyyaml>=6.0.2
11
+ Requires-Dist: astropy>=6.1.4
12
+ Requires-Dist: astroquery>=0.4.8.dev9474
13
+ Requires-Dist: pyvo>=1.5.3
14
+ Requires-Dist: matplotlib>=3.9.2
15
+ Requires-Dist: psutil>=5.9.0
16
+ Requires-Dist: rich>=13.0.0
17
+ Requires-Dist: networkx>=3.0
18
+ Requires-Dist: jinja2>=3.1.0
19
+
20
+ # ESPADA: Enhanced Spectral-line Pipeline for the ALMA Data Archive
21
+
22
+ > **Name note:** ESPADA was initially developed under the name **ADPALMAP**. Some legacy names may still appear in the code base, repository name, command-line entry point, documentation, or output labels. The command-line executable is now `espada`.
23
+
24
+ ESPADA is an end-to-end Python pipeline for generating advanced spectral-line data products from ALMA data. It wraps and coordinates data discovery/download from the ALMA Science Archive, source finding and parameterisation with [SoFiA-2](https://gitlab.com/SoFiA-Admin/SoFiA-2), visualisation with the [SoFiA Imaging Pipeline (SIP)](https://github.com/kmhess/SoFiA-image-pipeline), optional grouping of related detections, logging, quality assessment, and final HTML/JSON reports.
25
+
26
+ ESPADA is designed for minimal user intervention, while still allowing users to override the main pipeline configuration, SoFiA parameters, and SIP arguments when needed.
27
+
28
+ 📘 **Full documentation:** [ESPADA Documentation](docs/ESPADA_DOC.pdf)
29
+
30
+ ## Contents
31
+
32
+ - [Main features](#main-features)
33
+ - [Workflow overview](#workflow-overview)
34
+ - [Requirements](#requirements)
35
+ - [Installation](#installation)
36
+ - [Quick start](#quick-start)
37
+ - [Running ESPADA](#running-espada)
38
+ - [Configuration files](#configuration-files)
39
+ - [Input data](#input-data)
40
+ - [Outputs](#outputs)
41
+ - [Quality assessment and reports](#quality-assessment-and-reports)
42
+ - [Advanced usage](#advanced-usage)
43
+ - [Known limitations](#known-limitations)
44
+ - [Troubleshooting](#troubleshooting)
45
+ - [Acknowledgements](#acknowledgements)
46
+ - [Citation and license](#citation-and-license)
47
+
48
+ ## Main features
49
+
50
+ - Query and download ALMA Science Archive (ASA) products through TAP/ADQL services.
51
+ - Run SoFiA-2 source finding in `emission`, `absorption`, or `both` modes.
52
+ - Generate SIP visualisation products for detected sources.
53
+ - Process multiple FITS datasets in parallel with dynamic CPU/RAM-aware worker allocation.
54
+ - Optionally group spatially overlapping detections along the spectral axis.
55
+ - Generate execution logs, per-dataset QA products, and interactive HTML plus machine-readable JSON reports.
56
+ - Re-run individual pipeline stages without re-running the full workflow, provided the expected intermediate products are available.
57
+
58
+ ## Workflow overview
59
+
60
+ At a high level, ESPADA follows this sequence:
61
+
62
+ <p>
63
+ <img src="adpweb/images/Workflow_v2-1.png" alt="ESPADA workflow" width="450">
64
+ </p>
65
+
66
+ The main module, `espada`, orchestrates the workflow. The secondary modules are:
67
+
68
+ | Module | Role |
69
+ | --- | --- |
70
+ | `config` | Validate the main configuration and parameter files. |
71
+ | `logger` | Manage terminal and file logging. |
72
+ | `datap` | Query and download data from the ALMA Science Archive. |
73
+ | `sopar` | Prepare and run SoFiA-2. |
74
+ | `sipargs` | Translate `sip_args.yaml` into SIP command-line arguments. |
75
+ | `group` | Group overlapping source detections and re-process grouped masks. |
76
+ | `report` | Generate JSON and interactive HTML reports. |
77
+
78
+ ## Requirements
79
+
80
+ ESPADA requires:
81
+
82
+ - Python `>= 3.10`.
83
+ - [SoFiA-2](https://gitlab.com/SoFiA-Admin/SoFiA-2) installed and callable as:
84
+
85
+ ```bash
86
+ sofia
87
+ ```
88
+
89
+ - [SoFiA Imaging Pipeline (SIP)](https://github.com/kmhess/SoFiA-image-pipeline) installed and callable as:
90
+
91
+ ```bash
92
+ sofia_image_pipeline
93
+ ```
94
+
95
+ - [Ghostscript](https://www.ghostscript.com/) for the final HTML report and for converting SoFiA EPS diagnostic plots to PNG for browser display.
96
+
97
+ Debian/Ubuntu:
98
+
99
+ ```bash
100
+ sudo apt-get install ghostscript
101
+ ```
102
+
103
+ macOS with Homebrew:
104
+
105
+ ```bash
106
+ brew install ghostscript
107
+ ```
108
+
109
+ SIP combined images may also require ImageMagick if the SIP `combo` option is used.
110
+
111
+ ### Recommended Python environment
112
+
113
+ Using an isolated environment is strongly recommended. One possible setup with `pyenv` is:
114
+
115
+ ```bash
116
+ curl https://pyenv.run | bash
117
+ # Follow the shell instructions printed by pyenv, then reload your shell.
118
+ source ~/.bashrc
119
+
120
+ pyenv install 3.10
121
+ pyenv virtualenv 3.10 espada
122
+ pyenv activate espada
123
+ ```
124
+
125
+ To leave the environment:
126
+
127
+ ```bash
128
+ pyenv deactivate
129
+ ```
130
+
131
+ ## Installation
132
+
133
+ For a regular installation from PyPI:
134
+
135
+ ```bash
136
+ python -m pip install espada-astro
137
+ ```
138
+
139
+ For development, clone the repository and install it in editable mode:
140
+
141
+ ```bash
142
+ git clone https://github.com/Borjamomo96/ESPADA.git
143
+ cd ESPADA
144
+ python -m pip install -e .
145
+ ```
146
+
147
+ Editable mode is recommended when modifying ESPADA because it keeps all repository files available from the working tree.
148
+
149
+ Verify that the command-line entry point is available:
150
+
151
+ ```bash
152
+ espada --help
153
+ ```
154
+
155
+ ## Quick start
156
+
157
+ 1. Install ESPADA, SoFiA-2, SIP, and Ghostscript.
158
+ 2. Copy or edit the default `config.yaml` template.
159
+ 3. Choose one input route:
160
+ - local FITS datasets through `input_data_set` or `input_file`, or
161
+ - automatic ASA query/download through `enable_tap_service: True` and `download_par.yaml`.
162
+ 4. Run:
163
+
164
+ ```bash
165
+ espada -c config.yaml
166
+ ```
167
+
168
+ A minimal local-input run might use:
169
+
170
+ ```yaml
171
+ make_report: True
172
+ output_dir: espada_run/
173
+
174
+ enable_tap_service: False
175
+ input_data_set: [data_cube.fits, primary_beam.fits, mask.fits, continuum.fits]
176
+
177
+ enable_sofia: True
178
+ run_mode: both
179
+ use_mask: True
180
+ abs_flag_cube: True
181
+ auto_setup: True
182
+
183
+ enable_sip: True
184
+ enable_group: False
185
+ ```
186
+
187
+ A TAP-based run should set `enable_tap_service: True` in `config.yaml` and define the archive query in `download_par.yaml`.
188
+
189
+ ## Running ESPADA
190
+
191
+ The recommended execution method is the installed command-line interface:
192
+
193
+ ```bash
194
+ espada -c config.yaml
195
+ ```
196
+
197
+ ESPADA can search for a default `config.yaml` if no file is provided, but passing `-c` explicitly is recommended for reproducibility.
198
+
199
+ ### Command-line arguments
200
+
201
+ | Argument | Purpose |
202
+ | --- | --- |
203
+ | `-c`, `--config-file` | Path to the main ESPADA configuration file. |
204
+ | `-cp`, `--config-parameters` | Override `config.yaml` parameters from the terminal using `parameter=value`. Spaces are not allowed inside each assignment. |
205
+ | `-sop`, `--sofia-parameters` | Override SoFiA parameters using native SoFiA syntax, e.g. `linker.radiusXY=2`. Overrides apply to all SoFiA parameter files used in the run. |
206
+ | `-sarg`, `--sip-arguments` | Append native SIP command-line arguments, e.g. `-sarg -i 0.15 -m`. This argument should be placed last. |
207
+ | `-i`, `--info` | Print information about parameter files or individual parameters, e.g. `-i file=config.yaml` or `-i parameter=make_report`. |
208
+ | `--debug` | Enable debug logging and traceback output. |
209
+ | `-h`, `--help` | Show help. |
210
+
211
+ Examples:
212
+
213
+ ```bash
214
+ espada -c config.yaml
215
+ espada -c config.yaml -cp enable_tap_service=False input_file=espada_run/espada_input_file.txt
216
+ espada -c config.yaml -cp num_cores=5
217
+ espada -c config.yaml -sop linker.radiusXY=2 pipeline.verbose=true
218
+ espada -c config.yaml -sarg -i 0.15 -m
219
+ espada -c config.yaml --debug
220
+ espada -i file=config.yaml
221
+ espada -i parameter=filename_must_include
222
+ ```
223
+
224
+ Important notes:
225
+
226
+ - Do not add other ESPADA arguments after `-sarg`/`--sip-arguments`; they may be interpreted as SIP arguments or ignored.
227
+ - Some SoFiA parameters are controlled internally by ESPADA and cannot be safely overridden. See [SoFiA parameter handling](#sofia-parameter-handling).
228
+
229
+ ## Configuration files
230
+
231
+ ESPADA uses YAML configuration files, except for the native SoFiA `.par` files.
232
+
233
+ ### `config.yaml`
234
+
235
+ `config.yaml` is the main pipeline configuration file. It controls the global workflow, input data, archive downloads, SoFiA execution, SIP execution, grouping, logging, output directory, and report generation.
236
+
237
+ | Block | Parameters | Description |
238
+ | --- | --- | --- |
239
+ | General | `make_report`, `verbose`, `num_cores`, `output_dir` | Enable final reports, control terminal verbosity, set the maximum core budget, and choose the main output directory. |
240
+ | Logger | `clear_logs`, `log_file` | Configure log cleanup and log-file location. |
241
+ | Input data | `input_data_set`, `input_file` | Provide local data cube, primary beam, mask, and continuum files. |
242
+ | TAP service | `enable_tap_service`, `download_par_file` | Enable ASA download and point to `download_par.yaml`. |
243
+ | SoFiA | `enable_sofia`, `run_mode`, `use_mask`, `abs_flag_cube`, `auto_setup`, `sofia_abs_file`, `sofia_emi_file` | Configure source finding. |
244
+ | SIP | `enable_sip`, `sip_par_file` | Configure SIP image generation. |
245
+ | Group | `enable_group`, `overlap_mode`, `overlap_threshold` | Configure optional grouping of overlapping detections. |
246
+
247
+ Common values:
248
+
249
+ - `run_mode`: `emission`, `absorption`, or `both`.
250
+ - `overlap_mode`: `absflux`, `flux`, or `area`.
251
+ - `overlap_threshold`: value between `0` and `1`; the default documented value is `0.8`.
252
+
253
+ ### `download_par.yaml`
254
+
255
+ `download_par.yaml` configures the `datap` module. It is used only when `enable_tap_service: True`.
256
+
257
+ It contains three main groups:
258
+
259
+ 1. **Server settings**
260
+ - `server_address`: ALMA archive mirror, e.g. ESO, NRAO, or NAOJ URL.
261
+ - `credentials`: allow ALMA Science Portal login.
262
+ - `stored_credentials`: cache credentials between runs.
263
+
264
+ 2. **Query settings**
265
+ - `query_type`: one of `proposal`, `member_ous_id`, `conesearch`, `target`, `keysearch`, or `free`.
266
+ - `query_par`: parameters for the selected query type plus common filters such as `public`, `published`, `point`, `print_targets`, and `print_query`.
267
+
268
+ 3. **Download settings**
269
+ - `data_dir`: destination for downloaded data.
270
+ - `remove_compressed_file`: remove extracted compressed archive files after processing.
271
+ - `remove_archive_mask`: remove the original floating-point archive mask after creating the integer mask required by SoFiA-2.
272
+ - `dryrun`: inspect download size and URLs without downloading.
273
+ - `print_urls`: print download URLs.
274
+ - `filename_must_include`: restrict downloads to URLs containing specific strings.
275
+
276
+ Example proposal query:
277
+
278
+ ```yaml
279
+ query_type: proposal
280
+ query_par:
281
+ proposal_id: "2016.1.00778.S"
282
+ point: False
283
+ public: True
284
+ published: False
285
+ print_targets: True
286
+ print_query: True
287
+ ```
288
+
289
+ Example target query:
290
+
291
+ ```yaml
292
+ query_type: target
293
+ query_par:
294
+ sources: ["V605 Aql"]
295
+ search_radius: 2.0
296
+ point: False
297
+ public: True
298
+ published: False
299
+ print_targets: True
300
+ print_query: True
301
+ ```
302
+
303
+ Example key search:
304
+
305
+ ```yaml
306
+ query_type: keysearch
307
+ query_par:
308
+ search_dict:
309
+ target_name: ["NGC4418"]
310
+ proposal_id: ["2022.1.00738.S"]
311
+ point: False
312
+ public: True
313
+ published: False
314
+ print_targets: True
315
+ print_query: True
316
+ ```
317
+
318
+ After a TAP-based execution, ESPADA writes `espada_input_file.txt` inside the main output directory. This file lists the downloaded datasets in the format expected by `input_file`, so the same data can be reprocessed without querying the archive again.
319
+
320
+ ### SoFiA parameter files
321
+
322
+ ESPADA uses separate SoFiA parameter files for absorption and emission runs:
323
+
324
+ - `sofia_abs_default.par`
325
+ - `sofia_emi_default.par`
326
+
327
+ Users may edit these files or provide alternative files through `sofia_abs_file` and `sofia_emi_file`.
328
+
329
+ #### SoFiA parameter handling
330
+
331
+ The following SoFiA parameters are controlled or constrained by ESPADA because they affect the pipeline workflow:
332
+
333
+ | Parameter(s) | ESPADA behaviour |
334
+ | --- | --- |
335
+ | `input.data`, `input.primaryBeam`, `input.mask` | Controlled by `config.yaml` input settings or by the `datap` module. Values in SoFiA files are ignored. |
336
+ | `input.invert` | Controlled through `run_mode`. |
337
+ | `pipeline.threads` | Calculated internally from `num_cores`, worker count, and SoFiA recommendations. Values are kept between `1` and `8`. |
338
+ | `scfind.enable`, `contsub.enable`, `scaleNoise.enable`, `background.enable`, `threshold.enable`, `reliability.enable`, `dilation.enable` | Automatically disabled when a mask is actively used. |
339
+ | `output.directory` | Controlled by `output_dir`. |
340
+ | `output.filename` | Partially controlled by ESPADA to distinguish datasets and modes. |
341
+ | `output.writeCatXML` | Forced on, because SIP and ESPADA metadata handling require XML catalogues. |
342
+ | `output.writeCubelets` | Forced on, because SIP needs cubelets for visualisation. |
343
+
344
+ When `auto_setup: True`, ESPADA can adjust selected SoFiA settings from FITS header information, including smoothing/linking-related parameters. Treat this feature as experimental and check the logs for parameter changes.
345
+
346
+ ### `sip_args.yaml`
347
+
348
+ `sip_args.yaml` adapts SIP command-line options to YAML. ESPADA reads this file to build the SIP command.
349
+
350
+ Common SIP options include:
351
+
352
+ | Parameter | Description |
353
+ | --- | --- |
354
+ | `catalog_file` | SoFiA catalogue file (`.txt` or `.xml`) to use when SoFiA is disabled. |
355
+ | `source_id` | Source IDs to plot; `0` makes a field summary image, `-1` makes all sources plus summary images. |
356
+ | `output_image_file_type` | Output image format, commonly `png`. |
357
+ | `spec_full_range` | Plot spectra over the full spectral range. |
358
+ | `syn_beam_dimension` | User-provided beam dimensions if missing from FITS headers. |
359
+ | `channel_width` | Required when only moment maps are available. |
360
+ | `min_size` | Minimum image size in arcmin. |
361
+ | `snr_range` | SNR interval for the lowest contour. |
362
+ | `survey_list` | External survey overlays; use `none` for offline mode. |
363
+ | `combo` | Make combined images using ImageMagick. |
364
+ | `user_image` | User image for contour overlays. |
365
+ | `percentile_range` | Display percentile range for user images. |
366
+ | `spec_line` | Spectral line label/rest-frequency configuration. |
367
+ | `no_source_id` | Hide source IDs in plot titles. |
368
+ | `channel_maps` | Generate per-source channel-map PDFs. |
369
+ | `spec_only` | Generate spectra only. |
370
+ | `plot_units` | Plot moment-0 map units in Jy/beam km/s when applicable. |
371
+ | `overwrite` | Overwrite existing plots. |
372
+
373
+ ## Input data
374
+
375
+ ESPADA inherits the input requirements of SoFiA-2. Input image data must be standard FITS files with a single HDU containing the image or data cube.
376
+
377
+ Each dataset can include up to four files, in this order:
378
+
379
+ 1. Primary-beam-corrected data cube - **required**.
380
+ 2. Primary beam cube - optional.
381
+ 3. Mask cube - optional.
382
+ 4. Continuum cube - optional and used by SIP when applicable.
383
+
384
+ Expected formats:
385
+
386
+ - Data and primary-beam cubes are normally 3D: two spatial axes plus one spectral axis.
387
+ - 2D images are accepted and treated internally as single-channel cubes.
388
+ - 4D files are accepted only when the fourth axis has length one; that axis is discarded.
389
+ - Masks must have the same dimensions as the data, use integer values, and contain non-zero values for source pixels.
390
+
391
+ Input can be provided directly with `input_data_set`, through an external `input_file`, or through the TAP service.
392
+
393
+ ### `input_data_set`
394
+
395
+ Single dataset as a list:
396
+
397
+ ```yaml
398
+ input_data_set: [data.fits, pb.fits, mask.fits, continuum.fits]
399
+ ```
400
+
401
+ Single dataset as a string:
402
+
403
+ ```yaml
404
+ input_data_set: data.fits pb.fits mask.fits continuum.fits
405
+ ```
406
+
407
+ Multiple datasets as a dictionary:
408
+
409
+ ```yaml
410
+ input_data_set:
411
+ dataset_1: [data1.fits, pb1.fits, mask1.fits, continuum1.fits]
412
+ dataset_2: [data2.fits, "", "", continuum2.fits]
413
+ dataset_3: data3.fits pb3.fits mask3.fits
414
+ dataset_4: data4.fits
415
+ ```
416
+
417
+ Empty strings can be used as placeholders for missing optional files.
418
+
419
+ ### `input_file`
420
+
421
+ `input_file` points to a text file containing one dataset per line. Do not use YAML list brackets inside this file.
422
+
423
+ ```yaml
424
+ input_file: /path/to/espada_input_file.txt
425
+ ```
426
+
427
+ Example file contents:
428
+
429
+ ```text
430
+ 1: data1.fits pb1.fits mask1.fits continuum1.fits
431
+ 2: data2.fits pb2.fits mask2.fits continuum2.fits
432
+ 3: data3.fits pb3.fits mask3.fits
433
+ ```
434
+
435
+ The `use_mask` option can disable masks even when those files are present.
436
+
437
+ ## Outputs
438
+
439
+ All outputs are written under `output_dir` from `config.yaml` (default: `espada_run/`). A typical run creates:
440
+
441
+ ```text
442
+ output_dir/
443
+ ├── archive_data/ # optional; ASA downloads
444
+ ├── log_dir/
445
+ │ ├── raw_espada_<date>_<time>.log
446
+ │ └── espada_<date>_<time>.log
447
+ ├── espada_<dataset_name>/
448
+ │ ├── absorption_<dataset_name>_cubelets/
449
+ │ ├── absorption_<dataset_name>_figures/
450
+ │ ├── absorption_<dataset_name>_cat.txt
451
+ │ ├── absorption_<dataset_name>_cat.xml
452
+ │ ├── absorption_<dataset_name>_mask.fits
453
+ │ ├── absorption_<dataset_name>_mom0.fits
454
+ │ ├── absorption_<dataset_name>_mom1.fits
455
+ │ ├── absorption_<dataset_name>_mom2.fits
456
+ │ ├── absorption_<dataset_name>_sources.png
457
+ │ ├── absorption_<dataset_name>_logfile.log
458
+ │ ├── absorption_<dataset_name>_sip.log
459
+ │ ├── emission_<dataset_name>_cubelets/
460
+ │ ├── emission_<dataset_name>_figures/
461
+ │ ├── emission_<dataset_name>_cat.txt
462
+ │ ├── emission_<dataset_name>_cat.xml
463
+ │ ├── emission_<dataset_name>_mask.fits
464
+ │ ├── emission_<dataset_name>_mom0.fits
465
+ │ ├── emission_<dataset_name>_mom1.fits
466
+ │ ├── emission_<dataset_name>_mom2.fits
467
+ │ ├── emission_<dataset_name>_sources.png
468
+ │ └── quality_assessment_products/
469
+ │ ├── absorption_<dataset_name>_QA.png
470
+ │ ├── absorption_<dataset_name>_comparison_stats.txt
471
+ │ ├── emission_<dataset_name>_QA.png
472
+ │ └── emission_<dataset_name>_comparison_stats.txt
473
+ └── report_<date>_<time>/ # only when make_report=True
474
+ ├── index.html
475
+ ├── report.json
476
+ ├── images/
477
+ └── resources/
478
+ ```
479
+
480
+ The exact files depend on enabled modules, run mode, and available inputs.
481
+
482
+ ## Quality assessment and reports
483
+
484
+ ESPADA generates two QA layers.
485
+
486
+ ### Stage I: per-dataset diagnostics
487
+
488
+ After each SoFiA execution, ESPADA can generate:
489
+
490
+ - A moment-8 image: maximum projection for emission or minimum projection for absorption along the spectral axis.
491
+ - A mask-comparison figure when an external/user/archive mask is available.
492
+ - Cube statistics extracted from the SoFiA XML catalogue: mean, standard deviation, skewness, kurtosis, and number of detected sources.
493
+ - A `*_comparison_stats.txt` file with quantitative diagnostic information.
494
+
495
+ These products are written to `quality_assessment_products/` inside each dataset output directory.
496
+
497
+ ### Stage II: final HTML and JSON report
498
+
499
+ When `make_report: True`, the `report` module generates:
500
+
501
+ - `report.json`: a machine-readable summary of the run, including metadata, configuration, logs, per-dataset status, and output files.
502
+ - `index.html`: an interactive browser report with execution summary, dataset panels, QA galleries, SoFiA/SIP galleries, logs, and configuration views.
503
+
504
+ The report directory is self-contained and can be shared with collaborators as a single folder/archive.
505
+
506
+ ## Advanced usage
507
+
508
+ ### Re-running selected stages
509
+
510
+ ESPADA can skip stages that have already been run. For example, if SoFiA outputs already exist and follow ESPADA naming conventions, users can set:
511
+
512
+ ```yaml
513
+ enable_sofia: False
514
+ enable_sip: True
515
+ ```
516
+
517
+ ESPADA will attempt to infer the expected SoFiA products from the current configuration and input filenames.
518
+
519
+ ### Parallelisation
520
+
521
+ ESPADA uses two levels of parallelism:
522
+
523
+ 1. One Python worker process per dataset, up to the available CPU/RAM limit.
524
+ 2. SoFiA-level threading inside each worker through `pipeline.threads`.
525
+
526
+ Worker allocation accounts for:
527
+
528
+ - user-provided `num_cores`,
529
+ - physical CPU count,
530
+ - available system memory,
531
+ - number of datasets,
532
+ - approximate SoFiA memory use per worker: `2.25 * data_size + 1 GB`.
533
+
534
+ SoFiA threads per worker are capped at `8`, following SoFiA performance recommendations.
535
+
536
+ ### Grouping detections
537
+
538
+ When `enable_group: True`, ESPADA attempts to merge spatially overlapping SoFiA detections along the spectral axis.
539
+
540
+ The grouping algorithm:
541
+
542
+ 1. Retrieves the 3D SoFiA detection mask.
543
+ 2. Projects each detected source into a 2D footprint.
544
+ 3. Computes pairwise overlap using `area`, `flux`, or `absflux`.
545
+ 4. Creates connected groups of sources whose mutual overlap exceeds `overlap_threshold`.
546
+ 5. Builds a grouped mask.
547
+ 6. Re-runs SoFiA and SIP on grouped detections only.
548
+
549
+ The documented default choice, `overlap_mode: absflux` and `overlap_threshold: 0.8`, has worked well in limited point-source tests, but the optimal choice may depend on source morphology and science goals.
550
+
551
+ ### TAP downloads and reprocessing
552
+
553
+ For TAP-based runs, ESPADA creates `espada_input_file.txt` in `output_dir`. To reprocess the same downloaded datasets without querying the archive again:
554
+
555
+ ```yaml
556
+ enable_tap_service: False
557
+ input_file: espada_run/espada_input_file.txt
558
+ ```
559
+
560
+ Keeping extracted primary-beam and converted mask files can also avoid repeated downloads and conversions in later runs.
561
+
562
+ ## Known limitations
563
+
564
+ - The command-line executable is now `espada`.
565
+ - Some internal names may still contain ADPALMAP legacy labels.
566
+ - SoFiA and SIP executable names are assumed to be `sofia` and `sofia_image_pipeline`. Changing this inside ESPADA is possible but not recommended; installing the external tools so that those commands are available in `PATH` is preferred.
567
+ - Manually providing SIP `catalog_file` while using `run_mode: both` is not recommended. The current SIP YAML interface cannot specify separate absorption and emission catalogues for every dataset, which can lead to duplicated or incorrect SIP outputs.
568
+ - Manually provided SIP catalogues are discouraged for TAP-service runs because archive-download ordering may differ between executions.
569
+ - `auto_setup: True` is documented as experimental and should be checked against the generated logs and temporary SoFiA parameter files.
570
+
571
+ ## Troubleshooting
572
+
573
+ | Symptom | Possible fix |
574
+ | --- | --- |
575
+ | `espada: command not found` | Activate the correct environment and run `python -m pip install espada-astro`, or `python -m pip install -e .` from the repository root for development. |
576
+ | Python-related errors on import or syntax | Check that Python `>= 3.10` is active. |
577
+ | SoFiA or SIP fails immediately | Confirm that `sofia` and `sofia_image_pipeline` are installed and callable from the same environment. |
578
+ | HTML report misses SoFiA EPS diagnostic plots | Install Ghostscript and re-run report generation. |
579
+ | TAP run downloads more data than expected | Use `filename_must_include`, `dryrun: True`, and `print_urls: True` to inspect the selected products first. |
580
+ | Re-running a TAP dataset downloads files again | Reuse `espada_input_file.txt` with `enable_tap_service: False`, or keep extracted/converted files from the previous run. |
581
+ | SIP output is incorrect in `both` mode | Do not manually provide a single `catalog_file` list for `both`; run SoFiA through ESPADA or use separate `emission`/`absorption` runs. |
582
+
583
+ ## Acknowledgements
584
+
585
+ ESPADA acknowledges support from the ESO/ALMA development study **"Prototype for ALMA Spectral Line Advanced Data Product Pipeline"**, funded through the ESO **Advanced Study for Upgrades of the Atacama Large Millimeter/submillimeter Array (ALMA)** (CFP/ESO/22/328/AMA).
586
+
587
+ The `datap` module incorporates and adapts functionality from [ALminer](https://alminer.readthedocs.io/), the ALMA archive mining and visualisation toolkit. ESPADA also relies on the external SoFiA-2 and SIP packages.
588
+
589
+ ## Citation and license
590
+
591
+ A formal citation entry will be added when available. Users of ESPADA should also cite the relevant external tools and methods used in their analysis, including SoFiA-2, SIP, ALminer, and ALMA archive services as appropriate.
592
+
593
+ License information will be added when available.