def main_routine (baseDir="./",configPath="./python/parameter.cfg",generationType="r"):
  print "#################################################################"
  print "#################################################################"
  print "### optimal control #############################################"
  print "### preparation of smallest overlap functional ##################"
  print "#################################################################"
  print "#################################################################"

  ### globals for functional variation
  global time, cavityRead, cavityMemo, \
         nRead, nDown, nUp, nWrite, dimH, \
         cfg, \
         h0, hc_up, hc_down, hs_up, hs_down, hsep, \
         weight_up, weight_down, sepZeroWeight, \
         normUp, normDown, normRead, \
         hole, \
         iteration

  tmpDir=baseDir+"tmp/"
  #  parser.add_argument("--cfg" ,  help="config path")
  ### check for arguments, g: generate data, r: read data ###

  ### read config file ###
  print ("load from config file: " + configPath)

  configParser = cp.ConfigParser()
  configParser.read(configPath)
  print (configParser.sections())
  cfg=configParser.__dict__['_sections'].copy() 

  #for src, target in cfg['NVSETUP'].items():
  #  print(src + " : " + target)

  nRead =int(cfg['OCFourier']['{read_harmonic}'])
  nWrite=int(cfg['OCFourier']['{write_harmonic}'])
  nDown =nRead+nWrite
  nUp   =nDown+nWrite
  nTimeRead =int(cfg['OCTime']['{read_timecnt}'])
  dimH      =nRead + 2*nWrite

  normRead =float(cfg['OCConstraints']['{amplitude_read}']) 
  normDown =float(cfg['OCConstraints']['{amplitude_down}']) 
  normUp   =float(cfg['OCConstraints']['{amplitude_up}']) 

  name_readwrite = IOHelper.getNameReadWrite(**cfg)
  name_vector    = IOHelper.getVectorOverlap(**cfg)
  ### read config file ###


  ### prepare data with fortran ###
  cmd = "mkdir -p " + tmpDir
  print (tmpDir)
  call(cmd.split())
  replace_in_file('./python/py.parNvCenter.F95'       , tmpDir +'parNvCenter.F95',        **cfg['NVSETUP'])
  replace_in_file('./python/py.parSmallestOverlap.F95', tmpDir +'parSmallestOverlap.F95', **cfg['OCFourier'])
  replace_in_file(tmpDir +'parSmallestOverlap.F95', tmpDir +'parSmallestOverlap.F95',     **cfg['OCConstraints'])
  replace_in_file(tmpDir +'parSmallestOverlap.F95', tmpDir +'parSmallestOverlap.F95',     **cfg['OCTime'])
  replace_in_file(tmpDir +'parSmallestOverlap.F95', tmpDir +'parSmallestOverlap.F95',     **cfg['FILES'])

  #write config file
  with open(cfg['FILES']['{prefix}']+"parameter.cfg", 'wb') as configfile:
    configParser.write(configfile)

  cmd = "mv "+tmpDir+"parSmallestOverlap.F95 "+baseDir+"srcOptCntrl/parSmallestOverlap.F95"
  call(cmd.split())
  cmd = "mv "+tmpDir+"parNvCenter.F95 "+baseDir+"srcNv/parNvCenter.F95"
  call(cmd.split())

  print ("compile fortran routines")
  cmd = "./scripts/ifort-generateHarmonics.sh " + baseDir
  call(cmd.split())

  print ("invoke " +baseDir +"generateHarmonics")

  cmd = baseDir+"generateHarmonics"
  generateHarmonics = Popen(cmd.split(), stdin=PIPE)
  cmd = "echo " + generationType
  generateInput     = Popen(cmd.split(), stdout=generateHarmonics.stdin)
  output            = generateHarmonics.communicate()[0]
  generateInput.wait()
  ### prepare data with fortran ###


  ### read data for functional variation ###
  __,cavityMemo,cavityRead =IOHelper.harmonics_readwrite(**cfg)
  time                     =IOHelper.functionaltimes_readwrite(**cfg)

  h0,hs_down,hs_up,hc_down,hc_up,hsep=IOHelper.read_MtrxOverlap(**cfg['FILES']) 
  hole                               =IOHelper.read_HoleData(**cfg['FILES']) 
  ### read data for functional variation ###


  ### functional variation ###
  print ("\nstart minimization: ")

  varMax = 20
  varStep = 1
  success = False

  #constraints for constraintWeightDown and constraintWeightUp
  funcTime  =float(time['tfunc'])
  weight_down=float(cfg ['OCConstraints']['{temporal_weight_down}'])*funcTime/2.0
  weight_up  =float(cfg ['OCConstraints']['{temporal_weight_up}'])*funcTime/2.0

  minContraints= ( {'type' : 'ineq', 'fun'  : constraintNormRead },
                   {'type' : 'eq', 'fun'  : constraintNormDown },
                   {'type' : 'eq', 'fun'  : constraintNormUp },
                   {'type' : 'eq', 'fun'  : constraintWeightDown },
                   {'type' : 'eq', 'fun'  : constraintWeightUp },
#                   {'type' : 'eq', 'fun'  : constraintRealMaxCoefficient },
                   {'type' : 'ineq', 'fun'  : constraintZeroStartDown },
                   {'type' : 'ineq', 'fun'  : constraintZeroStartUp },
                   {'type' : 'ineq', 'fun'  : constraintPartialOverlap },
                   {'type' : 'ineq', 'fun'  : constraintStoreUp },
                   {'type' : 'ineq', 'fun'  : constraintStoreDownIneq },
#
  #                 {'type' : 'ineq', 'fun'  : constraintSeperateZero },
#                   {'type' : 'eq', 'fun'  : constraintStoreDown },
#                   {'type' : 'eq', 'fun'  : constraintHoleValue },
#                   {'type' : 'eq', 'fun'  : constraintHoleSlope },
#                   {'type' : 'eq', 'fun'  : constraintHoleCurv },
                 )


  while varStep < varMax and not success :
    gamma0=initGamma0()
    x,x0  =initx(gamma0)

  #    print (" calculate sepzero to initialize vector x (method=SLSQP):")
  #    iteration=1
  #    res=minimize(seperateZeroStore, #seperateZero, # smallestAbsoluteOverlap,
  #                 x0, #res.x, 
  #                 method='SLSQP',
  #                 constraints=sepzeroContraints,
  #                 tol=cfg['OCConstraints']['{tol_sepzero}'],
  #                 options={'maxiter' : 25000, 'disp' : True},
  #                 callback=monitor
  #               )

  #    x0=res.x
  #    sepZeroWeight = res.fun

  #    funcTime  =float(time['tfunc'])
  #    weight=float(cfg ['OCConstraints']['{temporal_weight_limit}'])
  #    sepZeroWeight=weight*funcTime/2e0

    print (" calculate smallest overlap of absolute values (method=SLSQP):")
    iteration=1
    res=minimize(seperateZero, #smallestOverlapSeperateZero, # smallestOverlapSeperatePeaks, #smallestComplxOverlap, # smallestAbsoluteOverlap, # smallestOverlapSeperateZeroPartial, #
                 x0, 
                 method='SLSQP',
                 constraints=minContraints,
                 tol=cfg['OCConstraints']['{tol_classic}'],
                 options={'maxiter' : 25000, 'disp' : True},
                 callback=monitor
               )

    success=res.success
    gamma=getGamma(res.x)

    print ("")    
    print (" current norm(aplhaR) = " +str(sp.linalg.norm(gamma[     :nRead])))
    print (" current norm(aplhaD) = " +str(sp.linalg.norm(gamma[nRead:nDown])))
    print (" current norm(aplhaU) = " +str(sp.linalg.norm(gamma[nDown:nUp  ])))
    print (" current partial Olap = " +str(partialOverlap(res.x)))
#    print (" current hole(value)  = " +str(constraintHoleValue(res.x)))
#    print (" current hole(slope)  = " +str(constraintHoleSlope(res.x)))
#    print (" current hole(value)  = " +str(constraintHoleCurv(res.x)))

   
    varStep+=1

  if (success):
    print ("\ndone with minimization, succeeded:")
  else:
    print ("\ndone with minimization, no success:")

  sp.savetxt(name_vector,sp.array([gamma.real,gamma.conj().imag]).T) 
                             # [real(gamma), imag(gamma)].conj()

  cmd=baseDir+"generateOptimized"
  call(cmd.split())