Skip to content
Snippets Groups Projects
Select Git revision
  • 655dcada152d03949f6bf6ae9c2055d2a4636866
  • master default protected
  • nightly_master
  • online_much_readconf_cleanup protected
  • online_mvd_readconf_cleanup protected
  • jul25_patches
  • cleanup_rich_v25a
  • jul24_patches
  • nov23_patches
  • DC_2404
  • nighly_master
  • DC_Jan24
  • DC_Nov23
  • DC_Oct23
  • feb23_patches
  • L1Algo-dev9
  • dec21_patches protected
  • apr21_patches protected
  • dev_2025_48
  • dev_2025_47
  • RC2_jul25
  • dev_2025_46
  • dev_2025_45
  • dev_2025_44
  • dev_2025_43
  • dev_2025_42
  • dev_2025_41
  • dev_2025_40
  • dev_2025_39
  • dev_2025_38
  • dev_2025_37
  • dev_2025_36
  • dev_2025_35
  • dev_2025_34
  • dev_2025_33
  • dev_2025_32
  • dev_2025_31
  • dev_2025_30
38 results

CbmRadDamage.cxx

Blame
  • CbmRadDamage.cxx 6.28 KiB
    /* Copyright (C) 2011-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
       SPDX-License-Identifier: GPL-3.0-only
       Authors: Volker Friese [committer], Florian Uhlig */
    
    /** @file CbmRadDamage.cxx
     ** @author Volker Friese <v.friese@gsi.de>
     ** @date 6 December 2011
     **/
    #include "CbmRadDamage.h"
    
    #include <Logger.h>  // for LOG
    
    #include <TMath.h>      // for Exp, Qe, K
    #include <TMathBase.h>  // for Abs
    #include <TString.h>    // for TString, operator+, operator<<
    
    #include <stdlib.h>  // for getenv
    
    
    // =====   Constructor   ==================================================
    CbmRadDamage::CbmRadDamage()
      : niel_neutron()
      , niel_proton()
      , niel_pion()
      , niel_electron()
      , fIAlpha(4.e-17)
      , fEGap0(1.166)
      , fEGapAlpha(4.73e-4)
      , fEGapBeta(636.)
      , fNeff0(9.0e11)
      , fNeffC(2.5e-14)
      , fNeffGc(1.5e-2)
      , fEpsilon(1.04e-12)
    {
      Init();
    }
    // ========================================================================
    
    
    // =====   Destructor   ===================================================
    CbmRadDamage::~CbmRadDamage() {}
    // ========================================================================
    
    
    // =====   Get leakage current   ==========================================
    Double_t CbmRadDamage::GetLeakageCurrent(Double_t fluence, Double_t volume, Double_t temperature)
    {
    
      // --- Boltzmann constant in ev/K
      Double_t kB = TMath::K() / TMath::Qe();
    
      // --- Leakage current at room temperature (293 K)
      Double_t i20 = fIAlpha * fluence * volume;
    
      // --- Gap energy at given temperature
      Double_t eGap = fEGap0 - fEGapAlpha * temperature * temperature / (temperature + fEGapBeta);
    
      // --- Leakage current at given temperature
      Double_t exponent = -1. * eGap / 2. / kB * (1. / temperature - 1. / 293.);
      Double_t iLeak    = i20 * temperature * temperature / 85849. * TMath::Exp(exponent);
    
      return iLeak;
    }
    // ========================================================================
    
    
    // =====   Get NIEL factor   ==============================================
    Double_t CbmRadDamage::GetNiel(Int_t type, Double_t energy)
    {
    
      // Convert energy to MeV like in table
      energy = energy * 1000.;
    
      std::map<Double_t, Double_t>* table = nullptr;
      Int_t atype                         = TMath::Abs(type);
    
      // Select table according to particle type
      switch (atype) {
        case 2112: table = &niel_neutron; break;  // neutrons
        case 2212: table = &niel_proton; break;   // protons
        case 211: table = &niel_pion; break;      // pions
        case 11: table = &niel_electron; break;   // electrons
        default: table = nullptr;
      }
    
      // Return zero for unknown particles
      if (!table) return 0.;
    
      // First table entry above selected energy
      std::map<Double_t, Double_t>::iterator it = table->upper_bound(energy);
    
      // Return zero if below lower limit
      if (it == table->begin()) {
        //LOG(warn) << "-I- Below table limit: " << atype << "  " << energy;
        return 0.;
      }
    
      // Return asymptotic value if above upper limit
      if (it == table->end()) {
        //LOG(warn) << "-I- Above table limit: " << atype << "  " << energy;
        switch (atype) {
          case 2112: return 0.44; break;
          case 2212: return 0.50; break;
          case 211: return 0.38; break;
          case 11: return 0.08; break;
          default: return 0.00; break;
        }
      }
    
      // Interpolate within table values
      Double_t e2 = (*it).first;
      Double_t v2 = (*it).second;
      it--;
      Double_t e1 = (*it).first;
      Double_t v1 = (*it).second;
    
      Double_t v = v1 + (v2 - v1) * (energy - e1) / (e2 - e1);
    
      return v;
    }
    // ========================================================================
    
    
    // =====   Get full depletion voltage   ===================================
    Double_t CbmRadDamage::GetVfd(Double_t fluence, Double_t d)
    {
    
      // --- Calculate effective doping concentration at given fluence
      Double_t corr1 = 0.7 * fNeff0 * (1. - TMath::Exp(-1. * fNeffC * fluence));
      Double_t corr2 = fNeffGc * fluence;
      Double_t nEff  = fNeff0 - corr1 - corr2;
    
      // --- Calculate full depletion voltage from doping concentration
      Double_t vfd = TMath::Qe() * nEff * d * d / 2. / fEpsilon;
    
      return vfd;
    }
    // ========================================================================
    
    
    // =====   Private method Init   ==========================================
    void CbmRadDamage::Init()
    {
    
      // --- Read NIEL tables
      ReadData("niel_neutrons.dat", niel_neutron);
      ReadData("niel_protons.dat", niel_proton);
      ReadData("niel_pions.dat", niel_pion);
      ReadData("niel_electrons.dat", niel_electron);
    
    
      // --- Proportionality constant of leakage current and fluence
      // --- for Silicon at room temperature
      // --- Numerical value provided by S. Chatterji
      fIAlpha = 4.e-17;  // [A/cm]
    
    
      // --- Constants for temperature dependence of leakage current
      // --- Values are for Silicon
      // --- Numerical values provided by S. Chatterji
      fEGap0     = 1.166;    // Gap energy [eV] at T = 0K
      fEGapAlpha = 4.73e-4;  // [ev/K]
      fEGapBeta  = 636.;     // [K]
    
    
      // --- Constants for effective doping concentration
      // --- Values are for Silicon
      // --- Numerical values provided by S. Chatterji
      fNeff0  = 9.0e11;   // Doping concentration without irradiation [cm^-3];
      fNeffC  = 2.5e-14;  // [cm^2]
      fNeffGc = 1.5e-2;   // [1/cm]
    
    
      // --- Permittivivity of Silicon
      fEpsilon = 1.04e-12;  // [F/cm]
    }
    // ========================================================================
    
    
    // =====   Private method ReadData   ======================================
    void CbmRadDamage::ReadData(const char* file, std::map<Double_t, Double_t>& table)
    {
    
      TString wrkdir   = getenv("VMCWORKDIR");
      TString fileName = wrkdir + "/input/" + TString(file);
      LOG(info) << "Reading " << fileName;
    
      std::ifstream* data = new std::ifstream(fileName.Data());
      if (!data->is_open()) { LOG(fatal) << "Error when reading from file!"; }
    
      Double_t e     = 0.;
      Double_t v     = 0.;
      Int_t nEntries = 0;
    
      *data >> e >> v;
      while (!data->eof()) {
        table[e] = v;
        nEntries++;
        *data >> e >> v;
      }
    
      data->close();
      delete data;
    
      std::map<Double_t, Double_t>::iterator it1 = table.begin();
      std::map<Double_t, Double_t>::iterator it2 = table.end();
      it2--;
    
      LOG(info) << nEntries << " values read; energy range " << (*it1).first << " to " << (*it2).first << " MeV; map size "
                << table.size();
    }
    // ========================================================================
    
    
    ClassImp(CbmRadDamage)