From 7d703cfe09403bb243ed1ce81f58aa5dc7a228a4 Mon Sep 17 00:00:00 2001
From: Pierre Morfouace <pierre.morfouace2@cea.fr>
Date: Thu, 24 Jun 2021 09:31:23 +0200
Subject: [PATCH] * Adding Physics class for sofia active target and Fission
 Fragment class

---
 NPLib/Detectors/Sofia/CMakeLists.txt          |   7 +-
 NPLib/Detectors/Sofia/TSofAtPhysics.cxx       | 273 ++++++++++++++++++
 NPLib/Detectors/Sofia/TSofAtPhysics.h         | 149 ++++++++++
 NPLib/Detectors/Sofia/TSofFissionFragment.cxx |  72 +++++
 NPLib/Detectors/Sofia/TSofFissionFragment.h   |  92 ++++++
 NPLib/Detectors/Sofia/TSofTwimPhysics.cxx     |  42 ++-
 NPLib/Detectors/Sofia/TSofTwimPhysics.h       |   3 +
 Projects/s455/Analysis.cxx                    | 120 +++++++-
 Projects/s455/Analysis.h                      |  10 +
 Projects/s455/calibration.txt                 |   1 +
 Projects/s455/s455.detector                   |   3 +
 11 files changed, 753 insertions(+), 19 deletions(-)
 create mode 100644 NPLib/Detectors/Sofia/TSofAtPhysics.cxx
 create mode 100644 NPLib/Detectors/Sofia/TSofAtPhysics.h
 create mode 100644 NPLib/Detectors/Sofia/TSofFissionFragment.cxx
 create mode 100644 NPLib/Detectors/Sofia/TSofFissionFragment.h

diff --git a/NPLib/Detectors/Sofia/CMakeLists.txt b/NPLib/Detectors/Sofia/CMakeLists.txt
index ad1352bcd..cf621e66f 100644
--- a/NPLib/Detectors/Sofia/CMakeLists.txt
+++ b/NPLib/Detectors/Sofia/CMakeLists.txt
@@ -7,6 +7,7 @@ add_custom_command(OUTPUT TSofTofWPhysicsDict.cxx COMMAND ${CMAKE_BINARY_DIR}/sc
 add_custom_command(OUTPUT TSofMwpcDataDict.cxx COMMAND ${CMAKE_BINARY_DIR}/scripts/build_dict.sh TSofMwpcData.h TSofMwpcDataDict.cxx TSofMwpcData.rootmap libNPSofia.dylib DEPENDS TSofMwpcData.h)
 
 add_custom_command(OUTPUT TSofAtDataDict.cxx COMMAND ${CMAKE_BINARY_DIR}/scripts/build_dict.sh TSofAtData.h TSofAtDataDict.cxx TSofAtData.rootmap libNPSofia.dylib DEPENDS TSofAtData.h)
+add_custom_command(OUTPUT TSofAtPhysicsDict.cxx COMMAND ${CMAKE_BINARY_DIR}/scripts/build_dict.sh TSofAtPhysics.h TSofAtPhysicsDict.cxx TSofAtPhysics.rootmap libNPSofia.dylib DEPENDS TSofAtPhysics.h)
 
 add_custom_command(OUTPUT TSofTrimDataDict.cxx COMMAND ${CMAKE_BINARY_DIR}/scripts/build_dict.sh TSofTrimData.h TSofTrimDataDict.cxx TSofTrimData.rootmap libNPSofia.dylib DEPENDS TSofTrimData.h)
 add_custom_command(OUTPUT TSofTrimPhysicsDict.cxx COMMAND ${CMAKE_BINARY_DIR}/scripts/build_dict.sh TSofTrimPhysics.h TSofTrimPhysicsDict.cxx TSofTrimPhysics.rootmap libNPSofia.dylib DEPENDS TSofTrimPhysics.h)
@@ -16,9 +17,11 @@ add_custom_command(OUTPUT TSofTwimPhysicsDict.cxx COMMAND ${CMAKE_BINARY_DIR}/sc
 
 add_custom_command(OUTPUT TSofBeamIDDict.cxx COMMAND ${CMAKE_BINARY_DIR}/scripts/build_dict.sh TSofBeamID.h TSofBeamIDDict.cxx TSofBeamID.rootmap libNPSofia.dylib DEPENDS TSofBeamID.h)
 
-add_library(NPSofia SHARED TSofSciData.cxx TSofSciDataDict.cxx TSofSciPhysics.cxx TSofSciPhysicsDict.cxx TSofMwpcData.cxx TSofMwpcDataDict.cxx TSofAtData.cxx TSofAtDataDict.cxx TSofTrimData.cxx TSofTrimDataDict.cxx TSofTrimPhysics.cxx TSofTrimPhysicsDict.cxx TSofTwimData.cxx TSofTwimDataDict.cxx TSofTwimPhysics.cxx TSofTwimPhysicsDict.cxx TSofTofWData.cxx TSofTofWDataDict.cxx TSofTofWPhysics.cxx TSofTofWPhysicsDict.cxx TSofBeamID.cxx TSofBeamIDDict.cxx)
+add_custom_command(OUTPUT TSofFissionFragmentDict.cxx COMMAND ${CMAKE_BINARY_DIR}/scripts/build_dict.sh TSofFissionFragment.h TSofFissionFragmentDict.cxx TSofFissionFragment.rootmap libNPSofia.dylib DEPENDS TSofFissionFragment.h)
+
+add_library(NPSofia SHARED TSofSciData.cxx TSofSciDataDict.cxx TSofSciPhysics.cxx TSofSciPhysicsDict.cxx TSofMwpcData.cxx TSofMwpcDataDict.cxx TSofAtData.cxx TSofAtDataDict.cxx TSofAtPhysics.cxx TSofAtPhysicsDict.cxx TSofTrimData.cxx TSofTrimDataDict.cxx TSofTrimPhysics.cxx TSofTrimPhysicsDict.cxx TSofTwimData.cxx TSofTwimDataDict.cxx TSofTwimPhysics.cxx TSofTwimPhysicsDict.cxx TSofTofWData.cxx TSofTofWDataDict.cxx TSofTofWPhysics.cxx TSofTofWPhysicsDict.cxx TSofBeamID.cxx TSofBeamIDDict.cxx TSofFissionFragment.cxx TSofFissionFragmentDict.cxx)
 
 target_link_libraries(NPSofia ${ROOT_LIBRARIES} NPCore NPPhysics)
 
-install(FILES TSofSciData.h TSofSciPhysics.h TSofMwpcData.h TSofAtData.h TSofTrimData.h TSofTrimPhysics.h TSofTwimData.h TSofTwimPhysics.h TSofTofWData.h TSofTofWPhysics.h TSofBeamID.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY})
+install(FILES TSofSciData.h TSofSciPhysics.h TSofMwpcData.h TSofAtData.h TSofAtPhysics.h TSofTrimData.h TSofTrimPhysics.h TSofTwimData.h TSofTwimPhysics.h TSofTofWData.h TSofTofWPhysics.h TSofBeamID.h TSofFissionFragment.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY})
 
