<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import xml.etree.ElementTree as et
import string
import numpy as np

class FebOpt(object):
    '''
    '''
    def __init__(self,model,mode='log',obj_var=None,obj_var_type=None,obj_var_range=None):
        self.mode = mode
        self.obj_var = obj_var
        self.model = model
        self.newmodel = string.replace(model,'.feb','_opt.feb')
        self.etree = et.parse(self.model)
        self._root = self.etree.getroot()
        if self.mode == 'log':
            dmy = map(int,obj_var_range.split(':'))
            if len(dmy) == 3:
                self.datarange = range(dmy[0],dmy[1],dmy[2])
            elif len(dmy) == 2:
                self.datarange = range(dmy[0],dmy[1])
            elif len(dmy) == 1:
                self.datarange = dmy[0]
            elif len(dmy) &gt; 3:
                print 'obj_var_range must have a len of 2 or 3. Exiting...'
                raise SystemExit
            self.logfile = 'tmp.log'
            for output in self._root.iter('Output'):
                for plotfile in output.findall('plotfile'):
                    output.remove(plotfile)
                dmy = et.SubElement(output,'logfile',file=self.logfile)
                et.SubElement(dmy,obj_var_type,data=obj_var).text = obj_var_range
                self.__indent(output,1)
            for pltlvl in self._root.iter('plot_level'):
                pltlvl.text = 'PLOT_NEVER'

        self.Materials = list(self._root.iter('material'))
        self.MaterialNames = []
        for m in self.Materials:
            try:
                self.MaterialNames.append(m.get('name'))
            except:
                self.MaterialNames.append(m.get('id'))

    def parseLog(self,name=None):
        if name is None:
            fid = open(self.logfile,'rt')
        else:
            fid = open(name,'rt')
        try:
            N = len(self.datarange)
        except:
            N = 1
        line = fid.readline()
        dmy = []
        flag = 1
        while line:
            line = fid.readline()
            if "E R R O R" in line:
                flag = 0
                break
            if 'Time =' in line:
                t = float(line.split('=')[-1])
            if 'Data =' in line:
                for i in xrange(N):
                    line = fid.readline()
                    dmy.append([t]+map(float,line.split(' '))[1:])
        dmy =[[0.0]*len(dmy[0])]+dmy #append zero value to start of list
        fid.close()
        if flag == 1:
            return np.array(dmy)
        else:
            return "ERROR"

    def updateMaterials(self,materials=None):
        '''
        materials - dictionary with structure
            {'material_name': {'constant_tag': constant_value}}
        '''
        for i in materials.keys():
            ind = self.MaterialNames.index(i)
            m = self.Materials[ind]
            for c in materials[i].keys():
                for tag in m.iter(c):
                    if isinstance(materials[i][c],np.ndarray):
                        dmy = materials[i][c].tolist()
                        dmy = map(str,dmy)
                        tag.text = string.join(dmy,',')
                    else:
                        tag.text = str(materials[i][c])

       
    def writeModel(self,name=None):
        if name is None:
            self.etree.write(self.newmodel,encoding='ISO-8859-1')
        else:
            self.etree.write(name,encoding='ISO-8859-1')

    def __indent(self,elem,level):
        i = '\n' + level*'  '
        if len(elem):
            if not elem.text or not elem.text.strip():
                elem.text = i + '  '
                if not elem.tail or not elem.tail.strip():
                    elem.tail = i
                for child in elem:
                    self.__indent(child, level+1)
                if not child.tail or not child.tail.strip():
                    child.tail = i
                if not elem.tail or not elem.tail.strip():
                    elem.tail = i
        else:
            if level and (not elem.tail or not elem.tail.strip()):
                elem.tail = i
    def changeLog(self,name):
        for tag in self._root.iter('logfile'):
            tag.set('file',name)
</pre></body></html>