Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:48:46

0001 #!/usr/bin/env python
0002 """
0003 ::
0004 
0005     ipython -i ck.py 
0006 
0007 See ana/steps.py to understand why drawstyle="steps-post" is 
0008 appropriate for rindex related plotting as rindex appears to artificially dupe 
0009 the last value to give equal number of "values" to "edges".
0010 
0011 https://arxiv.org/pdf/1206.5530.pdf
0012 
0013 Calculation of the Cherenkov light yield from low energetic secondary particles
0014 accompanying high-energy muons in ice and water with Geant4 simulations
0015 
0016 
0017 """
0018 import os, logging, numpy as np
0019 import matplotlib.pyplot as plt
0020 from opticks.ana.main import opticks_main
0021 from opticks.ana.key import keydir
0022 from opticks.ana.nload import np_load
0023 
0024 log = logging.getLogger(__name__)
0025 
0026 
0027 class CK(object):
0028     FIGPATH="/tmp/ck/ck_rejection_sampling.png" 
0029     PATH="/tmp/ck/ck_%d.npy" 
0030 
0031     kd = keydir()
0032     rindex_path = os.path.join(kd, "GScintillatorLib/LS_ori/RINDEX.npy")
0033 
0034     #random_path = os.path.expandvars("/tmp/$USER/opticks/TRngBufTest_0.npy")
0035     random_path="/tmp/QCtxTest/rng_sequence_f_ni1000000_nj16_nk16_tranche100000"
0036 
0037     def init_random(self, num): 
0038 
0039         rnd, paths = np_load(self.random_path)
0040         if len(paths) == 0:
0041             log.fatal("failed to find any precooked randoms, create them with : TEST=F QSimTest")
0042             assert 0 
0043         pass
0044         if num is None:
0045             num = len(rnd)
0046         else:
0047             enough = num <= len(rnd)
0048             if not enough:
0049                 log.fatal("not enough precooked randoms len(rnd) %d num %d " % (len(rnd), num))
0050             pass
0051             assert enough
0052         pass
0053         cursors = np.zeros( num, dtype=np.int32 ) 
0054 
0055         self.cursors = cursors
0056         self.rnd_paths = paths
0057         self.rnd = rnd 
0058         self.num = num 
0059 
0060 
0061     def init_rindex(self, BetaInverse):
0062 
0063         rindex = np.load(self.rindex_path)
0064         rindex[:,0] *= 1e6    # into eV 
0065         rindex_ = lambda ev:np.interp( ev, rindex[:,0], rindex[:,1] ) 
0066 
0067         Pmin = rindex[0,0]  
0068         Pmax = rindex[-1,0]  
0069         nMax = rindex[:,1].max() 
0070 
0071         maxCos = BetaInverse / nMax
0072         maxSin2 = (1.0 - maxCos) * (1.0 + maxCos)
0073 
0074         smry = "nMax %6.4f BetaInverse %6.4f maxCos %6.4f maxSin2 %6.4f" % (nMax, BetaInverse, maxCos, maxSin2) 
0075         print(smry)
0076 
0077         self.BetaInverse = BetaInverse
0078         self.maxCos = maxCos
0079         self.maxCosi = 1. - maxCos
0080         self.maxSin2 = maxSin2 
0081 
0082         self.rindex = rindex
0083         self.Pmin = Pmin
0084         self.Pmax = Pmax
0085         self.nMax = nMax
0086         
0087         self.rindex_ = rindex_
0088         self.p = np.zeros( (num,4,4), dtype=np.float64 )
0089 
0090 
0091     def __init__(self, num=None, BetaInverse=1.5, random=True):
0092         self.init_rindex(BetaInverse) 
0093         if random:
0094             self.init_random(num)
0095         pass
0096 
0097     def energy_sample_all(self, method="mxs2"):
0098         for idx in range(self.num):
0099             self.energy_sample(idx, method=method) 
0100             if idx % 1000 == 0:
0101                 print(" idx %d num %d " % (idx, self.num))
0102             pass
0103         pass
0104 
0105     def stepfraction_sample_all(self):
0106         for idx in range(self.num):
0107             self.stepfraction_sample(idx) 
0108             if idx % 1000 == 0:
0109                 print(" idx %d num %d " % (idx, self.num))
0110             pass
0111         pass
0112 
0113     def stepfraction_sample(self, idx):
0114         """
0115         What is the expectation for the stepfraction pdf ?
0116         A linear scaling proportionate to the numbers of
0117         photons at each end.
0118 
0119 
0120             
0121 
0122 
0123           G4double NumberOfPhotons, N;
0124 
0125           do { 
0126              rand = G4UniformRand();
0127              NumberOfPhotons = MeanNumberOfPhotons1 - rand *
0128                                     (MeanNumberOfPhotons1-MeanNumberOfPhotons2);
0129              N = G4UniformRand() *
0130                             std::max(MeanNumberOfPhotons1,MeanNumberOfPhotons2);
0131             // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
0132           } while (N > NumberOfPhotons);
0133 
0134 
0135 
0136         N = M1 - u (M1 - M2)
0137           = M1 + u (M2 - M1) 
0138 
0139         """
0140         MeanNumberOfPhotons = np.array([1000., 1.])
0141         self.MeanNumberOfPhotons = MeanNumberOfPhotons
0142 
0143         rnd = self.rnd
0144         cursors = self.cursors  
0145         uu = rnd[idx].ravel()
0146 
0147         loop = 0 
0148 
0149         NumberOfPhotons = 0.
0150         N = 0.
0151         stepfraction = 0.
0152 
0153         while True:
0154             loop += 1  
0155             u0 = uu[cursors[idx]]
0156             cursors[idx] += 1 
0157 
0158             stepfraction = u0 
0159             NumberOfPhotons = MeanNumberOfPhotons[0] - stepfraction*(MeanNumberOfPhotons[0] - MeanNumberOfPhotons[1])  
0160             # stepfraction=0  ->  MeanNumberOfPhotons[0]
0161             # stepfraction=1  ->  MeanNumberOfPhotons[1]
0162 
0163             u1 = uu[cursors[idx]]
0164             cursors[idx] += 1 
0165 
0166             N = u1*MeanNumberOfPhotons.max()  
0167             # why is this range not from .min to .max  ?
0168             # because the sampled number can and will be less that the mean 
0169             # in some places  
0170 
0171             reject = N > NumberOfPhotons
0172             if not reject:
0173                 break   
0174             pass
0175         pass
0176 
0177         p = self.p[idx]  
0178         i = self.p[idx].view(np.uint64) 
0179 
0180         p[1,0] = stepfraction
0181         p[1,1] = NumberOfPhotons
0182         p[1,2] = N
0183 
0184         p[2,0] = u0
0185         p[2,1] = u1
0186 
0187         i[3,1] = loop
0188 
0189 
0190     def stepfraction_sample_globals(self):
0191         self.globals( 
0192             "p",self.p,  
0193             "stepfraction",    self.p[:,1,0],       
0194             "NumberOfPhotons", self.p[:,1,1],
0195             "N",               self.p[:,1,2],
0196 
0197             "u0",              self.p[:,2,0],
0198             "u1",              self.p[:,2,1],
0199             "loop",            self.p.view(np.uint64)[:,3,1]
0200         )
0201 
0202     def stepfraction_plot(self):
0203 
0204         self.stepfraction_sample_globals()
0205 
0206         fdom = np.linspace(0,1,100)
0207         frg = np.array( [0, 1])
0208         nrg = self.MeanNumberOfPhotons    
0209         xf_ = lambda f:np.interp(f, frg, nrg ) 
0210         self.xf_ = xf_ 
0211 
0212         h_stepfraction = np.histogram( stepfraction )
0213         h_loop = np.histogram(loop, np.arange(loop.max()+1))  
0214 
0215         title = "ana/ck.py:stepfraction_plot : sampling stepfraction between extremes MeanNumberOfPhotons : %s " % repr(self.MeanNumberOfPhotons)
0216 
0217         fig, axs = plt.subplots(2,3, figsize=ok.figsize )
0218         plt.suptitle(title)
0219 
0220         ax = axs[0,0]
0221         ax.scatter( u0, u1, label="(u0,u1)", s=0.1 )
0222         ax.legend()
0223 
0224         ax = axs[0,1]
0225         ax.scatter( NumberOfPhotons, N, label="(NumberOfPhotons,N)", s=0.1 )
0226         ax.legend()
0227 
0228         ax = axs[0,2]
0229         h = h_stepfraction
0230         ax.plot( h[1][:-1], h[0], label="h_stepfraction", drawstyle="steps-post" )
0231 
0232         scale = h[0][0]/xf_(0)
0233         ax.plot( fdom, scale*xf_(fdom), label="xf_ scaled to hist"  )
0234         ax.legend()
0235 
0236         ax = axs[1,0]
0237         h = h_loop
0238         ax.plot( h[1][:-1], h[0], label="h_loop", drawstyle="steps-post" )
0239         ax.legend()
0240 
0241 
0242         ax = axs[1,1]
0243         ax.plot( fdom, xf_(fdom), label="xf_"  )
0244         ax.legend()
0245 
0246         fig.show()
0247 
0248 
0249 
0250     def energy_sample(self, idx, method="mxs2"):
0251         """
0252         Why the small difference between s2 when sampling and "expectation-interpolating" 
0253         in energy regions far from achoring points ? 
0254 
0255         The difference is also visible in ct but less clearly.
0256         Comparising directly the sampled rs and rindex its difficult 
0257         to see any difference. 
0258 
0259         When sampling the energy is a random value taked from a flat 
0260         energy distribution and interpolated individually to give the 
0261         refractive index.
0262 
0263         When "expectation-interpolating" the energy domain is an abstract analytic ideal
0264         sort of like a "sample" taken from an infinity of possible values.
0265 
0266         """
0267         rnd = self.rnd
0268         rindex = self.rindex
0269         rindex_ = self.rindex_
0270         cursors = self.cursors  
0271         num = self.num
0272         Pmin = self.Pmin
0273         Pmax = self.Pmax  
0274         nMax = self.nMax
0275         BetaInverse = self.BetaInverse
0276         maxSin2 = self.maxSin2
0277         maxCosi = self.maxCosi
0278 
0279         uu = rnd[idx].ravel()
0280 
0281         dump = idx < 10 or idx > num - 10  
0282         loop = 0 
0283 
0284         while True:
0285             u0 = uu[cursors[idx]]
0286             cursors[idx] += 1 
0287 
0288             u1 = uu[cursors[idx]]
0289             cursors[idx] += 1 
0290 
0291             sampledEnergy = Pmin + u0*(Pmax-Pmin)
0292             sampledRI = rindex_(sampledEnergy)
0293             cosTheta = BetaInverse/sampledRI
0294             sin2Theta = (1.-cosTheta)*(1.+cosTheta)
0295 
0296             if method == "mxs2": 
0297                 u1_maxSin2 = u1*maxSin2
0298                 keep_sampling = u1_maxSin2 > sin2Theta
0299             elif method == "mxct":  ## CANNOT DO THIS : MUST USE THE "CONTROLLING" S2 PDF
0300                 u1_maxCosi = u1*maxCosi
0301                 keep_sampling = u1_maxCosi > 1.-cosTheta
0302             else:
0303                 assert 0
0304             pass
0305 
0306             loop += 1  
0307 
0308             if dump:
0309                 fmt = "method %s idx %5d u0 %10.5f sampledEnergy %10.5f sampledRI %10.5f cosTheta %10.5f sin2Theta %10.5f u1 %10.5f"
0310                 vals = (method, idx, u0, sampledEnergy, sampledRI, cosTheta, sin2Theta, u1 )
0311                 print(fmt % vals) 
0312             pass
0313 
0314             if not keep_sampling:
0315                 break
0316             pass
0317         pass
0318 
0319         hc_eVnm = 1239.8418754200 # G4: h_Planck*c_light/(eV*nm)   
0320 
0321         sampledWavelength = hc_eVnm/sampledEnergy 
0322 
0323         p = self.p[idx]  
0324         i = self.p[idx].view(np.uint64) 
0325 
0326         p[0,0] = sampledEnergy
0327         p[0,1] = sampledWavelength
0328         p[0,2] = sampledRI
0329         p[0,3] = cosTheta
0330 
0331         p[1,0] = sin2Theta 
0332 
0333         p[2,0] = u0
0334         p[2,1] = u1
0335 
0336         i[3,1] = loop
0337 
0338     def globals(self, *args):
0339         assert len(args) % 2 == 0
0340         for i in range(len(args)//2):
0341             k = args[2*i+0]
0342             v = args[2*i+1]
0343             print("%10s : %s " % (k, str(v.shape)))
0344             globals()[k] = v 
0345         pass 
0346 
0347     def energy_sample_globals(self):
0348         p = self.p
0349         u0 = p[:,2,0]   
0350         u1 = p[:,2,1] 
0351        
0352         en = p[:,0,0]
0353         wl = p[:,0,1]
0354         rs = p[:,0,2]
0355         ct = p[:,0,3]
0356 
0357         s2 = p[:,1,0]
0358 
0359         self.globals(
0360            "p",p,
0361            "u0",u0,
0362            "u1",u1,
0363            "en",en,
0364            "ct",ct,
0365            "s2",s2,
0366            "rs",rs
0367          )
0368 
0369     def save(self):
0370         path = self.PATH % self.num
0371         fold = os.path.dirname(path)
0372         if not os.path.exists(fold):
0373             os.makedirs(fold)
0374         pass
0375         log.info("save to %s " % path)
0376         np.save(path, self.p)
0377 
0378     @classmethod
0379     def Load(cls, num):
0380         path = cls.PATH % num
0381         return np.load(path)
0382 
0383  
0384 
0385 if __name__ == '__main__':
0386     logging.basicConfig(level=logging.INFO)
0387     plt.ion()
0388 
0389     ok = opticks_main()
0390     kd = keydir(os.environ["OPTICKS_KEY"])
0391  
0392     num = 10000   # 10k    s2 deviations visible with these stats 
0393     #num = 100000  # 100k   still visible
0394     #num = 1000000 # 1M      still visible
0395     #num = None
0396     ck = CK(num, BetaInverse=1.5, random=False)
0397 
0398     ck.test_GetAverageNumberOfPhotons(1.78)
0399     #ck.scan_GetAverageNumberOfPhotons()
0400 
0401     #ck.stepfraction_sample_all()
0402     #ck.stepfraction_plot()
0403 
0404 
0405     enplot = False
0406 
0407 if enplot:
0408     method = "mxs2"
0409     #method = "mxct"
0410     ck.energy_sample_all(method=method)
0411     ck.save()
0412     ck.energy_sample_globals()
0413 
0414     ri  = ck.rindex 
0415     edom = ri[:,0] 
0416 
0417     #en_lim = np.array([edom[0],edom[-1]])
0418     en_lim = np.array([2,10])    ## hmm need to find s2_ roots 
0419 
0420     s2_lim = np.array([-0.01, 0.31])
0421     ct_lim = np.array([ 0.83, 1.01])
0422     rs_lim = np.array([ ri[:,1].min(), ri[:,1].max() ])
0423 
0424     
0425     # lambda functions of energy using np.interpolate inside ck.rindex_
0426     ri_ = ck.rindex_
0427     ct_ = lambda e:ck.BetaInverse/ri_(e)
0428     s2_ = lambda e:(1.-ck.BetaInverse/ri_(e))*(1.+ck.BetaInverse/ri_(e)) 
0429 
0430     ri_interp = ri_(edom)   
0431     ct_interp = ct_(edom)
0432     s2_interp = (1. - ct_interp)*(1. + ct_interp )
0433 
0434     en_u0 = ck.Pmin+u0*(ck.Pmax-ck.Pmin)
0435     s2_u1 = ck.maxSin2*u1
0436 
0437 
0438     # pick energy  bin look at the s2 sampled within
0439     # compare with expectations from interpolation 
0440     # is the deviation a statistical thing : the sampling
0441     # can only ever approach the expectation never getting there without 
0442     # infinite statistics  
0443     ebin = [5,5.1]
0444     a_s2 = s2[np.logical_and(en > ebin[0], en < ebin[1])]  
0445     a_s2_0 = s2_(ebin[0])
0446     a_s2_1 = s2_(ebin[1])
0447 
0448 
0449 if enplot:
0450     fig, ax = plt.subplots(figsize=ok.figsize) 
0451     fig.suptitle("s2 vs en : deviation between sampling and interpolated, more further from anchor points")
0452 
0453     ax.scatter( en, s2, s=0.1, label="sampled en vs s2") 
0454 
0455     ax.set_xlabel("en")
0456     ax.set_ylabel("s2")
0457     ax.set_xlim( en_lim )
0458     ax.set_ylim( s2_lim )
0459     xlim = ax.get_xlim()
0460 
0461     ax.plot( ri[:,0], s2_interp, label="s2_interp", color="r" )
0462     ax.scatter( ri[:,0] , s2_(ri[:,0]), color="b", label="en s2" ) 
0463 
0464 
0465     ax.set_xlim(xlim) 
0466     ylim = ax.get_ylim()
0467     #for e in ri[:,0]:
0468     #    ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0469     #pass 
0470     for i in list(range(len(ri)-1)):
0471         e0,v0 = ri[i]
0472         e1,v1 = ri[i+1]
0473         ax.plot( [e0,e1], [s2_(e0), s2_(e1)], linestyle="dotted", color="b" )
0474         #ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0475     pass 
0476 
0477     ax.plot( xlim, [0.,0.], linestyle="dotted", color="r" )
0478     ax.legend()
0479 
0480     fig.show()
0481 
0482 
0483 
0484 if enplot:
0485     fig, ax = plt.subplots(figsize=ok.figsize) 
0486     fig.suptitle("1-ct vs en : deviation between sampling and interpolated, more further from anchor points")
0487 
0488     ax.scatter( en, 1-ct, s=0.1, label="sampled en vs 1-ct") 
0489 
0490     ax.set_xlabel("en")
0491     ax.set_ylabel("1-ct")
0492     ax.set_xlim( en_lim )
0493     ax.set_ylim( 1-ct_lim[::-1] )
0494     xlim = ax.get_xlim()
0495 
0496     ax.plot( ri[:,0], 1 - ct_interp, label="1-ct_interp", color="r" )
0497     ax.scatter( ri[:,0] , 1 - ct_(ri[:,0]), color="b", label="en 1-ct" ) 
0498 
0499 
0500     ax.set_xlim(xlim) 
0501     ylim = ax.get_ylim()
0502     #for e in ri[:,0]:
0503     #    ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0504     #pass 
0505     for i in list(range(len(ri)-1)):
0506         e0,v0 = ri[i]
0507         e1,v1 = ri[i+1]
0508         ax.plot( [e0,e1], [1-ct_(e0), 1-ct_(e1)], linestyle="dotted", color="b" )
0509         #ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0510     pass 
0511 
0512     ax.plot( xlim, [0.,0.], linestyle="dotted", color="r" )
0513     ax.legend()
0514 
0515     fig.show()
0516 
0517 
0518 
0519 
0520 if enplot:
0521     fig, ax = plt.subplots(figsize=ok.figsize) 
0522     fig.suptitle("rs/ri vs en : deviation between sampling and interpolated, more further from anchor points")
0523 
0524     ax.scatter( en, rs, s=0.1, label="sampled en vs rs") 
0525 
0526     ax.set_xlabel("en")
0527     ax.set_ylabel("rs")
0528     ax.set_xlim( en_lim )
0529     ax.set_ylim( rs_lim )
0530     xlim = ax.get_xlim()
0531 
0532     ax.plot(    ri[:,0],  ri_(ri[:,0]), label="ri", color="r" )
0533     ax.scatter( ri[:,0] , ri[:,1],      label="en ri", color="b" ) 
0534 
0535 
0536     ax.set_xlim(xlim) 
0537     ylim = ax.get_ylim()
0538     #for e in ri[:,0]:
0539     #    ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0540     #pass 
0541     for i in list(range(len(ri)-1)):
0542         e0,v0 = ri[i]
0543         e1,v1 = ri[i+1]
0544         ax.plot( [e0,e1], [ri_(e0), ri_(e1)], linestyle="dotted", color="b" )
0545         #ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0546     pass 
0547 
0548     ax.plot( xlim, [0.,0.], linestyle="dotted", color="r" )
0549     ax.legend()
0550     fig.show()
0551 
0552 
0553 
0554 
0555 
0556 
0557 
0558 
0559 
0560 if 0:
0561 
0562     fig, axs = plt.subplots(2,3,figsize=ok.figsize) 
0563 
0564     title = "\n".join(
0565           ["Cerenkov Rejection Sampling, for JUNO LS refractive index (en:energy in eV ct:cosTheta s2:sin2Theta) ", 
0566            "2d plots:  (u0,u1) (en,ct) (en,ct)        (Pmin+u0*(Pmax-Pmin),u1*maxSin2) (s2,en) (s2,en) ",
0567            "RHS compares with interpolated expectation"
0568           ])  
0569 
0570     fig.suptitle(title) 
0571 
0572     ax = axs[0,0]
0573     ax.set_xlim(0,1)
0574     ax.set_ylim(0,1)
0575     ax.set_xlabel("u0")
0576     ax.set_ylabel("u1")
0577     ax.scatter( u0, u1, s=0.1) 
0578     ax.set_aspect('equal')  
0579 
0580     ax = axs[1,0]
0581     ax.set_xlabel("en_u0 : Pmin+u0*(Pmax-Pmin)")
0582     ax.set_ylabel("s2_u1 : u1*maxSin2")
0583     ax.set_ylim( s2_lim )
0584     ax.scatter( en_u0, s2_u1, s=0.1) 
0585     xlim = ax.get_xlim()
0586     ax.plot( xlim, [ck.maxSin2, ck.maxSin2] , linestyle="dotted", color="r") 
0587 
0588     ax = axs[0,1]
0589     ax.scatter( en, 1.-ct, s=0.1) 
0590     ax.set_xlabel("en")
0591     ax.set_ylabel("1-ct")
0592     ax.set_ylim( 1-ct_lim[::-1] ) 
0593     xlim = ax.get_xlim()
0594     ylim = ax.get_ylim()
0595     for e in ck.rindex[:,0]:
0596         ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0597     pass
0598     ax.set_xlim(xlim)
0599     ax.plot( xlim, [1.-ck.maxCos, 1.-ck.maxCos] , linestyle="dotted", color="r") 
0600    
0601     ax = axs[1,1]
0602     ax.scatter( en, s2, s=0.1) 
0603     ax.set_xlabel("en")
0604     ax.set_ylabel("s2")
0605     ax.set_ylim( s2_lim )
0606     xlim = ax.get_xlim()
0607     ylim = ax.get_ylim()
0608     for e in ck.rindex[:,0]:
0609         ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0610     pass
0611     ax.set_xlim(xlim)
0612  
0613     ax = axs[0,2]
0614     ax.scatter( en, ct, s=0.1) 
0615     ax.set_xlabel("en")
0616     ax.set_ylabel("ct")
0617     ax.set_ylim( ct_lim ) 
0618     xlim = ax.get_xlim()
0619     #ax.plot( ck.rindex[:,0], ck.BetaInverse/ck.rindex[:,1], drawstyle="steps-post" )
0620     ax.plot( ck.rindex[:,0], ct_interp, color="r" )  
0621     ax.set_xlim(xlim) 
0622     ax.plot( xlim, [1.,1.], linestyle="dotted", color="r" )
0623     ylim = ax.get_ylim()
0624     for e in ck.rindex[:,0]:
0625         ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0626     pass 
0627 
0628     if 0:
0629         for v in ck.BetaInverse/ck.rindex[:,1]:
0630             ax.plot( xlim, [v,v] , linestyle="dotted", color="b") 
0631         pass 
0632     pass
0633 
0634 
0635     ax = axs[1,2]
0636     ax.scatter( en, s2, s=0.1) 
0637     ax.set_xlabel("en")
0638     ax.set_ylabel("s2")
0639     ax.set_ylim( s2_lim )
0640     xlim = ax.get_xlim()
0641     ax.plot( ck.rindex[:,0], s2_interp, label="s2_interp", color="r" )
0642     ax.set_xlim(xlim) 
0643     ylim = ax.get_ylim()
0644     for e in ck.rindex[:,0]:
0645         ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0646     pass 
0647     ax.plot( xlim, [0.,0.], linestyle="dotted", color="r" )
0648 
0649 
0650     fig.show() 
0651     path = ck.FIGPATH
0652     print("save to %s " % path)
0653     fig.savefig(path)
0654 
0655 
0656 
0657 
0658 
0659 
0660 if 0:
0661     fig3, ax = plt.subplots(figsize=ok.figsize) 
0662 
0663     h = np.histogram( en )
0664     ax.plot( h[1][:-1], h[0], label="hist en" )
0665     ax.legend()
0666     fig3.show()
0667 
0668 
0669 
0670 if 0:
0671     fig2, ax = plt.subplots(figsize=ok.figsize) 
0672     fig2.suptitle( repr(ck.rindex.T) )
0673 
0674     ax.scatter( en, ct, s=0.5) 
0675     ax.set_xlabel("en")
0676     ax.set_ylabel("ct")
0677     xlim = ax.get_xlim()
0678 
0679     ax.plot( ck.rindex[:,0], ck.BetaInverse/ck.rindex[:,1], drawstyle="steps-post" )
0680     ax.set_xlim(xlim) 
0681     ax.plot( xlim, [1.,1.], linestyle="dotted", color="r" )
0682 
0683     ylim = ax.get_ylim()
0684     for e in ck.rindex[:,0]:
0685         ax.plot( [e,e], ylim , linestyle="dotted", color="b") 
0686     pass 
0687     for v in ck.BetaInverse/ck.rindex[:,1]:
0688         ax.plot( xlim, [v,v] , linestyle="dotted", color="b") 
0689     pass 
0690     
0691     fig2.show() 
0692 
0693