Skip to content

Commit 345ed3e

Browse files
author
Ali Basden
committed
debugging, adding features
1 parent 5f17567 commit 345ed3e

File tree

9 files changed

+185
-11
lines changed

9 files changed

+185
-11
lines changed

README_mac

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
Instructions for installing DASP (the Durham AO Simulation Platform) onto Mac OS X using MacPorts
2+
3+
4+
Date: 2013/11/05 (NAB), 2013/12/09 (NAB,ZG,DH)
5+
6+
Tested: 10.5.8 and 10.7.5 and 10.9.??
7+
8+
Authors: Angela Cortés, Nazim Bharmal, and Alastair Basden
9+
10+
11+
There are three options for using DASP on a computer that runs the Mac OS X OS.
12+
13+
14+
The easiest approach is to run DASP from a virtual machine using VirtualBox---see NAB for a copy of the VDI.
15+
It is possible (and has been done) to install all packages by hand into an existing Python installation. In some ways this can be better, but it took ~12 hours and required editing packages to ensure correct installation.
16+
Install all the pre-requisites that DASP requires for installation using MacPorts as a package manager. Note that this will install a version of DASP that isn't MPI-compatible as well as potentially another copy of Python and all its associated packages.
17+
18+
All commands to be entered at the command line are indented. Their output is also indented but only if it is important. Below are the commands for using MacPorts. First install that piece of software and ensure it can compile. Then update the packages and install Python, Numpy, and Scipy:
19+
20+
21+
sudo port selfupdate
22+
23+
sudo port install py27-numpy py27-scipy
24+
25+
26+
Check that the Python interpreter,
27+
28+
29+
python -c 'import sys ; print(sys.executable)'
30+
31+
/opt/local/bin/python
32+
33+
34+
is installed in a different directory from the system Python interpreter. This does mean you are installing another copy of Python onto your computer but the package dependencies are handled by MacPorts.
35+
36+
37+
If the line above doesn't begin with '/opt/local' then it is probable you have called the system Python interpreter. Try using 'python2.7' instead for all commands below. This would also imply changing the Makefiles in DASP.
38+
39+
40+
Now continue by installing ATLAS (optional)
41+
42+
43+
sudo port install atlas
44+
45+
46+
which if it fails is OK. Then install FFTW,
47+
48+
49+
sudo port install fftw-3-long fftw-3-single
50+
51+
52+
and then PyScientific and GNU Scientific Library plus the Python bindings,
53+
54+
55+
sudo port install py-scientific py27-gsl
56+
57+
58+
Finally we add GTK2, and the Python bindings together with the correct back-end for Matplotlib,
59+
60+
sudo port install gtk2 py-pygtk
61+
62+
sudo port install py27-matplotlib +gtk2
63+
64+
65+
Note that most installs were using the 'py' prefix but for GSL and matplotlib, it was necessary to use 'py27'.
66+
67+
(The software installed can also be summarized as: Python, ATLAS (LAPACK and BLAS), complete FFTW3, GTK and PyGTK, scipy, Scientific Python, GNU Scientific Library and the Python binding, matplotlib with the GTK backend.)
68+
69+
70+
mkdir DASP
71+
72+
cd DASP
73+
74+
git clone gitaosim@elise.cfai.dur.ac.uk:/home/gitaosim/aosim.git
75+
76+
77+
Note to access the GIT repository on elise, you will have to ask Alastair Basden for the password to the gitaosim user account.
78+
79+
80+
cd aosim
81+
82+
83+
Now you will attempt a compilation which will succeed iff the include directories in the makefiles include,
84+
85+
86+
/opt/local/include
87+
88+
89+
so if the following command fails,
90+
91+
92+
make -s
93+
94+
95+
then I would suggest checking the include directories first. A key file that could need adjusting is,
96+
97+
98+
aosim/cmod/src/Makefile.Darwin
99+
100+
101+
Once compilation is complete, follow the final instruction which will be similar to
102+
103+
104+
Remember to export PYTHONPATH=$PYTHONPATH:/Users/nab/sauce/aosim/working and add gui/bin to your path (export PATH=$PATH:/Users/nab/sauce/aosim/working/gui/bin ).
105+
106+
107+
where '/Users/nab/sauce/aosim/working' is replaced by the directory where aosim is installed. To test correct installation, type
108+
109+
110+
simctrl.py &
111+
112+
113+
to bring up the DASP control GUI. For further instructions and simulation examples, contact anyone using DASP. Obvious contacts are,
114+
115+
116+
Ali Bharmal for Mac OS X/Darwin questions
117+
118+
n.a.bharmal@dur.ac.uk
119+
120+
Alastair Basden for DASP questions
121+
122+
a.g.basden@dur.ac.uk

