diff --git a/lib/siplib.py b/lib/siplib.py
index 0ca0e4bae62fa7541094cfc2c656197995c26edc..dda1521ffbbc68924ba3f2c4e1174508579afce6 100644
--- a/lib/siplib.py
+++ b/lib/siplib.py
@@ -6,14 +6,14 @@
 # to determine the mandatory and optional elements to create a valid SIP document. This module is designed to
 # provide easy-to-use functions that bridges this shortcoming of the Pyxb API.
 #
-# Usage: Import module. Create an instance of Sip. Add elements through the Sip.add_X functions.
-#        Many of these functions require instances of other classes of the module.
-#
+# Usage: Import module. Create an instance of Sip.
+#        Add elements through the Sip.add_X functions. Many require instances of other classes of the module.
+#        call getprettyxml() and e.g. save to disk.
 #
 # Note on validation: From construction through every addition, the SIP should remain valid (or throw an error
 # that clearly points out where e.g. a given value does not meet the restrictions of the SIP schema.
 #
-# Note on code structure: This has to be seen as a compromise between elegant and maintainable code with well
+# Note on code structure: This has to be seen as a compromise between elegant and maintainable code with well-
 # structured inheritance close to the schema definition on the one hand, and something more straightforward to use,
 # with flatter hierarchies on the other hand.
 #
@@ -22,11 +22,12 @@
 # a supertype, and indeed is solved like this in the pyxb code. However, this then requires the use of an argument
 # list pointer, which hides the list of required and optional arguments from the user. Alternatively, all arguments
 # have to be mapped in all constructors repeatedly, creating lots of boilerplate code. This is the nicest approach
-# I could think of that keeps the whole thing reasonably maintainable.
+# I could think of that keeps the whole thing reasonably maintainable AND usable.
 
 
 import ltasip
 import pyxb
+import os.path
 
 VERSION = "SIPlib 0.1"
 
@@ -38,6 +39,15 @@ VERSION = "SIPlib 0.1"
 # Probably create a Station class for this
 # We should prepare a dictionary with all present
 
+# todo: create docstrings for everything.
+# specify types and explain purpose of the field (-> ask someone with more astronomical background)
+
+# todo: check what fields can be implicitely set
+# (e.g. parameter type in dataproduct may be derived from the specific dataproduct class that is used)
+# Some parameters may also be filled with a reasonable default value. Right now, usually only optional values
+# as per schema definition are optional parameters.
+
+
 
 # ===============================
 # Station definitions:
@@ -62,15 +72,13 @@ STATIONS = dict(stationA=stationA,
                 stationB=stationB)
 
 
-
-######################################### end station definitions
+# #############################################################################################
 
 
 # ==============
 # Processes:
 
 class ProcessMap():
-    #todo: relations
     def __init__(self,
                  strategyname,
                  strategydescription,
@@ -80,18 +88,19 @@ class ProcessMap():
                  observation_id,
                  process_source,
                  process_id,
+                 relations,
                  parset_source=None,
                  parset_id=None,
                  ):
 
+        __relations=ltasip.ProcessRelations()
+        for rel in relations:
+            __relations.append(rel.get_pyxb_processrelation())
         self.process_map = dict(processIdentifier=ltasip.IdentifierType(source=process_source, identifier=process_id),
-                           observationId=ltasip.IdentifierType(source=observation_source, identifier=observation_id),
-                           relations=ltasip.ProcessRelations().append(
-                               ltasip.ProcessRelation(relationType=ltasip.ProcessRelationType("GroupID"),
-                                                      identifier=ltasip.IdentifierType(source="somesource",
-                                                                                       identifier="relationID"))),
-                           strategyName=strategyname, strategyDescription=strategydescription, startTime=starttime,
-                           duration=duration)
+                                observationId=ltasip.IdentifierType(source=observation_source, identifier=observation_id),
+                                relations=__relations,
+                                strategyName=strategyname, strategyDescription=strategydescription, startTime=starttime,
+                                duration=duration)
 
         if parset_id and parset_source:
             self.process_map["parset"]=ltasip.IdentifierType(source=parset_source,identifier=parset_id)
@@ -99,6 +108,25 @@ class ProcessMap():
     def get_dict(self):
         return self.process_map
 
+class ProcessRelation():
+    def __init__(self,
+                 identifier_source,
+                 identifier,
+                 name=None,
+                 type="GroupID"
+    ):
+
+        self.__pyxb_processrelation=ltasip.ProcessRelation(
+            relationType=ltasip.ProcessRelationType(type),
+            identifier=ltasip.IdentifierType(
+                source=identifier_source,
+                identifier=identifier,
+                name=name)
+        )
+
+    def get_pyxb_processrelation(self):
+        return self.__pyxb_processrelation
+
 
 class SimpleProcess():
     def __init__(self, process_map):
@@ -112,14 +140,86 @@ class SimpleProcess():
 # PipelineRuns:
 
 class PipelineMap():
