# Worst case distance

from definitions import *
from pyopus.design.wcd import WorstCaseDistance
# If MPI is imported an application not using MPI will behave correctly
# (i.e. only slot 0 will run the program) even when started with mpirun/mpiexec
from pyopus.parallel.mpi import MPI
from pyopus.parallel.cooperative import cOS
import sys

# Script arguments 
#   noop computes worst case without operating parameters (assumed initial)

if __name__=='__main__':
	atDesign={
		# Result of design across corners
		  'c_out':   3.4227551453164880e-13, 
         'diff_l':   7.4308192182875534e-07, 
         'diff_w':   1.2789110397149770e-06, 
         'load_l':   2.1097689639936013e-06, 
         'load_w':   2.3180449555941561e-06, 
         'mirr_l':   4.0529113121872304e-07, 
        'mirr_ld':   1.3311984218957902e-06, 
         'mirr_w':   3.4036562767439648e-05, 
        'mirr_wd':   2.3745920801687639e-06, 
        'mirr_wo':   2.1285465666785311e-05, 
          'out_l':   5.3631175887258056e-07, 
          'out_w':   2.6406246699146450e-05, 
          'r_out':   3.0372450962642072e+00, 
	}
	
	# Create corner with the Monte Carlo model
	corners={
		'mc': {
			'params': {}, 
			'modules': [ 'mc' ]
		}
	}

	if len(sys.argv)>1 and sys.argv[1]=="noop":
		# No operating parameters
		# Add operating parameters to corner
		corners['mc']['params'].update({
			name: v['init'] for name, v in opParams.items()
		})
		opParams = {}
		
	# Worst case performances (skip area)
	wcList=list(measures.keys())
	wcList.sort()
	wcList.remove('area')

	# wcList = [ 'swing' ]
	
	# Prepare parallel environment
	cOS.setVM(MPI(mirrorMap={'*':'.'}))
	
	# 3-sigma worst case
	wc=WorstCaseDistance(
		heads, analyses, measures, corners, statParams, opParams, variables=variables, 
		fixedParams=atDesign, 
		stepTol=0.01,  # Try 0.0001
		sigmaBox=10, 
		debug=2, 
		spawnerLevel=0
	)
	wcresults, analysisCount = wc(wcList)
	# wcresults, analysisCount = wc(['vgs_drv'])
	# wcresults, analysisCount = wc(['cmrr', 'vgs_drv'])
	# wcresults, analysisCount = wc(['cmrr'])
	# wcresults, analysisCount = wc(['ugbw'])
	# wcresults, analysisCount = wc(['vgs_drv'])
	
	print(wc.formatResults())
	print(wc.analysisCount)
	
	# Finalize cOS parallel environment
	cOS.finalize()

