diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b225cf5d10cb1271ec2bdb3ab2d7a8508cf000fb..72251a148d01ab13a6157b5a1d7047f49a1b4c8b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -105,6 +105,13 @@ losoto_residual:
   script:
     - cwl-runner --no-container steps/LoSoTo.Residual.cwl test_jobs/losoto_residual.json
 
+losoto_polalign:
+  stage: test_steps
+  allow_failure: true
+  script:
+    - cwl-runner --no-container steps/LoSoTo.Polalign.cwl test_jobs/losoto_polalign.json
+    
+
 parset_selector:
   stage: test_steps
   allow_failure: true
@@ -116,6 +123,7 @@ file_selector:
   allow_failure: true
   script:
     - cwl-runner steps/FileSelector.cwl test_jobs/file_selector.json
+    
 
 NDPPP:
   stage: test_steps
diff --git a/steps/LoSoTo.Polalign.cwl b/steps/LoSoTo.Polalign.cwl
new file mode 100755
index 0000000000000000000000000000000000000000..a6a65068192cc1ce192f864364af6387dc44b453
--- /dev/null
+++ b/steps/LoSoTo.Polalign.cwl
@@ -0,0 +1,92 @@
+
+class: CommandLineTool
+cwlVersion: v1.0
+id: losoto_polalign
+
+$namespaces:
+  lofar: https://git.astron.nl/eosc/ontologies/raw/master/schema/lofar.owl
+$schema:
+  - https://git.astron.nl/eosc/ontologies/raw/master/schema/lofar.owl
+  
+doc: |
+    Estimate polarization misalignment as delay
+   
+requirements:
+  InlineJavascriptRequirement:
+    expressionLib:
+     - |
+        function get_config() {
+        var par = ['soltab = ' + inputs.soltab]
+        if (inputs.ncpu !== null) par.push('ncpu='+inputs.ncpu);
+        par.push('[polalign]')
+        par.push('operation = POLALIGN')
+        for(var field_name in inputs){
+            if(field_name === 'input_h5parm' ||
+               field_name === 'soltab' ||
+               field_name === 'ncpu') continue;
+            if(inputs[field_name] === null ||
+               inputs[field_name] === 'null') continue;
+            par.push(field_name+'='+inputs[field_name])
+        }
+        return par
+        }
+  InitialWorkDirRequirement:
+    listing:
+      - entryname: 'parset.config'
+        entry: $(get_config().join('\n'))
+      - entryname: $(inputs.input_h5parm.basename)
+        entry: $(inputs.input_h5parm)
+        writable: true
+
+
+
+baseCommand: "losoto"
+
+arguments:
+  - $(inputs.input_h5parm.basename)
+  - parset.config
+
+hints:
+  DockerRequirement:
+    dockerPull: lofareosc/lofar-pipeline-ci:latest
+
+inputs:
+  - id: input_h5parm
+    type: File
+    format: lofar:#H5Parm
+  - id: soltab
+    type: string
+    doc: "Solution table"
+  - id: soltabout
+    default: phasediff
+    type: string?
+    doc: output table name (same solset)
+  - id: maxResidual
+    type: float?
+    default: 1
+    doc: Maximum acceptable rms of the residuals in radians before flagging. Set to zero to avoid the check.
+  - id: fitOffset
+    type: boolean?
+    default: false
+    doc: Assume that together with a delay each station has also a differential phase offset (important for old LBA observations).
+    
+  - id: average
+    type: boolean?
+    default: false
+    doc: Mean-average in time the resulting delays/offset.
+  - id: replace
+    type: boolean?
+    default: false
+    doc: replace using smoothed value instead of flag bad data? Smooth must be active.
+  - id: refAnt
+    type: string?
+    doc: Reference antenna, if not set use the first one.
+    
+outputs:
+  - id: output_h5parm
+    type: File
+    format: lofar:#H5Parm
+    outputBinding:
+      glob: $(inputs.input_h5parm.basename)
+
+
diff --git a/test_jobs/losoto_polaling.json b/test_jobs/losoto_polaling.json
new file mode 100644
index 0000000000000000000000000000000000000000..eb4ccc687b0f32641bd9724ad46d3d8e50fafeeb
--- /dev/null
+++ b/test_jobs/losoto_polaling.json
@@ -0,0 +1,9 @@
+{
+    "input_h5parm": {
+            "class": "File",
+            "path": "/data/example.h5",
+        "format": "lofar:#H5Parm"
+        },
+    "soltab": "sol000/amplitude000",
+    "average": true
+}