diff --git a/README.md b/README.md
index cc4e8af902bbb607ca28da3d77347a011e30e2bf..21f8995ce38dfce975d548f06ad16249cf9967ce 100644
--- a/README.md
+++ b/README.md
@@ -36,11 +36,14 @@ Currently they are still mostly the original ATDB diagrams. They will be adapted
   
 ![](atdb/docs/ATDB-LDV%20-%20Deployment%20Diagram.png)
   
-## Manual deploy in Docker
+## CI/CD (semi) automatic deploy in Docker
 For the `master' branch there is a CI/CD pipeline in place which builds and deploys the backend at https://sdc.astron.nl:5554/atdb/ 
+
 The deploy step requires pushing the 'play' button in the gitlab pipelines section. 
 This is done to not have a mandatory deploy for every minor commmit.
 
+## Manual deploy in Docker (alternative to CI/CD)
+
 ### initial
 
     > cd ~/my_docker
diff --git a/atdb/taskdatabase/admin.py b/atdb/taskdatabase/admin.py
index 134b52d8d4ce0a91433c371a5605868778fe2f45..d38dc14d6aa10359b4b6febc150643f7ce434f1f 100644
--- a/atdb/taskdatabase/admin.py
+++ b/atdb/taskdatabase/admin.py
@@ -1,6 +1,5 @@
 from django.contrib import admin
-from .models import Status, DataProduct, Observation
+from .models import Status, Observation
 
 admin.site.register(Status)
-admin.site.register(DataProduct)
 admin.site.register(Observation)
\ No newline at end of file
diff --git a/atdb/taskdatabase/migrations/0003_auto_20210114_1133.py b/atdb/taskdatabase/migrations/0003_auto_20210114_1133.py
new file mode 100644
index 0000000000000000000000000000000000000000..51495fc7aaff428e1b6f6bed287fa0df137e3d5f
--- /dev/null
+++ b/atdb/taskdatabase/migrations/0003_auto_20210114_1133.py
@@ -0,0 +1,26 @@
+# Generated by Django 3.1.4 on 2021-01-14 10:33
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('taskdatabase', '0002_taskobject_metadata'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='observation',
+            name='progress',
+            field=models.CharField(blank=True, default='0%', max_length=40, null=True),
+        ),
+        migrations.AlterField(
+            model_name='taskobject',
+            name='task_type',
+            field=models.CharField(default='observation', max_length=20),
+        ),
+        migrations.DeleteModel(
+            name='DataProduct',
+        ),
+    ]
diff --git a/atdb/taskdatabase/models.py b/atdb/taskdatabase/models.py
index 8fa8af5b69107c9d079c156dea2dda799124a7c2..3436af0afca80cc5d843b5531fec01031e0c4d3a 100644
--- a/atdb/taskdatabase/models.py
+++ b/atdb/taskdatabase/models.py
@@ -7,30 +7,12 @@ from django.db.models import Sum
 datetime_format_string = '%Y-%m-%dT%H:%M:%SZ'
 
 TASK_TYPE_OBSERVATION = 'observation'
-TASK_TYPE_DATAPRODUCT = 'dataproduct'
 
 TYPE_VISIBILITY = 'visibility'
 
-# common model functions
-def get_sum_from_dataproduct_field(taskID, field):
-    """
-    sum the values of a field for certain taskID. (used to sum total of dataproduct sizes)
-    :param taskID:
-    :param field:
-    :return:
-    """
-    query = field + '__sum'
-    sum_value = DataProduct.objects.filter(taskID=taskID).aggregate(Sum(field))[query]
-    if sum_value == None:
-        sum_value = 0.0
-    return sum_value
-
-"""
-a base class of both Observation and Dataproducts
-"""
 class TaskObject(models.Model):
     name = models.CharField(max_length=100, default="unknown")
-    task_type = models.CharField(max_length=20, default=TASK_TYPE_DATAPRODUCT)
+    task_type = models.CharField(max_length=20, default=TASK_TYPE_OBSERVATION)
 
     taskID = models.CharField('runId', db_index=True, max_length=30, blank=True, null=True)
     creationTime = models.DateTimeField(default=datetime.utcnow, blank=True)
@@ -99,31 +81,6 @@ class Observation(TaskObject):
             duration = 0
         return duration
 
-    @property
-    def size(self):
-        # sum the sizes of all dataproducts with this taskID. In Mb
-        size = get_sum_from_dataproduct_field(self.taskID,'size')
-        return size
-
     def __str__(self):
         return str(self.taskID)
 
-
-class DataProduct(TaskObject):
-    # properties
-    filename = models.CharField(max_length=200, default="unknown")
-    description = models.CharField(max_length=255, default="unknown")
-    dataproduct_type = models.CharField('type', default=TYPE_VISIBILITY, max_length=50)
-    size = models.BigIntegerField(default=0)
-
-    # relationships
-    parent = models.ForeignKey(Observation, related_name='generated_dataproducts', on_delete=models.CASCADE, null=False)
-
-    # this translates a view-name (from urls.py) back to a url, to avoid hardcoded url's in the html templates
-    # bad : <td><a href="/atdb/observations/{{ observation.id }}/" target="_blank">{{ observation.taskID }} </a> </td>
-    # good: <td><a href="{{ observation.get_absolute_url }}" target="_blank">{{ observation.taskID }} </a> </td>
-    def get_absolute_url(self):
-        return reverse('dataproduct-detail-view-api', kwargs={'pk': self.pk})
-
-    def __str__(self):
-        return self.filename
diff --git a/atdb/taskdatabase/serializers.py b/atdb/taskdatabase/serializers.py
index 39040fcd1196f42f143b2f816e32679a346679b0..02d7a04c6dd8cfbdeaf2e5dc065deefb2d22b253 100644
--- a/atdb/taskdatabase/serializers.py
+++ b/atdb/taskdatabase/serializers.py
@@ -1,5 +1,5 @@
 from rest_framework import serializers
-from .models import DataProduct, Observation, Status, TaskObject
+from .models import Observation, Status, TaskObject
 import logging
 
 logger = logging.getLogger(__name__)
@@ -11,37 +11,7 @@ class StatusSerializer(serializers.ModelSerializer):
         fields = ('id','name','timestamp','property_taskID','property_task_type')
 
 
-class DataProductSerializer(serializers.ModelSerializer):
-    # this adds a 'parent_observation' list with hyperlinks to the DataProduct API.
-    # note that 'generatedByObservation' is not defined in the DataProduct model, but in the Observation model.
-
-    parent = serializers.PrimaryKeyRelatedField(
-        many=False,
-        queryset=Observation.objects.all(),
-        required=False,
-    )
-
-    status_history = serializers.StringRelatedField(
-        many=True,
-        required=False,
-    )
-
-    class Meta:
-        model = DataProduct
-        fields = ('id','task_type','name','filename','description',
-                  'taskID','creationTime','size',
-                  'my_status','new_status','status_history','parent',
-                  'data_location','node','quality','metadata')
-
-
 class ObservationSerializer(serializers.ModelSerializer):
-    # this adds a 'generated_dataproducts' list with hyperlinks to the Observation API.
-    # note that 'generated_dataproducts' is not defined in the DataProduct model, but comes from the related_field in Observation.parent.
-
-    generated_dataproducts = serializers.StringRelatedField(
-        many=True,
-        required=False,
-    )
 
     status_history = serializers.StringRelatedField(
         many=True,
@@ -53,8 +23,7 @@ class ObservationSerializer(serializers.ModelSerializer):
         fields = ('id','task_type', 'name','taskID',
                   'field_name','field_ra','field_dec',
                   'creationTime','starttime','endtime', 'duration', 'size',
-                  'my_status','new_status','status_history',
-                  'generated_dataproducts',
+                  'my_status','new_status','status_history','generated_dataproducts',
                   'data_location', 'node',
                   'skip_auto_ingest','observing_mode',
                   'quality','metadata','progress')
diff --git a/atdb/taskdatabase/services/algorithms.py b/atdb/taskdatabase/services/algorithms.py
index 5e61721adb643d22d8042d3d2f2f5232106d657c..6d9d0004d6e311dc6d95100251c225b2e3d9132c 100644
--- a/atdb/taskdatabase/services/algorithms.py
+++ b/atdb/taskdatabase/services/algorithms.py
@@ -8,7 +8,7 @@ import time
 import datetime
 import logging
 from .common import timeit
-from ..models import Observation, DataProduct
+from ..models import Observation
 
 DATE_FORMAT = "%Y-%m-%d"
 TIME_FORMAT = "%Y-%m-%d %H:%M:%SZ"
@@ -115,45 +115,3 @@ def get_next_observation(my_status, observing_mode, datawriter):
     return taskID,minutes_left
 
 
-# /atdb/post_dataproducts
-def add_dataproducts(dataproducts):
-    """
-    :param taskID: taskid of the observation
-    :param dataproducts: json list of dataproducts to be added to the provided taskid
-    :return:
-    """
-
-    taskID = None
-    dps = dataproducts.get('dps')
-    number_of_dataproducts = len(dps)
-
-    logger.info("add_dataproducts("+str(number_of_dataproducts)+")")
-
-    for dp in dps:
-        # get the common fields from the observation based on the given taskid
-        taskID = dp.get('taskID')
-        parent = Observation.objects.get(taskID=taskID)
-        parent_data_location = parent.data_location
-
-        node=dp.get('node',None)
-        new_status = dp.get('new_status','defined')
-        data_location = dp.get('data_dir',parent_data_location)
-        size = dp.get('size', 0)
-        myDataProduct = DataProduct(taskID=taskID,
-                                    node=node,
-                                    data_location=data_location,
-                                    filename=dp['filename'],
-                                    name=dp['filename'],
-                                    description=dp['filename'],
-                                    quality=dp['quality'],
-                                    metadata=dp['metadata'],
-                                    task_type='dataproduct',
-                                    new_status=new_status,
-                                    parent=parent,
-                                    size=size
-                                    )
-
-        logger.info('addding dataproduct: '+str(myDataProduct))
-        myDataProduct.save()
-
-    return taskID
diff --git a/atdb/taskdatabase/services/signals.py b/atdb/taskdatabase/services/signals.py
index cb7050b7b87a804b7db8a2dfba2b4b295f1d767b..1fce99e58a8999beb4fb61e28c4bca7b02c23dfd 100644
--- a/atdb/taskdatabase/services/signals.py
+++ b/atdb/taskdatabase/services/signals.py
@@ -5,7 +5,7 @@ from django.core.signals import request_started, request_finished
 from django.contrib.auth.models import User
 from django.dispatch import receiver
 from django.contrib.contenttypes.models import ContentType
-from taskdatabase.models import TaskObject, Observation, DataProduct, Status
+from taskdatabase.models import TaskObject, Observation, Status
 from . import jobs
 
 """
@@ -26,22 +26,17 @@ def request_started_handler(sender, **kwargs):
 def request_finished_handler(sender, **kwargs):
     logger.debug("signal : request_finished")
 
-#--- Observation and DataProduct signals-------------
+#--- Task signals-------------
 
 @receiver(pre_save, sender=Observation)
 def pre_save_observation_handler(sender, **kwargs):
     logger.info("SIGNAL : pre_save Observation(" + str(kwargs.get('instance')) + ")")
     handle_pre_save(sender, **kwargs)
 
-@receiver(pre_save, sender=DataProduct)
-def pre_save_dataproduct_handler(sender, **kwargs):
-    logger.info("SIGNAL : pre_save DataProduct(" + str(kwargs.get('instance')) + ")")
-    handle_pre_save(sender, **kwargs)
-
 
 def handle_pre_save(sender, **kwargs):
     """
-    pre_save handler for both Observation and Dataproduct. Mainly to check status changes and dispatch jobs in needed.
+    pre_save handler. Mainly to check status changes and dispatch jobs in needed.
     :param (in) sender: The model class that sends the trigger
     :param (in) kwargs: The instance of the object that sends the trigger.
     """
@@ -64,41 +59,6 @@ def handle_pre_save(sender, **kwargs):
         myStatus = Status(name=new_status, taskObject=myTaskObject)
         myStatus.save()
 
-        #myTaskObject.new_status = None
-
-        # when an observation goes to valid, calculate its total size by counting its dataproducts
-        # if (myTaskObject.task_type == 'observation') and 'valid' in myTaskObject.new_status:
-        #    # calculate total size
-        #    dps = DataProduct.objects.filter(taskID=myTaskObject.taskID)
-        #    size = 0
-        #    for dp in dps:
-        #        size = size + dp.size
-        #
-        #    logger.info("total size of observation "+myTaskObject.taskID+ " = "+ str(size))
-        #    # nv:11jun2019: this requires a database change first
-        #    # myTaskObject.size = size
-
-        if (myTaskObject.task_type == 'observation'):
-                # convert the utc timestamp to a format that Django REST API understands
-                # in its GUI, otherwise null values will be put in when hitting PUT.
-                s,_ = str(myStatus.timestamp).split('.')
-                myTimestamp = datetime.datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
-
-                if 'starting' in myTaskObject.new_status:
-                    myTaskObject.timestamp_starting = myTimestamp
-                elif 'running' in myTaskObject.new_status:
-                    myTaskObject.timestamp_running = myTimestamp
-                elif 'completing' in myTaskObject.new_status:
-                    myTaskObject.timestamp_completing = myTimestamp
-                elif 'ingesting' in myTaskObject.new_status:
-                    myTaskObject.timestamp_ingesting = myTimestamp
-                elif 'archived' in myTaskObject.new_status:
-                    myTaskObject.timestamp_archived = myTimestamp
-                elif 'aborted' in myTaskObject.new_status:
-                    myTaskObject.timestamp_aborted = myTimestamp
-                elif 'ingest_error' in myTaskObject.new_status:
-                    myTaskObject.timestamp_ingest_error = myTimestamp
-
     # temporarily disconnect the post_save handler to save the dataproduct (again) and avoiding recursion.
     # I don't use pre_save, because then the 'created' key is not available, which is the most handy way to
     # determine if this dataproduct already exists. (I could also check the database, but this is easier).
@@ -117,12 +77,6 @@ def post_save_observation_handler(sender, **kwargs):
     handle_post_save(sender, **kwargs)
 
 
-@receiver(post_save, sender=DataProduct)
-def post_save_dataproduct_handler(sender, **kwargs):
-    #logger.info("SIGNAL : post_save DataProduct(" + str(kwargs.get('instance')) + ")")
-    handle_post_save(sender, **kwargs)
-
-
 def handle_post_save(sender, **kwargs):
     """
      pre_save handler for both Observation and Dataproduct. To create and write its initial status
@@ -132,7 +86,7 @@ def handle_post_save(sender, **kwargs):
     logger.info("handle_post_save("+str(kwargs.get('instance'))+")")
     myTaskObject = kwargs.get('instance')
 
-    # CREATE NEW OBSERVATION / DATAPRODUCT
+    # Create new task
     if kwargs['created']:
         logger.info("save new "+str(myTaskObject.task_type))
 
@@ -143,12 +97,6 @@ def handle_post_save(sender, **kwargs):
         myStatus = Status(name=myTaskObject.new_status, taskObject=myTaskObject)
         myStatus.save()
 
-    # if there already is an observation with this taskID, then add this dataproduct to it
-    if (myTaskObject.task_type == 'dataproduct'):
-        logger.info("update dataproduct parent = " + str(myTaskObject.taskID))
-        parent = Observation.objects.get(taskID=myTaskObject.taskID)
-        myTaskObject.parent=parent
-
     # temporarily disconnect the post_save handler to save the dataproduct (again) and avoiding recursion.
     # I don't use pre_save, because then the 'created' key is not available, which is the most handy way to
     # determine if this dataproduct already exists. (I could also check the database, but this is easier).
@@ -159,14 +107,9 @@ def handle_post_save(sender, **kwargs):
 def connect_signals():
     #logger.info("connect_signals")
     pre_save.connect(pre_save_observation_handler, sender=Observation)
-    pre_save.connect(pre_save_dataproduct_handler, sender=DataProduct)
     post_save.connect(post_save_observation_handler, sender=Observation)
-    post_save.connect(post_save_dataproduct_handler, sender=DataProduct)
-
 
 def disconnect_signals():
     #logger.info("disconnect_signals")
     pre_save.disconnect(pre_save_observation_handler, sender=Observation)
-    pre_save.disconnect(pre_save_dataproduct_handler, sender=DataProduct)
     post_save.disconnect(post_save_observation_handler, sender=Observation)
-    post_save.disconnect(post_save_dataproduct_handler, sender=DataProduct)
\ No newline at end of file
diff --git a/atdb/taskdatabase/templates/taskdatabase/index.html b/atdb/taskdatabase/templates/taskdatabase/index.html
index a209cb6970be9be68ab6ba12951a34a45eb57009..b55c96dbefe5b35c91b8a7cf3eeecce90acbe0e3 100644
--- a/atdb/taskdatabase/templates/taskdatabase/index.html
+++ b/atdb/taskdatabase/templates/taskdatabase/index.html
@@ -45,7 +45,7 @@
     </div>
     {% include 'taskdatabase/pagination.html' %}
 </div>
-    <p class="footer"> Version 1.0.0 (7 jan 2021 - 08:30)
+    <p class="footer"> Version 1.0.0 (14 jan 2021 - 11:30)
     <script type="text/javascript">
         (function(seconds) {
             var refresh,
diff --git a/atdb/taskdatabase/templates/taskdatabase/observations.html b/atdb/taskdatabase/templates/taskdatabase/observations.html
index 86d3f5e763e9237b99e7151752b4b2bf3a4a1092..a3bdc922371b3bf850faa19b228d7b1df25a958d 100644
--- a/atdb/taskdatabase/templates/taskdatabase/observations.html
+++ b/atdb/taskdatabase/templates/taskdatabase/observations.html
@@ -40,14 +40,6 @@
                 {% endif %}
             </td>
             <td>
-                {% if observation.my_status == "complete" %}
-                   <a href="{% url 'dataproducts-list-view' observation.taskID %}" class="btn btn-success btn-sm" role="button">DPS</a>
-                {% elif observation.my_status == "incomplete" or "error" in observation.my_status %}
-                   <a href="{% url 'dataproducts-list-view' observation.taskID %}" class="btn btn-danger btn-sm" role="button">DPS</a>
-                {% else %}
-                    <a href="{% url 'dataproducts-list-view' observation.taskID %}" class="btn btn-primary btn-sm" role="button">DPS</a>
-                {% endif %}
-
                 {% if observation.my_status == "ingesting" %}
                 <a href="https://alta.astron.nl/science/monitor" class="btn btn-primary btn-sm" target="_blank" role="button">Monitor</a>
                 {% endif %}
@@ -72,11 +64,6 @@
                     {% endif %}
                 {% endif %}
 
-                {% if observation.my_status == "incomplete" or observation.my_status == "defined" %}
-                   <a href="{% url 'observation-dps-setstatus-view' observation.pk 'valid' 'valid' my_observations.number %}" class="btn btn-success btn-sm" role="button">Validate DPS</a>
-                   <a href="{% url 'observation-dps-setstatus-view' observation.pk 'invalid' 'removed_invisible' my_observations.number %}" class="btn btn-danger btn-sm" role="button">Failed</a>
-                {% endif %}
-
                 {% if observation.my_status == "completed" or observation.my_status == "incomplete" %}
                    <a href="{% url 'observation-setstatus-view' observation.pk 'valid' my_observations.number %}" class="btn btn-primary btn-sm" role="button">Ready to Ingest</a>
                 {% endif %}
@@ -85,34 +72,16 @@
                    <a href="{% url 'observation-setstatus-view' observation.pk 'completing' my_observations.number %}" class="btn btn-success btn-sm" role="button">Completing</a>
                 {% endif %}
 
-                {% if observation.my_status == "ingest error" or observation.my_status == "ingest aborted" %}
-                   <a href="{% url 'observation-dps-setstatus-view' observation.pk 'defined' 'defined' my_observations.number %}" class="btn btn-primary btn-sm" role="button">Retry Ingest</a>
-                {% endif %}
-
-
-                {% if observation.my_status == "archived" or "error" in observation.my_status or "aborted" in observation.my_status or observation.my_status == "completed" or observation.my_status == "incomplete" %}
-                   <a href="{% url 'observation-dps-setstatus-view' observation.pk 'removing' 'removing' my_observations.number %}" class="btn btn-warning btn-sm" role="button">Remove Data</a>
-                {% endif %}
-
                 {% if observation.my_status == "valid" %}
                    <a href="{% url 'observation-setstatus-view' observation.pk 'valid_priority' my_observations.number %}" class="btn btn-warning btn-sm" role="button">Priority Ingest</a>
                    <a href="{% url 'observation-setstatus-view' observation.pk 'completed' my_observations.number %}" class="btn btn-primary btn-sm" role="button">Cancel Ingest</a>
                 {% endif %}
-                {% if user.is_authenticated %}
-                  {% if observation.my_status == "ingesting" %}
-                   <a href="{% url 'observation-dps-setstatus-view' observation.pk 'ingest aborted' 'ingest aborted' my_observations.number %}" class="btn btn-danger btn-sm" role="button">Abort Ingest</a>
-                  {% endif %}
-                {% endif %}
 
                 {% if observation.my_status == "valid_priority" %}
                    <a href="{% url 'observation-setstatus-view' observation.pk 'valid' my_observations.number %}" class="btn btn-primary btn-sm" role="button">Cancel Priority</a>
                    <a href="{% url 'observation-setstatus-view' observation.pk 'completed' my_observations.number %}" class="btn btn-primary btn-sm" role="button">Cancel Ingest</a>
                 {% endif %}
 
-                {% if observation.my_status == "incomplete" %}
-                   <a href="{% url 'observation-dps-setstatus-view' observation.pk 'defined' 'defined' my_observations.number %}" class="btn btn-danger btn-sm" role="button">Reset</a>
-                {% endif %}
-
                 {% if observation.my_status == "archived" %}
                     <a href="{% url 'observation-setquality-view' observation.pk 'data_is_good' my_observations.number %}" class="btn btn-success btn-sm" role="button">Data is Good</a>
                     <a href="{% url 'observation-setquality-view' observation.pk 'data_is_bad' my_observations.number %}" class="btn btn-danger btn-sm" role="button">Data is Bad</a>
@@ -123,9 +92,6 @@
                     <a href="{% url 'observation-setquality-view' observation.pk 'data_is_bad' my_observations.number %}" class="btn btn-danger btn-sm" role="button">Data is Bad</a>
                 {% endif %}
 
-                {% if observation.my_status == "removing" %}
-                   <a href="{% url 'observation-dps-setstatus-view' observation.pk 'incomplete' 'incomplete' my_observations.number %}" class="btn btn-danger btn-sm" role="button">Cancel and Pray</a>
-                {% endif %}
             </td>
             </tr>
         </div>
diff --git a/atdb/taskdatabase/urls.py b/atdb/taskdatabase/urls.py
index b57453258c62ef1b703f2ec42dcb1d22e531d407..1d62b4d684d2ae861cf6cea96cb4bc1cb6a54bdc 100644
--- a/atdb/taskdatabase/urls.py
+++ b/atdb/taskdatabase/urls.py
@@ -8,16 +8,7 @@ urlpatterns = [
     #path('', views.index, name='index'),
     path('', views.IndexView.as_view(), name='index'),
 
-    # ex: /atdb/task/180223003/
-    path('task/<taskID>/', views.DataProductsListView.as_view(), name='dataproducts-list-view'),
-
     # --- REST API ---
-    # ex: /atdb/dataproducts/
-    path('dataproducts/', views.DataProductListViewAPI.as_view()),
-
-    # ex: /atdb/dataproducts/5/
-    path('dataproducts/<int:pk>/', views.DataProductDetailsViewAPI.as_view(),name='dataproduct-detail-view-api'),
-
     # ex: /atdb/observations/
     path('observations/', views.ObservationListViewAPI.as_view()),
 
@@ -27,9 +18,6 @@ urlpatterns = [
     # ex: /atdb/observations/5/
     path('observations/<int:pk>/', views.ObservationDetailsViewAPI.as_view(),name='observation-detail-view-api'),
 
-    # ex: /atdb/status/
-    path('status/', views.StatusListViewAPI.as_view(),name='status-list-view-api'),
-
     # --- custom requests ---
     # ex: /atdb/get_next_taskid?timestamp=2019-04-05
     path('get_next_taskid',
@@ -41,21 +29,11 @@ urlpatterns = [
          views.GetNextObservationView.as_view(),
          name='get-next-observation-view'),
 
-    # ex: /atdb/post_dataproducts&taskid=190405034
-    path('post_dataproducts',
-         views.PostDataproductsView.as_view(),
-         name='post-dataproducts-view'),
-
     # --- controller resources ---
     path('observations/<int:pk>/setstatus/<new_status>/<page>',
          views.ObservationSetStatus,
          name='observation-setstatus-view'),
-    path('observations/<int:pk>/setstatus_dps/<new_dps_status>/<new_obs_status>/<page>',
-         views.ObservationSetStatusDataProducts,
-         name='observation-dps-setstatus-view'),
-    path('dataproducts/<int:pk>/setstatus/<new_status>',
-         views.DataProductSetStatusView,
-         name='dataproduct-setstatus-view'),
+
     # set the quality field to 'good' or 'bad' (and transmit it to ALTA)
     path('observations/<int:pk>/setquality/<quality>/<page>',
          views.ObservationSetQuality,
diff --git a/atdb/taskdatabase/views.py b/atdb/taskdatabase/views.py
index 0ef8ec318e366aa933c93b2128f7c5cb04b88127..641651897d2fb101aa40e0cf1395574517034c6d 100644
--- a/atdb/taskdatabase/views.py
+++ b/atdb/taskdatabase/views.py
@@ -13,9 +13,9 @@ from django.template import loader
 from django.shortcuts import render, redirect
 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
 
-from .models import DataProduct, Observation, Status
+from .models import Observation, Status
 from django.db.models import Q
-from .serializers import DataProductSerializer, ObservationSerializer, StatusSerializer
+from .serializers import ObservationSerializer, StatusSerializer
 from .forms import FilterForm
 
 from .services import algorithms
@@ -48,25 +48,6 @@ class ObservationFilter(filters.FilterSet):
             'quality': ['exact', 'icontains'],
         }
 
-# example: /atdb/dataproducts?status__in=created,archived
-class DataProductFilter(filters.FilterSet):
-
-    class Meta:
-        model = DataProduct
-
-        fields = {
-            'dataproduct_type': ['exact', 'in'],  # ../dataproducts?dataProductType=IMAGE,VISIBILITY
-            'description': ['exact', 'icontains'],
-            'name': ['exact', 'icontains'],
-            'filename': ['exact', 'icontains'],
-            'taskID': ['exact', 'icontains'],
-            'creationTime': ['gt', 'lt', 'gte', 'lte', 'contains', 'exact'],
-            'size': ['gt', 'lt', 'gte', 'lte', 'contains', 'exact'],
-            'parent__taskID': ['exact', 'in', 'icontains'],
-            'my_status': ['exact', 'icontains', 'in'],
-            'data_location': ['exact', 'icontains'],
-            'node': ['exact', 'in'],
-        }
 
 # example: has 1811130001 been on 'running?'
 # http://localhost:8000/atdb/status/?&taskID=181130001&name=running
@@ -175,61 +156,7 @@ def get_searched_observations(search):
     return observations
 
 
-# example: /atdb/task/180323003/
-# https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/
-# calling this view renders the dataproducts.html template in the GUI
-# a custom pagination class to return more than the default 100 dataproducts
-class DataProductsPagination(pagination.PageNumberPagination):
-    page_size = 10000
-
-class DataProductsListView(ListView):
-    model = DataProduct
-    context_object_name = 'my_dataproducts_list'
-    template_name = 'taskdatabase/dataproducts.html'
-    pagination_class = DataProductsPagination
-
-    # override get_queryset to make a custom query on taskid
-    def get_queryset(self):
-        logger.info("DataProductsListView.get_queryset()")
-        taskid = self.kwargs['taskID']
-        my_queryset = DataProduct.objects.filter(taskID=taskid)
-        logger.info("my_queryset retrieved")
-        return my_queryset
-
-
-
 # ---------- REST API views -----------
-# example: /atdb/status
-
-class StatusListViewAPI(generics.ListCreateAPIView):
-    model = Status
-    queryset = Status.objects.all()
-    serializer_class = StatusSerializer
-    pagination_class = DataProductsPagination
-
-    filter_backends = (filters.DjangoFilterBackend,)
-    filter_class = StatusFilter
-
-
-# example: /atdb/dataproducts/
-# calling this view serializes the dataproduct list in a REST API
-class DataProductListViewAPI(generics.ListCreateAPIView):
-    model = DataProduct
-    queryset = DataProduct.objects.all()
-    serializer_class = DataProductSerializer
-    pagination_class = DataProductsPagination
-
-    # using the Django Filter Backend - https://django-filter.readthedocs.io/en/latest/index.html
-    filter_backends = (filters.DjangoFilterBackend,)
-    filter_class = DataProductFilter
-
-
-# example: /atdb/dataproducts/5/
-# calling this view serializes a dataproduct in the REST API
-class DataProductDetailsViewAPI(generics.RetrieveUpdateDestroyAPIView):
-    model = DataProduct
-    queryset = DataProduct.objects.all()
-    serializer_class = DataProductSerializer
 
 
 # example: /atdb/observations/
@@ -324,23 +251,6 @@ def ObservationSetStatus(request,pk,new_status,page):
     return redirect('/atdb/?page='+page)
 
 
-# set the status of an observation and all its dataproducts to 'new_dps_status'
-# example: 'Validate DPS' button
-# /atdb/observations/<int:pk>/setstatus_dps/<new_dps_status>/<new_obs_status>/<page>
-def ObservationSetStatusDataProducts(request,pk,new_dps_status,new_obs_status,page):
-    model = Observation
-    observation = Observation.objects.get(pk=pk)
-    observation.new_status = new_obs_status
-    observation.save()
-    taskid = observation.taskID
-
-    dataproducts = DataProduct.objects.filter(taskID=taskid)
-    for dataproduct in dataproducts:
-        dataproduct.new_status = new_dps_status
-        dataproduct.save()
-
-    return redirect('/atdb/?page='+page)
-
 # set the datawriter to which the observation will write to.
 # /atdb/observations/<int:pk>/setdatawriter/<nr>/<page>
 def SetDatawriter(request,pk,datawriter,page):
@@ -360,27 +270,9 @@ def SetDatawriter(request,pk,datawriter,page):
     observation.save()
     taskid = observation.taskID
 
-    dataproducts = DataProduct.objects.filter(taskID=taskid)
-    for dataproduct in dataproducts:
-        dataproduct.data_location = new_data_location
-        dataproduct.save()
-
     return redirect('/atdb/?page='+page)
 
 
-# set the status of a dataproduct to 'new_status'
-# example: 'Validate', 'Skip' and 'Remove' buttons
-def DataProductSetStatusView(request,pk,new_status):
-    model = DataProduct
-    dataproduct = DataProduct.objects.get(pk=pk)
-    dataproduct.new_status = new_status
-    dataproduct.save()
-
-    taskid = dataproduct.taskID
-
-    return redirect('/atdb/task/'+taskid)
-
-
 # get the next taskid based on starttime and what is currently in the database
 #/atdb/get_next_taskid?timestamp=2019-04-05
 class GetNextTaskIDView(generics.ListAPIView):
@@ -444,26 +336,3 @@ class GetNextObservationView(generics.ListAPIView):
         })
 
 
-# add dataproducts as a batch
-# /atdb/post_dataproducts&taskid=190405034
-class PostDataproductsView(generics.CreateAPIView):
-    queryset = DataProduct.objects.all()
-    serializer_class = DataProductSerializer
-    pagination_class = DataProductsPagination
-
-    def post(self, request, *args, **kwargs):
-
-        try:
-            body_unicode = request.body.decode('utf-8')
-            dataproducts = json.loads(body_unicode)
-        except Exception as e:
-            print(e)
-            dataproducts = None
-
-        taskID = algorithms.add_dataproducts(dataproducts)
-
-        # return a response
-        return Response({
-            'taskID': taskID,
-        })
-