diff --git a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.h b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.h
index 89fa0e161a3f73b06d54c5630dd7ac763b41bc69..652add49be92b54bcf1b273d8d1da11f1ad4fd52 100644
--- a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.h
+++ b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/TrackerReadoutGeometry/SiDetectorElement.h
@@ -178,6 +178,12 @@ namespace TrackerDD {
     /// SiCellId from Identifier
     SiCellId cellIdFromIdentifier(const Identifier& identifier) const;
       
+    /// Station
+    bool isInterface() const;
+    bool isUpstream() const;
+    bool isCentral() const;
+    bool isDownstream() const;
+
     //@}
     
     
diff --git a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SiDetectorElement.cxx b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SiDetectorElement.cxx
index 776fb48b7b0866a7f06724dae36d3256dd595cca..c9a29684d559305ac76ad06b2b632701df8cdc3c 100644
--- a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SiDetectorElement.cxx
+++ b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SiDetectorElement.cxx
@@ -1012,4 +1012,37 @@ namespace TrackerDD {
     return cellId;
   }
 
+  bool
+  SiDetectorElement::isInterface() const
+  {
+    const FaserSCT_ID* sctId = dynamic_cast<const FaserSCT_ID*>(getIdHelper());
+    if (nullptr == sctId) return false;
+    return ( (sctId->is_sct(m_id)) && (sctId->station(m_id) == 0) );
+  }
+
+  bool
+  SiDetectorElement::isUpstream() const
+  {
+    const FaserSCT_ID* sctId = dynamic_cast<const FaserSCT_ID*>(getIdHelper());
+    if (nullptr == sctId) return false;
+    return ( (sctId->is_sct(m_id)) && (sctId->station(m_id) == 1) );
+  }
+
+  bool
+  SiDetectorElement::isCentral() const
+  {
+    const FaserSCT_ID* sctId = dynamic_cast<const FaserSCT_ID*>(getIdHelper());
+    if (nullptr == sctId) return false;
+    return ( (sctId->is_sct(m_id)) && (sctId->station(m_id) == 2) );
+  }
+
+  bool
+  SiDetectorElement::isDownstream() const
+  {
+    const FaserSCT_ID* sctId = dynamic_cast<const FaserSCT_ID*>(getIdHelper());
+    if (nullptr == sctId) return false;
+    return ( (sctId->is_sct(m_id)) && (sctId->station(m_id) == 3) );
+  }
+
+
 } // namespace TrackerDD
