# -*- coding: UTF-8 -*-
import os, sys, traceback, json
from pyopus.misc.debug import DbgSetup, DbgMsgOut
DbgSetup(True, 1)

useMPI=True
mpiData={'cosdebug': 0,
 'mirror': True,
 'persistent': True,
 'processors': None,
 'vmdebug': 0}


projData={'analyses': {'AC': {'command': 'ac(10, 1e6, "dec", 100)',
                     'head': 'opus',
                     'modules': ['filter_netlist'],
                     'options': {},
                     'params': {},
                     'saves': []}},
 'analysisNames': ['AC'],
 'designPar': {'c1': {'hi': 6e-06, 'init': 2.5e-06, 'lo': 1e-12},
               'c2': {'hi': 6e-06, 'init': 2.5e-06, 'lo': 1e-12},
               'c3': {'hi': 6e-06, 'init': 2.8e-06, 'lo': 1e-12},
               'l1': {'hi': 0.002, 'init': 0.0014, 'lo': 1e-09},
               'r0': {'hi': 100000.0, 'init': 56000.0, 'lo': 100},
               'r1': {'hi': 10000.0, 'init': 400, 'lo': 10}},
 'designParNames': ['r0', 'c1', 'l1', 'c2', 'r1', 'c3'],
 'headNames': ['opus'],
 'heads': {'opus': {'moddefs': {'filter_netlist': {'file': 'filter_netlist.cir'}},
                    'options': {},
                    'params': {},
                    'settings': {},
                    'simulator': 'SpiceOpus'}},
 'measureLower': {'BW': 1000},
 'measureNames': ['BW', 'damping', 'ripple'],
 'measureNorm': {},
 'measureUpper': {'BW': 1100, 'damping': 0.05, 'ripple': 0.5},
 'measures': {'BW': {'analysis': 'AC',
                     'depends': [],
                     'expression': 'm.ACbandwidth(v("out")/v("in"), scale(), '
                                   "filter='lp', levelType='db', level=-3.0)",
                     'vector': False},
              'damping': {'analysis': 'AC',
                          'depends': [],
                          'expression': 'x = abs(scale())\n'
                                        "y = m.ACmag(v('out')/v('in'))\n"
                                        'bw = '
                                        "m.ACbandwidth(v('out')/v('in'),scale(),filter='lp', "
                                        "levelType='db', level=-3.0)\n"
                                        '#bw=1e3\n'
                                        'i = m.IatXval(x, bw+300)        # '
                                        'interpolated index\n'
                                        'i = int(np.round(i))        # parse '
                                        'the float to int\n'
                                        'y1 = m.XatIrange(y,i,len(y)-1)     # '
                                        'subvector of vector y from 0 to i '
                                        'index\n'
                                        'damping = y1.max()\n'
                                        'threshold = -20\n'
                                        'count_gt = np.sum(y1 > threshold)\n'
                                        'count_le = np.sum(y1 <= threshold)\n'
                                        'ratio = count_gt / len(y1)\n'
                                        '\n'
                                        '__result = ratio',
                          'vector': False},
              'ripple': {'analysis': 'AC',
                         'depends': [],
                         'expression': '#ripple\n'
                                       'x = abs(scale())\n'
                                       "y = m.ACmag(v('out')/v('in'))\n"
                                       '#bw =  '
                                       "m.ACbandwidth(v('out')/v('in'),scale(),filter='lp', "
                                       "levelType='db', level=-3.0)\n"
                                       'bw=1e3\n'
                                       'i = m.IatXval(x, bw-200)        '
                                       '#interpolated index\n'
                                       'i = int(np.round(i))        # parsethe '
                                       'float to int\n'
                                       'y1 = m.XatIrange(y,0,i)     # '
                                       'subvector of vector y from 0 to i '
                                       'index\n'
                                       'rup = y.max()\n'
                                       'rdn = y1.min()\n'
                                       'nom = y[0]\n'
                                       '__result = np.maximum(rup-nom, '
                                       'nom-rdn)',
                         'vector': False}},
 'mirrormap': {'filter_netlist.cir': '.'},
 'opPar': {},
 'opParNames': [],
 'statPar': {},
 'statParNames': [],
 'variableNames': [],
 'variables': {}}

