You are here: Home / Community / Workshops / 2008 - Fribourg / Content / Shakespeare / Effect / bin / interp / ies.py

ies.py

# last updated 29-Jul-2008 -- dmreagan

#import string, glob, os, sys, regex, copy
import string, glob, os, sys, re, copy


#----------------------------------------------------------------------
# helper function that could go anywhere, used mostly with map
def numberToString( x ):
    return '%s' % x


class IES:
    def __init__(self, file = None):
        self.data = {}
        self.readfile(file)
#----------------------------------------------------------------------
    def concat(self, key, value):
        self.data[key] = value
#----------------------------------------------------------------------
    def error(self,  fileId ):
        fileId.close()
        print "Error badly formed file"
        sys.exit(-1)
#----------------------------------------------------------------------
    def maxCandela(self):
        max = 0
        c = self.data['candela']
        for x in c.keys():
            for y in c[x]:
                if (max < eval(y)) :
                    max = eval(y)
        return max
#----------------------------------------------------------------------
    # This is a bit of a misnomer since the max vertical angle is always
    # 90 degrees.  This is the max angle less than 90 degrees
    def maxVertAngle(self):
        angles = self.data['vertAngle']
        length = len(angles)
        return eval(angles[length-2])

#----------------------------------------------------------------------
    # This function returns the angle at a specific percentage of maxcandela
    # ie. beam angle is angleAt(50), field angle is angleAt(10) etc
    def angleAt(self, percent):
        maxCandela = self.maxCandela()
        cd = maxCandela * percent * 0.01
        c = self.data['candela']
        for x in c.keys():
            for i in range(0, len(c[x])):
                if cd >= eval(c[x][i]):
                    t = (cd - eval(c[x][i]))/float(eval(cd[x][i-1]) -
                                                   eval(c[x][i]))
                    angles = self.data['vertAngle']
                    a = eval(angles[i]) + t * (eval(angles[i-1]) -
                                               eval(angles[i]))
                    return a * 2.0
        return -1

#----------------------------------------------------------------------
    def beamAngle(self):
        return self.angleAt(50)

#----------------------------------------------------------------------
    def fieldAngle(self):
        return self.angleAt(10)

#----------------------------------------------------------------------
    def cutoffAngle(self):
        return self.angleAt(0)

#----------------------------------------------------------------------
    # This is a more efficient function for returning all 4 values
    def maxCdBeamFieldCutoff(self):
        beam = field = cutoff = 0
        maxCd = self.maxCandela()
        bcd = maxCd * .5
        fcd = maxCd * .1
        ccd = 0
        angles = self.data['vertAngle']
        c = self.data['candela']
        for x in c.keys():
            for i in range(0, len(c[x])):
                if bcd >= eval(c[x][i]):
                    t = (bcd - eval(c[x][i]))/float(eval(c[x][i-1]) -
                                                   eval(c[x][i]))
                    beam = eval(angles[i]) + t * (eval(angles[i-1]) -
                                                  eval(angles[i])) * 2.0
                    bcd = -1
                if fcd >= eval(c[x][i]):
                    t = (fcd - eval(c[x][i]))/float(eval(c[x][i-1]) -
                                                   eval(c[x][i]))
                    field = eval(angles[i]) + t * (eval(angles[i-1]) -
                                                   eval(angles[i])) * 2.0
                    fcd = -1
                if ccd >= eval(c[x][i]):
                    t = (ccd - eval(c[x][i]))/float(eval(c[x][i-1]) -
                                                    eval(c[x][i]))
                    cutoff = eval(angles[i]) + t * (eval(angles[i-1]) -
                                                    eval(angles[i])) * 2.0
                    ccd = -1
        return [ maxCd, beam, field, cutoff]
#----------------------------------------------------------------------
    # This function places a vertical angle at one degree increments 
    # from 0 to maxAngle

    # Change to allow degree resolution with default of one.

    def changeToOneDegree(self, maxAngle):
        angleList = range(0, maxAngle + 1)
        aList = map(eval, self.data['vertAngle'])
        for x in self.data['horzAngle']:
            candelaList = map(eval, self.data['candela'][x])
            c1 = 0
            c2 = 1
            cList = []
            cList.append(numberToString(candelaList[0]))
            for y in angleList[1:]:
                if ( y > aList[c2]):
                    c1 = c1 + 1
                    c2 = c2 + 1
                # get scalar multiple for linear interpolation
                t = (y - aList[c1])/float(aList[c2] - aList[c1])
                # use t to compute the corresponding candela value for 
                #    angle y
                cList.append('%d' % (candelaList[c1] +
                              t * (candelaList[c2] - candelaList[c1])))

            cList.append('%d' % (candelaList[len(candelaList) - 1]))

            # We have to make a copy otherwise Python just sets a pointer
            self.data['candela'][x] = copy.copy(cList)
            del candelaList
            del cList
        angleList.append('90')
        self.data['vertAngle'] = map(numberToString, copy.copy(angleList))
        self.data['vAngles'] = '%d' % len(angleList)
        del aList
        del angleList
