diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2383cdc4ad72892a589501889f0615152d52ec22..ed252ac9de47b913582dff7294f4e57ca3cb443b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,7 @@ if(BUILD_TESTING)
   comin_test_add_plugin(TEST catalyst_test
     NAME "catalyst_adapter"
     PLUGIN_LIBRARY "$<TARGET_FILE:catalyst_adapter>"
-    OPTIONS "/home/nils/projects/comin/catalyst_adaptor/LiveOnly.py"
+    OPTIONS "/home/nils/projects/comin/catalyst_adaptor/pvExample.py"
+    #   OPTIONS "/home/nils/projects/comin/catalyst_adaptor/gridwriter.py"
   )
 endif()
diff --git a/catalyst_adapter.cpp b/catalyst_adapter.cpp
index 856ce20f345030444a301e143ccf430cde5e51c9..ec410eba9b404eb384a96c14a7dabe6b8f928f94 100644
--- a/catalyst_adapter.cpp
+++ b/catalyst_adapter.cpp
@@ -1,15 +1,17 @@
 #include <iostream>
 #include <vector>
+#include<unistd.h>
 
 #include <comin.h>
 #include <catalyst.hpp>
 
-#include "parse_isotime.hpp"
-
 int ierr = COMIN_SUCCESS;
+void catalyst_adapter_secondary_constructor();
 void catalyst_adapter_execute();
 void catalyst_adapter_destruct();
 
+static conduit_cpp::Node catalyst_exec_params;
+
 extern "C"{ // avoid name-mangling
   void comin_main(){
     conduit_cpp::Node catalyst_init_params;
@@ -32,26 +34,15 @@ extern "C"{ // avoid name-mangling
     }
     about_node.print();
 
+    comin_callback_register(EP_SECONDARY_CONSTRUCTOR, catalyst_adapter_secondary_constructor, &ierr);
     comin_callback_register(EP_ATM_WRITE_OUTPUT_BEFORE, catalyst_adapter_execute, &ierr);
     comin_callback_register(EP_DESTRUCTOR, catalyst_adapter_destruct, &ierr);
   }
 }
 
