Skip to content
Snippets Groups Projects
Commit c656f00e authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

Most FormFactor classes now delegating parameter registration to INode.

<code>

import edtools, re, sys

nodeList = '''\
FormFactorAnisoPyramid ./Core/HardParticle/FormFactorAnisoPyramid
FormFactorBox ./Core/HardParticle/FormFactorBox
FormFactorCantellatedCube ./Core/HardParticle/FormFactorCantellatedCube
FormFactorCone6 ./Core/HardParticle/FormFactorCone6
FormFactorCone ./Core/HardParticle/FormFactorCone
FormFactorCuboctahedron ./Core/HardParticle/FormFactorCuboctahedron
FormFactorCylinder ./Core/HardParticle/FormFactorCylinder
FormFactorDodecahedron ./Core/HardParticle/FormFactorDodecahedron
FormFactorDot ./Core/HardParticle/FormFactorDot
FormFactorEllipsoidalCylinder ./Core/HardParticle/FormFactorEllipsoidalCylinder
FormFactorFullSphere ./Core/HardParticle/FormFactorFullSphere
FormFactorFullSpheroid ./Core/HardParticle/FormFactorFullSpheroid
FormFactorHollowSphere ./Core/HardParticle/FormFactorHollowSphere
FormFactorGaussSphere ./Core/SoftParticle/FormFactorGauss
FormFactorHemiEllipsoid ./Core/HardParticle/FormFactorHemiEllipsoid
FormFactorIcosahedron ./Core/HardParticle/FormFactorIcosahedron
FormFactorLongBoxGauss ./Core/HardParticle/FormFactorLongBoxGauss
FormFactorLongBoxLorentz ./Core/HardParticle/FormFactorLongBoxLorentz
FormFactorPrism3 ./Core/HardParticle/FormFactorPrism3
FormFactorPrism6 ./Core/HardParticle/FormFactorPrism6
FormFactorPyramid ./Core/HardParticle/FormFactorPyramid
FormFactorSphereGaussianRadius ./Core/SoftParticle/FormFactorSphereGaussianRadius
FormFactorSphereLogNormalRadius ./Core/SoftParticle/FormFactorSphereLogNormalRadius
FormFactorTetrahedron ./Core/HardParticle/FormFactorTetrahedron
FormFactorTriangle ./Core/HardParticle/FormFactorTriangle
FormFactorTruncatedCube ./Core/HardParticle/FormFactorTruncatedCube
FormFactorTruncatedSphere ./Core/HardParticle/FormFactorTruncatedSphere
FormFactorTruncatedSpheroid ./Core/HardParticle/FormFactorTruncatedSpheroid
'''

def get_and_check_ctor_args(t, vars):
    avars = []
    if t!="":
        args = re.split(',\s+', t)
        for a in args:
            mm = re.search(r'double (\w+)( = \S+?)?', a)
            if not mm:
                raise Exception("Unexpected argument '%s' in constructor" % a)
            avars.append(mm.group(1))
    ndiff = len(avars) - len(vars)
    if ndiff<0:
        raise Exception("Not enough constructor args")
    for i in range(len(vars)):
        if avars[ndiff+i] != vars[i]:
            raise Exception("Argument '%s' does not match variable '%s'" %
                            (avars[ndiff+i], vars[i]))
    return avars