-   def __init__(self,
-        name,
-        version,
-        sourcedata, #= type="DataSources"/>
-        process_map
-   ):
-      pass
-      # todo
+    def __init__(self,
+                 name,
+                 version,
+                 sourcedata_source,
+                 sourcedata_identifiers,
+                 process_map
+    ):
+
+        __sourcedata=ltasip.DataSources()
+        for id in sourcedata_identifiers:
+            __sourcedata.append(ltasip.IdentifierType(identifier=id, source=sourcedata_source))
+
+        self.pipeline_map=dict(
+            pipelineName=name,
+            pipelineVersion=version,
+            sourceData=__sourcedata
+        )
+        self.pipeline_map.update(process_map.get_dict())
+
+    def get_dict(self):
+        return self.pipeline_map
+
+
+class SimplePipeline():
+    def __init__(self, pipeline_map):
+        self.__pyxb_pipeline=ltasip.PipelineRun(**pipeline_map.get_dict())
+
+    def get_pyxb_pipeline(self):
+        return self.__pyxb_pipeline
+
+
+class ImagingPipeline():
+    #todo
+    def get_pyxb_pipeline(self):
+        return self.__pyxb_pipeline
+
+class CalibrationPipeline():
+    #todo
+    def get_pyxb_pipeline(self):
+        return self.__pyxb_pipeline
+
+class AveragingPipeline():
+    #todo
+    def get_pyxb_pipeline(self):
+        return self.__pyxb_pipeline
+
+class PulsarPipeline():
+    #todo
+    def get_pyxb_pipeline(self):
+        return self.__pyxb_pipeline
+
+class CosmicRayPipeline():
+    def __init__(self, pipeline_map):
+        self.__pyxb_pipeline=ltasip.CosmicRayPipeline(**pipeline_map.get_dict())
+
+    def get_pyxb_pipeline(self):
+        return self.__pyxb_pipeline
+
+class LongBaselinePipeline():
+    def __init__(self,
+                 pipeline_map,
+                 subbandspersubbandgroup,
+                 subbandgroupspermS
+    ):
+        self.__pyxb_pipeline=ltasip.LongBaselinePipeline(
+            subbandsPerSubbandGroup=subbandspersubbandgroup,
+            subbandGroupsPerMS=subbandgroupspermS,
+            **pipeline_map.get_dict())
+
+    def get_pyxb_pipeline(self):
+        return self.__pyxb_pipeline
+
+class GenericPipeline():
+    def __init__(self, pipeline_map):
+        self.__pyxb_pipeline=ltasip.GenericPipeline(**pipeline_map.get_dict())
+
+    def get_pyxb_pipeline(self):
+        return self.__pyxb_pipeline
+
+
 
 
 # ==========
@@ -191,7 +291,7 @@ class PixelMapDataProduct():
         self.__pyxb_dataproduct = ltasip.PixelMapDataProduct(
             numberOfAxes=numberofaxes,
             numberOfCoordinates=len(coordinates),
-            coordinates = [x.get_pyxb_coordinate() for x in coordinates],
+            coordinate = [x.get_pyxb_coordinate() for x in coordinates],
             **dataproduct_map.get_dict())
     def get_pyxb_dataproduct(self):
         return self.__pyxb_dataproduct
@@ -205,8 +305,10 @@ class SkyImageDataProduct():
                  locationframe,
                  timeframe,
                  observationpointing,
-                 restoringbeammajor,
-                 restoringbeamminor,
+                 restoringbeammajor_angle,
+                 restoringbeammajor_angleunit,
+                 restoringbeamminor_angle,
+                 restoringbeamminor_angleunit,
                  rmsnoise):
 
         self.__pyxb_dataproduct = ltasip.SkyImageDataProduct(
@@ -215,9 +317,9 @@ class SkyImageDataProduct():
             coordinate = [x.get_pyxb_coordinate() for x in coordinates],
             locationFrame=locationframe,
             timeFrame=timeframe,
-            observationPointing=observationpointing,
-            restoringBeamMajor=restoringbeammajor,
-            restoringBeamMinor=restoringbeamminor,
+            observationPointing=observationpointing.get_pyxb_pointing(),
+            restoringBeamMajor=ltasip.Angle(restoringbeammajor_angle, units=restoringbeammajor_angleunit),
+            restoringBeamMinor=ltasip.Angle(restoringbeamminor_angle, units=restoringbeamminor_angleunit),
             rmsNoise=rmsnoise,
             **dataproduct_map.get_dict())
 
@@ -227,20 +329,20 @@ class SkyImageDataProduct():
 
 class CorrelatedDataProduct():
     def __init__(self,
-        dataproduct_map,
-        subarraypointing_source,
-        subarraypointing_identifier,
-        subband,
-		starttime,
-		duration,
-		integrationinterval,
-        integrationintervalunit,
-		central_frequency,
-        central_frequencyunit,
-        channelwidth_frequency,
-        channelwidth_frequencyunit,
-        channelspersubband,
-        stationsubband=None):
+                 dataproduct_map,
+                 subarraypointing_source,
+                 subarraypointing_identifier,
+                 subband,
+                 starttime,
+                 duration,
+                 integrationinterval,
+                 integrationintervalunit,
+                 central_frequency,
+                 central_frequencyunit,
+                 channelwidth_frequency,
+                 channelwidth_frequencyunit,
+                 channelspersubband,
+                 stationsubband=None):
 
         self.__pyxb_dataproduct=ltasip.CorrelatedDataProduct(
             subArrayPointingIdentifier=ltasip.IdentifierType(source=subarraypointing_source, identifier=subarraypointing_identifier),
@@ -291,8 +393,8 @@ class BeamFormedDataProduct():
 class PulpSummaryDataProduct():
     def __init__(self,
                  dataproduct_map,
-    			 filecontent,
-			     datatype):
+                 filecontent,
+                 datatype):
         self.__pyxb_dataproduct = ltasip.PulpSummaryDataProduct(
             fileContent=filecontent,
             dataType=datatype,
@@ -305,12 +407,12 @@ class PulpDataProduct():
     def __init__(self,
                  dataproduct_map,
                  filecontent,
-			     datatype,
-				 arrayBeam):
+                 datatype,
+                 arraybeam):
         self.__pyxb_dataproduct = ltasip.PulpDataProduct(
             fileContent=filecontent,
             dataType=datatype,
-
+            arrayBeam=arraybeam.get_pyxb_beam(),
             **dataproduct_map.get_dict())
 
     def get_pyxb_dataproduct(self):
