Skip to content
Snippets Groups Projects
TNebulaPhysics.cxx 11.3 KiB
Newer Older
/*****************************************************************************
 * Copyright (C) 2009-2019   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: Adrien Matta  contact address: matta@lpccaen.in2p3.fr    *
 *                                                                           *
 * Creation Date  : December 2019                                            *
 * Last update    :                                                          *
 *---------------------------------------------------------------------------*
 * Decription:                                                               *
 *  This class hold Nebula Treated data                                      *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * Comment:                                                                  *
 *                                                                           *   
 *                                                                           *
 *****************************************************************************/

#include "TNebulaPhysics.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"
Adrien Matta's avatar
Adrien Matta committed
#include "NPSystemOfUnits.h"
//   ROOT
#include "TChain.h"

ClassImp(TNebulaPhysics)


Adrien Matta's avatar
Adrien Matta committed
  ///////////////////////////////////////////////////////////////////////////
TNebulaPhysics::TNebulaPhysics()
Adrien Matta's avatar
Adrien Matta committed
  : m_EventData(new TNebulaData),
  m_EventPhysics(this),
  m_Spectra(0),
  m_Q_RAW_Threshold(0), // adc channels
  m_Q_Threshold(7),     // normal bars in MeV
  m_V_Threshold(1),     // veto bars in MeV
  m_NumberOfBars(0) {
  }

///////////////////////////////////////////////////////////////////////////
/// A usefull method to bundle all operation to add a detector
void TNebulaPhysics::ReadXML(NPL::XmlParser xml){ 
Adrien Matta's avatar
Adrien Matta committed
  std::vector<NPL::XML::block*> b = xml.GetAllBlocksWithName("NEBULA");  

  for(unsigned int i = 0 ; i < b.size() ; i++){
    m_NumberOfBars++;
    unsigned int id = b[i]->AsInt("ID");

    // position
    PositionX[id] = b[i]->AsDouble("PosX"); 
    PositionY[id] = b[i]->AsDouble("PosY"); 
    PositionZ[id] = b[i]->AsDouble("PosZ"); 
    // linear cal
    aQu[id] = b[i]->AsDouble("QUCal");
    bQu[id] = b[i]->AsDouble("QUPed");
    aQd[id] = b[i]->AsDouble("QDCal");
    bQd[id] = b[i]->AsDouble("QDPed");
    aTu[id] = b[i]->AsDouble("TUCal");
    bTu[id] = b[i]->AsDouble("TUOff");
    aTd[id] = b[i]->AsDouble("TDCal");
    bTd[id] = b[i]->AsDouble("TDOff");

    // T average offset
    avgT0[id] = b[i]->AsDouble("TAveOff");

    // slew correction T= tcal +slwT/sqrt(Qcal)
    slwTu[id] = b[i]->AsDouble("TUSlw");
    slwTd[id] = b[i]->AsDouble("TDSlw");

    // DT position cal
    DTa[id] = b[i]->AsDouble("DTCal");//!
    DTb[id] = b[i]->AsDouble("DTOff");//!


  } 
  cout << " -> " << m_NumberOfBars << " bars found" << endl;;
} 

