diff --git a/core/data/trd/CbmTrdCluster.cxx b/core/data/trd/CbmTrdCluster.cxx
index 0c49524486df0e9e5158395b273e56cca963bf1c..eca15855aa491ce6782950eb981a2a77f2dbce1e 100644
--- a/core/data/trd/CbmTrdCluster.cxx
+++ b/core/data/trd/CbmTrdCluster.cxx
@@ -140,7 +140,12 @@ Int_t CbmTrdCluster::IsChannelInRange(Int_t ch) const
 Bool_t CbmTrdCluster::Merge(CbmTrdCluster* second)
 {
   if (GetRow() != second->GetRow()) return kFALSE;
-  if (TMath::Abs(second->fStartTime - fStartTime) > 20) return kFALSE;
+  // time difference condition
+  if (fNCols == 1 || second->fNCols == 1) {
+    if (TMath::Abs(second->fStartTime - fStartTime) > 50) return kFALSE;
+  }
+  else if (TMath::Abs(second->fStartTime - fStartTime) > 20)
+    return kFALSE;
   // look before current
   if (second->fStartCh + second->fNCols == fStartCh && !second->HasOpenStop() && !HasOpenStart()) {
     //     cout<<"Merge before with "<<second->ToString();
diff --git a/core/data/trd/CbmTrdHit.cxx b/core/data/trd/CbmTrdHit.cxx
index 1a23ab122168ec4d646db89ff5d75ac6888bc81b..0006a58fd3f4fe5be425d3aafaa0f39d1f4ebecf 100644
--- a/core/data/trd/CbmTrdHit.cxx
+++ b/core/data/trd/CbmTrdHit.cxx
@@ -18,7 +18,7 @@
 using std::endl;
 using std::stringstream;
 
-CbmTrdHit::CbmTrdHit() : CbmPixelHit(), fDefine(0), fELoss(-1.)
+CbmTrdHit::CbmTrdHit() : CbmPixelHit(), fDefine(0), fNeighborId(-1), fELoss(-1.)
 {
   SetType(kTRDHIT);
   SetTime(-1);
@@ -29,6 +29,7 @@ CbmTrdHit::CbmTrdHit(Int_t address, const TVector3& pos, const TVector3& dpos, D
                      Double_t eLoss, Double_t time, Double_t timeError)
   : CbmPixelHit(address, pos, dpos, dxy, refId)
   , fDefine(0)
+  , fNeighborId(-1)
   , fELoss(eLoss)
 {
   SetType(kTRDHIT);
diff --git a/core/data/trd/CbmTrdHit.h b/core/data/trd/CbmTrdHit.h
index 5b24930c02bc6c8e1538885eb90779dcf1423b56..a8b3d5e7904bff5c214c3b0a0334253b34c758f0 100644
--- a/core/data/trd/CbmTrdHit.h
+++ b/core/data/trd/CbmTrdHit.h
@@ -80,6 +80,7 @@ public:
   Bool_t GetMaxType() const { return TESTBIT(fDefine, kMaxType); }
   Bool_t HasOverFlow() const { return TESTBIT(fDefine, kOvfl); }
   Bool_t IsRowCross() const { return TESTBIT(fDefine, kRowCross); }
+  Bool_t IsUsed() const { return (GetRefId() < 0); }
 
   /** Setters **/
   void SetELoss(Double_t loss) { fELoss = loss; }
@@ -94,9 +95,10 @@ public:
 
 private:
   UChar_t fDefine;    // hit extra info
+  Int_t fNeighborId;  // refId in case of row cross clusters
   Double32_t fELoss;  // Energy deposit due to TR + dEdx
 
-  ClassDef(CbmTrdHit, 3);
+  ClassDef(CbmTrdHit, 4);
 };
 
 #endif
diff --git a/core/detectors/trd/CbmTrdParModGas.cxx b/core/detectors/trd/CbmTrdParModGas.cxx
index e65fa1c3eeed740deb0483aa9bb0a4858ccccc67..61e97f6f2a515999a5d887d09d502752f076b976 100644
--- a/core/detectors/trd/CbmTrdParModGas.cxx
+++ b/core/detectors/trd/CbmTrdParModGas.cxx
@@ -118,6 +118,33 @@ Float_t CbmTrdParModGas::EkevFC(Float_t ekev) const
   //   return (sFASP-s0FASP)/gFASP;
 }
 
+//_______________________________________________________________________________________________
+Float_t CbmTrdParModGas::EfCkeV(Float_t efC) const
+{
+  /** Convert energy deposit to no of primary ionisations and apply gas gain.
+  * Currently gas gain is evaluated from 55Fe spectrum analysis on ArCO2(80/20)
+  */
+
+  Int_t gasId = GetNobleGasType() - 1;
+  Float_t wi  = (1. - fPercentCO2) * fgkWi[gasId] + fPercentCO2 * fgkWi[2];
+
+  //gas gain
+  // G = G[ev->ADC] * wi[ArCO2]/C[mV->ADC]/A[fC->mV]/e
+  // G[ev->ADC] : measured gain based on 55Fe spectrum (expo)
+  // wi[ArCO2]  : average energy to produce a ele-ion pair in mixture (27.24 ev)
+  // C[mV->ADC] : FASP out [2V] to ADC range [4096 ch] (2)
+  // A[fC->mV]  : FASP gain from CADENCE (6)
+  // e : 1.6e-4 [fC] electric charge
+  Double_t gain = 170.25 * TMath::Exp(fgkGGainUaPar[0] + fgkGGainUaPar[1] * fUa * 1.e-3)
+                  / 12.;  // for Xe correct Ar gain measurements TODO
+  if (gasId == 0) gain *= 0.6;
+
+  Float_t ekev = efC * wi / gain / 0.16;
+  if (VERBOSE)
+    printf("        ua[V]=%d gain[%5.2e] wi[eV]=%5.2f :: E[keV]=%6.3f E[fC]=%6.2f\n", fUa, gain, wi, ekev, efC);
+  return ekev;
+}
+
 //_______________________________________________________________________________________________
 Int_t CbmTrdParModGas::GetShellId(const Char_t shell) const
 {
diff --git a/core/detectors/trd/CbmTrdParModGas.h b/core/detectors/trd/CbmTrdParModGas.h
index 3a2c7efaddfc5abe0947299c89d9ee41c9955f53..b98d0d344d1f3936bfab7022ceff2e9701b40a97 100644
--- a/core/detectors/trd/CbmTrdParModGas.h
+++ b/core/detectors/trd/CbmTrdParModGas.h
@@ -49,6 +49,11 @@ public:
    * \return charge at FASP input in fC
    */
   Float_t EkevFC(Float_t ekev) const;
+  /** \brief Convert pad-plane charge in fC to energy deposit [keV] taking into account the gas gain
+   * \param[in] efc charge in fC 
+   * \return energy deposit in keV
+   */
+  Float_t EfCkeV(Float_t efc) const;
   TString GetFileName() const { return fFileNamePID; }
   Double_t GetNobleGas() const { return 1. - fPercentCO2; }
   const Char_t* GetNobleGasName() const { return (GetNobleGasType() - 1 ? "Ar" : "Xe"); }
diff --git a/macro/trd/geometry/trd.v18/Create_TRD_Geometry_v18b.C b/macro/trd/geometry/trd.v18/Create_TRD_Geometry_v18b.C
new file mode 100644
index 0000000000000000000000000000000000000000..057a85394296fd74c6359795e59e723f43f2cf5b
--- /dev/null
+++ b/macro/trd/geometry/trd.v18/Create_TRD_Geometry_v18b.C
@@ -0,0 +1,4365 @@
+/* Copyright (C) 2019 Horia Hulubei National Institute of Physics and Nuclear Engineering, Bucharest
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Alexandru Bercuci [committer] */
+
+///
+/// \file Create_TRD_Geometry_v18b.C
+/// \brief Generates TRD geometry in Root format.
+///
+
+// 2019-04-15 - AB - v18b    - put TRD layers at z-positions according to proposed CAD frame design (v20a for the TDR version).
+// 2019-04-15 - AB - v18a    - using TRD Bucharest chambers with FASP for the inner zone.
+// 2017-06-02 - DE - v17n    - increase pad granularity wrt v17l: type 6 = 24 rows, type 8 = 8 rows
+// 2017-05-31 - DE - v17l    - increase large module size to 96/99 cm
+// 2017-05-25 - DE - v17k    - use only 4 module types: 1, 3, 6, 8
+// 2017-05-25 - DE - v17j    - re-arrange inner zone to allow for a 2x1 hole
+// 2017-04-28 - DE - v17     - implement power bus bars as defined in the TDR
+// 2017-04-26 - DE - v17     - add aluminium ledge around backpanel
+// 2017-04-25 - DE - v17c_3e - reduce the number of FEBs on the small modules from 10, 6, 4 to 8, 4 and 2
+// 2017-02-14 - DE - v17b_3e - build TRD from ROB-3 only, optimise layout
+// 2017-01-10 - DE - v17a_3e - replace 6 ultimate density by 9 super density FEBs for TRD type 1 modules
+// 2016-07-05 - FU - v16a_3e - identical to v15a, change the way the trd volume is exported to resolve a bug with TGeoShape destructor
+// 2015-01-08 - DE - v15a_3e - reduce frame thickness in large modules to 15 mm instead of 20 mm
+// 2014-06-25 - DE - v14a_3e - consists of only 3 small and 3 large modules types (was 4+4 before)
+// 2014-06-25 - DE - v14a_3e - inner part of all 3 stations is now identical
+// 2014-05-02 - DE - v14a_3e - redesign inner part of station 3, now with 5x5-1 small modules, like in station 1 and station 2
+// 2014-05-02 - DE - v14a_3e - include optional GBTX readout boards on each module
+// 2014-05-02 - DE - v14a_3e - introduce 3x5=15 Spadic FEBs for ultimate density on module type 1
+//
+// 2013-11-14 - DE - v13q_3e - generate information about pad plane layout (CbmTrdPads_v14a.h) for all module types in this macro
+//
+// 2013-11-04 - DE - v13p4 - adapt the number of front-end boards to the pad layout of the 540 mm modules
+// 2013-11-04 - DE - v13p4 - use 8 module types (4x S + 4x L) to better match the occupancy
+// 2013-10-31 - DE - v13p4 - modify the support structure of station 1 to match with the MUCH/RICH platform
+// 2013-10-29 - DE - v13p4 - build lattice grid as TGeoBBox instead of VolumeAssembly - in run_sim.C save  9% of time compared to v13p7
+// 2013-10-29 - DE - v13p4 - build lattice grid as TGeoBBox instead of CompositeShape - in run_sim.C save 18% of time compared to v13p6
+//
+// 2013-10-28 - DE - introduce new geometry naming scheme: v13p1 - SIS 100 hadron
+// 2013-10-28 - DE - introduce new geometry naming scheme: v13p2 - SIS 100 electron
+// 2013-10-28 - DE - introduce new geometry naming scheme: v13p3 - SIS 100 muon
+// 2013-10-28 - DE - introduce new geometry naming scheme: v13p4 - SIS 300 electron
+// 2013-10-28 - DE - introduce new geometry naming scheme: v13p5 - SIS 300 muon
+// 2013-10-28 - DE - add option to draw the magnetic field vector in the magnet
+// 2013-09-27 - DE - do not use TGeoXtru to build the supports, use TGeoBBox instead
+//
+// 2013-06-25 - DE - v13g trd300_rich             (10 layers, z = 4100 ) - TRD right behind SIS300 RICH
+// 2013-06-25 - DE - v13h trd100_sts              ( 4 layers, z = 2600 ) - TRD completely on RICH/MUCH platform to allow TOF to move upstream
+// 2013-06-25 - DE - v13i trd100_rich             ( 2 layers, z = 4100 ) - TRD right behind RICH
+// 2013-06-25 - DE - v13j trd100_rich             ( 3 layers, z = 4100 ) - TRD right behind RICH
+// 2013-06-25 - DE - v13k trd100_rich             ( 4 layers, z = 4100 ) - TRD right behind RICH
+// 2013-06-25 - DE - ---  trd100_much_2_absorbers ( 4 layers, z = 4300 ) - same as version at z = 4600
+// 2013-06-25 - DE - v13l trd100_much_3_absorbers ( 4 layers, z = 4600 ) - TRD right behind SIS100 MUCH
+// 2013-06-25 - DE - v13m trd300_much_6_absorbers (10 layers, z = 5500 ) - TRD right behind SIS300 MUCH
+// 2013-06-25 - DE - v13n trd300_rich_stretched   (10 layers, z = 4600 ) - TRD stretched behind SIS300 RICH
+//
+// 2013-06-19 - DE - add TRD (I, II, III) labels on support structure
+// 2013-05-29 - DE - allow for flexible TRD z-positions defined by position of layer01
+// 2013-05-23 - DE - remove "trd_" prefix from node names (except top node)
+// 2013-05-22 - DE - radiators G30 (z=240 mm)
+// 2013-05-22 - DE - radiators H (z=275 mm - 125 * 2.2mm), (H++ z=335 mm)
+// 2013-05-22 - DE - radiators B++ (z=254 mm - 350 * 0.724 mm), K++ (z=254 mm - 350 * 0.724 mm)
+// 2013-04-17 - DE - introduce volume assembly for layers, e.g. trd_layer03
+// 2013-03-26 - DE - use Air as ASIC material
+// 2013-03-26 - DE - put support structure into its own assembly
+// 2013-03-26 - DE - move TRD upstream to z=400m
+// 2013-03-26 - DE - RICH will probably end at z=380 cm, TRD can move to 400 cm
+// 2013-03-25 - DE - shrink active area from 570 to 540 mm and 960 to 910 mm
+// 2013-03-06 - DE - add ASICs on FEBs
+// 2013-03-05 - DE - introduce supports for SIS100 and SIS300
+// 2013-03-05 - DE - replace all Float_t by Double_t
+// 2013-01-21 - DE - introduce TRD media, use TRDG10 as material for pad plane and FEBs
+// 2013-01-21 - DE - put backpanel into the geometry
+// 2013-01-11 - DE - allow for misalignment of TRD modules
+// 2012-11-04 - DE - add kapton foil, add FR4 padplane
+// 2012-11-03 - DE - add lattice grid on entrance window as CompositeShape
+
+// TODO:
+// - use Silicon as ASIC material
+
+// in root all sizes are given in cm
+
+#include "TDatime.h"
+#include "TFile.h"
+#include "TGeoArb8.h"
+#include "TGeoCompositeShape.h"
+#include "TGeoCone.h"
+#include "TGeoManager.h"
+#include "TGeoMaterial.h"
+#include "TGeoMatrix.h"
+#include "TGeoMedium.h"
+#include "TGeoPgon.h"
+#include "TGeoTube.h"
+#include "TGeoVolume.h"
+#include "TGeoXtru.h"
+#include "TList.h"
+#include "TRandom3.h"
+#include "TString.h"
+#include "TSystem.h"
+
+#include <iostream>
+
+// Name of output file with geometry
+const TString tagVersion = "v18b";
+//const TString subVersion   = "_1h";
+//const TString subVersion   = "_1e";
+//const TString subVersion   = "_1m";
+//const TString subVersion   = "_3e";
+//const TString subVersion   = "_3m";
+
+const Int_t setupid = 1;  // 1e is the default
+//const Double_t zfront[5]  = { 260., 410., 360., 410., 550. };  // original
+const Double_t zfront[5]  = {435.,         // SIS100 hadron
+                            435.,         // SIS100 electron
+                            472.,         // SIS100 muon
+                            410., 550.};  // muon_jpsi and muon_lmvm
+const TString setupVer[5] = {"_1h", "_1e", "_1m", "_3e", "_3m"};
+const TString subVersion  = setupVer[setupid];
+
+const TString geoVersion   = "trd_" + tagVersion + subVersion;
+const TString FileNameSim  = geoVersion + ".geo.root";
+const TString FileNameGeo  = geoVersion + "_geo.root";
+const TString FileNameInfo = geoVersion + ".geo.info";
+const TString FileNamePads = "CbmTrdPads_" + tagVersion + ".h";
+
+// display switches
+const Bool_t IncludeRadiator    = true;   // if radiator is included in geometry
+const Bool_t IncludeLattice     = true;   // if lattice grid is included in geometry
+const Bool_t IncludeKaptonFoil  = true;   // if entrance window is included in geometry
+const Bool_t IncludeGasFrame    = true;   // if frame around gas volume is included in geometry
+const Bool_t IncludePadplane    = true;   // if padplane is included in geometry
+const Bool_t IncludeBackpanel   = true;   // if backpanel is included in geometry
+const Bool_t IncludeAluLedge    = true;   // if Al-ledge around the backpanel is included in geometry
+const Bool_t IncludePowerbars   = true;   // if LV copper bus bars to be drawn
+const Bool_t IncludeFebs        = true;   // if FEBs are included in geometry
+const Bool_t IncludeRobs        = true;   // if ROBs are included in geometry
+const Bool_t IncludeAsics       = true;   // if ASICs are included in geometry
+const Bool_t IncludeSupports    = true;   // if support structure is included in geometry
+const Bool_t IncludeLabels      = true;   // if TRD (I, II, III) labels are plotted in (VisLevel 5)
+const Bool_t IncludeFieldVector = false;  // if magnetic field vector to be shown (in the magnet)
+
+// positioning switches
+const Bool_t DisplaceRandom = false;  // add random displacement of modules for alignment study
+const Bool_t RotateRandom   = false;  // add random rotation of modules for alignment study
+const Bool_t DoExplode      = false;  // add random displacement of modules for alignment study
+
+// positioning parameters
+const Double_t maxdx = 0.2;  // max +- 0.1 cm shift in x
+const Double_t maxdy = 0.2;  // max +- 0.1 cm shift in y
+const Double_t maxdz = 1.0;  // max +- 1.0 cm shift in z
+
+const Double_t maxdrotx = 2.0;  // 20.0; // max rotation around x
+const Double_t maxdroty = 2.0;  // 20.0; // max rotation around y
+const Double_t maxdrotz = 2.0;  // 20.0; // max rotation around z
+
+const Double_t ExplodeFactor = 1.02;  // 1.02; // Factor by which modules are exploded in the x/y plane
+
+// initialise random numbers
+TRandom3 r3(0);
+
+// Parameters defining the layout of the complete detector build out of different detector layers.
+const Int_t MaxLayers = 10;  // max layers
+
+// select layers to display
+//
+//const Int_t    ShowLayer[MaxLayers] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };  //  1st layer only
+//const Int_t    ShowLayer[MaxLayers] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 };  //  2nd layer only
+//const Int_t    ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 };  //  5th layer only
+//const Int_t    ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 };  //  6th layer only
+//const Int_t    ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 };  //  9th layer only
+//const Int_t    ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };  // 10th layer only
+//
+//const Int_t    ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };  // Station 1, layer 1, 2
+//const Int_t    ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 };  // Station 2, layer 5, 6
+//const Int_t    ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };  // Station 3, layer 9,10
+//const Int_t    ShowLayer[MaxLayers] = { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0 };  // Station 1 and 2
+//const Int_t    ShowLayer[MaxLayers] = { 1, 1, 0, 0, 1, 1, 1, 0, 1, 1 };  // Station 1, 2 and 3
+//
+//const Int_t    ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };  // SIS100-2l  // 1: plot, 0: hide
+//const Int_t    ShowLayer[MaxLayers] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };  // SIS100-3l  // 1: plot, 0: hide
+//
+//const Int_t    ShowLayer[MaxLayers] = { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 };  // SIS100-4l  // 1: plot, 0: hide
+//const Int_t    ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 };  // SIS300-mu  // 1: plot, 0: hide
+//const Int_t    ShowLayer[MaxLayers] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };  // SIS300-e   // 1: plot, 0: hide
+Int_t ShowLayer[MaxLayers] = {1, 1, 1, 1, 0, 0, 0, 0, 0, 0};  // SIS100-4l is default
+//{ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 };  // SIS100-4l is default
+
+Int_t BusBarOrientation[MaxLayers] = {1, 1, 1, 1, 0, 0, 0, 0, 0, 0};  // 1 = vertical
+
+Int_t PlaneId[MaxLayers];  // automatically filled with layer ID
+
+const Int_t LayerType[MaxLayers] = {10, 11, 10, 11, 20, 21,
+                                    20, 21, 30, 31};  // ab: a [1-3] - layer type, b [0,1] - vertical/horizontal pads
+// ### Layer Type 11 is Layer Type 1 with detector modules rotated by 90°
+// ### Layer Type 21 is Layer Type 2 with detector modules rotated by 90°
+// ### Layer Type 31 is Layer Type 3 with detector modules rotated by 90°
+
+// In the subroutine creating the layers this is recognized automatically
+
+const Int_t LayerNrInStation[MaxLayers] = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2};
+
+Double_t LayerPosition[MaxLayers] = {0.};  // start position = 0 - 2016-07-12 - DE
+
+// 5x z-positions from 260 till 550 cm
+//Double_t LayerPosition[MaxLayers] = { 260. }; // start position - 2013-10-28 - DE - v14_1h - SIS 100 hadron         ( 4 layers, z = 2600 )
+//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-10-28 - DE - v14_1e - SIS 100 electron       ( 4 layers, z = 4100 )
+//Double_t LayerPosition[MaxLayers] = { 360. }; // start position - 2014-06-16 - DE - v14_1m - SIS 100 muon           ( 4 layers, z = 3600 ) was 460.
+//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-10-28 - DE - v14_3e - SIS 300 electron       (10 layers, z = 4100 )
+//Double_t LayerPosition[MaxLayers] = { 550. }; // start position - 2013-10-28 - DE - v14_3m - SIS 300 muon     6_abs (10 layers, z = 5500 )
+//
+// obsolete variants
+//Double_t LayerPosition[MaxLayers] = { 460. }; // start position - 2013-10-28 - DE - v13x3 - SIS 100 muon         ( 4 layers, z = 4600 )
+//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-06-25 - DE - v13i trd100_rich             ( 2 layers, z = 4100 )
+//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-06-25 - DE - v13j trd100_rich             ( 3 layers, z = 4100 )
+//Double_t LayerPosition[MaxLayers] = { 430. }; // start position - 2013-06-25 - DE - ---  trd100_much_2_absorbers ( 4 layers, z = 4300 )
+//Double_t LayerPosition[MaxLayers] = { 460. }; // start position - 2013-06-25 - DE - v13n trd300_rich_stretched   (10 layers, z = 4600 )
+
+
+const Double_t LayerThickness         = 71.0;  //45.0;  // Thickness of one TRD layer in cm
+const Double_t LayerOffset[MaxLayers] = {0., 0., 0., 0., 5.,
+                                         0., 0., 0., 5., 0.};  // v13x[4,5] - z offset in addition to LayerThickness
+//const Double_t LayerOffset[MaxLayers] = {   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0. };  // SIS100 - z offset in addition to LayerThickness
+//const Double_t LayerOffset[MaxLayers] = {   0.,   0.,   0.,   0.,  95.,   0.,   0.,   0.,   5.,   0. };  // v13n       - z offset in addition to LayerThickness
+
+const Int_t LayerArraySize[3][4] = {{9, 4, 9, 11},  // for layer[1-3][i,o] below
+                                    {5, 5, 9, 11},
+                                    {5, 5, 9, 11}};
+
+
+// ### Layer Type 1
+// v14x - module types in the inner sector of layer type 1 - looking upstream
+const Int_t layer1i[9][4] = {  // abc: a module type - b orientation (x90 deg) in odd - c even layers
+  {323, 323, 321, 321}, {323, 323, 321, 321}, {323, 323, 321, 321}, {900, 900, 900, 900}, {900, 0, 0, 900},
+  {900, 900, 900, 900}, {303, 303, 301, 301}, {303, 303, 301, 301}, {303, 303, 301, 301}};  // number of modules: 24
+
+// v14x - module types in the outer sector of layer type 1 - looking upstream
+const Int_t layer1o[9][11] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+                              {0, 0, 723, 723, 0, 0, 0, 721, 721, 0, 0}, {0, 0, 723, 523, 0, 0, 0, 521, 721, 0, 0},
+                              {0, 0, 503, 503, 0, 0, 0, 501, 501, 0, 0}, {0, 0, 703, 503, 0, 0, 0, 501, 701, 0, 0},
+                              {0, 0, 703, 703, 0, 0, 0, 701, 701, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+                              {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+// number of modules: 26
+// Layer1 =  24 + 26;   // v14a
+
+
+// ### Layer Type 2
+// v14x - module types in the inner sector of layer type 2 - looking upstream
+const Int_t layer2i[5][5] = {  // abc: a module type - b orientation (x90 deg) in odd - c even layers
+  {323, 323, 321, 321, 321},
+  {223, 123, 121, 121, 221},
+  {203, 103, 0, 101, 201},
+  {203, 103, 101, 101, 201},
+  {303, 303, 301, 301, 301}};  // number of modules: 24
+
+// v14x - module types in the outer sector of layer type 2 - looking upstream
+const Int_t layer2o[9][11] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+                              {0, 823, 823, 823, 823, 821, 821, 821, 821, 821, 0},
+                              {0, 823, 823, 823, 723, 721, 721, 821, 821, 821, 0},
+                              {0, 823, 723, 623, 0, 0, 0, 621, 721, 821, 0},
+                              {0, 803, 703, 603, 0, 0, 0, 601, 701, 801, 0},
+                              {0, 803, 703, 603, 0, 0, 0, 601, 701, 801, 0},
+                              {0, 803, 803, 803, 703, 701, 701, 801, 801, 801, 0},
+                              {0, 803, 803, 803, 803, 801, 801, 801, 801, 801, 0},
+                              {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+// number of modules: 54
+// Layer2 =  24 + 54;   // v14a
+
+
+// ### Layer Type 3
+// v14x - module types in the inner sector of layer type 3 - looking upstream
+const Int_t layer3i[5][5] = {  // abc: a module type - b orientation (x90 deg) in odd - c even layers
+  {323, 323, 321, 321, 321},
+  {223, 123, 121, 121, 221},
+  {203, 103, 0, 101, 201},
+  {203, 103, 101, 101, 201},
+  {303, 303, 301, 301, 301}};
+// number of modules: 24
+
+// v14x - module types in the outer sector of layer type 3 - looking upstream
+const Int_t layer3o[9][11] = {
+  {823, 823, 823, 823, 823, 821, 821, 821, 821, 821, 821}, {823, 823, 823, 823, 823, 821, 821, 821, 821, 821, 821},
+  {823, 823, 823, 723, 623, 621, 621, 721, 821, 821, 821}, {823, 823, 723, 623, 0, 0, 0, 621, 721, 821, 821},
+  {803, 803, 703, 603, 0, 0, 0, 601, 701, 801, 801},       {803, 803, 703, 603, 0, 0, 0, 601, 701, 801, 801},
+  {803, 803, 803, 703, 603, 601, 601, 701, 801, 801, 801}, {803, 803, 803, 803, 803, 801, 801, 801, 801, 801, 801},
+  {803, 803, 803, 803, 803, 801, 801, 801, 801, 801, 801}};
+// number of modules: 90
+// Layer2 =  24 + 90;   // v14a
+
+
+// Parameters defining the layout of the different detector modules
+const Int_t NofModuleTypes             = 9;
+const Int_t ModuleType[NofModuleTypes] = {
+  0, 0, 0, 0, 1, 1, 1, 1, 2};  // 0 = small module, 1 = large module, 2 = bucharest small modules
+
+// FEB inclination angle
+const Double_t feb_rotation_angle[NofModuleTypes] = {
+  60, 90, 90, 80, 60, 60, 90, 90, 90};  // rotation around x-axis, 0 = vertical, 90 = horizontal
+//const Double_t feb_rotation_angle[NofModuleTypes] = { 60,  90,  90,  80,  80,  90,  90,  90 }; // rotation around x-axis, 0 = vertical, 90 = horizontal
+//const Double_t feb_rotation_angle[NofModuleTypes] = { 45,  45,  45,  45,  45,  45,  45,  45 }; // rotation around x-axis, 0 = vertical, 90 = horizontal
+
+// GBTx ROB definitions
+//// v17d
+//const Int_t RobsPerModule[NofModuleTypes] = {  4,  2,  2,  1,  2,  3,  2,  1 }; // number of GBTx ROBs on module
+//const Int_t GbtxPerRob[NofModuleTypes]    = {103,103,103,103,107,103,103,103 }; // number of GBTx ASICs on ROB
+//
+//const Int_t GbtxPerModule[NofModuleTypes] = {   12,  6,  6,  0,  0,  9,  6,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+//const Int_t RobTypeOnModule[NofModuleTypes]={ 3333, 33, 33,  0,  0,333, 33,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+//
+// v17l - 96 cm
+const Int_t RobsPerModule[NofModuleTypes] = {4, 2, 1, 1, 6, 6, 2, 2, 6};  // number of GBTx ROBs on module
+const Int_t GbtxPerRob[NofModuleTypes] = {103, 103, 103, 103, 103, 103, 103, 103, 103};  // number of GBTx ASICs on ROB
+
+const Int_t GbtxPerModule[NofModuleTypes]   = {12, 6, 3, 0, 18,
+                                             18, 6, 6, 18};  // for .geo.info - TODO: merge with above GbtxPerRob
+const Int_t RobTypeOnModule[NofModuleTypes] = {
+  3333, 33, 3, 0, 333333, 333333, 33, 33, 333333};  // for .geo.info - TODO: merge with above GbtxPerRob
+
+//// v17c
+//const Int_t RobsPerModule[NofModuleTypes] = {  4,  2,  1,  1,  2,  3,  2,  1 }; // number of GBTx ROBs on module
+//const Int_t GbtxPerRob[NofModuleTypes]    = {103,103,103,103,107,103,103,103 }; // number of GBTx ASICs on ROB
+//
+//const Int_t GbtxPerModule[NofModuleTypes] = {   12,  6,  3,  0,  0,  9,  6,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+//const Int_t RobTypeOnModule[NofModuleTypes]={ 3333, 33,  3,  0,  0,333, 33,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+
+//// v17b
+//const Int_t RobsPerModule[NofModuleTypes] = {  5,  3,  2,  1,  2,  3,  2,  1 }; // number of GBTx ROBs on module
+//const Int_t GbtxPerRob[NofModuleTypes]    = {103,103,103,103,107,103,103,103 }; // number of GBTx ASICs on ROB
+//
+//const Int_t GbtxPerModule[NofModuleTypes] = {   15,  9,  6,  0,  0,  9,  6,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+//const Int_t RobTypeOnModule[NofModuleTypes]={33333,333, 33,  0,  0,333, 33,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+
+//v17a // GBTx ROB definitions
+//v17a const Int_t RobsPerModule[NofModuleTypes] = {  3,  2,  1,  1,  2,  2,  1,  1 }; // number of GBTx ROBs on module
+//v17a const Int_t GbtxPerRob[NofModuleTypes]    = {105,105,105,103,107,105,105,103 }; // number of GBTx ASICs on ROB
+//v17a
+//v17a const Int_t GbtxPerModule[NofModuleTypes] = { 15, 10,  5,  0,  0, 10,  5,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+//v17a const Int_t RobTypeOnModule[NofModuleTypes]={555, 55,  5,  0,  0, 55,  5,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+
+//const Int_t RobsPerModule[NofModuleTypes] = {  2,  2,  1,  1,  2,  2,  1,  1 }; // number of GBTx ROBs on module
+//const Int_t GbtxPerRob[NofModuleTypes]    = {107,105,105,103,107,105,105,103 }; // number of GBTx ASICs on ROB
+//const Int_t GbtxPerModule[NofModuleTypes] = { 14,  8,  5,  0,  0, 10,  5,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+//const Int_t RobTypeOnModule[NofModuleTypes] = { 77, 53,  5,  0,  0, 55,  5,  3 }; // for .geo.info - TODO: merge with above GbtxPerRob
+
+// super density for type 1 modules - 2017 - 540 mm
+//// v17d
+//const Int_t FebsPerModule[NofModuleTypes] = {  8,  4,  4,  4, 12,  9,  6,  3 }; // number of FEBs on backside
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {210,210,210,105,108,107,107,107 }; // %100 gives number of ASICs on FEB, /100 gives grouping
+
+// v17l - 96 cm
+//const Int_t FebsPerModule[NofModuleTypes] = {  8,  4,  2,  4, 12,  8,  6,  4 }; // number of FEBs on backside
+//const Int_t FebsPerModule[NofModuleTypes] = {  8,  4,  2,  4, 12,  8,  6,  2 }; // number of FEBs on backside
+const Int_t FebsPerModule[NofModuleTypes] = {8, 4, 2, 4, 12, 12, 4, 4, 30};  // number of FEBs on backside
+const Int_t AsicsPerFeb[NofModuleTypes]   = {210, 210, 210, 105, 109,
+                                           109, 109, 109, 6};  // %100 gives number of ASICs on FEB, /100 gives grouping
+
+//// v17c
+//const Int_t FebsPerModule[NofModuleTypes] = {  8,  4,  2,  4, 12,  9,  6,  3 }; // number of FEBs on backside
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {210,210,210,105,108,107,107,107 }; // %100 gives number of ASICs on FEB, /100 gives grouping
+
+//// v17b
+//const Int_t FebsPerModule[NofModuleTypes] = {  10,  6,  4,  4, 12,  9,  6,  3 }; // number of FEBs on backside
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {210,210,210,105,108,107,107,107 }; // %100 gives number of ASICs on FEB, /100 gives grouping
+// v17a // super density for type 1 modules - 2017 - 540 mm
+// v17a //const Int_t FebsPerModule[NofModuleTypes] = {  9,  5,  6,  4, 12,  8,  4,  3 }; // number of FEBs on backside
+// v17a const Int_t FebsPerModule[NofModuleTypes] = {  9,  6,  3,  4, 12,  8,  4,  3 }; // number of FEBs on backside
+// v17a const Int_t AsicsPerFeb[NofModuleTypes]   = {210,210,210,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping
+//// ultimate density - 540 mm
+//const Int_t FebsPerModule[NofModuleTypes] = {  6,  5,  6,  4, 12,  8,  4,  3 }; // number of FEBs on backside - reduced FEBs (64 ch ASICs)
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {315,210,105,105,108,108,108,108 }; //  %100 gives number of ASICs on FEB, /100 gives grouping
+////const Int_t FebsPerModule[NofModuleTypes] = {  6,  5,  3,  2,  6,  3,  4,  3 }; // min number of FEBs // number of FEBs on backside - reduced FEBs (64 ch ASICs)
+////const Int_t AsicsPerFeb[NofModuleTypes]   = {315,210,210,210,216,216,108,108 }; //  %100 gives number of ASICs on FEB, /100 gives grouping
+////const Int_t AsicsPerFeb[NofModuleTypes]   = {216,210,210,210,216,216,108,108 }; //  %100 gives number of ASICs on FEB, /100 gives grouping
+//
+////// super density - 540 mm
+//const Int_t FebsPerModule[NofModuleTypes] = {  9,  5,  6,  4, 12,  6,  4,  3 }; // light // number of FEBs on backside - reduced FEBs (64 ch ASICs)
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {210,210,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping
+//
+//// normal density - 540 mm
+//const Int_t FebsPerModule[NofModuleTypes] = { 18, 10,  6,  4, 12,  6,  4,  3 }; // number of FEBs on backside (linked to pad layout) - mod4 = mod3, therefore same
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {105,105,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping
+
+// ultimate density - 570 mm
+//const Int_t FebsPerModule[NofModuleTypes] = {  6,  5,  3,  2,  5,  3,  2,  1 }; // min number of FEBs // number of FEBs on backside - reduced FEBs (64 ch ASICs)
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {216,210,210,210,216,216,216,216 }; //  %100 gives number of ASICs on FEB, /100 gives grouping
+//
+//const Int_t FebsPerModule[NofModuleTypes] = {  6,  5,  3,  3, 10,  5,  3,  3 }; // min (6) module types // number of FEBs on backside - reduced FEBs (64 ch ASICs)
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {216,210,210,210,108,108,108,108 }; //  %100 gives number of ASICs on FEB, /100 gives grouping
+//// super density - 570 mm
+//const Int_t FebsPerModule[NofModuleTypes] = { 10,  5,  5,  5, 12,  6,  4,  3 }; // light // number of FEBs on backside - reduced FEBs (64 ch ASICs)
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {210,210,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping
+//
+//// normal density - 570 mm
+//const Int_t FebsPerModule[NofModuleTypes] = { 19, 10,  5,  5, 12,  6,  4,  3 }; // number of FEBs on backside (linked to pad layout) - mod4 = mod3, therefore same
+//const Int_t AsicsPerFeb[NofModuleTypes]   = {105,105,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping
+
+
+/* TODO: activate connector grouping info below
+// ultimate - grouping of pads to connectors
+const Int_t RowsPerConnector[NofModuleTypes]  = {  6,  4,  2,  2,  2,  2,  2,  2 };
+const Int_t ColsPerConnector[NofModuleTypes]  = { 16, 16, 16, 16, 16, 16, 16, 16 };
+// super    - grouping of pads to connectors
+const Int_t RowsPerConnector[NofModuleTypes]  = {  4,  4,  2,  2,  2,  2,  2,  2 };
+const Int_t ColsPerConnector[NofModuleTypes]  = { 16, 16, 16, 16, 16, 16, 16, 16 };
+// normal   - grouping of pads to connectors
+const Int_t RowsPerConnector[NofModuleTypes]  = {  2,  2,  2,  2,  2,  2,  2,  2 };
+const Int_t ColsPerConnector[NofModuleTypes]  = { 16, 16, 16, 16, 16, 16, 16, 16 };
+*/
+
+
+const Double_t feb_z_offset = 0.1;  // 1 mm - offset in z of FEBs to backpanel
+const Double_t asic_offset  = 0.1;  // 1 mm - offset of ASICs to FEBs to avoid overlaps
+
+// ASIC parameters
+Double_t asic_distance;
+
+//const Double_t FrameWidth[2]    = { 1.5, 2.0 };   // Width of detector frames in cm
+const Double_t FrameWidth[3] = {1.5, 1.5, 1.5};  // Width of detector frames in cm
+// mini - production
+const Double_t DetectorSizeX[3] = {57., 99., 57.};  // => 54 x 54 cm2 & 96 x 96 cm2 active area
+const Double_t DetectorSizeY[3] = {57., 99., 57.};  // quadratic modules
+// 108 cm const Double_t DetectorSizeX[2] = { 57., 111.};   // => 54 x 54 cm2 & 108 x 108 cm2 active area
+// 108 cm const Double_t DetectorSizeY[2] = { 57., 111.};   // quadratic modules
+//// default
+//const Double_t DetectorSizeX[2] = { 60., 100.};   // => 57 x 57 cm2 & 96 x 96 cm2 active area
+//const Double_t DetectorSizeY[2] = { 60., 100.};   // quadratic modules
+
+// Parameters tor the lattice grid reinforcing the entrance window
+//const Double_t lattice_o_width[2] = { 1.5, 2.0 };   // Width of outer lattice frame in cm
+const Double_t lattice_o_width[2] = {1.5, 1.5};  // Width of outer lattice frame in cm
+const Double_t lattice_i_width[2] = {0.2, 0.2};  // { 0.4, 0.4 };   // Width of inner lattice frame in cm
+// Thickness (in z) of lattice frames in cm - see below
+
+// statistics
+Int_t ModuleStats[MaxLayers][NofModuleTypes] = {0};
+
+// z - geometry of TRD modules
+//const Double_t radiator_thickness     =  35.0;    // 35 cm thickness of radiator
+const Double_t radiator_thickness = 30.0;  // 30 cm thickness of radiator + shift pad plane to integer multiple of 1 mm
+const Double_t radiator_position  = -LayerThickness / 2. + radiator_thickness / 2.;
+
+//const Double_t lattice_thickness      =   1.0;  // 1.0;  // 10 mm thick lattice frames
+const Double_t lattice_thickness = 1.0 - 0.0025;  // 0.9975;  // 1.0;  // 10 mm thick lattice frames
+const Double_t lattice_position  = radiator_position + radiator_thickness / 2. + lattice_thickness / 2.;
+
+const Double_t kapton_thickness = 0.0025;  //  25 micron thickness of kapton
+const Double_t kapton_position  = lattice_position + lattice_thickness / 2. + kapton_thickness / 2.;
+
+const Double_t gas_thickness = 1.2;  //  12 mm thickness of gas
+const Double_t gas_position  = kapton_position + kapton_thickness / 2. + gas_thickness / 2.;
+
+// frame thickness
+const Double_t frame_thickness = gas_thickness;  // frame covers gas volume: from kapton foil to pad plane
+const Double_t frame_position =
+  -LayerThickness / 2. + radiator_thickness + lattice_thickness + kapton_thickness + frame_thickness / 2.;
+
+// pad plane
+const Double_t padcopper_thickness = 0.0025;  //  25 micron thickness of copper pads
+const Double_t padcopper_position  = gas_position + gas_thickness / 2. + padcopper_thickness / 2.;
+const Double_t padplane_thickness  = 0.0360;  // 360 micron thickness of padplane
+const Double_t padplane_position   = padcopper_position + padcopper_thickness / 2. + padplane_thickness / 2.;
+
+// backpanel components
+const Double_t carbon_thickness = 0.0190 * 2;  // use 2 layers!!   // 190 micron thickness for 1 layer of carbon fibers
+const Double_t honeycomb_thickness = 2.3 - kapton_thickness - padcopper_thickness - padplane_thickness
+                                     - carbon_thickness;  //  ~ 2.3 mm thickness of honeycomb
+const Double_t honeycomb_position = padplane_position + padplane_thickness / 2. + honeycomb_thickness / 2.;
+const Double_t carbon_position    = honeycomb_position + honeycomb_thickness / 2. + carbon_thickness / 2.;
+
+// aluminium thickness
+const Double_t aluminium_thickness = 0.4;  // crossbar of 1 x 1 cm at every module edge
+const Double_t aluminium_width     = 1.0;  // crossbar of 1 x 1 cm at every module edge
+const Double_t aluminium_position  = carbon_position + carbon_thickness / 2. + aluminium_thickness / 2.;
+
+// power bus bars
+const Double_t powerbar_thickness = 1.0;  // 1 cm in z direction
+const Double_t powerbar_width     = 2.0;  // 2 cm in x/y direction
+const Double_t powerbar_position  = aluminium_position + aluminium_thickness / 2. + powerbar_thickness / 2.;
+
+// readout boards
+//const  Double_t feb_width           =  10.0;    // width of FEBs in cm
+const Double_t feb_width          = 8.5;   // width of FEBs in cm
+const Double_t feb_thickness      = 0.25;  // light //  2.5 mm thickness of FEBs
+const Double_t febvolume_position = aluminium_position + aluminium_thickness / 2. + feb_width / 2.;
+
+// ASIC parameters
+const Double_t asic_thickness = 0.25;  // 2.5 mm asic_thickness
+const Double_t asic_width     = 3.0;   // 2.0;  1.0;   // 1 cm
+
+// --------------      BUCHAREST PROTOTYPE SPECIFICS      ----------------------------------
+// Frontpanel components
+const Double_t carbonBu_thickness    = 0.03;  // 300 micron thickness for 1 layer of carbon fibers
+const Double_t honeycombBu_thickness = 1.2;   // 12 mm thickness of honeycomb
+const Double_t WIN_Frame_thickness   = 0.6;   // entrance window framing 6x12 mm2
+const Double_t honeycombBu0_position = radiator_position + radiator_thickness / 2. + honeycombBu_thickness / 2.;
+const Double_t carbonBu1_position    = honeycombBu0_position + honeycombBu_thickness / 2. + carbonBu_thickness / 2.;
+// Active volume
+const Double_t gasBu_position = carbonBu1_position + carbonBu_thickness / 2. + gas_thickness / 2.;
+// Pad plane
+const Double_t padcopperBu_position = gasBu_position + gas_thickness / 2. + padcopper_thickness / 2.;
+const Double_t padplaneBu_position  = padcopperBu_position + padcopper_thickness / 2. + padplane_thickness / 2.;
+// Backpanel components
+const Double_t honeycombBu1_position = padplaneBu_position + padplane_thickness / 2. + honeycombBu_thickness / 2.;
+// PCB
+const Double_t glassFibre_thickness = 0.0270;  // 300 microns overall PCB thickness
+const Double_t cuCoating_thickness  = 0.0030;
+const Double_t glassFibre_position  = honeycombBu1_position + honeycombBu_thickness / 2. + glassFibre_thickness / 2.;
+const Double_t cuCoating_position   = glassFibre_position + glassFibre_thickness / 2. + cuCoating_thickness / 2.;
+//Frame around entrance window, active volume and exit window
+const Double_t frameBu_thickness = 2 * carbonBu_thickness + honeycombBu_thickness + gas_thickness + padcopper_thickness
+                                   + padplane_thickness + honeycombBu_thickness + glassFibre_thickness
+                                   + cuCoating_thickness;
+const Double_t frameBu_position = radiator_position + radiator_thickness / 2. + frameBu_thickness / 2.;
+
+// C-ROB3 parameters : GBTx ROBs
+const Double_t rob_size_x    = 20.0;  // 13.0; // 130 mm
+const Double_t rob_size_y    = 9.0;   //  4.5; //  45 mm
+const Double_t rob_yoffset   = 0.3;   // offset wrt detector frame (on the detector plane)
+const Double_t rob_zoffset   = -7.5;  // offset wrt entrace plane - center board
+const Double_t rob_thickness = feb_thickness;
+// GBTX parameters
+const Double_t gbtx_thickness = 0.25;  // 2.5 mm
+const Double_t gbtx_width     = 3.0;   // 2.0;  1.0;   // 1 cm
+const Double_t gbtx_distance  = 0.4;
+
+
+// Names of the different used materials which are used to build the modules
+// The materials are defined in the global media.geo file
+const TString KeepingVolumeMedium   = "air";
+const TString RadiatorVolumeMedium  = "TRDpefoam20";
+const TString LatticeVolumeMedium   = "TRDG10";
+const TString KaptonVolumeMedium    = "TRDkapton";
+const TString GasVolumeMedium       = "TRDgas";
+const TString PadCopperVolumeMedium = "TRDcopper";
+const TString PadPcbVolumeMedium    = "TRDG10";  // todo - put correct FEB material here
+const TString HoneycombVolumeMedium = "TRDaramide";
+const TString CarbonVolumeMedium    = "TRDcarbon";
+const TString FebVolumeMedium       = "TRDG10";  // todo - put correct FEB material here
+const TString AsicVolumeMedium      = "air";     // todo - put correct ASIC material here
+const TString TextVolumeMedium      = "air";     // leave as air
+const TString FrameVolumeMedium     = "TRDG10";
+const TString PowerBusVolumeMedium  = "TRDcopper";  // power bus bars
+const TString AluLegdeVolumeMedium  = "aluminium";  // aluminium frame around backpanel
+const TString AluminiumVolumeMedium = "aluminium";
+//const TString MylarVolumeMedium       = "mylar";
+//const TString RadiatorVolumeMedium    = "polypropylene";
+//const TString ElectronicsVolumeMedium = "goldcoatedcopper";
+
+
+// some global variables
+TGeoManager* gGeoMan = NULL;           // Pointer to TGeoManager instance
+TGeoVolume* gModules[NofModuleTypes];  // Global storage for module types
+
+// Forward declarations
+void create_materials_from_media_file();
+TGeoVolume* create_trd_module_type(Int_t moduleType);
+TGeoVolume* create_trdi_module_type(Int_t moduleType = 2);
+TGeoVolume* create_support_inner();
+void create_detector_layers(Int_t layer);
+void create_power_bars_vertical();
+void create_power_bars_horizontal();
+void create_xtru_supports();
+void create_box_supports();
+void add_trd_labels(TGeoVolume*, TGeoVolume*, TGeoVolume*);
+void create_mag_field_vector();
+void dump_info_file();
+void dump_digi_file();
+
+void Create_TRD_Geometry_v18b()
+{
+  // declare TRD layer layout
+  if (setupid > 2)
+    for (Int_t i = 0; i < MaxLayers; i++)
+      ShowLayer[i] = 1;  // show all layers
+
+  // Load needed material definition from media.geo file
+  create_materials_from_media_file();
+
+  // Position the layers in z
+  for (Int_t iLayer = 1; iLayer < MaxLayers; iLayer++)
+    LayerPosition[iLayer] =
+      LayerPosition[iLayer - 1] + LayerThickness + LayerOffset[iLayer];  // add offset for extra gaps
+
+  // Get the GeoManager for later usage
+  gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
+  gGeoMan->SetVisLevel(10);
+
+  // Create the top volume
+  TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
+  TGeoVolume* top  = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
+  gGeoMan->SetTopVolume(top);
+
+  TGeoVolume* trd = new TGeoVolumeAssembly(geoVersion);
+  top->AddNode(trd, 1);
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    Int_t moduleType = iModule + 1;
+    if (moduleType < 9) gModules[iModule] = create_trd_module_type(moduleType);
+    else
+      gModules[iModule] = create_trdi_module_type(moduleType - 9);
+  }
+
+  Int_t nLayer = 0;  // active layer counter
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) {
+    //    if ((iLayer != 0) && (iLayer != 3))  continue;  // first layer only - comment later on
+    //    if (iLayer != 0) continue;  // first layer only - comment later on
+    if (ShowLayer[iLayer]) {
+      PlaneId[iLayer] = ++nLayer;
+      create_detector_layers(iLayer);
+      //      printf("calling layer %2d\n",iLayer);
+    }
+  }
+
+  // TODO: remove or comment out
+  // test PlaneId
+  printf("generated TRD layers: ");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) printf(" %2d", PlaneId[iLayer]);
+  printf("\n");
+
+  if (IncludeSupports) { create_box_supports(); }
+
+  if (IncludePowerbars) {
+    create_power_bars_vertical();
+    create_power_bars_horizontal();
+  }
+
+  if (IncludeFieldVector) create_mag_field_vector();
+
+  gGeoMan->CloseGeometry();
+  //  gGeoMan->CheckOverlaps(0.001);
+  //  gGeoMan->PrintOverlaps();
+  gGeoMan->Test();
+
+  trd->Export(FileNameSim);  // an alternative way of writing the trd volume
+
+  TFile* outfile = new TFile(FileNameSim, "UPDATE");
+  //  TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", 0., 0., 0.);
+  TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", 0., 0., zfront[setupid]);
+  trd_placement->Write();
+  outfile->Close();
+
+  outfile = new TFile(FileNameGeo, "RECREATE");
+  gGeoMan->Write();  // use this is you want GeoManager format in the output
+  outfile->Close();
+
+  dump_info_file();
+  dump_digi_file();
+
+  top->Draw("ogl");
+
+  //top->Raytrace();
+
+  //  cout << "Press Return to exit" << endl;
+  //  cin.get();
+  //  exit();
+}
+
+
+//==============================================================
+void dump_digi_file()
+{
+  TDatime datetime;  // used to get timestamp
+
+  const Double_t ActiveAreaX[3] = {DetectorSizeX[0] - 2 * FrameWidth[0], DetectorSizeX[1] - 2 * FrameWidth[1],
+                                   DetectorSizeX[2] - 2 * FrameWidth[2]};
+  const Int_t NofSectors        = 3;
+  // v17b
+  //  const Int_t NofPadsInRow[2]  = { 80, 112 };  //  7 // number of pads in rows
+  //  const Int_t NofPadsInRow[2]  = { 80, 128 };  //  8 // number of pads in rows
+  const Int_t NofPadsInRow[3] = {80, 144, 72};  // number of pads in rows
+  //  const Int_t NofPadsInRow[2]  = { 80, 160 };  // 10 // number of pads in rows
+  Int_t nrow = 0;  // number of rows in module
+
+  const Double_t PadHeightInSector[NofModuleTypes][NofSectors] =  // pad height
+    {//v17b {  1.25,  1.50,  1.25 },   // module type 1 -  1.01 cm2
+     //v17b {  2.25,  2.25,  2.25 },   // module type 2 -  1.52 cm2
+     //v17b {  3.25,  3.50,  3.25 },   // module type 3 -  2.36 cm2
+
+     {1.50, 1.75, 1.50},  // module type 1 -  1.18 cm2
+     {3.25, 3.50, 3.25},  // module type 2 -  2.36 cm2
+     {6.75, 6.75, 6.75},  // module type 3 -  4.56 cm2
+     {6.75, 6.75, 6.75},  // module type 4 -
+
+     // 108 cm          {  2.25,  2.25,  2.25 },   // module type 5 -
+     // 108 cm          {  4.50,  4.50,  4.50 },   // module type 6 -  4.52 cm2
+     // 108 cm          {  9.00,  9.00,  9.00 },   // module type 7 -  6.37 cm2
+     // 108 cm          { 18.00, 18.00, 18.00 } }; // module type 8 - 12.73 cm2
+
+     {4.00, 4.00, 4.00},     // module type 5 -  2.67 cm2
+     {6.00, 6.00, 6.00},     // module type 6 -  4.00 cm2
+     {12.00, 12.00, 12.00},  // module type 7 -  8.00 cm2
+     {24.00, 24.00, 24.00},  // module type 8 - 16.00 cm2
+
+     //          {  3.75,  4.00,  3.75 },   // module type 5 -
+     //          {  5.00,  5.50,  5.00 },   // module type 6 -  4.52 cm2
+     //          {  7.50,  7.75,  7.50 },   // module type 7 -  6.37 cm2
+     //          { 15.25, 15.50, 15.25 } }; // module type 8 - 12.73 cm2
+     {2.70, 2.70, 2.70}};  // module type 9 -  triangular pads H=26.8+0.2 mm, W=7.3+0.2 mm
+
+  const Int_t NofRowsInSector[NofModuleTypes][NofSectors] =  // number of rows per sector
+    {                                                        //v17b {  12,  16,  12 },         // module type 1
+     //v17b {   8,   8,   8 },         // module type 2
+     //v17b {   4,   8,   4 },         // module type 3
+
+     {4, 24, 4},  // module type 1
+     {4, 8, 4},   // module type 2
+     {2, 4, 2},   // module type 3
+     {2, 4, 2},   // module type 4
+
+     {8, 8, 8},  // module type 5
+     {6, 4, 6},  // module type 6
+     {2, 4, 2},  // module type 7
+     {1, 2, 1},  // module type 8
+
+     //          {   8,   8,   8 },         // module type 5
+     //          {   4,   8,   4 },         // module type 6
+     //          {   2,   8,   2 },         // module type 7
+     //          {   2,   2,   2 } };       // module type 8
+     {2, 16, 2}};  // module type 9
+
+  // v17a   const Int_t NofPadsInRow[2]  = { 80, 128 };  // number of pads in rows
+  // v17a   Int_t nrow = 0;   // number of rows in module
+  // v17a
+  // v17a   const Double_t PadHeightInSector[NofModuleTypes][NofSectors] =  // pad height
+  // v17a         { {  1.50,  1.50,  1.50 },   // module type 1 -  1.01 cm2
+  // v17a           {  2.25,  2.25,  2.25 },   // module type 2 -  1.52 cm2
+  // v17a //          {  2.75,  2.50,  2.75 },   // module type 2 -  1.86 cm2
+  // v17a           {  4.50,  4.50,  4.50 },   // module type 3 -  3.04 cm2
+  // v17a           {  6.75,  6.75,  6.75 },   // module type 4 -  4.56 cm2
+  // v17a
+  // v17a           {  3.75,  4.00,  3.75 },   // module type 5 -  2.84 cm2
+  // v17a           {  5.75,  5.75,  5.75 },   // module type 6 -  4.13 cm2
+  // v17a           { 11.50, 11.50, 11.50 },   // module type 7 -  8.26 cm2
+  // v17a           { 15.25, 15.50, 15.25 } }; // module type 8 - 11.14 cm2
+  // v17a //          {  7.50,  7.75,  7.50 },   // module type 6 -  5.51 cm2
+  // v17a //          {  5.50,  5.75,  5.50 },   // module type 6 -  4.09 cm2
+  // v17a //          { 11.25, 11.50, 11.25 },   // module type 7 -  8.18 cm2
+  // v17a
+  // v17a   const Int_t NofRowsInSector[NofModuleTypes][NofSectors] =   // number of rows per sector
+  // v17a         { {  12,  12,  12 },         // module type 1
+  // v17a           {   8,   8,   8 },         // module type 2
+  // v17a //          {   8,   4,   8 },         // module type 2
+  // v17a           {   4,   4,   4 },         // module type 3
+  // v17a           {   2,   4,   2 },         // module type 4
+  // v17a
+  // v17a           {   8,   8,   8 },         // module type 5
+  // v17a           {   4,   8,   4 },         // module type 6
+  // v17a           {   2,   4,   2 },         // module type 7
+  // v17a           {   2,   2,   2 } };       // module type 8
+  // v17a //          {  10,   4,  10 },         // module type 5
+  // v17a //          {   4,   4,   4 },         // module type 6
+  // v17a //          {   2,  12,   2 },         // module type 6
+  // v17a //          {   2,   4,   2 },         // module type 7
+  // v17a //          {   2,   2,   2 } };       // module type 8
+  // v17a
+
+  Double_t HeightOfSector[NofModuleTypes][NofSectors];
+  Double_t PadWidth[NofModuleTypes];
+
+  // calculate pad width
+  for (Int_t im = 0; im < NofModuleTypes; im++)
+    PadWidth[im] = ActiveAreaX[ModuleType[im]] / NofPadsInRow[ModuleType[im]];
+
+  // calculate height of sectors
+  for (Int_t im = 0; im < NofModuleTypes; im++)
+    for (Int_t is = 0; is < NofSectors; is++)
+      HeightOfSector[im][is] = NofRowsInSector[im][is] * PadHeightInSector[im][is];
+
+  // check, if the entire module size is covered by pads
+  for (Int_t im = 0; im < NofModuleTypes; im++)
+    if (ActiveAreaX[ModuleType[im]] - (HeightOfSector[im][0] + HeightOfSector[im][1] + HeightOfSector[im][2]) != 0) {
+      printf("WARNING: sector size does not add up to module size for module "
+             "type %d\n",
+             im + 1);
+      printf("%.2f = %.2f + %.2f + %.2f\n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], HeightOfSector[im][1],
+             HeightOfSector[im][2]);
+      exit(1);
+    }
+
+  //==============================================================
+
+  printf("writing trd pad information file: %s\n", FileNamePads.Data());
+
+  FILE* ifile;
+  ifile = fopen(FileNamePads.Data(), "w");
+
+  if (ifile == NULL) {
+    printf("error opening %s\n", FileNamePads.Data());
+    exit(1);
+  }
+
+  fprintf(ifile, "//\n");
+  fprintf(ifile, "//   TRD pad layout for geometry %s\n", tagVersion.Data());
+  fprintf(ifile, "//\n");
+  fprintf(ifile, "// automatically generated by Create_TRD_Geometry_%s%s.C\n", tagVersion.Data(), subVersion.Data());
+  fprintf(ifile, "// created %d\n", datetime.GetDate());
+  fprintf(ifile, "//\n");
+
+  fprintf(ifile, "\n");
+  fprintf(ifile, "#ifndef CBMTRDPADS_H\n");
+  fprintf(ifile, "#define CBMTRDPADS_H\n");
+  fprintf(ifile, "\n");
+  fprintf(ifile, "Int_t fst1_sect_count = 3;\n");
+  fprintf(ifile, "// array of pad geometries in the TRD (trd1mod[1-%d])\n", NofModuleTypes);
+  fprintf(ifile, "// %d modules  // 3 sectors  // 4 values \n", NofModuleTypes);
+  fprintf(ifile, "Float_t fst1_pad_type[%d][3][4] =        \n", NofModuleTypes);
+  //fprintf(ifile,"Double_t fst1_pad_type[8][3][4] =       \n");
+  fprintf(ifile, "			 		 \n");
+
+  for (Int_t im = 0; im < NofModuleTypes; im++) {
+    if (im + 1 == 5) fprintf(ifile, "//---\n\n");
+    fprintf(ifile, "// module type %d\n", im + 1);
+
+    // number of pads
+    nrow = 0;  // reset number of pad rows to 0
+    for (Int_t is = 0; is < NofSectors; is++)
+      nrow += HeightOfSector[im][is] / PadHeightInSector[im][is];  // add number of rows in this sector
+    fprintf(ifile, "// number of pads: %3d x %2d = %4d\n", NofPadsInRow[ModuleType[im]], nrow,
+            NofPadsInRow[ModuleType[im]] * nrow);
+
+    // pad size
+    fprintf(ifile, "// pad size sector 1: %5.2f cm x %5.2f cm = %5.2f cm2\n", PadWidth[im], PadHeightInSector[im][1],
+            PadWidth[im] * PadHeightInSector[im][1]);
+    fprintf(ifile, "// pad size sector 0: %5.2f cm x %5.2f cm = %5.2f cm2\n", PadWidth[im], PadHeightInSector[im][0],
+            PadWidth[im] * PadHeightInSector[im][0]);
+
+    for (Int_t is = 0; is < NofSectors; is++) {
+      if ((im == 0) && (is == 0)) fprintf(ifile, "  { { ");
+      else if (is == 0)
+        fprintf(ifile, "    { ");
+      else
+        fprintf(ifile, "      ");
+
+      fprintf(ifile, "{ %.1f, %5.2f, %.1f/%3d, %5.2f }", ActiveAreaX[ModuleType[im]], HeightOfSector[im][is],
+              ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][is]);
+
+      if ((im == NofModuleTypes - 1) && (is == 2)) fprintf(ifile, " } };");
+      else if (is == 2)
+        fprintf(ifile, " },");
+      else
+        fprintf(ifile, ",");
+
+      fprintf(ifile, "\n");
+    }
+
+    fprintf(ifile, "\n");
+  }
+
+  fprintf(ifile, "#endif\n");
+
+  //  Int_t im = 0;
+  //  fprintf(ifile,"// module type %d	 		   \n", im+1);
+  //  fprintf(ifile,"  { { { %.1f, %5.2f, %.1f/%3d, %5.2f },    \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]);
+  //  fprintf(ifile,"      { %.1f, %5.2f, %.1f/%3d, %5.2f },    \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]);
+  //  fprintf(ifile,"      { %.1f, %5.2f, %.1f/%3d, %5.2f } },  \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]);
+  //  fprintf(ifile,"\n");
+  //
+  //  for (Int_t im = 1; im < NofModuleTypes-1; im++)
+  //  {
+  //    fprintf(ifile,"// module type %d	 		     \n", im+1);
+  //    fprintf(ifile,"    { { %.1f, %5.2f, %.1f/%3d, %5.2f },    \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]);
+  //    fprintf(ifile,"      { %.1f, %5.2f, %.1f/%3d, %5.2f },    \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]);
+  //    fprintf(ifile,"      { %.1f, %5.2f, %.1f/%3d, %5.2f } },  \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]);
+  //    fprintf(ifile,"\n");
+  //  }
+  //
+  //  Int_t im = 7;
+  //  fprintf(ifile,"// module type %d	 		   \n", im+1);
+  //  fprintf(ifile,"    { { %.1f, %5.2f, %.1f/%3d, %5.2f },    \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]);
+  //  fprintf(ifile,"      { %.1f, %5.2f, %.1f/%3d, %5.2f },    \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]);
+  //  fprintf(ifile,"      { %.1f, %5.2f, %.1f/%3d, %5.2f } } };\n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]);
+  //  fprintf(ifile,"\n");
+
+  fclose(ifile);
+}
+
+
+void dump_info_file()
+{
+  TDatime datetime;  // used to get timestamp
+
+  Double_t z_first_layer = 2000;  // z position of first layer (front)
+  Double_t z_last_layer  = 0;     // z position of last  layer (front)
+
+  Double_t xangle;   // horizontal angle
+  Double_t yangle;   // vertical   angle
+  Double_t yangleo;  // vertical   angle for outer modules
+
+  Double_t total_surface = 0;  // total surface
+  Double_t total_actarea = 0;  // total active area
+
+  Int_t channels_per_module[NofModuleTypes + 1] = {0};  // number of channels per module
+  Int_t channels_per_feb[NofModuleTypes + 1]    = {0};  // number of channels per feb
+  Int_t asics_per_module[NofModuleTypes + 1]    = {0};  // number of asics per module
+
+  Int_t total_modules[NofModuleTypes + 1]  = {0};  // total number of modules
+  Int_t total_febs[NofModuleTypes + 1]     = {0};  // total number of febs
+  Int_t total_asics[NofModuleTypes + 1]    = {0};  // total number of asics
+  Int_t total_gbtx[NofModuleTypes + 1]     = {0};  // total number of gbtx
+  Int_t total_rob3[NofModuleTypes + 1]     = {0};  // total number of gbtx rob3
+  Int_t total_rob5[NofModuleTypes + 1]     = {0};  // total number of gbtx rob5
+  Int_t total_rob7[NofModuleTypes + 1]     = {0};  // total number of gbtx rob7
+  Int_t total_channels[NofModuleTypes + 1] = {0};  // total number of channels
+
+  Int_t total_channels_u = 0;  // total number of ultimate channels
+  Int_t total_channels_s = 0;  // total number of super    channels
+  Int_t total_channels_r = 0;  // total number of regular  channels
+  Int_t total_channels_f = 0;  // total number of FASP  channels
+
+  printf("writing summary information file: %s\n", FileNameInfo.Data());
+
+  FILE* ifile;
+  ifile = fopen(FileNameInfo.Data(), "w");
+
+  if (ifile == NULL) {
+    printf("error opening %s\n", FileNameInfo.Data());
+    exit(1);
+  }
+
+  fprintf(ifile, "#\n##   %s information file\n#\n\n", geoVersion.Data());
+
+  fprintf(ifile, "# created %d\n\n", datetime.GetDate());
+
+  // determine first and last TRD layer
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) {
+    if (ShowLayer[iLayer]) {
+      if (z_first_layer > LayerPosition[iLayer]) z_first_layer = LayerPosition[iLayer];
+      if (z_last_layer < LayerPosition[iLayer]) z_last_layer = LayerPosition[iLayer];
+    }
+  }
+
+  fprintf(ifile, "# position\n");
+  // Show position of TRD
+  fprintf(ifile, "%4f cm z-front position of TRD in hadron   setup\n", zfront[0]);
+  fprintf(ifile, "%4f cm z-front position of TRD in electron setup\n", zfront[1]);
+  fprintf(ifile, "%4f cm z-front position of TRD in muon     setup\n", zfront[2]);
+  fprintf(ifile, "\n");
+
+  //  fprintf(ifile, "# envelope\n");
+  fprintf(ifile, "# detector thickness\n");
+  // Show extension of TRD
+  //  fprintf(ifile, "%4f cm   start of TRD (z)\n", z_first_layer);
+  fprintf(ifile, "%4f cm   end   of TRD (z)\n", z_last_layer + LayerThickness);
+  fprintf(ifile, "\n");
+
+  // Layer thickness
+  fprintf(ifile, "# layer thickness\n");
+  fprintf(ifile, "%4f cm   per single layer (z)\n", LayerThickness);
+  fprintf(ifile, "\n");
+
+  // Show extra gaps
+  fprintf(ifile, "# extra gaps\n ");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) fprintf(ifile, "%3f ", LayerOffset[iLayer]);
+  fprintf(ifile, "   extra gaps in z (cm)\n");
+  fprintf(ifile, "\n");
+
+  // Show layer flags
+  fprintf(ifile, "# generated TRD layers\n ");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) fprintf(ifile, "%2d ", PlaneId[iLayer]);
+  fprintf(ifile, "   planeID\n");
+  fprintf(ifile, "\n");
+
+  // Dimensions in x
+  fprintf(ifile, "# dimensions in x\n");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) {
+      if (PlaneId[iLayer] < 5)
+        fprintf(ifile, "%5f cm to %5f cm x-dimension of layer %2d\n",
+                -(2.0 * DetectorSizeX[0] + 2.0 * DetectorSizeX[1]), 2.0 * DetectorSizeX[0] + 2.0 * DetectorSizeX[1],
+                PlaneId[iLayer]);
+      else {
+        if (PlaneId[iLayer] < 9)
+          fprintf(ifile, "%5f cm to %5f cm x-dimension of layer %2d\n", -4.5 * DetectorSizeX[1], 4.5 * DetectorSizeX[1],
+                  PlaneId[iLayer]);
+        else
+          fprintf(ifile, "%5f cm to %5f cm x-dimension of layer %2d\n", -5.5 * DetectorSizeX[1], 5.5 * DetectorSizeX[1],
+                  PlaneId[iLayer]);
+      }
+    }
+  fprintf(ifile, "\n");
+
+  // Dimensions in y
+  fprintf(ifile, "# dimensions in y inner modules\n");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) {
+      if (PlaneId[iLayer] < 5)
+        fprintf(ifile, "%5f cm to %5f cm y-dimension of layer %2d\n", -4.5 * DetectorSizeY[0], 4.5 * DetectorSizeY[0],
+                PlaneId[iLayer]);
+      else {
+        if (PlaneId[iLayer] < 9)
+          fprintf(ifile, "%5f cm to %5f cm y-dimension of layer %2d\n", -3.5 * DetectorSizeY[1], 3.5 * DetectorSizeY[1],
+                  PlaneId[iLayer]);
+        else
+          fprintf(ifile, "%5f cm to %5f cm y-dimension of layer %2d\n", -4.5 * DetectorSizeY[1], 4.5 * DetectorSizeY[1],
+                  PlaneId[iLayer]);
+      }
+    }
+  fprintf(ifile, "\n");
+
+  // Dimensions in y
+  fprintf(ifile, "# dimensions in y outer modules\n");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) {
+      if (PlaneId[iLayer] < 5)
+        fprintf(ifile, "%5f cm to %5f cm y-dimension of layer %2d\n", -2.5 * DetectorSizeY[1], 2.5 * DetectorSizeY[1],
+                PlaneId[iLayer]);
+    }
+  fprintf(ifile, "\n");
+
+  // angles
+  fprintf(ifile, "# angles of acceptance for inner + outer modules\n");
+
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) {
+      if (iLayer < 4) {
+        //        fprintf(ifile,"y %10.4f cm   x %10.4f cm\n", 2.5 * DetectorSizeY[1], 3.5 * DetectorSizeX[1]);
+        yangle = atan(4.5 * DetectorSizeY[0]
+                      / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                 * 180. / acos(-1.);
+        yangleo = atan(2.5 * DetectorSizeY[1]
+                       / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                  * 180. / acos(-1.);
+        xangle = atan((2.0 * DetectorSizeX[0] + 2.0 * DetectorSizeX[1])
+                      / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                 * 180. / acos(-1.);
+      }
+      if ((iLayer >= 4) && (iLayer < 8)) {
+        //        fprintf(ifile,"y %10.4f cm   x %10.4f cm\n", 3.5 * DetectorSizeY[1], 4.5 * DetectorSizeX[1]);
+        yangle = atan(3.5 * DetectorSizeY[1] / (LayerPosition[iLayer] + LayerThickness / 2. + padplane_position)) * 180.
+                 / acos(-1.);
+        xangle = atan(4.5 * DetectorSizeX[1] / (LayerPosition[iLayer] + LayerThickness / 2. + padplane_position)) * 180.
+                 / acos(-1.);
+      }
+      if ((iLayer >= 8) && (iLayer < 10)) {
+        //        fprintf(ifile,"y %10.4f cm   x %10.4f cm\n", 4.5 * DetectorSizeY[1], 5.5 * DetectorSizeX[1]);
+        yangle = atan(4.5 * DetectorSizeY[1] / (LayerPosition[iLayer] + LayerThickness / 2. + padplane_position)) * 180.
+                 / acos(-1.);
+        xangle = atan(5.5 * DetectorSizeX[1] / (LayerPosition[iLayer] + LayerThickness / 2. + padplane_position)) * 180.
+                 / acos(-1.);
+      }
+      fprintf(ifile, "vi: %5.2f deg, vo: %5.2f deg, h: %5.2f deg - vertical/horizontal - layer %2d\n", yangle, yangleo,
+              xangle, PlaneId[iLayer]);
+    }
+  fprintf(ifile, "\n");
+
+  // aperture
+  fprintf(ifile, "# inner aperture\n");
+
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) {
+      if (iLayer < 4) {
+        //        fprintf(ifile,"y %10.4f cm   x %10.4f cm\n", 2.5 * DetectorSizeY[1], 3.5 * DetectorSizeX[1]);
+        yangle = atan(0.5 * DetectorSizeY[0]
+                      / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                 * 180. / acos(-1.);
+        xangle = atan(1.0 * DetectorSizeX[0]
+                      / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                 * 180. / acos(-1.);
+      }
+      if ((iLayer >= 4) && (iLayer < 8)) {
+        //        fprintf(ifile,"y %10.4f cm   x %10.4f cm\n", 3.5 * DetectorSizeY[1], 4.5 * DetectorSizeX[1]);
+        yangle = atan(0.5 * DetectorSizeY[0]
+                      / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                 * 180. / acos(-1.);
+        xangle = atan(0.5 * DetectorSizeX[0]
+                      / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                 * 180. / acos(-1.);
+      }
+      if ((iLayer >= 8) && (iLayer < 10)) {
+        //        fprintf(ifile,"y %10.4f cm   x %10.4f cm\n", 4.5 * DetectorSizeY[1], 5.5 * DetectorSizeX[1]);
+        yangle = atan(0.5 * DetectorSizeY[0]
+                      / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                 * 180. / acos(-1.);
+        xangle = atan(0.5 * DetectorSizeX[0]
+                      / (zfront[setupid] + LayerPosition[iLayer] + LayerThickness / 2. + padplane_position))
+                 * 180. / acos(-1.);
+      }
+      fprintf(ifile, "v: %5.2f deg, h: %5.2f deg - vertical/horizontal - layer %2d\n", yangle, xangle, PlaneId[iLayer]);
+    }
+  fprintf(ifile, "\n");
+
+  // Show layer positions
+  fprintf(ifile, "# z-positions of layer front\n");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) {
+    if (ShowLayer[iLayer])
+      fprintf(ifile, "%7.2f cm   z-position of layer %2d\n", LayerPosition[iLayer], PlaneId[iLayer]);
+  }
+  fprintf(ifile, "\n");
+
+  // flags
+  fprintf(ifile, "# flags\n");
+
+  fprintf(ifile, "support structure is    : ");
+  if (!IncludeSupports) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "radiator is             : ");
+  if (!IncludeRadiator) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "lattice grid is         : ");
+  if (!IncludeLattice) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "kapton window is        : ");
+  if (!IncludeKaptonFoil) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "gas frame is            : ");
+  if (!IncludeGasFrame) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "padplane is             : ");
+  if (!IncludePadplane) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "backpanel is            : ");
+  if (!IncludeBackpanel) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "Aluminium ledge is      : ");
+  if (!IncludeAluLedge) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "Power bus bars are      : ");
+  if (!IncludePowerbars) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "asics are               : ");
+  if (!IncludeAsics) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "front-end boards are    : ");
+  if (!IncludeFebs) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "GBTX readout boards are : ");
+  if (!IncludeRobs) fprintf(ifile, "NOT ");
+  fprintf(ifile, "included\n");
+
+  fprintf(ifile, "\n");
+
+
+  // module statistics
+  //  fprintf(ifile,"#\n##   modules\n#\n\n");
+  //  fprintf(ifile,"number of modules per type and layer:\n");
+  fprintf(ifile, "# modules\n");
+
+  for (Int_t iModule = 1; iModule <= NofModuleTypes; iModule++)
+    fprintf(ifile, "     mod%1d", iModule);
+  fprintf(ifile, "    total");
+
+  fprintf(ifile, "\n------------------------------------------------------------------"
+                 "---------------\n");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer]) {
+      for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+        fprintf(ifile, " %8d", ModuleStats[iLayer][iModule]);
+        total_modules[iModule] += ModuleStats[iLayer][iModule];  // sum up modules across layers
+      }
+      fprintf(ifile, "            layer %2d\n", PlaneId[iLayer]);
+    }
+  fprintf(ifile, "\n------------------------------------------------------------------"
+                 "---------------\n");
+
+  // total statistics
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    fprintf(ifile, " %8d", total_modules[iModule]);
+    total_modules[NofModuleTypes] += total_modules[iModule];
+  }
+  fprintf(ifile, " %8d", total_modules[NofModuleTypes]);
+  fprintf(ifile, "   number of modules\n");
+
+  //------------------------------------------------------------------------------
+
+  // number of FEBs
+  //  fprintf(ifile,"\n#\n##   febs\n#\n\n");
+  fprintf(ifile, "# febs\n");
+
+  fprintf(ifile, " ");
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    if ((AsicsPerFeb[iModule] / 100) == 3) fprintf(ifile, "%8du", FebsPerModule[iModule]);
+    else if ((AsicsPerFeb[iModule] / 100) == 2)
+      fprintf(ifile, "%8ds", FebsPerModule[iModule]);
+    else
+      fprintf(ifile, "%8d ", FebsPerModule[iModule]);
+  }
+  fprintf(ifile, "           FEBs per module\n");
+
+  // FEB total per type
+  total_febs[NofModuleTypes] = 0;  // reset sum to 0
+  fprintf(ifile, " ");
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    if ((AsicsPerFeb[iModule] / 100) == 3) {
+      total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule];
+      fprintf(ifile, "%8du", total_febs[iModule]);
+      total_febs[NofModuleTypes] += total_febs[iModule];
+    }
+    else
+      fprintf(ifile, "         ");
+  }
+  fprintf(ifile, "%8d", total_febs[NofModuleTypes]);
+  fprintf(ifile, "   ultimate  FEBs\n");
+
+  // FEB total per type
+  total_febs[NofModuleTypes] = 0;  // reset sum to 0
+  fprintf(ifile, " ");
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    if ((AsicsPerFeb[iModule] / 100) == 2) {
+      total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule];
+      fprintf(ifile, "%8ds", total_febs[iModule]);
+      total_febs[NofModuleTypes] += total_febs[iModule];
+    }
+    else
+      fprintf(ifile, "         ");
+  }
+  fprintf(ifile, "%8d", total_febs[NofModuleTypes]);
+  fprintf(ifile, "   super     FEBs\n");
+
+  // FEB total per type
+  total_febs[NofModuleTypes] = 0;  // reset sum to 0
+  fprintf(ifile, " ");
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    if ((AsicsPerFeb[iModule] / 100) == 1) {
+      total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule];
+      fprintf(ifile, "%8d ", total_febs[iModule]);
+      total_febs[NofModuleTypes] += total_febs[iModule];
+    }
+    else
+      fprintf(ifile, "         ");
+  }
+  fprintf(ifile, "%8d", total_febs[NofModuleTypes]);
+  fprintf(ifile, "   regular   FEBs\n");
+
+  // FEB total over all types
+  total_febs[NofModuleTypes] = 0;  // reset sum to 0
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule];
+    fprintf(ifile, " %8d", total_febs[iModule]);
+    total_febs[NofModuleTypes] += total_febs[iModule];
+  }
+  fprintf(ifile, " %8d", total_febs[NofModuleTypes]);
+  fprintf(ifile, "   number of FEBs\n");
+
+  //------------------------------------------------------------------------------
+
+  // number of ASICs
+  //  fprintf(ifile,"\n#\n##   asics\n#\n\n");
+  fprintf(ifile, "# asics\n");
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    fprintf(ifile, " %8d", AsicsPerFeb[iModule] % 100);
+  }
+  fprintf(ifile, "            ASICs per FEB\n");
+
+  // ASICs per module
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    asics_per_module[iModule] = FebsPerModule[iModule] * (AsicsPerFeb[iModule] % 100);
+    fprintf(ifile, " %8d", asics_per_module[iModule]);
+  }
+  fprintf(ifile, "            ASICs per module\n");
+
+  // ASICs per module type
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    total_asics[iModule] = total_febs[iModule] * (AsicsPerFeb[iModule] % 100);
+    fprintf(ifile, " %8d", total_asics[iModule]);
+    total_asics[NofModuleTypes] += total_asics[iModule];
+  }
+  fprintf(ifile, " %8d", total_asics[NofModuleTypes]);
+  fprintf(ifile, "   number of ASICs\n");
+
+  //------------------------------------------------------------------------------
+
+  // number of GBTXs
+  //  fprintf(ifile,"\n#\n##   asics\n#\n\n");
+  fprintf(ifile, "# gbtx\n");
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    fprintf(ifile, " %8d", GbtxPerModule[iModule]);
+  }
+  fprintf(ifile, "            GBTXs per module\n");
+
+  // GBTXs per module type
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    total_gbtx[iModule] = total_modules[iModule] * GbtxPerModule[iModule];
+    fprintf(ifile, " %8d", total_gbtx[iModule]);
+    total_gbtx[NofModuleTypes] += total_gbtx[iModule];
+  }
+  fprintf(ifile, " %8d", total_gbtx[NofModuleTypes]);
+  fprintf(ifile, "   number of GBTXs\n");
+
+  // GBTX ROB types per module type
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    fprintf(ifile, " %8d", RobTypeOnModule[iModule]);
+  }
+  fprintf(ifile, "            GBTX ROB types on module\n");
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    if ((RobTypeOnModule[iModule] % 10) == 7) total_rob7[iModule]++;
+    if ((RobTypeOnModule[iModule] / 10 % 10) == 7) total_rob7[iModule]++;
+    if ((RobTypeOnModule[iModule] / 100) == 7) total_rob7[iModule]++;
+
+    if ((RobTypeOnModule[iModule] % 10) == 5) total_rob5[iModule]++;
+    if ((RobTypeOnModule[iModule] / 10 % 10) == 5) total_rob5[iModule]++;
+    if ((RobTypeOnModule[iModule] / 100) == 5) total_rob5[iModule]++;
+
+    if ((RobTypeOnModule[iModule] % 10) == 3) total_rob3[iModule]++;
+    if ((RobTypeOnModule[iModule] / 10 % 10) == 3) total_rob3[iModule]++;
+    if ((RobTypeOnModule[iModule] / 100 % 10) == 3) total_rob3[iModule]++;
+    if ((RobTypeOnModule[iModule] / 1000 % 10) == 3) total_rob3[iModule]++;
+    if ((RobTypeOnModule[iModule] / 10000 % 10) == 3) total_rob3[iModule]++;
+    if ((RobTypeOnModule[iModule] / 100000 % 10) == 3) total_rob3[iModule]++;
+  }
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    total_rob7[iModule] *= total_modules[iModule];
+    fprintf(ifile, " %8d", total_rob7[iModule]);
+    total_rob7[NofModuleTypes] += total_rob7[iModule];
+  }
+  fprintf(ifile, " %8d", total_rob7[NofModuleTypes]);
+  fprintf(ifile, "   number of GBTX ROB7\n");
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    total_rob5[iModule] *= total_modules[iModule];
+    fprintf(ifile, " %8d", total_rob5[iModule]);
+    total_rob5[NofModuleTypes] += total_rob5[iModule];
+  }
+  fprintf(ifile, " %8d", total_rob5[NofModuleTypes]);
+  fprintf(ifile, "   number of GBTX ROB5\n");
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    total_rob3[iModule] *= total_modules[iModule];
+    fprintf(ifile, " %8d", total_rob3[iModule]);
+    total_rob3[NofModuleTypes] += total_rob3[iModule];
+  }
+  fprintf(ifile, " %8d", total_rob3[NofModuleTypes]);
+  fprintf(ifile, "   number of GBTX ROB3\n");
+
+  //------------------------------------------------------------------------------
+  fprintf(ifile, "# e-links\n");
+
+  // e-links used
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++)
+    fprintf(ifile, " %8d", asics_per_module[iModule] * 2);
+  fprintf(ifile, " %8d", total_asics[NofModuleTypes] * 2);
+  fprintf(ifile, "   e-links used\n");
+
+  // e-links available
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++)
+    fprintf(ifile, " %8d", GbtxPerModule[iModule] * 14);
+  fprintf(ifile, " %8d", total_gbtx[NofModuleTypes] * 14);
+  fprintf(ifile, "   e-links available\n");
+
+  // e-link efficiency
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    if (total_gbtx[iModule] != 0)
+      fprintf(ifile, " %7.1f%%", (float) total_asics[iModule] * 2 / (total_gbtx[iModule] * 14) * 100);
+    else
+      fprintf(ifile, "        -");
+  }
+  if (total_gbtx[NofModuleTypes] != 0)
+    fprintf(ifile, " %7.1f%%", (float) total_asics[NofModuleTypes] * 2 / (total_gbtx[NofModuleTypes] * 14) * 100);
+  fprintf(ifile, "   e-link efficiency\n\n");
+
+  //------------------------------------------------------------------------------
+
+  // number of channels
+  fprintf(ifile, "# channels\n");
+
+  // channels per module
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    if ((AsicsPerFeb[iModule] % 100) == 16) {
+      channels_per_feb[iModule]    = 80 * 6;  // rows  // 84, if 63 of 64 ch used
+      channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule];
+    }
+    if ((AsicsPerFeb[iModule] % 100) == 15) {
+      channels_per_feb[iModule]    = 80 * 6;  // rows
+      channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule];
+    }
+    if ((AsicsPerFeb[iModule] % 100) == 10) {
+      channels_per_feb[iModule]    = 80 * 4;  // rows
+      channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule];
+    }
+    if ((AsicsPerFeb[iModule] % 100) == 5) {
+      channels_per_feb[iModule]    = 80 * 2;  // rows
+      channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule];
+    }
+
+    if ((AsicsPerFeb[iModule] % 100) == 9) {
+      channels_per_feb[iModule]    = 144 * 2;  // rows
+      channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule];
+    }
+    if ((AsicsPerFeb[iModule] % 100) == 8) {
+      channels_per_feb[iModule]    = 128 * 2;  // rows
+      channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule];
+    }
+    if ((AsicsPerFeb[iModule] % 100) == 7) {
+      channels_per_feb[iModule]    = 112 * 2;  // rows
+      channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule];
+    }
+    // Bucharest module[s]
+    if ((AsicsPerFeb[iModule] % 100) == 6) {
+      channels_per_feb[iModule]    = 16 * 6;
+      channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule];
+    }
+  }
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++)
+    fprintf(ifile, " %8d", channels_per_module[iModule]);
+  fprintf(ifile, "            channels per module\n");
+
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++)
+    fprintf(ifile, " %8d", channels_per_feb[iModule]);
+  fprintf(ifile, "            channels per feb\n");
+
+  // channels used
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    total_channels[iModule] = channels_per_module[iModule] * total_modules[iModule];
+    fprintf(ifile, " %8d", total_channels[iModule]);
+    total_channels[NofModuleTypes] += total_channels[iModule];
+  }
+  fprintf(ifile, " %8d", total_channels[NofModuleTypes]);
+  fprintf(ifile, "   channels used\n");
+
+  // channels available
+  fprintf(ifile, " ");
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) {
+    if ((AsicsPerFeb[iModule] / 100) == 3) {
+      fprintf(ifile, "%8du", total_asics[iModule] * 32);
+      total_channels_u += total_asics[iModule] * 32;
+    }
+    else if ((AsicsPerFeb[iModule] / 100) == 2) {
+      fprintf(ifile, "%8ds", total_asics[iModule] * 32);
+      total_channels_s += total_asics[iModule] * 32;
+    }
+    else if ((AsicsPerFeb[iModule] / 100) == 1) {
+      fprintf(ifile, "%8d ", total_asics[iModule] * 32);
+      total_channels_r += total_asics[iModule] * 32;
+    }
+    else  // Bucharest type
+    {
+      fprintf(ifile, "%8d ", total_asics[iModule] * 16);
+      total_channels_f += total_asics[iModule] * 16;
+    }
+  }
+  fprintf(ifile, "%8d", total_asics[NofModuleTypes] * 32);
+  fprintf(ifile, "   channels available\n");
+
+  // channel ratio for u,s,r density
+  fprintf(ifile, " ");
+  fprintf(ifile, "%7.1f%%u", (float) total_channels_u / (total_asics[NofModuleTypes] * 32) * 100);
+  fprintf(ifile, "%7.1f%%s", (float) total_channels_s / (total_asics[NofModuleTypes] * 32) * 100);
+  fprintf(ifile, "%7.1f%%r", (float) total_channels_r / (total_asics[NofModuleTypes] * 32) * 100);
+  fprintf(ifile, "%7.1f%%f", (float) total_channels_f / (total_asics[8] * 16) * 100);
+  fprintf(ifile, "                                                        channel ratio\n");
+  fprintf(ifile, "\n");
+  fprintf(ifile, "%8.1f%%   channel efficiency\n",
+          1. * total_channels[NofModuleTypes] / (total_asics[NofModuleTypes] * 32) * 100);
+
+  //------------------------------------------------------------------------------
+
+  // total surface of TRD
+  for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++)
+    if (iModule <= 3) {
+      total_surface += total_modules[iModule] * DetectorSizeX[0] / 100 * DetectorSizeY[0] / 100;
+      total_actarea += total_modules[iModule] * (DetectorSizeX[0] - 2 * FrameWidth[0]) / 100
+                       * (DetectorSizeY[0] - 2 * FrameWidth[0]) / 100;
+    }
+    else {
+      total_surface += total_modules[iModule] * DetectorSizeX[1] / 100 * DetectorSizeY[1] / 100;
+      total_actarea += total_modules[iModule] * (DetectorSizeX[1] - 2 * FrameWidth[1]) / 100
+                       * (DetectorSizeY[1] - 2 * FrameWidth[1]) / 100;
+    }
+  fprintf(ifile, "\n");
+
+  // summary
+  fprintf(ifile, "%7.2f m2      total surface    \n", total_surface);
+  fprintf(ifile, "%7.2f m2      total active area\n", total_actarea);
+  fprintf(ifile, "%7.2f m3      total gas volume \n",
+          total_actarea * gas_thickness / 100);  // convert cm to m for thickness
+
+  fprintf(ifile, "%7.2f cm2/ch  average channel size\n", 100. * 100 * total_actarea / total_channels[NofModuleTypes]);
+  fprintf(ifile, "%7.2f ch/m2   channels per m2 active area\n", 1. * total_channels[NofModuleTypes] / total_actarea);
+  fprintf(ifile, "\n");
+
+  // gas volume position
+  fprintf(ifile, "# gas volume position\n");
+  for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++)
+    if (ShowLayer[iLayer])
+      fprintf(ifile, "%10.4f cm   position of gas volume - layer %2d\n",
+              LayerPosition[iLayer] + LayerThickness / 2. + gas_position, PlaneId[iLayer]);
+  fprintf(ifile, "\n");
+
+  fclose(ifile);
+}
+
+
+void create_materials_from_media_file()
+{
+  // Use the FairRoot geometry interface to load the media which are already defined
+  FairGeoLoader* geoLoad    = new FairGeoLoader("TGeo", "FairGeoLoader");
+  FairGeoInterface* geoFace = geoLoad->getGeoInterface();
+  TString geoPath           = gSystem->Getenv("VMCWORKDIR");
+  TString medFile           = geoPath + "/geometry/media.geo";
+  geoFace->setMediaFile(medFile);
+  geoFace->readMedia();
+
+  // Read the required media and create them in the GeoManager
+  FairGeoMedia* geoMedia   = geoFace->getMedia();
+  FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
+
+  FairGeoMedium* air       = geoMedia->getMedium(KeepingVolumeMedium);
+  FairGeoMedium* pefoam20  = geoMedia->getMedium(RadiatorVolumeMedium);
+  FairGeoMedium* G10       = geoMedia->getMedium(LatticeVolumeMedium);
+  FairGeoMedium* kapton    = geoMedia->getMedium(KaptonVolumeMedium);
+  FairGeoMedium* trdGas    = geoMedia->getMedium(GasVolumeMedium);
+  FairGeoMedium* copper    = geoMedia->getMedium(PadCopperVolumeMedium);
+  FairGeoMedium* carbon    = geoMedia->getMedium(CarbonVolumeMedium);
+  FairGeoMedium* honeycomb = geoMedia->getMedium(HoneycombVolumeMedium);
+  FairGeoMedium* aluminium = geoMedia->getMedium(AluminiumVolumeMedium);
+
+  //  FairGeoMedium* goldCoatedCopper = geoMedia->getMedium("goldcoatedcopper");
+  //  FairGeoMedium* polypropylene    = geoMedia->getMedium("polypropylene");
+  //  FairGeoMedium* mylar            = geoMedia->getMedium("mylar");
+
+  geoBuild->createMedium(air);
+  geoBuild->createMedium(pefoam20);
+  geoBuild->createMedium(trdGas);
+  geoBuild->createMedium(honeycomb);
+  geoBuild->createMedium(carbon);
+  geoBuild->createMedium(G10);
+  geoBuild->createMedium(copper);
+  geoBuild->createMedium(kapton);
+  geoBuild->createMedium(aluminium);
+
+  //  geoBuild->createMedium(goldCoatedCopper);
+  //  geoBuild->createMedium(polypropylene);
+  //  geoBuild->createMedium(mylar);
+}
+
+TGeoVolume* create_trd_module_type(Int_t moduleType)
+{
+  Int_t type           = ModuleType[moduleType - 1];
+  Double_t sizeX       = DetectorSizeX[type];
+  Double_t sizeY       = DetectorSizeY[type];
+  Double_t frameWidth  = FrameWidth[type];
+  Double_t activeAreaX = sizeX - 2 * frameWidth;
+  Double_t activeAreaY = sizeY - 2 * frameWidth;
+
+  TGeoMedium* keepVolMed      = gGeoMan->GetMedium(KeepingVolumeMedium);
+  TGeoMedium* radVolMed       = gGeoMan->GetMedium(RadiatorVolumeMedium);
+  TGeoMedium* latticeVolMed   = gGeoMan->GetMedium(LatticeVolumeMedium);
+  TGeoMedium* kaptonVolMed    = gGeoMan->GetMedium(KaptonVolumeMedium);
+  TGeoMedium* gasVolMed       = gGeoMan->GetMedium(GasVolumeMedium);
+  TGeoMedium* padcopperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium);
+  TGeoMedium* padpcbVolMed    = gGeoMan->GetMedium(PadPcbVolumeMedium);
+  TGeoMedium* honeycombVolMed = gGeoMan->GetMedium(HoneycombVolumeMedium);
+  TGeoMedium* carbonVolMed    = gGeoMan->GetMedium(CarbonVolumeMedium);
+  //  TGeoMedium* mylarVolMed       = gGeoMan->GetMedium(MylarVolumeMedium);
+  //  TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsVolumeMedium);
+  TGeoMedium* frameVolMed    = gGeoMan->GetMedium(FrameVolumeMedium);
+  TGeoMedium* aluledgeVolMed = gGeoMan->GetMedium(AluLegdeVolumeMedium);
+  TGeoMedium* febVolMed      = gGeoMan->GetMedium(FebVolumeMedium);
+  TGeoMedium* asicVolMed     = gGeoMan->GetMedium(AsicVolumeMedium);
+  //  TGeoMedium* aluminiumVolMed   = gGeoMan->GetMedium(AluminiumVolumeMedium);
+
+  TString name       = Form("module%d", moduleType);
+  TGeoVolume* module = new TGeoVolumeAssembly(name);
+
+
+  if (IncludeRadiator) {
+    // Radiator
+    //   TGeoBBox* trd_radiator = new TGeoBBox("", activeAreaX /2., activeAreaY /2., radiator_thickness /2.);
+    TGeoBBox* trd_radiator     = new TGeoBBox("trd_radiator", sizeX / 2., sizeY / 2., radiator_thickness / 2.);
+    TGeoVolume* trdmod1_radvol = new TGeoVolume("radiator", trd_radiator, radVolMed);
+    //     TGeoVolume* trdmod1_radvol = new TGeoVolume(Form("module%d_radiator", moduleType), trd_radiator, radVolMed);
+    //     TGeoVolume* trdmod1_radvol = new TGeoVolume(Form("trd1mod%dradiator", moduleType), trd_radiator, radVolMed);
+    trdmod1_radvol->SetLineColor(kBlue);
+    trdmod1_radvol->SetTransparency(70);  // (60);  // (70);  // set transparency for the TRD radiator
+    TGeoTranslation* trd_radiator_trans = new TGeoTranslation("", 0., 0., radiator_position);
+    module->AddNode(trdmod1_radvol, 1, trd_radiator_trans);
+  }
+
+  // Lattice grid
+  if (IncludeLattice) {
+
+    if (type == 0)  // inner modules
+    {
+      //     printf("lattice type %d\n", type);
+      // drift window - lattice grid - sprossenfenster
+      TGeoBBox* trd_lattice_mod0_ho = new TGeoBBox("trd_lattice_mod0_ho", sizeX / 2., lattice_o_width[type] / 2.,
+                                                   lattice_thickness / 2.);  // horizontal outer
+      TGeoBBox* trd_lattice_mod0_hi =
+        new TGeoBBox("trd_lattice_mod0_hi", sizeX / 2. - lattice_o_width[type], lattice_i_width[type] / 2.,
+                     lattice_thickness / 2.);  // horizontal inner
+      TGeoBBox* trd_lattice_mod0_vo =
+        new TGeoBBox("trd_lattice_mod0_vo", lattice_o_width[type] / 2., sizeX / 2. - lattice_o_width[type],
+                     lattice_thickness / 2.);  // vertical outer
+      TGeoBBox* trd_lattice_mod0_vi = new TGeoBBox("trd_lattice_mod0_vi", lattice_i_width[type] / 2.,
+                                                   0.20 * activeAreaY / 2. - lattice_i_width[type] / 2.,
+                                                   lattice_thickness / 2.);  // vertical inner
+      TGeoBBox* trd_lattice_mod0_vb = new TGeoBBox("trd_lattice_mod0_vb", lattice_i_width[type] / 2.,
+                                                   0.20 * activeAreaY / 2. - lattice_i_width[type] / 4.,
+                                                   lattice_thickness / 2.);  // vertical border
+
+      TGeoVolume* trd_lattice_mod0_vol_ho = new TGeoVolume("lattice0ho", trd_lattice_mod0_ho, latticeVolMed);
+      TGeoVolume* trd_lattice_mod0_vol_hi = new TGeoVolume("lattice0hi", trd_lattice_mod0_hi, latticeVolMed);
+      TGeoVolume* trd_lattice_mod0_vol_vo = new TGeoVolume("lattice0vo", trd_lattice_mod0_vo, latticeVolMed);
+      TGeoVolume* trd_lattice_mod0_vol_vi = new TGeoVolume("lattice0vi", trd_lattice_mod0_vi, latticeVolMed);
+      TGeoVolume* trd_lattice_mod0_vol_vb = new TGeoVolume("lattice0vb", trd_lattice_mod0_vb, latticeVolMed);
+
+      trd_lattice_mod0_vol_ho->SetLineColor(kYellow);  // kBlue);
+      trd_lattice_mod0_vol_vo->SetLineColor(kYellow);  // kOrange);
+      trd_lattice_mod0_vol_hi->SetLineColor(kYellow);  // kRed);
+      trd_lattice_mod0_vol_vi->SetLineColor(kYellow);  // kWhite);
+      trd_lattice_mod0_vol_vb->SetLineColor(kYellow);
+
+      TGeoTranslation* tv010 =
+        new TGeoTranslation("tv010", 0., (1.00 * activeAreaY / 2. + lattice_o_width[type] / 2.), 0);
+      TGeoTranslation* tv015 =
+        new TGeoTranslation("tv015", 0., -(1.00 * activeAreaY / 2. + lattice_o_width[type] / 2.), 0);
+
+      TGeoTranslation* th020 =
+        new TGeoTranslation("th020", (1.00 * activeAreaX / 2. + lattice_o_width[type] / 2.), 0., 0);
+      TGeoTranslation* th025 =
+        new TGeoTranslation("th025", -(1.00 * activeAreaX / 2. + lattice_o_width[type] / 2.), 0., 0);
+
+      Double_t hypos0[4] = {(0.60 * activeAreaY / 2.), (0.20 * activeAreaY / 2.), -(0.20 * activeAreaY / 2.),
+                            -(0.60 * activeAreaY / 2.)};
+
+      Double_t vxpos0[4] = {(0.60 * activeAreaX / 2.), (0.20 * activeAreaX / 2.), -(0.20 * activeAreaX / 2.),
+                            -(0.60 * activeAreaX / 2.)};
+
+      Double_t vypos0[5] = {(0.80 * activeAreaY / 2. + lattice_i_width[type] / 4.), (0.40 * activeAreaY / 2.),
+                            (0.00 * activeAreaY / 2.), -(0.40 * activeAreaY / 2.),
+                            -(0.80 * activeAreaY / 2. + lattice_i_width[type] / 4.)};
+
+      //       TGeoVolumeAssembly* trdmod0_lattice = new TGeoVolumeAssembly("mod0lattice"); // volume for lattice grid
+
+      TGeoBBox* trd_lattice_mod0  = new TGeoBBox("trd_lattice_mod0", sizeX / 2., sizeY / 2., lattice_thickness / 2.);
+      TGeoVolume* trdmod0_lattice = new TGeoVolume("lat_grid_mod0", trd_lattice_mod0, keepVolMed);
+
+      //       trdmod0_lattice->SetLineColor(kGreen);  // set color for keeping volume
+
+      // outer frame
+      trdmod0_lattice->AddNode(trd_lattice_mod0_vol_ho, 1, tv010);
+      trdmod0_lattice->AddNode(trd_lattice_mod0_vol_ho, 2, tv015);
+
+      trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vo, 3, th020);
+      trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vo, 4, th025);
+
+      // lattice piece number
+      Int_t lat0_no = 5;
+
+      // horizontal bars
+      for (Int_t y = 0; y < 4; y++) {
+        TGeoTranslation* t0xy = new TGeoTranslation("", 0, hypos0[y], 0);
+        trdmod0_lattice->AddNode(trd_lattice_mod0_vol_hi, lat0_no, t0xy);
+        lat0_no++;
+      }
+
+      // vertical bars
+      for (Int_t x = 0; x < 4; x++)
+        for (Int_t y = 0; y < 5; y++) {
+          TGeoTranslation* t0xy = new TGeoTranslation("", vxpos0[x], vypos0[y], 0);
+          if ((y == 0) || (y == 4)) trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vb, lat0_no, t0xy);  // border piece
+          else
+            trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vi, lat0_no, t0xy);  // middle piece
+          lat0_no++;
+        }
+
+      // add lattice to module
+      TGeoTranslation* trd_lattice_trans = new TGeoTranslation("", 0., 0., lattice_position);
+      module->AddNode(trdmod0_lattice, 1, trd_lattice_trans);
+    }
+
+    else if (type == 1)  // outer modules
+    {
+      //     printf("lattice type %d\n", type);
+      // drift window - lattice grid - sprossenfenster
+      TGeoBBox* trd_lattice_mod1_ho = new TGeoBBox("trd_lattice_mod1_ho", sizeX / 2., lattice_o_width[type] / 2.,
+                                                   lattice_thickness / 2.);  // horizontal outer
+      TGeoBBox* trd_lattice_mod1_hi =
+        new TGeoBBox("trd_lattice_mod1_hi", sizeX / 2. - lattice_o_width[type], lattice_i_width[type] / 2.,
+                     lattice_thickness / 2.);  // horizontal inner
+      TGeoBBox* trd_lattice_mod1_vo =
+        new TGeoBBox("trd_lattice_mod1_vo", lattice_o_width[type] / 2., sizeX / 2. - lattice_o_width[type],
+                     lattice_thickness / 2.);  // vertical outer
+      TGeoBBox* trd_lattice_mod1_vi = new TGeoBBox("trd_lattice_mod1_vi", lattice_i_width[type] / 2.,
+                                                   0.125 * activeAreaY / 2. - lattice_i_width[type] / 2.,
+                                                   lattice_thickness / 2.);  // vertical inner
+      TGeoBBox* trd_lattice_mod1_vb = new TGeoBBox("trd_lattice_mod1_vb", lattice_i_width[type] / 2.,
+                                                   0.125 * activeAreaY / 2. - lattice_i_width[type] / 4.,
+                                                   lattice_thickness / 2.);  // vertical border
+
+      TGeoVolume* trd_lattice_mod1_vol_ho = new TGeoVolume("lattice1ho", trd_lattice_mod1_ho, latticeVolMed);
+      TGeoVolume* trd_lattice_mod1_vol_hi = new TGeoVolume("lattice1hi", trd_lattice_mod1_hi, latticeVolMed);
+      TGeoVolume* trd_lattice_mod1_vol_vo = new TGeoVolume("lattice1vo", trd_lattice_mod1_vo, latticeVolMed);
+      TGeoVolume* trd_lattice_mod1_vol_vi = new TGeoVolume("lattice1vi", trd_lattice_mod1_vi, latticeVolMed);
+      TGeoVolume* trd_lattice_mod1_vol_vb = new TGeoVolume("lattice1vb", trd_lattice_mod1_vb, latticeVolMed);
+
+      trd_lattice_mod1_vol_ho->SetLineColor(kYellow);  // kBlue);
+      trd_lattice_mod1_vol_vo->SetLineColor(kYellow);  // kOrange);
+      trd_lattice_mod1_vol_hi->SetLineColor(kYellow);  // kRed);
+      trd_lattice_mod1_vol_vi->SetLineColor(kYellow);  // kWhite);
+      trd_lattice_mod1_vol_vb->SetLineColor(kYellow);
+
+      TGeoTranslation* tv110 =
+        new TGeoTranslation("tv110", 0., (1.00 * activeAreaY / 2. + lattice_o_width[type] / 2.), 0);
+      TGeoTranslation* tv118 =
+        new TGeoTranslation("tv118", 0., -(1.00 * activeAreaY / 2. + lattice_o_width[type] / 2.), 0);
+
+      TGeoTranslation* th120 =
+        new TGeoTranslation("th120", (1.00 * activeAreaX / 2. + lattice_o_width[type] / 2.), 0., 0);
+      TGeoTranslation* th128 =
+        new TGeoTranslation("th128", -(1.00 * activeAreaX / 2. + lattice_o_width[type] / 2.), 0., 0);
+
+      Double_t hypos1[7] = {(0.75 * activeAreaY / 2.), (0.50 * activeAreaY / 2.),  (0.25 * activeAreaY / 2.),
+                            (0.00 * activeAreaY / 2.), -(0.25 * activeAreaY / 2.), -(0.50 * activeAreaY / 2.),
+                            -(0.75 * activeAreaY / 2.)};
+
+      Double_t vxpos1[7] = {(0.75 * activeAreaX / 2.), (0.50 * activeAreaX / 2.),  (0.25 * activeAreaX / 2.),
+                            (0.00 * activeAreaX / 2.), -(0.25 * activeAreaX / 2.), -(0.50 * activeAreaX / 2.),
+                            -(0.75 * activeAreaX / 2.)};
+
+      Double_t vypos1[8] = {(0.875 * activeAreaY / 2. + lattice_i_width[type] / 4.),
+                            (0.625 * activeAreaY / 2.),
+                            (0.375 * activeAreaY / 2.),
+                            (0.125 * activeAreaY / 2.),
+                            -(0.125 * activeAreaY / 2.),
+                            -(0.375 * activeAreaY / 2.),
+                            -(0.625 * activeAreaY / 2.),
+                            -(0.875 * activeAreaY / 2. + lattice_i_width[type] / 4.)};
+
+      //       TGeoVolumeAssembly* trdmod1_lattice = new TGeoVolumeAssembly("mod1lattice"); // volume for lattice grid
+
+      TGeoBBox* trd_lattice_mod1  = new TGeoBBox("trd_lattice_mod1", sizeX / 2., sizeY / 2., lattice_thickness / 2.);
+      TGeoVolume* trdmod1_lattice = new TGeoVolume("lat_grid_mod1", trd_lattice_mod1, keepVolMed);
+
+      //       trdmod1_lattice->SetLineColor(kGreen);  // set color for keeping volume
+
+      // outer frame
+      trdmod1_lattice->AddNode(trd_lattice_mod1_vol_ho, 1, tv110);
+      trdmod1_lattice->AddNode(trd_lattice_mod1_vol_ho, 2, tv118);
+
+      trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vo, 3, th120);
+      trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vo, 4, th128);
+
+      // lattice piece number
+      Int_t lat1_no = 5;
+
+      // horizontal bars
+      for (Int_t y = 0; y < 7; y++) {
+        TGeoTranslation* t1xy = new TGeoTranslation("", 0, hypos1[y], 0);
+        trdmod1_lattice->AddNode(trd_lattice_mod1_vol_hi, lat1_no, t1xy);
+        lat1_no++;
+      }
+
+      // vertical bars
+      for (Int_t x = 0; x < 7; x++)
+        for (Int_t y = 0; y < 8; y++) {
+          TGeoTranslation* t1xy = new TGeoTranslation("", vxpos1[x], vypos1[y], 0);
+          if ((y == 0) || (y == 7)) trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vb, lat1_no, t1xy);  // border piece
+          else
+            trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vi, lat1_no, t1xy);  // middle piece
+          lat1_no++;
+        }
+
+      // add lattice to module
+      TGeoTranslation* trd_lattice_trans = new TGeoTranslation("", 0., 0., lattice_position);
+      module->AddNode(trdmod1_lattice, 1, trd_lattice_trans);
+    }
+
+  }  // with lattice grid
+
+  if (IncludeKaptonFoil) {
+    // Kapton Foil
+    TGeoBBox* trd_kapton          = new TGeoBBox("trd_kapton", sizeX / 2., sizeY / 2., kapton_thickness / 2.);
+    TGeoVolume* trdmod1_kaptonvol = new TGeoVolume("kaptonfoil", trd_kapton, kaptonVolMed);
+    //   TGeoVolume* trdmod1_kaptonvol = new TGeoVolume(Form("module%d_kaptonfoil", moduleType), trd_kapton, kaptonVolMed);
+    //   TGeoVolume* trdmod1_kaptonvol = new TGeoVolume(Form("trd1mod%dkapton", moduleType), trd_kapton, kaptonVolMed);
+    trdmod1_kaptonvol->SetLineColor(kGreen);
+    TGeoTranslation* trd_kapton_trans = new TGeoTranslation("", 0., 0., kapton_position);
+    module->AddNode(trdmod1_kaptonvol, 1, trd_kapton_trans);
+  }
+
+  // start of Frame in z
+  // Gas
+  TGeoBBox* trd_gas          = new TGeoBBox("trd_gas", activeAreaX / 2., activeAreaY / 2., gas_thickness / 2.);
+  TGeoVolume* trdmod1_gasvol = new TGeoVolume("gas", trd_gas, gasVolMed);
+  //   TGeoVolume* trdmod1_gasvol = new TGeoVolume(Form("module%d_gas", moduleType), trd_gas, gasVolMed);
+  //   TGeoVolume* trdmod1_gasvol = new TGeoVolume(Form("trd1mod%dgas", moduleType), trd_gas, gasVolMed);
+  //   trdmod1_gasvol->SetLineColor(kBlue);
+  trdmod1_gasvol->SetLineColor(kGreen);  // to avoid blue overlaps in the screenshots
+  trdmod1_gasvol->SetTransparency(40);   // set transparency for the TRD gas
+  TGeoTranslation* trd_gas_trans = new TGeoTranslation("", 0., 0., gas_position);
+  module->AddNode(trdmod1_gasvol, 1, trd_gas_trans);
+  // end of Frame in z
+
+  if (IncludeGasFrame) {
+    // frame1
+    TGeoBBox* trd_frame1          = new TGeoBBox("trd_frame1", sizeX / 2., frameWidth / 2., frame_thickness / 2.);
+    TGeoVolume* trdmod1_frame1vol = new TGeoVolume("frame1", trd_frame1, frameVolMed);
+    trdmod1_frame1vol->SetLineColor(kRed);
+
+    // translations
+    TGeoTranslation* trd_frame1_trans = new TGeoTranslation("", 0., activeAreaY / 2. + frameWidth / 2., frame_position);
+    module->AddNode(trdmod1_frame1vol, 1, trd_frame1_trans);
+    trd_frame1_trans = new TGeoTranslation("", 0., -(activeAreaY / 2. + frameWidth / 2.), frame_position);
+    module->AddNode(trdmod1_frame1vol, 2, trd_frame1_trans);
+
+
+    // frame2
+    TGeoBBox* trd_frame2          = new TGeoBBox("trd_frame2", frameWidth / 2., activeAreaY / 2., frame_thickness / 2.);
+    TGeoVolume* trdmod1_frame2vol = new TGeoVolume("frame2", trd_frame2, frameVolMed);
+    trdmod1_frame2vol->SetLineColor(kRed);
+
+    // translations
+    TGeoTranslation* trd_frame2_trans = new TGeoTranslation("", activeAreaX / 2. + frameWidth / 2., 0., frame_position);
+    module->AddNode(trdmod1_frame2vol, 1, trd_frame2_trans);
+    trd_frame2_trans = new TGeoTranslation("", -(activeAreaX / 2. + frameWidth / 2.), 0., frame_position);
+    module->AddNode(trdmod1_frame2vol, 2, trd_frame2_trans);
+  }
+
+  if (IncludePadplane) {
+    // Pad Copper
+    TGeoBBox* trd_padcopper          = new TGeoBBox("trd_padcopper", sizeX / 2., sizeY / 2., padcopper_thickness / 2.);
+    TGeoVolume* trdmod1_padcoppervol = new TGeoVolume("padcopper", trd_padcopper, padcopperVolMed);
+    //   TGeoVolume* trdmod1_padcoppervol = new TGeoVolume(Form("module%d_padcopper", moduleType), trd_padcopper, padcopperVolMed);
+    //   TGeoVolume* trdmod1_padcoppervol = new TGeoVolume(Form("trd1mod%dpadcopper", moduleType), trd_padcopper, padcopperVolMed);
+    trdmod1_padcoppervol->SetLineColor(kOrange);
+    TGeoTranslation* trd_padcopper_trans = new TGeoTranslation("", 0., 0., padcopper_position);
+    module->AddNode(trdmod1_padcoppervol, 1, trd_padcopper_trans);
+
+    // Pad Plane
+    TGeoBBox* trd_padpcb          = new TGeoBBox("trd_padpcb", sizeX / 2., sizeY / 2., padplane_thickness / 2.);
+    TGeoVolume* trdmod1_padpcbvol = new TGeoVolume("padplane", trd_padpcb, padpcbVolMed);
+    //   TGeoVolume* trdmod1_padpcbvol = new TGeoVolume(Form("module%d_padplane", moduleType), trd_padpcb, padpcbVolMed);
+    //   TGeoVolume* trdmod1_padpcbvol = new TGeoVolume(Form("trd1mod%dpadplane", moduleType), trd_padpcb, padpcbVolMed);
+    trdmod1_padpcbvol->SetLineColor(kBlue);
+    TGeoTranslation* trd_padpcb_trans = new TGeoTranslation("", 0., 0., padplane_position);
+    module->AddNode(trdmod1_padpcbvol, 1, trd_padpcb_trans);
+  }
+
+  if (IncludeBackpanel) {
+    // Honeycomb
+    TGeoBBox* trd_honeycomb          = new TGeoBBox("trd_honeycomb", sizeX / 2., sizeY / 2., honeycomb_thickness / 2.);
+    TGeoVolume* trdmod1_honeycombvol = new TGeoVolume("honeycomb", trd_honeycomb, honeycombVolMed);
+    //   TGeoVolume* trdmod1_honeycombvol = new TGeoVolume(Form("module%d_honeycomb", moduleType), trd_honeycomb, honeycombVolMed);
+    //   TGeoVolume* trdmod1_honeycombvol = new TGeoVolume(Form("trd1mod%dhoneycomb", moduleType), trd_honeycomb, honeycombVolMed);
+    trdmod1_honeycombvol->SetLineColor(kOrange);
+    TGeoTranslation* trd_honeycomb_trans = new TGeoTranslation("", 0., 0., honeycomb_position);
+    module->AddNode(trdmod1_honeycombvol, 1, trd_honeycomb_trans);
+
+    // Carbon fiber layers
+    TGeoBBox* trd_carbon          = new TGeoBBox("trd_carbon", sizeX / 2., sizeY / 2., carbon_thickness / 2.);
+    TGeoVolume* trdmod1_carbonvol = new TGeoVolume("carbonsheet", trd_carbon, carbonVolMed);
+    //   TGeoVolume* trdmod1_carbonvol = new TGeoVolume(Form("module%d_carbonsheet", moduleType), trd_carbon, carbonVolMed);
+    //   TGeoVolume* trdmod1_carbonvol = new TGeoVolume(Form("trd1mod%dcarbon", moduleType), trd_carbon, carbonVolMed);
+    trdmod1_carbonvol->SetLineColor(kGreen);
+    TGeoTranslation* trd_carbon_trans = new TGeoTranslation("", 0., 0., carbon_position);
+    module->AddNode(trdmod1_carbonvol, 1, trd_carbon_trans);
+  }
+
+  if (IncludeAluLedge) {
+    // Al-ledge
+    TGeoBBox* trd_aluledge1 = new TGeoBBox("trd_aluledge1", sizeY / 2., aluminium_width / 2., aluminium_thickness / 2.);
+    TGeoVolume* trdmod1_aluledge1vol = new TGeoVolume("aluledge1", trd_aluledge1, aluledgeVolMed);
+    trdmod1_aluledge1vol->SetLineColor(kRed);
+
+    // translations
+    TGeoTranslation* trd_aluledge1_trans =
+      new TGeoTranslation("", 0., sizeY / 2. - aluminium_width / 2., aluminium_position);
+    module->AddNode(trdmod1_aluledge1vol, 1, trd_aluledge1_trans);
+    trd_aluledge1_trans = new TGeoTranslation("", 0., -(sizeY / 2. - aluminium_width / 2.), aluminium_position);
+    module->AddNode(trdmod1_aluledge1vol, 2, trd_aluledge1_trans);
+
+
+    // Al-ledge
+    TGeoBBox* trd_aluledge2 =
+      new TGeoBBox("trd_aluledge2", aluminium_width / 2., sizeY / 2. - aluminium_width, aluminium_thickness / 2.);
+    TGeoVolume* trdmod1_aluledge2vol = new TGeoVolume("aluledge2", trd_aluledge2, aluledgeVolMed);
+    trdmod1_aluledge2vol->SetLineColor(kRed);
+
+    // translations
+    TGeoTranslation* trd_aluledge2_trans =
+      new TGeoTranslation("", sizeX / 2. - aluminium_width / 2., 0., aluminium_position);
+    module->AddNode(trdmod1_aluledge2vol, 1, trd_aluledge2_trans);
+    trd_aluledge2_trans = new TGeoTranslation("", -(sizeX / 2. - aluminium_width / 2.), 0., aluminium_position);
+    module->AddNode(trdmod1_aluledge2vol, 2, trd_aluledge2_trans);
+  }
+
+  // FEBs
+  if (IncludeFebs) {
+    // assemblies
+    TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly("febvol");  // the mother volume of all FEBs
+    TGeoVolumeAssembly* trd_feb_box =
+      new TGeoVolumeAssembly("febbox");  // volume for inclined FEBs, then shifted along y
+    //TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly(Form("module%d_febvol", moduleType));  // the mother volume of all FEBs
+    //TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly(Form("module%d_febbox", moduleType));  // volume for inclined FEBs, then shifted along y
+    //TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly(Form("trd1mod%dfebvol", moduleType));  // the mother volume of all FEBs
+    //TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly(Form("trd1mod%dfebbox", moduleType));  // volume for inclined FEBs, then shifted along y
+
+    // translations + rotations
+    TGeoTranslation* trd_feb_trans1;      // center to corner
+    TGeoTranslation* trd_feb_trans2;      // corner back
+    TGeoRotation* trd_feb_rotation;       // rotation around x axis
+    TGeoTranslation* trd_feb_y_position;  // shift to y position on TRD
+    //      TGeoTranslation *trd_feb_null;       // no displacement
+
+    // replaced by matrix operation (see below)
+    //  //      Double_t yback, zback;
+    //  //      TGeoCombiTrans  *trd_feb_placement;
+    //  //      // fix Z back offset 0.3 at some point
+    //  //      yback = -    sin(feb_rotation_angle/180*3.141)  * feb_width /2.;
+    //  //      zback = - (1-cos(feb_rotation_angle/180*3.141)) * feb_width /2. + 0.3;
+    //  //      trd_feb_placement = new TGeoCombiTrans(0, feb_pos_y + yback, zback, trd_feb_rotation);
+    //  //      trd_feb_box->AddNode(trdmod1_feb, iFeb+1, trd_feb_placement);
+
+    //      trd_feb_null       = new TGeoTranslation("", 0., 0., 0.);  // empty operation
+    trd_feb_trans1   = new TGeoTranslation("", 0., -feb_thickness / 2.,
+                                         -feb_width / 2.);  // move bottom right corner to center
+    trd_feb_trans2   = new TGeoTranslation("", 0., feb_thickness / 2.,
+                                         feb_width / 2.);  // move bottom right corner back
+    trd_feb_rotation = new TGeoRotation();
+    trd_feb_rotation->RotateX(feb_rotation_angle[moduleType - 1]);
+
+    TGeoHMatrix* incline_feb = new TGeoHMatrix("");
+
+    //        (*incline_feb) = (*trd_feb_null);        // OK
+    //        (*incline_feb) = (*trd_feb_y_position);  // OK
+    //        (*incline_feb) = (*trd_feb_trans1);      // OK
+    //        (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_y_position);  // OK
+    //        (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_trans2);      // OK
+    //        (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation);    // OK
+    //        (*incline_feb) =  (*trd_feb_trans1) * (*trd_feb_rotation) * (*trd_feb_trans2) * (*trd_feb_y_position);  // not OK
+    // trd_feb_y_position is displaced in rotated coordinate system
+
+    // matrix operation to rotate FEB PCB around its corner on the backanel
+    (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation) * (*trd_feb_trans2);  // OK
+
+    // Create all FEBs and place them in an assembly which will be added to the TRD module
+    TGeoBBox* trd_feb       = new TGeoBBox("trd_feb", activeAreaX / 2., feb_thickness / 2.,
+                                     feb_width / 2.);               // the FEB itself - as a cuboid
+    TGeoVolume* trdmod1_feb = new TGeoVolume("feb", trd_feb, febVolMed);  // the FEB made of a certain medium
+    //      TGeoVolume* trdmod1_feb = new TGeoVolume(Form("module%d_feb", moduleType), trd_feb, febVolMed);  // the FEB made of a certain medium
+    //      TGeoVolume* trdmod1_feb = new TGeoVolume(Form("trd1mod%dfeb", moduleType), trd_feb, febVolMed);  // the FEB made of a certain medium
+    trdmod1_feb->SetLineColor(kYellow);  // set yellow color
+    trd_feb_box->AddNode(trdmod1_feb, 1, incline_feb);
+    // now we have an inclined FEB
+
+    // ASICs
+    if (IncludeAsics) {
+      Double_t asic_pos;
+      Double_t asic_pos_x;
+      TGeoTranslation* trd_asic_trans0;  // ASIC on FEB x position
+      TGeoTranslation* trd_asic_trans1;  // center to corner
+      TGeoTranslation* trd_asic_trans2;  // corner back
+      TGeoRotation* trd_asic_rotation;   // rotation around x axis
+
+      trd_asic_trans1   = new TGeoTranslation("", 0., -(feb_thickness + asic_offset + asic_thickness / 2.),
+                                            -feb_width / 2.);  // move ASIC center to FEB corner
+      trd_asic_trans2   = new TGeoTranslation("", 0., feb_thickness + asic_offset + asic_thickness / 2.,
+                                            feb_width / 2.);  // move FEB corner back to asic center
+      trd_asic_rotation = new TGeoRotation();
+      trd_asic_rotation->RotateX(feb_rotation_angle[moduleType - 1]);
+
+      TGeoHMatrix* incline_asic;
+
+      // put many ASICs on each inclined FEB
+      TGeoBBox* trd_asic = new TGeoBBox("trd_asic", asic_width / 2., asic_thickness / 2.,
+                                        asic_width / 2.);  // ASIC dimensions
+      // TODO: use Silicon as ASICs material
+      TGeoVolume* trdmod1_asic = new TGeoVolume("asic", trd_asic, asicVolMed);  // the ASIC made of a certain medium
+      //        TGeoVolume* trdmod1_asic = new TGeoVolume(Form("module%d_asic", moduleType), trd_asic, asicVolMed);   // the ASIC made of a certain medium
+      //        TGeoVolume* trdmod1_asic = new TGeoVolume(Form("trd1mod%dasic", moduleType), trd_asic, asicVolMed);   // the ASIC made of a certain medium
+      trdmod1_asic->SetLineColor(kBlue);  // set blue color for ASICs
+
+      Int_t nofAsics   = AsicsPerFeb[moduleType - 1] % 100;
+      Int_t groupAsics = AsicsPerFeb[moduleType - 1] / 100;  // either 1 or 2 or 3 (new ultimate)
+
+      if ((nofAsics == 16) && (activeAreaX < 60)) asic_distance = 0.0;  // for 57 cm  // 0.1;  // for 60 cm
+      else
+        asic_distance = 0.4;
+
+      for (Int_t iAsic = 0; iAsic < (nofAsics / groupAsics); iAsic++) {
+        if (groupAsics == 1)  // single ASICs
+        {
+          asic_pos =
+            (iAsic + 0.5) / nofAsics - 0.5;  // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3
+
+          // ASIC 1
+          asic_pos_x      = asic_pos * activeAreaX;
+          trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset,
+                                                0.);  // move asic on top of FEB
+          incline_asic    = new TGeoHMatrix("");
+          (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2);  // OK
+          trd_feb_box->AddNode(trdmod1_asic, iAsic + 1,
+                               incline_asic);  // now we have ASICs on the inclined FEB
+        }
+
+        if (groupAsics == 2)  // pairs of ASICs
+        {
+          asic_pos = (iAsic + 0.5) / (nofAsics / groupAsics)
+                     - 0.5;  // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3
+
+          // ASIC 1
+          asic_pos_x      = asic_pos * activeAreaX + (0.5 + asic_distance / 2.) * asic_width;
+          trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset,
+                                                0.);  // move asic on top of FEB);
+          incline_asic    = new TGeoHMatrix("");
+          (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2);  // OK
+          trd_feb_box->AddNode(trdmod1_asic, 2 * iAsic + 1,
+                               incline_asic);  // now we have ASICs on the inclined FEB
+
+          // ASIC 2
+          asic_pos_x      = asic_pos * activeAreaX - (0.5 + asic_distance / 2.) * asic_width;
+          trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset,
+                                                0.);  // move asic on top of FEB
+          incline_asic    = new TGeoHMatrix("");
+          (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2);  // OK
+          trd_feb_box->AddNode(trdmod1_asic, 2 * iAsic + 2,
+                               incline_asic);  // now we have ASICs on the inclined FEB
+        }
+
+        if (groupAsics == 3)  // triplets of ASICs
+        {
+          asic_pos = (iAsic + 0.5) / (nofAsics / groupAsics)
+                     - 0.5;  // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3
+
+          // ASIC 1
+          asic_pos_x      = asic_pos * activeAreaX + 1.1 * asic_width;  // (0.5 + asic_distance/2.) * asic_width;
+          trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset,
+                                                0.);  // move asic on top of FEB);
+          incline_asic    = new TGeoHMatrix("");
+          (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2);  // OK
+          trd_feb_box->AddNode(trdmod1_asic, 3 * iAsic + 1,
+                               incline_asic);  // now we have ASICs on the inclined FEB
+
+          // ASIC 2
+          asic_pos_x      = asic_pos * activeAreaX;
+          trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset,
+                                                0.);  // move asic on top of FEB
+          incline_asic    = new TGeoHMatrix("");
+          (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2);  // OK
+          trd_feb_box->AddNode(trdmod1_asic, 3 * iAsic + 2,
+                               incline_asic);  // now we have ASICs on the inclined FEB
+
+          // ASIC 3
+          asic_pos_x      = asic_pos * activeAreaX - 1.1 * asic_width;  // (0.5 + asic_distance/2.) * asic_width;
+          trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset,
+                                                0.);  // move asic on top of FEB
+          incline_asic    = new TGeoHMatrix("");
+          (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2);  // OK
+          trd_feb_box->AddNode(trdmod1_asic, 3 * iAsic + 3,
+                               incline_asic);  // now we have ASICs on the inclined FEB
+        }
+      }
+      // now we have an inclined FEB with ASICs
+    }
+
+
+    // now go on with FEB placement
+    Double_t feb_pos;
+    Double_t feb_pos_y;
+
+    Int_t nofFebs = FebsPerModule[moduleType - 1];
+    for (Int_t iFeb = 0; iFeb < nofFebs; iFeb++) {
+      feb_pos = (iFeb + 0.5) / nofFebs - 0.5;  // equal spacing of FEBs on the backpanel
+      // cout << "feb_pos " << iFeb << ": " << feb_pos << endl;
+      feb_pos_y = feb_pos * activeAreaY;
+      feb_pos_y += feb_width / 2. * sin(feb_rotation_angle[moduleType - 1] * acos(-1.) / 180.);
+
+      // shift inclined FEB in y to its final position
+      trd_feb_y_position = new TGeoTranslation("", 0., feb_pos_y,
+                                               feb_z_offset);  // with additional fixed offset in z direction
+      //        trd_feb_y_position = new TGeoTranslation("", 0., feb_pos_y, 0.0);  // touching the backpanel with the corner
+      trd_feb_vol->AddNode(trd_feb_box, iFeb + 1, trd_feb_y_position);  // position FEB in y
+    }
+
+    if (IncludeRobs) {
+      // GBTx ROBs
+      Double_t rob_size_x    = 20.0;  // 13.0; // 130 mm
+      Double_t rob_size_y    = 9.0;   //  4.5; //  45 mm
+      Double_t rob_offset    = 1.2;
+      Double_t rob_thickness = feb_thickness;
+
+      TGeoVolumeAssembly* trd_rob_box =
+        new TGeoVolumeAssembly("robbox");  // volume for inclined FEBs, then shifted along y
+      TGeoBBox* trd_rob       = new TGeoBBox("trd_rob", rob_size_x / 2., rob_size_y / 2.,
+                                       rob_thickness / 2.);           // the ROB itself
+      TGeoVolume* trdmod1_rob = new TGeoVolume("rob", trd_rob, febVolMed);  // the ROB made of a certain medium
+      trdmod1_rob->SetLineColor(kRed);                                      // set color
+
+      //      TGeoHMatrix *incline_rob = new TGeoHMatrix("");
+      trd_rob_box->AddNode(trdmod1_rob, 1);
+
+      // GBTXs
+      Double_t gbtx_pos;
+      Double_t gbtx_pos_x;
+      Double_t gbtx_pos_y;
+      TGeoTranslation* trd_gbtx_trans1;  // center to corner
+
+      // GBTX parameters
+      const Double_t gbtx_thickness = 0.25;  // 2.5 mm
+      const Double_t gbtx_width     = 3.0;   // 2.0;  1.0;   // 1 cm
+
+      // put many GBTXs on each inclined FEB
+      TGeoBBox* trd_gbtx       = new TGeoBBox("trd_gbtx", gbtx_width / 2., gbtx_width / 2.,
+                                        gbtx_thickness / 2.);             // GBTX dimensions
+      TGeoVolume* trdmod1_gbtx = new TGeoVolume("gbtx", trd_gbtx, asicVolMed);  // the GBTX made of a certain medium
+      trdmod1_gbtx->SetLineColor(kGreen);                                       // set color for GBTXs
+
+      Int_t nofGbtxs   = GbtxPerRob[moduleType - 1] % 100;
+      Int_t groupGbtxs = GbtxPerRob[moduleType - 1] / 100;  // usually 1
+
+      //      nofGbtxs   = 7;
+      //      groupGbtxs = 1;
+
+      Int_t nofGbtxX = (nofGbtxs - 1) / 2. + 1;  // +1 is for GBTx master
+      Int_t nofGbtxY = 2;
+
+      Double_t gbtx_distance = 0.4;
+      Int_t iGbtx            = 1;
+
+      for (Int_t iGbtxX = 0; iGbtxX < nofGbtxX; iGbtxX++) {
+        gbtx_pos = (iGbtxX + 0.5) / nofGbtxX - 0.5;  // equal spacing of GBTXs on the FEB, e.g. for no=3 : -1/3, 0, +1/3
+        gbtx_pos_x = -gbtx_pos * rob_size_x;
+
+        if (iGbtxX > 0)
+          for (Int_t iGbtxY = 0; iGbtxY < nofGbtxY; iGbtxY++) {
+            gbtx_pos =
+              (iGbtxY + 0.5) / nofGbtxY - 0.5;  // equal spacing of GBTXs on the FEB, e.g. for no=3 : -1/3, 0, +1/3
+            gbtx_pos_y = gbtx_pos * rob_size_y;
+
+            trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y,
+                                                  rob_thickness / 2. + gbtx_thickness / 2.);  // move gbtx on top of ROB
+            trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++,
+                                 trd_gbtx_trans1);  // now we have GBTXs on the ROB
+          }
+        else {
+          gbtx_pos_y = 0;
+
+          trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y,
+                                                rob_thickness / 2. + gbtx_thickness / 2.);  // move gbtx on top of ROB
+          trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++,
+                               trd_gbtx_trans1);  // now we have GBTXs on the ROB
+        }
+      }
+
+      // now go on with ROB placement
+      Double_t rob_pos;
+      Double_t rob_pos_y;
+      TGeoTranslation* trd_rob_y_position;  // shift to y position on TRD
+
+      Int_t nofRobs = RobsPerModule[moduleType - 1];
+      for (Int_t iRob = 0; iRob < nofRobs; iRob++) {
+        rob_pos   = (iRob + 0.5) / nofRobs - 0.5;  // equal spacing of ROBs on the backpanel
+        rob_pos_y = rob_pos * activeAreaY;
+
+        // shift inclined ROB in y to its final position
+        if (feb_rotation_angle[moduleType - 1] == 90)  // if FEB parallel to backpanel
+          trd_rob_y_position = new TGeoTranslation("", 0., rob_pos_y,
+                                                   -feb_width / 2. + rob_offset);  // place ROBs close to FEBs
+        else {
+          //	    Int_t rob_z_pos = 0.;  // test where ROB is placed by default
+          Int_t rob_z_pos =
+            -feb_width / 2. + feb_width * cos(feb_rotation_angle[moduleType - 1] * acos(-1.) / 180.) + rob_offset;
+          if (rob_z_pos > feb_width / 2.)  // if the rob is too far out
+          {
+            rob_z_pos = feb_width / 2. - rob_thickness;  // place ROBs at end of feb volume
+            std::cout << "GBTx ROB was outside of the FEB volume, check "
+                         "overlap with FEB"
+                      << std::endl;
+          }
+          trd_rob_y_position = new TGeoTranslation("", 0., rob_pos_y, rob_z_pos);
+        }
+        trd_feb_vol->AddNode(trd_rob_box, iRob + 1, trd_rob_y_position);  // position FEB in y
+      }
+
+    }  // IncludeGbtx
+
+    // put FEB box on module
+    TGeoTranslation* trd_febvolume_trans = new TGeoTranslation("", 0., 0., febvolume_position);
+    gGeoMan->GetVolume(name)->AddNode(trd_feb_vol, 1,
+                                      trd_febvolume_trans);  // put febvolume at correct z position wrt to the module
+  }
+
+  return module;
+}
+
+
+//________________________________________________________________________________________________
+//  TRD Bucharest module definition
+TGeoTranslation* tr(NULL);
+TString sexpr;
+void addFlatCableHoles(const Char_t* name)
+{
+  sexpr = name;
+  sexpr += "_bd";
+  for (Int_t c(0); c < 9; c++) {
+    for (Int_t r(0); r < 10; r++) {
+      tr = new TGeoTranslation(Form("t%s%d%02d", name, c, r), (c - 4) * 6, 1.35 + 2.7 * r, 0.);
+      tr->RegisterYourself();
+      sexpr += Form("-%s_fc:t%s%d%02d", name, name, c, r);
+    }
+    for (Int_t r(0); r < 10; r++) {
+      tr = new TGeoTranslation(Form("t%s%d%02d", name, c, 10 + r), (c - 4) * 6, -1.35 - 2.7 * r, 0.);
+      tr->RegisterYourself();
+      sexpr += Form("-%s_fc:t%s%d%02d", name, name, c, 10 + r);
+    }
+  }
+}
+TGeoVolume* create_trdi_module_type(Int_t type)
+{
+  Info("create_trdi_module_type", "Bulding Bucharest Module [%d].", type);
+  Int_t moduleType     = 8;
+  Double_t sizeX       = DetectorSizeX[2];
+  Double_t sizeY       = DetectorSizeY[2];
+  Double_t frameWidth  = FrameWidth[2];
+  Double_t activeAreaX = sizeX - 2 * frameWidth;
+  Double_t activeAreaY = sizeY - 2 * frameWidth;
+
+  TGeoMedium* keepVolMed      = gGeoMan->GetMedium(KeepingVolumeMedium);
+  TGeoMedium* radVolMed       = gGeoMan->GetMedium(RadiatorVolumeMedium);
+  TGeoMedium* latticeVolMed   = gGeoMan->GetMedium(LatticeVolumeMedium);
+  TGeoMedium* kaptonVolMed    = gGeoMan->GetMedium(KaptonVolumeMedium);
+  TGeoMedium* gasVolMed       = gGeoMan->GetMedium(GasVolumeMedium);
+  TGeoMedium* padcopperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium);
+  TGeoMedium* padpcbVolMed    = gGeoMan->GetMedium(PadPcbVolumeMedium);
+  TGeoMedium* honeycombVolMed = gGeoMan->GetMedium(HoneycombVolumeMedium);
+  TGeoMedium* carbonVolMed    = gGeoMan->GetMedium(CarbonVolumeMedium);
+  //  TGeoMedium* mylarVolMed       = gGeoMan->GetMedium(MylarVolumeMedium);
+  //  TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsVolumeMedium);
+  TGeoMedium* frameVolMed     = gGeoMan->GetMedium(FrameVolumeMedium);
+  TGeoMedium* febVolMed       = gGeoMan->GetMedium(FebVolumeMedium);
+  TGeoMedium* asicVolMed      = gGeoMan->GetMedium(AsicVolumeMedium);
+  TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium);
+
+  TString name       = Form("module%d", 9 + type);
+  TGeoVolume* module = new TGeoVolumeAssembly(name);
+
+
+  if (IncludeRadiator) {  // Radiator
+    TGeoBBox* trd_radiator     = new TGeoBBox("trd_radiator", sizeX / 2., sizeY / 2., radiator_thickness / 2.);
+    TGeoVolume* trdmod1_radvol = new TGeoVolume("Radiator", trd_radiator, radVolMed);
+    trdmod1_radvol->SetLineColor(kRed);
+    trdmod1_radvol->SetTransparency(50);  // set transparency for the TRD radiator
+    TGeoTranslation* trd_radiator_trans = new TGeoTranslation("", 0., 0., radiator_position);
+    module->AddNode(trdmod1_radvol, 1, trd_radiator_trans);
+  }
+
+  Double_t winIn_C_thickness  = 0.02;
+  Double_t winIn_HC_thickness = 1.;
+  Double_t winIn_thickness    = winIn_HC_thickness + /*2**/ winIn_C_thickness;
+  if (IncludeLattice) {  // Entrance window in the case of the Bucharest prototype
+    // Carbon fiber layers
+    TGeoBBox* winIn_C = new TGeoBBox("winIn_C", 0.3 + activeAreaX / 2., 0.9 + activeAreaY / 2., winIn_C_thickness / 2.);
+    TGeoVolume* vol_winIn_C = new TGeoVolume("vol_winIn_C", winIn_C, carbonVolMed);
+    vol_winIn_C->SetLineColor(kGray);
+    // Honeycomb layer
+    TGeoBBox* winIn_HC =
+      new TGeoBBox("winIn_HC", -0.3 + activeAreaX / 2., 0.3 + activeAreaY / 2., winIn_HC_thickness / 2.);
+    TGeoVolume* vol_winIn_HC = new TGeoVolume("vol_winIn_HC", winIn_HC, honeycombVolMed);
+    vol_winIn_HC->SetLineColor(kOrange);
+    // framex
+    TGeoBBox* winIn_fx =
+      new TGeoBBox("winIn_fx", -0.3 + activeAreaX / 2, WIN_Frame_thickness / 2, winIn_HC_thickness / 2.);
+    TGeoVolume* vol_winIn_fx = new TGeoVolume("vol_winIn_fx", winIn_fx, frameVolMed);
+    vol_winIn_fx->SetLineColor(kBlue);
+    // framey
+    TGeoBBox* winIn_fy =
+      new TGeoBBox("winIn_fy", WIN_Frame_thickness / 2, (1.8 + activeAreaY) / 2, winIn_HC_thickness / 2.);
+    TGeoVolume* vol_winIn_fy = new TGeoVolume("vol_winIn_fy", winIn_fy, frameVolMed);
+    vol_winIn_fy->SetLineColor(kCyan);
+    // Add up all components
+    TGeoVolumeAssembly* trd_win_in = new TGeoVolumeAssembly("EntranceWin");
+    trd_win_in->AddNode(vol_winIn_fx, 1, new TGeoTranslation("", 0., 0.6 + activeAreaY / 2., 0));
+    trd_win_in->AddNode(vol_winIn_fx, 2, new TGeoTranslation("", 0., -(activeAreaY / 2. + 0.6), 0));
+    trd_win_in->AddNode(vol_winIn_fy, 1, new TGeoTranslation("", activeAreaX / 2., 0., 0));
+    trd_win_in->AddNode(vol_winIn_fy, 2, new TGeoTranslation("", -activeAreaX / 2., 0., 0));
+
+    trd_win_in->AddNode(vol_winIn_HC, 1);
+    trd_win_in->AddNode(vol_winIn_C, 1,
+                        new TGeoTranslation("", 0., 0., 0.5 * (winIn_HC_thickness + winIn_C_thickness)));
+    //     trd_win_in->AddNode(vol_winIn_C, 2,
+    //                     new TGeoTranslation("", 0., 0., -(winIn_thickness-winIn_C_thickness)/2.));
+    module->AddNode(trd_win_in, 1,
+                    new TGeoTranslation(
+                      "", 0., 0., gasBu_position - gas_thickness / 2. - winIn_C_thickness - winIn_HC_thickness / 2.));
+  }
+
+  // Gas. The volume has to be defined only for pads (read-out) area. Take care in the DigiPara definition
+  TGeoBBox* trd_gas   = new TGeoBBox("trd_gas", 0.5 * activeAreaX, 0.5 * activeAreaY, 0.5 * gas_thickness);
+  TGeoVolume* vol_gas = new TGeoVolume("gas", trd_gas, gasVolMed);
+  vol_gas->SetLineColor(kRed + 3);  //trdmod1_gasvol->SetTransparency(40);
+  TGeoBBox* trd_gas_dstr   = new TGeoBBox("trd_gas_dstr", 0.5 * activeAreaX, 0.2, 0.5 * gas_thickness);
+  TGeoVolume* vol_gas_dstr = new TGeoVolume("inlet", trd_gas_dstr, gasVolMed);
+  vol_gas_dstr->SetLineColor(kRed);
+  module->AddNode(vol_gas, 0, new TGeoTranslation("", 0., 0., gasBu_position));
+  module->AddNode(vol_gas_dstr, 0, new TGeoTranslation("", 0., 0.5 * activeAreaY + 0.2, gasBu_position));
+  module->AddNode(vol_gas_dstr, 1, new TGeoTranslation("", 0., -0.5 * activeAreaY - 0.2, gasBu_position));
+
+  const Double_t pp_pads_thickness = 0.0025;
+  const Double_t pp_pcb_thickness  = 0.0360;
+  const Double_t pp_hc_thickness   = 0.2;
+  const Double_t pp_c_thickness    = 0.05;
+  const Double_t pp_thickness      = /*pp_pads_thickness + */ pp_pcb_thickness + pp_hc_thickness + pp_c_thickness;
+  if (IncludePadplane) {
+    // Pad Copper
+    TGeoBBox* trd_pp       = new TGeoBBox("pp_cu", activeAreaX / 2., activeAreaY / 2., pp_pads_thickness / 2.);
+    TGeoVolume* vol_trd_pp = new TGeoVolume("vol_pp_cu", trd_pp, padcopperVolMed);
+    vol_trd_pp->SetLineColor(kRed);
+    // Pad Plane
+    TGeoBBox* trd_ppPCB = new TGeoBBox("pp_pcb", 1.0 + activeAreaX / 2., 0.9 + activeAreaY / 2., pp_pcb_thickness / 2.);
+    TGeoVolume* vol_trd_ppPCB = new TGeoVolume("vol_pp_pcb", trd_ppPCB, padpcbVolMed);
+    vol_trd_ppPCB->SetLineColor(kGreen);
+    // Pad Plane HC
+    TGeoBBox* trd_ppHC_bd =
+      new TGeoBBox("pp_hc_bd", 1.0 + activeAreaX / 2., 0.9 + activeAreaY / 2., pp_hc_thickness / 2.);
+    TGeoBBox* trd_ppHC_fc = new TGeoBBox("pp_hc_fc", 2.4 / 2., 0.8 / 2., (1.e-4 + pp_hc_thickness) / 2.);
+    addFlatCableHoles("pp_hc");
+    TGeoCompositeShape* trd_ppHC = new TGeoCompositeShape("pp_hc", sexpr.Data());
+    TGeoVolume* vol_trd_ppHC     = new TGeoVolume("vol_pp_hc", trd_ppHC, honeycombVolMed);
+    vol_trd_ppHC->SetLineColor(kOrange);
+    // Pad Plane C fiber
+    TGeoBBox* trd_ppC_bd = new TGeoBBox("pp_c_bd", 1.0 + activeAreaX / 2., 0.9 + activeAreaY / 2., pp_c_thickness / 2.);
+    TGeoBBox* trd_ppC_fc = new TGeoBBox("pp_c_fc", 2.4 / 2., 0.8 / 2., (1.e-4 + pp_c_thickness) / 2.);
+    addFlatCableHoles("pp_c");
+    TGeoCompositeShape* trd_ppC = new TGeoCompositeShape("pp_c", sexpr.Data());
+    TGeoVolume* vol_trd_ppC     = new TGeoVolume("vol_pp_c", trd_ppC, carbonVolMed);
+    vol_trd_ppC->SetLineColor(kGray);
+
+    // Add up all components
+    TGeoVolumeAssembly* vol_pp = new TGeoVolumeAssembly("PadPlane");
+    vol_pp->AddNode(vol_trd_pp, 1, new TGeoTranslation("", 0., 0., -pp_thickness / 2 - pp_pads_thickness / 2));
+    vol_pp->AddNode(vol_trd_ppPCB, 1, new TGeoTranslation("", 0., 0., -pp_thickness / 2 + pp_pcb_thickness / 2));
+    vol_pp->AddNode(vol_trd_ppHC, 1,
+                    new TGeoTranslation("", 0., 0., -pp_thickness / 2 + pp_pcb_thickness + pp_hc_thickness / 2));
+    vol_pp->AddNode(vol_trd_ppC, 1, new TGeoTranslation("", 0., 0., pp_thickness / 2 - pp_c_thickness / 2));
+    module->AddNode(vol_pp, 1,
+                    new TGeoTranslation("", 0., 0., gasBu_position + gas_thickness / 2. + pp_thickness / 2.));
+  }
+
+
+  if (IncludeGasFrame) {
+    // framex
+    TGeoBBox* frame_fx0       = new TGeoBBox("frame_fx0", activeAreaX / 2., 0.5 / 2., gas_thickness / 2.);
+    TGeoVolume* vol_frame_fx0 = new TGeoVolume("vol_frame_fx0", frame_fx0, frameVolMed);
+    vol_frame_fx0->SetLineColor(kYellow - 2);
+    Double_t frame_fx1_thickness = winIn_thickness + gas_thickness + pp_thickness;
+    TGeoBBox* frame_fx1          = new TGeoBBox("frame_fx1", 1. + activeAreaX / 2., 0.3 / 2., frame_fx1_thickness / 2.);
+    TGeoVolume* vol_frame_fx1    = new TGeoVolume("vol_frame_fx1", frame_fx1, frameVolMed);
+    vol_frame_fx1->SetLineColor(kViolet);  //vol_frame_fx1->SetTransparency(50);
+
+    // framey
+    TGeoBBox* frame_fy_0       = new TGeoBBox("frame_fy_0", 0.7 / 2., (1.8 + activeAreaY) / 2., winIn_thickness / 2.);
+    TGeoVolume* vol_frame_fy_0 = new TGeoVolume("vol_frame_fy_0", frame_fy_0, frameVolMed);
+    vol_frame_fy_0->SetLineColor(kBlue);
+    TGeoBBox* frame_fy_1 =
+      new TGeoBBox("frame_fy_1", 1.0 / 2., (1.8 + activeAreaY) / 2., 0.4 / 2.);  // catode wire support
+    TGeoVolume* vol_frame_fy_1 = new TGeoVolume("vol_frame_fy_1", frame_fy_1, frameVolMed);
+    vol_frame_fy_1->SetLineColor(kBlue - 3);
+    TGeoBBox* frame_fy_2       = new TGeoBBox("frame_fy_2", 0.7 / 2., (1.8 + activeAreaY) / 2.,
+                                        0.4 / 2.);  // anode wire support
+    TGeoVolume* vol_frame_fy_2 = new TGeoVolume("vol_frame_fy_2", frame_fy_2, frameVolMed);
+    vol_frame_fy_2->SetLineColor(kOrange + 4);
+    TGeoBBox* frame_fy_3       = new TGeoBBox("frame_fy_3", 0.4 / 2., (1.8 + activeAreaY) / 2.,
+                                        0.4 / 2.);  // pad-plane support
+    TGeoVolume* vol_frame_fy_3 = new TGeoVolume("vol_frame_fy_3", frame_fy_3, frameVolMed);
+    vol_frame_fy_3->SetLineColor(kYellow + 3);
+    // add up framey components
+    TGeoVolumeAssembly* vol_frame_fy0 =
+      new TGeoVolumeAssembly("vol_frame_fy0");  // the mother volume of wire support ledge
+    vol_frame_fy0->AddNode(vol_frame_fy_0, 1,
+                           new TGeoTranslation("", -0.3 - 0.7 / 2., 0., -(0.4 * 1.5 + winIn_thickness / 2.)));
+    vol_frame_fy0->AddNode(vol_frame_fy_1, 1, new TGeoTranslation("", -1.0 / 2., 0., -0.4));
+    vol_frame_fy0->AddNode(vol_frame_fy_2, 1, new TGeoTranslation("", -0.7 / 2., 0., 0.));
+    vol_frame_fy0->AddNode(vol_frame_fy_3, 1, new TGeoTranslation("", -0.4 / 2., 0., 0.4));
+    TGeoBBox* frame_fy1       = new TGeoBBox("frame_fy1", 0.3 / 2., 1.2 + activeAreaY / 2., frame_fx1_thickness / 2.);
+    TGeoVolume* vol_frame_fy1 = new TGeoVolume("vol_frame_fy1", frame_fy1, frameVolMed);
+    vol_frame_fy1->SetLineColor(kViolet + 2);  //vol_frame_fy1->SetTransparency(50);
+
+    // Add up all frames
+    Double_t frame_fx1_position       = -winIn_thickness - gas_thickness / 2. + frame_fx1_thickness / 2.;
+    TGeoVolumeAssembly* trd_gas_frame = new TGeoVolumeAssembly("Frame");  // the mother volume of gas frame
+    trd_gas_frame->AddNode(vol_frame_fx0, 1, new TGeoTranslation("", 0., activeAreaY / 2. + 0.4 + 0.5 / 2, 0));
+    trd_gas_frame->AddNode(vol_frame_fx0, 2, new TGeoTranslation("", 0., -(activeAreaY / 2. + 0.4 + 0.5 / 2), 0));
+    trd_gas_frame->AddNode(vol_frame_fx1, 1,
+                           new TGeoTranslation("", 0., activeAreaY / 2. + 0.4 + 0.5 + 0.3 / 2, frame_fx1_position));
+    trd_gas_frame->AddNode(vol_frame_fx1, 2,
+                           new TGeoTranslation("", 0., -(activeAreaY / 2. + 0.4 + 0.5 + 0.3 / 2), frame_fx1_position));
+    trd_gas_frame->AddNode(vol_frame_fy0, 1, new TGeoTranslation("", -activeAreaX / 2., 0., 0));
+    TGeoRotation* fy_rot = new TGeoRotation();
+    fy_rot->RotateZ(180.);
+    TGeoTranslation* fy_tra   = new TGeoTranslation("", -activeAreaX / 2., 0., 0);
+    TGeoHMatrix* fy_transform = new TGeoHMatrix("");
+    (*fy_transform)           = (*fy_rot) * (*fy_tra);
+    trd_gas_frame->AddNode(vol_frame_fy0, 2, fy_transform);
+    trd_gas_frame->AddNode(vol_frame_fy1, 1,
+                           new TGeoTranslation("", activeAreaX / 2. + 1.0 + 0.3 / 2, 0, frame_fx1_position));
+    trd_gas_frame->AddNode(vol_frame_fy1, 2,
+                           new TGeoTranslation("", -(activeAreaX / 2. + 1.0 + 0.3 / 2), 0, frame_fx1_position));
+    module->AddNode(trd_gas_frame, 1, new TGeoTranslation("", 0., 0., gasBu_position));
+  }
+
+
+  const Double_t bp_hc_thickness  = 2.;
+  const Double_t bp_pcb_thickness = 0.05;
+  const Double_t bp_cu_thickness  = 0.003;
+  const Double_t bp_thickness     = bp_cu_thickness + bp_hc_thickness + bp_pcb_thickness;
+  const Double_t bp_position      = gasBu_position + 0.5 * gas_thickness + pp_thickness;
+  if (IncludeBackpanel) {
+    // Honeycomb board and flat-cable hole
+    TGeoBBox* bp_hc_bd = new TGeoBBox("bp_hc_bd", activeAreaX / 2., activeAreaY / 2., bp_hc_thickness / 2.);
+    TGeoBBox* bp_hc_fc = new TGeoBBox("bp_hc_fc", 2.4 / 2., 0.8 / 2., (1.e-4 + bp_hc_thickness) / 2.);
+    addFlatCableHoles("bp_hc");
+    TGeoCompositeShape* bp_hc = new TGeoCompositeShape("bp_hc", sexpr.Data());
+    TGeoVolume* vol_bp_hc     = new TGeoVolume("vol_bp_hc", bp_hc, honeycombVolMed);
+    vol_bp_hc->SetLineColor(kOrange);
+    // Screen fibre-glass support (PCB)
+    TGeoBBox* bp_pcb_bd =
+      new TGeoBBox("bp_pcb_bd", 0.5 + activeAreaX / 2., 0.5 + activeAreaY / 2., bp_pcb_thickness / 2.);
+    TGeoBBox* bp_pcb_fc = new TGeoBBox("bp_pcb_fc", 2.4 / 2., 0.8 / 2., (1.e-3 + bp_pcb_thickness) / 2.);
+    addFlatCableHoles("bp_pcb");
+    TGeoCompositeShape* bp_pcb = new TGeoCompositeShape("bp_pcb", sexpr.Data());
+    TGeoVolume* vol_bp_pcb     = new TGeoVolume("vol_bp_pcb", bp_pcb, padpcbVolMed);
+    vol_bp_pcb->SetLineColor(kGreen);
+    // Pad Copper
+    TGeoBBox* bp_cu_bd = new TGeoBBox("bp_cu_bd", 0.5 + activeAreaX / 2., 0.5 + activeAreaY / 2., bp_cu_thickness / 2.);
+    TGeoBBox* bp_cu_fc = new TGeoBBox("bp_cu_fc", 2.4 / 2., 0.8 / 2., (1.e-3 + bp_cu_thickness) / 2.);
+    addFlatCableHoles("bp_cu");
+    TGeoCompositeShape* bp_cu = new TGeoCompositeShape("bp_cu", sexpr.Data());
+    TGeoVolume* vol_bp_cu     = new TGeoVolume("vol_bp_cu", bp_cu, padcopperVolMed);
+    vol_bp_cu->SetLineColor(kRed);
+
+    TGeoBBox* bp_fx       = new TGeoBBox("bp_fx", activeAreaX / 2., 0.5 / 2., bp_hc_thickness / 2.);
+    TGeoVolume* vol_bp_fx = new TGeoVolume("vol_bp_fx", bp_fx, frameVolMed);
+    vol_bp_fx->SetLineColor(kViolet);  //vol_gas_fx1->SetTransparency(50);
+    TGeoBBox* bp_fy       = new TGeoBBox("bp_fy", 0.5 / 2, 0.5 + 0.5 * activeAreaY, bp_hc_thickness / 2.);
+    TGeoVolume* vol_bp_fy = new TGeoVolume("vol_bp_fy", bp_fy, frameVolMed);
+    vol_bp_fy->SetLineColor(kViolet + 2);
+
+    // Add up all components
+    TGeoVolumeAssembly* trd_supp = new TGeoVolumeAssembly("BackPanel");
+    trd_supp->AddNode(vol_bp_hc, 1);
+    trd_supp->AddNode(vol_bp_pcb, 1, new TGeoTranslation("", 0., 0., 0.5 * (bp_hc_thickness + bp_pcb_thickness)));
+    trd_supp->AddNode(
+      vol_bp_cu, 1, new TGeoTranslation("", 0., 0., 0.5 * (bp_hc_thickness + 2 * bp_pcb_thickness + bp_cu_thickness)));
+    trd_supp->AddNode(vol_bp_fx, 1, new TGeoTranslation("", 0., 0.5 * (0.5 + activeAreaY), 0));
+    trd_supp->AddNode(vol_bp_fx, 2, new TGeoTranslation("", 0., -0.5 * (0.5 + activeAreaY), 0));
+    trd_supp->AddNode(vol_bp_fy, 1, new TGeoTranslation("", 0.5 * (0.5 + activeAreaX), 0., 0.));
+    trd_supp->AddNode(vol_bp_fy, 2, new TGeoTranslation("", -0.5 * (0.5 + activeAreaX), 0., 0.));
+    module->AddNode(
+      trd_supp, 1,
+      new TGeoTranslation("", 0., 0., gasBu_position + 0.5 * gas_thickness + pp_thickness + 0.5 * bp_hc_thickness));
+  }
+
+  // FEBs
+  // ROB FASP
+  const Double_t FASPRO_zspace    = 1.5;   // gap size between boards
+  const Double_t FASPRO_length    = 17.9;  // length of FASP FEBs in cm
+  const Double_t FASPRO_width     = 5.12;  // width of FASP FEBs in cm
+  const Double_t FASPRO_dx        = 0.01;  //
+  const Double_t FASPRO_dy        = 0.28;  //
+  const Double_t FASPRO_thickness = 0.17;
+  const Double_t FASPRO_position  = bp_position + bp_thickness + FASPRO_zspace;
+  const Double_t GETS_length      = 13.9;  // length of PolarFire FEBs in cm
+  const Double_t GETS_width       = 5.12;  // width of PolarFire FEBs in cm
+  const Double_t GETS_thickness   = 0.2;
+  const Double_t LVB_length       = 5.;   // length of LV FEBs in cm
+  const Double_t LVB_width        = 20.;  // width of LV FEBs in cm
+  const Double_t LVB_thickness    = 0.1;
+
+  // ASIC parameters
+  const Double_t fasp_size[]     = {1.2, 1.2, 0.2};  // FASP package and interposer size 1.5x1.5 cm2
+  const Double_t faspConn_size[] = {2.1, 0.3, 0.6};  // FASP package and interposer size 1.5x1.5 cm2
+  const Double_t fasp_xoffset    = 6.0;              // ASIC offset from ROC middle (horizontally)
+  const Double_t fasp_yoffset    = 1.35;             // ASIC offset from DET connector (vertical)
+  const Double_t fpga_size[]     = {1.2, 1.2, 0.2};  // PolarFire FPGA package size 1.5x1.5 cm2
+  // FMC+ connector definition
+  const Double_t FMCwidth  = 2.0;   // width of a MF FMC connector
+  const Double_t FMClength = 5.6;   // length of a MF FMC connector
+  const Double_t FMCheight = 1.13;  // height of a MF FMC connector
+  const Double_t FMCsuppD  = 0.8;   // outer radius of FMC connector side supports
+  const Double_t FMCsuppX  = 0.6;   // FMC connector side supports
+  // GETS2C-ROB3 connector boord parameters
+  const Double_t robConn_size_x = 3.9;  //15.0;
+  const Double_t robConn_size_y = 15.0;
+  //  const Double_t robConn_xoffset      =  6.0;
+  if (IncludeFebs) {
+    // Create all FEBs and place them in an assembly which will be added to the TRD module
+    TGeoBBox* faspro_bd       = new TGeoBBox("faspro_bd", FASPRO_length / 2., FASPRO_width / 2., FASPRO_thickness / 2.);
+    TGeoVolume* vol_faspro_bd = new TGeoVolume("vol_faspro_bd", faspro_bd, febVolMed);  // the FEB made of PCB
+    vol_faspro_bd->SetLineColor(kGreen + 3);  //vol_faspro_bd->SetTransparency(50);
+    TGeoBBox* gets_bd       = new TGeoBBox("gets_bd", GETS_length / 2., GETS_width / 2., GETS_thickness / 2.);
+    TGeoVolume* vol_gets_bd = new TGeoVolume("vol_gets_bd", gets_bd, febVolMed);  // the FEB made of PCB
+    vol_gets_bd->SetLineColor(kGreen + 8);                                        //vol_gets_bd->SetTransparency(50);
+    // Create the FMC connector
+    TGeoBBox* fmc_conn       = new TGeoBBox("fmc_conn", 0.5 * FMClength, 0.5 * FMCwidth, 0.5 * FMCheight);
+    TGeoVolume* vol_fmc_conn = new TGeoVolume("vol_fmc_conn", fmc_conn, febVolMed);  // the FMC  made of PCB
+    vol_fmc_conn->SetLineColor(kGray + 2);
+    TGeoTube* fmc_connSupp       = new TGeoTube("fmc_connSupp", 0, 0.5 * FMCsuppD, 0.5 * FMCheight);
+    TGeoVolume* vol_fmc_connSupp = new TGeoVolume("vol_fmc_connSupp", fmc_connSupp, aluminiumVolMed);  // support Al
+    vol_fmc_connSupp->SetLineColor(kGray);
+    TGeoVolumeAssembly* fmc_connect = new TGeoVolumeAssembly("FMC");
+    fmc_connect->AddNode(vol_fmc_conn, 1);
+    fmc_connect->AddNode(vol_fmc_connSupp, 1, new TGeoTranslation("", 0.5 * FMClength + FMCsuppX, 0, 0.));
+    fmc_connect->AddNode(vol_fmc_connSupp, 2, new TGeoTranslation("", -(0.5 * FMClength + FMCsuppX), 0, 0.));
+    // Add up all elements of FASPRO
+    TGeoVolumeAssembly* faspro = new TGeoVolumeAssembly("FASPRO");
+    faspro->AddNode(vol_faspro_bd, 1);
+    faspro->AddNode(fmc_connect, 0, new TGeoTranslation("", 0, 0, 0.5 * FMCheight + 0.5 * FASPRO_thickness));
+    Double_t GETS_zpos = 0.5 * FASPRO_thickness + FMCheight + 0.5 * GETS_thickness;
+    faspro->AddNode(vol_gets_bd, 1, new TGeoTranslation("", 0, 0, GETS_zpos));
+
+    // ASICs
+    if (IncludeAsics) {
+      TGeoBBox* fasp_asic       = new TGeoBBox("fasp_asic", 0.5 * fasp_size[0], 0.5 * fasp_size[1], 0.5 * fasp_size[2]);
+      TGeoVolume* vol_fasp_asic = new TGeoVolume("FASP", fasp_asic, padpcbVolMed);
+      vol_fasp_asic->SetLineColor(kBlack);
+      TGeoBBox* fasp_conn =
+        new TGeoBBox("fasp_conn", 0.5 * faspConn_size[0], 0.5 * faspConn_size[1], 0.5 * faspConn_size[2]);
+      TGeoVolume* vol_fasp_conn = new TGeoVolume("fasp_conn", fasp_conn, padpcbVolMed);
+      vol_fasp_conn->SetLineColor(kRed + 4);
+      for (Int_t cAsic(-1), iAsic(0); cAsic <= 1; cAsic++) {
+        faspro->AddNode(vol_fasp_asic, iAsic,
+                        new TGeoTranslation("", cAsic * fasp_xoffset, fasp_yoffset,
+                                            -1 * (0.5 * FASPRO_thickness + 0.5 * fasp_size[2])));
+        faspro->AddNode(vol_fasp_conn, iAsic,
+                        new TGeoTranslation("", cAsic * fasp_xoffset, 0.5 * FASPRO_width - 0.2 - 0.5 * faspConn_size[1],
+                                            -1 * (0.5 * FASPRO_thickness + 0.5 * faspConn_size[2])));
+        iAsic++;
+        faspro->AddNode(vol_fasp_asic, iAsic,
+                        new TGeoTranslation("", cAsic * fasp_xoffset, -fasp_yoffset,
+                                            -1 * (0.5 * FASPRO_thickness + 0.5 * fasp_size[2])));
+        faspro->AddNode(vol_fasp_conn, iAsic,
+                        new TGeoTranslation("", cAsic * fasp_xoffset,
+                                            -(0.5 * FASPRO_width - 0.2 - 0.5 * faspConn_size[1]),
+                                            -1 * (0.5 * FASPRO_thickness + 0.5 * faspConn_size[2])));
+        iAsic++;
+      }
+
+      TGeoBBox* fpga_asic       = new TGeoBBox("fpga_asic", 0.5 * fpga_size[0], 0.5 * fpga_size[1], 0.5 * fpga_size[2]);
+      TGeoVolume* vol_fpga_asic = new TGeoVolume("FPGA", fpga_asic, asicVolMed);
+      vol_fpga_asic->SetLineColor(kBlack);
+      faspro->AddNode(vol_fpga_asic, 0,
+                      new TGeoTranslation("", 0, -fasp_yoffset, GETS_zpos + 0.5 * GETS_thickness + 0.5 * fpga_size[2]));
+      faspro->AddNode(vol_fpga_asic, 1,
+                      new TGeoTranslation("", 0, fasp_yoffset, GETS_zpos + 0.5 * GETS_thickness + 0.5 * fpga_size[2]));
+    }
+    // supports for electronics
+    TGeoBBox* faspro_fy       = new TGeoBBox("faspro_fy", 0.4 / 2, 0.5 + 0.5 * activeAreaY, 0.5 * FASPRO_zspace);
+    TGeoVolume* vol_faspro_fy = new TGeoVolume("faspro_fy", faspro_fy, frameVolMed);
+    vol_faspro_fy->SetLineColor(kViolet + 2);  //vol_faspro_fy->SetTransparency(50);
+
+    // now go on with FEB placement
+    Int_t cFeb(-1);
+    TGeoVolumeAssembly* vol_feb = new TGeoVolumeAssembly("FEB");  // the mother volume of all FEBs
+    for (Int_t iFeb(0); cFeb < 2; cFeb++) {
+      vol_feb->AddNode(vol_faspro_fy, cFeb + 1,
+                       new TGeoTranslation("", (cFeb - 0.5) * (FASPRO_length + FASPRO_dx), 0.,
+                                           -0.5 * (FASPRO_thickness + FASPRO_zspace)));
+      for (Int_t rFeb(0); rFeb < 5; rFeb++) {
+        // the upper side ...
+        vol_feb->AddNode(
+          faspro, iFeb++,
+          new TGeoTranslation("", cFeb * (FASPRO_length + FASPRO_dx), (rFeb + 0.5) * (FASPRO_width + FASPRO_dy), 0));
+        // the bottom side ...
+        vol_feb->AddNode(
+          faspro, iFeb++,
+          new TGeoTranslation("", cFeb * (FASPRO_length + FASPRO_dx), -(rFeb + 0.5) * (FASPRO_width + FASPRO_dy), 0));
+      }
+    }
+    vol_feb->AddNode(vol_faspro_fy, cFeb + 1,
+                     new TGeoTranslation("", (cFeb - 0.5) * (FASPRO_length + FASPRO_dx), 0.,
+                                         -0.5 * (FASPRO_thickness + FASPRO_zspace)));
+
+    // add LV regulators boards
+    Double_t LVB_pos      = FMCheight + 0.5 * (FASPRO_thickness + LVB_thickness);
+    TGeoBBox* lv_bd       = new TGeoBBox("lv_bd", LVB_length / 2., LVB_width / 2., LVB_thickness / 2.);
+    TGeoVolume* vol_lv_bd = new TGeoVolume("lv_bd", lv_bd, febVolMed);  // the LV board made of PCB
+    vol_lv_bd->SetLineColor(kGreen - 3);
+    vol_feb->AddNode(
+      vol_lv_bd, 0,
+      new TGeoTranslation("", 0., 0.5 + 0.5 * (activeAreaY - LVB_width), LVB_pos + FMCheight + 0.5 * LVB_thickness));
+    vol_feb->AddNode(
+      vol_lv_bd, 1,
+      new TGeoTranslation("", 0., -0.5 + 0.5 * (-activeAreaY + LVB_width), LVB_pos + FMCheight + 0.5 * LVB_thickness));
+
+    if (IncludeRobs) {
+      TGeoVolumeAssembly* crob = new TGeoVolumeAssembly("C-ROB");
+      TGeoBBox* crob_bd        = new TGeoBBox("crob_bd", rob_size_x / 2., rob_size_y / 2., rob_thickness / 2.);
+      TGeoVolume* vol_crob_bd  = new TGeoVolume("crob_bd", crob_bd, febVolMed);  // the ROB made of PCB
+      vol_crob_bd->SetLineColor(kRed + 8);                                       // set color
+      TGeoRotation* crob_fmc_rot = new TGeoRotation("crob_fmc_rot");
+      crob_fmc_rot->RotateZ(90.);
+      crob_fmc_rot->RegisterYourself();
+      TGeoTranslation* crob_fmc_tra = new TGeoTranslation("crob_fmc_tra", 0., 0.5 * (FMCwidth - robConn_size_x) + 0.2,
+                                                          0.5 * (FMCheight + rob_thickness));
+      crob_fmc_tra->RegisterYourself();
+      TGeoHMatrix* crob_fmc_transform = new TGeoHMatrix("");
+      (*crob_fmc_transform)           = (*crob_fmc_rot) * (*crob_fmc_tra);
+      // Add GETS - CROB interface
+      TGeoBBox* crob_addapt = new TGeoBBox("crob_addapt", robConn_size_x / 2., robConn_size_y / 2., rob_thickness / 2.);
+      TGeoVolume* vol_crob_addapt = new TGeoVolume("crob_addapt", crob_addapt, febVolMed);  // the ROB made of PCB
+      vol_crob_addapt->SetLineColor(kRed + 6);                                              // set color
+      crob->AddNode(vol_crob_addapt, 0);
+      crob->AddNode(fmc_connect, 1, crob_fmc_transform);
+      crob->AddNode(vol_crob_bd, 1,
+                    new TGeoTranslation("", -0.5 * (rob_size_x - robConn_size_x) + 1.5, 0., FMCheight + rob_thickness));
+
+      // GBTXs
+      TGeoBBox* crob_gbtx       = new TGeoBBox("crob_gbtx", gbtx_width / 2., gbtx_width / 2., gbtx_thickness / 2.);
+      TGeoVolume* vol_crob_gbtx = new TGeoVolume("crob_gbtx", crob_gbtx, asicVolMed);
+      vol_crob_gbtx->SetLineColor(kGreen);
+      //place 3 GBTXs on each C-ROC
+      Double_t gbtx_pos_x = 0.5 * (-rob_size_x + gbtx_width) - 1.5 /*-0.5*/;
+      Double_t gbtx_pos_y = 0.5 * (rob_size_y - gbtx_width) - 0.5;
+      crob->AddNode(vol_crob_gbtx, 0,
+                    new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, FMCheight + rob_thickness + 0.5 * gbtx_thickness));
+      crob->AddNode(vol_crob_gbtx, 1,
+                    new TGeoTranslation("", gbtx_pos_x, -gbtx_pos_y, FMCheight + rob_thickness + 0.5 * gbtx_thickness));
+      crob->AddNode(vol_crob_gbtx, 2,
+                    new TGeoTranslation("", gbtx_pos_x + 5., 0., FMCheight + rob_thickness + 0.5 * gbtx_thickness));
+
+      // now go on with ROB placement
+      Int_t nofRobs = RobsPerModule[moduleType], nofRobsHalf(nofRobs / 2);
+      for (Int_t iRob = 0, jRob(0); iRob < nofRobsHalf; iRob++) {
+        Double_t rob_pos = (iRob + 0.5) / nofRobsHalf - 0.5,  // equal spacing of ROBs on the backpanel
+          rob_pos_y      = rob_pos * activeAreaY;
+        vol_feb->AddNode(crob, jRob++, new TGeoTranslation("", -0.5 * (FASPRO_length + FASPRO_dx), rob_pos_y, LVB_pos));
+        TGeoRotation* crob_rot = new TGeoRotation("crob_rot");
+        crob_rot->RotateZ(180.);
+        crob_rot->RegisterYourself();
+        TGeoTranslation* crob_tra =
+          new TGeoTranslation("crob_tra", 0.5 * (FASPRO_length + FASPRO_dx), rob_pos_y, LVB_pos);
+        crob_tra->RegisterYourself();
+        TGeoHMatrix* crob_transform = new TGeoHMatrix("");
+        (*crob_transform)           = (*crob_tra) * (*crob_rot);
+        vol_feb->AddNode(crob, jRob++, crob_transform);
+      }
+    }  // IncludeGbtx
+
+    // put FEB box on module
+    module->AddNode(vol_feb, 1,
+                    new TGeoTranslation("", 0., 0.,
+                                        FASPRO_position));  // put febvolume at correct z position wrt to the module
+  }
+
+  return module;
+}
+
+TGeoVolume* create_support_inner()
+{
+  Double_t sizeX              = DetectorSizeX[0];
+  Double_t sizeY              = DetectorSizeY[0];
+  TGeoMedium* frameVolMed     = gGeoMan->GetMedium(FrameVolumeMedium);
+  TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium);
+
+  // wall support
+  TGeoTranslation* tr(NULL);
+  TGeoBBox* wall_al_b      = new TGeoBBox("wall_al_b", 0.5 * 4 * sizeX, 1., 1.);
+  TGeoBBox* wall_fr4       = new TGeoBBox("wall_fr4", 1.e-4 + 0.5 * 4 * sizeX, 0.8, 0.8);
+  TGeoVolume* vol_wall_fr4 = new TGeoVolume("wall_fr4", wall_fr4, frameVolMed);
+  vol_wall_fr4->SetLineColor(kBlue - 9);
+  TGeoCompositeShape* wall_al = new TGeoCompositeShape("wall_al", "wall_al_b-wall_fr4");
+  TGeoVolume* vol_wall_al     = new TGeoVolume("wall_al", wall_al, aluminiumVolMed);
+  vol_wall_al->SetLineColor(kGray);
+  TGeoVolumeAssembly* bar = new TGeoVolumeAssembly("innerSupport");
+  bar->AddNode(vol_wall_al, 1);
+  bar->AddNode(vol_wall_fr4, 1);
+  return bar;
+}
+
+
+Int_t copy_nr(Int_t stationNr, Int_t copyNr, Int_t isRotated, Int_t planeNr, Int_t modinplaneNr)
+{
+  //printf("stationNr[%d] copyNr[%d] isRotated[%d] planeNr[%d] modinplaneNr[%d]\n", stationNr, copyNr, isRotated, planeNr, modinplaneNr);
+
+  if (modinplaneNr > 128)
+    printf("Warning: too many modules in this layer %02d (max 128 according to "
+           "CbmTrdAddress)\n",
+           planeNr);
+
+  return (stationNr * 100000000  // 1 digit
+          + copyNr * 1000000     // 2 digit
+          + isRotated * 100000   // 1 digit
+          + planeNr * 1000       // 2 digit
+          + modinplaneNr * 1);   // 3 digit
+}
+
+void create_detector_layers(Int_t layerId)
+{
+  Int_t module_id               = 0;
+  Int_t layerType               = LayerType[layerId] / 10;  // this is also a station number
+  Int_t isRotated               = LayerType[layerId] % 10;  // is 1 for layers 2,4, ...
+  TGeoRotation* module_rotation = new TGeoRotation();
+
+  Int_t stationNr = layerType;
+
+  // rotation is now done in the for loop for each module individually
+  //  if ( isRotated == 1 ) {
+  //    module_rotation = new TGeoRotation();
+  //    module_rotation->RotateZ(90.);
+  //  } else {
+  //    module_rotation = new TGeoRotation();
+  //    module_rotation->RotateZ( 0.);
+  //  }
+
+  Int_t innerarray_size1 = LayerArraySize[layerType - 1][0];
+  Int_t innerarray_size2 = LayerArraySize[layerType - 1][1];
+  const Int_t* innerLayer;
+
+  Int_t outerarray_size1 = LayerArraySize[layerType - 1][2];
+  Int_t outerarray_size2 = LayerArraySize[layerType - 1][3];
+  const Int_t* outerLayer;
+
+  if (1 == layerType) {
+    innerLayer = (Int_t*) layer1i;
+    outerLayer = (Int_t*) layer1o;
+  }
+  else if (2 == layerType) {
+    innerLayer = (Int_t*) layer2i;
+    outerLayer = (Int_t*) layer2o;
+  }
+  else if (3 == layerType) {
+    innerLayer = (Int_t*) layer3i;
+    outerLayer = (Int_t*) layer3o;
+  }
+  else {
+    std::cout << "Type of layer not known" << std::endl;
+  }
+
+  // add layer keeping volume
+  TString layername = Form("layer%02d", PlaneId[layerId]);
+  TGeoVolume* layer = new TGeoVolumeAssembly(layername);
+
+  // compute layer copy number
+  Int_t i = LayerType[layerId] / 10 * 10000    // 1 digit  // fStation
+            + LayerType[layerId] % 10 * 1000   // 1 digit  // isRotated
+            + LayerNrInStation[layerId] * 100  // 1 digit  // fLayer
+            + PlaneId[layerId];  // 2 digits // fPlane   // layer type as leading digit in copy number of layer
+  gGeoMan->GetVolume(geoVersion)->AddNode(layer, i);
+
+  //  Int_t i = 100 + PlaneId[layerId];
+  //  gGeoMan->GetVolume(geoVersion)->AddNode(layer, 1);
+  //  cout << layername << endl;
+
+  Double_t ExplodeScale = 1.00;
+  if (DoExplode)  // if explosion, set scale
+    ExplodeScale = ExplodeFactor;
+
+  Int_t modId = 0;  // module id, only within this layer
+
+  Int_t copyNr[NofModuleTypes] = {0};  // copy number for each module type
+  for (Int_t type = 1; type <= NofModuleTypes; type++) {
+    if (type > 4 && type < 9) continue;
+    for (Int_t j = (innerarray_size1 - 1); j >= 0; j--) {  // start from the bottom
+      for (Int_t i = 0; i < innerarray_size2; i++) {
+        module_id = *(innerLayer + (j * innerarray_size2 + i));
+        if (module_id / 100 == type) {
+          Float_t y = -(j - 4);
+          Float_t x = i - 1.5;
+
+          // displacement
+          Double_t dx = 0;
+          Double_t dy = 0;
+          Double_t dz = 0;
+
+          if (DisplaceRandom) {
+            dx = (r3.Rndm() - .5) * 2 * maxdx;  // max +- 0.1 cm shift
+            dy = (r3.Rndm() - .5) * 2 * maxdy;  // max +- 0.1 cm shift
+            dz = (r3.Rndm() - .5) * 2 * maxdz;  // max +- 1.0 cm shift
+          }
+
+          Double_t xPos = DetectorSizeX[0] * x * ExplodeScale + dx;
+          Double_t yPos = DetectorSizeY[0] * y * ExplodeScale + dy;
+          copyNr[type - 1]++;
+          modId++;
+
+          // statistics per layer and module type
+          ModuleStats[layerId][type - 1]++;
+
+          //          Int_t copy = copy_nr_modid(stationNr, layerNrInStation, copyNrIn[type - 1], PlaneId[layerId], modId);  // with modID
+          //          Int_t copy = copy_nr(stationNr, copyNrIn[type - 1], isRotated, PlaneId[layerId], modId);
+
+          // take care of FEB orientation - away from beam
+          Int_t copy      = 0;
+          module_rotation = new TGeoRotation();  // need to renew rotation to start from 0 degree angle
+          if (isRotated == 0)                    // layer 1,3 ...
+          {
+            copy = copy_nr(stationNr, copyNr[type - 1], module_id / 10 % 10, PlaneId[layerId], modId);
+            module_rotation->RotateZ(
+              (module_id / 10 % 10) * 90.);  // rotate module by   0 or 180 degrees, see layer[1-3][i,o] - vertical pads
+          }
+          else  // layer 2,4 ...
+          {
+            copy = copy_nr(stationNr, copyNr[type - 1], module_id % 10, PlaneId[layerId], modId);
+            module_rotation->RotateZ(
+              (module_id % 10) * 90.);  // rotate module by  90 or 270 degrees, see layer[1-3][i,o] - horizontal pads
+          }
+
+          // rotation
+          Double_t drotx = 0;
+          Double_t droty = 0;
+          Double_t drotz = 0;
+
+          if (RotateRandom) {
+            drotx = (r3.Rndm() - .5) * 2 * maxdrotx;
+            droty = (r3.Rndm() - .5) * 2 * maxdroty;
+            drotz = (r3.Rndm() - .5) * 2 * maxdrotz;
+
+            module_rotation->RotateZ(drotz);
+            module_rotation->RotateY(droty);
+            module_rotation->RotateX(drotx);
+          }
+
+          TGeoCombiTrans* module_placement =
+            new TGeoCombiTrans(xPos, yPos, LayerPosition[layerId] + LayerThickness / 2 + dz,
+                               module_rotation);  // shift by half layer thickness
+          //          gGeoMan->GetVolume(geoVersion)->AddNode(gModules[type - 1], copy, module_placement);
+          // add module to layer
+          printf("%s [%p]: type[%d] copy[%d]\n", layername.Data(), (void*) gModules[type - 1], type, copy);
+          gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement);
+        }
+      }
+    }
+  }
+
+  for (Int_t type = 5; type <= 8; type++) {
+    for (Int_t j = (outerarray_size1 - 1); j >= 0; j--) {  // start from the bottom
+      for (Int_t i = 0; i < outerarray_size2; i++) {
+        module_id = *(outerLayer + (j * outerarray_size2 + i));
+        if (module_id / 100 == type) {
+          Float_t y = -(j - 4);
+          Float_t x = i - 5;
+
+          // displacement
+          Double_t dx = 0;
+          Double_t dy = 0;
+          Double_t dz = 0;
+
+          if (DisplaceRandom) {
+            dx = (r3.Rndm() - .5) * 2 * maxdx;  // max +- 0.1 cm shift
+            dy = (r3.Rndm() - .5) * 2 * maxdy;  // max +- 0.1 cm shift
+            dz = (r3.Rndm() - .5) * 2 * maxdz;  // max +- 1.0 cm shift
+          }
+
+          //          Double_t xPos = DetectorSizeX[1] * x * ExplodeScale + dx;
+          Double_t xPos = 0;
+          //cout << "x before: " << x ;
+          if (x > 0) {
+            x += -2 + 0.5;
+            xPos = 2 * DetectorSizeX[0] + DetectorSizeX[1] * x * ExplodeScale + dx;
+          }
+          else {
+            x += +2 - 0.5;
+            xPos = -2 * DetectorSizeX[0] + DetectorSizeX[1] * x * ExplodeScale + dx;
+          }
+          //cout << " x after: " << x << endl;
+          Double_t yPos = DetectorSizeY[1] * y * ExplodeScale + dy;
+          copyNr[type - 1]++;
+          modId++;
+
+          // statistics per layer and module type
+          ModuleStats[layerId][type - 1]++;
+
+          //          Int_t copy = copy_nr_modid(stationNr, layerNrInStation, copyNrOut[type - 5],  PlaneId[layerId], modId);  // with modID
+          //          Int_t copy = copy_nr(stationNr, copyNrOut[type - 5], isRotated, PlaneId[layerId], modId);
+
+          // take care of FEB orientation - away from beam
+          Int_t copy      = 0;
+          module_rotation = new TGeoRotation();  // need to renew rotation to start from 0 degree angle
+          if (isRotated == 0)                    // layer 1,3 ...
+          {
+            copy = copy_nr(stationNr, copyNr[type - 1], module_id / 10 % 10, PlaneId[layerId], modId);
+            module_rotation->RotateZ(
+              (module_id / 10 % 10) * 90.);  // rotate module by   0 or 180 degrees, see layer[1-3][i,o] - vertical pads
+          }
+          else  // layer 2,4 ...
+          {
+            copy = copy_nr(stationNr, copyNr[type - 1], module_id % 10, PlaneId[layerId], modId);
+            module_rotation->RotateZ(
+              (module_id % 10) * 90.);  // rotate module by  90 or 270 degrees, see layer[1-3][i,o] - horizontal pads
+          }
+
+          // rotation
+          Double_t drotx = 0;
+          Double_t droty = 0;
+          Double_t drotz = 0;
+
+          if (RotateRandom) {
+            drotx = (r3.Rndm() - .5) * 2 * maxdrotx;
+            droty = (r3.Rndm() - .5) * 2 * maxdroty;
+            drotz = (r3.Rndm() - .5) * 2 * maxdrotz;
+
+            module_rotation->RotateZ(drotz);
+            module_rotation->RotateY(droty);
+            module_rotation->RotateX(drotx);
+          }
+
+          TGeoCombiTrans* module_placement =
+            new TGeoCombiTrans(xPos, yPos, LayerPosition[layerId] + LayerThickness / 2 + dz,
+                               module_rotation);  // shift by half layer thickness
+          //          gGeoMan->GetVolume(geoVersion)->AddNode(gModules[type - 1], copy, module_placement);
+          // add module to layer
+          gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement);
+        }
+      }
+    }
+  }
+
+  // add support structure for Bucharest inner-zone
+  Double_t sizeY    = DetectorSizeY[0];
+  TGeoVolume* inner = create_support_inner();
+  for (Int_t ib(0); ib < 4; ib++) {
+    layer->AddNode(inner, ib + 1,
+                   new TGeoTranslation("", 0., (1.5 - ib) * sizeY,
+                                       LayerPosition[layerId] + LayerThickness / 2 + gasBu_position
+                                         + 0.5 * gas_thickness + 0.286 + 1.));
+  }
+}
+
+
+void create_mag_field_vector()
+{
+  const TString cbmfield_01 = "cbm_field";
+  TGeoVolume* cbmfield_1    = new TGeoVolumeAssembly(cbmfield_01);
+  TGeoMedium* copperVolMed  = gGeoMan->GetMedium(PadCopperVolumeMedium);  // define Volume Medium
+  TGeoRotation* rotx090     = new TGeoRotation("rotx090");
+  rotx090->RotateX(90.);  // rotate  90 deg around x-axis
+  TGeoRotation* rotx270 = new TGeoRotation("rotx270");
+  rotx270->RotateX(270.);  // rotate 270 deg around x-axis
+
+  Int_t tube_length = 500;
+  Int_t cone_length = 120;
+  Int_t cone_width  = 280;
+
+  // field tube
+  TGeoTube* trd_field          = new TGeoTube("", 0., 100 / 2., tube_length / 2.);
+  TGeoVolume* trdmod1_fieldvol = new TGeoVolume("tube", trd_field, copperVolMed);
+  trdmod1_fieldvol->SetLineColor(kRed);
+  trdmod1_fieldvol->SetTransparency(30);                                   // transparency for the TRD
+  TGeoTranslation* trd_field_trans = new TGeoTranslation("", 0., 0., 0.);  // tube position
+  cbmfield_1->AddNode(trdmod1_fieldvol, 1, trd_field_trans);
+
+  // field cone
+  TGeoCone* trd_cone          = new TGeoCone("", cone_length / 2., 0., cone_width / 2., 0., 0.);
+  TGeoVolume* trdmod1_conevol = new TGeoVolume("cone", trd_cone, copperVolMed);
+  trdmod1_conevol->SetLineColor(kRed);
+  trdmod1_conevol->SetTransparency(30);  // transparency for the TRD
+  TGeoTranslation* trd_cone_trans = new TGeoTranslation("", 0., 0., (tube_length + cone_length) / 2.);  // cone position
+  cbmfield_1->AddNode(trdmod1_conevol, 1, trd_cone_trans);
+
+  TGeoCombiTrans* field_combi01 = new TGeoCombiTrans(0., 0., 40., rotx270);  // point in +y direction
+  gGeoMan->GetVolume(geoVersion)->AddNode(cbmfield_1, 1, field_combi01);
+
+  //   TGeoCombiTrans* field_combi02 = new TGeoCombiTrans( 200., 0., 0., rotx090);   // point in -y direction
+  //   gGeoMan->GetVolume(geoVersion)->AddNode(cbmfield_1, 2, field_combi02);
+}
+
+
+void create_power_bars_vertical()
+{
+  const TString power_01 = "power_bars_trd1";
+  TGeoVolume* power_1    = new TGeoVolumeAssembly(power_01);
+
+  TGeoBBox* power1;
+  TGeoBBox* power2;
+
+  TGeoVolume* power1_vol;
+  TGeoVolume* power2_vol;
+
+  TGeoTranslation* power1_trans;
+  TGeoTranslation* power2_trans;
+
+  const Int_t kColor = kBlue;  // bus bar color
+
+  TGeoMedium* powerBusVolMed = gGeoMan->GetMedium(PowerBusVolumeMedium);
+
+  //  // powerbus - horizontal short
+  //  power1     = new TGeoBBox("power1", (DetectorSizeX[1] - DetectorSizeX[0] - powerbar_width)/2., powerbar_width /2., powerbar_thickness /2.);
+  //  power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed);
+  //  power1_vol->SetLineColor(kColor);
+  //
+  //  // translations
+  //  power1_trans = new TGeoTranslation("",  1 * (DetectorSizeX[1] - DetectorSizeY[0]/2.),  1.5 * DetectorSizeY[1], 0.);
+  //  power_1->AddNode(power1_vol, 1, power1_trans);
+  //
+  //  power1_trans = new TGeoTranslation("", -1 * (DetectorSizeX[1] - DetectorSizeY[0]/2.), -1.5 * DetectorSizeY[1], 0.);
+  //  power_1->AddNode(power1_vol, 2, power1_trans);
+  //
+  //  // powerbus - horizontal long
+  //  power1     = new TGeoBBox("power1", (DetectorSizeX[0] - powerbar_width)/2., powerbar_width /2., powerbar_thickness /2.);
+  //  power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed);
+  //  power1_vol->SetLineColor(kColor);
+  //
+  //  // translations
+  //  power1_trans = new TGeoTranslation("", -1 * DetectorSizeX[0],  1.5 * DetectorSizeY[1], 0.);
+  //  power_1->AddNode(power1_vol, 3, power1_trans);
+  //
+  //  power1_trans = new TGeoTranslation("",  1 * DetectorSizeX[0], -1.5 * DetectorSizeY[1], 0.);
+  //  power_1->AddNode(power1_vol, 4, power1_trans);
+
+
+  // powerbus - vertical long
+  power2 =
+    new TGeoBBox("power2", powerbar_width / 2., (9 * DetectorSizeY[0] + powerbar_width) / 2., powerbar_thickness / 2.);
+  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  power2_vol->SetLineColor(kColor);
+
+  // translations
+  power2_trans = new TGeoTranslation("", -(2.0 * DetectorSizeX[0] + 1.0 * DetectorSizeX[1]), 0., 0.);
+  power_1->AddNode(power2_vol, 1, power2_trans);
+  power2_trans = new TGeoTranslation("", 2.0 * DetectorSizeX[0] + 1.0 * DetectorSizeX[1], 0., 0.);
+  power_1->AddNode(power2_vol, 2, power2_trans);
+
+  power2_trans = new TGeoTranslation("", -1.0 * DetectorSizeX[0], 0., 0.);
+  power_1->AddNode(power2_vol, 3, power2_trans);
+  power2_trans = new TGeoTranslation("", 1.0 * DetectorSizeX[0], 0., 0.);
+  power_1->AddNode(power2_vol, 4, power2_trans);
+
+  //  // powerbus - vertical middle
+  //  power2     = new TGeoBBox("power2", powerbar_width /2., (3 * DetectorSizeY[1] + powerbar_width) /2., powerbar_thickness /2.);
+  //  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  //  power2_vol->SetLineColor(kColor);
+  //
+  //  // translations
+  //  power2_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[0],  0., 0.);
+  //  power_1->AddNode(power2_vol, 7, power2_trans);
+  //  power2_trans = new TGeoTranslation("",  1.5 * DetectorSizeX[0],  0., 0.);
+  //  power_1->AddNode(power2_vol, 8, power2_trans);
+  //
+  //  // powerbus - vertical short 1
+  //  power2     = new TGeoBBox("power2", powerbar_width /2., 1 * DetectorSizeY[1] /2., powerbar_thickness /2.);
+  //  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  //  power2_vol->SetLineColor(kColor);
+  //  //  power2_vol->SetLineColor(kRed);
+  //
+  //  // translations
+  //  power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[1],  (2.0 * DetectorSizeY[1] + powerbar_width/2.), 0.);
+  //  power_1->AddNode(power2_vol, 9, power2_trans);
+  //  power2_trans = new TGeoTranslation("",  0.5 * DetectorSizeX[1], -(2.0 * DetectorSizeY[1] + powerbar_width/2.), 0.);
+  //  power_1->AddNode(power2_vol,10, power2_trans);
+  //
+  //  // powerbus - vertical short 2
+  //  power2     = new TGeoBBox("power2", powerbar_width /2., (1 * DetectorSizeY[1] + powerbar_width) /2., powerbar_thickness /2.);
+  //  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  //  power2_vol->SetLineColor(kColor);
+  //
+  //  // translations
+  //  power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[1], -2.0 * DetectorSizeY[1], 0.);
+  //  power_1->AddNode(power2_vol,11, power2_trans);
+  //  power2_trans = new TGeoTranslation("",  0.5 * DetectorSizeX[1],  2.0 * DetectorSizeY[1], 0.);
+  //  power_1->AddNode(power2_vol,12, power2_trans);
+  //
+  //  // powerbus - vertical short 3
+  //  power2     = new TGeoBBox("power2", powerbar_width /2., (2 * DetectorSizeY[0] + powerbar_width/2.) /2., powerbar_thickness /2.);
+  //  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  //  power2_vol->SetLineColor(kColor);
+  //
+  //  // translations
+  //  power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[0],  (1.5 * DetectorSizeY[0] + powerbar_width/4.), 0.);
+  //  power_1->AddNode(power2_vol,11, power2_trans);
+  //  power2_trans = new TGeoTranslation("",  0.5 * DetectorSizeX[0], -(1.5 * DetectorSizeY[0] + powerbar_width/4.), 0.);
+  //  power_1->AddNode(power2_vol,12, power2_trans);
+
+  Int_t l;
+  for (l = 0; l < 4; l++)
+    if ((ShowLayer[l]) && (BusBarOrientation[l] == 1))  // if geometry contains layer l
+    {
+      TString layername = Form("layer%02d", l + 1);
+      TGeoTranslation* power_placement =
+        new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness / 2. + powerbar_position);
+      gGeoMan->GetVolume(layername)->AddNode(power_1, l, power_placement);
+    }
+}
+
+
+void create_power_bars_horizontal()
+{
+  const TString power_01 = "power_bars_trd1";
+  TGeoVolume* power_1    = new TGeoVolumeAssembly(power_01);
+
+  TGeoBBox* power1;
+  TGeoBBox* power2;
+
+  TGeoVolume* power1_vol;
+  TGeoVolume* power2_vol;
+
+  TGeoTranslation* power1_trans;
+  TGeoTranslation* power2_trans;
+
+  const Int_t kColor = kBlue;  // bus bar color
+
+  TGeoMedium* powerBusVolMed = gGeoMan->GetMedium(PowerBusVolumeMedium);
+
+  // powerbus - vertical short
+  power1     = new TGeoBBox("power1", powerbar_width / 2., (DetectorSizeY[1] - DetectorSizeY[0] - powerbar_width) / 2.,
+                        powerbar_thickness / 2.);
+  power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed);
+  power1_vol->SetLineColor(kColor);
+
+  // translations
+  power1_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], -1 * (DetectorSizeY[1] - DetectorSizeY[0] / 2.), 0.);
+  power_1->AddNode(power1_vol, 1, power1_trans);
+
+  power1_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], 1 * (DetectorSizeY[1] - DetectorSizeY[0] / 2.), 0.);
+  power_1->AddNode(power1_vol, 2, power1_trans);
+
+  // powerbus - vertical long
+  power1 =
+    new TGeoBBox("power1", powerbar_width / 2., (DetectorSizeY[0] - powerbar_width) / 2., powerbar_thickness / 2.);
+  power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed);
+  power1_vol->SetLineColor(kColor);
+
+  // translations
+  power1_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], 1 * DetectorSizeY[0], 0.);
+  power_1->AddNode(power1_vol, 3, power1_trans);
+
+  power1_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], -1 * DetectorSizeY[0], 0.);
+  power_1->AddNode(power1_vol, 4, power1_trans);
+
+
+  // powerbus - horizontal long
+  power2 =
+    new TGeoBBox("power2", (7 * DetectorSizeX[1] + powerbar_width) / 2., powerbar_width / 2., powerbar_thickness / 2.);
+  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  power2_vol->SetLineColor(kColor);
+
+  // translations
+  power2_trans = new TGeoTranslation("", 0., -2.5 * DetectorSizeY[1], 0.);
+  power_1->AddNode(power2_vol, 1, power2_trans);
+  power2_trans = new TGeoTranslation("", 0., 2.5 * DetectorSizeY[1], 0.);
+  power_1->AddNode(power2_vol, 2, power2_trans);
+
+  power2_trans = new TGeoTranslation("", 0., -1.5 * DetectorSizeY[1], 0.);
+  power_1->AddNode(power2_vol, 3, power2_trans);
+  power2_trans = new TGeoTranslation("", 0., 1.5 * DetectorSizeY[1], 0.);
+  power_1->AddNode(power2_vol, 4, power2_trans);
+
+  // powerbus - horizontal middle
+  power2 =
+    new TGeoBBox("power2", (3 * DetectorSizeX[1] + powerbar_width) / 2., powerbar_width / 2., powerbar_thickness / 2.);
+  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  power2_vol->SetLineColor(kColor);
+
+  // translations
+  power2_trans = new TGeoTranslation("", 0., -1.5 * DetectorSizeY[0], 0.);
+  power_1->AddNode(power2_vol, 7, power2_trans);
+  power2_trans = new TGeoTranslation("", 0., 1.5 * DetectorSizeY[0], 0.);
+  power_1->AddNode(power2_vol, 8, power2_trans);
+
+  // powerbus - horizontal short 1
+  power2     = new TGeoBBox("power2", 2 * DetectorSizeX[1] / 2., powerbar_width / 2., powerbar_thickness / 2.);
+  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  power2_vol->SetLineColor(kColor);
+  //  power2_vol->SetLineColor(kRed);
+
+  // translations
+  power2_trans = new TGeoTranslation("", (2.5 * DetectorSizeX[1] + powerbar_width / 2.), 0.5 * DetectorSizeY[1], 0.);
+  power_1->AddNode(power2_vol, 9, power2_trans);
+  power2_trans = new TGeoTranslation("", -(2.5 * DetectorSizeX[1] + powerbar_width / 2.), -0.5 * DetectorSizeY[1], 0.);
+  power_1->AddNode(power2_vol, 10, power2_trans);
+
+  // powerbus - horizontal short 2
+  power2 =
+    new TGeoBBox("power2", (2 * DetectorSizeX[1] + powerbar_width) / 2., powerbar_width / 2., powerbar_thickness / 2.);
+  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  power2_vol->SetLineColor(kColor);
+
+  // translations
+  power2_trans = new TGeoTranslation("", -2.5 * DetectorSizeX[1], 0.5 * DetectorSizeY[1], 0.);
+  power_1->AddNode(power2_vol, 11, power2_trans);
+  power2_trans = new TGeoTranslation("", 2.5 * DetectorSizeX[1], -0.5 * DetectorSizeY[1], 0.);
+  power_1->AddNode(power2_vol, 12, power2_trans);
+
+  // powerbus - horizontal short 3
+  power2     = new TGeoBBox("power2", (2 * DetectorSizeX[0] + powerbar_width / 2.) / 2., powerbar_width / 2.,
+                        powerbar_thickness / 2.);
+  power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed);
+  power2_vol->SetLineColor(kColor);
+
+  // translations
+  power2_trans = new TGeoTranslation("", (1.5 * DetectorSizeX[0] + powerbar_width / 4.), 0.5 * DetectorSizeY[0], 0.);
+  power_1->AddNode(power2_vol, 11, power2_trans);
+  power2_trans = new TGeoTranslation("", -(1.5 * DetectorSizeX[0] + powerbar_width / 4.), -0.5 * DetectorSizeY[0], 0.);
+  power_1->AddNode(power2_vol, 12, power2_trans);
+
+  Int_t l;
+  for (l = 0; l < 4; l++)
+    if ((ShowLayer[l]) && (BusBarOrientation[l] == 0))  // if geometry contains layer l
+    {
+      TString layername = Form("layer%02d", l + 1);
+      TGeoTranslation* power_placement =
+        new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness / 2. + powerbar_position);
+      gGeoMan->GetVolume(layername)->AddNode(power_1, l, power_placement);
+    }
+}
+
+
+void create_xtru_supports()
+{
+  const TString trd_01 = "support_trd1";
+  TGeoVolume* trd_1    = new TGeoVolumeAssembly(trd_01);
+
+  const TString trd_02 = "support_trd2";
+  TGeoVolume* trd_2    = new TGeoVolumeAssembly(trd_02);
+
+  const TString trd_03 = "support_trd3";
+  TGeoVolume* trd_3    = new TGeoVolumeAssembly(trd_03);
+
+  //  const TString trdSupport = "supportframe";
+  //  TGeoVolume* trdsupport = new TGeoVolumeAssembly(trdSupport);
+  //
+  //  trdsupport->AddNode(trd_1, 1);
+  //  trdsupport->AddNode(trd_2, 2);
+  //  trdsupport->AddNode(trd_3, 3);
+
+  TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium);  // define Volume Medium
+
+  const Double_t x[12] = {-15, -15, -1, -1, -15, -15, 15, 15, 1, 1, 15, 15};  // IPB 400
+  const Double_t y[12] = {-20, -18, -18, 18,  18,  20,
+                          20,  18,  18,  -18, -18, -20};  // 30 x 40 cm in size, 2 cm wall thickness
+  const Double_t Hwid  = -2 * x[0];                       // 30
+  const Double_t Hhei  = -2 * y[0];                       // 40
+
+  Double_t AperX[3] = {450., 550., 600.};  // inner aperture in X of support structure for stations 1,2,3
+  Double_t AperY[3] = {350., 450., 500.};  // inner aperture in Y of support structure for stations 1,2,3
+  Double_t PilPosX;
+  Double_t BarPosY;
+
+  const Double_t BeamHeight = 570;  // beamline is at 5.7m above floor
+
+  Double_t PilPosZ[6];  // PilPosZ
+                        //  PilPosZ[0] = LayerPosition[0] + LayerThickness/2.;
+                        //  PilPosZ[1] = LayerPosition[3] + LayerThickness/2.;
+                        //  PilPosZ[2] = LayerPosition[4] + LayerThickness/2.;
+                        //  PilPosZ[3] = LayerPosition[7] + LayerThickness/2.;
+                        //  PilPosZ[4] = LayerPosition[8] + LayerThickness/2.;
+                        //  PilPosZ[5] = LayerPosition[9] + LayerThickness/2.;
+
+  PilPosZ[0] = LayerPosition[0] + 15;
+  PilPosZ[1] = LayerPosition[3] - 15 + LayerThickness;
+  PilPosZ[2] = LayerPosition[4] + 15;
+  PilPosZ[3] = LayerPosition[7] - 15 + LayerThickness;
+  PilPosZ[4] = LayerPosition[8] + 15;
+  PilPosZ[5] = LayerPosition[9] - 15 + LayerThickness;
+
+  //  cout << "PilPosZ[0]: " << PilPosZ[0] << endl;
+  //  cout << "PilPosZ[1]: " << PilPosZ[1] << endl;
+
+  TGeoRotation* rotx090 = new TGeoRotation("rotx090");
+  rotx090->RotateX(90.);  // rotate  90 deg around x-axis
+  TGeoRotation* roty090 = new TGeoRotation("roty090");
+  roty090->RotateY(90.);  // rotate  90 deg around y-axis
+  TGeoRotation* rotz090 = new TGeoRotation("rotz090");
+  rotz090->RotateZ(90.);  // rotate  90 deg around y-axis
+  TGeoRotation* roty270 = new TGeoRotation("roty270");
+  roty270->RotateY(270.);  // rotate 270 deg around y-axis
+
+  TGeoRotation* rotzx01 = new TGeoRotation("rotzx01");
+  rotzx01->RotateZ(90.);  // rotate  90 deg around z-axis
+  rotzx01->RotateX(90.);  // rotate  90 deg around x-axis
+
+  //  TGeoRotation  *rotxz01 = new TGeoRotation("rotxz01");
+  //  rotxz01->RotateX(  90.); // rotate  90 deg around x-axis
+  //  rotxz01->RotateZ(  90.); // rotate  90 deg around z-axis
+
+  Double_t ang1 = atan(3. / 4.) * 180. / acos(-1.);
+  //  cout << "DEDE " << ang1 << endl;
+  //  Double_t sin1 = acos(-1.);
+  //  cout << "DEDE " << sin1 << endl;
+  TGeoRotation* rotx080 = new TGeoRotation("rotx080");
+  rotx080->RotateX(90. - ang1);  // rotate  80 deg around x-axis
+  TGeoRotation* rotx100 = new TGeoRotation("rotx100");
+  rotx100->RotateX(90. + ang1);  // rotate 100 deg around x-axis
+
+  TGeoRotation* rotxy01 = new TGeoRotation("rotxy01");
+  rotxy01->RotateX(90.);    // rotate  90 deg around x-axis
+  rotxy01->RotateZ(-ang1);  // rotate  ang1   around rotated y-axis
+
+  TGeoRotation* rotxy02 = new TGeoRotation("rotxy02");
+  rotxy02->RotateX(90.);   // rotate  90 deg around x-axis
+  rotxy02->RotateZ(ang1);  // rotate  ang1   around rotated y-axis
+
+
+  //-------------------
+  // vertical pillars (Y)
+  //-------------------
+
+  // station 1
+  if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+  {
+    TGeoXtru* trd_H_vert1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_vert1->DefinePolygon(12, x, y);
+    trd_H_vert1->DefineSection(0, -(AperY[0] + Hhei), 0, 0, 1.0);
+    trd_H_vert1->DefineSection(1, BeamHeight, 0, 0, 1.0);
+    TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_01", trd_H_vert1, aluminiumVolMed);
+    trd_H_vert_vol1->SetLineColor(kYellow);
+    PilPosX = AperX[0];
+
+    TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[0], rotzx01);
+    trd_1->AddNode(trd_H_vert_vol1, 11, trd_H_vert_combi01);
+    TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[0], rotzx01);
+    trd_1->AddNode(trd_H_vert_vol1, 12, trd_H_vert_combi02);
+    TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[1], rotzx01);
+    trd_1->AddNode(trd_H_vert_vol1, 13, trd_H_vert_combi03);
+    TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[1], rotzx01);
+    trd_1->AddNode(trd_H_vert_vol1, 14, trd_H_vert_combi04);
+  }
+
+  // station 2
+  if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+  {
+    TGeoXtru* trd_H_vert1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_vert1->DefinePolygon(12, x, y);
+    trd_H_vert1->DefineSection(0, -(AperY[1] + Hhei), 0, 0, 1.0);
+    trd_H_vert1->DefineSection(1, BeamHeight, 0, 0, 1.0);
+    TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_02", trd_H_vert1, aluminiumVolMed);
+    trd_H_vert_vol1->SetLineColor(kYellow);
+    PilPosX = AperX[1];
+
+    TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[2], rotzx01);
+    trd_2->AddNode(trd_H_vert_vol1, 21, trd_H_vert_combi01);
+    TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[2], rotzx01);
+    trd_2->AddNode(trd_H_vert_vol1, 22, trd_H_vert_combi02);
+    TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[3], rotzx01);
+    trd_2->AddNode(trd_H_vert_vol1, 23, trd_H_vert_combi03);
+    TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[3], rotzx01);
+    trd_2->AddNode(trd_H_vert_vol1, 24, trd_H_vert_combi04);
+  }
+
+  // station 3
+  if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+  {
+    TGeoXtru* trd_H_vert1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_vert1->DefinePolygon(12, x, y);
+    trd_H_vert1->DefineSection(0, -(AperY[2] + Hhei), 0, 0, 1.0);
+    trd_H_vert1->DefineSection(1, BeamHeight, 0, 0, 1.0);
+    TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_03", trd_H_vert1, aluminiumVolMed);
+    trd_H_vert_vol1->SetLineColor(kYellow);
+    PilPosX = AperX[2];
+
+    TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[4], rotzx01);
+    trd_3->AddNode(trd_H_vert_vol1, 31, trd_H_vert_combi01);
+    TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[4], rotzx01);
+    trd_3->AddNode(trd_H_vert_vol1, 32, trd_H_vert_combi02);
+    TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[5], rotzx01);
+    trd_3->AddNode(trd_H_vert_vol1, 33, trd_H_vert_combi03);
+    TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[5], rotzx01);
+    trd_3->AddNode(trd_H_vert_vol1, 34, trd_H_vert_combi04);
+  }
+
+
+  //-------------------
+  // horizontal supports (X)
+  //-------------------
+
+  // station 1
+  if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+  {
+    TGeoXtru* trd_H_hori1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_hori1->DefinePolygon(12, x, y);
+    trd_H_hori1->DefineSection(0, -AperX[0], 0, 0, 1.0);
+    trd_H_hori1->DefineSection(1, AperX[0], 0, 0, 1.0);
+    TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_01", trd_H_hori1, aluminiumVolMed);
+    trd_H_hori_vol1->SetLineColor(kRed);
+    BarPosY = AperY[0];
+
+    TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[0], roty090);
+    trd_1->AddNode(trd_H_hori_vol1, 11, trd_H_hori_combi01);
+    TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[0], roty090);
+    trd_1->AddNode(trd_H_hori_vol1, 12, trd_H_hori_combi02);
+    TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[1], roty090);
+    trd_1->AddNode(trd_H_hori_vol1, 13, trd_H_hori_combi03);
+    TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[1], roty090);
+    trd_1->AddNode(trd_H_hori_vol1, 14, trd_H_hori_combi04);
+  }
+
+  // station 2
+  if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+  {
+    TGeoXtru* trd_H_hori1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_hori1->DefinePolygon(12, x, y);
+    trd_H_hori1->DefineSection(0, -AperX[1], 0, 0, 1.0);
+    trd_H_hori1->DefineSection(1, AperX[1], 0, 0, 1.0);
+    TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_02", trd_H_hori1, aluminiumVolMed);
+    trd_H_hori_vol1->SetLineColor(kRed);
+    BarPosY = AperY[1];
+
+    TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[2], roty090);
+    trd_2->AddNode(trd_H_hori_vol1, 21, trd_H_hori_combi01);
+    TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[2], roty090);
+    trd_2->AddNode(trd_H_hori_vol1, 22, trd_H_hori_combi02);
+    TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[3], roty090);
+    trd_2->AddNode(trd_H_hori_vol1, 23, trd_H_hori_combi03);
+    TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[3], roty090);
+    trd_2->AddNode(trd_H_hori_vol1, 24, trd_H_hori_combi04);
+  }
+
+  // station 3
+  if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+  {
+    TGeoXtru* trd_H_hori1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_hori1->DefinePolygon(12, x, y);
+    trd_H_hori1->DefineSection(0, -AperX[2], 0, 0, 1.0);
+    trd_H_hori1->DefineSection(1, AperX[2], 0, 0, 1.0);
+    TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_03", trd_H_hori1, aluminiumVolMed);
+    trd_H_hori_vol1->SetLineColor(kRed);
+    BarPosY = AperY[2];
+
+    TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[4], roty090);
+    trd_3->AddNode(trd_H_hori_vol1, 31, trd_H_hori_combi01);
+    TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[4], roty090);
+    trd_3->AddNode(trd_H_hori_vol1, 32, trd_H_hori_combi02);
+    TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[5], roty090);
+    trd_3->AddNode(trd_H_hori_vol1, 33, trd_H_hori_combi03);
+    TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[5], roty090);
+    trd_3->AddNode(trd_H_hori_vol1, 34, trd_H_hori_combi04);
+  }
+
+
+  //-------------------
+  // horizontal supports (Z)
+  //-------------------
+
+  // station 1
+  if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+  {
+    TGeoXtru* trd_H_slope1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_slope1->DefinePolygon(12, x, y);
+    trd_H_slope1->DefineSection(0, -(PilPosZ[1] - PilPosZ[0] - Hwid) / 2., 0, 0, 1.0);
+    trd_H_slope1->DefineSection(1, +(PilPosZ[1] - PilPosZ[0] - Hwid) / 2., 0, 0, 1.0);
+    TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_01", trd_H_slope1, aluminiumVolMed);
+    trd_H_slope_vol1->SetLineColor(kGreen);
+    PilPosX = AperX[0];
+    BarPosY = AperY[0];
+
+    TGeoCombiTrans* trd_H_slope_combi01 =
+      new TGeoCombiTrans((PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., rotz090);
+    trd_1->AddNode(trd_H_slope_vol1, 11, trd_H_slope_combi01);
+    TGeoCombiTrans* trd_H_slope_combi02 =
+      new TGeoCombiTrans(-(PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., rotz090);
+    trd_1->AddNode(trd_H_slope_vol1, 12, trd_H_slope_combi02);
+    TGeoCombiTrans* trd_H_slope_combi03 =
+      new TGeoCombiTrans((PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., rotz090);
+    trd_1->AddNode(trd_H_slope_vol1, 13, trd_H_slope_combi03);
+    TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.),
+                                                             (PilPosZ[0] + PilPosZ[1]) / 2., rotz090);
+    trd_1->AddNode(trd_H_slope_vol1, 14, trd_H_slope_combi04);
+  }
+
+  // station 2
+  if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+  {
+    TGeoXtru* trd_H_slope1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_slope1->DefinePolygon(12, x, y);
+    trd_H_slope1->DefineSection(0, -(PilPosZ[3] - PilPosZ[2] - Hwid) / 2., 0, 0, 1.0);
+    trd_H_slope1->DefineSection(1, +(PilPosZ[3] - PilPosZ[2] - Hwid) / 2., 0, 0, 1.0);
+    TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_02", trd_H_slope1, aluminiumVolMed);
+    trd_H_slope_vol1->SetLineColor(kGreen);
+    PilPosX = AperX[1];
+    BarPosY = AperY[1];
+
+    TGeoCombiTrans* trd_H_slope_combi01 =
+      new TGeoCombiTrans((PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., rotz090);
+    trd_2->AddNode(trd_H_slope_vol1, 21, trd_H_slope_combi01);
+    TGeoCombiTrans* trd_H_slope_combi02 =
+      new TGeoCombiTrans(-(PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., rotz090);
+    trd_2->AddNode(trd_H_slope_vol1, 22, trd_H_slope_combi02);
+    TGeoCombiTrans* trd_H_slope_combi03 =
+      new TGeoCombiTrans((PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., rotz090);
+    trd_2->AddNode(trd_H_slope_vol1, 23, trd_H_slope_combi03);
+    TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.),
+                                                             (PilPosZ[2] + PilPosZ[3]) / 2., rotz090);
+    trd_2->AddNode(trd_H_slope_vol1, 24, trd_H_slope_combi04);
+  }
+
+  // station 3
+  if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+  {
+    TGeoXtru* trd_H_slope1 = new TGeoXtru(2);  // define Xtrusion of 2 planes
+    trd_H_slope1->DefinePolygon(12, x, y);
+    trd_H_slope1->DefineSection(0, -(PilPosZ[5] - PilPosZ[4] - Hwid) / 2., 0, 0, 1.0);
+    trd_H_slope1->DefineSection(1, +(PilPosZ[5] - PilPosZ[4] - Hwid) / 2., 0, 0, 1.0);
+    TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_03", trd_H_slope1, aluminiumVolMed);
+    trd_H_slope_vol1->SetLineColor(kGreen);
+    PilPosX = AperX[2];
+    BarPosY = AperY[2];
+
+    TGeoCombiTrans* trd_H_slope_combi01 =
+      new TGeoCombiTrans((PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., rotz090);
+    trd_3->AddNode(trd_H_slope_vol1, 31, trd_H_slope_combi01);
+    TGeoCombiTrans* trd_H_slope_combi02 =
+      new TGeoCombiTrans(-(PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., rotz090);
+    trd_3->AddNode(trd_H_slope_vol1, 32, trd_H_slope_combi02);
+    TGeoCombiTrans* trd_H_slope_combi03 =
+      new TGeoCombiTrans((PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., rotz090);
+    trd_3->AddNode(trd_H_slope_vol1, 33, trd_H_slope_combi03);
+    TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.),
+                                                             (PilPosZ[4] + PilPosZ[5]) / 2., rotz090);
+    trd_3->AddNode(trd_H_slope_vol1, 34, trd_H_slope_combi04);
+  }
+
+  if (IncludeLabels) {
+
+    Int_t text_height    = 40;
+    Int_t text_thickness = 8;
+
+    TGeoTranslation* tr200 =
+      new TGeoTranslation(0., (AperY[0] + Hhei + text_height / 2.), PilPosZ[0] - 15 + text_thickness / 2.);
+    TGeoTranslation* tr201 =
+      new TGeoTranslation(0., (AperY[1] + Hhei + text_height / 2.), PilPosZ[2] - 15 + text_thickness / 2.);
+    TGeoTranslation* tr202 =
+      new TGeoTranslation(0., (AperY[2] + Hhei + text_height / 2.), PilPosZ[4] - 15 + text_thickness / 2.);
+
+    TGeoCombiTrans* tr203 =
+      new TGeoCombiTrans(-(AperX[0] + Hhei + text_thickness / 2.), (AperY[0] + Hhei - Hwid - text_height / 2.),
+                         (PilPosZ[0] + PilPosZ[1]) / 2., roty090);
+    TGeoCombiTrans* tr204 =
+      new TGeoCombiTrans(-(AperX[1] + Hhei + text_thickness / 2.), (AperY[1] + Hhei - Hwid - text_height / 2.),
+                         (PilPosZ[2] + PilPosZ[3]) / 2., roty090);
+    TGeoCombiTrans* tr205 =
+      new TGeoCombiTrans(-(AperX[2] + Hhei + text_thickness / 2.), (AperY[2] + Hhei - Hwid - text_height / 2.),
+                         (PilPosZ[4] + PilPosZ[5]) / 2., roty090);
+    TGeoCombiTrans* tr206 =
+      new TGeoCombiTrans((AperX[0] + Hhei + text_thickness / 2.), (AperY[0] + Hhei - Hwid - text_height / 2.),
+                         (PilPosZ[0] + PilPosZ[1]) / 2., roty270);
+    TGeoCombiTrans* tr207 =
+      new TGeoCombiTrans((AperX[1] + Hhei + text_thickness / 2.), (AperY[1] + Hhei - Hwid - text_height / 2.),
+                         (PilPosZ[2] + PilPosZ[3]) / 2., roty270);
+    TGeoCombiTrans* tr208 =
+      new TGeoCombiTrans((AperX[2] + Hhei + text_thickness / 2.), (AperY[2] + Hhei - Hwid - text_height / 2.),
+                         (PilPosZ[4] + PilPosZ[5]) / 2., roty270);
+
+    TGeoVolume* trdbox1 = new TGeoVolumeAssembly("trdbox1");  // volume for TRD text (108, 40, 8)
+    TGeoVolume* trdbox2 = new TGeoVolumeAssembly("trdbox2");  // volume for TRD text (108, 40, 8)
+    TGeoVolume* trdbox3 = new TGeoVolumeAssembly("trdbox3");  // volume for TRD text (108, 40, 8)
+    add_trd_labels(trdbox1, trdbox2, trdbox3);
+
+    // final placement
+    if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+    {
+      //    trd_1->AddNode(trdbox1, 1, tr200);
+      trd_1->AddNode(trdbox1, 4, tr203);
+      trd_1->AddNode(trdbox1, 7, tr206);
+    }
+    if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+    {
+      //    trd_2->AddNode(trdbox2, 2, tr201);
+      trd_2->AddNode(trdbox2, 5, tr204);
+      trd_2->AddNode(trdbox2, 8, tr207);
+    }
+    if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+    {
+      //    trd_3->AddNode(trdbox3, 3, tr202);
+      trd_3->AddNode(trdbox3, 6, tr205);
+      trd_3->AddNode(trdbox3, 9, tr208);
+    }
+  }
+
+  //  gGeoMan->GetVolume(geoVersion)->AddNode(trdsupport,1);
+
+  if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+    gGeoMan->GetVolume(geoVersion)->AddNode(trd_1, 1);
+  if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+    gGeoMan->GetVolume(geoVersion)->AddNode(trd_2, 2);
+  if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+    gGeoMan->GetVolume(geoVersion)->AddNode(trd_3, 3);
+}
+
+
+void add_trd_labels(TGeoVolume* trdbox1, TGeoVolume* trdbox2, TGeoVolume* trdbox3)
+{
+  // write TRD (the 3 characters) in a simple geometry
+  TGeoMedium* textVolMed = gGeoMan->GetMedium(TextVolumeMedium);
+
+  Int_t Tcolor = kBlue;  // kRed;
+  Int_t Rcolor = kBlue;  // kRed;  // kRed;
+  Int_t Dcolor = kBlue;  // kRed;  // kYellow;
+  Int_t Icolor = kBlue;  // kRed;
+
+  // define transformations for letter pieces
+  // T
+  TGeoTranslation* tr01 = new TGeoTranslation(0., -4., 0.);
+  TGeoTranslation* tr02 = new TGeoTranslation(0., 16., 0.);
+
+  // R
+  TGeoTranslation* tr11 = new TGeoTranslation(10, 0., 0.);
+  TGeoTranslation* tr12 = new TGeoTranslation(2, 0., 0.);
+  TGeoTranslation* tr13 = new TGeoTranslation(2, 16., 0.);
+  TGeoTranslation* tr14 = new TGeoTranslation(-2, 8., 0.);
+  TGeoTranslation* tr15 = new TGeoTranslation(-6, 0., 0.);
+
+  // D
+  TGeoTranslation* tr21 = new TGeoTranslation(12., 0., 0.);
+  TGeoTranslation* tr22 = new TGeoTranslation(6., 16., 0.);
+  TGeoTranslation* tr23 = new TGeoTranslation(6., -16., 0.);
+  TGeoTranslation* tr24 = new TGeoTranslation(4., 0., 0.);
+
+  // I
+  TGeoTranslation* tr31 = new TGeoTranslation(0., 0., 0.);
+  TGeoTranslation* tr32 = new TGeoTranslation(0., 16., 0.);
+  TGeoTranslation* tr33 = new TGeoTranslation(0., -16., 0.);
+
+  // make letter T
+  //   TGeoVolume *T = geom->MakeBox("T", Vacuum, 25., 25., 5.);
+  //   T->SetVisibility(kFALSE);
+  TGeoVolume* T = new TGeoVolumeAssembly("Tbox");  // volume for T
+
+  TGeoBBox* Tbar1b  = new TGeoBBox("trd_Tbar1b", 4., 16., 4.);  // | vertical
+  TGeoVolume* Tbar1 = new TGeoVolume("Tbar1", Tbar1b, textVolMed);
+  Tbar1->SetLineColor(Tcolor);
+  T->AddNode(Tbar1, 1, tr01);
+  TGeoBBox* Tbar2b  = new TGeoBBox("trd_Tbar2b", 16, 4., 4.);  // - top
+  TGeoVolume* Tbar2 = new TGeoVolume("Tbar2", Tbar2b, textVolMed);
+  Tbar2->SetLineColor(Tcolor);
+  T->AddNode(Tbar2, 1, tr02);
+
+  // make letter R
+  //   TGeoVolume *R = geom->MakeBox("R", Vacuum, 25., 25., 5.);
+  //   R->SetVisibility(kFALSE);
+  TGeoVolume* R = new TGeoVolumeAssembly("Rbox");  // volume for R
+
+  TGeoBBox* Rbar1b  = new TGeoBBox("trd_Rbar1b", 4., 20, 4.);
+  TGeoVolume* Rbar1 = new TGeoVolume("Rbar1", Rbar1b, textVolMed);
+  Rbar1->SetLineColor(Rcolor);
+  R->AddNode(Rbar1, 1, tr11);
+  TGeoBBox* Rbar2b  = new TGeoBBox("trd_Rbar2b", 4., 4., 4.);
+  TGeoVolume* Rbar2 = new TGeoVolume("Rbar2", Rbar2b, textVolMed);
+  Rbar2->SetLineColor(Rcolor);
+  R->AddNode(Rbar2, 1, tr12);
+  R->AddNode(Rbar2, 2, tr13);
+  TGeoTubeSeg* Rtub1b = new TGeoTubeSeg("trd_Rtub1b", 4., 12, 4., 90., 270.);
+  TGeoVolume* Rtub1   = new TGeoVolume("Rtub1", (TGeoShape*) Rtub1b, textVolMed);
+  Rtub1->SetLineColor(Rcolor);
+  R->AddNode(Rtub1, 1, tr14);
+  TGeoArb8* Rbar3b  = new TGeoArb8("trd_Rbar3b", 4.);
+  TGeoVolume* Rbar3 = new TGeoVolume("Rbar3", Rbar3b, textVolMed);
+  Rbar3->SetLineColor(Rcolor);
+  TGeoArb8* arb = (TGeoArb8*) Rbar3->GetShape();
+  arb->SetVertex(0, 12., -4.);
+  arb->SetVertex(1, 0., -20.);
+  arb->SetVertex(2, -8., -20.);
+  arb->SetVertex(3, 4., -4.);
+  arb->SetVertex(4, 12., -4.);
+  arb->SetVertex(5, 0., -20.);
+  arb->SetVertex(6, -8., -20.);
+  arb->SetVertex(7, 4., -4.);
+  R->AddNode(Rbar3, 1, tr15);
+
+  // make letter D
+  //   TGeoVolume *D = geom->MakeBox("D", Vacuum, 25., 25., 5.);
+  //   D->SetVisibility(kFALSE);
+  TGeoVolume* D = new TGeoVolumeAssembly("Dbox");  // volume for D
+
+  TGeoBBox* Dbar1b  = new TGeoBBox("trd_Dbar1b", 4., 20, 4.);
+  TGeoVolume* Dbar1 = new TGeoVolume("Dbar1", Dbar1b, textVolMed);
+  Dbar1->SetLineColor(Dcolor);
+  D->AddNode(Dbar1, 1, tr21);
+  TGeoBBox* Dbar2b  = new TGeoBBox("trd_Dbar2b", 2., 4., 4.);
+  TGeoVolume* Dbar2 = new TGeoVolume("Dbar2", Dbar2b, textVolMed);
+  Dbar2->SetLineColor(Dcolor);
+  D->AddNode(Dbar2, 1, tr22);
+  D->AddNode(Dbar2, 2, tr23);
+  TGeoTubeSeg* Dtub1b = new TGeoTubeSeg("trd_Dtub1b", 12, 20, 4., 90., 270.);
+  TGeoVolume* Dtub1   = new TGeoVolume("Dtub1", (TGeoShape*) Dtub1b, textVolMed);
+  Dtub1->SetLineColor(Dcolor);
+  D->AddNode(Dtub1, 1, tr24);
+
+  // make letter I
+  TGeoVolume* I = new TGeoVolumeAssembly("Ibox");  // volume for I
+
+  TGeoBBox* Ibar1b  = new TGeoBBox("trd_Ibar1b", 4., 12., 4.);  // | vertical
+  TGeoVolume* Ibar1 = new TGeoVolume("Ibar1", Ibar1b, textVolMed);
+  Ibar1->SetLineColor(Icolor);
+  I->AddNode(Ibar1, 1, tr31);
+  TGeoBBox* Ibar2b  = new TGeoBBox("trd_Ibar2b", 10., 4., 4.);  // - top
+  TGeoVolume* Ibar2 = new TGeoVolume("Ibar2", Ibar2b, textVolMed);
+  Ibar2->SetLineColor(Icolor);
+  I->AddNode(Ibar2, 1, tr32);
+  I->AddNode(Ibar2, 2, tr33);
+
+
+  // build text block "TRD"  <32> + 8 + <28> + 8 + <32> = 108
+
+  //  TGeoBBox *trdboxb = new TGeoBBox("", 108./2, 40./2, 8./2);
+  //  TGeoVolume *trdbox = new TGeoVolume("trdboxb", trdboxb, textVolMed);
+  //  trdbox->SetVisibility(kFALSE);
+
+  //  TGeoVolume* trdbox[0] = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8)
+  //  TGeoVolume* trdbox[1] = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8)
+  //  TGeoVolume* trdbox[2] = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8)
+
+  TGeoTranslation* tr100 = new TGeoTranslation(38., 0., 0.);
+  TGeoTranslation* tr101 = new TGeoTranslation(0., 0., 0.);
+  TGeoTranslation* tr102 = new TGeoTranslation(-38., 0., 0.);
+
+  //  TGeoTranslation *tr103 = new TGeoTranslation( -70., 0., 0.);  // on the same line
+  //  TGeoTranslation *tr104 = new TGeoTranslation( -86., 0., 0.);  // on the same line
+  //  TGeoTranslation *tr105 = new TGeoTranslation(-102., 0., 0.);  // on the same line
+
+  TGeoTranslation* tr110 = new TGeoTranslation(0., -50., 0.);
+  TGeoTranslation* tr111 = new TGeoTranslation(8., -50., 0.);
+  TGeoTranslation* tr112 = new TGeoTranslation(-8., -50., 0.);
+  TGeoTranslation* tr113 = new TGeoTranslation(16., -50., 0.);
+  TGeoTranslation* tr114 = new TGeoTranslation(-16., -50., 0.);
+
+  TGeoTranslation* tr200 = new TGeoTranslation(0., 0., 0.);
+  TGeoTranslation* tr201 = new TGeoTranslation(0., -50., 0.);
+  TGeoTranslation* tr202 = new TGeoTranslation(0., -100., 0.);
+
+  TGeoTranslation* tr210 = new TGeoTranslation(0., -150., 0.);
+  TGeoTranslation* tr213 = new TGeoTranslation(16., -150., 0.);
+  TGeoTranslation* tr214 = new TGeoTranslation(-16., -150., 0.);
+
+  // station 1
+  trdbox1->AddNode(T, 1, tr100);
+  trdbox1->AddNode(R, 1, tr101);
+  trdbox1->AddNode(D, 1, tr102);
+
+  trdbox1->AddNode(I, 1, tr110);
+
+  // station 2
+  trdbox2->AddNode(T, 1, tr100);
+  trdbox2->AddNode(R, 1, tr101);
+  trdbox2->AddNode(D, 1, tr102);
+
+  trdbox2->AddNode(I, 1, tr111);
+  trdbox2->AddNode(I, 2, tr112);
+
+  //// station 3
+  //  trdbox3->AddNode(T, 1, tr100);
+  //  trdbox3->AddNode(R, 1, tr101);
+  //  trdbox3->AddNode(D, 1, tr102);
+  //
+  //  trdbox3->AddNode(I, 1, tr110);
+  //  trdbox3->AddNode(I, 2, tr113);
+  //  trdbox3->AddNode(I, 3, tr114);
+
+  // station 3
+  trdbox3->AddNode(T, 1, tr200);
+  trdbox3->AddNode(R, 1, tr201);
+  trdbox3->AddNode(D, 1, tr202);
+
+  trdbox3->AddNode(I, 1, tr210);
+  trdbox3->AddNode(I, 2, tr213);
+  trdbox3->AddNode(I, 3, tr214);
+
+  //  TGeoScale *sc100 = new TGeoScale( 36./50., 36./50., 1.);  // text is vertical 50 cm, H-bar opening is 36 cm
+  //
+  //  // scale text
+  //  TGeoHMatrix *mat100 = new TGeoHMatrix("");
+  //  TGeoHMatrix *mat101 = new TGeoHMatrix("");
+  //  TGeoHMatrix *mat102 = new TGeoHMatrix("");
+  //  (*mat100) = (*tr100) * (*sc100);
+  //  (*mat101) = (*tr101) * (*sc100);
+  //  (*mat102) = (*tr102) * (*sc100);
+  //
+  //  trdbox->AddNode(T, 1, mat100);
+  //  trdbox->AddNode(R, 1, mat101);
+  //  trdbox->AddNode(D, 1, mat102);
+
+  //   // final placement
+  //   //   TGeoTranslation *tr103 = new TGeoTranslation(0., 400., 500.);
+  //   gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 1, new TGeoTranslation(0., 400., 500.));
+  //   gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 2, new TGeoTranslation(0., 500., 600.));
+  //   gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 3, new TGeoTranslation(0., 600., 700.));
+
+  //  return trdbox;
+}
+
+
+void create_box_supports()
+{
+  const TString trd_01 = "support_trd1";
+  TGeoVolume* trd_1    = new TGeoVolumeAssembly(trd_01);
+
+  const TString trd_02 = "support_trd2";
+  TGeoVolume* trd_2    = new TGeoVolumeAssembly(trd_02);
+
+  const TString trd_03 = "support_trd3";
+  TGeoVolume* trd_3    = new TGeoVolumeAssembly(trd_03);
+
+  //  const TString trdSupport = "supportframe";
+  //  TGeoVolume* trdsupport = new TGeoVolumeAssembly(trdSupport);
+  //
+  //  trdsupport->AddNode(trd_1, 1);
+  //  trdsupport->AddNode(trd_2, 2);
+  //  trdsupport->AddNode(trd_3, 3);
+
+  TGeoMedium* keepVolMed      = gGeoMan->GetMedium(KeepingVolumeMedium);
+  TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium);  // define Volume Medium
+
+  const Int_t I_height = 40;  // cm // I profile properties
+  const Int_t I_width  = 30;  // cm // I profile properties
+  const Int_t I_thick  = 2;   // cm // I profile properties
+
+  const Double_t BeamHeight     = 570;  // beamline is at 5.7m above the floor
+  const Double_t PlatformHeight = 234;  // platform is   2.34m above the floor
+  const Double_t PlatformOffset = 1;    // distance to platform
+
+  //  Double_t AperX[3] = { 450., 550., 600.};  // 100 cm modules  // inner aperture in X of support structure for stations 1,2,3
+  //  Double_t AperY[3] = { 350., 450., 500.};  // 100 cm modules  // inner aperture in Y of support structure for stations 1,2,3
+
+  const Double_t AperX[3] = {4.5 * DetectorSizeX[1], 5.5 * DetectorSizeX[1],
+                             6 * DetectorSizeX[1]};  // inner aperture in X of support structure for stations 1,2,3
+  const Double_t AperY[3] = {3.5 * DetectorSizeY[1], 4.5 * DetectorSizeY[1],
+                             5 * DetectorSizeY[1]};  // inner aperture in Y of support structure for stations 1,2,3
+  // platform
+  const Double_t AperYbot[3] = {BeamHeight - (PlatformHeight + PlatformOffset + I_height), 4.5 * DetectorSizeY[1],
+                                5 * DetectorSizeY[1]};  // inner aperture for station1
+
+  const Double_t xBarPosYtop[3] = {AperY[0] + I_height / 2., AperY[1] + I_height / 2., AperY[2] + I_height / 2.};
+  const Double_t xBarPosYbot[3] = {AperYbot[0] + I_height / 2., xBarPosYtop[1], xBarPosYtop[2]};
+
+  const Double_t zBarPosYtop[3] = {AperY[0] + I_height - I_width / 2., AperY[1] + I_height - I_width / 2.,
+                                   AperY[2] + I_height - I_width / 2.};
+  const Double_t zBarPosYbot[3] = {AperYbot[0] + I_height - I_width / 2., zBarPosYtop[1], zBarPosYtop[2]};
+
+  Double_t PilPosX;
+  Double_t PilPosZ[6];  // PilPosZ
+
+  PilPosZ[0] = LayerPosition[0] + I_width / 2.;
+  PilPosZ[1] = LayerPosition[3] - I_width / 2. + LayerThickness;
+  PilPosZ[2] = LayerPosition[4] + I_width / 2.;
+  PilPosZ[3] = LayerPosition[7] - I_width / 2. + LayerThickness;
+  PilPosZ[4] = LayerPosition[8] + I_width / 2.;
+  PilPosZ[5] = LayerPosition[9] - I_width / 2. + LayerThickness;
+
+  //  cout << "PilPosZ[0]: " << PilPosZ[0] << endl;
+  //  cout << "PilPosZ[1]: " << PilPosZ[1] << endl;
+
+  TGeoRotation* rotx090 = new TGeoRotation("rotx090");
+  rotx090->RotateX(90.);  // rotate  90 deg around x-axis
+  TGeoRotation* roty090 = new TGeoRotation("roty090");
+  roty090->RotateY(90.);  // rotate  90 deg around y-axis
+  TGeoRotation* rotz090 = new TGeoRotation("rotz090");
+  rotz090->RotateZ(90.);  // rotate  90 deg around y-axis
+  TGeoRotation* roty270 = new TGeoRotation("roty270");
+  roty270->RotateY(270.);  // rotate 270 deg around y-axis
+
+  TGeoRotation* rotzx01 = new TGeoRotation("rotzx01");
+  rotzx01->RotateZ(90.);  // rotate  90 deg around z-axis
+  rotzx01->RotateX(90.);  // rotate  90 deg around x-axis
+
+  TGeoRotation* rotzx02 = new TGeoRotation("rotzx02");
+  rotzx02->RotateZ(270.);  // rotate 270 deg around z-axis
+  rotzx02->RotateX(90.);   // rotate  90 deg around x-axis
+
+  Double_t ang1 = atan(3. / 4.) * 180. / acos(-1.);
+  //  cout << "DEDE " << ang1 << endl;
+  //  Double_t sin1 = acos(-1.);
+  //  cout << "DEDE " << sin1 << endl;
+  TGeoRotation* rotx080 = new TGeoRotation("rotx080");
+  rotx080->RotateX(90. - ang1);  // rotate  80 deg around x-axis
+  TGeoRotation* rotx100 = new TGeoRotation("rotx100");
+  rotx100->RotateX(90. + ang1);  // rotate 100 deg around x-axis
+
+  TGeoRotation* rotxy01 = new TGeoRotation("rotxy01");
+  rotxy01->RotateX(90.);    // rotate  90 deg around x-axis
+  rotxy01->RotateZ(-ang1);  // rotate  ang1   around rotated y-axis
+
+  TGeoRotation* rotxy02 = new TGeoRotation("rotxy02");
+  rotxy02->RotateX(90.);   // rotate  90 deg around x-axis
+  rotxy02->RotateZ(ang1);  // rotate  ang1   around rotated y-axis
+
+
+  //-------------------
+  // vertical pillars (Y)
+  //-------------------
+
+  // station 1
+  if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+  {
+    //      TGeoBBox* trd_I_vert1_keep  = new TGeoBBox("", I_thick /2., I_height /2. - I_thick, (BeamHeight + (AperY[0]+I_height) ) /2.);
+    TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick / 2., I_height / 2. - I_thick,
+                                              ((AperYbot[0] + I_height) + (AperY[0] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert1    = new TGeoVolume("trd_I_y11", trd_I_vert1_keep, aluminiumVolMed);
+    //      TGeoBBox* trd_I_vert2_keep  = new TGeoBBox("", I_width /2.,            I_thick /2., (BeamHeight + (AperY[0]+I_height) ) /2.);
+    TGeoBBox* trd_I_vert2_keep = new TGeoBBox("trd_I_vert2_keep", I_width / 2., I_thick / 2.,
+                                              ((AperYbot[0] + I_height) + (AperY[0] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert2    = new TGeoVolume("trd_I_y12", trd_I_vert2_keep, aluminiumVolMed);
+
+    trd_I_vert1->SetLineColor(kGreen);  // kBlue);  // Yellow);  // kOrange);
+    trd_I_vert2->SetLineColor(kGreen);  // kBlue);  // Yellow);  // kOrange);
+
+    TGeoTranslation* ty01 = new TGeoTranslation("ty01", 0., 0., 0.);
+    TGeoTranslation* ty02 = new TGeoTranslation("ty02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* ty03 = new TGeoTranslation("ty03", 0., -(I_height - I_thick) / 2., 0.);
+
+    //      TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("", I_width /2., I_height /2., (BeamHeight + (AperY[0]+I_height) ) /2.);
+    TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("trd_I_vert_vol1_keep", I_width / 2., I_height / 2.,
+                                                  ((AperYbot[0] + I_height) + (AperY[0] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert_vol1    = new TGeoVolume("trd_I_y10", trd_I_vert_vol1_keep, keepVolMed);
+
+    // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_vert_vol1->SetLineColor(kGreen);
+
+    // build I-bar trd_I_vert_vol1
+    trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01);
+    trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02);
+    trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03);
+
+    // close gap to horizontal z-bars
+    TGeoBBox* trd_I_vert3_keep =
+      new TGeoBBox("trd_I_vert3_keep", (I_width - I_thick) / 2. / 2., I_height / 2. - I_thick, I_thick / 2.);
+    TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y13", trd_I_vert3_keep, aluminiumVolMed);
+    trd_I_vert3->SetLineColor(kGreen);
+    //      TGeoTranslation *ty04 = new TGeoTranslation("ty04",  (I_thick/2. + (I_width-I_thick)/2./2.), 0., -( (AperYbot[0]+I_height) + (AperY[0]+I_height) - I_width) /2.);  // top
+    //      TGeoTranslation *ty05 = new TGeoTranslation("ty05",  (I_thick/2. + (I_width-I_thick)/2./2.), 0.,  ( (AperYbot[0]+I_height) + (AperY[0]+I_height) - I_width) /2.);  // bottom
+    TGeoTranslation* ty04 = new TGeoTranslation("ty04", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0.,
+                                                -(zBarPosYbot[0] + zBarPosYtop[0]) / 2.);  // top
+    TGeoTranslation* ty05 = new TGeoTranslation("ty05", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0.,
+                                                (zBarPosYbot[0] + zBarPosYtop[0]) / 2.);  // bottom
+    trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04);
+    trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05);
+
+    PilPosX = AperX[0];
+
+    TGeoCombiTrans* trd_I_vert_combi01 = new TGeoCombiTrans(
+      (PilPosX + I_height / 2.), -((AperYbot[0] + I_height) - (AperY[0] + I_height)) / 2., PilPosZ[0], rotzx01);
+    trd_1->AddNode(trd_I_vert_vol1, 11, trd_I_vert_combi01);
+    TGeoCombiTrans* trd_I_vert_combi02 = new TGeoCombiTrans(
+      -(PilPosX + I_height / 2.), -((AperYbot[0] + I_height) - (AperY[0] + I_height)) / 2., PilPosZ[0], rotzx01);
+    trd_1->AddNode(trd_I_vert_vol1, 12, trd_I_vert_combi02);
+    TGeoCombiTrans* trd_I_vert_combi03 = new TGeoCombiTrans(
+      (PilPosX + I_height / 2.), -((AperYbot[0] + I_height) - (AperY[0] + I_height)) / 2., PilPosZ[1], rotzx02);
+    trd_1->AddNode(trd_I_vert_vol1, 13, trd_I_vert_combi03);
+    TGeoCombiTrans* trd_I_vert_combi04 = new TGeoCombiTrans(
+      -(PilPosX + I_height / 2.), -((AperYbot[0] + I_height) - (AperY[0] + I_height)) / 2., PilPosZ[1], rotzx02);
+    trd_1->AddNode(trd_I_vert_vol1, 14, trd_I_vert_combi04);
+  }
+
+  // station 2
+  if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+  {
+    TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick / 2., I_height / 2. - I_thick,
+                                              (BeamHeight + (AperY[1] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert1    = new TGeoVolume("trd_I_y21", trd_I_vert1_keep, aluminiumVolMed);
+    TGeoBBox* trd_I_vert2_keep =
+      new TGeoBBox("trd_I_vert2_keep", I_width / 2., I_thick / 2., (BeamHeight + (AperY[1] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y22", trd_I_vert2_keep, aluminiumVolMed);
+    trd_I_vert1->SetLineColor(kGreen);
+    trd_I_vert2->SetLineColor(kGreen);
+
+    TGeoTranslation* ty01 = new TGeoTranslation("ty01", 0., 0., 0.);
+    TGeoTranslation* ty02 = new TGeoTranslation("ty02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* ty03 = new TGeoTranslation("ty03", 0., -(I_height - I_thick) / 2., 0.);
+
+    TGeoBBox* trd_I_vert_vol1_keep =
+      new TGeoBBox("trd_I_vert_vol1_keep", I_width / 2., I_height / 2., (BeamHeight + (AperY[1] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y20", trd_I_vert_vol1_keep, keepVolMed);
+
+    // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_vert_vol1->SetLineColor(kGreen);
+
+    // build I-bar trd_I_vert_vol1
+    trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01);
+    trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02);
+    trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03);
+
+    // close gap to horizontal z-bars
+    TGeoBBox* trd_I_vert3_keep =
+      new TGeoBBox("trd_I_vert3_keep", (I_width - I_thick) / 2. / 2., I_height / 2. - I_thick, I_thick / 2.);
+    TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y23", trd_I_vert3_keep, aluminiumVolMed);
+    trd_I_vert3->SetLineColor(kGreen);
+    TGeoTranslation* ty04 = new TGeoTranslation("ty04", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0.,
+                                                -(BeamHeight + (AperY[1] + I_height) - I_width) / 2.);  // top
+    TGeoTranslation* ty05 = new TGeoTranslation("ty05", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0.,
+                                                -(BeamHeight - (AperY[1] + I_height)) / 2. + zBarPosYbot[1]);  // bottom
+    trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04);
+    trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05);
+
+    PilPosX = AperX[1];
+
+    TGeoCombiTrans* trd_I_vert_combi01 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), -(BeamHeight - (AperY[1] + I_height)) / 2., PilPosZ[2], rotzx01);
+    trd_2->AddNode(trd_I_vert_vol1, 21, trd_I_vert_combi01);
+    TGeoCombiTrans* trd_I_vert_combi02 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), -(BeamHeight - (AperY[1] + I_height)) / 2., PilPosZ[2], rotzx01);
+    trd_2->AddNode(trd_I_vert_vol1, 22, trd_I_vert_combi02);
+    TGeoCombiTrans* trd_I_vert_combi03 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), -(BeamHeight - (AperY[1] + I_height)) / 2., PilPosZ[3], rotzx02);
+    trd_2->AddNode(trd_I_vert_vol1, 23, trd_I_vert_combi03);
+    TGeoCombiTrans* trd_I_vert_combi04 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), -(BeamHeight - (AperY[1] + I_height)) / 2., PilPosZ[3], rotzx02);
+    trd_2->AddNode(trd_I_vert_vol1, 24, trd_I_vert_combi04);
+  }
+
+  // station 3
+  if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+  {
+    TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick / 2., I_height / 2. - I_thick,
+                                              (BeamHeight + (AperY[2] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert1    = new TGeoVolume("trd_I_y31", trd_I_vert1_keep, aluminiumVolMed);
+    TGeoBBox* trd_I_vert2_keep =
+      new TGeoBBox("trd_I_vert2_keep", I_width / 2., I_thick / 2., (BeamHeight + (AperY[2] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y32", trd_I_vert2_keep, aluminiumVolMed);
+
+    trd_I_vert1->SetLineColor(kGreen);
+    trd_I_vert2->SetLineColor(kGreen);
+
+    TGeoTranslation* ty01 = new TGeoTranslation("ty01", 0., 0., 0.);
+    TGeoTranslation* ty02 = new TGeoTranslation("ty02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* ty03 = new TGeoTranslation("ty03", 0., -(I_height - I_thick) / 2., 0.);
+
+    TGeoBBox* trd_I_vert_vol1_keep =
+      new TGeoBBox("trd_I_vert_vol1_keep", I_width / 2., I_height / 2., (BeamHeight + (AperY[2] + I_height)) / 2.);
+    TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y30", trd_I_vert_vol1_keep, keepVolMed);
+
+    // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_vert_vol1->SetLineColor(kGreen);
+
+    // build I-bar trd_I_vert_vol1
+    trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01);
+    trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02);
+    trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03);
+
+    // close gap to horizontal z-bars
+    TGeoBBox* trd_I_vert3_keep =
+      new TGeoBBox("trd_I_vert3_keep", (I_width - I_thick) / 2. / 2., I_height / 2. - I_thick, I_thick / 2.);
+    TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y33", trd_I_vert3_keep, aluminiumVolMed);
+    trd_I_vert3->SetLineColor(kGreen);
+    TGeoTranslation* ty04 = new TGeoTranslation("ty04", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0.,
+                                                -(BeamHeight + (AperY[2] + I_height) - I_width) / 2.);  // top
+    TGeoTranslation* ty05 = new TGeoTranslation("ty05", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0.,
+                                                -(BeamHeight - (AperY[2] + I_height)) / 2. + zBarPosYbot[2]);  // bottom
+    trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04);
+    trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05);
+
+    PilPosX = AperX[2];
+
+    TGeoCombiTrans* trd_I_vert_combi01 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), -(BeamHeight - (AperY[2] + I_height)) / 2., PilPosZ[4], rotzx01);
+    trd_3->AddNode(trd_I_vert_vol1, 31, trd_I_vert_combi01);
+    TGeoCombiTrans* trd_I_vert_combi02 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), -(BeamHeight - (AperY[2] + I_height)) / 2., PilPosZ[4], rotzx01);
+    trd_3->AddNode(trd_I_vert_vol1, 32, trd_I_vert_combi02);
+    TGeoCombiTrans* trd_I_vert_combi03 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), -(BeamHeight - (AperY[2] + I_height)) / 2., PilPosZ[5], rotzx02);
+    trd_3->AddNode(trd_I_vert_vol1, 33, trd_I_vert_combi03);
+    TGeoCombiTrans* trd_I_vert_combi04 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), -(BeamHeight - (AperY[2] + I_height)) / 2., PilPosZ[5], rotzx02);
+    trd_3->AddNode(trd_I_vert_vol1, 34, trd_I_vert_combi04);
+  }
+
+
+  //-------------------
+  // horizontal supports (X)
+  //-------------------
+
+  // station 1
+  if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+  {
+    TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick / 2., I_height / 2. - I_thick, AperX[0]);
+    TGeoVolume* trd_I_hori1    = new TGeoVolume("trd_I_x11", trd_I_hori1_keep, aluminiumVolMed);
+    TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width / 2., I_thick / 2., AperX[0]);
+    TGeoVolume* trd_I_hori2    = new TGeoVolume("trd_I_x12", trd_I_hori2_keep, aluminiumVolMed);
+
+    trd_I_hori1->SetLineColor(kRed);  // Yellow);
+    trd_I_hori2->SetLineColor(kRed);  // Yellow);
+
+    TGeoTranslation* tx01 = new TGeoTranslation("tx01", 0., 0., 0.);
+    TGeoTranslation* tx02 = new TGeoTranslation("tx02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* tx03 = new TGeoTranslation("tx03", 0., -(I_height - I_thick) / 2., 0.);
+
+    TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width / 2., I_height / 2., AperX[0]);
+    TGeoVolume* trd_I_hori_vol1    = new TGeoVolume("trd_I_x10", trd_I_hori_vol1_keep, keepVolMed);
+
+    // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_hori_vol1->SetLineColor(kRed);
+
+    // build I-bar trd_I_hori_vol1
+    trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01);
+    trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02);
+    trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03);
+
+    TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[0], PilPosZ[0], roty090);
+    trd_1->AddNode(trd_I_hori_vol1, 11, trd_I_hori_combi01);
+    TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0., -xBarPosYbot[0], PilPosZ[0], roty090);
+    trd_1->AddNode(trd_I_hori_vol1, 12, trd_I_hori_combi02);
+    TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[0], PilPosZ[1], roty090);
+    trd_1->AddNode(trd_I_hori_vol1, 13, trd_I_hori_combi03);
+    TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0., -xBarPosYbot[0], PilPosZ[1], roty090);
+    trd_1->AddNode(trd_I_hori_vol1, 14, trd_I_hori_combi04);
+  }
+
+  // station 2
+  if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+  {
+    TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick / 2., I_height / 2. - I_thick, AperX[1]);
+    TGeoVolume* trd_I_hori1    = new TGeoVolume("trd_I_x21", trd_I_hori1_keep, aluminiumVolMed);
+    TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width / 2., I_thick / 2., AperX[1]);
+    TGeoVolume* trd_I_hori2    = new TGeoVolume("trd_I_x22", trd_I_hori2_keep, aluminiumVolMed);
+
+    trd_I_hori1->SetLineColor(kRed);
+    trd_I_hori2->SetLineColor(kRed);
+
+    TGeoTranslation* tx01 = new TGeoTranslation("tx01", 0., 0., 0.);
+    TGeoTranslation* tx02 = new TGeoTranslation("tx02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* tx03 = new TGeoTranslation("tx03", 0., -(I_height - I_thick) / 2., 0.);
+
+    TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width / 2., I_height / 2., AperX[1]);
+    TGeoVolume* trd_I_hori_vol1    = new TGeoVolume("trd_I_x20", trd_I_hori_vol1_keep, keepVolMed);
+
+    // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_hori_vol1->SetLineColor(kRed);
+
+    // build I-bar trd_I_hori_vol1
+    trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01);
+    trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02);
+    trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03);
+
+    TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[1], PilPosZ[2], roty090);
+    trd_2->AddNode(trd_I_hori_vol1, 21, trd_I_hori_combi01);
+    TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0., -xBarPosYbot[1], PilPosZ[2], roty090);
+    trd_2->AddNode(trd_I_hori_vol1, 22, trd_I_hori_combi02);
+    TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[1], PilPosZ[3], roty090);
+    trd_2->AddNode(trd_I_hori_vol1, 23, trd_I_hori_combi03);
+    TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0., -xBarPosYbot[1], PilPosZ[3], roty090);
+    trd_2->AddNode(trd_I_hori_vol1, 24, trd_I_hori_combi04);
+  }
+
+  // station 3
+  if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+  {
+    TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick / 2., I_height / 2. - I_thick, AperX[2]);
+    TGeoVolume* trd_I_hori1    = new TGeoVolume("trd_I_x31", trd_I_hori1_keep, aluminiumVolMed);
+    TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width / 2., I_thick / 2., AperX[2]);
+    TGeoVolume* trd_I_hori2    = new TGeoVolume("trd_I_x32", trd_I_hori2_keep, aluminiumVolMed);
+
+    trd_I_hori1->SetLineColor(kRed);
+    trd_I_hori2->SetLineColor(kRed);
+
+    TGeoTranslation* tx01 = new TGeoTranslation("tx01", 0., 0., 0.);
+    TGeoTranslation* tx02 = new TGeoTranslation("tx02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* tx03 = new TGeoTranslation("tx03", 0., -(I_height - I_thick) / 2., 0.);
+
+    TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width / 2., I_height / 2., AperX[2]);
+    TGeoVolume* trd_I_hori_vol1    = new TGeoVolume("trd_I_x30", trd_I_hori_vol1_keep, keepVolMed);
+
+    // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_hori_vol1->SetLineColor(kRed);
+
+    // build I-bar trd_I_hori_vol1
+    trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01);
+    trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02);
+    trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03);
+
+    TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[2], PilPosZ[4], roty090);
+    trd_3->AddNode(trd_I_hori_vol1, 31, trd_I_hori_combi01);
+    TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0., -xBarPosYbot[2], PilPosZ[4], roty090);
+    trd_3->AddNode(trd_I_hori_vol1, 32, trd_I_hori_combi02);
+    TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[2], PilPosZ[5], roty090);
+    trd_3->AddNode(trd_I_hori_vol1, 33, trd_I_hori_combi03);
+    TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0., -xBarPosYbot[2], PilPosZ[5], roty090);
+    trd_3->AddNode(trd_I_hori_vol1, 34, trd_I_hori_combi04);
+  }
+
+
+  //-------------------
+  // horizontal supports (Z)
+  //-------------------
+
+  // station 1
+  if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+  {
+    TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick / 2., I_height / 2. - I_thick,
+                                               (PilPosZ[1] - PilPosZ[0] - I_width) / 2.);
+    TGeoVolume* trd_I_slope1    = new TGeoVolume("trd_I_z11", trd_I_slope1_keep, aluminiumVolMed);
+    TGeoBBox* trd_I_slope2_keep =
+      new TGeoBBox("trd_I_slope2_keep", I_width / 2., I_thick / 2., (PilPosZ[1] - PilPosZ[0] - I_width) / 2.);
+    TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z12", trd_I_slope2_keep, aluminiumVolMed);
+
+    trd_I_slope1->SetLineColor(kYellow);
+    trd_I_slope2->SetLineColor(kYellow);
+
+    TGeoTranslation* tz01 = new TGeoTranslation("tz01", 0., 0., 0.);
+    TGeoTranslation* tz02 = new TGeoTranslation("tz02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* tz03 = new TGeoTranslation("tz03", 0., -(I_height - I_thick) / 2., 0.);
+
+    TGeoBBox* trd_I_slope_vol1_keep =
+      new TGeoBBox("trd_I_slope_vol1_keep", I_width / 2., I_height / 2., (PilPosZ[1] - PilPosZ[0] - I_width) / 2.);
+    TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z10", trd_I_slope_vol1_keep, keepVolMed);
+
+    // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_slope_vol1->SetLineColor(kYellow);
+
+    // build I-bar trd_I_slope_vol1
+    trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01);
+    trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02);
+    trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03);
+
+    PilPosX = AperX[0];
+
+    TGeoCombiTrans* trd_I_slope_combi01 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), zBarPosYtop[0], (PilPosZ[0] + PilPosZ[1]) / 2., rotz090);
+    trd_1->AddNode(trd_I_slope_vol1, 11, trd_I_slope_combi01);
+    TGeoCombiTrans* trd_I_slope_combi02 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), zBarPosYtop[0], (PilPosZ[0] + PilPosZ[1]) / 2., rotz090);
+    trd_1->AddNode(trd_I_slope_vol1, 12, trd_I_slope_combi02);
+    TGeoCombiTrans* trd_I_slope_combi03 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), -zBarPosYbot[0], (PilPosZ[0] + PilPosZ[1]) / 2., rotz090);
+    trd_1->AddNode(trd_I_slope_vol1, 13, trd_I_slope_combi03);
+    TGeoCombiTrans* trd_I_slope_combi04 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), -zBarPosYbot[0], (PilPosZ[0] + PilPosZ[1]) / 2., rotz090);
+    trd_1->AddNode(trd_I_slope_vol1, 14, trd_I_slope_combi04);
+  }
+
+  // station 2
+  if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+  {
+    TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick / 2., I_height / 2. - I_thick,
+                                               (PilPosZ[3] - PilPosZ[2] - I_width) / 2.);
+    TGeoVolume* trd_I_slope1    = new TGeoVolume("trd_I_z21", trd_I_slope1_keep, aluminiumVolMed);
+    TGeoBBox* trd_I_slope2_keep =
+      new TGeoBBox("trd_I_slope2_keep", I_width / 2., I_thick / 2., (PilPosZ[3] - PilPosZ[2] - I_width) / 2.);
+    TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z22", trd_I_slope2_keep, aluminiumVolMed);
+
+    trd_I_slope1->SetLineColor(kYellow);
+    trd_I_slope2->SetLineColor(kYellow);
+
+    TGeoTranslation* tz01 = new TGeoTranslation("tz01", 0., 0., 0.);
+    TGeoTranslation* tz02 = new TGeoTranslation("tz02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* tz03 = new TGeoTranslation("tz03", 0., -(I_height - I_thick) / 2., 0.);
+
+    TGeoBBox* trd_I_slope_vol1_keep =
+      new TGeoBBox("trd_I_slope_vol1_keep", I_width / 2., I_height / 2., (PilPosZ[3] - PilPosZ[2] - I_width) / 2.);
+    TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z20", trd_I_slope_vol1_keep, keepVolMed);
+
+    // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_slope_vol1->SetLineColor(kYellow);
+
+    // build I-bar trd_I_slope_vol1
+    trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01);
+    trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02);
+    trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03);
+
+    PilPosX = AperX[1];
+
+    TGeoCombiTrans* trd_I_slope_combi01 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), zBarPosYtop[1], (PilPosZ[2] + PilPosZ[3]) / 2., rotz090);
+    trd_2->AddNode(trd_I_slope_vol1, 21, trd_I_slope_combi01);
+    TGeoCombiTrans* trd_I_slope_combi02 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), zBarPosYtop[1], (PilPosZ[2] + PilPosZ[3]) / 2., rotz090);
+    trd_2->AddNode(trd_I_slope_vol1, 22, trd_I_slope_combi02);
+    TGeoCombiTrans* trd_I_slope_combi03 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), -zBarPosYbot[1], (PilPosZ[2] + PilPosZ[3]) / 2., rotz090);
+    trd_2->AddNode(trd_I_slope_vol1, 23, trd_I_slope_combi03);
+    TGeoCombiTrans* trd_I_slope_combi04 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), -zBarPosYbot[1], (PilPosZ[2] + PilPosZ[3]) / 2., rotz090);
+    trd_2->AddNode(trd_I_slope_vol1, 24, trd_I_slope_combi04);
+  }
+
+  // station 3
+  if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+  {
+    TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick / 2., I_height / 2. - I_thick,
+                                               (PilPosZ[5] - PilPosZ[4] - I_width) / 2.);
+    TGeoVolume* trd_I_slope1    = new TGeoVolume("trd_I_z31", trd_I_slope1_keep, aluminiumVolMed);
+    TGeoBBox* trd_I_slope2_keep =
+      new TGeoBBox("trd_I_slope2_keep", I_width / 2., I_thick / 2., (PilPosZ[5] - PilPosZ[4] - I_width) / 2.);
+    TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z32", trd_I_slope2_keep, aluminiumVolMed);
+
+    trd_I_slope1->SetLineColor(kYellow);
+    trd_I_slope2->SetLineColor(kYellow);
+
+    TGeoTranslation* tz01 = new TGeoTranslation("tz01", 0., 0., 0.);
+    TGeoTranslation* tz02 = new TGeoTranslation("tz02", 0., (I_height - I_thick) / 2., 0.);
+    TGeoTranslation* tz03 = new TGeoTranslation("tz03", 0., -(I_height - I_thick) / 2., 0.);
+
+    TGeoBBox* trd_I_slope_vol1_keep =
+      new TGeoBBox("trd_I_slope_vol1_keep", I_width / 2., I_height / 2., (PilPosZ[5] - PilPosZ[4] - I_width) / 2.);
+    TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z30", trd_I_slope_vol1_keep, keepVolMed);
+
+    // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2)
+    trd_I_slope_vol1->SetLineColor(kYellow);
+
+    // build I-bar trd_I_slope_vol1
+    trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01);
+    trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02);
+    trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03);
+
+    PilPosX = AperX[2];
+
+    TGeoCombiTrans* trd_I_slope_combi01 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), zBarPosYtop[2], (PilPosZ[4] + PilPosZ[5]) / 2., rotz090);
+    trd_3->AddNode(trd_I_slope_vol1, 31, trd_I_slope_combi01);
+    TGeoCombiTrans* trd_I_slope_combi02 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), zBarPosYtop[2], (PilPosZ[4] + PilPosZ[5]) / 2., rotz090);
+    trd_3->AddNode(trd_I_slope_vol1, 32, trd_I_slope_combi02);
+    TGeoCombiTrans* trd_I_slope_combi03 =
+      new TGeoCombiTrans((PilPosX + I_height / 2.), -zBarPosYbot[2], (PilPosZ[4] + PilPosZ[5]) / 2., rotz090);
+    trd_3->AddNode(trd_I_slope_vol1, 33, trd_I_slope_combi03);
+    TGeoCombiTrans* trd_I_slope_combi04 =
+      new TGeoCombiTrans(-(PilPosX + I_height / 2.), -zBarPosYbot[2], (PilPosZ[4] + PilPosZ[5]) / 2., rotz090);
+    trd_3->AddNode(trd_I_slope_vol1, 34, trd_I_slope_combi04);
+  }
+
+  if (IncludeLabels) {
+
+    Int_t text_height    = 40;
+    Int_t text_thickness = 8;
+
+    TGeoTranslation* tr200 = new TGeoTranslation(0., (AperY[0] + I_height + text_height / 2.),
+                                                 PilPosZ[0] - I_width / 2. + text_thickness / 2.);
+    TGeoTranslation* tr201 = new TGeoTranslation(0., (AperY[1] + I_height + text_height / 2.),
+                                                 PilPosZ[2] - I_width / 2. + text_thickness / 2.);
+    TGeoTranslation* tr202 = new TGeoTranslation(0., (AperY[2] + I_height + text_height / 2.),
+                                                 PilPosZ[4] - I_width / 2. + text_thickness / 2.);
+    TGeoCombiTrans* tr203 =
+      new TGeoCombiTrans(-(AperX[0] + I_height + text_thickness / 2.),
+                         (AperY[0] + I_height - I_width - text_height / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., roty090);
+    TGeoCombiTrans* tr204 =
+      new TGeoCombiTrans(-(AperX[1] + I_height + text_thickness / 2.),
+                         (AperY[1] + I_height - I_width - text_height / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., roty090);
+    TGeoCombiTrans* tr205 =
+      new TGeoCombiTrans(-(AperX[2] + I_height + text_thickness / 2.),
+                         (AperY[2] + I_height - I_width - text_height / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., roty090);
+    TGeoCombiTrans* tr206 =
+      new TGeoCombiTrans((AperX[0] + I_height + text_thickness / 2.),
+                         (AperY[0] + I_height - I_width - text_height / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., roty270);
+    TGeoCombiTrans* tr207 =
+      new TGeoCombiTrans((AperX[1] + I_height + text_thickness / 2.),
+                         (AperY[1] + I_height - I_width - text_height / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., roty270);
+    TGeoCombiTrans* tr208 =
+      new TGeoCombiTrans((AperX[2] + I_height + text_thickness / 2.),
+                         (AperY[2] + I_height - I_width - text_height / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., roty270);
+
+    TGeoVolume* trdbox1 = new TGeoVolumeAssembly("trdbox1");  // volume for TRD text (108, 40, 8)
+    TGeoVolume* trdbox2 = new TGeoVolumeAssembly("trdbox2");  // volume for TRD text (108, 40, 8)
+    TGeoVolume* trdbox3 = new TGeoVolumeAssembly("trdbox3");  // volume for TRD text (108, 40, 8)
+    add_trd_labels(trdbox1, trdbox2, trdbox3);
+
+    // final placement
+    if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+    {
+      //    trd_1->AddNode(trdbox1, 1, tr200);
+      trd_1->AddNode(trdbox1, 4, tr203);
+      trd_1->AddNode(trdbox1, 7, tr206);
+    }
+    if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+    {
+      //    trd_2->AddNode(trdbox2, 2, tr201);
+      trd_2->AddNode(trdbox2, 5, tr204);
+      trd_2->AddNode(trdbox2, 8, tr207);
+    }
+    if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+    {
+      //    trd_3->AddNode(trdbox3, 3, tr202);
+      trd_3->AddNode(trdbox3, 6, tr205);
+      trd_3->AddNode(trdbox3, 9, tr208);
+    }
+  }
+
+  if (ShowLayer[0])  // if geometry contains layer 1 (1st layer of station 1)
+    gGeoMan->GetVolume(geoVersion)->AddNode(trd_1, 1);
+  if (ShowLayer[4])  // if geometry contains layer 5 (1st layer of station 2)
+    gGeoMan->GetVolume(geoVersion)->AddNode(trd_2, 2);
+  if (ShowLayer[8])  // if geometry contains layer 9 (1st layer of station 3)
+    gGeoMan->GetVolume(geoVersion)->AddNode(trd_3, 3);
+}
diff --git a/reco/detectors/trd/CMakeLists.txt b/reco/detectors/trd/CMakeLists.txt
index f967f9fe37c184486242b7686d28cc242d3fe63c..99b31a43fbdefc4e101eb59c65bdacf66da9e9f8 100644
--- a/reco/detectors/trd/CMakeLists.txt
+++ b/reco/detectors/trd/CMakeLists.txt
@@ -52,6 +52,7 @@ CbmTrdHitProducer.cxx
 CbmTrdModuleRec.cxx 
 CbmTrdModuleRecR.cxx 
 CbmTrdModuleRecT.cxx 
+CbmTrdDigiRec.cxx 
 
 unpack/CbmTrdUnpackConfig.cxx
 unpack/CbmTrdUnpackAlgoBaseR.cxx
diff --git a/reco/detectors/trd/CbmTrdDigiRec.cxx b/reco/detectors/trd/CbmTrdDigiRec.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..87b169484f348bc966bbe665b4d9d81065216d62
--- /dev/null
+++ b/reco/detectors/trd/CbmTrdDigiRec.cxx
@@ -0,0 +1,118 @@
+/* Copyright (C) 2018-2020 Horia Hulubei National Institute of Physics and Nuclear Engineering, Bucharest
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Alexandru Bercuci[committer] */
+
+#include "CbmTrdDigiRec.h"
+
+#include "CbmTrdFASP.h"
+
+ClassImp(CbmTrdDigiRec)
+
+  //_____________________________________________________________________________
+  CbmTrdDigiRec::CbmTrdDigiRec()
+  : CbmTrdDigi()
+  , fStatus(0)
+{
+  fG[0] = 1.;
+  fG[1] = 1.;
+  memset(fT, 0, 3 * sizeof(Double_t));
+}
+
+//_____________________________________________________________________________
+CbmTrdDigiRec::CbmTrdDigiRec(const CbmTrdDigi& d, Double_t* G, Double_t* T) : CbmTrdDigi(d), fStatus(0)
+{
+  if (G) {
+    fG[0] = G[0];
+    fG[1] = G[1];
+  }
+  else {
+    fG[0] = 1.;
+    fG[1] = 1.;
+  }
+  if (T) memcpy(fT, T, 3 * sizeof(Double_t));
+  else
+    memset(fT, 0, 3 * sizeof(Double_t));
+
+  Int_t dt;
+  Double_t t, r = CbmTrdDigi::GetCharge(t, dt);
+  if (t > 4094) SETBIT(fStatus, 0);
+  if (r > 4094) SETBIT(fStatus, 1);
+}
+
+//_____________________________________________________________________________
+CbmTrdDigiRec::CbmTrdDigiRec(const CbmTrdDigi& d, const CbmTrdDigi& dr, Double_t* G, Double_t* T)
+  : CbmTrdDigi(d)
+  , fStatus(0)
+{
+  /** Constructor and RAW digi merger
+*/
+  if (G) {
+    fG[0] = G[0];
+    fG[1] = G[1];
+  }
+  else {
+    fG[0] = 1.;
+    fG[1] = 1.;
+  }
+  if (T) memcpy(fT, T, 3 * sizeof(Double_t));
+  else
+    memset(fT, 0, 3 * sizeof(Double_t));
+
+  Int_t dt;
+  Double_t t, r = dr.GetCharge(t, dt);
+  if (r > 4094) SETBIT(fStatus, 1);
+  CbmTrdDigi::GetCharge(t, dt);
+  if (t > 4094) SETBIT(fStatus, 0);
+  dt = dr.GetTimeDAQ() - GetTimeDAQ();
+  SetCharge(t, r, dt);
+  Int_t rtrg(dr.GetTriggerType() & 2), ttrg(GetTriggerType() & 1);
+  SetTriggerType(rtrg | ttrg);  //merge the triggers
+}
+
+//_____________________________________________________________________________
+Double_t CbmTrdDigiRec::GetCharge(Int_t typ, Bool_t& on) const
+{
+  Int_t dT;
+  Double_t T, R = CbmTrdDigi::GetCharge(T, dT);
+  on = kTRUE;
+  if (typ) {  // rectangular pairing
+    if (R > 0) {
+      R -= CbmTrdFASP::GetBaselineCorr();
+      return fG[1] * R;
+    }
+    else
+      on = kFALSE;
+  }
+  else {  // tilt pairing
+    if (T > 0) {
+      T -= CbmTrdFASP::GetBaselineCorr();
+      return fG[0] * T;
+    }
+    else
+      on = kFALSE;
+  }
+  return 0.;
+}
+
+//_____________________________________________________________________________
+Double_t CbmTrdDigiRec::GetTime(Int_t typ) const
+{
+  Int_t dT;
+  Double_t T, R = CbmTrdDigi::GetCharge(T, dT);
+  if (typ) {  // rectangular pairing
+    Double_t R0 = R - fT[2];
+    return GetTimeDAQ() + dT + fT[0] * R0 * R0 + fT[1] * R0;
+  }
+  else {  // tilt pairing
+    Double_t T0 = T - fT[2];
+    return GetTimeDAQ() + fT[0] * T0 * T0 + fT[1] * T0;
+  }
+}
+
+//_____________________________________________________________________________
+void CbmTrdDigiRec::Init(Double_t g[2], Double_t t[3])
+{
+  fG[0] = g[0];
+  fG[1] = g[1];
+  memcpy(fT, t, 3 * sizeof(Double_t));
+}
diff --git a/reco/detectors/trd/CbmTrdDigiRec.h b/reco/detectors/trd/CbmTrdDigiRec.h
new file mode 100644
index 0000000000000000000000000000000000000000..65420d4d80de5002c4e21f31ffe55f369f6afa05
--- /dev/null
+++ b/reco/detectors/trd/CbmTrdDigiRec.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2018-2020 Horia Hulubei National Institute of Physics and Nuclear Engineering, Bucharest
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Alexandru Bercuci[committer] */
+
+#ifndef CBMTRDDIGIREC_H
+#define CBMTRDDIGIREC_H
+
+#include "CbmTrdDigi.h"
+
+/** @class CbmTrdDigiRec
+ ** @brief Extend the TRD(2D) digi class to incorporate FEE calibration. 
+ ** @author Alexandru Bercucic <abercuci@niham.nipne.ro>
+ ** @since 01.10.2021
+ ** @date 01.10.2021
+ **
+ ** The digi class contains the information as it is produced by the FEE (ASIC/GETS)
+ ** The variation from channel to channel is captured by running the pulser on anode wires
+ ** using various signal values, frequencies, etc. The calibrated baselines, gains, jitter, 
+ ** etc. are transported via the parameter files and are applied to the data within the digRec
+ ** class which is in the end used to calculate the TRD hit parameters.
+ **/
+class CbmTrdDigiRec : public CbmTrdDigi {
+  friend class CbmTrdModuleRecT;
+
+public:
+  /** \brief Default constructor*/
+  CbmTrdDigiRec();
+  /** \brief Wrap CbmTrdDigi constructor*/
+  CbmTrdDigiRec(const CbmTrdDigi& d, Double_t* g = NULL, Double_t* t = NULL);
+  virtual ~CbmTrdDigiRec() { ; }
+
+  /** \brief Return calibrated tilt signal
+   * \param[out] on flag signal exists */
+  Double_t GetTiltCharge(Bool_t& on) const { return GetCharge(0, on); }
+  /** \brief Return calibrated tilt time [ns]*/
+  Double_t GetTiltTime() const { return GetTime(0); }
+  /** \brief Return calibrated rect signal
+   * \param[out] on flag signal exists */
+  Double_t GetRectCharge(Bool_t& on) const { return GetCharge(1, on); }
+  /** \brief Return calibrated rect time [ns]*/
+  Double_t GetRectTime() const { return GetTime(1); }
+  /** \brief Return calibrated signal
+   * \param[in] typ tilt [0], rect [1] 
+   * \param[out] on flag signal exists
+   */
+  Double_t GetCharge(Int_t typ, Bool_t& on) const;
+  /** \brief Return calibrated time
+   * \param[in] typ tilt [0], rect [1] 
+  */
+  Double_t GetTime(Int_t typ) const;
+  Bool_t HasRectOvf() const { return TESTBIT(fStatus, 1); }
+  Bool_t HasTiltOvf() const { return TESTBIT(fStatus, 0); }
+  /** \brief Init FEE gain and time walk corrections */
+  void Init(Double_t g[2], Double_t t[3]);
+
+protected:
+  /** \brief Constructor and merger*/
+  CbmTrdDigiRec(const CbmTrdDigi& dt, const CbmTrdDigi& dr, Double_t* g = NULL, Double_t* t = NULL);
+
+private:
+  UChar_t fStatus;             //< bit map to store calibration flags
+  Double_t fG[2];              //< FEE gain correction for channel T & R
+  Double_t fT[3];              //< FEE time walk  correction as function of charge
+  ClassDef(CbmTrdDigiRec, 1);  // Wrapper around the RAW TRD digi (CbmTrdDigi) to acount for calibration
+};
+
+#endif
diff --git a/reco/detectors/trd/CbmTrdHitProducer.cxx b/reco/detectors/trd/CbmTrdHitProducer.cxx
index 904d9d3177c536b07e97205791ed2b20b4938654..16e554833bd6e256a671294bb0adbb31c01a2e58 100644
--- a/reco/detectors/trd/CbmTrdHitProducer.cxx
+++ b/reco/detectors/trd/CbmTrdHitProducer.cxx
@@ -80,11 +80,19 @@ void CbmTrdHitProducer::addModuleHits(CbmTrdModuleRec* mod, Int_t* hitCounter, C
 //____________________________________________________________________________________
 CbmTrdModuleRec* CbmTrdHitProducer::AddModule(Int_t address, TGeoPhysicalNode* node)
 {
-  TString s(node->GetName());
-  Int_t typ = TString(s[s.Index("module") + 6]).Atoi();
+  CbmTrdGeoHandler geoHandler;
+  Int_t moduleAddress = geoHandler.GetModuleAddress(node->GetName()),
+        moduleType = geoHandler.GetModuleType(node->GetName()), lyId = CbmTrdAddress::GetLayerId(address);
+  if (moduleAddress != address) {
+    LOG(error) << "CbmTrdHitProducer::AddModule: Module ID " << address << " does not match geometry definition "
+               << moduleAddress << ". Module init failed!";
+    return NULL;
+  }
+  LOG(debug) << GetName() << "::AddModule(" << node->GetName() << " " << (moduleType < 9 ? 'R' : 'T') << "] mod["
+             << moduleAddress << "] ly[" << lyId << "] det[" << moduleAddress << "]";
 
   CbmTrdModuleRec* module(NULL);
-  if (typ == 9) { module = fModules[address] = new CbmTrdModuleRecT(address); }
+  if (moduleType >= 9) { module = fModules[address] = new CbmTrdModuleRecT(address); }
   else {
     module = fModules[address] = new CbmTrdModuleRecR(address);
   }
@@ -125,7 +133,7 @@ CbmTrdModuleRec* CbmTrdHitProducer::AddModule(Int_t address, TGeoPhysicalNode* n
     module->SetChmbPar(pChmb);
 
   // try to load Gain parameters for module
-  if (typ == 9) {
+  if (moduleType >= 9) {
     const CbmTrdParModGain* pGain(NULL);
     if (!fGainPar || !(pGain = (const CbmTrdParModGain*) fGainPar->GetModulePar(address))) {
       //LOG(warn) << GetName() << "::AddModule : No Gain params for modAddress "<< address <<". Using default.";
@@ -187,6 +195,7 @@ void CbmTrdHitProducer::processCluster(const Int_t clusterIdx)
   auto mod  = imod->second;
 
   std::vector<const CbmTrdDigi*> digivec = {};
+
   // get digis for current cluster
   for (Int_t iDigi = 0; iDigi < cluster->GetNofDigis(); iDigi++) {
     const CbmTrdDigi* digi = CbmDigiManager::Instance()->Get<CbmTrdDigi>(cluster->GetDigi(iDigi));
@@ -194,7 +203,6 @@ void CbmTrdHitProducer::processCluster(const Int_t clusterIdx)
     if (digi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kSPADIC && digi->GetCharge() <= 0) continue;
     digivec.emplace_back(digi);
   }
-
   mod->MakeHit(clusterIdx, cluster, &digivec);
 
   fNrClusters++;
@@ -207,7 +215,8 @@ Int_t CbmTrdHitProducer::addHits(CbmEvent* event)
   for (std::map<Int_t, CbmTrdModuleRec*>::iterator imod = fModules.begin(); imod != fModules.end(); imod++) {
     auto mod = imod->second;
 
-    mod->Finalize();
+    mod->PreProcessHits();
+    mod->PostProcessHits();
 
     addModuleHits(mod, &hitCounter, event);
   }
diff --git a/reco/detectors/trd/CbmTrdModuleRec.h b/reco/detectors/trd/CbmTrdModuleRec.h
index 6cac03d54c26f14153446f6c022638b5de64d556..93dbc1c2e81432041fedd476e3ebab1c513907cb 100644
--- a/reco/detectors/trd/CbmTrdModuleRec.h
+++ b/reco/detectors/trd/CbmTrdModuleRec.h
@@ -38,10 +38,10 @@ public:
    * \brief Clear local storage
    **/
   virtual void Clear(Option_t* opt = "");
-  /**
-   * \brief Reconstruct physics observables on hits
-   **/
-  virtual Bool_t Finalize() { return kTRUE; }
+  /** \brief Hit quality assesment */
+  virtual Bool_t PreProcessHits() { return kTRUE; }
+  /** \brief Hit quality assesment */
+  virtual Bool_t PostProcessHits() { return kTRUE; }
   /**
    * \brief Steering routine for finding digits clusters
    **/
diff --git a/reco/detectors/trd/CbmTrdModuleRecT.cxx b/reco/detectors/trd/CbmTrdModuleRecT.cxx
index f320f8a8afdc10387cc94dab9706ad6947bfee4a..fbeea5ce7a27ac4ebcbdecc5fbaa4ea6e5bca15e 100644
--- a/reco/detectors/trd/CbmTrdModuleRecT.cxx
+++ b/reco/detectors/trd/CbmTrdModuleRecT.cxx
@@ -4,13 +4,15 @@
 
 #include "CbmTrdModuleRecT.h"
 
+#include "CbmDigiManager.h"
 #include "CbmTrdCluster.h"
 #include "CbmTrdDigi.h"
+#include "CbmTrdDigiRec.h"
 #include "CbmTrdFASP.h"
 #include "CbmTrdHit.h"
 #include "CbmTrdParModDigi.h"
 
-#include <Logger.h>
+#include <FairLogger.h>
 
 #include <TClonesArray.h>
 #include <TF1.h>
@@ -34,6 +36,12 @@ CbmTrdModuleRecT::CbmTrdModuleRecT()
   , fConfigMap(0)
   , fT0(0)
   , fBuffer()
+  , fDigis()
+  , vt0(0)
+  , vcM(0)
+  , vrM(0)
+  , viM(0)
+  , vyM(0)
   , vs()
   , vse()
   , vt()
@@ -48,13 +56,19 @@ CbmTrdModuleRecT::CbmTrdModuleRecT(Int_t mod, Int_t ly, Int_t rot)
   , fConfigMap(0)
   , fT0(0)
   , fBuffer()
+  , fDigis()
+  , vt0(0)
+  , vcM(0)
+  , vrM(0)
+  , viM(0)
+  , vyM(0)
   , vs()
   , vse()
   , vt()
   , vx()
   , vxe()
 {
-  //printf("AddModuleT @ %d\n", mod); Config(1,0);
+  // printf("AddModuleT @ %d\n", mod); Config(1,0);
   SetNameTitle(Form("TrdRecT%d", mod), "Reconstructor for triangular read-out.");
 }
 
@@ -64,7 +78,7 @@ CbmTrdModuleRecT::~CbmTrdModuleRecT() {}
 //_______________________________________________________________________________
 Bool_t CbmTrdModuleRecT::AddDigi(const CbmTrdDigi* d, Int_t id)
 {
-  /* Add digi to cluster fragments. At first clusters are ordered on pad rows and time. 
+  /** Add digi to cluster fragments. At first clusters are ordered on pad rows and time. 
  * No channel ordering is assumed. The time condition for a digi to enter a cluster 
  * chunk is to have abs(dt)<5 wrt cluster t0 
  */
@@ -197,32 +211,562 @@ Int_t CbmTrdModuleRecT::FindClusters()
 Bool_t CbmTrdModuleRecT::MakeHits() { return kTRUE; }
 
 //_______________________________________________________________________________
-Bool_t CbmTrdModuleRecT::Finalize()
+Bool_t CbmTrdModuleRecT::PreProcessHits()
 {
-  /*  Steering routine for classifying hits and apply further analysis
+  /** Steering routine for classifying hits and apply further analysis
  * -> hit deconvolution (see Deconvolute)
+ */
+
+  Int_t nhits = fHits->GetEntriesFast();
+  if (CWRITE()) LOG(info) << "\n" << GetName() << "::PreProcessHits(" << nhits << ")";
+
+  CbmTrdHit* hit(NULL);
+  for (Int_t ih(0); ih < nhits; ih++) {
+    hit = (CbmTrdHit*) ((*fHits)[ih]);
+    if (!CheckConvolution(hit)) continue;
+    nhits += Deconvolute(hit);
+  }
+  nhits = fHits->GetEntriesFast();
+  if (CWRITE()) LOG(info) << "\n" << GetName() << "::Deconvolute(" << nhits << ")";
+  return kTRUE;
+}
+
+//_______________________________________________________________________________
+Bool_t CbmTrdModuleRecT::CheckConvolution(CbmTrdHit* /*h*/) const { return kFALSE; }
+
+//_______________________________________________________________________________
+Bool_t CbmTrdModuleRecT::Deconvolute(CbmTrdHit* /*h*/) { return kFALSE; }
+
+//_______________________________________________________________________________
+Bool_t CbmTrdModuleRecT::PostProcessHits()
+{
+  /**  Steering routine for classifying hits and apply further analysis
  * -> hit merging for row-cross (see RowCross)
  */
 
-  //   Int_t nhits=fHits->GetEntriesFast();
-  //   //if(CWRITE())
-  //     LOG(info) << "\n"<<GetName()<<"::Finalize("<<nhits<<")";
-  //   CbmTrdHit *hit(NULL), *hitp(NULL);
-  //   for(Int_t ih(0); ih<nhits; ih++){
-  //     hit = (CbmTrdHit*)((*fHits)[ih]);
-  //     for(Int_t jh(ih+1); jh<nhits; jh++){
-  //       hitp = (CbmTrdHit*)((*fHits)[jh]);
-  //       //if(CWRITE())
-  //       cout<<ih<<" "<<hit->ToString();
-  //       cout<<"-> "<<jh<<"  "<<hitp->ToString();
-  //     }
-  //   }
+  CbmTrdHit *h0(NULL), *h1(NULL);
+
+  Int_t a0, nhits = fHits->GetEntriesFast();
+  Float_t Dx(2 * fDigiPar->GetPadSizeX(0)), Dy(2 * fDigiPar->GetPadSizeY(0));
+  for (Int_t ih(0); ih < nhits; ih++) {
+    h0 = (CbmTrdHit*) ((*fHits)[ih]);
+    if (h0->IsUsed()) continue;
+
+    for (Int_t jh(ih + 1); jh < nhits; jh++) {
+      h1 = (CbmTrdHit*) ((*fHits)[jh]);
+      if (h1->IsUsed()) continue;
+
+      // basic check on Row
+      if (TMath::Abs(h1->GetY() - h0->GetY()) > Dy) continue;
+
+      // basic check on Col
+      if (TMath::Abs(h1->GetX() - h0->GetX()) > Dx) continue;
+
+      // basic check on Time
+      if (TMath::Abs(h1->GetTime() - h0->GetTime()) > 4000) continue;  // TODO check with preoper time calibration
+
+      // go to topologic checks
+      if (!(a0 = CheckMerge(h0->GetRefId(), h1->GetRefId()))) continue;
+
+      ProjectDigis(a0 < 0 ? h0->GetRefId() : h1->GetRefId(), a0 < 0 ? h1->GetRefId() : h0->GetRefId());
+
+      // call the working algorithm
+      if (MergeHits(h0, a0)) h0->SetRowCross(h1);
+      if (CWRITE()) {
+        cout << ih << " : " << h0->ToString();
+        cout << jh << " : " << h1->ToString();
+        cout << "\n" << endl;
+      }
+    }
+  }
+  nhits = 0;
+  for (Int_t ih(0); ih < fHits->GetEntriesFast(); ih++) {
+    h0 = (CbmTrdHit*) ((*fHits)[ih]);
+    if (!h0->IsUsed()) continue;
+    fHits->RemoveAt(ih);  //delete h0;
+    nhits++;
+  }
+  fHits->Compress();
+
+  // clear all calibrated digis
+  for (map<Int_t, vector<CbmTrdDigiRec*>>::iterator ic = fDigis.begin(); ic != fDigis.end(); ic++) {
+    for (vector<CbmTrdDigiRec*>::iterator id = ic->second.begin(); id != ic->second.end(); id++)
+      delete *id;
+    ic->second.clear();
+  }
+  fDigis.clear();
+
+  if (CWRITE()) LOG(info) << "\n" << GetName() << "::MergeHits(" << nhits << ")";
+  return kTRUE;
+}
+
+
+//_______________________________________________________________________________
+Int_t CbmTrdModuleRecT::CheckMerge(Int_t cid, Int_t cjd)
+{
+  /** Check topologic conditions if the 2 clusters (in digi representation) can be merged.
+ * The first pair is always from the bottom row
+ * return the anode candidate wrt boundary 1, 2, 3 for the first 3 anodes of the upper row; -1, -2, -3 for the bottom row (r0) or 0 if the check fails  
+ */
+
+  Bool_t on(kFALSE);
+  Int_t /*row, */ col, rowMax(0), vc[2] = {-1, -1}, vm[2] = {0}, vcid[2] = {cid, cjd};
+  Double_t t(0.), r(0.), rtMax(0.), T(0.), m, d, mdMax(0.), M[2] = {-1., -1.}, S[2] = {0.};
+  vector<CbmTrdDigiRec*>::iterator id, jd, jp[2];
+  for (Int_t rowId(0); rowId < 2; rowId++) {
+    rtMax = 0.;
+    mdMax = 0.;
+    for (id = fDigis[vcid[rowId]].begin(); id != fDigis[vcid[rowId]].end(); id++) {
+      GetPadRowCol((*id)->GetAddressChannel(), col);
+      //cout<<(*id)->ToString();
+
+      // mark max position and type
+      t = (*id)->GetTiltCharge(on);
+      if (on && t > rtMax) {
+        vc[rowId] = col;
+        vm[rowId] = 0;
+        rtMax     = t;
+      }
+      r = (*id)->GetRectCharge(on);
+      if (on && r > rtMax) {
+        vc[rowId] = col;
+        vm[rowId] = 1;
+        rtMax     = r;
+      }
+
+      m = 0.;
+      d = 0.;
+      if (!rowId) {  // compute TR pairs on the bottom row
+        m = 0.5 * (t + r);
+        d = r - t;
+      }
+      else {  // compute RT pairs on the upper row
+        jd = id + 1;
+        T  = 0.;
+        if (jd != fDigis[vcid[rowId]].end()) T = (*jd)->GetTiltCharge(on);
+
+        m = 0.5 * (r + T);
+        d = r - T;
+      }
+      if (TMath::Abs(m) > 0.) d = 1.e2 * d / m;
+      if (m > mdMax) {
+        mdMax     = m;
+        M[rowId]  = m;
+        S[rowId]  = d;
+        jp[rowId] = id;
+        rowMax    = rowId;
+      }
+    }
+  }
+  rowMax = M[0] > M[1] ? 0 : 1;
+
+  // basic check on col of the max signal
+  Int_t dc = vc[1] - vc[0];
+  if (dc < 0 || dc > 1) return 0;
+
+  // special care for both tilt maxima :  the TT case
+  // recalculate values on the min row on neighbor column
+  if (!vm[0] && !vm[1]) {
+    if (rowMax == 0) {  // modify r=1
+      r = T = 0.;
+      if (M[1] >= 0) {
+        if (jp[1] != fDigis[cjd].end()) jp[1]++;
+        if (jp[1] != fDigis[cjd].end()) {
+          r = (*jp[1])->GetRectCharge(on);
+          jp[1]++;
+          if (jp[1] != fDigis[cjd].end()) T = (*jp[1])->GetTiltCharge(on);
+        }
+      }
+      M[1] = 0.5 * (r + T);
+      S[1] = r - T;
+    }
+    else {  // modify r=0
+      r = t = 0.;
+      if (M[0] >= 0) {
+        if (jp[0] != fDigis[cid].begin()) jp[0]--;
+        if (jp[0] != fDigis[cid].begin()) {
+          r = (*jp[0])->GetRectCharge(on);
+          t = (*jp[0])->GetTiltCharge(on);
+        }
+      }
+      M[0] = 0.5 * (t + r);
+      S[0] = r - t;
+    }
+  }
+  rowMax = M[0] > M[1] ? 0 : 1;
+
+  // Build the ratio of the charge
+  Float_t mM = M[rowMax ? 0 : 1] / M[rowMax];
+
+  //   Float_t mM_c[] = {0.03, 0.243, 0.975},  //  center of distribution for each anode hypo
+  //           mM_s[] = {0., 1.7e-3, 8.8e-3},  //  slope of distribution for each anode hypo
+  //           mM_r[] = {0.03,  0.03,  0.01};  //  range of distribution for each anode hypo in proper coordinates
+  //   for(Int_t ia(0); ia<3; ia++)
+  //     if(TMath::Abs(mM_s[ia] * S[rowMax] + mM_c[ia] - mM) < mM_r[ia] ) return (rowMax?1:-1) * (3-ia);
+
+  Float_t mS = TMath::Abs(S[rowMax]), mM_l[3] = {0.15, 0.5, 1}, mM_r[3] = {0, 0.28, 1}, mS_r[3] = {43, 27, 20}, dSdM[2],
+          S0[2];
+  for (Int_t i(0); i < 2; i++) {
+    dSdM[i] = (mS_r[i + 1] - mS_r[i]) / (mM_r[i + 1] - mM_r[i]);
+    S0[i]   = mS_r[i] - dSdM[i] * mM_r[i];
+  }
+  Int_t irange = mM < mM_r[1] ? 0 : 1;
+  if (mS > S0[irange] + dSdM[irange] * mM) return 0;
+
+  for (Int_t ia(0); ia < 3; ia++) {
+    if (mM < mM_l[ia]) return (rowMax ? 1 : -1) * (3 - ia);
+  }
+  return 0;
+}
+
+
+//_______________________________________________________________________________
+Bool_t CbmTrdModuleRecT::MergeHits(CbmTrdHit* h, Int_t a0)
+{
+  Int_t n0(vs.size() - 2);
+  Double_t dx(0.), dy(0.);
+
+  switch (n0) {
+    case 1:
+      if (IsMaxTilt()) {  // T
+        dx = -0.5;
+        dy = 0;
+      }
+      else {  // R
+        dx = 0.5;
+        dy = 0;
+      }
+      break;
+    case 2:
+      if (IsOpenLeft() && IsOpenRight()) {  // RT
+        dx = viM == 1 ? 0. : -1;
+        dy = -0.5;
+      }
+      else {  // TR
+        dx = 0.;
+        dy = 0.5;
+      }
+      break;
+    case 3:
+      if (IsMaxTilt() && !IsSymmHit()) {  // TRT asymm
+        dx = viM == 1 ? 0. : -1;
+        dy = GetYoffset();
+      }
+      else if (!IsMaxTilt() && IsSymmHit()) {  // TRT symm
+        dx = 0.;
+        dy = GetYoffset();
+      }
+      else if (IsMaxTilt() && IsSymmHit()) {  // RTR symm
+        dx = GetXoffset();
+        dy = 0.;
+      }
+      else if (!IsMaxTilt() && !IsSymmHit()) {  // RTR asymm
+        dx = GetXoffset();
+        dy = viM == 1 ? -0.5 : 0.5;
+      }
+      break;
+    default:
+      dx = GetXoffset();
+      dy = GetYoffset();
+      break;
+  }
+
+  RecenterXoffset(dx);
+  Int_t typ(GetHitClass());
+  // get position correction [pw]
+  Double_t xcorr = GetXcorr(dx, typ, 1) / fDigiPar->GetPadSizeX(0), xcorrBias(xcorr);
+  if (IsBiasX()) {
+    typ        = GetHitRcClass(a0);
+    Int_t xmap = vyM & 0xff;
+    switch (n0) {
+      case 4:
+        if (dx < 0) xcorrBias += (IsBiasXleft() ? -0.12 : 0.176);
+        else
+          xcorrBias += (xmap == 53 || xmap == 80 || xmap == 113 || xmap == 117 ? -0.176 : 0.12);
+        break;
+      case 5:
+      case 7:
+        if (typ < 0) break;
+        if (xmap == 50 || xmap == 58 || xmap == 146 || xmap == 154) {
+          if (typ == 2) xcorr += 0.0813;
+          else if (typ == 3) {
+            xcorr -= 0.0813;
+            typ = 2;
+          }
+          dx -= xcorr;
+          RecenterXoffset(dx);
+          xcorrBias = GetXcorr(dx, typ, 2) / fDigiPar->GetPadSizeX(0);
+        }
+        else {
+          dx -= xcorr;
+          RecenterXoffset(dx);
+          if (typ < 2) xcorrBias = GetXcorr(dx, typ, 2) / fDigiPar->GetPadSizeX(0);
+          else if (typ == 2)
+            xcorrBias = 0.12;
+          else if (typ == 3)
+            xcorrBias = -0.12;
+        }
+        break;
+      default:
+        if (typ < 0) break;
+        else if (typ == 2)
+          xcorr += 0.0813;
+        else if (typ == 3) {
+          xcorr -= 0.0813;
+          typ = 2;
+        }
+        dx -= xcorr;
+        RecenterXoffset(dx);
+        xcorrBias = GetXcorr(dx, typ, 2) / fDigiPar->GetPadSizeX(0);
+        break;
+    }
+  }
+  else {
+    if (typ) xcorrBias += (dx < 0 ? 1 : -1) * 0.0293;
+  }
+  dx -= xcorrBias;
+  RecenterXoffset(dx);
+  dy = dx - dy;
+  RecenterYoffset(dy);
+  if (dy < -0.5 || dy > 0.5) printf("!!! dy = %f r[%d]\n", dy, vrM);
+
+  Double_t ycorr = GetYcorr(dy) / fDigiPar->GetPadSizeY(0);
+  dy += ycorr;
+  RecenterYoffset(dy);
+  dx *= fDigiPar->GetPadSizeX(0);
+  dy *= fDigiPar->GetPadSizeY(0);
+
+  TVector3 local_pad, local_pad_err;
+  Int_t srow, sector = fDigiPar->GetSectorRow(vrM, srow);
+  fDigiPar->GetPadPosition(sector, vcM, srow, local_pad, local_pad_err);
+
+  Double_t edx(1), edy(1), edt(60), time(-21), tdrift(100), e(200);
+  Double_t local[3] = {local_pad[0] + dx, local_pad[1] + dy, local_pad[2]}, global[3];
+  // globalErr[3] = {0/*edx*/, 0/*edy*/, 0.};
+  LocalToMaster(local, global);
+  h->SetX(global[0]);
+  h->SetY(global[1]);
+  h->SetZ(global[2]);
+  h->SetDx(edx);
+  h->SetDy(edy);
+  h->SetDz(0.);
+  h->SetDxy(0.);
+  h->SetTime(CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP) * (vt0 + time) - tdrift + 30.29, edt);
+  h->SetELoss(e);
+  // hit->SetClassType();
+  // hit->SetMaxType(tM);
+  // if(ovf) hit->SetOverFlow();
+
+  if (CWRITE()) {
+    printf("-> loc[%6.2f %6.2f %6.2f] err[%6.2f %6.2f %6.2f]\n", local_pad[0], local_pad[1], local_pad[2],
+           local_pad_err[0], local_pad_err[1], local_pad_err[2]);
+    printf("REC col[%2d] row[%2d] dx[%7.3f(pw) %7.3f(cm)] x[%7.2f] y[%7.2f] dy[%5.2f] t0[%llu]\n", vcM, vrM,
+           dx / fDigiPar->GetPadSizeX(0), dx, global[0], global[1], dy, vt0);
+  }
+
+  return kTRUE;
+}
+
+//_______________________________________________________________________________
+Bool_t CbmTrdModuleRecT::BuildHit(CbmTrdHit* h)
+{
+  Int_t n0(vs.size() - 2);
+  Double_t dx(0.), dy(0.);  //, da(0.);
+
+  switch (n0) {
+    case 1:
+      if (IsMaxTilt()) {  // T
+        dx = -0.5;
+        dy = 0;
+      }
+      else {  // R
+        dx = 0.5;
+        dy = 0;
+      }
+      break;
+    case 2:
+      if (IsOpenLeft() && IsOpenRight()) {  // RT
+        dx = viM == 1 ? 0. : -1;
+        dy = -0.5;
+      }
+      else {  // TR
+        dx = 0.;
+        dy = 0.5;
+      }
+      break;
+    case 3:
+      if (IsMaxTilt() && !IsSymmHit()) {  // TRT asymm
+        dx = viM == 1 ? 0. : -1;
+        dy = GetYoffset();
+      }
+      else if (!IsMaxTilt() && IsSymmHit()) {  // TRT symm
+        dx = 0.;
+        dy = GetYoffset();
+      }
+      else if (IsMaxTilt() && IsSymmHit()) {  // RTR symm
+        dx = GetXoffset();
+        dy = 0.;
+      }
+      else if (!IsMaxTilt() && !IsSymmHit()) {  // RTR asymm
+        dx = GetXoffset();
+        dy = viM == 1 ? -0.5 : 0.5;
+      }
+      break;
+    default:
+      dx = GetXoffset();
+      dy = GetYoffset();
+      break;
+  }
+  RecenterXoffset(dx);
+
+  // get position correction
+  Double_t xcorr = GetXcorr(dx, GetHitClass()) / fDigiPar->GetPadSizeX(0);
+  dx -= xcorr;
+  RecenterXoffset(dx);
+  dy = dx - dy;
+  RecenterYoffset(dy);
+  if (dy < -0.5 || dy > 0.5) printf("!!! dy = %f r[%d]\n", dy, vrM);
+
+  Double_t ycorr = GetYcorr(dy) / fDigiPar->GetPadSizeY(0);
+  dy += ycorr;
+  RecenterYoffset(dy);
+  dx *= fDigiPar->GetPadSizeX(0);
+  dy *= fDigiPar->GetPadSizeY(0);
+
+  // get anode wire offset
+  Int_t ia(0);
+  Float_t ya(0.);  //  anode position in local pad coordinates
+  for (; ia <= NANODE; ia++) {
+    ya = -1.35 + ia * 0.3;
+    if (dy > ya + 0.15) continue;
+    break;
+  }
+  //  da = dy-ya;
+  //   //correct inside apmlification region
+  //   da*=-0.7;
+  //   if(da<-0.015) da+=0.1;
+  //   else if(da>0.015) da-=0.1;
+  //   dy+=da;
+  //   da = dy - ya;
+
+  // Error parametrization X : parabolic model on cl size
+  Double_t parX[] = {0.713724, -0.318667, 0.0366036};
+  Double_t parY[] = {0.0886413, 0., 0.0435141};
+  Int_t nex       = TMath::Min(n0, 7);
+  Double_t edx = parX[0] + parX[1] * nex + parX[2] * nex * nex, edy = parY[0] + parY[2] * dy * dy,
+           edt = 26.33;  // should be parametrized as function of da TODO
+  // use this trick to force larger roads on CbmLitTrackFinderBranch
+  // target code from CbmLitTrackFinderBranch::FollowTracks and CbmLitHitData::AddHit
+  // bool hitInside = (pixelHit->GetX() < (tpar.GetX() + devX)) && (pixelHit->GetX() > (tpar.GetX() - devX))
+  if (n0 < 3) {
+    edx = 1.;
+    edy = 1.;
+    edt = 60.;
+  }
+
+  TVector3 local_pad, local_pad_err;
+  Int_t srow, sector = fDigiPar->GetSectorRow(vrM, srow);
+  fDigiPar->GetPadPosition(sector, vcM, srow, local_pad, local_pad_err);
+
+  Double_t local[3] = {local_pad[0] + dx, local_pad[1] + dy, local_pad[2]}, global[3];
+  //globalErr[3] = {edx, edy, 0.};
+  LocalToMaster(local, global);
+
+  // COMPUTE TIME
+  for (Int_t idx(1); idx <= n0; idx++) {
+    Double_t dtFEE =
+      fgDT[0] * (vs[idx] - fgDT[1]) * (vs[idx] - fgDT[1]) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP);
+    if (vxe[idx] > 0) vx[idx] += dy / fDigiPar->GetPadSizeY(0);
+    fgT->SetPoint(idx - 1, vx[idx], vt[idx] - dtFEE);
+  }
+  Double_t xc = vx[n0 + 2];
+  for (Int_t ip(n0); ip < fgT->GetN(); ip++) {
+    fgT->SetPoint(ip, xc, 0);
+    xc += 0.5;
+  }
+  Double_t time(-21.), tdrift(100);  // should depend on Ua
+  if (n0 > 1 && (fgT->Fit("pol1", "QC", "goff") == 0)) {
+    TF1* f = fgT->GetFunction("pol1");
+    time   = f->GetParameter(0) - fgDT[2];
+    if (TMath::IsNaN(time)) time = -21;
+    //dtime += TMath::Abs(f->GetParameter(1)*(vx[n0+1] - vx[1]));
+  }
+
+  // COMPUTE ENERGY
+  for (UInt_t idx(0); idx < vs.size(); idx++) {
+    if (vxe[idx] > 0) {
+      fgEdep->SetPoint(idx, vx[idx] + dy / fDigiPar->GetPadSizeY(0), vs[idx]);
+      fgEdep->SetPointError(idx, vxe[idx], vse[idx]);
+    }
+    else {
+      fgEdep->SetPoint(idx, vx[idx], vs[idx]);
+      fgEdep->SetPointError(idx, vxe[idx], vse[idx]);
+    }
+  }
+  xc = vx[n0 + 2];
+  for (Int_t ip(vs.size()); ip < fgEdep->GetN(); ip++) {
+    //fgEdep->RemovePoint(ip);
+    xc += 0.5;
+    fgEdep->SetPoint(ip, xc, 0);
+    fgEdep->SetPointError(ip, 0., 300);
+  }
+  //if(CWRITE()) fgEdep->Print();
+
+  Double_t e(0.), xlo(*vx.begin()), xhi(*vx.rbegin());
+  fgPRF->SetParameter(0, vs[viM]);
+  fgPRF->FixParameter(1, dx / fDigiPar->GetPadSizeX(0));
+  fgPRF->SetParameter(2, 0.65);
+  fgPRF->SetParLimits(2, 0.45, 10.5);
+  fgEdep->Fit(fgPRF, "QBN", "goff", xlo - 0.5, xhi + 0.5);
+  if (!fgPRF->GetNDF()) return NULL;
+  //chi = fgPRF->GetChisquare()/fgPRF->GetNDF();
+  e = fgPRF->Integral(xlo - 0.5, xhi + 0.5);
+
+  // apply MC correction
+  Float_t gain0 = 210.21387;  //(XeCO2 @ 1900V)
+  //   Float_t grel[3] = {1., 0.98547803, 0.93164071},
+  //           goff[3][3] = {
+  //             {0.05714, -0.09, -0.09},
+  //             {0., -0.14742, -0.14742},
+  //             {0., -0.29, -0.393}
+  //           };
+  //   Int_t ian=0;
+  //   if(TMath::Abs(dy)<=0.3) ian=0;
+  //   else if(TMath::Abs(dy)<=0.6) ian=1;
+  //   else if(TMath::Abs(dy)<=0.9) ian=2;
+  //   Int_t isize=0;
+  //   if(n0<=3) isize=0;
+  //   else if(n0<=4) isize=1;
+  //   else isize=2;
+  Float_t gain = gain0;  //*grel[ian];
+  e /= gain;             // apply effective gain
+  //e+=goff[ian][isize];  // apply missing energy offset
+
+  h->SetX(global[0]);
+  h->SetY(global[1]);
+  h->SetZ(global[2]);
+  h->SetDx(edx);
+  h->SetDy(edy);
+  h->SetDz(0);
+  h->SetDxy(0.);
+  h->SetTime(CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP) * (vt0 + time) - tdrift + 30.29, edt);
+  h->SetELoss(e);
+  // hit->SetClassType();
+  // hit->SetMaxType(tM);
+  // if(ovf) hit->SetOverFlow();
+
+  if (CWRITE()) {
+    printf("-> loc[%6.2f %6.2f %6.2f] err[%6.2f %6.2f %6.2f]\n", local_pad[0], local_pad[1], local_pad[2],
+           local_pad_err[0], local_pad_err[1], local_pad_err[2]);
+    printf("REC col[%2d] row[%2d] x[%7.2f] dx[%5.2f] y[%7.2f] dy[%5.2f] t0[%llu]\n", vcM, vrM, global[0], dx, global[1],
+           dy, vt0);
+  }
+
   return kTRUE;
 }
 
 #include <TCanvas.h>
 #include <TH1.h>
-#define NANODE 9
 //_______________________________________________________________________________
 CbmTrdHit* CbmTrdModuleRecT::MakeHit(Int_t ic, const CbmTrdCluster* cl, std::vector<const CbmTrdDigi*>* digis)
 {
@@ -257,191 +801,155 @@ CbmTrdHit* CbmTrdModuleRecT::MakeHit(Int_t ic, const CbmTrdCluster* cl, std::vec
   }
 
   if (CWRITE()) cout << cl->ToString();
+  if (!LoadDigis(digis, ic)) return NULL;
+  if (!ProjectDigis(ic)) return NULL;
+  Int_t nofHits  = fHits->GetEntriesFast();
+  CbmTrdHit* hit = new ((*fHits)[nofHits]) CbmTrdHit();
+  hit->SetAddress(fModAddress);
+  hit->SetRefId(ic);
+  //hit->SetMatch();
+  BuildHit(hit);
+  if (CWRITE()) cout << hit->ToString();
+  if (CDRAW()) DrawHit(hit);
+  return hit;
+}
 
-  // check cluster integrity and do digi merging if needed
-  vector<Bool_t> vmask(digis->size(), 0);  // masks in case of merged Digis
-  vector<CbmTrdDigi*> vdgM;
-  if (cl->GetNCols() != digis->size() && !MergeDigis(digis, &vdgM, &vmask)) {
-    cout << cl->ToString();
-    for (vector<const CbmTrdDigi*>::iterator i = digis->begin(); i != digis->end(); i++)
-      cout << (*i)->ToString();
-    return NULL;
-  }
-
-  // Read in all digis information()
-  ULong64_t t0 = fT0 + cl->GetStartTime();  // absolute hit time (prompt signal)
-  Int_t n0(0), ovf(0), cM;
-  if (!(n0 = LoadDigis(digis, &vdgM, &vmask, t0, cM))) {
-    cout << cl->ToString();
-    for (vector<const CbmTrdDigi*>::iterator i = digis->begin(); i != digis->end(); i++)
-      cout << (*i)->ToString();
-    return NULL;
-  }
-  if (n0 < 0) {
-    ovf = 1;
-    n0 *= -1;
-  }
-
-  // analyse digis topology; no of signal types, maximum, etc
-  Bool_t tM(kTRUE);  // maximum type tilt=1; rect=0
-  Int_t nL(0);       // signal index for the max signal
-  Int_t col, row = GetPadRowCol(cl->GetStartCh(), col);
-  Double_t max(0.),  // maximum signal
-    LS(0.),          // left side sum of signals
-    S(0.);           // sum of signals
-  Int_t nr(0), nt(0);
-  for (Int_t is(1); is <= n0; is++) {
-    if (vxe[is] > 0) {  // select tilted coupling
-      nt++;
-      S += vs[is];
-      if (vs[is] > max) {
-        max = vs[is];
-        tM  = kTRUE;
-        nL  = is;
-        LS += vs[is];
-      }
-    }
-    else {  // select rectangular coupling
-      nr++;
-      S += vs[is];
-      if (vs[is] > max) {
-        max = vs[is];
-        tM  = kFALSE;
-        nL  = is;
-        LS += vs[is];
-      }
-    }
-  }
-  col += cM;
-  S -= LS;
-  LS -= max;
-  // evaluate asymmetry
-  Int_t lr(0),        // max signal left-right asymmetry wrt central pad
-    tr(0),            // left-right innequality for symmetric clusters
-    nR(n0 + 1 - nL);  // no of signals to the right of maximum
-  if (nL < nR) lr = 1;
-  else if (nL > nR)
-    lr = -1;
-  if (!lr && (n0 % 2)) tr = (LS < S ? -1 : 1);
-  // compute x and y offset from center pad
-  Double_t dx(0.), dy(0.), edx(0.21650635),
-    edy(0.77942286);  // fixed error parametrization
-  switch (n0) {
-    case 1:
-      if (nt) {
-        dx = -0.5;
-        dy = 0;
-      }  // T
-      else {
-        dx = 0.5;
-        dy = 0;
-      }  // R
-      break;
-    case 2:
-      if (cl->HasOpenStart() && cl->HasOpenStop()) {
-        dx = cM ? -1. : 0.;
-        dy = -0.5;
-      }  // RT
-      else {
-        dx = 0.;
-        dy = 0.5;
-      }  // TR
-      break;
-    case 3:
-      if (tM && lr) {
-        dx = cM ? -1. : 0.;
-        dy = GetYoffset(n0);
-      }  // TRT asymm
-      else if (!tM && !lr) {
-        dx = 0.;
-        dy = GetYoffset(n0);
-      }  // TRT symm
-      else if (tM && !lr) {
-        dx = GetXoffset(n0);
-        dy = 0.;
-      }  // RTR symm
-      else if (!tM && lr) {
-        dx = GetXoffset(n0);
-        dy = cM ? 0.5 : -0.5;
-      }  // RTR asymm
-      break;
-    default:
-      dx = GetXoffset(n0);
-      dy = GetYoffset(n0);
-      break;
+//_______________________________________________________________________________
+Int_t CbmTrdModuleRecT::GetHitClass() const
+{
+  /** Incapsulate hit classification criteria based on signal topology
+ * [0] : center hit type
+ * [1]  : side hit type
+ */
+
+  Int_t n0(vs.size() - 2);
+  if ((n0 == 5 && ((IsMaxTilt() && IsSymmHit()) || (!IsMaxTilt() && !IsSymmHit()))) ||  // TRTRT symm/asymm
+      n0 == 4 || (n0 == 3 && ((IsMaxTilt() && IsSymmHit()) || (!IsMaxTilt() && !IsSymmHit()))))
+    return 1;  // RTR symm/asymm
+  else if (n0 > 5 && HasOvf())
+    return 2;
+  return 0;
+}
+
+//_______________________________________________________________________________
+Int_t CbmTrdModuleRecT::GetHitRcClass(Int_t a0) const
+{
+  Int_t a0m    = TMath::Abs(a0);
+  UChar_t xmap = vyM & 0xff;
+  if (a0m == 2 && IsBiasXleft() && IsBiasXright() && !IsBiasXmid()) return 0;
+  else if (a0m == 3 && ((IsBiasXleft() && IsBiasXright()) || xmap == 116 || xmap == 149 || xmap == 208))
+    return 1;
+  else if (!IsBiasXleft()
+           && (a0m == 2
+               || (a0m == 3 && ((!IsBiasXright() && IsBiasXmid()) || xmap == 209 || xmap == 212 || xmap == 145))))
+    return 2;
+  else if (!IsBiasXright()
+           && (a0m == 2 || (a0m == 3 && ((!IsBiasXleft() && IsBiasXmid()) || xmap == 112 || xmap == 117))))
+    return 3;
+  else
+    return -1;
+}
+
+//_______________________________________________________________________________
+Double_t CbmTrdModuleRecT::GetXoffset(Int_t n0) const
+{
+  Double_t dx(0.), R(0.);
+  Int_t n(n0 ? n0 : vs.size());
+  for (Int_t ir(0); ir < n; ir++) {
+    if (vxe[ir] > 0) continue;  // select rectangular coupling
+    R += vs[ir];
+    dx += vs[ir] * vx[ir];
   }
-  if (dx < -0.5 && cM > 0) {  // shift graph representation to fit dx[pw] in [-0.5, 0.5]
-    dx += 1.;
-    col -= 1;
-    for (UInt_t idx(0); idx < vx.size(); idx++)
-      vx[idx] += 1;
-  }
-  if (dx > 0.5) {  // dirty fix for compound clusters TODO
-    Int_t ishift = Int_t(dx - 0.5) + 1;
-    dx -= ishift;
-    col += ishift;
-    for (UInt_t idx(0); idx < vx.size(); idx++)
-      vx[idx] -= ishift;
-  }
-  dy = dx - dy;  // only on natural scalling !
-  // go to cm scale
-  dx *= fDigiPar->GetPadSizeX(0);
-  dy *= fDigiPar->GetPadSizeY(0);
+  if (TMath::Abs(R) > 0) return dx / R;
+  LOG(warn) << GetName() << "::GetXoffset : Unexpected null sum.";
+  return 0.;
+}
 
-  // apply systematic correction for x (MC derived)
-  Int_t typ = 0;                                    // [0] center hit type
-                                                    // [1] side hit type
-  if ((n0 == 5 && ((tM && !lr) || (!tM && lr))) ||  // TRTRT symm/asymm
-      n0 == 4 || (n0 == 3 && ((tM && !lr) || (!tM && lr != 0))))
-    typ = 1;  // RTR symm/asymm
-  Double_t xcorr(0.);
-  Int_t nbins((NBINSCORRX - 1) >> 1), ii = nbins + TMath::Nint(dx / fgCorrXdx), i0, i1;
-  if (ii < 0 || ii >= NBINSCORRX)
-    LOG(warn) << GetName() << "::MakeHit : Idx " << ii << " outside range for displacement " << dx << ".";
-  else {
-    if (dx < fgCorrXdx * ii) {
-      i0 = TMath::Max(0, ii - 1);
-      i1 = ii;
-    }
-    else {
-      i0 = ii;
-      i1 = TMath::Min(NBINSCORRX - 1, ii + 1);
+//_______________________________________________________________________________
+Double_t CbmTrdModuleRecT::GetYoffset(Int_t n0) const
+{
+  Double_t dy(0.), T(0.);
+  Int_t n(n0 ? n0 : vs.size());
+  for (Int_t it(0); it < n; it++) {
+    if (vxe[it] > 0) {  // select tilted coupling
+      T += vs[it];
+      dy += vs[it] * vx[it];
     }
-    Double_t DDx = (fgCorrXval[typ][i1] - fgCorrXval[typ][i0]), a = DDx / fgCorrXdx,
-             b = fgCorrXval[typ][i0] - DDx * (i0 - nbins);
-    xcorr      = 0.1 * (b + a * dx);
   }
-  dx += xcorr;
-  dy += xcorr;
-  if (dx > 0.5 * fDigiPar->GetPadSizeX(0)) dx = 0.5 * fDigiPar->GetPadSizeX(0);
-  else if (dx < -0.5 * fDigiPar->GetPadSizeX(0))
-    dx = -0.5 * fDigiPar->GetPadSizeX(0);
+  if (TMath::Abs(T) > 0) return dy / T;
+  LOG(warn) << GetName() << "::GetYoffset : Unexpected null sum.";
+  return 0.;
+}
+
+//_______________________________________________________________________________
+Double_t CbmTrdModuleRecT::GetXcorr(Double_t dxIn, Int_t typ, Int_t cls) const
+{
+  /** Give the linear interpolation of SYS correction for current position offset "dx" based 
+ * on LUT calculated wrt MC EbyE data. The position offset is expresed in [pw] units 
+ * while the output is in [cm]
+ */
+
+  if (typ < 0 || typ > 2) {
+    //LOG(error)<< GetName() << "::GetXcorr : type in-param "<<typ<<" out of range.";
+    return 0;
+  }
+  Double_t dx = TMath::Abs(dxIn);
+  Int_t ii    = TMath::Max(0, TMath::Nint(dx / fgCorrXdx) - 1), i0;  //  i1;
 
-  if (dy > 0.5 * fDigiPar->GetPadSizeY(0)) {  //
-    //printf("BEFORE dy[%+6.4f] dx[%+6.4f] {n[%d] max[%c] lr[%+d]}\n", dy, dx, n0, tM?'T':'R', lr);
-    dy -= fDigiPar->GetPadSizeY(0);
+  if (ii < 0 || ii > NBINSCORRX) {
+    LOG(warn) << GetName() << "::GetXcorr : LUT idx " << ii << " out of range for dx=" << dxIn;
+    return 0;
   }
-  if (dy < -0.5 * fDigiPar->GetPadSizeY(0)) {  //
-    //printf("(BEFORE) dy[%+6.4f] dx[%+6.4f] {n[%d] max[%c] lr[%+d]}\n", dy, dx, n0, tM?'T':'R', lr);
-    dy += fDigiPar->GetPadSizeY(0);
+  if (dx < fgCorrXdx * ii) {
+    i0 = TMath::Max(0, ii - 1);
+    /*i1=ii;*/
+  }
+  else {
+    i0 = ii;
+    /*i1=TMath::Min(NBINSCORRX-1,ii+1);*/
   }
 
-  // process y offset
-  // apply systematic correction for y (MC derived)
+  Float_t* xval = &fgCorrXval[typ][i0];
+  if (cls == 1) xval = &fgCorrRcXval[typ][i0];
+  else if (cls == 2)
+    xval = &fgCorrRcXbiasXval[typ][i0];
+  Double_t DDx = (xval[1] - xval[0]), a = DDx / fgCorrXdx, b = xval[0] - DDx * (i0 + 0.5);
+  return (dxIn > 0 ? 1 : -1) * b + a * dxIn;
+}
+
+//_______________________________________________________________________________
+Double_t CbmTrdModuleRecT::GetYcorr(Double_t dy, Int_t /* cls*/) const
+{
+  /** Process y offset. Apply systematic correction for y (MC derived).
+ * The position offset is expresed in [pw] units while the output is in [cm]
+ */
   Float_t fdy(1.), yoff(0.);
+  Int_t n0(vs.size() - 2);
   switch (n0) {
     case 3:
       fdy  = fgCorrYval[0][0];
       yoff = fgCorrYval[0][1];
-      if (tM && !lr) dy -= tr * 0.5 * fDigiPar->GetPadSizeY(0);
-      else if (lr)
-        dy -= 0.5 * fDigiPar->GetPadSizeY(0);
-      ;
+      if (IsMaxTilt() && IsSymmHit()) {
+        fdy  = 0.;
+        yoff = (dy > 0 ? -1 : 1) * 1.56;
+      }
+      else if (!IsMaxTilt() && !IsSymmHit()) {
+        fdy  = 0.;
+        yoff = (dy > 0 ? -1 : 1) * 1.06;
+      }
+      else if (!IsMaxTilt() && IsSymmHit()) {
+        fdy  = 2.114532;
+        yoff = -0.263;
+      }
+      else /*if(IsMaxTilt()&&!IsSymmHit())*/ {
+        fdy  = 2.8016010;
+        yoff = -1.38391;
+      }
       break;
     case 4:
       fdy  = fgCorrYval[1][0];
       yoff = fgCorrYval[1][1];
-      if ((!tM && lr == 1) || (tM && lr == -1)) yoff *= -1;
+      if ((!IsMaxTilt() && IsLeftHit()) || (IsMaxTilt() && !IsLeftHit())) yoff *= -1;
       break;
     case 5:
     case 7:
@@ -455,195 +963,361 @@ CbmTrdHit* CbmTrdModuleRecT::MakeHit(Int_t ic, const CbmTrdCluster* cl, std::vec
     case 10:
       fdy  = fgCorrYval[3][0];
       yoff = fgCorrYval[3][1];
-      if ((!tM && lr == 1) || (tM && lr == -1)) yoff *= -1;
+      if ((!IsMaxTilt() && IsLeftHit()) || (IsMaxTilt() && !IsLeftHit())) yoff *= -1;
       break;
   }
-  dy *= fdy;
-  dy += yoff;
-  if (dy > 0.5 * fDigiPar->GetPadSizeY(0)) dy = 0.5 * fDigiPar->GetPadSizeY(0);
-  else if (dy < -0.5 * fDigiPar->GetPadSizeY(0))
-    dy = -0.5 * fDigiPar->GetPadSizeY(0);
+  return dy * fdy + yoff;
+}
 
-  // get anode wire offset
-  Int_t ia(0);
-  Float_t ya;  //  anode position in local pad coordinates
-  for (; ia <= NANODE; ia++) {
-    ya = -1.35 + ia * 0.3;
-    if (dy > ya + 0.15) continue;
-    break;
+//_______________________________________________________________________________
+void CbmTrdModuleRecT::RecenterXoffset(Double_t& dx)
+{
+  /** Shift graph representation to fit dx[pw] in [-0.5, 0.5]
+   */
+
+  if (dx >= -0.5 && dx < 0.5) return;
+  Int_t ishift = Int_t(dx - 0.5) + (dx > 0.5 ? 1 : 0);
+  if (vcM + ishift < 0) ishift = -vcM;
+  else if (vcM + ishift >= GetNcols())
+    ishift = GetNcols() - vcM - 1;
+  LOG(debug) << GetName() << "::RecenterXoffset : shift dx offset by " << ishift << " from dx=" << dx << " to "
+             << dx - ishift << " center col from " << (Int_t) vcM << " to " << Int_t(vcM + ishift);
+  dx -= ishift;
+  vcM += ishift;
+  for (UInt_t idx(0); idx < vx.size(); idx++)
+    vx[idx] -= ishift;
+}
+
+
+//_______________________________________________________________________________
+void CbmTrdModuleRecT::RecenterYoffset(Double_t& dy)
+{
+  /** Shift graph representation to fit dy[ph] in [-0.5, 0.5]
+   */
+
+  if (dy >= -0.5 && dy < 0.5) return;
+  Int_t ishift = Int_t(dy - 0.5) + (dy > 0.5 ? 1 : 0);
+  //   if(vrM+ishift < 0) ishift = - vrM;
+  //   else if(vrM+ishift >= GetNrows()) ishift = GetNrows() - vrM -1;
+  LOG(debug) << GetName() << "::RecenterYoffset : shift dy offset by " << ishift << " from dy=" << dy << " to "
+             << dy - ishift;
+  dy -= ishift;
+  //vrM+= ishift;
+  //   if(vrM==0 && dy<-0.5) dy=-0.5;
+  //   if(vrM==GetNrows() -1 && dy>0.5) dy=0.5;
+}
+
+//_______________________________________________________________________________
+Int_t CbmTrdModuleRecT::LoadDigis(vector<const CbmTrdDigi*>* din, Int_t cid)
+{
+  /** Load RAW digis info in calibration aware strucuture CbmTrdDigiReco
+ * Do basic sanity checks; also incomplete adjacent digi and if found merge them.
+ */
+  Int_t col(-1), /*row, */ colT(-1), colR(-1);
+  const CbmTrdDigi *dgT(NULL), *dgR(NULL);
+  for (vector<const CbmTrdDigi*>::iterator i = din->begin(), j = i + 1; i != din->end(); i++) {
+    dgT = (*i);
+    //row =
+    GetPadRowCol(dgT->GetAddressChannel(), colT);
+    // check column order for cluster
+    if (col >= 0 && colT != col + 1) {
+      LOG(error) << GetName() << "::LoadDigis : digis in cluster " << cid << " not in increasing order !";
+      return 0;
+    }
+    col  = colT;
+    colR = -1;
+    dgR  = NULL;
+    if (j != din->end()) {
+      dgR = (*j);
+      //row =
+      GetPadRowCol(dgR->GetAddressChannel(), colR);
+    }
+    if (colR == colT) {
+      fDigis[cid].push_back(new CbmTrdDigiRec(*dgT, *dgR));
+      j = din->erase(j);
+    }
+    else
+      fDigis[cid].push_back(new CbmTrdDigiRec(*dgT));
+
+    if (j != din->end()) j++;
   }
+  return fDigis[cid].size();
+}
 
-  // Error parametrization X : parabolic model on cl size
-  Double_t parX[] = {0.713724, -0.318667, 0.0366036};
-  Int_t nex       = TMath::Min(n0, 7);
-  edx             = parX[0] + parX[1] * nex + parX[2] * nex * nex;
-  Double_t parY[] = {0.0886413, 0., 0.0435141};
-  edy             = parY[0] + parY[2] * dy * dy;
+//_______________________________________________________________________________
+Int_t CbmTrdModuleRecT::ProjectDigis(Int_t cid, Int_t cjd)
+{
+  /** Load digis information in working vectors Digis are represented in the normal coordinate system of
+   * (pad width [pw], DAQ time [clk], signal [ADC chs]) with rectangular signals at integer 
+   * positions.  
+   */
+
+  if (fDigis.find(cid) == fDigis.end()) {
+    LOG(warn) << GetName() << "::ProjectDigis : Request cl id " << cid << " not found.";
+    return 0;
+  }
 
-  if (CWRITE()) {
-    printf("row[%2d] col[%2d] sz[%d%c] M[%d%c] dx[mm]=%6.3f dy[mm]=%6.3f "
-           "t0[clk]=%llu OVF[%c]\n",
-           row, col, n0, (lr ? (lr < 0 ? 'L' : 'R') : 'C'), cM, (tM ? 'T' : 'R'), 10 * dx, 10 * dy, t0,
-           (ovf ? 'y' : 'n'));
-    for (UInt_t idx(0); idx < vs.size(); idx++) {
-      printf("%2d%cdt[%2d] s[ADC]=%6.1f+-%6.1f x[pw]=%5.2f+-%5.2f\n", idx, (UInt_t(nL) == idx ? '*' : ' '), vt[idx],
-             vs[idx], vse[idx], vx[idx], vxe[idx]);
+  vs.clear();
+  vse.clear();
+  vx.clear();
+  vxe.clear();
+  vt.clear();
+  vt0 = 0;
+  vrM = 0;
+  vcM = 0;
+  vyM = 0;
+  viM = 0;
+
+  Bool_t on(0);         // flag signal transmition
+  Int_t n0(0), nsr(0),  // no of signals in the cluster (all/rect)
+    NR(0), nr(0),       // no of rect signals/channel in case of RC
+    NT(0), nt(0),       // no of tilt signals/channel in case of RC
+    ovf(1);             // over-flow flag for at least one of the digis
+  //dt;
+  Char_t ddt,            // signal time offset wrt prompt
+    dt0(0);              // cluster time offset wrt arbitrary t0
+  Double_t r, re(100.),  // rect signal
+    t, te(100.),         // tilt signal
+    err,                 // final error parametrization for signal
+    xc(-0.5),            // running signal-pad position
+    max(0.);             // max signal
+  Int_t j(0), col(-1), col0(0), col1(0), step(0), row1;
+
+  // link second row if needed
+  vector<CbmTrdDigiRec*>::iterator i1;
+  if (cjd >= 0) {
+    if (fDigis.find(cjd) == fDigis.end()) {
+      LOG(warn) << GetName() << "::ProjectDigis : Request cl id " << cjd << " not found. Skip second row.";
+      cjd = -1;
     }
+    else
+      i1 = fDigis[cjd].begin();
   }
 
-  // compute energy
-  for (UInt_t idx(0); idx < vs.size(); idx++) {
-    if (vxe[idx] > 0) {
-      fgEdep->SetPoint(idx, vx[idx] + dy / fDigiPar->GetPadSizeY(0), vs[idx]);
-      fgEdep->SetPointError(idx, vxe[idx], vse[idx]);
+  const CbmTrdDigiRec *dg(NULL), *dg0(NULL), *dg1(NULL);
+  for (vector<CbmTrdDigiRec*>::iterator i = fDigis[cid].begin(); i != fDigis[cid].end(); i++, j++) {
+    dg  = (*i);
+    dg0 = NULL;
+    dg1 = NULL;
+    if (CWRITE()) cout << "dg0 :" << dg->ToString();
+
+    //  initialize
+    if (col < 0) {
+      vrM = GetPadRowCol(dg->GetAddressChannel(), col);
+      vt0 = dg->GetTimeDAQ();  // set arbitrary t0 to avoid double digis loop
     }
-    else {
-      fgEdep->SetPoint(idx, vx[idx], vs[idx]);
-      fgEdep->SetPointError(idx, vxe[idx], vse[idx]);
+    GetPadRowCol(dg->GetAddressChannel(), col0);
+    nr = nt = 0;
+
+    // read calibrated signals
+    t = dg->GetTiltCharge(on);
+    if (on) nt = 1;
+    r = dg->GetRectCharge(on);
+    if (on) nr = 1;
+    // look for matching neighbor digis in case of pad row cross
+    if (cjd >= 0) {
+      if ((dg0 = (i1 != fDigis[cjd].end()) ? (*i1) : NULL)) {
+        row1 = GetPadRowCol(dg0->GetAddressChannel(), col1);
+        if (!step) step = vrM - row1;
+        if (col1 == col0) {
+          r += dg0->GetRectCharge(on);
+          if (on) nr++;
+        }
+        else
+          dg0 = NULL;
+      }
+      if (step == 1 && i1 != fDigis[cjd].begin()) {
+        dg1 = (*(i1 - 1));
+        GetPadRowCol(dg1->GetAddressChannel(), col1);
+        if (col1 == col0 - 1) {
+          t += dg1->GetTiltCharge(on);
+          if (on) nt++;
+        }
+        else
+          dg1 = NULL;
+      }
+      if (step == -1 && i1 != fDigis[cjd].end() && i1 + 1 != fDigis[cjd].end()) {
+        dg1 = (*(i1 + 1));
+        GetPadRowCol(dg1->GetAddressChannel(), col1);
+        if (col1 == col0 + 1) {
+          t += dg1->GetTiltCharge(on);
+          if (on) nt++;
+        }
+        else
+          dg1 = NULL;
+      }
+      if (dg0) i1++;
+    }
+    if (CWRITE()) {
+      if (dg0) cout << "dgR :" << dg0->ToString();
+      if (dg1) cout << "dgT :" << dg1->ToString();
+      cout << "-------------------------------------" << endl;
     }
-  }
-  Double_t xc = vx[n0 + 2];
-  for (Int_t ip(vs.size()); ip < fgEdep->GetN(); ip++) {
-    //fgEdep->RemovePoint(ip);
-    xc += 0.5;
-    fgEdep->SetPoint(ip, xc, 0);
-    fgEdep->SetPointError(ip, 0., 300);
-  }
-  if (CWRITE()) fgEdep->Print();
-
-  Double_t e(0.), chi(100), xlo(*vx.begin()), xhi(*vx.rbegin());
-  fgPRF->SetParameter(0, max);
-  fgPRF->FixParameter(1, dx / fDigiPar->GetPadSizeX(0));
-  fgPRF->SetParameter(2, 0.65);
-  fgPRF->SetParLimits(2, 0.45, 10.5);
-  fgEdep->Fit(fgPRF, "QBN", "goff", xlo - 0.5, xhi + 0.5);
-  if (!fgPRF->GetNDF()) return NULL;
-  chi = fgPRF->GetChisquare() / fgPRF->GetNDF();
-  e   = fgPRF->Integral(xlo - 0.5, xhi + 0.5);
-
-  // apply MC correction
-  Float_t gain0 = 210.21387;  //(XeCO2 @ 1900V)
-  //   Float_t grel[3] = {1., 0.98547803, 0.93164071},
-  //           goff[3][3] = {
-  //             {0.05714, -0.09, -0.09},
-  //             {0., -0.14742, -0.14742},
-  //             {0., -0.29, -0.393}
-  //           };
-  //   Int_t ian=0;
-  //   if(TMath::Abs(dy)<=0.3) ian=0;
-  //   else if(TMath::Abs(dy)<=0.6) ian=1;
-  //   else if(TMath::Abs(dy)<=0.9) ian=2;
-  //   Int_t isize=0;
-  //   if(n0<=3) isize=0;
-  //   else if(n0<=4) isize=1;
-  //   else isize=2;
-  Float_t gain = gain0;  //*grel[ian];
-  e /= gain;             // apply effective gain
-  //e+=goff[ian][isize];  // apply missing energy offset
 
-  TVector3 local_pad, local_pad_err;
-  Int_t srow, sector = fDigiPar->GetSectorRow(row, srow);
-  fDigiPar->GetPadPosition(sector, col, srow, local_pad, local_pad_err);
-  //printf("r[%2d] c[%2d] max[%d] lr[%d] n0[%d] cM[%d] nM[%d] dx[%7.4f] dy[%7.4f] loc[%6.2f %6.2f %6.2f] err[%6.2f %6.2f %6.2f] e[%f] chi[%f]\n", row, col, mtyp, lr, n0, cM, nM, dx, dy, local_pad[0], local_pad[1], local_pad[2], local_pad_err[0], local_pad_err[1], local_pad_err[2], e, chi);
-  Double_t local[3] = {local_pad[0] + dx, local_pad[1] + dy, local_pad[2]}, global[3], globalErr[3] = {edx, edy, 0.};
-  LocalToMaster(local, global);
+    // process tilt signal/time
+    ddt = dg->GetTiltTime() - vt0;
+    if (ddt < dt0) dt0 = ddt;
+    if (abs(t) > 0) {
+      if (nt > 1) t *= 0.5;
+      err = te * (nt > 1 ? 0.707 : 1);
+      if (dg->HasTiltOvf()) {
+        ovf = -1;
+        err = 150.;
+      }
+      if (t > max) {
+        max = t;
+        vcM = j;
+        SetMaxTilt(1);
+        viM = vs.size();
+      }
+    }
+    else
+      err = 300.;
+    vt.push_back(ddt);
+    vs.push_back(t);
+    vse.push_back(err);
+    vx.push_back(xc);
+    vxe.push_back(0.035);
+    xc += 0.5;
 
-  // process time profile
-  for (Int_t idx(1); idx <= n0; idx++) {
-    Double_t dtFEE =
-      fgDT[0] * (vs[idx] - fgDT[1]) * (vs[idx] - fgDT[1]) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP);
-    if (vxe[idx] > 0) vx[idx] += dy / fDigiPar->GetPadSizeY(0);
-    fgT->SetPoint(idx - 1, vx[idx], vt[idx] - dtFEE);
-  }
-  xc = vx[n0 + 2];
-  for (Int_t ip(n0); ip < fgT->GetN(); ip++) {
-    fgT->SetPoint(ip, xc, 0);
+    // process rect signal/time
+    ddt = dg->GetRectTime() - vt0;
+    if (ddt < dt0) dt0 = ddt;
+    if (abs(r) > 0) {
+      nsr++;
+      if (nr > 1) r *= 0.5;
+      err = re * (nr > 1 ? 0.707 : 1);
+      if (dg->HasRectOvf()) {
+        ovf = -1;
+        err = 150.;
+      }
+      if (r > max) {
+        max = r;
+        vcM = j;
+        SetMaxTilt(0);
+        viM = vs.size();
+      }
+    }
+    else
+      err = 300.;
+    vt.push_back(ddt);
+    vs.push_back(r);
+    vse.push_back(err);
+    vx.push_back(xc);
+    vxe.push_back(0.);
     xc += 0.5;
+    NR += nr;
+    NT += nt;
   }
 
-  Double_t time(-21.),
-    edt(26.33),   // should be parametrized as function of da TODO
-    tdrift(100);  // should depend on Ua
-  if (n0 > 1 && (fgT->Fit("pol1", "QC", "goff") == 0)) {
-    TF1* f = fgT->GetFunction("pol1");
-    time   = f->GetParameter(0) - fgDT[2];
-    if (TMath::IsNaN(time)) time = -21;
-    //dtime += TMath::Abs(f->GetParameter(1)*(vx[n0+1] - vx[1]));
+  // add front and back anchor points if needed
+  if (TMath::Abs(vs[0]) > 1.e-3) {
+    xc  = vx[0];
+    ddt = vt[0];
+    vs.insert(vs.begin(), 0);
+    vse.insert(vse.begin(), 300);
+    vt.insert(vt.begin(), ddt);
+    vx.insert(vx.begin(), xc - 0.5);
+    vxe.insert(vxe.begin(), 0);
+    viM++;
   }
-
-  if (CDRAW()) {
-    Double_t rangex(vx[0] - 0.25), rangeX(vx[n0 + 2] + 0.25);
-    cvs->cd(1);
-    hf->Draw("p");
-    hf->GetXaxis()->SetRangeUser(rangex, rangeX);
-    hf->SetTitle(Form("%d[%d] row[%d] col[%2d] an[%+d] m[%+4.2f] s[%4.2f] E[%7.2f] chi2[%7.2f]", ic, Int_t(vs.size()),
-                      row, col, ia, fgPRF->GetParameter(1), fgPRF->GetParameter(2), e, chi));
-    hf->GetXaxis()->SetRangeUser(rangex, rangeX);
-    hf->GetYaxis()->SetRangeUser(-100., 4500);
-    fgEdep->Draw("pl");
-    fgPRF->Draw("same");
-
-    cvs->cd(2);
-    hf = (TH1*) hf->DrawClone("p");
-    hf->GetXaxis()->SetRangeUser(rangex, rangeX);
-    hf->GetYaxis()->SetRangeUser(-10, 20);
-    //hf->SetTitle(Form("%d row[%d] col[%2d] an[%+d] m[%+4.2f] s[%4.2f] E[%7.2f] chi2[%7.2f]", ic, row, col, ia, fgPRF->GetParameter(1), fgPRF->GetParameter(2), fgPRF->Integral(xlo, xhi), fgPRF->GetChisquare()/fgPRF->GetNDF()));
-    //       hf->GetXaxis()->SetRangeUser(xlo-0.25, xhi+0.25);
-    //       //hf->GetYaxis()->SetRangeUser(0., 4500);
-    fgT->Draw("pl");
-    cvs->Modified();
-    cvs->Update();
-    cvs->SaveAs(Form("cl_%02d_A%d.gif", ic, ia));
+  Int_t n(vs.size() - 1);
+  if (TMath::Abs(vs[n]) > 1.e-3) {
+    xc  = vx[n] + 0.5;
+    ddt = vt[n];
+    vs.push_back(0);
+    vse.push_back(300);
+    vt.push_back(ddt);
+    vx.push_back(xc);
+    vxe.push_back(0.035);
   }
 
-  Int_t nofHits  = fHits->GetEntriesFast();
-  CbmTrdHit* hit = new ((*fHits)[nofHits])
-    CbmTrdHit(fModAddress, global, globalErr,
-              0.,  // sxy chi,
-              ic,
-              e,  // energy
-              CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP) * (t0 + time) - tdrift + 30.29, edt);
-  hit->SetClassType();
-  hit->SetMaxType(tM);
-  if (ovf) hit->SetOverFlow();
-  if (CWRITE()) cout << hit->ToString();
-  return hit;
-}
-
-//_______________________________________________________________________________
-Double_t CbmTrdModuleRecT::GetXoffset(Int_t n0) const
-{
-  Double_t dx(0.), R(0.);
-  for (Int_t ir(1); ir <= n0; ir++) {
-    if (vxe[ir] > 0) continue;  // select rectangular coupling
-    R += vs[ir];
-    dx += vs[ir] * vx[ir];
+  n0 = vs.size() - 2;
+  // compute cluster asymmetry
+  Int_t nR = n0 + 1 - viM;
+  if (nR == viM) {
+    SetSymmHit(1);
+    if (vs.size() % 2) {
+      Double_t LS(0.), RS(0.);
+      for (UChar_t idx(0); idx < viM; idx++)
+        LS += vs[idx];
+      for (UInt_t idx(viM + 1); idx < vx.size(); idx++)
+        RS += vs[idx];
+      SetLeftSgn(LS < RS ? 0 : 1);
+    }
   }
-  if (TMath::Abs(R) > 0) return dx / R;
-  LOG(warn) << GetName() << "::GetDx : Unexpected null sum.";
-  return 0.;
-}
+  else {
+    SetSymmHit(0);
+    if (viM < nR) SetLeftHit(0);
+    else if (viM > nR)
+      SetLeftHit(1);
+  }
+  // recenter time and space profile
+  vt0 += dt0;
+  for (UInt_t idx(0); idx < vx.size(); idx++) {
+    vt[idx] -= dt0;
+    vx[idx] -= vcM;
+  }
+  vcM += col;
+
+  // check if all signals have same significance
+  Int_t nmiss = 2 * nsr - NR;  //printf("R : nsr[%d] NR[%d] nmiss[%d]\n", nsr, NR, nmiss);
+  if (cjd >= 0 && nmiss) {
+    SetBiasX(1);
+    for (UChar_t idx(1); idx < viM; idx++) {
+      if (vxe[idx] > 0.) continue;  //  select rect signals
+      if (vse[idx] > re * 0.8) SetBiasXleft(1);
+    }
+    if (vxe[viM] <= 0. && vse[viM] > re * 0.8) SetBiasXmid(1);
+    for (UChar_t idx(viM + 1); idx < vs.size() - 1; idx++) {
+      if (vxe[idx] > 0.) continue;  //  select rect signals
+      if (vse[idx] > re * 0.8) SetBiasXright(1);
+    }
+  }
+  else
+    SetBiasX(0);
+  nmiss = 2 * n0 - 2 * nsr - NT;  //printf("T : n0[%d] nsr[%d] NT[%d] nmiss[%d]\n", n0, nsr, NT, nmiss);
+  if (cjd >= 0 && nmiss) {
+    SetBiasY();
+    for (UChar_t idx(1); idx < viM; idx++) {
+      if (vxe[idx] > 0. && vse[idx] > te * 0.8) SetBiasYleft(1);  //  select tilt signals
+    }
+    if (vxe[viM] > 0. && vse[viM] > te * 0.8) SetBiasYmid(1);
+    for (UChar_t idx(viM + 1); idx < vs.size() - 1; idx++) {
+      if (vxe[idx] > 0. && vse[idx] > te * 0.8) SetBiasYright(1);  //  select tilt signals
+    }
+  }
+  else
+    SetBiasY(0);
 
-//_______________________________________________________________________________
-Double_t CbmTrdModuleRecT::GetYoffset(Int_t n0) const
-{
-  Double_t dy(0.), T(0.);
-  for (Int_t it(1); it <= n0; it++) {
-    if (vxe[it] > 0) {  // select tilted coupling
-      T += vs[it];
-      dy += vs[it] * vx[it];
+  if (CWRITE()) {
+    printf("t0[clk]=%llu col[%2d] row[%2d] sz[%d] OVF[%c] %c", vt0, vcM, vrM, Int_t(vs.size() - 2),
+           (ovf < 0 ? 'y' : 'n'), IsOpenLeft() ? '(' : '[');
+    if (IsSymmHit()) {
+      if (HasLeftSgn()) printf("<|");
+      else
+        printf("|>");
+    }
+    else
+      printf("%s", IsLeftHit() ? "<<" : ">>");
+    printf("%c bias[%c %c]\n", IsOpenRight() ? ')' : ']', IsBiasX() ? (IsBiasXleft() ? '<' : '>') : 'o',
+           IsBiasY() ? (IsBiasYleft() ? '<' : '>') : 'o');
+    for (UInt_t idx(0); idx < vs.size(); idx++) {
+      printf("%2d dt[%2d] s[ADC]=%6.1f+-%6.1f x[pw]=%5.2f+-%5.2f ", idx, vt[idx], vs[idx], vse[idx], vx[idx], vxe[idx]);
+      if (idx == viM) printf("[%s]", (IsMaxTilt() ? "//" : "||"));
+      printf("\n");
     }
   }
-  if (TMath::Abs(T) > 0) return dy / T;
-  LOG(warn) << GetName() << "::GetDy : Unexpected null sum.";
-  return 0.;
+
+  if (ovf < 0) SetOvf();  //printf("SetOvf %d\n", vyM); }
+  return ovf * (vs.size() - 2);
 }
 
 //_______________________________________________________________________________
 Int_t CbmTrdModuleRecT::LoadDigis(vector<const CbmTrdDigi*>* digis, vector<CbmTrdDigi*>* vdgM, vector<Bool_t>* vmask,
                                   ULong64_t& t0, Int_t& cM)
 {
-  /* Load digis information in working vectors. 
+  /** Load digis information in working vectors. 
  * The digis as provided by the digitizer are replaced by the merged one 
  * according to the vmask map. Digis are represented in the normal coordinate system of
  * (pad width [pw], DAQ time [clk], signal [ADC chs]) with rectangular signals at integer 
@@ -772,6 +1446,206 @@ Int_t CbmTrdModuleRecT::LoadDigis(vector<const CbmTrdDigi*>* digis, vector<CbmTr
   return ovf * n0;
 }
 
+
+//_______________________________________________________________________________
+Int_t CbmTrdModuleRecT::LoadDigisRC(vector<const CbmTrdDigi*>* digis, const Int_t r0, const Int_t a0,
+                                    /*vector<CbmTrdDigi*> *vdgM, */ ULong64_t& t0, Int_t& cM)
+{
+  /** Load digis information for row-cross hits in working vectors. 
+  * The digis as provided by the digitizer are replaced by the merged one (TODO) 
+  * according to the vmask map. Digis are represented in the normal coordinate system of
+  * (pad width [pw], DAQ time [clk], signal [ADC chs]) with rectangular signals at integer 
+  * positions.  
+  * TODO 
+  * 1. Time information in the secondary row not used. 
+  * 2. Time walk (dependence on charge) not recovered by calibration. 
+  * 
+  */
+  vs.clear();
+  vse.clear();
+  vx.clear();
+  vxe.clear();
+  vt.clear();
+
+  cM = 0;  // relative position of maximum signal
+  Int_t step,
+    n0(0),   // number of measured signals
+    ovf(1),  // over-flow flag for at least one of the digis
+    dt, dT;
+  Char_t ddt,               // signal time offset wrt prompt
+    dt0(0);                 // cluster time offset wrt arbitrary t0
+  Double_t r, R, re(100.),  // rect signal
+    t, T, te(100.),         // tilt signal
+    err,                    // final error parametrization for signal
+    xc(0.),                 // running signal-pad position
+    max(0.);                // max signal
+  Int_t j(0), row, col, col0(-1), col1(0);
+  //vector<CbmTrdDigi*>::iterator idgM=vdgM->begin();
+
+  vector<const CbmTrdDigi*>::iterator i0, i1, ix0, ix1;
+  i0 = digis->begin();
+  i1 = i0;
+  do {
+    row = GetPadRowCol((*i1)->GetAddressChannel(), col1);
+    if (col0 < 0) col0 = col1;
+    if (row == r0) i1++;
+    else
+      break;
+  } while (i1 != digis->end());
+  ix0  = i1;
+  ix1  = digis->end();
+  col  = col0;
+  step = -1;
+  if (a0 > 0) {
+    i0   = i1;
+    ix0  = digis->end();
+    ix1  = i1;
+    i1   = digis->begin();
+    col  = col0;
+    col0 = col1;
+    col1 = col;
+    col  = col0;
+    step = 1;
+  }
+  if (CWRITE()) printf("col0[%d] col1[%d] step[%2d]\n", col0, col1, step);
+  const CbmTrdDigi *dg0(NULL), *dg1(NULL), *dg10(NULL);
+
+  // always loop on the largest cluster
+  for (; i0 != ix0; i0++, j++) {
+    dg0  = (*i0);
+    dg1  = NULL;
+    dg10 = NULL;
+    if (CWRITE()) cout << "dg0 :" << dg0->ToString();
+
+    r = dg0->GetCharge(t, dt);
+    if (t > 0) t -= CbmTrdFASP::GetBaselineCorr();
+    if (r > 0) r -= CbmTrdFASP::GetBaselineCorr();
+
+    if (t0 == 0) t0 = dg0->GetTimeDAQ();  // set arbitrary t0 to avoid double digis loop
+    ddt = dg0->GetTimeDAQ() - t0;
+    if (ddt < dt0) dt0 = ddt;
+
+    // check column wise organization
+    row = GetPadRowCol(dg0->GetAddressChannel(), col0);
+    if (col + j != col0) {
+      LOG(error) << GetName() << "::LoadDigisRC : digis in cluster not in increasing order " << col0 << " !";
+      return 0;
+    }
+
+    // look for matching neighbor digis
+    if ((dg1 = (i1 != ix1) ? (*i1) : NULL)) {
+      GetPadRowCol(dg1->GetAddressChannel(), col1);
+      if (col1 == col0) {
+        R = dg1->GetCharge(T, dT);
+        if (R > 0.) r += R - CbmTrdFASP::GetBaselineCorr();
+      }
+      else
+        dg1 = NULL;
+    }
+    if (step == 1 && i1 != digis->begin()) {
+      dg10 = (*(i1 - 1));
+      GetPadRowCol(dg10->GetAddressChannel(), col1);
+      if (col1 == col0 - 1) {
+        dg10->GetCharge(T, dT);
+        if (T > 0.) t += T - CbmTrdFASP::GetBaselineCorr();
+      }
+      else
+        dg10 = NULL;
+    }
+    if (step == -1 && i1 != ix1 && i1 + 1 != ix1) {
+      dg10 = (*(i1 + 1));
+      GetPadRowCol(dg10->GetAddressChannel(), col1);
+      if (col1 == col0 + 1) {
+        dg10->GetCharge(T, dT);
+        if (T > 0.) t += T - CbmTrdFASP::GetBaselineCorr();
+      }
+      else
+        dg10 = NULL;
+    }
+    if (dg1) i1++;
+
+    if (CWRITE()) {
+      if (dg1) cout << "dgR :" << dg1->ToString();
+      if (dg10) cout << "dgT :" << dg10->ToString();
+      cout << "-------------------------------------" << endl;
+    }
+
+    // process tilt signal
+    if (t > 0) {
+      err = te;
+      n0++;
+      if (t > max) {
+        max = t;
+        cM  = j;
+      }
+    }
+    else
+      err = 300.;
+    vt.push_back(ddt);
+    vs.push_back(t);
+    vse.push_back(err);
+    vx.push_back(xc);
+    vxe.push_back(0.035);
+
+    // process rect signal
+    ddt += dt;
+    if (ddt < dt0) dt0 = ddt;
+    if (r > 0) {
+      err = re;
+      n0++;
+      if (r > max) {
+        max = r;
+        cM  = j;
+      }
+    }
+    else
+      err = 300.;
+    vt.push_back(ddt);
+    vs.push_back(r);
+    vse.push_back(err);
+    vx.push_back(xc);
+    vxe.push_back(0.);
+    xc += 1;
+  }
+
+  //   // remove merged digis if they were created
+  //   if(idgM != vdgM->end()) LOG(warn) << GetName() << "::LoadDigis : not all merged digis have been consumed !";
+  //   for(idgM=vdgM->begin(); idgM!=vdgM->end(); idgM++) delete (*idgM);
+  //
+  // add front and back anchor points if needed
+  if (TMath::Abs(vs[0]) > 1.e-3) {
+    xc  = vx[0];
+    ddt = vt[0];
+    vs.insert(vs.begin(), 0);
+    vse.insert(vse.begin(), 300);
+    vt.insert(vt.begin(), ddt);
+    vx.insert(vx.begin(), xc - 1);
+    vxe.insert(vxe.begin(), 0);
+  }
+  Int_t n(vs.size() - 1);
+  if (TMath::Abs(vs[n]) > 1.e-3) {
+    xc  = vx[n] + 1;
+    ddt = vt[n];
+    vs.push_back(0);
+    vse.push_back(300);
+    vt.push_back(ddt);
+    vx.push_back(xc);
+    vxe.push_back(0.035);
+  }
+
+  // recenter time and space profile
+  if (cM + col >= fDigiPar->GetNofColumns()) cM = fDigiPar->GetNofColumns() - col - 1;
+  else if (cM + col < 0)
+    cM = -col;
+  t0 += dt0;
+  for (UInt_t idx(0); idx < vx.size(); idx++) {
+    vt[idx] -= dt0;
+    vx[idx] -= cM;
+  }
+  cM += col;
+  return ovf * n0;
+}
+
 //_______________________________________________________________________________
 Bool_t CbmTrdModuleRecT::MergeDigis(vector<const CbmTrdDigi*>* digis, vector<CbmTrdDigi*>* vdgM, vector<Bool_t>* vmask)
 {
@@ -828,33 +1702,47 @@ Bool_t CbmTrdModuleRecT::MergeDigis(vector<const CbmTrdDigi*>* digis, vector<Cbm
   return kTRUE;
 }
 
-Float_t CbmTrdModuleRecT::fgCorrXdx                 = 0.005;
-Float_t CbmTrdModuleRecT::fgCorrXval[2][NBINSCORRX] = {
-  {0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,
-   0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  -0.144, -0.091, -0.134, -0.185, -0.120, -0.115, -0.125,
-   -0.125, -0.124, -0.124, -0.122, -0.120, -0.119, -0.116, -0.114, -0.113, -0.111, -0.109, -0.107, -0.105, -0.102,
-   -0.100, -0.098, -0.097, -0.093, -0.091, -0.089, -0.087, -0.084, -0.082, -0.079, -0.077, -0.074, -0.072, -0.068,
-   -0.065, -0.062, -0.059, -0.056, -0.053, -0.049, -0.046, -0.043, -0.039, -0.036, -0.032, -0.029, -0.025, -0.022,
-   -0.018, -0.015, -0.011, -0.007, -0.003, 0.000,  0.003,  0.007,  0.011,  0.014,  0.018,  0.022,  0.025,  0.029,
-   0.032,  0.036,  0.039,  0.043,  0.046,  0.049,  0.053,  0.056,  0.059,  0.062,  0.065,  0.068,  0.071,  0.074,
-   0.077,  0.080,  0.082,  0.084,  0.087,  0.090,  0.091,  0.094,  0.096,  0.098,  0.100,  0.103,  0.104,  0.107,
-   0.108,  0.110,  0.113,  0.115,  0.116,  0.120,  0.121,  0.121,  0.123,  0.125,  0.124,  0.127,  0.140,  0.119,
-   0.114,  0.028,  0.049,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,
-   0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000},
-  {0.003,  0.013,  0.026,  0.039,  0.052,  0.065,  0.078,  0.091,  0.104,  0.118,  0.132,  0.145,  0.160,  0.174,
-   0.189,  0.203,  0.219,  0.234,  0.250,  0.267,  0.283,  0.301,  0.319,  0.338,  0.357,  0.375,  0.398,  0.419,
-   0.440,  0.464,  0.491,  0.514,  0.541,  0.569,  0.598,  0.623,  0.660,  0.696,  0.728,  0.763,  0.804,  0.847,
-   0.888,  0.930,  0.988,  1.015,  1.076,  1.128,  1.167,  1.228,  1.297,  1.374,  1.443,  1.511,  1.564,  0.000,
-   0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,
-   0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,
-   0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  0.000,  -1.992, -1.884, -1.765, -1.703, -1.609, -1.572, -1.493,
-   -1.426, -1.356, -1.309, -1.243, -1.202, -1.109, -1.069, -1.026, -0.970, -0.933, -0.881, -0.844, -0.803, -0.767,
-   -0.721, -0.691, -0.659, -0.629, -0.596, -0.569, -0.541, -0.514, -0.490, -0.466, -0.441, -0.419, -0.397, -0.377,
-   -0.357, -0.337, -0.319, -0.301, -0.283, -0.267, -0.250, -0.234, -0.218, -0.203, -0.189, -0.174, -0.160, -0.145,
-   -0.131, -0.119, -0.104, -0.091, -0.078, -0.064, -0.052, -0.039, -0.026, -0.013, -0.002}};
-Float_t CbmTrdModuleRecT::fgCorrYval[NBINSCORRY][2] = {{2.421729, 0.},
-                                                       {1.537359, 0.483472},
-                                                       {1.1752, 0.},
-                                                       {1.154183, -0.090229}};
+
+Float_t CbmTrdModuleRecT::fgCorrXdx                 = 0.01;
+Float_t CbmTrdModuleRecT::fgCorrXval[3][NBINSCORRX] = {
+  {-0.001, -0.001, -0.002, -0.002, -0.003, -0.003, -0.003, -0.004, -0.004, -0.006, -0.006, -0.006, -0.007,
+   -0.007, -0.008, -0.008, -0.008, -0.009, -0.009, -0.011, -0.011, -0.011, -0.012, -0.012, -0.012, -0.012,
+   -0.013, -0.013, -0.013, -0.013, -0.014, -0.014, -0.014, -0.014, -0.014, -0.016, -0.016, -0.016, -0.016,
+   -0.017, -0.017, -0.017, -0.018, -0.018, -0.018, -0.018, -0.018, 0.000,  0.000,  0.000},
+  {0.467, 0.430, 0.396, 0.364, 0.335, 0.312, 0.291, 0.256, 0.234, 0.219, 0.207, 0.191, 0.172,
+   0.154, 0.147, 0.134, 0.123, 0.119, 0.109, 0.122, 0.113, 0.104, 0.093, 0.087, 0.079, 0.073,
+   0.067, 0.063, 0.058, 0.053, 0.049, 0.046, 0.042, 0.038, 0.036, 0.032, 0.029, 0.027, 0.024,
+   0.022, 0.019, 0.017, 0.014, 0.013, 0.011, 0.009, 0.007, 0.004, 0.003, 0.001},
+  {0.001,  0.001,  0.001,  0.001,  0.002,  0.002,  0.001,  0.002,  0.004,  0.003,  0.002,  0.002,  0.002,
+   0.002,  0.002,  0.002,  0.003,  0.004,  0.003,  0.004,  0.004,  0.007,  0.003,  0.004,  0.002,  0.002,
+   -0.011, -0.011, -0.012, -0.012, -0.012, -0.013, -0.013, -0.013, -0.014, -0.014, -0.014, -0.016, -0.016,
+   -0.016, -0.017, -0.017, -0.017, -0.018, -0.018, -0.018, -0.019, 0.029,  0.018,  0.001}};
+Float_t CbmTrdModuleRecT::fgCorrYval[NBINSCORRY][2]   = {{2.421729, 0.},
+                                                       {0.629389, -0.215285},
+                                                       {0.23958, 0.},
+                                                       {0.151913, 0.054404}};
+Float_t CbmTrdModuleRecT::fgCorrRcXval[2][NBINSCORRX] = {
+  {-0.00050, -0.00050, -0.00150, -0.00250, -0.00250, -0.00350, -0.00450, -0.00450, -0.00550, -0.00650,
+   -0.00650, -0.00750, -0.00850, -0.00850, -0.00850, -0.00950, -0.00950, -0.00950, -0.01050, -0.01150,
+   -0.01150, -0.01150, -0.01250, -0.01250, -0.01250, -0.01250, -0.01350, -0.01350, -0.01350, -0.01350,
+   -0.01450, -0.01450, -0.01450, -0.01550, -0.01550, -0.01550, -0.01550, -0.01650, -0.01650, -0.01550,
+   -0.01650, -0.01614, -0.01620, -0.01624, -0.01626, -0.01627, -0.01626, -0.01624, -0.01620, -0.01615},
+  {0.36412, 0.34567, 0.32815, 0.31152, 0.29574, 0.28075, 0.26652, 0.25302, 0.24020, 0.22803, 0.21647, 0.21400, 0.19400,
+   0.18520, 0.17582, 0.16600, 0.14600, 0.13800, 0.14280, 0.14200, 0.13400, 0.12600, 0.12200, 0.11000, 0.10200, 0.09400,
+   0.09000, 0.08600, 0.08200, 0.07400, 0.07000, 0.06600, 0.06600, 0.06200, 0.05800, 0.05400, 0.05400, 0.05000, 0.04600,
+   0.04600, 0.04200, 0.03800, 0.03800, 0.03400, 0.03400, 0.03000, 0.03000, 0.02600, 0.02200, 0.02200}};
+Float_t CbmTrdModuleRecT::fgCorrRcXbiasXval[3][NBINSCORRX] = {
+  {0.00100, 0.00260, 0.00540, 0.00740, 0.00900, 0.01060, 0.01300, 0.01460, 0.01660, 0.01900, 0.02060, 0.02260, 0.02420,
+   0.02700, 0.02860, 0.02980, 0.03220, 0.03340, 0.03540, 0.03620, 0.03820, 0.04020, 0.04180, 0.04340, 0.04460, 0.04620,
+   0.04740, 0.04941, 0.05088, 0.05233, 0.05375, 0.05515, 0.05653, 0.05788, 0.05921, 0.06052, 0.06180, 0.06306, 0.06430,
+   0.06551, 0.06670, 0.06786, 0.06901, 0.07012, 0.07122, 0.07229, 0.07334, 0.07436, 0.07536, 0.07634},
+  {0.00100, 0.00380, 0.00780, 0.00900, 0.01220, 0.01460, 0.01860, 0.01940, 0.02260, 0.02540, 0.02820, 0.03060, 0.03220,
+   0.03660, 0.03980, 0.04094, 0.04420, 0.04620, 0.04824, 0.04980, 0.05298, 0.05532, 0.05740, 0.05991, 0.06217, 0.06500,
+   0.06540, 0.06900, 0.07096, 0.07310, 0.07380, 0.07729, 0.07935, 0.08139, 0.08340, 0.08538, 0.08734, 0.08928, 0.08900,
+   0.09307, 0.09493, 0.09340, 0.09858, 0.09620, 0.09740, 0.10386, 0.09980, 0.10726, 0.10892, 0.11056},
+  {0.00011, 0.00140, 0.00340, 0.00420, 0.00500, 0.00620, 0.00820, 0.00860, 0.01060, 0.01100, 0.01220, 0.01340, 0.01500,
+   0.01540, 0.01700, 0.01820, 0.01900, 0.02060, 0.02180, 0.02260, 0.02340, 0.02420, 0.02500, 0.02500, 0.02660, 0.02740,
+   0.02820, 0.02900, 0.03020, 0.03180, 0.03300, 0.03260, 0.03380, 0.03460, 0.03500, 0.03580, 0.03780, 0.03820, 0.03860,
+   0.03900, 0.04100, 0.04180, 0.04060, 0.04300, 0.04340, 0.04340, 0.04380, 0.04460, 0.04580, 0.04540}};
 
 ClassImp(CbmTrdModuleRecT)
diff --git a/reco/detectors/trd/CbmTrdModuleRecT.h b/reco/detectors/trd/CbmTrdModuleRecT.h
index 39d577e13d3cf9efada27284066d0c37678f4751..6c6e96d3c098d3c56d49b9ca371fada58716c48e 100644
--- a/reco/detectors/trd/CbmTrdModuleRecT.h
+++ b/reco/detectors/trd/CbmTrdModuleRecT.h
@@ -10,14 +10,29 @@
 #include <list>
 #include <map>
 #include <vector>
-#define NBINSCORRX 151  //! no of bins in the discretized correction LUT
+#define NBINSCORRX 50   //! no of bins in the discretized correction LUT
 #define NBINSCORRY 4    //! no of bins in the parametrization correction
+#define NANODE 9
 
+using std::list;
+using std::map;
+using std::vector;
 class TGraphErrors;
+class CbmTrdDigiRec;
 class TF1;
-/**
-  * \brief Triangular pad module; Cluster finding and hit reconstruction algorithms
-  **/
+/** @class CbmTrdModuleRecT
+ ** @brief Cluster finding and hit reconstruction algorithms for the TRD(2D) module. 
+ ** @author Alexandru Bercucic <abercuci@niham.nipne.ro>
+ ** @since 01.02.2019
+ ** @date 01.10.2021
+ **
+ ** Extend the TRD module reconstructor for the particular case of inner TRD-2D modules.
+ ** The class is a collection of algorithms to :
+ ** - identify time and spatially correlated digis and build clusters
+ ** - identify the type of clusters and apply further merging/deconvolution
+ ** - apply FEE (channel gain, baseline) and detector (energy gain, maps, etc) calibration
+ ** - steer the calculation of hit 4D parameters (x, y, t, E)
+ **/
 class CbmTrdModuleRecT : public CbmTrdModuleRec {
 public:
   enum CbmTrdModuleRecTconfig
@@ -41,16 +56,67 @@ public:
    * \param[in] d drawing toggle
    */
   virtual inline void Config(Bool_t v, Bool_t d);
+  virtual void DrawHit(CbmTrdHit*) const { ; }
   /** \brief Count RO channels (R or T) with data**/
   virtual Int_t GetOverThreshold() const;
+  /** \brief Check hit quality (deconvolute pile-ups, etc)**/
+  virtual Bool_t PreProcessHits();
   /** \brief Finalize hits (merge RC hits, etc)**/
-  virtual Bool_t Finalize();
+  virtual Bool_t PostProcessHits();
   /** \brief Finalize clusters **/
   virtual Int_t FindClusters();
   /** \brief Steering routine for building hits **/
   virtual Bool_t MakeHits();
   /** \brief Steering routine for converting cluster to hit **/
   virtual CbmTrdHit* MakeHit(Int_t cId, const CbmTrdCluster* c, std::vector<const CbmTrdDigi*>* digis);
+  /** \brief Load RAW digis into working array of RECO digis
+   * \param[in] din list of RAW digis in increasing order of column no
+   * \param[in] cid cluster index in the cluster array 
+   * \return no of digis loaded
+   */
+  Int_t LoadDigis(vector<const CbmTrdDigi*>* din, Int_t cid);
+  Int_t ProjectDigis(Int_t cid, Int_t cjd = -1);
+  /** \brief Implement topologic cuts for hit merging
+   * \return index of anode wire wrt to boundary or 0 if check fails 
+   */
+  Int_t CheckMerge(Int_t cid, Int_t cjd);
+  /** \brief Algorithm for hit merging
+   * \param[in] h hit to be modified by addition of hp.
+   * \param[in] a0 anode hypothesis around boundary (see CheckMerge function).
+   * \return TRUE if succesful.
+   */
+  Bool_t MergeHits(CbmTrdHit* h, Int_t a0);
+  Bool_t BuildHit(CbmTrdHit* h);
+  UShort_t GetHitMap() const { return vyM; }
+  /** \brief x position correction based on LUT
+   * \param[in] dx offset computed on charge sharing expressed in [pw]
+   * \param[in] typ hit type central pad [0] or edge [1]
+   * \param[in] cls correction class x wrt center [0] row-cross [1] row-cross biassed x [2]
+   * \return correction expresed in [cm]
+   */
+  Double_t GetXcorr(Double_t dx, Int_t typ, Int_t cls = 0) const;
+  /** \brief y position correction based on LUT
+   * \param[in] dy offset computed on charge sharing expressed in [ph]
+   * \param[in] cls correction class 
+   * \return correction expresed in [cm]
+   */
+  Double_t GetYcorr(Double_t dy, Int_t cls = 0) const;
+  /** \brief Shift graph representation to [-0.5, 0.5]
+   * \param[in] dx offset wrt center pad [pw]
+   */
+  void RecenterXoffset(Double_t& dx);
+  /** \brief Shift graph representation to [-0.5, 0.5]
+   * \param[in] dy offset wrt center pad [ph]
+   */
+  void RecenterYoffset(Double_t& dy);
+  /** \brief Hit classification wrt center pad
+   * \return hit type : center hit [0]; side hit [1]
+   */
+  Int_t GetHitClass() const;
+  /** \brief Hit classification wrt signal bias
+   * \return hit type : center hit [0]; side hit [1]
+   */
+  Int_t GetHitRcClass(Int_t a0) const;
 
 protected:
 private:
@@ -59,8 +125,18 @@ private:
 
   Bool_t CDRAW() const { return TESTBIT(fConfigMap, kDraw); }
   Bool_t CWRITE() const { return TESTBIT(fConfigMap, kVerbose); }
-  Double_t GetXoffset(Int_t n0) const;
-  Double_t GetYoffset(Int_t n0) const;
+  /** \brief Implement cuts for hit convolution definition
+   * \param[in] h hit to be analysed.
+   * \return TRUE if double cluster
+   */
+  Bool_t CheckConvolution(CbmTrdHit* h) const;
+  /** \brief Algorithm for cluster spliting
+   * \param[in] h hit to be analysed.
+   * \return TRUE if succesful. The extra cluster is added to the end of the hits array 
+   */
+  Bool_t Deconvolute(CbmTrdHit* h);
+  Double_t GetXoffset(Int_t n0 = 0) const;
+  Double_t GetYoffset(Int_t n0 = 0) const;
   /** \brief Load digis info into local data structures
    * \param[in] digis initial digis list shrinked for incomplete digis.
    * \param[in] vdgM list of merged digis
@@ -71,6 +147,9 @@ private:
    */
   Int_t LoadDigis(std::vector<const CbmTrdDigi*>* digis, std::vector<CbmTrdDigi*>* vdgM, std::vector<Bool_t>* vmask,
                   ULong64_t& t0, Int_t& cM);
+  Int_t LoadDigisRC(vector<const CbmTrdDigi*>* digis, const Int_t r0, const Int_t a0,
+                    /*vector<CbmTrdDigi*> *vdgM, */ ULong64_t& t0, Int_t& cM);
+
   /** \brief Merge R/T signals to digis if topological conditions in cluster are fulfilled
    * \param[in] digis initial digis list.
    * \param[out] vdgM list of merged digis
@@ -79,25 +158,61 @@ private:
    */
   Bool_t MergeDigis(std::vector<const CbmTrdDigi*>* digis, std::vector<CbmTrdDigi*>* vdgM, std::vector<Bool_t>* vmask);
 
+  Bool_t HasLeftSgn() const { return TESTBIT(vyM, 3); }
+  Bool_t HasOvf() const { return TESTBIT(vyM, 12); }
+  Bool_t IsBiasX() const { return TESTBIT(vyM, 4); }
+  Bool_t IsBiasXleft() const { return TESTBIT(vyM, 5); }
+  Bool_t IsBiasXmid() const { return TESTBIT(vyM, 6); }
+  Bool_t IsBiasXright() const { return TESTBIT(vyM, 7); }
+  Bool_t IsBiasY() const { return TESTBIT(vyM, 8); }
+  Bool_t IsBiasYleft() const { return TESTBIT(vyM, 9); }
+  Bool_t IsLeftHit() const { return TESTBIT(vyM, 2); }
+  Bool_t IsMaxTilt() const { return TESTBIT(vyM, 0); }
+  Bool_t IsOpenLeft() const { return (viM % 2 && !IsMaxTilt()) || (!(viM % 2) && IsMaxTilt()); }
+  inline Bool_t IsOpenRight() const;
+  Bool_t IsSymmHit() const { return TESTBIT(vyM, 1); }
+  void SetBiasX(Bool_t set = 1) { set ? SETBIT(vyM, 4) : CLRBIT(vyM, 4); }
+  void SetBiasXleft(Bool_t set = 1) { set ? SETBIT(vyM, 5) : CLRBIT(vyM, 5); }
+  void SetBiasXmid(Bool_t set = 1) { set ? SETBIT(vyM, 6) : CLRBIT(vyM, 6); }
+  void SetBiasXright(Bool_t set = 1) { set ? SETBIT(vyM, 7) : CLRBIT(vyM, 7); }
+  void SetBiasY(Bool_t set = 1) { set ? SETBIT(vyM, 8) : CLRBIT(vyM, 8); }
+  void SetBiasYleft(Bool_t set = 1) { set ? SETBIT(vyM, 9) : CLRBIT(vyM, 9); }
+  void SetBiasYmid(Bool_t set = 1) { set ? SETBIT(vyM, 10) : CLRBIT(vyM, 10); }
+  void SetBiasYright(Bool_t set = 1) { set ? SETBIT(vyM, 11) : CLRBIT(vyM, 11); }
+  void SetLeftSgn(Bool_t set = 1) { set ? SETBIT(vyM, 3) : CLRBIT(vyM, 3); }
+  void SetLeftHit(Bool_t set = 1) { set ? SETBIT(vyM, 2) : CLRBIT(vyM, 2); }
+  void SetSymmHit(Bool_t set = 1) { set ? SETBIT(vyM, 1) : CLRBIT(vyM, 1); }
+  void SetMaxTilt(Bool_t set = 1) { set ? SETBIT(vyM, 0) : CLRBIT(vyM, 0); }
+  void SetOvf(Bool_t set = 1) { set ? SETBIT(vyM, 12) : CLRBIT(vyM, 12); }
+
   UChar_t fConfigMap;                                  // task configuration settings
   ULong64_t fT0;                                       //! start time of event/time slice [clk]
   std::map<Int_t, std::list<CbmTrdCluster*>> fBuffer;  //row-wise organized clusters
-  std::vector<Double_t> vs;                            //! working copy of signals from cluster
-  std::vector<Double_t> vse;                           //! working copy of signal errors from cluster
-  std::vector<Char_t> vt;                              //! working copy of signal relative timing
-  std::vector<Double_t> vx;                            //! working copy of signal relative positions
-  std::vector<Double_t> vxe;                           //! working copy of signal relative position errors
+  std::map<Int_t, vector<CbmTrdDigiRec*>> fDigis;      //!cluster-wise organized calibrated digi
+  // working representation of a hit on which the reconstruction is performed
+  ULong64_t vt0;              //! start time of current hit [clk]
+  UChar_t vcM;                //! maximum col
+  UChar_t vrM;                //! maximum row
+  UChar_t viM;                //! index of maximum signal in the projection
+  UShort_t vyM;               //! bit map for cluster topology classification
+  std::vector<Double_t> vs;   //! working copy of signals from cluster
+  std::vector<Double_t> vse;  //! working copy of signal errors from cluster
+  std::vector<Char_t> vt;     //! working copy of signal relative timing
+  std::vector<Double_t> vx;   //! working copy of signal relative positions
+  std::vector<Double_t> vxe;  //! working copy of signal relative position errors
 
   static Float_t fgCorrXdx;                  //! step of the discretized correction LUT
-  static Float_t fgCorrXval[2][NBINSCORRX];  //! discretized correction LUT
+  static Float_t fgCorrXval[3][NBINSCORRX];  //! discretized correction LUT
   static Float_t fgCorrYval[NBINSCORRY][2];  //! discretized correction params
+  static Float_t fgCorrRcXval[2][NBINSCORRX];       //! discretized correction LUT
+  static Float_t fgCorrRcXbiasXval[3][NBINSCORRX];  //! discretized correction LUT
   static Double_t fgDT[3];                   //! FASP delay wrt signal
   static TGraphErrors* fgEdep;               //! data handler for cluster PRF
   static TF1* fgPRF;                         //! fitter for cluster PRF
   static TGraphErrors* fgT;                  //! data handler for cluster TRF
 
   ClassDef(CbmTrdModuleRecT,
-           1)  // Triangular pad module; Cluster finding and hit reconstruction algorithms
+           2)  // Triangular pad module; Cluster finding and hit reconstruction algorithms
 };
 
 void CbmTrdModuleRecT::Config(Bool_t v, Bool_t d)
@@ -111,4 +226,10 @@ void CbmTrdModuleRecT::Config(Bool_t v, Bool_t d)
     CLRBIT(fConfigMap, kDraw);
   printf("CbmTrdModuleRecT::Draw[%c]\n", CDRAW() ? 'y' : 'n');
 }
+
+Bool_t CbmTrdModuleRecT::IsOpenRight() const
+{
+  Int_t nR = vs.size() - 1 - viM;
+  return (nR % 2 && IsMaxTilt()) || (!(nR % 2) && !IsMaxTilt());
+}
 #endif
diff --git a/reco/detectors/trd/CbmTrdRecoLinkDef.h b/reco/detectors/trd/CbmTrdRecoLinkDef.h
index c0f2d416da957939c564ef5a1fc6ebb5067035b9..92169034aee6d743659257453822b1a44d706fee 100644
--- a/reco/detectors/trd/CbmTrdRecoLinkDef.h
+++ b/reco/detectors/trd/CbmTrdRecoLinkDef.h
@@ -1,6 +1,6 @@
 /* Copyright (C) 2020 Institut fuer Kernphysik, Goethe-Universitaet Frankfurt, Frankfurt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Pascal Raisig [committer] */
+   Authors: Pascal Raisig [committer], Alexandru Bercuci */
 
 // $Id: TrdRecoLinkDef.h $
 
@@ -17,6 +17,7 @@
 #pragma link C++ class CbmTrdModuleRec + ;
 #pragma link C++ class CbmTrdModuleRecR + ;
 #pragma link C++ class CbmTrdModuleRecT + ;
+#pragma link C++ class CbmTrdDigiRec + ;
 
 #pragma link C++ class CbmTrdClusterizerFastQa + ;
 #pragma link C++ class CbmTrdHitDensityQa + ;
diff --git a/sim/detectors/trd/CbmTrdModuleSimT.cxx b/sim/detectors/trd/CbmTrdModuleSimT.cxx
index 94a181046e06010616a109e6378b24632a598f0d..53d9c63723fea2201f158fade6ad25da19dd1384 100644
--- a/sim/detectors/trd/CbmTrdModuleSimT.cxx
+++ b/sim/detectors/trd/CbmTrdModuleSimT.cxx
@@ -92,22 +92,36 @@ Bool_t CbmTrdModuleSimT::MakeDigi(CbmTrdPoint* point, Double_t time, Bool_t TR)
 
   // General processing on the MC point
   Double_t ELossTR(0.), ELossdEdX(point->GetEnergyLoss());
-  if (fRadiator && TR) {
-    //    nofElectrons++;
-    if (
-      fRadiator->LatticeHit(
-        point)) {  // electron has passed lattice grid (or frame material) befor reaching the gas volume -> TR-photons have been absorbed by the lattice grid
-                   //      nofLatticeHits++;
+  if (IsLabMeasurement()) {
+    ELossdEdX = 0.;
+    if (IsFeCalib()) {
+      //E[keV]=5.895; // 55Fe, Ka (89%)
+      //E[keV]=6.492; // 55Fe, Kb (11%)
+      ELossTR = gRandom->Uniform() > 0.89 ? 6.492 : 5.895;
     }
-    else if (gout[2] >= gin[2]) {  //electron has passed the radiator
-      TVector3 mom;
-      point->Momentum(mom);
-      ELossTR = fRadiator->GetTR(mom);
+    else {  // TODO implement Xrays spectrum
+      ;     //if (fRadiator) ELossTR = fRadiator->GetXray(mom)*1.e6; // keV
+    }
+    if (VERBOSE) {
+      printf("CbmTrdModuleSimT::MakeDigi for %s ...\n", (IsFeCalib() ? "55Fe" : "X-rays"));
+      if (ELossTR > 0) LOG(info) << "    Ex " << ELossTR << " keV";
+    }
+  }
+  else {
+    if (fRadiator && TR) {
+      //    nofElectrons++;
+      if (
+        fRadiator->LatticeHit(
+          point)) {  // electron has passed lattice grid (or frame material) befor reaching the gas volume -> TR-photons have been absorbed by the lattice grid
+                     //      nofLatticeHits++;
+      }
+      else if (gout[2] >= gin[2]) {  //electron has passed the radiator
+        TVector3 mom;
+        point->Momentum(mom);
+        ELossTR = fRadiator->GetTR(mom);
+      }
     }
   }
-  //ELossTR=5.895; // 55Fe, Ka (89%)
-  //ELossTR=6.492; // 55Fe, Kb (11%)
-  //ELossdEdX = gRandom->Gaus(ELossdEdX, );
 
   // compute track length in the gas volume
   Double_t trackLength(0.), txy(0.);
@@ -274,7 +288,8 @@ Bool_t CbmTrdModuleSimT::MakeDigi(CbmTrdPoint* point, Double_t time, Bool_t TR)
     //ELossTR = gRandom->Gaus(ELossTR, ); // account for gain uncertainty
     ELossTR = fChmbPar->EkevFC(ELossTR);  // convert Edep [keV] to collected charge [fC]
 
-    ScanPadPlane(ain, tdrift * diffx, ELossTR, time + point->GetTime() + tdrift);
+    if (!IsLabMeasurement()) tdrift += time + point->GetTime();
+    ScanPadPlane(ain, tdrift * diffx, ELossTR, tdrift);
   }
   return kTRUE;
 }
@@ -530,7 +545,7 @@ void CbmTrdModuleSimT::AddDigi(Int_t address, Double_t* charge, Double_t time /*
   digi = new CbmTrdDigi(address, charge[0], charge[1], ULong64_t(TMath::Ceil(time)));
   digi->SetAddressModule(fModAddress);  // may not be needed in the future
   digiMatch          = new CbmMatch();
-  Double_t weighting = 1;
+  Double_t weighting = fChmbPar->EfCkeV(charge[0] * 0.1);  // save th. energy which is seen by pads;
   digiMatch->AddLink(CbmLink(weighting, fPointId, fEventId, fInputId));
   //digi->SetMatch(digiMatch);
 
diff --git a/sim/detectors/trd/CbmTrdModuleSimT.h b/sim/detectors/trd/CbmTrdModuleSimT.h
index 7224d7e653e8d73bcde0ad85cb1c2885fd856ef7..dbf03facf48bc251ef9c48888234570a99543e60 100644
--- a/sim/detectors/trd/CbmTrdModuleSimT.h
+++ b/sim/detectors/trd/CbmTrdModuleSimT.h
@@ -11,10 +11,17 @@ class CbmTimeSlice;
 class CbmTrdFASP;
 class CbmTrdTrianglePRF;
 class CbmTrdParSetAsic;
-/**
-  * \brief Simulation module implementation for triangular pad geometry
-  * \author Alex Bercuci <abercuci@niham.nipne.ro> 
-  **/
+/** @class CbmTrdModuleSimT
+ ** @brief Simulation module implementation for TRD-2D physics and FEE
+ ** @author Alex Bercuci <abercuci@niham.nipne.ro>  
+ ** @since 01.02.2019 
+ ** @date 10.10.2021 
+ **
+ ** The class is steered via CbmTrdDigitizer by looping over all MC points 
+ ** generated during track propagation. The class can be used to digitize MC 
+ ** output but also simulate laboratory set-ups (\sa SetLabMeasurement()) like 
+ ** 55Fe (\sa SetFeCalib()) or X-rays (\sa SetFeCalib(kFALSE))   
+ **/
 class CbmTrdModuleSimT : public CbmTrdModuleSim {
 public:
   enum ECbmTrdModuleSimT