diff --git a/NPLib/Detectors/Sofia/TSofAtPhysics.cxx b/NPLib/Detectors/Sofia/TSofAtPhysics.cxx
new file mode 100644
index 000000000..fa6c7f63e
--- /dev/null
+++ b/NPLib/Detectors/Sofia/TSofAtPhysics.cxx
@@ -0,0 +1,273 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2020   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: Pierre Morfouace  contact address: pierre.morfouace2@cea.fr                        *
+ *                                                                           *
+ * Creation Date  : November 2020                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold SofAt Treated  data                               *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+#include "TSofAtPhysics.h"
+
+//   STL
+#include <sstream>
+#include <iostream>
+#include <cmath>
+#include <stdlib.h>
+#include <limits>
+using namespace std;
+
+//   NPL
+#include "RootInput.h"
+#include "RootOutput.h"
+#include "NPDetectorFactory.h"
+#include "NPOptionManager.h"
+
+//   ROOT
+#include "TChain.h"
+
+ClassImp(TSofAtPhysics)
+
+
+  ///////////////////////////////////////////////////////////////////////////
+TSofAtPhysics::TSofAtPhysics()
+  : m_EventData(new TSofAtData),
+  m_PreTreatedData(new TSofAtData),
+  m_EventPhysics(this),
+  m_NumberOfDetectors(0){
+  }
+
+///////////////////////////////////////////////////////////////////////////
+/// A usefull method to bundle all operation to add a detector
+void TSofAtPhysics::AddDetector(TVector3 ){
+  // In That simple case nothing is done
+  // Typically for more complex detector one would calculate the relevant 
+  // positions (stripped silicon) or angles (gamma array)
+  m_NumberOfDetectors++;
+} 
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::AddDetector(double R, double Theta, double Phi){
+  // Compute the TVector3 corresponding
+  TVector3 Pos(R*sin(Theta)*cos(Phi),R*sin(Theta)*sin(Phi),R*cos(Theta));
+  // Call the cartesian method
+  AddDetector(Pos);
+} 
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::BuildSimplePhysicalEvent() {
+  BuildPhysicalEvent();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::BuildPhysicalEvent() {
+
+  PreTreat();
+
+  unsigned int mysizeE = m_PreTreatedData->GetMultiplicity();
+  for (UShort_t e = 0; e < mysizeE ; e++) {
+    if(m_PreTreatedData->GetPileUp(e) != 1 && m_PreTreatedData->GetOverflow(e) != 1){
+      AnodeNbr.push_back(m_PreTreatedData->GetAnodeNbr(e));
+      Energy.push_back(m_PreTreatedData->GetEnergy(e));
+    }
+  }
+
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::PreTreat() {
+  // This method typically applies thresholds and calibrations
+  // Might test for disabled channels for more complex detector
+
+  // clear pre-treated object
+  ClearPreTreatedData();
+
+  // instantiate CalibrationManager
+  static CalibrationManager* Cal = CalibrationManager::getInstance();
+
+  unsigned int mysize = m_EventData->GetMultiplicity();
+  for (unsigned int i = 0; i < mysize ; ++i) {
+    //double Energy = Cal->ApplyCalibration("SofAt/SEC"+NPL::itoa(m_EventData->GetSectionNbr(i))+"_ANODE"+NPL::itoa(m_EventData->GetAnodeNbr(i))+"_ENERGY",m_EventData->GetEnergy(i));
+  
+    m_PreTreatedData->SetAnodeNbr(m_EventData->GetAnodeNbr(i));
+    m_PreTreatedData->SetEnergy(m_EventData->GetEnergy(i));
+    m_PreTreatedData->SetPileUp(m_EventData->GetPileUp(i));
+    m_PreTreatedData->SetOverflow(m_EventData->GetOverflow(i));
+  }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::ReadAnalysisConfig() {
+  bool ReadingStatus = false;
+
+  // path to file
+  string FileName = "./configs/ConfigSofAt.dat";
+
+  // open analysis config file
+  ifstream AnalysisConfigFile;
+  AnalysisConfigFile.open(FileName.c_str());
+
+  if (!AnalysisConfigFile.is_open()) {
+    cout << " No ConfigSofAt.dat found: Default parameter loaded for Analayis " << FileName << endl;
+    return;
+  }
+  cout << " Loading user parameter for Analysis from ConfigSofAt.dat " << endl;
+
+  // Save it in a TAsciiFile
+  TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig();
+  asciiConfig->AppendLine("%%% ConfigSofAt.dat %%%");
+  asciiConfig->Append(FileName.c_str());
+  asciiConfig->AppendLine("");
+  // read analysis config file
+  string LineBuffer,DataBuffer,whatToDo;
+  while (!AnalysisConfigFile.eof()) {
+    // Pick-up next line
+    getline(AnalysisConfigFile, LineBuffer);
+
+    // search for "header"
+    string name = "ConfigSofAt";
+    if (LineBuffer.compare(0, name.length(), name) == 0) 
+      ReadingStatus = true;
+
+    // loop on tokens and data
+    while (ReadingStatus ) {
+      whatToDo="";
+      AnalysisConfigFile >> whatToDo;
+
+      // Search for comment symbol (%)
+      if (whatToDo.compare(0, 1, "%") == 0) {
+        AnalysisConfigFile.ignore(numeric_limits<streamsize>::max(), '\n' );
+      }
+
+      else if (whatToDo=="E_THRESHOLD") {
+        AnalysisConfigFile >> DataBuffer;
+        m_E_Threshold = atof(DataBuffer.c_str());
+        cout << whatToDo << " " << m_E_Threshold << endl;
+      }
+
+      else {
+        ReadingStatus = false;
+      }
+    }
+  }
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::Clear() {
+  AnodeNbr.clear();
+  Energy.clear();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::ReadConfiguration(NPL::InputParser parser) {
+  vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("SofAt");
+  if(NPOptionManager::getInstance()->GetVerboseLevel())
+    cout << "//// " << blocks.size() << " detectors found " << endl; 
+
+  vector<string> cart = {"POS"};
+  vector<string> sphe = {"R","Theta","Phi"};
+
+  for(unsigned int i = 0 ; i < blocks.size() ; i++){
+    if(blocks[i]->HasTokenList(cart)){
+      if(NPOptionManager::getInstance()->GetVerboseLevel())
+        cout << endl << "////  SofAt " << i+1 <<  endl;
+
+      TVector3 Pos = blocks[i]->GetTVector3("POS","mm");
+      AddDetector(Pos);
+    }
+    else if(blocks[i]->HasTokenList(sphe)){
+      if(NPOptionManager::getInstance()->GetVerboseLevel())
+        cout << endl << "////  SofAt " << i+1 <<  endl;
+      double R = blocks[i]->GetDouble("R","mm");
+      double Theta = blocks[i]->GetDouble("Theta","deg");
+      double Phi = blocks[i]->GetDouble("Phi","deg");
+      AddDetector(R,Theta,Phi);
+    }
+    else{
+      cout << "ERROR: check your input file formatting " << endl;
+      exit(1);
+    }
+  }
+
+  ReadAnalysisConfig();
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::AddParameterToCalibrationManager() {
+  CalibrationManager* Cal = CalibrationManager::getInstance();
+
+  for(int sec = 0; sec < m_NumberOfDetectors; sec++){
+    Cal->AddParameter("SofAt","SEC"+NPL::itoa(sec+1)+"_ALIGN","SofAt_SEC"+NPL::itoa(sec+1)+"_ALIGN");
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::InitializeRootInputRaw() {
+  TChain* inputChain = RootInput::getInstance()->GetChain();
+  inputChain->SetBranchStatus("SofAt",  true );
+  inputChain->SetBranchAddress("SofAt", &m_EventData );
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::InitializeRootInputPhysics() {
+  TChain* inputChain = RootInput::getInstance()->GetChain();
+  inputChain->SetBranchAddress("SofAt", &m_EventPhysics);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+void TSofAtPhysics::InitializeRootOutput() {
+  TTree* outputTree = RootOutput::getInstance()->GetTree();
+  outputTree->Branch("SofAt", "TSofAtPhysics", &m_EventPhysics);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//            Construct Method to be pass to the DetectorFactory              //
+////////////////////////////////////////////////////////////////////////////////
+NPL::VDetector* TSofAtPhysics::Construct() {
+  return (NPL::VDetector*) new TSofAtPhysics();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//            Registering the construct method to the factory                 //
+////////////////////////////////////////////////////////////////////////////////
+extern "C"{
+  class proxy_SofAt{
+    public:
+      proxy_SofAt(){
+        NPL::DetectorFactory::getInstance()->AddToken("SofAt","SofAt");
+        NPL::DetectorFactory::getInstance()->AddDetector("SofAt",TSofAtPhysics::Construct);
+      }
+  };
+
+  proxy_SofAt p_SofAt;
+}
+
diff --git a/NPLib/Detectors/Sofia/TSofAtPhysics.h b/NPLib/Detectors/Sofia/TSofAtPhysics.h
new file mode 100644
index 000000000..55fc600bf
--- /dev/null
+++ b/NPLib/Detectors/Sofia/TSofAtPhysics.h
@@ -0,0 +1,149 @@
+#ifndef TSofAtPHYSICS_H
+#define TSofAtPHYSICS_H
+/*****************************************************************************
+ * Copyright (C) 2009-2020   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: Pierre Morfouace  contact address: pierre.morfouace2@cea.fr                        *
+ *                                                                           *
+ * Creation Date  : November 2020                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold SofAt Treated data                                *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+// C++ headers 
+#include <vector>
+#include <map>
+#include <string>
+using namespace std;
+
+// ROOT headers
+#include "TObject.h"
+#include "TH1.h"
+#include "TVector3.h"
+#include "TSpline.h"
+// NPTool headers
+#include "TSofAtData.h"
+#include "NPCalibrationManager.h"
+#include "NPVDetector.h"
+#include "NPInputParser.h"
+
+
+
+class TSofAtPhysics : public TObject, public NPL::VDetector {
+  //////////////////////////////////////////////////////////////
+  // constructor and destructor
+  public:
+    TSofAtPhysics();
+    ~TSofAtPhysics() {};
+
+
+  //////////////////////////////////////////////////////////////
+  // Inherited from TObject and overriden to avoid warnings
+  public: 
+    void Clear();   
+    void Clear(const Option_t*) {};
+
+
+  //////////////////////////////////////////////////////////////
+  // data obtained after BuildPhysicalEvent() and stored in
+  // output ROOT file
+  public:
+    vector<int>      AnodeNbr;
+    vector<double>   Energy;
+
+  /// A usefull method to bundle all operation to add a detector
+  void AddDetector(TVector3 POS); 
+  void AddDetector(double R, double Theta, double Phi); 
+  
+  //////////////////////////////////////////////////////////////
+  // methods inherited from the VDetector ABC class
+  public:
+    // read stream from ConfigFile to pick-up detector parameters
+    void ReadConfiguration(NPL::InputParser);
+
+    // add parameters to the CalibrationManger
+    void AddParameterToCalibrationManager();
+
+    // 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 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 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();
+
+    // clear the raw and physical data objects event by event
+    void ClearEventPhysics() {Clear();}      
+    void ClearEventData()    {m_EventData->Clear();}   
+
+
+  //////////////////////////////////////////////////////////////
+  // specific methods to SofAt array
+  public:
+    // remove bad channels, calibrate the data and apply thresholds
+    void PreTreat();
+
+    // 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();
+
+    // give and external TSofAtData object to TSofAtPhysics. 
+    // needed for online analysis for example
+    void SetRawDataPointer(TSofAtData* rawDataPointer) {m_EventData = rawDataPointer;}
+
+  // objects are not written in the TTree
+  private:
+    TSofAtData*         m_EventData;        //!
+    TSofAtData*         m_PreTreatedData;   //!
+    TSofAtPhysics*      m_EventPhysics;     //!
+
+  // getters for raw and pre-treated data object
+  public:
+    TSofAtData* GetRawData()        const {return m_EventData;}
+    TSofAtData* GetPreTreatedData() const {return m_PreTreatedData;}
+
+  // parameters used in the analysis
+  private:
+    double m_E_Threshold;     //!
+
+  // number of detectors
+  private:
+    int m_NumberOfDetectors;  //!
+
+  // Static constructor to be passed to the Detector Factory
+  public:
+    static NPL::VDetector* Construct();
+
+    ClassDef(TSofAtPhysics,1)  // SofAtPhysics structure
+};
+#endif
diff --git a/NPLib/Detectors/Sofia/TSofFissionFragment.cxx b/NPLib/Detectors/Sofia/TSofFissionFragment.cxx
new file mode 100644
index 000000000..d2b9393d0
--- /dev/null
+++ b/NPLib/Detectors/Sofia/TSofFissionFragment.cxx
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2020   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: Pierre Morfouace  contact address: pierre.morfouace2@cea.fr                        *
+ * Creation Date  : May 2021                                           *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold FissionFragment Raw data                                    *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+#include "TSofFissionFragment.h"
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+using namespace std; 
+
+ClassImp(TSofFissionFragment)
+
+
+//////////////////////////////////////////////////////////////////////
+TSofFissionFragment::TSofFissionFragment() {
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+TSofFissionFragment::~TSofFissionFragment() {
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+void TSofFissionFragment::Clear() {
+  fFF_Z.clear();
+  fFF_Qmax.clear();
+  fFF_AoQ.clear();
+  fFF_A.clear();
+  fFF_Beta.clear();
+  fFF_Gamma.clear();
+  fFF_Brho.clear();
+  
+  fFF_Zsum = -1;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////
+void TSofFissionFragment::Dump() const {
+  // This method is very useful for debuging and worth the dev.
+  cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TSofFissionFragment::Dump()] XXXXXXXXXXXXXXXXX" << endl;
+
+  for(int i=0; i<fFF_Z.size(); i++){
+    cout << "fFF_Z: " << fFF_Z[i] << endl;
+    cout << "fFF_AoQ: " << fFF_AoQ[i] << endl;
+    cout << "fFF_A: " << fFF_A[i] << endl;
+    cout << "fFF_Beta: " << fFF_Beta[i] << endl;
+    cout << "fFF_Gamma: " << fFF_Gamma[i] << endl;
+    cout << "fFF_Brho: " << fFF_Brho[i] << endl;
+  } 
+}
diff --git a/NPLib/Detectors/Sofia/TSofFissionFragment.h b/NPLib/Detectors/Sofia/TSofFissionFragment.h
new file mode 100644
index 000000000..0425f3acd
--- /dev/null
+++ b/NPLib/Detectors/Sofia/TSofFissionFragment.h
@@ -0,0 +1,92 @@
+#ifndef __FissionFragmentDATA__
+#define __FissionFragmentDATA__
+/*****************************************************************************
+ * Copyright (C) 2009-2020   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: Pierre Morfouace  contact address: pierre.morfouace2@cea.fr                        *
+ *                                                                           *
+ * Creation Date  : May 2021                                                 *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This class hold FissionFragment Raw data                                    *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *   
+ *                                                                           *
+ *****************************************************************************/
+
+// STL
+#include <vector>
+using namespace std;
+
+// ROOT
+#include "TObject.h"
+
+class TSofFissionFragment : public TObject {
+  //////////////////////////////////////////////////////////////
+  // data members are hold into vectors in order 
+  // to allow multiplicity treatment
+  private:
+    vector<double> fFF_Z; 
+    vector<double> fFF_Qmax;
+    vector<double> fFF_AoQ;
+    vector<double> fFF_A;
+    vector<double> fFF_Beta;
+    vector<double> fFF_Gamma;
+    vector<double> fFF_Brho;
+    double fFF_Zsum;
+
+  //////////////////////////////////////////////////////////////
+  // Constructor and destructor
+  public: 
+    TSofFissionFragment();
+    ~TSofFissionFragment();
+    
+
+  //////////////////////////////////////////////////////////////
+  // Inherited from TObject and overriden to avoid warnings
+  public:
+    void Clear();
+    void Clear(const Option_t*) {};
+    void Dump() const;
+
+
+  //////////////////////////////////////////////////////////////
+  // Getters and Setters
+  // Prefer inline declaration to avoid unnecessary called of 
+  // frequently used methods
+  // add //! to avoid ROOT creating dictionnary for the methods
+  public:
+    //////////////////////    SETTERS    ////////////////////////
+    inline void SetZsum(double val){fFF_Zsum = val;};//!
+    inline void SetZ(double val){fFF_Z.push_back(val);};//!
+    inline void SetQmax(double val){fFF_Qmax.push_back(val);};//!
+    inline void SetAoQ(double val){fFF_AoQ.push_back(val);};//!
+    inline void SetA(double val){fFF_A.push_back(val);};//!
+    inline void SetBeta(double val){fFF_Beta.push_back(val);};//!
+    inline void SetGamma(double val){fFF_Gamma.push_back(val);};//!
+    inline void SetBrho(double val){fFF_Brho.push_back(val);};//!
+
+    //////////////////////    GETTERS    ////////////////////////
+    inline double GetZsum() const {return fFF_Zsum;}//! 
+    inline double GetZ(int i) const {return fFF_Z[i];}//! 
+    inline double GetQmax(int i) const {return fFF_Qmax[i];}//! 
+    inline double GetAoQ(int i) const {return fFF_AoQ[i];}//! 
+    inline double GetA(int i) const {return fFF_A[i];}//! 
+    inline double GetBeta(int i) const {return fFF_Beta[i];}//! 
+    inline double GetGamma(int i) const {return fFF_Gamma[i];}//! 
+    inline double GetBrho(int i) const {return fFF_Brho[i];}//! 
+
+  //////////////////////////////////////////////////////////////
+  // Required for ROOT dictionnary
+  ClassDef(TSofFissionFragment,1)  // FissionFragment structure
+};
+
+#endif
diff --git a/NPLib/Detectors/Sofia/TSofTwimPhysics.cxx b/NPLib/Detectors/Sofia/TSofTwimPhysics.cxx
index e6081585b..c9cd1b7c3 100644
--- a/NPLib/Detectors/Sofia/TSofTwimPhysics.cxx
+++ b/NPLib/Detectors/Sofia/TSofTwimPhysics.cxx
@@ -103,10 +103,14 @@ void TSofTwimPhysics::BuildPhysicalEvent() {
 
   unsigned int mysizeE = m_PreTreatedData->GetMultiplicity();
   for (UShort_t e = 0; e < mysizeE ; e++) {
-    int SectionNbr = m_PreTreatedData->GetSectionNbr(e);
-    int AnodeNbr   = m_PreTreatedData->GetAnodeNbr(e);
-    double Energy  = m_PreTreatedData->GetEnergy(e);
-    double DT      = m_PreTreatedData->GetDriftTime(e);
+    int SectionNbr  = m_PreTreatedData->GetSectionNbr(e);
+    int AnodeNumber = m_PreTreatedData->GetAnodeNbr(e);
+    double Energy   = m_PreTreatedData->GetEnergy(e);
+    double DT       = m_PreTreatedData->GetDriftTime(e);
+    
+    AnodeSecNbr.push_back(SectionNbr);
+    AnodeNbr.push_back(AnodeNumber);
+    AnodeEnergy.push_back(Energy);
 
     if(SectionNbr==1){
       anode_energy_sec1.push_back(Energy);
@@ -126,6 +130,7 @@ void TSofTwimPhysics::BuildPhysicalEvent() {
     }
   }
 
+  static CalibrationManager* Cal = CalibrationManager::getInstance();
   double Esec1=0;
   double Esec2=0;
   double Esec3=0;
@@ -153,6 +158,8 @@ void TSofTwimPhysics::BuildPhysicalEvent() {
 
   if(Esec1>0){
     Esec1 = Esec1 / anode_energy_sec1.size();
+    Esec1 = Cal->ApplyCalibration("SofTwim/SEC1_ALIGN",Esec1);
+
     DTsec1 = DTsec1 / anode_dt_sec1.size();
     EnergySection.push_back(Esec1);
     DriftTime.push_back(DTsec1);
@@ -160,6 +167,8 @@ void TSofTwimPhysics::BuildPhysicalEvent() {
   }
   if(Esec2>0){
     Esec2 = Esec2 / anode_energy_sec2.size();
+    Esec2 = Cal->ApplyCalibration("SofTwim/SEC2_ALIGN",Esec2);
+
     DTsec2 = DTsec2 / anode_dt_sec2.size();
     EnergySection.push_back(Esec2);
     DriftTime.push_back(DTsec2);
@@ -167,6 +176,8 @@ void TSofTwimPhysics::BuildPhysicalEvent() {
   }
   if(Esec3>0){
     Esec3 = Esec3 / anode_energy_sec3.size();
+    Esec3 = Cal->ApplyCalibration("SofTwim/SEC3_ALIGN",Esec3);
+    
     DTsec3 = DTsec3 / anode_dt_sec3.size();
     EnergySection.push_back(Esec3);
     DriftTime.push_back(DTsec3);
@@ -174,6 +185,8 @@ void TSofTwimPhysics::BuildPhysicalEvent() {
   }
   if(Esec4>0){
     Esec4 = Esec4 / anode_energy_sec4.size();
+    Esec4 = Cal->ApplyCalibration("SofTwim/SEC4_ALIGN",Esec4);
+    
     DTsec4 = DTsec4 / anode_dt_sec4.size();
     EnergySection.push_back(Esec4);
     DriftTime.push_back(DTsec4);
@@ -199,15 +212,17 @@ void TSofTwimPhysics::PreTreat() {
 
   unsigned int mysize = m_EventData->GetMultiplicity();
   for (unsigned int i = 0; i < mysize ; ++i) {
-    double Energy = Cal->ApplyCalibration("SofTwim/SEC"+NPL::itoa(m_EventData->GetSectionNbr(i))+"_ANODE"+NPL::itoa(m_EventData->GetAnodeNbr(i))+"_ENERGY",m_EventData->GetEnergy(i));
-    double DT = Cal->ApplyCalibration("SofTwim/SEC"+NPL::itoa(m_EventData->GetSectionNbr(i))+"_ANODE"+NPL::itoa(m_EventData->GetAnodeNbr(i))+"_TIME",m_EventData->GetDriftTime(i));
+    if(m_EventData->GetPileUp(i) != 1 && m_EventData->GetOverflow(i) != 1){
+      double Energy = Cal->ApplyCalibration("SofTwim/SEC"+NPL::itoa(m_EventData->GetSectionNbr(i))+"_ANODE"+NPL::itoa(m_EventData->GetAnodeNbr(i))+"_ENERGY",m_EventData->GetEnergy(i));
+      double DT = Cal->ApplyCalibration("SofTwim/SEC"+NPL::itoa(m_EventData->GetSectionNbr(i))+"_ANODE"+NPL::itoa(m_EventData->GetAnodeNbr(i))+"_TIME",m_EventData->GetDriftTime(i));
   
-    m_PreTreatedData->SetSectionNbr(m_EventData->GetSectionNbr(i));
-    m_PreTreatedData->SetAnodeNbr(m_EventData->GetAnodeNbr(i));
-    m_PreTreatedData->SetEnergy(Energy);
-    m_PreTreatedData->SetDriftTime(DT);
-    m_PreTreatedData->SetPileUp(m_EventData->GetPileUp(i));
-    m_PreTreatedData->SetOverflow(m_EventData->GetOverflow(i));
+      m_PreTreatedData->SetSectionNbr(m_EventData->GetSectionNbr(i));
+      m_PreTreatedData->SetAnodeNbr(m_EventData->GetAnodeNbr(i));
+      m_PreTreatedData->SetEnergy(Energy);
+      m_PreTreatedData->SetDriftTime(DT);
+      m_PreTreatedData->SetPileUp(m_EventData->GetPileUp(i));
+      m_PreTreatedData->SetOverflow(m_EventData->GetOverflow(i));
+    }
   }
 }
 
@@ -301,6 +316,9 @@ void TSofTwimPhysics::Clear() {
   SectionNbr.clear();
   EnergySection.clear();
   DriftTime.clear();
+  AnodeNbr.clear();
+  AnodeSecNbr.clear();
+  AnodeEnergy.clear();
 }
 
 
diff --git a/NPLib/Detectors/Sofia/TSofTwimPhysics.h b/NPLib/Detectors/Sofia/TSofTwimPhysics.h
index aaa6a00c7..9e90e16ce 100644
--- a/NPLib/Detectors/Sofia/TSofTwimPhysics.h
+++ b/NPLib/Detectors/Sofia/TSofTwimPhysics.h
@@ -63,6 +63,9 @@ class TSofTwimPhysics : public TObject, public NPL::VDetector {
     vector<int>      SectionNbr;
     vector<double>   EnergySection;
     vector<double>   DriftTime;
+    vector<int>      AnodeNbr;
+    vector<int>      AnodeSecNbr;
+    vector<double>   AnodeEnergy;
 
   /// A usefull method to bundle all operation to add a detector
   void AddDetector(TVector3 POS); 
diff --git a/Projects/s455/Analysis.cxx b/Projects/s455/Analysis.cxx
index 1f8b2a72e..a92862dbc 100644
--- a/Projects/s455/Analysis.cxx
+++ b/Projects/s455/Analysis.cxx
@@ -37,15 +37,17 @@ Analysis::~Analysis(){
 ////////////////////////////////////////////////////////////////////////////////
 void Analysis::Init(){
   SofBeamID = new TSofBeamID();
+  SofFF = new TSofFissionFragment();
   SofSci= (TSofSciPhysics*) m_DetectorManager->GetDetector("SofSci");
   SofTrim= (TSofTrimPhysics*) m_DetectorManager->GetDetector("SofTrim");
   SofTwim= (TSofTwimPhysics*) m_DetectorManager->GetDetector("SofTwim");
   SofTofW= (TSofTofWPhysics*) m_DetectorManager->GetDetector("SofTofW");
+  SofAt= (TSofAtPhysics*) m_DetectorManager->GetDetector("SofAt");
 
   InitParameter();
   InitOutputBranch();
   LoadCut();
-
+  LoadSpline();
 
 }
 
@@ -54,6 +56,7 @@ void Analysis::TreatEvent(){
   ReInitValue();
   //cout << "************" << endl;
   BeamAnalysis();
+
   unsigned int sofsci_size = SofSci->DetectorNbr.size();
   if(sofsci_size==2){
     double start_time = SofSci->TimeNs[1];
@@ -61,6 +64,92 @@ void Analysis::TreatEvent(){
     SofTofW->SetStartTime(start_time);
     SofTofW->BuildPhysicalEvent();
   }
+
+  FissionFragmentAnalysis();
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Analysis::FissionFragmentAnalysis(){
+  unsigned int softofw_size = SofTofW->PlasticNbr.size();
+  unsigned int softwim_size = SofTwim->SectionNbr.size();
+
+  double TOF_CC[2];
+  double Plastic[2];
+  double TOF_left = -1;
+  double TOF_right = -1;
+  double Esec[2];
+  double Section[2];
+  double E_left = -1;
+  double E_right = -1;
+  double E1 = -1;
+  double E2 = -1;
+  double E3 = -1;
+  double E4 = -1;
+  double L_CC = 8.;
+  double Beta_left;
+  double Beta_right;
+  double Beta_norm = 0.7;
+
+  for(int i = 0; i<2; i++){
+    TOF_CC[i] = -1;
+    Plastic[i] = -1;
+    Esec[i] = -1;
+    Section[i] = -1;
+  }
+
+
+  if(softofw_size==2 && softwim_size==2){ 
+    for(unsigned int i=0; i< softofw_size; i++){
+      TOF_CC[i] = SofTofW->CalTof[i];
+      Plastic[i] = SofTofW->PlasticNbr[i];
+
+      Esec[i] = SofTwim->EnergySection[i];
+      int sec = SofTwim->SectionNbr[i];
+      Section[i] = sec;
+
+      if(sec==1)
+        E1 = SofTwim->EnergySection[i];
+      else if(sec==2)
+        E2 = SofTwim->EnergySection[i];
+      else if(sec==3)
+        E3 = SofTwim->EnergySection[i]; 
+      else if(sec==4)
+        E4 = SofTwim->EnergySection[i];     
+    }
+  }
+
+  if(Plastic[0]<Plastic[1]){
+    TOF_left = TOF_CC[0];
+    TOF_right = TOF_CC[1];
+  }
+  else{
+    TOF_left = TOF_CC[1];
+    TOF_right = TOF_CC[0];
+  }
+
+  if(TOF_left != -1 && TOF_right != -1 && abs(Plastic[0]-Plastic[1]) != 1){
+    double velocity_left = L_CC/TOF_left;
+    double velocity_right = L_CC/TOF_right;
+
+    Beta_left = velocity_left * m/ns / NPUNITS::c_light;
+    Beta_right = velocity_right * m/ns / NPUNITS::c_light;
+
+    /*E1 = E1 / fcorr_z_beta[0]->Eval(Beta_left) * fcorr_z_beta[0]->Eval(Beta_norm);
+    E2 = E2 / fcorr_z_beta[1]->Eval(Beta_left) * fcorr_z_beta[1]->Eval(Beta_norm);
+    E3 = E3 / fcorr_z_beta[2]->Eval(Beta_right) * fcorr_z_beta[2]->Eval(Beta_norm);
+    E4 = E4 / fcorr_z_beta[3]->Eval(Beta_right) * fcorr_z_beta[3]->Eval(Beta_norm);
+*/
+    double Zsum = E_left + E_right;
+
+    SofFF->SetBeta(Beta_left);
+    SofFF->SetBeta(Beta_right);
+    SofFF->SetZ(E1);
+    SofFF->SetZ(E2);
+    SofFF->SetZ(E3);
+    SofFF->SetZ(E4);
+    SofFF->SetZsum(Zsum);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -137,6 +226,27 @@ void Analysis::LoadCut(){
   }
 }
 
+
+////////////////////////////////////////////////////////////////////////////////
+void Analysis::LoadSpline(){
+  TString input_path = "./calibration/SofTwim/spline/";
+
+  TString rootfile = input_path + "spline_beta.root";
+  TFile* ifile = new TFile(rootfile,"read");
+
+  TString splinename;
+  if(ifile->IsOpen()){
+    cout << "Loading Beta spline for fission fragment analysis..." << endl;
+    for(int i=0; i<4; i++){
+      splinename = Form("spline_beta_sec%i",i+1);
+      fcorr_z_beta[i] = (TSpline3*) ifile->FindObjectAny(splinename);
+    }
+    ifile->Close();
+  }
+  else
+    cout << "File " << rootfile << " not found!" << endl;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 int Analysis::DetermineQmax(){
   int Qmax;
@@ -171,23 +281,23 @@ void Analysis::End(){
 ////////////////////////////////////////////////////////////////////////////////
 void Analysis::InitParameter(){
   fLS2_0 = 136.3706933;
-  //fDS2   = 9500;
-  fDS2   = 10000;
+  fDS2   = 9500;
   //fDCC   = -30000;
-  fDCC   = -40000;
+  fDCC   = -10000;
   fK_LS2 = -2.5e-8;
   fBrho0 = 10.8183; // run401 -> 182Hg
-
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void Analysis::ReInitValue(){
   SofBeamID->Clear();
+  SofFF->Clear();
 }
 ////////////////////////////////////////////////////////////////////////////////
 void Analysis::InitOutputBranch(){
   //RootOutput::getInstance()->GetTree()->Branch("Zbeam",&Zbeam,"Zbeam/D");
   RootOutput::getInstance()->GetTree()->Branch("SofBeamID","TSofBeamID",&SofBeamID);
+  RootOutput::getInstance()->GetTree()->Branch("SofFissionFragment","TSofFissionFragment",&SofFF);
 
 }
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/Projects/s455/Analysis.h b/Projects/s455/Analysis.h
index 32a97cef9..747011bf9 100644
--- a/Projects/s455/Analysis.h
+++ b/Projects/s455/Analysis.h
@@ -23,14 +23,17 @@
 // Root
 #include "TCutG.h"
 #include "TRandom3.h"
+#include "TSpline.h"
 
 // NPTool
 #include"NPVAnalysis.h"
 #include"TSofTofWPhysics.h"
 #include"TSofTrimPhysics.h"
+#include"TSofAtPhysics.h"
 #include"TSofTwimPhysics.h"
 #include"TSofSciPhysics.h"
 #include"TSofBeamID.h"
+#include"TSofFissionFragment.h"
 
 class Analysis: public NPL::VAnalysis{
   public:
@@ -45,19 +48,23 @@ class Analysis: public NPL::VAnalysis{
     void InitParameter();
     void ReInitValue();
     void BeamAnalysis();
+    void FissionFragmentAnalysis();
 
     static NPL::VAnalysis* Construct();
 
   public:
     void LoadCut();
+    void LoadSpline();
     int DetermineQmax();
 
   private:
     TSofSciPhysics* SofSci;
     TSofTrimPhysics* SofTrim;
+    TSofAtPhysics* SofAt;
     TSofTwimPhysics* SofTwim;
     TSofTofWPhysics* SofTofW;
     TSofBeamID* SofBeamID;
+    TSofFissionFragment* SofFF;
 
   private:
     double fLS2_0; 
@@ -71,5 +78,8 @@ class Analysis: public NPL::VAnalysis{
     TCutG* cutQ79[3];
     TCutG* cutQ80[3];
     TCutG* cutQ81[3];
+    
+    TSpline3* fcorr_z_beta[4];
+
 };
 #endif
diff --git a/Projects/s455/calibration.txt b/Projects/s455/calibration.txt
index d77958d2c..97c363264 100644
--- a/Projects/s455/calibration.txt
+++ b/Projects/s455/calibration.txt
@@ -14,6 +14,7 @@ CalibrationFilePath
 ./calibration/SofSci/SofSci_physics.cal
 ./calibration/SofTwim/SofTwim_Energy.cal
 ./calibration/SofTwim/SofTwim_Time.cal
+./calibration/SofTwim/SofTwim_Align.cal
 ./calibration/SofTofW/ClockOffset.cal
 ./calibration/SofTofW/SofTofW_physics.cal
 ./calibration/SofTofW/VFTX_TOFW1_PMT1.cal
diff --git a/Projects/s455/s455.detector b/Projects/s455/s455.detector
index 3cb3ec2ce..58296af6c 100644
--- a/Projects/s455/s455.detector
+++ b/Projects/s455/s455.detector
@@ -14,6 +14,9 @@ SofSci
 SofSci
  POS= 0 0 0 m
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+SofAt
+ POS= 0 0 200
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 SofTrim
  POS= 0 0 -500
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-- 
GitLab