.. _tutorial: Quickstart ========== These tutorials make use of the example data included in the example_ folder. See the repository :ref:`cloning` section to install the data. You can find the script in example/tutorial_code.py .. _example: https://github.com/ldolan05/ACID/tree/main/example The architecture of ACID is slightly different to the original ACID code written by Lucy Dolan. ACID now works under the hood as a class (called Acid), rather than previously as a function. The main method (ACID) of the Acid class is now a Result class with its own methods and attributes that allow useful analysis. The legacy ACID function is still available for backwards compatibility, however it is recommended to use the Acid class for new applications. The tutorials below walk through how to use ACID for a variety of applications using the new class structure. The ACID_HARPS funciton was deprecated as of 2.0, instead, you should refer to the :ref:`datalist` tutorial for running on multiple orders. Inputting a Single Spectrum --------------------------- ACID returns LSD profiles based on input spectra. First, lets walk through an example for a single spectrum. ACID requires an input spectrum and stellar line list. An example spectrum and line list are contained in the 'example' directory of the source code. In the 'example' directory we can set up our inputs are follows: .. code-block:: python from astropy.io import fits spec_file = fits.open('sample_spec_1.fits') # Extract wavelength, spectrum, error and SN from the example fits file wavelength = spec_file[0].data # Wavelengths in Angstroms spectrum = spec_file[1].data # Spectral Flux error = spec_file[2].data # Spectral Flux Errors sn = spec_file[3].data # SN of Spectrum linelist = 'example_linelist.txt' # You can use a path to a VALD linelist The stellar line list can be obtained from VALD_ using their 'Extract Stellar' feature. You should input stellar parameters that correspond to your object and ensure that the wavelength range input covers the entire wavelength range of your spectrum. .. _VALD: http://vald.astro.uu.se/ We can then run ACID and plot the final results: .. code-block:: python import numpy as np import ACID_code as acid # choose a velocity grid for the final profile(s) deltav = acid.calc_deltav(wavelength) # velocity pixel size must not be smaller than the spectral pixel size - can use acid.calc_deltav function if unsure what this would be. velocities = np.arange(-25, 25, deltav) # Initiate Acid Acid = acid.Acid(velocities=velocities, linelist=linelist) # Run ACID result = Acid.ACID(wavelength, spectrum, error, sn, nsteps=5000) # Plot your final profile result.plot_profiles() # See documentation for more plot kwarg options # Obtain your profiles directly as arrays with: profile_flux = result[0] profile_error = result[1] profile_cov = result[2] # If you feel the need to continue sampling, you can do so with: # result.continue_sampling(nsteps=2000) # And then plot walkers to see the difference! See :ref:`result` for more analysis available on the Result object. Multiple frames --------------- Multiple frames of data can be input to directly to ACID. ACID adjusts these frames and performs the continuum fit on a combined spectrum (constructed from all frames). For this reason, frames must be from the same observation night where little variation is expected in the spectral continuum. As in the previous example, we must first read in the data: .. code-block:: python from astropy.io import fits import glob # finds sample files in 'example directory'. Each file is a different frame. files = glob.glob('sample_spec_*.fits') # create lists for wavelengths, spectra, errors and sn for all frames wavelengths = [] spectra = [] errors = [] sn = [] for file in files: spec_file = fits.open('%s'%file) wavelengths.append(spec_file[0].data) # Wavelengths in Angstroms spectra.append(spec_file[1].data) # Spectral Flux errors.append(spec_file[2].data) # Spectral Flux Errors sn.append(spec_file[3].data) # SN of Spectrum linelist = 'example_linelist.txt' # Insert path to line list Once the inputs have been constructed, ACID can be applied and the results plotted. .. code-block:: python import ACID_code as acid import numpy as np # choose a velocity grid for the final profile(s) # velocity pixel size must not be smaller than the spectral pixel size, # you can use acid.calc_deltav function if unsure what this would be. deltav = acid.calc_deltav(wavelengths[0]) velocities = np.arange(-25, 25, deltav) # run ACID function Acid = acid.Acid(velocities=velocities, linelist=linelist) result = Acid.ACID(wavelengths, spectra, errors, sn, nsteps=5000) # plot results result.plot_profiles() # Remember you can obtain the combined profiles list via: profile_flux = result[0] profile_error = result[1] profile_cov = result[2] # Or the per-frame profile frame_flux = result[0,0] # frame 0 flux frame_error = result[0,1] # frame 0 error frame_cov = result[0,2] # frame 0 covariance matrix # Or the full frame profile list full_profiles = result.profiles # Is a 3D list of shape (n_frames, 3, n_velocities) containing the flux, error and covariance profiles for each frame. Multiple Orders --------------- As of ACID 1.4, the Acid class is designed to only handle a single order of ACID. This change was made to better handle the parallel processing of multiple orders on a computer cluster. If you would like to run ACID for a full observation of an echelle spectrograph, see the :ref:`datalist` section for full tutorial on how to put multiple Data objects into a list and run ACID on each order separately. If you wish to run ACID for different wavelength ranges, then you can simply save the Result object for each wavelength range and process them separately. See the :ref:`result` section. Using Deterministic profile in MCMC fitting ------------------------------------------- As of 1.4, ACID can infer the profile points at each MCMC step from the continuum parameters. This means the sampler does not fit the profile points, but instead fits only the continuum parameters and calculates the profile from the alpha matrix and the continuum model. The end result is the same, given enough steps. As of 1.5, this setting now defaults to True and is recommended to be left on as it significantly decrease convergence time and computation time per step, while fully maintaining accuracy. The feature can be disabled by setting deterministic_profile=False when calling ACID, which will match legacy behaviour. .. code-block:: python # ... same code as before to set up data and run ACID ... Acid = acid.Acid(velocities=velocities, linelist=linelist) result = Acid.ACID(wavelength, spectrum, error, sn, nsteps=2000, deterministic_profile=False) # Now runs ACID without inferring the profile points from the continuum parameters. Running ACID until convergence (section below) shows the vast improvement in convergence times with this setting. Running ACID Until Convergence ------------------------------ As of version 1.4, ACID can also detect if the sampler has converged based on the computed autocorrelation time of the sampler. You can configure the following parameters by passing them to the ACID function: .. code-block:: text max_steps : IntLike, optional If set, the sampler will run until max_steps or convergence is reached by estimation using the emcee autocorrelation time (tau). The sampler will check for convergence every 'check_interval' steps, and will require a minimum number of checks ('min_checks') and a minimum tau factor ('min_tau_factor') before it can stop. The stopping criterion is met when the change in tau is less than 'tau_tol' for all parameters. By default None, which means no maximum. If a value is inputted, the nsteps parameter is ignored. The continue_sampling method in Result or Acid can still be used normally to continue sampling after either stopping criterion is reached. check_interval : IntLike, optional Interval (in steps) at which to check for MCMC convergence if max_steps is set, by default 1000. Only used if max_steps is set. min_checks : IntLike, optional Minimum number of checks before MCMC can be stopped, by default 1. Only used if max_steps is set. min_tau_factor : IntLike, optional Minimum tau factor for MCMC stopping criterion, by default 50, which is the emcee recommendation, it's not recommend to set a value below 50 unless you want to force convergence for the deterministic_profile=False option. Only used if max_steps is set. tau_tol : float, optional Tolerance for tau convergence in MCMC stopping criterion, by default 0.1. Only used if max_steps is set. .. code-block:: python # ... same code as before to set up data and run ACID ... Acid = acid.Acid(velocities=velocities, linelist=linelist) result = Acid.ACID(wavelength, spectrum, error, sn, max_steps=5000, deterministic_profile=False) .. code-block:: text Iteration 1/5, last tolerance: inf>0.1, neff: 0.00<50: 100% 1000/1000 [00:04<00:00, 227.45it/s] Iteration 2/5, last tolerance: inf>0.1, neff: 0.00<50: 100% 1000/1000 [00:04<00:00, 234.49it/s] Iteration 3/5, last tolerance: 0.5674>0.1, neff: 7.00<50: 100% 1000/1000 [00:04<00:00, 219.90it/s] Iteration 4/5, last tolerance: 0.3913>0.1, neff: 7.00<50: 100% 1000/1000 [00:04<00:00, 228.78it/s] Iteration 5/5, last tolerance: 0.2756>0.1, neff: 7.00<50: 100% 1000/1000 [00:04<00:00, 222.20it/s] Not converged after reaching max steps of 5000. Final effective sample size: 7.00, final tolerance: 0.3184. Consider increasing max_steps. The above code will still have a fully working sampler, which can plot the profiles as per normal (see the Results class, or the Other functions page for possible plotting options). The sampler will give the following warning however: .. code-block:: text The number of MCMC steps is less than 50 times the maximum autocorrelation time. The sampler may not have converged. Consider running more steps or checking the walker plots. The max autocorrelation time is 651.30, therefore the minimum number of steps should be roughly 32565. Disabling burnin from autocorrelation time, instead using burnin=steps-1000 If we turn back on the deterministic profile feature, we see a significant improvement in convergence: .. code-block:: python # ... same code as before to set up data and run ACID ... Acid = acid.Acid(velocities=velocities, linelist=linelist) result = Acid.ACID(wavelength, spectrum, error, sn, max_steps=5000, deterministic_profile=True) .. code-block:: text Iteration 1/5, last tolerance: inf>0.1, neff: 0.00<50: 100% 1000/1000 [00:03<00:00, 282.63it/s] Iteration 2/5, last tolerance: inf>0.1, neff: 0.00<50: 100% 1000/1000 [00:03<00:00, 284.76it/s] Iteration 3/5, last tolerance: 0.0793<0.1, neff: 26.00<50: 100% 1000/1000 [00:03<00:00, 286.68it/s] Iteration 4/5, last tolerance: 0.0181<0.1, neff: 38.00<50: 100% 1000/1000 [00:03<00:00, 286.20it/s] Converged at step 4000. Final tolerance: 0.0066, final effective sample size: 51.00.