taskData={'cornerNames': ['nominal'],
 'corners': {('nominal', ('opus',)): {'modules': [], 'params': {}}},
 'fixedParameterNames': [],
 'name': 'optimization',
 'optParameterNames': ['r0', 'c1', 'l1', 'c2', 'r1', 'c3'],
 'output': {'aggregatordebug': 0,
            'evaluatordebug': 0,
            'keepfiles': False,
            'optimizerdebug': 0,
            'saveallresults': False,
            'savewaveforms': 'always',
            'simulatordebug': 0,
            'taskdebug': 1},
 'parameterNames': ['r0', 'c1', 'l1', 'c2', 'r1', 'c3'],
 'parameters': {'c1': {'hi': 6e-06, 'init': 2.5e-06, 'lo': 1e-09},
                'c2': {'hi': 6e-06, 'init': 2.5e-06, 'lo': 1e-09},
                'c3': {'hi': 6e-06, 'init': 2.8e-06, 'lo': 1e-09},
                'l1': {'hi': 0.002, 'init': 0.0014, 'lo': 1e-06},
                'r0': {'hi': 100000.0, 'init': 56000.0, 'lo': 1000.0},
                'r1': {'hi': 10000.0, 'init': 400, 'lo': 10}},
 'requirementNames': ['BW', 'damping', 'ripple'],
 'requirements': {'exclude': [],
                  'lower': {'BW': 900},
                  'norm': {},
                  'tradeoff': {},
                  'upper': {'BW': 1100, 'damping': 0.05, 'ripple': 0.5}},
 'settings': {'aggregatorsettings': {},
              'evaluatorsettings': {},
              'failurepenalty': 1000000.0,
              'forwardsolution': False,
              'incrementalcorners': True,
              'initialstep': 0.25,
              'maxiter': None,
              'method': 'ParallelSADE',
              'optimizersettings': {},
              'stopsatisfied': True,
              'stoptol': 1e-05,
              'tradeoffmultiplier': 0},
 'type': 'cbd'}

if __name__=='__main__':
  import numpy as np
  np.random.seed(0)

  if useMPI:
    from pyopus.parallel.mpi import MPI
    from pyopus.parallel.cooperative import cOS

    cOS.setDebug(mpiData['cosdebug'])
    if mpiData['mirror']:
      vm=MPI(mirrorMap=projData['mirrormap'], persistentStorage=mpiData['persistent'], debug=mpiData['vmdebug'])
    else:
      vm=MPI(debug=mpiData['vmdebug'])
    cOS.setVM(vm)

    hosts=MPI.vmStatus['hosts']
    slots=MPI.vmStatus['slots']
    DbgMsgOut('VM', 'Process list (total %d):' % (len(slots)))
    for host in hosts.keys():
      DbgMsgOut('VM', '  Host %s with %d process(es)' % (host, len(hosts[host]['slots'])))
      for slot in hosts[host]['slots']:
        DbgMsgOut('VM', '    slot %d: pid=0x%x (%d)' % (slot, slots[slot]['pid'], slots[slot]['pid']))

  from pyopus.design.sqlite import SQLiteDatabase
  sqld=SQLiteDatabase(os.path.join('..', taskData['name']+'.sqlite'))

  from pyopus.gui.tasks import taskRunner

  try:
    runner=taskRunner[taskData['type']]
    runner(projData, taskData, sqld)
  except Exception as e:
    DbgMsgOut('TASK', 'Task terminated due to exception.')
    DbgMsgOut('TASK', traceback.format_exc())
    sys.exit(1)

  if useMPI:
    cOS.finalize()
