diff --git a/steps/DemixingStepGenerator.cwl b/steps/DemixingStepGenerator.cwl
new file mode 100755
index 0000000000000000000000000000000000000000..ad67dd42f8d7db269310c5255da9b026aa8aaae8
--- /dev/null
+++ b/steps/DemixingStepGenerator.cwl
@@ -0,0 +1,171 @@
+#!/usr/bin/env cwl-runner
+
+class: CommandLineTool
+cwlVersion: v1.0
+id: demixstepSgenerator
+baseCommand: [parset_concat.py]
+
+requirements:
+  DockerRequirement:
+    dockerPull: prefactor-utils:latest
+
+arguments: ['demixer']
+
+inputs:
+  - id: parset
+    type: File
+    inputBinding:
+        position: -1
+        prefix: --input_parset
+  - id: step_name
+    type: string
+    default: demix_step
+    doc: unique name for the step
+    inputBinding:
+        position: -1
+  - id: secondary_files
+    type: File[]
+    doc: Files other than the input used to process the data
+###############################################################################
+  - id: baseline
+    type: string
+    default: “”
+    doc: Baselines to demix. See Description of baseline selection parameters.
+    inputBinding:
+      prefix: baseline=
+      separate: false
+  - id: blrange
+    type: double[]
+    default: “”
+    doc: Baselines to demix. See Description of baseline selection parameters.
+    inputBinding:
+      prefix: blrange=
+      separate: false
+  - id: corrtype
+    type: string
+    default: cross
+    doc: Baselines to demix. Correlation type to match? Must be auto, cross, or an empty string.
+    inputBinding:
+      prefix: corrtype=
+      separate: false
+  - id: timestep
+    type: integer
+    default: 1
+    doc: Number of time slots to average when subtracting. It is truncated if exceeding the actual number of times. Note that the data itself will also be averaged by this amount.
+    inputBinding:
+      prefix: timestep=
+      separate: false
+  - id: freqstep
+    type: integer
+    default: 1
+    doc: Number of channels to average when subtracting. It is truncated if exceeding the actual number of channels. Note that the data itself will also be averaged by this amount.
+    inputBinding:
+      prefix: freqstep=
+      separate: false
+  - id: demixtimestep
+    type: integer
+    default: timestep
+    doc: Number of time slots to average when demixing. It is truncated if exceeding the actual number of times. It defaults to the averaging used for the subtract.
+    inputBinding:
+      prefix: demixtimestep=
+      separate: false
+  - id: demixfreqstep
+    type: integer
+    default: freqstep
+    doc: Number of channels to average when demixing. It is truncated if exceeding the actual number of channels. It defaults to the averaging used for the subtract.
+    inputBinding:
+      prefix: demixfreqstep=
+      separate: false
+  - id: ntimechunk
+    type: integer
+    default: #cores
+    doc: Number of demix time slots (after averaging) that are processed jointly in as much a parallel way as possible. If subtract uses different time averaging, it has to fit integrally.
+    inputBinding:
+      prefix: ntimechunk=
+      separate: false
+  - id: skymodel
+    type: string
+    default: sky
+    doc: The name of the SourceDB to use (i.e., the output of makesourcedb).
+    inputBinding:
+      prefix: skymodel=
+      separate: false
+  - id: instrumentmodel
+    type: string
+    default: instrument
+    doc: The name of the ParmDB to use. The ParmDB does not need to exist. If it does not exist it will be created.
+    inputBinding:
+      prefix: instrumentmodel=
+      separate: false
+  - id: subtractsources
+    type: string[]
+    default:
+    doc: Names of the sources to subtract. If none are given, demixing comes down to averaging. The sources must exist as patches in the SourceDB.
+    inputBinding:
+      prefix: subtractsources=
+      separate: false
+  - id: modelsources
+    type: string vector
+    default: []
+    doc: Names of sources with models to take into account when solving. the sources must exist as patches in the SourceDB. Note that the target should NOT be part of this parameter. If a model of the target has to be used, it has to be given in parameter targetsource.
+    inputBinding:
+      prefix: modelsources=
+      separate: false
+  - id: targetsource
+    type: string
+    default: ''
+    doc: It can be used to specify the name of the source model of the target. If given, the target source model (its patch in the SourceDB) is taken into account when solving; in this case parameter othersources cannot be given. It cannot be given if ignoretarget=true. If not given, the target is projected away or ignored (depending on parameter ignoretarget).
+    inputBinding:
+      prefix: targetsource=
+      separate: false
+  - id: ignoretarget
+    type: bool
+    default: false
+    doc: false = project the target source away; true = ignore the target
+    inputBinding:
+      prefix: ignoretarget=
+      separate: false
+  - id: othersources
+    type: string vector
+    default: []
+    doc: Names of sources of which the direction is taken into account when demixing by projecting the directions away. The direction needs to be specified if the source is unknown (which is usually the case). It can be done using parameters <step>.<sourcename>.phasecenter.
+    inputBinding:
+      prefix: othersources=
+      separate: false
+  - id: propagatesolutions
+    type: bool
+    default: true
+    doc: If set to true, solutions of a time slot are used as initial values for the next time slot. If set to false, the diagonal elements of the Jones matrix are initialized to one and the off-diagonal elements to zero.
+    inputBinding:
+      prefix: propagatesolutions=
+      separate: false
+  - id: defaultgain
+    type: double
+    default: 1
+    doc: The default and initial gain for the directional gains that are computed internally.
+    inputBinding:
+      prefix: defaultgain=
+      separate: false
+  - id: maxiter
+    type: int
+    default: 50
+    doc: Maximum number of iterations used in the LM solve
+    inputBinding:
+      prefix: maxiter=
+      separate: false
+
+
+stdout: output_parset
+outputs:
+  - id: output_parset
+    doc: Parset output file
+    streamable: True
+    type: File
+    outputBinding:
+        glob: output_parset
+
+  - id: secondary_files
+    doc: files needed to execute the step
+    type: File[]
+    outputBinding:
+      outputEval: $(inputs.secondary_files)