diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/openBIS-premise-imaging.jar b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/openBIS-premise-imaging.jar
index 45ead497c522efa717bddc73cad091ebc4377b20..9ce77c0ca4a5774a6b963fd3a2988ff084089a31 100644
Binary files a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/openBIS-premise-imaging.jar and b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/openBIS-premise-imaging.jar differ
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetConfig.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetConfig.java
similarity index 100%
rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetConfig.java
rename to core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetConfig.java
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControl.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControl.java
similarity index 76%
rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControl.java
rename to core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControl.java
index 676549859dcc0392372795bba39b12eafbd9d042..7d5c27fe9ce8562ced6418828f8734a80d90e365 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControl.java
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControl.java
@@ -33,6 +33,9 @@ public class ImagingDataSetControl implements Serializable
     @JsonProperty
     private String label;
 
+    @JsonProperty
+    private String section;
+
     @JsonProperty
     private String type;
 
@@ -40,7 +43,10 @@ public class ImagingDataSetControl implements Serializable
     private List<String> values;
 
     @JsonProperty
-    private List<Integer> range;
+    private String unit;
+
+    @JsonProperty
+    private List<String> range;
 
     @JsonProperty
     private boolean multiselect;
@@ -50,6 +56,8 @@ public class ImagingDataSetControl implements Serializable
 
     @JsonProperty
     private List<Integer> speeds;
+    @JsonProperty
+    private List<ImagingDataSetControlVisibility> visibility;
 
     @JsonProperty
     private Map<String, String> metaData;
@@ -65,6 +73,28 @@ public class ImagingDataSetControl implements Serializable
         this.label = label;
     }
 
+    @JsonIgnore
+    public String getSection()
+    {
+        return section;
+    }
+
+    public void setSection(String section)
+    {
+        this.section = section;
+    }
+
+    @JsonIgnore
+    public String getUnit()
+    {
+        return unit;
+    }
+
+    public void setUnit(String unit)
+    {
+        this.unit = unit;
+    }
+
     @JsonIgnore
     public String getType()
     {
@@ -121,16 +151,28 @@ public class ImagingDataSetControl implements Serializable
     }
 
     @JsonIgnore
-    public List<Integer> getRange()
+    public List<String> getRange()
     {
         return range;
     }
 
-    public void setRange(List<Integer> range)
+    public void setRange(List<String> range)
     {
         this.range = range;
     }
 
