File indexing completed on 2026-04-09 07:49:21
0001
0002
0003
0004 #include <iostream>
0005 #include <iomanip>
0006 #include <bitset>
0007
0008 #include "scuda.h"
0009 #include "squad.h"
0010 #include "ssys.h"
0011 #include "sseq.h"
0012 #include "spath.h"
0013
0014 #include "NPX.h"
0015 #include "OpticksPhoton.h"
0016 #include "OpticksPhoton.hh"
0017
0018
0019 struct sseq_test
0020 {
0021 static int FFS_0();
0022 static int FFS_1();
0023 static int add_nibble_0();
0024 static int add_nibble_1();
0025 static int add_nibble_2();
0026 static int truncation();
0027 };
0028
0029
0030 int sseq_test::FFS_0()
0031 {
0032 typedef long long LL ;
0033
0034 LL zero = 0ll ;
0035 LL one = 1ll ;
0036
0037 for(LL i=-1 ; i < 64 ; i++)
0038 {
0039 LL x = i == -1 ? zero : ( one << i ) ;
0040 std::cout
0041 << " x " << std::setw(16) << std::hex << x << std::dec
0042 << " FFS(x) " << std::setw(2) << FFS(x)
0043 << " FFSLL(x) " << std::setw(2) << FFSLL(x)
0044 << std::endl
0045 ;
0046 }
0047 return 0;
0048 }
0049
0050 int sseq_test::FFS_1()
0051 {
0052 typedef unsigned long long ULL ;
0053 for(int i=-1 ; i < 64 ; i++)
0054 {
0055 ULL x = i == -1 ? 0ull : ( 1ull << i ) ;
0056
0057 unsigned f32 = FFS(x) ;
0058 unsigned f64 = FFSLL(x) ;
0059
0060 unsigned x32 = rFFS(f32) ;
0061 ULL x64 = rFFSLL(f64) ;
0062
0063 std::cout
0064
0065 << " i " << std::setw(3) << i
0066 << " x " << std::setw(16) << std::hex << x << std::dec
0067 << " FFS(x) " << std::setw(2) << f32
0068 << " FFSLL(x) " << std::setw(2) << f64
0069 << " x32 " << std::setw(16) << std::hex << x32 << std::dec
0070 << " x64 " << std::setw(16) << std::hex << x64 << std::dec
0071 << std::endl
0072 ;
0073
0074 if(i < 32) assert( x32 == x );
0075 assert( x64 == x );
0076 }
0077 return 0 ;
0078 }
0079
0080 int sseq_test::add_nibble_0()
0081 {
0082 sseq seq ;
0083 seq.zero();
0084
0085 for(unsigned bounce=0 ; bounce < 16 ; bounce++)
0086 {
0087 unsigned flag = 0x1 << bounce ;
0088 unsigned boundary = bounce ;
0089 seq.add_nibble( bounce, flag, boundary );
0090 std::cout
0091 << " flag.dec " << std::setw(5) << std::dec << flag << std::dec
0092 << " flag.hex " << std::setw(5) << std::hex << flag << std::dec
0093 << " FFS(flag) " << std::setw(2) << FFS(flag)
0094 << " ( FFS(flag) & 0xfull ) " << std::setw(2) << ( FFS(flag) & 0xfull )
0095 << " boundary " << std::setw(2) << boundary
0096 << " ( boundary & 0xfull ) " << std::setw(2) << ( boundary & 0xfull )
0097 << seq.desc()
0098 << std::endl
0099 ;
0100 }
0101 std::cout << "NB the nibble restriction means that FFS(flag) of 15 is the max step flag that can be carried in the seqhis sequence " << std::endl ;
0102 return 0;
0103 }
0104
0105
0106 int sseq_test::add_nibble_1()
0107 {
0108 for(unsigned i=0 ; i < 16 ; i++)
0109 {
0110 unsigned flag = 0x1 << i ;
0111 std::cout
0112 << " flag " << std::setw(6) << flag
0113 << " FFS(flag) " << std::setw(2) << FFS(flag)
0114 << " OpticksPhoton::Flag(flag) " << std::setw(20) << OpticksPhoton::Flag(flag)
0115 << std::endl
0116 ;
0117 }
0118 return 0;
0119 }
0120
0121 int sseq_test::add_nibble_2()
0122 {
0123 sseq a ;
0124 {
0125 a.zero();
0126 a.add_nibble(0, TORCH, 0);
0127 a.add_nibble(1, BOUNDARY_TRANSMIT, 0);
0128 a.add_nibble(2, BOUNDARY_TRANSMIT, 0);
0129 a.add_nibble(3, BOUNDARY_TRANSMIT, 0);
0130 a.add_nibble(4, BOUNDARY_TRANSMIT, 0);
0131 a.add_nibble(5, EFFICIENCY_COLLECT, 0);
0132 }
0133 std::cout << "a " << a.desc_seqhis() << std::endl ;
0134
0135 sseq b ;
0136 {
0137 b.zero();
0138 b.add_nibble(0, TORCH, 0);
0139 b.add_nibble(1, BOUNDARY_TRANSMIT, 0);
0140 b.add_nibble(2, BOUNDARY_TRANSMIT, 0);
0141 b.add_nibble(3, BOUNDARY_TRANSMIT, 0);
0142 b.add_nibble(4, BOUNDARY_TRANSMIT, 0);
0143 b.add_nibble(5, EFFICIENCY_CULL, 0);
0144 }
0145 std::cout << "b " << b.desc_seqhis() << std::endl ;
0146 return 0 ;
0147 }
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 int sseq_test::truncation()
0165 {
0166 for(int i=0 ; i < 18 ; i++)
0167 {
0168 unsigned flag = 0x1 << i ;
0169 bool truncated = ( FFS(flag) & 0xfu ) != FFS(flag) ;
0170
0171 const char* abr = OpticksPhoton::Abbrev(flag) ;
0172 std::cout
0173 << " flag: 0x1 << " << std::setw(2) << i
0174 << " FFS(flag) " << std::setw(2) << FFS(flag)
0175 << " FFS(flag) & 0xfu " << std::setw(2) << ( FFS(flag) & 0xfu )
0176 << " truncated " << ( truncated ? "YES" : "NO " )
0177 << " OpticksPhoton::Abbrev(flag) [" << abr << "]"
0178 << "\n"
0179 ;
0180 }
0181 return 0;
0182 }
0183
0184
0185
0186 void test_GetNibble()
0187 {
0188 typedef unsigned long long ULL ;
0189 ULL x = 0x0123456789abcdefull ;
0190
0191 for(unsigned i=0 ; i < 16 ; i++)
0192 {
0193 unsigned nib = sseq::GetNibble(x, i);
0194 std::cout << std::setw(3) << i << " nib " << std::hex << nib << std::dec << std::endl ;
0195 }
0196 }
0197
0198 void test_ClearNibble()
0199 {
0200 typedef unsigned long long ULL ;
0201 ULL x = 0xa123456789abcdefull ;
0202
0203 for(int i=-1 ; i < 16 ; i++)
0204 {
0205 if( i > -1 ) sseq::ClearNibble(x, i);
0206 std::cout << std::setw(3) << i << " x " << std::setw(16) << std::setfill('0') << std::hex << x << std::dec << std::endl ;
0207 }
0208 }
0209
0210 void test_SetNibble()
0211 {
0212 typedef unsigned long long ULL ;
0213 ULL x = 0xa123456789abcdefull ;
0214
0215 for(int i=-1 ; i < 16 ; i++)
0216 {
0217 if( i > -1 ) sseq::SetNibble(x, i, 0xf);
0218 std::cout << std::setw(3) << i << " x " << std::setw(16) << std::setfill('0') << std::hex << x << std::dec << std::endl ;
0219 }
0220 }
0221
0222 void test_get_flag_set_flag()
0223 {
0224 sseq seq ;
0225 seq.zero();
0226
0227 std::vector<unsigned> history = {
0228 CERENKOV,
0229 BOUNDARY_TRANSMIT,
0230 BOUNDARY_TRANSMIT,
0231 BULK_SCATTER,
0232 BULK_REEMIT,
0233 BOUNDARY_TRANSMIT,
0234 SURFACE_DETECT,
0235 BULK_ABSORB,
0236 SCINTILLATION,
0237 TORCH
0238 } ;
0239
0240 for(unsigned i=0 ; i < history.size() ; i++) seq.add_nibble(i, history[i], 0) ;
0241
0242
0243 std::cout << seq.desc_seqhis() << std::endl ;
0244
0245 for(unsigned i=0 ; i < history.size() ; i++)
0246 {
0247 unsigned flag = seq.get_flag(i) ;
0248 assert( flag == history[i] );
0249 std::cout << OpticksPhoton::Flag(flag) << std::endl ;
0250 std::cout << seq.desc_seqhis() << std::endl ;
0251 }
0252
0253
0254 std::cout << seq.desc_seqhis() << std::endl ;
0255
0256 for(unsigned i=0 ; i < history.size() ; i++)
0257 {
0258 unsigned flag = seq.get_flag(i) ;
0259 if(flag == BULK_ABSORB) seq.set_flag(i, BULK_REEMIT) ;
0260 }
0261
0262
0263 std::cout << seq.desc_seqhis() << std::endl ;
0264
0265
0266 }
0267
0268
0269
0270 void test_desc_seqhis(const std::vector<unsigned>& history)
0271 {
0272 sseq seq ;
0273 seq.zero();
0274
0275 for(int bounce=0 ; bounce < history.size() ; bounce++)
0276 {
0277 unsigned flag = history[bounce] ;
0278 unsigned boundary = 0 ;
0279 seq.add_nibble( bounce, flag, boundary );
0280
0281 std::cout
0282 << std::setw(20) << OpticksPhoton::Flag(flag)
0283 << " : " << seq.desc_seqhis()
0284 << std::endl
0285 ;
0286 }
0287 }
0288
0289 void test_desc_seqhis_0()
0290 {
0291 std::vector<unsigned> history = {
0292 CERENKOV,
0293 BOUNDARY_TRANSMIT,
0294 BOUNDARY_TRANSMIT,
0295 BULK_SCATTER,
0296 BULK_REEMIT,
0297 BOUNDARY_TRANSMIT,
0298 SURFACE_DETECT,
0299 BULK_ABSORB,
0300 SCINTILLATION,
0301 TORCH,
0302 BOUNDARY_TRANSMIT,
0303 BOUNDARY_TRANSMIT,
0304 BULK_SCATTER,
0305 BULK_REEMIT,
0306 BOUNDARY_TRANSMIT,
0307 SURFACE_DETECT,
0308 BULK_ABSORB,
0309 SCINTILLATION
0310 } ;
0311
0312 test_desc_seqhis(history);
0313 }
0314
0315
0316
0317 template<int N>
0318 std::string desc_flag(unsigned flag)
0319 {
0320 std::stringstream ss ;
0321 ss
0322 << std::hex << flag << std::dec
0323 << " "
0324 << std::bitset<N>(flag).to_string()
0325 ;
0326 std::string s = ss.str();
0327 return s ;
0328 }
0329
0330 template<typename T>
0331 void test_wraparound(std::vector<unsigned>& history )
0332 {
0333 unsigned long long seqhis = 0ull ;
0334 unsigned long long four = 4ull ;
0335
0336 for(unsigned i=0 ; i < history.size() ; i++)
0337 {
0338 T flag = history[i];
0339 T slot = i ;
0340
0341 unsigned long long change = (( FFS(flag) & 0xfull ) << four*slot );
0342
0343 seqhis |= change ;
0344
0345 std::cout
0346 << std::setw(20) << OpticksPhoton::Flag(flag)
0347 << " "
0348 << " FFS(flag) " << std::setw(1) << std::hex << FFS(flag) << std::dec
0349 << " "
0350 << " seqhis " << std::setw(16) << std::hex << seqhis << std::dec
0351 << " change " << std::setw(16) << std::hex << change << std::dec
0352 << std::endl
0353 ;
0354 }
0355
0356 for(int i=0 ; i < 16 ; i++) std::cout << desc_flag<4>(i) << std::endl ;
0357
0358 std::cout << " (0xd | 0xc) == 0xd " << desc_flag<4>(0xd | 0xc) << std::endl ;
0359 std::cout << " (0xc | 0xa) == 0xe " << desc_flag<4>(0xc | 0xa) << std::endl ;
0360 }
0361
0362
0363 void test_desc_seqhis_1()
0364 {
0365 std::cout << "test_desc_seqhis_1" << std::endl ;
0366 std::vector<unsigned> history = {
0367 TORCH,
0368 BOUNDARY_TRANSMIT,
0369 BOUNDARY_TRANSMIT,
0370 BOUNDARY_TRANSMIT,
0371 BOUNDARY_TRANSMIT,
0372 SURFACE_SREFLECT,
0373 SURFACE_SREFLECT,
0374 BOUNDARY_TRANSMIT,
0375 BOUNDARY_REFLECT,
0376 BOUNDARY_REFLECT,
0377 BOUNDARY_TRANSMIT,
0378 SURFACE_SREFLECT,
0379 SURFACE_SREFLECT,
0380 SURFACE_SREFLECT,
0381 BOUNDARY_TRANSMIT,
0382 BOUNDARY_REFLECT,
0383 BOUNDARY_TRANSMIT,
0384 SURFACE_SREFLECT,
0385 BOUNDARY_TRANSMIT,
0386 SURFACE_ABSORB
0387 } ;
0388
0389 test_desc_seqhis(history);
0390
0391
0392 }
0393
0394
0395
0396
0397
0398
0399
0400
0401 void test_shiftwrap()
0402 {
0403 unsigned long long seqhis = 0ull ;
0404 for(unsigned j=0 ; j < 2 ; j++)
0405 for(unsigned i=0 ; i < 16 ; i++)
0406 {
0407 unsigned slot = j*16 + i ;
0408 unsigned long long flag = j == 0 ? 0x5ull : 0xfull ;
0409 unsigned long long change = flag << 4*slot ;
0410 seqhis |= change ;
0411
0412 std::cout
0413 << " seqhis " << std::setw(16) << std::hex << seqhis << std::dec
0414 << " change " << std::setw(16) << std::hex << change << std::dec
0415 << std::endl
0416 ;
0417 }
0418 }
0419
0420 void test_load_seq()
0421 {
0422 const char* path = spath::Resolve("$TMP/GEOM/$GEOM/$EXECUTABLE/ALL$VERSION/$EVT/seq.npy") ;
0423 NP* a = NP::LoadIfExists(path);
0424 std::cout << " path " << path << " a " << ( a ? a->sstr() : "-" ) << std::endl ;
0425 if(!a) return ;
0426
0427 std::vector<sseq> qq ;
0428 NPX::VecFromArray<sseq>(qq, a );
0429
0430 int num = ssys::getenvint("NUM", 100);
0431 std::cout << " dumping first " << num << std::endl ;
0432 for(int i=0 ; i < std::min(int(qq.size()), num) ; i++)
0433 {
0434 const sseq& q = qq[i] ;
0435
0436 std::string seqhis = q.seqhis_();
0437 std::cout << "[" << seqhis << "]" << std::endl ;
0438 }
0439 }
0440
0441 void test_sort_seq()
0442 {
0443 const char* path = spath::Resolve("$TMP/GEOM/$GEOM/$EXECUTABLE/ALL$VERSION/$EVT/seq.npy") ;
0444 NP* a = NP::LoadIfExists(path);
0445 std::cout << " path " << path << " a " << ( a ? a->sstr() : "-" ) << std::endl ;
0446 if(!a) return ;
0447
0448 std::vector<sseq> qq ;
0449 NPX::VecFromArray<sseq>(qq, a );
0450
0451 std::sort(qq.begin(), qq.end() );
0452
0453 int num = ssys::getenvint("NUM", 100);
0454 for(int i=0 ; i < std::min(int(qq.size()), num) ; i++)
0455 {
0456 const sseq& q = qq[i] ;
0457 std::cout << q.desc_seqhis() << std::endl ;
0458
0459 }
0460 }
0461
0462 void test_unique_seq_counts_with_first_index()
0463 {
0464 const char* path = spath::Resolve("$TMP/GEOM/$GEOM/$EXECUTABLE/ALL$VERSION/$EVT/seq.npy") ;
0465 NP* a = NP::LoadIfExists(path);
0466 std::cout << " path " << path << " a " << ( a ? a->sstr() : "-" ) << std::endl ;
0467 if(!a) return ;
0468
0469 }
0470
0471
0472
0473 int main()
0474 {
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488 const char* TEST = ssys::getenvvar("TEST", "ALL");
0489 bool ALL = strcmp(TEST, "ALL") == 0 ;
0490
0491 int rc = 0 ;
0492 if(ALL||0==strcmp(TEST,"add_nibble_0")) rc += sseq_test::add_nibble_0();
0493 if(ALL||0==strcmp(TEST,"add_nibble_1")) rc += sseq_test::add_nibble_1();
0494 if(ALL||0==strcmp(TEST,"add_nibble_2")) rc += sseq_test::add_nibble_2();
0495 if(ALL||0==strcmp(TEST,"truncation")) rc += sseq_test::truncation();
0496
0497 return rc ;
0498 }
0499
0500
0501