Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /**
0002 sphoton_test.cc
0003 =================
0004 
0005 ::
0006 
0007      ~/o/sysrap/tests/sphoton_test.sh
0008      TEST=set_lpos ~/o/sysrap/tests/sphoton_test.sh
0009 
0010      OFFSET=100,100,100 ~/o/sysrap/tests/sphoton_test.sh
0011      OFFSET=1000,1000,1000 ~/o/sysrap/tests/sphoton_test.sh
0012 
0013 
0014 **/
0015 
0016 #include <iostream>
0017 #include <array>
0018 #include <bitset>
0019 
0020 #include "scuda.h"
0021 #include "squad.h"
0022 #include "sphoton.h"
0023 #include "ssys.h"
0024 #include "NPX.h"
0025 #include "NPFold.h"
0026 
0027 #include "OpticksPhoton.h"
0028 
0029 struct sphoton_test
0030 {
0031     static std::string dump_(const char* label, unsigned mask);
0032     static void dump( const char* label, unsigned mask);
0033 
0034     static int qphoton_();
0035     static int cast();
0036     static int ephoton_();
0037     static int make_ephoton_array();
0038     static int sphoton_selector_();
0039     static int set_flag();
0040     static int addto_flagmask();
0041     static int change_flagmask();
0042     static int digest();
0043     static int sphotond_();
0044     static int Get();
0045     static int dGet();
0046     static int set_polarization();
0047     static int dot_pol_cross_mom_nrm();
0048     static int make_record_array();
0049     static int ChangeTimeInsitu();
0050 
0051     static int index();
0052     static int demoarray();
0053     static int set_lpos();
0054 
0055     static NP* MockupPhotonsWithContiguousIIndex(const std::vector<size_t>& starts);
0056     static int GetIndexBeyondCursorContiguousIIndex();
0057     static int GetContiguousIIndexStartIndices();
0058 
0059     template<typename T> static int localize_(sphoton& l, const sphoton& p, bool normalize );
0060     static int localize();
0061 
0062     static int main();
0063 };
0064 
0065 
0066 std::string sphoton_test::dump_(const char* label, unsigned mask)
0067 {
0068     std::bitset<32> bs(mask);
0069     std::stringstream ss ;
0070     ss << std::setw(25) << label << " " << bs << " " << std::setw(2) << bs.count() ;
0071     std::string s = ss.str();
0072     return s ;
0073 }
0074 void sphoton_test::dump( const char* label, unsigned mask)
0075 {
0076     std::cout << dump_(label, mask) << std::endl ;
0077 }
0078 
0079 int sphoton_test::qphoton_()
0080 {
0081 #ifdef WITH_QPHOTON
0082     qphoton qp ;
0083     qp.q.zero();
0084     std::cout << qp.q.desc() << std::endl ;
0085 #else
0086     assert(0);
0087 #endif
0088     return 0;
0089 }
0090 
0091 int sphoton_test::cast()
0092 {
0093     sphoton p ;
0094     quad4& q = (quad4&)p ;
0095     q.zero();
0096 
0097     p.wavelength = 501.f ;
0098 
0099     std::cout << q.desc() << std::endl ;
0100     std::cout << p.desc() << std::endl ;
0101     return 0;
0102 }
0103 int sphoton_test::ephoton_()
0104 {
0105     sphoton p ;
0106     p.ephoton();
0107     std::cout << p.desc() << std::endl ;
0108     return 0;
0109 }
0110 int sphoton_test::make_ephoton_array()
0111 {
0112     NP* p = sphoton::make_ephoton_array(8);
0113     std::cout
0114         << " p " << ( p ? p->sstr() : "-" )
0115         << std::endl
0116         << " p.repr " << ( p ? p->repr<float>() : "-" )
0117         << std::endl
0118         ;
0119     p->save("$FOLD/sphoton_test_make_ephoton_array.npy") ;
0120     return 0;
0121 }
0122 
0123 int sphoton_test::sphoton_selector_()
0124 {
0125     sphoton p ;
0126     p.ephoton();
0127 
0128     unsigned hitmask = 0xdeadbeef ;
0129     sphoton_selector s(hitmask) ;
0130     assert( s(p) == false );
0131 
0132     p.set_flag(hitmask);
0133     assert( s(p) == true );
0134     return 0;
0135 }
0136 
0137 int sphoton_test::set_flag()
0138 {
0139     sphoton p = {} ;
0140     std::cout << "set_flag.0 : " << p.descFlag() << "\n" ;
0141 
0142     p.set_flag( SURFACE_DETECT );
0143     std::cout << "set_flag.1 : " << p.descFlag() << "\n" ;
0144 
0145     p.set_flag( EFFICIENCY_COLLECT );
0146     std::cout << "set_flag.2 : " << p.descFlag() << "\n" ;
0147 
0148     return 0 ;
0149 }
0150 
0151 int sphoton_test::addto_flagmask()
0152 {
0153     sphoton p = {} ;
0154     std::cout << "addto_flagmask.0 : " << p.descFlag() << "\n" ;
0155 
0156     p.addto_flagmask( SURFACE_DETECT );
0157     std::cout << "addto_flagmask.1 SURFACE_DETECT : " << p.descFlag() << "\n" ;
0158 
0159     p.addto_flagmask( EFFICIENCY_COLLECT );
0160     std::cout << "addto_flagmask.2 EFFICIENCY_COLLECT : " << p.descFlag() << "\n" ;
0161 
0162     p.addto_flagmask( EFFICIENCY_CULL );
0163     std::cout << "addto_flagmask.3 EFFICIENCY_CULL : " << p.descFlag() << "\n" ;
0164 
0165 
0166 
0167     return 0 ;
0168 }
0169 
0170 
0171 
0172 
0173 
0174 
0175 /**
0176 
0177                      zero 00000000000000000000000000000000  0
0178               |= CERENKOV 00000000000000000000000000000001  1
0179          |= SCINTILLATION 00000000000000000000000000000011  2
0180                   |= MISS 00000000000000000000000000000111  3
0181            |= BULK_ABSORB 00000000000000000000000000001111  4
0182            |= BULK_REEMIT 00000000000000000000000000011111  5
0183           |= BULK_SCATTER 00000000000000000000000000111111  6
0184         |= SURFACE_DETECT 00000000000000000000000001111111  7
0185         |= SURFACE_ABSORB 00000000000000000000000011111111  8
0186       |= SURFACE_DREFLECT 00000000000000000000000111111111  9
0187       |= SURFACE_SREFLECT 00000000000000000000001111111111 10
0188       |= BOUNDARY_REFLECT 00000000000000000000011111111111 11
0189      |= BOUNDARY_TRANSMIT 00000000000000000000111111111111 12
0190                  |= TORCH 00000000000000000001111111111111 13
0191              |= NAN_ABORT 00000000000000000011111111111111 14
0192        |= EFFICIENCY_CULL 00000000000000000111111111111111 15
0193     |= EFFICIENCY_COLLECT 00000000000000001111111111111111 16
0194           &= ~BULK_ABSORB 00000000000000001111111111110111 15
0195           &= ~BULK_REEMIT 00000000000000001111111111100111 14
0196           |=  BULK_REEMIT 00000000000000001111111111110111 15
0197           |=  BULK_ABSORB 00000000000000001111111111111111 16
0198 
0199 **/
0200 
0201 int sphoton_test::change_flagmask()
0202 {
0203     unsigned flagmask = 0u ;         dump("zero", flagmask );
0204     flagmask |= CERENKOV ;           dump("|= CERENKOV", flagmask );
0205     flagmask |= SCINTILLATION ;      dump("|= SCINTILLATION", flagmask );
0206     flagmask |= MISS ;               dump("|= MISS", flagmask );
0207     flagmask |= BULK_ABSORB ;        dump("|= BULK_ABSORB", flagmask );
0208     flagmask |= BULK_REEMIT ;        dump("|= BULK_REEMIT", flagmask );
0209     flagmask |= BULK_SCATTER ;       dump("|= BULK_SCATTER", flagmask );
0210     flagmask |= SURFACE_DETECT ;     dump("|= SURFACE_DETECT", flagmask );
0211     flagmask |= SURFACE_ABSORB ;     dump("|= SURFACE_ABSORB", flagmask );
0212     flagmask |= SURFACE_DREFLECT ;   dump("|= SURFACE_DREFLECT", flagmask );
0213     flagmask |= SURFACE_SREFLECT ;   dump("|= SURFACE_SREFLECT", flagmask );
0214     flagmask |= BOUNDARY_REFLECT ;   dump("|= BOUNDARY_REFLECT", flagmask );
0215     flagmask |= BOUNDARY_TRANSMIT ;  dump("|= BOUNDARY_TRANSMIT", flagmask );
0216     flagmask |= TORCH ;              dump("|= TORCH", flagmask);
0217     flagmask |= NAN_ABORT ;          dump("|= NAN_ABORT", flagmask );
0218     flagmask |= EFFICIENCY_CULL ;    dump("|= EFFICIENCY_CULL", flagmask );
0219     flagmask |= EFFICIENCY_COLLECT ; dump("|= EFFICIENCY_COLLECT", flagmask) ;
0220     flagmask &= ~BULK_ABSORB ;       dump("&= ~BULK_ABSORB", flagmask);
0221     flagmask &= ~BULK_REEMIT ;       dump("&= ~BULK_REEMIT", flagmask);
0222     flagmask |=  BULK_REEMIT ;       dump("|=  BULK_REEMIT", flagmask);
0223     flagmask |=  BULK_ABSORB ;       dump("|=  BULK_ABSORB", flagmask);
0224     return 0;
0225 }
0226 
0227 int sphoton_test::digest()
0228 {
0229     sphoton p ;
0230     p.ephoton();
0231 
0232     std::cout
0233         << " p.digest()   " << p.digest() << std::endl
0234         << " p.digest(16) " << p.digest(16) << std::endl
0235         << " p.digest(12) " << p.digest(12) << std::endl
0236         ;
0237 
0238     return 0;
0239 }
0240 
0241 int sphoton_test::sphotond_()
0242 {
0243     sphoton  f ;
0244     sphotond d ;
0245 
0246     assert( sizeof(d) == 2*sizeof(f) );
0247     assert( sizeof(f) == 16*sizeof(float) );
0248     assert( sizeof(d) == 16*sizeof(double) );
0249     return 0;
0250 }
0251 
0252 int sphoton_test::Get()
0253 {
0254     std::cout << "test_sphoton::Get" << std::endl ;
0255     float time_0 =  3.f ;
0256     float time_1 = 13.f ;
0257 
0258     NP* a = NP::Make<float>(2, 4, 4);
0259     std::array<float, 32> vv = {{
0260        0.f,  1.f,  2.f,  time_0,
0261        4.f,  5.f,  6.f,  7.f,
0262        8.f,  9.f, 10.f, 11.f,
0263       12.f, 13.f, 14.f, 15.f,
0264 
0265       10.f, 11.f, 12.f, time_1,
0266       14.f, 15.f, 16.f, 17.f,
0267       18.f, 19.f, 20.f, 21.f,
0268       22.f, 23.f, 24.f, 25.f
0269      }};
0270 
0271     memcpy( a->values<float>(), vv.data(), sizeof(float)*vv.size() );
0272 
0273     sphoton p0 ;
0274     sphoton::Get(p0, a, 0 );
0275     assert( p0.time == time_0 );
0276 
0277     sphoton p1 ;
0278     sphoton::Get(p1, a, 1 );
0279     assert( p1.time == time_1 );
0280     return 0;
0281 }
0282 
0283 int sphoton_test::dGet()
0284 {
0285     std::cout << "test_sphoton::dGet" << std::endl ;
0286 
0287     double time_0 =  3. ;
0288     double time_1 = 13. ;
0289 
0290     NP* a = NP::Make<double>(2, 4, 4);
0291     std::array<double, 32> vv = {{
0292        0.,  1.,  2.,  time_0,
0293        4.,  5.,  6.,  7.,
0294        8.,  9., 10., 11.,
0295       12., 13., 14., 15.,
0296 
0297       10., 11., 12., time_1,
0298       14., 15., 16., 17.,
0299       18., 19., 20., 21.,
0300       22., 23., 24., 25.
0301      }};
0302 
0303     memcpy( a->values<double>(), vv.data(), sizeof(double)*vv.size() );
0304 
0305     sphotond p0 ;
0306     sphotond::Get(p0, a, 0 );
0307     assert( p0.time == time_0 );
0308 
0309     sphotond p1 ;
0310     sphotond::Get(p1, a, 1 );
0311     assert( p1.time == time_1 );
0312     return 0;
0313 }
0314 
0315 
0316 /**
0317 set_polarization
0318 -----------------
0319 
0320 ::
0321 
0322     .      nrm
0323             Z
0324      mom    |
0325         \   |
0326          \  |
0327           \ |
0328            \|
0329      -------+--------- X
0330 
0331 
0332 * pol:transverse to mom
0333 * trv:perpendicular to plane of incidence (-Y axis into page)
0334 
0335 
0336 **/
0337 
0338 int sphoton_test::set_polarization()
0339 {
0340     std::cout << "sphoton_test::set_polarization" << std::endl ;
0341 
0342     float3 nrm = make_float3(0.f, 0.f, 1.f) ;
0343     float3 mom = normalize(make_float3( 1.f, 0.f, -1.f ));
0344 
0345     float3 trv = normalize(cross(mom, nrm )) ;   // -Y
0346     float3 trv1 = normalize(cross(nrm, mom )) ;  // +Y
0347 
0348     std::cout
0349         << " nrm "  << nrm << std::endl
0350         << " mom "  << mom << std::endl
0351         << " trv "  << trv << std::endl
0352         << " trv1 "  << trv1 << std::endl
0353         ;
0354 
0355     sphoton p ;
0356     p.zero();
0357     p.mom = mom ;
0358 
0359     const int N = 16 ;
0360     for(int i=0 ; i <= N ; i++)
0361     {
0362         float frac_twopi = float(i)/float(N)  ;
0363         p.set_polarization(frac_twopi) ;
0364 
0365         std::cout
0366             << p.descDir()
0367             << " frac_twopi " << std::fixed << std::setw(7) << std::setprecision(3) << frac_twopi
0368             //<< " dot(p.mom,p.pol) " << std::fixed << std::setw(7) << std::setprecision(3) << dot(p.mom,p.pol)
0369             << " dot(p.pol, nrm) " << std::fixed << std::setw(7) << std::setprecision(3) <<  dot(p.pol, nrm)
0370             << " dot(p.pol, trv) " << std::fixed << std::setw(7) << std::setprecision(3) <<  dot(p.pol, trv)
0371             << std::endl
0372             ;
0373 
0374         // dot(p.pol, nrm) zero where p.pol is orthogonal to the normal
0375 
0376     }
0377     return 0;
0378 }
0379 
0380 
0381 
0382 /**
0383 dot_pol_cross_mom_nrm
0384 -----------------------
0385 
0386 
0387     mom      nrm
0388        .      |
0389          .    |
0390            .  |
0391              .|
0392      ---------+----------
0393 
0394 * mom and nrm vectors define the plane of incidence, they lie within it
0395 * pol is transverse to mom, so there is a circle of possible directions including
0396 
0397   * transverse to plane of incidence (S polarized)
0398   * within the plane of incidence (P polarized)
0399   * combination of S and P polarizations by
0400     sweeping the pol vector around the mom vector
0401     whilst staying transverse to the mom vector
0402 
0403 
0404 **/
0405 
0406 
0407 int sphoton_test::dot_pol_cross_mom_nrm()
0408 {
0409     printf("//sphoton_test::dot_pol_cross_mom_nrm \n");
0410 
0411     float3 nrm = normalize(make_float3(0.f, 0.f, 1.f)) ;
0412 
0413     //float3 mom = normalize(make_float3(1.f, 0.f, -1.f ));  // 45 degrees
0414     //float3 mom = normalize(make_float3(2.f, 0.f, -1.f ));  // shallower
0415     float3 mom = normalize(make_float3(1.f, 0.f, -2.f ));    // steeper
0416 
0417 
0418     float3 tra = cross( mom, nrm ) ;
0419     float ltr = length(tra) ;
0420     float mct = dot(mom,nrm) ;
0421     float st = sqrt( 1.f - mct*mct );
0422     float llmm = ltr*ltr + mct*mct ;   // tis close to 1.f
0423 
0424     std::stringstream ss ;
0425     ss
0426         << " nrm "  << nrm
0427         << " mom "  << mom
0428         << " tra "  << tra
0429         << " mct "  << mct
0430         << " st "  << st
0431         << " ltr "  << ltr
0432         << " llmm "  << llmm
0433         ;
0434 
0435     std::string str = ss.str();
0436     std::cout << str << std::endl ;
0437 
0438 
0439     sphoton p ;
0440     p.zero();
0441     p.mom = mom ;
0442 
0443     const int N = ssys::getenvint("N", 16)  ;
0444 
0445     NP* a = NP::Make<float>(N, 4);
0446     float* aa = a->values<float>();
0447 
0448     for(int i=0 ; i < N ; i++)
0449     {
0450         float frac_twopi = float(i)/float(N)  ;
0451         p.set_polarization(frac_twopi) ;
0452         float check_pol_mom_transverse = dot(p.mom,p.pol) ;
0453         assert( std::abs(check_pol_mom_transverse) < 1e-6f ) ;
0454 
0455         float pot = dot( p.pol, tra ) ;  // value is cos(pol-trans-angle)*sin(mom-nrm-angle)
0456         float pot_st = pot/st ;   // this is spol_frac which stays in range from -1. to 1.
0457         float pot_mct = pot/mct ; // some unholy combination that is not constrained to -1. to 1.
0458 
0459         std::cout
0460             << p.descDir()
0461             << " frac_twopi " << std::fixed << std::setw(7) << std::setprecision(3) << frac_twopi
0462             << " pot " << std::fixed << std::setw(7) << std::setprecision(3) << pot
0463             << " pot_mct " << std::fixed << std::setw(7) << std::setprecision(3) << pot_mct
0464             << " pot_st " << std::fixed << std::setw(7) << std::setprecision(3) << pot_st
0465             << std::endl
0466             ;
0467 
0468         aa[i*4+0] = frac_twopi ;
0469         aa[i*4+1] = pot ;
0470         aa[i*4+2] = pot_mct ;
0471         aa[i*4+3] = pot_st ;
0472     }
0473     a->save("$FOLD/dot_pol_cross_mom_nrm.npy");
0474     return 0;
0475 }
0476 
0477 
0478 /**
0479 sphoton_test::make_record_array
0480 ---------------------------------
0481 
0482 ::
0483 
0484     In [15]: np.min(t.record[:,:,0].reshape(-1,4),axis=0)
0485     Out[15]: array([-9.,  0., -9.,  0.], dtype=float32)
0486 
0487     In [16]: np.max(t.record[:,:,0].reshape(-1,4),axis=0)
0488     Out[16]: array([9., 0., 9., 9.], dtype=float32)
0489 
0490 
0491 **/
0492 
0493 
0494 
0495 int sphoton_test::make_record_array()
0496 {
0497     std::vector<float>* offset = ssys::getenvfloatvec("OFFSET","0,0,0");
0498     assert( offset && offset->size() == 3 );
0499 
0500     std::cout << "sphoton_test::make_record_array OFFSET [ " ;
0501     for(int i=0 ; i < 3 ; i++) std::cout
0502          << std::fixed << std::setw(10) << std::setprecision(4) << (*offset)[i]
0503          ;
0504     std::cout << " ]" << std::endl ;
0505 
0506 
0507     NP* a = NP::Make<float>( 360, 10, 4, 4 );
0508     int ni = a->shape[0] ;
0509     int nj = a->shape[1] ;
0510     int nk = a->shape[2] ;
0511     int nl = a->shape[3] ;
0512     float* aa = a->values<float>();
0513 
0514     for(int i=0 ; i < ni ; i++)
0515     {
0516         float t = 2.f*M_PIf * float(i)/360.  ;
0517         float ct = cos(t);
0518         float st = sin(t);
0519 
0520         for(int j=0 ; j < nj ; j++)
0521         {
0522             int idx_ij = i*nj*nk*nl + j*nk*nl ;
0523             sphoton p = {} ;
0524 
0525             // XZ ripples on pond heading outwards from origin
0526             p.pos.x = (*offset)[0] + ct*float(j) ;
0527             p.pos.y = (*offset)[1] + 0.f ;
0528             p.pos.z = (*offset)[2] + st*float(j) ;
0529             p.time = float(j) ;
0530 
0531             p.mom.x = ct ;
0532             p.mom.y = 0.f ;
0533             p.mom.z = st ;
0534 
0535             memcpy( aa + idx_ij, p.cdata(), sizeof(float)*nk*nl );
0536         }
0537     }
0538     a->set_meta<std::string>("rpos", "4,GL_FLOAT,GL_FALSE,64,0,false" );
0539     // Q:What reads this OpenGL attribute metadata ?
0540     // A:sysrap/SGLFW.h SGLFW_Attribute
0541 
0542 
0543     static const int N = 4 ;
0544     float mn[N] = {} ;
0545     float mx[N] = {} ;
0546 
0547     int item_stride = 4 ;
0548     int item_offset = 0 ;
0549 
0550     a->minmax2D_reshaped<N,float>(mn, mx, item_stride, item_offset );
0551     for(int j=0 ; j < N ; j++) std::cout
0552           << std::setw(2) << j
0553           << " mn "
0554           << std::setw(10) << std::fixed << std::setprecision(4) << mn[j]
0555           << " mx "
0556           << std::setw(10) << std::fixed << std::setprecision(4) << mx[j]
0557           << std::endl
0558           ;
0559 
0560     a->save("$FOLD/record.npy");
0561     return 0;
0562 }
0563 
0564 
0565 int sphoton_test::ChangeTimeInsitu()
0566 {
0567     std::vector<sphoton> pp(3) ;
0568     pp[0] = {} ;
0569     pp[1] = {} ;
0570     pp[2] = {} ;
0571 
0572     pp[0].time = 0.1f ;
0573     pp[1].time = 0.2f ;
0574     pp[2].time = 0.3f ;
0575 
0576     NP* a = NPX::ArrayFromVec<float, sphoton>(pp, 4, 4);
0577     sphoton::ChangeTimeInsitu(a, 100.f);
0578 
0579     NPFold* f = new NPFold ;
0580     f->add("a", a );
0581     f->save("$FOLD/ChangeTimeInsitu");
0582 
0583     return 0 ;
0584 }
0585 
0586 int sphoton_test::index()
0587 {
0588     sphoton p = {} ;
0589     std::vector<uint64_t> xx = {
0590          0x0,
0591          0x1,
0592          0xff,
0593          0xffff,
0594          0xffffff,
0595          0xffffffff,
0596          0xffffffffff,
0597          0xffffffffffff,
0598          0xffffffffffffff
0599      };
0600 
0601     std::vector<uint64_t> ii = {
0602          0x0,
0603          0x1,
0604          0xff,
0605          0xffff,
0606          0xffffff,
0607          0xffffffff,
0608          0xffffffffff,
0609          0xffffffffffff,
0610          0xffffffffffffff
0611      };
0612 
0613 
0614     uint64_t INDEX_MAX = 0xffffffffff ;  //  0xffffffffff/1e9 = 1099.511   1.099 trillion
0615     unsigned IDENTITY_MAX = 0xffffffu ;  // 0xffffff/1e6 = 16.777215    16.7 million
0616 
0617     for(size_t i=0 ; i < xx.size() ; i++)
0618     {
0619         uint64_t x0 = xx[i];
0620         unsigned i0 = ii[i]; // narrow
0621 
0622         p.set_index(x0);
0623         p.set_identity(i0);
0624 
0625         uint64_t x1 = p.get_index();
0626         unsigned i1 = p.get_identity();
0627 
0628         std::cout
0629            << std::setw(4) << i
0630            << " x0 "
0631            << std::setw(15) << std::hex << x0 << std::dec
0632            << " x1 "
0633            << std::setw(15) << std::hex << x1 << std::dec
0634            << " ( x0 & INDEX_MAX ) "
0635            << std::setw(15) << std::hex << ( x0 & INDEX_MAX ) << std::dec
0636            << " ( x1 & INDEX_MAX ) "
0637            << std::setw(15) << std::hex << ( x1 & INDEX_MAX ) << std::dec
0638            << " i0 "
0639            << std::setw(15) << std::hex << i0 << std::dec
0640            << " i1 "
0641            << std::setw(15) << std::hex << i1 << std::dec
0642            << " ( i0 & IDENTITY_MAX ) "
0643            << std::setw(15) << std::hex << ( x0 & IDENTITY_MAX ) << std::dec
0644            << " ( x1 & IDENTITY_MAX ) "
0645            << std::setw(15) << std::hex << ( x1 & IDENTITY_MAX ) << std::dec
0646            << "\n"
0647            ;
0648 
0649         assert( ( x0 & INDEX_MAX ) == x1 ) ;
0650         assert( ( i0 & IDENTITY_MAX ) == i1 ) ;
0651     }
0652     return 0 ;
0653 }
0654 
0655 int sphoton_test::demoarray()
0656 {
0657     NP* p = sphoton::demoarray(10);
0658     p->save("$FOLD/demoarray.npy");
0659     return 0 ;
0660 }
0661 
0662 int sphoton_test::set_lpos()
0663 {
0664      sphoton p = {};
0665 
0666      float eps = 1e-6 ;  // 1e-7 has one fphi deviant
0667      int ni = 1000 ;
0668 
0669      std::cout
0670          << "[sphoton_test::set_lpos"
0671          << " eps "  << std::setw(10) << std::setprecision(8) << std::fixed << eps
0672          << " ni " << ni
0673          << "\n"
0674          ;
0675 
0676      int deviant = 0 ;
0677      for(int i=0 ; i < ni ; i++)
0678      {
0679          //float f = float(i)/float(ni) ;
0680          float f = float(i+1)/float(ni+1) ;  // avoid zero and one
0681 
0682          float cost_0 = f;
0683          float fphi_0 = f;
0684          p.set_lpos(cost_0, fphi_0);
0685          float cost_1 = p.get_cost();
0686          float fphi_1 = p.get_fphi();
0687 
0688          float cost_01 = ( cost_0 - cost_1 );
0689          float fphi_01 = ( fphi_0 - fphi_1 ) ;
0690 
0691          bool select = std::abs(cost_01) > eps || std::abs(fphi_01) > eps ;
0692          if(select)
0693          {
0694              deviant += 1 ;
0695              std::cout
0696                  << std::setw(5) << i
0697                  << " cost_0 "  << std::setw(10) << std::setprecision(6) << std::fixed << cost_0
0698                  << " cost_1 "  << std::setw(10) << std::setprecision(6) << std::fixed << cost_1
0699                  << " cost_01*1e6 " << std::setw(10) << std::setprecision(6) << std::fixed << cost_01*1e6
0700                  << " fphi_0 "  << std::setw(10) << std::setprecision(6) << std::fixed << fphi_0
0701                  << " fphi_1 "  << std::setw(10) << std::setprecision(6) << std::fixed << fphi_1
0702                  << " fphi_01*1e6 " << std::setw(10) << std::setprecision(6) << std::fixed << fphi_01*1e6
0703                  << " p.pos.x " << std::setw(10) << std::setprecision(6) << std::fixed << p.pos.x
0704                  << " p.pos.y " << std::setw(10) << std::setprecision(6) << std::fixed << p.pos.y
0705                  << " p.pos.z " << std::setw(10) << std::setprecision(6) << std::fixed << p.pos.z
0706                  << "\n"
0707                  ;
0708 
0709          }
0710     }
0711 
0712      std::cout
0713          << "]sphoton_test::set_lpos deviant " << deviant << "\n" ;
0714 
0715 
0716 
0717     return 0 ;
0718 }
0719 
0720 /**
0721 sphoton_test::MockupPhotonsWithContiguousIIndex
0722 -------------------------------------------------
0723 
0724 Creates an array of *ni* "starts[-1]" photons.
0725 For the i-th photon the index of the *starts* ranges
0726 that *i* is part of gives a *j* index that yields
0727 an *ii* result.
0728 
0729 **/
0730 
0731 
0732 NP* sphoton_test::MockupPhotonsWithContiguousIIndex(const std::vector<size_t>& starts) // static
0733 {
0734     size_t nj = starts.size();
0735     size_t ni = starts[nj-1] ;
0736 
0737     NP* photons = sphoton::zeros(ni);
0738     sphoton* pp = (sphoton*)photons->bytes();
0739     for(size_t i=0 ; i < ni ; i++ )
0740     {
0741         unsigned ii = 0 ;
0742         for(size_t j=1 ; j < nj ; j++)
0743         {
0744             bool j_range = i >= starts[j-1] && i < starts[j] ;
0745             if( j_range )
0746             {
0747                 ii = j*100 ;
0748                 break ;
0749             }
0750         }
0751 
0752 
0753         pp[i].set_iindex__( ii );
0754     }
0755     return photons ;
0756 }
0757 
0758 int sphoton_test::GetIndexBeyondCursorContiguousIIndex()
0759 {
0760     std::vector<size_t> starts = { 0, 100, 200, 400, 600, 800, 1000 };
0761     NP* photons = MockupPhotonsWithContiguousIIndex(starts);
0762 
0763     sphoton* pp = (sphoton*)photons->bytes();
0764     size_t num = photons->num_items();
0765 
0766     std::cout
0767         << "sphoton_test::GetIndexBeyondCursorContiguousIIndex"
0768         << "\n"
0769         ;
0770 
0771 
0772     std::vector<size_t> recover ;
0773 
0774     size_t cursor = 0 ;
0775     recover.push_back(cursor);
0776     do
0777     {
0778         cursor = sphoton::GetIndexBeyondCursorContiguousIIndex(pp, num, cursor );
0779         recover.push_back(cursor);
0780         std::cout << " cursor " << cursor << "\n" ;
0781     }
0782     while( cursor < num );
0783     assert( recover == starts );
0784 
0785     return 0 ;
0786 }
0787 
0788 int sphoton_test::GetContiguousIIndexStartIndices()
0789 {
0790     std::vector<size_t> starts = { 0, 100, 200, 400, 600, 800, 1000 };
0791     NP* photons = MockupPhotonsWithContiguousIIndex(starts);
0792     sphoton* pp = (sphoton*)photons->bytes();
0793     size_t num = photons->num_items();
0794 
0795     std::vector<size_t> recover ;
0796     sphoton::GetContiguousIIndexStartIndices(recover, pp, num );
0797     assert( recover == starts );
0798 
0799     return 0 ;
0800 }
0801 
0802 template<typename T>
0803 int sphoton_test::localize_(sphoton& l, const sphoton& p, bool normalize )
0804 {
0805     std::array<T, 16> src = {{
0806          1.,     0.,     0.,     0.,
0807          0.,     1.,     0.,     0.,
0808          0.,     0.,     1.,     0.,
0809          100., 200.,   300.,     1.  }} ;
0810 
0811     glm::tmat4x4<T> tr(1.) ;
0812     memcpy( glm::value_ptr(tr), src.data(), sizeof(T)*16 );
0813     p.localize( l, tr, normalize );
0814 
0815     return 0 ;
0816 }
0817 
0818 int sphoton_test::localize()
0819 {
0820     sphoton p = {} ;
0821     p.pos = { 0.f, 0.f, 0.f } ;
0822     p.mom = { 0.f, 0.f, 1.f } ;
0823     p.pol = { 0.f, 1.f, 0.f } ;
0824 
0825     sphoton l = {} ;
0826 
0827     int rc = localize_<double>(l,p, false);
0828 
0829     std::cout
0830         << "localize"
0831         << "\n"
0832         << "p " << p.desc()
0833         << "\n"
0834         << "l " << l.desc()
0835         << "\n"
0836         ;
0837 
0838     return rc ;
0839 }
0840 
0841 
0842 
0843 
0844 int sphoton_test::main()
0845 {
0846     const char* TEST = ssys::getenvvar("TEST","make_record_array") ;
0847     bool ALL = 0 == strcmp(TEST, "ALL");
0848 
0849     int rc = 0 ;
0850 
0851     if(ALL||0==strcmp(TEST, "qphoton_"))              rc += qphoton_();
0852     if(ALL||0==strcmp(TEST, "cast"))                  rc += cast();
0853     if(ALL||0==strcmp(TEST, "ephoton_"))              rc += ephoton_();
0854     if(ALL||0==strcmp(TEST, "make_ephoton_array"))    rc += make_ephoton_array();
0855     if(ALL||0==strcmp(TEST, "sphoton_selector_"))     rc += sphoton_selector_();
0856     if(ALL||0==strcmp(TEST, "set_flag"))              rc += set_flag();
0857     if(ALL||0==strcmp(TEST, "addto_flagmask"))        rc += addto_flagmask();
0858     if(ALL||0==strcmp(TEST, "change_flagmask"))       rc += change_flagmask();
0859     if(ALL||0==strcmp(TEST, "digest"))                rc += digest();
0860     if(ALL||0==strcmp(TEST, "sphotond_"))             rc += sphotond_();
0861     if(ALL||0==strcmp(TEST, "Get"))                   rc += Get();
0862     if(ALL||0==strcmp(TEST, "dGet"))                  rc += dGet();
0863     if(ALL||0==strcmp(TEST, "set_polarization"))      rc += set_polarization();
0864     if(ALL||0==strcmp(TEST, "dot_pol_cross_mom_nrm")) rc += dot_pol_cross_mom_nrm();
0865     if(ALL||0==strcmp(TEST, "make_record_array"))     rc += make_record_array();
0866     if(ALL||0==strcmp(TEST, "ChangeTimeInsitu"))      rc += ChangeTimeInsitu();
0867     if(ALL||0==strcmp(TEST, "index"))                 rc += index();
0868     if(ALL||0==strcmp(TEST, "demoarray"))             rc += demoarray();
0869     if(ALL||0==strcmp(TEST, "set_lpos"))              rc += set_lpos();
0870 
0871     if(ALL||0==strcmp(TEST, "GetIndexBeyondCursorContiguousIIndex")) rc += GetIndexBeyondCursorContiguousIIndex();
0872     if(ALL||0==strcmp(TEST, "GetContiguousIIndexStartIndices"))      rc += GetContiguousIIndexStartIndices();
0873     if(ALL||0==strcmp(TEST, "localize"))                             rc += localize();
0874 
0875     return rc ;
0876 }
0877 
0878 int main()
0879 {
0880     return sphoton_test::main();
0881 }
0882