base/readConfig.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ def end_element(self,name):
349349
print sys.exc_value
350350
v=None
351351
self.error=1
352+
raise
352353
if hasattr(self.this,self.curmodule):
353354
if hasattr(getattr(self.this,self.curmodule),attrs["name"]):
354355
if bInfo==1:#overwrite prev value
@@ -510,7 +511,7 @@ def setSearchOrder(self,searchOrder):
510511
@type searchOrder: List
511512
"""
512513
self.searchOrder=searchOrder
513-
def getVal(self,varname,default=None,searchOrder=None,raiseerror=1):
514+
def getVal(self,varname,default=None,searchOrder=None,raiseerror=1,warn=1):
514515
"""Return the value of a variable stored in the XML file.
515516
This would be used e.g. myvar=x.getVal("myvar") where x is the
516517
instance of AOXml (self). A default value can be given. If no default
@@ -549,7 +550,8 @@ def getVal(self,varname,default=None,searchOrder=None,raiseerror=1):
549550
print "ERROR: value not found %s"%str(varname)
550551
raise Exception("ERROR: value not found: %s %s"%(str(varname),str(searchOrder)))
551552
else:
552-
print "WARNING: using default value of %s for %s %s"%(str(val),str(varname),str(searchOrder))
553+
if warn:
554+
print "WARNING: using default value of %s for %s %s"%(str(val),str(varname),str(searchOrder))
553555
return val
554556

555557
def setVal(self,varname,value,searchOrder=None,raiseerror=1):

base/saveOutput.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def generateNext(self,msg=None):
166166
newdim=int(key[10:])+1
167167
util.FITS.WriteKey(self.ff,"NAXIS%d"%self.nd,str(newdim))
168168
else:
169-
print "saveOutput: waiting for data but not valid (debug=%s)"%debug
169+
print "saveOutput: waiting for data but not valid (debug=%s)"%self.debug
170170
self.dataValid=0
171171
else:
172172
self.dataValid=0

base/splitOutput.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import types
33
import base.fwdMsg
44
#import Numeric
5-
#import numpy
5+
import numpy
66
import cmod.utils
77
import base.aobase
88
class splitOutput(base.aobase.aobase):
@@ -43,7 +43,7 @@ def __init__(self,parent,config,args={},forGUISetup=0,debug=None,idstr=None):
4343
#Code must be python code that extracts part of an array from parentData, and writes it to outputData, e.g. "outputData=parentData[0:10]". This can be as complex as you like.
4444
self.outputData=None
4545
self.compiledCode=compile(self.code,"<string>","exec")
46-
self.shape=None
46+
self.shape=config.getVal("splitOutputShape",raiseerror=0)
4747
self.dtype=None
4848
self.feedback=0#not a feedback object by default...
4949
self.forGUISetup=forGUISetup
@@ -86,7 +86,7 @@ def finalInitialisation(self):
8686
if self.initialised==0:
8787
dtype=None
8888
if self.shape=="fromparent":#attempt to get shape from parent (could be dangerous if parent not yet created properly).
89-
d={"parentData":self.parent.outputData,"outputData":self.outputData,"parent":self.parent}
89+
d={"parentData":self.parent.outputData,"outputData":self.outputData,"parent":self.parent,"numpy":numpy,"config":self.config}
9090
exec self.compiledCode in d
9191
self.shape=d["outputData"].shape
9292
print "splitOutput got shape of %s from parent (code=%s)"%(self.shape,self.code)
@@ -138,7 +138,7 @@ def generateNext(self,msg=None):
138138
if self.newDataWaiting:
139139
if self.parent.dataValid==1:
140140
self.dataValid=1
141-
d={"parentData":self.parent.outputData,"outputData":self.outputData,"parent":self.parent}
141+
d={"parentData":self.parent.outputData,"outputData":self.outputData,"parent":self.parent,"config":self.config,"numpy":numpy}
142142
exec self.compiledCode in d
143143
outputData=d["outputData"]
144144
if outputData.shape!=self.shape:
@@ -160,7 +160,7 @@ def generateNext(self,msg=None):
160160

161161
## self.outputData=cmod.utils.arrayFromArray(self.parent.outputData[self.startOffset:self.endOffset],self.shape,self.dtype)
162162
else:
163-
print "splitOutput: waiting for data but not valid (debug=%s)"%debug
163+
print "splitOutput: waiting for data but not valid (debug=%s)"%self.debug
164164
self.dataValid=0
165165
else:
166166
self.dataValid=0

util/Ctrl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def __init__(self,globals=None,paramfile=[],debug=None):
167167
self.config.this.simID=self.simID
168168
self.sockConn=util.SockConn.SockConn(self.config.getVal("testrunport",default=9000)+self.rank,globals=self.globals,startThread=1,listenSTDIN=self.listenSTDIN)
169169
os.nice(self.config.getVal("nice",default=nice))
170-
if self.config.getVal("connectPortDict",default=1):
170+
if self.config.getVal("connectPortDict",default=0,warn=0):
171171
try:
172172
t=threading.Thread(target=self.connectPortDict)
173173
t.daemon=True

