Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:06

0001 #pragma once
0002 /**
0003 QPMTTest.h
0004 =============
0005 
0006 NB this header is used by three QPMT tests:
0007 
0008 1. standard om built QPMTTest (CUDA)
0009 2. standalone QPMT_Test.sh built QPMT_Test (CUDA)
0010 3. standalone QPMT_MockTest.sh built QPMT_MockTest (MOCK_CURAND using CPU only)
0011 
0012 **/
0013 
0014 template <typename T> struct QPMT ;
0015 struct NP ;
0016 struct NPFold ;
0017 
0018 
0019 template<typename T>
0020 struct QPMTTest
0021 {
0022     static constexpr const char* LPMTID_LIST = "0,10,55,98,100,137,1000,10000,17611,50000,51000,52000,52399,52400,52747,54000,54004" ;
0023     // HMM: duplicates SPMT::LPMTID_LIST
0024 
0025     const QPMT<T>* qpmt ;
0026 
0027     const char* lpmtid_list ;  // comma delimited string of ints from LPMTID_LIST envvar or default
0028 
0029     NP*         lpmtid ;       // array created from the string
0030     int         num_lpmtid ;
0031 
0032 
0033     NP*         lpmtidx ;
0034     int         num_lpmtidx ;
0035 
0036     NP*         lpmtcat ;      // array of cpu side category lookups using QPMT::get_lpmtcat
0037     int         num_lpmtcat ;
0038 
0039     NP*         energy_eV_domain ;
0040     NP*         theta_radians_domain ;   // from 0. to pi/2
0041     NP*         costh_domain ;           // from 0. to 1.  (reverse:true)
0042 
0043     int         num_mct ;            // input from NUM_MCT envvar or default
0044     NP*         mct_domain ;         // from NP::MinusCosThetaLinearAngle
0045 
0046     // small PMT info
0047     static NP* GetSPMTID(const char* spec);
0048     //static constexpr const char* SPMTID_SPEC = "20000,30000,40000,45599" ; // 45599 + 1 - 20000 = 25600
0049     static constexpr const char* SPMTID_SPEC = "[20000:45600]" ; // 45599 + 1 - 20000 = 25600
0050 
0051     const char* spmtid_spec ;
0052     NP*         spmtid ;       // array created from the string
0053     int         num_spmtid ;
0054     NP*         spmtidx ;
0055     int         num_spmtidx ;
0056 
0057 
0058     QPMTTest(const NPFold* jpmt );
0059 
0060     NPFold* make_qscan() const ;
0061     NPFold* serialize(const char* scan_name=nullptr) const ;
0062 };
0063 
0064 
0065 #include "ssys.h"
0066 #include "srng.h"
0067 
0068 #include "NPX.h"
0069 #include "NPFold.h"
0070 
0071 #include "QPMT.hh"
0072 
0073 
0074 
0075 
0076 
0077 
0078 /**
0079 QPMTTest::QPMTTest
0080 --------------------
0081 
0082 np.linspace( 1.55, 15.50, 1550-155+1 )
0083 
0084 **/
0085 
0086 template<typename T>
0087 inline QPMTTest<T>::QPMTTest(const NPFold* jpmt  )
0088     :
0089     qpmt(new QPMT<T>(jpmt)),
0090     lpmtid_list(ssys::getenvvar("LPMTID_LIST", LPMTID_LIST)), // pick some lpmtid
0091     lpmtid(NPX::FromString<int>(lpmtid_list,',')),            // create array from string
0092     num_lpmtid(lpmtid->shape[0]),
0093     lpmtidx(NP::Make<int>(num_lpmtid)),
0094     num_lpmtidx(qpmt->get_lpmtidx_from_lpmtid(lpmtidx->values<int>(),lpmtid->cvalues<int>(),num_lpmtid)), // CPU side lookups
0095     lpmtcat(NP::Make<int>(num_lpmtid)),
0096     num_lpmtcat(qpmt->get_lpmtcat_from_lpmtid(lpmtcat->values<int>(),lpmtid->cvalues<int>(),num_lpmtid)), // CPU side lookups
0097     energy_eV_domain(NP::Linspace<T>(1.55,15.50,1550-155+1)),
0098     theta_radians_domain(NP::ThetaRadians<T>(91,0.5)),
0099     costh_domain(NP::Cos(theta_radians_domain)),
0100     num_mct(ssys::getenvint("NUM_MCT",900)),   // 181
0101     mct_domain(NP::MakeWithType<T>(NP::MinusCosThetaLinearAngle<double>(num_mct))),
0102     spmtid_spec(ssys::getenvvar("SPMTID_SPEC", SPMTID_SPEC)),
0103     spmtid(GetSPMTID(spmtid_spec)),            // create array from string
0104     num_spmtid(spmtid->shape[0]),
0105     spmtidx(NP::Make<int>(num_spmtid)),
0106     num_spmtidx(qpmt->get_spmtidx_from_spmtid(spmtidx->values<int>(),spmtid->cvalues<int>(),num_spmtid)) // CPU side lookups
0107 {
0108 }
0109 
0110 /**
0111 QPMTTest::GetSPMTID
0112 --------------------
0113 
0114 Either comma delimited lists OR slice ARange_FromString spec are handled, eg::
0115 
0116     "20000,30000,40000,45599"   # 4 listed values
0117     "[20000:45600]"             # 25600 values using python slice spec (start,stop,step)
0118 
0119 **/
0120 
0121 
0122 template<typename T>
0123 inline NP* QPMTTest<T>::GetSPMTID(const char* spec) // static
0124 {
0125     if(!spec) return nullptr ;
0126     bool is_comma_delimited_list = strstr(spec,",");
0127     return  is_comma_delimited_list ? NPX::FromString<int>(spec,',') : NP::ARange_FromString<int>(spec) ;
0128 }
0129 
0130 
0131 template<typename T>
0132 inline NPFold* QPMTTest<T>::make_qscan() const
0133 {
0134     NPFold* qscan = new NPFold ;
0135 
0136     qscan->add("energy_eV_domain", energy_eV_domain ) ;
0137     qscan->add("theta_radians_domain", theta_radians_domain ) ;
0138     qscan->add("costh_domain", costh_domain ) ;
0139     qscan->add("mct_domain", mct_domain ) ;
0140 
0141     qscan->add("lpmtid",  lpmtid ) ;
0142     qscan->add("lpmtidx", lpmtidx ) ;
0143     qscan->add("lpmtcat", lpmtcat ) ;
0144 
0145     qscan->add("spmtid",  spmtid ) ;
0146     qscan->add("spmtidx", spmtidx ) ;
0147 
0148 
0149     qscan->add("pmtcat_rindex",    qpmt->pmtcat_scan(qpmt_RINDEX,    energy_eV_domain) ) ;
0150     qscan->add("pmtcat_stackspec", qpmt->pmtcat_scan(qpmt_CATSPEC,   energy_eV_domain) ) ;
0151     qscan->add("pmtcat_qeshape",   qpmt->pmtcat_scan(qpmt_QESHAPE,   energy_eV_domain) ) ;
0152     qscan->add("pmtcat_s_qeshape", qpmt->pmtcat_scan(qpmt_S_QESHAPE, energy_eV_domain) ) ;
0153     qscan->add("pmtcat_cetheta",   qpmt->pmtcat_scan(qpmt_CETHETA,   theta_radians_domain) ) ;
0154     qscan->add("pmtcat_cecosth",   qpmt->pmtcat_scan(qpmt_CECOSTH,   costh_domain ) ) ;
0155 
0156     qscan->add("spec",    qpmt->mct_lpmtid_scan(qpmt_SPEC,    mct_domain, lpmtid) ) ;
0157     qscan->add("spec_ce", qpmt->mct_lpmtid_scan(qpmt_SPEC_ce, mct_domain, lpmtid) ) ;
0158 
0159     qscan->add("art" ,    qpmt->mct_lpmtid_scan(qpmt_ART , mct_domain, lpmtid) ) ;
0160     qscan->add("arte",    qpmt->mct_lpmtid_scan(qpmt_ARTE, mct_domain, lpmtid) ) ;
0161     qscan->add("atqc",    qpmt->mct_lpmtid_scan(qpmt_ATQC, mct_domain, lpmtid) ) ;
0162     qscan->add("comp",    qpmt->mct_lpmtid_scan(qpmt_COMP, mct_domain, lpmtid) ) ;
0163     qscan->add("ll",      qpmt->mct_lpmtid_scan(qpmt_LL  , mct_domain, lpmtid) ) ;
0164 
0165 
0166     qscan->add("s_qescale",   qpmt->spmtid_scan(qpmt_S_QESCALE, spmtid ) ) ;
0167 
0168 
0169     return qscan ;
0170 }
0171 
0172 template<typename T>
0173 inline NPFold* QPMTTest<T>::serialize(const char* scan_name_) const
0174 {
0175     const char* scan_name = scan_name_ ? scan_name_ : "qscan" ;
0176     NPFold* f = new NPFold ;
0177     f->add_subfold("qpmt", qpmt->serialize() );
0178     f->add_subfold(scan_name, make_qscan() );
0179     return f ;
0180 }
0181 
0182