diff --git a/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/DBObjectBuilder.h b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/DBObjectBuilder.h
new file mode 100644
index 0000000000000000000000000000000000000000..2be342dc98e0b6e59732f6dd2d9af22a667217c9
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/DBObjectBuilder.h
@@ -0,0 +1,164 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file   DBObjectBuilder.h
+ * @author Grzegorz Gach <grzegorz.gach@cern.ch>
+ * @date   2018-01-16
+ * 
+ * @brief  Header file for base class for database objects builders
+ * 
+ */
+
+#ifndef AFP_DBTOOLS_DBOBJECTBUILDER_H
+#define AFP_DBTOOLS_DBOBJECTBUILDER_H
+
+#include "DBObjectBuilderBase.h"
+
+#include <boost/property_tree/ptree.hpp>
+
+#include <vector>
+#include <string>
+#include <list>
+
+namespace AFP
+{
+
+  /// @brief Base class for builders producing objects based on database information.
+  ///
+  /// Classes building database objects should derive from this
+  /// template. It should be enough to override only
+  /// DBObjectBuilderBase::addBuilderCommand function.
+  template<typename OUTPUT_TYPE>
+  class DBObjectBuilder : public DBObjectBuilderBase
+  {
+  public:
+    /// Deletes #m_inputData
+    virtual ~DBObjectBuilder () {for (CommandBase* comm : m_commands) delete comm;}
+
+    /// The method sets value of the given field of #m_object.
+    ///
+    /// @param field pointer to class member field which value is to be set
+    /// @param value value to be assigned to the field
+    template <typename VALUE_TYPE>
+    void setFieldValue (VALUE_TYPE OUTPUT_TYPE::* const field, const VALUE_TYPE value)
+    {if (field) m_object->*field = value;}
+
+    /// @brief Method creating a database object based on passed input data.
+    ///
+    /// The method creates a new output database object and fills with
+    /// data from the input argument.
+    OUTPUT_TYPE build (const boost::property_tree::ptree::value_type& inputData);
+
+    /// @copydoc DBObjectbuilder::generateBuilderCommands
+    std::string generateBuilderCommands () override final;
+
+    /// @brief This method adds new command objects to the list depending on argument
+    ///
+    /// This is the only method that needs to be overridden when
+    /// creating a new builder.
+    ///
+    /// @param name name of the element in database
+    ///
+    /// @return true if name was recognised, false if not
+    virtual bool addBuilderCommand (const std::string& name) = 0;
+
+  protected:
+    // --------------- NESTED CLASSES ---------------
+    /// Nested class base for storing commands for building objects
+    class CommandBase
+    {
+    public:
+      /// Does nothing
+      virtual ~CommandBase() {}
+
+      /// Execute method which calls proper method of the DBObjectBuilder in order to create output object.
+      virtual void executeSetFieldValue (const boost::property_tree::ptree::value_type& inputData, DBObjectBuilder<OUTPUT_TYPE>* parentObject) const = 0;
+    };
+
+    /// Template of nested command class that calls the method setting the object value with proper type.
+    template <typename VALUE_TYPE>
+    class Command : public CommandBase
+    {
+    public:
+      /// Sets pointer to the output object field to be set
+      Command (VALUE_TYPE OUTPUT_TYPE::*field) : m_field (field) {}
+
+      /// Does nothing
+      virtual ~Command() {}
+
+      /// @copydoc CommandBase::executeSetfieldvalue
+      void executeSetFieldValue (const boost::property_tree::ptree::value_type& inputData, DBObjectBuilder<OUTPUT_TYPE>* parentObject) const override
+      {parentObject->setFieldValue<VALUE_TYPE>(m_field, inputData.second.get_value<VALUE_TYPE>());}
+
+    protected:
+      /// Pointer to class member to be set by this command.
+      VALUE_TYPE OUTPUT_TYPE::*m_field;
+    };
+    // --------------- END NESTED CLASSES ---------------
+
+    /// List of commands used for creating an object. The order is important.
+    std::list<CommandBase*> m_commands;
+
+    /// Pointer to the conditions object that is being set. Used by the DBObjectBuilder::build method.
+    OUTPUT_TYPE* m_object;
+
+  };				// end of DBObjectBuilder class declaration
+
+
+  // ==============================================
+  // =============== IMPLEMENTATION ===============
+  // ==============================================
+
+  template<typename OUTPUT_TYPE>
+  std::string DBObjectBuilder<OUTPUT_TYPE>::generateBuilderCommands ()
+  {
+    // clear list of commnads
+    for (CommandBase* comm : this->m_commands)
+      delete comm;
+    this->m_commands.clear();
+
+
+    // fill list with commands
+    std::stringstream unknownVariables;
+    for (const std::vector<std::string>& element : this->m_specification)
+      if (addBuilderCommand(element[0]) == false)
+	unknownVariables<<element[0]<<", ";
+
+    std::stringstream warningMessage;
+    // if list of unknown variables is not empty generate warning message
+    if (!unknownVariables.str().empty())
+      warningMessage <<"DBObjectBuilder will skip following variables present in database: "<<unknownVariables.str();
+
+    return warningMessage.str();
+  }
+
+
+  template<typename OUTPUT_TYPE>
+  OUTPUT_TYPE DBObjectBuilder<OUTPUT_TYPE>::build (const boost::property_tree::ptree::value_type& inputData)
+  {
+    OUTPUT_TYPE output;
+    m_object = &output;
+    typedef std::list<DBObjectBuilder<OUTPUT_TYPE>::CommandBase*> CommandsList_t;
+
+    typename CommandsList_t::const_iterator commandIter = m_commands.begin();
+    const typename CommandsList_t::const_iterator commandIterEnd = m_commands.end();
+    for (const boost::property_tree::ptree::value_type& data : inputData.second) {
+      if (commandIterEnd != commandIter) {
+	DBObjectBuilder<OUTPUT_TYPE>::CommandBase* comm = *commandIter;
+	++commandIter;
+	
+	comm->executeSetFieldValue(data, this);
+      }
+    }
+
+    m_object = nullptr;
+
+    return output;
+  }
+
+
+} // namespace AFP
+
+#endif	//  AFP_DBTOOLS_DBOBJECTBUILDER_H
diff --git a/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/DBObjectBuilderBase.h b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/DBObjectBuilderBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..df9c68a4678440cf7974d2711b9c9191265b4383
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/DBObjectBuilderBase.h
@@ -0,0 +1,91 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file   DBObjectBuilderBase.h
+ * @author Grzegorz Gach <grzegorz.gach@cern.ch>
+ * @date   2018-01-19
+ * 
+ * @brief  Header file for DBObjectBuilderBase class
+ * 
+ */
+
+#include<string>
+#include<vector>
+
+namespace AFP
+{
+
+  /// @brief Class parsing conditions database specification
+  ///
+  /// This class contains DBObjectBuilder methods which do not need
+  /// templates.
+  class DBObjectBuilderBase
+  {
+  public:
+    /// Does nothing
+    virtual ~DBObjectBuilderBase() {}
+
+    /// @brief Parses specification string from database and prepare
+    /// list of builder methods.
+    ///
+    /// @param specification a string with specification format is
+    /// described in:
+    /// https://twiki.cern.ch/twiki/bin/view/AtlasComputing/JsonFormatForCrest
+    ///
+    /// @return string with warning message - should be used to report
+    /// not recognised variables names in the database (the message is
+    /// returned instead of being printed because this is not Athena
+    /// algorithm)
+    std::string setSpecification (const std::string specification);
+    
+    /// @brief Creates a list of Command objects to be called when
+    /// reading database record.
+    ///
+    /// This method generates a list of builder command objects
+    /// DBObjectBuilder::m_commands that will construct output object
+    /// in the same order as information in the database is
+    /// saved. When object is being build the input data and list of
+    /// commands are iterated simultaneously and input data element is
+    /// passed as an argument to the corresponding command from the
+    /// list.
+    ///
+    /// The list of commands is generated based on #m_specification.
+    ///
+    /// @note For each field in the database there should be a
+    /// corresponding command object. If the database field is not
+    /// processed a command object with nullptr should be created.
+    ///
+    /// @return string with warning message - should be used to report
+    /// not recognised variables names in the database (the message is
+    /// returned instead of being printed because this is not Athena
+    /// algorithm)
+    virtual std::string generateBuilderCommands () = 0;
+
+  protected:
+    /// Calls DBObjectBuilderBase::trimSpaces (std::string) for each string in the vector
+    void trimSpaces (std::vector<std::string>& toTrim) const;
+
+    /// Removes spaces from the beginning and end of the string
+    void trimSpaces (std::string& toTrim) const;
+
+    /// @brief Parses payload specification string and saves output to vector
+    ///
+
+    /// Payload specification stream format is described in:
+    /// https://twiki.cern.ch/twiki/bin/view/AtlasComputing/JsonFormatForCrest
+    /// The function splits the string into pairs name-type and saves
+    /// them as a vector of strings with two elements. All pairs are
+    /// added to a global output vector.
+    void parsePayloadSpec (const std::string& input, std::vector< std::vector<std::string> >& output) const;
+
+    /// @brief vector describing format of the data saved in the database
+    ///
+    /// A vector of vectors. Each subvector contains exactly two
+    /// elements: name and type. The elements are in the same order as
+    /// data.
+    std::vector< std::vector<std::string> > m_specification;
+  };
+
+} // AFP namespace 
diff --git a/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/ISiLocAlignDBTool.h b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/ISiLocAlignDBTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..94f450024928cb47ee6341bdce99f1067bb2d6d3
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/ISiLocAlignDBTool.h
@@ -0,0 +1,72 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/// @file   ISiLocAlignDBTool.h
+/// @author Grzegorz Gach <gach@agh.edu.pl>
+/// @date   2017-12-03
+/// 
+/// @brief  Header file for interface of SiLocAlignDBTool used to read local alignment for database
+#ifndef AFP_DBTOOLS_ISILOCALIGNDBTOOL_H
+#define AFP_DBTOOLS_ISILOCALIGNDBTOOL_H
+
+
+// FrameWork includes
+#include "GaudiKernel/IAlgTool.h"
+
+// database access
+#include "AthenaKernel/IOVSvcDefs.h"
+
+// general includes
+#include <vector>
+#include <memory>
+
+namespace AFP
+{
+  // forward declarations
+  class SiLocAlignData;
+
+  static const InterfaceID IID_ISiLocAlignDBTool ("ISiLocAlignDBTool", 1, 0);
+
+  
+  /// Interface to tool providing local alignment of silicon detectors from the conditions database.
+  class ISiLocAlignDBTool : virtual public IAlgTool
+  {
+  public:
+    static const InterfaceID &interfaceID()
+    {return IID_ISiLocAlignDBTool;}
+
+    /// Does nothing
+    virtual ~ISiLocAlignDBTool() override {}
+
+    /// Initilise tool
+    virtual StatusCode initialize() = 0;
+
+    /// Finalise tool
+    virtual StatusCode finalize() = 0;
+
+    /// Provide alignment parameters for a given plane. Returns nullptr if no data available.
+    virtual const SiLocAlignData* alignment (const int stationID, const int planeID) const = 0;
+
+    /// Returns reference to a vector of alignments for a given station.
+    ///
+    /// It is enough to get this reference only once, because the
+    /// vector is a member of the class. Whenever new conditions are
+    /// loaded the values in the vector will be updated.
+    ///
+    /// @warning if in database there was no data about the given
+    /// layer a nullptr will be stored in the vector.
+    virtual const std::vector<std::unique_ptr<const SiLocAlignData> >& alignment (const int stationID) const = 0;
+
+
+  protected:
+    /// @brief Method called when new conditions are loaded
+    ///
+    /// The method copies information from #m_conditionsData to 
+    virtual StatusCode update (IOVSVC_CALLBACK_ARGS) = 0;
+  };
+
+
+}      // namespace AFP
+
+#endif // > ! AFP_DBTOOLS_SILOCALIGNDBTOOL_H
diff --git a/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignDBTool.h b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignDBTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..154d4c84e0c5d22d21d59260cce01f6807ed872e
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignDBTool.h
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/// @file   SiLocAlignDBTool.h
+/// @author Grzegorz Gach <gach@agh.edu.pl>
+/// @date   2017-12-03
+/// 
+/// @brief  Header file for SiLocAlignDBTool used to read local alignment for database
+#ifndef AFP_DBTOOLS_SILOCALIGNDBTOOL_H
+#define AFP_DBTOOLS_SILOCALIGNDBTOOL_H
+
+// Local includes
+#include "AFP_DBTools/ISiLocAlignDBTool.h"
+#include "AFP_DBTools/SiLocAlignData.h"
+
+// FrameWork includes
+#include "AthenaBaseComps/AthAlgTool.h"
+
+// database access
+#include "AthenaKernel/IOVSvcDefs.h"
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+#include "AthenaPoolUtilities/AthenaAttributeList.h"
+// general includes
+#include <cassert>
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace AFP
+{
+  /// Tool providing local alignment of silicon detectors from the conditions database.
+  class SiLocAlignDBTool : virtual public AFP::ISiLocAlignDBTool, 
+			   public AthAlgTool
+  {
+  public:
+    SiLocAlignDBTool(const std::string& type,
+		     const std::string& name,
+		     const IInterface* parent);
+
+    /// Does nothing
+    virtual ~SiLocAlignDBTool() override {}
+
+    /// Register method SiLocAlignDBTool::update() to be called when conditions change
+    virtual StatusCode initialize() override;
+
+    /// Does nothing
+    virtual StatusCode finalize() override {return StatusCode::SUCCESS;}
+
+    /// Provide alignment parameters for a given plane. Returns nullptr if no data available.
+    const SiLocAlignData* alignment (const int stationID, const int planeID) const override;
+    
+    /// Returns reference to a vector of alignments for a given station.
+    ///
+    /// It is enough to get this reference only once, because the
+    /// vector is a member of the class. Whenever new conditions are
+    /// loaded the values in the vector will be updated.
+    ///
+    /// @warning if in database there was no data about the given
+    /// layer a nullptr will be stored in the vector.
+    const std::vector<std::unique_ptr<const SiLocAlignData> >& alignment (const int stationID) const override
+    {assert (stationID < s_numberOfStations); return m_alignments.at(stationID);}
+
+
+  private:
+    /// @brief Method called when new conditions are loaded
+    ///
+    /// The method copies information from #m_conditionsData to 
+    StatusCode update (IOVSVC_CALLBACK_ARGS) override;
+
+    /// @brief Resizes #m_alignments to size of maxLayers and sets size of layers for each station
+    ///
+    /// @warning The method first deletes existing alignments by
+    /// calling SiLocAlignDBTool::clearAlignments(). This is done in
+    /// order to prevent memory leaks originating from shrinking
+    /// #m_alignments
+    ///
+    /// @param maxLayers vector with numbers of layers in each station
+    void resizeAlignments (const std::vector<int>& maxLayers);
+
+    /// Attributes list storing bare information from the database
+    const DataHandle<AthenaAttributeList> m_conditionsData;
+
+    /// @brief Information about alignments represented with SiLocAlignData objects
+    ///
+    /// Main variable storing information about alignment. The index
+    /// of the first vector represents stationID number. The index of
+    /// the second vector represents plane number in the station. If
+    /// there is no information about plane a nullptr is stored.
+    std::vector<std::vector<std::unique_ptr<const SiLocAlignData> > > m_alignments;
+
+    /// Name of the database folder with alignment information
+    std::string m_folderName;
+
+    /// Number of AFP stations for which the tool should work
+    static const int s_numberOfStations;
+  };
+
+
+}      // namespace AFP
+
+#endif // > ! AFP_DBTOOLS_SILOCALIGNDBTOOL_H
diff --git a/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignData.h b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignData.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a73647986c5ec8ae796d435c752fd4afea8acbe
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignData.h
@@ -0,0 +1,65 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file   SiLocAlignData.h
+ * @author Grzegorz Gach <grzegorz.gach@cern.ch>
+ * @date   2018-01-17
+ * 
+ * @brief  Header file for class SiLocAlignData.
+ * 
+ */
+
+
+#ifndef AFP_DBTOOLS_SILOCALIGNDATA_H
+#define AFP_DBTOOLS_SILOCALIGNDATA_H
+
+
+namespace AFP
+{
+
+  /// Class storing information about alignment.
+  class SiLocAlignData 
+  {
+    /// allow only builder to change object values
+    friend class SiLocAlignDataBuilder;
+  public:
+    /// ID of the station to which aligment applies (see xAOD::AFPStationID)
+    int stationID () const {return m_stationID;}
+
+    /// ID of the layer in station to which aligment applies (see xAOD::AFPPixelLayerID)
+    int layerID () const {return m_layerID;}
+
+    /// Shift of the plane in X direction with respect to the nominal position
+    double xShift () const {return m_xShift;}
+
+    /// Shift of the plane in Y direction with respect to the nominal position
+    double yShift () const {return m_yShift;}
+
+    /// Shift of the plane in Z direction with respect to the nominal position
+    double zShift () const {return m_zShift;}
+
+    /// Rotation angle
+    double alpha () const {return m_alpha;}
+
+    /// Rotation angle
+    double beta () const {return m_beta;}
+
+    /// Rotation angle
+    double gamma () const {return m_gamma;}
+
+  private:
+    int m_stationID;
+    int m_layerID;
+    double m_xShift;
+    double m_yShift;
+    double m_zShift;
+    double m_alpha;
+    double m_beta;
+    double m_gamma;
+  };
+
+} // namespace AFP
+
+#endif	//  AFP_DBTOOLS_SILOCALIGNDATA_H
diff --git a/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignDataBuilder.h b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignDataBuilder.h
new file mode 100644
index 0000000000000000000000000000000000000000..6655ec59da4ca0148b6e1dc92fcad7ce32ff6ec4
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/AFP_DBTools/SiLocAlignDataBuilder.h
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file   SiLocAlignDataBuilder.h
+ * @author Grzegorz Gach <grzegorz.gach@cern.ch>
+ * @date   2018-01-17
+ * 
+ * @brief  Header file for class SiLocAlignDataBuilder.
+ * 
+ */
+
+#ifndef AFP_DBTOOLS_SILOCALIGNDATABUILDER_H
+#define AFP_DBTOOLS_SILOCALIGNDATABUILDER_H
+
+#include"DBObjectBuilder.h"
+#include"SiLocAlignData.h"
+
+#include<string>
+
+namespace AFP
+{
+  /// Class for building tracking detectors local alignment info from conditions database
+  class SiLocAlignDataBuilder : public DBObjectBuilder<SiLocAlignData>
+  {
+  public:
+
+    /// @copydoc DBObjectBuilder::addBuilderCommand
+    virtual bool addBuilderCommand (const std::string& name) override;
+  };
+
+} // namespace AFP
+
+#endif	//  AFP_DBTOOLS_SILOCALIGNDATABUILDER_H
diff --git a/ForwardDetectors/AFP/AFP_DBTools/CMakeLists.txt b/ForwardDetectors/AFP/AFP_DBTools/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..11c39fe296fbfe1cc1927f863a6589b7627db549
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/CMakeLists.txt
@@ -0,0 +1,27 @@
+################################################################################
+# Package: AFP_DBTools
+################################################################################
+
+# Declare the package name:
+atlas_subdir( AFP_DBTools )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          Control/AthenaBaseComps
+                          Control/AthenaKernel
+                          Control/StoreGate
+                          Database/AthenaPOOL/AthenaPoolUtilities
+                          GaudiKernel)
+
+# External dependencies:
+find_package( Boost )
+
+# Component(s) in the package:
+atlas_add_component( AFP_DBTools
+                     src/*.cxx
+                     src/components/*.cxx
+                     LINK_LIBRARIES AthenaBaseComps AthenaKernel StoreGateLib SGtests AthenaPoolUtilities GaudiKernel ${Boost_LIBRARIES})
+
+# Install files from the package:
+atlas_install_headers( AFP_DBTools )
+atlas_install_python_modules( python/*.py )
\ No newline at end of file
diff --git a/ForwardDetectors/AFP/AFP_DBTools/python/AFPDBBase.py b/ForwardDetectors/AFP/AFP_DBTools/python/AFPDBBase.py
new file mode 100644
index 0000000000000000000000000000000000000000..bb48e8bd6f1d8c9e619f5627b15b747b2fd80af3
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/python/AFPDBBase.py
@@ -0,0 +1,109 @@
+#!/bin/env python
+
+from PyCool import cool
+
+class AFPDBRecordBase(object):
+    def serialiseValues (self):
+        output = "["
+        for quantity in dir(self):        # loop over all elements in class
+            if not callable(getattr(self, quantity)) and not quantity.startswith("__"): # select only user variables 
+                # print "Moj " + quantity + " wynosi: " +  str(getattr(self, quantity))
+                output += str(getattr(self, quantity)) + ", "
+
+        output = output[:-2] # remove the last comma and space ", "
+        output += "]"        # close bracket
+
+        return output
+
+    def serialiseTypes (self):
+        output = '"folder_payloadspec": "'
+        for quantity in dir(self):        # loop over all elements in class
+            if not callable(getattr(self, quantity)) and not quantity.startswith('__'): # select only user variables 
+                output += quantity + ': ' + self.translateType(type(getattr(self, quantity))) + ', ' # append variable name and type
+
+        output = output[:-2] # remove the last comma and space ", "
+        output += '"'        # close parenthisis
+
+        return output
+
+    def translateType (self, typeName):
+        if (typeName == int):
+            return "Int32"
+        elif (typeName == float):
+            return "Float"
+        else:
+            raise ValueError ("Unknown type of field. Need to update method translateType")
+
+
+class AFPDBTableBase (object):
+    def __init__ (self):
+        self.records = []
+        self.iovStartRun = 0
+        self.iovStartLumiBlock = 0
+        self.iovEndRun = 0
+        self.iovEndLumiBlock = 0
+
+        self.tag = "AFPTest-00-00-00"
+        self.folderName = "/FWD/AFP/TEST"
+        self.spec = cool.RecordSpecification()
+#        self.spec.extend("data", cool.StorageType.Blob64k)
+        self.spec.extend("data", cool.StorageType.String16M)
+#        self.desc = '<timeStamp>run-lumi</timeStamp><addrHeader><address_header service_type="71" clid="1238547719" /></addrHeader><typeName>CondAttrListCollection</typeName>'
+        self.desc = '<timeStamp>run-lumi</timeStamp><addrHeader><address_header service_type="71" clid="40774348" /></addrHeader><typeName>AthenaAttributeList</typeName>'
+        self.data = cool.Record(self.spec)
+        self.folderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, self.spec)
+
+
+
+    def serialiseHeader (self):
+        output = '"node_description": '
+#        output += '"<timeStamp>run-lumi</timeStamp><addrHeader><address_header service_type="71" clid="1238547719" /></addrHeader<typeName>CondAttrListCollection</typeName>"'
+        output += '"<timeStamp>run-lumi</timeStamp><addrHeader><address_header service_type=\\"71\\" clid=\\"40774348\\" /></addrHeader><typeName>AthenaAttributeList</typeName> "'
+        
+        return output
+
+    def serialiseRecords (self):
+        output = '"data_array": ['
+        if (len(self.records) > 0):
+            channelID = 1
+
+            for entry in self.records:
+                output += '{'
+                output += '"' + str(channelID) + '" : '
+                output += entry.serialiseValues()
+                output += '}, '
+                channelID += 1
+
+            # remove the last comma and space ", "
+            output = output[:-2] 
+            # close bracket
+            output += ']'
+
+        return output
+            
+    def serialiseTable (self):
+        if (len(self.records) < 1):
+            raise ValueError ("Empty records list. Please, fill records before serialising table.")
+
+        output = '{'
+        output += self.serialiseHeader() + ', '
+        output += self.records[0].serialiseTypes() + ', '
+        output += self.serialiseRecords()
+        output += '}'
+        
+        return output
+
+    def saveToDB (self):
+        self.data['data'] = self.serialiseTable()
+        iovStart=(self.iovStartRun<<32) + self.iovStartLumiBlock;
+        print "before self.iovEndRun=" + str(self.iovEndRun)
+        iovEnd=(self.iovEndRun<<32) + self.iovEndLumiBlock;
+        print "after self.iovEndRun=" + str(self.iovEndRun)
+        
+        self.folder.storeObject(iovStart, iovEnd, self.data, 0, self.tag)
+
+    def createFolder (self, db):
+        print self.folderSpec
+        self.folder = db.createFolder(self.folderName, self.folderSpec, self.desc, True)
+
+
diff --git a/ForwardDetectors/AFP/AFP_DBTools/scripts/AFPLocalAlignDBCreate.py b/ForwardDetectors/AFP/AFP_DBTools/scripts/AFPLocalAlignDBCreate.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a966985b02b25ed56101c664d772b25e25b9392
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/scripts/AFPLocalAlignDBCreate.py
@@ -0,0 +1,108 @@
+#!/bin/env python
+
+# Taken from InnerDetector/InDetRecTools/TRT_ElectronPidTools/DatabaseTools/WritePyCoolAll.py
+
+import json
+import sys
+
+from AFP_DBTools.AFPDBBase import AFPDBRecordBase, AFPDBTableBase
+
+from PyCool import cool
+
+class AFPLocalAlignRecord(AFPDBRecordBase):
+    def __init__ (self):
+        self.reset()
+
+    def reset (self):
+        self.stationID=-1
+        self.layerID=-1
+        
+        self.shiftX=0.1
+        self.shiftY=0.4
+        self.shiftZ=0.6
+
+        self.alpha=0.
+        self.beta=0.
+        self.gamma=0.
+        
+class AFPLocalAlignRecordHandler:
+    def __init__ (self):
+        self.reset()
+
+    def reset (self):
+        self.iovSet=False
+        self.anglesSet=False
+        self.shiftSet=False
+        self.idSet=False        # true if stationID and laeryID were set
+
+        self.record = AFPLocalAlignRecord()
+        
+
+
+class AFPLocalAlignmentFiller (AFPDBTableBase):
+    """A class that creates a conditions database with AFP internal alignment."""
+
+    def __init__ (self):
+        super(AFPLocalAlignmentFiller, self).__init__()
+
+        self.folderName="/FWD/AFP/LocalAlignment/SiliconPlanes"
+        self.tag="TestTag-00"
+
+def main():
+    dbFile = "Example.db"
+    dbName = "CONDBR2" 
+    
+    # remove the old db file so that we can write the new one
+    try:
+        import os
+        os.remove(dbFile)
+    except:
+        pass
+
+    # get database service and open database
+    dbSvc = cool.DatabaseSvcFactory.databaseService()
+
+    # database accessed via physical name
+    dbString = "sqlite://;schema=%s;dbname=%s" % (dbFile, dbName)
+    try:
+        db = dbSvc.createDatabase(dbString)
+    except Exception, e:
+        print 'Problem creating database', e
+        sys.exit(-1)
+    print "Created database", dbString
+    
+    filler = AFPLocalAlignmentFiller()
+    for statID in range (0, 4):
+        for layID in range (0, 4):
+            rec = AFPLocalAlignRecord()
+            rec.stationID = statID
+            rec.layerID = layID
+            fstatID = float(statID)
+            flayID = float(layID)
+            rec.shiftX = fstatID + (flayID/10)
+            rec.shiftY = -fstatID - (flayID/10)
+            rec.shiftZ = +fstatID - (flayID/10)
+            rec.alpha = -fstatID + (flayID/10)
+
+            filler.records.append(rec);
+    
+    print filler.serialiseTable()
+
+    filler.iovStartRun = 305359
+    filler.iovStartLumiBlock = 0
+
+    filler.iovEndRun = 305360
+    filler.iovEndLumiBlock = 0
+
+    filler.folderName = "/FWD/AFP/LocalAlignment/SiliconPlanes"
+    filler.createFolder(db)
+
+    filler.saveToDB()
+    
+
+    print "\nClose database"
+    db.closeDatabase()
+
+
+if __name__=="__main__":
+    main()
diff --git a/ForwardDetectors/AFP/AFP_DBTools/src/DBObjectBuilderBase.cxx b/ForwardDetectors/AFP/AFP_DBTools/src/DBObjectBuilderBase.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4b54a3e5284f1670d48ec28d6bc7738ae0670eab
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/src/DBObjectBuilderBase.cxx
@@ -0,0 +1,80 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file   DBObjectBuilderBase.cxx
+ * @author Grzegorz Gach <grzegorz.gach@cern.ch>
+ * @date   2018-01-19
+ * 
+ * @brief  Implementation file for DBObjectBuilderBase
+ * 
+ */
+
+#include "../AFP_DBTools/DBObjectBuilderBase.h"
+#include <sstream>
+#include <list>
+
+namespace AFP
+{
+
+  std::string DBObjectBuilderBase::setSpecification (const std::string specification) 
+  {
+    parsePayloadSpec(specification, m_specification);
+    return generateBuilderCommands();
+  }
+
+  void DBObjectBuilderBase::trimSpaces (std::vector<std::string>& toTrim) const
+  {
+    for (std::string& element : toTrim)
+      trimSpaces (element);
+  }
+
+  void DBObjectBuilderBase::trimSpaces (std::string& toTrim) const
+  {
+    const size_t first = toTrim.find_first_not_of(' ');
+    if (std::string::npos == first) {
+      toTrim = "";
+    }
+    else {
+      const size_t last = toTrim.find_last_not_of(' ');
+      toTrim = toTrim.substr(first, (last - first + 1));
+    }
+  }
+  
+  void DBObjectBuilderBase::parsePayloadSpec (const std::string& input, std::vector< std::vector<std::string> >& output) const
+  {
+    using namespace std;
+
+    // split string into element strings (i.e. text with pairs name:type)
+    stringstream inputStream (input);
+    
+    const char elementsSeparator = ',';
+    std::list<string> inputElements;
+
+    string token;
+    while ( getline(inputStream, token, elementsSeparator) ) 
+      inputElements.push_back(token);
+
+    // save final output as a vector and parse element strings
+    const char typeSeparator = ':';
+    output.resize(inputElements.size());
+    unsigned int index = 0;
+    for (const string& element : inputElements) {
+      stringstream inputElementStream (element);
+      // element strings should be pairs of strings separated with a colon
+      output[index].resize(2);
+      // read name of the variable
+      getline(inputElementStream, token, typeSeparator); 
+      output[index][0] = token;
+      // read type of the variable
+      getline(inputElementStream, token, typeSeparator); 
+      output[index][1] = token; // trim spaces and assign
+      // trim spaces and assign
+      trimSpaces(output[index]);
+
+      ++index;
+    }
+  }
+
+} // AFP namespace
diff --git a/ForwardDetectors/AFP/AFP_DBTools/src/SiLocAlignDBTool.cxx b/ForwardDetectors/AFP/AFP_DBTools/src/SiLocAlignDBTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..740e9af7258e9a17a93fd3b37b8b8391a5ec9fae
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/src/SiLocAlignDBTool.cxx
@@ -0,0 +1,121 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file   SiLocAlignDBTool.cxx
+ * @author Grzegorz Gach <grzegorz.gach@cern.ch>
+ * @date   2017-12-03
+ * 
+ * @brief  File with implementation of SiLocAlignDBTool
+ */
+
+#include "../AFP_DBTools/SiLocAlignDBTool.h"
+#include "../AFP_DBTools/SiLocAlignDataBuilder.h"
+#include "../AFP_DBTools/SiLocAlignData.h"
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+
+#include <sstream>
+#include <string>
+#include <list>
+#include <map>
+
+namespace AFP
+{
+  const int SiLocAlignDBTool::s_numberOfStations = 4;
+  
+  SiLocAlignDBTool::SiLocAlignDBTool(const std::string& type,
+				     const std::string& name,
+				     const IInterface* parent) : 
+    AthAlgTool  (type, name, parent),
+    m_alignments (s_numberOfStations)
+  {
+    declareInterface<AFP::ISiLocAlignDBTool>(this);
+    declareProperty( "folderName", m_folderName = "/FWD/AFP/LocalAlignment/SiliconPlanes", "Name of the folder in database");
+  }
+
+  StatusCode SiLocAlignDBTool::initialize()
+  {
+    StatusCode regSC = detStore()->regFcn(&SiLocAlignDBTool::update, this, m_conditionsData , m_folderName.data(), true);
+    if (regSC.isFailure())
+      ATH_MSG_WARNING ("Failed to register SiLocAlignDBTool::update in detStore().");
+
+    return StatusCode::SUCCESS;
+  }
+
+  const SiLocAlignData* SiLocAlignDBTool::alignment (const int stationID, const int planeID) const
+  {
+    assert (stationID < s_numberOfStations);
+    
+    try {
+      return m_alignments[stationID].at(planeID).get();
+    }
+    catch (const std::out_of_range& excpetion) {
+      ATH_MSG_WARNING ("Access to SiLocAlignDBTool::m_alignments["<<stationID<<"].at("<<planeID<<") is out of range.");
+      return nullptr;
+    }
+
+    return nullptr;
+  }
+
+  void SiLocAlignDBTool::resizeAlignments (const std::vector<int>& maxLayers)
+  {
+    m_alignments.resize (maxLayers.size());
+
+    int stationID = 0;
+    for (int layersN : maxLayers)
+      m_alignments[stationID++].resize(layersN);
+  }
+
+
+  StatusCode SiLocAlignDBTool::update (IOVSVC_CALLBACK_ARGS)
+  {
+    // read database content
+    boost::property_tree::ptree inputData;
+    const coral::AttributeList attrList = m_conditionsData->coralList();
+    std::stringstream inputJSON (attrList["data"].data<std::string>());
+    boost::property_tree::read_json(inputJSON, inputData);
+    boost::property_tree::ptree& payload = inputData.get_child("data_array");
+
+    SiLocAlignDataBuilder builder;
+    // configure builder and check for warning messages
+    std::string builderWarning = builder.setSpecification(inputData.get<std::string>("folder_payloadspec"));
+    if (!builderWarning.empty())
+      ATH_MSG_WARNING(builderWarning);
+
+    // Create alignment objects based on parsed information from database. Also find number of stations and layers
+    std::list<std::unique_ptr<const SiLocAlignData> > alignmentsList;
+    int maxStationID = 0;
+    std::vector<int> maxLayers (maxStationID+1, 0);
+    for (boost::property_tree::ptree::value_type node : payload)
+      for (boost::property_tree::ptree::value_type nodeData : node.second) {
+
+	// create new alignment object and read station and layer ID
+	std::unique_ptr<const SiLocAlignData> newAlignment = std::make_unique<const SiLocAlignData> (builder.build(nodeData));
+	const int stationID = newAlignment->stationID();
+	const int layerID = newAlignment->layerID();
+	
+	// find highest stationID and highest layerID for a given station
+	if (maxStationID < stationID) {
+	  maxStationID = stationID;
+	  maxLayers.resize(maxStationID + 1, 0);
+	}
+				  
+	if (layerID >= maxLayers[stationID])
+	  maxLayers[stationID] = layerID+1;
+
+	// add alignment object to output list
+	alignmentsList.push_back(std::move(newAlignment));
+      }
+
+    resizeAlignments (maxLayers);
+
+    // rewrite new alignments to the output vector
+    for (std::unique_ptr<const SiLocAlignData>& locAlign : alignmentsList)
+      m_alignments[locAlign->stationID()][locAlign->layerID()] = std::move(locAlign);
+
+    return StatusCode::SUCCESS;
+  }
+}
diff --git a/ForwardDetectors/AFP/AFP_DBTools/src/SiLocAlignDataBuilder.cxx b/ForwardDetectors/AFP/AFP_DBTools/src/SiLocAlignDataBuilder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f05684014a6adb80c460f806d1820186e6d86b82
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/src/SiLocAlignDataBuilder.cxx
@@ -0,0 +1,55 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file   SiLocAlignDataBuilder.cxx
+ * @author Grzegorz Gach <grzegorz.gach@cern.ch>
+ * @date   2018-01-17
+ * 
+ * @brief  Source file for class SiLocAlignDataBuilder.
+ * 
+ */
+
+
+#include "../AFP_DBTools/SiLocAlignDataBuilder.h"
+
+#include <sstream>
+
+namespace AFP
+{
+  bool SiLocAlignDataBuilder::addBuilderCommand (const std::string& name) 
+  {
+    if (name == "stationID")
+      this->m_commands.push_back(new Command<int> (&SiLocAlignData::m_stationID));
+
+    else if (name == "layerID")
+      this->m_commands.push_back(new Command<int> (&SiLocAlignData::m_layerID));
+
+    else if (name == "shiftX")
+      this->m_commands.push_back(new Command<double> (&SiLocAlignData::m_xShift));
+
+    else if (name == "shiftY")
+      this->m_commands.push_back(new Command<double> (&SiLocAlignData::m_yShift));
+
+    else if (name == "shiftZ")
+      this->m_commands.push_back(new Command<double> (&SiLocAlignData::m_zShift));
+
+    else if (name == "alpha")
+      this->m_commands.push_back(new Command<double> (&SiLocAlignData::m_alpha));
+
+    else if (name == "beta")
+      this->m_commands.push_back(new Command<double> (&SiLocAlignData::m_beta));
+
+    else if (name == "gamma")
+      this->m_commands.push_back(new Command<double> (&SiLocAlignData::m_gamma));
+
+    else {
+      this->m_commands.push_back(new Command<double> (nullptr));
+      return false;
+    }
+
+    return true;
+  }
+
+} // AFP namespace
diff --git a/ForwardDetectors/AFP/AFP_DBTools/src/components/AFP_DBTools_entries.cxx b/ForwardDetectors/AFP/AFP_DBTools/src/components/AFP_DBTools_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c34c4e0a48e6d3605a22f6d52f7dbe9b472ffa0d
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/src/components/AFP_DBTools_entries.cxx
@@ -0,0 +1,12 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "AFP_DBTools/SiLocAlignDBTool.h"
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+DECLARE_NAMESPACE_TOOL_FACTORY(AFP, SiLocAlignDBTool)
+
+DECLARE_FACTORY_ENTRIES(AFP_DBTools) {
+  DECLARE_NAMESPACE_TOOL(AFP, SiLocAlignDBTool)
+}
diff --git a/ForwardDetectors/AFP/AFP_DBTools/src/components/AFP_DBTools_load.cxx b/ForwardDetectors/AFP/AFP_DBTools/src/components/AFP_DBTools_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e5ca5ca2598cc1d24c9e07a4af015f090f24e877
--- /dev/null
+++ b/ForwardDetectors/AFP/AFP_DBTools/src/components/AFP_DBTools_load.cxx
@@ -0,0 +1,8 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(AFP_DBTools)
+