diff --git a/.gitignore b/.gitignore
index 33a4376b8db4f13a17178a5f2bc9c74a4dfd7c9d..908556d1c514536da6b9f731b228ff3fc5199e4b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,4 +48,5 @@ Projects/T40/19Fdp.reaction
 Projects/T40/configs/*.dat
 Outputs
 Outputs/*
-Outputs/*/*.*
\ No newline at end of file
+Outputs/*/*.*
+NPLib/Utility/npspectra_test
\ No newline at end of file
diff --git a/NPLib/Detectors/LightPipe/TLightPipeData.cxx b/NPLib/Detectors/LightPipe/TLightPipeData.cxx
index 4203e20bc1eb8f234d6f2c1646c7cbcd89d56658..b31f980e4dbaed99e2b4d3fa5e40f92aac2304ae 100644
--- a/NPLib/Detectors/LightPipe/TLightPipeData.cxx
+++ b/NPLib/Detectors/LightPipe/TLightPipeData.cxx
@@ -40,40 +40,4 @@ TLightPipeData::TLightPipeData() {
 TLightPipeData::~TLightPipeData() {
 }
 
-
-
 //////////////////////////////////////////////////////////////////////
-void TLightPipeData::Clear() {
-  // Energy
-  fLightPipe_E_DetectorNbr.clear();
-  fLightPipe_Energy.clear();
-  // Time
-  fLightPipe_T_DetectorNbr.clear();
-  fLightPipe_Time.clear();
-}
-
-
-
-//////////////////////////////////////////////////////////////////////
-void TLightPipeData::Dump() const {
-  // This method is very useful for debuging and worth the dev.
-  cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TLightPipeData::Dump()] XXXXXXXXXXXXXXXXX" << endl;
-
-  // Energy
-  size_t mysize = fLightPipe_E_DetectorNbr.size();
-  cout << "LightPipe_E_Mult: " << mysize << endl;
- 
-  for (size_t i = 0 ; i < mysize ; i++){
-    cout << "DetNbr: " << fLightPipe_E_DetectorNbr[i]
-         << " Energy: " << fLightPipe_Energy[i];
-  }
-  
-  // Time
-  mysize = fLightPipe_T_DetectorNbr.size();
-  cout << "LightPipe_T_Mult: " << mysize << endl;
- 
-  for (size_t i = 0 ; i < mysize ; i++){
-    cout << "DetNbr: " << fLightPipe_T_DetectorNbr[i]
-         << " Time: " << fLightPipe_Time[i];
-  }
-}
diff --git a/NPLib/Detectors/LightPipe/TLightPipeData.h b/NPLib/Detectors/LightPipe/TLightPipeData.h
index 659fcbc1dd7194f60fd21a4c525f689100f6fb52..7c1b8e2d7088dbd71a27f0d9f11d68239a48e13a 100644
--- a/NPLib/Detectors/LightPipe/TLightPipeData.h
+++ b/NPLib/Detectors/LightPipe/TLightPipeData.h
@@ -24,7 +24,7 @@
 
 // STL
 #include <vector>
-using namespace std;
+#include <iostream>
 
 // ROOT
 #include "TObject.h"
@@ -33,29 +33,75 @@ class TLightPipeData : public TObject {
   //////////////////////////////////////////////////////////////
   // data members are hold into vectors in order 
   // to allow multiplicity treatment
-  private: 
-    // Energy
-    vector<UShort_t>   fLightPipe_E_DetectorNbr;
-    vector<Double_t>   fLightPipe_Energy;
-
-    // Time
-    vector<UShort_t>   fLightPipe_T_DetectorNbr;
-    vector<Double_t>   fLightPipe_Time;
-
-
+public:
+	// Energy (# of photons)
+	// Left side
+	std::vector<UShort_t>  fLightPipe_Left_LayerNbr;
+	std::vector<UShort_t>  fLightPipe_Left_RowNbr;
+	std::vector<Double_t>  fLightPipe_Left_Energy;
+	// Right side
+	std::vector<UShort_t>  fLightPipe_Right_LayerNbr;
+	std::vector<UShort_t>  fLightPipe_Right_RowNbr;
+	std::vector<Double_t>  fLightPipe_Right_Energy;
+	// Top
+	std::vector<UShort_t>  fLightPipe_Top_LayerNbr;
+	std::vector<UShort_t>  fLightPipe_Top_RowNbr;
+	std::vector<Double_t>  fLightPipe_Top_Energy;
+	// Bottom
+	std::vector<UShort_t>  fLightPipe_Bottom_LayerNbr;
+	std::vector<UShort_t>  fLightPipe_Bottom_RowNbr;
+	std::vector<Double_t>  fLightPipe_Bottom_Energy;
+
+public:
+	enum  { Left_t, Right_t, Top_t, Bottom_t };
+	
   //////////////////////////////////////////////////////////////
   // Constructor and destructor
-  public: 
-    TLightPipeData();
-    ~TLightPipeData();
+public: 
+	TLightPipeData();
+	~TLightPipeData();
     
 
   //////////////////////////////////////////////////////////////
   // Inherited from TObject and overriden to avoid warnings
-  public:
-    void Clear();
-    void Clear(const Option_t*) {};
-    void Dump() const;
+public:
+	void Clear()
+		{
+			fLightPipe_Left_LayerNbr.clear();
+			fLightPipe_Left_RowNbr.clear();
+			fLightPipe_Left_Energy.clear();
+
+			fLightPipe_Right_LayerNbr.clear();
+			fLightPipe_Right_RowNbr.clear();
+			fLightPipe_Right_Energy.clear();
+
+			fLightPipe_Top_LayerNbr.clear();
+			fLightPipe_Top_RowNbr.clear();
+			fLightPipe_Top_Energy.clear();
+
+			fLightPipe_Bottom_LayerNbr.clear();
+			fLightPipe_Bottom_RowNbr.clear();
+			fLightPipe_Bottom_Energy.clear();
+		}
+	void Clear(const Option_t*) {};
+	void Dump() const
+		{
+#if 0
+			// This method is very useful for debuging and worth the dev.
+			std::cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TLightPipeData::Dump()] XXXXXXXXXXXXXXXXX\n";
+			// Energy
+			size_t mysize = fLightPipe_E_DetectorNbr.size();
+			std::cout << "LightPipe_E_Mult: " << mysize << "\n";
+			for (size_t i = 0 ; i < mysize ; i++){
+				std::cout << "DetNbr: " << fLightPipe_E_DetectorNbr[i]
+									<< "RowNbr (x): " << fLightPipe_E_RowNbr[i]
+									<< "ColumnNbr (y): " << fLightPipe_E_ColumnNbr[i]
+									<< "DetNbr (z): " << fLightPipe_E_DetectorNbr[i]
+									<< " Energy: " << fLightPipe_Energy[i];
+			}
+			std::cout << "\n";
+#endif
+		}
 
 
   //////////////////////////////////////////////////////////////
@@ -63,42 +109,40 @@ class TLightPipeData : public TObject {
   // Prefer inline declaration to avoid unnecessary called of 
   // frequently used methods
   // add //! to avoid ROOT creating dictionnary for the methods
-  public:
-    //////////////////////    SETTERS    ////////////////////////
-    // Energy
-    inline void SetEnergy(const UShort_t& DetNbr,const Double_t& Energy){
-      fLightPipe_E_DetectorNbr.push_back(DetNbr);
-      fLightPipe_Energy.push_back(Energy);
-    };//!
-
-    // Time
-    inline void SetTime(const UShort_t& DetNbr,const Double_t& Time)	{
-      fLightPipe_T_DetectorNbr.push_back(DetNbr);     
-      fLightPipe_Time.push_back(Time);
-    };//!
-
-
-    //////////////////////    GETTERS    ////////////////////////
-    // Energy
-    inline UShort_t GetMultEnergy() const
-      {return fLightPipe_E_DetectorNbr.size();}
-    inline UShort_t GetE_DetectorNbr(const unsigned int &i) const 
-      {return fLightPipe_E_DetectorNbr[i];}//!
-    inline Double_t Get_Energy(const unsigned int &i) const 
-      {return fLightPipe_Energy[i];}//!
-
-    // Time
-    inline UShort_t GetMultTime() const
-      {return fLightPipe_T_DetectorNbr.size();}
-    inline UShort_t GetT_DetectorNbr(const unsigned int &i) const 
-      {return fLightPipe_T_DetectorNbr[i];}//!
-    inline Double_t Get_Time(const unsigned int &i) const 
-      {return fLightPipe_Time[i];}//!
-
+public:
+	//////////////////////    SETTERS    ////////////////////////
+	// Energy
+	void SetEnergy(Int_t side, UShort_t layer, UShort_t row, Double_t energy) {
+		switch(side) {
+		case Left_t:
+			fLightPipe_Left_LayerNbr.push_back(layer);
+			fLightPipe_Left_RowNbr.push_back(row);
+			fLightPipe_Left_Energy.push_back(energy);
+			break;
+		case Right_t:
+			fLightPipe_Right_LayerNbr.push_back(layer);
+			fLightPipe_Right_RowNbr.push_back(row);
+			fLightPipe_Right_Energy.push_back(energy);
+			break;
+		case Top_t:
+			fLightPipe_Top_LayerNbr.push_back(layer);
+			fLightPipe_Top_RowNbr.push_back(row);
+			fLightPipe_Top_Energy.push_back(energy);
+			break;
+		case Bottom_t:
+			fLightPipe_Bottom_LayerNbr.push_back(layer);
+			fLightPipe_Bottom_RowNbr.push_back(row);
+			fLightPipe_Bottom_Energy.push_back(energy);
+			break;
+		default:
+			std::cerr << "WARNING: Invalid side: " << side << " specified to TLightPipeData::SetEnergy(); nothing will be set!\n";
+			break;
+		}
+	};//!
 
   //////////////////////////////////////////////////////////////
   // Required for ROOT dictionnary
-  ClassDef(TLightPipeData,1)  // LightPipeData structure
+  ClassDef(TLightPipeData,1);  // LightPipeData structure
 };
 
 #endif
diff --git a/NPLib/Detectors/LightPipe/TLightPipePhysics.cxx b/NPLib/Detectors/LightPipe/TLightPipePhysics.cxx
index dc81b1ab50cee0b636f881ecfa5f561fe38a27f2..34553e07c8e648abea55b8e291eb5cbc4918a641 100644
--- a/NPLib/Detectors/LightPipe/TLightPipePhysics.cxx
+++ b/NPLib/Detectors/LightPipe/TLightPipePhysics.cxx
@@ -28,6 +28,8 @@
 #include <cmath>
 #include <stdlib.h>
 #include <limits>
+#include <algorithm>
+#include <iterator>
 using namespace std;
 
 //   NPL
@@ -81,19 +83,13 @@ void TLightPipePhysics::BuildSimplePhysicalEvent() {
 void TLightPipePhysics::BuildPhysicalEvent() {
   // apply thresholds and calibration
   PreTreat();
-
-  // match energy and time together
-  unsigned int mysizeE = m_PreTreatedData->GetMultEnergy();
-  unsigned int mysizeT = m_PreTreatedData->GetMultTime();
-  for (UShort_t e = 0; e < mysizeE ; e++) {
-    for (UShort_t t = 0; t < mysizeT ; t++) {
-      if (m_PreTreatedData->GetE_DetectorNbr(e) == m_PreTreatedData->GetT_DetectorNbr(t)) {
-        DetectorNumber.push_back(m_PreTreatedData->GetE_DetectorNbr(e));
-        Energy.push_back(m_PreTreatedData->Get_Energy(e));
-        Time.push_back(m_PreTreatedData->Get_Time(t));
-      }
-    }
-  }
+#if 0
+  // copy calibrated data
+	copy(m_PreTreatedData->GetE_RowNbr().begin(), m_PreTreatedData->GetE_RowNbr().end(), back_inserter(RowNumber));
+	copy(m_PreTreatedData->GetE_ColumnNbr().begin(), m_PreTreatedData->GetE_ColumnNbr().end(), back_inserter(ColumnNumber));
+	copy(m_PreTreatedData->GetE_DetectorNbr().begin(), m_PreTreatedData->GetE_DetectorNbr().end(), back_inserter(DetectorNumber));
+	copy(m_PreTreatedData->Get_Energy().begin(), m_PreTreatedData->Get_Energy().end(), back_inserter(Energy));
+#endif
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -107,23 +103,18 @@ void TLightPipePhysics::PreTreat() {
   // instantiate CalibrationManager
   static CalibrationManager* Cal = CalibrationManager::getInstance();
 
+#if 0
   // Energy
   unsigned int mysize = m_EventData->GetMultEnergy();
   for (UShort_t i = 0; i < mysize ; ++i) {
     if (m_EventData->Get_Energy(i) > m_E_RAW_Threshold) {
-      Double_t Energy = Cal->ApplyCalibration("LightPipe/ENERGY"+NPL::itoa(m_EventData->GetE_DetectorNbr(i)),m_EventData->Get_Energy(i));
+      Double_t Energy = m_EventData->Get_Energy(i); // ORIGINAL:: Cal->ApplyCalibration("LightPipe/ENERGY"+NPL::itoa(m_EventData->GetE_DetectorNbr(i)),m_EventData->Get_Energy(i));
       if (Energy > m_E_Threshold) {
-        m_PreTreatedData->SetEnergy(m_EventData->GetE_DetectorNbr(i), Energy);
+        m_PreTreatedData->SetEnergy(m_EventData->GetE_RowNbr(i), m_EventData->GetE_ColumnNbr(i), m_EventData->GetE_DetectorNbr(i), Energy);
       }
     }
   }
-
-  // Time 
-  mysize = m_EventData->GetMultTime();
-  for (UShort_t i = 0; i < mysize; ++i) {
-    Double_t Time= Cal->ApplyCalibration("LightPipe/TIME"+NPL::itoa(m_EventData->GetT_DetectorNbr(i)),m_EventData->Get_Time(i));
-    m_PreTreatedData->SetTime(m_EventData->GetT_DetectorNbr(i), Time);
-  }
+#endif
 }
 
 
@@ -194,9 +185,10 @@ void TLightPipePhysics::ReadAnalysisConfig() {
 
 ///////////////////////////////////////////////////////////////////////////
 void TLightPipePhysics::Clear() {
+  RowNumber.clear();
+  ColumnNumber.clear();
   DetectorNumber.clear();
   Energy.clear();
-  Time.clear();
 }
 
 
diff --git a/NPLib/Detectors/LightPipe/TLightPipePhysics.h b/NPLib/Detectors/LightPipe/TLightPipePhysics.h
index 01932fea9df41325bf11a9713dc25ceef96c9c64..6f241ffad80b8dba9f867366c309a81d30efd44e 100644
--- a/NPLib/Detectors/LightPipe/TLightPipePhysics.h
+++ b/NPLib/Detectors/LightPipe/TLightPipePhysics.h
@@ -46,25 +46,26 @@ class TLightPipeSpectra;
 class TLightPipePhysics : public TObject, public NPL::VDetector {
   //////////////////////////////////////////////////////////////
   // constructor and destructor
-  public:
-    TLightPipePhysics();
-    ~TLightPipePhysics() {};
+public:
+	TLightPipePhysics();
+	~TLightPipePhysics() {};
 
 
   //////////////////////////////////////////////////////////////
   // Inherited from TObject and overriden to avoid warnings
-  public: 
-    void Clear();   
-    void Clear(const Option_t*) {};
+public: 
+	void Clear();   
+	void Clear(const Option_t*) {};
 
 
   //////////////////////////////////////////////////////////////
   // data obtained after BuildPhysicalEvent() and stored in
   // output ROOT file
-  public:
-    vector<int>      DetectorNumber;
-    vector<double>   Energy;
-    vector<double>   Time;
+public:
+	vector<int>      RowNumber;      // x
+	vector<int>      ColumnNumber;   // y
+	vector<int>      DetectorNumber; // z
+	vector<double>   Energy;
 
   /// A usefull method to bundle all operation to add a detector
   void AddDetector(TVector3 POS, string shape); 
@@ -72,109 +73,109 @@ class TLightPipePhysics : public TObject, public NPL::VDetector {
   
   //////////////////////////////////////////////////////////////
   // methods inherited from the VDetector ABC class
-  public:
-    // read stream from ConfigFile to pick-up detector parameters
-    void ReadConfiguration(NPL::InputParser);
+public:
+	// read stream from ConfigFile to pick-up detector parameters
+	void ReadConfiguration(NPL::InputParser);
 
-    // add parameters to the CalibrationManger
-    void AddParameterToCalibrationManager();
+	// add parameters to the CalibrationManger
+	void AddParameterToCalibrationManager();
 
-    // method called event by event, aiming at extracting the 
-    // physical information from detector
-    void BuildPhysicalEvent();
+	// method called event by event, aiming at extracting the 
+	// physical information from detector
+	void BuildPhysicalEvent();
 
-    // same as BuildPhysicalEvent() method but with a simpler
-    // treatment
-    void BuildSimplePhysicalEvent();
+	// same as BuildPhysicalEvent() method but with a simpler
+	// treatment
+	void BuildSimplePhysicalEvent();
 
-    // same as above but for online analysis
-    void BuildOnlinePhysicalEvent()  {BuildPhysicalEvent();};
+	// same as above but for online analysis
+	void BuildOnlinePhysicalEvent()  {BuildPhysicalEvent();};
 
-    // activate raw data object and branches from input TChain
-    // in this method mother branches (Detector) AND daughter leaves 
-    // (fDetector_parameter) have to be activated
-    void InitializeRootInputRaw();
+	// activate raw data object and branches from input TChain
+	// in this method mother branches (Detector) AND daughter leaves 
+	// (fDetector_parameter) have to be activated
+	void InitializeRootInputRaw();
 
-    // activate physics data object and branches from input TChain
-    // in this method mother branches (Detector) AND daughter leaves 
-    // (fDetector_parameter) have to be activated
-    void InitializeRootInputPhysics();
+	// activate physics data object and branches from input TChain
+	// in this method mother branches (Detector) AND daughter leaves 
+	// (fDetector_parameter) have to be activated
+	void InitializeRootInputPhysics();
 
-    // create branches of output ROOT file
-    void InitializeRootOutput();
+	// create branches of output ROOT file
+	void InitializeRootOutput();
 
-    // clear the raw and physical data objects event by event
-    void ClearEventPhysics() {Clear();}      
-    void ClearEventData()    {m_EventData->Clear();}   
+	// clear the raw and physical data objects event by event
+	void ClearEventPhysics() {Clear();}      
+	void ClearEventData()    {m_EventData->Clear();}   
 
-    // methods related to the TLightPipeSpectra class
-    // instantiate the TLightPipeSpectra class and 
-    // declare list of histograms
-    void InitSpectra();
+	// methods related to the TLightPipeSpectra class
+	// instantiate the TLightPipeSpectra class and 
+	// declare list of histograms
+	void InitSpectra();
 
-    // fill the spectra
-    void FillSpectra();
+	// fill the spectra
+	void FillSpectra();
 
-    // used for Online mainly, sanity check for histograms and 
-    // change their color if issues are found, for example
-    void CheckSpectra();
+	// used for Online mainly, sanity check for histograms and 
+	// change their color if issues are found, for example
+	void CheckSpectra();
 
-    // used for Online only, clear all the spectra
-    void ClearSpectra();
+	// used for Online only, clear all the spectra
+	void ClearSpectra();
 
-    // write spectra to ROOT output file
-    void WriteSpectra();
+	// write spectra to ROOT output file
+	void WriteSpectra();
 
 
   //////////////////////////////////////////////////////////////
   // specific methods to LightPipe array
-  public:
-    // remove bad channels, calibrate the data and apply thresholds
-    void PreTreat();
+public:
+	// remove bad channels, calibrate the data and apply thresholds
+	void PreTreat();
 
-    // clear the pre-treated object
-    void ClearPreTreatedData()   {m_PreTreatedData->Clear();}
+	// clear the pre-treated object
+	void ClearPreTreatedData()   {m_PreTreatedData->Clear();}
 
-    // read the user configuration file. If no file is found, load standard one
-    void ReadAnalysisConfig();
+	// read the user configuration file. If no file is found, load standard one
+	void ReadAnalysisConfig();
 
-    // give and external TLightPipeData object to TLightPipePhysics. 
-    // needed for online analysis for example
-    void SetRawDataPointer(TLightPipeData* rawDataPointer) {m_EventData = rawDataPointer;}
+	// give and external TLightPipeData object to TLightPipePhysics. 
+	// needed for online analysis for example
+	void SetRawDataPointer(TLightPipeData* rawDataPointer) {m_EventData = rawDataPointer;}
     
   // objects are not written in the TTree
-  private:
-    TLightPipeData*         m_EventData;        //!
-    TLightPipeData*         m_PreTreatedData;   //!
-    TLightPipePhysics*      m_EventPhysics;     //!
+private:
+	TLightPipeData*         m_EventData;        //!
+	TLightPipeData*         m_PreTreatedData;   //!
+	TLightPipePhysics*      m_EventPhysics;     //!
 
   // getters for raw and pre-treated data object
-  public:
-    TLightPipeData* GetRawData()        const {return m_EventData;}
-    TLightPipeData* GetPreTreatedData() const {return m_PreTreatedData;}
+public:
+	TLightPipeData* GetRawData()        const {return m_EventData;}
+	TLightPipeData* GetPreTreatedData() const {return m_PreTreatedData;}
 
   // parameters used in the analysis
-  private:
-    // thresholds
-    double m_E_RAW_Threshold; //!
-    double m_E_Threshold;     //!
+private:
+	// thresholds
+	double m_E_RAW_Threshold; //!
+	double m_E_Threshold;     //!
 
   // number of detectors
-  private:
-    int m_NumberOfDetectors;  //!
+private:
+	int m_NumberOfDetectors;  //!
 
   // spectra class
-  private:
-    TLightPipeSpectra* m_Spectra; // !
+private:
+	TLightPipeSpectra* m_Spectra; // !
 
   // spectra getter
-  public:
-    map<string, TH1*>   GetSpectra(); 
+public:
+	map<string, TH1*>   GetSpectra(); 
 
   // Static constructor to be passed to the Detector Factory
-  public:
-    static NPL::VDetector* Construct();
+public:
+	static NPL::VDetector* Construct();
 
-    ClassDef(TLightPipePhysics,1)  // LightPipePhysics structure
+	ClassDef(TLightPipePhysics,1)  // LightPipePhysics structure
 };
 #endif
diff --git a/NPLib/Detectors/LightPipe/TLightPipeSpectra.cxx b/NPLib/Detectors/LightPipe/TLightPipeSpectra.cxx
index dcd074d9a3e6b4ba753b8f8da92fd0b6289edbc5..26e904c5e0a1f35a7ac51e66eee4fab1b511f185 100644
--- a/NPLib/Detectors/LightPipe/TLightPipeSpectra.cxx
+++ b/NPLib/Detectors/LightPipe/TLightPipeSpectra.cxx
@@ -108,67 +108,67 @@ void TLightPipeSpectra::InitPhysicsSpectra() {
 
 ////////////////////////////////////////////////////////////////////////////////
 void TLightPipeSpectra::FillRawSpectra(TLightPipeData* RawData) {
-  static string name;
-  static string family;
-
-  // Energy 
-  unsigned int sizeE = RawData->GetMultEnergy();
-  for (unsigned int i = 0; i < sizeE; i++) {
-    name = "LightPipe"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW";
-    family = "LightPipe/RAW";
-
-    FillSpectra(family,name,RawData->Get_Energy(i));
-  }
-
-  // Time
-  unsigned int sizeT = RawData->GetMultTime();
-  for (unsigned int i = 0; i < sizeT; i++) {
-    name = "LightPipe"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW";
-    family = "LightPipe/RAW";
-
-    FillSpectra(family,name,RawData->Get_Time(i));
-  }
+  // static string name;
+  // static string family;
+
+  // // Energy 
+  // unsigned int sizeE = RawData->GetMultEnergy();
+  // for (unsigned int i = 0; i < sizeE; i++) {
+  //   name = "LightPipe"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW";
+  //   family = "LightPipe/RAW";
+
+  //   FillSpectra(family,name,RawData->Get_Energy(i));
+  // }
+
+  // // Time
+  // unsigned int sizeT = RawData->GetMultTime();
+  // for (unsigned int i = 0; i < sizeT; i++) {
+  //   name = "LightPipe"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW";
+  //   family = "LightPipe/RAW";
+
+  //   FillSpectra(family,name,RawData->Get_Time(i));
+  // }
 }
 
 
 
 ////////////////////////////////////////////////////////////////////////////////
 void TLightPipeSpectra::FillPreTreatedSpectra(TLightPipeData* PreTreatedData) {
-  static string name;
-  static string family;
+  // static string name;
+  // static string family;
   
-  // Energy 
-  unsigned int sizeE = PreTreatedData->GetMultEnergy();
-  for (unsigned int i = 0; i < sizeE; i++) {
-    name = "LightPipe"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL";
-    family = "LightPipe/CAL";
-
-    FillSpectra(family,name,PreTreatedData->Get_Energy(i));
-  }
-
-  // Time
-  unsigned int sizeT = PreTreatedData->GetMultTime();
-  for (unsigned int i = 0; i < sizeT; i++) {
-    name = "LightPipe"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL";
-    family = "LightPipe/CAL";
-
-    FillSpectra(family,name,PreTreatedData->Get_Time(i));
-  }
+  // // Energy 
+  // unsigned int sizeE = PreTreatedData->GetMultEnergy();
+  // for (unsigned int i = 0; i < sizeE; i++) {
+  //   name = "LightPipe"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL";
+  //   family = "LightPipe/CAL";
+
+  //   FillSpectra(family,name,PreTreatedData->Get_Energy(i));
+  // }
+
+  // // Time
+  // unsigned int sizeT = PreTreatedData->GetMultTime();
+  // for (unsigned int i = 0; i < sizeT; i++) {
+  //   name = "LightPipe"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL";
+  //   family = "LightPipe/CAL";
+
+  //   FillSpectra(family,name,PreTreatedData->Get_Time(i));
+  // }
 }
 
 
 
 ////////////////////////////////////////////////////////////////////////////////
 void TLightPipeSpectra::FillPhysicsSpectra(TLightPipePhysics* Physics) {
-  static string name;
-  static string family;
-  family= "LightPipe/PHY";
-
-  // Energy vs time
-  unsigned int sizeE = Physics->Energy.size();
-  for(unsigned int i = 0 ; i < sizeE ; i++){
-    name = "LightPipe_ENERGY_TIME";
-    FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]);
-  }
+  // static string name;
+  // static string family;
+  // family= "LightPipe/PHY";
+
+  // // Energy vs time
+  // unsigned int sizeE = Physics->Energy.size();
+  // for(unsigned int i = 0 ; i < sizeE ; i++){
+  //   name = "LightPipe_ENERGY_TIME";
+  //   FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]);
+  // }
 }
 
diff --git a/NPSimulation/Detectors/LightPipe/LightPipe.cc b/NPSimulation/Detectors/LightPipe/LightPipe.cc
index b058407638661d993828feee4cfce10e38fc4aac..f29b9ac21eac8f226e375a8fcdc3e0ebed98f947 100644
--- a/NPSimulation/Detectors/LightPipe/LightPipe.cc
+++ b/NPSimulation/Detectors/LightPipe/LightPipe.cc
@@ -1,18 +1,18 @@
 /*****************************************************************************
- * Copyright (C) 2009-2018   this file is part of the NPTool Project         *
+ * Copyright (C) 2009-2018   this file is part of the NPTool Project       *
  *                                                                           *
  * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
  * For the list of contributors see $NPTOOL/Licence/Contributors             *
  *****************************************************************************/
 
 /*****************************************************************************
- * Original Author: Greg Christian  contact address: gchristian@tamu.edu     *
+ * Original Author: Greg Christian  contact address: gchristian@tamu.edu                        *
  *                                                                           *
- * Creation Date  : July 2018                                                *
+ * Creation Date  : July 2018                                           *
  * Last update    :                                                          *
  *---------------------------------------------------------------------------*
  * Decription:                                                               *
- *  This class describe  LightPipe simulation                                *
+ *  This class describe  LightPipe simulation                             *
  *                                                                           *
  *---------------------------------------------------------------------------*
  * Comment:                                                                  *
@@ -23,6 +23,8 @@
 #include <sstream>
 #include <cmath>
 #include <limits>
+#include <fstream>
+#include <algorithm>
 //G4 Geometry object
 #include "G4Tubs.hh"
 #include "G4Box.hh"
@@ -37,10 +39,18 @@
 #include "G4PVPlacement.hh"
 #include "G4VisAttributes.hh"
 #include "G4Colour.hh"
+#include "G4OpticalSurface.hh"
+#include "G4LogicalBorderSurface.hh"
+#include "G4LogicalSkinSurface.hh"
+
+// ROOT
+#include "TSystem.h"
+#include "TMath.h"
 
 // NPTool header
 #include "LightPipe.hh"
 #include "CalorimeterScorers.hh"
+#include "PhotoDiodeScorers.hh"
 #include "RootOutput.h"
 #include "MaterialManager.hh"
 #include "NPSDetectorFactory.hh"
@@ -53,120 +63,74 @@ using namespace std;
 using namespace CLHEP;
 
 
-//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
-namespace LightPipe_NS{
-  // Energy and time Resolution
-  const double EnergyThreshold = 0.1*MeV;
-  const double ResoTime = 4.5*ns ;
-  const double ResoEnergy = 1.0*MeV ;
-  const double Radius = 50*mm ; 
-  const double Width = 100*mm ;
-  const double Thickness = 300*mm ;
-  const string Material = "BC400";
-}
-//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
-//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 // LightPipe Specific Method
 LightPipe::LightPipe(){
   m_Event = new TLightPipeData() ;
   m_LightPipeScorer = 0;
-  m_SquareDetector = 0;
-  m_CylindricalDetector = 0;
-
 
   // RGB Color + Transparency
-  m_VisSquare = new G4VisAttributes(G4Colour(0, 1, 0, 0.5));   
-  m_VisCylinder = new G4VisAttributes(G4Colour(0, 0, 1, 0.5));   
-
+  m_VisSquare = new G4VisAttributes(G4Colour(0, 0, 1, 0.5));
+	m_VisPipe   = new G4VisAttributes(G4Colour(0, 1, 0, 0.5));
+	m_VisPD     = new G4VisAttributes(G4Colour(0.1, 0.2, 0.3));
+	m_ScintillatorMaterial = CreateScintillatorMaterial();
+	m_PipeMaterial = CreatePipeMaterial();
+	//m_Wrapping = CreateWrappingMaterial();
+	m_ReflectiveSurface = CreateReflectiveSurface();
+
+	m_VisSquare->SetForceWireframe(true);
+	m_VisPipe->SetForceWireframe(true);
 }
 
 LightPipe::~LightPipe(){
 }
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
-void LightPipe::AddDetector(G4ThreeVector POS, string  Shape){
-  // Convert the POS value to R theta Phi as Spherical coordinate is easier in G4 
-  m_R.push_back(POS.mag());
-  m_Theta.push_back(POS.theta());
-  m_Phi.push_back(POS.phi());
-  m_Shape.push_back(Shape);
-}
-
-
-//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
-void LightPipe::AddDetector(double  R, double  Theta, double  Phi, string  Shape){
-  m_R.push_back(R);
-  m_Theta.push_back(Theta);
-  m_Phi.push_back(Phi);
-  m_Shape.push_back(Shape);
-}
-
-//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
-G4LogicalVolume* LightPipe::BuildSquareDetector(){
-  if(!m_SquareDetector){
-    G4Box* box = new G4Box("LightPipe_Box",LightPipe_NS::Width*0.5,
-        LightPipe_NS::Width*0.5,LightPipe_NS::Thickness*0.5);
-
-    G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(LightPipe_NS::Material);
-    m_SquareDetector = new G4LogicalVolume(box,DetectorMaterial,"logic_LightPipe_Box",0,0,0);
-    m_SquareDetector->SetVisAttributes(m_VisSquare);
-    m_SquareDetector->SetSensitiveDetector(m_LightPipeScorer);
-  }
-  return m_SquareDetector;
+void LightPipe::AddDetector(G4int nrow, G4int ncol, G4int nlayer, G4double width, G4double thickness, G4double pipe_width, G4double pipe_thickness){
+	m_Detector.emplace_back(make_tuple(nrow,ncol,nlayer,width,thickness,pipe_width,pipe_thickness));
 }
 
-//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
-G4LogicalVolume* LightPipe::BuildCylindricalDetector(){
-  if(!m_CylindricalDetector){
-    G4Tubs* tub = new G4Tubs("LightPipe_Cyl",0,LightPipe_NS::Radius,LightPipe_NS::Thickness*0.5,0,360*deg);
 
-    G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(LightPipe_NS::Material);
-    m_CylindricalDetector = new G4LogicalVolume(tub,DetectorMaterial,"logic_LightPipe_tub",0,0,0);
-    m_CylindricalDetector->SetVisAttributes(m_VisSquare);
-    m_CylindricalDetector->SetSensitiveDetector(m_LightPipeScorer);
 
-  }
-  return m_CylindricalDetector;
-}
-
-//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
-//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 // Virtual Method of NPS::VDetector class
 
 // Read stream at Configfile to pick-up parameters of detector (Position,...)
 // Called in DetecorConstruction::ReadDetextorConfiguration Method
 void LightPipe::ReadConfiguration(NPL::InputParser parser){
+
+	G4double width = 10*mm;
+	G4double thickness = 10*mm;
+	G4double pipe_width = 3*mm;
+	G4double pipe_thickness = 1*mm;
+	G4int nrow   = 1;
+	G4int ncol   = 1;
+	G4int nlayer = 1;
+
   vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("LightPipe");
-  if(NPOptionManager::getInstance()->GetVerboseLevel())
+  if(true || NPOptionManager::getInstance()->GetVerboseLevel())
     cout << "//// " << blocks.size() << " detectors found " << endl; 
-
-  vector<string> cart = {"POS","Shape"};
-  vector<string> sphe = {"R","Theta","Phi","Shape"};
+	vector<string> lp   = {"WIDTH","THICKNESS","PIPE_WIDTH","PIPE_THICKNESS","NROW","NCOL","NLAYER"};
 
   for(unsigned int i = 0 ; i < blocks.size() ; i++){
-    if(blocks[i]->HasTokenList(cart)){
-      if(NPOptionManager::getInstance()->GetVerboseLevel())
-        cout << endl << "////  LightPipe " << i+1 <<  endl;
-    
-      G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm"));
-      string Shape = blocks[i]->GetString("Shape");
-      AddDetector(Pos,Shape);
-    }
-    else if(blocks[i]->HasTokenList(sphe)){
-      if(NPOptionManager::getInstance()->GetVerboseLevel())
+		if(blocks[i]->HasTokenList(lp)){
+      if(true || NPOptionManager::getInstance()->GetVerboseLevel()){
         cout << endl << "////  LightPipe " << i+1 <<  endl;
-      double R = blocks[i]->GetDouble("R","mm");
-      double Theta = blocks[i]->GetDouble("Theta","deg");
-      double Phi = blocks[i]->GetDouble("Phi","deg");
-      string Shape = blocks[i]->GetString("Shape");
-      AddDetector(R,Theta,Phi,Shape);
+			}
+			width = blocks[i]->GetDouble("WIDTH", "mm");
+			thickness = blocks[i]->GetDouble("THICKNESS", "mm");
+			pipe_width = blocks[i]->GetDouble("PIPE_WIDTH", "mm");
+			pipe_thickness = blocks[i]->GetDouble("PIPE_THICKNESS", "mm");
+			nrow = blocks[i]->GetInt("NROW");
+			ncol = blocks[i]->GetInt("NCOL");
+			nlayer = blocks[i]->GetInt("NLAYER");
     }
     else{
       cout << "ERROR: check your input file formatting " << endl;
       exit(1);
     }
   }
+	//
+	AddDetector(nrow, ncol, nlayer, width, thickness, pipe_width, pipe_thickness);
 }
 
 
@@ -175,39 +139,230 @@ void LightPipe::ReadConfiguration(NPL::InputParser parser){
 // Construct detector and inialise sensitive part.
 // Called After DetecorConstruction::AddDetector Method
 void LightPipe::ConstructDetector(G4LogicalVolume* world){
-  for (unsigned short i = 0 ; i < m_R.size() ; i++) {
-
-    G4double wX = m_R[i] * sin(m_Theta[i] ) * cos(m_Phi[i] ) ;
-    G4double wY = m_R[i] * sin(m_Theta[i] ) * sin(m_Phi[i] ) ;
-    G4double wZ = m_R[i] * cos(m_Theta[i] ) ;
-    G4ThreeVector Det_pos = G4ThreeVector(wX, wY, wZ) ;
-    // So the face of the detector is at R instead of the middle
-    Det_pos+=Det_pos.unit()*LightPipe_NS::Thickness*0.5;
-    // Building Detector reference frame
-    G4double ii = cos(m_Theta[i]) * cos(m_Phi[i]);
-    G4double jj = cos(m_Theta[i]) * sin(m_Phi[i]);
-    G4double kk = -sin(m_Theta[i]);
-    G4ThreeVector Y(ii,jj,kk);
-    G4ThreeVector w = Det_pos.unit();
-    G4ThreeVector u = w.cross(Y);
-    G4ThreeVector v = w.cross(u);
-    v = v.unit();
-    u = u.unit();
-
-    G4RotationMatrix* Rot = new G4RotationMatrix(u,v,w);
-
-    if(m_Shape[i] == "Cylindrical"){
-      new G4PVPlacement(G4Transform3D(*Rot,Det_pos),
-          BuildCylindricalDetector(),
-          "LightPipe",world,false,i+1);
-    }
+	bool warnOverlap = false;
 
-    else if(m_Shape[i] == "Square"){
-      new G4PVPlacement(G4Transform3D(*Rot,Det_pos),
-          BuildSquareDetector(),
-          "LightPipe",world,false,i+1);
-    }
-  }
+
+	//Create experimental hall
+	G4Material* Vacuum = MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum") ;
+	G4double expHall_x = 10.*m;
+	G4double expHall_y = 10.*m;
+	G4double expHall_z = 10.*m;
+    
+	G4Box* fExperimentalHall_box = new G4Box("expHall_box",expHall_x,expHall_y,expHall_z);
+	G4LogicalVolume* fExperimentalHall_log = new G4LogicalVolume(fExperimentalHall_box,
+																															 Vacuum,"expHall_log",0,0,0);
+	G4VPhysicalVolume* fExperimentalHall_phys = new G4PVPlacement(0,G4ThreeVector(),
+																																fExperimentalHall_log,"expHall",0,false,0);
+    
+	fExperimentalHall_log->SetVisAttributes(G4VisAttributes::Invisible);
+	
+	auto BuildRectangle = [this](G4double width, G4double length, G4double thickness, G4Material* material){
+    G4Box* box = new G4Box("LightPipe_Box",width*0.5,
+													 length*0.5,thickness*0.5);
+    G4LogicalVolume* Detector = new G4LogicalVolume(box,material,"logic_LightPipe_Box",0,0,0);
+    Detector->SetVisAttributes(this->m_VisSquare);
+//    Detector->SetSensitiveDetector(this->m_LightPipeScorer);
+		return Detector;
+	};
+	auto getCenter = [&](int i, int imax, double width){
+		return (i - (imax/2.))*width + width/2.;
+	};
+	
+	int i=0, j=0, k=0;
+
+	int iPipeX=1, iPipeY=1, iDet=1;
+	for(const auto& det : m_Detector) {
+		const G4int& nrow = get<0>(det);
+		const G4int& ncol = get<1>(det);
+		const G4int& nlayer = get<2>(det);
+		const G4double& width = get<3>(det);
+		const G4double& thickness = get<4>(det);
+		const G4double& pipe_width = get<5>(det);
+		const G4double& pipe_thickness = get<6>(det);
+		const G4double  pd_thickness = 1*mm;
+
+		vector<vector<G4PVPlacement*> > physVol(nrow);
+		for(auto& v : physVol) { v.resize(ncol); }
+
+
+		auto buildRow = [&](G4int irow, G4double z){
+			G4double rowWidthX = nrow*width;
+			G4double pipe_length = width*ncol + 1*cm;
+			//
+			// Build light pipe above detectors
+			//
+			// Create geometric object
+			G4ThreeVector pipePos(
+				0, getCenter(irow, nrow, width) + width/2. + pipe_thickness/2., z);
+			auto pipe = BuildRectangle(
+				pipe_length, pipe_width, pipe_thickness, m_PipeMaterial);
+			pipe->SetVisAttributes(m_VisPipe);
+			// Rotate it
+			G4RotationMatrix* myRotation = new G4RotationMatrix();
+			myRotation->rotateX(90.*deg);
+			// Create PV Placement
+			G4PVPlacement* pv = new G4PVPlacement(
+				myRotation, pipePos, pipe, "LightPipe_PipeX", world, false, iPipeX++, warnOverlap);
+
+			std::vector<G4PVPlacement*> pvRow;
+			for(int icol=0; icol< ncol; ++icol){
+				//
+				// Build row of detectors
+				//
+				//
+				// Create geometric object
+				G4ThreeVector Det_pos
+					(getCenter(icol,ncol,width), getCenter(irow,nrow,width), z);
+				auto Scintillator = BuildRectangle(width, width, thickness, m_ScintillatorMaterial);
+//				Scintillator->SetSensitiveDetector(this->m_LightPipeScorer);
+				// Create PV placement
+				pvRow.push_back(
+					new G4PVPlacement(
+						0, Det_pos, Scintillator, "LightPipe_Detector", world, false, iDet++, warnOverlap) );
+			}
+			// Create reflective surfaces between detectors
+			for(int icol=0; icol< ncol; ++icol){
+				// to the left
+				if(icol != 0) {
+					new G4LogicalBorderSurface("CrystalSurface", pvRow.at(icol-1), pvRow.at(icol), m_ReflectiveSurface);
+				} else {
+					new G4LogicalBorderSurface("CrystalSurface", fExperimentalHall_phys, pvRow.at(icol), m_ReflectiveSurface);
+				}
+				// to the right
+				if(icol != ncol-1) {
+					new G4LogicalBorderSurface("CrystalSurface", pvRow.at(icol), pvRow.at(icol+1), m_ReflectiveSurface);
+				} else {
+				new G4LogicalBorderSurface("CrystalSurface", pvRow.at(icol), fExperimentalHall_phys,  m_ReflectiveSurface);
+				}
+			}
+			return pvRow;
+		};
+
+		buildRow(5,0);
+#if 0
+		
+		int pdNum = 1;
+		for(int ilayer = 0; ilayer< nlayer; ++ilayer){
+			G4double detZ = getCenter(ilayer,nlayer,thickness) + pipe_thickness*ilayer;
+			for(int irow = 0; irow< nrow; ++irow){
+				for(int icol = 0; icol< ncol; ++icol){
+					//
+					// Build detectors
+					G4ThreeVector Det_pos
+						(getCenter(irow,nrow,width),
+						 getCenter(icol,ncol,width),
+						 detZ);
+					auto Rect = BuildRectangle(width, width, thickness, m_ScintillatorMaterial);
+					auto pvScint = new G4PVPlacement(0, Det_pos, Rect,"LightPipe_Detector",world,false,i+1,warnOverlap);
+					physVol.at(irow).at(icol) = pvScint;
+					++i;
+				} // for(icol...)
+			} // for(irow...)
+			//
+			// Reflection between detectors
+			for(int irow = -1; irow< nrow; ++irow){
+				for(int icol = -1; icol< ncol; ++icol){
+					if(icol > -1) {
+						auto pvLeft = irow != -1 ? physVol.at(irow).at(icol) : fExperimentalHall_phys;
+						auto pvRight = irow != nrow-1 ? physVol.at(irow+1).at(icol) : fExperimentalHall_phys;
+						new G4LogicalBorderSurface("CrystalSurface", pvLeft, pvRight, m_ReflectiveSurface);
+						new G4LogicalBorderSurface("CrystalSurface", pvRight, pvLeft, m_ReflectiveSurface);
+					}
+					if(irow > -1) {
+						auto pvUp = icol != -1 ? physVol.at(irow).at(icol) : fExperimentalHall_phys;
+						auto pvDn = icol != ncol - 1 ? physVol.at(irow).at(icol+1) : fExperimentalHall_phys;
+						new G4LogicalBorderSurface("CrystalSurface", pvUp, pvDn, m_ReflectiveSurface);
+						new G4LogicalBorderSurface("CrystalSurface", pvDn, pvUp, m_ReflectiveSurface);
+					}
+					//new G4LogicalSkinSurface("m_ReflectiveSurface",logicCsI,m_ReflectiveSurface);
+				}
+			}
+			//
+			// Build Pipes		
+			auto buildPipe = [&](bool horizontal, G4double layer_center) {
+				G4PVPlacement* pvLast = 0;
+				G4double pipe_center_z = layer_center + thickness*0.5 + pipe_thickness*0.5;
+
+				int ircmax = horizontal ? ncol : nrow;
+				for(int irc=0; irc< ircmax; ++irc){
+					G4double pipe_center_xy = getCenter(irc,ircmax,width);
+					G4ThreeVector LG_pos = horizontal ?
+						G4ThreeVector(0,pipe_center_xy-thickness/2.,pipe_center_z-thickness/2.) :
+						G4ThreeVector(pipe_center_xy,0,pipe_center_z);
+					G4Material* mat = m_PipeMaterial;
+
+					G4double pipe_length = horizontal ? width*nrow : width*ncol;
+					pipe_length += 1*cm;
+					auto pipe =  horizontal ?
+						BuildRectangle(pipe_length, pipe_width, pipe_thickness, mat) :
+						BuildRectangle(pipe_width, pipe_length, pipe_thickness, mat) ;
+					pipe->SetVisAttributes(m_VisPipe);
+					G4PVPlacement* pv = 0;
+					if(horizontal){
+						G4RotationMatrix* myRotation = new G4RotationMatrix();
+						myRotation->rotateX(90.*deg);
+						pv = new G4PVPlacement(myRotation, LG_pos, pipe, "LightPipe_PipeX",world,false, j+1, warnOverlap);
+						++j;
+					} else {
+						pv = new G4PVPlacement(0, LG_pos, pipe, "LightPipe_PipeY",world,false, k+1, warnOverlap);
+						++k;
+					}
+					new G4LogicalBorderSurface("CrystalSurface", pv, fExperimentalHall_phys, m_ReflectiveSurface);
+					if(pvLast) {
+						new G4LogicalBorderSurface("CrystalSurface", pvLast, pv, m_ReflectiveSurface);
+						new G4LogicalBorderSurface("CrystalSurface", pv, pvLast, m_ReflectiveSurface);
+					}
+					pvLast = pv;
+#if 0
+					int icrmax = horizontal ? nrow : ncol;
+					for(int icr = 0; icr< icrmax; ++icr) {
+						auto pvDet = horizontal ? physVol.at(icr).at(irc) : physVol.at(irc).at(icr);
+						new G4LogicalBorderSurface("CrystalSurface", pv, pvDet, m_ReflectiveSurface);
+					}
+#endif
+#if 0
+					//
+					// Photodiode
+					G4String NamePD = "PhotoDiode";
+					G4Material* PDMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary("Si");
+					G4Box* solidPhotoDiode = horizontal ?
+						new G4Box(NamePD, 0.5*pipe_thickness, 0.5*pipe_width, 0.5*pd_thickness) :
+						new G4Box(NamePD, 0.5*pipe_width, 0.5*pipe_thickness, 0.5*pd_thickness) ;
+						
+					G4LogicalVolume* logicPD = new G4LogicalVolume(solidPhotoDiode, PDMaterial, NamePD,0,0,0);
+					logicPD->SetSensitiveDetector(m_PDScorer);
+					logicPD->SetVisAttributes(m_VisPD);
+
+					G4RotationMatrix* myRotation = new G4RotationMatrix();
+					if(horizontal) { myRotation->rotateY(90.*deg); }
+					else           { myRotation->rotateX(90.*deg); }
+					//
+					// RIGHT / TOP
+					G4int side = horizontal ? TLightPipeData::Right_t : TLightPipeData::Top_t;
+					G4ThreeVector PD_Pos = horizontal ?
+						G4ThreeVector(pipe_length*0.5 + 0.5*pd_thickness, pipe_center_xy, pipe_center_z) :
+						G4ThreeVector(pipe_center_xy, pipe_length*0.5 + 0.5*pd_thickness, pipe_center_z) ;
+					new G4PVPlacement(myRotation, PD_Pos, logicPD, NamePD, world, false, pdNum, warnOverlap);
+					m_DetectorMap[pdNum++] = make_tuple(side, ilayer, irc);
+					//
+					// LEFT / BOTTOM
+					side = horizontal ? TLightPipeData::Left_t : TLightPipeData::Bottom_t;
+					if(horizontal) { PD_Pos.set(-PD_Pos.x(),+PD_Pos.y(),PD_Pos.z()); }
+					else           { PD_Pos.set(+PD_Pos.x(),-PD_Pos.y(),PD_Pos.z()); }
+					new G4PVPlacement(myRotation, PD_Pos, logicPD, NamePD, world, false, pdNum, warnOverlap);
+					m_DetectorMap[pdNum++] = make_tuple(side, ilayer, irc);
+#endif
+				}
+			};
+			//
+			if(!(ilayer%2)) { // even
+				// even layers get vertical light pipes downstream
+				buildPipe(false, detZ);
+			}
+			buildPipe(true, detZ);
+		} // for(ilayer)
+#endif
+	}
 }
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 // Add Detector branch to the EventTree.
@@ -224,41 +379,249 @@ void LightPipe::InitializeRootOutput(){
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 // Read sensitive part and fill the Root tree.
 // Called at in the EventAction::EndOfEventAvtion
-void LightPipe::ReadSensitive(const G4Event* ){
+void LightPipe::ReadSensitive(const G4Event* event){
   m_Event->Clear();
-
+	return;
   ///////////
   // Calorimeter scorer
-  CalorimeterScorers::PS_Calorimeter* Scorer= (CalorimeterScorers::PS_Calorimeter*) m_LightPipeScorer->GetPrimitive(0);
+  NPS::HitsMap<G4double*>* CaloHitMap;
+  std::map<G4int, G4double**>::iterator Calo_itr;
+
+  G4int CaloCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("LightPipeScorer/Calorimeter");
+  CaloHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(CaloCollectionID));
+
+  // Loop on the Calo map
+#if 0
+  for (Calo_itr = CaloHitMap->GetMap()->begin() ; Calo_itr != CaloHitMap->GetMap()->end() ; Calo_itr++){
 
-  unsigned int size = Scorer->GetMult(); 
-  for(unsigned int i = 0 ; i < size ; i++){
-    double Energy = RandGauss::shoot(Scorer->GetEnergy(i),LightPipe_NS::ResoEnergy);
+    G4double* Info = *(Calo_itr->second);
+    double Energy = RandGauss::shoot(Info[0],LightPipe_NS::ResoEnergy);
     if(Energy>LightPipe_NS::EnergyThreshold){
-      double Time = RandGauss::shoot(Scorer->GetTime(i),LightPipe_NS::ResoTime);
-      int DetectorNbr = Scorer->GetLevel(i)[0];
-      m_Event->SetEnergy(DetectorNbr,Energy);
-      m_Event->SetTime(DetectorNbr,Time); 
+      //double Time = RandGauss::shoot(Info[1],LightPipe_NS::ResoTime);
+      int DetectorNbr = (int) Info[2];
+      m_Event->SetEnergy(0,0,DetectorNbr,Energy);
     }
   }
+#endif
+  // clear map for next event
+  CaloHitMap->clear();
+
+	// PhotoDiode //
+	NPS::HitsMap<G4double*>* PhotoDiodeHitMap;
+	std::map<G4int, G4double**>::iterator PhotoDiode_itr;
+
+	G4int PhotoDiodeCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("PDScorer/PhotoDiode");
+	PhotoDiodeHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(PhotoDiodeCollectionID));
+
+	// Loop on the PhotoDiode map
+	map<int, int> NumberOfOpticalPhoton; // <det no, # photons>
+	for(const auto& hit : *PhotoDiodeHitMap->GetMap()) {
+		G4double* Info = *(hit.second);
+		G4int detectorNumber = Info[7];
+		if(NumberOfOpticalPhoton.find(detectorNumber) == NumberOfOpticalPhoton.end()){
+			NumberOfOpticalPhoton[detectorNumber] = 0;
+		}
+		NumberOfOpticalPhoton[detectorNumber] += Info[8];
+	}
+
+	for(const auto& pd : NumberOfOpticalPhoton) {
+		int det = pd.first; // detector number
+		int numPhoton = pd.second;
+		auto detMap = m_DetectorMap.find(det);
+		if(detMap != m_DetectorMap.end()){
+			const auto& side = get<0>(detMap->second);
+			const auto& layer = get<1>(detMap->second);
+			const auto& row = get<2>(detMap->second);
+			m_Event->SetEnergy(side, layer, row, numPhoton);
+		} else {
+			std::cerr << "WARNING:: Detector number encountered without map! The number is: " << det << "\nSkipping event...\n";
+		}
+	}
+
+	PhotoDiodeHitMap->clear();
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 ////////////////////////////////////////////////////////////////   
-void LightPipe::InitializeScorers() { 
+void LightPipe::InitializeScorers() {
   // This check is necessary in case the geometry is reloaded
-  bool already_exist = false; 
+  bool already_exist = false;
+	vector<G4int> NestingLevel;
+	NestingLevel.push_back(0);
+	NestingLevel.push_back(1);
   m_LightPipeScorer = CheckScorer("LightPipeScorer",already_exist) ;
+	m_PDScorer = CheckScorer("PDScorer",already_exist) ;
 
-  if(already_exist) 
+  if(already_exist) {
     return ;
+	}
 
   // Otherwise the scorer is initialised
   vector<int> level; level.push_back(0);
-  G4VPrimitiveScorer* Calorimeter= new CalorimeterScorers::PS_Calorimeter("Calorimeter",level, 0) ;
+  G4VPrimitiveScorer* Calorimeter= new CalorimeterScorers::PS_Calorimeter("Calorimeter",NestingLevel, 0) ;
   //and register it to the multifunctionnal detector
   m_LightPipeScorer->RegisterPrimitive(Calorimeter);
+
+	G4VPrimitiveScorer* PDScorer =
+		new PHOTODIODESCORERS::PS_PhotoDiode_Rectangle
+		("PhotoDiode",0,GetPipeWidth(0),GetPipeWidth(0),1,1);
+	m_PDScorer->RegisterPrimitive(PDScorer);
+	
   G4SDManager::GetSDMpointer()->AddNewDetector(m_LightPipeScorer) ;
+	G4SDManager::GetSDMpointer()->AddNewDetector(m_PDScorer) ;
+}
+        
+G4Material* LightPipe::CreateScintillatorMaterial() const {
+	// p-Terphenyl
+	// Taken from Proteus, Inc. specs
+	// See here: http://people.physics.tamu.edu/christian/files/p-terphenyl.png
+	//
+	G4double specificGravity = 1.23; // from proteus
+	G4double densityReference = 0.999972*g/cm3; // water @4-deg C [ the standard ]
+	G4double density = specificGravity*densityReference;
+	
+	G4Material* material = new G4Material("p_Terphenyl_Scint", density, 2);
+	material->AddElement(MaterialManager::getInstance()->GetElementFromLibrary("H"), 10);
+	material->AddElement(MaterialManager::getInstance()->GetElementFromLibrary("C"), 14);
+	
+	// Adding Scintillation property:
+	vector<double> energy, scint, fast, slow, rindx, atten;
+	{
+		// Read emission spectrum from datfile (+ add constant parameters)
+		ifstream ifs(gSystem->ExpandPathName("$NPTOOL/NPSimulation/Detectors/LightPipe/p-terphenyl_emission.dat"));
+		if(!ifs.good()){
+			std::cerr << "ERROR: Couldn't open file: \"$NPTOOL/NPSimulation/Detectors/LightPipe/p-terphenyl_emission.dat\"\n";
+			exit(1);
+		}
+		double wl, pr;
+		while(ifs >> wl >> pr) {
+			energy.emplace_back( h_Planck*c_light / (wl*nm) ); // convert to energy
+			scint.emplace_back(pr);   // scintillation probability
+			rindx.emplace_back(1.65); // refractive index
+			fast.emplace_back(3*ns);     // FAST component ???
+			slow.emplace_back(100*ns);   // SLOW component ???
+			atten.emplace_back(4.73*mm); // Attenuation length (from https://arxiv.org/pdf/1305.0442.pdf)
+		}
+	}
+
+	// Set Material Properties
+	G4int numPoints = energy.size();
+	G4MaterialPropertiesTable* MPT = new G4MaterialPropertiesTable();
+	MPT->AddConstProperty("SCINTILLATIONYIELD", 27000/MeV); // from proteus
+	MPT->AddProperty("SCINTILLATION", &energy[0], &scint[0], numPoints);
+	MPT->AddProperty("RINDEX", &energy[0], &rindx[0], numPoints) ;
+	MPT->AddProperty("ABSLENGTH", &energy[0], &atten[0], numPoints);
+	MPT->AddProperty("FASTCOMPONENT", &energy[0], &fast[0], numPoints);
+	MPT->AddProperty("SLOWCOMPONENT", &energy[0], &slow[0], numPoints);
+	MPT->AddConstProperty("RESOLUTIONSCALE", 1.0);
+	MPT->AddConstProperty("FASTTIMECONSTANT", 20*ns); // ?????
+	MPT->AddConstProperty("SLOWTIMECONSTANT", 100*ns); // ?????
+	MPT->AddConstProperty("YIELDRATIO",1.0); // ?????
+	material->SetMaterialPropertiesTable(MPT);
+	return material;
+}
+
+G4Material* LightPipe::CreatePipeMaterial() const {
+	// Bicron BC-482A
+	// https://www.crystals.saint-gobain.com/sites/imdf.crystals.com/files/documents/bc482a-bc484-data-sheet.pdf
+	// https://www.crystals.saint-gobain.com/sites/imdf.crystals.com/files/documents/organics-plastic-scintillators.pdf
+	//
+	G4double density = 1.03*g/cm3;
+	
+	G4Material* material = new G4Material("BC482A_WLS", density, 2);
+	material->AddElement(MaterialManager::getInstance()->GetElementFromLibrary("H"), 10); // H:C ratio - 1.110
+	material->AddElement(MaterialManager::getInstance()->GetElementFromLibrary("C"), 9);
+	
+	// Adding WLS property
+	auto readDatfile = [](const char* fname, vector<double>& energy, vector<double>& abs, vector<double>& emit){
+		ifstream ifs(gSystem->ExpandPathName(fname));
+		if(!ifs.good()) {
+			std::cerr << "ERROR: no file: \"" << fname << "\"\n";
+			exit(1);
+		}
+		// skip header
+		std::string dummy;
+		std::getline(ifs, dummy);
+
+		double wl, pr_a, pr_e;
+		while(ifs >> wl >> pr_a >> pr_e) {
+			energy.emplace_back( h_Planck*c_light / (wl*nm) ); // convert to energy
+			abs.emplace_back(pr_a);   // absorption probability
+			emit.emplace_back(pr_e);  // emission probability
+		}
+		// SORT IN ORDER OF INCREASING ENERGY
+		vector<int> isort(energy.size());
+		vector<double> e0 = energy, pa0 = abs, pe0 = emit;
+		TMath::Sort((int)energy.size(), &energy[0], &isort[0]);
+		for(size_t i=0; i< energy.size(); ++i){
+			energy.at(i) = e0.at(isort.at(i));
+			abs.at(i) = pa0.at(isort.at(i));
+			emit.at(i) = pe0.at(isort.at(i));
+		}
+	};
+	// Absorption & Emission
+	vector<double> energy, p_abs, p_emit;
+	readDatfile("$NPTOOL/NPSimulation/Detectors/LightPipe/BC482A_properties.dat", energy, p_abs, p_emit);
+	//
+	// Absorption is given as a probability, but GEANT4 needs a length
+	// Invert and set the minimum to 0.4336 mm, which is the (measured)
+	// attenuation length for EJ-280 @peak absorption.
+	// This is not exact, but it's close.
+	// For absorption of 0, set attenuation length very long (5 m)
+	for(auto&& p : p_abs) {
+		p = p > 0 ? (0.4336*mm) / p : 5*m;
+	}
+
+	//
+	const size_t numPoints = energy.size();
+	vector<double> rindx(numPoints, 1.59);
+	vector<double> abslength(numPoints, 400*cm); // BULK attenuation length
+	
+	// Set Material Properties
+	G4MaterialPropertiesTable* MPT = new G4MaterialPropertiesTable();
+	MPT->AddProperty("RINDEX", &energy[0], &rindx[0], numPoints);
+	MPT->AddProperty("ABSLENGTH", &energy[0], &abslength[0], numPoints);
+	MPT->AddProperty("WLSABSLENGTH", &energy[0], &p_abs[0], numPoints);
+	MPT->AddProperty("WLSCOMPONENT", &energy[0], &p_emit[0], numPoints);
+	MPT->AddConstProperty("WLSTIMECONSTANT", 12.*ns);
+	MPT->AddConstProperty("WLSMEANNUMBEROFPHOTONS", 0.86);
+
+	material->SetMaterialPropertiesTable(MPT);
+	return material;
+}
+
+G4Material* LightPipe::CreateWrappingMaterial() const {
+	// Teflon (C2F4) -- for now
+	//
+	G4double density = 2.2*g/cm3;
+	
+	G4Material* material = new G4Material("TEFLON", density, 2);
+	material->AddElement(MaterialManager::getInstance()->GetElementFromLibrary("F"), 4); // H:C ratio - 1.110
+	material->AddElement(MaterialManager::getInstance()->GetElementFromLibrary("C"), 2);
+	return material;
+}
+
+G4OpticalSurface* LightPipe::CreateReflectiveSurface() const {
+	G4OpticalSurface* OpticalCrystalSurface = new G4OpticalSurface("CrystalSurface");
+	OpticalCrystalSurface->SetType(dielectric_metal);
+	//polished: smooth perfectly polished surcface
+	//ground: rough surface
+	OpticalCrystalSurface->SetFinish(polished);
+	//unified
+	//glisur
+	OpticalCrystalSurface->SetModel(glisur);
+            
+	G4double pp[] = {0.01*eV, 10*eV};
+	const G4int num = sizeof(pp)/sizeof(G4double);
+	G4double reflectivity[] = {1., 1.};
+	G4double efficiency[] = {1., 1.};
+            
+	G4MaterialPropertiesTable* OpticalCrystalSurfaceProperty = new G4MaterialPropertiesTable();
+            
+	OpticalCrystalSurfaceProperty->AddProperty("REFLECTIVITY",pp,reflectivity,num);
+	OpticalCrystalSurfaceProperty->AddProperty("EFFICIENCY",pp,efficiency,num);
+	OpticalCrystalSurface->SetMaterialPropertiesTable(OpticalCrystalSurfaceProperty);
+	return OpticalCrystalSurface;
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -276,13 +639,13 @@ NPS::VDetector* LightPipe::Construct(){
 //            Registering the construct method to the factory                 //
 ////////////////////////////////////////////////////////////////////////////////
 extern"C" {
-  class proxy_nps_LightPipe{
-    public:
-      proxy_nps_LightPipe(){
-        NPS::DetectorFactory::getInstance()->AddToken("LightPipe","LightPipe");
-        NPS::DetectorFactory::getInstance()->AddDetector("LightPipe",LightPipe::Construct);
-      }
-  };
-
-  proxy_nps_LightPipe p_nps_LightPipe;
+class proxy_nps_LightPipe{
+public:
+	proxy_nps_LightPipe(){
+		NPS::DetectorFactory::getInstance()->AddToken("LightPipe","LightPipe");
+		NPS::DetectorFactory::getInstance()->AddDetector("LightPipe",LightPipe::Construct);
+	}
+};
+
+proxy_nps_LightPipe p_nps_LightPipe;
 }
diff --git a/NPSimulation/Detectors/LightPipe/LightPipe.hh b/NPSimulation/Detectors/LightPipe/LightPipe.hh
index 72d7eb87c156c1e6df57527b80d8654f15a7f22f..9980c8d220a36915901e9bfd29a84dd4259f0ae5 100644
--- a/NPSimulation/Detectors/LightPipe/LightPipe.hh
+++ b/NPSimulation/Detectors/LightPipe/LightPipe.hh
@@ -24,7 +24,8 @@
 // C++ header
 #include <string>
 #include <vector>
-using namespace std;
+#include <tuple>
+#include <map>
 
 // G4 headers
 #include "G4ThreeVector.hh"
@@ -37,81 +38,91 @@ using namespace std;
 #include "TLightPipeData.h"
 #include "NPInputParser.h"
 
+class G4OpticalSurface;
+
 class LightPipe : public NPS::VDetector{
   ////////////////////////////////////////////////////
   /////// Default Constructor and Destructor /////////
   ////////////////////////////////////////////////////
-  public:
-    LightPipe() ;
-    virtual ~LightPipe() ;
-
-    ////////////////////////////////////////////////////
-    /////// Specific Function of this Class ///////////
-    ////////////////////////////////////////////////////
-  public:
-    // Cartesian
-    void AddDetector(G4ThreeVector POS, string Shape);
-    // Spherical
-    void AddDetector(double R,double Theta,double Phi,string Shape);  
-
+public:
+	LightPipe() ;
+	virtual ~LightPipe() ;
 
-    G4LogicalVolume* BuildSquareDetector();
-    G4LogicalVolume* BuildCylindricalDetector();
-  
-  private:
-    G4LogicalVolume* m_SquareDetector;
-    G4LogicalVolume* m_CylindricalDetector;
+	////////////////////////////////////////////////////
+	/////// Specific Function of this Class ///////////
+	////////////////////////////////////////////////////
+public:
+	// Cartesian
+	void AddDetector(G4int nrow, G4int ncol, G4int nlayer, G4double width, G4double thickness, G4double pipe_width, G4double pipe_thickness);
     
-    ////////////////////////////////////////////////////
-    //////  Inherite from NPS::VDetector class /////////
-    ////////////////////////////////////////////////////
-  public:
-    // Read stream at Configfile to pick-up parameters of detector (Position,...)
-    // Called in DetecorConstruction::ReadDetextorConfiguration Method
-    void ReadConfiguration(NPL::InputParser) ;
+	////////////////////////////////////////////////////
+	//////  Inherite from NPS::VDetector class /////////
+	////////////////////////////////////////////////////
+public:
+	// Read stream at Configfile to pick-up parameters of detector (Position,...)
+	// Called in DetecorConstruction::ReadDetextorConfiguration Method
+	void ReadConfiguration(NPL::InputParser) ;
 
-    // Construct detector and inialise sensitive part.
-    // Called After DetecorConstruction::AddDetector Method
-    void ConstructDetector(G4LogicalVolume* world) ;
+	// Construct detector and inialise sensitive part.
+	// Called After DetecorConstruction::AddDetector Method
+	void ConstructDetector(G4LogicalVolume* world) ;
 
-    // Add Detector branch to the EventTree.
-    // Called After DetecorConstruction::AddDetector Method
-    void InitializeRootOutput() ;
+	// Add Detector branch to the EventTree.
+	// Called After DetecorConstruction::AddDetector Method
+	void InitializeRootOutput() ;
 
-    // Read sensitive part and fill the Root tree.
-    // Called at in the EventAction::EndOfEventAvtion
-    void ReadSensitive(const G4Event* event) ;
+	// Read sensitive part and fill the Root tree.
+	// Called at in the EventAction::EndOfEventAvtion
+	void ReadSensitive(const G4Event* event) ;
 
-  public:   // Scorer
-    //   Initialize all Scorer used by the MUST2Array
-    void InitializeScorers() ;
+private:
+	G4Material* m_ScintillatorMaterial;
+	G4Material* m_PipeMaterial;
+	G4Material* m_WrappingMaterial;
+	G4OpticalSurface* m_ReflectiveSurface;
 
-    //   Associated Scorer
-    G4MultiFunctionalDetector* m_LightPipeScorer ;
-    ////////////////////////////////////////////////////
-    ///////////Event class to store Data////////////////
-    ////////////////////////////////////////////////////
-  private:
-    TLightPipeData* m_Event ;
+	G4Material* CreateScintillatorMaterial() const;
+	G4Material* CreatePipeMaterial() const;
+	G4Material* CreateWrappingMaterial() const;
+	G4OpticalSurface* CreateReflectiveSurface() const;
+	
+public:   // Scorer
+	//   Initialize all Scorer used by the MUST2Array
+	void InitializeScorers() ;
 
-    ////////////////////////////////////////////////////
-    ///////////////Private intern Data//////////////////
-    ////////////////////////////////////////////////////
-  private: // Geometry
-    // Detector Coordinate 
-    vector<double>  m_R; 
-    vector<double>  m_Theta;
-    vector<double>  m_Phi; 
-    
-    //   Shape type
-    vector<string> m_Shape ;
-   
-    // Visualisation Attribute
-    G4VisAttributes* m_VisSquare;
-    G4VisAttributes* m_VisCylinder;
+	//   Associated Scorer
+	G4MultiFunctionalDetector* m_LightPipeScorer ;
+	G4MultiFunctionalDetector* m_PDScorer;
+	////////////////////////////////////////////////////
+	///////////Event class to store Data////////////////
+	////////////////////////////////////////////////////
+private:
+	TLightPipeData* m_Event ;
+	std::map<int, std::tuple<int, int, int> > m_DetectorMap; // <detNo, <side, layer, row/col> >
+	
+public:
+	G4int    GetNrow(size_t i)          const { return std::get<0>(m_Detector.at(i)); }
+	G4int    GetNcol(size_t i)          const { return std::get<1>(m_Detector.at(i)); }
+	G4int    GetNlayer(size_t i)        const { return std::get<2>(m_Detector.at(i)); }
+	G4double GetWidth(size_t i)         const { return std::get<3>(m_Detector.at(i)); }
+	G4double GetThickness(size_t i)     const { return std::get<4>(m_Detector.at(i)); }
+	G4double GetPipeWidth(size_t i)     const { return std::get<5>(m_Detector.at(i)); }
+	G4double GetPipeThickness(size_t i) const { return std::get<6>(m_Detector.at(i)); }
+	////////////////////////////////////////////////////
+	///////////////Private intern Data//////////////////
+	////////////////////////////////////////////////////
+private: // Geometry
+	// Detector Coordinate
+	std::vector<std::tuple<G4int, G4int, G4int, G4double, G4double, G4double, G4double> > m_Detector;
+
+private:
+	// Visualisation Attribute
+	G4VisAttributes* m_VisSquare;
+	G4VisAttributes* m_VisPipe;
+	G4VisAttributes* m_VisPD;
 
   // Needed for dynamic loading of the library
-  public:
-    static NPS::VDetector* Construct();
+public:
+	static NPS::VDetector* Construct();
 };
 #endif
diff --git a/NPSimulation/Detectors/LightPipe/WLS_absorption.dat b/NPSimulation/Detectors/LightPipe/WLS_absorption.dat
new file mode 100644
index 0000000000000000000000000000000000000000..ea2dc5dbd125b6154fd71f5bbc8dbdaea8977a63
--- /dev/null
+++ b/NPSimulation/Detectors/LightPipe/WLS_absorption.dat
@@ -0,0 +1,46 @@
+324	0.23543424030519855
+330	0.2797744973266716
+336	0.3568982562212688
+342	0.45794399557184606
+348	0.5720861560960396
+354	0.6423607325337347
+360	0.7237046979297348
+366	0.8169704975047025
+372	0.8954133588231912
+378	0.9457181027326789
+384	0.9901303540388469
+390	0.9955050870093485
+396	0.9538469297065142
+402	0.8898202898772857
+408	0.8584075622446017
+414	0.8364139962860144
+420	0.7851614701046612
+426	0.7082888913779626
+432	0.6392903396510657
+438	0.5515063263380027
+444	0.4256967788043867
+450	0.2415679335503349
+456	0.13310591472926148
+462	0.030562155168096572
+468	0.008148621487096941
+474	0.002747241342357043
+480	0.
+486	0.
+492	0.
+498	0.
+504	0.
+510	0.
+516	0.
+522	0.
+528	0.
+534	0.
+540	0.
+546	0.
+552	0.
+558	0.
+564	0.
+570	0.
+576	0.
+582	0.
+588	0.
+594	0.
diff --git a/NPSimulation/Detectors/LightPipe/WLS_emission.dat b/NPSimulation/Detectors/LightPipe/WLS_emission.dat
new file mode 100644
index 0000000000000000000000000000000000000000..5ead863e4071735e0520bac20d13c7104d18f96f
--- /dev/null
+++ b/NPSimulation/Detectors/LightPipe/WLS_emission.dat
@@ -0,0 +1,46 @@
+324	0.
+330	0.
+336	0.
+342	0.
+348	0.
+354	0.
+360	0.
+366	0.
+372	0.
+378	0.
+384	0.
+390	0.
+396	0.
+402	0.
+408	0.
+414	0.
+420	0.
+426	0.
+432	0.
+438	0.
+444	0.08657197078612922
+450	0.24244440143865642
+456	0.463427444632436
+462	0.8093744108256966
+468	0.9283384225343975
+474	0.9789958445998295
+480	0.9952580190378026
+486	0.9683221897945588
+492	0.8580880346078893
+498	0.695394404265841
+504	0.5420850105165227
+510	0.44045761435208164
+516	0.37538391688413775
+522	0.32514287498636296
+528	0.2727348311625266
+534	0.21490510479855662
+540	0.16099793158878195
+546	0.11888268966239912
+552	0.08963478399179192
+558	0.06809158627158829
+564	0.0527319299208866
+570	0.03171523603459048
+576	0.020248021089946944
+582	0.014252509594427476
+588	0.010999675726623082
+594	0.008252310074156277
diff --git a/NPSimulation/Detectors/LightPipe/WLS_properties.dat b/NPSimulation/Detectors/LightPipe/WLS_properties.dat
new file mode 100644
index 0000000000000000000000000000000000000000..d1993d1bbf5160ca0fde3bd40b9c318efc34832d
--- /dev/null
+++ b/NPSimulation/Detectors/LightPipe/WLS_properties.dat
@@ -0,0 +1,47 @@
+Wavelength:Absorption:Emission/D
+324	0.23543424030519855	0.                  
+330	0.2797744973266716	0.                  
+336	0.3568982562212688	0.                  
+342	0.45794399557184606	0.                  
+348	0.5720861560960396	0.                  
+354	0.6423607325337347	0.                  
+360	0.7237046979297348	0.                  
+366	0.8169704975047025	0.                  
+372	0.8954133588231912	0.                  
+378	0.9457181027326789	0.                  
+384	0.9901303540388469	0.                  
+390	0.9955050870093485	0.                  
+396	0.9538469297065142	0.                  
+402	0.8898202898772857	0.                  
+408	0.8584075622446017	0.                  
+414	0.8364139962860144	0.                  
+420	0.7851614701046612	0.                  
+426	0.7082888913779626	0.                  
+432	0.6392903396510657	0.                  
+438	0.5515063263380027	0.                  
+444	0.4256967788043867	0.08657197078612922 
+450	0.2415679335503349	0.24244440143865642 
+456	0.13310591472926148	0.463427444632436   
+462	0.030562155168096572	0.8093744108256966  
+468	0.008148621487096941	0.9283384225343975  
+474	0.002747241342357043	0.9789958445998295  
+480	0.			0.9952580190378026  
+486	0.			0.9683221897945588  
+492	0.			0.8580880346078893  
+498	0.			0.695394404265841   
+504	0.			0.5420850105165227  
+510	0.			0.44045761435208164 
+516	0.			0.37538391688413775 
+522	0.			0.32514287498636296 
+528	0.			0.2727348311625266  
+534	0.			0.21490510479855662 
+540	0.			0.16099793158878195 
+546	0.			0.11888268966239912 
+552	0.			0.08963478399179192 
+558	0.			0.06809158627158829 
+564	0.			0.0527319299208866  
+570	0.			0.03171523603459048 
+576	0.			0.020248021089946944
+582	0.			0.014252509594427476
+588	0.			0.010999675726623082
+594	0.			0.008252310074156277
diff --git a/NPSimulation/Detectors/LightPipe/p-terphenyl_emission.dat b/NPSimulation/Detectors/LightPipe/p-terphenyl_emission.dat
new file mode 100644
index 0000000000000000000000000000000000000000..911fd86e3b592819efa3fa5f6e107bd40df7c4b4
--- /dev/null
+++ b/NPSimulation/Detectors/LightPipe/p-terphenyl_emission.dat
@@ -0,0 +1,75 @@
+361.445321354552	1.444922829859e-02
+363.533013158026	1.992315208414e-02
+364.607099230735	2.869952020107e-02
+365.934586736136	4.028891270207e-02
+366.827511784590	8.985356445997e-02
+366.261348583594	6.378451194015e-02
+365.727105563070	5.495775945116e-02
+367.906637885795	1.267952419141e-01
+368.982123966420	1.732616789934e-01
+370.072450130948	2.544713850373e-01
+371.160256281229	3.635928111621e-01
+372.695112959061	6.233185502033e-01
+371.718019434732	4.647609552326e-01
+376.097990865051	8.630744205872e-01
+376.469086296499	1.000000000000e+00
+380.495509061244	7.496087058979e-01
+382.834082283160	5.997447928985e-01
+384.493651666098	4.822893537483e-01
+388.027551646199	3.892674207881e-01
+391.648532118639	4.936935058515e-01
+392.715898153355	6.229178224304e-01
+394.292307066117	7.753631725814e-01
+397.402564651012	9.681631000138e-01
+401.972470488523	8.510528339580e-01
+404.372028055235	6.591217885477e-01
+405.966693071214	5.398317811562e-01
+408.375826692067	4.341851531419e-01
+412.195608288497	3.754834092222e-01
+415.889669174122	4.479017417278e-01
+420.794456905001	5.864537571663e-01
+425.369682772591	5.261713873970e-01
+428.389779847734	4.187470504375e-01
+430.391511165200	3.370199593801e-01
+432.729244382367	2.634128119145e-01
+435.922942439021	2.100928551832e-01
+441.537870184918	2.063859494648e-01
+447.182926101154	2.396809152272e-01
+452.266074840458	2.095415871399e-01
+455.798014809477	1.641183146772e-01
+457.388423801394	1.272126261154e-01
+460.140279359942	1.002024376139e-01
+463.331457402348	7.687915721502e-02
+468.408166105241	6.350386965489e-02
+474.543560793774	6.616764087099e-02
+480.143816456717	5.912486759856e-02
+484.190175334178	4.587216052248e-02
+487.721835301614	3.443216612122e-02
+491.759738131266	2.484442744244e-02
+496.309539855112	1.787785615624e-02
+501.894115429403	1.402851166410e-02
+508.004869978624	1.227757393170e-02
+514.108344486685	1.015310425803e-02
+519.689224040079	7.631673360851e-03
+525.266407572576	5.522321716898e-03
+530.837767072145	3.765871563834e-03
+536.425030661633	2.901162607052e-03
+542.543625255181	2.656083660074e-03
+548.662779851895	2.441689797166e-03
+554.776894420114	2.145581012474e-03
+560.883728947172	1.763139708609e-03
+567.004003550218	1.631609711317e-03
+573.125398159597	1.524506269596e-03
+579.255192816468	1.537699988162e-03
+585.381627454342	1.504113933399e-03
+591.514782130211	1.564396165356e-03
+597.640656764919	1.522476355408e-03
+603.771571428122	1.551429813673e-03
+609.908086122988	1.663345549497e-03
+616.039560789357	1.703296236145e-03
+622.174955477890	1.806729639767e-03
+628.309230160091	1.896706428831e-03
+634.442944839125	1.980801015043e-03
+640.574419505495	2.027543975111e-03
+646.709254190862	2.137886140935e-03
+650.970318282232	2.232582668682e-03
diff --git a/NPSimulation/Process/BeamReaction.cc b/NPSimulation/Process/BeamReaction.cc
index b7cf24e0dad55050812cfa12de1bccc001f2f7d5..27158ff4ecf1c7916123d31012d9cab47c6b33b2 100644
--- a/NPSimulation/Process/BeamReaction.cc
+++ b/NPSimulation/Process/BeamReaction.cc
@@ -184,10 +184,17 @@ void NPS::BeamReaction::DoIt(const G4FastTrack& fastTrack,G4FastStep& fastStep)
    
     G4ParticleDefinition* LightName;
 
-    if(m_Reaction.GetUseExInGeant4())
-     LightName = IonTable->GetIon(LightZ, LightA, m_Reaction.GetExcitation3()*MeV);
-    else 
-     LightName = IonTable->GetIon(LightZ, LightA);
+		if(LightZ == 0 && LightA == 1) // neutron is special case
+		{
+			LightName = G4Neutron::Definition();
+		}
+		else
+		{	
+			if(m_Reaction.GetUseExInGeant4())
+				LightName = IonTable->GetIon(LightZ, LightA, m_Reaction.GetExcitation3()*MeV);
+			else 
+				LightName = IonTable->GetIon(LightZ, LightA);
+		}
 
     // Nucleus 4
     G4int HeavyZ = m_Reaction.GetNucleus4()->GetZ() ;