File indexing completed on 2026-04-09 07:49:21
0001
0002 """
0003 sreport.py
0004 ======================
0005
0006 ::
0007
0008 PLOT=Substamp_ONE_Delta PICK=A ~/o/sreport.sh
0009 PLOT=Substamp_ONE_Delta PICK=B ~/o/sreport.sh
0010
0011 PLOT=Substamp_ONE_Etime PICK=A ~/o/sreport.sh
0012 PLOT=Substamp_ONE_Etime PICK=B ~/o/sreport.sh
0013
0014 PLOT=Substamp_ONE_maxb_scan PICK=A ~/o/sreport.sh
0015 PLOT=Substamp_ONE_maxb_scan PICK=B ~/o/sreport.sh
0016
0017 PLOT=Ranges_ONE ~/o/sreport.sh
0018 PLOT=Ranges_SPAN ~/o/sreport.sh
0019
0020 PLOT=Substamp_ALL_Etime_vs_Photon ~/o/sreport.sh
0021 PLOT=Substamp_ALL_Hit_vs_Photon ~/o/sreport.sh
0022 PLOT=Substamp_ALL_RATIO_vs_Photon ~/o/sreport.sh
0023
0024 PLOT=Subprofile_ONE PICK=A ~/o/sreport.sh
0025 PLOT=Subprofile_ONE PICK=B ~/o/sreport.sh
0026
0027 PLOT=Subprofile_ALL ~/o/sreport.sh
0028 PLOT=Runprof_ALL ~/o/sreport.sh
0029
0030 """
0031
0032 import os, numpy as np
0033 from opticks.ana.fold import Fold
0034 from opticks.ana.npmeta import NPMeta
0035
0036 def format_large_number(number):
0037 if number//1000000 == 0:
0038 if number % 1000 == 0:
0039 num_K = number//1000
0040 num = "%dK" % num_K
0041 else:
0042 num = "%d" % number
0043 pass
0044 elif number//1000000 > 0:
0045 if number % 1000000 == 0:
0046 num_M = number//1000000
0047 num = "%dM" % num_M
0048 else:
0049 num = "%d" % number
0050 pass
0051 else:
0052 num = "%d" % number
0053 pass
0054 return num
0055
0056
0057
0058 COMMANDLINE = os.environ.get("COMMANDLINE", "")
0059 STEM = os.environ.get("STEM", "")
0060 HEADLINE = "%s ## %s " % (COMMANDLINE, STEM )
0061 JOB = os.environ.get("JOB", "")
0062 PLOT = os.environ.get("PLOT", "")
0063 STEM = os.environ.get("STEM", "")
0064 MODE = int(os.environ.get("MODE", "2"))
0065 PICK = os.environ.get("PICK", "AB")
0066 TLIM = np.array(list(map(int,os.environ.get("TLIM", "0,0").split(","))),dtype=np.int32)
0067
0068
0069 if MODE != 0:
0070 from opticks.ana.pvplt import *
0071 pass
0072
0073 labels_ = lambda l:l.view("|S%d" % l.shape[1])[:,0]
0074 tv_ = lambda a:a.view("datetime64[us]")
0075
0076
0077 palette = ["red","green", "blue",
0078 "cyan", "magenta", "yellow",
0079 "tab:orange", "tab:pink", "tab:olive",
0080 "tab:purple", "tab:grey", "tab:cyan"
0081 ]
0082
0083
0084 def make_title(meta, method, symbol):
0085 base = meta.base.replace("/data/blyth/opticks/GEOM/", "")
0086 smry = meta.smry("GPUMeta,prefix,creator")
0087 sfmt = meta.smry("stampFmt")
0088 titl = "%s:%s %s " % (symbol,method, sfmt)
0089 title = " ".join([titl,base,smry])
0090 return title
0091
0092 smry__ = lambda _:NPMeta.Summarize(_)
0093 smry_ = lambda _:list(map(smry__, _))
0094
0095
0096 class Subprofile(object):
0097 """
0098 Why VM is so large with CUDA
0099
0100 * https://forums.developer.nvidia.com/t/high-virtual-memory-consumption-on-linux-for-cuda-programs-is-it-possible-to-avoid-it/67706/4
0101
0102 """
0103 FONTSIZE = 20
0104 XLABEL = "Time from 1st sprof.h stamp (seconds)"
0105 YLABEL = "VM and/or RSS sprof.h memory (GB) "
0106
0107 @classmethod
0108 def Time_VM_RS(cls, f):
0109 subprofile = f.subprofile
0110 assert len(subprofile.shape) == 3
0111 t0 = subprofile[0,0,0]
0112 sp = subprofile.reshape(-1,3)
0113 tp = (sp[:,0] - t0)/1e6
0114 vm = sp[:,1]/1e6
0115 rs = sp[:,2]/1e6
0116 return tp, vm, rs
0117
0118 @classmethod
0119 def Title(cls, f):
0120 meta = f.subprofile_meta
0121 base = meta.base.replace("/data/blyth/opticks/GEOM/", "")
0122 smry = meta.smry("GPUMeta,prefix,creator")
0123 sfmt = meta.smry("stampFmt")
0124 title = "\n".join([base,smry,sfmt])
0125 return title
0126
0127
0128 class Subprofile_ALL(object):
0129 """
0130 RSS vs time for both "a" and "b"
0131 """
0132 def __init__(self, fold, symbol="fold.subprofile"):
0133 base = eval(symbol)
0134 label = RUN_META.Title(fold)
0135
0136 fontsize = Subprofile.FONTSIZE
0137 if MODE == 2:
0138 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=label, equal=False)
0139 ax = axs[0]
0140 for sym in base.ff:
0141 f = getattr(base, sym)
0142
0143 tp,vm,rs = Subprofile.Time_VM_RS(f)
0144
0145 if "VM" in os.environ:
0146 ax.scatter( tp, vm, label="%s : VM(GB) vs time(s)" % sym.upper())
0147 ax.plot( tp, vm )
0148 pass
0149 ax.scatter( tp, rs, label="%s : RSS(GB) vs time(s)" % sym.upper())
0150 ax.plot( tp, rs )
0151 pass
0152 ax.set_xlabel(Subprofile.XLABEL, fontsize=Subprofile.FONTSIZE )
0153 ax.set_ylabel(Subprofile.YLABEL, fontsize=Subprofile.FONTSIZE )
0154 ax.legend()
0155 fig.show()
0156
0157
0158 class Runprof_ALL(object):
0159 """
0160 PLOT=Runprof_ALL ~/o/sreport.sh
0161 """
0162 def __init__(self, fold, symbol="fold.runprof"):
0163 rp = eval(symbol)
0164 label = "Runprof_ALL "
0165 fontsize = Subprofile.FONTSIZE
0166 if MODE == 2:
0167 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=label, equal=False)
0168 ax = axs[0]
0169
0170 tp = (rp[:,0] - rp[0,0])/1e6
0171 vm = rp[:,1]/1e6
0172 rs = rp[:,2]/1e6
0173
0174 if "VM" in os.environ:
0175 ax.scatter( tp, vm, label="%s : VM(GB) vs time(s)" % symbol)
0176 ax.plot( tp, vm )
0177 pass
0178 ax.scatter( tp, rs, label="%s : RSS(GB) vs time(s)" % symbol )
0179 ax.plot( tp, rs )
0180 pass
0181 ax.set_xlabel(Subprofile.XLABEL, fontsize=Subprofile.FONTSIZE )
0182 ax.set_ylabel(Subprofile.YLABEL, fontsize=Subprofile.FONTSIZE )
0183
0184 yl = ax.get_ylim()
0185 ax.vlines( tp[::4], yl[0], yl[1], color="blue", label="nBeg" )
0186 ax.vlines( tp[1::4], yl[0], yl[1], color="red", label="nEnd" )
0187 ax.vlines( tp[2::4], yl[0], yl[1], color="cyan", label="pBeg" )
0188 ax.vlines( tp[3::4], yl[0], yl[1], color="pink", label="pEnd" )
0189
0190 ax.legend()
0191 fig.show()
0192 pass
0193
0194
0195 class Subprofile_ONE(object):
0196 """
0197 PLOT=Subprofile_ONE ~/o/sreport.sh
0198 """
0199 def __init__(self, fold, symbol="fold.subprofile.a"):
0200 f = eval(symbol)
0201
0202 meta = f.subprofile_meta
0203 names = f.subprofile_names
0204 labels = f.subprofile_labels
0205 title = RUN_META.Title(fold)
0206
0207 tp,vm,rs = Subprofile.Time_VM_RS(f)
0208
0209 if MODE == 2:
0210 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0211 ax = axs[0]
0212 if "VM" in os.environ:
0213 ax.scatter( tp, vm, label="VM(GB) vs time(s)")
0214 ax.plot( tp, vm )
0215 pass
0216 ax.scatter( tp, rs, label="RSS(GB) vs time(s)")
0217 ax.plot( tp, rs )
0218 ax.set_xlabel(Subprofile.XLABEL, fontsize=Subprofile.FONTSIZE )
0219 ax.set_ylabel(Subprofile.YLABEL, fontsize=Subprofile.FONTSIZE )
0220 ax.legend()
0221 fig.show()
0222 pass
0223
0224
0225 class Substamp(object):
0226 @classmethod
0227 def ETime(cls, f):
0228 etime = f.delta_substamp[:,-1]/1e6
0229 return etime
0230 @classmethod
0231 def Subcount(cls, f, label="photon"):
0232 _icol = np.where(f.subcount_labels == label)[0]
0233 icol = _icol[0] if len(_icol) == 1 else -1
0234 subcount = f.subcount[:,icol] if icol > -1 else None
0235 return subcount
0236 @classmethod
0237 def Labels(cls, f):
0238 labels = f.substamp_labels
0239 labels_s = smry_(labels)
0240 return labels_s
0241 @classmethod
0242 def DeltaColumn(cls, f, label ):
0243 _c = np.where( f.substamp_labels == label )[0]
0244 c = _c[0] if len(_c) == 1 else -1
0245 return f.delta_substamp[:,c] if c > -1 else None
0246
0247 @classmethod
0248 def Hdr(cls, f):
0249 labels_s = cls.Labels(f)
0250 hdr = (" " * 8 + " %4s " * len(labels_s) ) % tuple(labels_s)
0251 return hdr
0252 @classmethod
0253 def Title(cls, f, symbol="a"):
0254 meta = f.substamp_meta
0255 title = make_title(meta, method="Substamp", symbol=symbol)
0256 return title
0257
0258
0259 class Substamp_ONE_Etime(object):
0260 """
0261 Switches from using subcount_photon to submeta_NumPhotonCollected
0262 as that avoids needing to gather and save large photons arrays.
0263 """
0264 def __init__(self, fold, symbol="fold.substamp.a", esym="a" ):
0265
0266 f = eval(symbol)
0267
0268 substamp = f.substamp
0269 meta = f.substamp_meta
0270 names = f.substamp_names
0271 delta = f.delta_substamp
0272
0273 photon = SUB_META.NumPhotonCollected(fold, esym)/1e6
0274 etime = Substamp.ETime(f)
0275
0276 title = RUN_META.Title(fold)
0277
0278 hdr = Substamp.Hdr(f)
0279
0280 desc = "\n".join([title, hdr, symbol, repr(delta)])
0281 print(desc)
0282
0283 assert len(substamp.shape) == 2
0284 assert delta.shape == substamp.shape
0285 fontsize = 20
0286
0287 deg = 1
0288 linefit = np.poly1d(np.polyfit(photon, etime, deg))
0289 linefit_label = "line fit: slope %10.2f intercept %10.2f " % (linefit.coef[0], linefit.coef[1])
0290
0291 if MODE == 2:
0292 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0293 ax = axs[0]
0294 ax.scatter( photon, etime, label="etime(s)_vs_photon (millions)")
0295 ax.plot( photon, linefit(photon), label=linefit_label )
0296
0297 ax.set_yscale('log')
0298 ax.set_ylabel("Event time (seconds)", fontsize=fontsize )
0299 ax.set_xlabel("Number of Photons (Millions)", fontsize=fontsize )
0300 ax.legend()
0301 fig.show()
0302 pass
0303
0304
0305 class Substamp_ALL_Hit_vs_Photon(object):
0306 def __init__(self, fold, symbol="fold.substamp", ):
0307 base = eval(symbol)
0308 title = RUN_META.Title(fold)
0309 fontsize = 20
0310 if MODE == 2:
0311 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0312 ax = axs[0]
0313 for sym in base.ff:
0314 f = getattr(base, sym)
0315
0316 p_symbol = "fold.submeta_NumPhotonCollected.%s[:,0]" % sym
0317
0318 _photon = eval(p_symbol)
0319
0320 _hit = Substamp.Subcount(f, "hit")
0321
0322 photon = _photon/1e6
0323 hit = _hit/1e6
0324
0325 deg = 1
0326 linefit = np.poly1d(np.polyfit(photon, hit, deg))
0327 linefit_label = "%s:line fit: slope %10.3f intercept %10.3f " % (sym.upper(), linefit.coef[0], linefit.coef[1])
0328
0329 ax.scatter( photon, hit, label="%s : hit_vs_photon (millions)" % sym.upper() )
0330 ax.plot( photon, linefit(photon), linestyle="dotted", label=linefit_label, )
0331 pass
0332
0333 ax.set_ylabel("Number of Hits (Millions)", fontsize=fontsize )
0334 ax.set_xlabel("Number of Photons (Millions)", fontsize=fontsize )
0335 ax.legend()
0336 ax.legend()
0337 fig.show()
0338 pass
0339
0340
0341 class Substamp_ALL_Etime_vs_Photon(object):
0342 def __init__(self, fold, symbol="fold.substamp"):
0343 base = eval(symbol)
0344 title = RUN_META.Title(fold)
0345 fontsize = 20
0346 YSCALE = os.environ.get("YSCALE", "log")
0347 YMIN = float(os.environ.get("YMIN", "1e-2"))
0348 YMAX = float(os.environ.get("YMAX", "1e4"))
0349
0350 if MODE == 2:
0351 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0352 ax = axs[0]
0353 for sym in base.ff:
0354 f = getattr(base, sym)
0355
0356 etime = Substamp.ETime(f)
0357 p_symbol = "fold.submeta_NumPhotonCollected.%s[:,0]" % sym
0358 _photon = eval(p_symbol)
0359 photon = _photon/1e6
0360
0361 deg = 1
0362 linefit = np.poly1d(np.polyfit(photon, etime, deg))
0363 linefit_label = "%s : line fit: slope %10.3f intercept %10.3f " % (sym.upper(), linefit.coef[0], linefit.coef[1])
0364
0365 ax.scatter( photon, etime, label="%s : etime(s)_vs_photon (millions)" % sym.upper() )
0366 ax.plot( photon, linefit(photon), label=linefit_label )
0367 pass
0368 ax.set_xlim( -5, 105 );
0369 ax.set_ylim( YMIN, YMAX );
0370 ax.set_yscale(YSCALE)
0371 ax.set_ylabel("Event time (seconds)", fontsize=fontsize )
0372 ax.set_xlabel("Number of Photons (Millions)", fontsize=fontsize )
0373 ax.legend()
0374 ax.legend()
0375 fig.show()
0376 pass
0377
0378
0379 class Substamp_ALL_RATIO_vs_Photon(object):
0380 """
0381 PLOT=Substamp_ALL_RATIO_vs_Photon ~/o/sreport.sh
0382 """
0383 def __init__(self, fold, symbol="fold.substamp"):
0384 base = eval(symbol)
0385
0386 title = RUN_META.Title(fold)
0387
0388 fontsize = 20
0389 if MODE == 2:
0390 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0391 ax = axs[0]
0392 assert "a" in base.ff
0393 assert "b" in base.ff
0394
0395 a_photon = fold.submeta_NumPhotonCollected.a[:,0]/1e6
0396 b_photon = fold.submeta_NumPhotonCollected.b[:,0]/1e6
0397 assert np.all( a_photon == b_photon )
0398
0399 a_etime = Substamp.ETime(base.a)
0400 b_etime = Substamp.ETime(base.b)
0401 boa_etime = b_etime/a_etime
0402
0403 ax.scatter( a_photon, boa_etime, label="boa_etime(s)_vs_photon (millions)" )
0404 ax.plot( a_photon, boa_etime, label=None, linestyle="dotted" )
0405 pass
0406 ax.set_ylabel("Geant4/Opticks Event time ratio", fontsize=fontsize )
0407 ax.set_xlabel("Number of Photons (Millions)", fontsize=fontsize )
0408 ax.set_ylim( 0, 250)
0409 ax.set_xlim( -5, 105)
0410
0411
0412 ax.legend(loc="lower right")
0413 fig.show()
0414 pass
0415
0416
0417 class Substamp_ONE_Delta(object):
0418 def __init__(self, fold, symbol="fold.substamp.a" ):
0419 f = eval(symbol)
0420 delta = f.delta_substamp
0421
0422 title = RUN_META.Title(fold)
0423
0424 labels_s = Substamp.Labels(f)
0425
0426 ax = None
0427 if MODE == 2:
0428 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0429 ax = axs[0]
0430 if TLIM[1] > TLIM[0]:
0431 ax.set_xlim(*TLIM)
0432 pass
0433 for i in range(len(delta)):
0434 for j in range(len(delta[i])):
0435 label = None if i > 0 else labels_s[j]
0436 color = palette[j % len(palette)]
0437 ax.vlines( delta[i,j], i-0.5, i+0.5, label=label , colors=[color] )
0438 pass
0439 pass
0440 ax.legend(loc="center")
0441 fig.show()
0442 pass
0443 self.ax = ax
0444
0445 class Substamp_ONE_maxb_scan(object):
0446 def __init__(self, fold, symbol="fold.substamp.a", esym="a" ):
0447 f = eval(symbol)
0448 delta = f.delta_substamp
0449 photon = SUB_META.NumPhotonCollected(fold, esym)/1e6
0450 u_photon = np.unique(photon)
0451 assert len(u_photon) == 1, u_photon
0452 n_photon = u_photon[0]
0453 num = format_large_number(n_subcount_photon)
0454
0455 _subcount_hit = Substamp.Subcount(f, "hit")
0456
0457 title0 = Substamp.Title(f, symbol=symbol)
0458 if PLOT.endswith("_HIT"):
0459 title1 = "Hit count for %s photons vs MAX_BOUNCE " % num
0460 else:
0461 title1 = "Launch Time[us] for %s photons vs MAX_BOUNCE " % num
0462 pass
0463 title = "\n".join([title0, title1])
0464
0465 labels_s = Substamp.Labels(f)
0466
0467 pre = Substamp.DeltaColumn(f, "t_PreLaunch")
0468 pos = Substamp.DeltaColumn(f, "t_PostLaunch")
0469 launch = pos - pre
0470 mxb = np.arange(len(launch))
0471
0472 sel = slice(18)
0473 deg = 1
0474 linefit = np.poly1d(np.polyfit(mxb[sel], launch[sel], deg))
0475 linefit_label = "%s : line fit: slope %10.2f intercept %10.2f " % (symbol, linefit.coef[0], linefit.coef[1])
0476
0477 print(labels_s)
0478
0479 ax = None
0480 if MODE == 2:
0481 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0482 ax = axs[0]
0483 if PLOT.endswith("_HIT"):
0484 ax.plot( mxb, _subcount_hit, label=None )
0485 ax.scatter( mxb, _subcount_hit, label="hit count vs max bounce (0->31) ")
0486 ax.set_ylabel("Hit count", fontsize=20 )
0487 ax.set_xlabel("OPTICKS_MAX_BOUNCE (aka MAX_TRACE)", fontsize=20 )
0488 else:
0489 ax.scatter( mxb, launch, label="launch time [us] vs max bounce (0->31) ")
0490 ax.plot( mxb, linefit(mxb), linestyle="dotted", label=linefit_label )
0491 ax.text(-0.05, -0.1, HEADLINE, va='bottom', ha='left', family="monospace", fontsize=12, transform=ax.transAxes)
0492 ax.set_ylabel("GPU Launch Time [us] ", fontsize=12 )
0493 pass
0494 ax.legend(loc="lower right")
0495 fig.show()
0496 pass
0497 self.ax = ax
0498
0499
0500
0501 class Ranges_SPAN(object):
0502 """
0503 PLOT=Ranges_SPAN ~/o/sreport.sh
0504
0505 TODO: split off QRng upload, probably most of upload_geom from that
0506
0507 """
0508 def __init__(self, fold, symbol="fold"):
0509
0510 NPC = fold.submeta_NumPhotonCollected.a[:,0]
0511
0512 title = RUN_META.Title(fold)
0513 print(title)
0514
0515 print("NPC:%s" % str(NPC))
0516
0517 t0 = fold.ranges[0,0]
0518 ax = None
0519 if MODE == 2:
0520 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0521 ax = axs[0]
0522 names = ["init", "load_geom", "upload_geom", "simulate", "download", "upload_genstep" ]
0523 COLORS = ["yellow", "magenta", "cyan", "red", "green", "blue" ]
0524
0525 for i, name in enumerate(names):
0526 color = COLORS[i%len(COLORS)]
0527 ww = np.where( np.char.endswith( fold.ranges_names, name ))[0]
0528 if i > 3:
0529 assert len(ww) == len(NPC)
0530 pass
0531 for j, w in enumerate(ww):
0532 rg = (fold.ranges[w] - t0)/1e6
0533 ax.axvspan(rg[0], rg[1], alpha=0.5, color=color, label=name if j==0 else None )
0534 pass
0535 pass
0536 ax.legend(loc="center right")
0537
0538 ax.set_xlim(-5,180)
0539 ax.set_xlabel("cxr_min.sh (CSGOptiXSMTest) Process Run Time[s]", fontsize=20 );
0540 fig.show()
0541 pass
0542 self.ax = ax
0543
0544
0545
0546
0547 class Ranges_ONE(object):
0548 """
0549 PLOT=Ranges_ONE ~/o/sreport.sh
0550 """
0551 def __init__(self, fold, symbol="fold"):
0552
0553 NPC = fold.submeta_NumPhotonCollected.a[:,0]
0554 print("NPC:%s" % str(NPC))
0555 title = RUN_META.Title(fold)
0556 print(title)
0557
0558 names = ["simulate", "download", "upload_genstep" ]
0559
0560
0561 COLORS = ["red", "green", "blue" ]
0562 ax = None
0563 if MODE == 2:
0564 fig, axs = mpplt_plotter(nrows=1, ncols=1, label=title, equal=False)
0565 ax = axs[0]
0566 for i, name in enumerate(names):
0567 color = COLORS[i%len(COLORS)]
0568 w = np.where( np.char.endswith( fold.ranges_names, name ))[0]
0569 rgs = fold.ranges[w]
0570 assert len(rgs) == len(NPC)
0571 ax.plot( NPC/1e6, rgs[:,2]/1e6, color=color )
0572 ax.scatter( NPC/1e6, rgs[:,2]/1e6, label="%s" % name, color=color )
0573 pass
0574 ax.legend(loc="center right")
0575 ax.set_yscale('log')
0576 ax.set_ylim(5e-4,50)
0577 ax.set_xlim(-5,105)
0578 ax.set_ylabel("Time (seconds)", fontsize=20);
0579 ax.set_xlabel("Number of \"TORCH\" Photons from CD center (Millions)", fontsize=20 );
0580 fig.show()
0581 pass
0582 self.ax = ax
0583
0584
0585
0586
0587 class SUB_META(object):
0588 @classmethod
0589 def NumPhotonCollected(cls, fold, esym):
0590 assert esym in ["a", "b"]
0591 p_symbol = "fold.submeta_NumPhotonCollected.%s[:,0]" % esym
0592 photon = eval(p_symbol)
0593 return photon
0594
0595
0596 class RUN_META(object):
0597 @classmethod
0598 def _QSim__Switches(cls, fold):
0599 """
0600 eg: 'CONFIG_Release PRODUCTION WITH_CHILD WITH_CUSTOM4 PLOG_LOCAL '
0601 """
0602 SKIPS = "WITH_CHILD PLOG_LOCAL".split();
0603 switches = list(filter(lambda _:not _.startswith("NOT-"), fold.run_meta.QSim__Switches.split(",")))
0604 switches = list(filter(lambda _:not _ in SKIPS, switches ))
0605 return switches
0606
0607 @classmethod
0608 def QSim__Switches(cls, fold):
0609 """
0610 eg: 'CONFIG_Release PRODUCTION WITH_CHILD WITH_CUSTOM4 PLOG_LOCAL '
0611 """
0612 switches = cls._QSim__Switches(fold)
0613 return " ".join(switches)
0614
0615 @classmethod
0616 def QSim__RNGLabel(cls, fold):
0617 switches = cls._QSim__Switches(fold)
0618 return "RNG_PHILOX" if "RNG_PHILOX" in switches else "RNG_XORWOW"
0619
0620
0621 @classmethod
0622 def ABCD_Title(cls, *rr):
0623 SCRIPT = None
0624 for i, r in enumerate(rr):
0625 _SCRIPT = getattr(r.run_meta, 'SCRIPT', "cxs_min.sh")
0626 if i == 0:
0627 SCRIPT = _SCRIPT
0628 else:
0629 assert SCRIPT == _SCRIPT
0630 pass
0631 pass
0632 topline = "%s ## %s " % ( COMMANDLINE, SCRIPT )
0633
0634 cvar = ["RUNNING_MODE","EVENT_MODE","MAX_BOUNCE"]
0635
0636
0637
0638 ctrls = []
0639 for var in cvar:
0640 val = None
0641 for i, r in enumerate(rr):
0642 _val = getattr(r.run_meta, "OPTICKS_%s" % var, "?" )
0643
0644 if i == 0:
0645 val = _val
0646 else:
0647 assert val == _val, ( val, _val )
0648 pass
0649 pass
0650 ctrls.append("%s:%s" % (var,val))
0651 pass
0652 ctrl = " ".join(ctrls)
0653
0654 for i, r in enumerate(rr):
0655 SWITCHES = cls.QSim__Switches(r)
0656 print(SWITCHES)
0657 pass
0658 title = "\n".join([topline, ctrl])
0659 return title
0660
0661 @classmethod
0662 def AB_Title(cls, a, b):
0663 """
0664 :param a: sreport Fold
0665 :param b: sreport Fold
0666 :return str: title
0667
0668 In addition to providing the title this also
0669 asserts consistency between the sreport fold
0670 for the below run_meta:
0671
0672 1. SCRIPT
0673 2. OPTICKS_RUNNING_MODE, OPTICKS_EVENT_MODE, OPTICKS_MAX_BOUNCE, OPTICKS_MAX_PHOTON
0674 3. QSim__Switches
0675 """
0676 a_SCRIPT = getattr(a.run_meta, 'SCRIPT', "cxs_min.sh")
0677 b_SCRIPT = getattr(b.run_meta, 'SCRIPT', "cxs_min.sh")
0678 assert a_SCRIPT == b_SCRIPT, (a_SCRIPT, b_SCRIPT)
0679 SCRIPT = a_SCRIPT
0680
0681
0682 topline = "%s ## %s " % ( COMMANDLINE, SCRIPT )
0683
0684 cvar = ["RUNNING_MODE","EVENT_MODE","MAX_BOUNCE","MAX_PHOTON"]
0685
0686
0687 ctrls = []
0688 for var in cvar:
0689 a_val = getattr(a.run_meta, "OPTICKS_%s" % var, "?" )
0690 b_val = getattr(a.run_meta, "OPTICKS_%s" % var, "?" )
0691 assert a_val == b_val, (a_val, b_val)
0692 val = a_val
0693 ctrls.append("%s:%s" % (var,val))
0694 pass
0695 ctrl = " ".join(ctrls)
0696
0697
0698 a_SWITCHES = cls.QSim__Switches(a)
0699 b_SWITCHES = cls.QSim__Switches(b)
0700 assert a_SWITCHES == b_SWITCHES, (a_SWITCHES, b_SWITCHES)
0701 SWITCHES = a_SWITCHES
0702
0703 title = "\n".join([topline, ctrl])
0704 return title
0705
0706 @classmethod
0707 def GPUMeta(cls, fold, simplify=True):
0708 gpu = fold.run_meta.GPUMeta
0709 if simplify and (gpu.startswith("0:") or gpu.startswith("1:")):
0710 gpu = gpu[2:]
0711 pass
0712 return "%s : %s" % (fold.symbol, gpu)
0713
0714
0715 @classmethod
0716 def Title(cls, fold):
0717 SCRIPT = getattr(fold.run_meta, 'SCRIPT', "cxs_min.sh")
0718 GPUMeta = fold.run_meta.GPUMeta
0719 topline = "%s ## %s : %s " % ( COMMANDLINE, SCRIPT, GPUMeta )
0720 SWITCHES = cls.QSim__Switches(fold)
0721
0722 cvar = ["RUNNING_MODE","EVENT_MODE","MAX_BOUNCE","MAX_PHOTON"]
0723
0724
0725 ctrls = []
0726 for var in cvar:
0727 val = getattr(fold.run_meta, "OPTICKS_%s" % var, "?" )
0728 ctrls.append("%s:%s" % (var,val))
0729 pass
0730 ctrl = " ".join(ctrls)
0731
0732 title = "\n".join([topline, SWITCHES, ctrl])
0733 return title
0734
0735
0736
0737
0738
0739
0740 if __name__ == '__main__':
0741
0742 print("[sreport.py:PLOT[%s]" % PLOT )
0743 print("[sreport.py:fold = Fold.Load" )
0744 fold = Fold.Load("$SREPORT_FOLD", symbol="fold")
0745 print("]sreport.py:fold = Fold.Load" )
0746
0747 print("[sreport.py:repr(fold)" )
0748 print(repr(fold))
0749 print("]sreport.py:repr(fold)" )
0750
0751
0752 SWITCHES = RUN_META.QSim__Switches(fold)
0753 print("MODE:%d PICK:%s SWITCHES:%s " % (MODE, PICK, SWITCHES) )
0754 print("COMMANDLINE:%s" % COMMANDLINE)
0755
0756 if PLOT.startswith("Substamp_ONE") and hasattr(fold, "substamp"):
0757 for e in PICK:
0758 esym = e.lower()
0759 f = getattr(fold.substamp, esym, None)
0760 symbol = "fold.substamp.%s" % esym
0761 pass
0762 if f is None: continue
0763 if PLOT.startswith("Substamp_ONE_Delta"): Substamp_ONE_Delta(fold, symbol=symbol )
0764 if PLOT.startswith("Substamp_ONE_Etime"): Substamp_ONE_Etime(fold, symbol=symbol, esym=esym )
0765 if PLOT.startswith("Substamp_ONE_maxb_scan"): Substamp_ONE_maxb_scan(fold, symbol=symbol, esym=esym )
0766 pass
0767 pass
0768
0769 if PLOT.startswith("Ranges_ONE") and hasattr(fold, "ranges") and hasattr(fold,"submeta_NumPhotonCollected") :
0770 Ranges_ONE(fold, symbol="fold")
0771 if PLOT.startswith("Ranges_SPAN") and hasattr(fold, "ranges") and hasattr(fold,"submeta_NumPhotonCollected") :
0772 Ranges_SPAN(fold, symbol="fold")
0773 pass
0774 if PLOT.startswith("Substamp_ALL"):
0775 if hasattr(fold, "substamp"):
0776 if PLOT.startswith("Substamp_ALL_Etime_vs_Photon"): Substamp_ALL_Etime_vs_Photon( fold, symbol="fold.substamp" )
0777 if PLOT.startswith("Substamp_ALL_Hit_vs_Photon"): Substamp_ALL_Hit_vs_Photon( fold, symbol="fold.substamp" )
0778 if PLOT.startswith("Substamp_ALL_RATIO_vs_Photon"): Substamp_ALL_RATIO_vs_Photon( fold, symbol="fold.substamp" )
0779 else:
0780 print(".sreport.py: fold does not have substamp : CANNOT PLOT [%s]" % PLOT)
0781 pass
0782 pass
0783 if PLOT.startswith("Subprofile_ONE") and hasattr(fold, "subprofile"):
0784 for e in PICK:
0785 f = getattr(fold.subprofile, e.lower(), None)
0786 symbol = "fold.subprofile.%s" % e.lower()
0787 if f is None: continue
0788 Subprofile_ONE(fold, symbol=symbol)
0789 pass
0790 pass
0791 if PLOT.startswith("Subprofile_ALL") and hasattr(fold, "subprofile"):
0792 Subprofile_ALL(fold, symbol="fold.subprofile")
0793 pass
0794 if PLOT.startswith("Runprof_ALL") and hasattr(fold, "runprof"):
0795 Runprof_ALL(fold, symbol="fold.runprof" )
0796 pass
0797 print("]sreport.py:PLOT[%s]" % PLOT )
0798 pass
0799
0800