@@ -321,84 +423,170 @@ class PulpDataProduct():
 # ============
 # Coordinates:
 
-
-class SpectralCoordinateLinear():
+class SpectralCoordinate():
     def __init__(self,
                  quantity_type,
                  quantity_value,
-                 linearaxis,
+                 axis,
                  ):
-        self.__pyxb_coordinate=ltasip.SpectralCoordinate(
-            spectralLinearAxis=linearaxis.get_pyxb_axis(),
-            spectralQuantity=ltasip.SpectralQuantity(value_=quantity_value, type=quantity_type)
-        )
-
-    def get_pyxb_coordinate(self):
-        return self.__pyxb_coordinate
-
 
+        args = dict(spectralQuantity=ltasip.SpectralQuantity(value_=quantity_value, type=quantity_type))
 
-class SpectralCoordinateTabular():
-    def __init__(self,
-                 quantity_type,
-                 quantity_value,
-                 tabularaxis,
-                 ):
+        if isinstance(axis, LinearAxis):
+            args.update(dict(spectralLinearAxis=axis.get_pyxb_axis()))
+        elif isinstance(axis, TabularAxis):
+            args.update(dict(spectralTabularAxis=axis.get_pyxb_axis()))
+        else:
+            print "wrong axis type:",type(axis)
 
-        self.__pyxb_coordinate=ltasip.SpectralCoordinate(
-            spectralTabularAxis=tabularaxis.get_pyxb_axis(),
-            spectralQuantity=ltasip.SpectralQuantity(value_=quantity_value, type=quantity_type)
-        )
+        self.__pyxb_coordinate=ltasip.SpectralCoordinate(**args)
 
     def get_pyxb_coordinate(self):
         return self.__pyxb_coordinate
 
 
-class TimeCoordinateLinear():
+class TimeCoordinate():
     def __init__(self,
                  equinox,
-                 linearaxis,
+                 axis,
                  ):
-        self.__pyxb_coordinate=ltasip.TimeCoordinate(
-            timeLinearAxis=linearaxis.get_pyxb_axis(),
-            equinox=equinox
-        )
+
+        args = dict(equinox=equinox)
+
+        if isinstance(axis, LinearAxis):
+            args.update(dict(timeLinearAxis=axis.get_pyxb_axis()))
+        elif isinstance(axis, TabularAxis):
+            args.update(dict(timeTabularAxis=axis.get_pyxb_axis()))
+        else:
+            print "wrong axis type:",type(axis)
+
+        self.__pyxb_coordinate=ltasip.TimeCoordinate(**args)
+
 
     def get_pyxb_coordinate(self):
         return self.__pyxb_coordinate
 
 
-
-class TimeCoordinateTabular():
+class PolarizationCoordinate():
     def __init__(self,
-                 equinox,
                  tabularaxis,
-                 ):
-
-        self.__pyxb_coordinate=ltasip.TimeCoordinate(
-            timeTabularAxis=tabularaxis.get_pyxb_axis(),
-            equinox=equinox
-        )
+                 polarizations
+    ):
+        self.__pyxb_coordinate=ltasip.PolarizationCoordinate(
+            polarizationTabularAxis=tabularaxis.get_pyxb_axis(),
+            polarization=polarizations)
 
     def get_pyxb_coordinate(self):
         return self.__pyxb_coordinate
 
 
 class DirectionCoordinate():
