# DDFacet tutorial for beginner This documentation gives a brief overview of how to use DDFacet to input a LOFAR-type measurementSet and output reconstructed images. ## Biblio :page_facing_up: [DDFacet](https://arxiv.org/pdf/1712.02078) *C. Tasse, B. Hugo, M. Mirmont, O. Smirnov, M. Atemkeng, L. Bester, M.J. Hardcastle4, R. Lakhoo, S. Perkins and T. Shimwel «Multi-core multi-node parallelization of the radio interferometric imaging pipeline DDFacet»* :page_facing_up: [DDFacet parallel](https://arxiv.org/pdf/1712.02078) *N. Monnier, D. Guibert, C. Tasse, N. Gac, F. Orieux, E. Raffin, O. M. Smirnov, B. V. Hugo «Faceting for direction-dependent spectral deconvolution»* ## Context **DDFacet** is a radio astronomy imaging pipeline currently used in production on telescopes such as LOFAR and MeerKat. Its main purpose is to transform **MeasurementSets** (MS) — raw observational data collected by radio interferometers — into reconstructed sky images in FITS format (`*.fits`). MeasurementSets contain the measured visibilities, while the resulting FITS files provide calibrated images of the sky, ready for analysis or calibration purposes. The pipeline performs **computationally intensive** and **highly parameterized calculations**, allowing it to adapt to different observational setups and scientific requirements. All available option commands are listed in the section [Exhaustive list of DDF commands](#exhaustive-list-of-ddf-commands) , and their explanations are provided in [Key parameter explanation](#key-parameter-explanation). To facilitate execution on **High Performance Computing (HPC) systems**, DDFacet's team provides a **parallel** and **parameterized** implementation packaged in a Singularity container (`.sif`). Singularity is a container technology designed for HPC, enabling complex applications to run with all dependencies in an isolated and reproducible environment. This tutorial provides: - Examples of running DDFacet on your own laptop in the section [Running DDFacet on your own laptop](#running-ddfacet-on-your-own-laptop), to help users familiarize themselves with the pipeline and file formats. - A procedure for deploying DDFacet on a multi-node HPC cluster using Slurm, described in the section Multinode Execution, for processing large MeasurementSets efficiently in parallel. ## Requirements - Download ddfacet singularity image: `ddf_dev_np1.22.4.sif` [NAS - vaader](https://nasext-vaader.insa-rennes.fr/ietr-vaader/) - Download parset example: `Template.parset` [NAS - vaader](https://nasext-vaader.insa-rennes.fr/ietr-vaader/) - Having a measurementSet (i.e. **\*.ms** ==> set of folders) - (option) Download the script that facilitates reading **\*.fits** (based on the ds9 tool): `dsm.py` [NAS - vaader](https://nasext-vaader.insa-rennes.fr/ietr-vaader/) ## Exhaustive list of DDF commands <details> <summary style="cursor: pointer; color: #007bff;"> Click here to reveal the section </summary> | 📝 **Note** | | ------------------------------------------------------------ | |This section provides a comprehensive list of available DDF commands. It is based on the output of `DDF.py -h`. Not all commands are used in this tutorial; this is mainly for reference and advanced users. | ``` Usage: DDF.py [parset file] [options] Questions and suggestions: cyril.tasse@obspm.fr Options: --version show program's version number and exit -h, --help show this help message and exit Visibility data options: --Data-MS=MS(s) Single MS name, or list of comma-separated MSs, or name of *.txt file listing MSs. Note that each MS may also be specified as a glob pattern (e.g. *.MS), and may be suffixed with "//Dx" and/or "//Fy" to select specific DATA_DESC_ID and FIELD_IDs in the MS. "x" and "y" can take the form of a single number, a Pythonic range (e.g. "0:16"), an inclusive range ("0~15"), or "*" to select all. E.g. "foo.MS//D*//F0:2" selects all DDIDs, and fields 0 and 1 from foo.MS. If D and/or F is not specified, --Selection-Field and --Selection-DDID is used as the default. (default: ) --Data-ColName=COLUMN MS column to image (default: CORRECTED_DATA) --Data-ChunkHours=N Process data in chunks of less than or equal to N hours. Use 0 for no chunking. (default: 0.0) --Data-Sort=0|1 if True, data will be resorted by baseline-time order internally. This usually speeds up processing. (default: False) Predict: --Predict-ColName=COLUMN MS column to write predict to. Can be empty to disable. (default: none) --Predict-MaskSquare=IMAGE Use this field if you want to predict (in/out)side a square region. Syntax is (MaskOutSide,NpixInside). For example setting (0,1000) will predict the outer (1000x1000) square only (default: none) --Predict-FromImage=IMAGE In --Image-Mode=Predict, will predict data from this image, rather than --Data-InitDicoModel (default: none) --Predict-InitDicoModel=FILENAME Resume deconvolution from given DicoModel (default: none) --Predict-Overwrite=0|1 Allow overwriting of predict column (default: True) Data selection options: --Selection-Field=FIELD default FIELD_ID to read, if not specified in --Data- MS. (default: 0) --Selection-DDID=DDID default DATA_DESC_ID to read, if not specified in --Data-MS. (default: 0) --Selection-TaQL=TaQL additional TaQL selection string (default: ) --Selection-ChanStart=N First channel (default: 0) --Selection-ChanEnd=N Last channel+1, -1 means up and including last channel. (default: -1) --Selection-ChanStep=N Channel stepping (default: 1) --Selection-FlagAnts=ANT,... List of antennas to be flagged, e.g. "RS,CS017LBA" (default: ) --Selection-UVRangeKm=KM_MIN,KM_MAX Select baseline range (default: [0, 2000]) --Selection-TimeRange=SELECTION_TIMERANGE Select time range (two comma separated values) containing UTC start and end times in ISO8601 (default: ) --Selection-TimeRangeFromStartMin=SELECTION_TIMERANGEFROMSTARTMIN In minutes before start of obs. (default: ) --Selection-DistMaxToCore=KM Select antennas by specifying a maximum distance to core (default: ) --Selection-AutoFlagNyquist=SELECTION_AUTOFLAGNYQUIST flag those baselines that are not properly sampled (default: 0) Options for input and output image names: --Output-Mode=Dirty|Clean|Predict|PSF What to do. (default: Clean) --Output-Clobber=0|1 Allow overwriting of existing parset and images (can't be specified via parset!) (default: False) --Output-Name=BASENAME Base name of output images (default: image) --Output-ShiftFacetsFile=OUTPUT_SHIFTFACETSFILE Astrometric correction per facet, when Image- Mode=RestoreAndShift (default: none) --Output-RestoringBeam=OUTPUT_RESTORINGBEAM (default: none) --Output-Also=CODES Save also these images (i.e. adds to the default set of --Output-Images) (default: ) --Output-Cubes=CODES Also save cube versions for these images (only MmRrIi codes recognized) (default: ) --Output-Images=OUTPUT_IMAGES Combination of letter codes indicating what images to save. Uppercase for intrinsic flux scale [D]irty, [M]odel, [C]onvolved model, [R]esiduals, restored [I]mage; Lowercase for apparent flux scale [d]irty, [m]odel, [c]onvolved model, [r]esiduals, restored [i]mage; Other images: [P]SF, [N]orm, [n]orm facets, [S] flux scale, [A]lpha (spectral index), [X] mixed- scale (intrinsic model, apparent residuals, i.e. Cyrils original output), [o] intermediate mOdels (Model_i), [e] intermediate rEsiduals (Residual_i), [k] intermediate masK image, [z] intermediate auto mask-related noiZe image, [g] intermediate dirty images (only if [Debugging] SaveIntermediateDirtyImages is enabled). [F] intrinsic MFS restored image [f] apparent MFS restored image Use "all" to save all. (default: DdPAMRIikemz) --Output-StokesResidues=OUTPUT_STOKESRESIDUES After cleaning Stokes I, output specified residues if [r] or [R] is specified in option Output-Images. Note that the imager does not perform deconvolution on any Stokes products other than I - it only outputs residues. (default: I) SPIMaps: --SPIMaps-AlphaThreshold=N Multiple of the RMS in final residual which determines threshold for fitting alpha map. (default: 15) General imager settings: --Image-NPix=NPIX Image size. (default: 5000) --Image-Cell=ARCSEC Cell size. (default: 5.0) --Image-PhaseCenterRADEC=RA,DEC Use non-default phase centre. If "align" is used, all MSs will be rephased to the phase centre of the first MS. Otherwise, specify [HH:MM:SS,DD:MM:SS] direction. If empty, no rephasing is done. (default: none) --Image-SidelobeSearchWindow=NPIX Size of PSF subwindow (centred around the main lobe) to search for the highest sidelobe when fitting the PSF size. (default: 200) Spacial tessellation settings: --Facets-NFacets=N Number of facets to use. (default: 3) --Facets-CatNodes=FACETS_CATNODES (default: none) --Facets-DiamMax=DEG Max facet size, for tessellations. Larger facets will be broken up. (default: 180.0) --Facets-DiamMin=DEG Min facet size, for tessellations. Smaller facets will be merged. (default: 0.0) --Facets-MixingWidth=FACETS_MIXINGWIDTH Sigma of the gaussian (in pixels) being used to mix the facets on their edges (default: 10) --Facets-PSFOversize=X For cleaning, use oversize PSF relative to size of facet. (default: 1.0) --Facets-PSFFacets=N Number of PSF facets to make. 0: same as NFacets (one PSF per facet) 1: one PSF for entire field. (default: 0) --Facets-Padding=FACTOR Facet padding factor. (default: 1.7) --Facets-Circumcision=N Set to non-0 to override NPixMin computation in FacetsToIm(). Debugging option, really. (default: 0) --Facets-FluxPaddingAppModel=FACETS_FLUXPADDINGAPPMODEL For flux-dependent facet-padding, the apparant model image (or cube) (default: none) --Facets-FluxPaddingScale=FACETS_FLUXPADDINGSCALE The factor applied to the --Facets-Padding for the facet with the highest flux (default: 2.0) --Facets-SkipTh=FACETS_SKIPTH Skip gridding/degridding if the mean Jones power is lower than this level (useful in mosaicing mode) (default: 0.0) Data and imaging weight settings: --Weight-ColName=COLUMN Read data weights from specified column. Use WEIGHT_SPECTRUM or WEIGHT, more rarely IMAGING_WEIGHT. You can also specify a list of columns like using --Weight-ColName=[WEIGHT_SPECTRUM,IMAGING_WEIGHT] (default: WEIGHT_SPECTRUM) --Weight-Mode=Natural|Uniform|Robust|Briggs Image weighting. (default: Briggs) --Weight-MFS=0|1 If True, MFS uniform/Briggs weighting is used (all channels binned onto one uv grid). If 0, binning is per-band. (default: True) --Weight-Robust=R Briggs robustness parameter, from -2 to 2. (default: 0.0) --Weight-SuperUniform=X Super/subuniform weighting: FoV for weighting purposes is taken as X*Image_Size (default: 1.0) --Weight-OutColName=COLUMN Save the internally computed weights into this column (default: none) --Weight-EnableSigmoidTaper=WEIGHT_ENABLESIGMOIDTAPER Toggles sigmoid tapering type:bool (default: 0) --Weight-SigmoidTaperInnerCutoff=WEIGHT_SIGMOIDTAPERINNERCUTOFF Inner taper cutoff in uvwavelengths type:float (default: 0.0) --Weight-SigmoidTaperOuterCutoff=WEIGHT_SIGMOIDTAPEROUTERCUTOFF Outer taper cutoff in uvwavelengths type:float (default: 0.0) --Weight-SigmoidTaperInnerRolloffStrength=WEIGHT_SIGMOIDTAPERINNERROLLOFFSTRENGTH Rolloff strength on inner taper if enabled. 1.0 is essentially a boxcar, 0.0 means very long rolloffs type:float (default: 0.5) --Weight-SigmoidTaperOuterRolloffStrength=WEIGHT_SIGMOIDTAPEROUTERROLLOFFSTRENGTH Rolloff strength on outer taper if enabled. 1.0 is essentially a boxcar, 0.0 means very long rolloffs type:float (default: 0.5) Low level parameters related to the forward and backward image to visibility spaces transforms: --RIME-Precision=S|D Single or double precision gridding. DEPRECATED? (default: S) --RIME-PolMode=I|IQ|IU|IV|IQU|IQUV Polarization mode. (default: I) --RIME-FullMTilde=RIME_FULLMTILDE Uee the full MTilde as described in the paper to do the image plane correction type:bool (default: False) --RIME-FFTMachine=RIME_FFTMACHINE (default: FFTW) --RIME-ForwardMode=BDA-degrid|Classic|Montblanc Forward predict mode. (default: BDA-degrid) --RIME-BackwardMode=BDA-grid|Classic Backward mode. (default: BDA-grid) --RIME-DecorrMode=RIME_DECORRMODE decorrelation mode (default: ) --RIME-DecorrLocation=Center|Edge where decorrelation is estimated (default: Edge) Imager convolution function settings: --CF-OverS=N Oversampling factor. (default: 11) --CF-Support=N CF support size. (default: 7) --CF-Nw=PLANES Number of w-planes. Setting this to 1 enables AIPS style faceting. (default: 100) --CF-wmax=METERS Maximum w coordinate. Visibilities with larger w will not be gridded. If 0, no maximum is imposed. (default: 0.0) Compression settings (baseline-dependent averaging [BDA] and sparsification): --Comp-GridDecorr=X Maximum BDA decorrelation factor (gridding) (default: 0.02) --Comp-GridFoV=Full|Facet FoV over which decorrelation factor is computed (gridding) (default: Facet) --Comp-DegridDecorr=X Maximum BDA decorrelation factor (degridding) (default: 0.02) --Comp-DegridFoV=Full|Facet FoV over which decorrelation factor is computed (degridding) (default: Facet) --Comp-Sparsification=N1,N2,... apply sparsification compression to initial major cycles. Sparsification refers to throwing away random visibilities. Supply a list of factors: e.g. 100,30,10 would mean only 1/100 of the data is used for the first major cycle, 1/30 for the second, 1/10 for the third, and full data for the fourth cycle onwards. This can substantially accelerate deconvolution of deep observations, since, in these regimes, very little sensitivity is required for model construction in the initial cycles. (default: 0) --Comp-BDAMode=1|2 BDA block computation mode. 1 for Cyril's old mode, 2 for Oleg's new mode. 2 is faster but see issue #319. (default: 1) --Comp-BDAJones=COMP_BDAJONES If disabled, gridders and degridders will apply a Jones terms per visibility. If 'grid', gridder will apply them per BDA block, if 'both' so will the degridder. This is faster but possibly less accurate, if you have rapidly evolving Jones terms. (default: 0) Parallelization options: --Parallel-NCPU=N Number of CPUs to use in parallel mode. 0: use all available. 1: disable parallelism. (default: 0) --Parallel-Affinity=PARALLEL_AFFINITY pin processes to cores. -1/1/2 determines stepping used in selecting cores. Alternatively specifies a list of length NCPU. Alternatively "disable" to disable affinity settings Alternatively "enable_ht" uses stepping of 1 (equivalent to Parallel.Affinity=1), will use all vthreads - the obvious exception is if HT is disabled at BIOS level Alternatively "disable_ht" autodetects the NUMA layout of the chip for Debian-based systems and dont use both vthreads per core Use 1 if unsure. (default: 1) --Parallel-MainProcessAffinity=PARALLEL_MAINPROCESSAFFINITY this should be set to a core that is not used by forked processes, this option is ignored when using option "disable or disable_ht" for Parallel.Affinity (default: 0) --Parallel-MotherNode=PARALLEL_MOTHERNODE (default: localhost) Cache management options: --Cache-Reset=0|1 Reset all caches (including PSF and dirty image) (default: False) --Cache-Jones=reset|auto Reset cached Jones (default: auto) --Cache-SmoothBeam=reset|auto|force Reset cached smooth beam (default: auto) --Cache-Weight=reset|auto Reset cached weight (default: auto) --Cache-PSF=off|reset|auto|force Cache PSF data. (default: auto) --Cache-Dirty=off|reset|auto|forcedirty|forceresidual Cache dirty image data. (default: auto) --Cache-VisData=off|auto|force Cache visibility data and flags at runtime. (default: auto) --Cache-LastResidual=0|1 Cache last residual data (at end of last minor cycle) (default: True) --Cache-Dir=CACHE_DIR Directory to store caches in. Default is to keep cache next to the MS, but this can cause performance issues with e.g. NFS volumes. If you have fast local storage, point to it. %metavar:DIR (default: ) --Cache-DirWisdomFFTW=CACHE_DIRWISDOMFFTW Directory in which to store the FFTW wisdom files (default: ~/.fftw_wisdom) --Cache-ResetWisdom=0|1 Reset Wisdom file (default: False) --Cache-CF=0|1 Cache convolution functions. With many CPUs, may be faster to recompute. (default: True) --Cache-HMP=0|1 Cache HMP basis functions. With many CPUs, may be faster to recompute. (default: False) Apply E-Jones (beam) during imaging: --Beam-Model=None|LOFAR|FITS|GMRT|ATCA Beam model to use. (default: none) --Beam-At=facet|tessel when DDESolutions are enabled, compute beam per facet, or per larger solution tessel (default: facet) --Beam-PhasedArrayMode=A|AE PhasedArrayMode beam mode. (default: AE) --Beam-NBand=N Number of channels over which same beam value is used. 0 means use every channel. (default: 0) --Beam-CenterNorm=0|1 Normalize beam so that its amplitude at the centre is 1. (default: False) --Beam-Smooth=BEAM_SMOOTH Compute the interpolated smooth beam (default: False) --Beam-SmoothNPix=BEAM_SMOOTHNPIX Number of pixels the beam is evaluated and smoothed (default: 11) --Beam-SmoothInterpMode=BEAM_SMOOTHINTERPMODE Linear/Log (default: Linear) --Beam-FITSFile=BEAM_FITSFILE Beam FITS file pattern. A beam pattern consists of eight FITS files, i.e. a real and imaginary part for each of the four Jones terms. The following substitutions are performed to form up the eight filenames: $(corr) or $(xy) is replaced by the Jones element label (e.g. "xx" or "rr"), $(reim) is replaced by "re" or "im", $(realimag) is replaced by "real" or "imag". Uppercase variables are replaced by uppercase values, e.g. $(REIM) by "RE" pr "IM". Use "unity" if you want to apply a unity matrix for the E term (e.g. only want to do visibility derotations). Correlation labels (XY or RL) are determined by reading the MS, but may be overridden by the FITSFeed option. To use a heterogeneous mix of beams you have to first type specialize the antennas using a json configuration of the following format: {'lband': { 'patterns': { 'cmd::default': ['$(stype)_$(corr)_$(reim).fits',...], }, 'define-stationtypes': { 'cmd::default': 'meerkat', 'ska000': 'ska' } }, ... } This will substitute 'meerkat' for all antennas but ska000, with 'meerkat_$(corr)_$(reim).fits' whereas beams for ska000 will be loaded from 'ska_$(corr)_$(reim).fits' in this example. The station name may be specified as regex by adding a '~' infront of the pattern to match, e.g '~ska[0-9]{3}': 'ska' will assgign all the 'ska' type to all matching names such as ska000, ska001, ..., skaNNN. Each station type in the pattern section may specify a list of patterns for different frequency ranges. Multiple keyed dictionaries such as this may be specified within one file. They will be treated as chained configurations, adding more patterns and station-types to the first such block. Warning: Once a station is type-specialized the type applies to **ALL** chained blocks! Blocks from more than one config file can be loaded by comma separation, e.g. ' --Beam-FITSFile conf1.json,conf2.json,...', however no block may define multiple types for any station. If patterns for a particular station type already exists more patterns are just appended to the existing list. Warning: where multiple patterns specify the same frequency range the first such pattern closest to the MS SPW frequency coverage will be loaded. If no configuration file is provided the pattern may not contain $(stype) -- station independence is assumed. This is the same as specifing the following config: {'lband': { 'patterns': { 'cmd::default': ['$(corr)_$(reim).fits',...], }, 'define- stationtypes': { 'cmd::default': 'cmd::default' } } (default: beam_$(corr)_$(reim).fits) --Beam-FITSFeed=None|xy|XY|rl|RL If set, overrides correlation labels given by the measurement set. (default: none) --Beam-FITSFeedSwap=0|1 swap feed patterns (X to Y and R to L) (default: False) --Beam-DtBeamMin=MIN change in minutes on which the beam is re-evaluated (default: 5.0) --Beam-FITSParAngleIncDeg=DEG increment in PA in degrees at which the beam is to be re-evaluated (on top of DtBeamMin) (default: 5.0) --Beam-FITSLAxis=AXIS L axis of FITS file. Minus sign indicates reverse coordinate convention. (default: -X) --Beam-FITSMAxis=AXIS M axis of FITS file. Minus sign indicates reverse coordinate convention. (default: Y) --Beam-FITSVerbosity=LEVEL set to >0 to have verbose output from FITS interpolator classes. (default: 0) --Beam-FITSFrame=BEAM_FITSFRAME coordinate frame for FITS beams. Currently, alt-az, equatorial and zenith mounts are supported. (default: altaz) --Beam-FeedAngle=BEAM_FEEDANGLE offset feed angle to add to parallactic angle (default: 0.0) --Beam-ApplyPJones=BEAM_APPLYPJONES derotate visibility data (only when FITS beam is active and also time sampled). If you have equatorial mounts this is not what you should be doing! (default: 0) --Beam-FlipVisibilityHands=BEAM_FLIPVISIBILITYHANDS apply anti-diagonal matrix if FITS beam is enabled effectively swapping X and Y or R and L and their respective hands (default: 0) Multifrequency imaging options: --Freq-BandMHz=MHz Gridding cube frequency step. If 0, --Freq-NBand is used instead. (default: 0.0) --Freq-FMinMHz=MHz Gridding cube frequency Min. If 0, is ignored. (default: 0.0) --Freq-FMaxMHz=MHz Gridding cube frequency Max. If 0, is ignored. (default: 0.0) --Freq-DegridBandMHz=MHz Degridding cube frequency step. If 0, --Freq- NDegridBand is used instead. (default: 0.0) --Freq-NBand=N Number of image bands for gridding. (default: 1) --Freq-NDegridBand=N Number of image bands for degridding. 0 means degrid each channel. (default: 0) Apply DDE solutions during imaging (@cyriltasse please document this section): --DDESolutions-DDSols=DDESOLUTIONS_DDSOLS Name of the DDE solution file (default: ) --DDESolutions-SolsDir=DDESOLUTIONS_SOLSDIR Name of the directry of the DDE Solutions which contains [SolsDir]/[MSNames]/killMS.[SolsName].sols.npz (default: none) --DDESolutions-GlobalNorm=DDESOLUTIONS_GLOBALNORM Option to normalise the Jones matrices (options: MeanAbs, MeanAbsAnt, BLBased or SumBLBased). See code for more detail (default: none) --DDESolutions-JonesNormList=DDESOLUTIONS_JONESNORMLIST Deprecated? (default: AP) --DDESolutions-JonesMode=Scalar|Diag|Full (default: Full) --DDESolutions-DDModeGrid=DDESOLUTIONS_DDMODEGRID In the gridding step, apply Jones matrices Amplitude (A) or Phase (P) or Amplitude&Phase (AP) (default: AP) --DDESolutions-DDModeDeGrid=DDESOLUTIONS_DDMODEDEGRID In the degridding step, apply Jones matrices Amplitude (A) or Phase (P) or Amplitude&Phase (AP) (default: AP) --DDESolutions-ScaleAmpGrid=DDESOLUTIONS_SCALEAMPGRID Deprecated? (default: 0) --DDESolutions-ScaleAmpDeGrid=DDESOLUTIONS_SCALEAMPDEGRID Deprecated? (default: 0) --DDESolutions-CalibErr=DDESOLUTIONS_CALIBERR Deprecated? (default: 10.0) --DDESolutions-Type=Krigging|Nearest Deprecated? (default: Nearest) --DDESolutions-Scale=DEG Deprecated? (default: 1.0) --DDESolutions-gamma=DDESOLUTIONS_GAMMA Deprecated? (default: 4.0) --DDESolutions-RestoreSub=DDESOLUTIONS_RESTORESUB Deprecated? (default: False) --DDESolutions-ReWeightSNR=DDESOLUTIONS_REWEIGHTSNR Deprecated? (default: 0.0) Apply pointing offsets to beam during DFT predict. Requires Montblanc in --RIME-ForwardMode.: --PointingSolutions-PointingSolsCSV=POINTINGSOLUTIONS_POINTINGSOLSCSV Filename of CSV containing time-variable pointing solutions. None initializes all antenna pointing offsets to 0, 0 (default: none) --PointingSolutions-InterpolationMode=LERP Interpolation mode (default: LERP) Common deconvolution options. Not all of these apply to all deconvolution modes: --Deconv-Mode=HMP|Hogbom|SSD|WSCMS Deconvolution algorithm. (default: HMP) --Deconv-MaxMajorMaxMajorIter=N Max number of major cycles. (default: 20) --Deconv-MaxMinorIter=N Max number of (overall) minor cycle iterations (HMP, Hogbom). (default: 20000) --Deconv-AllowNegative=0|1 Allow negative components (HMP, Hogbom). (default: True) --Deconv-Gain=GAIN Loop gain (HMP, Hogbom). (default: 0.1) --Deconv-FluxThreshold=Jy Absolute flux threshold at which deconvolution is stopped (HMP, Hogbom, SSD). (default: 0.0) --Deconv-CycleFactor=X Cycle factor: used to set a minor cycle stopping threshold based on PSF sidelobe level (HMP, Hogbom). Use 0 to disable, otherwise 2.5 is a reasonable value, but may lead to very shallow minor cycle. (default: 0.0) --Deconv-RMSFactor=X Set minor cycle stopping threshold to X*{residual RMS at start of major cycle} (HMP, Hogbom, SSD). (default: 0.0) --Deconv-PeakFactor=X Set minor cycle stopping threshold to X*{peak residual at start of major cycle} (HMP, Hogbom, SSD). (default: 0.15) --Deconv-PrevPeakFactor=X Set minor cycle stopping threshold to X*{peak residual at end of previous major cycle} (HMP). (default: 0.0) --Deconv-NumRMSSamples=N How many samples to draw for RMS computation. Use 0 to use all pixels (most precise). (default: 10000) --Deconv-ApproximatePSF=SF when --Comp-Sparsification is on, use approximate (i.e. central facet) PSF for cleaning while operating above the given sparsification factor (SF). This speeds up HMP reinitialization in major cycles. A value of 1-10 is sensible. Set to 0 to always use precise per-facet PSF. (default: 0) --Deconv-PSFBox=BOX determines the size of the PSF subtraction box used in CLEAN-style deconvolution (if appropriate). Use "auto" (or "sidelobe") for a Clark-CLEAN-style box taken out to a certain sidelobe (faster). Use "full" to subtract the full PSF, Hogbom-style (more accurate, can also combine with --Image-PSFOversize for maximum accuracy). Use an integer number to set an explicit box radius, in pixels. (HMP) (default: auto) Masking options. The logic being Mask_{i+1} = ExternalMask | ResidualMask | Mask_{i}: --Mask-External=FILENAME External clean mask image (FITS format). (default: none) --Mask-Auto=MASK_AUTO Do automatic masking (default: False) --Mask-AutoRMSFactor=MASK_AUTORMSFACTOR RMS Factor for automasking HMP (default: 3) --Mask-SigTh=MASK_SIGTH set Threshold (in sigma) for automatic masking (default: 10) --Mask-FluxImageType=MASK_FLUXIMAGETYPE If Auto enabled, does the cut of SigTh either on the ModelConv or the Restored (default: ModelConv) When using a noise map to HMP or to mask: --Noise-MinStats=NOISE_MINSTATS The parameters to compute the noise-map-based mask for step i+1 from the residual image at step i. Should be [box_size,box_step] (default: [60, 2]) --Noise-BrutalHMP=NOISE_BRUTALHMP If noise map is computed, this option enabled, it first computes an image plane deconvolution with a high gain value, and compute the noise-map-based mask using the brutal-restored image (default: True) Hybrid Matching Pursuit (aka multiscale/multifrequency) mode deconvolution options: --HMP-Alpha=MIN,MAX,N List of alphas to fit. (default: [-1.0, 1.0, 11]) --HMP-Scales=LIST List of scales to use. (default: [0]) --HMP-Ratios=HMP_RATIOS @cyriltasse please document (default: ['']) --HMP-NTheta=N Number of PA steps to use. (default: 6) --HMP-SolverMode=PI|NNLS Solver mode: pseudoinverse, or non-negative least squares. (default: PI) --HMP-AllowResidIncrease=FACTOR Allow the maximum residual to increase by at most this much relative to the lowest residual, before bailing out due to divergence. (default: 0.1) --HMP-MajorStallThreshold=X Major cycle stall threshold. If the residual at the beginning of a major cycle is above X*residual at the beginning of the previous major cycle, then we consider the deconvolution stalled and bail out. (default: 0.8) --HMP-Taper=HMP_TAPER Weighting taper size for HMP fit. If 0, determined automatically. (default: 0) --HMP-Support=HMP_SUPPORT Basis function support size. If 0, determined automatically. (default: 0) --HMP-PeakWeightImage=HMP_PEAKWEIGHTIMAGE weigh the peak finding by given image (default: none) --HMP-Kappa=HMP_KAPPA Regularization parameter. If stddev of per-alpha solutions exceeds the maximum solution amplitude divided by Kappa, forces a fully-regularized solution. Use 0 for no such regularization. (default: 0.0) --HMP-OuterSpaceTh=HMP_OUTERSPACETH (default: 2.0) --HMP-FractionRandomPeak=HMP_FRACTIONRANDOMPEAK (default: none) Hogbom: --Hogbom-PolyFitOrder=HOGBOM_POLYFITORDER polynomial order for frequency fitting (default: 4) --Hogbom-LinearPeakfinding=Joint|Separate Perform EVPA-preserving (complex-valued) polarization CLEAN (Pratley-Johnston-Hollitt) or separate Q and U cleaning. (default: Joint) WSCMS: --WSCMS-NumFreqBasisFuncs=WSCMS_NUMFREQBASISFUNCS number of basis functions to use for the fit to the frequency axis (default: 4) --WSCMS-MultiScale=WSCMS_MULTISCALE whether to use multi-scale or not (recommended to use Hogbom if not using multi-scale) (default: True) --WSCMS-MultiScaleBias=WSCMS_MULTISCALEBIAS scale bias parameter (smaller values give more weight to larger scales) (default: 0.55) --WSCMS-ScaleBasis=WSCMS_SCALEBASIS the kind of scale kernels to use (only Gauss available for now) (default: Gauss) --WSCMS-Scales=WSCMS_SCALES Scale sizes in pixels/FWHM eg. [0, 4, 8, 16] (if None determined automatically) (default: none) --WSCMS-MaxScale=WSCMS_MAXSCALE The maximum extent of the scale functions in pixels (default: 250) --WSCMS-NSubMinorIter=WSCMS_NSUBMINORITER Number of iterations for the sub minor loop (default: 250) --WSCMS-SubMinorPeakFact=WSCMS_SUBMINORPEAKFACT Peak factor of sub minor loop (default: 0.85) --WSCMS-MinorStallThreshold=WSCMS_MINORSTALLTHRESHOLD if the peak in the minor cycle decreases by less than this fraction it has stalled and we go back to the major cycle (default: 1e-07) --WSCMS-MinorDivergenceFactor=WSCMS_MINORDIVERGENCEFACTOR if the peak flux increases by more than this fraction between minor cycles then it has diverged and we go back to a major cycle (default: 1.3) --WSCMS-AutoMask=WSCMS_AUTOMASK whether to use scale dependent auto-masking (default: True) --WSCMS-AutoMaskThreshold=WSCMS_AUTOMASKTHRESHOLD Threshold at which the scale dependent mask should be fixed. (default: none) --WSCMS-AutoMaskRMSFactor=WSCMS_AUTOMASKRMSFACTOR Default multiple of RMS at which to start AutoMasking in case no (default: 3) --WSCMS-CacheSize=WSCMS_CACHESIZE the number of items to keep in the cache dict before spilling over to disk (default: 3) --WSCMS-Padding=WSCMS_PADDING padding in the minor cycle. Can often be much smaller than facet padding (default: 1.2) Montblanc settings (for --Image-PredictMode=Montblanc): --Montblanc-TensorflowServerTarget=URL URL for the TensorflowServer, e.g. grpc://tensorflow.server.com:8888/ (default: ) --Montblanc-LogFile=FILENAME None to dump as Output-Name.montblanc.log, otherwise user-specified filename (default: none) --Montblanc-MemoryBudget=MONTBLANC_MEMORYBUDGET Predictor memory budget in GiB (default: 4.0) --Montblanc-LogLevel=NOTSET|DEBUG|INFO|WARNING|ERROR|CRITICAL Log level to write to console, rest of the messages goes to log file (default: WARNING) --Montblanc-SolverDType=single|double Data type used in solver, (default: double) --Montblanc-DriverVersion=tf Backend to use, (default: tf) SSD deconvolution mode settings: --SSDClean-Parallel=0|1 Enable parallel mode. (default: True) --SSDClean-IslandDeconvMode=SSDCLEAN_ISLANDDECONVMODE Moresane, GA, Sasir, ... (default: GA) --SSDClean-SSDSolvePars=SSDCLEAN_SSDSOLVEPARS (default: ['S', 'Alpha']) --SSDClean-SSDCostFunc=SSDCLEAN_SSDCOSTFUNC (default: ['Chi2', 'MinFlux']) --SSDClean-BICFactor=SSDCLEAN_BICFACTOR (default: 0.0) --SSDClean-ArtifactRobust=SSDCLEAN_ARTIFACTROBUST (default: False) --SSDClean-ConvFFTSwitch=SSDCLEAN_CONVFFTSWITCH (default: 1000) --SSDClean-NEnlargePars=SSDCLEAN_NENLARGEPARS (default: 0) --SSDClean-NEnlargeData=SSDCLEAN_NENLARGEDATA (default: 2) --SSDClean-RestoreMetroSwitch=SSDCLEAN_RESTOREMETROSWITCH (default: 0) --SSDClean-MinMaxGroupDistance=SSDCLEAN_MINMAXGROUPDISTANCE (default: [10, 50]) --SSDClean-MaxIslandSize=SSDCLEAN_MAXISLANDSIZE (default: 0) --SSDClean-InitType=SSDCLEAN_INITTYPE (default: HMP) SSD2 deconvolution mode settings: --SSD2-PolyFreqOrder=SSD2_POLYFREQORDER Add Polyi to --SSDClean-SSDSolvePars. (default: 2) --SSD2-SolvePars=SSD2_SOLVEPARS (default: ['Poly']) --SSD2-InitType=SSD2_INITTYPE (default: ['HMP', 'MultiSlice:Orieux']) --SSD2-ConvexifyIslands=SSD2_CONVEXIFYISLANDS (default: 1) --SSD2-NLastCyclesDeconvAll=SSD2_NLASTCYCLESDECONVALL This parameter sets how many of the last cycles will deconvolve all islands. If set to 0, SSD2 will use --Deconv-CycleFactor, --Deconv-PeakFactor, --Deconv- RMSFactor to determine threshold above which islands are reestimated. If set to 2, in the last 2 major cycle all islands are estimated. If -1: Always deconv all islands regardless of the cycle number (default: 1) MultiSliceDeconv: --MultiSliceDeconv-Type=MULTISLICEDECONV_TYPE MORESANE, Orieux, etc (default: MORESANE) --MultiSliceDeconv-PolyFitOrder=MULTISLICEDECONV_POLYFITORDER (default: 2) GAClean: --GAClean-NSourceKin=GACLEAN_NSOURCEKIN (default: 50) --GAClean-NMaxGen=GACLEAN_NMAXGEN (default: 50) --GAClean-MinSizeInit=GACLEAN_MINSIZEINIT (default: 10) --GAClean-AlphaInitHMP=GACLEAN_ALPHAINITHMP (default: [-4.0, 1.0, 6]) --GAClean-ScalesInitHMP=GACLEAN_SCALESINITHMP (default: [0, 1, 2, 4, 8, 16, 24, 32]) --GAClean-GainInitHMP=GACLEAN_GAININITHMP (default: 0.1) --GAClean-RatiosInitHMP=GACLEAN_RATIOSINITHMP (default: ['']) --GAClean-NThetaInitHMP=GACLEAN_NTHETAINITHMP (default: 4) --GAClean-MaxMinorIterInitHMP=GACLEAN_MAXMINORITERINITHMP (default: 10000) --GAClean-AllowNegativeInitHMP=GACLEAN_ALLOWNEGATIVEINITHMP (default: False) --GAClean-RMSFactorInitHMP=GACLEAN_RMSFACTORINITHMP (default: 3.0) --GAClean-ParallelInitHMP=0|1 run island init in parallel. Serial mode may reduce RAM pressure, and could be useful for debugging. (default: True) --GAClean-NCPU=GACLEAN_NCPU number of cores to use for parallel fitness calculations (in large-island mode). Default of 0 means use as many as specified by --Parallel-NCPU. If you find yourself running out of memory here, you might want to specify a small number of cores for this step. (default: 0) PyMoresane internal options: --MORESANE-NMajorIter=MORESANE_NMAJORITER Maximum number of iterations allowed in the major loop. Exit condition. (default: 200) --MORESANE-NMinorIter=MORESANE_NMINORITER Maximum number of iterations allowed in the minor loop. Serves as an exit condition when the SNR is does not reach a maximum. (default: 200) --MORESANE-Gain=MORESANE_GAIN Loop gain for the deconvolution. (default: 0.1) --MORESANE-ForcePositive=MORESANE_FORCEPOSITIVE Boolean specifier for whether or not a model must be strictly positive. (default: True) --MORESANE-SigmaCutLevel=MORESANE_SIGMACUTLEVEL Number of sigma at which thresholding is to be performed. (default: 1) Options related to logging: --Log-Memory=0|1 log memory use (default: False) --Log-Boring=0|1 disable progress bars and other pretty console output (default: False) --Log-Append=0|1 append to log file if it exists (default truncates) (default: False) Debugging options for the discerning masochist: --Debug-PauseWorkers=0|1 Pauses worker processes upon launch (with SIGSTOP). Useful to attach gdb to workers. (default: False) --Debug-FacetPhaseShift=L,M Shift in facet coordinates in arcseconds for l and m (this phase steers the sky over the image plane). (default: [0.0, 0.0]) --Debug-PrintMinorCycleRMS=0|1 Compute and print RMS in minor cycle iterations. (default: False) --Debug-DumpCleanSolutions=DEBUG_DUMPCLEANSOLUTIONS Dump intermediate minor cycle solutions to a file. Use 0 or 1, or give an explicit list of things to dump (default: 0) --Debug-DumpCleanPostageStamps=X,Y,R Also dump postage stamps when cleaning within a radius R of X,Y. Implies --Debug-DumpCleanSolutions. (default: ) --Debug-CleanStallThreshold=DEBUG_CLEANSTALLTHRESHOLD Throw an exception when a fitted CLEAN component is below this threshold in flux. Useful for debugging. (default: 0.0) --Debug-MemoryGreedy=0|1 Enable memory-greedy mode. Retain certain shared arrays in RAM as long as possible. (default: True) --Debug-APPVerbose=DEBUG_APPVERBOSE Verbosity level for multiprocessing. (default: 0) --Debug-Pdb=never|always|auto Invoke pdb on unexpected error conditions (rather than exit). If set to 'auto', then invoke pdb only if --Log-Boring is 0. (default: auto) Miscellaneous options: --Misc-RandomSeed=N seed random number generator with explicit seed, if given. Useful for reproducibility of the random-based optimizations (sparsification, etc.). (default: none) --Misc-ConserveMemory=MISC_CONSERVEMEMORY if true, tries to minimize memory use at possible expense of runtime. (default: 0) --Misc-IgnoreDeprecationMarking=0|1 if true, tries to run deprecated modes. Currently this means that deconvolution machines are reset and reinitialized each major cycle. (default: False) ``` </details> ## Key parameter explanation <details> <summary style="cursor: pointer; color: #007bff;"> Click here to reveal the section </summary> | 📝 **Note** | | ------------------------------------------------------------ | |This section explains the main parameters used in DDFacet, their equivalents in the PREESM dataflow model, and their default values. These parameters control the imaging and deconvolution process. The key values have been found running DDF with default values and allow to pipelines developers to set up their prototypes with the same parameters value for fair comparison. | ### Parameters Exposed in the PREESM Dataflow Model: | PREESM Parameter | DDFacet Equivalent | DDF Value | Description | | --------------------- | --------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `NUM_MAJOR_CYCLE` | `Deconv-MaxMajorIter` | `20` | Number of CLEAN major cycles. More cycles improve convergence but increase sequential processing time. | | `NUM_MINOR_CYCLE` | `Deconv-MaxMinorIter` | `1000` | Number of minor iterations per major cycle. Too small leads to incomplete deconvolution; too large adds no value. | | `NUM_KERNEL_SUPPORT` | `CF-Support` | `7` | Size (in pixels) of the convolution kernel support. Small values cause artifacts; large values increase memory use without added benefit. | | `OVERSAMPLING_FACTOR` | `CF-OverS` | `11` | Oversampling factor for the convolution kernel. Larger values increase accuracy but also memory usage. | | `NUM_KERNELS` | `CF-Nw` | `100` | Number of w-projection kernels (planes) used to correct for non-coplanar baselines. | | `GRID_SIZE` | `Image-NPix` | `4000` | Size (in pixels) of the image grid. Must match the expected field of view and resolution. $NPix =\frac{FoV (arcsec)}{CellSize(arcsec)}$ | ### Constants Fixed in the PREESM Configuration: | PREESM Constant | DDFacet Equivalent | Value | Description | | -------------------- | -------------------- | ------------- | ------------------------------------------------------------------------------------------------ | | `Config.gain` | `Deconv-Gain` | `0.1` | Fraction of the peak flux removed at each minor iteration. Low values ensure stable convergence. | | `Config.noisyfactor` | `Deconv-NoiseFactor` | `1.5` | CLEAN stopping threshold, defined as a multiple of the estimated image RMS noise. | | `Config.max_w` | `CF-wmax` | `20000` | Maximum w-component used for gridding. Visibilities with higher w values are excluded. | | `Config.cell_size` | `Image-Cell` | `15` (arcsec) | Angular size of an image pixel. Defines resolution and field of view. | </details> ## Running DDFacet on your own laptop a.k.a Single node (multicore) Execution <details> <summary style="cursor: pointer; color: #007bff;"> Click here to reveal the section </summary> | 📝 **Note** | | ------------------------------------------------------------ | |The tutorial really starts here. This section how to install tools and usage of DDFacet on your own laptop considering that you have a Linux x86. | - Run the following commands to install dependencies and prepare your working environment: ```bash # install singularity sudo apt update sudo apt install singularity-container -y # Install DS9 viewer (for FITS files) sudo apt install saods9 # Create a writable folder for data sudo mkdir -p /media/tasse/data sudo chown -R $USER /media/tasse ``` - Once everything is ready, you can start DDFacet inside the container: - Single-node architecture (multicore): ```bash # run the singularity environment singularity shell -B/home -B/media/tasse/data ./ddf_dev_np1.22.4.sif ``` - Multi-node architecture ```bash # run the singularity environment mpirun -np 2 singularity exec -B/home -B/media/tasse/data ./ddf_dev_np1.22.4.sif [DDFacet command directly] ``` This will drop you into a shell where you can run `DDF.py` with your `.parset` file and `.ms` input. Here after are examples of command line usage and expected results explanation. #### Default imaging (dirty map) ```bash DDF.py Template.parset \ --Data-MS 0000.MS \ --Output-Name default/test \ --Data-ColName DATA ``` ###### Output: The command will generate two FITS files in the `default` folder: * `test.dirty.fits`: The raw, uncalibrated image. * `test.dirty.corr.fits`: The calibrated image (if calibration is applied). ###### Displaying the results: `python dsm.py default/test.dirty.fits` or if you don't mind about calibration: `ds9 *.fits -lock frame wcs -zoom to fit` ![ds9](https://hackmd.io/_uploads/rk9bjCEkex.png) > :bulb: Color map suggestion in DS9: Color > `inferno` #### Degridding To generate model visibilities from an input image (useful for subtraction or calibration): - copy a `test.dirty.fits` file in the right location. ``` DDF.py Template.parset \ --Data-MS 0000.MS \ --Output-Name predict/test \ --Output-Mode Predict \ --Predict-ColName DDF_PREDICT \ --Predict-FromImage predict/test.dirty.fits ``` ###### Output: The command will generate two FITS files in the `default` folder: * `test.cube.model.fits`: Spectral cube model The command will also store the predicted visibilities in the column `DDF_PREDICT` of `0000.MS` > :bulb: If the input image (`.fits`) only contains a single frequency channel and the MS has multiple channels, DDFacet will replicate the image across the spectral axis to create a matching cube. #### Clean When you observe the sky with a radio telescope, you don't get a perfect image right away. What you get is a dirty image — it contains real sources, but also lots of artifacts from the instrument's point spread function (PSF). The Clean mode helps remove these artifacts and reconstruct a clearer, more realistic image of the sky. Use this mode when you want to visualize a usable sky image or create accurate sky models for calibration or source subtraction. ``` DDF.py Template.parset \ --Data-MS 0000.MS \ --Output-Name clean/test \ --Output-Mode Clean \ --Deconv-Mode Hogbom \ --Freq-NBand 1 \ --Freq-NDegridBand 1 \ --Mask-Auto False \ --Deconv-MaxMajorIter 1 \ --Deconv-MaxMinorIter 3 \ --nCPU 1 ``` ###### Output: The command will generate two FITS files in the `clean` folder: * `test.alfa.fits`: Weight map showing confidence per pixel in the model. * `test.app.model.fits`: The reconstructed model of the sky (just the detected sources). * `test.app.restored.fits`: The final clean image: model + residual smoothed with the PSF. * `test.brutalModelConv01.fits`: Raw versions of model images (for advanced use/debugging). * `test.brutalRestored01.fits`: Raw versions of restored images (for advanced use/debugging). * `test.mask01.fits`: Mask used to guide automatic cleaning (based on signal thresholds). * `test.noise01.fits`: Noise estimation map of the image. * `test.residual01.fits`: What’s left after subtracting the model from the dirty image. ![Screenshot from 2025-04-23 11-43-11](https://hackmd.io/_uploads/Hk_9PVLkgg.png) |Deconv-Mode | Speed | Resources | Use When…| | -------- | -------- | -------- | -------- | |HMP (Harmonic Matching Pursuit)| 🟢 Fast | 🟢 Light | You want quick results and decent cleaning, good default.| Hogbom | 🟡 Medium | 🟡 Medium | Classic CLEAN, for point sources. SSD (Steepest-Descent Deconvolution)| 🔴 Very Slow | 🔴 Heavy | Gradient-based deconv, avoid unless you really need precise large-scale structures. WSCMS (Weighted Source Component Model Subtaction) | 🔴 Very Slow | 🔴 Heavy | Advanced method for complex sky models, but slow and memory-hungry. </details> ## Running DDFacet MPI on your on laptop <details> <summary style="cursor: pointer; color: #007bff;"> Click here to reveal the section </summary> | 📝 **Note** | | ------------------------------------------------------------ | | This section how to install tools and usage of DDFacet a multinode Cluster faking multi-node execution on a Linux x86. The procedure start with a distributed measurementSet and apply the MPI version of DDFacet.| ```mermaid graph LR; A[Split-MS] --> B[MPI-DDFacet]; B --> C[image.fits]; ``` ### Distributed MeasurementSet The following steps explain how to properly split a measurementSet for multinode-DDFacet execution. - Dowload python casacore: `pip install python-casacore` - Download the script to split measurementSet [here](https://github.com/Ophelie-Renaud/ddfacet-dft-fft-g2g-tutorials). ```python import os import shutil import numpy as np from casacore.tables import table import argparse def split_ms(ms_path, output_prefix, criterion='time', n_splits=2): assert criterion in ['time', 'scan', 'field', 'spw'], "Critère non supporté pour split standard." t = table(ms_path) colname = { 'time': 'TIME', 'scan': 'SCAN_NUMBER', 'field': 'FIELD_ID', 'spw': 'DATA_DESC_ID' }[criterion] column = t.getcol(colname) unique_vals = sorted(set(column)) print(f"📊 {criterion.upper()} values trouvées : {unique_vals}") if n_splits > len(unique_vals): print(f"⚠️ Seulement {len(unique_vals)} valeurs distinctes pour {colname}, ajustement de n_splits.") n_splits = len(unique_vals) groups = [[] for _ in range(n_splits)] for i, val in enumerate(unique_vals): groups[i % n_splits].append(val) for i, group_vals in enumerate(groups): val_str = ','.join(map(str, group_vals)) query_str = f"{colname} IN [{val_str}]" sub = t.query(query_str) out_path = f"{output_prefix}_{criterion}_{i}.ms" if os.path.exists(out_path): shutil.rmtree(out_path) sub.copy(out_path, deep=True) print(f"✅ Split {i} : {sub.nrows()} lignes -> {out_path}") t.close() def split_by_channel(ms_path, output_prefix): t = table(ms_path) data = t.getcol('DATA') n_channels = data.shape[1] t.close() print(f"📡 Nombre de canaux détectés : {n_channels}") for chan_idx in range(n_channels): print(f"\n📤 Extraction du canal {chan_idx}") out_path = f"{output_prefix}_channel_{chan_idx}.ms" if os.path.exists(out_path): shutil.rmtree(out_path) shutil.copytree(ms_path, out_path) t_out = table(out_path, readonly=False) data_all = t_out.getcol('DATA') masked_data = np.zeros_like(data_all) masked_data[:, chan_idx, :] = data_all[:, chan_idx, :] t_out.putcol('DATA', masked_data) t_out.close() print(f"✅ Canal {chan_idx} sauvegardé dans : {out_path}") if __name__ == "__main__": parser = argparse.ArgumentParser(description="Split Measurement Set (MS) selon divers critères.") parser.add_argument("ms_path", help="Chemin vers le MS d'entrée.") parser.add_argument("output_prefix", help="Préfixe ou dossier de sortie.") parser.add_argument("--criterion", choices=['time', 'scan', 'field', 'spw', 'channel'], default='time', help="Critère de découpe (par défaut: time).") parser.add_argument("--n_splits", type=int, default=2, help="Nombre de splits (non utilisé si criterion=channel).") args = parser.parse_args() if args.criterion == 'channel': split_by_channel(args.ms_path, args.output_prefix) else: split_ms(args.ms_path, args.output_prefix, criterion=args.criterion, n_splits=args.n_splits) ``` Usage: ```bash python split_ms_tool.py /path/to/my.ms output_prefix --criterion field --n_splits 3 ``` *where `criterion field` ∈ [`time` (default: split by observation time), `scan` (split by scan number, continuous observation sequence), `field` (split by field/source ID), `spw` (split by spectral window (frequency), `channel` (split each spectral channel into a separate MS)], `n_splits` by default limited to your MS criterion field* . ### Fake a Multinode execution on your laptop Here after are examples of command line usage running MPI version of DDFacet on your laptop. For the expected results explanation please refer to section single node execution where the DDFacet options used are basically the same. #### Default imaging (dirty map) Change the measurementSets names with your distributed measuremenSets names. ``` mpirun -np 2 singularity exec -B /home -B /media/tasse/data \ ./ddf_dev_np1.22.4.sif DDF.py Template.parset \ --Data-MS 0000.MS,0000.MS \ --Output-Name default/test \ --Data-ColName DATA ``` #### Degridding ``` mpirun -np 2 singularity exec -B /home -B /media/tasse/data \ ./ddf_dev_np1.22.4.sif DDF.py Template.parset \ --Data-MS 0000.MS,0000.MS \ --Output-Name predict/test \ --Output-Mode Predict \ --Predict-ColName DDF_PREDICT \ --Predict-FromImage predict/test.dirty.fits ``` #### Clean <p align="center"> <img src="https://hackmd.io/_uploads/rytkVN2Glx.png" alt="Figure DDFacet" width="400"/> <br> <sub>The Figure gives an overview of the parallelization implemented within DDFacet. The following command enables the reconstruction of a distributed MeasurementSet across a multi-node architecture, based on the work by N. Monnier et al: <a href="https://hal.science/hal-03729202/document">DDFacet parallel</a>.</sub> </p> ``` mpirun -np 2 singularity exec -B /home -B /media/tasse/data \ ./ddf_dev_np1.22.4.sif DDF.py Template.parset \ --Data-MS 0000.MS,0000.MS \ --Output-Name clean/test \ --Output-Mode Clean \ --Deconv-Mode HMP \ --Freq-NBand 3 \ --Freq-NDegridBand 1 \ --Mask-Auto True \ --Mask-SigTh 15 \ --Mask-AutoRMSFactor 3 \ --Deconv-MaxMajorIter 1 \ --Deconv-MaxMinorIter 5 ``` </details> ## Running DDFacet MPI on Ruche Mesocentre a.k.a Multinode Execution <details> <summary style="cursor: pointer; color: #007bff;"> Click here to reveal the section </summary> | 📝 **Note** | | ------------------------------------------------------------ | | This section how to install tools and usage of DDFacet on [Ruche Mesocentre Cluster](https://mesocentre.pages.centralesupelec.fr/user_doc/), a SLURM-based cluster, however feel free to crash & test it wherever you can. The procedure start with a distributed measurementSet and apply the MPI version of DDFacet.| - To run on the Ruche Mesocentre cluster, you first need a valid account. - Check your eligibility: Ruche is accessible to all researchers from ENS Paris-Saclay, CentraleSupélec, Université Paris-Saclay, Maison de la Simulation, otherwise you can pay. - Prepare a [project referee](https://mesocentre.universite-paris-saclay.fr/ruche/project_creation_form.html.txt?utm_source=chatgpt.com) - Send the document to the support: `ruche.support@universite-paris-saclay.fr` Once the account is activated, you can connect via SSH and submit jobs through SLURM. SLURM manages the allocation of resources (nodes, CPUs, GPUs, memory, time limits) and schedules jobs. Here, an example job script `slurm.sh`: ```shell #!/bin/bash #SBATCH --job-name=ddfacet_job #SBATCH --output=%x.out #SBATCH --error=%x.err #SBATCH --time=02:00:00 #SBATCH --nodes=1 #SBATCH --ntasks=2 #SBATCH --partition=cpu_med set -x # mode debug # Chargement des modules module purge module load intel/19.0.3/gcc-4.8.5 module load singularity/3.8.3/gcc-11.2.0 # Nettoyage environnement Python utilisateur unset PYTHONPATH export PYTHONNOUSERSITE=1 export PYTHONUSERBASE=/tmp # HOME factice dans le conteneur FAKE_HOME="/tmp/fakehome_${SLURM_JOB_ID}" mkdir -p $FAKE_HOME # Lancement sans le vrai $HOME srun singularity exec --cleanenv --no-home \ -H $FAKE_HOME \ -B /gpfs/users/renaudo/data:/media/tasse/data \ -B /home/renaudo/Template.parset:/media/tasse/Template.parset \ ./ddf_dev_np1.22.4.sif DDF.py /media/tasse/Template.parset \ --Data-MS /media/tasse/data/0000.MS,/media/tasse/data/0000.MS \ --Output-Name /media/tasse/data/clean/test \ --Output-Mode Clean \ --Deconv-Mode HMP \ --Freq-NBand 3 \ --Freq-NDegridBand 1 \ --Mask-Auto True \ --Mask-SigTh 15 \ --Mask-AutoRMSFactor 3 \ --Deconv-MaxMajorIter 1 \ --Deconv-MaxMinorIter 5 ``` - Transfer the mandatory file on the Cluster: ```bash rsync -avh --progress ddf_dev_np1.22.4.sif renaudo@ruche.mesocentre.universite-paris-saclay.fr:/home/renaudo/ rsync -avh --progress Template.parset renaudo@ruche.mesocentre.universite-paris-saclay.fr:/home/renaudo/ rsync -avh --progress SB155.rebin.ms renaudo@ruche.mesocentre.universite-paris-saclay.fr:/home/renaudo/ rsync -avh --progress slurm.sh renaudo@ruche.mesocentre.universite-paris-saclay.fr:/home/renaudo/ ``` - Connect and prepare the workspace ```bash ssh renaudo@ruche.mesocentre.universite-paris-saclay.fr cd /home/renaudo/ mkdir -p /gpfs/users/renaudo/data ``` - Submit the job ```bash sbatch slurm.sh ``` - (optional) Commands for monitoring ```bash squeue -u renaudo # check job status cat ddfacet_job.out # standard output cat ddfacet_job.err # error logs ``` - Generated files are stored in `ls -lh ~/clean`. To copy them back locally: `rsync -avh --progress renaudo@ruche.mesocentre.universite-paris-saclay.fr:/gpfs/users/renaudo/clean/ ~/local/path/clean/` </details> ## Multiple Chain Execution of Distributed MSs on a Ruche <details> <summary style="cursor: pointer; color: #007bff;"> Click here to reveal the section </summary> | 📝 **Note** | | ------------------------------------------------------------ | |The goal here is to run DDFacet multiple times imaging diferent measuremenSet where we control the number of visibilities, why not the grid size and why not the number of sources/ minor cycle and store the latency of each. This will allow to generate a trend line of DDFacet behavior (fixing other options) to position according with existing imager trend lines at NenuFAR level and extrapolation to SKAO scale and to position according real time execution target.| ```mermaid graph LR; subgraph Loop["For ms ∊ [ms_min; ms_ax]"] B[MPI-DDFacet] --> C[image.fits] end ``` Here is the `slurm_multi.sh`: ```shell #!/bin/bash #SBATCH --job-name=ddfacet_multi #SBATCH --output=%x.out #SBATCH --error=%x.err #SBATCH --time=04:00:00 #SBATCH --nodes=1 #SBATCH --ntasks=1 #SBATCH --cpus-per-task=40 #SBATCH --partition=cpu_med set -x module purge module load intel/19.0.3/gcc-4.8.5 module load singularity/3.8.3/gcc-11.2.0 unset PYTHONPATH export PYTHONNOUSERSITE=1 export PYTHONUSERBASE=/tmp FAKE_HOME="/tmp/fakehome_${SLURM_JOB_ID}" mkdir -p $FAKE_HOME # List of MeasurementSets to process MS_LIST=( "/media/tasse/data/0000.MS" "/media/tasse/data/0000.MS" "/media/tasse/data/0000.MS" ) # Loop over them for MS in "${MS_LIST[@]}"; do BASENAME=$(basename "$MS" .MS) START=$(date +%s) srun singularity exec --cleanenv --no-home \ -H $FAKE_HOME \ -B /gpfs/users/renaudo/data:/media/tasse/data \ -B /home/renaudo/Template.parset:/media/tasse/Template.parset \ ./ddf_dev_np1.22.4.sif DDF.py /media/tasse/Template.parset \ --Data-MS "$MS" \ --Output-Name /media/tasse/data/clean/${BASENAME} \ --Output-Mode Clean \ --Deconv-Mode HMP \ --Freq-NBand 3 \ --Freq-NDegridBand 1 \ --Mask-Auto True \ --Mask-SigTh 15 \ --Mask-AutoRMSFactor 3 \ --Deconv-MaxMajorIter 1 \ --Deconv-MaxMinorIter 5\ --Parallel-NCPU ${SLURM_CPUS_PER_TASK} END=$(date +%s) RUNTIME=$((END-START)) echo "${BASENAME} took ${RUNTIME} seconds" | tee -a runtimes.log done ``` - Transfer the mandatory file on the Cluster: ``` rsync -avh --progress slurm_multi.sh renaudo@ruche.mesocentre.universite-paris-saclay.fr:/home/renaudo/ ``` - Connect and prepare the workspace ```bash ssh renaudo@ruche.mesocentre.universite-paris-saclay.fr cd /home/renaudo/ mkdir -p /gpfs/users/renaudo/data ``` - Submit the job ```bash sbatch slurm_multi.sh ``` - (optional) Commands for monitoring ```bash squeue -u renaudo # check job status cat ddfacet_job.out # standard output cat ddfacet_job.err # error logs ``` - Recuperons les timings: `rsync -avh --progress renaudo@ruche.mesocentre.universite-paris-saclay.fr:/gpfs/users/renaudo/runtimes.log ~/Desktop/` - Affichons la courbe de tendance des timing: ```python import matplotlib.pyplot as plt # Lecture du fichier ms_names = [] runtimes = [] with open("runtimes.log") as f: for line in f: parts = line.strip().split() ms_names.append(parts[0]) runtimes.append(float(parts[2])) # secondes # Création de la figure plt.figure(figsize=(8,5)) plt.plot(ms_names, runtimes, marker='o', linestyle='-', color='blue') plt.xlabel("MeasurementSet") plt.ylabel("Runtime (s)") plt.title("Execution time per MS") plt.grid(True) plt.tight_layout() plt.show() ``` </details> ## Read measuremenSet ToDo ## Note :warning: *This tutorial has been tested from the `SB155.rebin.ms` mesuremenSet obtained from NenuFAR via nancep.* Contributions and ideas are welcome! ## Contact For questions or feedback, please contact: - This tutorial was written by [Ophélie Renaud](mailto:ophelie.renaud@ens-paris-saclay.fr) from PREESM/SimSDP community (previously @INSA, @IETR, now @SATIE paris-saclay, @IRISA, @ENS Rennes :fr:).