+    @JsonIgnore
+    public List<ImagingDataSetControlVisibility> getVisibility()
+    {
+        return visibility;
+    }
+
+    public void setVisibility(
+            List<ImagingDataSetControlVisibility> visibility)
+    {
+        this.visibility = visibility;
+    }
+
     @JsonIgnore
     public Map<String, String> getMetaData()
     {
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControlVisibility.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControlVisibility.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a364ad0745a2c5f8205090e428b27662bbaa792
--- /dev/null
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetControlVisibility.java
@@ -0,0 +1,88 @@
+/*
+ *  Copyright ETH 2023 Zürich, Scientific IT Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package ch.ethz.sis.openbis.generic.dssapi.v3.dto.imaging;
+
+import ch.systemsx.cisd.base.annotation.JsonObject;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+@JsonObject("dss.dto.imaging.ImagingDataSetControlVisibility")
+public class ImagingDataSetControlVisibility implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    @JsonProperty
+    private String label;
+    @JsonProperty
+    private List<String> values;
+    @JsonProperty
+    private List<String> range;
+    @JsonProperty
+    private String unit;
+
+    @JsonIgnore
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public void setLabel(String label)
+    {
+        this.label = label;
+    }
+    @JsonIgnore
+    public List<String> getValues()
+    {
+        return values;
+    }
+
+    public void setValues(List<String> values)
+    {
+        this.values = values;
+    }
+    @JsonIgnore
+    public List<String> getRange()
+    {
+        return range;
+    }
+
+    public void setRange(List<String> range)
+    {
+        this.range = range;
+    }
+
+    @JsonIgnore
+    public String getUnit()
+    {
+        return unit;
+    }
+
+    public void setUnit(String unit)
+    {
+        this.unit = unit;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "ImagingDataSetControlVisibility: " + label;
+    }
+}
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetExport.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetExport.java
similarity index 100%
rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetExport.java
rename to core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetExport.java
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetImage.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetImage.java
similarity index 100%
rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetImage.java
rename to core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetImage.java
diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetPreview.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetPreview.java
similarity index 100%
rename from api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetPreview.java
rename to core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetPreview.java
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetPropertyConfig.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetPropertyConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b9d9b71eb00bd109bb61218469ab131e72cc009
--- /dev/null
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/imaging/ImagingDataSetPropertyConfig.java
@@ -0,0 +1,62 @@
+/*
+ *  Copyright ETH 2023 Zürich, Scientific IT Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package ch.ethz.sis.openbis.generic.dssapi.v3.dto.imaging;
+
+import ch.systemsx.cisd.base.annotation.JsonObject;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+@JsonObject("dss.dto.imaging.ImagingDataSetPropertyConfig")
+public class ImagingDataSetPropertyConfig implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    @JsonProperty
+    ImagingDataSetConfig config;
+
+    @JsonProperty
+    List<ImagingDataSetImage> images;
+
+    @JsonIgnore
+    public ImagingDataSetConfig getConfig()
+    {
+        return config;
+    }
+
+    public void setConfig(ImagingDataSetConfig config)
+    {
+        this.config = config;
+    }
+
+    @JsonIgnore
+    public List<ImagingDataSetImage> getImages()
+    {
+        return images;
+    }
+
+    public void setImages(
+            List<ImagingDataSetImage> images)
+    {
+        this.images = images;
+    }
+
+
+}
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/ImagingService.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/ImagingService.java
index b0cdb230c587d8ccb5d4899d9728cd0a9640dad1..0beb0960aee4891de964cd7913f3adde04aabff7 100644
--- a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/ImagingService.java
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/ImagingService.java
@@ -25,6 +25,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
 import ch.ethz.sis.openbis.generic.dssapi.v3.IDataStoreServerApi;
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.imaging.ImagingDataSetConfig;
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.imaging.ImagingDataSetImage;
+import ch.ethz.sis.openbis.generic.dssapi.v3.dto.imaging.ImagingDataSetPropertyConfig;
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.service.CustomDSSServiceExecutionOptions;
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.service.id.ICustomDSSServiceId;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.imaging.adaptor.IImagingDataSetAdaptor;
@@ -44,6 +45,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
 import ch.systemsx.cisd.openbis.generic.shared.dto.OpenBISSessionHolder;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import org.apache.log4j.Logger;
@@ -63,21 +65,17 @@ public class ImagingService implements ICustomDSSServiceExecutor
     private static final Logger
             operationLog = LogFactory.getLogger(LogCategory.OPERATION, ImagingService.class);
 
-    private static final String SCRIPT_PATH = "script-path";
-
-    private String scriptPath;
 
     public ImagingService(Properties properties)
     {
         this.properties = properties;
-        this.scriptPath = PropertyUtils.getProperty(properties, SCRIPT_PATH);
     }
 
     @Override
     public Serializable executeService(String sessionToken, ICustomDSSServiceId serviceId,
             CustomDSSServiceExecutionOptions options)
     {
-        operationLog.info("Executing service:" + serviceId);
+        operationLog.info("Executing imaging service:" + serviceId);
         ImagingDataContainer data = getDataFromParams(options.getParameters());
         try
         {
@@ -100,14 +98,21 @@ public class ImagingService implements ICustomDSSServiceExecutor
     {
         DataSet dataSet = getDataSet(sessionToken, data);
 
-        Config config =
-                readConfig(dataSet.getJsonProperty("$IMAGING_DATA_CONFIG"), Config.class);
-        final String adaptorName = config.config.getAdaptor();
+        ImagingDataSetPropertyConfig config =
+                readConfig(dataSet.getJsonProperty("$IMAGING_DATA_CONFIG"), ImagingDataSetPropertyConfig.class);
+        final String adaptorName = config.getConfig().getAdaptor();
 
-        IImagingDataSetAdaptor
-                adaptor =
-                ClassUtils.create(IImagingDataSetAdaptor.class, adaptorName, properties);
+        if(adaptorName == null || adaptorName.isBlank()) {
+            throw new UserFailureException("Adaptor name is missing from the config!");
+        }
 
+        IImagingDataSetAdaptor adaptor = null;
+        try
+        {
+            adaptor = ClassUtils.create(IImagingDataSetAdaptor.class, adaptorName, properties);
+        } catch(Exception e) {
+            throw new UserFailureException("Could not load adapter: " + adaptorName, e);
+        }
         IHierarchicalContent content =
                 getHierarchicalContentProvider(sessionToken).asContent(
                         dataSet.getPermId().getPermId());
@@ -116,12 +121,13 @@ public class ImagingService implements ICustomDSSServiceExecutor
         File rootFile = root.getFile();
         Map<String, Serializable> previewParams = data.getPreview().getConfig();
         Map<String, String> meta = data.getPreview().getMetaData();
+        String format = data.getPreview().getFormat();
 
         ImagingServiceContext context = new ImagingServiceContext(sessionToken, getApplicationServerApi(), getDataStoreServerApi());
 
         data.getPreview().setBytes(
                 adaptor.process(context,
-                        rootFile, previewParams, meta).toString());
+                        rootFile, previewParams, meta, format).toString());
         return data;
     }
 
@@ -175,6 +181,8 @@ public class ImagingService implements ICustomDSSServiceExecutor
             ObjectMapper objectMapper = getObjectMapper();
             return objectMapper.readValue(new ByteArrayInputStream(val.getBytes()),
                     clazz);
+        } catch (JsonMappingException mappingException) {
+            throw new UserFailureException(mappingException.toString(), mappingException);
         } catch (Exception e)
         {
             throw new UserFailureException("Could not read the parameters!", e);
@@ -210,38 +218,6 @@ public class ImagingService implements ICustomDSSServiceExecutor
         return result.get(new DataSetPermId(data.getPermId()));
     }
 
-    public static final class Config
-    {
-        @JsonProperty
-        ImagingDataSetConfig config;
-
-        @JsonProperty
-        List<ImagingDataSetImage> images;
-
-        @JsonIgnore
-        public ImagingDataSetConfig getConfig()
-        {
-            return config;
-        }
-
-        public void setConfig(ImagingDataSetConfig config)
-        {
-            this.config = config;
-        }
-
-        @JsonIgnore
-        public List<ImagingDataSetImage> getImages()
-        {
-            return images;
-        }
-
-        public void setImages(
-                List<ImagingDataSetImage> images)
-        {
-            this.images = images;
-        }
-    }
-
     private void validateInputParams(Map<String, Object> params)
     {
         if (!params.containsKey("permId"))
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/IImagingDataSetAdaptor.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/IImagingDataSetAdaptor.java
index 2208100f55030e56f3c270fd8413113e4f836608..ea3b5ad6e14376c8023db65c17afb38b25bd6ce7 100644
--- a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/IImagingDataSetAdaptor.java
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/IImagingDataSetAdaptor.java
@@ -25,6 +25,7 @@ import java.util.Map;
 
 public interface IImagingDataSetAdaptor
 {
-    Serializable process(ImagingServiceContext context, File rootFile, Map<String, Serializable> previewConfig, Map<String, String> metaData);
+    Serializable process(ImagingServiceContext context, File rootFile,
+            Map<String, Serializable> previewConfig, Map<String, String> metaData, String format);
 
 }
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetExampleAdaptor.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetExampleAdaptor.java
index c9385c3da83376533a5a3ddaee77c7709efa23b4..e553d1382d09354f6f82fbe4fd8b8341a7b2403d 100644
--- a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetExampleAdaptor.java
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetExampleAdaptor.java
@@ -38,7 +38,8 @@ public final class ImagingDataSetExampleAdaptor implements IImagingDataSetAdapto
     }
 
     @Override
-    public Serializable process(ImagingServiceContext context, File rootFile, Map<String, Serializable> previewConfig, Map<String, String> metaData)
+    public Serializable process(ImagingServiceContext context, File rootFile,
+            Map<String, Serializable> previewConfig, Map<String, String> metaData, String format)
     {
         BufferedImage img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
         for(int y=0;y<HEIGHT; y++)
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetJythonAdaptor.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetJythonAdaptor.java
index 60476537ca1c3e14a3d387381f81e5468351a0aa..51e5043ba32212f9b7e15a49cf35758776af7552 100644
--- a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetJythonAdaptor.java
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetJythonAdaptor.java
@@ -40,7 +40,8 @@ public class ImagingDataSetJythonAdaptor implements IImagingDataSetAdaptor
         }
     }
     @Override
-    public Serializable process(ImagingServiceContext context, File rootFile, Map<String, Serializable> previewConfig, Map<String, String> metaData)
+    public Serializable process(ImagingServiceContext context, File rootFile,
+            Map<String, Serializable> previewConfig, Map<String, String> metaData, String format)
     {
         CustomDSSServiceExecutionOptions options = new CustomDSSServiceExecutionOptions();
         options.withParameter("sessionToken", context.getSessionToken());
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetPythonAdaptor.java b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetPythonAdaptor.java
index 2720f7fc6a2736455a40f03d4bab4e12fe9e4f01..8c720261064f4fb676f5b798e79e0b274e026fa8 100644
--- a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetPythonAdaptor.java
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/lib/premise-sources/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/imaging/adaptor/ImagingDataSetPythonAdaptor.java
@@ -38,11 +38,11 @@ public abstract class ImagingDataSetPythonAdaptor implements IImagingDataSetAdap
 
     @Override
     public Serializable process(ImagingServiceContext context, File rootFile,
-            Map<String, Serializable> previewConfig, Map<String, String> metaData)
+            Map<String, Serializable> previewConfig, Map<String, String> metaData, String format)
     {
 
         ProcessBuilder processBuilder = new ProcessBuilder(pythonPath,
-                scriptPath, rootFile.getAbsolutePath(), convertMapToJson(previewConfig), convertMapToJson(metaData));
+                scriptPath, rootFile.getAbsolutePath(), convertMapToJson(previewConfig), convertMapToJson(metaData), format);
         processBuilder.redirectErrorStream(false);
 
         String fullOutput;
@@ -63,9 +63,6 @@ public abstract class ImagingDataSetPythonAdaptor implements IImagingDataSetAdap
         }
 
         String[] resultSplit = fullOutput.split("\n");
-//        for(int i=0;i< resultSplit.length;i++) {
-//            System.out.println("||> " + resultSplit[i].substring(0, Math.min(resultSplit[i].length(), 1000)));
-//        }
         return resultSplit[resultSplit.length-1];
     }
 
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/nanonis_dat.py b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/nanonis_dat.py
index d30b24bca91bb1797072382b776bb9b625e0396a..ef2acb909668703176d5f4856f21aba2b86700e5 100644
--- a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/nanonis_dat.py
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/nanonis_dat.py
@@ -8,6 +8,7 @@ import os
 import sys
 from spmpy_terry import spm   # <--- class spm defines objects of type spm with their attributes and class functions
 import spmpy_terry as spmpy   # <--- spmpy has other methods
+from datetime import datetime
 
 import matplotlib.pyplot as plt
 # %matplotlib inline
@@ -32,6 +33,7 @@ def get_channel(img, channel_name = 'z'):
 file = sys.argv[1]
 params = json.loads(sys.argv[2])
 meta_data = json.loads(sys.argv[3])
+format = sys.argv[4]
 
 
 folder_dir = os.path.join(file, 'original')
@@ -43,43 +45,56 @@ def generate_random_image(height, width):
     imarray = numpy.random.rand(height,width,3) * 255
     im = Image.fromarray(imarray.astype('uint8')).convert('RGBA')
     img_byte_arr = io.BytesIO()
-    im.save(img_byte_arr, format='PNG')
+    im.save(img_byte_arr, format=format)
     img_byte_arr = img_byte_arr.getvalue()
     encoded = base64.b64encode(img_byte_arr)
     return encoded
 
 
-def get_sxm_image():
-    img = load_image(file_path)
-    channel = get_channel(img, 'z')
-    img_byte_arr = io.BytesIO()
-    plt.imshow(channel[0])
-    plt.savefig(img_byte_arr, format="png")
-    # print(img.header)
-    img_byte_arr = img_byte_arr.getvalue()
-    encoded = base64.b64encode(img_byte_arr)
-    return encoded
+def get_dat_image(channel_x, channel_y, x_axis, y_axis, colormap, scaling, grouping, print_legend):
+    specs = spmpy.importall(folder_dir, '', 'spec')
 
+    for spec in specs:
+        date_time = spec.get_param('Saved Date')
+        spec.date_time = datetime.strptime(date_time, "%d.%m.%Y %H:%M:%S")
 
-def get_sxm_image2():
-    img = load_image(file_path)
-    channel = get_channel(img, 'z')[0]
+    # sort measurements according to date
+    specs.sort(key=lambda d: d.date_time)
+    specs_sub = list(filter(lambda spec:spec.name in grouping, specs))
 
-    min_val = numpy.min(channel)
-    max_val = numpy.max(channel)
-    scaled_data = (channel - min_val) / (max_val - min_val)
-    img = Image.fromarray(numpy.uint8(scaled_data * 255), 'L')
+    print_legend = print_legend
+    show = False
+    fig = spmpy.specs_plot(specs_sub, channelx=channel_x, channely=channel_y, direction='forward',
+                           print_legend=print_legend, show=show, colormap=colormap, scaling=scaling,
+                           x_axis=x_axis, y_axis=y_axis)
 
     img_byte_arr = io.BytesIO()
-    img.save(img_byte_arr, format='PNG')
+    plt.savefig(img_byte_arr, format=format)
     img_byte_arr = img_byte_arr.getvalue()
     encoded = base64.b64encode(img_byte_arr)
     return encoded
 
+
+
+
+
 print(params)
 if params['mode'] == '1':
-    print(get_sxm_image())
+    print(generate_random_image(640, 640))
 elif params['mode'] == '2':
-    print(get_sxm_image2())
-elif params['mode'] == '3':
-    print(generate_random_image(640, 640))
\ No newline at end of file
+    parameters = dict(
+        channel_x=params['channel x'],
+        channel_y=params['channel y'],
+        x_axis=[float(x) for x in params['x-axis']],
+        y_axis=[float(x) for x in params['y-axis']],
+        colormap=params['colormap'],
+        scaling=params['scaling'],
+        grouping=params['grouping']
+    )
+    if "color" in params:
+        parameters['color'] = params['color']
+    if "print_legend" in params:
+        parameters['print_legend'] = params['print_legend'].upper() == "TRUE"
+    else:
+        parameters['print_legend'] = True
+    print(get_dat_image(**parameters))
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/nanonis_sxm.py b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/nanonis_sxm.py
index f8e912b6018491fbea9d2b912c4281e69dc1d223..0863f13fbd4e7106b2eb2c37042e881317458fd9 100644
--- a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/nanonis_sxm.py
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/nanonis_sxm.py
@@ -34,10 +34,11 @@ def get_channel(img, channel_name = 'z'):
     channel = img.get_channel(channel_name)
     return channel
 
-
+print("SYS.ARGV:" + str(sys.argv))
 file = sys.argv[1]
 params = json.loads(sys.argv[2])
 meta_data = json.loads(sys.argv[3])
+format = sys.argv[4]
 
 
 folder_dir = os.path.join(file, 'original')
@@ -65,8 +66,8 @@ def get_sxm_image():
     fig = img.plot(show=False, show_params=False)
     fig.frameon=False
     # plt.title(None)
-    plt.axis('off')
-    plt.savefig(img_byte_arr, format="png", bbox_inches='tight')
+    # plt.axis('off')
+    plt.savefig(img_byte_arr, format=format)
 
     # print(img.header)
     img_byte_arr = img_byte_arr.getvalue()
@@ -91,7 +92,7 @@ def get_sxm_image2():
     img = Image.fromarray(numpy.uint8(scaled_data * 255), 'L')
 
     img_byte_arr = io.BytesIO()
-    img.save(img_byte_arr, format='PNG')
+    img.save(img_byte_arr, format=format)
     img_byte_arr = img_byte_arr.getvalue()
     encoded = base64.b64encode(img_byte_arr)
 
@@ -104,6 +105,62 @@ def get_sxm_image2():
 
     return encoded
 
+
+def get_sxm_image3(channel_name, scaling, color_scale):
+    img = load_image(file_path)
+    # channel = get_channel(img, channel_name)
+    img_byte_arr = io.BytesIO()
+
+    log = False
+    if scaling == 'logarithmic':
+        log = True
+    fig = img.plot(show=False, show_params=False, hide=True, channel=channel_name, log=log)
+    fig.frameon=False
+    # plt.title('None')
+    plt.axis('off')
+    plt.savefig(img_byte_arr, format="png", bbox_inches='tight')
+
+    pilImg = Image.open(img_byte_arr)
+    print(f"SIZE={pilImg.size}")
+    im2 = pilImg.crop(pilImg.getbbox())
+    print(f"SIZE={im2.size}")
+    img_byte_arr = io.BytesIO()
+    im2.save(img_byte_arr, format='PNG')
+
+    # print(img.header)
+    img_byte_arr = img_byte_arr.getvalue()
+    encoded = base64.b64encode(img_byte_arr)
+    print_params = img.print_params(show=False).split('\n')
+    print_params = {x: y for x, y in (s.split(':') for s in print_params)}
+    print_params = json.dumps(print_params)
+    print(f'PARAMS={print_params}')
+    header = json.dumps(img.header, cls=NumpyEncoder)
+    print(f'HEADER={header}')
+
+    return encoded
+
+def get_sxm_image4(channel_name, x_axis, y_axis, scaling, color_scale, colormap, colormap_scaling):
+    img = load_image(file_path)
+    img_byte_arr = io.BytesIO()
+
+    log = False
+    if scaling == 'logarithmic':
+        log = True
+    fig = img.plot(show=False, show_params=False, channel=channel_name, log=log, cmap=colormap,
+                   color_scale=color_scale, x_axis=x_axis, y_axis=y_axis, colormap_scaling=colormap_scaling)
+    plt.savefig(img_byte_arr, format=format)
+
+    img_byte_arr = img_byte_arr.getvalue()
+    encoded = base64.b64encode(img_byte_arr)
+    print_params = img.print_params(show=False).split('\n')
+    print_params = {x: y for x, y in (s.split(':') for s in print_params)}
+    print_params = json.dumps(print_params)
+    print(f'PARAMS={print_params}')
+    header = json.dumps(img.header, cls=NumpyEncoder)
+    print(f'HEADER={header}')
+
+    return encoded
+
 print(params)
 if params['mode'] == '1':
     # print(f'IMG={get_sxm_image()}')
@@ -113,4 +170,20 @@ elif params['mode'] == '2':
     print(f'{get_sxm_image2()}')
 elif params['mode'] == '3':
     # print(f'IMG={generate_random_image(320, 320)}')
-    print(f'{generate_random_image(256, 256)}')
\ No newline at end of file
+    print(f'{generate_random_image(256, 256)}')
+elif params['mode'] == '4':
+    channel = params['channel']
+    scaling = params['scaling']
+    color_scale = [float(x) for x in params['color-scale']]
+    print(f'{get_sxm_image3(channel, scaling, color_scale)}')
+elif params['mode'] == '5':
+    channel = params['channel']
+    x_axis = [float(x) for x in params['x-axis']]
+    y_axis = [float(x) for x in params['y-axis']]
+    color_scale = [float(x) for x in params['color-scale']]
+    colormap = params['colormap']
+    scaling = params['scaling']
+    colormap_scaling = False
+    if "colormap_scaling" in params:
+        colormap_scaling = params['colormap_scaling'].upper() == "TRUE"
+    print(f'{get_sxm_image4(channel, x_axis, y_axis, scaling, color_scale, colormap, colormap_scaling)}')
\ No newline at end of file
diff --git a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/spmpy_terry.py b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/spmpy_terry.py
index 937ca5fc2779fda4d8408fe12f6aabb714a279da..57702f4aef451c718be269e712179144f2ec8499 100644
--- a/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/spmpy_terry.py
+++ b/core-plugin-openbis/dist/core-plugins/imaging/1/dss/custom-services/imaging/spmpy_terry.py
@@ -332,11 +332,38 @@ class spm:
                 show_params = params['show_params']
             else:
                 show_params = False
-                
+
             if 'show' in params:
                 show = params['show']
             else:
                 show = True
+
+            # PREMISE - specific params
+
+            if 'hide' in params:
+                hide = params['hide']
+            else:
+                hide = False
+
+            if 'color_scale' in params:
+                color_scale = params['color_scale']
+            else:
+                color_scale = False
+
+            if 'x_axis' in params:
+                x_axis = params['x_axis']
+            else:
+                x_axis = False
+
+            if 'y_axis' in params:
+                y_axis = params['y_axis']
+            else:
+                y_axis = False
+
+            if 'colormap_scaling' in params:
+                colormap_scaling = params['colormap_scaling']
+            else:
+                colormap_scaling = False
                 
                 
             
@@ -348,41 +375,83 @@ class spm:
             width = self.get_param('width')
             height = self.get_param('height')
             pix_y,pix_x = np.shape(chData)
-            
+
+            # fig = plt.figure(figsize=(6, 4))
             fig = plt.figure()#figsize=(6,4))
-            
+
             
             ImgOrigin = 'lower'
             if self.get_param('scan_dir') == 'down':
                 ImgOrigin = 'upper'
-            
-            
+
+            if color_scale:
+                chData = np.clip(chData, color_scale[0], color_scale[1])
+
+            if x_axis and y_axis:
+                plt.ylim(y_axis[0], y_axis[1])
+                plt.xlim(x_axis[0], x_axis[1])
+                # plt.axis([x_axis[0], x_axis[1], y_axis[0], y_axis[1]])
+
+            plot_params = dict(
+                X = np.abs(chData) if log else chData,
+                aspect = 'equal',
+                extent = [0,width[0],0,height[0]],
+                cmap = cmap,
+                origin = ImgOrigin,
+                interpolation = 'none'
+            )
             if log:
-                im = plt.imshow(np.abs(chData), aspect = 'equal', extent = [0,width[0],0,height[0]], cmap = cmap, norm=LogNorm(), origin = ImgOrigin)
-            else:
-                im = plt.imshow(chData, aspect = 'equal',extent = [0,width[0],0,height[0]], cmap = cmap, origin = ImgOrigin)
+                plot_params['norm'] = LogNorm()
+
+            if colormap_scaling:
+                min_x = x_axis[0]
+                max_x = x_axis[1]
+                min_y = y_axis[0]
+                max_y = y_axis[1]
+
+                shape = chData.shape
+                minx = int(np.floor(shape[0] * min_x / width[0]))
+                maxx = int(np.ceil(shape[0] * max_x / width[0]))
+                miny = int(np.floor(shape[1] * min_y / height[0]))
+                maxy = int(np.ceil(shape[1] * max_y / height[0]))
+
+                mini = np.min(chData[minx:maxx, miny:maxy])
+                maxi = np.max(chData[minx:maxx, miny:maxy])
+
+                mini = int(mini*100)/100
+                maxi = int(maxi*100)/100
+                plot_params['vmin'] = mini
+                plot_params['vmax'] = maxi
+
+            im = plt.imshow(**plot_params)
+
+            # if log:
+            #     im = plt.imshow(np.abs(chData), aspect = 'equal', extent = [0,width[0],0,height[0]], cmap = cmap, norm=LogNorm(), origin = ImgOrigin)
+            # else:
+            #     im = plt.imshow(chData, aspect = 'equal',extent = [0,width[0],0,height[0]], cmap = cmap, origin = ImgOrigin)
             
             
             if clim:
                 plt.clim(clim)
                 
             
-            im.axes.set_xticks([0,width[0]])
-            im.axes.set_xticklabels([0,np.round(width[0],2)])
-            im.axes.set_yticks([0,height[0]])
-            im.axes.set_yticklabels([0,np.round(height[0],2)])
+            # im.axes.set_xticks([0,width[0]])
+            # im.axes.set_xticklabels([0,np.round(width[0],2)])
+            # im.axes.set_yticks([0,height[0]])
+            # im.axes.set_yticklabels([0,np.round(height[0],2)])
             
             if show_params:
                 title = self.print_params(show = False);
             else:
                 title = self.path  
-                
-            # plt.title(title + '\n', loc='left')
-            # plt.xlabel('x (%s)' % width[1])
-            # plt.ylabel('y (%s)' % height[1])
-            
-            # cbar = plt.colorbar(im,fraction=0.046, pad=0.02, format='%.2g',shrink = 0.5,aspect=10)
-            # cbar.set_label('%s (%s)' % (channel,chUnit))
+
+            if not hide:
+                # plt.title(title + '\n', loc='left')
+                plt.xlabel('x (%s)' % width[1])
+                plt.ylabel('y (%s)' % height[1])
+                print(f'AXES={im.axes}')
+                cbar = plt.colorbar(im)#,fraction=0.046, pad=0.02, format='%.2g',shrink = 0.5,aspect=10)
+                cbar.set_label('channel:%s (%s)' % (channel,chUnit))
             
             if show:
                 plt.show()
@@ -561,17 +630,61 @@ def specs_plot(specs,**params):
     else:
         offset = 0
 
-    
+    # PREMISE specific
+    if 'show' in params:
+        show = params['show']
+    else:
+        show = True
+
+    if 'colormap' in params:
+        colormap = params['colormap']
+        cmap = plt.get_cmap(colormap)
+        color = cmap(np.linspace(0,1,len(specs)))
+    else:
+        colormap = False
+
+    if 'scaling' in params:
+        scaling = params['scaling']
+    else:
+        scaling = False
+
+    if 'x_axis' in params:
+        x_axis = params['x_axis']
+    else:
+        x_axis = False
+
+    if 'y_axis' in params:
+        y_axis = params['y_axis']
+    else:
+        y_axis = False
+    #######
+
     fig = plt.figure(figsize=(6,4))
 
     counter = 0
-    for (s,c) in zip(specs,color):
-        
-        (x_data,x_unit) = s.get_channel(channelx,direction=direction)
-        (y_data,y_unit) = s.get_channel(channely,direction=direction)
+    for (s, c) in zip(specs, color):
         
-        
-        plt.plot(x_data,y_data+counter*offset,color = c,label = s.name)
+        (x_data, x_unit) = s.get_channel(channelx, direction=direction)
+        if x_axis:
+            x_data = np.clip(x_data, x_axis[0], x_axis[1])
+
+        (y_data, y_unit) = s.get_channel(channely, direction=direction)
+        if y_axis:
+            y_data = np.clip(y_data, y_axis[0], y_axis[1])
+
+        if scaling:
+            if scaling == 'lin-lin':
+                plt.plot(x_data, y_data, color=c, label=s.name)
+            elif scaling == "lin-log":
+                plt.semilogy(x_data, np.abs(y_data), color=c, label=s.name)
+            elif scaling == 'log-lin':
+                plt.semilogx(np.abs(x_data), y_data, color=c, label=s.name)
+            elif scaling == 'log-log':
+                plt.loglog(np.abs(x_data), np.abs(y_data), color=c, label=s.name)
+            else:
+                plt.plot(x_data, y_data, color=c, label=s.name)
+        else:
+            plt.plot(x_data,y_data+counter*offset,color = c,label = s.name)
         counter = counter + 1
     
     plt.xlabel('%s (%s)' % (channelx,x_unit))
@@ -579,8 +692,9 @@ def specs_plot(specs,**params):
     
     if print_legend:
         plt.legend()
-    
-    plt.show()
+
+    if show:
+        plt.show()
     
     return fig