-    def __init__(linearaxis_a,
+    def __init__(self,
+                 linearaxis_a,
                  linearaxis_b,
-                 PC0_0,
-                 PC0_1,
-                 PC1_0,
-                 PC1_1,
+                 pc0_0,
+                 pc0_1,
+                 pc1_0,
+                 pc1_1,
                  equinox,
-                 raDecSystem,
+                 radecsystem,
                  projection,
-                 projectionParameters,
-                 longitudePole,
-                 latitudePole):
-        pass
-        #todo
+                 projectionparameters,
+                 longitudepole_angle,
+                 longitudepole_angleunit,
+                 latitudepole_angle,
+                 latitudepole_angleunit):
+
+        self.__pyxb_coordinate=ltasip.DirectionCoordinate(
+            directionLinearAxis=[linearaxis_a.get_pyxb_axis(), linearaxis_b.get_pyxb_axis()],
+            PC0_0=pc0_0,
+            PC0_1=pc0_1,
+            PC1_0=pc1_0,
+            PC1_1=pc1_1,
+            equinox=equinox,
+            raDecSystem=radecsystem,
+            projection=projection,
+            projectionParameters=projectionparameters,
+            longitudePole=ltasip.Angle(longitudepole_angle, units=longitudepole_angleunit),
+            latitudePole=ltasip.Angle(latitudepole_angle, units=latitudepole_angleunit)
+        )
+
+    def get_pyxb_coordinate(self):
+        return self.__pyxb_coordinate
+
+
+
+# ########
+# Others:
+
+
+class ArrayBeam():
+    def __init__(self,
+                 subarraypointingidentifier_source,
+                 subarraypointingidentifier,
+                 beamnumber,
+                 dispersionmeasure,
+                 numberofsubbands,
+                 stationsubbands,
+                 samplingtime,
+                 samplingtimeunit,
+                 centralfrequencies,
+                 centralfrequencies_unit,
+                 channelwidth_frequency,
+                 channelwidth_frequencyunit,
+                 channelspersubband,
+                 stokes):
+        self.__pyxb_beam=ltasip.ArrayBeam(
+            subArrayPointingIdentifier=ltasip.IdentifierType(source=subarraypointingidentifier_source, identifier=subarraypointingidentifier),
+            beamNumber=beamnumber,
+            dispersionMeasure=dispersionmeasure,
+            numberOfSubbands=numberofsubbands,
+            stationSubbands=stationsubbands,
+            samplingTime=ltasip.Time(samplingtime, units=samplingtimeunit),
+            centralFrequencies=ltasip.ListOfFrequencies(frequencies=centralfrequencies, unit=centralfrequencies_unit),
+            channelWidth=ltasip.Frequency(channelwidth_frequency, units=channelwidth_frequencyunit),
+            channelsPerSubband=channelspersubband,
+            stokes=stokes
+        )
+
+    def get_pyxb_beam(self):
+        return self.__pyxb_beam
+
+class PointingRaDec():
+
+    def __init__(self,
+                 ra_angle,
+                 ra_angleunit,
+                 dec_angle,
+                 dec_angleunit,
+                 equinox):
+
+        self.__pyxb_pointing=ltasip.Pointing(
+            rightAscension=ltasip.Angle(ra_angle, units=ra_angleunit),
+            declination=ltasip.Angle(dec_angle, units=dec_angleunit),
+            equinox=equinox)
+
+    def get_pyxb_pointing(self):
+        return self.__pyxb_pointing
+
+
+class PointingAltAz():
+
+    def __init__(self,
+                 az_angle,
+                 az_angleunit,
+                 alt_angle,
+                 alt_angleunit,
+                 equinox):
+
+        self.__pyxb_pointing=ltasip.Pointing(
+            azimuth=ltasip.Angle(az_angle, units=az_angleunit),
+            altitude=ltasip.Angle(alt_angle, units=alt_angleunit),
+            equinox=equinox)
+
+    def get_pyxb_pointing(self):
+        return self.__pyxb_pointing
+
 
 class LinearAxis():
     def __init__(self,
@@ -441,12 +629,110 @@ class TabularAxis():
     def get_pyxb_axis(self):
         return self.__pyxb_axis
 
+class CorrelatorProcessing():
+    def __init__(self,
+                 integrationinterval,
+                 integrationinterval_unit,
+                 channelwidth_frequency=None,
+                 channelwidth_frequencyunit=None,
+                 channelspersubband=None,
+                 processingtype="Correlator",
+                 ):
+        self.__pyxb_rtprocessing=ltasip.Correlator(
+            integrationInterval=ltasip.Time(integrationinterval,units=integrationinterval_unit),
+            processingType=processingtype,
+            channelWidth=ltasip.Frequency(channelwidth_frequency, units=channelwidth_frequencyunit),
+            channelsPerSubband=channelspersubband
+        )
+
+    def get_pyxb_rtprocessing(self):
+        return self.__pyxb_rtprocessing
+
+class CoherentStokesProcessing():
+    #todo
+    def get_pyxb_rtprocessing(self):
+        return self.__pyxb_rtprocessing
+
+class IncoherentStokesProcessing():
+    #todo
+    def get_pyxb_rtprocessing(self):
+        return self.__pyxb_rtprocessing
+
+class FlysEyeProcessing():
+    #todo
+    def get_pyxb_rtprocessing(self):
+        return self.__pyxb_rtprocessing
+
+class NonStandardProcessing():
+    #todo
+    def get_pyxb_rtprocessing(self):
+        return self.__pyxb_rtprocessing
+
+class SubArrayPointing():
+    def __init__(self,
+                 pointing,
+                 beamnumber,
+                 subarraypointingidentifier,
+                 subarraypointingidentifier_source,
+                 measurementtype,
+                 targetname,
+                 starttime,
+                 duration,
+                 numberofprocessing,
+                 numberofcorrelateddataproducts,
+                 numberofbeamformeddataproducts,
+                 relations,
+                 correlatorprocessing=None,
+                 coherentstokesprocessing=None,
+                 incoherentstokesprocessing=None,
+                 flyseyeprocessing=None,
+                 nonstandardprocessing=None,
+                 measurementdescription=None):
+
+        __relations=ltasip.ProcessRelations()
+        for rel in relations:
+            __relations.append(rel.get_pyxb_processrelation())
+
+        __processing=None
+        for processing in [correlatorprocessing, coherentstokesprocessing, incoherentstokesprocessing, flyseyeprocessing, nonstandardprocessing]:
+            if processing:
+                if __processing is None:
+                    __processing=ltasip.Processing()
+                __processing.append(correlatorprocessing.get_pyxb_rtprocessing()
+                )
+
+
+        self.__pyxb_subarraypointing = ltasip.SubArrayPointing(
+            pointing=pointing.get_pyxb_pointing(),
+            beamNumber=beamnumber,
+            subArrayPointingIdentifier=ltasip.IdentifierType(identifier=subarraypointingidentifier,source=subarraypointingidentifier_source),
+            measurementType=measurementtype,
+            targetName=targetname,
+            startTime=starttime,
+            duration=duration,
+            numberOfProcessing=numberofprocessing,
+            numberOfCorrelatedDataProducts=numberofcorrelateddataproducts,
+            numberOfBeamFormedDataProducts=numberofbeamformeddataproducts,
+            processing=__processing,
+            relations=__relations,
+            measurementDescription=measurementdescription)
+
+    def get_pyxb_subarraypointing(self):
+        return self.__pyxb_subarraypointing
+
+
+# #############################################################################################
 
 # ============
 # SIP document
 
 class Sip():
 
+    print "\n################"
+    print  VERSION
+    print "################\n"
+
+    print "===\nCreating base document...\n"
     sip = ltasip.ltaSip()
 
     #-----------
@@ -471,7 +757,6 @@ class Sip():
             contactAuthor=project_contactauthor,
             telescope=project_telescope,
             projectDescription=project_description,
-            #dataProduct=dataproduct,
             coInvestigator=project_coinvestigators,
             )
 
