File indexing completed on 2026-04-09 07:49:43
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 #if defined(__CUDACC__) || defined(__CUDABE__)
0143 # define SPHOTON_METHOD __host__ __device__ __forceinline__
0144 #else
0145 # define SPHOTON_METHOD inline
0146 #endif
0147 #include <cstdint>
0148
0149 #if defined(__CUDACC__) || defined(__CUDABE__)
0150 #else
0151 #include <iostream>
0152 #include <iomanip>
0153 #include <sstream>
0154 #include <vector>
0155 #include <cstring>
0156 #include <csignal>
0157 #include <cassert>
0158 #include <glm/glm.hpp>
0159
0160 #include "scuda.h"
0161 #include "stran.h"
0162 #include "smath.h"
0163 #include "OpticksPhoton.h"
0164
0165 struct NP ;
0166 #endif
0167
0168
0169
0170
0171 struct sphoton
0172 {
0173 #if defined(__CUDACC__) || defined(__CUDABE__)
0174 #else
0175 static constexpr const char* NAME = "sphoton" ;
0176 #endif
0177
0178
0179 float3 pos ;
0180 float time ;
0181
0182 float3 mom ;
0183 unsigned hitcount_iindex ;
0184
0185 float3 pol ;
0186 float wavelength ;
0187
0188
0189 unsigned orient_boundary_flag ;
0190 unsigned identity ;
0191 unsigned index ;
0192 unsigned flagmask ;
0193
0194 SPHOTON_METHOD void set_prd( unsigned boundary, unsigned identity, float orient, unsigned iindex );
0195
0196
0197 SPHOTON_METHOD void set_hitcount_one_iindex( unsigned ii ){ hitcount_iindex = ( 0x00010000u ) | (( 0x0000ffffu & ii ) << 0 ); }
0198 SPHOTON_METHOD void set_iindex__( unsigned ii ){ hitcount_iindex = ( hitcount_iindex & 0xffff0000u ) | (( 0x0000ffffu & ii ) << 0 ); }
0199 SPHOTON_METHOD void set_hitcount( unsigned hc ){ hitcount_iindex = ( hitcount_iindex & 0x0000ffffu ) | (( 0x0000ffffu & hc ) << 16); }
0200
0201 SPHOTON_METHOD unsigned iindex() const { return ( hitcount_iindex & 0x0000ffffu ) >> 0 ; }
0202 SPHOTON_METHOD unsigned hitcount() const { return ( hitcount_iindex & 0xffff0000u ) >> 16 ; }
0203
0204 SPHOTON_METHOD unsigned flag() const { return (orient_boundary_flag & 0x0000ffffu) >> 0 ; }
0205 SPHOTON_METHOD unsigned boundary() const { return (orient_boundary_flag & 0x7fff0000u) >> 16 ; }
0206 SPHOTON_METHOD float orient() const { return (orient_boundary_flag & 0x80000000u) ? -1.f : 1.f ; }
0207
0208
0209 SPHOTON_METHOD void set_flag(unsigned flag) { orient_boundary_flag = ( orient_boundary_flag & 0xffff0000u ) | (( flag & 0xffffu ) << 0 ) ; flagmask |= flag ; }
0210 SPHOTON_METHOD void set_boundary(unsigned boundary) { orient_boundary_flag = ( orient_boundary_flag & 0x8000ffffu ) | (( boundary & 0x7fffu ) << 16 ) ; }
0211 SPHOTON_METHOD void set_orient(float orient){ orient_boundary_flag = ( orient_boundary_flag & 0x7fffffffu ) | (( orient < 0.f ? 0x1u : 0x0u ) << 31 ) ; }
0212
0213
0214 SPHOTON_METHOD void set_flagmask(unsigned _flagmask) { flagmask = _flagmask ; }
0215 SPHOTON_METHOD void addto_flagmask(unsigned flag) { flagmask |= flag ; }
0216 SPHOTON_METHOD void scrub_flagmask(unsigned flag) { flagmask &= ~flag ; }
0217
0218 SPHOTON_METHOD void zero_flags() { orient_boundary_flag = 0u ; identity = 0u ; index = 0u ; flagmask = 0u ; hitcount_iindex = 0u ; }
0219
0220 SPHOTON_METHOD float* data() { return &pos.x ; }
0221 SPHOTON_METHOD const float* cdata() const { return &pos.x ; }
0222
0223
0224 SPHOTON_METHOD void set_index(uint64_t full_index)
0225 {
0226
0227 index = ( static_cast<unsigned>((full_index >> 0 ) & 0xffffffffu) << 0 ) ;
0228
0229
0230 identity = ( static_cast<unsigned>((full_index >> 32) & 0xffu ) << 24 ) | ( identity & 0xffffffu ) ;
0231 }
0232 SPHOTON_METHOD uint64_t get_index() const { return (static_cast<uint64_t>(identity >> 24) << 32) | static_cast<uint64_t>(index); }
0233
0234
0235
0236 SPHOTON_METHOD void set_identity(unsigned id) { identity = ( identity & 0xff000000u ) | ( id & 0x00ffffffu ); }
0237 SPHOTON_METHOD unsigned get_identity() const { return identity & 0x00ffffffu ; }
0238 SPHOTON_METHOD unsigned pmtid() const
0239 {
0240 unsigned id = get_identity() ;
0241 return id == 0 ? 0xffffffffu : id - 1 ;
0242 }
0243
0244
0245 SPHOTON_METHOD void zero()
0246 {
0247 pos.x = 0.f ; pos.y = 0.f ; pos.z = 0.f ; time = 0.f ;
0248 mom.x = 0.f ; mom.y = 0.f ; mom.z = 0.f ; hitcount_iindex = 0u ;
0249 pol.x = 0.f ; pol.y = 0.f ; pol.z = 0.f ; wavelength = 0.f ;
0250 orient_boundary_flag = 0u ; identity = 0u ; index = 0u ; flagmask = 0u ;
0251 }
0252
0253 #ifdef WITH_LOCALIZE
0254 template<typename T>
0255 SPHOTON_METHOD void localize(sphoton& l, const glm::tmat4x4<T>& tr, bool normalize) const
0256 {
0257
0258 glm::tvec4<T> p_pos(pos.x, pos.y, pos.z, T(1.f));
0259 glm::tvec4<T> l_pos = tr * p_pos;
0260 l.pos = make_float3(l_pos.x, l_pos.y, l_pos.z);
0261
0262 glm::tvec4<T> p_mom(mom.x, mom.y, mom.z, T(0.f));
0263 glm::tvec4<T> l_mom_ = tr * p_mom;
0264 glm::tvec3<T> l_mom(l_mom_);
0265 if(normalize) l_mom = glm::normalize(l_mom);
0266 l.mom = make_float3(l_mom.x, l_mom.y, l_mom.z);
0267
0268 glm::tvec4<T> p_pol(pol.x, pol.y, pol.z, T(0.f));
0269 glm::tvec4<T> l_pol_ = tr * p_pol;
0270 glm::tvec3<T> l_pol(l_pol_);
0271 if(normalize) l_pol = glm::normalize(l_pol);
0272 l.pol = make_float3(l_pol.x, l_pol.y, l_pol.z);
0273 }
0274 #endif
0275
0276
0277 struct key_functor
0278 {
0279 float tw;
0280 SPHOTON_METHOD uint64_t operator()(const sphoton& p) const
0281 {
0282 unsigned id = p.get_identity() ;
0283 unsigned bucket = static_cast<unsigned>(p.time / tw);
0284 return (uint64_t(id) << 48) | uint64_t(bucket);
0285 }
0286 };
0287
0288 struct reduce_op
0289 {
0290 SPHOTON_METHOD sphoton operator()(const sphoton& a, const sphoton& b) const
0291 {
0292 bool a_first = fminf(a.time, b.time) == a.time ;
0293 sphoton r = a_first ? a : b ;
0294 r.flagmask = a.flagmask | b.flagmask ;
0295 r.set_hitcount( a.hitcount() + b.hitcount() );
0296 return r;
0297 }
0298 };
0299
0300 struct select_pred
0301 {
0302 unsigned mask;
0303 SPHOTON_METHOD bool operator()(const sphoton& p) const { return (p.flagmask & mask) != 0; }
0304 };
0305
0306
0307
0308
0309 #if defined(__CUDACC__) || defined(__CUDABE__)
0310 #else
0311
0312 SPHOTON_METHOD bool is_cerenkov() const { return (flagmask & CERENKOV) != 0 ; }
0313 SPHOTON_METHOD bool is_reemit() const { return (flagmask & BULK_REEMIT) != 0 ; }
0314
0315 SPHOTON_METHOD unsigned flagmask_count() const ;
0316 SPHOTON_METHOD std::string desc() const ;
0317 SPHOTON_METHOD std::string descBase() const ;
0318 SPHOTON_METHOD std::string descPos() const ;
0319 SPHOTON_METHOD std::string descDir() const ;
0320 SPHOTON_METHOD std::string descDetail() const ;
0321 SPHOTON_METHOD std::string descFlag() const ;
0322 SPHOTON_METHOD std::string descDigest() const ;
0323
0324 SPHOTON_METHOD const char* flag_() const ;
0325 SPHOTON_METHOD const char* abbrev_() const ;
0326 SPHOTON_METHOD std::string flagmask_() const ;
0327
0328
0329 SPHOTON_METHOD void ephoton() ;
0330 SPHOTON_METHOD void normalize_mom_pol();
0331 SPHOTON_METHOD void transverse_mom_pol();
0332 SPHOTON_METHOD void set_polarization(float frac_twopi);
0333 SPHOTON_METHOD static sphoton make_ephoton();
0334 SPHOTON_METHOD static NP* make_ephoton_array(size_t num_photon);
0335 SPHOTON_METHOD static NP* zeros(size_t num_photon) ;
0336 SPHOTON_METHOD static NP* demoarray(size_t num_photon);
0337 SPHOTON_METHOD std::string digest(unsigned numval=16) const ;
0338 SPHOTON_METHOD static bool digest_match( const sphoton& a, const sphoton& b, unsigned numval=16 ) ;
0339
0340 SPHOTON_METHOD static float DeltaMax( const float* aa, const float* bb, int num );
0341 SPHOTON_METHOD static float4 DeltaMax( const sphoton& a, const sphoton& b ) ;
0342 SPHOTON_METHOD static bool EqualFlags( const sphoton& a, const sphoton& b) ;
0343
0344 SPHOTON_METHOD static void Get( sphoton& p, const NP* a, unsigned idx );
0345 SPHOTON_METHOD static void Get( std::vector<sphoton>& pp, const NP* a );
0346
0347 SPHOTON_METHOD static void MinMaxPost( float* mn, float* mx, const NP* a, bool skip_flagmask_zero );
0348 SPHOTON_METHOD static std::string DescMinMaxPost( const NP* _a, bool skip_flagmask_zero );
0349 SPHOTON_METHOD static std::string Desc(const NP* a, size_t edge=20);
0350 SPHOTON_METHOD static NP* MockupForMergeTest(size_t ni);
0351
0352 template<typename T>
0353 SPHOTON_METHOD static bool IsPhotonArray( const NP* a );
0354
0355 SPHOTON_METHOD static void ChangeTimeInsitu( NP* a, float t0 );
0356
0357 SPHOTON_METHOD void transform_float( const glm::tmat4x4<float>& tr, bool normalize=true );
0358 SPHOTON_METHOD void transform( const glm::tmat4x4<double>& tr, bool normalize=true );
0359
0360 SPHOTON_METHOD void populate_simtrace_input( quad4& q ) const ;
0361
0362 SPHOTON_METHOD float get_cost() const ;
0363 SPHOTON_METHOD float get_fphi() const ;
0364 SPHOTON_METHOD void set_lpos(float lposcost, float lposfphi);
0365
0366 SPHOTON_METHOD static size_t GetIndexBeyondCursorContiguousIIndex( const sphoton* pp, size_t num, size_t cursor=0 );
0367 SPHOTON_METHOD static void GetContiguousIIndexStartIndices( std::vector<size_t>& starts, const sphoton* pp, size_t num );
0368 #endif
0369
0370 };
0371
0372
0373
0374
0375
0376 #if defined(__CUDACC__) || defined(__CUDABE__)
0377 #else
0378
0379 struct sphotond
0380 {
0381 double3 pos ;
0382 double time ;
0383
0384 double3 mom ;
0385 unsigned long long hitcount_iindex ;
0386
0387 double3 pol ;
0388 double wavelength ;
0389
0390 unsigned long long orient_boundary_flag ;
0391 unsigned long long identity ;
0392 unsigned long long index ;
0393 unsigned long long flagmask ;
0394
0395
0396 SPHOTON_METHOD static void FromFloat( sphotond& d, const sphoton& s );
0397 SPHOTON_METHOD static void Get( sphotond& p, const NP* a, unsigned idx );
0398 SPHOTON_METHOD void transform_float( const glm::tmat4x4<float>& tr, bool normalize=true );
0399 SPHOTON_METHOD void transform( const glm::tmat4x4<double>& tr, bool normalize=true );
0400 SPHOTON_METHOD const double* cdata() const { return &pos.x ; }
0401
0402
0403 };
0404
0405
0406 SPHOTON_METHOD void sphotond::FromFloat( sphotond& d, const sphoton& s )
0407 {
0408 typedef unsigned long long ull ;
0409
0410 d.pos.x = double(s.pos.x) ;
0411 d.pos.y = double(s.pos.y) ;
0412 d.pos.z = double(s.pos.z) ;
0413 d.time = double(s.time) ;
0414
0415 d.mom.x = double(s.mom.x) ;
0416 d.mom.y = double(s.mom.y) ;
0417 d.mom.z = double(s.mom.z) ;
0418 d.hitcount_iindex = ull(s.hitcount_iindex) ;
0419
0420 d.pol.x = double(s.pol.x) ;
0421 d.pol.y = double(s.pol.y) ;
0422 d.pol.z = double(s.pol.z) ;
0423 d.wavelength = double(s.wavelength) ;
0424
0425 d.orient_boundary_flag = ull(s.orient_boundary_flag) ;
0426 d.identity = ull(s.identity) ;
0427 d.index = ull(s.index) ;
0428 d.flagmask = ull(s.flagmask) ;
0429 }
0430
0431 SPHOTON_METHOD void sphotond::Get( sphotond& p, const NP* a, unsigned idx )
0432 {
0433 assert(a && a->has_shape(-1,4,4) && a->ebyte == sizeof(double) && idx < unsigned(a->shape[0]) );
0434 assert( sizeof(sphotond) == sizeof(double)*16 );
0435 memcpy( &p, a->cvalues<double>() + idx*16, sizeof(sphotond) );
0436 }
0437
0438 SPHOTON_METHOD void sphotond::transform_float( const glm::tmat4x4<float>& tr, bool normalize )
0439 {
0440 glm::tmat4x4<double> trd ;
0441 TranConvert(trd, tr);
0442 transform(trd, normalize );
0443 }
0444
0445 SPHOTON_METHOD void sphotond::transform( const glm::tmat4x4<double>& tr, bool normalize )
0446 {
0447 double one(1.);
0448 double zero(0.);
0449
0450 unsigned count = 1 ;
0451 unsigned stride = 4*4 ;
0452
0453 assert( sizeof(*this) == sizeof(double)*16 );
0454 double* p0 = (double*)this ;
0455
0456 Tran<double>::Apply( tr, p0, one, count, stride, 0, false );
0457 Tran<double>::Apply( tr, p0, zero, count, stride, 4, normalize );
0458 Tran<double>::Apply( tr, p0, zero, count, stride, 8, normalize );
0459 }
0460
0461 #endif
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482 SPHOTON_METHOD void sphoton::set_prd( unsigned boundary_, unsigned identity_, float orient_, unsigned iindex_ )
0483 {
0484 set_boundary(boundary_);
0485 set_identity(identity_);
0486 set_orient( orient_ );
0487 set_hitcount_one_iindex( iindex_ );
0488 }
0489
0490
0491
0492 #if defined(__CUDACC__) || defined(__CUDABE__)
0493 #else
0494
0495 #include <cassert>
0496 #include <bitset>
0497 #include "sdigest.h"
0498 #include "OpticksPhoton.hh"
0499 #include "NP.hh"
0500
0501
0502
0503 SPHOTON_METHOD unsigned sphoton::flagmask_count() const
0504 {
0505 return std::bitset<32>(flagmask).count() ;
0506 }
0507
0508 SPHOTON_METHOD std::string sphoton::desc() const
0509 {
0510 std::stringstream ss ;
0511 ss << descBase() << " "<< descDetail() ;
0512 std::string s = ss.str();
0513 return s ;
0514 }
0515
0516 SPHOTON_METHOD std::string sphoton::descPos() const
0517 {
0518 std::stringstream ss ;
0519 ss
0520 << " pos " << pos
0521 << " t " << std::setw(8) << time
0522 << " "
0523 ;
0524 std::string s = ss.str();
0525 return s ;
0526 }
0527
0528 SPHOTON_METHOD std::string sphoton::descDir() const
0529 {
0530 std::stringstream ss ;
0531 ss
0532 << " mom " << mom
0533 << " iindex " << std::setw(4) << iindex()
0534 << " "
0535 << " pol " << pol
0536 << " wl " << std::setw(8) << wavelength
0537 << " "
0538 ;
0539 std::string s = ss.str();
0540 return s ;
0541 }
0542
0543 SPHOTON_METHOD std::string sphoton::descBase() const
0544 {
0545 std::stringstream ss ;
0546 ss << descPos()
0547 << descDir()
0548 ;
0549 std::string s = ss.str();
0550 return s ;
0551 }
0552 SPHOTON_METHOD std::string sphoton::descDetail() const
0553 {
0554 std::stringstream ss ;
0555 ss
0556 << " bn " << boundary()
0557 << " fl " << std::hex << flag() << std::dec
0558 << " id " << identity
0559 << " or " << orient()
0560 << " ix " << index
0561 << " fm " << std::hex << flagmask << std::dec
0562 << " ab " << OpticksPhoton::Abbrev( flag() )
0563 << " ii " << iindex()
0564 ;
0565 std::string s = ss.str();
0566 return s ;
0567 }
0568
0569 SPHOTON_METHOD std::string sphoton::descDigest() const
0570 {
0571 std::stringstream ss ;
0572 ss
0573 << " "
0574 << " digest(16) " << digest(16)
0575 << " "
0576 << " digest(12) " << digest(12)
0577 ;
0578 std::string s = ss.str();
0579 return s ;
0580 }
0581
0582
0583 SPHOTON_METHOD const char* sphoton::flag_() const
0584 {
0585 return OpticksPhoton::Flag(flag()) ;
0586 }
0587
0588 SPHOTON_METHOD const char* sphoton::abbrev_() const
0589 {
0590 return OpticksPhoton::Abbrev(flag()) ;
0591 }
0592 SPHOTON_METHOD std::string sphoton::flagmask_() const
0593 {
0594 return OpticksPhoton::FlagMaskLabel(flagmask) ;
0595 }
0596
0597
0598 SPHOTON_METHOD std::string sphoton::descFlag() const
0599 {
0600 std::stringstream ss ;
0601 ss
0602 << " sphoton idx " << index
0603 << " flag " << flag_()
0604 << " flagmask " << flagmask_()
0605 ;
0606 std::string s = ss.str();
0607 return s ;
0608 }
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622 SPHOTON_METHOD void sphoton::ephoton()
0623 {
0624 quad4& q = (quad4&)(*this) ;
0625
0626 qvals( q.q0.f , "EPHOTON_POST" , "0,0,0,0" );
0627 qvals( q.q1.f, q.q2.f, "EPHOTON_MOMW_POLW", "1,0,0,1,0,1,0,500" );
0628 qvals( q.q3.i , "EPHOTON_FLAG", "0,0,0,0" );
0629 normalize_mom_pol();
0630 transverse_mom_pol();
0631 }
0632
0633 SPHOTON_METHOD void sphoton::normalize_mom_pol()
0634 {
0635 mom = normalize(mom);
0636 pol = normalize(pol);
0637 }
0638
0639 SPHOTON_METHOD void sphoton::transverse_mom_pol()
0640 {
0641 float mom_pol = fabsf( dot(mom, pol)) ;
0642 float eps = 1e-5 ;
0643 bool is_transverse = mom_pol < eps ;
0644
0645 if(!is_transverse )
0646 {
0647 std::cout
0648 << " sphoton::transverse_mom_pol "
0649 << " FAIL "
0650 << " mom " << mom
0651 << " pol " << pol
0652 << " mom_pol " << mom_pol
0653 << " eps " << eps
0654 << " is_transverse " << is_transverse
0655 << std::endl
0656 ;
0657 }
0658 assert(is_transverse);
0659 }
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671 SPHOTON_METHOD void sphoton::set_polarization(float frac_twopi)
0672 {
0673 float phase = 2.f*M_PIf*frac_twopi ;
0674 pol.x = cosf(phase) ;
0675 pol.y = sinf(phase) ;
0676 pol.z = 0.f ;
0677 smath::rotateUz(pol, mom);
0678 }
0679
0680
0681 SPHOTON_METHOD sphoton sphoton::make_ephoton()
0682 {
0683 sphoton p ;
0684 p.ephoton();
0685 return p ;
0686 }
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698 SPHOTON_METHOD NP* sphoton::make_ephoton_array(size_t num_photon)
0699 {
0700 sphoton ep ;
0701 ep.ephoton() ;
0702
0703 NP* ph = zeros(num_photon);
0704 sphoton* pp = (sphoton*)ph->bytes();
0705 for(size_t i=0 ; i < num_photon ; i++)
0706 {
0707 sphoton p = ep ;
0708 p.pos.y = float(i)*100.f ;
0709 pp[i] = p ;
0710 }
0711 return ph ;
0712 }
0713 SPHOTON_METHOD NP* sphoton::zeros(size_t num_photon)
0714 {
0715 NP* ph = NP::Make<float>(num_photon, 4, 4 );
0716 return ph ;
0717 }
0718
0719 SPHOTON_METHOD NP* sphoton::demoarray(size_t num_photon)
0720 {
0721 NP* ph = zeros(num_photon);
0722 sphoton* pp = (sphoton*)ph->bytes();
0723 for(size_t i=0 ; i < num_photon ; i++)
0724 {
0725 sphoton& p = pp[i] ;
0726
0727 p.pos = make_float3( 0.1f + i*0.1f, 0.2f + i*0.1f , 0.3f + i*0.1f );
0728 p.time = i*0.1f ;
0729
0730 p.mom = make_float3( 0.1f + i*0.1f, 0.2f + i*0.1f , 0.3f + i*0.1f );
0731 p.set_orient( i % 2 == 0 ? 1.f : -1.f );
0732 p.set_hitcount_one_iindex( i*1000 );
0733
0734 p.pol = make_float3( 0.1f + i*0.1f, 0.2f + i*0.1f , 0.3f + i*0.1f );
0735 p.wavelength = 400.f + 10.f*i ;
0736
0737 p.set_boundary( i*10 );
0738 p.set_flag( i*100 );
0739
0740 uint64_t full_index = 0xffffffff + i ;
0741 p.set_index( full_index );
0742
0743 p.set_identity( i*200 );
0744 p.set_flagmask( SURFACE_DETECT | EFFICIENCY_COLLECT );
0745
0746 }
0747 return ph ;
0748 }
0749
0750
0751
0752
0753
0754
0755
0756 SPHOTON_METHOD std::string sphoton::digest(unsigned numval) const
0757 {
0758 assert( numval <= 16 );
0759 return sdigest::Buf( (const char*)cdata() , numval*sizeof(float) );
0760 }
0761
0762 SPHOTON_METHOD bool sphoton::digest_match( const sphoton& a, const sphoton& b, unsigned numval )
0763 {
0764 std::string adig = a.digest(numval);
0765 std::string bdig = b.digest(numval);
0766 return strcmp( adig.c_str(), bdig.c_str() ) == 0 ;
0767 }
0768
0769 SPHOTON_METHOD float sphoton::DeltaMax( const float* aa, const float* bb, int num )
0770 {
0771 float dmax = 0.f ;
0772 for(int i=0 ; i < num ; i++)
0773 {
0774 float a = *(aa+i) ;
0775 float b = *(bb+i) ;
0776 float ab = std::abs(a - b);
0777 if(ab > dmax) dmax = ab ;
0778 }
0779 return dmax ;
0780 }
0781
0782 SPHOTON_METHOD float4 sphoton::DeltaMax( const sphoton& a, const sphoton& b )
0783 {
0784 float4 dmax = make_float4( 0.f, 0.f, 0.f, 0.f );
0785 dmax.x = DeltaMax( &a.pos.x, &b.pos.x, 3 );
0786 dmax.y = DeltaMax( &a.mom.x, &b.mom.x, 3 );
0787 dmax.z = DeltaMax( &a.pol.x, &b.pol.x, 3 );
0788 dmax.w = std::max( DeltaMax( &a.time, &b.time, 1 ), DeltaMax( &a.wavelength, &b.wavelength, 1 ) ) ;
0789 return dmax ;
0790 }
0791
0792
0793 SPHOTON_METHOD bool sphoton::EqualFlags( const sphoton& a, const sphoton& b)
0794 {
0795 return a.hitcount_iindex == b.hitcount_iindex &&
0796 a.orient_boundary_flag == b.orient_boundary_flag &&
0797 a.identity == b.identity &&
0798 a.index == b.index &&
0799 a.flagmask == b.flagmask
0800 ;
0801
0802 }
0803
0804
0805
0806 SPHOTON_METHOD void sphoton::Get( sphoton& p, const NP* a, unsigned idx )
0807 {
0808 bool expected = a && a->has_shape(-1,4,4) && a->ebyte == sizeof(float) && idx < unsigned(a->shape[0]) ;
0809 if(!expected) std::cerr
0810 << "sphoton::Get not expected error "
0811 << " a " << ( a ? "Y" : "N" )
0812 << " a.shape " << ( a ? a->sstr() : "-" )
0813 << " a.ebyte " << ( a ? a->ebyte : -1 )
0814 << " a.shape[0] " << ( a ? a->shape[0] : -1 )
0815 << " idx " << idx
0816 << std::endl
0817 ;
0818
0819 assert( expected );
0820 assert( sizeof(sphoton) == sizeof(float)*16 );
0821 memcpy( &p, a->cvalues<float>() + idx*16, sizeof(sphoton) );
0822 }
0823
0824 SPHOTON_METHOD void sphoton::Get( std::vector<sphoton>& pp, const NP* a )
0825 {
0826 bool is_f = IsPhotonArray<float>(a);
0827 assert( is_f );
0828 unsigned num = a->shape[0] ;
0829 pp.resize(num);
0830 memcpy( pp.data(), a->cvalues<float>(), sizeof(sphoton)*num );
0831 }
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844 SPHOTON_METHOD void sphoton::MinMaxPost( float* mn, float* mx, const NP* _a, bool skip_flagmask_zero )
0845 {
0846 NP* a = const_cast<NP*>(_a);
0847
0848 std::vector<NP::INT> sh = a->shape ;
0849 a->change_shape(-1,4,4);
0850
0851 bool is_f = IsPhotonArray<float>(a);
0852 bool is_d = IsPhotonArray<double>(a);
0853 bool is_f_xor_d = is_f ^ is_d ;
0854
0855 if(!is_f_xor_d) std::cerr
0856 << "sphoton::MinMaxPost FATAL UNEXPECTED ARRAY "
0857 << " is_f " << ( is_f ? "YES" : "NO " )
0858 << " is_d " << ( is_d ? "YES" : "NO " )
0859 << "\n"
0860 ;
0861
0862 bool expect = is_f_xor_d ;
0863 assert(expect);
0864 if(!expect) std::raise(SIGINT);
0865
0866 int ni = a->num_items() ;
0867 int nj = 4 ;
0868 float MAX = std::numeric_limits<float>::max() ;
0869
0870 for(int j=0 ; j < nj ; j++)
0871 {
0872 mn[j] = MAX ;
0873 mx[j] = -MAX ;
0874 }
0875
0876
0877
0878 for(int i=0 ; i < ni ; i++)
0879 {
0880 if( is_f )
0881 {
0882 sphoton* p = reinterpret_cast<sphoton*>(a->bytes() + i*a->item_bytes());
0883 if(skip_flagmask_zero && p->flagmask == 0u) continue ;
0884 const float* xyzt = p->cdata();
0885 for(int j=0 ; j < nj ; j++)
0886 {
0887 float vj = xyzt[j] ;
0888 if( vj < mn[j] ) mn[j] = vj ;
0889 if( vj > mx[j] ) mx[j] = vj ;
0890 }
0891 }
0892 else if( is_d )
0893 {
0894 sphotond* p = reinterpret_cast<sphotond*>(a->bytes() + i*a->item_bytes());
0895 if(skip_flagmask_zero && p->flagmask == 0u) continue ;
0896 const double* xyzt = p->cdata();
0897
0898 for(int j=0 ; j < nj ; j++)
0899 {
0900 double vj = xyzt[j] ;
0901 if( vj < double(mn[j]) ) mn[j] = vj ;
0902 if( vj > double(mx[j]) ) mx[j] = vj ;
0903 }
0904 }
0905 }
0906 a->reshape(sh);
0907 }
0908
0909 SPHOTON_METHOD std::string sphoton::DescMinMaxPost( const NP* _a, bool skip_flagmask_zero )
0910 {
0911 float4 mn = {} ;
0912 float4 mx = {} ;
0913 MinMaxPost( &mn.x , &mx.x, _a, skip_flagmask_zero );
0914
0915 std::stringstream ss ;
0916 ss
0917 << "[sphoton::DescMinMaxPost\n"
0918 << " a " << ( _a ? _a->sstr() : "-" ) << "\n"
0919 << " mn " << mn << "\n"
0920 << " mx " << mx << "\n"
0921 << "]sphoton::DescMinMaxPost\n"
0922 ;
0923 std::string str = ss.str();
0924 return str ;
0925 }
0926
0927 SPHOTON_METHOD std::string sphoton::Desc(const NP* a, size_t edge)
0928 {
0929 std::stringstream ss ;
0930 ss << "[sphoton::Desc a.sstr " << ( a ? a->sstr() : "-" ) << "\n" ;
0931 size_t ni = a->num_items();
0932 sphoton* pp = (sphoton*)a->bytes();
0933 for(size_t i=0 ; i < ni ; i++)
0934 {
0935 if(i < edge || i > (ni - edge)) ss << std::setw(6) << i << " : " << pp[i].desc() << "\n" ;
0936 else if( i == edge ) ss << std::setw(6) << "" << " : " << "..." << "\n" ;
0937 }
0938
0939 std::string str = ss.str() ;
0940 return str ;
0941 }
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953 SPHOTON_METHOD NP* sphoton::MockupForMergeTest(size_t ni)
0954 {
0955 NP* a = NP::Make<float>(ni, 4, 4);
0956 sphoton* aa = (sphoton*)a->bytes();
0957 for(size_t i=0 ; i < ni ; i++)
0958 {
0959 sphoton& p = aa[i];
0960 p.time = float( i % 100 )*0.1f ;
0961 p.set_index(i);
0962 p.set_identity( i % 100 );
0963 p.set_hitcount( 1 );
0964 p.flagmask = i % 5 == 0 ? EFFICIENCY_COLLECT : EFFICIENCY_CULL ;
0965 }
0966 return a ;
0967 }
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981 template<typename T>
0982 SPHOTON_METHOD bool sphoton::IsPhotonArray( const NP* a )
0983 {
0984 assert( sizeof(sphoton) == sizeof(float)*16 );
0985 assert( sizeof(sphotond) == sizeof(double)*16 );
0986 return a && a->has_shape(-1,4,4) && a->ebyte == sizeof(T) ;
0987 }
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001 SPHOTON_METHOD void sphoton::ChangeTimeInsitu( NP* a, float t0 )
1002 {
1003 bool is_f = IsPhotonArray<float>(a);
1004 bool is_d = IsPhotonArray<double>(a);
1005 bool is_f_xor_d = is_f ^ is_d ;
1006
1007 if(!is_f_xor_d) std::cerr
1008 << "sphoton::ChangeTimeInsitu FATAL "
1009 << " is_f " << ( is_f ? "YES" : "NO " )
1010 << " is_d " << ( is_d ? "YES" : "NO " )
1011 << "\n"
1012 ;
1013
1014 bool expect = is_f_xor_d ;
1015 assert(expect);
1016 if(!expect) std::raise(SIGINT);
1017
1018 for(NP::INT i=0 ; i < a->num_items() ; i++)
1019 {
1020 if( is_f )
1021 {
1022 sphoton* p = reinterpret_cast<sphoton*>(a->bytes() + i*a->item_bytes());
1023 p->time = t0 ;
1024 }
1025 else if( is_d )
1026 {
1027 sphotond* p = reinterpret_cast<sphotond*>(a->bytes() + i*a->item_bytes());
1028 p->time = t0 ;
1029 }
1030 }
1031 }
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 SPHOTON_METHOD void sphoton::transform_float( const glm::tmat4x4<float>& tr, bool normalize )
1047 {
1048 glm::tmat4x4<double> trd ;
1049 TranConvert(trd, tr);
1050 transform(trd, normalize );
1051 }
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 SPHOTON_METHOD void sphoton::transform( const glm::tmat4x4<double>& tr, bool normalize )
1068 {
1069 float one(1.);
1070 float zero(0.);
1071
1072 unsigned count = 1 ;
1073 unsigned stride = 4*4 ;
1074
1075 assert( sizeof(*this) == sizeof(float)*16 );
1076 float* p0 = (float*)this ;
1077
1078 Tran<double>::ApplyToFloat( tr, p0, one, count, stride, 0, false );
1079 Tran<double>::ApplyToFloat( tr, p0, zero, count, stride, 4, normalize );
1080 Tran<double>::ApplyToFloat( tr, p0, zero, count, stride, 8, normalize );
1081 }
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 SPHOTON_METHOD void sphoton::populate_simtrace_input( quad4& q ) const
1093 {
1094 q.q0.f.x = pos.x ;
1095 q.q0.f.y = pos.y ;
1096 q.q0.f.z = pos.z ;
1097
1098 q.q1.f.x = mom.x ;
1099 q.q1.f.y = mom.y ;
1100 q.q1.f.z = mom.z ;
1101 }
1102
1103
1104
1105
1106 SPHOTON_METHOD float sphoton::get_cost() const
1107 {
1108 return normalize_cost(pos);
1109 }
1110 SPHOTON_METHOD float sphoton::get_fphi() const
1111 {
1112 return normalize_fphi(pos);
1113 }
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124 SPHOTON_METHOD void sphoton::set_lpos(float lposcost, float lposfphi)
1125 {
1126 float cost = lposcost < -1.f ? -1.f : (lposcost > 1.f ? 1.f : lposcost);
1127 float fphi = lposfphi < 0.f ? 0.f : (lposfphi >= 1.f ? 0.999999f : lposfphi);
1128
1129 float theta = acosf(cost);
1130
1131 float phi = (fphi * 2.0f - 1.0f) * M_PIf;
1132
1133 float sin_theta = sinf(theta);
1134
1135 pos.x = sin_theta * cosf(phi);
1136 pos.y = sin_theta * sinf(phi);
1137 pos.z = cost;
1138 }
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 SPHOTON_METHOD size_t sphoton::GetIndexBeyondCursorContiguousIIndex( const sphoton* pp, size_t num, size_t cursor )
1157 {
1158 assert( cursor < num );
1159 unsigned ii0 = pp[cursor].iindex();
1160 for(size_t i=cursor+1 ; i < num ; i++)
1161 {
1162 unsigned ii = pp[i].iindex();
1163 if( ii != ii0 ) return i ;
1164 }
1165 return num ;
1166 }
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177 SPHOTON_METHOD void sphoton::GetContiguousIIndexStartIndices( std::vector<size_t>& starts, const sphoton* pp, size_t num )
1178 {
1179 size_t cursor = 0 ;
1180 starts.push_back(cursor);
1181 do
1182 {
1183 cursor = sphoton::GetIndexBeyondCursorContiguousIIndex(pp, num, cursor );
1184 starts.push_back(cursor);
1185 }
1186 while( cursor < num );
1187 }
1188
1189
1190
1191
1192
1193 #endif
1194
1195
1196 #if defined(__CUDACC__) || defined(__CUDABE__)
1197 #else
1198 inline std::ostream& operator<<(std::ostream& os, const sphoton& p )
1199 {
1200 os << "sphoton"
1201 << std::endl
1202 << p.desc()
1203 << std::endl
1204 ;
1205 return os;
1206 }
1207 #endif
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219 struct sphoton_selector
1220 {
1221 uint32_t hitmask ;
1222 sphoton_selector(uint32_t hitmask_) : hitmask(hitmask_) {};
1223 SPHOTON_METHOD bool operator() (const sphoton& p) const { return ( p.flagmask & hitmask ) == hitmask ; }
1224 SPHOTON_METHOD bool operator() (const sphoton* p) const { return ( p->flagmask & hitmask ) == hitmask ; }
1225 };
1226
1227