diff --git a/graphics/VTI12/VTI12Plugins/VTI12FaserPlugin/CMakeLists.txt b/graphics/VTI12/VTI12Plugins/VTI12FaserPlugin/CMakeLists.txt
index 0b3f7d70f2a29d83f80db64ff20521b05b90d69c..da838e26dfb3c16ffacee2b4a6f6c851467bfaff 100644
--- a/graphics/VTI12/VTI12Plugins/VTI12FaserPlugin/CMakeLists.txt
+++ b/graphics/VTI12/VTI12Plugins/VTI12FaserPlugin/CMakeLists.txt
@@ -16,4 +16,4 @@ atlas_add_library( VTI12FaserPlugin
    VTI12FaserPlugin/*.h src/*.cxx src/*.qrc 
    PUBLIC_HEADERS VTI12FaserPlugin
    LINK_LIBRARIES Qt5::Core Qt5::Gui Qt5::Widgets
-   PRIVATE_LINK_LIBRARIES VP1Base VTI12GuideLineSystems VTI12GeometrySystems VTI12SimHitSystems VTI12RawDataSystems VTI12TrackSystems)
+   PRIVATE_LINK_LIBRARIES VP1Base VTI12GuideLineSystems VTI12GeometrySystems VTI12SimHitSystems VTI12RawDataSystems VTI12PRDSystems VTI12TrackSystems)
diff --git a/graphics/VTI12/VTI12Plugins/VTI12FaserPlugin/src/VP1FaserChannel.cxx b/graphics/VTI12/VTI12Plugins/VTI12FaserPlugin/src/VP1FaserChannel.cxx
index 478b929050e0daab47b4b7a3df1b3bd375cc142e..daef7351c106196be0292cacac462645034360a4 100755
--- a/graphics/VTI12/VTI12Plugins/VTI12FaserPlugin/src/VP1FaserChannel.cxx
+++ b/graphics/VTI12/VTI12Plugins/VTI12FaserPlugin/src/VP1FaserChannel.cxx
@@ -18,11 +18,12 @@
 #include "VTI12GuideLineSystems/VP1GuideLineSystem.h"
 #include "VTI12SimHitSystems/VP1SimHitSystem.h"
 #include "VTI12RawDataSystems/VP1RawDataSystem.h"
+#include "VTI12PRDSystems/VP1PrepRawDataSystem.h"
 #include "VP1Base/VP1QtUtils.h"
 
 VP1FaserChannel::VP1FaserChannel()
   : IVP13DStandardChannelWidget(VP1CHANNELNAMEINPLUGIN(VP1FaserChannel,"Faser"),
-				"This channel shows geometry, hits and tracks.",
+				"This channel shows geometry, hits, clusters, spacepoints and tracks.",
 				"Dave Casper dcasper@uci.edu")
 {
 }
@@ -30,6 +31,7 @@ VP1FaserChannel::VP1FaserChannel()
 void VP1FaserChannel::init()
 {
   addSystem(new VP1TrackSystem);
+  addSystem(new VP1PrepRawDataSystem);
   addSystem(new VP1RawDataSystem);
   addSystem(new VP1SimHitSystem);
   addSystem(new VP1GeometrySystem);
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/CMakeLists.txt b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c065a1849b34c23bfae3986eac831a6c86dbea9a
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+
+# Declare the package name:
+atlas_subdir( VTI12PRDSystems )
+
+# External dependencies:
+find_package( Coin3D )
+find_package( Qt5 COMPONENTS Core Gui Widgets)
+find_package( GeoModel COMPONENTS GeoModelKernel )
+
+# Generate UI files automatically:
+set( CMAKE_AUTOUIC TRUE )
+# Generate MOC files automatically:
+set( CMAKE_AUTOMOC TRUE )
+
+# Component(s) in the package:
+atlas_add_library( VTI12PRDSystems VTI12PRDSystems/*.h src/*.cxx
+   PUBLIC_HEADERS VTI12PRDSystems
+   PRIVATE_INCLUDE_DIRS ${COIN3D_INCLUDE_DIRS}
+   ${CMAKE_CURRENT_BINARY_DIR}
+   LINK_LIBRARIES ${GEOMODEL_LIBRARIES} GeoPrimitives TrackerPrepRawData TrackerReadoutGeometry TrkPrepRawData TrackerSpacePoint VP1Base VTI12Utils Qt5::Core Qt5::Gui
+   PRIVATE_LINK_LIBRARIES ${COIN3D_LIBRARIES} AthContainers EventPrimitives GeoModelUtilities TrackerIdentifier  TrkCompetingRIOsOnTrack TrkMeasurementBase TrkRIO_OnTrack TrkSegment TrkSurfaces TrkTrack VTI12GuideLineSystems VP1HEPVis )
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandleBase.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandleBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..b28bfea064a4ecef295aae29bd136d3f4f60f962
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandleBase.h
@@ -0,0 +1,154 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+#ifndef PRDCOLLECTIONHANDLEBASE_H
+#define PRDCOLLECTIONHANDLEBASE_H
+
+#include "VP1Base/VP1StdCollection.h"
+#include "VTI12PRDSystems/PRDDetTypes.h"
+#include <vector>
+
+class PRDSysCommonData;
+class PRDSystemController;
+class PRDHandleBase;
+class VP1ExtraSepLayerHelper;
+class SoSeparator;
+class SoMaterial;
+namespace Trk { class PrepRawData; }
+
+class PRDCollHandleBase : public VP1StdCollection {
+
+  Q_OBJECT
+
+public:
+
+  PRDCollHandleBase(PRDDetType::Type,PRDSysCommonData*,const QString& key) ;
+  virtual void init(VP1MaterialButtonBase* mat=0);//reimplementations must start with a call to this.
+  virtual ~PRDCollHandleBase();
+
+  //Called from init(). Should set current cut values and
+  //connections with controller to monitor future changes. Reimplement
+  //the ..Specific method to setup subsystem specific settings.
+  void setupSettingsFromController(PRDSystemController*);
+protected:
+  virtual void setupSettingsFromControllerSpecific(PRDSystemController*) {};
+public:
+
+  ///////////////////////////////////////////////////////////
+  //  For loading the data and resetting after each event: //
+  ///////////////////////////////////////////////////////////
+
+  virtual bool load();
+
+  PRDSysCommonData * common() const { return m_common; }
+
+  //For use by the handles:
+  VP1ExtraSepLayerHelper * sephelperDetailedNodes () const;
+  VP1ExtraSepLayerHelper * sephelperSimpleNodes() const;
+  SoMaterial * highLightMaterial() const;
+
+  //If highlight outliers is set, other highlight modes (TRT HT, ...) will be ignored.
+  //Other highlight modes are indicated by the return value of highLight() in the PRDHandleBase's
+  bool highLightOutliers() const;
+  double highLightWeight() const { return m_highlightweight; }
+
+  bool drawErrors() const;
+  bool drawRDOs() const;
+
+
+  //Detail level of shown prds:
+  enum DETAIL { SIMPLE, DETAILED, AUTO };//AUTO => Use Level of detail (SoLOD nodes) to switch between simple/detailed shapes.
+  static QString toString(const DETAIL&);
+
+  void getLODSeparators(int index, VP1ExtraSepLayerHelper*& sephelper_detail,VP1ExtraSepLayerHelper*& sephelper_simple);
+
+  enum COLOURMETHOD { ByTechOnly, BySegment, ByTrack, BySegmentAndTrack };
+  static QString toString(const COLOURMETHOD&);
+  COLOURMETHOD colourMethod() const { return m_colourmethod; }
+  bool colourByTracks() const { return m_colourmethod==ByTrack||m_colourmethod==BySegmentAndTrack; }
+  bool colourBySegments() const { return m_colourmethod==BySegment||m_colourmethod==BySegmentAndTrack; }
+
+  DETAIL detailLevel() const;
+  bool simpleDetailLevel() const { return detailLevel()==SIMPLE; }
+signals:
+  void detailLevelChanged();
+public slots:
+  void setGeneralPRDDetailLevel(DETAIL);
+  void setColourMethod(PRDCollHandleBase::COLOURMETHOD);
+  void setDrawErrors(bool);
+  void setDrawRDOs(bool);
+  void setHighLightOutliers(bool);
+  void setHighLightWeight(const double&);
+  void setAllowedEta(const VP1Interval&);
+  void setAllowedPhi(const QList<VP1Interval>&);
+
+private slots:
+  void detailComboBoxItemChanged();
+
+protected:
+  virtual PRDHandleBase* addPRD(const Trk::PrepRawData*) = 0;//Return pointer to the handle. Base class (this) will own it.
+
+  virtual DETAIL defaultDetailLevel() const { return AUTO; }
+  //Use to loop over prds in derived classes:
+  void addHandle(PRDHandleBase*);//All handles must be added here (so they can be retrieved by the next methods).
+  std::vector<PRDHandleBase*>& getPrdHandles();
+  const std::vector<PRDHandleBase*>& getPrdHandles() const;
+
+  virtual void postLoadInitialisation() {}
+  virtual bool cut(PRDHandleBase*) = 0;//Return true if should be shown (based on various cuts), false otherwise.
+  virtual void eraseEventDataSpecific() {}
+
+  //Utility (fixme: put in utility class elsewhere).
+  template <class T> void cleanupPtrContainer(T&) const;//Delete pointers and calls .clear()
+  //   template <class T> void cleanupNodeContainer(T&) const;//unref's pointers and calls .clear()
+
+  virtual float lodArea() const { return 500.0f*500.0f; }//Reimplement Override to tune LOD shift for a given collection.
+
+  void recheckCutStatus(PRDHandleBase*);//Call in derived classes for handles that might be effected by a change in cuts.
+
+  //Convenience methods which can be called from derived classes (but specialised procedures might be more optimal)
+  void recheckCutStatusOfAllHandles();
+  void recheckCutStatusOfAllVisibleHandles();
+  void recheckCutStatusOfAllNotVisibleHandles();
+
+public:
+  int nShownHandles() { return m_nshownhandles; }
+
+  //For use only by PRDHandleBase::setVisible(..):
+  void incrementNShownHandles() { ++m_nshownhandles; }
+  void decrementNShownHandles() { --m_nshownhandles; }
+
+protected:
+  qint32 provideCollTypeID() const;
+  virtual QString provideText() const;
+  virtual void assignDefaultMaterial(SoMaterial*) const;
+  virtual QColor defaultColor() const = 0;//Will be used in assignDefaultMaterial
+  QString provideSection() const;
+  QString provideSectionToolTip() const;
+  QList<QWidget*> provideExtraWidgetsForGuiRow() const;
+  QByteArray extraWidgetsState() const;
+  void setExtraWidgetsState(const QByteArray&);
+private slots:
+  void collVisibilityChanged(bool);
+private:
+
+  class Imp;
+  Imp * m_d;
+
+  PRDSysCommonData * m_common;
+  int m_nshownhandles;
+  COLOURMETHOD m_colourmethod;
+  double m_highlightweight;
+};
+
+//Fixme: Move elsewhere (at least to our cxx!):
+template <class T> void PRDCollHandleBase::cleanupPtrContainer(T&t) const
+{
+  typename T::iterator it(t.begin()), itE(t.end());
+  for (;it!=itE;++it)
+    delete *it;
+  t.clear();
+}
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandle_SCT.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandle_SCT.h
new file mode 100644
index 0000000000000000000000000000000000000000..5aed81dfa215ef0c967091edce87a3212ccda0c4
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandle_SCT.h
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PRDCOLLHANDLE_SCT_H
+#define PRDCOLLHANDLE_SCT_H
+
+#include "VTI12PRDSystems/PRDCollHandleBase.h"
+#include "VTI12PRDSystems/PRDCommonFlags.h"
+
+class PRDCollHandle_SCT : public PRDCollHandleBase {
+
+  Q_OBJECT
+
+public:
+
+  static QStringList availableCollections(IVP1System*);//For the collection widget.
+
+  PRDCollHandle_SCT(PRDSysCommonData *,const QString& key);
+  virtual ~PRDCollHandle_SCT();
+
+public slots:
+  void setPartsFlags(PRDCommonFlags::TrackerPartsFlags);//BarrelA, BarrelC, EndcapA, EndcapC
+  void setExcludeIsolatedClusters(bool);
+
+protected:
+  virtual PRDHandleBase * addPRD(const Trk::PrepRawData*) override;
+  virtual bool cut(PRDHandleBase*) override;
+
+  virtual void eraseEventDataSpecific() override;
+  virtual void postLoadInitialisation() override;
+  virtual void setupSettingsFromControllerSpecific(PRDSystemController*) override;
+  virtual float lodArea() const override { return 800.0f*800.0f; }
+  virtual QColor defaultColor() const override;
+
+private:
+
+  class Imp;
+  Imp * m_d;
+
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandle_SpacePoints.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandle_SpacePoints.h
new file mode 100644
index 0000000000000000000000000000000000000000..3727c491885bccee19611358d1abe1cfa0d2cdf7
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCollHandle_SpacePoints.h
@@ -0,0 +1,56 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Header file for class PRDCollHandle_SpacePoints           //
+//                                                            //
+//  Description: Collection handles for space points.         //
+//               For historical reasons this inherits from    //
+//               the PRD class.                               //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: September 2008                           //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#ifndef PRDCOLLHANDLE_SPACEPOINTS_H
+#define PRDCOLLHANDLE_SPACEPOINTS_H
+
+#include "VTI12PRDSystems/PRDCollHandleBase.h"
+#include "VTI12PRDSystems/PRDCommonFlags.h"
+
+class PRDCollHandle_SpacePoints : public PRDCollHandleBase {
+
+  Q_OBJECT
+
+public:
+
+  static QStringList availableCollections(IVP1System*);//For the collection widget.
+
+  PRDCollHandle_SpacePoints(PRDSysCommonData*,const QString& key);
+  virtual ~PRDCollHandle_SpacePoints();
+
+protected:
+  virtual PRDHandleBase* addPRD(const Trk::PrepRawData*) override { return 0; }
+  virtual bool load() override;
+  virtual bool cut(PRDHandleBase*) override;
+  virtual void eraseEventDataSpecific() override;
+  virtual void postLoadInitialisation() override;
+  virtual void setupSettingsFromControllerSpecific(PRDSystemController*) override;
+  virtual float lodArea() const override { return 800.0f*800.0f; }
+  virtual QColor defaultColor() const override;
+
+public slots:
+  void setPartsFlags(PRDCommonFlags::TrackerPartsFlags);//Interface, Upstream, Central, Downstream
+
+private:
+
+  class Imp;
+  Imp * m_d;
+
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCommonFlags.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCommonFlags.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a82f911cb779cea06922d5b6af52c32ada769ce
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDCommonFlags.h
@@ -0,0 +1,40 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Common flags shared by several subsystems                 //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: November 2007                            //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#ifndef PRDCOMMONFLAGS_H
+#define PRDCOMMONFLAGS_H
+
+#include <QFlags>
+
+class PRDCommonFlags {
+public:
+
+  enum TrackerPartsFlag {
+    None           = 0x000000,
+    Interface      = 0x000001,
+    Upstream       = 0x000002,
+    Central        = 0x000004,
+    Downstream     = 0x000008,
+    AllBaseline    = 0x00000E,
+    All            = 0x00000F
+  };
+  Q_DECLARE_FLAGS(TrackerPartsFlags, TrackerPartsFlag)
+
+private:
+  PRDCommonFlags();
+  ~PRDCommonFlags();
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(PRDCommonFlags::TrackerPartsFlags)
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDDetTypes.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDDetTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc3c0f31a866a1d381f7631118438aa88bcebaf9
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDDetTypes.h
@@ -0,0 +1,25 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+#ifndef PRDDETTYPES_H
+#define PRDDETTYPES_H
+
+#include <QString>
+
+class PRDDetType {
+public:
+  enum Type {
+    SCT, SpacePoints
+  };
+  static QString typeToString(const Type&);
+  static Type stringToType(const QString&str, bool & status);
+  static qint32 typeToInt(const Type& t);
+  static Type intToType(const qint32&i, bool & status);
+
+private:
+  PRDDetType();
+};
+
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandleBase.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandleBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..c91208db1851db786955f52347e5479703482b4d
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandleBase.h
@@ -0,0 +1,87 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PRDHANDLEBASE_H
+#define PRDHANDLEBASE_H
+
+//Fixme: check and doublecheck how to reduce memory used per prd (also includes maps in collhandle).
+
+#include "VTI12PRDSystems/PRDSysCommonData.h"
+
+#include "GeoModelKernel/GeoPVConstLink.h"
+
+//#include "CLHEP/Geometry/Transform3D.h"
+#include "GeoPrimitives/GeoPrimitives.h"
+
+#include <QFlags>
+#include <QStringList>
+
+
+
+
+class PRDCollHandleBase;
+class SoMaterial;
+class SoNode;
+class SoTransform;
+class SoSeparator;
+
+namespace Trk {
+  class PrepRawData;
+}
+
+class TracksAndSegments;
+
+class PRDHandleBase {
+public:
+
+  PRDHandleBase(PRDCollHandleBase*);
+  virtual ~PRDHandleBase();
+
+  void setVisible(bool);//use by the collection handle.
+  bool visible() const { return m_visible; }
+  virtual void buildShapes(SoNode*&shape_simple, SoNode*&shape_detailed) = 0;
+  virtual int regionIndex() { return 0; }//prds near each other should return same index (used for optimal LOD usage in AUTO detail mode) (only called once/event)
+  virtual bool highLight() const { return false; }//Return true to get hit highlighted (for e.g. a TRT hits with HT).
+                                            //Outlier highlighting overrides this and is handled in the base classes.
+  virtual bool transformUsesSurfacePositionOnly() const { return false; }//Override and return true if should use just the surface position.
+
+  //Return current shapes (0 if not built at the moment):
+  SoSeparator* sepSimple() const;
+  SoSeparator* sepDetailed() const;
+
+  PRDSysCommonData * common() const { return m_common; }
+
+  virtual Amg::Vector3D center() const;//Default impl. returns positionPRD()
+  Amg::Vector3D positionPRD() const;// The center of the getPRD()
+  Amg::Vector3D positionSecondPRD() const;//The center of the getSecondPRD(). returns (0,0,0) if not available.
+
+  //For PRDCollHandleBase only:
+  Amg::Transform3D getTransform_CLHEP() const;
+  virtual SoTransform * createTransform() const;
+  void update3DObjects();//Call whenever some setting changes in a way which requires changes to the shape of the 3D representation of the prd.
+  void updateMaterial();
+
+  virtual QStringList clicked() const;//Called when user selects the node. The returned strings will be displayed in the textbox.
+
+  PRDCollHandleBase * collHandle() const;
+
+  virtual const Trk::PrepRawData * getPRD() const = 0;//Reimplement to allow access to prd pointer in a generic way.
+  virtual const Trk::PrepRawData * getSecondPRD() const { return 0; }//For SCT spacepoints
+
+  virtual bool isSane() const {return true;} //!< Returns false if the PRD is not safe to draw
+private:
+
+  // Illegal to copy/assign a PRDHandleBase:
+  PRDHandleBase(const PRDHandleBase & );
+  PRDHandleBase & operator= (const PRDHandleBase & );
+
+  class Imp;
+  Imp * m_d;
+  PRDSysCommonData * m_common;
+//   inline void registerTransform(SoTransform*);
+  bool m_visible;//Here for inlining
+
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandle_SCT.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandle_SCT.h
new file mode 100644
index 0000000000000000000000000000000000000000..59aad50caf42a92f7a4245285642c0c6239dc584
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandle_SCT.h
@@ -0,0 +1,34 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+#ifndef PRDHANDLE_SCT_H
+#define PRDHANDLE_SCT_H
+
+#include "VTI12PRDSystems/PRDHandleBase.h"
+#include "TrackerPrepRawData/FaserSCT_Cluster.h"
+
+class PRDCollHandle_SCT;
+
+class PRDHandle_SCT : public PRDHandleBase {
+public:
+
+  PRDHandle_SCT(PRDCollHandle_SCT*,const Tracker::FaserSCT_Cluster*);
+  virtual ~PRDHandle_SCT() {};
+
+  void buildShapes(SoNode*&shape_simple, SoNode*&shape_detailed);
+  int regionIndex();
+
+  const Tracker::FaserSCT_Cluster * cluster() const { return m_cluster; }
+  const Trk::PrepRawData * getPRD() const { return m_cluster; }
+  bool isInterface()  const { return m_cluster->detectorElement()->isInterface(); }
+  bool isUpstream()   const { return m_cluster->detectorElement()->isUpstream(); }
+  bool isCentral()    const { return m_cluster->detectorElement()->isCentral(); }
+  bool isDownstream() const { return m_cluster->detectorElement()->isDownstream(); }
+
+private:
+  const Tracker::FaserSCT_Cluster* m_cluster;
+
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandle_SpacePoint.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandle_SpacePoint.h
new file mode 100644
index 0000000000000000000000000000000000000000..55fcc919ee95d632ab335b7e9cdbb34e2cf8c67e
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDHandle_SpacePoint.h
@@ -0,0 +1,70 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Header file for class PRDHandle_SpacePoint                //
+//                                                            //
+//  Description: Handles for SpacePoints (not really "PRDs")  //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: September 2008                           //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#ifndef PRDHANDLE_SPACEPOINT_H
+#define PRDHANDLE_SPACEPOINT_H
+
+#include "VTI12PRDSystems/PRDHandleBase.h"
+
+#include "TrackerReadoutGeometry/SiDetectorElement.h"
+#include "TrackerSpacePoint/FaserSCT_SpacePoint.h"
+#include "TrkPrepRawData/PrepRawData.h"
+
+#include "GeoPrimitives/GeoPrimitives.h"
+
+
+
+// namespace Trk { class SpacePoint; }
+class PRDCollHandle_SpacePoints;
+
+class PRDHandle_SpacePoint : public PRDHandleBase {
+public:
+
+  PRDHandle_SpacePoint(PRDCollHandle_SpacePoints*, const Tracker::FaserSCT_SpacePoint*);
+  virtual ~PRDHandle_SpacePoint();
+
+  void buildShapes(SoNode*&shape_simple, SoNode*&shape_detailed);
+  int regionIndex();
+
+  Amg::Vector3D center() const { return m_sp->globalPosition(); }
+
+//SCT spacepoints have two clusters, Pixels one:
+  bool isSCT() { return getSecondPRD(); }
+
+  const Tracker::FaserSCT_SpacePoint * spacePoint() const { return m_sp; }
+  const Trk::PrepRawData * getPRD() const { return m_sp->clusterList().first; }
+  const Trk::PrepRawData * getSecondPRD() const { return m_sp->clusterList().second; }
+  bool isInterface()  const { return dynamic_cast<const TrackerDD::SiDetectorElement*>(getPRD()->detectorElement())->isInterface(); }
+  bool isUpstream()   const { return dynamic_cast<const TrackerDD::SiDetectorElement*>(getPRD()->detectorElement())->isUpstream(); }
+  bool isCentral()    const { return dynamic_cast<const TrackerDD::SiDetectorElement*>(getPRD()->detectorElement())->isCentral(); }
+  bool isDownstream() const { return dynamic_cast<const TrackerDD::SiDetectorElement*>(getPRD()->detectorElement())->isDownstream(); }
+  // bool isBarrel() const
+  // { return static_cast<const InDetDD::SiDetectorElement*>(getPRD()->detectorElement())->isBarrel(); }
+  // bool isPositiveZ() const { return m_sp->globalPosition().z() > 0.0; }
+
+private:
+
+  // Uncomment to make it illegal to copy/assign a PRDHandle_SpacePoint:
+  // PRDHandle_SpacePoint( const PRDHandle_SpacePoint & );
+  // PRDHandle_SpacePoint & operator= ( const PRDHandle_SpacePoint & );
+
+  const Tracker::FaserSCT_SpacePoint* m_sp;
+  class Imp;
+  Imp * m_d;
+
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDSysCommonData.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDSysCommonData.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c522891b4234932237f9d0f793cfe9b49e72063
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDSysCommonData.h
@@ -0,0 +1,75 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Header file for class PRDSysCommonData                    //
+//                                                            //
+//  Description: Common pointers, data, node-to-object maps   //
+//               etc. for the prd system                      //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: July 2008                                //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#ifndef PRDSYSCOMMONDATA_H
+#define PRDSYSCOMMONDATA_H
+
+#include "VP1Base/VP1HelperClassBase.h"
+class IVP13DSystem;
+class HitsSoNodeManager;
+class PRDSystemController;
+class VP1SoMaterialMixer;
+// class InDetProjHelper;
+class PRDTrackSegmentHelper;
+class SoTransform;
+class SoPath;
+class PRDHandleBase;
+namespace Trk { class PrepRawData; }
+
+class PRDSysCommonData : public VP1HelperClassBase {
+public:
+
+  PRDSysCommonData(IVP13DSystem *, PRDSystemController*);
+  virtual ~PRDSysCommonData();
+
+  IVP13DSystem * system() const;
+  HitsSoNodeManager * nodeManager() const;
+  PRDSystemController * controller() const;
+  VP1SoMaterialMixer * materialMixer() const;
+//   InDetProjHelper * indetProjHelper_SCT() const;
+  PRDTrackSegmentHelper * trackAndSegmentHelper() const;
+
+  void registerTransform2Handle(SoTransform*transform,PRDHandleBase*handle);
+  void registerPRD2Handle(const Trk::PrepRawData*prd,PRDHandleBase*handle);
+  //Access pick->handle association (and pop path):
+  PRDHandleBase * pickedPathToHandle( SoPath*pickedPath );
+
+  void clearEventData(); //Deletes AscObjSelectionManager
+
+private:
+
+  class Imp;
+  Imp * m_d;
+
+  IVP13DSystem * m_3dsystem;
+  HitsSoNodeManager * m_nodeManager;
+  PRDSystemController * m_controller;
+  VP1SoMaterialMixer * m_materialMixer;
+//   InDetProjHelper * m_indetProjHelper_SCT;
+
+  PRDTrackSegmentHelper * m_trackAndSegmentHelper;
+
+};
+
+inline IVP13DSystem* PRDSysCommonData::system() const { return m_3dsystem; }
+inline HitsSoNodeManager* PRDSysCommonData::nodeManager() const { return m_nodeManager; }
+inline PRDSystemController * PRDSysCommonData::controller() const { return m_controller; }
+inline VP1SoMaterialMixer * PRDSysCommonData::materialMixer() const { return m_materialMixer; }
+// inline InDetProjHelper * PRDSysCommonData::indetProjHelper_SCT() const { return m_indetProjHelper_SCT; }
+inline PRDTrackSegmentHelper * PRDSysCommonData::trackAndSegmentHelper() const { return m_trackAndSegmentHelper; }
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDSystemController.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDSystemController.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5455f38db8e97755a4952ffc54a9116709644ca
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDSystemController.h
@@ -0,0 +1,149 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Header file for class PRDSystemController                 //
+//                                                            //
+//  Description: Controller widget for the PRD system.        //
+//               Keeps all nasty gui stuff internally, and    //
+//               only presents the actual interesting data    //
+//               with specialised access methods and signals. //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: November 2007                            //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#ifndef PRDSYSTEMCONTROLLER_H
+#define PRDSYSTEMCONTROLLER_H
+
+#include "VP1Base/VP1Controller.h"
+#include "VTI12PRDSystems/PRDCollHandleBase.h"
+#include "VTI12PRDSystems/PRDCommonFlags.h"
+#include "VTI12PRDSystems/PRDDetTypes.h"
+// #include "VTI12Utils/InDetProjFlags.h"
+#include <QByteArray>
+#include <set>
+class VP1CollectionWidget;
+class SoMaterial;
+class SoGroup;
+
+class PRDSystemController : public VP1Controller {
+
+  Q_OBJECT
+
+public:
+
+  PRDSystemController(IVP1System * sys);
+  virtual ~PRDSystemController();
+
+  void actualRestoreSettings(VP1Deserialise&);
+  int currentSettingsVersion() const;
+  void actualSaveSettings(VP1Serialise&) const;
+
+  //Use by the system to access the collection widget, which again is
+  //the main entry point for communication with the prd collections
+  //(loading/hiding/etc.).
+  VP1CollectionWidget * collWidget() const;
+
+  SoGroup * drawOptions(PRDDetType::Type) const;
+
+  SoMaterial * getHighLightMaterial();
+  double highLightMaterialWeight() const;//value indicates relative weight
+				   //of highlight material. 0.0
+				   //obviously means no high light
+				   //material, and values > 999.0
+				   //should be taken to mean infinite
+				   //weight
+
+  //Stateless on-click info:
+  bool printInfoOnClick() const;
+  bool zoomOnClick() const;
+  bool muonOrientToChambersOnClick() const;
+
+  //Access relevant information of controller:
+  PRDCollHandleBase::COLOURMETHOD colourMethod() const;
+
+  bool selectionModeMultiple() const;
+  bool showSelectionLine() const;
+  SoMaterial * getMultiSelectionLineMaterial() const;
+
+  bool highLightOutliers() const;
+  bool drawErrors() const;
+  bool drawRDOs() const;
+
+  bool projectSCTHits() const;
+
+  //Cuts;
+  VP1Interval cutAllowedEta() const;
+  QList<VP1Interval> cutAllowedPhi() const;//All off: empty list. All on: list with one entry: ]-inf,inf[
+  PRDCommonFlags::TrackerPartsFlags trackerPartsFlags() const;
+  bool sctExcludeIsolatedClusters() const;
+  //Used ID parts:
+//   InDetProjFlags::DetTypeFlags inDetPartsUsingProjections() const;
+
+  std::set<PRDDetType::Type> shownCollectionTypes() const;
+
+signals:
+  //The following signals are emitted when any of the relevant information in the controller changes value:
+
+  //Display modes and projections:
+  //  void generalPRDDetailLevelChanged(PRDCollHandleBase::DETAIL);
+  void colourMethodChanged(PRDCollHandleBase::COLOURMETHOD);
+  void selectionModeMultipleChanged(bool);
+  void showSelectionLineChanged(bool);
+  void clearSelection() const;//only signal
+  void highLightMaterialWeightChanged(const double&);
+  void highLightOutliersChanged(bool);
+  void drawErrorsChanged(bool);
+  void drawRDOsChanged(bool);
+//   void projectSCTHitsChanged(bool);
+
+  //Cuts:
+  void cutAllowedEtaChanged(const VP1Interval&);
+  void cutAllowedPhiChanged(const QList<VP1Interval>&);
+  void trackerPartsFlagsChanged(PRDCommonFlags::TrackerPartsFlags);
+  void sctExcludeIsolatedClustersChanged(bool);
+
+  //Used ID parts:
+//   void inDetPartsUsingProjectionsChanged(InDetProjFlags::DetTypeFlags);
+  void shownCollectionTypesChanged(const std::set<PRDDetType::Type>&);
+  
+private:
+
+  class Imp;
+  Imp * m_d;
+
+  //For verbose output:
+  template <class T> static QString toString( const T& t ) { return VP1Controller::toString(t); }//unhide base methods
+
+  static QString toString( const PRDCollHandleBase::DETAIL& par ) { return PRDCollHandleBase::toString(par); }
+  static QString toString( const PRDCollHandleBase::COLOURMETHOD& par ) { return PRDCollHandleBase::toString(par); }
+  static QString toString( const std::set<PRDDetType::Type>& s ) { return "["+str(s.size())+" types]"; }
+
+
+private slots:
+  void emitClearSelection();
+  // void updateHighlightGui();
+  void possibleChange_colourMethod();
+  void possibleChange_selectionModeMultiple();
+  void possibleChange_showSelectionLine();
+  void possibleChange_highLightMaterialWeight();
+  void possibleChange_highLightOutliers();
+  void possibleChange_drawErrors();
+  void possibleChange_drawRDOs();
+  void possibleChange_cutAllowedEta();
+  void possibleChange_cutAllowedPhi();
+  void possibleChange_trackerPartsFlags();
+  void possibleChange_sctExcludeIsolatedClusters();
+  
+//   void possibleChange_projectSCTHits();
+//   void possibleChange_inDetPartsUsingProjections();
+  void possibleChange_shownCollectionTypes();
+
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDTrackSegmentHelper.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDTrackSegmentHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa3880118207b8aaf86e0a112a1c789c18955722
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/PRDTrackSegmentHelper.h
@@ -0,0 +1,67 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Header file for class PRDTrackSegmentHelper               //
+//                                                            //
+//  Description: Class for keeping track of visible tracks    //
+//               and segments and their materials, for        //
+//               colour-prd-by-XXX modes.                     //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: December 2007                            //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#ifndef PRDTRACKSEGMENTHELPER_H
+#define PRDTRACKSEGMENTHELPER_H
+
+#include "VP1Base/VP1HelperClassBase.h"
+#include <QObject>
+#include <vector>
+#include <map>
+
+class SoMaterial;
+class PRDHandleBase;
+namespace Trk
+{
+  class Track;
+  class Segment;
+  class PrepRawData;
+}
+
+class PRDTrackSegmentHelper : public QObject, public VP1HelperClassBase {
+
+  Q_OBJECT
+
+public:
+
+  PRDTrackSegmentHelper( std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >* prd2handle,
+			 IVP1System* sys = 0, QObject * parent = 0);
+  virtual ~PRDTrackSegmentHelper();
+
+  //This is used to inform the class of changes in visible tracks and segments:
+  void visibleTracksChanged(const std::vector< std::pair<const Trk::Track*, const SoMaterial*> >&);
+  void visibleSegmentsChanged(const std::vector< std::pair<const Trk::Segment*, const SoMaterial*> >&);
+
+  SoMaterial * trackMaterial(const Trk::Track*) const;
+  SoMaterial * segmentMaterial(const Trk::Segment*) const;
+  class TracksAndSegments {
+  public:
+    inline TracksAndSegments(const std::vector<const Trk::Track*>&,const std::vector<const Trk::Track*>&,const std::vector< const Trk::Segment* >& );
+    std::vector<const Trk::Track*> tracks;//tracks using the given prd in the fit
+    std::vector<const Trk::Track*> tracks_outliers;//tracks where the given prd is associated as 'outlier'
+    std::vector< const Trk::Segment* > segments;//segments using the given prd
+  };
+  const TracksAndSegments * tracksAndSegments(const Trk::PrepRawData*);//0 means no tracks/segments
+private:
+
+  class Imp;
+  Imp * m_d;
+
+};
+
+#endif
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/VP1PrepRawDataSystem.h b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/VP1PrepRawDataSystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4957860c7fd71b769a6285148ed08570dc62471
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/VTI12PRDSystems/VP1PrepRawDataSystem.h
@@ -0,0 +1,69 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef VP1PREPRAWDATASYSTEM_H
+#define VP1PREPRAWDATASYSTEM_H
+
+#include "VP1Base/IVP13DSystemSimple.h"
+#include "GeoModelKernel/GeoPVConstLink.h"//It would be good to get rid of this.
+// #include "VTI12Utils/InDetProjFlags.h"
+#include <vector>
+#include <QList>
+
+class SoMaterial;
+namespace Trk
+{
+  class Track;
+  class Segment;
+  class PrepRawData;
+}
+
+class VP1PrepRawDataSystem : public IVP13DSystemSimple {
+
+  Q_OBJECT
+
+public:
+  VP1PrepRawDataSystem();
+  virtual ~VP1PrepRawDataSystem();
+  void buildEventSceneGraph(StoreGateSvc* sg, SoSeparator *root);
+  void buildPermanentSceneGraph(StoreGateSvc* detstore, SoSeparator *root);//For TRT Projection surfaces
+  void systemcreate(StoreGateSvc* detstore);
+  void systemerase();
+  void systemuncreate();
+
+  void userPickedNode(SoNode* pickedNode, SoPath * pickedPath);
+  void userSelectedSingleNode(SoCooperativeSelection*, SoNode* , SoPath*);//SINGLE
+  void userDeselectedSingleNode(SoCooperativeSelection*, SoNode* , SoPath*);//SINGLE
+  void userChangedSelection(SoCooperativeSelection*, QSet<SoNode*>, QSet<SoPath*>);//TOGGLE/SHIFT
+  void userClickedOnBgd();
+
+  virtual void deselectAll(SoCooperativeSelection* exception_sel = 0);
+
+  virtual QWidget * buildController();
+
+  QByteArray saveState();
+  void restoreFromState(QByteArray);
+
+public slots:
+  void visibleTracksChanged(const std::vector< std::pair<const Trk::Track*, const SoMaterial*> >&);
+  void visibleSegmentsChanged(const std::vector< std::pair<const Trk::Segment*, const SoMaterial*> >&);
+//   void setApplicableIDProjections( InDetProjFlags::InDetProjPartsFlags sct );
+
+signals:
+//   void usedIDProjectionsChanged( InDetProjFlags::DetTypeFlags );
+  void selectedPRDsChanged(const QList<const Trk::PrepRawData*>&);
+
+private slots:
+//   void emitUsedIDProjectionsChanged(InDetProjFlags::DetTypeFlags);//for controller
+  void selectionModeChanged();
+  void selectionVisualsChanged();
+  void clearSelection();
+  void updateSelectionVisualsAndPossiblyEmitPRDList();
+private:
+  class Imp;
+  Imp * m_d;
+};
+
+#endif
+
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandleBase.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandleBase.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ab77031616aea40c79363999e224542b4c124987
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandleBase.cxx
@@ -0,0 +1,832 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+#include "VTI12PRDSystems/PRDCollHandleBase.h"
+#include "VTI12PRDSystems/PRDSysCommonData.h"
+#include "VTI12PRDSystems/PRDHandleBase.h"
+#include "VTI12PRDSystems/VP1PrepRawDataSystem.h"
+#include "VTI12PRDSystems/PRDSystemController.h"
+#include "VTI12Utils/VP1JobConfigInfo.h"
+#include "VTI12Utils/VP1SGAccessHelper.h"
+#include "VTI12Utils/VP1SGContentsHelper.h"
+#include "VP1Base/VP1ExtraSepLayerHelper.h"
+#include "VP1Base/VP1Serialise.h"
+#include "VP1Base/VP1QtInventorUtils.h"
+#include "VP1Base/VP1Deserialise.h"
+#include "VP1Base/VP1Msg.h"
+
+#include "TrackerPrepRawData/FaserSCT_ClusterContainer.h"
+
+#include "EventPrimitives/EventPrimitives.h"
+
+#include <Inventor/nodes/SoSeparator.h>
+#include <Inventor/nodes/SoLevelOfDetail.h>
+#include <Inventor/nodes/SoMaterial.h>
+
+#include <QComboBox>
+
+//____________________________________________________________________
+class PRDCollHandleBase::Imp {
+public:
+  PRDCollHandleBase * theclass = nullptr;
+
+  //Collection definition:
+  QString storegate_key;
+  PRDDetType::Type detType;
+
+  template <class T>
+  bool actualLoad();//Templated according to collection type.
+
+  VP1ExtraSepLayerHelper * sephelper_detail = nullptr;
+  VP1ExtraSepLayerHelper * sephelper_simple = nullptr;
+  SoSeparator * sep_lods = nullptr;
+  std::map<int,std::pair<SoLevelOfDetail*,std::pair<VP1ExtraSepLayerHelper*,VP1ExtraSepLayerHelper*> > > regionindex2lodhelpers;//idx->(sephelperdetailed,sephelpersimple)
+  DETAIL generalprddetaillevel;
+  void updateDetailSepAttachments();
+
+  SoMaterial * highlightmaterial = nullptr;
+  bool highlightoutliers = false;
+  bool drawerrors = false;
+  bool drawrdos = false;
+
+  VP1Interval allowedEta;
+  QList<VP1Interval> allowedPhi;
+
+  bool ensureLoaded();//first call each event will attempt to load
+              //PRDs from storegate. Returns false in case of
+              //problems this events. (This is inexpensive to
+              //call)
+
+  //Vector of prd handles:
+  std::vector<PRDHandleBase*> prdhandles;
+
+  bool etaPhiCut(PRDHandleBase*);
+
+  //Extra widgets:
+  QComboBox * comboBox_detailLevel = nullptr;
+};
+
+//____________________________________________________________________
+PRDCollHandleBase::PRDCollHandleBase(PRDDetType::Type type,PRDSysCommonData*cd,const QString& key)
+  : VP1StdCollection(cd->system(),"PRDCollHandle_"+PRDDetType::typeToString(type)+"_"+key), m_d(new Imp), m_common(cd),m_nshownhandles(0),
+  m_colourmethod(ByTechOnly), m_highlightweight(999999.0)
+{
+  m_d->theclass = this;
+  m_d->detType = type;
+  m_d->storegate_key = key;
+  m_d->highlightmaterial = 0;
+  m_d->highlightoutliers = false;
+  m_d->drawerrors = false;
+  m_d->drawrdos = false;
+  m_d->sephelper_detail = 0;
+  m_d->sephelper_simple = 0;
+  m_d->sep_lods = 0;
+  m_d->comboBox_detailLevel = new QComboBox;
+  m_d->comboBox_detailLevel->setToolTip("Level of realism in representation"
+    " (\"Auto\" switches mode based on distance to camera)");
+  m_d->comboBox_detailLevel->addItems(QStringList()<<"Low"<<"Auto"<<"High");//Low==simple, High==detailed. Don't change order.
+  m_d->generalprddetaillevel = SIMPLE;
+  m_d->comboBox_detailLevel->setCurrentIndex(0);//corresponds to simple.
+  connect(m_d->comboBox_detailLevel,SIGNAL(currentIndexChanged(int)),this,SLOT(detailComboBoxItemChanged()));
+  connect(this,SIGNAL(visibilityChanged(bool)),this,SLOT(collVisibilityChanged(bool)));
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::init(VP1MaterialButtonBase*)
+{
+  VP1StdCollection::init();//this call is required
+
+  SoSeparator * sep_detail = new SoSeparator;
+  sep_detail->setName("PRDColl_sep_detail");
+  SoSeparator * sep_simple = new SoSeparator;
+  sep_simple->setName("PRDColl_sep_simple");
+  m_d->sep_lods = new SoSeparator;
+  m_d->sep_lods->setName("PRDColl_sep_lods");
+  sep_detail->ref();
+  sep_simple->ref();
+  m_d->sep_lods->ref();
+
+  m_d->sephelper_detail = new VP1ExtraSepLayerHelper(sep_detail,128);
+  m_d->sephelper_simple = new VP1ExtraSepLayerHelper(sep_simple,128);
+
+  setupSettingsFromController(common()->controller());
+
+  //Setup detail level:
+  setGeneralPRDDetailLevel(defaultDetailLevel());
+  m_d->updateDetailSepAttachments();
+
+}
+
+
+//____________________________________________________________________
+PRDCollHandleBase::~PRDCollHandleBase()
+{
+  //Lod sep-helpers:
+  std::map<int,std::pair<SoLevelOfDetail*,std::pair<VP1ExtraSepLayerHelper*,VP1ExtraSepLayerHelper*> > >::iterator it, itE = m_d->regionindex2lodhelpers.end();
+  for (it = m_d->regionindex2lodhelpers.begin();it!=itE;++it) {
+    delete it->second.second.first;
+    delete it->second.second.second;
+    it->second.first->unref();
+  }
+  m_d->regionindex2lodhelpers.clear();
+
+  //Cleanup separators:
+  if (m_d->sephelper_detail) {
+    SoSeparator * sep_detail = m_d->sephelper_detail->topSeparator();
+    delete m_d->sephelper_detail;
+    sep_detail->unref();
+  }
+  if (m_d->sephelper_simple) {
+    SoSeparator * sep_simple = m_d->sephelper_simple->topSeparator();
+    delete m_d->sephelper_simple;
+    sep_simple->unref();
+  }
+  if (m_d->sep_lods)
+    m_d->sep_lods->unref();
+
+  cleanupPtrContainer(m_d->prdhandles);
+
+  if (m_d->highlightmaterial)
+    m_d->highlightmaterial->unref();
+
+  delete m_d;
+}
+
+//____________________________________________________________________
+bool PRDCollHandleBase::load() {
+  bool safeToLoad(false);
+  switch (m_d->detType){
+    case PRDDetType::SCT:
+    safeToLoad = VP1JobConfigInfo::hasSCTGeometry();
+    break;
+    default:
+    safeToLoad = false;
+  }
+
+  if (!safeToLoad){
+    message("Required geometry not enabled in job.");
+    return false;
+  }
+
+  switch (m_d->detType){
+    case PRDDetType::SCT:   return m_d->actualLoad<Tracker::FaserSCT_ClusterContainer>();
+    //SpacePoints implements their own load.
+    default:
+    return false;
+  }
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::collVisibilityChanged(bool vis)
+{
+  if (VP1Msg::verbose())
+    messageVerbose("TrackCollHandleBase::collVisibilityChanged => "+str(vis));
+  if (vis)
+    recheckCutStatusOfAllNotVisibleHandles();//Fixme -> ofallhandles? All must be not visible anyway...
+  else
+    recheckCutStatusOfAllVisibleHandles();
+}
+
+//____________________________________________________________________
+template <class T>
+bool PRDCollHandleBase::Imp::actualLoad()
+{
+  /////////////////////////////////////////////////////////////////////////
+  // Retrieve element container from event store:
+  const T* container;
+  VP1SGAccessHelper sg_access(theclass->systemBase());
+  if(!sg_access.retrieve(container,storegate_key))
+    return false;
+
+  typename T::const_iterator element, lastElement(container->end());
+
+  /////////////////////////////////////////////////////////////////////////
+  // Sanity check:
+  if ( container->size()==0 && container->begin()!=lastElement ) {
+    theclass->message("ERROR: container '"+storegate_key+"' has size()==0, but different begin() and end() iterators!");
+    return false;
+  }
+
+  /////////////////////////////////////////////////////////////////////////
+  // In case the container was created incorrectly we must fallback to a different method of getting the prds:
+  bool fallback(false);
+  const DataHandle<typename T::base_value_type> firstElementD, lastElementD;
+  if ( container->size()!=0 && container->begin()==lastElement ) {
+    //This is either an empty container, or it is a case of an incorrectly created container which we must get by datahandles.
+    theclass->messageDebug("Retrieved empty container. This might be misleading. Now going to attempt to load prds via datahandles instead.");
+    if (VP1SGContentsHelper(theclass->systemBase()).getKeys<T>().count()!=1) {
+      theclass->messageDebug("But seems that there is not exactly one collection of type "+QString(typeid(T).name())
+        +", so we won't attempt that anyway!! Thus we assume there there are simply no prd's.");
+    } else {
+      if(sg_access.retrieve(firstElementD, lastElementD,true)) {
+        if (firstElementD==lastElementD) {
+          theclass->messageDebug("No prd's found when accessed by datahandles either. It seems that there really are just no prds in this collection.");
+        } else {
+          fallback = true;
+        }
+      } else {
+        theclass->messageDebug("Failed retrieval by datahandles. We take that as a sign that there really are just no prds in this collection ");
+      }
+    }
+  }
+
+  theclass->messageVerbose("Loop over actual prd's and create handles");
+  //Retrieve prds and create handles:
+
+  int ignoredUnsafeHandle_NoPRD(0);
+  int ignoredUnsafeHandle_NoDetElem(0);
+  int ignoredUnsafeHandle_NotSane(0);
+  typename T::base_value_type::const_iterator prd, prdLast;
+  int iprds(0);
+  if (!fallback) {
+        // element = container->begin();
+        //         prd = (*element)->begin();
+        //         ++iprds;
+        //         PRDHandleBase * handle = theclass->addPRD(*prd);
+        //         theclass->addHandle(handle);
+        //         theclass->common()->registerPRD2Handle(*prd,handle);  
+        //               theclass->systemBase()->updateGUI();
+    for ( element = container->begin(); element!=lastElement ; ++element) {
+      prd = (*element)->begin(), prdLast = (*element)->end();
+      for ( ; prd!=prdLast ; ++prd) {
+        ++iprds;
+        if (!*prd) {
+          ++ignoredUnsafeHandle_NoPRD;
+          continue;
+        }
+        PRDHandleBase * handle = theclass->addPRD(*prd);
+        if (handle) {
+          if (!handle->isSane()) ignoredUnsafeHandle_NotSane++;
+          if (!handle->getPRD()->detectorElement()) {
+            ++ignoredUnsafeHandle_NoDetElem;
+            delete handle;
+          } else {
+            theclass->addHandle(handle);
+            theclass->common()->registerPRD2Handle(*prd,handle);
+          }
+        }
+      }
+      if (!(iprds%100))
+        theclass->systemBase()->updateGUI();
+    }
+
+  } else {
+
+    for ( const DataHandle<typename T::base_value_type> elementD(firstElementD); elementD!=lastElementD; ++elementD ) {
+      prd = (*elementD).begin(), prdLast = (*elementD).end();
+      for ( ; prd!=prdLast ; ++prd) {
+        ++iprds;
+        if (!*prd) {
+          ++ignoredUnsafeHandle_NoPRD;
+          continue;
+        }
+        PRDHandleBase * handle = theclass->addPRD(*prd);
+        if (handle) {
+          if (!handle->isSane()) ignoredUnsafeHandle_NotSane++;
+
+          if (!handle->getPRD()->detectorElement()) {
+            ++ignoredUnsafeHandle_NoDetElem;
+            delete handle;
+          } else {
+            theclass->addHandle(handle);
+            theclass->common()->registerPRD2Handle(*prd,handle);
+          }
+        }
+        if (!(iprds%100))
+          theclass->systemBase()->updateGUI();
+      }
+    }
+  }
+  theclass->systemBase()->updateGUI();
+  prdhandles.resize(prdhandles.size());
+
+  if (ignoredUnsafeHandle_NoPRD)
+    theclass->message("WARNING - ignoring "+str(ignoredUnsafeHandle_NoPRD)+" null prd pointer(s).");
+  if (ignoredUnsafeHandle_NoDetElem)
+    theclass->message("WARNING - ignoring "+str(ignoredUnsafeHandle_NoDetElem)+" prd pointer(s) with null detector elements.");
+  if (ignoredUnsafeHandle_NotSane)
+    theclass->message("WARNING - found "+str(ignoredUnsafeHandle_NotSane)+" prd pointer(s) which fail sanity checks (i.e. contain NaNs).");
+
+  //Perform initialisation needed for cuts (e.g. those of the "global" type, such as requiring a number of PRDs in the same detector module):
+  theclass->messageVerbose("postLoadInitialisation");
+  theclass->postLoadInitialisation();
+
+  theclass->systemBase()->updateGUI();
+
+  //Show the handles that need to be shown:
+  theclass->recheckCutStatusOfAllNotVisibleHandles();//Use this method to not get the deselectAll call
+
+  theclass->message("Found "+QString::number(iprds)+" ("+QString::number(theclass->nShownHandles())+" shown) PRDs in container '"+storegate_key+"'");
+
+  return true;
+
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::Imp::updateDetailSepAttachments()
+{
+  SoSeparator * collsep = theclass->collSep();
+  if (!collsep)
+    return;
+  bool save = collsep->enableNotify(false);
+  if (generalprddetaillevel==PRDCollHandleBase::DETAILED) {
+    //Detail
+    if (collsep->findChild(sephelper_detail->topSeparator())<0)
+      collsep->addChild(sephelper_detail->topSeparator());
+  } else {
+    //No detail
+    if (collsep->findChild(sephelper_detail->topSeparator())>-1)
+      collsep->removeChild(sephelper_detail->topSeparator());
+  }
+  if (generalprddetaillevel==PRDCollHandleBase::SIMPLE) {
+    //Simple
+    if (collsep->findChild(sephelper_simple->topSeparator())<0)
+      collsep->addChild(sephelper_simple->topSeparator());
+  } else {
+    //No simple
+    if (collsep->findChild(sephelper_simple->topSeparator())>-1)
+      collsep->removeChild(sephelper_simple->topSeparator());
+  }
+  if (generalprddetaillevel==PRDCollHandleBase::AUTO) {
+    //LOD
+    if (collsep->findChild(sep_lods)<0)
+      collsep->addChild(sep_lods);
+  } else {
+    //No LOD
+    if (collsep->findChild(sep_lods)>-1)
+      collsep->removeChild(sep_lods);
+  }
+  if (save) {
+    collsep->enableNotify(true);
+    collsep->touch();
+  }
+}
+
+//____________________________________________________________________
+VP1ExtraSepLayerHelper * PRDCollHandleBase::sephelperDetailedNodes() const
+{
+  return m_d->sephelper_detail;
+}
+
+//____________________________________________________________________
+VP1ExtraSepLayerHelper * PRDCollHandleBase::sephelperSimpleNodes() const
+{
+  return m_d->sephelper_simple;
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::detailComboBoxItemChanged()
+{
+  messageVerbose("Collection detail level combo box changed index");
+  switch(m_d->comboBox_detailLevel->currentIndex()) {
+    case 1:
+    setGeneralPRDDetailLevel(AUTO);
+    break;
+    case 2:
+    setGeneralPRDDetailLevel(DETAILED);
+    break;
+    default:
+    case 0:
+    setGeneralPRDDetailLevel(SIMPLE);
+    break;
+  }
+}
+
+//____________________________________________________________________
+PRDCollHandleBase::DETAIL PRDCollHandleBase::detailLevel() const
+{
+  return m_d->generalprddetaillevel;
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::setGeneralPRDDetailLevel( DETAIL dm )
+{
+  if (m_d->generalprddetaillevel==dm)
+    return;
+  m_d->generalprddetaillevel = dm;
+  messageVerbose("Detail level changed");
+//   common()->system()->deselectAll();
+
+  //Update gui combobox:
+  int targetIndex(0);
+  switch(m_d->generalprddetaillevel) {
+    case AUTO:
+    targetIndex = 1;
+    break;
+    case DETAILED:
+    targetIndex = 2;
+    break;
+    default:
+    case SIMPLE:
+    targetIndex = 0;
+    break;
+  }
+  if (targetIndex!=m_d->comboBox_detailLevel->currentIndex()) {
+    bool save = m_d->comboBox_detailLevel->blockSignals(true);
+    m_d->comboBox_detailLevel->setCurrentIndex(targetIndex);
+    m_d->comboBox_detailLevel->blockSignals(save);
+  }
+
+  //Actual changes to 3D representation:
+  m_d->updateDetailSepAttachments();
+
+  detailLevelChanged();
+
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::getLODSeparators(int index, VP1ExtraSepLayerHelper*& sephelper_detail,VP1ExtraSepLayerHelper*& sephelper_simple)
+{
+  const float complexity = 0.3f;//Fixme: Hardcoded here.
+  std::map<int,std::pair<SoLevelOfDetail*,std::pair<VP1ExtraSepLayerHelper*,VP1ExtraSepLayerHelper*> > >::iterator it = m_d->regionindex2lodhelpers.find(index);
+  if (it!=m_d->regionindex2lodhelpers.end()) {
+    sephelper_detail = it->second.second.first;
+    sephelper_simple = it->second.second.second;
+    //To try to scale somehow different regions to change at "the same time":
+    it->second.first->screenArea.setValue(lodArea()*(sephelper_detail->topSeparator()->getNumChildren()+1)/(complexity+0.5f));
+    return;
+  }
+  SoLevelOfDetail * lod = new SoLevelOfDetail;
+  SoSeparator * sep_detail = new SoSeparator;
+  SoSeparator * sep_simple = new SoSeparator;
+  lod->addChild(sep_detail);
+  lod->addChild(sep_simple);
+  lod->screenArea.setValue(lodArea()/(complexity+0.5f));
+  m_d->sep_lods->addChild(lod);
+  sephelper_detail = new VP1ExtraSepLayerHelper(sep_detail);
+  sephelper_simple = new VP1ExtraSepLayerHelper(sep_simple);
+
+  lod->ref();
+  m_d->regionindex2lodhelpers[index] =
+    std::pair<SoLevelOfDetail*,std::pair<VP1ExtraSepLayerHelper*,VP1ExtraSepLayerHelper*> >
+    (lod,std::pair<VP1ExtraSepLayerHelper*,VP1ExtraSepLayerHelper*>(sephelper_detail,sephelper_simple));
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::addHandle(PRDHandleBase*handle)
+{
+  if (handle)
+    m_d->prdhandles.push_back(handle);
+}
+
+//____________________________________________________________________
+std::vector<PRDHandleBase*>& PRDCollHandleBase::getPrdHandles()
+{
+  return m_d->prdhandles;
+}
+
+//____________________________________________________________________
+const std::vector<PRDHandleBase*>& PRDCollHandleBase::getPrdHandles() const
+{
+  return m_d->prdhandles;
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::recheckCutStatus(PRDHandleBase*handle)
+{
+  handle->setVisible( visible() && cut(handle) && m_d->etaPhiCut(handle) );
+}
+
+//Fixme: A few of the methods of this class should be inlined (requires a few more public data members)
+
+//____________________________________________________________________
+void PRDCollHandleBase::setupSettingsFromController(PRDSystemController*controller)
+{
+  assert(controller);
+  largeChangesBegin();
+
+  collSep()->addChild(controller->drawOptions(m_d->detType));
+
+  m_d->highlightmaterial = controller->getHighLightMaterial();
+  m_d->highlightmaterial->ref();
+
+  connect(controller,SIGNAL(highLightOutliersChanged(bool)),this,SLOT(setHighLightOutliers(bool)));
+  setHighLightOutliers(controller->highLightOutliers());
+
+  connect(controller,SIGNAL(colourMethodChanged(PRDCollHandleBase::COLOURMETHOD)),this,SLOT(setColourMethod(PRDCollHandleBase::COLOURMETHOD)));
+  setColourMethod(controller->colourMethod());
+
+  connect(controller,SIGNAL(drawErrorsChanged(bool)),this,SLOT(setDrawErrors(bool)));
+  setDrawErrors(controller->drawErrors());
+
+  connect(controller,SIGNAL(drawRDOsChanged(bool)),this,SLOT(setDrawRDOs(bool)));
+  setDrawRDOs(controller->drawRDOs());
+
+  connect(controller,SIGNAL(highLightMaterialWeightChanged(const double&)),this,SLOT(setHighLightWeight(const double&)));
+  setHighLightWeight(controller->highLightMaterialWeight());
+
+  connect(controller,SIGNAL(cutAllowedEtaChanged(const VP1Interval&)),
+    this,SLOT(setAllowedEta(const VP1Interval&)));
+  setAllowedEta(controller->cutAllowedEta());
+
+  connect(controller,SIGNAL(cutAllowedPhiChanged(const QList<VP1Interval>&)),
+    this,SLOT(setAllowedPhi(const QList<VP1Interval>&)));
+  setAllowedPhi(controller->cutAllowedPhi());
+
+  setupSettingsFromControllerSpecific(controller);
+  largeChangesEnd();
+}
+
+
+//____________________________________________________________________
+void PRDCollHandleBase::recheckCutStatusOfAllHandles()
+{
+  messageVerbose("PRDCollHandleBase::recheckCutStatusOfAllHandles");
+
+  common()->system()->deselectAll();
+
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(m_d->prdhandles.begin()),itE(m_d->prdhandles.end());
+  int i(0);
+  for (;it!=itE;++it) {
+    recheckCutStatus(*it);
+    if (!(i++%200))
+      systemBase()->updateGUI();//since called from ::actualLoad<..>(..)
+  }
+  largeChangesEnd();
+  if (visible()) message("Have "+QString::number(getPrdHandles().size())+" ("+QString::number(nShownHandles())+" shown) PRDs");
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::recheckCutStatusOfAllVisibleHandles()
+{
+  messageVerbose("PRDCollHandleBase::recheckCutStatusOfAllVisibleHandles");
+  if (!visible()) return;
+  //This method is called when a cut is tightened - thus we better start by deselectAll to avoid weird highlighting issues.
+  common()->system()->deselectAll();
+
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(m_d->prdhandles.begin()),itE(m_d->prdhandles.end());
+  for (;it!=itE;++it) {
+    if ((*it)->visible())
+      recheckCutStatus(*it);
+  }
+  largeChangesEnd();
+  if (visible()) message("Have "+QString::number(getPrdHandles().size())+" ("+QString::number(nShownHandles())+" shown) PRDs");    
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::recheckCutStatusOfAllNotVisibleHandles()
+{
+  messageVerbose("PRDCollHandleBase::recheckCutStatusOfAllNotVisibleHandles");
+
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(m_d->prdhandles.begin()),itE(m_d->prdhandles.end());
+  for (;it!=itE;++it) {
+    if (!(*it)->visible())
+      recheckCutStatus(*it);
+  }
+  largeChangesEnd();
+  if (visible()) message("Have "+QString::number(getPrdHandles().size())+" ("+QString::number(nShownHandles())+" shown) PRDs");
+}
+
+
+//____________________________________________________________________
+bool PRDCollHandleBase::highLightOutliers() const
+{
+  return m_d->highlightoutliers;
+}
+
+//____________________________________________________________________
+bool PRDCollHandleBase::drawErrors() const
+{
+  return m_d->drawerrors;
+}
+
+//____________________________________________________________________
+bool PRDCollHandleBase::drawRDOs() const
+{
+  return m_d->drawrdos;
+}
+
+//____________________________________________________________________
+SoMaterial * PRDCollHandleBase::highLightMaterial() const
+{
+  return  m_d->highlightmaterial;
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::setHighLightOutliers(bool b)
+{
+  if (m_d->highlightoutliers==b)
+    return;
+  m_d->highlightoutliers = b;
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(m_d->prdhandles.begin()),itE(m_d->prdhandles.end());
+  for (;it!=itE;++it) {
+    (*it)->updateMaterial();
+    //Fixme: Improve performance by only calling updateMaterial() on
+    //those that are outliers on at least one track.
+  }
+  largeChangesEnd();
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::setDrawErrors(bool b)
+{
+  if (m_d->drawerrors==b)
+    return;
+  m_d->drawerrors = b;
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(m_d->prdhandles.begin()),itE(m_d->prdhandles.end());
+  for (;it!=itE;++it) {
+    (*it)->update3DObjects();
+    //Fixme: Improve performance by only calling updateMaterial() on
+    //those that are outliers on at least one track.
+  }
+  largeChangesEnd();
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::setDrawRDOs(bool b)
+{
+  if (m_d->drawrdos==b)
+    return;
+  m_d->drawrdos = b;
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(m_d->prdhandles.begin()),itE(m_d->prdhandles.end());
+  for (;it!=itE;++it) {
+    (*it)->update3DObjects();
+    //Fixme: Improve performance by only calling updateMaterial() on
+    //those that are outliers on at least one track.
+  }
+  largeChangesEnd();
+}
+
+
+//____________________________________________________________________
+void PRDCollHandleBase::setHighLightWeight(const double& hlw)
+{
+  if (m_highlightweight == hlw)
+    return;
+  m_highlightweight = hlw;
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(m_d->prdhandles.begin()),itE(m_d->prdhandles.end());
+  for (;it!=itE;++it) {
+    if (m_d->highlightoutliers || (*it)->highLight())
+      (*it)->updateMaterial();
+    //Fixme: We can improve performance here by investigating whether
+    //the handle actually is an outlier for at least one track, or if
+    //highlighting is at all applicable for the collection (maybe it is turned off).
+  }
+  largeChangesEnd();
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::setColourMethod(PRDCollHandleBase::COLOURMETHOD cm)
+{
+  if (m_colourmethod==cm)
+    return;
+  m_colourmethod = cm;
+
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(m_d->prdhandles.begin()),itE(m_d->prdhandles.end());
+  for (;it!=itE;++it) {
+    (*it)->updateMaterial();
+    //Fixme: Improve performance by only calling on those that are on tracks/segments as relevant.
+  }
+  largeChangesEnd();
+
+}
+
+//____________________________________________________________________
+QString PRDCollHandleBase::toString(const PRDCollHandleBase::DETAIL& d)
+{
+  switch (d) {
+    case SIMPLE: return "SIMPLE";
+    case DETAILED: return "DETAILED";
+    case AUTO: return "AUTO";
+    default: return "Unknown (ERROR)";
+  }
+}
+
+//____________________________________________________________________
+QString PRDCollHandleBase::toString(const COLOURMETHOD& cm)
+{
+  switch (cm) {
+    case ByTechOnly: return "ByTechOnly";
+    case BySegment: return "BySegment";
+    case ByTrack: return "ByTrack";
+    case BySegmentAndTrack: return "BySegmentAndTrack";
+    default: return "Unknown (ERROR)";
+  }
+}
+
+//____________________________________________________________________
+qint32 PRDCollHandleBase::provideCollTypeID() const
+{
+  return PRDDetType::typeToInt(m_d->detType);
+}
+
+//____________________________________________________________________
+QString PRDCollHandleBase::provideText() const
+{
+  return m_d->storegate_key;
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::assignDefaultMaterial(SoMaterial*m) const
+{
+  VP1QtInventorUtils::setMatColor( m, defaultColor(), 0.18/*brightness*/ );
+}
+
+//____________________________________________________________________
+QString PRDCollHandleBase::provideSection() const
+{
+  switch (m_d->detType) {
+    case PRDDetType::SCT:
+    return "Tracker PRDs";
+    case PRDDetType::SpacePoints:
+    return "Tracker Space Points";
+    default: return "Unknown Section";
+  }
+}
+
+//____________________________________________________________________
+QString PRDCollHandleBase::provideSectionToolTip() const
+{
+  switch (m_d->detType) {
+    case PRDDetType::SCT:
+    return "Tracker PRD collections in event";
+    case PRDDetType::SpacePoints:
+    return "Space Point collections in event";
+    default: return "Error: PRDDetType not recognised.";
+  }
+}
+
+//____________________________________________________________________
+QList<QWidget*> PRDCollHandleBase::provideExtraWidgetsForGuiRow() const
+{
+  return QList<QWidget*>() << m_d->comboBox_detailLevel;
+}
+
+//____________________________________________________________________
+QByteArray PRDCollHandleBase::extraWidgetsState() const
+{
+  VP1Serialise serialise(0/*version*/,systemBase());
+  serialise.save(m_d->comboBox_detailLevel);
+  serialise.disableUnsavedChecks();
+  return serialise.result();
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::setExtraWidgetsState(const QByteArray& ba)
+{
+  VP1Deserialise state(ba, systemBase());
+  if (state.version()!=0)
+    return;//just ignore silently... i guess we ought to warn?
+  state.restore(m_d->comboBox_detailLevel);
+  state.disableUnrestoredChecks();
+  detailComboBoxItemChanged();
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::setAllowedEta(const VP1Interval& e)
+{
+  if (m_d->allowedEta==e)
+    return;
+  bool relaxed(e.contains(m_d->allowedEta));
+  bool tightened(m_d->allowedEta.contains(e));
+  m_d->allowedEta=e;
+  if (relaxed)
+    recheckCutStatusOfAllNotVisibleHandles();
+  else if (tightened)
+    recheckCutStatusOfAllVisibleHandles();
+  else
+    recheckCutStatusOfAllHandles();
+}
+
+//____________________________________________________________________
+void PRDCollHandleBase::setAllowedPhi(const QList<VP1Interval>& l)
+{
+  if (m_d->allowedPhi==l)
+    return;
+  m_d->allowedPhi=l;
+  recheckCutStatusOfAllHandles();
+}
+
+//____________________________________________________________________
+bool PRDCollHandleBase::Imp::etaPhiCut(PRDHandleBase* handle)
+{
+  bool allPhiAllowed = allowedPhi.count()==1&&allowedPhi.at(0).isAllR();
+  bool allEtaAllowed = allowedEta.isAllR();
+  if (allEtaAllowed&&allPhiAllowed)
+    return true;
+  if (allowedPhi.isEmpty()||allowedEta.isEmpty())
+    return false;
+  Amg::Vector3D p = handle->center();
+  if (!allEtaAllowed) {
+    if (!allowedEta.contains(p.eta()))
+      return false;
+  }
+  if (!allPhiAllowed) {
+    double phi(p.phi());
+    foreach(VP1Interval i,allowedPhi) {
+      if (i.contains(phi)||i.contains(phi+2*M_PI)||i.contains(phi-2*M_PI))
+        return true;
+    }
+    return false;
+  }
+  return true;
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandle_SCT.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandle_SCT.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..48e348aaa6efc971326179f7fd375e639eac91b1
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandle_SCT.cxx
@@ -0,0 +1,158 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "VTI12PRDSystems/PRDCollHandle_SCT.h"
+#include "VTI12PRDSystems/PRDHandle_SCT.h"
+#include "VTI12PRDSystems/PRDSystemController.h"
+#include "TrackerPrepRawData/FaserSCT_Cluster.h"
+#include <QColor>
+
+#include "VTI12Utils/VP1JobConfigInfo.h"
+#include "VTI12Utils/VP1SGContentsHelper.h"
+#include "TrackerPrepRawData/FaserSCT_ClusterContainer.h"
+
+//____________________________________________________________________
+QStringList PRDCollHandle_SCT::availableCollections(IVP1System*sys)
+{
+  return VP1JobConfigInfo::hasSCTGeometry() ? VP1SGContentsHelper(sys).getKeys<Tracker::FaserSCT_ClusterContainer>() : QStringList();
+}
+
+//____________________________________________________________________
+class PRDCollHandle_SCT::Imp {
+public:
+  std::set<const TrackerDD::SiDetectorElement*> touchedelements;
+
+  PRDCommonFlags::TrackerPartsFlags trackerpartsflags;
+  bool excludeisolatedclusters = false;
+};
+
+//____________________________________________________________________
+PRDCollHandle_SCT::PRDCollHandle_SCT(PRDSysCommonData * cd,const QString& key)
+  : PRDCollHandleBase(PRDDetType::SCT,cd,key), m_d(new Imp)
+{
+  m_d->trackerpartsflags = PRDCommonFlags::All;
+  m_d->excludeisolatedclusters = true;
+}
+
+//____________________________________________________________________
+PRDCollHandle_SCT::~PRDCollHandle_SCT()
+{
+  delete m_d;
+}
+
+//____________________________________________________________________
+QColor PRDCollHandle_SCT::defaultColor() const
+{
+  return QColor::fromRgbF(1.0, 1.0, 0.5 );//light yellow
+}
+
+//____________________________________________________________________
+PRDHandleBase* PRDCollHandle_SCT::addPRD( const Trk::PrepRawData * prd )
+{
+  assert(dynamic_cast<const Tracker::FaserSCT_Cluster*>(prd));
+  return new PRDHandle_SCT(this,static_cast<const Tracker::FaserSCT_Cluster*>(prd));
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SCT::postLoadInitialisation()
+{
+  std::vector<PRDHandleBase*>::iterator it(getPrdHandles().begin()),itE(getPrdHandles().end());
+  for (;it!=itE;++it)
+    m_d->touchedelements.insert(static_cast<PRDHandle_SCT*>(*it)->cluster()->detectorElement());
+  m_d->touchedelements.insert(0);//To always show clusters whose elements have no otherSide() pointer.
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SCT::eraseEventDataSpecific()
+{
+  m_d->touchedelements.clear();
+}
+
+//____________________________________________________________________
+bool PRDCollHandle_SCT::cut(PRDHandleBase*handlebase)
+{
+  PRDHandle_SCT * handle = static_cast<PRDHandle_SCT*>(handlebase);
+  assert(handle);
+
+  if (m_d->trackerpartsflags!=PRDCommonFlags::All) {
+    if (handle->isInterface()) 
+        if (!(m_d->trackerpartsflags & PRDCommonFlags::Interface)) return false;
+    if (handle->isUpstream())
+        if (!(m_d->trackerpartsflags & PRDCommonFlags::Upstream)) return false;
+    if (handle->isCentral())
+        if (!(m_d->trackerpartsflags & PRDCommonFlags::Central)) return false;
+    if (handle->isDownstream())
+        if (!(m_d->trackerpartsflags & PRDCommonFlags::Downstream)) return false;        
+  }
+
+  if (m_d->excludeisolatedclusters) {
+    if (!m_d->touchedelements.count(handle->cluster()->detectorElement()->otherSide()))
+      return false;
+  }
+
+  return true;
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SCT::setPartsFlags(PRDCommonFlags::TrackerPartsFlags flags ) {
+  //NB: The code is this method is very similar in PRDCollHandle_Pixel::setPartsFlags, PRDCollHandle_SCT::setPartsFlags,
+  //PRDCollHandle_TRT::setPartsFlags and and PRDCollHandle_SpacePoints::setPartsFlags
+  //Fixme: base decision to recheck on visibility also!
+
+  if (m_d->trackerpartsflags==flags)
+    return;
+
+  bool interfaceChanged = (m_d->trackerpartsflags&PRDCommonFlags::Interface)!=(flags&PRDCommonFlags::Interface);
+  bool upstreamChanged = (m_d->trackerpartsflags&PRDCommonFlags::Upstream)!=(flags&PRDCommonFlags::Upstream);
+  bool centralChanged = (m_d->trackerpartsflags&PRDCommonFlags::Central)!=(flags&PRDCommonFlags::Central);
+  bool downstreamChanged = (m_d->trackerpartsflags&PRDCommonFlags::Downstream)!=(flags&PRDCommonFlags::Downstream);
+
+  m_d->trackerpartsflags=flags;
+
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(getPrdHandles().begin()),itE(getPrdHandles().end());
+  for (;it!=itE;++it) {
+    PRDHandle_SCT* handle = static_cast<PRDHandle_SCT*>(*it);
+    if (handle->isInterface()) 
+    {
+        if (interfaceChanged) recheckCutStatus(handle);
+    }
+    else if (handle->isUpstream())
+    {
+        if (upstreamChanged) recheckCutStatus(handle);
+    }
+    else if (handle->isCentral())
+    {
+        if (centralChanged) recheckCutStatus(handle);
+    }
+    else if (handle->isDownstream())
+    {
+        if (downstreamChanged) recheckCutStatus(handle);
+    }
+  }
+  largeChangesEnd();
+
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SCT::setExcludeIsolatedClusters(bool excludeisolated)
+{
+  if (m_d->excludeisolatedclusters==excludeisolated)
+    return;
+  m_d->excludeisolatedclusters=excludeisolated;
+  if (excludeisolated)
+    recheckCutStatusOfAllVisibleHandles();
+  else
+    recheckCutStatusOfAllNotVisibleHandles();
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SCT::setupSettingsFromControllerSpecific(PRDSystemController*controller)
+{
+  connect(controller,SIGNAL(trackerPartsFlagsChanged(PRDCommonFlags::TrackerPartsFlags)),this,SLOT(setPartsFlags(PRDCommonFlags::TrackerPartsFlags)));
+  setPartsFlags(controller->trackerPartsFlags());
+
+  connect(controller,SIGNAL(sctExcludeIsolatedClustersChanged(bool)),this,SLOT(setExcludeIsolatedClusters(bool)));
+  setExcludeIsolatedClusters(controller->sctExcludeIsolatedClusters());
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandle_SpacePoints.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandle_SpacePoints.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..59ede3c1eaba3f234ba3800fd0bc3c2095693579
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDCollHandle_SpacePoints.cxx
@@ -0,0 +1,185 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Implementation of class PRDCollHandle_SpacePoints         //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: September 2008                           //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#include "VTI12PRDSystems/PRDCollHandle_SpacePoints.h"
+#include "VTI12PRDSystems/PRDHandle_SpacePoint.h"
+#include "VTI12PRDSystems/PRDSystemController.h"
+#include "VP1Base/IVP1System.h"
+#include "VTI12Utils/VP1JobConfigInfo.h"
+#include "VTI12Utils/VP1SGContentsHelper.h"
+#include "VTI12Utils/VP1SGAccessHelper.h"
+#include "TrackerSpacePoint/FaserSCT_SpacePointContainer.h"
+#include <QColor>
+
+//____________________________________________________________________
+QStringList PRDCollHandle_SpacePoints::availableCollections(IVP1System*sys)
+{
+  if (!VP1JobConfigInfo::hasSCTGeometry())
+    return QStringList();
+  QStringList keys = VP1SGContentsHelper(sys).getKeys<FaserSCT_SpacePointContainer>();
+  QStringList unsafekeys;
+  if (!VP1JobConfigInfo::hasSCTGeometry()) {
+    foreach (QString key,keys) {
+      if (key.contains("sct",Qt::CaseInsensitive))
+	unsafekeys << key;
+    }
+  }
+  foreach (QString unsafekey,unsafekeys)
+    keys.removeAll(unsafekey);
+  return keys;
+}
+
+//____________________________________________________________________
+class PRDCollHandle_SpacePoints::Imp {
+public:
+  PRDCommonFlags::TrackerPartsFlags trackerpartsflags;
+};
+
+
+//____________________________________________________________________
+PRDCollHandle_SpacePoints::PRDCollHandle_SpacePoints(PRDSysCommonData* common,const QString& key)
+  : PRDCollHandleBase(PRDDetType::SpacePoints,common,key), m_d(new Imp)
+{
+  m_d->trackerpartsflags = (PRDCommonFlags::All);
+}
+
+//____________________________________________________________________
+PRDCollHandle_SpacePoints::~PRDCollHandle_SpacePoints()
+{
+  delete m_d;
+}
+
+//____________________________________________________________________
+QColor PRDCollHandle_SpacePoints::defaultColor() const
+{
+  return QColor::fromRgbF(1.0, 1.0, 0.5 );//light yellow
+}
+
+//____________________________________________________________________
+bool PRDCollHandle_SpacePoints::load()
+{
+  /////////////////////////////////////////////////////////////////////////
+  // Retrieve element container from event store:
+  const FaserSCT_SpacePointContainer* container;
+  if(!VP1SGAccessHelper(systemBase()).retrieve(container,text()))
+    return false;
+
+  int isp(0);
+  FaserSCT_SpacePointContainer::const_iterator itElement, itElementE(container->end());
+  for (itElement=container->begin();itElement!=itElementE;++itElement) {
+    FaserSCT_SpacePointContainer::base_value_type::const_iterator it, itE((*itElement)->end());
+    for (it=(*itElement)->begin();it!=itE;++it) {
+      const Tracker::FaserSCT_SpacePoint * sp = *it;
+      ++isp;
+      if (!sp) {
+	message("WARNING - ignoring null spacepoint pointer.");
+	continue;
+      }
+      if (!sp->clusterList().first) {
+	message("WARNING - ignoring spacepoint with null first cluster.");
+	continue;
+      }
+      PRDHandleBase * handle = new PRDHandle_SpacePoint(this,sp);
+      if (handle) {
+	addHandle(handle);
+	//We just register the first of the (possibly) two prds here (fixme: check that it works):
+	common()->registerPRD2Handle(handle->getPRD(),handle);
+      } else {
+	message("WARNING - ignoring null handle pointer.");
+      }
+      if (!(isp%100))
+	systemBase()->updateGUI();
+    }
+  }
+  return true;
+}
+
+//____________________________________________________________________
+bool PRDCollHandle_SpacePoints::cut(PRDHandleBase*handlebase)
+{
+  PRDHandle_SpacePoint * handle = static_cast<PRDHandle_SpacePoint*>(handlebase);
+  assert(handle);
+
+  if (m_d->trackerpartsflags!=PRDCommonFlags::All) {
+    if (handle->isInterface()) 
+        if (!(m_d->trackerpartsflags & PRDCommonFlags::Interface)) return false;
+    if (handle->isUpstream())
+        if (!(m_d->trackerpartsflags & PRDCommonFlags::Upstream)) return false;
+    if (handle->isCentral())
+        if (!(m_d->trackerpartsflags & PRDCommonFlags::Central)) return false;
+    if (handle->isDownstream())
+        if (!(m_d->trackerpartsflags & PRDCommonFlags::Downstream)) return false;        
+  }
+
+  return true;
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SpacePoints::eraseEventDataSpecific()
+{
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SpacePoints::postLoadInitialisation()
+{
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SpacePoints::setupSettingsFromControllerSpecific(PRDSystemController*controller)
+{
+  connect(controller,SIGNAL(trackerPartsFlagsChanged(PRDCommonFlags::TrackerPartsFlags)),
+	  this,SLOT(setPartsFlags(PRDCommonFlags::TrackerPartsFlags)));
+  setPartsFlags(controller->trackerPartsFlags());
+}
+
+//____________________________________________________________________
+void PRDCollHandle_SpacePoints::setPartsFlags(PRDCommonFlags::TrackerPartsFlags flags)
+{
+  //NB: The code is this method is very similar in PRDCollHandle_Pixel::setPartsFlags, PRDCollHandle_SCT::setPartsFlags,
+  //PRDCollHandle_TRT::setPartsFlags and and PRDCollHandle_SpacePoints::setPartsFlags
+  //Fixme: base decision to recheck on visibility also!
+
+  if (m_d->trackerpartsflags==flags)
+    return;
+
+  bool interfaceChanged = (m_d->trackerpartsflags&PRDCommonFlags::Interface)!=(flags&PRDCommonFlags::Interface);
+  bool upstreamChanged = (m_d->trackerpartsflags&PRDCommonFlags::Upstream)!=(flags&PRDCommonFlags::Upstream);
+  bool centralChanged = (m_d->trackerpartsflags&PRDCommonFlags::Central)!=(flags&PRDCommonFlags::Central);
+  bool downstreamChanged = (m_d->trackerpartsflags&PRDCommonFlags::Downstream)!=(flags&PRDCommonFlags::Downstream);
+
+  m_d->trackerpartsflags=flags;
+
+  largeChangesBegin();
+  std::vector<PRDHandleBase*>::iterator it(getPrdHandles().begin()),itE(getPrdHandles().end());
+  for (;it!=itE;++it) {
+    PRDHandle_SpacePoint* handle = static_cast<PRDHandle_SpacePoint*>(*it);
+    if (handle->isInterface()) 
+    {
+        if (interfaceChanged) recheckCutStatus(handle);
+    }
+    else if (handle->isUpstream())
+    {
+        if (upstreamChanged) recheckCutStatus(handle);
+    }
+    else if (handle->isCentral())
+    {
+        if (centralChanged) recheckCutStatus(handle);
+    }
+    else if (handle->isDownstream())
+    {
+        if (downstreamChanged) recheckCutStatus(handle);
+    }
+  }
+  largeChangesEnd();
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDDetTypes.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDDetTypes.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..86332ea0175acb0902ed2b6e32d8f7b9864a5e17
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDDetTypes.cxx
@@ -0,0 +1,49 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "VTI12PRDSystems/PRDDetTypes.h"
+
+//______________________________________________
+QString PRDDetType::typeToString(const Type& t)
+{
+  switch (t) {
+  case SCT: return "SCT";
+  case SpacePoints: return "SpacePoints";
+  default: return "UNKNOWN";
+  }
+}
+
+//______________________________________________
+PRDDetType::Type PRDDetType::stringToType(const QString&str, bool & status)
+{
+  status = true;
+  if (str=="SCT") return SCT;
+  if (str=="SpacePoints") return SpacePoints;
+  status = false;
+  return SCT;//people better watch the return status!
+}
+
+
+//______________________________________________
+qint32 PRDDetType::typeToInt(const Type& t)
+{
+  switch (t) {
+  case SCT: return 0;
+  case SpacePoints: return 1;
+  default: return -1;
+  }
+}
+
+//______________________________________________
+PRDDetType::Type PRDDetType::intToType(const qint32&i, bool & status)
+{
+  status = true;
+  switch (i) {
+  case 0: return SCT;
+  case 1: return SpacePoints;
+  default:
+    status = false;
+    return SCT;//people better watch the return status!
+  }
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandleBase.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandleBase.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2e1c76e306c937a995938f83446d56fd5d826e81
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandleBase.cxx
@@ -0,0 +1,471 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "VTI12PRDSystems/PRDHandleBase.h"
+#include "VTI12Utils/HitsSoNodeManager.h"
+#include "VTI12PRDSystems/PRDCollHandleBase.h"
+#include "VTI12PRDSystems/VP1PrepRawDataSystem.h"
+#include "VTI12PRDSystems/PRDTrackSegmentHelper.h"
+
+#include "VP1Base/VP1ExtraSepLayerHelper.h"
+#include "VP1Base/VP1SoMaterialMixer.h"
+#include "VP1Base/VP1Msg.h"
+
+#include "VTI12Utils/VP1LinAlgUtils.h"
+
+#include <Inventor/C/errors/debugerror.h>
+#include <Inventor/nodes/SoSeparator.h>
+#include <Inventor/nodes/SoTransform.h>
+#include <Inventor/nodes/SoMaterial.h>
+
+#include "TrkSurfaces/Surface.h"
+#include "TrkPrepRawData/PrepRawData.h"
+
+#include "GeoPrimitives/GeoPrimitives.h"
+#include "GeoPrimitives/GeoPrimitivesHelpers.h"
+
+#include <vector>
+#include <algorithm>
+#include <sstream>
+
+//____________________________________________________________________
+class PRDHandleBase::Imp {
+public:
+  PRDCollHandleBase* colhandle;
+  void rebuild3DObjects(PRDHandleBase*);
+  void attach3DObjects(PRDHandleBase*);
+  void detach3DObjects();
+
+  static Amg::Vector3D positionPRD(const Trk::PrepRawData* prd);
+
+  //Child 0 is the transform, then follows the node representing the shapes.
+  SoSeparator * sepDetailed;
+  SoSeparator * sepSimple;
+  SoMaterial * currentmaterial;
+  VP1ExtraSepLayerHelper* sephelper_lod_detail;
+  VP1ExtraSepLayerHelper* sephelper_lod_simple;
+
+  SoMaterial * determineMaterial(PRDHandleBase*);
+};
+
+//____________________________________________________________________
+SoSeparator* PRDHandleBase::sepSimple() const
+{
+  return m_d->sepSimple;
+}
+
+//____________________________________________________________________
+SoSeparator* PRDHandleBase::sepDetailed() const
+{
+  return m_d->sepDetailed;
+}
+
+//____________________________________________________________________
+PRDHandleBase::PRDHandleBase(PRDCollHandleBase*colhandle)
+  : m_d(new Imp), m_common(colhandle->common()),m_visible(false)
+{
+  m_d->colhandle = colhandle;
+  m_d->sepDetailed = 0;
+  m_d->sepSimple = 0;
+  m_d->currentmaterial = 0;
+  m_d->sephelper_lod_detail = 0;
+  m_d->sephelper_lod_simple = 0;
+}
+
+
+//____________________________________________________________________
+PRDHandleBase::~PRDHandleBase()
+{
+  if (m_d->sepDetailed)
+    m_d->sepDetailed->unref();
+  if (m_d->sepSimple)
+    m_d->sepSimple->unref();
+  if (m_d->currentmaterial)
+    m_d->currentmaterial->unref();
+
+  delete m_d;
+}
+
+//____________________________________________________________________
+void PRDHandleBase::Imp::rebuild3DObjects(PRDHandleBase*theclass)
+{  
+  //Fixme:
+  SoTransform * transform(0);
+  //If visible and already build: Detach separators (and ensure we got the sephelpers):
+  if (theclass->m_visible) {
+    if (!sephelper_lod_detail) {
+      int idx = theclass->regionIndex();
+      colhandle->getLODSeparators(idx, sephelper_lod_detail,sephelper_lod_simple);
+    }
+    detach3DObjects();
+  }
+
+  //Ensure separators are built and with no children:
+  if (sepDetailed) {
+    //We might get transform from this one:
+    if (sepDetailed->getNumChildren()>0) {      
+      transform = static_cast<SoTransform*>(sepDetailed->getChild(0));
+      transform->ref();
+    }
+    sepDetailed->removeAllChildren();
+  } else {
+    sepDetailed = new SoSeparator;
+    sepDetailed->ref();
+    //     sepDetailed->renderCaching.setValue(SoSeparator::ON);
+    //     sepDetailed->boundingBoxCaching.setValue(SoSeparator::ON);
+  }
+  if (sepSimple) {
+    sepSimple->removeAllChildren();
+  } else {
+    sepSimple = new SoSeparator;
+    //     sepSimple->renderCaching.setValue(SoSeparator::ON);
+    //     sepSimple->boundingBoxCaching.setValue(SoSeparator::ON);
+    sepSimple->ref();
+  }
+  //Attach transforms:
+  if (!transform) {    
+    transform = theclass->createTransform();
+    transform->ref();
+    theclass->common()->registerTransform2Handle(transform,theclass);
+  }
+  sepDetailed->addChild(transform);//For efficiency it is important that this happens BEFORE buildShapes(..) is called.
+  sepSimple->addChild(transform);
+  transform->unref();
+
+  SoNode* shape_simple(0), * shape_detailed(0);
+  theclass->buildShapes(shape_simple, shape_detailed);
+  if (!shape_simple)
+    shape_simple = theclass->common()->nodeManager()->getShapeNode_Point();//Add single point as a stop-gap measure.
+  if (!shape_detailed)
+    shape_detailed = shape_simple;//Could not create detailed shape for some reason. Use simple shape instead.
+
+  sepSimple->addChild(shape_simple);
+  sepDetailed->addChild(shape_detailed);
+
+  //Attach if visible:
+  if (theclass->m_visible)
+    attach3DObjects(theclass);
+}
+
+// //____________________________________________________________________
+// inline void PRDHandleBase::registerTransform(SoTransform*transform)//FIXME: Pass-through not needed
+// {
+//   //Use this pass-through method to get around a friend-problem
+//   //FIXME  common()->system()->registerTransform2Handle(transform,this);
+// }
+
+//____________________________________________________________________
+void PRDHandleBase::updateMaterial()
+{
+  //We need to change the current material. This means we need to
+  //clear the cache. Only if we are visible do we need to do a
+  //detach->clear material->attach cycle to trigger attachment under new material.
+
+  if (!m_d->currentmaterial)
+    return;//We have no material cached and is thus not attached either.
+  if (m_visible) {
+    //See if the material changed. If it did, detach, update the material, attach again.
+    SoMaterial * newmat = m_d->determineMaterial(this);
+    newmat->ref();
+    if (newmat!=m_d->currentmaterial) {
+      m_d->detach3DObjects();
+      m_d->currentmaterial->unref();
+      m_d->currentmaterial = newmat;
+      m_d->attach3DObjects(this);
+    } else {
+      newmat->unref();
+    }
+  } else {
+    //Just clear material.
+    m_d->currentmaterial->unref();
+    m_d->currentmaterial = 0;
+  }
+}
+
+//____________________________________________________________________
+void PRDHandleBase::Imp::attach3DObjects(PRDHandleBase*theclass)
+{
+  if (!currentmaterial) {
+    currentmaterial = determineMaterial(theclass);
+    currentmaterial->ref();
+  }
+  if (sepDetailed) {
+    if (colhandle->sephelperDetailedNodes())
+      colhandle->sephelperDetailedNodes()->addNodeUnderMaterial(sepDetailed,currentmaterial);
+    if (sephelper_lod_detail)
+      sephelper_lod_detail->addNodeUnderMaterial(sepDetailed,currentmaterial);
+  }
+  if (sepSimple) {
+    if (colhandle->sephelperSimpleNodes())
+      colhandle->sephelperSimpleNodes()->addNodeUnderMaterial(sepSimple,currentmaterial);
+    if (sephelper_lod_simple)
+      sephelper_lod_simple->addNodeUnderMaterial(sepSimple,currentmaterial);
+  }
+}
+
+//____________________________________________________________________
+void PRDHandleBase::Imp::detach3DObjects()
+{
+  if (!currentmaterial)
+    return;//Can never have been attached!
+  if (sepDetailed) {
+    if (colhandle->sephelperDetailedNodes())
+      colhandle->sephelperDetailedNodes()->removeNodeUnderMaterial(sepDetailed,currentmaterial);
+    if (sephelper_lod_detail)
+      sephelper_lod_detail->removeNodeUnderMaterial(sepDetailed,currentmaterial);
+  }
+  if (sepSimple) {
+    if (colhandle->sephelperSimpleNodes())
+      colhandle->sephelperSimpleNodes()->removeNodeUnderMaterial(sepSimple,currentmaterial);
+    if (sephelper_lod_simple)
+      sephelper_lod_simple->removeNodeUnderMaterial(sepSimple,currentmaterial);
+  }
+}
+
+//____________________________________________________________________
+PRDCollHandleBase * PRDHandleBase::collHandle() const
+{
+  return m_d->colhandle;
+}
+
+//____________________________________________________________________
+void PRDHandleBase::setVisible(bool vis)
+{
+  if (vis==m_visible)
+    return;
+  //std::cout<<"Changing visible status from "<<m_visible<<" to "<<vis<<" for: "<<*getPRD()<<std::endl;
+  m_visible=vis;
+  if (vis) {
+    m_d->colhandle->incrementNShownHandles();
+    if (!m_d->sepSimple||!m_d->sepDetailed)
+      m_d->rebuild3DObjects(this);//The call to rebuild also fixes attached state.
+    else
+      m_d->attach3DObjects(this);
+  } else {
+    m_d->colhandle->decrementNShownHandles();
+    m_d->detach3DObjects();
+  }
+}
+
+//____________________________________________________________________
+void PRDHandleBase::update3DObjects() {
+  //Fixme: If selected we really need to redo selection updates!!!
+  if (m_visible) {
+    m_d->rebuild3DObjects(this);
+  } else {
+    //Simply clear the present 3D objects. They will only be recreated if/when the prd becomes visible again.
+    if (m_d->sepDetailed) {
+      m_d->sepDetailed->unref();
+      m_d->sepDetailed = 0;
+    }
+    if (m_d->sepSimple) {
+      m_d->sepSimple->unref();
+      m_d->sepSimple = 0;
+    }
+  }
+
+}
+
+//____________________________________________________________________
+QStringList PRDHandleBase::clicked() const
+{
+  const Trk::PrepRawData * prd = getPRD();
+  if (!prd)
+    return QStringList("Null PRD");
+  std::ostringstream os;
+  os << *(prd);
+  return QString(os.str().c_str()).split("\n");
+}
+
+
+//____________________________________________________________________
+Amg::Vector3D PRDHandleBase::Imp::positionPRD(const Trk::PrepRawData* prd)
+{
+  if (!prd)
+    return Amg::Vector3D(0,0,0);
+  if (!prd->detectorElement())
+    return Amg::Vector3D(0.0,0.0,0.0);
+  const Trk::Surface& theSurface = prd->detectorElement()->surface(prd->identify());
+
+  const Amg::Vector3D hitpos = theSurface.localToGlobal(prd->localPosition());
+
+  const Amg::Vector3D pos(hitpos);
+  return pos;
+}
+
+//____________________________________________________________________
+Amg::Vector3D PRDHandleBase::positionPRD() const
+{
+  return Imp::positionPRD(getPRD());
+}
+
+//____________________________________________________________________
+Amg::Vector3D PRDHandleBase::positionSecondPRD() const
+{
+  return Imp::positionPRD(getSecondPRD());
+}
+
+
+//____________________________________________________________________
+Amg::Vector3D PRDHandleBase::center() const
+{
+  return positionPRD();
+}
+
+//____________________________________________________________________
+Amg::Transform3D PRDHandleBase::getTransform_CLHEP() const
+{  
+  if (m_d->sepDetailed&&m_d->sepDetailed->getNumChildren()>0) {
+    //For efficiency/consistency we simply copy the transform from the
+    //inventor transformation (only loose slight precision in the
+    //double->float->double conversions):
+    SoTransform * transform = static_cast<SoTransform*>(m_d->sepDetailed->getChild(0));
+    float tx, ty, tz;
+    transform->translation.getValue().getValue(tx,ty,tz);
+    SbVec3f so_rotaxis;
+    float so_rotangle;
+    transform->rotation.getValue().getValue(so_rotaxis, so_rotangle);
+    float rx, ry, rz;
+    so_rotaxis.getValue(rx,ry,rz);
+    Amg::Vector3D axis(rx,ry,rz);
+//    Amg::AngleAxis3D angleAxis = Amg::getRotation3DfromAngleAxis( so_rotangle, axis );
+//    Amg::Rotation3D rot;
+//    rot = angleAxis;
+    Amg::Rotation3D rot = Amg::getRotation3DfromAngleAxis( so_rotangle, axis );
+    return Amg::Translation3D(tx,ty,tz) * rot;
+  }
+  std::cout<<"VP1 PRDHandleBase Warning: getTransform_CLHEP called at inopportune moment!!"<<std::endl;
+
+  //NB: Some code duplicated here and in the createTransform() method.
+
+  const Trk::PrepRawData * prd = getPRD();
+  if (!prd) {
+    return Amg::Transform3D::Identity();
+  }
+  const Trk::Surface& theSurface = prd->detectorElement()->surface(prd->identify());
+  Amg::Vector3D theHitGPos;
+  if ( transformUsesSurfacePositionOnly() ) {
+    // for tubes, should use position of center of tube (if drawing full tube)
+    theHitGPos= Amg::Vector3D(theSurface.center());
+  } else {
+    // for clusters or short tubes, use position of hit.
+    theHitGPos = theSurface.localToGlobal(prd->localPosition()); //theSurface 'new s' a Vector3D and returns pointer
+  }
+
+//  CLHEP::Hep3Vector t(theSurface.transform().getTranslation());
+//  return HepGeom::Transform3D( HepGeom::Translate3D(theHitGPos->x()-t.x(),theHitGPos->y()-t.y(),theHitGPos->z()-t.z()) * (theSurface.transform()) );
+  Amg::Vector3D t;
+  t = Amg::getTranslationVectorFromTransform(theSurface.transform());
+  Amg::Translation3D transl = Amg::Translation3D(theHitGPos.x()-t.x(), theHitGPos.y()-t.y(), theHitGPos.z()-t.z());
+  Amg::Transform3D transf = transl * (theSurface.transform());
+  return transf;
+}
+
+//____________________________________________________________________
+SoTransform * PRDHandleBase::createTransform() const
+{  
+  //NB: Some code duplicated here and in the getTransform_CLHEP() method.
+  const Trk::PrepRawData * prd = getPRD();
+  if (!prd) {
+    std::cerr<<"PRDHandleBase::createTransform() No prd!"<<std::endl;
+    return new SoTransform;
+  }
+  const Trk::Surface& theSurface = prd->detectorElement()->surface(prd->identify());
+  SoTransform * theHitTransform = VP1LinAlgUtils::toSoTransform(theSurface.transform());
+
+  Amg::Vector3D theHitGPos;
+  if ( transformUsesSurfacePositionOnly() ) {
+    // for tubes, should use position of center of tube (if drawing full tube)
+    theHitGPos= Amg::Vector3D (theSurface.center());
+  } else {
+    // for strips, clusters or short tubes, use position of hit.
+    theHitGPos = theSurface.localToGlobal(prd->localPosition());
+  }
+  if ((theHitGPos)[0]!=(theHitGPos)[0] || (theHitGPos)[1]!=(theHitGPos)[1] || (theHitGPos)[2]!=(theHitGPos)[2]){
+    std::cerr<<"PRDHandleBase::createTransform() NaN in globalposition"<<std::endl;
+  }
+  theHitTransform->translation.setValue((theHitGPos)[0], (theHitGPos)[1], (theHitGPos)[2]);
+  return theHitTransform;
+}
+
+//____________________________________________________________________
+SoMaterial * PRDHandleBase::Imp::determineMaterial(PRDHandleBase*theclass)
+{
+  double hlw = colhandle->highLightWeight();
+  //Get most frequent special case (i.e. no highlighting ) out of the
+  //way first for efficiency:
+  if (colhandle->colourMethod()!=PRDCollHandleBase::ByTechOnly) {
+    std::map<SoMaterial*,double> materials;
+      //-> Retrieve tracks/segments.
+      const PRDTrackSegmentHelper::TracksAndSegments * ts = theclass->common()->trackAndSegmentHelper()->tracksAndSegments(theclass->getPRD());
+      if (ts) {
+	//-> Add all materials from tracks as appropriate
+	if (colhandle->colourByTracks()) {
+	  for (unsigned i = 0; i < ts->tracks.size(); ++i) {
+	    SoMaterial * mat = theclass->common()->trackAndSegmentHelper()->trackMaterial(ts->tracks[i]);
+	    if (mat)
+	      materials[mat]=1.0;
+	    else
+	      std::cout<< "PRDHandleBase ERROR: Did not find track material!"<<std::endl;
+	  }
+	}
+	//-> Add all materials from segments as appropriate
+	if (colhandle->colourBySegments()) {
+	  for (unsigned i = 0; i < ts->segments.size(); ++i) {
+	    SoMaterial * mat = theclass->common()->trackAndSegmentHelper()->segmentMaterial(ts->segments[i]);
+	    if (mat)
+	      materials[mat]=1.0;
+	    else
+	      std::cout<< "PRDHandleBase ERROR: Did not find segment material (2)!"<<std::endl;
+	  }
+	}
+	if (hlw>0.0&&colhandle->highLightOutliers()) {
+	  //Add outliers (if colourbytracks) + a highlightmaterial, all with appropriate weights.
+	  if (colhandle->colourByTracks()&&!ts->tracks_outliers.empty()) {
+	    if (hlw>999.0) {
+	      materials[colhandle->highLightMaterial()] = ts->tracks_outliers.size();
+	    } else {
+	      for (unsigned i = 0; i < ts->tracks_outliers.size(); ++i) {
+		SoMaterial * mat = theclass->common()->trackAndSegmentHelper()->trackMaterial(ts->tracks_outliers[i]);
+		if (mat)
+		  materials[mat]=1.0/(hlw+1.0);
+		else
+		  std::cout<< "PRDHandleBase ERROR: Did not find track material (3)!"<<std::endl;
+	      }
+ 	      materials[colhandle->highLightMaterial()] = ts->tracks_outliers.size()*hlw/(hlw+1.0);
+	    }
+	  }
+	} else {
+	  //Just add materials from outliers - and see if we need highlighting also.
+	  if (colhandle->colourByTracks()) {
+	    for (unsigned i = 0; i < ts->tracks_outliers.size(); ++i) {
+	      SoMaterial * mat = theclass->common()->trackAndSegmentHelper()->trackMaterial(ts->tracks_outliers[i]);
+	      if (mat)
+		materials[mat]=1.0;
+		else
+		  std::cout<< "PRDHandleBase ERROR: Did not find track material (4)!"<<std::endl;
+	    }
+	  }
+	  if (hlw>0.0&&!colhandle->highLightOutliers()&&theclass->highLight()) {
+	    unsigned ntrackssegments= (colhandle->colourByTracks()?ts->tracks.size()+ts->tracks_outliers.size():0)
+                                      +(colhandle->colourBySegments()?ts->segments.size():0);
+	    if (ntrackssegments)
+	      materials[colhandle->highLightMaterial()] = hlw*ntrackssegments;
+	  }
+	}
+	if (!materials.empty())
+	  return theclass->common()->materialMixer()->getMixedMaterial(materials);
+      }
+  }
+
+
+  //OK, just use the tech colour - and possibly some non-outlier-highlighting.
+  if (hlw>0.0&&!colhandle->highLightOutliers()&&theclass->highLight()) {
+    if (hlw>999.0)
+      return colhandle->highLightMaterial();
+    return theclass->common()->materialMixer()->getMixedMaterial(colhandle->highLightMaterial(),hlw,colhandle->material(),1.0);
+  } else {
+    return colhandle->material();
+  }
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandle_SCT.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandle_SCT.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..62a3eb28abf74da4a63d062ff83f1e5cf8c990bc
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandle_SCT.cxx
@@ -0,0 +1,104 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+#include "VTI12PRDSystems/PRDHandle_SCT.h"
+#include "VTI12Utils/HitsSoNodeManager.h"
+#include "VTI12PRDSystems/PRDCollHandle_SCT.h"
+#include "VP1HEPVis/nodes/SoTransparency.h"
+
+#include <Inventor/nodes/SoSeparator.h>
+#include <Inventor/nodes/SoTranslation.h>
+#include <Inventor/nodes/SoMaterial.h>
+
+#include "TrackerReadoutGeometry/SiDetectorElement.h"
+
+#include "GeoPrimitives/GeoPrimitives.h"
+
+
+//____________________________________________________________________
+PRDHandle_SCT::PRDHandle_SCT(PRDCollHandle_SCT*collhandle, const Tracker::FaserSCT_Cluster*clus)
+  : PRDHandleBase(static_cast<PRDCollHandleBase*>(collhandle)), m_cluster(clus)
+{
+    SoTransparency::initClass();
+}
+
+//____________________________________________________________________
+void PRDHandle_SCT::buildShapes(SoNode*&shape_simple, SoNode*&shape_detailed)
+{
+  double striplength = m_cluster->detectorElement()->etaPitch();
+
+  //SoSeparator * errSimple  = new SoSeparator;
+  SoSeparator * errDetailed  = new SoSeparator;
+
+  //errSimple->addChild(common()->nodeManager()->getShapeNode_Strip(striplength));
+  shape_simple=common()->nodeManager()->getShapeNode_Strip(striplength);
+
+  const Amg::Vector2D& localpos = m_cluster->localPosition();
+  const Amg::Vector2D& localposHIT = m_cluster->detectorElement()->rawLocalPositionOfCell( m_cluster->identify() ); // Lorentz shift is not corrected because this class cannot use SiLorentzAngleTool
+  SoTranslation * localtrans0 = new SoTranslation;
+  localtrans0->translation.setValue(localposHIT[Trk::locX]-localpos[Trk::locX],localposHIT[Trk::locY]-localpos[Trk::locY],0);
+
+  const std::vector<Identifier> rdolist = m_cluster->rdoList();
+  if (rdolist.size() == 1 || !collHandle()->drawRDOs())
+  {
+    errDetailed->addChild(localtrans0);
+    errDetailed->addChild(common()->nodeManager()->getShapeNode_Strip(striplength,
+					     m_cluster->detectorElement()->phiPitch( m_cluster->localPosition() ),//strip width
+					     m_cluster->detectorElement()->thickness()*3.0));
+    //strip thickness - scaled up by factor of 3 (looks better)
+    //Fixme: Should we drop this upscaling of thickness?
+
+    //Translate back so errDetailed is left sane (eg. when drawing errors later)
+    SoTranslation * localtransBack = new SoTranslation;
+    localtransBack->translation.setValue(-(localtrans0->translation.getValue()));
+    errDetailed->addChild(localtransBack);
+  } else
+  {
+    SoSeparator * rdos = new SoSeparator;
+    rdos->addChild(localtrans0);
+
+    rdos->addChild(common()->nodeManager()->getShapeNode_Strip(striplength,
+					     m_cluster->detectorElement()->phiPitch( m_cluster->localPosition() ),//strip width
+					     m_cluster->detectorElement()->thickness()*3.0));
+    //strip thickness - scaled up by factor of 3 (looks better)
+    //Fixme: Should we drop this upscaling of thickness?
+
+    SoTransparency * transparent = new SoTransparency;
+    transparent->transparency.setValue(0.5);
+    rdos->addChild( transparent );
+    Amg::Vector2D localposOLD = localposHIT;
+    for (const Identifier& rdo_id : rdolist)
+    {
+      if (rdo_id == m_cluster->identify() )
+        continue;
+
+      const Amg::Vector2D& localposRDO = m_cluster->detectorElement()->rawLocalPositionOfCell(rdo_id); // Lorentz shift is not corrected because this class cannot use SiLorentzAngleTool
+
+      SoTranslation * localtrans = new SoTranslation;
+      localtrans->translation.setValue(localposRDO[Trk::locX]-localposOLD[Trk::locX],localposRDO[Trk::locY]-localposOLD[Trk::locY],0);
+      rdos->addChild(localtrans);
+
+      rdos->addChild(common()->nodeManager()->getShapeNode_Strip(striplength,
+					     m_cluster->detectorElement()->phiPitch( m_cluster->localPosition() ),//strip width
+					     m_cluster->detectorElement()->thickness()*3.0));
+
+      localposOLD = localposRDO;
+    }
+    errDetailed->addChild(rdos);
+  }
+
+//  shape_simple = errSimple;
+  shape_detailed = errDetailed;
+}
+
+//____________________________________________________________________
+int PRDHandle_SCT::regionIndex()
+{
+  //instead of identifier juggling, we simply discretize by center coordinate.
+  static const double l=100.0;//CLHEP::mm
+  return       static_cast<int>(m_cluster->detectorElement()->center().z()/l)
+         +1000*static_cast<int>(m_cluster->detectorElement()->center().y()/l)
+      +1000000*static_cast<int>(m_cluster->detectorElement()->center().x()/l);
+  //Fixme: Use identifiers instead for more intuitive regions.
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandle_SpacePoint.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandle_SpacePoint.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0616dc8168c609e7db9d2367659f022a3d2da63a
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDHandle_SpacePoint.cxx
@@ -0,0 +1,69 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Implementation of class PRDHandle_SpacePoint              //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: September 2008                           //
+//                                                            //
+//           update: March 2014 Riccardo.Maria.Bianchi@cern.ch//
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#include "VTI12PRDSystems/PRDHandle_SpacePoint.h"
+#include "VTI12PRDSystems/PRDCollHandle_SpacePoints.h"
+#include "VTI12Utils/HitsSoNodeManager.h"
+
+#include <Inventor/C/errors/debugerror.h>
+#include <Inventor/nodes/SoPointSet.h>
+#include <Inventor/nodes/SoVertexProperty.h>
+
+//____________________________________________________________________
+class PRDHandle_SpacePoint::Imp {
+public:
+};
+
+
+//____________________________________________________________________
+PRDHandle_SpacePoint::PRDHandle_SpacePoint(PRDCollHandle_SpacePoints* ch, const Tracker::FaserSCT_SpacePoint* sp)
+  : PRDHandleBase(ch), m_sp(sp), m_d(new Imp)
+{
+}
+
+//____________________________________________________________________
+PRDHandle_SpacePoint::~PRDHandle_SpacePoint()
+{
+  delete m_d;
+}
+
+//____________________________________________________________________
+int PRDHandle_SpacePoint::regionIndex() {
+  static const double l=isSCT() ? 100.0 : 200.0;//CLHEP::mm
+  Amg::Vector3D c(center());
+  return       static_cast<int>(c.z()/l)
+         +1000*static_cast<int>(c.y()/l)
+      +1000000*static_cast<int>(c.x()/l);
+  //Fixme: Use identifiers instead for more intuitive regions.
+}
+
+//____________________________________________________________________
+void PRDHandle_SpacePoint::buildShapes(SoNode*&shape_simple, SoNode*&shape_detailed)
+{
+  if (getSecondPRD()) {
+    Amg::Transform3D prdtransform(getTransform_CLHEP());
+    Amg::Vector3D p((prdtransform.inverse())*(m_sp->globalPosition()));
+    SoPointSet       * points    = new SoPointSet;
+    SoVertexProperty * vertices = new SoVertexProperty;
+    vertices->vertex.set1Value(0,p.x(),p.y(),p.z());
+    points->numPoints=1;
+    points->vertexProperty.setValue(vertices);
+    shape_simple = points;
+  } else {
+    shape_simple = common()->nodeManager()->getShapeNode_Point();
+  }
+  shape_detailed = shape_simple;
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDSysCommonData.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDSysCommonData.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..088878c57065aa5129d6a86fa71092cae83a34f6
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDSysCommonData.cxx
@@ -0,0 +1,111 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Implementation of class PRDSysCommonData                  //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: July 2008                                //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#include "VTI12PRDSystems/PRDSysCommonData.h"
+#include "VP1Base/IVP13DSystem.h"
+
+#include "VTI12Utils/HitsSoNodeManager.h"
+#include "VTI12PRDSystems/PRDSystemController.h"
+#include "VTI12PRDSystems/PRDTrackSegmentHelper.h"
+
+// #include "VP1GuideLineSystems/InDetProjHelper.h"
+#include "VP1Base/VP1SoMaterialMixer.h"
+
+#include <Inventor/C/errors/debugerror.h>
+#include <Inventor/nodes/SoSeparator.h>
+#include <Inventor/nodes/SoTransform.h>
+#include <Inventor/SoPath.h>
+
+
+//____________________________________________________________________
+class PRDSysCommonData::Imp {
+public:
+  //The following map is used to figure out which handle a clicked node corresponds to.
+  //We use the SoTransform node to uniquely identify this association.
+  std::map<SoNode*,PRDHandleBase*> sotransform2prdhandle;
+  PRDHandleBase * pickedPathToHandle( SoPath*pickedPath );
+
+  //The following map is used to find handles for a given prd pointer:
+  std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> > prd2handles;
+};
+
+
+//____________________________________________________________________
+PRDSysCommonData::PRDSysCommonData(IVP13DSystem *sys, PRDSystemController*controller)
+  : VP1HelperClassBase(sys,"PRDSysCommonData"), m_d(new Imp),
+    m_controller(controller)
+{
+  m_3dsystem = sys;
+  m_nodeManager = new HitsSoNodeManager(sys);
+  m_materialMixer = new VP1SoMaterialMixer;
+//   m_indetProjHelper_SCT = InDetProjHelper::createSCTHelper(sys);
+
+  m_trackAndSegmentHelper = new PRDTrackSegmentHelper(&(m_d->prd2handles),sys);
+}
+
+//____________________________________________________________________
+PRDSysCommonData::~PRDSysCommonData()
+{
+  delete m_nodeManager;
+  delete m_materialMixer;
+//   delete m_indetProjHelper_SCT;
+  delete m_trackAndSegmentHelper;
+  delete m_d;
+}
+
+//____________________________________________________________________
+void PRDSysCommonData::clearEventData()
+{
+  m_d->sotransform2prdhandle.clear();
+  m_d->prd2handles.clear();
+}
+
+
+//_____________________________________________________________________________________
+void PRDSysCommonData::registerTransform2Handle(SoTransform*transform,PRDHandleBase*handle)
+{
+  assert(m_d->sotransform2prdhandle.find(transform)==m_d->sotransform2prdhandle.end());
+  m_d->sotransform2prdhandle[transform] = handle;
+}
+
+//_____________________________________________________________________________________
+void PRDSysCommonData::registerPRD2Handle(const Trk::PrepRawData*prd,PRDHandleBase*handle)
+{
+  if (m_d->prd2handles.find(prd)==m_d->prd2handles.end()) {
+    QList<PRDHandleBase*> l;
+    l<<handle;
+    m_d->prd2handles[prd] = l;
+  } else {
+    m_d->prd2handles[prd] << handle;
+  }
+}
+
+//_____________________________________________________________________________________
+PRDHandleBase * PRDSysCommonData::pickedPathToHandle( SoPath*pickedPath )
+{
+  while (pickedPath->getLength()>4) {//4 is a bit arbitrary...
+    if (pickedPath->getNodeFromTail(0)->getTypeId()==SoSeparator::getClassTypeId()) {
+      //If at least two children and the first is an SoTransform, then it might be what we are looking for.
+      SoSeparator * sep = static_cast<SoSeparator*>(pickedPath->getNodeFromTail(0));
+      if (sep->getNumChildren()>1&&sep->getChild(0)->getTypeId()==SoTransform::getClassTypeId()) {
+	std::map<SoNode*,PRDHandleBase*>::iterator it = m_d->sotransform2prdhandle.find(sep->getChild(0));
+	if ( it!=m_d->sotransform2prdhandle.end())
+	  return it->second;
+      }
+    }
+    pickedPath->pop();//FIXME:  NO NEED TO DO ANYTHING ELSE THAN FIND THE HANDLE!!
+  }
+  return 0;
+}
+
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDSystemController.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDSystemController.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ab57c6cb1b4facb4de3639b23185887940b03273
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDSystemController.cxx
@@ -0,0 +1,501 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Implementation of class PRDSystemController               //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: November 2007                            //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#define VP1IMPVARNAME m_d
+
+#include "VTI12PRDSystems/PRDSystemController.h"
+#include "ui_vp1prdcontrollerform.h"
+#include "ui_prd_settings_cuts_form.h"
+#include "ui_prd_settings_display_form.h"
+#include "ui_prd_settings_interactions_form.h"
+#include "VP1Base/VP1QtInventorUtils.h"
+#include "VP1Base/VP1Serialise.h"
+#include "VP1Base/VP1Deserialise.h"
+#include "VP1Base/VP1QtUtils.h"
+#include "VP1Base/VP1CollectionWidget.h"
+#include <Inventor/nodes/SoMaterial.h>
+#include <QBuffer>
+#include <QTimer>
+#include <QSet>
+
+//____________________________________________________________________
+class PRDSystemController::Imp {
+public:
+  PRDSystemController * theclass = nullptr;
+  Ui::VP1PrdControllerForm ui{};
+  Ui::PRDSysSettingsInteractionsForm ui_int{};
+  Ui::PRDSysSettingsDisplayForm ui_disp{};
+  Ui::PRDSysSettingsCutsForm ui_cuts{};
+  VP1CollectionWidget * collWidget = nullptr;
+
+  SoMaterial * highlightmaterial = nullptr;
+
+  PRDCollHandleBase::COLOURMETHOD last_colourMethod;
+  bool last_drawErrors = false;
+  bool last_drawRDOs = false;
+  bool last_highLightOutliers = false;
+  double last_highLightMaterialWeight = 0.0;
+  bool last_projectSCTHits = false;
+  //Cuts:
+  VP1Interval last_cutAllowedEta;
+  QList<VP1Interval> last_cutAllowedPhi;//All off: empty list. All on: list with one entry: ]-inf,inf[
+  PRDCommonFlags::TrackerPartsFlags last_trackerPartsFlags;
+  bool last_sctExcludeIsolatedClusters = false;
+  std::set<PRDDetType::Type> last_shownCollectionTypes;
+  bool last_selectionModeMultiple = false;
+  bool last_showSelectionLine = false;
+  //Used ID parts:
+//   InDetProjFlags::DetTypeFlags last_inDetPartsUsingProjections;
+
+  QSet<PRDDetType::Type> shownCollectionTypes() const;
+};
+
+//____________________________________________________________________
+PRDSystemController::PRDSystemController(IVP1System * sys)
+  : VP1Controller(sys,"PRDSystemController"),m_d(new Imp)
+{
+  m_d->theclass = this;
+  m_d->ui.setupUi(this);
+
+  //FIXME: Dialogs and collwidget!
+  m_d->collWidget = new VP1CollectionWidget;
+  //   m_d->trackcollwidget = new TrackCollWidget;
+  setupCollWidgetInScrollArea(m_d->ui.collWidgetScrollArea,m_d->collWidget);
+  initDialog(m_d->ui_cuts, m_d->ui.pushButton_settings_cuts);
+  initDialog(m_d->ui_disp, m_d->ui.pushButton_settings_display);
+  initDialog(m_d->ui_int, m_d->ui.pushButton_settings_interactions);
+
+  m_d->highlightmaterial = 0;
+
+  m_d->ui_int.matButton_multiselline->setMaterial(VP1MaterialButton::createMaterial(1,1,0));
+
+  m_d->ui_cuts.groupBox_cuts_tracksegmentassociation->setVisible(false);//Since it is not used at the moment!
+  if (!VP1QtUtils::environmentVariableIsOn("VP1_DEVEL_ENABLEREFIT"))
+    m_d->ui_int.groupBox_selectionMode->setVisible(false);
+
+  m_d->ui_disp.widget_drawOptions_PixelSCT->setComplexityDisabled();
+  m_d->ui_disp.widget_drawOptions_PixelSCT->setPointSizes(3.0);
+
+  m_d->ui_cuts.etaPhiCutWidget->setEtaCutEnabled(false);
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  //  Setup connections which monitor changes in the controller so that we may emit signals as appropriate:  //
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  addUpdateSlot(SLOT(possibleChange_colourMethod()));
+  connectToLastUpdateSlot(m_d->ui_disp.checkBox_colourByTrack);
+  connectToLastUpdateSlot(m_d->ui_disp.checkBox_colourBySegment);
+  
+  addUpdateSlot(SLOT(possibleChange_drawErrors()));
+  connectToLastUpdateSlot(m_d->ui_disp.checkBox_drawErrors);
+  
+  addUpdateSlot(SLOT(possibleChange_drawRDOs()));
+  connectToLastUpdateSlot(m_d->ui_disp.checkBox_drawRDOs);
+  
+  addUpdateSlot(SLOT(possibleChange_highLightOutliers()));
+  connectToLastUpdateSlot(m_d->ui_disp.horizontalSlider_highlights_intensity);
+
+  addUpdateSlot(SLOT(possibleChange_highLightMaterialWeight()));
+  connectToLastUpdateSlot(m_d->ui_disp.horizontalSlider_highlights_intensity);
+
+  addUpdateSlot(SLOT(possibleChange_highLightOutliers()));
+  connectToLastUpdateSlot(m_d->ui_disp.checkBox_highlight_trackoutliers);
+  connectToLastUpdateSlot(m_d->ui_disp.checkBox_colourByTrack);
+  connectToLastUpdateSlot(m_d->ui_disp.horizontalSlider_highlights_intensity);
+
+//   addUpdateSlot(SLOT(possibleChange_projectSCTHits()));
+//   connectToLastUpdateSlot(m_d->ui_disp.checkBox_showsct_projected);
+
+  addUpdateSlot(SLOT(possibleChange_cutAllowedEta()));
+  connectToLastUpdateSlot(m_d->ui_cuts.etaPhiCutWidget,SIGNAL(allowedEtaChanged(const VP1Interval&)));
+
+  addUpdateSlot(SLOT(possibleChange_cutAllowedPhi()));
+  connectToLastUpdateSlot(m_d->ui_cuts.etaPhiCutWidget,SIGNAL(allowedPhiChanged(const QList<VP1Interval>&)));
+
+  addUpdateSlot(SLOT(possibleChange_trackerPartsFlags()));
+  connectToLastUpdateSlot(m_d->ui_cuts.checkBox_cut_tracker_interface);
+  connectToLastUpdateSlot(m_d->ui_cuts.checkBox_cut_tracker_upstream);
+  connectToLastUpdateSlot(m_d->ui_cuts.checkBox_cut_tracker_central);
+  connectToLastUpdateSlot(m_d->ui_cuts.checkBox_cut_tracker_downstream);
+
+  addUpdateSlot(SLOT(possibleChange_sctExcludeIsolatedClusters()));
+  connectToLastUpdateSlot(m_d->ui_cuts.checkBox_cut_sct_excludeisolatedclusters);
+
+  // addUpdateSlot(SLOT(possibleChange_inDetPartsUsingProjections()));
+  // connectToLastUpdateSlot(this,SIGNAL(projectSCTHitsChanged(bool)));
+  // connectToLastUpdateSlot(this,SIGNAL(trackerPartsFlagsChanged(PRDCommonFlags::TrackerPartsFlags)));
+  // connectToLastUpdateSlot(collWidget(),SIGNAL(visibleStdCollectionTypesChanged(const QList<qint32>&)));
+
+  addUpdateSlot(SLOT(possibleChange_selectionModeMultiple()));
+  connectToLastUpdateSlot(m_d->ui_int.checkBox_selModeMultiple);
+
+  addUpdateSlot(SLOT(possibleChange_showSelectionLine()));
+  connectToLastUpdateSlot(m_d->ui_int.checkBox_showSelectionLine);
+
+  addUpdateSlot(SLOT(possibleChange_shownCollectionTypes()));
+  connectToLastUpdateSlot(collWidget(),SIGNAL(visibleStdCollectionTypesChanged(const QList<qint32>&)));
+
+  // addUpdateSlot(SLOT(updateHighlightGui()));
+  // connectToLastUpdateSlot(this,SIGNAL(highLightOutliersChanged(bool)));
+
+  //Stateless:
+  connect(m_d->ui_int.pushButton_clearSelection,SIGNAL(clicked()),this,SLOT(emitClearSelection()));
+
+  initLastVars();
+
+}
+
+//____________________________________________________________________
+PRDSystemController::~PRDSystemController()
+{
+  if (m_d->highlightmaterial)
+    m_d->highlightmaterial->unref();
+  delete m_d;
+}
+
+//____________________________________________________________________
+VP1CollectionWidget * PRDSystemController::collWidget() const
+{
+  return m_d->collWidget;
+}
+
+//____________________________________________________________________
+SoGroup * PRDSystemController::drawOptions(PRDDetType::Type t) const
+{
+  //FIXME: SET APPROPRIATE DEFAULTS!!!!
+  switch (t) {
+  case PRDDetType::SCT:
+  case PRDDetType::SpacePoints:
+    return m_d->ui_disp.widget_drawOptions_PixelSCT->drawOptionsGroup();
+  default:
+    return m_d->ui_disp.widget_drawOptions_PixelSCT->drawOptionsGroup();
+  }
+}
+
+//____________________________________________________________________
+QSet<PRDDetType::Type> PRDSystemController::Imp::shownCollectionTypes() const
+{
+  QSet<PRDDetType::Type> s;
+  foreach (qint32 i,collWidget->visibleStdCollectionTypes()) {
+    bool ok;
+    PRDDetType::Type t = PRDDetType::intToType(i,ok);
+    if (ok)
+      s.insert(t);
+  }
+  return s;
+}
+
+//____________________________________________________________________
+SoMaterial * PRDSystemController::getMultiSelectionLineMaterial() const
+{
+  QList<SoMaterial*> mats = m_d->ui_int.matButton_multiselline->handledMaterials();
+  if (mats.count()!=1) {
+    message("ERROR: No material in button!");
+    return 0;//probably giving a crash...
+  }
+  return mats.at(0);
+}
+
+//____________________________________________________________________
+void PRDSystemController::emitClearSelection()
+{
+  messageVerbose("Emitting clearSelection()");
+  emit clearSelection();
+}
+
+//____________________________________________________________________
+SoMaterial * PRDSystemController::getHighLightMaterial()
+{
+  if (!m_d->highlightmaterial) {
+    m_d->highlightmaterial = new SoMaterial;
+    m_d->highlightmaterial->ref();
+    m_d->highlightmaterial->diffuseColor.setValue( 1.0f, 0.0f, 0.0f );
+    m_d->ui_disp.materialbutton_highlights_material->copyValuesFromMaterial(m_d->highlightmaterial);
+    m_d->ui_disp.materialbutton_highlights_material->handleMaterial(m_d->highlightmaterial);
+  }
+  return m_d->highlightmaterial;
+}
+
+//____________________________________________________________________
+bool PRDSystemController::printInfoOnClick() const
+{
+  return m_d->ui_int.checkBox_printinfo->isChecked();
+}
+
+//____________________________________________________________________
+bool PRDSystemController::zoomOnClick() const
+{
+  return m_d->ui_int.checkBox_zoom->isChecked();
+}
+
+//____________________________________________________________________
+VP1Interval PRDSystemController::cutAllowedEta() const
+{
+  return m_d->ui_cuts.etaPhiCutWidget->allowedEta();
+}
+
+//____________________________________________________________________
+QList<VP1Interval> PRDSystemController::cutAllowedPhi() const
+{
+  return m_d->ui_cuts.etaPhiCutWidget->allowedPhi();
+}
+
+//____________________________________________________________________
+PRDCommonFlags::TrackerPartsFlags PRDSystemController::trackerPartsFlags() const
+{
+  PRDCommonFlags::TrackerPartsFlags flag = PRDCommonFlags::None;
+  if (m_d->ui_cuts.checkBox_cut_tracker_interface->isChecked()) flag |= PRDCommonFlags::Interface;
+  if (m_d->ui_cuts.checkBox_cut_tracker_upstream->isChecked()) flag |= PRDCommonFlags::Upstream;
+  if (m_d->ui_cuts.checkBox_cut_tracker_central->isChecked()) flag |= PRDCommonFlags::Central;
+  if (m_d->ui_cuts.checkBox_cut_tracker_downstream->isChecked()) flag |= PRDCommonFlags::Downstream;
+  return flag;
+}
+
+//____________________________________________________________________
+bool PRDSystemController::sctExcludeIsolatedClusters() const
+{
+  return m_d->ui_cuts.checkBox_cut_sct_excludeisolatedclusters->isChecked();
+}
+
+//____________________________________________________________________
+PRDCollHandleBase::COLOURMETHOD PRDSystemController::colourMethod() const
+{
+  if (m_d->ui_disp.checkBox_colourByTrack->isChecked()) {
+    if (m_d->ui_disp.checkBox_colourBySegment->isChecked())
+      return PRDCollHandleBase::BySegmentAndTrack;
+    else
+      return PRDCollHandleBase::ByTrack;
+  } else {
+    if (m_d->ui_disp.checkBox_colourBySegment->isChecked())
+      return PRDCollHandleBase::BySegment;
+    else
+      return PRDCollHandleBase::ByTechOnly;
+  }
+}
+
+//____________________________________________________________________
+bool PRDSystemController::drawErrors() const
+{
+  if (m_d->ui_disp.checkBox_drawErrors->isChecked()) return true;
+  return false;
+}
+
+//____________________________________________________________________
+bool PRDSystemController::drawRDOs() const
+{
+  if (m_d->ui_disp.checkBox_drawRDOs->isChecked()) return true;
+  return false;
+}
+
+
+//____________________________________________________________________
+bool PRDSystemController::highLightOutliers() const
+{
+  return highLightMaterialWeight() != 0.0
+    && m_d->ui_disp.checkBox_highlight_trackoutliers->isChecked() && m_d->ui_disp.checkBox_colourByTrack->isChecked();
+}
+
+// //____________________________________________________________________
+// void PRDSystemController::updateHighlightGui()
+// {
+//   const bool outlierHLEnabledInGui(m_d->ui_disp.checkBox_highlight_trackoutliers->isChecked() && m_d->ui_disp.checkBox_colourByTrack->isChecked());
+//   m_d->ui_disp.checkBox_highlight_trtht->setEnabled(!outlierHLEnabledInGui);
+//   m_d->ui_disp.checkBox_highlight_maskedmdts->setEnabled(!outlierHLEnabledInGui);
+//   m_d->ui_disp.checkBox_highlight_mdt_ADC_below->setEnabled(!outlierHLEnabledInGui);
+//   m_d->ui_disp.spinBox_highlight_mdt_ADC_below->setEnabled(!outlierHLEnabledInGui);
+// }
+
+//____________________________________________________________________
+double PRDSystemController::highLightMaterialWeight() const
+{
+  int val = m_d->ui_disp.horizontalSlider_highlights_intensity->value();
+  if (val<=1) return 0.0;
+  if (val==2) return 1.0;
+  if (val==3) return 1.9;
+  if (val==4) return 2.8;
+  if (val==5) return 5.0;
+  return 99999.0;
+}
+
+//____________________________________________________________________
+// bool PRDSystemController::projectSCTHits() const { return m_d->ui_disp.checkBox_showsct_projected->isChecked(); }
+
+// //____________________________________________________________________
+// InDetProjFlags::DetTypeFlags PRDSystemController::inDetPartsUsingProjections() const
+// {
+//   std::set<PRDDetType::Type> showncolltypes =  shownCollectionTypes();
+//   PRDCommonFlags::InDetPartsFlags indetparts = inDetPartsFlags();
+
+//   InDetProjFlags::DetTypeFlags flag = InDetProjFlags::NoDet;
+
+//   if ( projectPixelHits() && showncolltypes.find(PRDDetType::Pixel)!=showncolltypes.end() ) {
+//     if (indetparts & PRDCommonFlags::BarrelPositive)
+//       flag |= InDetProjFlags::Pixel_brlpos;
+//     if (indetparts & PRDCommonFlags::BarrelNegative)
+//       flag |= InDetProjFlags::Pixel_brlneg;
+//     if (indetparts & PRDCommonFlags::EndCapPositive)
+//       flag |= InDetProjFlags::Pixel_ecpos;
+//     if (indetparts & PRDCommonFlags::EndCapNegative)
+//       flag |= InDetProjFlags::Pixel_ecneg;
+//   }
+
+//   if ( projectSCTHits() && showncolltypes.find(PRDDetType::SCT)!=showncolltypes.end() ) {
+//     if (indetparts & PRDCommonFlags::BarrelPositive)
+//       flag |= InDetProjFlags::SCT_brlpos;
+//     if (indetparts & PRDCommonFlags::BarrelNegative)
+//       flag |= InDetProjFlags::SCT_brlneg;
+//     if (indetparts & PRDCommonFlags::EndCapPositive)
+//       flag |= InDetProjFlags::SCT_ecpos;
+//     if (indetparts & PRDCommonFlags::EndCapNegative)
+//       flag |= InDetProjFlags::SCT_ecneg;
+//   }
+
+//   if ( projectTRTHits() && showncolltypes.find(PRDDetType::TRT)!=showncolltypes.end() ) {
+//      if (indetparts & PRDCommonFlags::BarrelPositive)
+//       flag |= InDetProjFlags::TRT_brlpos;
+//     if (indetparts & PRDCommonFlags::BarrelNegative)
+//       flag |= InDetProjFlags::TRT_brlneg;
+//     if (indetparts & PRDCommonFlags::EndCapPositive)
+//       flag |= InDetProjFlags::TRT_ecpos;
+//     if (indetparts & PRDCommonFlags::EndCapNegative)
+//       flag |= InDetProjFlags::TRT_ecneg;
+//   }
+
+//   return flag;
+// }
+
+//____________________________________________________________________
+bool PRDSystemController::selectionModeMultiple() const
+{
+  return m_d->ui_int.checkBox_selModeMultiple->isChecked();
+}
+
+//____________________________________________________________________
+bool PRDSystemController::showSelectionLine() const
+{
+  return m_d->ui_int.checkBox_showSelectionLine->isChecked();
+}
+
+//____________________________________________________________________
+std::set<PRDDetType::Type> PRDSystemController::shownCollectionTypes() const
+{
+  std::set<PRDDetType::Type> s;
+  foreach(qint32 i, collWidget()->visibleStdCollectionTypes()) {
+    bool ok;
+    PRDDetType::Type t = PRDDetType::intToType(i, ok);
+    if (ok)
+      s.insert(t);
+    else
+      message("shownCollectionTypes ERROR: Could not decode collection type");
+  }
+  return s;
+}
+
+
+//____________________________________________________________________
+int PRDSystemController::currentSettingsVersion() const
+{
+  return 1;
+}
+
+//____________________________________________________________________
+void PRDSystemController::actualSaveSettings(VP1Serialise&s) const
+{
+  s.save(m_d->ui_disp.checkBox_colourByTrack);
+  s.save(m_d->ui_disp.checkBox_colourBySegment);
+  s.save(m_d->ui_disp.checkBox_highlight_trackoutliers);
+  s.save(m_d->ui_cuts.checkBox_cut_tracker_interface);
+  s.save(m_d->ui_cuts.checkBox_cut_tracker_upstream);
+  s.save(m_d->ui_cuts.checkBox_cut_tracker_central);
+  s.save(m_d->ui_cuts.checkBox_cut_tracker_downstream);
+  s.save(m_d->ui_cuts.checkBox_cut_sct_excludeisolatedclusters);
+//   s.save(m_d->ui_disp.checkBox_showsct_projected);
+  s.save(m_d->ui_disp.horizontalSlider_highlights_intensity);
+  s.save(m_d->ui_disp.materialbutton_highlights_material);
+  s.save(m_d->ui_int.checkBox_selModeMultiple);
+  s.save(m_d->ui_int.checkBox_showSelectionLine);
+  s.save(m_d->ui_int.matButton_multiselline);
+  s.save(m_d->ui_cuts.etaPhiCutWidget);
+  s.save(m_d->ui_disp.widget_drawOptions_PixelSCT);
+  s.save(m_d->ui_int.checkBox_printinfo);
+  s.save(m_d->ui_int.checkBox_zoom);
+
+  s.save(m_d->ui_disp.checkBox_drawErrors);
+  s.save(m_d->ui_disp.checkBox_drawRDOs);
+
+  //Not used yet:
+  s.ignoreWidget(m_d->ui_cuts.checkBox_cuts_ts_exclude_hits_on_track);
+  s.ignoreWidget(m_d->ui_cuts.checkBox_cuts_ts_exclude_hits_not_on_track);
+  s.ignoreWidget(m_d->ui_cuts.checkBox_cuts_ts_exclude_hits_on_segments);
+  s.ignoreWidget(m_d->ui_cuts.checkBox_cuts_ts_exclude_not_on_segments);
+
+}
+
+
+//____________________________________________________________________
+void PRDSystemController::actualRestoreSettings(VP1Deserialise& s)
+{
+  if (s.version()<0||s.version()>1) {
+    message("Warning: State data in .vp1 file has unsupported version ("+str(s.version())+")");
+    return;
+  }
+  s.restore(m_d->ui_disp.checkBox_colourByTrack);
+  s.restore(m_d->ui_disp.checkBox_colourBySegment);
+  s.restore(m_d->ui_disp.checkBox_highlight_trackoutliers);
+  s.restore(m_d->ui_cuts.checkBox_cut_tracker_interface);
+  s.restore(m_d->ui_cuts.checkBox_cut_tracker_upstream);
+  s.restore(m_d->ui_cuts.checkBox_cut_tracker_central);
+  s.restore(m_d->ui_cuts.checkBox_cut_tracker_downstream);
+  s.restore(m_d->ui_cuts.checkBox_cut_sct_excludeisolatedclusters);
+//   s.restore(m_d->ui_disp.checkBox_showsct_projected);
+  s.restore(m_d->ui_disp.horizontalSlider_highlights_intensity);
+  s.restore(m_d->ui_disp.materialbutton_highlights_material);
+  s.restore(m_d->ui_int.checkBox_selModeMultiple);
+  s.restore(m_d->ui_int.checkBox_showSelectionLine);
+  s.restore(m_d->ui_int.matButton_multiselline);
+  s.restore(m_d->ui_cuts.etaPhiCutWidget);
+  s.restore(m_d->ui_disp.widget_drawOptions_PixelSCT);
+  s.restore(m_d->ui_int.checkBox_printinfo);
+  s.restore(m_d->ui_int.checkBox_zoom);
+
+  s.restore(m_d->ui_disp.checkBox_drawErrors);
+  s.restore(m_d->ui_disp.checkBox_drawRDOs);
+  
+  //Not used yet:
+  s.ignoreWidget(m_d->ui_cuts.checkBox_cuts_ts_exclude_hits_on_track);
+  s.ignoreWidget(m_d->ui_cuts.checkBox_cuts_ts_exclude_hits_not_on_track);
+  s.ignoreWidget(m_d->ui_cuts.checkBox_cuts_ts_exclude_hits_on_segments);
+  s.ignoreWidget(m_d->ui_cuts.checkBox_cuts_ts_exclude_not_on_segments);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Test for possible changes in values and emit signals as appropriate:
+// (possibleChange_XXX() slots code provided by macros)
+#define VP1CONTROLLERCLASSNAME PRDSystemController
+#include "VP1Base/VP1ControllerMacros.h"
+
+//The actual code for each variable:
+// POSSIBLECHANGE_IMP(projectSCTHits)
+POSSIBLECHANGE_IMP(highLightMaterialWeight)
+// POSSIBLECHANGE_IMP(inDetPartsUsingProjections)
+POSSIBLECHANGE_IMP(cutAllowedEta)
+POSSIBLECHANGE_IMP(cutAllowedPhi)
+POSSIBLECHANGE_IMP(trackerPartsFlags)
+POSSIBLECHANGE_IMP(sctExcludeIsolatedClusters)
+POSSIBLECHANGE_IMP(shownCollectionTypes)
+POSSIBLECHANGE_IMP(selectionModeMultiple)
+POSSIBLECHANGE_IMP(showSelectionLine)
+POSSIBLECHANGE_IMP(colourMethod)
+POSSIBLECHANGE_IMP(highLightOutliers)
+POSSIBLECHANGE_IMP(drawErrors)
+POSSIBLECHANGE_IMP(drawRDOs)
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDTrackSegmentHelper.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDTrackSegmentHelper.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6c95319ca563ca46604349f10e4ad53dde1ec378
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/PRDTrackSegmentHelper.cxx
@@ -0,0 +1,532 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+
+////////////////////////////////////////////////////////////////
+//                                                            //
+//  Implementation of class PRDTrackSegmentHelper             //
+//                                                            //
+//  Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch)  //
+//  Initial version: December 2007                            //
+//                                                            //
+////////////////////////////////////////////////////////////////
+
+#include "VTI12PRDSystems/PRDTrackSegmentHelper.h"
+#include "VTI12PRDSystems/PRDCollHandleBase.h"
+#include "VTI12PRDSystems/PRDHandleBase.h"
+
+#include "TrkMeasurementBase/MeasurementBase.h"
+#include "TrkRIO_OnTrack/RIO_OnTrack.h"
+#include "TrkCompetingRIOsOnTrack/CompetingRIOsOnTrack.h"
+#include "AthContainers/DataVector.h"
+#include "TrkTrack/Track.h"
+#include "TrkSegment/Segment.h"
+
+#include <set>
+
+//____________________________________________________________________
+class PRDTrackSegmentHelper::Imp {
+public:
+  PRDTrackSegmentHelper * theclass = nullptr;
+  std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >* prd2handles = nullptr;
+
+  std::map< const Trk::Track*, const SoMaterial* > tracks2mat;
+  std::map< const Trk::Segment*, const SoMaterial* > segments2mat;
+
+
+  void addTrackToPRDs(const Trk::Track *, bool outliers );
+  void removeTrackFromPRDs(const Trk::Track *, bool outliers);
+  void updateMaterialOfPRDs(const Trk::Track *, bool outliers );
+
+  void addSegmentToPRDs(const Trk::Segment * );
+  void removeSegmentFromPRDs(const Trk::Segment *);
+  void updateMaterialOfPRDs(const Trk::Segment * );
+
+  template <class T>
+  void removeEntryFromVector(std::vector<T*>&v,T*t);//Removes first occurrence of t from v (does nothing if not found).
+                                                    //Element order is not preserved. FIXME: To utility class.
+
+  //static inline const Trk::PrepRawData* measurementToPRD(const Trk::MeasurementBase*);//Might return null.
+  static inline std::vector<const Trk::PrepRawData*> measurementToPRDs(const Trk::MeasurementBase*);//Might return empty vector.
+
+  //We keep this map around in order to give track associations for
+  //prds (in particular those whose handles are created after the
+  //change in visible tracks):
+  //
+  //NB (TK): I guess a track association tool could do this too - but
+  //why add that dependency for something which is dead simple?
+  std::map< const Trk::PrepRawData*,TracksAndSegments > prdsOnTracksAndSegments;
+
+};
+
+//____________________________________________________________________
+template <class T>
+void PRDTrackSegmentHelper::Imp::removeEntryFromVector(std::vector<T*>&v,T*t)
+{
+  const unsigned n(v.size());
+  for (unsigned i(0); i<n;++i) {
+    if (v[i]==t) {
+      if (i==n-1) {
+	v.resize(n-1);
+	return;
+      } else {
+	v[i]=v[n-1];
+	v.resize(n-1);
+	return;
+      }
+    }
+  }
+}
+
+//____________________________________________________________________
+PRDTrackSegmentHelper::PRDTrackSegmentHelper(std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >* prd2handles,
+					     IVP1System* sys, QObject * parent)
+  : QObject(parent), VP1HelperClassBase(sys,"PRDTrackSegmentHelper"), m_d(new Imp)
+{
+  m_d->theclass = this;
+  m_d->prd2handles = prd2handles;
+}
+
+//____________________________________________________________________
+PRDTrackSegmentHelper::~PRDTrackSegmentHelper()
+{
+  delete m_d;
+}
+
+//____________________________________________________________________
+void PRDTrackSegmentHelper::visibleTracksChanged(const std::vector< std::pair<const Trk::Track*, const SoMaterial*> >& tracks)
+{
+  //NB: Code here is very similar to code in visibleSegmentsChanged!!
+  messageVerbose("visibleTracksChanged start (old ntracks = "+QString::number(m_d->tracks2mat.size())
+		 +", new ntracks = "+QString::number(tracks.size())+")");
+
+  if (tracks.empty()) {
+    //Special case #1 - loop over previous track's, remove their pointers from the relevant prd handles + update their materials.
+    messageVerbose("special case #1 - new track list is empty");
+    std::map< const Trk::Track*, const SoMaterial* >::iterator it, itE = m_d->tracks2mat.end();
+    for (it=m_d->tracks2mat.begin();it!=itE;++it) {
+      m_d->removeTrackFromPRDs(it->first,false);//measurements
+      m_d->removeTrackFromPRDs(it->first,true);//outliers
+    }
+    m_d->tracks2mat.clear();
+    messageVerbose("visibleTracksChanged end");
+    return;
+  }
+
+  if (m_d->tracks2mat.empty()) {
+    //special case #2 - no previous tracks, so just loop over incoming
+    //tracks, and add their pointers to the relevant prd handles + update their materials.
+    messageVerbose("special case #2 - old track list is empty");
+    std::vector< std::pair<const Trk::Track*, const SoMaterial*> >::const_iterator it(tracks.begin()), itE(tracks.end());
+    for (;it!=itE;++it) {
+      m_d->tracks2mat.insert(*it);
+      m_d->addTrackToPRDs(it->first, false );//measurements
+      m_d->addTrackToPRDs(it->first, true );//outliers
+    }
+    messageVerbose("visibleTracksChanged end");
+    return;
+  }
+
+  //Normal case - need to remove some trackpointers, add some, and for others possibly just update their materials.
+  messageVerbose("normal case - neither old, nor new, track lists are empty");
+
+  //First check if any previously visible tracks simply disappeared.
+  // --> Create std::set for faster searches.
+  std::set<const Trk::Track*> newtracksset;
+    std::vector< std::pair<const Trk::Track*, const SoMaterial*> >::const_iterator it(tracks.begin()), itE(tracks.end());
+    for (;it!=itE;++it)
+      newtracksset.insert(it->first);
+  std::set<const Trk::Track*>::const_iterator newtrackssetEnd(newtracksset.end());
+
+  // --> Check old tracks versus this set - remove if no match:
+  std::map< const Trk::Track*, const SoMaterial* >::iterator it2, it2E = m_d->tracks2mat.end();
+  for (it2=m_d->tracks2mat.begin();it2!=it2E;) {
+    if (newtracksset.find(it2->first)==newtrackssetEnd) {
+      m_d->removeTrackFromPRDs(it2->first,false);//measurements
+      m_d->removeTrackFromPRDs(it2->first,true);//outliers
+      m_d->tracks2mat.erase(it2++);//postfix ++ operator must be used as here (due to the erase call)
+    } else {
+      it2++;
+    }
+  }
+
+  // Next, check all tracks that are now visible - if not previously
+  // visible we add their pointers to the relevant handles. If just
+  // the material changed, we make sure the prd handle updates its
+  // material.
+  it2E=m_d->tracks2mat.end();
+  for (it=tracks.begin();it!=itE;++it) {
+    it2 = m_d->tracks2mat.find(it->first);
+    if (it2==it2E) {
+      m_d->tracks2mat[it->first] = it->second;
+      m_d->addTrackToPRDs(it->first, false );//measurements
+      m_d->addTrackToPRDs(it->first, true );//outliers
+    } else {
+      //we need to update the track material - but only if it changed of course.
+      if (it->second!=it2->second) {
+	m_d->tracks2mat[it->first] = it->second;
+	m_d->updateMaterialOfPRDs(it->first, false );//measurements
+	m_d->updateMaterialOfPRDs(it->first, true );//outliers
+      }
+    }
+  }
+  messageVerbose("visibleTracksChanged end");
+
+}
+
+//____________________________________________________________________
+void PRDTrackSegmentHelper::visibleSegmentsChanged(const std::vector< std::pair<const Trk::Segment*, const SoMaterial*> >& segments)
+{
+  //NB: Code here is very similar to code in visibleTracksChanged!!
+  messageVerbose("visibleSegmentsChanged start (old nsegments = "+QString::number(m_d->segments2mat.size())
+		 +", new nsegments = "+QString::number(segments.size())+")");
+
+  if (segments.empty()) {
+    //Special case #1 - loop over previous segment's, remove their pointers from the relevant prd handles + update their materials.
+    messageVerbose("special case #1 - new segment list is empty");
+    std::map< const Trk::Segment*, const SoMaterial* >::iterator it, itE = m_d->segments2mat.end();
+    for (it=m_d->segments2mat.begin();it!=itE;++it) {
+      m_d->removeSegmentFromPRDs(it->first);
+    }
+    m_d->segments2mat.clear();
+    messageVerbose("visibleSegmentsChanged end");
+    return;
+  }
+
+  if (m_d->segments2mat.empty()) {
+    //special case #2 - no previous segments, so just loop over incoming
+    //segments, and add their pointers to the relevant prd handles + update their materials.
+    messageVerbose("special case #2 - old segment list is empty");
+    std::vector< std::pair<const Trk::Segment*, const SoMaterial*> >::const_iterator it(segments.begin()), itE(segments.end());
+    for (;it!=itE;++it) {
+      m_d->segments2mat.insert(*it);
+      m_d->addSegmentToPRDs(it->first );
+    }
+    messageVerbose("visibleSegmentsChanged end");
+    return;
+  }
+
+  //Normal case - need to remove some segmentpointers, add some, and for others possibly just update their materials.
+  messageVerbose("normal case - neither old, nor new, segment lists are empty");
+
+  //First check if any previously visible segments simply disappeared.
+  // --> Create std::set for faster searches.
+  std::set<const Trk::Segment*> newsegmentsset;
+    std::vector< std::pair<const Trk::Segment*, const SoMaterial*> >::const_iterator it(segments.begin()), itE(segments.end());
+    for (;it!=itE;++it)
+      newsegmentsset.insert(it->first);
+  std::set<const Trk::Segment*>::const_iterator newsegmentssetEnd(newsegmentsset.end());
+
+  // --> Check old segments versus this set - remove if no match:
+  std::map< const Trk::Segment*, const SoMaterial* >::iterator it2, it2E = m_d->segments2mat.end();
+  for (it2=m_d->segments2mat.begin();it2!=it2E;) {
+    if (newsegmentsset.find(it2->first)==newsegmentssetEnd) {
+      m_d->removeSegmentFromPRDs(it2->first);
+      m_d->segments2mat.erase(it2++);//postfix ++ operator must be used as here (due to the erase call)
+    } else {
+      it2++;
+    }
+  }
+
+  // Next, check all segments that are now visible - if not previously
+  // visible we add their pointers to the relevant handles. If just
+  // the material changed, we make sure the prd handle updates its
+  // material.
+  it2E=m_d->segments2mat.end();
+  for (it=segments.begin();it!=itE;++it) {
+    it2 = m_d->segments2mat.find(it->first);
+    if (it2==it2E) {
+      m_d->segments2mat[it->first] = it->second;
+      m_d->addSegmentToPRDs(it->first);
+    } else {
+      //we need to update the segment material - but only if it changed of course.
+      if (it->second!=it2->second) {
+	m_d->segments2mat[it->first] = it->second;
+	m_d->updateMaterialOfPRDs(it->first);
+      }
+    }
+  }
+  messageVerbose("visibleSegmentsChanged end");
+}
+
+//____________________________________________________________________
+void PRDTrackSegmentHelper::Imp::addSegmentToPRDs(const Trk::Segment * seg)
+{
+  // if (verbose())
+  //   theclass->messageVerbose("addSegmentToPRDs start");
+  if (!seg) {
+    theclass->message("ERROR: Received null segment pointer!");
+    return;
+  }
+  std::map< const Trk::PrepRawData*,TracksAndSegments >::iterator itInfo;
+  std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >::const_iterator itHandle, itHandleEnd(prd2handles->end());
+  std::vector<const Trk::MeasurementBase*>::const_iterator
+    it (seg->containedMeasurements().begin()), itE(seg->containedMeasurements().end());
+  const Trk::PrepRawData * prd;
+  for (;it!=itE;++it) {
+    std::vector<const Trk::PrepRawData*> prds = Imp::measurementToPRDs(*it); // need to handle compound measurements too.
+    std::vector<const Trk::PrepRawData*>::const_iterator itPrd = prds.begin(), itEnd=prds.end();
+    for (;itPrd!=itEnd;itPrd++){
+      prd = *itPrd;
+      itInfo = prdsOnTracksAndSegments.find(prd);
+      if (itInfo==prdsOnTracksAndSegments.end()) {
+        prdsOnTracksAndSegments.insert(std::pair<const Trk::PrepRawData*,TracksAndSegments>(prd,
+          TracksAndSegments(std::vector<const Trk::Track*>(),
+          std::vector<const Trk::Track*>(),
+          std::vector< const Trk::Segment* >(1,seg))));
+
+      } else {
+        itInfo->second.segments.push_back(seg);
+      }
+      itHandle = prd2handles->find(prd);
+      if (itHandle!=itHandleEnd) {
+        QList<PRDHandleBase*> handles = itHandle->second;
+        foreach (PRDHandleBase*handle,handles)
+          if (handle->collHandle()->colourBySegments())
+          handle->updateMaterial();
+      }
+
+    }
+  }
+  // theclass->messageVerbose("addSegmentToPRDs end");
+}
+
+//____________________________________________________________________
+void PRDTrackSegmentHelper::Imp::removeSegmentFromPRDs(const Trk::Segment * seg)
+{
+  // if (verbose())
+  //   theclass->messageVerbose("removeSegmentFromPRDs start");
+  if (!seg) {
+    theclass->message("ERROR: Received null segment pointer!");
+    return;
+  }
+  std::map< const Trk::PrepRawData*,TracksAndSegments >::iterator itInfo;
+  std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >::const_iterator itHandle, itHandleEnd(prd2handles->end());
+  std::vector<const Trk::MeasurementBase*>::const_iterator
+    it (seg->containedMeasurements().begin()), itE(seg->containedMeasurements().end());
+  const Trk::PrepRawData * prd;
+  for (;it!=itE;++it) {
+    std::vector<const Trk::PrepRawData*> prds = Imp::measurementToPRDs(*it); // need to handle compound measurements too.
+    std::vector<const Trk::PrepRawData*>::const_iterator itPrd = prds.begin(), itEnd=prds.end();
+    for (;itPrd!=itEnd;itPrd++){
+      prd = *itPrd;
+      itInfo = prdsOnTracksAndSegments.find(prd);
+      if (itInfo!=prdsOnTracksAndSegments.end()) {
+        removeEntryFromVector(itInfo->second.segments,seg);
+        itHandle = prd2handles->find(prd);
+        if (itHandle!=itHandleEnd) {
+          QList<PRDHandleBase*> handles = itHandle->second;
+          foreach (PRDHandleBase*handle,handles)
+            if (handle->collHandle()->colourBySegments())
+            handle->updateMaterial();
+        }
+      }
+    }
+  }
+
+  // if (verbose())
+  //   theclass->messageVerbose("removeSegmentToPRDs end");
+}
+
+//____________________________________________________________________
+void PRDTrackSegmentHelper::Imp::updateMaterialOfPRDs(const Trk::Segment * seg)
+{
+  // if (verbose())
+  //   theclass->messageVerbose("updateMaterialOfPRDs(segment) start");
+  if (!seg) {
+    theclass->message("ERROR: Received null segment pointer!");
+    return;
+  }
+  std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >::const_iterator itHandle, itHandleEnd(prd2handles->end());
+  std::vector<const Trk::MeasurementBase*>::const_iterator
+    it (seg->containedMeasurements().begin()), itE(seg->containedMeasurements().end());
+  const Trk::PrepRawData * prd;
+  for (;it!=itE;++it) {
+    std::vector<const Trk::PrepRawData*> prds = Imp::measurementToPRDs(*it); // need to handle compound measurements too.
+    std::vector<const Trk::PrepRawData*>::const_iterator itPrd = prds.begin(), itEnd=prds.end();
+    for (;itPrd!=itEnd;itPrd++){
+      prd = *itPrd;
+      itHandle = prd2handles->find(prd);
+      if (itHandle!=itHandleEnd) {
+        QList<PRDHandleBase*> handles = itHandle->second;
+        foreach (PRDHandleBase*handle,handles)
+          if (handle->collHandle()->colourByTracks())
+          handle->updateMaterial();
+      }
+    }
+  }
+
+  // if (verbose())
+  //   theclass->messageVerbose("updateMaterialOfPRDs(segment) end");
+}
+
+//____________________________________________________________________
+void PRDTrackSegmentHelper::Imp::addTrackToPRDs(const Trk::Track * trk, bool outliers )
+{
+  // if (verbose())
+  //   theclass->messageVerbose("addTrackToPRDs start");
+  if (!trk) {
+    theclass->message("ERROR: Received null track pointer!");
+    return;
+  }
+  std::map< const Trk::PrepRawData*,TracksAndSegments >::iterator itInfo;
+  std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >::const_iterator itHandle, itHandleEnd(prd2handles->end());
+  DataVector<const Trk::MeasurementBase>::const_iterator
+    it ( outliers ? trk->outliersOnTrack()->begin() : trk->measurementsOnTrack()->begin() ),
+    itE( outliers ? trk->outliersOnTrack()->end() : trk->measurementsOnTrack()->end() );
+  const Trk::PrepRawData * prd;
+  for (;it!=itE;++it) {
+    std::vector<const Trk::PrepRawData*> prds = Imp::measurementToPRDs(*it); // need to handle compound measurements too.
+    std::vector<const Trk::PrepRawData*>::const_iterator itPrd = prds.begin(), itEnd=prds.end();
+    for (;itPrd!=itEnd;itPrd++){
+      prd = *itPrd;
+      if (prd) {
+        itInfo = prdsOnTracksAndSegments.find(prd);
+        if (itInfo==prdsOnTracksAndSegments.end()) {
+          prdsOnTracksAndSegments.insert(std::pair<const Trk::PrepRawData*,TracksAndSegments>(prd,
+            TracksAndSegments((outliers?std::vector<const Trk::Track*>():std::vector<const Trk::Track*>(1,trk)),
+            (outliers?std::vector<const Trk::Track*>(1,trk):std::vector<const Trk::Track*>()),
+            std::vector< const Trk::Segment* >())));
+        } else {
+          if (outliers)
+            itInfo->second.tracks_outliers.push_back(trk);
+          else
+            itInfo->second.tracks.push_back(trk);
+        }
+        itHandle = prd2handles->find(prd);
+        if (itHandle!=itHandleEnd) {
+          QList<PRDHandleBase*> handles = itHandle->second;
+          foreach (PRDHandleBase*handle,handles)
+            if (handle->collHandle()->colourByTracks())
+            handle->updateMaterial();
+        }
+      }
+    }
+  }
+  // if (verbose())
+  //   theclass->messageVerbose("addTrackToPRDs end");
+}
+
+//____________________________________________________________________
+void PRDTrackSegmentHelper::Imp::removeTrackFromPRDs(const Trk::Track * trk, bool outliers)
+{
+  // if (verbose())
+  //   theclass->messageVerbose("removeTrackFromPRDs start");
+  if (!trk) {
+    theclass->message("ERROR: Received null track pointer!");
+    return;
+  }
+  std::map< const Trk::PrepRawData*,TracksAndSegments >::iterator itInfo;
+  std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >::const_iterator itHandle, itHandleEnd(prd2handles->end());
+  DataVector<const Trk::MeasurementBase>::const_iterator
+    it ( outliers ? trk->outliersOnTrack()->begin() : trk->measurementsOnTrack()->begin() ),
+    itE( outliers ? trk->outliersOnTrack()->end() : trk->measurementsOnTrack()->end() );
+  const Trk::PrepRawData * prd;
+  for (;it!=itE;++it) {
+    std::vector<const Trk::PrepRawData*> prds = Imp::measurementToPRDs(*it); // need to handle compound measurements too.
+    std::vector<const Trk::PrepRawData*>::const_iterator itPrd = prds.begin(), itEnd=prds.end();
+    for (;itPrd!=itEnd;itPrd++){
+      prd = *itPrd;
+      itInfo = prdsOnTracksAndSegments.find(prd);
+      if (itInfo!=prdsOnTracksAndSegments.end()) {
+        removeEntryFromVector((outliers?itInfo->second.tracks_outliers:itInfo->second.tracks),trk);
+        itHandle = prd2handles->find(prd);
+        if (itHandle!=itHandleEnd) {
+          QList<PRDHandleBase*> handles = itHandle->second;
+          foreach (PRDHandleBase*handle,handles)
+            if (handle->collHandle()->colourByTracks())
+            handle->updateMaterial();
+        }
+      }
+    }
+  }
+
+  // if (verbose())
+  //   theclass->messageVerbose("removeTrackToPRDs end");
+}
+
+//____________________________________________________________________
+void PRDTrackSegmentHelper::Imp::updateMaterialOfPRDs(const Trk::Track * trk, bool outliers )
+{
+  // if (verbose())
+  //   theclass->messageVerbose("updateMaterialOfPRDs(track) start");
+  if (!trk) {
+    theclass->message("ERROR: Received null track pointer!");
+    return;
+  }
+  std::map< const Trk::PrepRawData *, QList<PRDHandleBase *> >::const_iterator itHandle, itHandleEnd(prd2handles->end());
+  DataVector<const Trk::MeasurementBase>::const_iterator
+    it ( outliers ? trk->outliersOnTrack()->begin() : trk->measurementsOnTrack()->begin() ),
+    itE( outliers ? trk->outliersOnTrack()->end() : trk->measurementsOnTrack()->end() );
+  const Trk::PrepRawData * prd;
+  for (;it!=itE;++it) {
+    std::vector<const Trk::PrepRawData*> prds = Imp::measurementToPRDs(*it); // need to handle compound measurements too.
+    std::vector<const Trk::PrepRawData*>::const_iterator itPrd = prds.begin(), itEnd=prds.end();
+    for (;itPrd!=itEnd;itPrd++){
+      prd = *itPrd;
+      itHandle = prd2handles->find(prd);
+      if (itHandle!=itHandleEnd) {
+        QList<PRDHandleBase*> handles = itHandle->second;
+        foreach (PRDHandleBase*handle,handles)
+          if (handle->collHandle()->colourByTracks())
+          handle->updateMaterial();
+      }
+    }
+  }
+
+  // if (verbose())
+  //   theclass->messageVerbose("updateMaterialOfPRDs(track) end");
+}
+
+//____________________________________________________________________
+const PRDTrackSegmentHelper::TracksAndSegments * PRDTrackSegmentHelper::tracksAndSegments(const Trk::PrepRawData* prd)
+{
+  std::map< const Trk::PrepRawData*,TracksAndSegments >::iterator itInfo = m_d->prdsOnTracksAndSegments.find(prd);
+  return itInfo == m_d->prdsOnTracksAndSegments.end() ? 0 : &(itInfo->second);
+}
+
+
+//____________________________________________________________________
+inline  std::vector<const Trk::PrepRawData *> PRDTrackSegmentHelper::Imp::measurementToPRDs(const Trk::MeasurementBase* measbase)
+{
+  std::vector<const Trk::PrepRawData *>prds;
+  const Trk::RIO_OnTrack * rio = dynamic_cast<const Trk::RIO_OnTrack *>(measbase);
+  if (rio) prds.push_back( rio->prepRawData() );
+  const Trk::CompetingRIOsOnTrack * crot = dynamic_cast<const Trk::CompetingRIOsOnTrack *>(measbase);
+  if (crot) {
+
+	//    for (unsigned int i=0; i< crot->numberOfContainedROTs (); ++i) prds.push_back( crot->rioOnTrack(i) ? crot->rioOnTrack(i)->prepRawData() : 0 );
+    for (unsigned int i=0; i< crot->numberOfContainedROTs (); ++i) {
+    	if (crot->rioOnTrack(i).identify().getString() != "") { // FIXME: search for a better way to see if the rioOnTrack is present
+    		prds.push_back(crot->rioOnTrack(i).prepRawData());
+    	}
+    	else {
+    		prds.push_back(0);
+    	}
+    }
+  }
+  return prds;
+}
+
+//____________________________________________________________________
+inline PRDTrackSegmentHelper::TracksAndSegments::TracksAndSegments(const std::vector<const Trk::Track*>& t,
+								   const std::vector<const Trk::Track*>& to,
+								   const std::vector< const Trk::Segment* >& s )
+  : tracks(t), tracks_outliers(to), segments(s)
+{
+}
+
+//____________________________________________________________________
+SoMaterial * PRDTrackSegmentHelper::trackMaterial(const Trk::Track* t) const
+{
+  std::map< const Trk::Track*, const SoMaterial* >::const_iterator it = m_d->tracks2mat.find(t);
+  return it == m_d->tracks2mat.end() ? 0 : const_cast<SoMaterial *>(it->second);//fixme; const_cast is temporary hack. Remove const from materials!
+}
+
+//____________________________________________________________________
+SoMaterial * PRDTrackSegmentHelper::segmentMaterial(const Trk::Segment* s) const
+{
+  std::map< const Trk::Segment*, const SoMaterial* >::const_iterator it = m_d->segments2mat.find(s);
+  return it == m_d->segments2mat.end() ? 0 : const_cast<SoMaterial *>(it->second);//fixme; const_cast is temporary hack. Remove const from materials!
+}
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/VP1PrepRawDataSystem.cxx b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/VP1PrepRawDataSystem.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8aaa32ec8be75b88a88de538c4a011516c29e6b5
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/VP1PrepRawDataSystem.cxx
@@ -0,0 +1,523 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//Fixme: cleanup includes.
+#include "VTI12Utils/VP1JobConfigInfo.h"
+#include "VTI12Utils/VP1DetInfo.h"
+#include "VTI12PRDSystems/VP1PrepRawDataSystem.h"
+#include "VTI12PRDSystems/PRDSystemController.h"
+#include "VTI12PRDSystems/PRDSysCommonData.h"
+#include "VTI12PRDSystems/PRDHandleBase.h"
+#include "VTI12PRDSystems/PRDTrackSegmentHelper.h"
+#include "VTI12PRDSystems/PRDCollHandle_SCT.h"
+#include "VTI12PRDSystems/PRDCollHandle_SpacePoints.h"
+
+#include "VP1Base/VP1Serialise.h"
+#include "VP1Base/VP1Deserialise.h"
+#include "VP1Base/VP1CollectionWidget.h"
+#include "VP1Base/SoCooperativeSelection.h"
+#include "VP1Base/VP1QtInventorUtils.h"
+#include "VP1Base/VP1CameraHelper.h"
+
+#include <QBuffer>
+#include <QByteArray>
+
+#include <Inventor/nodes/SoSeparator.h>
+#include <Inventor/nodes/SoComplexity.h>
+#include <Inventor/nodes/SoTransform.h>
+#include <Inventor/nodes/SoMaterial.h>
+#include <Inventor/nodes/SoDrawStyle.h>
+#include <Inventor/nodes/SoSwitch.h>
+#include <Inventor/nodes/SoLineSet.h>
+#include <Inventor/nodes/SoPickStyle.h>
+#include <Inventor/nodes/SoVertexProperty.h>
+#include <Inventor/SoPath.h>
+
+#include <map>
+
+//Fixme: Update visuals if any detail level changes!
+
+//____________________________________________________________________
+class VP1PrepRawDataSystem::Imp {
+public:
+  VP1PrepRawDataSystem * theclass = nullptr;
+  PRDSysCommonData * common = nullptr;
+  PRDSystemController * controller = nullptr;
+  SoCooperativeSelection * selNode_click = nullptr;
+  SoCooperativeSelection * selNode_highlight = nullptr;
+  
+//   InDetProjFlags::InDetProjPartsFlags idprojflags_sct;
+  
+  SoSeparator * multisel_sep = nullptr;
+  void clearMultiSelLine() {
+    while (multisel_sep&&multisel_sep->getNumChildren()>2)
+      multisel_sep->removeChild(2);
+  }
+  
+  QList<PRDHandleBase*> currentlySelectedHandles;
+  QList<const Trk::PrepRawData*> lastEmittedPRDList;
+  void selectionChanged() {
+    currentlySelectedHandles.removeAll(0);//just to be sure
+    clearMultiSelLine();
+    
+    //Proper highlighting:
+    if (selNode_highlight) {
+      selNode_highlight->deselectAll();
+      foreach(PRDHandleBase*handle,currentlySelectedHandles) {
+        // 	theclass->messageDebug("Highlighting handle...");
+        SoSeparator* target = handle->collHandle()->simpleDetailLevel() ? handle->sepSimple() : handle->sepDetailed();
+        SoPath * path = new SoPath(selNode_highlight);
+        path->ref();
+        // 	theclass->messageDebug("Attempting to highlight sep="+str(target));
+        if (!VP1QtInventorUtils::changePathTail(path,selNode_highlight,target)) {
+          theclass->message("ERROR: Failed to relocate picked node.");
+          path->unref();
+          continue;
+        }
+        selNode_highlight->select(path);
+        path->unref();
+      }
+      selNode_highlight->touch();
+      if (multisel_sep&&currentlySelectedHandles.count()>1&&controller->showSelectionLine()) {
+        SoLineSet * line = new SoLineSet;
+        SoVertexProperty * vertices = new SoVertexProperty;
+        line->vertexProperty = vertices;
+        line->numVertices.set1Value(0,currentlySelectedHandles.count());
+        int i(0);
+        foreach(PRDHandleBase*handle,currentlySelectedHandles) {
+          Amg::Vector3D pos(handle->center());
+          vertices->vertex.set1Value(i++,pos.x(),pos.y(),pos.z());
+        }
+        multisel_sep->addChild(line);
+        //Fixme: make this unpickable!!
+        
+      }
+    }
+    
+    //emit signal if appropriate:
+    QList<const Trk::PrepRawData*> currentPRDs;
+    for(int i = 0; i < currentlySelectedHandles.count(); ++i) {
+      PRDHandleBase*handle = currentlySelectedHandles.at(i);
+      const Trk::PrepRawData* prd1 = handle->getPRD();
+      const Trk::PrepRawData* prd2 = handle->getSecondPRD();
+      if (prd1&&currentPRDs.contains(prd1)) prd1 = 0;
+      if (prd2&&currentPRDs.contains(prd2)) prd2 = 0;
+      if (!prd2) {
+        if (!prd1)
+          continue;
+        currentPRDs << prd1;
+      } else {
+        //both prd1 and prd2 are non-zero and not in the list
+        //already. Which should be first? We order them by distance to
+        //the preceding or following prd.
+        
+        Amg::Vector3D p1(handle->positionPRD());
+        Amg::Vector3D p2(handle->positionSecondPRD());
+        
+        if (i>0) {
+          Amg::Vector3D prevpos = currentlySelectedHandles.at(i-1)->center();
+          if ((p1-prevpos).mag2()>(p2-prevpos).mag2()) {
+            //prd2 before prd1
+            currentPRDs << prd2;
+            currentPRDs << prd1;
+          } else {
+            //prd1 before prd2
+            currentPRDs << prd1;
+            currentPRDs << prd2;
+          }
+        } else {
+          if (i+1<currentlySelectedHandles.count()) {
+            Amg::Vector3D nextpos = currentlySelectedHandles.at(i+1)->center();
+            if ((p1-nextpos).mag2()>(p2-nextpos).mag2()) {
+              //prd1 before prd2
+              currentPRDs << prd1;
+              currentPRDs << prd2;
+            } else {
+              //prd2 before prd1
+              currentPRDs << prd2;
+              currentPRDs << prd1;
+            }
+          } else {
+            //Only this one. Just add them:
+            currentPRDs << prd1;
+            currentPRDs << prd2;
+          }
+        }
+      }
+    }
+    if (currentPRDs!=lastEmittedPRDList) {
+      lastEmittedPRDList = currentPRDs;
+      theclass->messageVerbose("Emitting list of "+str(lastEmittedPRDList.count())+" selected PRDs");
+      emit theclass->selectedPRDsChanged(lastEmittedPRDList);
+    }
+  }
+  
+  template <class T>
+  QList<PRDCollHandleBase*> createSpecificCollections() {
+    QList<PRDCollHandleBase*> l;
+    foreach (QString name, T::availableCollections(theclass)) {
+      T * col = new T(common,name);
+      col->init();
+      l << col;
+    }
+    return l;
+  }
+  QList<PRDCollHandleBase*> createCollections() {
+    QList<PRDCollHandleBase*> l;
+    l << createSpecificCollections<PRDCollHandle_SCT>();
+    l << createSpecificCollections<PRDCollHandle_SpacePoints>();
+    return l;
+  }
+  
+  void ensureInitCommonData() {
+    if (!common) {
+      theclass->ensureBuildController();
+      common = new PRDSysCommonData(theclass,controller);
+    }
+  }
+};
+
+//_____________________________________________________________________________________
+VP1PrepRawDataSystem::VP1PrepRawDataSystem()
+: IVP13DSystemSimple("Hits",
+                     "System showing tracking hits (PRD's)",
+                     "Edward.Moyse@cern.ch, Thomas.Kittelmann@cern.ch"), m_d(new Imp)
+{
+  m_d->theclass = this;
+  m_d->common = 0;
+  m_d->controller = 0;
+//   m_d->idprojflags_sct = InDetProjFlags::NoProjections;
+  m_d->selNode_click = 0;
+  m_d->selNode_highlight = 0;
+  m_d->multisel_sep = 0;
+  
+}
+
+//_____________________________________________________________________________________
+VP1PrepRawDataSystem::~VP1PrepRawDataSystem()
+{
+  delete m_d;
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::systemcreate(StoreGateSvc* /*detstore*/)
+{
+  messageVerbose("systemcreate");
+  m_d->ensureInitCommonData();
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::systemuncreate()
+{
+  if (m_d->multisel_sep) {
+    m_d->multisel_sep->unref();
+    m_d->multisel_sep=0;
+  }
+  
+  delete m_d->common; m_d->common = 0;
+  m_d->controller = 0;
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::systemerase()
+{
+  messageVerbose("systemerase");
+  
+  deselectAll();
+  
+  m_d->common->controller()->collWidget()->clear();
+  
+  m_d->common->clearEventData();
+  
+  if (m_d->selNode_click) {
+    unregisterSelectionNode(m_d->selNode_click);
+    unregisterSelectionNode(m_d->selNode_highlight);
+    m_d->selNode_click->unref();
+    m_d->selNode_click=0;
+    m_d->selNode_highlight->unref();
+    m_d->selNode_highlight=0;
+  }
+  
+  m_d->clearMultiSelLine();
+  
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::buildPermanentSceneGraph(StoreGateSvc* /*detstore*/, SoSeparator * /*root*/)
+{
+  messageVerbose("buildPermanentSceneGraph (does not do anything)");
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::buildEventSceneGraph(StoreGateSvc*, SoSeparator *root)
+{
+  messageVerbose("buildEventSceneGraph");
+  
+  // set complexity to a lower value, so that e.g. the straws are manageable
+  SoComplexity * complexity = new SoComplexity;
+  complexity->value.setValue(0.3f);//Fixme: Hardcoded here and elsewhere
+  root->addChild(complexity);
+  
+  //   //Point sizes and line widths:
+  //   root->addChild(m_d->controller->prdDrawStyle());
+  
+  //Create collection list based on contents of event store, inform
+  //about projections, populate gui and apply states:
+  QList<PRDCollHandleBase*> cols = m_d->createCollections();
+  
+  //Inform about appropriate projects:
+  foreach (PRDCollHandleBase* col,cols) {
+    
+    connect(col,SIGNAL(detailLevelChanged()),this,SLOT(updateSelectionVisualsAndPossiblyEmitPRDList()));
+        
+  }
+  
+  m_d->controller->collWidget()->setCollections(cols);
+  
+  
+  //Add collections to event scenegraph:
+  m_d->selNode_click = new SoCooperativeSelection;
+  m_d->selNode_click->ref();
+  m_d->selNode_highlight = new SoCooperativeSelection;
+  m_d->selNode_highlight->ref();
+  m_d->selNode_click->activePolicy = SoCooperativeSelection::ACTIVE;
+  m_d->selNode_highlight->activePolicy = SoCooperativeSelection::INERT;
+  m_d->selNode_click->policy = SoCooperativeSelection::SINGLE;
+  m_d->selNode_highlight->policy = SoCooperativeSelection::SINGLE;
+  
+  foreach (VP1StdCollection* col,m_d->controller->collWidget()->collections<VP1StdCollection>())
+  m_d->selNode_click->addChild(col->collSwitch());
+  m_d->selNode_highlight->addChild(m_d->selNode_click);
+  root->addChild(m_d->selNode_highlight);
+  
+  registerSelectionNode(m_d->selNode_click);
+  registerSelectionNode(m_d->selNode_highlight);
+  
+  if (!m_d->multisel_sep) {
+    m_d->multisel_sep = new SoSeparator;
+    m_d->multisel_sep->ref();
+    SoPickStyle * ps = new SoPickStyle;
+    ps->style= SoPickStyle::UNPICKABLE;
+    m_d->multisel_sep->addChild(ps);
+    m_d->multisel_sep->addChild(m_d->controller->getMultiSelectionLineMaterial());
+  }
+  root->addChild(m_d->multisel_sep);
+  
+  
+  messageVerbose("buildEventSceneGraph done");
+  
+}
+
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::deselectAll(SoCooperativeSelection* exception_sel)
+{
+  if (exception_sel)
+    message("WARNING: The PRD system always deselects all registered nodes/");
+  IVP13DSystemSimple::deselectAll(0);
+  m_d->currentlySelectedHandles.clear();
+  m_d->selectionChanged();
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::selectionVisualsChanged()
+{
+  m_d->selectionChanged();
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::clearSelection()
+{
+  messageVerbose("clearSelection");
+  deselectAll();
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::selectionModeChanged()
+{
+  messageVerbose("selectionModeChanged");
+  deselectAll();
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::updateSelectionVisualsAndPossiblyEmitPRDList()
+{
+  messageVerbose("updateSelectionVisualsAndPossiblyEmitPRDList");
+  m_d->selectionChanged();
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::userPickedNode(SoNode*, SoPath *)
+{
+  messageVerbose("userPickedNode");
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::userSelectedSingleNode(SoCooperativeSelection* sel, SoNode*, SoPath*pickedPath)
+{
+  if (m_d->selNode_highlight==sel)
+    return;
+  messageVerbose("userSelectedSingleNode");
+  PRDHandleBase * handle = m_d->common->pickedPathToHandle(pickedPath);//This also pops the path, so that all shape nodes
+  //making up the whole shape will be highlighted
+  sel->deselectAll();
+  
+  if (!handle) {
+    deselectAll();
+    message("Error: Could not identify picked node");
+    return;
+  }
+  
+  if (!m_d->controller->selectionModeMultiple()) {
+    if (m_d->currentlySelectedHandles.count()==1&&*(m_d->currentlySelectedHandles.begin())==handle)
+      return;
+    m_d->currentlySelectedHandles.clear();
+    m_d->currentlySelectedHandles<<handle;
+    if (m_d->controller->zoomOnClick()) {
+      std::set<SoCamera*> cameras(getCameraList());
+      std::set<SoCamera*>::iterator it,itE = cameras.end();
+      for (it=cameras.begin();it!=itE;++it)
+        VP1CameraHelper::animatedZoomToPath(*it,handle->collHandle()->collSep(),pickedPath,2.0,1.0);
+    }
+    if (m_d->controller->printInfoOnClick()) {
+      foreach (QString line, handle->clicked())
+      message(line);
+    }
+  } else {
+    if (m_d->currentlySelectedHandles.contains(handle)) {
+      m_d->currentlySelectedHandles.removeAll(handle);
+    } else {
+      m_d->currentlySelectedHandles << handle;
+    }
+  }
+  
+  m_d->selectionChanged();
+  
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::userDeselectedSingleNode(SoCooperativeSelection* sel, SoNode*, SoPath*)
+{
+  if (m_d->selNode_highlight==sel)
+    return;
+  //  messageVerbose("userDeselectedSingleNode");
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::userChangedSelection(SoCooperativeSelection*sel , QSet<SoNode*>, QSet<SoPath*>)
+{
+  if (m_d->selNode_highlight==sel)
+    return;
+  messageVerbose("userChangedSelection");
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::userClickedOnBgd()
+{
+  messageVerbose("userClickedOnBgd");
+  if (!m_d->controller->selectionModeMultiple()) {
+    m_d->currentlySelectedHandles.clear();
+    m_d->selectionChanged();
+  }
+}
+
+
+//_____________________________________________________________________________________
+QWidget * VP1PrepRawDataSystem::buildController()
+{
+  messageVerbose("buildController");
+  m_d->controller = new PRDSystemController(this);
+  
+//   messageVerbose("Passing ID projection settings on to collWidget");
+  
+  connect(m_d->controller,SIGNAL(selectionModeMultipleChanged(bool)),this,SLOT(selectionModeChanged()));
+  connect(m_d->controller,SIGNAL(showSelectionLineChanged(bool)),this,SLOT(selectionVisualsChanged()));
+  connect(m_d->controller,SIGNAL(clearSelection()),this,SLOT(clearSelection()));
+  
+//   connect(m_d->controller,SIGNAL(inDetPartsUsingProjectionsChanged(InDetProjFlags::DetTypeFlags)),
+//           this,SLOT(emitUsedIDProjectionsChanged(InDetProjFlags::DetTypeFlags)));
+//   InDetProjFlags::DetTypeFlags f = m_d->controller->inDetPartsUsingProjections();
+//   if ( f != InDetProjFlags::NoDet)
+//     emitUsedIDProjectionsChanged(f);//Fixme: Check that this is actually sufficiently late for the guideline sys!!!
+  
+  return m_d->controller;
+}
+
+//_____________________________________________________________________________________
+QByteArray VP1PrepRawDataSystem::saveState() {
+  
+  VP1Serialise serialise(0/*version*/,this);
+  serialise.save(IVP13DSystemSimple::saveState());
+  
+  ensureBuildController();
+  
+  serialise.save(m_d->controller->saveSettings());
+  serialise.save(m_d->controller->collWidget());
+  
+  serialise.disableUnsavedChecks();//We do the testing in the controller
+  return serialise.result();
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::restoreFromState(QByteArray ba) {
+  //Version & base state:
+  VP1Deserialise state(ba,this);
+  if (state.version()!=0) {
+    message("Warning: State data in .vp1 file is in wrong format - ignoring!");
+    return;
+  }
+  ensureBuildController();
+  
+  IVP13DSystemSimple::restoreFromState(state.restoreByteArray());
+  
+  m_d->controller->restoreSettings(state.restoreByteArray());
+  state.restore(m_d->controller->collWidget());//We do the testing in the controller
+  
+  state.disableUnrestoredChecks();//We do the testing in the controller
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::visibleTracksChanged(const std::vector< std::pair<const Trk::Track*, const SoMaterial*> >& tracks)
+{
+  m_d->ensureInitCommonData();
+  if (!m_d->common)
+    return;//for signals received after uncreate
+  m_d->common->trackAndSegmentHelper()->visibleTracksChanged(tracks);
+  selectionVisualsChanged();
+}
+
+//_____________________________________________________________________________________
+void VP1PrepRawDataSystem::visibleSegmentsChanged(const std::vector< std::pair<const Trk::Segment*, const SoMaterial*> >& segments)
+{
+  m_d->ensureInitCommonData();
+  if (!m_d->common)
+    return;//for signals received after uncreate
+  m_d->common->trackAndSegmentHelper()->visibleSegmentsChanged(segments);
+  selectionVisualsChanged();
+}
+
+// //_____________________________________________________________________________________
+// void VP1PrepRawDataSystem::emitUsedIDProjectionsChanged(InDetProjFlags::DetTypeFlags f)
+// {
+//   messageVerbose("emits usedIDProjectionsChanged");
+//   emit usedIDProjectionsChanged(f);
+// }
+
+// //_____________________________________________________________________________________
+// void VP1PrepRawDataSystem::setApplicableIDProjections( InDetProjFlags::InDetProjPartsFlags sct)
+// {
+//   messageVerbose("Signal received in setApplicableProjections (from "
+//                  +QString(sender()?sender()->objectName():"NULL sender")+")");
+//   if (m_d->idprojflags_sct==sct) {
+//     return;
+//   }
+  
+//   m_d->idprojflags_sct = sct;
+  
+//   if (!m_d->controller)
+//     return;//applied upon creation of collections instead
+   
+//   //NB: Add for pixel/sct as well once supported!
+  
+// }
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_cuts_form.ui b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_cuts_form.ui
new file mode 100644
index 0000000000000000000000000000000000000000..e7ae1dbecd13c7219377e730d4e2a8fe28cb92f3
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_cuts_form.ui
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PRDSysSettingsCutsForm</class>
+ <widget class="QWidget" name="PRDSysSettingsCutsForm">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>528</width>
+    <height>536</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_2">
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>Direction</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <item>
+       <widget class="VP1EtaPhiCutWidget" name="etaPhiCutWidget" native="true"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QGroupBox" name="groupBox_cuts_idgeneral">
+     <property name="title">
+      <string>Tracker General</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_4">
+      <item>
+       <layout class="QGridLayout" name="_3">
+        <property name="horizontalSpacing">
+         <number>6</number>
+        </property>
+        <property name="verticalSpacing">
+         <number>0</number>
+        </property>
+        <item row="0" column="0" colspan="2">
+         <widget class="QLabel" name="label_9">
+          <property name="text">
+           <string>Show data from stations:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0">
+         <widget class="QCheckBox" name="checkBox_cut_tracker_interface">
+          <property name="text">
+           <string>Interface (Station 0)</string>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QCheckBox" name="checkBox_cut_tracker_upstream">
+          <property name="text">
+           <string>Upstream (Station 1)</string>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0">
+         <widget class="QCheckBox" name="checkBox_cut_tracker_central">
+          <property name="text">
+           <string>Central (Station 2)</string>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1">
+         <widget class="QCheckBox" name="checkBox_cut_tracker_downstream">
+          <property name="text">
+           <string>Downstream (Station 3)</string>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <spacer>
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>1</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QGroupBox" name="groupBox_cuts_sct">
+     <property name="title">
+      <string>SCT</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <item>
+       <widget class="QCheckBox" name="checkBox_cut_sct_excludeisolatedclusters">
+        <property name="toolTip">
+         <string>&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Require the neighbouring wafer to have at least one cluster.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+        </property>
+        <property name="text">
+         <string>Exclude isolated SCT clusters</string>
+        </property>
+        <property name="checked">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="3" column="0" colspan="2">
+    <widget class="QGroupBox" name="groupBox_cuts_tracksegmentassociation">
+     <property name="title">
+      <string>Track/Segment association cuts</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_5">
+      <item>
+       <layout class="QVBoxLayout" name="_9">
+        <property name="spacing">
+         <number>0</number>
+        </property>
+        <item>
+         <widget class="QCheckBox" name="checkBox_cuts_ts_exclude_hits_on_track">
+          <property name="text">
+           <string>Exclude hits on tracks</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="checkBox_cuts_ts_exclude_hits_not_on_track">
+          <property name="text">
+           <string>Exclude hits not on tracks</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="checkBox_cuts_ts_exclude_hits_on_segments">
+          <property name="text">
+           <string>Exclude hits on segments</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="checkBox_cuts_ts_exclude_not_on_segments">
+          <property name="text">
+           <string>Exclude hits not on segments</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <spacer>
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>1</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="4" column="0" colspan="2">
+    <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <property name="spacing">
+      <number>0</number>
+     </property>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pushButton_close">
+       <property name="text">
+        <string>&amp;Close</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>VP1EtaPhiCutWidget</class>
+   <extends>QWidget</extends>
+   <header>VP1Base/VP1EtaPhiCutWidget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_display_form.ui b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_display_form.ui
new file mode 100644
index 0000000000000000000000000000000000000000..da8809026fdd23debd96ddb4884db5ea5b208954
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_display_form.ui
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PRDSysSettingsDisplayForm</class>
+ <widget class="QWidget" name="PRDSysSettingsDisplayForm">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>470</width>
+    <height>437</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_3">
+   <item row="4" column="0" colspan="2">
+    <layout class="QHBoxLayout">
+     <property name="spacing">
+      <number>0</number>
+     </property>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pushButton_close">
+       <property name="text">
+        <string>&amp;Close</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="0" column="1" rowspan="4">
+    <layout class="QVBoxLayout" name="verticalLayout_4">
+     <item>
+      <widget class="QGroupBox" name="groupBox_2">
+       <property name="title">
+        <string>Draw style - SCT</string>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <item>
+         <widget class="VP1DrawOptionsWidget" name="widget_drawOptions_PixelSCT" native="true"/>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Association Colouring</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Colour by:</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="checkBox_colourByTrack">
+        <property name="toolTip">
+         <string>If selected, PrepRawData which are assigned to a track will take the colour of that track.</string>
+        </property>
+        <property name="text">
+         <string>Tracks</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="checkBox_colourBySegment">
+        <property name="toolTip">
+         <string>If selected, PrepRawData which are assigned to a segment will take the colour of that segment.</string>
+        </property>
+        <property name="text">
+         <string>Segments</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QGroupBox" name="groupBox_highlights">
+     <property name="title">
+      <string>Highlights</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="4" column="0" colspan="2">
+       <layout class="QHBoxLayout" name="_5">
+        <property name="spacing">
+         <number>0</number>
+        </property>
+       </layout>
+      </item>
+      <item row="0" column="0">
+       <layout class="QHBoxLayout" name="_7">
+        <item>
+         <widget class="QLabel" name="label_highlights_material">
+          <property name="text">
+           <string>Colour:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="VP1MaterialButton" name="materialbutton_highlights_material">
+          <property name="text">
+           <string/>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item row="0" column="1">
+       <layout class="QHBoxLayout" name="_8">
+        <property name="spacing">
+         <number>5</number>
+        </property>
+        <item>
+         <widget class="QLabel" name="label_highlights_intensity">
+          <property name="text">
+           <string>Intensity:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSlider" name="horizontalSlider_highlights_intensity">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimum">
+           <number>1</number>
+          </property>
+          <property name="maximum">
+           <number>6</number>
+          </property>
+          <property name="pageStep">
+           <number>1</number>
+          </property>
+          <property name="value">
+           <number>3</number>
+          </property>
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="tickPosition">
+           <enum>QSlider::TicksBelow</enum>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item row="1" column="0" colspan="2">
+       <widget class="QCheckBox" name="checkBox_highlight_trackoutliers">
+        <property name="text">
+         <string>Track Outliers</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QGroupBox" name="groupBox_5">
+     <property name="title">
+      <string>Details</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <item>
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Draw</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="checkBox_drawErrors">
+        <property name="toolTip">
+         <string>If selected, PrepRawData which are assigned to a track will take the colour of that track.</string>
+        </property>
+        <property name="text">
+         <string>Errors</string>
+        </property>
+        <property name="checked">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="checkBox_drawRDOs">
+        <property name="toolTip">
+         <string>If selected, PrepRawData which are assigned to a track will take the colour of that track.</string>
+        </property>
+        <property name="text">
+         <string>RDOs</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>VP1MaterialButton</class>
+   <extends>QPushButton</extends>
+   <header>VP1Base/VP1MaterialButton.h</header>
+  </customwidget>
+  <customwidget>
+   <class>VP1DrawOptionsWidget</class>
+   <extends>QWidget</extends>
+   <header>VP1Base/VP1DrawOptionsWidget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_interactions_form.ui b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_interactions_form.ui
new file mode 100644
index 0000000000000000000000000000000000000000..81889b9b33c19ebef0f18567cfa6b475d684bf77
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/prd_settings_interactions_form.ui
@@ -0,0 +1,178 @@
+<ui version="4.0" >
+ <class>PRDSysSettingsInteractionsForm</class>
+ <widget class="QWidget" name="PRDSysSettingsInteractionsForm" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>256</width>
+    <height>260</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_4" >
+   <item>
+    <widget class="QGroupBox" name="groupBox" >
+     <property name="title" >
+      <string>Action on PRD selection</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2" >
+      <item>
+       <layout class="QVBoxLayout" >
+        <property name="spacing" >
+         <number>-1</number>
+        </property>
+        <item>
+         <widget class="QCheckBox" name="checkBox_printinfo" >
+          <property name="text" >
+           <string>Print information (a dump)</string>
+          </property>
+          <property name="checked" >
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout" >
+        <item>
+         <widget class="QCheckBox" name="checkBox_zoom" >
+          <property name="text" >
+           <string>Zoom</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="_2" >
+          <item>
+           <spacer>
+            <property name="orientation" >
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType" >
+             <enum>QSizePolicy::Fixed</enum>
+            </property>
+            <property name="sizeHint" stdset="0" >
+             <size>
+              <width>20</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_selectionMode" >
+     <property name="title" >
+      <string>Selection mode</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3" >
+      <property name="margin" >
+       <number>4</number>
+      </property>
+      <item>
+       <widget class="QCheckBox" name="checkBox_selModeMultiple" >
+        <property name="text" >
+         <string>Select multiple (for interactive track fits)</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_2" >
+        <item>
+         <spacer name="horizontalSpacer" >
+          <property name="orientation" >
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType" >
+           <enum>QSizePolicy::Fixed</enum>
+          </property>
+          <property name="sizeHint" stdset="0" >
+           <size>
+            <width>20</width>
+            <height>10</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="pushButton_clearSelection" >
+          <property name="text" >
+           <string>Clear</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout" >
+          <item>
+           <widget class="QCheckBox" name="checkBox_showSelectionLine" >
+            <property name="text" >
+             <string>Line</string>
+            </property>
+            <property name="checked" >
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="VP1MaterialButton" name="matButton_multiselline" >
+            <property name="text" >
+             <string/>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" >
+     <property name="spacing" >
+      <number>0</number>
+     </property>
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pushButton_close" >
+       <property name="text" >
+        <string>&amp;Close</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>VP1MaterialButton</class>
+   <extends>QPushButton</extends>
+   <header>VP1Base/VP1MaterialButton.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/vp1prdcontrollerform.ui b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/vp1prdcontrollerform.ui
new file mode 100644
index 0000000000000000000000000000000000000000..a380fad4163f26b55837e480bdab137209d98ca4
--- /dev/null
+++ b/graphics/VTI12/VTI12Systems/VTI12PRDSystems/src/vp1prdcontrollerform.ui
@@ -0,0 +1,102 @@
+<ui version="4.0" >
+ <class>VP1PrdControllerForm</class>
+ <widget class="QWidget" name="VP1PrdControllerForm" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>234</width>
+    <height>135</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" >
+   <property name="leftMargin" >
+    <number>6</number>
+   </property>
+   <property name="topMargin" >
+    <number>6</number>
+   </property>
+   <property name="rightMargin" >
+    <number>0</number>
+   </property>
+   <property name="bottomMargin" >
+    <number>4</number>
+   </property>
+   <property name="horizontalSpacing" >
+    <number>0</number>
+   </property>
+   <item row="0" column="0" >
+    <widget class="QWidget" native="1" name="widget_settingsButtonsPlaceholder" >
+     <property name="sizePolicy" >
+      <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <layout class="QGridLayout" >
+      <property name="margin" >
+       <number>0</number>
+      </property>
+      <property name="spacing" >
+       <number>0</number>
+      </property>
+      <item row="0" column="0" >
+       <widget class="QPushButton" name="pushButton_settings_cuts" >
+        <property name="toolTip" >
+         <string>Configure track cuts on quantities such as eta, phi and momentum</string>
+        </property>
+        <property name="text" >
+         <string>Cuts</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1" >
+       <widget class="QPushButton" name="pushButton_settings_display" >
+        <property name="toolTip" >
+         <string>Configure track colours</string>
+        </property>
+        <property name="text" >
+         <string>Display</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2" >
+       <widget class="QPushButton" name="pushButton_settings_interactions" >
+        <property name="toolTip" >
+         <string>Settings for what happens in response to selections (printout, zooms, ...)</string>
+        </property>
+        <property name="text" >
+         <string>Interactions</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="0" column="1" >
+    <spacer>
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeType" >
+      <enum>QSizePolicy::Preferred</enum>
+     </property>
+     <property name="sizeHint" stdset="0" >
+      <size>
+       <width>1</width>
+       <height>3</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="1" column="0" colspan="2" >
+    <widget class="QScrollArea" name="collWidgetScrollArea" />
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/graphics/VTI12/VTI12Systems/VTI12RawDataSystems/VTI12RawDataSystems/VP1RawDataColl_SCT_RDO.h b/graphics/VTI12/VTI12Systems/VTI12RawDataSystems/VTI12RawDataSystems/VP1RawDataColl_SCT_RDO.h
index 78870c26b9c2dedbbb75c4b3434511c8c2bc253e..3c2eb6a6aae29cc407f019c41db8094e1ccb9c2a 100644
--- a/graphics/VTI12/VTI12Systems/VTI12RawDataSystems/VTI12RawDataSystems/VP1RawDataColl_SCT_RDO.h
+++ b/graphics/VTI12/VTI12Systems/VTI12RawDataSystems/VTI12RawDataSystems/VP1RawDataColl_SCT_RDO.h
@@ -30,8 +30,6 @@ public:
 
   bool cut(VP1RawDataHandleBase*);
 
-  bool usesInDetPartsCuts() { return true; }//To get InDet parts cuts
-
 protected:
   void assignDefaultMaterial(SoMaterial*) const;
   bool load();
diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/CMakeLists.txt b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/CMakeLists.txt
index f8dfd19e8d3c13e9df693506262f6963d17f4e23..6f1fb47a2f414fc7dcd5316a89da7421eed8b59a 100644
--- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/CMakeLists.txt
+++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/CMakeLists.txt
@@ -40,5 +40,4 @@ atlas_add_library( VTI12TrackSystems VTI12TrackSystems/*.h src/*.cxx
    TrkMaterialOnTrack TrkMeasurementBase TrkPrepRawData
    TrkPseudoMeasurementOnTrack TrkRIO_OnTrack TrkSegment TrkTrack
    TrkTrackSummary TrkExInterfaces TrkFitterInterfaces VP1HEPVis
-   #VP1PRDSystems 
    )
diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandleBase.cxx b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandleBase.cxx
index f36256e23acf7d939432d9f84308cbed0319c8df..9ebac1b2ed7f32092f68e0a23734bb889e1afe0b 100644
--- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandleBase.cxx
+++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandleBase.cxx
@@ -194,7 +194,7 @@ void TrackCollHandleBase::setupSettingsFromController(TrackSystemController* con
   assert(controller);
   largeChangesBegin();
 
-  connect(controller->customTourEditor(),SIGNAL(clipVolumeRadiusChanged(double)),this,SLOT(clipVolumeChanged(double)));
+  if (controller->customTourEditor()) connect(controller->customTourEditor(),SIGNAL(clipVolumeRadiusChanged(double)),this,SLOT(clipVolumeChanged(double)));
 
   connect(controller,SIGNAL(propagatorChanged(Trk::IExtrapolator *)),this,SLOT(setPropagator(Trk::IExtrapolator *)));
   setPropagator(controller->propagator());