def refactor_class(node, fnbase):
    fnc = fnbase+".cpp"
    fnh = fnbase+".h"

    with open(fnh, 'r') as f:
        th = f.read()

    with open(fnc, 'r') as f:
        tc = f.read()

    # class declaration -> find base class
    m = re.search(r'\nclass (BA_CORE_API_ )?%s\s+(final\s+)?:\s+public\s+(\w+)' % node, th)
    if not m:
        raise Exception(node+": base class not found")
    baseClass = m.group(3)

    print("\n"+fnbase+": "+node+" < "+baseClass)

    # find constructor implementation
    ctors = []
    for m in re.finditer(r'^%s::%s(.*?^){(.*?)^}' % (node, node), tc, re.M | re.DOTALL):
        inits = m.group(1)
        if re.search(node, inits):
            continue # it's a delegating c'tor, ignorable for our purpose
        ctors.append(m.group(2))
    if len(ctors)==0:
        raise Exception("Constructor for "+node+" not found in "+fnc)
    if len(ctors)>1:
        raise Exception("Several constructors for "+node+" found in "+fnc)
    blocks = re.split(r';', ctors[0])

    names = []
    vars = []
    units = []
    minis = []
    maxis = []
    cname = '"NamelessClass"'
    for cmd in blocks:
        m = re.search(r'setName\((".*?")\)', cmd)
        if m:
            cname = m.group(1)
            continue
    for cmd in blocks:
        m = re.search(r'registerParameter(.*)', cmd)
        if not m:
            continue
        txt = m.group(1)
        m = re.match(r'\((".*?"), &m_(\w+)\)(\.setUnit\((".*?")\))?(\.set\w+\(.*?\))?$', txt)
        if not m:
            print(node, "-->nonstandard args-->", txt)
            continue
        names.append(m.group(1))
        vars.append(m.group(2))
        units.append(m.group(4) or '""')
        if not m.group(5):
            minis.append("-INF")
            maxis.append("+INF")
        else:
            limits = m.group(5)
            if re.match(r'\.set(Nonnegative|Postive)', limits):
                minis.append("0")
                maxis.append("+INF")
            else:
                mm = re.match(r'.setLimited\((.*?),\s+(.*?)\)', limits)
                minis.append(mm.group(1))
                maxis.append(mm.group(2))
    print(node, "  ", cname, names, vars, units, minis, maxis)

    def ed_h(fn, t):
        ti = t
        # add P-based c'tor
        pattern = r'(\n    %s\(' % node
        pattern += r'((double\s+\w+)?'
        pattern += r'(,\s+double\s+\w+)*)'
        pattern += r'(,\s+bool position_at_center = false)?'
        pattern += r'(,\s+size_t n_samples)?'
        pattern += r'\);\n)'
        m = re.search(pattern, t, re.S)
        if not m:
            raise Exception("Constructor not matched")
        ctor = m.group(1)
        avars = get_and_check_ctor_args(m.group(2), vars)

        arg_pac = edtools.found_or_empty(r', bool position_at_center = false', ctor)
        arg_nsa = ""
        if re.search(r', size_t n_samples', ctor):
            arg_nsa = ', size_t n_samples = 0'
        outpat = r'\n    %s(const std::vector<double> P%s%s);\1' % (node, arg_pac, arg_nsa)
        t = re.sub(pattern, outpat, t, 0, re.S)

        # declare references;
        for var in vars:
            t = re.sub(r'(\n    )(double)( m_%s;)' % var, r'\1const \2&\3', t)
        return t

    edtools.ed_file(ed_h, fnh)

    def ed_c(fn, t):
        # add P-based c'tor
        pattern = r'\n%s::%s\(' % (node, node)
        pattern += r'((.*?)'
        pattern += r'((,\s+bool position_at_center)?'
        pattern += r'(,\s+size_t n_samples)?))'
        pattern += r'\)(.*?)\n({.*?\n})'
        m = re.search(pattern, t, re.S)
        if not m:
            print(pattern)
            raise Exception("c'tor not found in cpp file")
        allargs = m.group(1)
        avars = get_and_check_ctor_args(m.group(2), vars)
        optargs = m.group(3)
        have_pac = (m.group(4) is not None)
        have_nsa = m.group(5) is not None
        block = m.group(7)

        for i in range(len(vars)):
            block = re.sub(r'.*registerPar.*\n', '', block)
        block = re.sub(r'.*setName\(.*\n', '', block)

        # new c'tor with old implementation block
        outpat = r'\n%s::%s(const std::vector<double> P' % (node, node)
        if have_pac:
            outpat += r', bool position_at_center'
        if have_nsa:
            outpat += r', size_t n_samples'
        outpat += r')\n : %s({%s, %s, {' % (baseClass, cname, '"class_tooltip"')
        outpat += ', '.join([r'{%s, %s, %s, %s, %s, 0}' %
                             (names[i], units[i], '"para_tooltip"',
                              minis[i], maxis[i]) for i in range(len(names))])
        outpat += r'}}, P)\n'
        for i in range(len(vars)):
            outpat += r' , m_%s(m_P[%i])\n' % (vars[i], i)
        if have_pac:
            outpat += r' , m_position_at_center(position_at_center)\n'
        if have_nsa:
            outpat += r' , m_n_samples(n_samples)\n'
        outpat += edtools.text2re(block)
        # old c'tor refers to new c'tor
        outpat += r'\n\n%s::%s(' % (node, node)
        outpat += r'%s)\n : %s(std::vector<double>{%s}' % (allargs, node, ', '.join(avars))
        if have_pac:
            outpat += r', position_at_center'
        if have_nsa:
            outpat += r', n_samples'
        outpat += r')\n{}\n'

        t = re.sub(pattern, outpat, t, 0, re.S)

        if not re.search(r'registerPar', t):
            t = re.sub(r'#include "Core/Parametrization/ParameterPool.h"\n', '', t)
            t = re.sub(r'#include "Core/Parametrization/RealParameter.h"\n', '', t)

        return t

    edtools.ed_file(ed_c, fnc)

nsuccess = 0
nfailure = 0
nodeEntries = re.split(r'\n', nodeList.rstrip())
for entry in nodeEntries:
    node, fnbase = re.split(' ', entry)
    try:
        refactor_class(node, fnbase)
        print("SUCCESS "+node)
        nsuccess += 1
    except Exception as e:
        print("FAILURE "+node+": "+str(e))
        nfailure += 1
print("%i/%i class conversions failed" % (nfailure, nsuccess+nfailure))
</code>
parent ad8673c5
No related branches found
No related tags found
No related merge requests found
Showing
with 154 additions and 91 deletions
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment