diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/ElectronicsResponse.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/ElectronicsResponse.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd4cc0f53f446f19710e93ce7db3ca9593631c31
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/ElectronicsResponse.h
@@ -0,0 +1,108 @@
+/* -*- C++ -*- */
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ElectronicsResponse_h
+#define ElectronicsResponse_h
+/** @class ElectronicsResponse
+
+// ------------
+// Authors:
+//   Iakovidis George        <george.iakovidis@cern.ch>
+//   Karakostas Konstantinos <konstantinos.karakostas@cern.ch>
+//   Leontsinis Stefanos     <stefanos.leontsinis@cern.ch>
+//   Nektarios Chr. Benekos  <nbenekos@cern.ch> 
+//   Jessica Metcalfe        <jessica.metcalfe@gmail.com>
+//////////////////////////////////////////////////////////////////////////////
+ 
+Comments to be added here....
+
+
+*/
+
+/// ROOT
+#include <TROOT.h>
+#include <TH1.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TF1.h>
+#include <TMath.h>
+
+/// STD'S
+#include <algorithm>
+#include <cmath>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include <utility>
+#include <string>
+#include <sstream>
+#include <sys/stat.h>
+
+/// Projects
+#include "MM_Digitization/MmElectronicsToolInput.h"
+#include "MM_Digitization/MmDigitToolOutput.h"
+#include "MM_Digitization/StripsResponse.h"
+
+using std::vector;
+using std::cout;
+using std::endl;
+
+/// ROOT Classed
+class TF1;
+class TH1;
+class TH1F;
+class TH2F;
+
+class ElectronicsResponse {
+  
+private:
+  /** power of responce function */
+  float alpha; 
+  /**  */
+  float RC ;
+  /** hreshold "Voltage" for histoBNL */
+  float electronicsThreshold;
+  float m_StripResponse_qThreshold;
+  float m_StripResponse_driftGap;
+  float m_StripResponse_driftVelocity;
+
+  TF1 *intFn;
+  StripsResponse* stripObject ;  
+public :
+
+  ElectronicsResponse();
+  virtual ~ElectronicsResponse();
+  void clearValues ();
+  void bnlResponceFunction(const vector <int> & numberofStrip, const vector <float> & qStrip, const vector <float> & tStrip);
+  MmDigitToolOutput GetResponceFrom(const MmElectronicsToolInput & digiInput);
+
+  float tMinFromIntegration;
+  float tminFromIntegrationAboveThreshold;
+  float tMinFromFirstPeak;
+  vector <float> tStripElectronicsAbThr;
+  vector <float> qStripElectronics;
+  vector <int> nStripElectronics;
+
+  inline void set_alpha(float val) {alpha = val;};
+  inline void set_RC (float val) {RC = val;};
+  inline void set_electronicsThreshold(float val) {electronicsThreshold = val;};
+ 
+  float get_alpha() const { return alpha;};
+  float get_RC () const { return RC;};
+  float get_electronicsThreshold() const { return electronicsThreshold;};
+   
+  float get_tMinFromIntegration () const { return tMinFromIntegration;};
+  float get_tminFromIntegrationAboveThreshold () const { return tminFromIntegrationAboveThreshold;};
+  float get_tMinFromFirstPeak () const { return tMinFromFirstPeak;};
+ 
+  vector <float>  get_tStripElectronicsAbThr () const { return tStripElectronicsAbThr;};
+  vector <float>  get_qStripElectronics () const { return qStripElectronics;};
+  vector <int>  get_nStripElectronics () const { return nStripElectronics;};
+
+
+};
+
+#endif
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/IMM_DigitizationTool.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/IMM_DigitizationTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d24f75a54e85d38f6e0b03ebecc93890779a434
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/IMM_DigitizationTool.h
@@ -0,0 +1,30 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MM_DIGITIZATION_IMM_DIGITIZATIONTOOL_H
+#define MM_DIGITIZATION_IMM_DIGITIZATIONTOOL_H
+
+#include "MM_Digitization/MmDigitToolOutput.h"
+#include "GaudiKernel/IAlgTool.h"
+/*-----------------------------------------------
+ 
+Created March 2013 by Nektarios Chr. Benekos
+
+Interface for tools which convert MicroMegas digitization input quantities into the signal
+-----------------------------------------------*/
+
+class MmDigitToolInput;
+
+static const InterfaceID IID_IMM_DigitizationTool("IMM_DigitizationTool",1,0);
+
+class IMM_DigitizationTool : virtual public IAlgTool {
+ public:
+
+  virtual MmDigitToolOutput digitize(/*const MmDigitToolInput& input*/) = 0;
+   
+  static const InterfaceID& interfaceID()
+    { return IID_IMM_DigitizationTool; }
+};
+
+#endif
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_Digitizer.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_Digitizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b9677399c7e56a0e8616cf54e65b0239e09a087
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_Digitizer.h
@@ -0,0 +1,34 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONDIGITIZATION_MM_DIGITIZER_H
+#define MUONDIGITIZATION_MM_DIGITIZER_H 
+
+/// Gaudi External 
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+
+class IMuonDigitizationTool;
+ 
+/*******************************************************************************/
+class MM_Digitizer : public AthAlgorithm {
+
+ public:
+
+  MM_Digitizer(const std::string& name, ISvcLocator* pSvcLocator);
+  ~MM_Digitizer();
+    
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+  
+  ToolHandle<IMuonDigitizationTool> m_digTool;
+ 
+};
+/*******************************************************************************/
+#endif // MUONDIGITIZATION_MM_DIGITIZER_H
+
+
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_Response_DigitTool.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_Response_DigitTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..59fe1263cbaa344f07fcbc59505d3be8b9d585d4
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_Response_DigitTool.h
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MM_DIGITIZATION_MM_RESPONSE_DIGITTOOL_H
+#define MM_DIGITIZATION_MM_RESPONSE_DIGITTOOL_H
+
+#include "GaudiKernel/AlgTool.h"
+#include "MM_Digitization/MmDigitToolOutput.h"
+#include "MM_Digitization/IMM_DigitizationTool.h"
+	
+#include "GaudiKernel/ServiceHandle.h"
+
+#include "CLHEP/Random/RandomEngine.h"
+#include "AthenaKernel/IAtRndmGenSvc.h"
+/*-----------------------------------------------
+ 
+Created March 2013 by Nektarios Chr. Benekos
+	  
+Digitization tool which uses MM_Response to convert MM digitization
+input quantities into the output
+
+-----------------------------------------------*/
+/*******************************************************************************/ 
+
+namespace MuonGM{
+  class MuonDetectorManager;
+}
+class MmIdHelper;
+class IAtRndmGenSvc;
+	
+class MM_Response_DigitTool : public AlgTool, virtual public IMM_DigitizationTool {
+ public:
+  MM_Response_DigitTool( const std::string& type, 
+			const std::string& name, 
+			const IInterface* parent );
+	
+  MmDigitToolOutput digitize(/* const MmDigitToolInput& input */ ); 	 
+  StatusCode initialize();
+  bool initializeStrip();
+	 
+ private:
+ 	 
+  const MuonGM::MuonDetectorManager* m_muonGeoMgr;
+  const MmIdHelper*         m_idHelper;
+	  
+ protected: 
+  CLHEP::HepRandomEngine *m_rndmEngine;    // Random number engine used - not init in SiDigitization
+  std::string m_rndmEngineName;// name of random engine
+  ServiceHandle <IAtRndmGenSvc> m_rndmSvc;      // Random number service
+	
+};
+	
+#endif
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitToolInput.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitToolInput.h
new file mode 100644
index 0000000000000000000000000000000000000000..6fbb06e60d1a933602f89ca5e67f23c25998fdf0
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitToolInput.h
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MM_DIGITIZATION_MMDIGITTOOLINPUT_H
+#define MM_DIGITIZATION_MMDIGITTOOLINPUT_H
+#include "Identifier/Identifier.h"
+/*-----------------------------------------------
+ 
+Created March 2013 by Nektarios Chr. Benekos
+   Karakostas Konstantinos   <Konstantinos.Karakostas@cern.ch>
+   
+Class to store input needed for the MM_Digitization tools:
+- G4 driftradius
+- position along tube
+- magnetic field strength at hit position   <-- ToDo: get the lorentz angle from the mag field
+- local temperature
+- electric charge
+- gamma factor
+- hit Identifier	
+
+-----------------------------------------------*/
+/*******************************************************************************/ 
+class MmDigitToolInput {
+ public:
+ 
+  MmDigitToolInput(int stripIdLocal, double posx, double incomingAngle, double field, int stripMaxId)
+   :  m_stripIDLocal(stripIdLocal),
+      m_xpos(posx),
+      m_incomingAngle(incomingAngle),
+      m_field(field),
+      m_stripMaxId(stripMaxId)
+  { }
+    
+      
+  ~MmDigitToolInput() {}
+
+      int    stripIDLocal()        const { return m_stripIDLocal; }
+      double positionWithinStrip() const { return m_xpos; }
+      double incomingAngle()       const { return m_incomingAngle; }
+      double magneticField()       const { return m_field; }
+      int    stripMaxID()          const { return m_stripMaxId; }
+      Identifier getHitID()        const { return m_hitID; }
+       
+ private:
+      int    m_stripIDLocal;
+      double m_xpos; 
+      double m_incomingAngle;
+      double m_field; 
+      int    m_stripMaxId;
+      Identifier m_hitID;
+};
+/*******************************************************************************/ 	 
+#endif  
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitToolOutput.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitToolOutput.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a71e86050cb51f312c6de771bb7494a56c52bf6
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitToolOutput.h
@@ -0,0 +1,59 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MM_DIGITIZATION_MMDIGITTOOLOUTPUT_H
+#define MM_DIGITIZATION_MMDIGITTOOLOUTPUT_H
+
+/*-----------------------------------------------
+ 
+Created March 2013 by Nektarios Chr. Benekos
+    Karakostas Konstantinos   <Konstantinos.Karakostas@cern.ch>
+
+Class to store output produced by MDT_Digitization tools:
+- was hit efficient
+- strip position
+- strip charge
+- strip time
+- first strip position [for Trigger study]
+- first strip time [for Trigger study]
+	 
+-----------------------------------------------*/
+	
+class MmDigitToolOutput {
+ public:
+    MmDigitToolOutput(bool hitWasEff, std::vector <int> strpos, std::vector<float> time, std::vector<float> charge, int strTrig, float strTimeTrig )
+     :  m_hitWasEff(hitWasEff),
+        m_strpos(strpos),
+        m_time(time),
+        m_charge(charge),
+        m_stripForTrigger(strTrig),
+        m_stripTimeForTrigger(strTimeTrig),
+        m_isValid(false)
+    {
+        if(m_strpos.size() > 0 && m_time.size() > 0 && m_charge.size() > 0) m_isValid = true;
+    } 
+	
+    ~MmDigitToolOutput() {}
+ 	
+    bool hitWasEfficient()  const { return m_hitWasEff; } 
+    std::vector<int> stripPos() const { return m_strpos; }
+    std::vector<float> stripTime() const { return m_time; }
+    std::vector<float> stripCharge() const { return m_charge; } 
+    int stripForTrigger() const { return m_stripForTrigger; }
+    float stripTimeForTrigger() const { return m_stripTimeForTrigger; }
+    void set_StripForTrigger(int val)  { m_stripForTrigger = val; }
+    void set_StripTimeForTrigger(float val) { m_stripTimeForTrigger = val; }
+    bool isValid() { return m_isValid; }
+    	
+ private:
+    bool  m_hitWasEff;
+    std::vector<int> m_strpos;  
+    std::vector<float>  m_time; 
+    std::vector<float> m_charge;
+    int m_stripForTrigger;
+    float m_stripTimeForTrigger;
+    bool m_isValid;
+};
+	 
+#endif
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitizationTool.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitizationTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..b5515167e3c3a7fd8d1b82914e8e4355e1e52708
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmDigitizationTool.h
@@ -0,0 +1,275 @@
+/* -*- C++ -*- */
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MM_DIGITIZATIONTOOL_H
+#define MM_DIGITIZATIONTOOL_H
+/** @class MmDigitizationTool
+
+    @section MM_DigitizerDetails Class methods and properties
+    // ------------
+    // Authors:
+    //   Nektarios Chr. Benekos  <nectarios.benekos@cern.ch>
+    //   Konstantinos Karakostas <Konstantinos.Karakostas@cern.ch>
+    ////////////////////////////////////////////////////////////////////////////////
+
+    In the initialize() method, the PileUpMerge and StoreGate services are initialized, and a pointer to an instance of the class 
+    MuonDetectorManager is retrieved from the detector store and used to obtain a MmIdHelper.
+    The MMDigitContainer is initialized and the simulation identifier helper retrieved, together with the pointer to the digitization tool. 
+    Random numbers are obtained in the code from a dedicated stream via AtRndmSvc, 
+    which is also initialized in the initialize() method. 
+    In the execute() method, the digits and the SDOs (Simulation Data Object,
+    container for simulation data to be preserved after the digitization procedue, and persistified together with the RDOs) 
+    containers are created and recorded on StoreGate; the GenericMuonSimHit collection are merged using the 
+    TimedHitCollection sorted container (done in handleMicroMegasSimhit(TimedHitPtr<GenericMuonSimHit>& hit)) method); 
+    into a loop over the TimedHitCollection for the given DetectorElement, 
+    the handleMicroMegasSimhit() method converts the SimID into the Offline ID to be associated to the Digit and pass to the 
+    digitization tool the drift radius and the distance to the chamber RO side (for the propagation delay computation).
+    The digitization tool returns a drift time, charge and strip position which are used together with the Offline ID, 
+    to create the digit object (in doDigitization() method).
+    The finalize() method returns a SUCCESS StatusCode if the digitization procedure ends succesfully.
+
+    In the initialize() method...
+    In the execute() method...
+*/
+
+#include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#include "HitManagement/TimedHitCollection.h"
+#include "MuonSimEvent/GenericMuonSimHitCollection.h"
+#include "MuonSimEvent/GenericMuonSimHit.h"
+#include "PileUpTools/PileUpToolBase.h"
+#include "Identifier/Identifier.h"
+ 
+#include "MM_Digitization/MmSortedHitVector.h"
+
+#include "CLHEP/Random/RandomEngine.h"
+#include "CLHEP/Geometry/Point3D.h"
+#include "CLHEP/Vector/ThreeVector.h"
+#include "AthenaKernel/IAtRndmGenSvc.h"
+ 
+#include "MuonDigToolInterfaces/IMuonDigitizationTool.h"
+#include "MM_Digitization/StripsResponse.h"
+#include "MM_Digitization/ElectronicsResponse.h"
+   
+#include <string>
+#include <sstream>
+#include <vector>
+#include <map>
+/*******************************************************************************/ 
+namespace MuonGM{
+  class MuonDetectorManager;
+  class MMReadoutElement;
+  class MuonChannelDesign;
+}
+namespace CLHEP{
+  class HepRandomEngine;
+}
+
+class StoreGateSvc;
+class ActiveStoreSvc;
+class PileUpMergeSvc;
+
+class MmDigitContainer;
+class MmDigitCollection;
+class MmIdHelper;
+class MicromegasHitIdHelper;
+class IAtRndmGenSvc;
+class MsgStream;
+
+class IMM_DigitizationTool;
+class MuonSimDataCollection;
+
+class StripsResponse;
+class ElectronicsResponse;
+
+class TTree;
+class TFile;
+ 
+/*******************************************************************************/ 	
+
+class MmDigitizationTool : virtual public IMuonDigitizationTool, public PileUpToolBase {
+
+public:
+  MmDigitizationTool(const std::string& type, const std::string& name, const IInterface* parent);
+
+  /** Initialize */
+  virtual StatusCode initialize();
+
+  /** When being run from PileUpToolsAlgs, this method is called at the start of the subevts loop. Not able to access SubEvents */
+  StatusCode prepareEvent(const unsigned int /*nInputEvents*/);
+  
+  /** When being run from PileUpToolsAlgs, this method is called for each active bunch-crossing to process current SubEvents bunchXing is in ns */
+  StatusCode  processBunchXing(int bunchXing,
+ 			       PileUpEventInfo::SubEvent::const_iterator bSubEvents,
+ 			       PileUpEventInfo::SubEvent::const_iterator eSubEvents); 
+ 
+  /** When being run from PileUpToolsAlgs, this method is called at the end of the subevts loop. Not (necessarily) able to access SubEvents */
+  StatusCode mergeEvent();
+
+  /** When being run from MM_Digitizer, this method is called during the event loop */
+
+  /** alternative interface which uses the PileUpMergeSvc to obtain 
+      all the required SubEvents. */ 
+  virtual StatusCode processAllSubEvents(); 
+ 		 
+  /** Just calls processAllSubEvents - leaving for back-compatibility 
+      (IMuonDigitizationTool) */ 
+
+  StatusCode digitize();
+
+  /** Finalize */
+  StatusCode finalize();
+
+  /** accessors */
+  ServiceHandle<IAtRndmGenSvc> getRndmSvc() const { return m_rndmSvc; }    // Random number service
+  CLHEP::HepRandomEngine  *getRndmEngine() const { return m_rndmEngine; } // Random number engine used
+
+  void setAmplification(const double amplification) { 
+    m_amplification = amplification; 
+  } 
+
+  void set (const double bunchTime);
+
+private:
+
+  ServiceHandle<StoreGateSvc> m_sgSvc;
+  ActiveStoreSvc*             m_activeStore;
+  
+  /** Record MmDigitContainer and MuonSimDataCollection */
+  StatusCode recordDigitAndSdoContainers();
+   
+  MmDigitContainer*      m_digitContainer;
+  MuonSimDataCollection* m_sdoContainer;
+  MmSortedHitVector      m_hits;
+	 
+  const MmIdHelper*       m_idHelper;
+  MicromegasHitIdHelper*  muonHelper;
+  
+  const MuonGM::MuonDetectorManager* m_MuonGeoMgr;
+ 
+  ToolHandle <IMM_DigitizationTool> m_digitTool;
+  std::list<GenericMuonSimHitCollection*> m_MMHitCollList;
+  bool  checkMMSimHit(const GenericMuonSimHit& /* hit */ ) const; 
+    
+  //CONFIGURATION
+  bool m_validationSetup;
+  double m_energyThreshold;
+  bool m_saveInternalHistos;
+  bool m_checkMMSimHits;
+  bool m_useTof;
+  bool m_useAttenuation;
+  bool m_useProp;
+ 
+  //pile-up
+  TimedHitCollection<GenericMuonSimHit>* m_thpcMM; // the hits
+
+  ///////////////////////////////////////////////////////////////////
+  // Access to the event methods:
+  ///////////////////////////////////////////////////////////////////
+  // Get next event and extract collection of hit collections:
+  StatusCode getNextEvent();
+  StatusCode doDigitization();
+  
+  void  fillMaps(const GenericMuonSimHit * mmHit, const Identifier digitId, const double driftR);
+  int   digitizeTime(double time) const;
+  bool outsideWindow(double time) const; // default +-50...
+ 
+  //TIMING SCHEME
+  bool   m_useTimeWindow;
+  double m_inv_c_light;
+  double m_DiffMagSecondMuonHit;
+
+  //TDC ELECTRONICS  
+  double m_ns2TDC;
+  double m_resTDC;
+
+  // RandomGenerators
+  //  double m_FlatDist;
+  //  double m_GaussDist;  
+  //  double m_PoissonDist;  
+  //  double m_GammaDist;
+  double m_Polya;
+  double m_timeWindowLowerOffset;
+  double m_timeWindowUpperOffset;
+  double m_bunchTime;
+  double * m_sprob;
+  double m_amplification;
+
+  // StripsResponse stuff...
+  StripsResponse *m_StripsResponse;
+  float m_qThreshold, m_diffusSigma, m_LogitundinalDiffusSigma, m_driftGap, m_driftVelocity, m_crossTalk1, m_crossTalk2;
+  float m_qThresholdForTrigger;
+
+  // ElectronicsResponse stuff...
+  ElectronicsResponse *m_ElectronicsResponse;
+  float m_alpha;// power of responce function 
+  float m_RC ;// time constant of responce function
+  float m_electronicsThreshold; // threshold "Voltage" for histoBNL
+  TFile *m_file;
+  TTree *m_ntuple;
+  TH1I *m_AngleDistr, *m_AbsAngleDistr, *m_ClusterLength2D, *m_ClusterLength, *m_gasGap,  *m_gasGapDir ;
+  
+  int m_n_Station_side, m_n_Station_eta, m_n_Station_phi, m_n_Station_multilayer, m_n_Station_layer, m_n_hitStripID, m_n_StrRespTrg_ID, m_n_strip_multiplicity, m_n_strip_multiplicity_2;
+  int exitcode, m_n_hitPDGId;
+  double m_n_hitOnSurface_x, m_n_hitOnSurface_y, m_n_hitDistToChannel, m_n_hitIncomingAngle,m_n_StrRespTrg_Time, m_n_hitIncomingAngleRads, m_n_hitKineticEnergy, m_n_hitDepositEnergy;
+  float  tofCorrection, bunchTime, globalHitTime;
+  std::vector<int> m_n_StrRespID;
+  std::vector<float> m_n_StrRespCharge, m_n_StrRespTime;
+
+  // vector <TH1F*> m_histoBNL;
+   
+  // private methods need to compute the induce charge on the strip
+  double qStrip        (const int & nElectrons, const double & gammaDist) const;
+  double qStripR       (const double x) const;
+  double qStripR       (const double x, const std::string stationType) const;
+  double qStripPhi     (const double x, const std::string stationType) const;
+  double fparamPhi     (const double x, const int N, const double * p) const;   
+  //	  double getDriftTime(const MMReadoutElement* descriptor, const Amg::Vector3D& pos) const;
+
+
+protected:  
+
+  PileUpMergeSvc *m_mergeSvc; // Pile up service
+  std::string m_inputObjectName; // name of the input objects
+  std::string m_outputObjectName; // name of the output digits
+  std::string m_outputSDOName; // name of the output SDOs
+
+  ServiceHandle <IAtRndmGenSvc> m_rndmSvc;      // Random number service
+  CLHEP::HepRandomEngine *m_rndmEngine;    // Random number engine used - not init in SiDigitization
+  std::string m_rndmEngineName;// name of random engine
+  int m_maskMultiplet;
+
+};
+/*******************************************************************************/
+inline bool MmDigitizationTool::outsideWindow(double driftTime) const {
+  double time = driftTime; //m_bunchTime is included already....updated one..
+  //  double time = driftTime+m_bunchTime;
+  return time < m_timeWindowLowerOffset || time > m_timeWindowUpperOffset;
+}
+/*******************************************************************************/
+inline double MmDigitizationTool::qStrip (const int & nElectrons, const double& gammaDist) const {
+ 
+  // find the charge on the wire
+ 
+  //  double amplification = 0.58e5;
+  double amplification = m_amplification;
+  double stripCharge = 0.0; 
+ 
+  for (int i=0; i<nElectrons; i++) {
+    double RNDpol = 0.0;
+    if (m_Polya > -1.0) {
+      RNDpol = gammaDist/(1.0+m_Polya);
+    } 
+    stripCharge += amplification*RNDpol;
+  }
+  return stripCharge;
+}
+/*******************************************************************************/
+inline void MmDigitizationTool::set (const double bunchTime) {m_bunchTime = bunchTime;}
+
+#endif // MmDigitizationTool
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmElectronicsToolInput.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmElectronicsToolInput.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9f3e2b9fe9a726f994c19a5cb641cab90aa84e2
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmElectronicsToolInput.h
@@ -0,0 +1,28 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MM_DIGITIZATION_MMELECTRONICSTOOLINPUT_H
+#define MM_DIGITIZATION_MMELECTRONICSTOOLINPUT_H
+ 
+/*******************************************************************************/ 
+class MmElectronicsToolInput {
+ 
+ public:
+ 
+  MmElectronicsToolInput(std::vector<int> NumberOfStripsPos, std::vector<float> chipCharge, std::vector<float> chipTime ) :
+    m_NumberOfStripsPos(NumberOfStripsPos),m_chipCharge(chipCharge),m_chipTime(chipTime) {}
+          
+    ~MmElectronicsToolInput() {}
+  
+    std::vector<int> NumberOfStripsPos() const { return m_NumberOfStripsPos; }
+    std::vector<float> chipCharge() const { return m_chipCharge; } 
+    std::vector<float> chipTime() const { return m_chipTime; }
+ 
+ private:
+    std::vector<int> m_NumberOfStripsPos; 
+    std::vector<float> m_chipCharge; 
+    std::vector<float> m_chipTime;
+};
+/*******************************************************************************/ 	 
+#endif  
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmSortedHitVector.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmSortedHitVector.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbfb64af3c9c6275cec04c25f6650adb027b986f
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MmSortedHitVector.h
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MM_DIGITIZATION_MMSORTEDHITVECTOR_H
+#define MM_DIGITIZATION_MMSORTEDHITVECTOR_H
+/*******************************************************************************/	
+class micromegas_hit_info {
+ public:
+  micromegas_hit_info(Identifier i,double t,int ch,double strP,const TimedHitPtr<GenericMuonSimHit>* aHit) : 
+    id(i),time(t),charge(ch),stripPos(strP),simhit(aHit) {}
+    micromegas_hit_info(Identifier i,double t,int ch) : id(i),time(t),charge(ch) {}
+      micromegas_hit_info() :time(0.),charge(0) {}
+	Identifier id;
+	double time;
+	int charge;
+	double stripPos;
+	const TimedHitPtr<GenericMuonSimHit>* simhit;
+	bool operator < (const micromegas_hit_info& aInfo) const 
+	{ 
+	  if(id <  aInfo.id)
+	    return true;
+	  else if(id == aInfo.id)
+	    return time < aInfo.time; 
+	  return false;
+	} 
+};
+/*******************************************************************************/	
+// instead of using a map we use a sorted vector to temporary store the hits.
+typedef std::vector<micromegas_hit_info> HitVector;
+typedef HitVector::iterator HitIt;
+/*******************************************************************************/	 
+class MmSortedHitVector : public HitVector {
+ public:
+  void insert(const micromegas_hit_info& hit);
+  void sort();
+  bool isSorted() { return m_isSorted; }
+ private:
+  bool m_isSorted;
+};
+/*******************************************************************************/
+inline void MmSortedHitVector::sort() {
+  std::sort(HitVector::begin(),HitVector::end());
+  m_isSorted = true;
+}
+/*******************************************************************************/
+inline void MmSortedHitVector::insert(const micromegas_hit_info& hit) {
+  push_back(hit);
+  m_isSorted = false;
+}
+/*******************************************************************************/	
+#endif
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/StripsResponse.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/StripsResponse.h
new file mode 100644
index 0000000000000000000000000000000000000000..23e75a13a981ebb527cc15a8dd51d738d5445cea
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/StripsResponse.h
@@ -0,0 +1,179 @@
+/* -*- C++ -*- */
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef StripsResponse_H
+#define StripsResponse_H
+/** @class StripsResponse
+
+// ------------
+// Authors:
+//   Iakovidis George        <george.iakovidis@cern.ch>
+//   Karakostas Konstantinos <konstantinos.karakostas@cern.ch>
+//   Leontsinis Stefanos     <stefanos.leontsinis@cern.ch>
+//   Nektarios Chr. Benekos  <nbenekos@cern.ch>    
+//////////////////////////////////////////////////////////////////////////////
+  
+Comments to be added here...
+
+*/
+
+#include "GaudiKernel/AlgFactory.h"
+#include "GaudiKernel/IToolSvc.h"
+#include "GaudiKernel/Service.h"
+#include "AthenaKernel/MsgStreamMember.h"
+#include "GaudiKernel/StatusCode.h"
+
+/// ROOT
+#include <TROOT.h>
+#include <TFile.h>
+#include <TF1.h>
+#include <TRandom.h>
+#include <TRandom3.h>
+#include <TCanvas.h>
+#include <TMath.h>
+
+/// Projects
+#include "MM_Digitization/MmDigitToolInput.h"
+#include "MM_Digitization/MmDigitToolOutput.h"
+
+/// STD'S
+#include <algorithm>
+#include <cmath>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include <utility>
+#include <string>
+#include <sstream>
+#include <sys/stat.h>
+
+using std::vector;
+using std::cout;
+using std::endl;
+
+/// ROOT Classed
+class TF1;
+class TRandom;
+class TRandom3;
+
+class ElectronicsResponse;
+class MmDigitToolInput;
+class MmDigitToolOutput;
+
+class StripsResponse {
+  
+private:
+
+  /** qThreshold=2e, we accept a good strip if the charge is >=2e */
+  float qThreshold; 
+  /** // 0.350/10 diffusSigma=transverse diffusion (350 μm per 1cm ) for 93:7 @ 600 V/cm, according to garfield  */
+  float diffusSigma; 
+  float LogitundinalDiffusSigma;  
+  float pitch; 
+  /** //pitch=0.500 properties of the micromegas ToDo: to be reviewed */
+  float stripwidth; 
+  /** crosstalk of neighbor strips, it's 15%  */
+  float crossTalk1;//0.10; // 
+  /** // crosstalk of second neighbor strips, it's 6% */
+  float crossTalk2;//0.03; 
+  /** // (degrees) Magnetic Field 0.5 T */
+  float Lorentz_Angle; 
+
+  /// ToDo: random number from custom functions
+  TF1 *polya, *conv_gaus;
+ 
+public :
+
+  float driftGap;  
+  /** //0.050 drift velocity in [mm/ns], driftGap=5 mm +0.128 mm (the amplification gap) */
+  float driftVelocity; 
+ 
+  StripsResponse();
+   
+  virtual ~StripsResponse();
+  MmDigitToolOutput GetResponceFrom(const MmDigitToolInput & digiInput);
+    
+  void calculateResponceFrom (const float & hitx, const int & stripOffest, const float & thetaD, const int & stripMaxID);
+  void initializationFrom ();
+  void testRandomNumGens (UInt_t sd);
+  void writeHistos();
+  void initHistos ();
+  void clearValues ();
+  void initFunctions ();
+  void whichStrips(const float & hitx, const int & stripOffest, const float & thetaD, const int & stripMaxID);
+  
+  inline void set_qThreshold (float val) { qThreshold = val; };
+  inline void set_diffusSigma (float val) { diffusSigma = val; };
+  inline void set_LogitundinalDiffusSigma (float val) { LogitundinalDiffusSigma = val; };
+  inline void set_driftVelocity (float val) { driftVelocity = val; };
+  inline void set_crossTalk1 (float val) { crossTalk1 = val; };
+  inline void set_crossTalk2 (float val) { crossTalk2 = val; };
+  inline void set_driftGap      (float val) {driftGap = val;};
+  inline void set_stripWidth      (float val) {stripwidth = val;};
+   
+  float get_stripWidth    () const { return stripwidth   ;};
+  float get_qThreshold    () const { return qThreshold   ;};
+  float get_driftGap      () const { return driftGap     ;};
+  float get_driftVelocity () const { return driftVelocity;};
+
+/*
+  Coverity defects
+  float get_tMinFirstPeak () const { return tMinFirstPeak;};
+  float get_tMinIntegration () const { return tMinIntegration;};
+  float get_tminIntegrationAboveThreshold () const { return tminIntegrationAboveThreshold;};
+*/  
+  
+  vector <float> get_tStripElectronicsAbThr() const { return tStripElectronicsAbThr;};
+  vector <float> get_qStripElectronics() const { return qStripElectronics;};
+  vector <float> get_finaltStripNoSlewing() const { return finaltStripNoSlewing;};
+  vector <float> get_finalqStrip() const { return finalqStrip;};
+  vector <float> get_finaltStrip() const { return finaltStrip;};
+  vector <int>   get_nStripElectronics() const { return nStripElectronics;};
+  vector <int>   get_finalNumberofStrip() const { return finalNumberofStrip;};
+
+  vector <int>   finalNumberofStrip;
+  vector <int>   nStripElectronics;
+  vector <float> finalqStrip;
+  vector <float> finaltStrip;
+  vector <float> finaltStripNoSlewing;
+  vector <float> tStripElectronicsAbThr;
+  vector <float> qStripElectronics;
+ 
+  int    nstrip;
+  float  temp_polya;
+  float  polya_theta;
+  float  numberOfElectrons;
+/*
+  Coverity defects
+  float  tMinFirstPeak;
+  float  tMinIntegration;
+  float  tminIntegrationAboveThreshold;
+*/ 
+
+// whichStrips()
+  int dimClusters; //dimClusters=total number of collisions
+  int MaxPrimaryIons;
+  vector <int> stripNumber;
+  double pt,xx, xxDiffussion, yy, yyDiffussion ;
+  int primaryion; 
+  vector <int> firstq;
+  float lmean;
+  vector <float> qstrip; 
+  vector <float> cntTimes;
+  vector <float> tStrip;
+  vector <float> qStrip;
+  vector <float> time;  //Drift velocity [mm/ns]
+  vector <int> numberofStrip;
+  
+  vector <float> clusterelectrons;
+  vector <float> l;
+  float totalelectrons;
+  float ll;
+   
+  TRandom * gRandom_loc;
+  TRandom3 *randomNum;
+};
+#endif
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/cmt/Makefile b/MuonSpectrometer/MuonDigitization/MM_Digitization/cmt/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c2c9dbbed79a7894e694cf7a0c7d1bf0756334c3
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/cmt/Makefile
@@ -0,0 +1,4 @@
+include $(CMTROOT)/src/Makefile.header
+
+include $(CMTROOT)/src/constituents.make
+
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/cmt/requirements b/MuonSpectrometer/MuonDigitization/MM_Digitization/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..0bdcdf6ecec08012286acb0e4a932452a7d27335
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/cmt/requirements
@@ -0,0 +1,52 @@
+package MM_Digitization
+
+author   Nektarios Benekos <nectarios.benekos@cern.ch>
+manager  Nektarios Benekos <nectarios.benekos@cern.ch>
+
+public
+use  AtlasPolicy                AtlasPolicy-*                   
+use  AthenaKernel               AthenaKernel-*                  Control
+use  AthenaBaseComps            AthenaBaseComps-*               Control
+use  PileUpTools                PileUpTools-*                   Control
+use  AtlasCLHEP                 AtlasCLHEP-*                    External
+use  GaudiInterface             GaudiInterface-*                External
+use  AtlasROOT                  AtlasROOT-*                     External 
+use  Identifier                 Identifier-*                    DetectorDescription
+use  HitManagement              HitManagement-*                 Simulation
+use  MuonDigToolInterfaces      MuonDigToolInterfaces-*         MuonSpectrometer/MuonDigitization
+use  MuonSimEvent               MuonSimEvent-*                  MuonSpectrometer
+ 
+private
+use  StoreGate                  StoreGate-*                     Control
+use  AtlasAIDA                  AtlasAIDA-*                     External
+use  AtlasHepMC                 AtlasHepMC-*                    External
+use  GeneratorObjects           GeneratorObjects-*              Generators
+use  MuonDigitContainer         MuonDigitContainer-*            MuonSpectrometer
+use  MuonIdHelpers              MuonIdHelpers-*                 MuonSpectrometer
+use  MuonSimData                MuonSimData-*                   MuonSpectrometer
+use  PathResolver               PathResolver-*                  Tools
+use  TrkDetDescrUtils           TrkDetDescrUtils-*              Tracking/TrkDetDescr
+use  TrkSurfaces                TrkSurfaces-*                   Tracking/TrkDetDescr
+use  TrkEventPrimitives         TrkEventPrimitives-*            Tracking/TrkEvent
+use  EventInfo                  EventInfo-*                     Event
+use  EventInfoMgt               EventInfoMgt-*                  Event
+###use  MuonCondInterface          MuonCondInterface-*             MuonSpectrometer/MuonConditions/MuonCondGeneral
+use  MuonReadoutGeometry        MuonReadoutGeometry-*           MuonSpectrometer/MuonDetDescr
+#use  MuonDigiExample            MuonDigiExample-*               MuonSpectrometer/MuonDigitization
+use  AtlasCLHEP_RandomGenerators AtlasCLHEP_RandomGenerators-*   Simulation/Tools
+
+
+
+
+public
+library MM_Digitization *.cxx components/*.cxx
+apply_pattern component_library
+apply_pattern declare_joboptions files="-s=../share *.txt *.py"
+apply_pattern declare_python_modules files="*.py" 
+#apply_pattern declare_runtime_extras extras="*.rt"
+ 
+apply_tag  ROOTBasicLibs 
+apply_tag  ROOTMathLibs 
+apply_tag  ROOTSTLDictLibs 
+apply_tag  ROOTGraphicsLibs
+apply_tag  ROOTTableLibs 
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/python/MM_DigitizationConfig.py b/MuonSpectrometer/MuonDigitization/MM_Digitization/python/MM_DigitizationConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..bfb13c2cbc15ccb107fd5a1b6b81f5a7c3f6377b
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/python/MM_DigitizationConfig.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+#
+# Import MM_Digitization job properties
+#
+from Digitization.DigitizationFlags import jobproperties
+from AthenaCommon.BeamFlags import jobproperties
+from AthenaCommon import CfgMgr
+from AthenaCommon.AppMgr import ToolSvc, ServiceMgr
+
+# The earliest bunch crossing time for which interactions will be sent 
+# to the MdtDigitizationTool. 
+def MM_FirstXing(): 
+    return -250 
+
+# The latest bunch crossing time for which interactions will be sent 
+# to the MdtDigitizationTool. 
+def MM_LastXing(): 
+    return 200 
+
+def MmDigitizationTool(name="MmDigitizationTool",**kwargs):
+    kwargs.setdefault("RndmSvc", jobproperties.Digitization.rndmSvc() )   
+    # set rndm seeds
+    mmRndm = kwargs.setdefault("RndmEngine","MM_Digitization")
+    jobproperties.Digitization.rndmSeedList.addSeed(mmRndm, 49261510, 105132394 )
+    if jobproperties.Digitization.doXingByXingPileUp():
+        kwargs.setdefault("FirstXing", MM_FirstXing() ) # this should match the range for the MM in Digitization/share/MuonDigitization.py
+        kwargs.setdefault("LastXing",  MM_LastXing() )  # this should match the range for the MM in Digitization/share/MuonDigitization.py
+    kwargs.setdefault("CheckSimHits", True)
+    kwargs.setdefault("InputObjectName", "MicromegasSensitiveDetector")
+    kwargs.setdefault("OutputObjectName", "MM_DIGITS")
+    kwargs.setdefault("OutputSDOName", "MM_SDO")
+    kwargs.setdefault("ValidationSetup", False)
+    ## Strip response
+    kwargs.setdefault("qThreshold", 0.001)
+    kwargs.setdefault("DiffusSigma", 0.036)
+    kwargs.setdefault("LogitundinalDiffusSigma", 0.019)
+    kwargs.setdefault("DriftVelocity", 0.047)
+    kwargs.setdefault("crossTalk1", 0.0)
+    kwargs.setdefault("crossTalk2", 0.0)
+    ## Chip/electronics response
+    kwargs.setdefault("alpha", 2.5)
+    kwargs.setdefault("RC", 20.)
+    
+    return CfgMgr.MmDigitizationTool(name,**kwargs)
+       #return CfgMgr.MM_PileUpTool(name,**kwargs)
+    #else:
+       #return CfgMgr.MdtDigitizationTool(name,**kwargs)
+
+def getMMRange(name="MMRange", **kwargs): 
+    # bunch crossing range in ns 
+    kwargs.setdefault('FirstXing', MM_FirstXing() ) 
+    kwargs.setdefault('LastXing',  MM_LastXing() ) 
+    kwargs.setdefault('CacheRefreshFrequency', 1.0 ) #default 0 no dataproxy reset 
+    kwargs.setdefault('ItemList', ["GenericMuonSimHitCollection#MicromegasSensitiveDetector"] ) 
+    return CfgMgr.PileUpXingFolder(name, **kwargs) 
+
+	
+def MM_Response_DigitTool(name="MM_Response_DigitTool",**kwargs):
+    kwargs.setdefault("RndmSvc", jobproperties.Digitization.rndmSvc())
+    mmRndm = kwargs.setdefault("RndmEngine", "MMResponse")
+    jobproperties.Digitization.rndmSeedList.addSeed(mmRndm, 49261510,105132394 )
+    return CfgMgr.MM_Response_DigitTool(name,**kwargs)
+
+
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/python/MM_DigitizationConfigDb.py b/MuonSpectrometer/MuonDigitization/MM_Digitization/python/MM_DigitizationConfigDb.py
new file mode 100644
index 0000000000000000000000000000000000000000..b99cf5c4996754bd3e7e1a4e6d40d8d3c14af8ab
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/python/MM_DigitizationConfigDb.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+from AthenaCommon.CfgGetter import addTool 
+addTool("MM_Digitization.MM_DigitizationConfig.MmDigitizationTool","MmDigitizationTool")
+addTool("MM_Digitization.MM_DigitizationConfig.MM_Response_DigitTool","MM_Response_DigitTool")
+addTool("MM_Digitization.MM_DigitizationConfig.getMMRange", "MMRange") 
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/share/MicroMegas_Digitization_jobOptions.py b/MuonSpectrometer/MuonDigitization/MM_Digitization/share/MicroMegas_Digitization_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..4ee311ee3a86a270acd2f1fb7d1a55ffbcfa6704
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/share/MicroMegas_Digitization_jobOptions.py
@@ -0,0 +1,31 @@
+include.block ("MM_Digitization/MicroMegas_Digitization_jobOptions.py")
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence() 
+
+from AthenaCommon import CfgGetter
+from Digitization.DigitizationFlags import jobproperties
+
+job += CfgGetter.getAlgorithm("MM_Digitizer/MM_Digitizer", tryDefaultConfigurable=True) 
+from MM_Digitization.MM_DigitizationConf import MmDigitizationTool
+MmDigitizationTool = MmDigitizationTool("MmDigitizationTool", 
+                                        RndmSvc = jobproperties.Digitization.rndmSvc.get_Value(),
+                                        RndmEngine = "MM_Digitization",
+                                        InputObjectName = "MicromegasSensitiveDetector", 
+                                        OutputObjectName = "MM_DIGITS", 
+                                        OutputSDOName = "MM_SDO", 
+                                        CheckSimHits = True,
+                                        ## Strip response
+                                        qThreshold = 0.00000001,
+                                        DiffusSigma = 0.036,
+                                        LogitundinalDiffusSigma = 0.019,
+                                        DriftVelocity = 0.047,
+                                        crossTalk1 = 0.0,
+                                        crossTalk2 = 0.0,
+                                        ## Chip/electronics response
+                                        alpha = 2.5,
+                                        RC = 20.,
+                                        SaveInternalHistos = True,
+                                        qThresholdForTrigger = 2,
+                                        ValidationSetup = False,
+                                        EnergyThreshold = 50,
+                                        OutputLevel = DEBUG)
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/share/postInclude.MicroMegasDigitization.py b/MuonSpectrometer/MuonDigitization/MM_Digitization/share/postInclude.MicroMegasDigitization.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c64715f70c7d4a56f7e4d4644169e94e070f2cc
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/share/postInclude.MicroMegasDigitization.py
@@ -0,0 +1,36 @@
+#########################################################
+#
+# MM_Digitization/postInclude.MicroMegasDigitization.py
+# Nektarios Chr. Benekos
+# This job option should be added via the postInclude
+# command line argument.
+#########################################################
+include.block ("MM_Digitization/postInclude.MicroMegasDigitization.py")
+from Digitization.DigitizationFlags import digitizationFlags
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+if digitizationFlags.doXingByXingPileUp():
+     MMdigitization = job.PileUpToolsAlg.PileUpTools[ "MmDigitizationTool" ]
+else:
+     from MM_Digitization.MM_DigitizationConf import MmDigitizationTool as MMdigitization
+     MMdigitization.RndmSvc = jobproperties.Digitization.rndmSvc.get_Value()
+     MMdigitization.RndmEngine = "MM_Digitization"
+     MMdigitization.InputObjectName = "MicromegasSensitiveDetector" 
+     MMdigitization.OutputObjectName = "MM_DIGITS"
+     MMdigitization.OutputSDOName = "MM_SDO" 
+     MMdigitization.CheckSimHits = True
+     MMdigitization.ValidationSetup = False
+     ## Strip response
+     MMdigitization.qThreshold = 0.00000000001
+     MMdigitization.qThresholdForTrigger = 2.
+     MMdigitization.DiffusSigma = 0.036
+     MMdigitization.LogitundinalDiffusSigma = 0.019
+     MMdigitization.DriftVelocity = 0.047
+     MMdigitization.crossTalk1 = 0.0
+     MMdigitization.crossTalk2 = 0.0
+     ## Chip/electronics response
+     MMdigitization.alpha = 2.5
+     MMdigitization.RC = 20. 
+     MMdigitization.SaveInternalHistos = True
+     MMdigitization.EnergyThreshold = 50
+     MMdigitization.OutputLevel = DEBUG
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/ElectronicsResponse.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/ElectronicsResponse.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2ede48af2e841c892df15fdd2a2f62d723722b04
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/ElectronicsResponse.cxx
@@ -0,0 +1,187 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ *  ElectronicsResponse.cxx
+ *  MC for micromegas athena integration
+ *
+ **/
+//~ 
+/// PROJECTS
+#include "GaudiKernel/MsgStream.h"
+#include "MM_Digitization/ElectronicsResponse.h"
+ 
+/*******************************************************************************/
+ElectronicsResponse::ElectronicsResponse()
+{
+  //stripObject = 0;
+  stripObject = new StripsResponse();
+  m_StripResponse_qThreshold = stripObject->get_qThreshold();
+  m_StripResponse_driftGap = stripObject->get_driftGap();
+  m_StripResponse_driftVelocity = stripObject->get_driftVelocity();
+//  if(stripObject) delete stripObject;
+//  clearValues();
+  alpha = 2.5;
+  RC = 20.0;
+  electronicsThreshold = (m_StripResponse_qThreshold * ( TMath::Power(alpha,alpha)*TMath::Exp(-alpha)) ) ;
+       
+  //---------------------------------------------------------
+   
+  intFn = new TF1("intFn","[3]*TMath::Power((x-[2])/[1],[0])*TMath::Exp(-(x-[2])/[1])", 0, 3*( m_StripResponse_driftGap/m_StripResponse_driftVelocity ) );
+  intFn->SetParameter( 0, alpha);
+  intFn->SetParameter( 1, RC);
+}
+/*******************************************************************************/
+void ElectronicsResponse::clearValues()
+{
+  tMinFromIntegration = -1;
+  tminFromIntegrationAboveThreshold = -1;
+  tMinFromFirstPeak = -1;
+  tStripElectronicsAbThr.clear();
+  qStripElectronics.clear();
+  nStripElectronics.clear();
+}
+/*******************************************************************************/
+MmDigitToolOutput ElectronicsResponse::GetResponceFrom(const MmElectronicsToolInput & digiInput)
+{
+  clearValues();
+  bnlResponceFunction(digiInput.NumberOfStripsPos(), digiInput.chipCharge(), digiInput.chipTime() );
+  /// ToDo: include loop for calculating Trigger study vars
+  // MmDigitToolOutput(bool hitWasEff, std::vector <int> strpos, std::vector<float> time, std::vector<int> charge, int strTrig, float strTimeTrig ):     
+  MmDigitToolOutput tmp(true, nStripElectronics, tStripElectronicsAbThr, qStripElectronics, 5, 0.3);
+  return tmp;
+}
+/*******************************************************************************/
+void ElectronicsResponse::bnlResponceFunction(const vector <int> & numberofStrip, const vector <float> & qStrip, const vector <float> & tStrip){ 
+
+  //int minStrip=1000000, maxStrip=-10000000;
+  //tStripElectronicsAbThr.clear();
+  //nStripElectronics.clear();
+  //qStripElectronics.clear();
+
+  //stripObject = new StripsResponse();
+  //cout << "stripObject->get_qThreshold()" << stripObject->get_qThreshold() << endl;
+  //cout << "m_StripResponse_driftGap" << m_StripResponse_driftGap << endl;
+  //cout << "m_StripResponse_driftVelocity" << m_StripResponse_driftVelocity << endl;
+  
+    
+  for (unsigned int ii = 0; ii < numberofStrip.size(); ii++) {
+    
+    //   cout << "----------for strip number " << numberofStrip.at(ii) << "---------" << endl;
+    //cout << "time max: " << 3*(m_StripResponse_driftGap/m_StripResponse_driftVelocity) << endl;
+    //cout << "charge at (0,50,100,200): " << intFn->Eval(0,0,0) << ", " << intFn->Eval(50,0,0) << ", " << intFn->Eval(100,0,0) << ", " << intFn->Eval(200,0,0) << endl;
+    
+    //find min and max times for each strip:
+    
+    //maxChargeThisStrip = intFn->GetMaximum(0, 3*(m_StripResponse_driftGap/m_StripResponse_driftVelocity), 1.0E-10, 100, false);
+    //maxChargeThisStrip = intFn->GetMaximum(50,300);
+    //maxChargeThisStrip = intFn->GetMaximum(tStrip.at(ii),3*(m_StripResponse_driftGap/m_StripResponse_driftVelocity) );
+    
+
+    //cout << "maxChargeThisStrip(with tmin = tstrip): " << maxChargeThisStrip << endl;
+    
+    double maxChargeThisStrip = 0;
+    double maxChargeLeftNeighbor = 0;
+    double maxChargeRightNeighbor = 0;
+  
+    Athena::MsgStreamMember log("ElectronicsResponse::bnlResponceFunction"); 
+    // find the maximum charge:
+    if ( ii > 0 ) {
+      log << MSG::DEBUG << "for Left neighbor:   tStrip.at(ii-1) "<< tStrip.at(ii-1) << " qStrip.at(ii-1) " << qStrip.at(ii-1) << endreq;    
+      intFn->SetParameter( 2, tStrip.at(ii-1));
+      intFn->SetParameter( 3, qStrip.at(ii-1));
+      maxChargeLeftNeighbor = intFn->GetMaximum(tStrip.at(ii-1),3*(m_StripResponse_driftGap/m_StripResponse_driftVelocity));
+    }
+ 
+    if ( ii+1 < numberofStrip.size() ) {
+      log << MSG::DEBUG << "for Right neighbor:   tStrip.at(ii+1) "<< tStrip.at(ii+1) << " qStrip.at(ii+1) " << qStrip.at(ii+1) << endreq;
+      intFn->SetParameter( 2, tStrip.at(ii+1));
+      intFn->SetParameter( 3, qStrip.at(ii+1));
+      maxChargeRightNeighbor = intFn->GetMaximum(tStrip.at(ii+1),3*(m_StripResponse_driftGap/m_StripResponse_driftVelocity));    
+    }
+
+    if ( ii > 0 ) {
+      log << MSG::DEBUG << "for This strip:    tStrip.at(ii) "<< tStrip.at(ii) << " qStrip.at(ii) " << qStrip.at(ii) << endreq;
+      intFn->SetParameter( 2, tStrip.at(ii));
+      intFn->SetParameter( 3, qStrip.at(ii));
+      maxChargeThisStrip = intFn->GetMaximum(tStrip.at(ii),3*(m_StripResponse_driftGap/m_StripResponse_driftVelocity));
+    }
+    
+    log << MSG::DEBUG << "Check if a strip or its neighbors were above electronics threshold (" << electronicsThreshold << "):   maxChargeLeftNeighbor: " << maxChargeLeftNeighbor << ", maxChargeRightNeighbor: " << maxChargeRightNeighbor << ", maxChargeThisStrip: " << maxChargeThisStrip << endreq; 
+     
+    // Look at strip if it or its neighbor was above threshold:
+    if ( maxChargeLeftNeighbor > electronicsThreshold || maxChargeRightNeighbor > electronicsThreshold || maxChargeThisStrip > electronicsThreshold ) {
+	
+      intFn->SetParameter( 2, tStrip.at(ii));
+      intFn->SetParameter( 3, qStrip.at(ii));
+
+      float localPeak = 0;
+      float localPeakt = 0;
+      float localPeakq = 0;
+
+      float stepSize = 0.1; //ns(?) step size corresponding to VMM discriminator
+
+      for (int jj = tStrip.at(ii); jj < (3*( m_StripResponse_driftGap/m_StripResponse_driftVelocity))/stepSize; jj++) {
+      
+      	//cout << "start looking for local peak: " << endl;
+	
+	
+	float thisStep = jj*stepSize;
+	float nextStep = (jj+1)*stepSize;
+	float oneAfterStep = (jj+2)*stepSize;
+	
+	//cout << "intFn->Eval(thisStep,0,0): " << intFn->Eval(thisStep,0,0) << endl;
+	//cout << "intFn->Derivative(thisStep,0,0.001): " << intFn->Derivative(thisStep,0,0.001) << endl;
+
+	if (localPeak == 0 ) {  //haven't found a local peak yet
+	
+	  //cout << "intFn->Eval(nextStep,0,0): " << intFn->Eval(nextStep,0,0) << endl;
+	  //cout << "intFn->Derivative(nextStep,0,0.001): " << intFn->Derivative(nextStep,0,0.001) << endl;
+	 
+	  //check if the charge for the next points is less than the current step and the derivative of the first point is positive or 0 and the next point is negative:
+	  if ( ( intFn->Eval(thisStep,0,0) < intFn->Eval(nextStep,0,0) ) && ( intFn->Eval(nextStep,0,0) > intFn->Eval(oneAfterStep,0,0) ) &&
+	       (intFn->Derivative(thisStep,0,0.001) > 0 && intFn->Derivative(oneAfterStep,0,0.001) < 0 ) ) {
+	    // && (intFn->Derivative(thisStep,0,0.001)>0 && intFn->Derivative(nextStep,0,0.001)<=0 )
+	    // && (intFn->Eval(oneAfterStep,0,0) < intFn->Eval(nextStep,0,0))
+	  
+
+	    localPeak = 1;  
+	    localPeakt = nextStep;
+	    localPeakq = intFn->Eval(nextStep,0,0);
+	    
+	    log << MSG::DEBUG << "found a peak!    for strip number: " << numberofStrip.at(ii) << " at time: " << nextStep << " with charge: " << intFn->Eval(nextStep,0,0) << endreq;
+	    
+	    nStripElectronics.push_back(numberofStrip.at(ii));
+	    tStripElectronicsAbThr.push_back(localPeakt);
+	    qStripElectronics.push_back(localPeakq);
+            	   
+	  }
+	}
+      }
+    }
+  }
+
+  //---------------------------------------------------------
+  //   /// DUMMY:
+  //   tMinFromFirstPeak = tMinFromIntegration;
+    
+  //   nStripElectronics.push_back(ii);
+  //   tStripElectronicsAbThr.push_back(tMinFromFirstPeak);
+  //   if (maxOfIntegration>=electronicsThreshold) qStripElectronics.push_back(maxOfIntegration);
+  //   else qStripElectronics.push_back(-50000.);
+  // }
+  // tMinFromFirstPeak = 50000.;
+  // for (size_t j = 0;j<tStripElectronicsAbThr.size();j++){
+  //   if (tMinFromFirstPeak>tStripElectronicsAbThr.at(j)) tMinFromFirstPeak = tStripElectronicsAbThr.at(j);
+  // }
+  //delete spectrum;
+}///end of bnl responce function
+/*******************************************************************************/
+ElectronicsResponse::~ElectronicsResponse()
+{ 
+  if (stripObject) delete stripObject;
+  if (intFn) delete intFn;
+  clearValues();
+}
+/*******************************************************************************/
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Digitizer.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Digitizer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7148332e1ac38d521b79b4c761989a1d5830cd55
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Digitizer.cxx
@@ -0,0 +1,44 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/// Gaudi External 
+#include "AthenaBaseComps/AthMsgStreamMacros.h"
+#include "AthenaKernel/errorcheck.h"
+ 
+#include "MuonDigToolInterfaces/IMuonDigitizationTool.h"
+#include "MM_Digitization/MM_Digitizer.h"
+
+/*******************************************************************************/
+MM_Digitizer::MM_Digitizer(const std::string& name, ISvcLocator* pSvcLocator)
+  : AthAlgorithm(name, pSvcLocator),
+    m_digTool("MmDigitizationTool", this )
+{
+  declareProperty("MM_DigitizationTool", m_digTool , "AthAlgTool which performs the MicroMegas digitization");
+}
+
+/*******************************************************************************/
+MM_Digitizer::~MM_Digitizer()  {}
+/*******************************************************************************/
+StatusCode MM_Digitizer::initialize() { 
+  // intitialize store gate active store
+  if (m_digTool.retrieve().isFailure()) {
+    ATH_MSG_FATAL ("MM_Digitizer::Could not retrieve MM Digitization Tool!"); 
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_DEBUG ("MM_Digitizer::Retrieved MM Digitization Tool."); 
+  return StatusCode::SUCCESS;
+    
+}
+/*******************************************************************************/
+StatusCode MM_Digitizer::execute() {
+  ATH_MSG_DEBUG ("MM_Digitizer::in execute()");  
+  return m_digTool->digitize();
+}
+/*******************************************************************************/
+StatusCode MM_Digitizer::finalize() { 
+  ATH_MSG_INFO ("MM_Digitizer::finalize");  
+  return StatusCode::SUCCESS;
+}
+/*******************************************************************************/
+
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Response_DigitTool.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Response_DigitTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..61d7597aa0307be402f2b772fd753687ab051a39
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Response_DigitTool.cxx
@@ -0,0 +1,94 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "GaudiKernel/ToolFactory.h"
+#include "GaudiKernel/MsgStream.h"
+
+#include "StoreGate/StoreGateSvc.h"
+
+#include "MM_Digitization/MmDigitToolInput.h"
+#include "MM_Digitization/MM_Response_DigitTool.h"
+
+
+#include "MuonIdHelpers/MmIdHelper.h"
+#include "MuonReadoutGeometry/MuonDetectorManager.h"
+
+#include "AthenaKernel/IAtRndmGenSvc.h"
+
+#include <iostream>
+#include <vector>
+
+using namespace MuonGM;
+using namespace std;
+/*******************************************************************************/ 
+MM_Response_DigitTool::MM_Response_DigitTool( const std::string& type,
+                                              const std::string& name,
+                                              const IInterface* parent )
+  : AlgTool(type,name,parent)
+  , m_rndmEngine(0)
+  , m_rndmEngineName("MuonDigitization")
+  , m_rndmSvc("AtRndmGenSvc", name )
+{
+  declareInterface<IMM_DigitizationTool>(this); 	
+  declareProperty("RndmSvc",    m_rndmSvc,         "Random Number Service used in Muon digitization" );
+  declareProperty("RndmEngine", m_rndmEngineName,  "Random engine name");
+}
+/*******************************************************************************/
+MmDigitToolOutput MM_Response_DigitTool::digitize( /*const MmDigitToolInput& input*/ )
+{	
+  vector<float> a, b;
+  vector<int> c;  
+  MmDigitToolOutput output(false, c, b, a, 1, 1);
+  return output;
+}
+/*******************************************************************************/ 
+StatusCode MM_Response_DigitTool::initialize()
+{
+  MsgStream log(msgSvc(),name());
+
+  StoreGateSvc* detStore=0;
+  StatusCode status = serviceLocator()->service("DetectorStore", detStore);
+
+  if (status.isSuccess()) {
+    if(detStore->contains<MuonDetectorManager>( "Muon" )){
+      status = detStore->retrieve(m_muonGeoMgr);
+      if (status.isFailure()) {
+        if (log.level()<=MSG::FATAL) log << MSG::FATAL << "Could not retrieve MuonGeoModelDetectorManager!" << endreq;
+        return status;
+      }
+      else {
+        if (log.level()<=MSG::DEBUG) log << MSG::DEBUG << "MuonGeoModelDetectorManager retrieved from StoreGate."<< endreq;
+        //initialize the MdtIdHelper
+        m_idHelper = m_muonGeoMgr->mmIdHelper();
+        if (log.level()<=MSG::DEBUG) log << MSG::DEBUG << "MdtIdHelper: " << m_idHelper << endreq;
+        if(!m_idHelper) return status;
+      }
+    }
+  }
+
+  if (!m_rndmSvc.retrieve().isSuccess())
+    {
+      if (log.level()<=MSG::FATAL) log << MSG::FATAL << " Could not initialize Random Number Service" << endreq;
+      return StatusCode::FAILURE;
+    }     
+	   
+  // getting our random numbers stream
+  if (log.level()<=MSG::DEBUG) log << MSG::DEBUG << "Getting random number engine : <" << m_rndmEngineName << ">" << endreq;
+  m_rndmEngine = m_rndmSvc->GetEngine(m_rndmEngineName);
+  if (m_rndmEngine==0) {
+    if (log.level()<=MSG::FATAL) log << MSG::FATAL << "Could not find RndmEngine : " << m_rndmEngineName << endreq;
+    return StatusCode::FAILURE;
+  }
+	
+  
+  initializeStrip();
+	
+  return StatusCode::SUCCESS;
+}
+/*******************************************************************************/	
+bool MM_Response_DigitTool::initializeStrip(){	  
+  return true;
+}
+/*******************************************************************************/
+ 
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MmDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MmDigitizationTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6c8bac9b6b3485d1ed1db1c0d4d1dde3d17cff3b
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MmDigitizationTool.cxx
@@ -0,0 +1,1069 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// MmDigitizationTool
+// ------------
+// Authors: Nektarios Chr. Benekos <nectarios.benekos@cern.ch>
+//          Konstantinos Karakostas <Konstantinos.Karakostas@cern.ch>
+////////////////////////////////////////////////////////////////////////////////
+
+
+//Inputs
+#include "MuonSimData/MuonSimDataCollection.h"
+#include "MuonSimData/MuonSimData.h"
+ 
+//Outputs
+#include "MuonDigitContainer/MmDigitContainer.h"
+
+//MM digitization includes
+#include "MM_Digitization/MmDigitizationTool.h"
+#include "MM_Digitization/IMM_DigitizationTool.h"
+#include "MM_Digitization/MmDigitToolInput.h"
+#include "MuonSimEvent/MM_SimIdToOfflineId.h"
+
+#include "MuonReadoutGeometry/NSWenumeration.h"
+#include "MuonReadoutGeometry/NSWgeometry.h"
+ 
+//Gaudi - Core
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/AlgFactory.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "PathResolver/PathResolver.h"
+#include "AIDA/IHistogram1D.h"
+#include "EventInfo/TagInfo.h"
+#include "EventInfoMgt/ITagInfoMgr.h"
+
+//Geometry
+#include "MuonReadoutGeometry/MuonDetectorManager.h"
+#include "MuonReadoutGeometry/MMReadoutElement.h"
+#include "MuonReadoutGeometry/MuonChannelDesign.h"
+#include "MuonIdHelpers/MmIdHelper.h"
+#include "MuonSimEvent/MicromegasHitIdHelper.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkEventPrimitives/LocalDirection.h"
+#include "TrkSurfaces/Surface.h"
+
+//Pile-up
+#include "PileUpTools/PileUpMergeSvc.h"
+
+//Truth
+#include "CLHEP/Units/PhysicalConstants.h"
+#include "GeneratorObjects/HepMcParticleLink.h"
+#include "HepMC/GenParticle.h"
+
+//Random Numbers
+#include "AthenaKernel/IAtRndmGenSvc.h"
+#include "CLHEP/Random/RandGauss.h"
+#include "CLHEP/Random/RandFlat.h"
+#include "CLHEP/Random/RandGamma.h"
+#include "CLHEP/Random/RandPoisson.h"
+#include "AtlasCLHEP_RandomGenerators/RandGaussZiggurat.h"
+#include "CLHEP/Random/RandExponential.h"
+
+//ROOT
+#include "TH1.h"
+#include "TTree.h"
+#include "TFile.h"
+
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+
+using namespace MuonGM;
+
+/*******************************************************************************/
+MmDigitizationTool::MmDigitizationTool(const std::string& type, const std::string& name, const IInterface* parent)
+  : PileUpToolBase(type, name, parent)
+  , m_sgSvc("StoreGateSvc", name)
+  , m_digitContainer(NULL)
+  , m_sdoContainer(NULL)
+  , m_digitTool("MM_Response_DigitTool", this)
+  , m_validationSetup(false)
+  , m_energyThreshold(50.)
+  , m_saveInternalHistos(false)
+  , m_thpcMM(0)
+  , m_Polya(0.0)
+  , m_sprob(0)
+  , m_amplification(0.0)
+  , m_StripsResponse(0)
+  , m_qThreshold(0.001) 
+  , m_diffusSigma(0.036)
+  , m_LogitundinalDiffusSigma(0.019)
+  , m_driftVelocity(0.047)
+  , m_crossTalk1(0.)
+  , m_crossTalk2(0.)
+  , m_qThresholdForTrigger(1.)
+  , m_ElectronicsResponse(0)
+  , m_file(0)
+  , m_ntuple(0)
+  , m_AngleDistr(0)
+  , m_AbsAngleDistr(0), m_ClusterLength2D(0), m_ClusterLength(0)
+  , m_mergeSvc(0)
+  , m_inputObjectName("")
+  , m_outputObjectName("")
+  , m_rndmSvc("AtRndmGenSvc", name )
+  , m_rndmEngine(0)
+  , m_rndmEngineName("MuonDigitization")
+{
+
+  declareInterface<IMuonDigitizationTool>(this);
+
+  declareProperty("MaskMultiplet", m_maskMultiplet = 0,  "0: all, 1: first, 2: second, 3: both"  );
+  
+  //Random numbers service               
+  declareProperty("RndmSvc",             m_rndmSvc,            "Random Number Service used in Muon digitization");
+  declareProperty("RndmEngine",          m_rndmEngineName,     "Random engine name");
+  declareProperty("DigitizationTool",    m_digitTool,          "Tool which handle the digitization process");
+  declareProperty("MCStore",             m_sgSvc,              "help");
+
+  //Object names                         
+  declareProperty("InputObjectName",     m_inputObjectName     =  "MicromegasSensitiveDetector");
+  declareProperty("OutputObjectName",    m_outputObjectName    =  "MM_DIGITS");
+  declareProperty("OutputSDOName",       m_outputSDOName       =  "MM_SDO");
+
+  //Configurations
+  declareProperty("CheckSimHits",        m_checkMMSimHits      =  true,       "Control on the hit validity");
+ 
+  //Timing scheme                         
+  declareProperty("UseTimeWindow",       m_useTimeWindow  =  true);
+  declareProperty("WindowLowerOffset",   m_timeWindowLowerOffset = -50.);
+  declareProperty("WindowUpperOffset",   m_timeWindowUpperOffset = +50.);
+  declareProperty("DiffMagSecondMuonHit",m_DiffMagSecondMuonHit = 0.1);
+ 
+  // electronics
+  declareProperty("ns2TDC",              m_ns2TDC = 0.78125, "Conversion factor TDC/ns");
+  declareProperty("ResolutionTDC",       m_resTDC = 0.5, "TDC resolution");
+
+  // Constants vars for the StripsResponse class
+  // qThreshold=2e, we accept a good strip if the charge is >=2e
+  declareProperty("qThreshold",              m_qThreshold = 0.001); 
+  // transverse diffusion (350 μm per 1cm ) for 93:7 @ 600 V/cm, according to garfield      
+  declareProperty("DiffusSigma",             m_diffusSigma = 0.036);    
+  declareProperty("LogitundinalDiffusSigma", m_LogitundinalDiffusSigma = 0.019);
+  // 0.050 drift velocity in [mm/ns], driftGap=5 mm +0.128 mm (the amplification gap)
+  declareProperty("driftGap",                m_driftGap = 5.128);
+  declareProperty("DriftVelocity",           m_driftVelocity = 0.047);  
+  // crosstalk of neighbor strips, it's 15%
+  declareProperty("crossTalk1",		     m_crossTalk1 = 0.0);        
+  // crosstalk of neighbor strips, it's 6%
+  declareProperty("crossTalk2",		     m_crossTalk2 = 0.0); 
+  declareProperty("qThresholdForTrigger",    m_qThresholdForTrigger = 1.0); 
+  
+  // Constants vars for the ElectronicsResponse
+  declareProperty("alpha",                   m_alpha = 2.5);
+  declareProperty("RC",                      m_RC = 20.);
+  declareProperty("electronicsThreshold",    m_electronicsThreshold = 0.000811174);
+   
+  declareProperty("SaveInternalHistos",  m_saveInternalHistos = false   );
+  declareProperty("ValidationSetup",     m_validationSetup = false   );
+  declareProperty("EnergyThreshold",     m_energyThreshold = 50., "Minimal energy to produce a PRD"  );
+
+}
+/*******************************************************************************/
+// member function implementation
+//--------------------------------------------
+StatusCode MmDigitizationTool::initialize() {
+
+  StatusCode status(StatusCode::SUCCESS);
+  ATH_MSG_DEBUG ("MmDigitizationTool:: in initialize()") ;
+  ATH_MSG_DEBUG ( "Configuration  MmDigitizationTool " );
+  ATH_MSG_DEBUG ( "RndmSvc                " << m_rndmSvc             );
+  ATH_MSG_DEBUG ( "RndmEngine             " << m_rndmEngineName      );
+  ATH_MSG_DEBUG ( "MCStore                " << m_sgSvc               );
+  ATH_MSG_DEBUG ( "DigitizationTool       " << m_digitTool           );
+  ATH_MSG_DEBUG ( "InputObjectName        " << m_inputObjectName     );
+  ATH_MSG_DEBUG ( "OutputObjectName       " << m_outputObjectName    );
+  ATH_MSG_DEBUG ( "OutputSDOName          " << m_outputSDOName       );
+  ATH_MSG_DEBUG ( "UseTimeWindow          " << m_useTimeWindow       );
+  ATH_MSG_DEBUG ( "CheckSimHits           " << m_checkMMSimHits      );
+  ATH_MSG_DEBUG ( "ns2TDC                 " << m_ns2TDC              );
+  ATH_MSG_DEBUG ( "ResolutionTDC          " << m_resTDC              );
+  ATH_MSG_DEBUG ( "Threshold              " << m_qThreshold          ); 
+  ATH_MSG_DEBUG ( "DiffusSigma            " << m_diffusSigma 	     );    
+  ATH_MSG_DEBUG ( "LogitundinalDiffusSigma" << m_LogitundinalDiffusSigma );
+  ATH_MSG_DEBUG ( "DriftVelocity          " << m_driftVelocity       );  
+  ATH_MSG_DEBUG ( "crossTalk1             " << m_crossTalk1 	     );        
+  ATH_MSG_DEBUG ( "crossTalk2             " << m_crossTalk2 	     ); 
+  ATH_MSG_INFO ( "ValidationSetup         " << m_validationSetup     );
+  ATH_MSG_INFO ( "EnergyThreshold         " << m_energyThreshold     );
+  
+  // initialize random number generators
+  // then initialize the CSC identifier helper
+  // This method must be called before looping over the hits
+  // to digitize them using the method digitize_hit below
+  m_bunchTime = 0.0;
+
+  // initialize random number generators
+  //  double average_int = 30;  // average interactions per cm
+  //  m_FlatDist = CLHEP::RandFlat::shoot(m_rndmEngine, 0.0,1.0);
+  //  m_GaussDist = CLHEP::RandGauss::shoot(m_rndmEngine,0.0,1.0); 
+  //  m_GammaDist = CLHEP::RandGamma::shoot(m_rndmEngine, (1.0+m_Polya), 1.0);
+  //  m_PoissonDist = CLHEP::RandPoisson::shoot(m_rndmEngine, average_int);
+
+
+  // initialize transient event store
+  if (m_sgSvc.retrieve().isFailure()) {
+    ATH_MSG_FATAL ( "Could not retrieve StoreGateSvc!" );
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_DEBUG ( "Retrieved StoreGateSvc." );
+
+  status = service("ActiveStoreSvc", m_activeStore);
+  if ( !status.isSuccess() ) {
+    ATH_MSG_FATAL ( "Could not get active store service" );
+    return status;
+  }
+
+  // initialize transient detector store and MuonGeoModel OR MuonDetDescrManager 
+  StoreGateSvc* detStore=0;
+  m_MuonGeoMgr=0;
+  status = serviceLocator()->service("DetectorStore", detStore);
+  if (status.isSuccess()) {
+    if(detStore->contains<MuonGM::MuonDetectorManager>( "Muon" )){
+       
+      status = detStore->retrieve(m_MuonGeoMgr);
+      if (status.isFailure()) {
+	ATH_MSG_FATAL ( "Could not retrieve MuonGeoModelDetectorManager!" );
+	return status;
+      }
+      else {
+	ATH_MSG_DEBUG ( "Retrieved MuonGeoModelDetectorManager from StoreGate" );
+	//initialize the MmIdHelper
+	m_idHelper  = m_MuonGeoMgr->mmIdHelper();
+	if(!m_idHelper) return status;
+	ATH_MSG_DEBUG ( "Retrieved MmIdHelper " << m_idHelper );
+      }
+    }
+  }
+  else {
+    ATH_MSG_FATAL ( "Could not retrieve DetectorStore!" );
+    return status;
+  }
+   
+  // check the input object name
+  if (m_inputObjectName=="") {
+    ATH_MSG_FATAL ( "Property InputObjectName not set !" );
+    return StatusCode::FAILURE;
+  }
+  else {
+    ATH_MSG_DEBUG ( "Input objects: '" << m_inputObjectName << "'" );
+  }
+   
+  // check the output object name
+  if (m_outputObjectName=="") {
+    ATH_MSG_FATAL ( "Property OutputObjectName not set !" );
+    return StatusCode::FAILURE;
+  }
+  else {
+    ATH_MSG_DEBUG ( "Output digits: '" << m_outputObjectName << "'" );
+  }
+   
+  //initialize the digit container 
+  try{
+    m_digitContainer = new MmDigitContainer(m_idHelper->detectorElement_hash_max());
+  }
+  catch(std::bad_alloc){
+    ATH_MSG_FATAL ( "Could not create a new MicroMegas DigitContainer!" );
+    return StatusCode::FAILURE;
+  }
+  m_digitContainer->addRef();
+   
+  //simulation identifier helper       
+  muonHelper = MicromegasHitIdHelper::GetHelper();
+   
+  //get the r->t conversion tool
+  status  = m_digitTool.retrieve();
+  if( status.isFailure() ) {
+    ATH_MSG_FATAL("Could not retrieve digitization tool! " << m_digitTool);
+    return StatusCode::FAILURE;
+  }
+  else {
+    ATH_MSG_DEBUG("Retrieved digitization tool!" << m_digitTool);
+  }
+  
+  // initialize inverse lightSpeed (c_light in m/s)
+  m_inv_c_light = 1./(CLHEP::c_light);
+   
+  if (!m_rndmSvc.retrieve().isSuccess()) {
+    ATH_MSG_ERROR("Could not initialize Random Number Service");
+  }     
+   
+  // getting our random numbers stream
+  ATH_MSG_DEBUG ( "Getting random number engine : <" << m_rndmEngineName << ">" );
+  if (!m_rndmSvc.retrieve().isSuccess()){
+    ATH_MSG_ERROR("Could not initialize Random Number Service");
+  }
+  m_rndmEngine = m_rndmSvc->GetEngine(m_rndmEngineName);
+  if (m_rndmEngine==0) {
+    ATH_MSG_ERROR("Could not find RndmEngine : " << m_rndmEngineName );
+    return StatusCode::FAILURE;
+  }
+  
+  //locate the PileUpMergeSvc and initialize our local ptr
+  const bool CREATEIF(true);
+  if (!(service("PileUpMergeSvc", m_mergeSvc, CREATEIF)).isSuccess() || 0 == m_mergeSvc) {
+    ATH_MSG_ERROR ( "Could not find PileUpMergeSvc" );
+    return StatusCode::FAILURE;
+  }
+
+  // StripsResponse Creation
+  m_StripsResponse = new StripsResponse();
+  m_StripsResponse->set_qThreshold(m_qThreshold);
+  m_StripsResponse->set_diffusSigma(m_diffusSigma);
+  m_StripsResponse->set_LogitundinalDiffusSigma(m_LogitundinalDiffusSigma);
+  m_StripsResponse->set_driftGap(m_driftGap);
+  m_StripsResponse->set_driftVelocity(m_driftVelocity); 
+  m_StripsResponse->set_crossTalk1(m_crossTalk1);
+  m_StripsResponse->set_crossTalk2(m_crossTalk2);
+ 
+  m_ElectronicsResponse = new ElectronicsResponse(); 
+  m_ElectronicsResponse->set_alpha(m_alpha);
+  m_ElectronicsResponse->set_RC(m_RC);
+  m_ElectronicsResponse->set_electronicsThreshold(m_electronicsThreshold);
+  
+  //ROOT Staff for internal validation
+  if (m_saveInternalHistos) m_file = new TFile("MM_fullSimu_plots.root","RECREATE");
+  m_ntuple = new TTree("fullSim","fullSim");
+
+  m_ntuple->Branch("exitcode",&exitcode);
+  m_ntuple->Branch("Station_side",&m_n_Station_side);
+  m_ntuple->Branch("Station_eta",&m_n_Station_eta);
+  m_ntuple->Branch("Station_phi",&m_n_Station_phi);
+  m_ntuple->Branch("Station_multilayer",&m_n_Station_multilayer);
+  m_ntuple->Branch("Station_layer",&m_n_Station_layer);
+  
+  m_ntuple->Branch("hitPDGId",&m_n_hitPDGId);
+  m_ntuple->Branch("hitKineticEnergy",&m_n_hitKineticEnergy);
+  m_ntuple->Branch("hitDepositEnergy",&m_n_hitDepositEnergy);
+  m_ntuple->Branch("hitOnSurface_x",&m_n_hitOnSurface_x);
+  m_ntuple->Branch("hitOnSurface_y",&m_n_hitOnSurface_y);
+  m_ntuple->Branch("hitStripID",&m_n_hitStripID);
+  m_ntuple->Branch("hitDistToChannel",&m_n_hitDistToChannel);
+  m_ntuple->Branch("hitIncomingAngle",&m_n_hitIncomingAngle);
+  m_ntuple->Branch("hitIncomingAngleRads",&m_n_hitIncomingAngleRads);
+  
+  m_ntuple->Branch("StrRespID",&m_n_StrRespID);
+  m_ntuple->Branch("StrRespCharge",&m_n_StrRespCharge);
+  m_ntuple->Branch("StrRespTime",&m_n_StrRespTime);
+  m_ntuple->Branch("StrRespTrg_ID",&m_n_StrRespTrg_ID);
+  m_ntuple->Branch("StrRespTrg_Time",&m_n_StrRespTrg_Time);
+  m_ntuple->Branch("Strip_Multiplicity_byDiffer",&m_n_strip_multiplicity);
+  m_ntuple->Branch("Strip_Multiplicity_2",&m_n_strip_multiplicity_2);
+  m_ntuple->Branch("tofCorrection",&tofCorrection);
+  m_ntuple->Branch("bunchTime",&bunchTime);
+  m_ntuple->Branch("globalHitTime",&globalHitTime);
+  
+  m_AngleDistr = new TH1I("m_AngleDistr", "m_AngleDistr", 360, -180., 180.);
+  m_AbsAngleDistr = new TH1I("m_AbsAngleDistr", "m_AbsAngleDistr", 180, 0., 180.);
+  m_ClusterLength2D = new TH1I("m_ClusterLength2D", "m_ClusterLength2D", 100, 0., 100.);
+  m_ClusterLength = new TH1I("m_ClusterLength", "m_ClusterLength", 100, 0., 100.);
+  m_gasGap = new TH1I("m_gasGap", "m_gasGap", 100, 0., 100.);
+  m_gasGapDir = new TH1I("m_gasGapDir", "m_gasGapDir", 20, -10., 10.);
+ 
+  // m_thpcMM->reserve(20000);
+ 
+ 
+  return status;
+}
+/*******************************************************************************/ 
+//----------------------------------------------------------------------
+// PrepareEvent method:
+//----------------------------------------------------------------------
+StatusCode MmDigitizationTool::prepareEvent(unsigned int nInputEvents) {
+
+  ATH_MSG_DEBUG("MmDigitizationTool::prepareEvent() called for " << nInputEvents << " input events" );
+  //m_digitContainer->cleanup();
+  m_MMHitCollList.clear();
+  // if (0 == m_thpcMM) { /*m_thpcMM->reserve(20000);*/  m_thpcMM = new TimedHitCollection<GenericMuonSimHit>();   }
+  //m_thpcMM = new TimedHitCollection<GenericMuonSimHit>();   
+  
+  if(!m_thpcMM) { 
+        m_thpcMM = new TimedHitCollection<GenericMuonSimHit>();
+  }else{
+	ATH_MSG_ERROR ( "m_thpcMM is not null" );
+	return StatusCode::FAILURE;	
+  }
+  
+  //m_MMHitCollList.push_back(NULL);
+  return StatusCode::SUCCESS;
+}
+/*******************************************************************************/
+StatusCode MmDigitizationTool::processBunchXing(int bunchXing,
+						PileUpEventInfo::SubEvent::const_iterator bSubEvents,
+						PileUpEventInfo::SubEvent::const_iterator eSubEvents) {
+
+  ATH_MSG_DEBUG ( "MmDigitizationTool::in processBunchXing()"  << bunchXing );
+  
+  PileUpEventInfo::SubEvent::const_iterator iEvt = bSubEvents;
+ 
+  //loop on event and sub-events for the current bunch Xing
+  for (; iEvt!=eSubEvents; ++iEvt) {
+    StoreGateSvc& seStore = *iEvt->pSubEvtSG;
+    const EventInfo* pEI(0);
+    if (seStore.retrieve(pEI).isSuccess()) {
+      ATH_MSG_INFO( "SubEvt EventInfo from StoreGate " << seStore.name() << " :"
+		    << " bunch crossing : " << bunchXing
+		    << " time offset : " << iEvt->time()
+		    << " event number : " << pEI->event_ID()->event_number()
+		    << " run number : " << pEI->event_ID()->run_number() );
+    }
+ 
+    PileUpTimeEventIndex thisEventIndex = PileUpTimeEventIndex(static_cast<int>(iEvt->time()),iEvt->index());
+      
+    const GenericMuonSimHitCollection* seHitColl = 0;
+    if (!seStore.retrieve(seHitColl,m_inputObjectName).isSuccess()) {
+      ATH_MSG_ERROR ( "SubEvent MicroMegas SimHitCollection not found in StoreGate " << seStore.name() );
+      return StatusCode::FAILURE;
+    }
+    ATH_MSG_VERBOSE ( "MicroMegas SimHitCollection found with " << seHitColl->size() << " hits" );
+    
+    const double timeOfBCID(static_cast<double>(iEvt->time()));
+    ATH_MSG_DEBUG ( "timeOfBCID " << timeOfBCID );
+
+    //Copy hit Collection
+    GenericMuonSimHitCollection* MMHitColl = new GenericMuonSimHitCollection(m_inputObjectName);
+    
+    GenericMuonSimHitCollection::const_iterator i = seHitColl->begin();
+    GenericMuonSimHitCollection::const_iterator e = seHitColl->end();
+ 
+    // Read hits from this collection
+    for (; i!=e; ++i){ 
+      GenericMuonSimHit mmhit(*i);
+      MMHitColl->Insert(mmhit);
+    }
+    m_thpcMM->insert(thisEventIndex, MMHitColl);
+    
+    //store these for deletion at the end of mergeEvent
+    m_MMHitCollList.push_back(MMHitColl);
+ 
+  }//  while (iEvt != eSubEvents) {
+  return StatusCode::SUCCESS;
+}
+
+/*******************************************************************************/
+StatusCode MmDigitizationTool::getNextEvent() {
+
+  // Get next event and extract collection of hit collections:
+  // This is applicable to non-PileUp Event... 
+
+  ATH_MSG_DEBUG ( "MmDigitizationTool::getNextEvent()" );
+   
+  if (!m_mergeSvc) {
+    const bool CREATEIF(true);
+    if (!(service("PileUpMergeSvc", m_mergeSvc, CREATEIF)).isSuccess() ||
+	0 == m_mergeSvc) {
+      ATH_MSG_ERROR ("Could not find PileUpMergeSvc" );
+      return StatusCode::FAILURE;
+    }
+  }
+
+  // initialize pointer
+  //m_thpcMM = 0;
+ 
+  //  get the container(s)
+  typedef PileUpMergeSvc::TimedList<GenericMuonSimHitCollection>::type TimedHitCollList;
+ 
+  //this is a list<info<time_t, DataLink<GenericMuonSimHitCollection> > >
+  TimedHitCollList hitCollList;
+    
+  if (!(m_mergeSvc->retrieveSubEvtsData(m_inputObjectName, hitCollList).isSuccess()) ) {
+    ATH_MSG_ERROR ( "Could not fill TimedHitCollList" );
+    return StatusCode::FAILURE;
+  }  
+  if (hitCollList.size()==0) {
+    ATH_MSG_ERROR ( "TimedHitCollList has size 0" );
+    return StatusCode::FAILURE;
+  }
+  else {
+    ATH_MSG_DEBUG ( hitCollList.size() << " MicroMegas SimHitCollections with key " << m_inputObjectName << " found" );
+  } 
+   
+  // create a new hits collection - Define Hit Collection
+  // m_thpcMM = new TimedHitCollection<GenericMuonSimHit>() ;
+  if(!m_thpcMM) { 
+        m_thpcMM = new TimedHitCollection<GenericMuonSimHit>();
+  }else{
+	ATH_MSG_ERROR ( "m_thpcMM is not null" );
+	return StatusCode::FAILURE;	
+  }
+ 
+  //now merge all collections into one
+  TimedHitCollList::iterator iColl(hitCollList.begin());
+  TimedHitCollList::iterator endColl(hitCollList.end());
+ 
+  // loop on the hit collections
+  while(iColl != endColl) {
+    const GenericMuonSimHitCollection* tmpColl(iColl->second);  
+    m_thpcMM->insert(iColl->first, tmpColl);
+    ATH_MSG_DEBUG ( "MMSimHitCollection found with " << tmpColl->size() << " hits"  );
+    ++iColl; 
+  } 
+  return StatusCode::SUCCESS;
+} 
+/*******************************************************************************/
+StatusCode MmDigitizationTool::mergeEvent() {
+
+  StatusCode status = StatusCode::SUCCESS;
+
+  // ATH_MSG_DEBUG ( "MmDigitizationTool::in mergeEvent()" );
+
+  // Cleanup and record the Digit container in StoreGate
+  status = recordDigitAndSdoContainers();
+  if(!status.isSuccess()) {
+    ATH_MSG_FATAL("MMDigitizationTool::recordDigitAndSdoContainers failed.");
+    return StatusCode::FAILURE; 
+  }
+   
+  status = doDigitization();
+  if (status.isFailure()) { ATH_MSG_ERROR ( "doDigitization Failed" );  return StatusCode::FAILURE; }
+ 
+  // reset the pointer (delete null pointer should be safe)
+  if (m_thpcMM){
+    delete m_thpcMM;
+    m_thpcMM = 0;
+  }
+  
+  // remove cloned one in processBunchXing...... 
+  std::list<GenericMuonSimHitCollection*>::iterator MMHitColl = m_MMHitCollList.begin();
+  std::list<GenericMuonSimHitCollection*>::iterator MMHitCollEnd = m_MMHitCollList.end();
+  while(MMHitColl!=MMHitCollEnd) {
+    delete (*MMHitColl);
+    ++MMHitColl;
+  }
+  m_MMHitCollList.clear(); 
+  return status;
+}
+/*******************************************************************************/
+StatusCode MmDigitizationTool::digitize() {
+  return this->processAllSubEvents(); 
+}
+/*******************************************************************************/
+StatusCode MmDigitizationTool::processAllSubEvents() {
+ 
+  ATH_MSG_DEBUG ("MmDigitizationTool::processAllSubEvents()");
+
+  StatusCode status = recordDigitAndSdoContainers();
+  //if(!status.isSuccess()) {
+  //  ATH_MSG_FATAL("MMDigitizationTool::recordDigitAndSdoContainers failed.");
+  //  return StatusCode::FAILURE; // there are no hits in this event
+  //}
+
+  //ATH_MSG_DEBUG ( "MicroMegas SDO collection (MmSDOCollection) recorded in StoreGate." );
+
+  //merging of the hit collection in getNextEvent method   
+
+  if (0 == m_thpcMM ) {
+    status = getNextEvent();
+    if(status.isFailure()) {
+      ATH_MSG_FATAL( "There are no MicroMegas hits in this event" );
+      return StatusCode::FAILURE;
+    }
+  }
+  
+  status = doDigitization();
+  if(!status.isSuccess()) { 
+    ATH_MSG_ERROR( "MmDigitizationTool :: doDigitization() Failed" );  
+    return StatusCode::FAILURE; 
+  }
+  
+  // reset the pointer (delete null pointer should be safe)
+  if (m_thpcMM){
+    delete m_thpcMM;
+    m_thpcMM = 0;
+  }
+  return StatusCode::SUCCESS;
+}
+/*******************************************************************************/
+StatusCode MmDigitizationTool::finalize() {
+  //ATH_MSG_DEBUG("MMDigitizationTool::finalize() ---- m_digitContainer->digit_size() = "<<m_digitContainer->digit_size() );
+  m_digitContainer->release();
+  
+  if (m_saveInternalHistos) {
+    m_ntuple->Write();
+    m_AngleDistr->Write();
+    m_AbsAngleDistr->Write();
+    m_ClusterLength2D->Write();
+    m_ClusterLength->Write();
+    m_gasGap->Write();
+    m_gasGapDir->Write();
+    m_file->Close();
+  }
+  return StatusCode::SUCCESS;
+}
+/*******************************************************************************/
+StatusCode MmDigitizationTool::recordDigitAndSdoContainers() { 
+ 
+  // cleanup digit container
+  m_digitContainer->cleanup();
+  
+  // record the digit container in StoreGate
+  m_activeStore->setStore(&*m_sgSvc);
+  StatusCode status = m_sgSvc->record(m_digitContainer, m_outputObjectName);
+  if(status.isFailure()) {
+    ATH_MSG_FATAL("Unable to record Micromegas digit container in StoreGate");
+    return status;
+  }else { ATH_MSG_DEBUG("MmDigitContainer recorded in StoreGate.");}
+  
+  // create and record the SDO container in StoreGate
+  m_sdoContainer = new MuonSimDataCollection();
+  status = m_sgSvc->record(m_sdoContainer, m_outputSDOName);
+  if(status.isFailure()) {
+    ATH_MSG_FATAL("Unable to record MM SDO collection in StoreGate");
+    return status;
+  } else { ATH_MSG_DEBUG("MMSDOCollection recorded in StoreGate."); }
+  
+  return status;
+}
+
+/*******************************************************************************/
+StatusCode MmDigitizationTool::doDigitization() {
+
+  
+  GenericMuonSimHitCollection* inputSimHitColl=NULL;
+ 
+  if (m_validationSetup)
+    {  
+      inputSimHitColl = new GenericMuonSimHitCollection("MicromegasSensitiveDetector");
+      StatusCode status = m_sgSvc->record(inputSimHitColl,"InputMicroMegasHits");
+      if (status.isFailure())  {
+	ATH_MSG_ERROR ( "Unable to record Input MicromegasSensitiveDetector HIT collection in StoreGate"  );
+	return status;
+      }
+    }
+        
+  if( m_maskMultiplet == 3 ) {
+   
+    return StatusCode::SUCCESS;
+  }
+ 
+  // Perform null check on m_thpcCSC
+  //   if(!m_thpcMM) {
+  //     ATH_MSG_ERROR ( "m_thpcMM is null" );
+  //     return StatusCode::FAILURE;
+  //   }
+
+  //iterate over hits and fill id-keyed drift time map
+  TimedHitCollection< GenericMuonSimHit >::const_iterator i, e;
+  const GenericMuonSimHit* previousHit = 0;
+   
+  // ATH_MSG_DEBUG("create PRD container of size " << m_idHelper->detectorElement_hash_max()); 
+  std::map<Identifier,int> hitsPerChannel;
+  int nhits = 0;
+
+  // nextDetectorElement-->sets an iterator range with the hits of current detector element , returns a bool when done
+  while( m_thpcMM->nextDetectorElement(i, e) ) {
+        
+    // Loop over the hits:
+    while (i != e) {
+
+      TimedHitPtr<GenericMuonSimHit> phit = *i++;
+      const GenericMuonSimHit& hit(*phit);
+      
+      // SimHits without energy loss are not recorded.
+      // not needed because of already done in sensitive detector
+      // https://svnweb.cern.ch/trac/atlasoff/browser/MuonSpectrometer/MuonG4/MuonG4SD/trunk/src/MicromegasSensitiveDetector.cxx?rev=542333#L65
+      // if(hit.depositEnergy()==0.) continue;
+
+      if( previousHit && abs(hit.particleEncoding())==13 && abs(previousHit->particleEncoding())==13 ) {
+	Amg::Vector3D diff = previousHit->localPosition() - hit.localPrePosition();
+	ATH_MSG_DEBUG("second hit from a muon: prev " <<  previousHit->localPosition() << " current " << hit.localPrePosition() << " diff " << diff );
+	if( diff.mag() < m_DiffMagSecondMuonHit ) continue;
+      }
+      m_n_hitPDGId = hit.particleEncoding();
+      m_n_hitDepositEnergy = hit.depositEnergy();
+      m_n_hitKineticEnergy = hit.kineticEnergy();
+
+      globalHitTime = hit.globalpreTime();
+      tofCorrection = hit.globalPosition().mag()/CLHEP::c_light;
+      bunchTime = globalHitTime - tofCorrection;
+      const float stripPropagationTime = 0.;
+      static const float jitter = 0.;
+      float MMDigitTime = bunchTime + jitter + stripPropagationTime;
+
+      //     ATH_MSG_DEBUG ( "MMDigitTime " << timeOfBCID );
+
+      const float timeWindowStrip = 120.; //driftvelocity gap;
+      if (MMDigitTime < -timeWindowStrip || MMDigitTime > timeWindowStrip) {
+	exitcode = 4; m_ntuple->Fill();
+	continue;
+      }
+  
+      // SimHits without energy loss are not recorded.
+      ///if(hit.depositEnergy()==0. && abs(hit.particleEncoding())!=13) continue;
+
+      m_n_Station_side=-111; m_n_Station_eta=-111; m_n_Station_phi=-111; m_n_Station_multilayer=-111; m_n_Station_layer=-111; m_n_hitStripID=-111; m_n_StrRespTrg_ID=-111;
+      m_n_hitOnSurface_x=-999.; m_n_hitOnSurface_y=-999.; m_n_hitDistToChannel=-999.; m_n_hitIncomingAngle=-999.; m_n_StrRespTrg_Time=-999.;
+      m_n_strip_multiplicity = -999.;
+      exitcode = 0;
+      m_n_StrRespID.clear();
+      m_n_StrRespCharge.clear(); m_n_StrRespTime.clear();
+
+      const int idHit = hit.GenericId();
+      // the G4 time or TOF from IP
+      double G4Time(hit.globalTime());
+      // see what are the members of GenericMuonSimHit
+      const Amg::Vector3D globPos = hit.globalPosition();
+   
+      // convert sim id helper to offline id  
+      muonHelper = MicromegasHitIdHelper::GetHelper();  
+      MM_SimIdToOfflineId simToOffline(*m_idHelper);
+      
+      //get the hit Identifier and info
+      int simId=hit.GenericId();
+      Identifier layid = simToOffline.convert(simId);
+   
+      // Read the information about the Micro Megas hit
+      ATH_MSG_DEBUG ( "> idHit  " << idHit << " Hit bunch time  " << bunchTime << " tot " << globalHitTime << " tof/G4 time " << hit.globalTime() << " globalPosition " << globPos 
+		      << "hit: r " << hit.globalPosition().perp() << " z " << hit.globalPosition().z() << " mclink " << hit.particleLink() << " station eta " << m_idHelper->stationEta(layid) << " station phi " << m_idHelper->stationPhi(layid) << " multiplet " << m_idHelper->multilayer(layid) ); 
+
+      if (m_validationSetup){
+	GenericMuonSimHit* copyHit = new GenericMuonSimHit(idHit, hit.globalpreTime(), hit.globalTime(), hit.globalPosition(), hit.localPosition(), hit.globalPrePosition(), hit.localPrePosition(), hit.particleEncoding(), hit.kineticEnergy(), hit.globalDirection(), hit.depositEnergy(), hit.StepLength(), hit.trackNumber() ); 
+	ATH_MSG_INFO("Validation:  globalHitTime, G4Time, BCtime = "<<globalHitTime<<" "<<G4Time<<" "<<bunchTime << "\n: " << copyHit->print() );
+        inputSimHitColl->Insert(*copyHit);
+      }
+      // Important checks for hits (global time, position along strip, charge, masked chambers etc..) DO NOT SET THIS CHECK TO FALSE IF YOU DON'T KNOW WHAT YOU'RE DOING !
+      if(m_checkMMSimHits) { if(checkMMSimHit(hit) == false) {exitcode = 8; m_ntuple->Fill();continue;} }
+  
+ 
+      // sanity checks
+      if( !m_idHelper->is_mm(layid) ){
+	ATH_MSG_WARNING("MM id is not a mm id! " << m_idHelper->stationNameString(m_idHelper->stationName(layid)) );
+      }		
+				
+      std::string stName = m_idHelper->stationNameString(m_idHelper->stationName(layid));
+      int isSmall = stName[2] == 'S';
+ 
+      if( m_idHelper->is_mdt(layid)|| m_idHelper->is_rpc(layid)|| m_idHelper->is_tgc(layid)|| m_idHelper->is_csc(layid)|| m_idHelper->is_stgc(layid) ){
+	ATH_MSG_WARNING("MM id has wrong technology type! " << m_idHelper->is_mdt(layid) << " " << m_idHelper->is_rpc(layid) << " " << m_idHelper->is_tgc(layid) << " " << m_idHelper->is_csc(layid) << " " << m_idHelper->is_stgc(layid) );
+	exitcode = 9; m_ntuple->Fill();
+      }
+
+      if( m_idHelper->stationPhi(layid) == 0 ){
+	ATH_MSG_WARNING("unexpected phi range " << m_idHelper->stationPhi(layid) );
+	exitcode = 9; m_ntuple->Fill();
+	continue;
+      }
+
+
+      // remove hits in masked multiplet
+      if( m_maskMultiplet == m_idHelper->multilayer(layid) ) continue;
+	
+
+      // get readout element
+      const MuonGM::MMReadoutElement* detEl = m_MuonGeoMgr->getMMReadoutElement(layid);
+      if( !detEl ){
+	ATH_MSG_WARNING( "Failed to retrieve detector element for: isSmall " << isSmall << " eta " << m_idHelper->stationEta(layid) << " phi " << m_idHelper->stationPhi(layid) << " ml " << m_idHelper->multilayer(layid) );
+	exitcode = 10; m_ntuple->Fill();
+	continue;
+      }
+ 
+      // surface
+      const Trk::PlaneSurface& surf = detEl->surface(layid);
+
+      // calculate the inclination angle 
+      //Angle
+      const Amg::Vector3D GloDire(hit.globalDirection().x(), hit.globalDirection().y(), hit.globalDirection().z());
+      Trk::LocalDirection locDire;
+      surf.globalToLocalDirection(GloDire, locDire);
+      float inAngle_XZ = fabs( locDire.angleXZ() / CLHEP::degree);
+      inAngle_XZ = 90. - inAngle_XZ ;
+      //      inAngle_XZ = MM_READOUT [muonHelper->GetLayer(simId)-1]*inAngle_XZ ;
+      ATH_MSG_DEBUG(" At eta " << m_idHelper->stationEta(layid) << " phi " << m_idHelper->stationPhi(layid) <<  "\n IncomingAngle: " <<  locDire.angleXZ() / CLHEP::degree << "\n inAngle_XZ, " << inAngle_XZ << " , " << inAngle_XZ * CLHEP::degree << "   ..   "  << CLHEP::degree );
+ 
+      // compute hit position within the detector element/surfaces
+      // Amg::Transform3D globalToLocal = detEl->absTransform().inverse();
+      Amg::Vector3D hpos(hit.globalPosition().x(),hit.globalPosition().y(),hit.globalPosition().z());
+      // Amg::Vector3D lpos = globalToLocal*hpos;
+      // compute the hit position on the readout plane (same as in MuonFastDigitization)
+      Amg::Vector3D slpos = surf.transform().inverse()*hpos;
+      Amg::Vector2D posOnSurfUnProjected(slpos.x(),slpos.y());
+      
+      // double gasGapThickness = detEl->getDesign(layid)->gasGapThickness();
+      
+      Amg::Vector3D locdir(0., 0., 0.);
+      if (MM_READOUT[m_idHelper->gasGap(layid)-1]==1) locdir = surf.transform().inverse().linear()*Amg::Vector3D(hit.globalDirection().x(), hit.globalDirection().y(), hit.globalDirection().z());
+      else locdir = surf.transform().inverse().linear()*Amg::Vector3D(hit.globalDirection().x(), hit.globalDirection().y(), -hit.globalDirection().z());
+	
+      double scale, scaletop;
+      double gasgap = 5.;
+	   
+      scale = -slpos.z()/locdir.z();
+      scaletop = (gasgap+slpos.z())/locdir.z();
+      // scaletop = (fabs(gasGapThickness) + slpos.z())/locdir.z();
+      	
+      Amg::Vector3D hitOnSurface = slpos + scale*locdir;
+      Amg::Vector3D hitOnTopSurface = slpos + scaletop*locdir;
+      Amg::Vector2D posOnSurf (hitOnSurface.x(), hitOnSurface.y());
+      Amg::Vector2D posOnTopSurf (hitOnTopSurface.x(),hitOnTopSurface.y());
+
+      // account for time offset
+      double shiftTimeOffset = MMDigitTime* m_driftVelocity;
+      Amg::Vector3D hitAfterTimeShift(hitOnSurface.x(),hitOnSurface.y(),shiftTimeOffset);
+      Amg::Vector3D hitAfterTimeShiftOnSurface = hitAfterTimeShift - (shiftTimeOffset/locdir.z())*locdir;
+	
+      ATH_MSG_DEBUG("slpos.z " << slpos.z() << ", locdir " << locdir.z() << ", scale " << scale << ", hitOnSurface.z " << hitOnSurface.z() << ", hitOnTopSurface.z " << hitOnTopSurface.z() );
+
+      if( fabs(hitOnSurface.z()) > 0.1 ) ATH_MSG_WARNING("bad propagation to surface " << hitOnSurface );
+      if( fabs(hitAfterTimeShiftOnSurface.z()) > 0.1 ) ATH_MSG_WARNING("bad propagation to surface after time shift " << hitAfterTimeShiftOnSurface );
+      
+      m_n_Station_side = muonHelper->GetSide(simId);
+      m_n_Station_eta = muonHelper->GetZSector(simId); 
+      m_n_Station_phi = muonHelper->GetPhiSector(simId);
+      m_n_Station_multilayer = muonHelper->GetMultiLayer(simId);
+      m_n_Station_layer = muonHelper->GetLayer(simId); 
+ 
+      if(hit.kineticEnergy()<m_energyThreshold && abs(hit.particleEncoding())==11) {
+      	exitcode = 5;
+      	m_ntuple->Fill();
+      	continue;
+      }
+    
+      // perform bound check
+      if( !surf.insideBounds(posOnSurf) ){
+	exitcode = 1;
+      	m_ntuple->Fill();
+      	continue;
+      }
+  		
+      m_gasGap->Fill(m_n_Station_layer);
+      m_gasGapDir->Fill(MM_READOUT [m_n_Station_layer-1]);
+      
+      int stripNumber = detEl->stripNumber(posOnSurf,layid);
+      int LastStripNumber = detEl->stripNumber(posOnTopSurf, layid);
+      if( stripNumber == -1 ){
+	ATH_MSG_WARNING("!!! Failed to obtain strip number " << m_idHelper->print_to_string(layid) <<  "\n\t\t with pos " << posOnSurf 
+			<< " z " << slpos.z() << " eKin: " << hit.kineticEnergy() << " eDep: " << hit.depositEnergy() << " unprojectedStrip: " << detEl->stripNumber(posOnSurfUnProjected, layid));
+	exitcode = 2; m_ntuple->Fill();
+	continue;
+      }
+      m_n_strip_multiplicity = LastStripNumber - stripNumber;
+            
+      
+      // re-definition of ID
+      Identifier parentID = m_idHelper->parentID(layid);
+      Identifier DigitId = m_idHelper->channelID(parentID, m_idHelper->multilayer(layid), m_idHelper->gasGap(layid), stripNumber);
+      // ATH_MSG_DEBUG(" re-definition of ID; " << m_idHelper->print_to_string(id) );
+			
+      int& counts = hitsPerChannel[DigitId];
+      ++counts;
+      if( counts > 1 ) {exitcode = 11; m_ntuple->Fill(); continue;}
+      ++nhits;
+
+
+      IdentifierHash hash;
+      // contain (name, eta, phi, multiPlet)
+      m_idHelper->get_detectorElement_hash(layid, hash);
+      // ATH_MSG_DEBUG(" looking up collection using hash " << (int)hash << " " << m_idHelper->print_to_string(layid) );
+      
+      const MuonGM::MuonChannelDesign* mmChannelDes = detEl->getDesign(DigitId); 
+      double distToChannel_withStripID = mmChannelDes->distanceToChannel(posOnSurf, stripNumber);
+      double distToChannel = mmChannelDes->distanceToChannel(posOnSurf);
+      ATH_MSG_DEBUG(" looking up collection using hash " << (int)hash << " " << m_idHelper->print_to_string(layid) << " DigitId: " << m_idHelper->print_to_string(DigitId));
+  
+      if ( fabs(distToChannel_withStripID - distToChannel) > mmChannelDes->channelWidth(posOnSurf)) {
+	ATH_MSG_WARNING( "Found: distToChannel_withStripID: " << distToChannel_withStripID << " != distToChannel: " << distToChannel  );
+	exitcode = 12; m_ntuple->Fill();
+	continue;
+      }
+  
+      // ATH_MSG_DEBUG( "Found: distToChannel_withStripID: " << distToChannel_withStripID << " ? distToChannel: " << distToChannel  );
+ 
+      //starting the digitization
+      const Identifier elemId = m_idHelper -> elementID(DigitId); //
+      // ATH_MSG_DEBUG( "executeDigi() - element identifier is: " << m_idHelper->show_to_string(elemId) ); 
+
+      //store local hit position + sign
+      // ATH_MSG_DEBUG( " MmDigitToolInput create... " );
+      const MmDigitToolInput StripdigitInput(stripNumber, distToChannel, inAngle_XZ, 0., detEl->numberOfStrips(layid)); 
+      m_AngleDistr->Fill(inAngle_XZ);
+      m_AbsAngleDistr->Fill(fabs(inAngle_XZ));
+  
+  
+      // digitize input for strip response
+      m_StripsResponse->set_stripWidth(mmChannelDes->channelWidth(posOnSurf));
+      MmDigitToolOutput StripdigitOutput( m_StripsResponse->GetResponceFrom(StripdigitInput) );
+      if(!StripdigitOutput.isValid()) continue;
+      
+      // digitize input for strip response
+      m_StripsResponse->set_stripWidth(mmChannelDes->channelWidth(posOnSurf));
+             
+      // simulate strip response, check if strip fired
+      const std::vector<int> & StripsResponse_stripPos = StripdigitOutput.stripPos();
+      const std::vector<float> & StripsResponse_stripTime = StripdigitOutput.stripTime();
+      const std::vector<float> & StripsResponse_stripCharge = StripdigitOutput.stripCharge();
+      
+      //ATH_MSG_DEBUG("posOnSurf       " << posOnSurf.x() << " " << posOnSurf.y() );
+      //ATH_MSG_DEBUG( " Incoming at: " << stripNumber << " channelWidth: " << mmChannelDes->channelWidth(posOnSurf) << " ? " <<  m_StripsResponse->get_stripWidth());
+      //float maxChargeFound(0.);
+      float firstTimeFound(100000.);
+      float lastTimeFound(0.);
+      int posForTrigger(0), posForLast(0);
+      for (int i=0; i<(int)StripsResponse_stripPos.size(); i++) {
+	if ( (firstTimeFound > StripsResponse_stripTime[i]) && (StripsResponse_stripCharge[i] > m_qThresholdForTrigger)) {firstTimeFound = StripsResponse_stripTime[i]; posForTrigger = i;}
+	if ( (lastTimeFound < StripsResponse_stripTime[i]) && (StripsResponse_stripCharge[i] > m_qThresholdForTrigger)) {lastTimeFound = StripsResponse_stripTime[i]; posForLast = i;}
+	Amg::Vector2D tmpPos (posOnSurf.x()+ (StripsResponse_stripPos[i] - stripNumber )*0.425 , posOnSurf.y());
+	//ATH_MSG_DEBUG( " For: " << i<< " we have :" << StripsResponse_stripPos[i] << "   ?   "<< mmChannelDes->channelNumber(tmpPos) << " with charge: " << StripsResponse_stripCharge[i] << " time: " << StripsResponse_stripTime[i] << " timeForTrig: " << firstTimeFound);
+      }
+      m_n_strip_multiplicity_2 = MM_READOUT [muonHelper->GetLayer(simId)-1]*StripsResponse_stripPos[StripsResponse_stripPos.size()-1] - (-MM_READOUT [muonHelper->GetLayer(simId)-1])*StripsResponse_stripPos[0];
+			
+      //ATH_MSG_DEBUG("Final: MM_READOUT ["<< m_n_Station_layer-1 <<"] "<< MM_READOUT [m_n_Station_layer-1] << "  ??  " << m_n_strip_multiplicity << " from " <<  stripNumber << " to " << LastStripNumber << " while: " << StripsResponse_stripPos[0] << " to " << StripsResponse_stripPos[StripsResponse_stripPos.size()-1]);
+      
+      StripdigitOutput.set_StripForTrigger(StripsResponse_stripPos[posForTrigger]);
+      StripdigitOutput.set_StripTimeForTrigger(StripsResponse_stripTime[posForTrigger]);
+      m_ClusterLength->Fill(StripsResponse_stripPos[StripsResponse_stripPos.size()-1] - StripsResponse_stripPos[0] );
+      m_ClusterLength2D->Fill(StripsResponse_stripPos[posForLast] - StripsResponse_stripPos[posForTrigger]);
+			
+      m_n_hitStripID=stripNumber;
+      m_n_StrRespTrg_ID=StripsResponse_stripPos[posForTrigger];
+      m_n_hitDistToChannel=distToChannel; 
+      m_n_hitIncomingAngle=inAngle_XZ; 
+      m_n_hitIncomingAngleRads = inAngle_XZ * CLHEP::degree;
+      m_n_StrRespTrg_Time=StripsResponse_stripTime[posForTrigger];
+      m_n_hitOnSurface_x=posOnSurf.x();
+      m_n_hitOnSurface_y = posOnSurf.y();
+  		
+      m_n_StrRespID = StripsResponse_stripPos;
+      m_n_StrRespCharge = StripsResponse_stripCharge; 
+      m_n_StrRespTime = StripsResponse_stripTime;
+  		
+      m_ntuple->Fill();
+  		
+      //ATH_MSG_DEBUG( " Cluster length: " << StripsResponse_stripPos[StripsResponse_stripPos.size()-1] - StripsResponse_stripPos[0] );
+			
+      const MmElectronicsToolInput ElectronicDigitInput( StripdigitOutput.stripPos(), StripdigitOutput.stripCharge(), StripdigitOutput.stripTime() );       
+      MmDigitToolOutput ElectronicOutput( m_ElectronicsResponse->GetResponceFrom(ElectronicDigitInput) );
+
+      if(!ElectronicOutput.isValid()) ATH_MSG_WARNING ( "MmDigitizationTool::doDigitization() -- there is no electronics response even though there is a strip response." );
+
+      /* unused variables to prevent compilation warnings */
+      /*
+
+	const std::vector<int> & chipResponsePos = ElectronicOutput.stripPos();
+	const std::vector<float> & chipResponseTime = ElectronicOutput.stripTime();
+	const std::vector<float> & chipResponseCharge = ElectronicOutput.stripCharge(); 
+      */
+      
+      // The collections should use the detector element hashes not the module hashes to be consistent with the PRD granularity. 
+      IdentifierHash detIdhash ;
+      // set RE hash id 
+      int gethash_code = m_idHelper->get_detectorElement_hash(elemId, detIdhash);
+      if (gethash_code != 0) {
+	ATH_MSG_ERROR ( "MmDigitizationTool --  collection hash Id NOT computed for id = " << m_idHelper->show_to_string(elemId) ); 
+	// continue;
+      } 
+      
+      MmDigit*  newDigit = new MmDigit(DigitId, StripdigitOutput.stripTime(), StripdigitOutput.stripPos(), StripdigitOutput.stripCharge(), 
+				       ElectronicOutput.stripTime(),ElectronicOutput.stripPos(),ElectronicOutput.stripCharge(),
+				       StripdigitOutput.stripForTrigger(), StripdigitOutput.stripTimeForTrigger()  );
+      
+      //ATH_MSG_DEBUG ( "strip and chip response digit created" );
+
+      MmDigitCollection* digitCollection = 0;
+ 	
+      // put new collection in storegate
+      // Get the messaging service, print where you are
+      m_activeStore->setStore( &*m_sgSvc );
+      MmDigitContainer::const_iterator it_coll = m_digitContainer->indexFind(detIdhash);
+      if (m_digitContainer->end() ==  it_coll) {
+	digitCollection = new MmDigitCollection(elemId, detIdhash);
+	digitCollection->push_back(newDigit);
+	m_activeStore->setStore( &*m_sgSvc );
+	StatusCode status = m_digitContainer->addCollection(digitCollection, detIdhash);
+	// ATH_MSG_DEBUG ( "MM digitCollection status: " << status );
+	if (status.isFailure()) {
+	  ATH_MSG_ERROR ( "Couldn't record MicroMegas DigitCollection with key=" << detIdhash  << " in StoreGate!" );
+	  // delete  digitCollection;
+	  // digitCollection    = 0 ;
+	  // return StatusCode::RECOVERABLE; // consistent with ERROR message above. 
+	}
+	//else ATH_MSG_DEBUG ( "New MicroMegas DigitCollection with key=" << detIdhash << " recorded in StoreGate." );
+      }
+      else {
+	digitCollection = const_cast<MmDigitCollection*>( it_coll->cptr() );
+	digitCollection->push_back(newDigit);
+      }
+        
+      // fill the SDO collection in StoreGate
+      // create here deposit for MuonSimData, link and tof
+      ///MuonSimData::Deposit deposit(HepMcParticleLink(phit->trackNumber(), phit.eventId()), MuonMCData(G4Time, 0));
+      MuonSimData::Deposit deposit(hit.particleLink(), MuonMCData(hitOnSurface.x(), hitOnSurface.y()));
+      std::vector<MuonSimData::Deposit> deposits;
+      deposits.push_back(deposit);
+      m_sdoContainer->insert(std::make_pair(DigitId, MuonSimData(deposits, inAngle_XZ * CLHEP::degree*1000)));
+         
+      // ATH_MSG_DEBUG( " MmDigitToolInput outsideWindow: " << outsideWindow(m_bunchTime) ); 
+      // it should be decided by bunchtime. -400 to +200
+      // if (outsideWindow(m_bunchTime)) continue;
+
+      //digitCollection = getDigitCollection(elemId);
+      //ATH_MSG_DEBUG ( "Finished MmDigitizationTool::MM digit and SDO stored in the DigitCollection" );
+      previousHit = &hit;
+    }//while(i != e)
+  }//while(m_thpcMM->nextDetectorElement(i, e))
+  // reset the pointer if it is not null
+
+  ATH_MSG_DEBUG ( "MmDigitization Done!"  );
+
+  if (m_thpcMM){
+    delete m_thpcMM;
+    m_thpcMM = 0;
+  }
+	     
+  return StatusCode::SUCCESS;
+} 
+/*******************************************************************************/
+bool MmDigitizationTool::checkMMSimHit( const GenericMuonSimHit& /*hit*/ ) const {
+  // ATH_MSG_DEBUG ("MmDigitizationTool::checkMMSimHit()");
+  /*
+  //get the hit Identifier and info
+  const int simId = hit.GenericId();  
+  std::string stationName = muonHelper->GetStationName(simId);
+  int stationEta = muonHelper->GetZSector(simId);
+  int stationPhi  = muonHelper->GetPhiSector(simId);
+  int multilayer = muonHelper->GetMultiLayer(simId); // mmMultiplet in MmIdHelpers
+  int layer = muonHelper->GetLayer(simId); // mmGasGap in MmIdHelpers
+  int side = muonHelper->GetSide(simId);
+         
+  //  ATH_MSG_VERBOSE("Micromegas hit: r " << hit.globalPosition().perp() << " z " << hit.globalPosition().z() << " mclink " << hit.particleLink()
+  //		  << " stName " << stationName << " eta " << stationEta << " phi " << stationPhi << " ml " << multilayer << " layer " << layer << " side " << side );
+  
+  // the G4 time or TOF from IP
+  double MM_Hit_globalTime = hit.globalTime() ;
+  double MM_Hit_globalPreTime = hit.globalpreTime() ;
+
+  double timeOfFlight = 0.5* ( MM_Hit_globalPreTime - MM_Hit_globalTime );
+
+  // extract the distance to the origin of the module to Time of flight 
+  // Use the coordinate of the center of the module to calculate the time of flight  
+  Amg::Vector3D distance = 0.5* ( hit.globalPrePosition() + hit.globalPosition() );
+  double m_time = timeOfFlight/CLHEP::ns - distance.mag()/CLHEP::c_light/CLHEP::ns;
+ 
+  ATH_MSG_VERBOSE(     "Micromegas hit  "
+  << " MM_Hit_globalPreTime ["  << MM_Hit_globalPreTime  << "]"
+  << " MM_Hit_globalTime ["  << MM_Hit_globalTime  << "]" 
+  << " timeOfFlight ["   << timeOfFlight  << "]"
+  << " point  ["        << distance       << "]"
+  << " m_time ["         << m_time     << "]" );
+  */
+  
+  return true;
+}     
+/*******************************************************************************/
+int MmDigitizationTool::digitizeTime(double time) const {
+
+  int    tdcCount;
+  double tmpCount = time/m_ns2TDC;
+  double rand = CLHEP::RandGaussZiggurat::shoot(m_rndmEngine, tmpCount, m_resTDC);
+  tdcCount = static_cast<long>(rand);
+   
+  if (tdcCount < 0 || tdcCount > 4096){
+    //ATH_MSG_DEBUG( " Count outside TDC window: " << tdcCount );
+  }
+   
+  return tdcCount;
+}
+/*******************************************************************************/
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/StripsResponse.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/StripsResponse.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0839204f7d1e23d92f5a3ea91a97e8b627a92fc0
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/StripsResponse.cxx
@@ -0,0 +1,319 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ *  StripsResponse.cxx
+ *  MC for micromegas athena integration
+ *
+ **/
+
+/// PROJECTS
+#include "MM_Digitization/StripsResponse.h"
+#include "GaudiKernel/MsgStream.h"
+/*******************************************************************************/
+StripsResponse::StripsResponse():
+  qThreshold(0.001), 
+  diffusSigma(0.360/10.),
+  LogitundinalDiffusSigma(0.190/10.),
+  pitch(0.500),
+  stripwidth(pitch - 0.0),
+  polya(0),
+  conv_gaus(0),
+  driftGap(5.128),
+  driftVelocity(0.047),
+  gRandom_loc(0),
+  randomNum(0)
+{
+  clearValues();
+  initializationFrom();
+}
+/*******************************************************************************/
+void StripsResponse::initHistos()
+{
+  // For validation purposes only...
+}
+/*******************************************************************************/
+void StripsResponse::writeHistos()
+{}
+/*******************************************************************************/
+void StripsResponse::initFunctions()
+{
+  polya  = new TF1("polya","(1./[1])*(TMath::Power([0]+1,[0]+1)/TMath::Gamma([0]+1))*TMath::Power(x,[0])*TMath::Exp(-([0]+1)*x)", 0., 4.);
+  conv_gaus  = new TF1("conv_gaus","1.*TMath::Exp(-TMath::Power(x,2.)/(2.*[0]*[0])) + 0.001*TMath::Exp(-TMath::Power(x,2)/(2.*[1]*[1]))", -1., 1.);
+  Athena::MsgStreamMember log("tripsResponse_uM::initFunctions");
+  log << MSG::DEBUG << "tripsResponse_uM::initFunctions DONE" << endreq;
+  // if(msgLevel(MSG::DEBUG)) msg(MSG::DEBUG) << "\t \t StripsResponse::initFunctions DONE " << endreq;
+}
+/*******************************************************************************/
+void StripsResponse::clearValues()
+{
+  /// Delete Gen:
+  if (conv_gaus !=0) delete conv_gaus;
+  if (polya !=0) delete polya;
+  if (gRandom_loc !=0) delete gRandom_loc;
+}
+/*******************************************************************************/
+void StripsResponse::initializationFrom()
+{
+  crossTalk1=0.0;
+  crossTalk2=0.0;
+  Lorentz_Angle = 0.0;
+
+  initHistos ();
+  initFunctions();
+  randomNum = new TRandom3(1);
+  randomNum->SetSeed(1);
+
+  Athena::MsgStreamMember log("StripsResponse::initializationFrom");
+  log << MSG::DEBUG << "StripsResponse::initializationFrom set values" << endreq;
+  polya->SetParameter(0, 2.3);
+  polya->SetParameter(1, 1.);
+  log << MSG::DEBUG << "StripsResponse::initializationFrom getRandom: " << polya->GetRandom() << endreq;
+}
+/*******************************************************************************/
+void StripsResponse::testRandomNumGens(UInt_t sd)
+{
+  TRandom3 *randomNum_ = new TRandom3(1);
+  TRandom *rsave = gRandom;
+  TRandom *r0 = new TRandom(1);
+  Athena::MsgStreamMember log("StripsResponse::testRandomNumGens"); 
+  rsave->Clear();
+  r0->Clear();
+  r0->SetSeed(1);
+  gRandom->Clear();
+  gRandom->SetSeed(sd);//always the same random numbers !!!
+  rsave->SetSeed(1);//always the same random numbers !!!
+  printf("Seeds a: %d | %d | %d\n", gRandom->GetSeed(), rsave->GetSeed(), r0->GetSeed());
+  float pt_ = gRandom->Uniform();
+  float pt = rsave->Uniform();
+  float pt0 = r0->Uniform();
+  for (int i=0; i< 6; i++) {
+    pt_ = gRandom->Uniform();
+    pt = rsave->Uniform();
+    pt0 = r0->Uniform();
+
+    log << MSG::DEBUG <<"\tpt <> " << randomNum_->Uniform() << "  " << pt << "  " << pt_ << "  " << pt0 << " | " << gRandom->GetSeed() << endreq;
+    log << MSG::DEBUG << gRandom->GetSeed() << "  " << randomNum_->GetSeed() << endreq;
+  }
+  log << MSG::DEBUG << gRandom->GetSeed() << "  " << randomNum_->GetSeed() << endreq;
+}
+/*******************************************************************************/
+MmDigitToolOutput StripsResponse::GetResponceFrom(const MmDigitToolInput & digiInput)
+{
+  Athena::MsgStreamMember log("StripsResponse::GetResponceFrom"); 
+  log << MSG::DEBUG << "\t \t StripsResponse::GetResponceFrom start " << endreq;
+
+  /// Reduce internal calls of functions
+  calculateResponceFrom(digiInput.positionWithinStrip() , digiInput.stripIDLocal() , digiInput.incomingAngle() , digiInput.stripMaxID() );
+  
+  log << MSG::DEBUG << "\t \t StripsResponse::GetResponceFrom MmDigitToolOutput create " << endreq;
+  /// ToDo: include loop for calculating Trigger study vars
+ 
+  // MmDigitToolOutput(bool hitWasEff, std::vector <int> strpos, std::vector<float> time, std::vector<int> charge, int strTrig, float strTimeTrig ): 
+  MmDigitToolOutput tmp(true, finalNumberofStrip, finaltStrip, finalqStrip, 5, 0.3);
+  log << MSG::DEBUG << "StripsResponse::GetResponceFrom -> hitWasEfficient(): " << tmp.hitWasEfficient() << endreq;
+  return tmp;
+}
+/*******************************************************************************/
+void StripsResponse::calculateResponceFrom(const float & hitx, const int & stripID, const float & thetaD, const int & stripMaxID) /// <-------- stripID!!!
+{
+  Athena::MsgStreamMember log("StripsResponse::calculateResponceFrom"); 
+  log << MSG::DEBUG << "\t \t StripsResponse::calculateResponceFrom start " << endreq;
+  finalNumberofStrip.clear();
+  finalqStrip.clear();
+  finaltStrip.clear();
+  crossTalk1=0.0;
+  crossTalk2=0.0;
+  Lorentz_Angle = 0.0;
+  log << MSG::DEBUG << "\t \t StripsResponse::calculateResponceFrom call whichStrips " << endreq;
+  whichStrips(hitx, stripID, thetaD, stripMaxID);
+}
+//__________________________________________________________________________________________________
+//==================================================================================================
+// calculate the strips that got fired, charge and time. Assume any angle thetaD....
+//==================================================================================================
+void StripsResponse::whichStrips(const float & hitx, const int & stripID, const float & thetaD, const int & stripMaxID){
+
+  dimClusters=7000; //dimClusters=total number of collisions
+  MaxPrimaryIons = 300; 
+  pt=0.;
+  xx=0.;
+  xxDiffussion=0.;
+  yy=0.; 
+  yyDiffussion=0.;
+  
+  // NelectronProb has the probability that a primary ionization cluster
+  float NelectronProb[23]={65.6,80.6,87.0,90.5,92.75,94.30,95.35,96.16,96.77,97.26,
+			   97.65,97.95,98.20,98.40,98.56,98.68,98.775,98.850,98.913,98.967,99.016,99.061,99.105};
+  
+  lmean = 10./26.;  //  24 e/8 mm or 23 e/10mm (as it has been used here) according to Sauli's paper, for Argon
+
+  float theta = thetaD*TMath::Pi()/180.0, xoff=0.;
+  
+
+  //define the polya distribution to get the flactuations of the charges...
+  //  Double_t polya_alpha=1., polya_beta=(0.02-1.)/4., temp_polya, polya_theta=0.43;
+  polya_theta=2.3;
+
+  //name, name of the above C++ function, min,max, number of parameters (a,b)
+  //Initialize parameters
+  polya->SetParameter(0, polya_theta);
+  polya->SetParameter(1, 1.);
+
+  // zero charge,  time of primary ionization clusters etc
+  l.clear(); l.resize(dimClusters, 0.);
+  clusterelectrons.clear(); clusterelectrons.resize(dimClusters, 0.);
+  qstrip.clear(); qstrip.resize(dimClusters, 0.);
+  time.clear(); time.resize(dimClusters, 0.);
+  cntTimes.clear(); cntTimes.resize(dimClusters, 0.);
+  firstq.clear(); firstq.resize(dimClusters, 0.);
+  ll = 0;
+  totalelectrons = 0;
+  primaryion = 0;
+ 
+  // Now generate the primary ionization colisions, Poisson distributed
+  while (ll<driftGap/TMath::Cos(theta)){
+    pt = randomNum->Uniform();
+    ll = ll-lmean*log(pt);
+    if (ll>driftGap/TMath::Cos(theta)) break; // if you exceed the driftGap, go out...
+    l[primaryion]=ll;
+    pt = 100.0*randomNum->Uniform();
+    // Use the Nelectron probability to calculate number of electrons per collision
+    
+    float limProb1=NelectronProb[22], limProb2;
+    
+    for (int k = 0; k<dimClusters; k++){
+      
+      if (k<23) {
+        if (pt <= NelectronProb[0]) {
+          clusterelectrons[primaryion] = clusterelectrons[primaryion] + k + 1;
+          totalelectrons = totalelectrons + clusterelectrons[primaryion];
+          break;
+        } else
+          if (pt <= NelectronProb[k] && pt > NelectronProb[k-1]){
+            clusterelectrons[primaryion] = clusterelectrons[primaryion] + k + 1;
+            totalelectrons = totalelectrons + clusterelectrons[primaryion];
+            break;
+          }
+      } else {
+        // more probabilities according to Fischle paper
+        limProb2 = limProb1 + 21.6/((k)*(k));
+        if (pt <= limProb2 && pt > limProb1){
+          clusterelectrons[primaryion] = clusterelectrons[primaryion] + k + 1;
+          totalelectrons = totalelectrons + clusterelectrons[primaryion];
+          break;
+        }
+        
+        limProb1 = limProb2;
+      }
+    }// end of loop for total cluster ionization
+    
+    primaryion = primaryion + 1;
+    if (primaryion >= MaxPrimaryIons) break; //don't create more than "MaxPrimaryIons" along a track....
+  }//end of clusters loop
+  for (int m=0; m<primaryion; m++){    
+    yy = l[m]*cos(theta);  // path of the drifted electrons
+    for(int j=1;j<=clusterelectrons[m];j++){
+      //
+      //===================================================
+      // calculate the new charge due to the Polya fluctiation of the avalanche
+      // do this for each electron separately rather than the full cluster (by George Iakovidis)
+      temp_polya = polya->GetRandom();
+      //===================================================
+      //
+      yyDiffussion = randomNum->Gaus(yy, LogitundinalDiffusSigma*yy); // insert longitundinal diffusion of electron
+      if(diffusSigma==0 || LogitundinalDiffusSigma==0) conv_gaus->SetParameters(diffusSigma*yy, 0.0);
+      else conv_gaus->SetParameters(diffusSigma*yy, 1.0);
+
+      float temp_gaus_conv = conv_gaus->GetRandom();
+      xxDiffussion = hitx + l[m]*sin(theta) + temp_gaus_conv;// insert transverese diffusion of electron
+
+      xx = xxDiffussion + TMath::Tan(Lorentz_Angle * TMath::Pi()/180.)*yyDiffussion;
+
+      nstrip = xx/(stripwidth+(pitch-stripwidth));
+      if (xx<0) nstrip = nstrip - 1;
+      nstrip = nstrip + stripID;
+
+      if (xx-hitx>l[m]*sin(theta)) {
+        xoff = xx-(hitx+l[m]*sin(theta));
+      } else {
+        xoff = (hitx+l[m]*sin(theta))-xx;
+      }
+      numberOfElectrons = 1.0*temp_polya;//single electron fluctuation
+      numberofStrip.push_back(nstrip);  qStrip.push_back(numberOfElectrons); tStrip.push_back(TMath::Sqrt(yyDiffussion*yyDiffussion+xoff*xoff)/driftVelocity);
+    }
+
+    // for each charge, assigne a crosstalk to the two neighbor strips... crossTalk1 for the strip+-1 and crossTalk2 for the strip+-2
+    // do strip+-1 crosstalk only if it is greater than 0% (by George Iakovidis)
+    if (crossTalk1 > 0.0) {
+      if (nstrip-1>-1) {
+        numberofStrip.push_back(nstrip-1);  qStrip.push_back(crossTalk1*numberOfElectrons);
+        tStrip.push_back(TMath::Sqrt(yyDiffussion*yyDiffussion+xoff*xoff)/driftVelocity);
+      }
+      if (nstrip+1>-1) {
+        numberofStrip.push_back(nstrip+1);  qStrip.push_back(crossTalk1*numberOfElectrons);
+        tStrip.push_back(TMath::Sqrt(yyDiffussion*yyDiffussion+xoff*xoff)/driftVelocity);
+      }
+    }
+    // do strip+-2 crosstalk only if it is greater than 0% (by George Iakovidis)
+    if (crossTalk2 > 0.0) {
+      if (nstrip-2>-1) {
+        numberofStrip.push_back(nstrip-2);  qStrip.push_back(crossTalk2*numberOfElectrons);
+        tStrip.push_back(TMath::Sqrt(yyDiffussion*yyDiffussion+xoff*xoff)/driftVelocity);
+      }
+      if (nstrip+2>-1) {
+        numberofStrip.push_back(nstrip+2);  qStrip.push_back(crossTalk2*numberOfElectrons);
+        tStrip.push_back(TMath::Sqrt(yyDiffussion*yyDiffussion+xoff*xoff)/driftVelocity);
+      }
+    }
+    // end of crosstalk assignemnt
+    
+  }
+  //calculate the time per strip, in case you cross the qThreshold=2e-
+  nstrip = 0;
+  for (size_t ii = 0; ii<numberofStrip.size(); ii++){
+    nstrip = numberofStrip.at(ii);
+    if (qstrip[nstrip] == 0) firstq[nstrip] = 0;
+    qstrip[nstrip] = qstrip[nstrip] + qStrip.at(ii);
+
+    // find the strip that receives charge above the qThreshold, assign as time the mean time of the arriving e
+    if ((qstrip[nstrip] > 0.0 && firstq[nstrip] == 0 && qstrip[nstrip]<qThreshold) ||
+	(qstrip[nstrip] > 0.0 && firstq[nstrip] == 0 && qstrip[nstrip]>=qThreshold && cntTimes[nstrip]>=0.)) {
+      time[nstrip] = time[nstrip] + tStrip.at(ii);
+      cntTimes[nstrip] = cntTimes[nstrip]+1;
+    }
+    if (qstrip[nstrip]>=qThreshold && firstq[nstrip] == 0) {
+      time[nstrip] = time[nstrip]/cntTimes[nstrip];
+      firstq[nstrip] = 1;
+      cntTimes[nstrip]=0;
+      stripNumber.push_back(nstrip);     // record the strip number that got a hit for 1rst time...
+    }
+  }
+  
+  int minStripEv=1000000, maxStripEv=-10000000;
+  for (size_t ii = 0; ii<numberofStrip.size(); ii++){
+    if (qStrip.at(ii)<qThreshold) {continue;}
+    if (minStripEv>=numberofStrip.at(ii)) { minStripEv=numberofStrip.at(ii);}
+    if (maxStripEv<=numberofStrip.at(ii)) { maxStripEv=numberofStrip.at(ii);}
+  }
+  for (int ii=minStripEv; ii<=maxStripEv; ii++) {
+    if ( qstrip[ii]==0 || qstrip[ii]<qThreshold) {  continue;}   // bad strip... ignore it...
+    if ( ii > stripMaxID || ii == 0 ) continue; // do not consider strips outside allowed range, i.e. outside chamber
+    
+    finalNumberofStrip.push_back(ii); finalqStrip.push_back(qstrip[ii]); finaltStrip.push_back(time[ii]); 
+  }
+
+  //
+  //****************************************************************************
+  // end of debug=10, plot the pulse of the strip... qStrip vs strip number
+  //****************************************************************************
+  //
+  numberofStrip.clear(); qStrip.clear(); tStrip.clear();
+} // end of whichStrips()
+/*******************************************************************************/
+StripsResponse::~StripsResponse()
+{
+  clearValues();
+}
+/*******************************************************************************/
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/components/MM_Digitization_entries.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/components/MM_Digitization_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9d856cfddfb44ea7ca6658f1fb4a1b910b71b534
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/components/MM_Digitization_entries.cxx
@@ -0,0 +1,16 @@
+#include "GaudiKernel/DeclareFactoryEntries.h" 
+#include "MM_Digitization/MmDigitizationTool.h"
+#include "MM_Digitization/MM_Digitizer.h"
+#include "MM_Digitization/MM_Response_DigitTool.h"
+#include "AthenaKernel/IAtRndmGenSvc.h"
+
+DECLARE_ALGORITHM_FACTORY( MM_Digitizer )
+
+DECLARE_TOOL_FACTORY( MM_Response_DigitTool )
+DECLARE_TOOL_FACTORY( MmDigitizationTool )
+
+DECLARE_FACTORY_ENTRIES(MM_Digitization) {
+    DECLARE_ALGORITHM( MM_Digitizer )
+    DECLARE_TOOL( MM_Response_DigitTool )
+    DECLARE_TOOL( MmDigitizationTool )
+}
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/components/MM_Digitization_load.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/components/MM_Digitization_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a4418a12d1ce5e43632e7b0ac7b5847cf626099a
--- /dev/null
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/components/MM_Digitization_load.cxx
@@ -0,0 +1,3 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(MM_Digitization)