forked from AER-RC/common
-
Notifications
You must be signed in to change notification settings - Fork 1
/
FortranFile.py
167 lines (134 loc) · 4.78 KB
/
FortranFile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# for Python 3 compatibility
from __future__ import print_function
import struct
import types
class FortranFile:
sizeFormat='I'
def __init__(self,fileName,write=False,network=False):
if write:
self.file=open(fileName,'wb')
else:
self.file=open(fileName,'rb')
self.write=write
if network: self.byteOrder='!'
else: self.byteOrder='='
def writeRecord(self,vector):
pass
def readFloatVector(self):
return self.readRecord('f')
def readDoubleVector(self):
return self.readRecord('d')
def readFormatVector(self,formatString):
return self.readRecord(formatString)
def readFormatData(self,formatString):
record=self.getRecord()
if record:
vectorFmt='%s%s'%(self.byteOrder,formatString)
try:
return struct.unpack(vectorFmt,record)
except:
return None
return None
def getRecord(self):
stringSize = struct.calcsize(self.sizeFormat)
try:
size = struct.unpack(self.sizeFormat, self.file.read(stringSize))[0]
buff = self.file.read(size)
otherSize = struct.unpack(self.sizeFormat, self.file.read(stringSize))[0]
if otherSize != size: return None
return buff
except:
return None
def readRecord(self,id):
record=self.getRecord()
if record:
size=len(record)/struct.calcsize(id)
vectorFmt='%s%0d%s'%(self.byteOrder,size,id)
try:
return struct.unpack(vectorFmt,record)
except:
return None
return None
def reset(self):
self.file.seek(0)
def writeSpecialFormatVector(self,data,formatString,outputSize):
buffer=''
for index,value in enumerate(data):
print(formatString[index],value)
if type(value) in [types.ListType,types.TupleType]:
for x in value: buffer += struct.pack(formatString[index],x)
else:
buffer += struct.pack(formatString[index],value)
for index in range(len(buffer),outputSize):buffer+=struct.pack('b',0)
size = struct.pack(self.sizeFormat,(len(buffer)))
print(len(buffer))
self.file.write(size+buffer+size)
def writeFormatVector(self,data,formatString,outputSize=None):
buffer=b''
for index,value in enumerate(data):
if isinstance(value, (list, tuple)):
# if type(value) in [types.ListType,types.TupleType]:
# buffer += struct.pack(formatString[index] * len(value), *value)
for x in value:
buffer += struct.pack(formatString[index],x)
else:
buffer += struct.pack(formatString[index],value)
if outputSize is not None:
for index in range(len(buffer),outputSize):buffer+=struct.pack('b',0)
size = struct.pack(self.sizeFormat,(len(buffer)))
self.file.write(size+buffer+size)
def writeFloatVector(self,data):
formatString=''
for i in data: formatString+='f'
self.writeFormatVector(data,formatString)
def close(self):
if self.file:
self.file.close()
self.file=None
def __del__(self):
self.close()
def readReflectance(fileName):
fortranFile=FortranFile(fileName)
format='114d2i5d4i10d'
data=fortranFile.readFormatData(format)
#print data
OK=True
length=0
wn1=None
refls=[]
while OK:
try:
v1,v2,dv,nWN=fortranFile.readFormatVector('ddfi')
#print v1,v2,dv,nWN
except:
nWN=-1
if nWN>0:
data=fortranFile.readFloatVector()
refls+=data
if wn1 is None:
wn1=v1
wndv=dv
wn2=v2
else: OK=False
return wn1,wn2,wndv,refls
def writeReflectance(fileName,v1,v2,dv,reflCoeff):
def refl(wn,coeff):
return coeff[0]+coeff[1]*wn+coeff[2]*wn**2
maxWNs=2400
nFillHeader=264
fillHeader=map(lambda x:0.,range(nFillHeader))
fortranFile=FortranFile(fileName,write=True)
fortranFile.writeFloatVector(fillHeader)
nWNs=int(round((v2-v1)/dv)+1)
if nWNs>maxWNs:
dv=(wn2-wn1)/(maxWNs-1)
nWNs=int(round((v2-v1)/dv)+1)
fortranFile.writeFormatVector((v1,v2,dv,nWNs),'ddfi')
refl=map(lambda x:refl(v1+x*dv,reflCoeff),range(nWNs))
fortranFile.writeFloatVector(refl)
fortranFile.writeFormatVector((v2,v2,dv,-99),'ddfi')
fortranFile.close()
if __name__ == '__main__':
fileName='SOL.REFLECTANCE'
wn1,wn2,wndv,data=readReflectance(fileName)
print(wn1,wn2,wndv,len(data),min(data),max(data))