-void catalyst_adapter_execute(){
-  conduit_cpp::Node catalyst_exec_params;
-
-  static int64_t cycle = 0;
-  catalyst_exec_params["catalyst/state/cycle"] = cycle;
-  cycle++;
-
-  const char* datetime_ptr = NULL;
-  int datetime_len = 0;
-  comin_current_get_datetime(&datetime_ptr, &datetime_len, &ierr);
-
-  auto t = parse_isotime(std::string(datetime_ptr, datetime_len));
-  double time = std::chrono::duration_cast<std::chrono::seconds>(t.time_since_epoch()).count();
-  catalyst_exec_params["catalyst/state/time"] = time;
+void catalyst_adapter_secondary_constructor(){
 
+  // prepare the execute node
   for(int jg = 1; jg<=comin_descrdata_get_global_n_dom(); ++jg){
     std::cout << "dom: " << jg << std::endl;
     auto channel = catalyst_exec_params[std::string("catalyst/channels/domain")+std::to_string(jg)];
@@ -88,21 +79,40 @@ void catalyst_adapter_execute(){
     }
     channel["data/topologies/mesh/elements/connectivity"].set(vidx);
 
-    // dummy field
-    channel["data/fields/foo/association"] = "element";
-    channel["data/fields/foo/topology"] = "mesh";
-    channel["data/fields/foo/volume_dependend"] = false;
-    channel["data/fields/foo/values"].set(std::vector<double>(ncells, 42.0));
+    for(void* it = comin_var_get_descr_list_head();
+        it != nullptr;
+        it = comin_var_get_descr_list_next(it)){
+      t_comin_var_descriptor var_desc;
+      comin_var_get_descr_list_var_desc(it, &var_desc, &ierr);
+      int zaxis_id = -1;
+      comin_metadata_get_integer(var_desc, "zaxis_id", &zaxis_id, &ierr);
+      if(var_desc.id == jg &&
+         zaxis_id == COMIN_ZAXIS_2D){
+        channel["data/fields/" + std::string(var_desc.name) + "/association"] = "element";
+        channel["data/fields/" + std::string(var_desc.name) + "/topology"] = "mesh";
+        channel["data/fields/" + std::string(var_desc.name) + "/volume_dependend"] = false;
+        int ep = EP_ATM_WRITE_OUTPUT_BEFORE;
+        void* handle = comin_var_get(1, &ep, var_desc, COMIN_FLAG_READ);
+        channel["data/fields/" + std::string(var_desc.name) + "/values"]
+          .set_external(comin_var_get_ptr(handle), ncells);
+      }
+    }
   }
+}
 
-  //std::cout << catalyst_exec_params.to_json() << std::endl;
+void catalyst_adapter_execute(){
 
+  static int64_t cycle = 0;
+  catalyst_exec_params["catalyst/state/cycle"] = cycle;
+  catalyst_exec_params["catalyst/state/time"] = cycle;
+  cycle++;
 
   enum catalyst_status err = catalyst_execute(conduit_cpp::c_node(&catalyst_exec_params));
   if (err != catalyst_status_ok)
   {
     printf("Failed to execute Catalyst: %d\n", err);
   }
+  sleep(1);
 }
 
 
diff --git a/gridwriter.py b/gridwriter.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a339fb758d1dfb4a644e5a27d5b37a35343041a
--- /dev/null
+++ b/gridwriter.py
@@ -0,0 +1,74 @@
+# script-version: 2.0
+# Sample Catalyst Python script to generate data outputs.
+# One can use this directly or create a modified version
+# to customize write frequency, output directory etc.
+
+#---------------------------------------------------------
+# Input parameters
+#---------------------------------------------------------
+# Specify the Catalyst channel name
+catalystChannel = "domain1"
+
+# Specify the write frequency
+frequency = 1
+
+# Specify the output directory. Ideally, this should be an
+# absolute path to avoid confusion.
+outputDirectory = "vtk"
+
+# Specify extractor type to use, if any.
+# e.g. for CSV, set extractorType to 'CSV'
+extractorType = None
+
+#---------------------------------------------------------
+from paraview.simple import *
+
+# Specify the Catalyst channel name
+def create_extractor(data):
+    if extractorType is not None:
+        return CreateExtractor(extractorType, data, registrationName=extractorType)
+
+    grid = data.GetClientSideObject().GetOutputDataObject(0)
+    if grid.IsA('vtkImageData'):
+        return CreateExtractor('VTI', data, registrationName='VTI')
+    elif grid.IsA('vtkRectilinearGrid'):
+        return CreateExtractor('VTR', data, registrationName='VTR')
+    elif grid.IsA('vtkStructuredGrid'):
+        return CreateExtractor('VTS', data, registrationName='VTS')
+    elif grid.IsA('vtkPolyData'):
+        return CreateExtractor('VTP', data, registrationName='VTP')
+    elif grid.IsA('vtkUnstructuredGrid'):
+        return CreateExtractor('VTU', data, registrationName='VTU')
+    elif grid.IsA('vtkUniformGridAMR'):
+        return CreateExtractor('VTH', data, registrationName='VTH')
+    elif grid.IsA('vtkMultiBlockDataSet'):
+        return CreateExtractor('VTM', data, registrationName='VTM')
+    elif grid.IsA('vtkPartitionedDataSet'):
+        return CreateExtractor('VTPD', data, registrationName='VTPD')
+    elif grid.IsA('vtkPartitionedDataSetCollection'):
+        return CreateExtractor('VTPC', data, registrationName='VTPC')
+    elif  grid.IsA('vtkHyperTreeGrid'):
+        return CreateExtractor('HTG', data, registrationName='HTG')
+    else:
+        raise RuntimeError("Unsupported data type: %s", grid.GetClassName())
+
+
+# Pipeline
+data = TrivialProducer(registrationName=catalystChannel)
+
+# Returns extractor type based on data (or you can manually specify
+extractor = create_extractor(data)
+
+# ------------------------------------------------------------------------------
+# Catalyst options
+from paraview import catalyst
+options = catalyst.Options()
+options.ExtractsOutputDirectory = outputDirectory
+options.GlobalTrigger.Frequency = frequency
+
+# ------------------------------------------------------------------------------
+if __name__ == '__main__':
+    from paraview.simple import SaveExtractsUsingCatalystOptions
+    # Code for non in-situ environments; if executing in post-processing
+    # i.e. non-Catalyst mode, let's generate extracts using Catalyst options
+    SaveExtractsUsingCatalystOptions(options)
diff --git a/parse_isotime.hpp b/parse_isotime.hpp
deleted file mode 100644
index a464803077e69b44153fc8f0f97cfa636dcf16cb..0000000000000000000000000000000000000000
--- a/parse_isotime.hpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <chrono>
-#include <ctime>
-
-static std::chrono::time_point<std::chrono::system_clock>
-parse_isotime(const std::string& iso8601) {
-  using namespace std;
-    tm t = {};
-    // F: Equivalent to %Y-%m-%d, the ISO 8601 date format.
-    // T: ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S
-    // z: ISO 8601 offset from UTC in timezone (1 minute=1, 1 hour=100). If timezone cannot be determined, no characters
-    strptime(iso8601.c_str(), "%FT%T%z", &t);
-    return chrono::system_clock::from_time_t(mktime(&t));
-}
diff --git a/pvExample.py b/pvExample.py
index 627691590b661a9841660fcb556697fe0620df50..255ed2f525c8745aa7bf7934c454bcc1b9f2ce35 100644
--- a/pvExample.py
+++ b/pvExample.py
@@ -1,42 +1,29 @@
 import os
 from paraview.simple import *
 
-renderView1 = GetRenderView()
-
-producer = TrivialProducer(registrationName='domain1')
-
-display = Show(producer, renderView1)
-if len(producer.PointData) > 0:
-    field_name = producer.PointData[0].GetName()
-    ColorBy(display, ('POINTS', field_name))
-else:
-    field_name = producer.CellData[0].GetName()
-    ColorBy(display, ('CELLS', field_name))
-
-producer2 = TrivialProducer(registrationName='domain2')
-display = Show(producer2, renderView1)
-if len(producer2.PointData) > 0:
-    field_name = producer2.PointData[0].GetName()
-    ColorBy(display, ('POINTS', field_name))
-else:
-    field_name = producer2.CellData[0].GetName()
-    ColorBy(display, ('CELLS', field_name))
-
-pNG1 = CreateExtractor('PNG', renderView1, registrationName='PNG1')
-pNG1.Trigger = 'TimeStep'
-
-pNG1.Writer.FileName = 'RenderView1_{timestep:06d}{camera}.png'
-pNG1.Writer.ImageResolution = [1920, 1080]
-pNG1.Writer.Format = 'PNG'
-
 # ------------------------------------------------------------------------------
 # Catalyst options
 from paraview import catalyst
 options = catalyst.Options()
 options.GlobalTrigger = 'TimeStep'
 options.EnableCatalystLive = 1
+options.CatalystLiveURL = 'localhost:22222'
 options.CatalystLiveTrigger = 'TimeStep'
 
+lonlat2sphere = '-1*sin(coordsX)*cos(coordsY)*iHat+cos(coordsX)*cos(coordsY)*jHat+sin(coordsY)*kHat'
+
+domain1 = TrivialProducer(registrationName='domain1')
+calculator1 = Calculator(registrationName='Calculator1', Input=domain1)
+calculator1.CoordinateResults = 1
+calculator1.Function = lonlat2sphere
+calculator1Display = Show(calculator1)
+
+domain2 = TrivialProducer(registrationName='domain2')
+calculator2 = Calculator(registrationName='Calculator2', Input=domain2)
+calculator2.CoordinateResults = 1
+calculator2.Function = lonlat2sphere
+calculator2Display = Show(calculator2)
+
 # ------------------------------------------------------------------------------
 if __name__ == '__main__':
     from paraview.simple import SaveExtractsUsingCatalystOptions