From 5bc1399bc69d6b4b7ed3d7c68c4ba52c88c471fb Mon Sep 17 00:00:00 2001
From: Simone Pagan Griso <simone.pagan.griso@cern.ch>
Date: Thu, 30 Apr 2015 10:47:17 +0200
Subject: [PATCH] 'Fix python to determine if is simulation'
 (InDetPrepRawDataToxAOD-00-01-16)

---
 .../InDetPrepRawDataToxAOD/cmt/requirements   |   44 +
 .../InDetPrepRawDataToxAOD/doc/TRT.txt        |   37 +
 .../share/InDetDxAOD.py                       |  219 ++++
 .../src/PixelPrepDataToxAOD.cxx               | 1066 +++++++++++++++++
 .../src/PixelPrepDataToxAOD.h                 |  104 ++
 .../src/SCT_PrepDataToxAOD.cxx                |  590 +++++++++
 .../src/SCT_PrepDataToxAOD.h                  |   87 ++
 .../src/TRT_PrepDataToxAOD.cxx                |  342 ++++++
 .../src/TRT_PrepDataToxAOD.h                  |   66 +
 .../InDetPrepRawDataToxAOD_entries.cxx        |   18 +
 .../InDetPrepRawDataToxAOD_load.cxx           |    4 +
 11 files changed, 2577 insertions(+)
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/cmt/requirements
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/doc/TRT.txt
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/share/InDetDxAOD.py
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/PixelPrepDataToxAOD.cxx
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/PixelPrepDataToxAOD.h
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/SCT_PrepDataToxAOD.cxx
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/SCT_PrepDataToxAOD.h
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/TRT_PrepDataToxAOD.cxx
 create mode 100644 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/TRT_PrepDataToxAOD.h
 create mode 100755 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/components/InDetPrepRawDataToxAOD_entries.cxx
 create mode 100755 InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/components/InDetPrepRawDataToxAOD_load.cxx

diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/cmt/requirements b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/cmt/requirements
new file mode 100644
index 00000000000..0fbff6f8bd2
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/cmt/requirements
@@ -0,0 +1,44 @@
+package InDetPrepRawDataToxAOD
+
+author Alex Alonso
+
+public
+use  AtlasPolicy                AtlasPolicy-*
+use  GaudiInterface             GaudiInterface-*                External
+
+private
+
+use InDetPrepRawData    InDetPrepRawData-*   InnerDetector/InDetRecEvent
+
+use InDetIdentifier             InDetIdentifier-*            InnerDetector/InDetDetDescr
+
+use  TRT_ConditionsServices  TRT_ConditionsServices-*        InnerDetector/InDetConditions
+use  TRT_DriftFunctionTool   TRT_DriftFunctionTool-*         InnerDetector/InDetRecTools
+
+use TrkTruthData        TrkTruthData-*          Tracking/TrkEvent
+
+use  AthenaBaseComps           AthenaBaseComps-*               Control
+use  Identifier                Identifier-*                    DetectorDescription
+
+use  xAODTracking              xAODTracking-*                  Event/xAOD
+
+use InDetRawData                InDetRawData-*      InnerDetector/InDetRawEvent
+
+use  InDetSimData              InDetSimData-*        InnerDetector/InDetRawEvent
+use  InDetSimEvent             InDetSimEvent-*        InnerDetector
+#use  GeoPrimitives              GeoPrimitives-*                 DetectorDescription
+#use  EventPrimitives            EventPrimitives-*               Event
+use TrkSurfaces           TrkSurfaces-*          Tracking/TrkDetDescr
+
+
+use InDetReadoutGeometry InDetReadoutGeometry-* InnerDetector/InDetDetDescr
+
+use  AtlasHepMC                 AtlasHepMC-*           External
+use  AtlasCLHEP                 AtlasCLHEP-*           External
+use  AtlasROOT                  AtlasROOT-*            External
+
+public
+apply_pattern component_library
+apply_pattern declare_joboptions files="*.py"
+library InDetPrepRawDataToxAOD *.cxx components/*.cxx
+
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/doc/TRT.txt b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/doc/TRT.txt
new file mode 100644
index 00000000000..4795afa2ef1
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/doc/TRT.txt
@@ -0,0 +1,37 @@
+This tools is inspired on:
+MuonSpectrometer/MuonCnv/MuonPrepRawDataToxAOD
+
+To run, you have to have flag:
+
+rec.doAOD=True
+InDetFlags.doxAOD.set_Value_and_Lock()
+
+Then, in: InnerDetector/InDetExample/InDetRecExample/share/WriteInDetAOD.py
+Add:
+if InDetFlags.doxAOD():
+  InDetAODList += ['xAOD::PrepRawDataContainer_v1#TRT_DriftCircles']
+  InDetAODList += ['xAOD::PrepRawDataAuxContainer_v1#TRT_DriftCirclesAux.']
+
+In: InnerDetector/InDetExample/InDetRecExample/share/InDetxAODCreator.py
+
+from TRT_ConditionsServices.TRT_ConditionsServicesConf import
+TRT_StrawNeighbourSvc
+TRTStrawNeighbourSvc=TRT_StrawNeighbourSvc()
+ServiceMgr += TRTStrawNeighbourSvc
+
+from TRT_ConditionsServices.TRT_ConditionsServicesConf import TRT_CalDbSvc
+TRTCalibDBSvc=TRT_CalDbSvc()
+ServiceMgr += TRTCalibDBSvc
+
+from InDetPrepRawDataToxAOD.InDetPrepRawDataToxAODConf import
+TRT_PrepDataToxAOD
+xAOD_TRT_PrepDataToxAOD = TRT_PrepDataToxAOD( name =
+"xAOD_TRT_PrepDataToxAOD")
+xAOD_TRT_PrepDataToxAOD.OutputLevel=DEBUG
+print "Add TRT xAOD PrepRawData:"
+print xAOD_TRT_PrepDataToxAOD
+topSequence += xAOD_TRT_PrepDataToxAOD
+
+
+
+
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/share/InDetDxAOD.py b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/share/InDetDxAOD.py
new file mode 100644
index 00000000000..4887e638ab8
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/share/InDetDxAOD.py
@@ -0,0 +1,219 @@
+#################
+### Steering options
+#################
+# Select active sub-systems
+dumpPixInfo=True
+dumpSctInfo=True
+dumpTrtInfo=False
+
+# Bytestream errors (for sub-systems who have implemented it)
+dumpBytestreamErrors=True
+
+# Force to do not dump truth info if set to False
+#  (otherwise determined by autoconf below)
+dumpTruthInfo=True
+
+# Print settings for main tools
+printIdTrkDxAODConf = True
+
+## Autoconfiguration adjustements
+isIdTrkDxAODSimulation = False
+if (globalflags.DataSource == 'geant4'):
+    isIdTrkDxAODSimulation = True
+
+if ( 'dumpTruthInfo' in dir() ):
+    dumpTruthInfo = dumpTruthInfo and isIdTrkDxAODSimulation
+
+print "isIdTrkDxAODSimulation=", isIdTrkDxAODSimulation
+print "dumpTruthInfo=", dumpTruthInfo
+
+if InDetFlags.doSLHC():
+    dumpTrtInfo=False
+
+## Other settings
+# Prefix for decoration, if any
+prefixName = ""
+
+## More fine-tuning available for each tool/alg below (default value shown)
+
+#################
+### Setup tools
+#################
+if dumpTrtInfo:
+    from TRT_ConditionsServices.TRT_ConditionsServicesConf import TRT_StrawNeighbourSvc
+    TRTStrawNeighbourSvc=TRT_StrawNeighbourSvc()
+    ServiceMgr += TRTStrawNeighbourSvc
+
+    from TRT_ConditionsServices.TRT_ConditionsServicesConf import TRT_CalDbSvc
+    TRTCalibDBSvc=TRT_CalDbSvc()
+    ServiceMgr += TRTCalibDBSvc
+
+    from TRT_ToT_Tools.TRT_ToT_ToolsConf import TRT_ToT_dEdx
+    TRT_dEdx_Tool = TRT_ToT_dEdx(name="TRT_ToT_dEdx")
+    ToolSvc += TRT_dEdx_Tool
+
+if dumpPixInfo: 
+    from AthenaCommon.AlgSequence import AlgSequence 
+    topSequence = AlgSequence() 
+    from PixelCalibAlgs.PixelCalibAlgsConf import PixelChargeToTConversion 
+    PixelChargeToTConversionSetter = PixelChargeToTConversion(name = "PixelChargeToTConversionSetter") 
+    topSequence += PixelChargeToTConversionSetter 
+    if (printIdTrkDxAODConf):
+        print PixelChargeToTConversionSetter
+        print PixelChargeToTConversionSetter.properties()
+
+
+#################
+### Setup decorators tools
+#################
+
+if dumpTrtInfo:
+    from InDetPrepRawDataToxAOD.InDetPrepRawDataToxAODConf import TRT_PrepDataToxAOD
+    xAOD_TRT_PrepDataToxAOD = TRT_PrepDataToxAOD( name = "xAOD_TRT_PrepDataToxAOD")
+    ## Content steering Properties (default value shown as comment)
+    xAOD_TRT_PrepDataToxAOD.OutputLevel=INFO
+    xAOD_TRT_PrepDataToxAOD.UseTruthInfo = dumpTruthInfo
+    #xAOD_TRT_PrepDataToxAOD.WriteSDOs    = True
+
+    topSequence += xAOD_TRT_PrepDataToxAOD
+    if (printIdTrkDxAODConf):
+        print xAOD_TRT_PrepDataToxAOD
+        print xAOD_TRT_PrepDataToxAOD.properties()
+
+if dumpSctInfo:
+    from InDetPrepRawDataToxAOD.InDetPrepRawDataToxAODConf import SCT_PrepDataToxAOD
+    xAOD_SCT_PrepDataToxAOD = SCT_PrepDataToxAOD( name = "xAOD_SCT_PrepDataToxAOD")
+    ## Content steering Properties (default value shown as comment)
+    xAOD_SCT_PrepDataToxAOD.OutputLevel=INFO
+    xAOD_SCT_PrepDataToxAOD.UseTruthInfo        = dumpTruthInfo
+    xAOD_SCT_PrepDataToxAOD.WriteRDOinformation = False
+    #xAOD_SCT_PrepDataToxAOD.WriteSDOs           = True
+    #xAOD_SCT_PrepDataToxAOD.WriteSiHits         = True # if available
+
+    topSequence += xAOD_SCT_PrepDataToxAOD
+    if (printIdTrkDxAODConf):
+        print xAOD_SCT_PrepDataToxAOD
+        print xAOD_SCT_PrepDataToxAOD.properties()
+
+if dumpPixInfo:
+    from InDetPrepRawDataToxAOD.InDetPrepRawDataToxAODConf import PixelPrepDataToxAOD
+    xAOD_PixelPrepDataToxAOD = PixelPrepDataToxAOD( name = "xAOD_PixelPrepDataToxAOD")
+    ## Content steering Properties (default value shown as comment)
+    xAOD_PixelPrepDataToxAOD.OutputLevel          = INFO
+    xAOD_PixelPrepDataToxAOD.UseTruthInfo         = dumpTruthInfo
+    xAOD_PixelPrepDataToxAOD.WriteRDOinformation  = False
+    xAOD_PixelPrepDataToxAOD.WriteNNinformation   = False
+    #xAOD_PixelPrepDataToxAOD.WriteSDOs            = True
+    #xAOD_PixelPrepDataToxAOD.WriteSiHits          = True # if available
+    if InDetFlags.doSLHC():
+        xAOD_PixelPrepDataToxAOD.WriteNNinformation=False
+
+    topSequence += xAOD_PixelPrepDataToxAOD
+    if (printIdTrkDxAODConf):
+        print xAOD_PixelPrepDataToxAOD
+        print xAOD_PixelPrepDataToxAOD.properties()
+
+
+#################
+### Setup derivation framework
+#################
+from AthenaCommon import CfgMgr
+
+# DerivationJob is COMMON TO ALL DERIVATIONS
+DerivationFrameworkJob = CfgMgr.AthSequencer("MySeq2")
+
+# Set up stream auditor
+from AthenaCommon.AppMgr import ServiceMgr as svcMgr
+if not hasattr(svcMgr, 'DecisionSvc'):
+        svcMgr += CfgMgr.DecisionSvc()
+svcMgr.DecisionSvc.CalcStats = True
+
+
+# Add the TSOS augmentation tool to the derivation framework
+augmentationTools=[]
+
+from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__TrackStateOnSurfaceDecorator
+DFTSOS = DerivationFramework__TrackStateOnSurfaceDecorator(name = "DFTrackStateOnSurfaceDecorator",
+                                                          ContainerName = "InDetTrackParticles",
+                                                          DecorationPrefix = prefixName,
+                                                          StoreTRT   = dumpTrtInfo,
+                                                          StoreSCT   = dumpSctInfo,
+                                                          StorePixel = dumpPixInfo,
+                                                          IsSimulation = isIdTrkDxAODSimulation,
+                                                          OutputLevel = INFO)
+if dumpTrtInfo:
+    #Add tool to calculate TRT-based dEdx
+    DFTSOS.TRT_ToT_dEdx = TRT_dEdx_Tool
+
+ToolSvc += DFTSOS
+augmentationTools+=[DFTSOS]
+if (printIdTrkDxAODConf):
+    print DFTSOS
+    print DFTSOS.properties()
+
+# Add BS error augmentation tool
+if dumpBytestreamErrors:
+    from DerivationFrameworkInDet.DerivationFrameworkInDetConf import DerivationFramework__EventInfoBSErrDecorator
+    DFEI = DerivationFramework__EventInfoBSErrDecorator(name = "DFEventInfoBSErrDecorator",
+                                                        ContainerName = "EventInfo",
+                                                        DecorationPrefix = prefixName,
+                                                        OutputLevel =INFO)
+    ToolSvc += DFEI
+    augmentationTools+=[DFEI]
+    if (printIdTrkDxAODConf):
+        print DFEI
+        print DFEI.properties()
+
+# Add the derivation job to the top AthAlgSeqeuence
+from DerivationFrameworkCore.DerivationFrameworkCoreConf import DerivationFramework__CommonAugmentation
+DerivationFrameworkJob += CfgMgr.DerivationFramework__CommonAugmentation("DFTSOS_KERN",
+                                                                        AugmentationTools = augmentationTools,
+                                                                        OutputLevel =INFO)
+
+topSequence += DerivationFrameworkJob
+if (printIdTrkDxAODConf):
+    print DerivationFrameworkJob
+    print DerivationFrameworkJob.properties()
+
+#################
+### Steer output file content
+#################
+from OutputStreamAthenaPool.MultipleStreamManager import MSMgr
+from D2PDMaker.D2PDHelpers import buildFileName
+from PrimaryDPDMaker.PrimaryDPDFlags import primDPD
+streamName = primDPD.WriteDAOD_IDTRKVALIDStream.StreamName
+fileName   = buildFileName( primDPD.WriteDAOD_IDTRKVALIDStream )
+IDTRKVALIDStream = MSMgr.NewPoolRootStream( streamName, fileName )
+excludedAuxData = "-caloExtension.-cellAssociation.-clusterAssociation.-trackParameterCovarianceMatrices.-parameterX.-parameterY.-parameterZ.-parameterPX.-parameterPY.-parameterPZ.-parameterPosition"
+# Add generic event information
+IDTRKVALIDStream.AddItem("xAOD::EventInfo#*")
+IDTRKVALIDStream.AddItem("xAOD::EventAuxInfo#*")
+# Add track particles collection
+IDTRKVALIDStream.AddItem("xAOD::TrackParticleContainer#InDetTrackParticles")
+IDTRKVALIDStream.AddItem("xAOD::TrackParticleAuxContainer#InDetTrackParticlesAux."+excludedAuxData)
+# Add vertices
+IDTRKVALIDStream.AddItem("xAOD::VertexContainer#PrimaryVertices")
+IDTRKVALIDStream.AddItem("xAOD::VertexAuxContainer#PrimaryVerticesAux.-vxTrackAtVertex")
+# Add links and measurements
+IDTRKVALIDStream.AddItem("xAOD::TrackStateValidationContainer#*")
+IDTRKVALIDStream.AddItem("xAOD::TrackStateValidationAuxContainer#*")
+IDTRKVALIDStream.AddItem("xAOD::TrackMeasurementValidationContainer#*")
+IDTRKVALIDStream.AddItem("xAOD::TrackMeasurementValidationAuxContainer#*")
+# Add info about electrons and muons (are small containers)
+IDTRKVALIDStream.AddItem("xAOD::MuonContainer#Muons")
+IDTRKVALIDStream.AddItem("xAOD::MuonAuxContainer#MuonsAux.")
+IDTRKVALIDStream.AddItem("xAOD::ElectronContainer#Electrons")
+IDTRKVALIDStream.AddItem("xAOD::ElectronAuxContainer#ElectronsAux.")
+IDTRKVALIDStream.AddItem("xAOD::TrackParticleContainer#GSFTrackParticles")
+IDTRKVALIDStream.AddItem("xAOD::TrackParticleAuxContainer#GSFTrackParticlesAux."+excludedAuxData)
+# Add truth-related information
+if dumpTruthInfo:
+  IDTRKVALIDStream.AddItem("xAOD::TruthParticleContainer#*")
+  IDTRKVALIDStream.AddItem("xAOD::TruthParticleAuxContainer#TruthParticlesAux.-caloExtension")
+  IDTRKVALIDStream.AddItem("xAOD::TruthVertexContainer#*")
+  IDTRKVALIDStream.AddItem("xAOD::TruthVertexAuxContainer#*")
+  IDTRKVALIDStream.AddItem("xAOD::TruthEventContainer#*")
+  IDTRKVALIDStream.AddItem("xAOD::TruthEventAuxContainer#*")
+
+if (printIdTrkDxAODConf):
+    print IDTRKVALIDStream
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/PixelPrepDataToxAOD.cxx b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/PixelPrepDataToxAOD.cxx
new file mode 100644
index 00000000000..2824e53949a
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/PixelPrepDataToxAOD.cxx
@@ -0,0 +1,1066 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// PixelPrepDataToxAOD.cxx
+//   Implementation file for class PixelPrepDataToxAOD
+///////////////////////////////////////////////////////////////////
+
+#include "PixelPrepDataToxAOD.h"
+
+#include "InDetPrepRawData/PixelClusterContainer.h"
+
+#include "xAODTracking/TrackMeasurementValidation.h"
+#include "xAODTracking/TrackMeasurementValidationContainer.h"
+#include "xAODTracking/TrackMeasurementValidationAuxContainer.h"
+
+#include "Identifier/Identifier.h"
+#include "InDetIdentifier/PixelID.h"
+#include "InDetReadoutGeometry/PixelModuleDesign.h"
+
+
+#include "TrkTruthData/PRD_MultiTruthCollection.h"
+#include "HepMC/GenParticle.h"
+#include "HepMC/GenVertex.h"
+#include "InDetSimEvent/SiHit.h"
+#include "InDetSimData/InDetSimDataCollection.h"
+
+
+#include "TMath.h" 
+#include "CLHEP/Geometry/Point3D.h"
+
+
+/////////////////////////////////////////////////////////////////////
+//
+//         Constructor with parameters:
+//
+/////////////////////////////////////////////////////////////////////
+PixelPrepDataToxAOD::PixelPrepDataToxAOD(const std::string &name, ISvcLocator *pSvcLocator) :
+  AthAlgorithm(name,pSvcLocator),
+  m_PixelHelper(0),
+  m_firstEventWarnings(true)
+{ 
+  // --- Steering and configuration flags
+ 
+  declareProperty("UseTruthInfo", m_useTruthInfo=false);
+  declareProperty("WriteSDOs", m_writeSDOs = true);
+  declareProperty("WriteSiHits", m_writeSiHits = true);
+  declareProperty("WriteNNinformation", m_writeNNinformation = true);
+  declareProperty("WriteRDOinformation", m_writeRDOinformation = true);
+
+  // --- Configuration keys
+  declareProperty("SiClusterContainer",  m_clustercontainer = "PixelClusters");
+  declareProperty("MC_SDOs", m_SDOcontainer = "PixelSDO_Map");
+  declareProperty("MC_Hits", m_sihitContainer = "PixelHits");
+  declareProperty("PRD_MultiTruth", m_multiTruth = "PRD_MultiTruthPixel");
+
+  // --- Services and Tools
+
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Initialize method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode PixelPrepDataToxAOD::initialize()
+{
+  ATH_CHECK( detStore()->retrieve(m_PixelHelper, "PixelID") );
+
+  //make sure we don't write what we don't have
+  if (not m_useTruthInfo) {
+    m_writeSDOs = false;
+    m_writeSiHits = false;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Execute method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode PixelPrepDataToxAOD::execute() 
+{
+  //Mandatory. Require if the algorithm is scheduled.
+  const InDet::PixelClusterContainer* PixelClusterContainer = 0;     
+  if( evtStore()->retrieve(PixelClusterContainer,m_clustercontainer).isFailure() ) {
+    ATH_MSG_ERROR("Cannot retrieve Pixel PrepDataContainer " << m_clustercontainer);
+    return StatusCode::FAILURE;
+  }
+
+  // Optional. Normally only available in Hits files -- samples need to digitised and Hits need to be copied for this to work
+  const SiHitCollection* sihitCollection = 0;
+  if((m_writeNNinformation||m_writeSiHits)&&m_useTruthInfo) {
+    if ( evtStore()->contains<SiHitCollection>(m_sihitContainer) ) {
+      ATH_CHECK(evtStore()->retrieve(sihitCollection, m_sihitContainer));
+    } else {
+      if (m_firstEventWarnings) {
+	ATH_MSG_WARNING("Si Hit cotainer no found (" << m_sihitContainer << "). Skipping it although requested.");
+	sihitCollection = 0;
+      }
+    }
+  }
+
+  // Optional. On RDO
+  const InDetSimDataCollection* sdoCollection = 0;
+  if(m_writeSDOs) {
+    if ( evtStore()->contains<InDetSimDataCollection>(m_SDOcontainer) ) {
+      ATH_CHECK(evtStore()->retrieve(sdoCollection, m_SDOcontainer));
+    } else {
+      if (m_firstEventWarnings) {
+	ATH_MSG_WARNING("SDO Collection not found (" << m_SDOcontainer << "). Skipping it although requested.");
+	sdoCollection = 0;
+      }
+    }
+  }
+
+  // Optional. On ESD and AOD
+  const PRD_MultiTruthCollection* prdmtColl = 0;
+  if (m_useTruthInfo) {
+    if ( evtStore()->contains<PRD_MultiTruthCollection>(m_multiTruth) ) {
+      ATH_CHECK(evtStore()->retrieve(prdmtColl, m_multiTruth));
+    } else {
+      ATH_MSG_WARNING("PRD Truth collection missing (" << m_multiTruth << "). Skipping it although requested.");
+      prdmtColl = 0;
+    }
+  }
+
+
+  // Create the xAOD container and its auxiliary store:
+  xAOD::TrackMeasurementValidationContainer* xaod = new xAOD::TrackMeasurementValidationContainer();
+  CHECK( evtStore()->record( xaod, m_clustercontainer ) );
+  xAOD::TrackMeasurementValidationAuxContainer* aux = new xAOD::TrackMeasurementValidationAuxContainer();
+  CHECK( evtStore()->record( aux, m_clustercontainer + "Aux." ) );
+  xaod->setStore( aux );
+
+  std::vector<unsigned int>* offsets = new std::vector<unsigned int>( m_PixelHelper->wafer_hash_max(), 0 );
+  CHECK( evtStore()->record( offsets, m_clustercontainer + "Offsets" ) );
+
+  
+  // Loop over the container
+  unsigned int counter(0);
+  
+  for( const auto& clusterCollection : *PixelClusterContainer){
+
+    //Fill Offset container
+    (*offsets)[clusterCollection->identifyHash()] = counter;
+
+    // skip empty collections
+    if( clusterCollection->empty() ) continue;
+    
+    // loop over collection and convert to xAOD
+    for( auto& prd : *clusterCollection ){    
+      ++counter;
+
+      Identifier clusterId = prd->identify();
+      if ( !clusterId.is_valid() ) {
+        ATH_MSG_WARNING("Pixel cluster identifier is not valid");
+      }
+            
+      // create and add xAOD object
+      xAOD::TrackMeasurementValidation* xprd = new xAOD::TrackMeasurementValidation();
+      xaod->push_back(xprd);
+      
+      //Set Identifier
+      xprd->setIdentifier( clusterId.get_compact() );
+
+      //Set Global Position
+      Amg::Vector3D gpos = prd->globalPosition();
+      xprd->setGlobalPosition(gpos.x(),gpos.y(),gpos.z());
+
+      //Set Local Position
+      const Amg::Vector2D& locpos = prd->localPosition();
+
+      // Set local error matrix
+      xprd->setLocalPosition( locpos.x(),  locpos.y() ); 
+      
+      const Amg::MatrixX& localCov = prd->localCovariance();
+      //std::cout << localCov <<  std::endl;
+      if(localCov.size() == 1){
+	//std::cout << "Size  == 1" << std::endl;
+        xprd->setLocalPositionError( localCov(0,0), 0., 0. ); 
+      } else if(localCov.size() == 4){
+	//std::cout << "Size  == 2" << std::endl;
+        xprd->setLocalPositionError( localCov(0,0), localCov(1,1), localCov(0,1) );     
+      } else {
+	//std::cout << "Size  == "<< localCov.size() << std::endl;
+        xprd->setLocalPositionError(0.,0.,0.);
+      }
+         
+      // Set vector of hit identifiers
+      std::vector< uint64_t > rdoIdentifierList;
+      for( const auto &hitIdentifier : prd->rdoList() ){
+        rdoIdentifierList.push_back( hitIdentifier.get_compact() );
+        //May want to addinformation about the individual hits here
+      }
+      xprd->setRdoIdentifierList(rdoIdentifierList);
+   
+      //Add pixel cluster properties
+      xprd->auxdata<int>("bec")          =   m_PixelHelper->barrel_ec(clusterId)   ;
+      xprd->auxdata<int>("layer")        =   m_PixelHelper->layer_disk(clusterId)  ;   
+      xprd->auxdata<int>("phi_module")   =   m_PixelHelper->phi_module(clusterId)  ;
+      xprd->auxdata<int>("eta_module")   =   m_PixelHelper->eta_module(clusterId)  ;
+         
+      //xprd->auxdata<int>("col")         =  m_PixelHelper->eta_index(clusterId);
+      //xprd->auxdata<int>("row")         =  m_PixelHelper->phi_index(clusterId);
+      xprd->auxdata<int>("eta_pixel_index")         =  m_PixelHelper->eta_index(clusterId);
+      xprd->auxdata<int>("phi_pixel_index")         =  m_PixelHelper->phi_index(clusterId);
+   
+
+      const InDet::SiWidth cw = prd->width();
+      xprd->auxdata<int>("sizePhi") = (int)cw.colRow()[0];
+      xprd->auxdata<int>("sizeZ")   = (int)cw.colRow()[1];
+      xprd->auxdata<int>("size")    = (int)prd->rdoList().size();
+   
+      xprd->auxdata<float>("charge")  =  prd->totalCharge(); 
+      xprd->auxdata<int>("ToT")       =  prd->totalToT(); 
+      xprd->auxdata<int>("LVL1A")     =  prd->LVL1A(); 
+   
+      xprd->auxdata<char>("isFake")      =  (char)prd->isFake(); 
+      xprd->auxdata<char>("gangedPixel") =  (char)prd->gangedPixel(); 
+      xprd->auxdata<int>("isSplit")      =  (int)prd->isSplit(); 
+      xprd->auxdata<float>("splitProbability1")  =  prd->splitProbability1(); 
+      xprd->auxdata<float>("splitProbability2")  =  prd->splitProbability2(); 
+
+      // Need to add something to Add the NN splitting information
+      if(m_writeNNinformation)addNNInformation( xprd,  prd, 7, 7);
+      
+      // Add information for each contributing hit
+      if(m_writeRDOinformation) addRdoInformation(xprd,  prd);
+  
+  
+  
+      // Add the Detector element ID  --  not sure if needed as we have the informations above
+      const InDetDD::SiDetectorElement* de = prd->detectorElement();
+      uint64_t detElementId(0);
+      if(de){
+        Identifier detId = de->identify();
+        if ( detId.is_valid() ) {
+          detElementId = detId.get_compact();
+        }
+      }
+      xprd->auxdata<uint64_t>("detectorElementID") = detElementId;
+      
+      // Use the MultiTruth Collection to get a list of all true particle contributing to the cluster
+      if(prdmtColl){
+        std::vector<int> barcodes;
+        //std::pair<PRD_MultiTruthCollection::const_iterator,PRD_MultiTruthCollection::const_iterator>;
+        auto range = prdmtColl->equal_range(clusterId);
+        for (auto i = range.first; i != range.second; ++i) {
+           barcodes.push_back( i->second.barcode() );
+        }
+        xprd->auxdata< std::vector<int> >("truth_barcode") = barcodes;
+      }
+
+      // Use the SDO Collection to get a list of all true particle contributing to the cluster per readout element
+      //  Also get the energy deposited by each true particle per readout element   
+      if( sdoCollection ){
+        addSDOInformation( xprd, prd,sdoCollection);
+      }
+    
+      // Now Get the most detailed truth from the SiHits
+      // Note that this could get really slow if there are a lot of hits and clusters
+      if(  sihitCollection  ){
+        if(m_writeSiHits)
+          addSiHitInformation( xprd, prd, sihitCollection); 
+        if(m_writeNNinformation)
+          addNNTruthInfo(  xprd, prd, sihitCollection );
+      }
+    }
+  }
+  ATH_MSG_DEBUG( " recorded PixelPrepData objects: size " << xaod->size() );
+
+  m_firstEventWarnings = false;
+
+  return StatusCode::SUCCESS;
+}
+
+
+void PixelPrepDataToxAOD::addSDOInformation( xAOD::TrackMeasurementValidation* xprd,
+                                            const InDet::PixelCluster* prd,
+                                            const InDetSimDataCollection* sdoCollection ) const
+{
+  std::vector<int> sdo_word;
+  std::vector< std::vector< int > > sdo_depositsBarcode;
+  std::vector< std::vector< float > > sdo_depositsEnergy;
+  // find hit
+  for( const auto &hitIdentifier : prd->rdoList() ){
+    auto pos = sdoCollection->find(hitIdentifier);
+    if( pos != sdoCollection->end() ) {
+      sdo_word.push_back( pos->second.word() ) ;
+      
+      std::vector< int > sdoDepBC;
+      std::vector< float > sdoDepEnergy;
+      for( auto deposit : pos->second.getdeposits() ){
+        if(deposit.first){
+          sdoDepBC.push_back( deposit.first->barcode());
+        } else {
+          sdoDepBC.push_back( -1 );   
+        }
+        sdoDepEnergy.push_back( deposit.second  );
+        ATH_MSG_DEBUG(" SDO Energy Deposit " << deposit.second  ) ;
+      }
+      sdo_depositsBarcode.push_back( sdoDepBC );
+      sdo_depositsEnergy.push_back( sdoDepEnergy );
+    }
+  }
+  xprd->auxdata< std::vector<int> >("sdo_words")  = sdo_word;
+  xprd->auxdata< std::vector< std::vector<int> > >("sdo_depositsBarcode")  = sdo_depositsBarcode;
+  xprd->auxdata< std::vector< std::vector<float> > >("sdo_depositsEnergy") = sdo_depositsEnergy;
+}
+
+
+
+void  PixelPrepDataToxAOD::addSiHitInformation( xAOD::TrackMeasurementValidation* xprd, 
+                                               const InDet::PixelCluster* prd,
+                                               const SiHitCollection* sihitCollection) const
+                             
+                             
+{
+
+  std::vector<SiHit> matchingHits = findAllHitsCompatibleWithCluster(  prd, sihitCollection );
+
+  int numHits = matchingHits.size();
+
+  std::vector<float> sihit_energyDeposit(numHits,0);
+  std::vector<float> sihit_meanTime(numHits,0);
+  std::vector<int>   sihit_barcode(numHits,0);
+  std::vector<int>   sihit_pdgid(numHits,0);
+  
+  std::vector<float> sihit_startPosX(numHits,0);
+  std::vector<float> sihit_startPosY(numHits,0);
+  std::vector<float> sihit_startPosZ(numHits,0);
+
+  std::vector<float> sihit_endPosX(numHits,0);
+  std::vector<float> sihit_endPosY(numHits,0);
+  std::vector<float> sihit_endPosZ(numHits,0);
+
+  int hitNumber(0);
+  const InDetDD::SiDetectorElement* de = prd->detectorElement();
+  if(de){
+    for ( auto sihit : matchingHits ) {          
+      sihit_energyDeposit[hitNumber] =  sihit.energyLoss() ;
+      sihit_meanTime[hitNumber] =  sihit.meanTime() ;
+      sihit_barcode[hitNumber] =  sihit.particleLink().barcode() ;
+      if(sihit.particleLink().isValid()){
+        sihit_pdgid[hitNumber]   = sihit.particleLink()->pdg_id();
+      }
+    
+      // Convert Simulation frame into reco frame
+      const HepGeom::Point3D<double>& startPos=sihit.localStartPosition();
+
+      Amg::Vector2D pos= de->hitLocalToLocal( startPos.z(), startPos.y() );
+      sihit_startPosX[hitNumber] =  pos[0];
+      sihit_startPosY[hitNumber] =  pos[1];
+      sihit_startPosZ[hitNumber] =  startPos.x();
+ 
+
+      const HepGeom::Point3D<double>& endPos=sihit.localEndPosition();
+      pos= de->hitLocalToLocal( endPos.z(), endPos.y() );
+      sihit_endPosX[hitNumber] =  pos[0];
+      sihit_endPosY[hitNumber] =  pos[1];
+      sihit_endPosZ[hitNumber] =  endPos.x();
+      ++hitNumber;
+    }
+  }
+
+  xprd->auxdata<std::vector<float> >("sihit_energyDeposit") = sihit_energyDeposit;
+  xprd->auxdata<std::vector<float> >("sihit_meanTime") = sihit_meanTime;
+  xprd->auxdata<std::vector<int> >("sihit_barcode") = sihit_barcode;
+  xprd->auxdata<std::vector<int> >("sihit_pdgid") = sihit_pdgid;
+  
+  xprd->auxdata<std::vector<float> >("sihit_startPosX") = sihit_startPosX;
+  xprd->auxdata<std::vector<float> >("sihit_startPosY") = sihit_startPosY;
+  xprd->auxdata<std::vector<float> >("sihit_startPosZ") = sihit_startPosZ;
+
+  xprd->auxdata<std::vector<float> >("sihit_endPosX") = sihit_endPosX;
+  xprd->auxdata<std::vector<float> >("sihit_endPosY") = sihit_endPosY;
+  xprd->auxdata<std::vector<float> >("sihit_endPosZ") = sihit_endPosZ;
+
+
+}
+
+
+
+
+
+
+std::vector<SiHit> PixelPrepDataToxAOD::findAllHitsCompatibleWithCluster( const InDet::PixelCluster* prd, 
+                                                                          const SiHitCollection* collection) const
+{
+  ATH_MSG_VERBOSE( "Got " << collection->size() << " SiHits to look through" );
+  std::vector<SiHit>  matchingHits;
+    
+  // Check if we have detector element  --  needed to find the local position of the SiHits
+  const InDetDD::SiDetectorElement* de = prd->detectorElement();
+  if(!de)
+    return matchingHits;
+
+  std::vector<const SiHit* >  multiMatchingHits;
+  
+  for ( const auto&  siHit : *collection) {
+    // Check if it is a Pixel hit
+    if( !siHit.isPixel() )
+      continue;
+     
+    //Check if it is on the correct module
+    Identifier clusterId = prd->identify();
+  
+    if( m_PixelHelper->barrel_ec(clusterId) != siHit.getBarrelEndcap() ||
+        m_PixelHelper->layer_disk(clusterId)!= siHit.getLayerDisk()    ||  
+        m_PixelHelper->phi_module(clusterId)!= siHit.getPhiModule()    ||
+        m_PixelHelper->eta_module(clusterId)!= siHit.getEtaModule() ) 
+       continue;
+
+    // Now we have all hits in the module that match lets check to see if they match the cluster
+    // Must be within +/- 1 hits of any hit in the cluster to be included
+    ATH_MSG_DEBUG("Hit is on the same module");
+    
+    HepGeom::Point3D<double>  averagePosition =  siHit.localStartPosition() + siHit.localEndPosition();
+    averagePosition *= 0.5;
+    Amg::Vector2D pos = de->hitLocalToLocal( averagePosition.z(), averagePosition.y() );
+    InDetDD::SiCellId diode = de->cellIdOfPosition(pos);
+   
+    for( const auto &hitIdentifier : prd->rdoList() ){
+
+      ATH_MSG_DEBUG("Truth Phi " <<  diode.phiIndex() << " Cluster Phi " <<   m_PixelHelper->phi_index( hitIdentifier ) );
+      ATH_MSG_DEBUG("Truth Eta " <<  diode.etaIndex() << " Cluster Eta " <<   m_PixelHelper->eta_index( hitIdentifier ) );
+
+      if( abs( int(diode.etaIndex()) - m_PixelHelper->eta_index( hitIdentifier ) ) <=1  
+       && abs( int(diode.phiIndex()) - m_PixelHelper->phi_index( hitIdentifier ) ) <=1 ) 
+      {
+        multiMatchingHits.push_back(&siHit);   
+        break;   
+      }     
+    }
+  }
+  
+  
+  //Now we will now make 1 SiHit for each true particle if the SiHits "touch" other 
+  std::vector<const SiHit* >::iterator siHitIter  = multiMatchingHits.begin();
+  std::vector<const SiHit* >::iterator siHitIter2 = multiMatchingHits.begin();
+  ATH_MSG_DEBUG( "Found " << multiMatchingHits.size() << " SiHit " );
+  for ( ; siHitIter != multiMatchingHits.end(); siHitIter++) {
+    const SiHit* lowestXPos  = *siHitIter;
+    const SiHit* highestXPos = *siHitIter;
+
+
+    // We will merge these hits
+    std::vector<const SiHit* > ajoiningHits;
+    ajoiningHits.push_back( *siHitIter );
+    
+    siHitIter2 = siHitIter+1;    
+    while ( siHitIter2 != multiMatchingHits.end() ) {
+      // Need to come from the same truth particle 
+            
+      if( (*siHitIter)->particleLink().barcode() != (*siHitIter2)->particleLink().barcode() ){
+        ++siHitIter2;
+        continue;
+      }
+      
+      // Check to see if the SiHits are compatible with each other.
+      if (fabs((highestXPos->localEndPosition().x()-(*siHitIter2)->localStartPosition().x()))<0.00005 &&
+          fabs((highestXPos->localEndPosition().y()-(*siHitIter2)->localStartPosition().y()))<0.00005 &&
+          fabs((highestXPos->localEndPosition().z()-(*siHitIter2)->localStartPosition().z()))<0.00005 )
+      {
+        highestXPos = *siHitIter2;
+        ajoiningHits.push_back( *siHitIter2 );
+        // Dont use hit  more than once
+        siHitIter2 = multiMatchingHits.erase( siHitIter2 );
+      }else if (fabs((lowestXPos->localStartPosition().x()-(*siHitIter2)->localEndPosition().x()))<0.00005 &&
+                fabs((lowestXPos->localStartPosition().y()-(*siHitIter2)->localEndPosition().y()))<0.00005 &&
+                fabs((lowestXPos->localStartPosition().z()-(*siHitIter2)->localEndPosition().z()))<0.00005)
+      {
+        lowestXPos = *siHitIter2;
+        ajoiningHits.push_back( *siHitIter2 );
+        // Dont use hit  more than once
+        siHitIter2 = multiMatchingHits.erase( siHitIter2 );
+      } else {
+        ++siHitIter2;
+      }
+    }
+    
+    if( ajoiningHits.size() == 0){
+      ATH_MSG_WARNING("This should really never happen");
+      continue;
+    }else if(ajoiningHits.size() == 1){
+      // Copy Si Hit ready to return
+      matchingHits.push_back( *ajoiningHits[0] );
+      continue;
+    } else {
+    //  Build new SiHit and merge information together.  
+      ATH_MSG_DEBUG("Merging " << ajoiningHits.size() << " SiHits together." );
+      
+      
+      float energyDep(0);
+      float time(0);
+      for( auto& siHit :  ajoiningHits){
+        energyDep += siHit->energyLoss();
+        time += siHit->meanTime();    
+      }
+      time /= (float)ajoiningHits.size();
+       
+      matchingHits.push_back(  SiHit(lowestXPos->localStartPosition(), 
+                                     highestXPos->localEndPosition(),
+                                     energyDep,
+                                     time,
+                                     (*siHitIter)->particleLink().barcode(),
+                                     0, // 0 for pixel 1 for Pixel
+                                     (*siHitIter)->getBarrelEndcap(),
+                                     (*siHitIter)->getLayerDisk(),
+                                     (*siHitIter)->getEtaModule(),
+                                     (*siHitIter)->getPhiModule(),
+                                     (*siHitIter)->getSide() ) );
+     ATH_MSG_DEBUG("Finished Merging " << ajoiningHits.size() << " SiHits together." );
+
+    }
+  } 
+  
+
+  return matchingHits;
+  
+}
+
+void PixelPrepDataToxAOD::addRdoInformation(xAOD::TrackMeasurementValidation* xprd, 
+                                           const InDet::PixelCluster* pixelCluster ) const
+{
+  ATH_MSG_VERBOSE( " Starting creating input from cluster "   );
+
+
+  const std::vector<Identifier>& rdos  = pixelCluster->rdoList();  
+
+  const std::vector<float> chList     = pixelCluster->chargeList();
+  const std::vector<int>  totList     = pixelCluster->totList();
+
+  // std::vector<int>  rowList;
+  // std::vector<int>  colList;
+  std::vector<int>  etaIndexList;
+  std::vector<int>  phiIndexList;
+
+  ATH_MSG_VERBOSE( "Number of RDOs: " << rdos.size() );
+  
+  //Itererate over all elements hits in the cluster and fill the charge and tot matricies 
+  std::vector<Identifier>::const_iterator rdosBegin = rdos.begin();
+  std::vector<Identifier>::const_iterator rdosEnd = rdos.end();
+
+  ATH_MSG_VERBOSE(" Putting together the n. " << rdos.size() << " rdos into a matrix.");
+
+  for (; rdosBegin!= rdosEnd; ++rdosBegin)
+  {
+    Identifier rId =  *rdosBegin;
+    // rowList.push_back( m_PixelHelper->phi_index(rId) );
+    // colList.push_back( m_PixelHelper->eta_index(rId) );  
+    phiIndexList.push_back( m_PixelHelper->phi_index(rId) );
+    etaIndexList.push_back( m_PixelHelper->eta_index(rId) );  
+  }//end iteration on rdos
+
+
+  // xprd->auxdata< std::vector<int> >("rdo_row")  = rowList;
+  // xprd->auxdata< std::vector<int> >("rdo_col")  = colList;
+  xprd->auxdata< std::vector<int> >("rdo_phi_pixel_index")  = phiIndexList;
+  xprd->auxdata< std::vector<int> >("rdo_eta_pixel_index")  = etaIndexList;
+  xprd->auxdata< std::vector<float> >("rdo_charge")  = chList;
+  xprd->auxdata< std::vector<int> >("rdo_tot")  = totList;
+  
+}
+
+
+void PixelPrepDataToxAOD::addNNInformation(xAOD::TrackMeasurementValidation* xprd, 
+                                           const InDet::PixelCluster* pixelCluster, 
+                                           const unsigned int sizeX, const unsigned int sizeY ) const
+{
+  ATH_MSG_VERBOSE( " Starting creating input from cluster "   );
+
+  const InDetDD::SiDetectorElement* de = pixelCluster->detectorElement();
+  if (de==0) {
+    ATH_MSG_ERROR("Could not get detector element");
+    return;
+  }
+
+
+  const InDetDD::PixelModuleDesign* design(dynamic_cast<const InDetDD::PixelModuleDesign*>(&de->design()));
+	if (not design) {
+		ATH_MSG_WARNING("PixelModuleDesign was not retrieved in function 'addNNInformation'");
+		return;
+	}
+  const std::vector<Identifier>& rdos  = pixelCluster->rdoList();  
+
+  const std::vector<float>& chList     = pixelCluster->chargeList();
+  const std::vector<int>&  totList     = pixelCluster->totList();
+
+  ATH_MSG_VERBOSE( "Number of RDOs: " << rdos.size() );
+  ATH_MSG_VERBOSE( "Number of charges: " << chList.size() );
+  ATH_MSG_VERBOSE( "Number of TOT: " << totList.size() );
+
+ 
+  //Calculate the centre of the cluster
+  int phiPixelIndexMin, phiPixelIndexMax, etaPixelIndexMin, etaPixelIndexMax;
+  InDetDD::SiCellId cellIdWeightedPosition= getCellIdWeightedPosition( pixelCluster, &phiPixelIndexMin, &phiPixelIndexMax, &etaPixelIndexMin, &etaPixelIndexMax);
+
+  if (!cellIdWeightedPosition.isValid())
+  {
+    ATH_MSG_WARNING( "Weighted position is on invalid CellID." );
+  }
+
+  int etaPixelIndexWeightedPosition=cellIdWeightedPosition.etaIndex();
+  int phiPixelIndexWeightedPosition=cellIdWeightedPosition.phiIndex();
+
+
+  ATH_MSG_DEBUG(" weighted pos phiPixelIndex: " << phiPixelIndexWeightedPosition << " etaPixelIndex: " << etaPixelIndexWeightedPosition ); 
+
+  // SiLocalPosition PixelModuleDesign::positionFromColumnRow(const int column, const int row) const;
+  //
+  // Given row and column index of diode, returns position of diode center
+  // ALTERNATIVE/PREFERED way is to use localPositionOfCell(const SiCellId & cellId) or 
+  // rawLocalPositionOfCell method in SiDetectorElement.
+  // DEPRECATED (but used in numerous places)
+  //
+  // Comment by Hide (referring the original comment in the code) : 2015-02-04
+  // I automatically replaced column to etaPixelIndex and row to phiPixelIndex here. It was bofore:
+  // InDetDD::SiLocalPosition siLocalPosition( design->positionFromColumnRow(columnWeightedPosition,rowWeightedPosition) ); 
+  //
+  // Then I assume the argument of column/row in this function is in offline manner, not the real hardware column/row.
+  // 
+  InDetDD::SiLocalPosition w = design->positionFromColumnRow(etaPixelIndexWeightedPosition,phiPixelIndexWeightedPosition);
+
+
+  double localEtaPixelIndexWeightedPosition = w.xEta();
+  double localPhiPixelIndexWeightedPosition    = w.xPhi();
+
+  int centralIndexX=(sizeX-1)/2;
+  int centralIndexY=(sizeY-1)/2;
+
+
+
+  // Check to see if the cluster is too big for the NN
+
+  if (abs(phiPixelIndexWeightedPosition-phiPixelIndexMin)>centralIndexX ||
+      abs(phiPixelIndexWeightedPosition-phiPixelIndexMax)>centralIndexX)
+  {
+    ATH_MSG_DEBUG(" Cluster too large phiPixelIndexMin " << phiPixelIndexMin << " phiPixelIndexMax " << phiPixelIndexMax << " centralX " << centralIndexX);
+    //return;
+  }
+
+  if (abs(etaPixelIndexWeightedPosition-etaPixelIndexMin)>centralIndexY ||
+      abs(etaPixelIndexWeightedPosition-etaPixelIndexMax)>centralIndexY)
+  {
+    ATH_MSG_DEBUG(" Cluster too large etaPixelIndexMin" << etaPixelIndexMin << " etaPixelIndexMax " << etaPixelIndexMax << " centralY " << centralIndexY);
+    //return;
+  }
+
+  std::vector< std::vector<float> > matrixOfToT (sizeX, std::vector<float>(sizeY,0) );
+  std::vector< std::vector<float> > matrixOfCharge(sizeX, std::vector<float>(sizeY,0));
+  std::vector<float> vectorOfPitchesY(sizeY,0.4);
+
+
+  //Itererate over all elements hits in the cluster and fill the charge and tot matrices 
+  std::vector<Identifier>::const_iterator rdosBegin = rdos.begin();
+  std::vector<Identifier>::const_iterator rdosEnd = rdos.end();
+  auto charge = chList.begin();    
+  auto tot = totList.begin();    
+
+  ATH_MSG_VERBOSE(" Putting together the n. " << rdos.size() << " rdos into a matrix.");
+
+  for (; rdosBegin!= rdosEnd; ++rdosBegin)
+  {
+    
+    Identifier rId =  *rdosBegin;
+    int absphiPixelIndex = m_PixelHelper->phi_index(rId)-phiPixelIndexWeightedPosition    + centralIndexX;
+    int absetaPixelIndex = m_PixelHelper->eta_index(rId)-etaPixelIndexWeightedPosition + centralIndexY;
+  
+    ATH_MSG_VERBOSE( " Phi Index: " << m_PixelHelper->phi_index(rId) << " absphiPixelIndex: " << absphiPixelIndex << " eta Idx: " << m_PixelHelper->eta_index(rId) << " absetaPixelIndex: " << absetaPixelIndex << " charge " << *charge );
+  
+    if (absphiPixelIndex <0 || absphiPixelIndex >= (int)sizeX)
+    {
+      ATH_MSG_DEBUG(" problem with index: " << absphiPixelIndex << " min: " << 0 << " max: " << sizeX);
+      continue;
+    }
+    
+    if (absetaPixelIndex <0 || absetaPixelIndex >= (int)sizeY)
+    {
+      ATH_MSG_DEBUG(" problem with index: " << absetaPixelIndex << " min: " << 0 << " max: " << sizeY);
+      continue;
+    }
+
+    InDetDD::SiCellId  cellId = de->cellIdFromIdentifier(*rdosBegin);
+    InDetDD::SiDiodesParameters diodeParameters = design->parameters(cellId);
+    float pitchY = diodeParameters.width().xEta();
+  
+    if ( (not totList.empty()) && tot    != totList.end()) {
+      matrixOfToT[absphiPixelIndex][absetaPixelIndex]   =*tot;
+      ++tot;
+    } else matrixOfToT[absphiPixelIndex][absetaPixelIndex]   = -1;
+
+    if ( (not chList.empty()) && charge != chList.end()){
+     matrixOfCharge[absphiPixelIndex][absetaPixelIndex]=*charge;
+     ++charge;
+    } else matrixOfCharge[absphiPixelIndex][absetaPixelIndex] = -1;
+  
+    if (pitchY > 0.1)
+    {
+      vectorOfPitchesY[absetaPixelIndex]=pitchY;
+    }
+  }//end iteration on rdos
+  
+
+  ATH_MSG_VERBOSE( " End RDO LOOP " );
+
+  // Using the centre of the module and beam spot calculate
+  // the incidence angles of the tracks
+  const Amg::Vector2D& prdLocPos = pixelCluster->localPosition();
+  InDetDD::SiLocalPosition centroid(prdLocPos);
+
+  Amg::Vector3D globalPos = de->globalPosition(centroid);
+  Amg::Vector3D trackDir = globalPos; // - beamSpotPosition; 
+  trackDir.normalize();
+
+  Amg::Vector3D module_normal = de->normal();
+  Amg::Vector3D module_phiax  = de->phiAxis();
+  Amg::Vector3D module_etaax  = de->etaAxis();
+
+  // Calculate the phi incidence angle
+  float trkphicomp  = trackDir.dot(module_phiax);
+  float trketacomp  = trackDir.dot(module_etaax);
+  float trknormcomp = trackDir.dot(module_normal);
+  double bowphi     = atan2(trkphicomp,trknormcomp);
+  double boweta     = atan2(trketacomp,trknormcomp);
+  double tanl = de->getTanLorentzAnglePhi();
+  if(bowphi > TMath::Pi()/2) bowphi -= TMath::Pi();
+  if(bowphi < -TMath::Pi()/2) bowphi += TMath::Pi();
+  int readoutside = design->readoutSide();
+  double angle = atan(tan(bowphi)-readoutside*tanl);
+
+
+  // Calculate the theta incidence angle
+  ATH_MSG_VERBOSE( " Angle theta bef corr: " << boweta );
+  if (boweta>TMath::Pi()/2.) boweta-=TMath::Pi();
+  if (boweta<-TMath::Pi()/2.) boweta+=TMath::Pi();
+
+
+  ATH_MSG_VERBOSE(" Angle phi: " << angle << " theta: " << boweta );
+  ATH_MSG_VERBOSE(" PhiPixelIndexWeightedPosition: " << phiPixelIndexWeightedPosition << " EtaPixelIndexWeightedPosition: " << etaPixelIndexWeightedPosition );
+
+  // store the matrixOfToT in a vector  
+  std::vector<float> vectorOfCharge(sizeX*sizeY,0);
+  std::vector<float> vectorOfToT(sizeX*sizeY,0);
+  int counter(0);
+  for (unsigned int u=0;u<sizeX;u++)
+  {
+    for (unsigned int s=0;s<sizeY;s++)
+    {    
+      vectorOfToT[counter]    = matrixOfToT[u][s];
+      vectorOfCharge[counter] = matrixOfCharge[u][s];
+      ++counter;
+    }
+  }
+
+  ATH_MSG_VERBOSE( "matrixOfToT converted in a std::vector<float>  " );
+
+  ATH_MSG_VERBOSE( "... and saved  " );
+  // Add information to xAOD
+  xprd->auxdata< int >("NN_sizeX") = sizeX;
+  xprd->auxdata< int >("NN_sizeY") = sizeY;
+
+  xprd->auxdata< float >("NN_phiBS") = angle;
+  xprd->auxdata< float >("NN_thetaBS") = boweta;
+
+  xprd->auxdata< std::vector<float> >("NN_matrixOfToT")      = vectorOfToT;
+  xprd->auxdata< std::vector<float> >("NN_matrixOfCharge")   = vectorOfCharge;
+  xprd->auxdata< std::vector<float> >("NN_vectorOfPitchesY") = vectorOfPitchesY;
+  
+  
+  xprd->auxdata< int >("NN_etaPixelIndexWeightedPosition") = etaPixelIndexWeightedPosition;
+  xprd->auxdata< int >("NN_phiPixelIndexWeightedPosition") = phiPixelIndexWeightedPosition;
+
+  xprd->auxdata< float >("NN_localEtaPixelIndexWeightedPosition") = localEtaPixelIndexWeightedPosition;
+  xprd->auxdata< float >("NN_localPhiPixelIndexWeightedPosition") = localPhiPixelIndexWeightedPosition;
+
+  ATH_MSG_VERBOSE( "NN training Written" );
+}
+
+void  PixelPrepDataToxAOD::addNNTruthInfo(  xAOD::TrackMeasurementValidation* xprd,
+                                            const InDet::PixelCluster* pixelCluster, 
+                                            const SiHitCollection* sihitCollection ) const
+{
+
+  std::vector<SiHit> matchingHits = findAllHitsCompatibleWithCluster(  pixelCluster, sihitCollection );
+
+  unsigned int numberOfSiHits = matchingHits.size();
+  
+  std::vector<float> positionsX(numberOfSiHits,0);
+  std::vector<float> positionsY(numberOfSiHits,0);
+
+  std::vector<float> positions_indexX(numberOfSiHits,0);
+  std::vector<float> positions_indexY(numberOfSiHits,0);
+
+  std::vector<float> theta(numberOfSiHits,0);
+  std::vector<float> phi(numberOfSiHits,0);
+
+  std::vector<int>   barcode(numberOfSiHits,0);
+  std::vector<int>   pdgid(numberOfSiHits,0);
+  std::vector<float> chargeDep(numberOfSiHits,0);
+  std::vector<float> truep(numberOfSiHits,0);
+
+  std::vector<float> pathlengthX(numberOfSiHits,0);
+  std::vector<float> pathlengthY(numberOfSiHits,0);
+  std::vector<float> pathlengthZ(numberOfSiHits,0);
+
+  std::vector<int>   motherBarcode(numberOfSiHits,0);
+  std::vector<int>   motherPdgid(numberOfSiHits,0);
+
+
+
+  // Check if we have detector element  --  needed to find the local position of the SiHits
+  const InDetDD::SiDetectorElement* de = pixelCluster->detectorElement();
+  if(!de)
+    return;
+
+  InDetDD::SiCellId cellIdWeightedPosition = getCellIdWeightedPosition( pixelCluster );
+
+  const InDetDD::PixelModuleDesign* design(dynamic_cast<const InDetDD::PixelModuleDesign*>(&de->design()));
+  if (not design) {
+		ATH_MSG_WARNING("PixelModuleDesign was not retrieved in function 'addNNTruthInfo'");
+		return;
+	}
+  // lorentz shift correction    
+  double shift = de->getLorentzCorrection();
+  
+  unsigned hitNumber(0);
+  for( auto& siHit : matchingHits ){
+    
+    HepGeom::Point3D<double> averagePosition = (siHit.localStartPosition() + siHit.localEndPosition()) * 0.5;
+    
+    ATH_MSG_VERBOSE("Truth Part X: " << averagePosition.y() << " shift " << shift << " Y: " << averagePosition.z() );
+
+    // position lorentz shift corrected
+    float YposC = averagePosition.y()-shift;
+
+    if (fabs(YposC)>design->width()/2 && 
+        fabs(averagePosition.y())<design->width()/2)
+    {
+      if (YposC>design->width()/2)
+      {
+        YposC=design->width()/2-1e-6;
+      } else if (YposC<-design->width()/2)
+      {
+        YposC=-design->width()/2+1e-6;
+      }
+    }
+        
+    positionsX[hitNumber] = YposC;
+    positionsY[hitNumber] = averagePosition.z();
+
+    HepGeom::Point3D<double> deltaPosition = siHit.localEndPosition() - siHit.localStartPosition();
+    
+    pathlengthX[hitNumber] = deltaPosition.y();
+    pathlengthY[hitNumber] = deltaPosition.z();
+    pathlengthZ[hitNumber] = deltaPosition.x();
+
+
+    
+    InDetDD::SiLocalPosition siLocalTruthPosition(averagePosition.z(),YposC ) ;
+    InDetDD::SiCellId cellIdOfTruthPosition =design->cellIdOfPosition(siLocalTruthPosition);
+
+    int truthEtaIndex =  cellIdOfTruthPosition.etaIndex();
+    int truthPhiIndex =  cellIdOfTruthPosition.phiIndex();
+
+    InDetDD::SiDiodesParameters diodeParameters = design->parameters(cellIdOfTruthPosition);
+    double pitchY = diodeParameters.width().xEta();
+    double pitchX = diodeParameters.width().xPhi();
+
+    // pixel center
+    // SiLocalPosition PixelModuleDesign::positionFromColumnRow(const int column, const int row) const;
+    //
+    // Given row and column index of diode, returns position of diode center
+    // ALTERNATIVE/PREFERED way is to use localPositionOfCell(const SiCellId & cellId) or 
+    // rawLocalPositionOfCell method in SiDetectorElement.
+    // DEPRECATED (but used in numerous places)
+    //
+    // Comment by Hide (referring the original comment in the code) : 2015-02-04
+    // I automatically replaced column to etaPixelIndex and row to phiPixelIndex here. It was bofore:
+    // InDetDD::SiLocalPosition siLocalPosition( design->positionFromColumnRow(truthColumn,truthRow) ); 
+    //
+    // Then I assume the argument of column/row in this function is in offline manner, not the real hardware column/row.
+    // 
+    InDetDD::SiLocalPosition siLocalPositionCenter(design->positionFromColumnRow(truthEtaIndex,truthPhiIndex)); 
+    double pixelCenterY = siLocalPositionCenter.xEta();
+    double pixelCenterX = siLocalPositionCenter.xPhi();
+    
+
+    // truth index
+    double truthIndexY =  truthEtaIndex + (averagePosition.z() - pixelCenterY)/pitchY;
+    double truthIndexX =  truthPhiIndex + (YposC               - pixelCenterX)/pitchX;
+
+    positions_indexX[hitNumber] = truthIndexX - cellIdWeightedPosition.phiIndex();
+    positions_indexY[hitNumber] = truthIndexY - cellIdWeightedPosition.etaIndex();
+
+    HepGeom::Point3D<double> diffPositions = (siHit.localEndPosition() - siHit.localStartPosition());
+    double bowphi = atan2( diffPositions.y(), diffPositions.x() );
+   
+
+    //Truth Track incident angle theta
+    theta[hitNumber] = atan2(diffPositions.z() ,diffPositions.x());
+    //Truth track incident angle phi -- correct for lorentz angle
+    float tanlorentz = de->getTanLorentzAnglePhi();
+    int readoutside = design->readoutSide();
+    phi[hitNumber] = atan(tan(bowphi)-readoutside*tanlorentz);
+    
+    if(siHit.particleLink().isValid()){
+      barcode[hitNumber] = siHit.particleLink().barcode(); 
+      
+      auto particle = siHit.particleLink();
+      pdgid[hitNumber]   = particle->pdg_id();
+      truep[hitNumber]  = particle->momentum().rho();
+      if ( particle->production_vertex() ){
+        auto vertex =  particle->production_vertex();
+        if( vertex->particles_in_const_begin() !=  vertex->particles_in_const_end() ){
+          motherBarcode[hitNumber] =  (*vertex->particles_in_const_begin())->barcode();
+          motherPdgid[hitNumber]    =  (*vertex->particles_in_const_begin())->pdg_id();
+        }
+      }
+    }
+    chargeDep[hitNumber] = siHit.energyLoss() ;
+    
+    ++hitNumber;
+  }
+
+
+  xprd->auxdata< std::vector<float> >("NN_positionsX") = positionsX;
+  xprd->auxdata< std::vector<float> >("NN_positionsY") = positionsY;
+
+  xprd->auxdata< std::vector<float> >("NN_positions_indexX") = positions_indexX;
+  xprd->auxdata< std::vector<float> >("NN_positions_indexY") = positions_indexY;
+
+  xprd->auxdata< std::vector<float> >("NN_theta")     = theta;
+  xprd->auxdata< std::vector<float> >("NN_phi")       = phi;
+
+  xprd->auxdata< std::vector<int> >("NN_barcode")     = barcode;
+  xprd->auxdata< std::vector<int> >("NN_pdgid")       = pdgid;
+  xprd->auxdata< std::vector<float> >("NN_energyDep") = chargeDep;
+  xprd->auxdata< std::vector<float> >("NN_trueP")     = truep;
+
+  xprd->auxdata< std::vector<int> >("NN_motherBarcode") = motherBarcode;
+  xprd->auxdata< std::vector<int> >("NN_motherPdgid")   = motherPdgid;
+ 
+
+  xprd->auxdata< std::vector<float> >("NN_pathlengthX") = pathlengthX;
+  xprd->auxdata< std::vector<float> >("NN_pathlengthY") = pathlengthY;
+  xprd->auxdata< std::vector<float> >("NN_pathlengthZ") = pathlengthZ;
+
+
+}
+
+
+
+
+InDetDD::SiCellId PixelPrepDataToxAOD::getCellIdWeightedPosition(  const InDet::PixelCluster* pixelCluster,
+                                                                   int *rphiPixelIndexMin,
+                                                                   int *rphiPixelIndexMax,
+                                                                   int *retaPixelIndexMin,
+                                                                   int *retaPixelIndexMax   ) const
+{
+
+  const InDetDD::SiDetectorElement* de = pixelCluster->detectorElement();
+  if (de==0) {
+    ATH_MSG_ERROR("Could not get detector element");
+    return InDetDD::SiCellId();
+  }
+
+  const InDetDD::PixelModuleDesign* design(dynamic_cast<const InDetDD::PixelModuleDesign*>(&de->design()));
+  if (not design) {
+    ATH_MSG_WARNING("PixelModuleDesign was not retrieved in function 'getCellIdWeightedPosition'");
+    return InDetDD::SiCellId();
+  }
+  const std::vector<Identifier>& rdos  = pixelCluster->rdoList();  
+
+  ATH_MSG_VERBOSE( "Number of RDOs: " << rdos.size() );
+  const std::vector<float>& chList     = pixelCluster->chargeList();
+
+  ATH_MSG_VERBOSE( "Number of charges: " << chList.size() );
+  std::vector<Identifier>::const_iterator rdosBegin = rdos.begin();
+  std::vector<Identifier>::const_iterator rdosEnd = rdos.end();
+
+  auto charge = chList.begin();    
+
+  InDetDD::SiLocalPosition sumOfWeightedPositions(0,0,0);
+  double sumOfCharge=0;
+
+  int phiPixelIndexMin =  99999;
+  int phiPixelIndexMax = -99999;
+  int etaPixelIndexMin =  99999;
+  int etaPixelIndexMax = -99999;
+
+  for (; rdosBegin!= rdosEnd; ++rdosBegin, ++charge)
+  {
+  
+    Identifier rId =  *rdosBegin;
+    int phiPixelIndex = m_PixelHelper->phi_index(rId);
+    int etaPixelIndex = m_PixelHelper->eta_index(rId);
+  
+    ATH_MSG_VERBOSE(" Adding pixel phiPixelIndex: " << phiPixelIndex << " etaPixelIndex: " << etaPixelIndex << " charge: " << *charge );
+    
+    // SiLocalPosition PixelModuleDesign::positionFromColumnRow(const int column, const int row) const;
+    //
+    // Given row and column index of diode, returns position of diode center
+    // ALTERNATIVE/PREFERED way is to use localPositionOfCell(const SiCellId & cellId) or 
+    // rawLocalPositionOfCell method in SiDetectorElement.
+    // DEPRECATED (but used in numerous places)
+    //
+    // Comment by Hide (referring the original comment in the code): 2015-02-04
+    // I automatically replaced column to etaPixelIndex and row to phiPixelIndex here. It was bofore:
+    // InDetDD::SiLocalPosition siLocalPosition( design->positionFromColumnRow(column,row) ); 
+    //
+    // Then I assume the argument of column/row in this function is in offline manner, not the real hardware column/row.
+    // 
+    InDetDD::SiLocalPosition siLocalPosition( design->positionFromColumnRow(etaPixelIndex,phiPixelIndex) ); 
+    ATH_MSG_VERBOSE ( "Local Position: Row = " << siLocalPosition.xRow() << ", Col = " << siLocalPosition.xColumn() );
+  
+    sumOfWeightedPositions += (*charge)*siLocalPosition;
+    sumOfCharge += (*charge);
+
+    if (phiPixelIndex < phiPixelIndexMin)
+      phiPixelIndexMin = phiPixelIndex; 
+     
+    if (phiPixelIndex > phiPixelIndexMax)
+      phiPixelIndexMax = phiPixelIndex;
+    
+    if (etaPixelIndex < etaPixelIndexMin)
+      etaPixelIndexMin = etaPixelIndex;
+      
+    if (etaPixelIndex > etaPixelIndexMax)
+      etaPixelIndexMax = etaPixelIndex;
+
+  }
+  sumOfWeightedPositions /= sumOfCharge;
+
+  ATH_MSG_VERBOSE ( "Wighted position: Row = " << sumOfWeightedPositions.xRow() << ", Col = " << sumOfWeightedPositions.xColumn() );
+
+  if(rphiPixelIndexMin) *rphiPixelIndexMin = phiPixelIndexMin;
+  if(rphiPixelIndexMax) *rphiPixelIndexMax = phiPixelIndexMax;
+  if(retaPixelIndexMin) *retaPixelIndexMin = etaPixelIndexMin;
+  if(retaPixelIndexMax) *retaPixelIndexMax = etaPixelIndexMax;
+
+  //what you want to know is simple:
+  //just the phiPixelIndex and etaPixelIndex of this average position!
+
+  InDetDD::SiCellId cellIdWeightedPosition=design->cellIdOfPosition(sumOfWeightedPositions);
+
+
+  return cellIdWeightedPosition;
+  
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Finalize method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode PixelPrepDataToxAOD::finalize()
+{
+  return StatusCode::SUCCESS;
+}
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/PixelPrepDataToxAOD.h b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/PixelPrepDataToxAOD.h
new file mode 100644
index 00000000000..98d86b9aba7
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/PixelPrepDataToxAOD.h
@@ -0,0 +1,104 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// PixelPrepDataToxAOD.h
+//   Header file for class PixelPrepDataToxAOD
+///////////////////////////////////////////////////////////////////
+
+#ifndef PIXELPREPDATATOXAOD_H
+#define PIXELPREPDATATOXAOD_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+#include "InDetSimEvent/SiHitCollection.h"
+#include "xAODTracking/TrackMeasurementValidation.h"
+
+
+#include <string>
+
+class PixelID;
+class SiHit;
+class InDetSimDataCollection;
+
+
+namespace InDet
+{
+  class PixelCluster;
+}
+
+namespace InDetDD
+{
+  class SiCellId; 
+}
+
+
+
+class PixelPrepDataToxAOD : public AthAlgorithm  {
+
+public:
+  // Constructor with parameters:
+  PixelPrepDataToxAOD(const std::string &name,ISvcLocator *pSvcLocator);
+
+  // Basic algorithm methods:
+  virtual StatusCode initialize();
+  virtual StatusCode execute();
+  virtual StatusCode finalize();
+
+private:
+
+  void  addSDOInformation( xAOD::TrackMeasurementValidation* xprd,
+                           const InDet::PixelCluster* prd,
+                           const InDetSimDataCollection* sdoCollection ) const;
+
+
+  void  addSiHitInformation( xAOD::TrackMeasurementValidation* xprd, 
+                             const InDet::PixelCluster* prd,
+                             const SiHitCollection* collection) const;
+  
+  std::vector<SiHit>  findAllHitsCompatibleWithCluster(const InDet::PixelCluster* prd,
+                                                       const SiHitCollection* collection) const;
+
+
+  void  addNNTruthInfo( xAOD::TrackMeasurementValidation* xprd,
+                        const InDet::PixelCluster* prd, 
+                        const SiHitCollection* collection ) const;
+
+  void  addNNInformation( xAOD::TrackMeasurementValidation* xprd, 
+                         const InDet::PixelCluster* pixelCluster, 
+                         const unsigned int SizeX, 
+                         const unsigned int SizeY ) const;
+
+  void  addRdoInformation( xAOD::TrackMeasurementValidation* xprd, 
+                         const InDet::PixelCluster* pixelCluster) const;
+
+
+
+   InDetDD::SiCellId getCellIdWeightedPosition(  const InDet::PixelCluster* pixelCluster,
+                                                 int *rrowMin = 0,
+                                                 int *rrowMax = 0,
+                                                 int *rcolMin = 0,
+                                                 int *rcolMax = 0 ) const;
+
+
+  const PixelID *m_PixelHelper;
+  std::string  m_clustercontainer;
+  std::string  m_SDOcontainer;
+  std::string  m_sihitContainer;
+  std::string  m_multiTruth;
+
+  bool  m_useTruthInfo;
+  bool  m_writeSDOs;
+  bool  m_writeSiHits;
+  bool  m_writeNNinformation;
+  bool  m_writeRDOinformation;
+
+  // -- Private members   
+  bool m_firstEventWarnings;
+
+};
+
+
+#endif 
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/SCT_PrepDataToxAOD.cxx b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/SCT_PrepDataToxAOD.cxx
new file mode 100644
index 00000000000..44b6d41c0ad
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/SCT_PrepDataToxAOD.cxx
@@ -0,0 +1,590 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// SCT_PrepDataToxAOD.cxx
+//   Implementation file for class SCT_PrepDataToxAOD
+///////////////////////////////////////////////////////////////////
+
+#include "SCT_PrepDataToxAOD.h"
+
+#include "InDetPrepRawData/SCT_ClusterContainer.h"
+
+#include "xAODTracking/TrackMeasurementValidationContainer.h"
+#include "xAODTracking/TrackMeasurementValidationAuxContainer.h"
+
+#include "Identifier/Identifier.h"
+#include "InDetIdentifier/SCT_ID.h"
+
+#include "InDetRawData/SCT_RDO_Container.h"
+#include "InDetRawData/SCT_RDO_Collection.h"
+
+#include "TrkTruthData/PRD_MultiTruthCollection.h"
+#include "HepMC/GenParticle.h"
+#include "InDetSimEvent/SiHit.h"
+#include "InDetSimData/InDetSimDataCollection.h"
+
+#include "CLHEP/Geometry/Point3D.h"
+
+
+
+/////////////////////////////////////////////////////////////////////
+//
+//         Constructor with parameters:
+//
+/////////////////////////////////////////////////////////////////////
+SCT_PrepDataToxAOD::SCT_PrepDataToxAOD(const std::string &name, ISvcLocator *pSvcLocator) :
+  AthAlgorithm(name,pSvcLocator),
+  m_incidentSvc("IncidentSvc", name),
+  m_SCTHelper(0),
+  m_firstEventWarnings(true)
+{ 
+  // --- Steering and configuration flags
+  declareProperty("UseTruthInfo", m_useTruthInfo=false);
+  declareProperty("WriteRDOinformation", m_writeRDOinformation =true);
+  declareProperty("WriteSDOs", m_writeSDOs = true);
+  declareProperty("WriteSiHits", m_writeSiHits = true);
+
+  // --- Configuration keys
+  declareProperty("SiClusterContainer",  m_clustercontainer = "SCT_Clusters");
+  declareProperty("MC_SDOs", m_SDOcontainer = "SCT_SDO_Map");
+  declareProperty("MC_Hits", m_sihitContainer = "SCT_Hits");
+  declareProperty("PRD_MultiTruth", m_multiTruth = "PRD_MultiTruthSCT");
+
+  // --- Services and Tools
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Initialize method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode SCT_PrepDataToxAOD::initialize()
+{
+
+  CHECK ( detStore()->retrieve(m_SCTHelper, "SCT_ID") );
+
+  CHECK ( m_incidentSvc.retrieve() );
+  // register to the incident service:
+  m_incidentSvc->addListener( this, IncidentType::EndEvent);
+
+  //make sure we don't write what we don't have
+  if (not  m_useTruthInfo) {
+    m_writeSDOs = false;
+    m_writeSiHits = false;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Execute method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode SCT_PrepDataToxAOD::execute() 
+{     
+  const SCT_RDO_Container * rdoContainer(0);
+   
+  // the cluster ambiguity map
+  if ( m_writeRDOinformation ) {
+    if(!evtStore()->contains<SCT_RDO_Container>("SCT_RDOs")){
+      if (m_firstEventWarnings) {
+	ATH_MSG_WARNING("RDO ASSOC: No SCT RDO container in StoreGate");
+      }
+    }
+    else {
+      if(evtStore()->retrieve(rdoContainer,"SCT_RDOs").isFailure()) {
+        ATH_MSG_WARNING( "Failed to retrieve SCT RDO container" );
+      }
+    }
+  
+    if ( rdoContainer != 0){
+
+      // get all the RIO_Collections in the container
+      
+      for( auto& collection: *rdoContainer ){
+
+        //get all the RDOs in the collection
+        for (auto& rdo : *collection) {
+
+          if ( !rdo) {
+            ATH_MSG_WARNING( "Null SCT RDO. Skipping it");
+            continue;
+          }
+
+          Identifier rdoId = rdo->identify();
+	  
+          m_IDtoRAWDataMap.insert( std::pair< Identifier, const SCT_RDORawData*>( rdoId, rdo ) );      
+        } // collection
+      } // container
+    } // Have container;
+  }   
+  ATH_MSG_DEBUG("Size of RDO map is "<<m_IDtoRAWDataMap.size());
+
+  // Mandatory. This is needed and required if this algorithm is scheduled.
+  const InDet::SCT_ClusterContainer* sctClusterContainer = 0;     
+  if( evtStore()->retrieve(sctClusterContainer,m_clustercontainer).isFailure() ) {
+    ATH_MSG_ERROR("Cannot retrieve SCT PrepDataContainer " << m_clustercontainer);
+    return StatusCode::FAILURE;
+  }
+
+  // Optional. Normally only available in Hits files -- samples need to digitised and Hits need to be copied for this to work
+  const SiHitCollection* sihitCollection = 0;
+  if (m_writeSiHits) {
+    if (evtStore()->contains<SiHitCollection>(m_sihitContainer)) {
+      ATH_CHECK(evtStore()->retrieve(sihitCollection, m_sihitContainer));
+    } else {
+      if (m_firstEventWarnings) {
+	ATH_MSG_WARNING("SiHit collection not available (" << m_sihitContainer << "). Skipping although requested.");
+	sihitCollection = 0;
+      }	
+    }
+  }
+
+  // Optional. On RDO
+  const InDetSimDataCollection* sdoCollection = 0;
+  if (m_writeSDOs) {
+    if ( evtStore()->contains<InDetSimDataCollection>(m_SDOcontainer) ) {
+      ATH_CHECK(evtStore()->retrieve(sdoCollection, m_SDOcontainer));
+    } else {
+      ATH_MSG_WARNING("SDO container not available (" << m_SDOcontainer << "). Skipping although requested.");
+      sdoCollection = 0;
+    }
+  }
+
+  // Optional. On ESD and AOD
+  const PRD_MultiTruthCollection* prdmtColl = 0;
+  if (m_useTruthInfo) {
+    if ( evtStore()->contains<PRD_MultiTruthCollection>(m_multiTruth) ) {
+      ATH_CHECK(evtStore()->retrieve(prdmtColl, m_multiTruth));
+    } else {
+      ATH_MSG_WARNING("MultiTruth container not available (" << m_multiTruth << "). Skipping although requested.");
+      prdmtColl = 0;
+    }
+  }
+
+
+  // Create the xAOD container and its auxiliary store:
+  xAOD::TrackMeasurementValidationContainer* xaod = new xAOD::TrackMeasurementValidationContainer();
+  CHECK( evtStore()->record( xaod, m_clustercontainer ) );
+  xAOD::TrackMeasurementValidationAuxContainer* aux = new xAOD::TrackMeasurementValidationAuxContainer();
+  CHECK( evtStore()->record( aux, m_clustercontainer + "Aux." ) );
+  xaod->setStore( aux );
+  
+  std::vector<unsigned int>* offsets = new std::vector<unsigned int>( m_SCTHelper->wafer_hash_max(), 0 );
+  CHECK( evtStore()->record( offsets, m_clustercontainer + "Offsets" ) );
+  
+  // Loop over the container
+  unsigned int counter(0);
+  for( const auto& clusterCollection : *sctClusterContainer){
+
+    //Fill Offset container
+    (*offsets)[clusterCollection->identifyHash()] = counter;
+    
+    // skip empty collections
+    if( clusterCollection->empty() ) continue;
+
+         
+    // loop over collection and convert to xAOD
+    for( auto& prd : *clusterCollection ){
+      ++counter;
+      
+      Identifier clusterId = prd->identify();
+      if ( !clusterId.is_valid() ) {
+        ATH_MSG_WARNING("SCT cluster identifier is not valid!");
+      }
+              
+      // create and add xAOD object
+      xAOD::TrackMeasurementValidation* xprd = new xAOD::TrackMeasurementValidation();
+      xaod->push_back(xprd);
+  
+      //Set Identifier
+      xprd->setIdentifier( clusterId.get_compact() );
+
+      //Set Global Position
+      Amg::Vector3D gpos = prd->globalPosition();
+      xprd->setGlobalPosition(gpos.x(),gpos.y(),gpos.z());
+
+      //Set Local Position
+      const Amg::Vector2D& locpos = prd->localPosition();
+      float locY(0.);
+      float locX = locpos.x();
+      if ( !(std::isinf(locpos.y()) || std::isnan(locpos.y())) ){
+        if (locpos.y()>=1e-07)
+          locY=locpos.y();
+      } else { 
+        locY = -9999.;
+      }
+
+      // Set local error matrix
+      xprd->setLocalPosition(locX,locY); 
+      
+      const Amg::MatrixX& localCov = prd->localCovariance();
+      if(localCov.size() == 1){
+        xprd->setLocalPositionError( localCov(0,0), 0., 0. ); 
+      } else if(localCov.size() == 4){
+        xprd->setLocalPositionError( localCov(0,0), localCov(1,1), localCov(0,1) );     
+      } else {
+        xprd->setLocalPositionError(0.,0.,0.);
+      }
+         
+      // Set vector of hit identifiers
+      std::vector< uint64_t > rdoIdentifierList;
+      for( const auto &hitIdentifier : prd->rdoList() ){
+        rdoIdentifierList.push_back( hitIdentifier.get_compact() );
+      }
+      xprd->setRdoIdentifierList(rdoIdentifierList);      
+
+      //Add SCT specific information
+      const InDet::SiWidth cw = prd->width();
+      xprd->auxdata<int>("size") = (int)cw.colRow()[0];
+
+      xprd->auxdata<int>("bec")          =   m_SCTHelper->barrel_ec(clusterId)   ;
+      xprd->auxdata<int>("layer")        =   m_SCTHelper->layer_disk(clusterId)  ;   
+      xprd->auxdata<int>("phi_module")   =   m_SCTHelper->phi_module(clusterId)  ;
+      xprd->auxdata<int>("eta_module")   =   m_SCTHelper->eta_module(clusterId)  ;
+      xprd->auxdata<int>("side")         =   m_SCTHelper->side(clusterId)        ;
+   
+      // Add the Detector element ID  --  not sure if needed as we have the informations above
+      const InDetDD::SiDetectorElement* de = prd->detectorElement();
+      uint64_t detElementId(0);
+      if(de){
+        Identifier detId = de->identify();
+        if ( detId.is_valid() ) {
+          detElementId = detId.get_compact();
+        }
+      }
+      xprd->auxdata<uint64_t>("detectorElementID") = detElementId;
+   
+      //Add details about the individual hits 
+      if(m_writeRDOinformation)
+        addRDOInformation(xprd, prd);
+   
+      
+      // Use the MultiTruth Collection to get a list of all true particle contributing to the cluster
+      if(prdmtColl){
+        std::vector<int> barcodes;
+        //std::pair<PRD_MultiTruthCollection::const_iterator,PRD_MultiTruthCollection::const_iterator>;
+        auto range = prdmtColl->equal_range(clusterId);
+        for (auto i = range.first; i != range.second; ++i) {
+           barcodes.push_back( i->second.barcode() );
+        }
+        xprd->auxdata< std::vector<int> >("truth_barcode") = barcodes;
+      }
+
+      // Use the SDO Collection to get a list of all true particle contributing to the cluster per readout element
+      //  Also get the energy deposited by each true particle per readout element   
+      if( sdoCollection ){
+        addSDOInformation( xprd, prd,sdoCollection);
+      }
+    
+      // Now Get the most detailed truth from the SiHits
+      // Note that this could get really slow if there are a lot of hits and clusters
+      if( sihitCollection  ){
+        addSiHitInformation( xprd, prd, sihitCollection); 
+      }
+    }
+  }
+  ATH_MSG_DEBUG( " recorded SCT_PrepData objects: size " << xaod->size() );
+
+  m_firstEventWarnings = false; //disable one-time warnings
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+void SCT_PrepDataToxAOD::addSDOInformation( xAOD::TrackMeasurementValidation* xprd,
+                                            const InDet::SCT_Cluster* prd,
+                                            const InDetSimDataCollection* sdoCollection ) const
+{
+  std::vector<int> sdo_word;
+  std::vector< std::vector< int > > sdo_depositsBarcode;
+  std::vector< std::vector< float > > sdo_depositsEnergy;
+  // find hit
+  for( const auto &hitIdentifier : prd->rdoList() ){
+    auto pos = sdoCollection->find(hitIdentifier);
+    if( pos != sdoCollection->end() ) {
+      sdo_word.push_back( pos->second.word() ) ;
+      
+      std::vector< int > sdoDepBC;
+      std::vector< float > sdoDepEnergy;
+      for( auto deposit : pos->second.getdeposits() ){
+        if(deposit.first){
+          sdoDepBC.push_back( deposit.first->barcode());
+        } else {
+          sdoDepBC.push_back( -1 );   
+        }
+        sdoDepEnergy.push_back( deposit.second  );
+        ATH_MSG_DEBUG(" SDO Energy Deposit " << deposit.second  ) ;
+      }
+      sdo_depositsBarcode.push_back( sdoDepBC );
+      sdo_depositsEnergy.push_back( sdoDepEnergy );
+    }
+  }
+  xprd->auxdata< std::vector<int> >("sdo_words")  = sdo_word;
+  xprd->auxdata< std::vector< std::vector<int> > >("sdo_depositsBarcode")  = sdo_depositsBarcode;
+  xprd->auxdata< std::vector< std::vector<float> > >("sdo_depositsEnergy") = sdo_depositsEnergy;
+}
+
+
+
+void  SCT_PrepDataToxAOD::addSiHitInformation( xAOD::TrackMeasurementValidation* xprd, 
+                                               const InDet::SCT_Cluster* prd,
+                                               const SiHitCollection* sihitCollection) const
+                             
+                             
+{
+
+  std::vector<SiHit> matchingHits = findAllHitsCompatibleWithCluster(  prd, sihitCollection );
+
+  int numHits = matchingHits.size();
+
+  std::vector<float> sihit_energyDeposit(numHits,0);
+  std::vector<float> sihit_meanTime(numHits,0);
+  std::vector<int>   sihit_barcode(numHits,0);
+  
+  std::vector<float> sihit_startPosX(numHits,0);
+  std::vector<float> sihit_startPosY(numHits,0);
+  std::vector<float> sihit_startPosZ(numHits,0);
+
+  std::vector<float> sihit_endPosX(numHits,0);
+  std::vector<float> sihit_endPosY(numHits,0);
+  std::vector<float> sihit_endPosZ(numHits,0);
+
+  int hitNumber(0);
+  const InDetDD::SiDetectorElement* de = prd->detectorElement();
+  if(de){
+    for ( auto sihit : matchingHits ) {          
+      sihit_energyDeposit[hitNumber] =  sihit.energyLoss() ;
+      sihit_meanTime[hitNumber] =  sihit.meanTime() ;
+      sihit_barcode[hitNumber] =  sihit.particleLink().barcode() ;
+    
+      // Convert Simulation frame into reco frame
+      const HepGeom::Point3D<double>& startPos=sihit.localStartPosition();
+
+      Amg::Vector2D pos= de->hitLocalToLocal( startPos.z(), startPos.y() );
+      sihit_startPosX[hitNumber] =  pos[0];
+      sihit_startPosY[hitNumber] =  pos[1];
+      sihit_startPosZ[hitNumber] =  startPos.x();
+ 
+
+      const HepGeom::Point3D<double>& endPos=sihit.localEndPosition();
+      pos= de->hitLocalToLocal( endPos.z(), endPos.y() );
+      sihit_endPosX[hitNumber] =  pos[0];
+      sihit_endPosY[hitNumber] =  pos[1];
+      sihit_endPosZ[hitNumber] =  endPos.x();
+      ++hitNumber;
+    }
+  }
+
+  xprd->auxdata<std::vector<float> >("sihit_energyDeposit") = sihit_energyDeposit;
+  xprd->auxdata<std::vector<float> >("sihit_meanTime") = sihit_meanTime;
+  xprd->auxdata<std::vector<int> >("sihit_barcode") = sihit_barcode;
+  
+  xprd->auxdata<std::vector<float> >("sihit_startPosX") = sihit_startPosX;
+  xprd->auxdata<std::vector<float> >("sihit_startPosY") = sihit_startPosY;
+  xprd->auxdata<std::vector<float> >("sihit_startPosZ") = sihit_startPosZ;
+
+  xprd->auxdata<std::vector<float> >("sihit_endPosX") = sihit_endPosX;
+  xprd->auxdata<std::vector<float> >("sihit_endPosY") = sihit_endPosY;
+  xprd->auxdata<std::vector<float> >("sihit_endPosZ") = sihit_endPosZ;
+
+
+}
+
+
+
+
+
+std::vector<SiHit> SCT_PrepDataToxAOD::findAllHitsCompatibleWithCluster( const InDet::SCT_Cluster* prd, 
+                                                                         const SiHitCollection* collection) const
+{
+  ATH_MSG_VERBOSE( "Got " << collection->size() << " SiHits to look through" );
+  std::vector<SiHit>  matchingHits;
+    
+  // Check if we have detector element  --  needed to find the local position of the SiHits
+  const InDetDD::SiDetectorElement* de = prd->detectorElement();
+  if(!de)
+    return matchingHits;
+
+  std::vector<const SiHit* >  multiMatchingHits;
+  
+  for ( const auto&  siHit : *collection) {
+    // Check if it is a SCT hit
+    if( !siHit.isSCT() )
+      continue;
+     
+    //Check if it is on the correct module
+    Identifier clusterId = prd->identify();
+  
+    if( m_SCTHelper->barrel_ec(clusterId) != siHit.getBarrelEndcap() ||
+        m_SCTHelper->layer_disk(clusterId)!= siHit.getLayerDisk()    ||  
+        m_SCTHelper->phi_module(clusterId)!= siHit.getPhiModule()    ||
+        m_SCTHelper->eta_module(clusterId)!= siHit.getEtaModule()    ||
+        m_SCTHelper->side(clusterId)      != siHit.getSide()  ) 
+       continue;
+
+    // Now we have all hits in the module that match lets check to see if they match the cluster
+    // Must be within +/- 1 hits of any hit in the cluster to be included
+    ATH_MSG_DEBUG("Hit is on the same module");
+    
+    HepGeom::Point3D<double>  averagePosition =  siHit.localStartPosition() + siHit.localEndPosition();
+    averagePosition *= 0.5;
+    Amg::Vector2D pos = de->hitLocalToLocal( averagePosition.z(), averagePosition.y() );
+    InDetDD::SiCellId diode = de->cellIdOfPosition(pos);
+   
+    for( const auto &hitIdentifier : prd->rdoList() ){
+      //if( abs( int(diode.etaIndex()) - m_SCTHelper->eta_index( hitIdentifier ) ) <=1 ) 
+      //if( abs( int(diode.phiIndex() - m_SCTHelper->phi_index( hitIdentifier ) ) <=1 ) 
+      ATH_MSG_DEBUG("Truth Strip " <<  diode.phiIndex() << " Cluster Strip " <<   m_SCTHelper->strip( hitIdentifier ) );
+
+      if( abs( int(diode.phiIndex()) -  m_SCTHelper->strip( hitIdentifier ) ) <=1)
+      {
+        multiMatchingHits.push_back(&siHit);   
+        break;   
+      }     
+    }
+  }
+  
+  
+  //Now we will now make 1 SiHit for each true particle if the SiHits "touch" other 
+  std::vector<const SiHit* >::iterator siHitIter  = multiMatchingHits.begin();
+  std::vector<const SiHit* >::iterator siHitIter2 = multiMatchingHits.begin();
+  ATH_MSG_DEBUG( "Found " << multiMatchingHits.size() << " SiHit " );
+  for ( ; siHitIter != multiMatchingHits.end(); siHitIter++) {
+    const SiHit* lowestXPos = *siHitIter;
+    const SiHit* highestXPos = *siHitIter;
+
+
+    // We will merge these hits
+    std::vector<const SiHit* > ajoiningHits;
+    ajoiningHits.push_back( *siHitIter );
+  
+    siHitIter2 = siHitIter+1;    
+    while ( siHitIter2 != multiMatchingHits.end() ) {
+    // Need to come from the same truth particle 
+      if( (*siHitIter)->particleLink().barcode() != (*siHitIter2)->particleLink().barcode() ){
+        ++siHitIter2;
+        continue;
+      }
+       
+      // Check to see if the SiHits are compatible with each other.
+      if (fabs((highestXPos->localEndPosition().x()-(*siHitIter2)->localStartPosition().x()))<0.00005 &&
+          fabs((highestXPos->localEndPosition().y()-(*siHitIter2)->localStartPosition().y()))<0.00005 &&
+          fabs((highestXPos->localEndPosition().z()-(*siHitIter2)->localStartPosition().z()))<0.00005 )
+      {
+        highestXPos = *siHitIter2;
+        ajoiningHits.push_back( *siHitIter2 );
+        // Dont use hit  more than once
+        siHitIter2 = multiMatchingHits.erase( siHitIter2 );
+      }else if (fabs((lowestXPos->localStartPosition().x()-(*siHitIter2)->localEndPosition().x()))<0.00005 &&
+                fabs((lowestXPos->localStartPosition().y()-(*siHitIter2)->localEndPosition().y()))<0.00005 &&
+                fabs((lowestXPos->localStartPosition().z()-(*siHitIter2)->localEndPosition().z()))<0.00005)
+      {
+        lowestXPos = *siHitIter2;
+        ajoiningHits.push_back( *siHitIter2 );
+        // Dont use hit  more than once
+        siHitIter2 = multiMatchingHits.erase( siHitIter2 );
+      } else {
+        ++siHitIter2;
+      }
+    }
+    
+    if( ajoiningHits.size() == 0){
+      ATH_MSG_WARNING("This should really never happen");
+      continue;
+    }else if(ajoiningHits.size() == 1){
+      // Copy Si Hit ready to return
+      matchingHits.push_back( *ajoiningHits[0] );
+      continue;
+    } else {
+    //  Build new SiHit and merge information together.  
+      ATH_MSG_DEBUG("Merging " << ajoiningHits.size() << " SiHits together." );
+      
+      
+      float energyDep(0);
+      float time(0);
+      for( auto& siHit :  ajoiningHits){
+        energyDep += siHit->energyLoss();
+        time += siHit->meanTime();    
+      }
+      time /= (float)ajoiningHits.size();
+       
+      matchingHits.push_back(  SiHit(lowestXPos->localStartPosition(), 
+                                     highestXPos->localEndPosition(),
+                                     energyDep,
+                                     time,
+                                     (*siHitIter)->particleLink().barcode(),
+                                     1, // 0 for pixel 1 for SCT
+                                     (*siHitIter)->getBarrelEndcap(),
+                                     (*siHitIter)->getLayerDisk(),
+                                     (*siHitIter)->getEtaModule(),
+                                     (*siHitIter)->getPhiModule(),
+                                     (*siHitIter)->getSide() ) );
+    }
+  } 
+  
+
+  return matchingHits;
+  
+}
+
+void SCT_PrepDataToxAOD::addRDOInformation(xAOD::TrackMeasurementValidation* xprd, 
+                                           const InDet::SCT_Cluster* prd) const{
+
+
+  std::vector<int> strip;
+  std::vector<int> timebin;
+  std::vector<int> groupsize;
+  
+  for( const auto &hitIdentifier : prd->rdoList() ){
+    auto result = m_IDtoRAWDataMap.find(hitIdentifier);
+    if( result != m_IDtoRAWDataMap.end() ){
+      const SCT_RDORawData *sctRdo = result->second;
+      const SCT3_RawData* rdo3 = dynamic_cast<const SCT3_RawData*>(sctRdo);
+      int tbin(-1);
+      int gs(-1);
+      if (rdo3!=0){
+        tbin = rdo3->getTimeBin();
+        gs = rdo3->getGroupSize();
+      }
+      timebin.push_back( tbin);
+      groupsize.push_back( gs);
+      strip.push_back(sctRdo->getStrip()); 
+    } else {
+      timebin.push_back( -1 );
+      strip.push_back( -1 );
+      groupsize.push_back( -1 );     
+    }
+  }
+  
+  xprd->auxdata< std::vector<int> >("rdo_strip") = strip;
+  xprd->auxdata< std::vector<int> >("rdo_timebin") = timebin;
+  xprd->auxdata< std::vector<int> >("rdo_groupsize") = groupsize;
+  
+}
+
+void SCT_PrepDataToxAOD::handle(const Incident& inc) {
+  
+  /// clear map of RDOs<->identifiers
+  if ( m_writeRDOinformation && inc.type() == IncidentType::EndEvent ){
+    ATH_MSG_VERBOSE("'EndEvent' incident caught. Refreshing Cache.");
+    m_IDtoRAWDataMap.clear();
+  }     
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Finalize method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode SCT_PrepDataToxAOD::finalize()
+{
+  return StatusCode::SUCCESS;
+}
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/SCT_PrepDataToxAOD.h b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/SCT_PrepDataToxAOD.h
new file mode 100644
index 00000000000..d9821e973d4
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/SCT_PrepDataToxAOD.h
@@ -0,0 +1,87 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// SCT_PrepDataToxAOD.h
+//   Header file for class SCT_PrepDataToxAOD
+///////////////////////////////////////////////////////////////////
+
+#ifndef SCT_PREPDATATOXAOD_H
+#define SCT_PREPDATATOXAOD_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/IIncidentListener.h"
+
+#include "InDetSimEvent/SiHitCollection.h"
+#include "xAODTracking/TrackMeasurementValidation.h"
+
+
+#include <string>
+
+class SCT_ID;
+class SiHit;
+class InDetSimDataCollection;
+class SCT_RDORawData;
+class Identifier;
+
+namespace InDet
+{
+  class SCT_Cluster;
+}
+
+
+class SCT_PrepDataToxAOD : public AthAlgorithm, virtual public IIncidentListener {
+
+public:
+  // Constructor with parameters:
+  SCT_PrepDataToxAOD(const std::string &name,ISvcLocator *pSvcLocator);
+
+  // Basic algorithm methods:
+  virtual StatusCode initialize();
+  virtual StatusCode execute();
+  virtual StatusCode finalize();
+
+  virtual void handle(const Incident& inc);
+  
+private:
+
+
+  void addSDOInformation( xAOD::TrackMeasurementValidation* xprd,
+                          const InDet::SCT_Cluster* prd,
+                          const InDetSimDataCollection* sdoCollection ) const;
+
+
+  void addSiHitInformation( xAOD::TrackMeasurementValidation* xprd, 
+                             const InDet::SCT_Cluster* prd,
+                             const SiHitCollection* collection) const;
+
+  std::vector<SiHit>  findAllHitsCompatibleWithCluster(const InDet::SCT_Cluster* prd,
+                                                       const SiHitCollection* collection) const;
+
+  void addRDOInformation(xAOD::TrackMeasurementValidation*, const InDet::SCT_Cluster*) const;
+ 
+ 
+  ServiceHandle<IIncidentSvc>                         m_incidentSvc;   //!< IncidentSvc to catch begin of event and end of envent
+ 
+  const SCT_ID *m_SCTHelper;
+  std::string  m_clustercontainer;
+  std::string  m_SDOcontainer;
+  std::string  m_sihitContainer;
+  std::string  m_multiTruth;
+
+  bool  m_useTruthInfo;
+  bool  m_writeRDOinformation;
+  bool  m_writeSDOs;
+  bool  m_writeSiHits;
+  
+  std::map< Identifier, const SCT_RDORawData* > m_IDtoRAWDataMap;
+
+  // --- private members
+  bool m_firstEventWarnings;
+  
+};
+
+
+#endif 
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/TRT_PrepDataToxAOD.cxx b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/TRT_PrepDataToxAOD.cxx
new file mode 100644
index 00000000000..72e65dc383d
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/TRT_PrepDataToxAOD.cxx
@@ -0,0 +1,342 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// TRT_PrepDataToxAOD.cxx
+//   Implementation file for class TRT_PrepDataToxAOD
+///////////////////////////////////////////////////////////////////
+
+#include "TRT_PrepDataToxAOD.h"
+
+#include "InDetPrepRawData/TRT_DriftCircleContainer.h"
+//#include "EventPrimitives/EventPrimitivesHelpers.h"
+
+#include "xAODTracking/TrackMeasurementValidation.h"
+#include "xAODTracking/TrackMeasurementValidationContainer.h"
+#include "xAODTracking/TrackMeasurementValidationAuxContainer.h"
+
+
+#include "Identifier/Identifier.h"
+#include "InDetIdentifier/TRT_ID.h"
+
+
+#include "TrkSurfaces/Surface.h"
+#include "TRT_ConditionsServices/ITRT_StrawNeighbourSvc.h"
+#include "TRT_DriftFunctionTool/ITRT_DriftFunctionTool.h"
+
+#include "TrkTruthData/PRD_MultiTruthCollection.h"
+#include "InDetSimEvent/TRTUncompressedHitCollection.h"
+#include "InDetSimData/InDetSimDataCollection.h"
+
+
+/////////////////////////////////////////////////////////////////////
+//
+//         Constructor with parameters:
+//
+/////////////////////////////////////////////////////////////////////
+TRT_PrepDataToxAOD::TRT_PrepDataToxAOD(const std::string &name, ISvcLocator *pSvcLocator) :
+  AthAlgorithm(name,pSvcLocator),
+  m_driftFunctionTool("TRT_DriftFunctionTool"),
+  m_trtcaldbSvc("TRT_CalDbSvc", name),
+  m_neighbourSvc("TRT_StrawNeighbourSvc", name),
+  m_TRTStrawSummarySvc("InDetTRTStrawStatusSummarySvc",name),
+  m_TRTHelper(0),
+  m_firstEventWarnings(true)
+{ 
+  // --- Steering and configuration flags
+  declareProperty("UseTruthInfo",          m_useTruthInfo=false);
+  declareProperty("WriteSDOs",             m_writeSDOs = true);
+
+  // --- Configuration keys
+  declareProperty("DriftCircleContainer",  m_driftcirclecontainer="TRT_DriftCircles");
+  declareProperty("MC_TRTUncompressedHit", m_SDOcontainer="TRT_SDO_Map");
+  declareProperty("PRD_MultiTruth",        m_multiTruth="PRD_MultiTruthTRT");
+
+  // --- Services and Tools
+  declareProperty("TRTDriftFunctionTool",  m_driftFunctionTool);
+  declareProperty("TRTCalDbSvc",           m_trtcaldbSvc);
+  declareProperty("NeighbourSvc",          m_neighbourSvc);
+  declareProperty("TRTStrawSummarySvc",    m_TRTStrawSummarySvc);
+  declareProperty("NeighbourSvc",          m_neighbourSvc);
+
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Initialize method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode TRT_PrepDataToxAOD::initialize()
+{
+  ATH_MSG_DEBUG("Initialize");
+
+  // --- Retrieve services and tools
+  CHECK ( detStore()->retrieve(m_TRTHelper, "TRT_ID") );
+
+  CHECK ( m_neighbourSvc.retrieve() );
+
+  CHECK ( m_trtcaldbSvc.retrieve() );
+
+  CHECK ( m_TRTStrawSummarySvc.retrieve() );
+
+  CHECK( m_driftFunctionTool.retrieve() );
+
+  return StatusCode::SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Execute method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode TRT_PrepDataToxAOD::execute() 
+{
+  //This is needed for the algorithm. If not there, it fails
+  const InDet::TRT_DriftCircleContainer* m_trtPrds = 0;
+  if( evtStore()->retrieve(m_trtPrds,m_driftcirclecontainer).isFailure() ) {
+    ATH_MSG_ERROR("Cannot retrieve TRT PrepDataContainer " << m_driftcirclecontainer);
+    return StatusCode::FAILURE;
+  }
+
+  //This is optional for the algorithm. If not there, just print a one-time warning
+  // On ESD 
+  const PRD_MultiTruthCollection* m_prdmtColl = 0;
+  if (m_useTruthInfo) {
+    if ( evtStore()->contains<PRD_MultiTruthCollection>(m_multiTruth) ) {
+      if ( evtStore()->retrieve(m_prdmtColl, m_multiTruth).isFailure() ) {
+	  ATH_MSG_ERROR("ERROR in retrieving PRD MultiTruth collection although available (" << m_multiTruth << ").");
+	  return StatusCode::FAILURE;
+      }
+    } else {
+	if (m_firstEventWarnings) {
+	  ATH_MSG_WARNING("PRD MultiTruth collection not available (" << m_multiTruth << "). Skipping this info although requested.");
+	  m_prdmtColl = 0;
+	}
+    }
+  }
+
+  //This is optional for the algorithm. If not there, just print a one-time warning
+  // On RDO
+  const InDetSimDataCollection* m_sdoCollection = 0;
+  if (m_useTruthInfo && m_writeSDOs) {
+    if ( evtStore()->contains<InDetSimDataCollection>(m_SDOcontainer) ) {
+      if ( evtStore()->retrieve(m_sdoCollection, m_SDOcontainer).isFailure() ) {
+	ATH_MSG_ERROR("ERROR in retrieving SDO container despite being available. Collection = " << m_SDOcontainer);
+	return StatusCode::FAILURE;
+      }
+    } else {
+      if (m_firstEventWarnings) {
+	ATH_MSG_WARNING("SDO Collection not available (" << m_SDOcontainer << "). Skipping this info although requested.");
+	m_sdoCollection = 0;
+      }
+    }
+  }
+
+
+  // Create the xAOD container and its auxiliary store:
+  xAOD::TrackMeasurementValidationContainer* xaod = new xAOD::TrackMeasurementValidationContainer();
+  CHECK( evtStore()->record( xaod, m_driftcirclecontainer ) );
+  xAOD::TrackMeasurementValidationAuxContainer* aux = new xAOD::TrackMeasurementValidationAuxContainer();
+  CHECK( evtStore()->record( aux, m_driftcirclecontainer + "Aux." ) );
+  xaod->setStore( aux );
+  
+  std::vector<unsigned int>* offsets = new std::vector<unsigned int>( m_TRTHelper->straw_layer_hash_max() , 0 );
+  CHECK( evtStore()->record( offsets, m_driftcirclecontainer + "Offsets" ) );
+  
+  InDet::TRT_DriftCircleContainer::const_iterator it = m_trtPrds->begin();
+  InDet::TRT_DriftCircleContainer::const_iterator it_end = m_trtPrds->end();
+  unsigned int counter(0);
+  for( ; it!=it_end; ++it ) {
+
+    //Fill Offset container
+    if( m_TRTHelper->straw_layer_hash_max() <= (*it)->identifyHash() ) 
+      ATH_MSG_ERROR("My assumption about the maximum size of the hash was wrong");
+    (*offsets)[ (*it)->identifyHash() ] = counter;
+
+    // skip empty collections
+    if( (*it)->empty() ) continue;
+    
+    // loop over collection and convert to xAOD
+    for( const auto& prd : **it ){
+      
+      ++counter;
+      
+      // create and add xAOD object
+      xAOD::TrackMeasurementValidation* xprd = new xAOD::TrackMeasurementValidation();
+      xaod->push_back(xprd);
+
+      Identifier surfaceID = prd->identify();
+
+      xprd->setIdentifier(surfaceID.get_compact());
+
+
+      // Save ID info:
+      xprd->auxdata<int>("bec")         =   m_TRTHelper->barrel_ec( surfaceID )     ;
+      xprd->auxdata<int>("layer")       =   m_TRTHelper->layer_or_wheel(surfaceID ) ;  
+      xprd->auxdata<int>("phi_module")  =   m_TRTHelper->phi_module( surfaceID )    ;
+      xprd->auxdata<int>("strawlayer")  =   m_TRTHelper->straw_layer( surfaceID )   ;
+      xprd->auxdata<int>("strawnumber") =   m_TRTHelper->straw( surfaceID )         ;
+      int chip=0;
+      int board=-1;
+      m_neighbourSvc->getChip(surfaceID,chip);
+      if(abs(m_TRTHelper->barrel_ec(surfaceID))<2)  
+        board=m_neighbourSvc->chipToBoardBarrel(chip,m_TRTHelper->layer_or_wheel(surfaceID));
+      else if (chip<12) 
+        board=0;
+      else {
+        chip=chip-20;
+        board=1;
+      }
+      xprd->auxdata<int>("board") =   board ; 
+      xprd->auxdata<int>("chip")  =   chip  ;
+
+      
+      //Set Local Position
+      const Amg::Vector2D& locpos = prd->localPosition();
+      float locY(0.);
+      float locX = locpos.x();
+      if ( !(std::isinf(locpos.y()) || std::isnan(locpos.y())) ){
+        if (locpos.y()>=1e-07)
+          locY=locpos.y();
+      } else { 
+        locY = -9999.;
+      }
+
+      // Set local error matrix
+      xprd->setLocalPosition(locX,locY); 
+      
+      const Amg::MatrixX& localCov = prd->localCovariance();
+      if(localCov.size() == 1){
+        xprd->setLocalPositionError( localCov(0,0), 0., 0. ); 
+      } else if(localCov.size() == 2){
+        xprd->setLocalPositionError( localCov(0,0), localCov(1,1), localCov(0,1) );     
+      } else {
+        xprd->setLocalPositionError(0.,0.,0.);
+      }
+   
+            
+      //Set Global position
+      const Amg::Vector3D* gpos = prd->detectorElement()->surface(surfaceID).localToGlobal(prd->localPosition());
+      if(gpos){
+        xprd->setGlobalPosition(gpos->x(),gpos->y(),gpos->z());
+        delete gpos;
+      }
+
+
+      //TRT hit bit word
+      unsigned int word = prd->getWord();
+
+      //TRTCond::RtRelation const *rtr = m_trtcaldbSvc->getRtRelation(surfaceID);
+      double tot = prd->timeOverThreshold();
+      bool isvalid=false;
+      xprd->auxdata<float>("drifttime")  = prd->driftTime(isvalid)   ;
+      xprd->auxdata<int>("status")      = isvalid;
+      xprd->auxdata<float>("tot")        = tot ;
+      xprd->auxdata<char>("isHT")        = prd->highLevel()    ;
+      xprd->auxdata<float>("T0")         = m_trtcaldbSvc->getT0(surfaceID)   ; 
+
+
+      // Save time info:
+      xprd->auxdata<float>("leadingEdge")  = prd->rawDriftTime();
+
+      //Drift Time corrections
+      xprd->auxdata<float>("driftTimeToTCorrection") = m_driftFunctionTool->driftTimeToTCorrection(tot,surfaceID);
+      if(prd->highLevel()) 
+        xprd->auxdata<float>("driftTimeHTCorrection") = m_driftFunctionTool->driftTimeHTCorrection(surfaceID);
+      else 
+        xprd->auxdata<float>("driftTimeHTCorrection") = 0;
+      
+      
+      //HT Bit patterens
+      unsigned int theWord = word & 0x04020100; //HT bits mask
+      char highThreshold = 0;
+      //this is the agreed-upon binning for HT bit patterns...
+      if (theWord == 0x04000000) //pattern 1
+        highThreshold = 1;
+      else if (theWord == 0x00020000) //pattern 2
+        highThreshold = 2;
+      else if (theWord == 0x00000100) //pattern 3
+        highThreshold = 3;
+      else if (theWord == 0x04020000) //pattern 4
+        highThreshold = 4;
+      else if (theWord == 0x00020100) //pattern 5
+        highThreshold = 5;
+      else if (theWord == 0x04000100) //pattern 6
+        highThreshold = 6;
+      else if (theWord == 0x04020100) //pattern 7
+        highThreshold = 7;
+      
+      xprd->auxdata<char>("highThreshold") = highThreshold;
+      
+      //Full bit patternword from the TRT
+      xprd->auxdata<unsigned int>("bitPattern") = word;
+      
+      char isArgonStraw = 0;
+      if (!m_TRTStrawSummarySvc.empty()) {
+        if (m_TRTStrawSummarySvc->getStatusHT(surfaceID) != TRTCond::StrawStatus::Good) {
+          isArgonStraw = 1;
+        }
+      }
+      xprd->auxdata<char>("isArgon")              = isArgonStraw            ;
+
+
+      // Use the MultiTruth Collection to get a list of all true particle contributing to the DC
+      if(m_prdmtColl){
+        std::vector<int> barcodes;
+        auto range = m_prdmtColl->equal_range(surfaceID);
+        for (auto i = range.first; i != range.second; ++i) {
+          barcodes.push_back( i->second.barcode() );
+        }
+        xprd->auxdata< std::vector<int> >("truth_barcode") = barcodes;
+      }
+
+      if( m_sdoCollection ){
+        // find hit
+        auto pos = m_sdoCollection->find(surfaceID);
+        int sdo_word = -1000000;
+        if( pos != m_sdoCollection->end() ) {
+          sdo_word = pos->second.word();
+        }           
+        xprd->auxdata<int>("sdo_word")      = sdo_word;
+      }
+
+    }
+  }
+  ATH_MSG_DEBUG( " recorded TRT_PrepData obejcts: size " << xaod->size() );
+
+
+
+  // Code to test that something was added to SG:
+  StatusCode sc = StatusCode::SUCCESS;
+  if (msgLvl(MSG::DEBUG)){
+    const xAOD::TrackMeasurementValidationContainer* xaod2;
+    sc = evtStore()->retrieve(xaod2, m_driftcirclecontainer);
+    if (sc.isFailure()) {
+      ATH_MSG_DEBUG("Failed to retrieve " << m_driftcirclecontainer);
+    }
+    else   ATH_MSG_DEBUG("xAOD info retreived " << m_driftcirclecontainer << "\t" << xaod2->size());
+ 
+    const xAOD::TrackMeasurementValidationAuxContainer* aux2;
+    sc = evtStore()->retrieve(aux2, (m_driftcirclecontainer+ "Aux.")); 
+    if (sc.isFailure()) {
+      ATH_MSG_DEBUG("Failed to retrieve " << m_driftcirclecontainer<< "Aux.");
+    }
+    else   ATH_MSG_DEBUG("xAOD info retrieved " << m_driftcirclecontainer << "Aux. \t");
+  }
+
+  // --- end of event. Disable one-time warnings
+  m_firstEventWarnings = false;
+ 
+  return sc; 
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+//        Finalize method: 
+//
+/////////////////////////////////////////////////////////////////////
+StatusCode TRT_PrepDataToxAOD::finalize()
+{
+  return StatusCode::SUCCESS;
+}
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/TRT_PrepDataToxAOD.h b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/TRT_PrepDataToxAOD.h
new file mode 100644
index 00000000000..8a3fd43579b
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/TRT_PrepDataToxAOD.h
@@ -0,0 +1,66 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// TRT_PrepDataToxAOD.h
+//   Header file for class TRT_PrepDataToxAOD
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRT_PREPDATATOXAOD_H
+#define TRT_PREPDATATOXAOD_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#include "TRT_ConditionsServices/ITRT_StrawNeighbourSvc.h"
+#include "TRT_ConditionsServices/ITRT_CalDbSvc.h"
+#include "TRT_ConditionsServices/ITRT_StrawStatusSummarySvc.h"
+#include "TRT_DriftFunctionTool/ITRT_DriftFunctionTool.h"
+
+
+#include <string>
+
+class TRT_ID;
+class ITRT_CalDbSvc ;
+class ITRT_DriftFunctionTool;
+class ITRT_StrawSummarySvc;
+
+
+class TRT_PrepDataToxAOD : public AthAlgorithm  {
+
+public:
+  // Constructor with parameters:
+  TRT_PrepDataToxAOD(const std::string &name,ISvcLocator *pSvcLocator);
+
+  // Basic algorithm methods:
+  virtual StatusCode initialize(); 
+  virtual StatusCode execute();
+  virtual StatusCode finalize();
+
+private:
+
+  // --- Steering and configuration flags
+  bool m_useTruthInfo;
+  bool m_writeSDOs;
+
+  // --- Configuration keys
+  std::string  m_driftcirclecontainer;
+  std::string  m_SDOcontainer;
+  std::string  m_multiTruth;
+
+  // --- Services and Tools
+  ToolHandle< ITRT_DriftFunctionTool >      m_driftFunctionTool ; //!< DriftFunctionTool
+  ServiceHandle<ITRT_CalDbSvc>              m_trtcaldbSvc       ;
+  ServiceHandle<ITRT_StrawNeighbourSvc>     m_neighbourSvc      ;
+  ServiceHandle<ITRT_StrawStatusSummarySvc> m_TRTStrawSummarySvc; 
+  const TRT_ID *m_TRTHelper;
+
+  // ---- Internal members
+  bool m_firstEventWarnings;
+
+};
+
+
+#endif 
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/components/InDetPrepRawDataToxAOD_entries.cxx b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/components/InDetPrepRawDataToxAOD_entries.cxx
new file mode 100755
index 00000000000..5313b9af720
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/components/InDetPrepRawDataToxAOD_entries.cxx
@@ -0,0 +1,18 @@
+#include "GaudiKernel/DeclareFactoryEntries.h"
+#include "../TRT_PrepDataToxAOD.h"
+#include "../SCT_PrepDataToxAOD.h"
+#include "../PixelPrepDataToxAOD.h"
+
+
+//using namespace InDet;
+
+DECLARE_ALGORITHM_FACTORY( TRT_PrepDataToxAOD )
+DECLARE_ALGORITHM_FACTORY( SCT_PrepDataToxAOD )
+DECLARE_ALGORITHM_FACTORY( PixelPrepDataToxAOD )
+
+DECLARE_FACTORY_ENTRIES( InDetPrepRawDataToxAOD ) 
+{
+  DECLARE_ALGORITHM( TRT_PrepDataToxAOD )
+  DECLARE_ALGORITHM( SCT_PrepDataToxAOD )
+  DECLARE_ALGORITHM( PixelPrepDataToxAOD )
+}
diff --git a/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/components/InDetPrepRawDataToxAOD_load.cxx b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/components/InDetPrepRawDataToxAOD_load.cxx
new file mode 100755
index 00000000000..249ab411bec
--- /dev/null
+++ b/InnerDetector/InDetEventCnv/InDetPrepRawDataToxAOD/src/components/InDetPrepRawDataToxAOD_load.cxx
@@ -0,0 +1,4 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES( InDetPrepRawDataToxAOD )
+
-- 
GitLab