@@ -488,7 +773,6 @@ class Sip():
         self.sip.relatedDataProduct.append(dataproduct.get_pyxb_dataproduct())
         return self.get_prettyxml()
 
-    # todo: subarraypointings, transientbufferboardevents
     def add_observation(self,
                         observingmode,
                         instrumentfilter,
@@ -509,13 +793,25 @@ class Sip():
                         channelwidth_frequencyunit=None,
                         observationdescription=None,
                         channelspersubband=None,
-                        subarraypointings=None, #" type="SubArrayPointings"/>
-                        transientbufferboardevents=None #" type="TransientBufferBoardEvents"/>
+                        subarraypointings=None,
+                        transientbufferboardevents=None
     ):
 
-        stations = ltasip.Stations()
+        __stations = ltasip.Stations()
         for station in stationlist:
-            stations.append(station)
+            __stations.append(station)
+
+        __tbbevents=None,
+        if(transientbufferboardevents):
+            __tbbevents = ltasip.TransientBufferBoardEvents()
+            for source in transientbufferboardevents:
+                __tbbevents.append(ltasip.TransientBufferBoardEvent(eventSource=source))
+
+        __pointings=None
+        if(subarraypointings):
+            __pointings = ltasip.SubArrayPointings()
+            for point in subarraypointings:
+                __pointings.append(point.get_pyxb_subarraypointing())
 
         obs = ltasip.Observation(
             observingMode=observingmode,
@@ -525,7 +821,7 @@ class Sip():
             antennaSet=antennaset,
             timeSystem=timesystem,
             numberOfStations=numberofstations,
-            stations=stations,
+            stations=__stations,
             numberOfSubArrayPointings=numberofsubarraypointings,
             numberOftransientBufferBoardEvents=numberoftbbevents,
             numberOfCorrelatedDataProducts=numberofcorrelateddataproducts,
@@ -534,8 +830,8 @@ class Sip():
             observationDescription=observationdescription,
             channelWidth=ltasip.Frequency(channelwidth_frequency, units=channelwidth_frequencyunit),
             channelsPerSubband=channelspersubband,
-            subArrayPointings=None, #" type="SubArrayPointings"/>
-            transientBufferBoardEvents=None, #" type="TransientBufferBoardEvents"/>
+            subArrayPointings=__pointings,
+            transientBufferBoardEvents=__tbbevents,
             **process_map.get_dict()
         )
 
@@ -544,11 +840,11 @@ class Sip():
 
 
 
-    def add_pipelinerun(self):
+    def add_pipelinerun(self, pipeline):
+        self.sip.pipelineRun.append(pipeline.get_pyxb_pipeline())
         return self.get_prettyxml()
 
 
-    # todo relations
     def add_unspecifiedprocess(self,
                                observingmode,
                                description,
@@ -578,6 +874,7 @@ class Sip():
         return self.get_prettyxml()
 
 
+    # this will also validate the document so far
     def get_prettyxml(self):
         try:
             return self.sip.toDOM().toprettyxml()
@@ -592,13 +889,25 @@ class Sip():
 
 
 
+# ########################################################## end SIP class
+
+
+
+
+
+
+
+
+
 
-########################################################### end SIP class
+
+
+# ############################################################################
 
 
 def main():
 
-# todo: This should be moved to testing, but makes it easier for me now.
+    # todo: This should be moved to testing, but makes it easier for me now.
 
     # create example doc with mandatory attributes
     mysip = Sip(project_code="code",
@@ -623,16 +932,11 @@ def main():
                     )
                 )
     )
-
-    # add optional attributes
-    # mysip.add_project_coInvestigator("sidekick3")
-    # mysip.add_dataproduct_checksum("MD5", "anotherchecksum")
-
-    print "===\nCreated base document:\n"
     mysip.prettyprint()
 
+    print "===\nAdding related generic dataproduct:\n"
     # add optional dataproduct item