util/FITS.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ def ReadHeader(filename, asFloat = 1) :
227227
buffer = file.read(2880)
228228
return( { 'raw' : rawHeader, 'parsed' : header} )
229229

230-
def MakeHeader(shape,dtype,extraHeader=None,doByteSwap=1,extension=0):
230+
def MakeHeader(shape,dtype,extraHeader=None,doByteSwap=1,extension=0,splitExtraHeader=0):
231231
"""Return a text string which can be used as a header"""
232232
if dtype=="b": bitpix=8
233233
elif dtype=="B": bitpix=8
@@ -265,6 +265,10 @@ def MakeHeader(shape,dtype,extraHeader=None,doByteSwap=1,extension=0):
265265
key != 'BITPIX' and \
266266
key[:5] != 'NAXIS' and \
267267
key != 'END' :
268+
if splitExtraHeader:
269+
while len(rec)>80:
270+
header.append(rec[:80])
271+
rec=string.ljust(key,8)+"= "+rec[80:]
268272
header.append(rec)
269273
header.append('END')
270274
header = map(lambda x: string.ljust(x,80)[:80], header)

util/computeRecon.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""
88
import util.FITS,numpy
99
import sys,time,os
10+
import util.gradientOperator
1011
#import util.dot as quick
1112
#sys.path.insert(0,"/home/ali/c/lapack")
1213
#import svd
@@ -30,6 +31,24 @@
3031

3132
import cmod.svd,scipy.sparse
3233

34+
def keyboard(banner=None):
35+
"""A class that allows us to break to python console on exception."""
36+
import code, sys
37+
38+
# use exception trick to pick up the current frame
39+
try:
40+
raise None
41+
except:
42+
frame = sys.exc_info()[2].tb_frame.f_back
43+
44+
# evaluate commands in current namespace
45+
namespace = frame.f_globals.copy()
46+
namespace.update(frame.f_locals)
47+
48+
code.interact(banner=banner, local=namespace)
49+
50+
51+
3352
class sparseHolder:
3453
def __init__(self):
3554
self.data=None
@@ -54,6 +73,12 @@ def __init__(self,pmxfname,rcond=0.1,regularisation=0.):
5473
self.timename=pmxfname[:-5]+"_timing.txt"
5574
self.cntname=pmxfname[:-5]+"_cnt.txt"
5675
self.regularisation=regularisation
76+
77+
def initFromParams(paramList=["params.xml"],batchno=0):
78+
import base.readConfig
79+
self.c=base.readConfig.AOXml(paramList,batchno=batchno)
80+
c=self.c
81+
5782
def log(self,txt):
5883
f=open(self.timename,"a")
5984
f.write(txt)

util/dm.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@
88
import util.dot as quick
99
import time
1010

11+
12+
def calcNactList(config,batchno,reconidstr):
13+
if type(config) in [type([]),type("")]:
14+
import base.readConfig
15+
config=base.readConfig.AOXml(config,batchno=batchno)
16+
config.setSearchOrder(["tomoRecon_%s"%reconidstr,"tomoRecon","globals"])
17+
dmObj=config.getVal("dmObj")
18+
pupil=config.getVal("pupil")
19+
atmosGeom=config.getVal("atmosGeom")
20+
dmList=dmObj.makeDMList(reconidstr)
21+
nacts=0
22+
nactsList=[]
23+
for dm in dmList:
24+
if dm.zonalDM:
25+
tmp=dm.computeDMPupil(atmosGeom,centObscuration=pupil.r2,retPupil=0)
26+
nactsList.append(int(tmp[0].sum()))
27+
else:#modal DM
28+
nactsList.append(dm.nact)
29+
return nactsList
1130
"""Contains:
1231
dmInfo class - info about a given DM
1332
dmOverview class - overview of all DMs in a system

util/sci.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -992,16 +992,18 @@ def doScienceCalc(self,inputData,control,curtime=0):
992992
if self.luckyCnt==0:
993993
if self.luckyImg==None:
994994
self.luckyImg=numpy.empty((self.nimg,self.nimg),self.fpDataType)
995-
995+
self.luckyRms=self.phaseRMS
996996
self.luckyImg[:]=self.instImg
997997
else:
998+
self.luckyRms+=self.phaseRMS
998999
self.luckyImg+=self.instImg
9991000
self.luckyCnt+=1
10001001
if self.luckyCnt>=self.luckyNSampFrames:
10011002
self.luckyCnt=0
10021003
#Now do the lucky calculations.
10031004
self.luckyImg/=self.luckyImg.sum()#normalise it
10041005
self.computeScientificParameters(self.luckyImg,self.luckyDict)
1006+
self.luckyDict["rms"]=self.luckyRms/self.luckyNSampFrames#the mean RMS phase that went into this image.
10051007
if self.luckyHistory==None:
10061008
self.luckyHistoryKeys=self.luckyDict.keys()
10071009
self.luckyHistory=numpy.zeros((len(self.luckyHistoryKeys),self.luckyHistorySize),numpy.float32)

0 commit comments

Comments
 (0)