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