-    mysip.add_related_dataproduct(
+    print mysip.add_related_dataproduct(
         GenericDataProduct(
             DataProductMap(
                 type="Unknown",
@@ -647,13 +951,66 @@ def main():
         )
     )
 
-    print "===\nAdded related dataproduct:\n"
-    mysip.prettyprint()
 
+    # add optional dataproduct item
+    print "===\nAdding related pulp summary dataproduct:\n"
+    print mysip.add_related_dataproduct(
+        PulpSummaryDataProduct(
+            DataProductMap(
+                type="Unknown",
+                source="space",
+                identifier="fourtytwo",
+                size=2048,
+                filename="/home/paulus/test.h5",
+                fileformat="HDF5",
+                processsource="someone gave it to me",
+                processid="SIPlib 0.1"
+            ),
+            filecontent=["content_a","content_b"],
+            datatype="CoherentStokes"
+        )
+    )
 
 
+
+    # add optional dataproduct item
+    print "===\nAdding related pulp dataproduct:\n"
+    print mysip.add_related_dataproduct(
+        PulpDataProduct(
+            DataProductMap(
+                type="Unknown",
+                source="space",
+                identifier="fourtytwo",
+                size=2048,
+                filename="/home/paulus/test.h5",
+                fileformat="HDF5",
+                processsource="someone gave it to me",
+                processid="SIPlib 0.1"
+            ),
+            filecontent=["content_a","content_b"],
+            datatype="CoherentStokes",
+            arraybeam=ArrayBeam(
+                subarraypointingidentifier_source="source",
+                subarraypointingidentifier="id",
+                beamnumber=4,
+                dispersionmeasure=16,
+                numberofsubbands=3,
+                stationsubbands=[1,2,3],
+                samplingtime=3,
+                samplingtimeunit="ms",
+                centralfrequencies="",
+                centralfrequencies_unit="MHz",
+                channelwidth_frequency=160,
+                channelwidth_frequencyunit="MHz",
+                channelspersubband=5,
+                stokes=["I","Q"]
+            )
+        )
+    )
+
     # add optional dataproduct item
-    mysip.add_related_dataproduct(
+    print "===\nAdding related sky image dataproduct:\n"
+    print mysip.add_related_dataproduct(
         SkyImageDataProduct(
             DataProductMap(
                 type="Unknown",
@@ -667,10 +1024,10 @@ def main():
             ),
             numberofaxes=2,
             coordinates=[
-                SpectralCoordinateLinear(
+                SpectralCoordinate(
                     quantity_type="Frequency",
                     quantity_value=20.0,
-                    linearaxis=LinearAxis(
+                    axis=LinearAxis(
                         number=5,
                         name="bla",
                         units="parsec",
@@ -678,36 +1035,85 @@ def main():
                         increment=5,
                         referencepixel=7.5,
                         referencevalue=7.4)),
-                SpectralCoordinateTabular(
+                SpectralCoordinate(
                     quantity_type="Frequency",
                     quantity_value=20.0,
+                    axis=TabularAxis(
+                        number=5,
+                        name="bla",
+                        units="parsec",
+                        length=5,
+                        )),
+                DirectionCoordinate(
+                    linearaxis_a=LinearAxis(
+                        number=5,
+                        name="bla",
+                        units="parsec",
+                        length=5,
+                        increment=5,
+                        referencepixel=7.5,
+                        referencevalue=7.4),
+                    linearaxis_b=LinearAxis(
+                        number=5,
+                        name="bla",
+                        units="parsec",
+                        length=5,
+                        increment=5,
+                        referencepixel=7.5,
+                        referencevalue=7.4),
+                    pc0_0=0.0,
+                    pc0_1=0.1,
+                    pc1_0=1.0,
+                    pc1_1=1.1,
+                    equinox="SUN",
+                    radecsystem="ICRS",
+                    projection="rear",
+                    projectionparameters=[1.0,1.0,1.0],
+                    longitudepole_angle=1.0,
+                    longitudepole_angleunit="degrees",
+                    latitudepole_angle=2.0,
+                    latitudepole_angleunit="degrees",
+                    ),
+                PolarizationCoordinate(
                     tabularaxis=TabularAxis(
                         number=5,
                         name="bla",
                         units="parsec",
                         length=5,
-                        ))
+                        ),
+                    polarizations=["I","YY","XX","Q"]
+                ),
+                TimeCoordinate(
+                    equinox="SUN",
+                    axis=TabularAxis(
+                        number=5,
+                        name="timetabular",
+                        units="parsec",
+                        length=5,
+                        ),
+                )
             ],
             locationframe="GEOCENTER",
             timeframe="timeframe",
-            observationpointing=ltasip.Pointing(
-                rightAscension=ltasip.Angle(2.0, units="degrees"),
-                #azimuth=ltasip.Angle(),
-                declination=ltasip.Angle(2.0, units="degrees"),
-                #altitude=ltasip.Angle(),
-                equinox="SUN"),
-            restoringbeammajor=ltasip.Angle(2.0, units="degrees"),
-            restoringbeamminor=ltasip.Angle(2.0, units="degrees"),
+            observationpointing=PointingRaDec(
+                ra_angle=1.0,
+                ra_angleunit="degrees",
+                dec_angle=42.0,
+                dec_angleunit="degrees",
+                equinox="SUN"
+            ),
+            restoringbeammajor_angle=1.0,
+            restoringbeammajor_angleunit="degrees",
+            restoringbeamminor_angle=2.0,
+            restoringbeamminor_angleunit="degrees",
             rmsnoise=ltasip.Pixel("1.0", units="Jy/beam")
         )
     )
 
-    print "===\nAdded another related dataproduct:\n"
-    mysip.prettyprint()
-
 
-       # add optional dataproduct item
-    mysip.add_related_dataproduct(
+    # add optional dataproduct item
+    print "===\nAdded related correlated dataproduct:\n"
+    print mysip.add_related_dataproduct(
         CorrelatedDataProduct(
             DataProductMap(
                 type="Unknown",
@@ -735,55 +1141,112 @@ def main():
             )
     )
 
-    print "===\nAdded yet another related dataproduct:\n"
-    mysip.prettyprint()
+    # add optional dataproduct item
+    print "===\nAdding related pixelmap dataproduct:\n"
+    print mysip.add_related_dataproduct(
+        PixelMapDataProduct(
+            DataProductMap(
+                type="Unknown",
+                source="space",
+                identifier="fourtytwo",
+                size=2048,
+                filename="/home/paulus/test.h5",
+                fileformat="HDF5",
+                processsource="someone gave it to me",
+                processid="SIPlib 0.1"
+            ),
+            numberofaxes=5,
+            coordinates=[SpectralCoordinate(
+                quantity_type="Frequency",
+                quantity_value=20.0,
+                axis=LinearAxis(
+                    number=5,
+                    name="bla",
+                    units="parsec",
+                    length=5,
+                    increment=5,
+                    referencepixel=7.5,
+                    referencevalue=7.4))]
+        )
+    )
+
 
 
     # add optional observation item
-    mysip.add_observation(observingmode="Interferometer",
-                          instrumentfilter="10-70 MHz",
-                          clock_frequency='160',
-                          clock_frequencyunit="MHz",
-                          stationselection="Core",
-                          antennaset="HBA Zero",
-                          timesystem="UTC",
-                          stationlist=[STATIONS.get("stationA"), STATIONS.get("stationB")],
-                          numberofstations=5,
-                          numberofsubarraypointings=5,
-                          numberoftbbevents=5,
-                          numberofcorrelateddataproducts=5,
-                          numberofbeamformeddataproducts=5,
-                          numberofbitspersample=5,
-                          process_map=
-                          ProcessMap(
-                              strategyname="strategy1",
-                              strategydescription="awesome strategy",
-                              starttime="1980-03-23T10:20:15",
-                              duration= "P6Y3M10DT15H",
-                              observation_source="SAS",
-                              observation_id="SAS VIC Tree Id",
-                              process_source="MoM",
-                              process_id="MoM Id",
-                              parset_source="parsource",
-                              parset_id="parid"
-                          ),
-                          observationdescription="description",
-                          channelwidth_frequency=160,
-                          channelwidth_frequencyunit="MHz",
-                          channelspersubband=5,
-                          subarraypointings=None, #" type="SubArrayPointings"/>
-                          transientbufferboardevents=None #" type="TransientBufferBoardEvents"/>
+    print "===\nAdding observation:\n"
+    print mysip.add_observation(observingmode="Interferometer",
+                                instrumentfilter="10-70 MHz",
+                                clock_frequency='160',
+                                clock_frequencyunit="MHz",
+                                stationselection="Core",
+                                antennaset="HBA Zero",
+                                timesystem="UTC",
+                                stationlist=[STATIONS.get("stationA"), STATIONS.get("stationB")],
+                                numberofstations=5,
+                                numberofsubarraypointings=5,
+                                numberoftbbevents=5,
+                                numberofcorrelateddataproducts=5,
+                                numberofbeamformeddataproducts=5,
+                                numberofbitspersample=5,
+                                process_map=
+                                ProcessMap(
+                                    strategyname="strategy1",
+                                    strategydescription="awesome strategy",
+                                    starttime="1980-03-23T10:20:15",
+                                    duration= "P6Y3M10DT15H",
+                                    observation_source="SAS",
+                                    observation_id="SAS VIC Tree Id",
+                                    process_source="MoM",
+                                    process_id="MoM Id",
+                                    parset_source="parsource",
+                                    parset_id="parid",
+                                    relations=[ProcessRelation(
+                                        identifier_source="source",
+                                        identifier="90")]
+                                ),
+                                observationdescription="description",
+                                channelwidth_frequency=160,
+                                channelwidth_frequencyunit="MHz",
+                                channelspersubband=5,
+                                subarraypointings=[SubArrayPointing(
+                                    pointing=PointingAltAz(
+                                        az_angle=20,
+                                        az_angleunit="degrees",
+                                        alt_angle=30,
+                                        alt_angleunit="degrees",
+                                        equinox="SUN"
+                                    ),
+                                    beamnumber=5,
+                                    subarraypointingidentifier="id",
+                                    subarraypointingidentifier_source="idsource",
+                                    measurementtype="All Sky",
+                                    targetname="Sun",
+                                    starttime="1980-03-23T10:20:15",
+                                    duration= "P6Y3M10DT15H",
+                                    numberofprocessing=1,
+                                    numberofcorrelateddataproducts=2,
+                                    numberofbeamformeddataproducts=1,
+                                    relations=[ProcessRelation(
+                                        identifier_source="source",
+                                        identifier="90")],
+                                    correlatorprocessing=CorrelatorProcessing(
+                                        integrationinterval=0.5,
+                                        integrationinterval_unit="ns",
+                                        channelwidth_frequency=160,
+                                        channelwidth_frequencyunit="MHz"
+                                    )
+                                )],
+                                transientbufferboardevents=["event1","event2"]
     )
 
-    print "===\nAdded observation:\n"
-    mysip.prettyprint()
-
-    mysip.add_parset(source="Unknkown",identifier="Parset1", contents="blabla")
-
-    print "===\nAdded parset:\n"
-    mysip.prettyprint()
+    print "===\nAdding parset:\n"
+    print mysip.add_parset(
+        source="Unknkown",
+        identifier="Parset1",
+        contents="blabla")
 
-    mysip.add_unspecifiedprocess(
+    print "===\nAdding unspecified process:\n"
+    print mysip.add_unspecifiedprocess(
         observingmode="Interferometer",
         description="unspecified",
         process_map=
@@ -797,11 +1260,140 @@ def main():
             process_source="MoM",
             process_id="MoM Id",
             parset_source="parsource",
-            parset_id="parid")
+            parset_id="parid",
+            relations=[ProcessRelation(
+                identifier_source="source",
+                identifier="90",
+                name="name"),
+                       ProcessRelation(
+                           identifier_source="sourceB",
+                           identifier="7",
+                           name="another name")
+            ]
+        )
     )
 
-    print "===\nAdded unspecified process:\n"
-    mysip.prettyprint()
+    print "===\nAdding simple pipelinerun:\n"
+    print mysip.add_pipelinerun(
+        SimplePipeline(
+            PipelineMap(
+                name="simple",
+                version="version",
+                sourcedata_identifiers=["ID1","ID2"],
+                sourcedata_source="space",
+                process_map=ProcessMap(
+                    strategyname="strategy1",
+                    strategydescription="awesome strategy",
+                    starttime="1980-03-23T10:20:15",
+                    duration= "P6Y3M10DT15H",
+                    observation_source="SAS",
+                    observation_id="SAS VIC Tree Id",
+                    process_source="MoM",
+                    process_id="MoM Id",
+                    parset_source="parsource",
+                    parset_id="parid",
+                    relations=[
+                        ProcessRelation(
+                            identifier_source="source",
+                            identifier="90")]
+                    ),
+                )
+        )
+    )
+
+
+    print "===\nAdding generic pipelinerun:\n"
+    print mysip.add_pipelinerun(
+        GenericPipeline(
+            PipelineMap(
+                name="generic",
+                version="version",
+                sourcedata_identifiers=["ID1","ID2"],
+                sourcedata_source="space",
+                process_map=ProcessMap(
+                    strategyname="strategy1",
+                    strategydescription="awesome strategy",
+                    starttime="1980-03-23T10:20:15",
+                    duration= "P6Y3M10DT15H",
+                    observation_source="SAS",
+                    observation_id="SAS VIC Tree Id",
+                    process_source="MoM",
+                    process_id="MoM Id",
+                    parset_source="parsource",
+                    parset_id="parid",
+                    relations=[
+                        ProcessRelation(
+                            identifier_source="source",
+                            identifier="90")]
+                    ),
+                )
+        )
+    )
+
+    print "===\nAdding cosmic ray pipelinerun:\n"
+    print mysip.add_pipelinerun(
+        CosmicRayPipeline(
+            PipelineMap(
+                name="cosmic ray",
+                version="version",
+                sourcedata_identifiers=["ID1","ID2"],
+                sourcedata_source="space",
+                process_map=ProcessMap(
+                    strategyname="strategy1",
+                    strategydescription="awesome strategy",
+                    starttime="1980-03-23T10:20:15",
+                    duration= "P6Y3M10DT15H",
+                    observation_source="SAS",
+                    observation_id="SAS VIC Tree Id",
+                    process_source="MoM",
+                    process_id="MoM Id",
+                    parset_source="parsource",
+                    parset_id="parid",
+                    relations=[
+                        ProcessRelation(
+                            identifier_source="source",
+                            identifier="90")]
+                    ),
+                )
+        )
+    )
+
+
+    print "===\nAdding long baseline pipelinerun:\n"
+    print mysip.add_pipelinerun(
+        LongBaselinePipeline(
+            PipelineMap(
+                name="long baseline",
+                version="version",
+                sourcedata_identifiers=["ID1","ID2"],
+                sourcedata_source="space",
+                process_map=ProcessMap(
+                    strategyname="strategy1",
+                    strategydescription="awesome strategy",
+                    starttime="1980-03-23T10:20:15",
+                    duration= "P6Y3M10DT15H",
+                    observation_source="SAS",
+                    observation_id="SAS VIC Tree Id",
+                    process_source="MoM",
+                    process_id="MoM Id",
+                    parset_source="parsource",
+                    parset_id="parid",
+                    relations=[
+                        ProcessRelation(
+                            identifier_source="source",
+                            identifier="90")]
+                    ),
+                ),
+            subbandspersubbandgroup=5,
+            subbandgroupspermS=5
+
+        )
+    )
+
+    #path = os.path.expanduser("~/sip9091.xml")
+    #with open(path, 'w+') as f:
+    #   f.write(mysip.get_prettyxml())
+