///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::BuildSimplePhysicalEvent() {
  BuildPhysicalEvent();
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::BuildPhysicalEvent() {
  // apply thresholds and calibration

  // instantiate CalibrationManager
  static CalibrationManager* Cal = CalibrationManager::getInstance();
Adrien Matta's avatar
Adrien Matta committed
  static double rawQup,calQup,rawQdown,calQdown,rawTup,calTup,rawTdown,calTdown,calQ,calT,Y;
  static unsigned int ID;
  // All vector size 
  static unsigned int QUsize, QDsize, TUsize, TDsize ; 
  QUsize = m_EventData->GetChargeUpMult();
  QDsize = m_EventData->GetChargeDownMult();
  TUsize = m_EventData->GetTimeUpMult();
  TDsize = m_EventData->GetTimeDownMult();
  static double threshold;
  // loop on Qup
  for (unsigned int qup = 0; qup < QUsize ; qup++) {
    rawQup = m_EventData->GetChargeUp(qup);
    rawTup=-1;
    rawQdown=-1;
    rawTdown=-1;
    if (rawQup > m_Q_RAW_Threshold) {
      ID = m_EventData->GetChargeUpID(qup);
      if(ID<121)
        threshold=m_Q_Threshold;
      else
        threshold=m_V_Threshold;

      // look for associated Charge down
      for(unsigned int qdown = 0 ; qdown < QDsize ; qdown++){
        if(m_EventData->GetChargeDownID(qdown)==ID){
          rawQdown=m_EventData->GetChargeDown(qdown); 
          if(rawQdown > m_Q_RAW_Threshold){
            // Look for the associate time 
            for(unsigned int tdown = 0 ; tdown < TDsize; tdown++){
              if(m_EventData->GetTimeDownID(qdown)==ID) {
                rawTdown=m_EventData->GetTimeDown(qdown);
                break;
              }
            }// TDown
          }//if raw threshold down

          break;
        } //if match ID 

      }// Qdwown 

      if(rawTdown>0){ // Tdown is found, means Qdown as well
        // look for Tup  
        for(unsigned int tup = 0 ; tup < TUsize ; tup++){
          if(m_EventData->GetTimeUpID(tup)==ID){
            rawTup = m_EventData->GetTimeUp(tup);
            break;
          }
        }
      }
      // Got everything, do the math
      if(rawTup>0){
        //std::cout << "Hello 2"  << std::endl;
Adrien Matta's avatar
Adrien Matta committed
        // cal Q Up and Down
Adrien Matta's avatar
Adrien Matta committed
        calQup=aQu[ID]*(rawQup-bQu[ID]);
        calQdown=aQd[ID]*(rawQdown-bQd[ID]);
Adrien Matta's avatar
Adrien Matta committed
        
        // average value of Up and Down
        calQ=sqrt(calQup*calQdown); 

        // cal T  Up
Adrien Matta's avatar
Adrien Matta committed
        calTup=aTu[ID]*rawTup+bTu[ID];
        // slew correction
        calTup -= slwTu[ID]/sqrt(rawQup-bQu[ID]);

Adrien Matta's avatar
Adrien Matta committed
        // cal T Down
Adrien Matta's avatar
Adrien Matta committed
        calTdown=aTd[ID]*rawTdown+bTd[ID];
        // slew correction
        calTdown -= slwTd[ID]/sqrt(rawQdown-bQd[ID]);

        //std::cout << calQ  << " " << threshold << std::endl;
Adrien Matta's avatar
Adrien Matta committed
        if(calQ>threshold){

        //std::cout << "Hello 3"  << std::endl;
Adrien Matta's avatar
Adrien Matta committed
          calT= (calTdown+calTup)*0.5+avgT0[ID]+Cal->GetPedestal("NEBULA_T_ID"+NPL::itoa(ID)); 
          Y=(calTdown-calTup)*DTa[ID]+DTb[ID]+Cal->GetPedestal("NEBULA_Y_ID"+NPL::itoa(ID));

          DetectorNumber.push_back(ID);
          Charge.push_back(calQ);
          TOF.push_back(calT);
          PosY.push_back(Y+PositionY[ID]);
          PosX.push_back(PositionX[ID]);
          PosZ.push_back(PositionZ[ID]);

Adrien Matta's avatar
Adrien Matta committed
          if(ID<121)
Adrien Matta's avatar
Adrien Matta committed
            IsVeto.push_back(0);
          else
            IsVeto.push_back(1);

        }
Adrien Matta's avatar
Adrien Matta committed
    }// if raw threshold up
  } // Qup
}

///////////////////////////////////////////////////////////////////////////
Adrien Matta's avatar
Adrien Matta committed
void TNebulaPhysics::PreTreat() {
Adrien Matta's avatar
Adrien Matta committed
}
Adrien Matta's avatar
Adrien Matta committed
///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::ReadAnalysisConfig() {
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::Clear() {
  DetectorNumber.clear();
Adrien Matta's avatar
Adrien Matta committed
  Charge.clear();
  TOF.clear();
  PosY.clear();
  PosX.clear();
  PosZ.clear();
  IsVeto.clear();
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::ReadConfiguration(NPL::InputParser parser) {
  vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("NEBULA");
  if(NPOptionManager::getInstance()->GetVerboseLevel())
    cout << "//// " << blocks.size() << " detector(s) found " << endl; 
  vector<string> token= {"XML","Offset","InvertX","InvertY"};

  for(unsigned int i = 0 ; i < blocks.size() ; i++){
    if(blocks[i]->HasTokenList(token)){
      cout << endl << "////  Nebula (" << i+1 << ")" << endl;
      unsigned int det = std::atoi(blocks[i]->GetMainValue().c_str());
      string xmlpath = blocks[i]->GetString("XML");
      NPL::XmlParser xml;
      xml.LoadFile(xmlpath);
      ReadXML(xml);
      TVector3 offset = blocks[i]->GetTVector3("Offset","mm"); 
      bool invertX = blocks[i]->GetInt("InvertX"); 
      bool invertY = blocks[i]->GetInt("InvertY"); 
      m_offset[det] = offset;
      m_invertX[det] = invertX;
      m_invertY[det] = invertY;
    }
  }
}

///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::InitSpectra() {
  m_Spectra = new TNebulaSpectra(m_NumberOfBars);
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::FillSpectra() {
  m_Spectra -> FillRawSpectra(m_EventData);
  m_Spectra -> FillPhysicsSpectra(m_EventPhysics);
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::CheckSpectra() {
  m_Spectra->CheckSpectra();
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::ClearSpectra() {
  // To be done
}



///////////////////////////////////////////////////////////////////////////
map< string , TH1*> TNebulaPhysics::GetSpectra() {
  if(m_Spectra)
    return m_Spectra->GetMapHisto();
  else{
    map< string , TH1*> empty;
    return empty;
  }
}

///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::WriteSpectra() {
  m_Spectra->WriteSpectra();
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::AddParameterToCalibrationManager() {
  CalibrationManager* Cal = CalibrationManager::getInstance();
Adrien Matta's avatar
Adrien Matta committed

  vector<double> standardO={0};
  for (int i = 0; i < m_NumberOfBars; ++i) {
Adrien Matta's avatar
Adrien Matta committed
    Cal->AddParameter("NEBULA_T_ID"+ NPL::itoa(i+1),standardO);
    Cal->AddParameter("NEBULA_Y_ID"+ NPL::itoa(i+1),standardO);
  }
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::InitializeRootInputRaw() {
  TChain* inputChain = RootInput::getInstance()->GetChain();
  inputChain->SetBranchStatus("Nebula",  true );
  inputChain->SetBranchAddress("Nebula", &m_EventData );
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::InitializeRootInputPhysics() {
  TChain* inputChain = RootInput::getInstance()->GetChain();
  inputChain->SetBranchAddress("Nebula", &m_EventPhysics);
}



///////////////////////////////////////////////////////////////////////////
void TNebulaPhysics::InitializeRootOutput() {
  TTree* outputTree = RootOutput::getInstance()->GetTree("Nebula");
  outputTree->Branch("Nebula", "TNebulaPhysics", &m_EventPhysics);
}



////////////////////////////////////////////////////////////////////////////////
//            Construct Method to be pass to the DetectorFactory              //
////////////////////////////////////////////////////////////////////////////////
NPL::VDetector* TNebulaPhysics::Construct() {
  return (NPL::VDetector*) new TNebulaPhysics();
}



////////////////////////////////////////////////////////////////////////////////
//            Registering the construct method to the factory                 //
////////////////////////////////////////////////////////////////////////////////
extern "C"{
Adrien Matta's avatar
Adrien Matta committed
  class proxy_Nebula{
    public:
      proxy_Nebula(){
        NPL::DetectorFactory::getInstance()->AddToken("NEBULA","Nebula");
        NPL::DetectorFactory::getInstance()->AddDetector("NEBULA",TNebulaPhysics::Construct);
      }
  };
Adrien Matta's avatar
Adrien Matta committed
  proxy_Nebula p_Nebula;