# Result
# All parameters
#       cmrr >     6.00000e+01 wc=    5.99889e+01 wcd=    2.38682e+00 neval= 758 2 OK
#       gain >     6.00000e+01 wc=    6.03467e+01 wcd=    1.20936e+01 neval= 797 2 OK
#       isup <     1.00000e-03 wc=    2.21376e-04 wcd=    2.00000e+01 neval= 338 1 SENS+
#     out_op >    -1.25000e-02 wc=   -1.26342e-02 wcd=    1.46207e+00 neval= 296 1 OK
#     out_op <     1.25000e-02 wc=    1.25005e-02 wcd=    7.95162e-01 neval= 118 1 OK
#   overshdn <     1.50000e-01 wc=    6.90693e-02 wcd=    2.90215e+01 neval= 727 2 OUTSIDE+
#   overshup <     1.50000e-01 wc=    7.96516e-02 wcd=    2.82886e+01 neval= 799 2 OUTSIDE+
#   ph_slope <     0.00000e+00 wc=   -0.00000e+00 wcd=    0.00000e+00 neval= 137 1 SENS0
#         pm >     5.00000e+01 wc=    4.99975e+01 wcd=    1.50606e+01 neval= 346 2 OK
#   psrr_vdd >     6.00000e+01 wc=    5.99967e+01 wcd=    1.59696e+01 neval= 623 2 OK
#   psrr_vss >     6.00000e+01 wc=    5.99896e+01 wcd=    6.19946e+00 neval= 479 3 OK
#     slewdn >     2.00000e+06 wc=    5.88698e+06 wcd=    2.88507e+01 neval= 189 1 OUTSIDE+
#     slewup >     2.00000e+06 wc=    1.99989e+06 wcd=    1.71749e+01 neval=1089 2 OK
#      swing >     1.00000e+00 wc=    1.12190e+00 wcd=    2.23537e+01 neval= 300 3 OUTSIDE+
#     tsetdn <     1.00000e-06 wc=    2.09838e-07 wcd=    2.85859e+01 neval= 185 1 SENS+
#     tsetup <     1.00000e-06 wc=    4.15276e-07 wcd=    2.23119e+01 neval= 707 2 OUTSIDE+
#       ugbw >     1.00000e+07 wc=    1.00012e+07 wcd=    5.31465e+00 neval= 138 1 OK
# vds_drv[0] >     0.00000e+00 wc=   -2.23990e-03 wcd=    1.15538e+01 neval= 239 1 OK
# vds_drv[1] >     0.00000e+00 wc=   -1.29015e-03 wcd=    1.29388e+01 neval= 235 1 OK
# vds_drv[2] >     0.00000e+00 wc=    1.17922e-01 wcd=    1.00000e+01 neval= 129 1 OUTSIDE+
# vds_drv[3] >     0.00000e+00 wc=   -8.10656e-05 wcd=    5.62283e+00 neval= 191 1 OK
# vds_drv[4] >     0.00000e+00 wc=    5.22128e-01 wcd=    2.89123e+01 neval= 488 3 OUTSIDE+
# vds_drv[5] >     0.00000e+00 wc=    1.00224e-01 wcd=    1.41421e+01 neval= 137 1 OUTSIDE+
# vds_drv[6] >     0.00000e+00 wc=    1.74014e-04 wcd=    9.33510e+00 neval= 126 1 OK
# vds_drv[7] >     0.00000e+00 wc=    4.24175e-01 wcd=    2.63805e+01 neval= 167 1 SENS+
# vgs_drv[0] >     0.00000e+00 wc=    9.01518e-03 wcd=    2.66957e+01 neval= 736 3 OUTSIDE+
# vgs_drv[1] >     0.00000e+00 wc=    1.00806e-02 wcd=    2.59544e+01 neval= 335 2 OUTSIDE+
# vgs_drv[2] >     0.00000e+00 wc=    2.31211e-02 wcd=    1.14839e+01 neval= 146 1 OUTSIDE+
# vgs_drv[3] >     0.00000e+00 wc=    7.23921e-02 wcd=    1.92968e+01 neval= 142 1 OUTSIDE+
# vgs_drv[4] >     0.00000e+00 wc=    1.89886e-03 wcd=    1.82913e+01 neval= 200 1 OUTSIDE+
# vgs_drv[5] >     0.00000e+00 wc=    9.29153e-02 wcd=    2.61797e+01 neval= 605 2 OUTSIDE+
# vgs_drv[6] >     0.00000e+00 wc=    1.19309e-01 wcd=    2.23607e+01 neval= 242 2 OUTSIDE+
# vgs_drv[7] >     0.00000e+00 wc=    7.54566e-02 wcd=    1.73106e+01 neval= 269 2 OUTSIDE+
# 
# No operating parameters
#       cmrr >     6.00000e+01 wc=    5.99680e+01 wcd=    4.86683e+00 neval= 463 2 OK
#       gain >     6.00000e+01 wc=    5.99978e+01 wcd=    2.08527e+01 neval= 330 2 OK
#       isup <     1.00000e-03 wc=    2.14773e-04 wcd=    1.97590e+01 neval= 295 1 SENS+
#     out_op >    -1.25000e-02 wc=   -1.25514e-02 wcd=    1.47232e+00 neval= 281 1 OK
#     out_op <     1.25000e-02 wc=    1.25004e-02 wcd=    8.25196e-01 neval=  89 1 OK
#   overshdn <     1.50000e-01 wc=    6.62315e-02 wcd=    2.90679e+01 neval= 418 2 OUTSIDE+
#   overshup <     1.50000e-01 wc=    7.67008e-02 wcd=    2.79355e+01 neval= 397 1 SENS+
#   ph_slope <     0.00000e+00 wc=   -0.00000e+00 wcd=    0.00000e+00 neval= 106 1 SENS0
#         pm >     5.00000e+01 wc=    4.99958e+01 wcd=    1.45120e+01 neval= 354 1 OK
#   psrr_vdd >     6.00000e+01 wc=    5.99990e+01 wcd=    1.68510e+01 neval= 323 1 OK
#   psrr_vss >     6.00000e+01 wc=    6.00001e+01 wcd=    6.65732e+00 neval= 815 2 OK
#     slewdn >     2.00000e+06 wc=    6.22242e+06 wcd=    2.71171e+01 neval= 205 1 OUTSIDE+
#     slewup >     2.00000e+06 wc=    3.53477e+06 wcd=    2.14140e+01 neval= 685 2 OUTSIDE+
#      swing >     1.00000e+00 wc=    1.30295e+00 wcd=    2.22168e+01 neval= 172 1 SENS+
#     tsetdn <     1.00000e-06 wc=    2.24249e-07 wcd=    2.97211e+01 neval= 332 2 SENS+
#     tsetup <     1.00000e-06 wc=    2.75582e-07 wcd=    2.15636e+01 neval=1070 2 OUTSIDE+
#       ugbw >     1.00000e+07 wc=    9.99193e+06 wcd=    1.18031e+01 neval= 178 1 OK
# vds_drv[0] >     0.00000e+00 wc=   -1.62269e-03 wcd=    1.37241e+01 neval= 195 2 OK
# vds_drv[1] >     0.00000e+00 wc=   -4.20765e-04 wcd=    1.51966e+01 neval= 123 1 OK
# vds_drv[2] >     0.00000e+00 wc=    2.09021e-01 wcd=    1.00000e+01 neval=  87 1 OUTSIDE+
# vds_drv[3] >     0.00000e+00 wc=   -3.81367e-05 wcd=    8.00005e+00 neval= 129 1 OK
# vds_drv[4] >     0.00000e+00 wc=    5.93660e-01 wcd=    2.44715e+01 neval= 134 1 SENS+
# vds_drv[5] >     0.00000e+00 wc=    1.69136e-01 wcd=    1.41421e+01 neval=  94 1 OUTSIDE+
# vds_drv[6] >     0.00000e+00 wc=    6.12520e-02 wcd=    1.00000e+01 neval=  87 1 OUTSIDE+
# vds_drv[7] >     0.00000e+00 wc=    5.22910e-01 wcd=    2.00000e+01 neval= 116 1 SENS+
# vgs_drv[0] >     0.00000e+00 wc=    1.56581e-02 wcd=    2.64548e+01 neval= 299 2 OUTSIDE+
# vgs_drv[1] >     0.00000e+00 wc=    1.49802e-02 wcd=    2.59364e+01 neval= 326 2 OUTSIDE+
# vgs_drv[2] >     0.00000e+00 wc=    2.69550e-02 wcd=    1.13844e+01 neval= 108 1 OUTSIDE+
# vgs_drv[3] >     0.00000e+00 wc=    7.92806e-02 wcd=    1.88280e+01 neval= 157 1 OUTSIDE+
# vgs_drv[4] >     0.00000e+00 wc=    6.29148e-03 wcd=    1.94601e+01 neval= 109 1 OUTSIDE+
# vgs_drv[5] >     0.00000e+00 wc=    1.64301e-01 wcd=    2.23607e+01 neval= 258 2 OUTSIDE+
# vgs_drv[6] >     0.00000e+00 wc=    1.64319e-01 wcd=    2.23607e+01 neval= 218 2 OUTSIDE+
# vgs_drv[7] >     0.00000e+00 wc=    8.86048e-02 wcd=    1.73210e+01 neval= 171 2 OUTSIDE+