#----------------------------------------------------------------------
    def readfile(self, file='stdin' ):
        if file == None: return
        if (file == 'stdin'):
            f = sys.stdin
        else:
            f = open(file, 'r')

        lines = f.readlines()
        i = 0
        # remove any blank lines from lines
        while i < len(lines):
            line = lines[i]
            if len(string.split(line)) == 0:
                del lines[i]
            i = i + 1

        i = 0
        self.concat('head', {})

        while i < len(lines):
            line = lines[i]
        #tilt = regex.match("TILT", line)
            tilt = re.match("TILT", line)
        #xy = regex.match("<position>", line)
            xy = re.match("<position>", line)
            if xy >= 0:
                self.data['head']['position'] = line
                i = i + 1
            elif tilt == -1 :
                self.data['head'][i] = line
                i = i + 1
                continue
            else:
                self.concat('tilt', line)
                i = i + 1
                break

        line = lines[i]
        l = string.split(line)
        i = i + 1

        if len(l) != 10:
            self.error( f )
        else:
            self.concat('nlamps', l[0])
            self.concat('lpm', l[1])
            self.concat('mult', l[2])
            self.concat('vAngles', l[3])
            self.concat('hAngles', l[4])
            self.concat('photoType', l[5])
            self.concat('unitsType', l[6])
            self.concat('oWidth', l[7])
            self.concat('oLength', l[8])
            self.concat('oHeight', l[9])

        line = lines[i]
        l = string.split(line)
        i = i + 1

        if len(l) != 3:
            self.error( f )
        else:
            self.concat('ballast', l[0])
            self.concat('reserved', l[1])
            self.concat('watts', l[2])

        self.concat('vertAngle', string.split(lines[i]))
        self.concat('horzAngle', string.split(lines[i+1]))
        self.concat('candela', {})
        i = i + 2
        for x in self.data['horzAngle']:
            if i >= len(lines):
                self.error(f)
            self.data['candela'][x] = string.split(lines[i])
            i = i + 1

        if( file != 'stdin'):
            f.close()
#----------------------------------------------------------------------
    def writefile(self, output='stdout'):
        if(output == 'stdout'):
            f = sys.stdout
        else:
            f = open(output, 'w+')
            for x in self.data['head'].keys():
                str = self.data['head'][x]
        #pat = regex.compile("degree")
                pat = re.compile("degree")
                index = pat.search(str)
                if index >= 0:
                    a,b = pat.regs[0]
            #i = regex.search(".ies",output)
                    i = re.search(".ies",output)
                    if i >= 0:
                        self.data['head'][x] = output[0: i] + ' ' + str[a:]

        h = self.data['head']
        l = h.keys()
        l.sort()
        for x in l:
            f.write( h[x])

        f.write('\n')
        f.write(self.data['tilt'] + '\n')
        f.write(self.data['nlamps'] + ' ' + self.data['lpm'] + ' ' +
                self.data['mult'] + ' ' + self.data['vAngles'] + ' ' +
                self.data['hAngles'] + ' ' + self.data['photoType'] + ' ' +
                self.data['unitsType'] + ' ' + self.data['oWidth'] + ' ' +
                self.data['oLength'] + ' ' + self.data['oHeight'] + '\n'*2 )

        f.write(self.data['ballast'] + ' ' +
                self.data['reserved'] + ' ' +
                self.data['watts'] + '\n'*2 )

        f.write(string.join(self.data['vertAngle']) + '\n' )
        f.write(string.join(self.data['horzAngle']) + '\n' )
        for x in self.data['horzAngle']:
            f.write(string.join(self.data['candela'][x]) + '\n' )

        if(output != 'stdout'):
            f.close()

#----------------------------------------------------------------------     
    def __repr__(self):  return '<Set:' + `self.data` + '>'
#----------------------------------------------------------------------
    def __getitem__(self, key):
        return self.data.keys()[key]
#----------------------------------------------------------------------
    def __len__(self): return(len(self.data))
by AMcneil last modified Feb 29, 2016 12:25 PM