def shutter(self, w, a=None): if a == "off": print "Shutter off" sendCmd("shutter off", self.prefix, self.cam) sendCmd("shutter blockonread 0", self.prefix, self.cam) d = darc.Control(self.prefix) d.Set("ocamShutter", 0) #for reference only elif a == "external": sendCmd("shutter external", self.prefix, self.cam) sendCmd("shutter on", self.prefix, cam) d = darc.Control(self.prefix) d.Set("ocamShutter", 1) #reference only else: lfreq = float(a[0].get_text()) opentime = float(a[1].get_text()) delay = float(a[2].get_text()) fps = int(a[3].get_text()) print lfreq, opentime, delay, fps prepareShutter(lfreq, opentime, delay, fps, prefix=self.prefix, cam=self.cam) d = darc.Control(self.prefix) #and for reference (only)... d.Set("ocamShutter", numpy.array([lfreq, opentime, delay, fps]).astype("f"))
def main(ip="192.168.1.1", ipiport="192.168.1.10", prefix="main", cam=4): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((ip, 0)) port = sock.getsockname()[1] print "Bound on port %d. Sending initial data" % port initdata = numpy.array([ 0x42, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00 ]).astype(numpy.uint8) sock.sendto(initdata, (ipiport, 4)) d = darc.Control(prefix) ipdata = numpy.zeros((4, ), numpy.uint8) ipdata[:] = map(int, ip.split(".")) ipstr = hex(ipdata.view(numpy.uint32).byteswap()[0]) if ipstr[-1] == "L": ipstr = ipstr[:-1] d.Set( "aravisCmd%d" % cam, "R[0xb14]=0x190;R[0xb18]=0x3;R[0xb10]=%s;R[0xb00]=%d;R[0x20017800]=0x0;R[0x20017814]=0x6;R[0x2001781c]=0x0;R[0x20017818]=0x0;R[0x20017830]=0x0;R[0x16000]=0x1;" % (ipstr, port)) vhex = numpy.vectorize(hex) while 1: data, addr = sock.recvfrom(1024) print "Got data %s from %s" % (str(data), str(addr)) print vhex(numpy.fromstring(data, dtype=numpy.uint8)) print data[28:] if addr[0] == ipiport and addr[1] == 4: data = numpy.fromstring(data, dtype=numpy.uint8) packet = numpy.zeros((8, ), numpy.uint8) packet[3] = 0xc3 packet[6:8] = data[6:8] sock.sendto(packet, (ipiport, 4)) print "Sent response:", packet print vhex(packet)
def setValue(self, e, txt, final=0): if final == 1: #return pressed indx = self.widgets.body.index(self.SetButton) name = self.widgets.body[indx + 1].get_edit_text() value = self.widgets.body[indx + 2].get_edit_text() w = self.widgets.body[indx + 3] try: d = darc.Control(self.prefix) err = d.Set(name, eval(value)) except: txt = traceback.format_exc() else: if len(err) == 0: txt = "Set %s" % name else: txt = "Error setting %s" % name w = self.widgets.body[indx + 3] if type(w) == urwid.Button: w = urwid.Text(txt) self.widgets.body.insert(indx + 3, w) else: w.set_text(txt) elif final == 2: #escape pressed: indx = self.widgets.body.index(self.SetButton) self.widgets.set_focus(indx)
def getSumSplitBin(self, w=None, a=None): d = darc.Control(self.prefix) lst = d.GetSummerList() print lst lst.sort() self.ls.clear() for s in lst: self.ls.append([s]) self.tv.show_all() lst = d.GetSplitterList() print lst lst.sort() self.lss.clear() for s in lst: self.lss.append([s]) self.tvs.show_all() lst = d.GetBinnerList() print lst lst.sort() self.lsb.clear() for s in lst: self.lsb.append([s]) self.tvb.show_all() return False
def pokeAll(self, pokevalList, nAv=10, setInDarc=0, cond=0.01, scale=None, delay=0): """Very simple, does a global least squares fit to produce control matrix, if required. If scale==1, will scale poke matrix and rmx by pokevalList.""" ndm = len(self.nactList) d = darc.Control(self.prefix) pmx = d.Get("rmx") offset = 0 for i in range(ndm): nact = self.nactList[i] dmpmx = self.pokeSimple(i, pokevalList[i], nAv=nAv, delay=delay) pmx[offset:offset + nact] = dmpmx offset += nact if setInDarc: if scale == 0: scale = None if scale != None: scale = pokevalList rmx = self.reconstruct(pmx, cond, scale=scale) d.Set("rmx", rmx) return pmx
def getChanged(self, e, txt=None, final=0): if final == 1: #user has pressed return... try: d = darc.Control(self.prefix) if len(txt) == 0: labels = d.GetLabels() labels.sort() txt = "" for l in labels: data = d.Get(l) txt += l + ": " if type(data) == numpy.ndarray and data.size > 100: txt += "Array dtype %s shape %s\n" % ( data.dtype.char, data.shape) else: txt += str(data) + "\n" else: print txt else: txt = str(d.Get(txt)) except: txt = traceback.format_exc() lab = urwid.Text(txt) indx = self.widgets.body.index(self.GetButton) + 2 self.widgets.body.insert(indx, lab) elif final == 2: indx = self.widgets.body.index(e) while type(self.widgets.body[indx]) != urwid.Button: self.widgets.body.remove(self.widgets.body[indx])
def removeBinner(self, w, a=None): m = self.tvb.get_model() c = self.tvb.get_cursor() txt = m[c[0]][0] print "Removing", txt d = darc.Control(self.prefix) d.StopBinner(txt) self.getSumSplitBin()
def pokeSimple(self, dmNo, pokeval, actNos=None, nAv=10, setInDarc=0, cond=0.01, delay=0): """ Performs a basic push-pull poke. More complications could poke patterns of actuators, e.g.a Hadamard matrix, sinusoids, etc. Inefficient implementation - in a real system, you probably want to set actuators to a 2D array, with dimensions X,nacts. Darc will then play this sequence, repeating when it gets to the end. You can then record a sequence of slopes.""" print "Assuming system is in calibration mode (light sources etc) with valid reference slopes. actuators should be set to mid-range." print "Assuming response of system is fast enough that no delay is required between poking and recording slopes. Note - in simulation, this may not be the case" d = darc.Control(self.prefix) nslopes = d.Get("subapFlag").sum() * 2 nacts = self.nactList[dmNo] pmx = numpy.zeros((nacts, nslopes), numpy.float32) d.Set("addActuators", 0) actuators = d.Get("actuators") offset = sum(self.nactList[:dmNo]) if actNos is None: actNos = range(nacts) # all actuators for i in range(nacts): if not i in actNos: continue print "Poking %d/%d" % (i, nacts) #push actuators[i + offset] += pokeval d.Set("actuators", actuators) #record if delay != 0: time.sleep(delay) sl = d.SumData("rtcCentBuf", nAv)[0] / nAv / pokeval #pull actuators[i + offset] -= 2 * pokeval d.Set("actuators", actuators) #record if delay != 0: time.sleep(delay) sl2 = d.SumData("rtcCentBuf", nAv)[0] / nAv / pokeval #reset actuators[i + offset] += pokeval #store pmx[i] = (sl - sl2) / 2. d.Set("actuators", actuators) if setInDarc: rmx = self.reconstruct(pmx, cond) fullrmx = d.Get("rmx") fullrmx[offset:offset + nacts] = rmx print "Setting rmx in darc" d.Set("rmx", fullrmx) return pmx
def endSim(self): if not self.useExistingDarc: print "Stopping darc %s" % self.prefix try: self.ctrl = darc.Control(self.prefix) if self.ctrl != None: self.ctrl.ControlHalt() self.ctrl = None except: print "Unable to halt darc %s" % self.prefix traceback.print_exc()
def takeRefSlopes(self, nAv=10, setInDarc=0): d = darc.Control(self.prefix) ref = d.Get("refCentroids") d.Set("refCentroids", None) time.sleep(1) sl = d.SumData("rtcCentBuf", nAv)[0] / nAv if setInDarc: d.Set("refCentroids", sl) else: #reset back to what they were. d.Set("refCentroids", ref) return sl
def addSummer(self, w, a=None): s = self.entryStream.get_text() n = int(self.entryNframes.get_text()) f = self.entryDatatype.get_text() h = int(self.checkbuttonHead.get_active()) r = int(self.checkbuttonRolling.get_active()) ns = int(self.entryNstore.get_text()) print "adding", s, n, f, h, r, ns d = darc.Control(self.prefix) d.StartSummer(s, n, fromHead=h, rolling=r, dtype=f, nstore=ns) self.getSumSplitBin()
def setNuma(): """Without subapAllocation... whole rmx on each numa node""" d = darc.Control() nthr = d.Get("ncamThreads").sum() nnodes = numa.get_max_node() + 1 #specify which numa nodes the threads are closest to: threadToNuma = numpy.zeros(nthr, numpy.int32) #all node 0 for now...! rmx = d.Get("gainReconmxT") d.Set("threadToNuma", threadToNuma) for i in range(nnodes): d.SetNuma("gainReconmxT%d" % i, rmx, i)
def __init__(self, nactList=None, prefix=""): """nactList: List of number of actuators of each DM. prefix: darc prefix """ if nactList is None: d = darc.Control(prefix) nactList = [d.Get("nacts")] print "Assuming 1 DM" if type(nactList) == type(0): nactList = [nactList] print "Assuming 1 DM" self.nactList = nactList self.prefix = prefix
def measureLatency(self, actno, amp, nsteps, nrecord): d = darc.Control(self.prefix) acts = d.Get("actuators") acts2 = numpy.zeros((nsteps, acts.size), numpy.float32) acts2[:] = acts.ravel() acts2[:, actno] += amp * numpy.sin( numpy.arange(nsteps) / float(nsteps) * 2 * numpy.pi) d.Set("actuators", acts2) data = d.GetStreamBlock(["rtcCentBuf", "rtcActuatorBuf"], nrecord, asArray=1) d.Set("actuators", acts) return data
def getStatus(self): try: d = darc.Control(self.prefix) txt = d.GetStream("rtcStatusBuf")[0].tostring().strip("\0") except: txt = traceback.format_exc() indx = self.widgets.body.index(self.StatusButton) + 1 if type(self.widgets.body[indx]) == SelText: self.widgets.body[indx].set_caption(txt) else: si = SelText(txt, "") si.connect("change", self.removeStatus) self.widgets.body.insert(indx, si)
def measureLinearity(self,actno,actmin,actmax,nsteps=50,nAv=1,delay=0.5): d=darc.Control(self.prefix) actuators=d.Get("actuators") nslopes=d.Get("subapFlag").sum()*2 orig=actuators[actno] step=(actmax-actmin)/nsteps res=numpy.zeros((nsteps,nslopes),numpy.float32) for i in range(nsteps): actuators[actno]=actmin+i*step d.Set("actuators",actuators) if delay!=0: time.sleep(delay) sl=d.SumData("rtcCentBuf",nAv)[0]/nAv res[i]=sl actuators[actno]=orig d.Set("actuators",actuators) return res,numpy.arange(nsteps)*step+actmin
def addSplitter(self, w, a=None): stream = self.entrySplitStream.get_text() s = int(self.entrySplitStart.get_text()) e = int(self.entrySplitEnd.get_text()) step = int(self.entrySplitStep.get_text()) block = int(self.entrySplitBlock.get_text()) h = int(self.checkbuttonSplitHead.get_active()) ns = int(self.entrySplitNstore.get_text()) print "adding", stream, s, e, step, block, h, ns d = darc.Control(self.prefix) name = d.StartSplitter(stream, s, e, step, block, fromHead=h, nstore=ns) self.getSumSplitBin()
def setNuma2(): """With subapAllocation: partial rmx on each numa node""" d = darc.Control() nthr = d.Get("ncamThreads").sum() nnodes = numa.get_max_node() + 1 #specify which numa nodes the threads are closest to: threadToNuma = numpy.zeros(nthr, numpy.int32) #all node 0 for now...! sf = d.Get("subapFlag") nsub = sf.size sa = numpy.zeros(nsub, numpy.int32) #divide all threads equally... sa[:] = nthr - 1 start = 0 for i in range(nthr): end = start + nsub / nthr sa[start:end] = i start = end print numpy.reshape(sa, (7, 7)) print numpy.reshape(sf, (7, 7)) d.Set("threadToNuma", threadToNuma, swap=1) rmx = d.Get("gainReconmxT") #nslope,nact thrSubapCnt = numpy.zeros(nthr, numpy.int32) rmxPart = [] for i in range(nthr): rmxPart.append([]) indx = 0 for i in range(nsub): if sf[i]: thrSubapCnt[sa[i]] += 1 rmxPart[sa[i]].append(rmx[indx]) rmxPart[sa[i]].append(rmx[indx + 1]) indx += 2 for i in range(nthr): r = numpy.array(rmxPart[i]) print "Thread %d rmx shape %s, dtype %s" % (i, str(r.shape), r.dtype) d.SetNuma("gainReconmxT%d" % i, r, int(threadToNuma[i]), swap=1) d.Set("subapAllocation", sa, swap=1)
def sendCmd(cmd, prefix="", cam=0): """Sends a cameralink serial command through an iport device, using the darc interface. Packet format is: 4 bytes 0 4 bytes for number of characters following The characters Padding up to 4 bytes""" print "%s (cam %d)" % (cmd, cam) d = darc.Control(prefix) if cmd[-2:] != "\r\n": cmd = cmd + "\r\n" l = len(cmd) a = numpy.zeros((4 + (l + 3) // 4, ), numpy.uint32) a[0] = cam a[1] = 0x40058000 #the address a[2] = 0 a[3] = l a[3] = a[3].byteswap() cmd += "\0" * ((4 - l % 4) % 4) a[4:] = numpy.fromstring(cmd, dtype=numpy.uint32) for i in a: print hex(i) d.Set("aravisMem", a.view(numpy.int32))
def addBinner(self, w, a=None): stream = self.entryBinStream.get_text() s = int(self.entryBinStart.get_text()) e = int(self.entryBinEnd.get_text()) x = int(self.entryBinX.get_text()) y = int(self.entryBinY.get_text()) dt = (self.entryBinDtype.get_text()) stride = int(self.entryBinStride.get_text()) h = int(self.checkbuttonSplitHead.get_active()) ns = int(self.entrySplitNstore.get_text()) print "adding", stream, x, y, dt, s, e, stride, h, ns d = darc.Control(self.prefix) name = d.StartBinner(stream, x, y, s, e, stride, dt, fromHead=h, nstore=ns) self.getSumSplitBin()
def getTelemetry(self): indx = self.widgets.body.index(self.TelemetryButton) + 1 if type(self.widgets.body[indx]) == urwid.Button: #get telemetry... dec = None txt = "" try: d = darc.Control(self.prefix) dec = d.GetDecimation() except: txt = traceback.format_exc() if dec == None: t = urwid.Text(txt) self.widgets.body.insert(indx, t) else: plist = [] for i in range(3): plist.append(urwid.Pile([])) cols = urwid.Columns(plist, 1) else: #finish telemetry while type(self.widgets.body[indx]) != urwid.Button: self.widgets.body.remove(self.widgets.body[indx])
def openLoop(self, prefix=""): d = darc.Control(prefix) d.Set("addActuators", 0)
#Currently works with configScao80Numa.py, started with: #darccontrol configScao80Numa.py -o -b 512*1024*1024 -N 512*1024*1024 import sys import numpy import numa import darc def setNuma(case="gig57"): """With subapAllocation: partial rmx on each numa node""" d = darc.Control() nthr = d.Get("ncamThreads").sum() nnodes = numa.get_max_node() + 1 #specify which numa nodes the threads are closest to: threadToNuma = numpy.zeros(nthr, numpy.int32) #all node 0 for now...! #Use numactl --hardware to get some of this information... however, note this isn't foolproof, e.g. for the Xeon Phi and other systems with specialised memory. #Also assumes that the threadAffinity in the config file is set to correspond to this as well. #gig57: if case == "gig57": if nthr != 16: raise Exception("Expecting 16 threads") threadToNuma[:8] = 0 threadToNuma[8:] = 1 elif case == "EPYC": if nthr != 32: raise Exception("Expecting 32 threads") threadToNuma[:] = numpy.arange(nthr) // 4 sf = d.Get("subapFlag") nsub = sf.size
def pokeSine(self,nFrames,pokeVal=1000.,dmNo=0,baseFreq=5,nrec=2,fname="sinePoke.fits",fno=-20,order=None,nRepeats=1,repeatIfErr=10): """nFrames - number of iterations over which to poke. baseFreq - minimum number of sine waves to fit within nFrames. nrec - number of cycles to record (for averaging purposes) fno - number of frames to allow for sync purposes. Make this more negative for faster systems (or closer to zero for simulation!). order - if None, will increase the freq of neighbouring actuators in a linear fashion. Otherwise, can be the index order in which this should be done. nRepeats - number of times to repeat the recording, with an offset added to the frequency of each actuator each time (so that different dynamics can be explored). repeatIfErr - number of times to repeat if an error is obtained, before giving up. If -ve, will repeat indefinitely Use processSine() function below to process this data... """ if order is not None: raise Exception("order not yet implemented - sorry!") d=darc.Control(self.prefix) nslopes=d.Get("subapFlag").sum()*2 nacts=d.Get("nacts")#self.nactList[dmNo] actOrig=d.Get("actuators") FITS.Write(actOrig,"tmpActOrig.fits") print("Writing original actuators to tmpActOrig.fits") pokeArr=numpy.zeros((nFrames,nacts),numpy.float32) nactDm=self.nactList[dmNo] offset=sum(self.nactList[:dmNo]) writeMode="w" freqOffset=0. dataList=[] errList=[] extraHeader=["POKEVAL = %d"%pokeVal,"NFRAMES = %d"%nFrames,"DMNUMBER= %d"%dmNo,"BASEFREQ= %d"%baseFreq,"NRECORD = %d"%nrec] for rpt in range(nRepeats): err=0 pokeArr[:]=actOrig for i in range(nactDm): freq=baseFreq+(freqOffset+i)%nactDm pokeArr[:,offset+i]+=numpy.sin(numpy.arange(nFrames)/float(nFrames)*2.*numpy.pi*freq)*pokeVal d.Set("actuators",pokeArr) time.sleep(1.) takeData=repeatIfErr if takeData==0: takeData=1 while takeData: err=0 data=d.GetStreamBlock(["rtcActuatorBuf","rtcCentBuf"],nFrames*nrec,asArray=1,fno=fno) #check the data is okay. for key in ["rtcCentBuf","rtcActuatorBuf"]: f=data[key][2] if not numpy.alltrue((f[1:]-f[:-1])==1): print "Cycle %d: Some frames missing from %s"%(rpt,key) err=1 if not numpy.alltrue(data["rtcCentBuf"][2]==data["rtcActuatorBuf"][2]): allframenumbersequal=0 print "Cycle %d: actuator and slope frame numbers don't agree"%rpt err=1 allframetimesequal=1 for key in ["rtcCentBuf","rtcActuatorBuf"]: ftime=data[key][1] fdiff=ftime[1:]-ftime[:-1] if not numpy.alltrue(fdiff<=numpy.median(fdiff)*3): allframetimesequal=0 err=1 print "Cycle %d: Not all frame times within 3x median frame time"%rpt if err==0:#got data okay takeData=0 elif takeData>1: print "Error in data - repeating acquisition (another %d times to try)"%takeData takeData-=1 elif takeData==1: takeData=0 if repeatIfErr==0: print "Error in data - continuing anyway" else: print "Error in data - cannot acquire (is your network fast enough? Is the frame rate too high?)" else: print "Error in data - repeating acquisition (will continue until successful...!)" if repeatIfErr!=0 and err!=0: raise Exception("Unable to capture data") #subtract the actuator offset (midrange) data["rtcActuatorBuf"][0]=data["rtcActuatorBuf"][0]-actOrig dataList.append(data) if fname is not None: FITS.Write(data["rtcCentBuf"][0],fname,writeMode=writeMode,extraHeader=extraHeader) writeMode="a" extraHeader=None FITS.Write(data["rtcCentBuf"][1],fname,writeMode="a")#times FITS.Write(data["rtcCentBuf"][2],fname,writeMode="a")#frameno FITS.Write(data["rtcActuatorBuf"][0],fname,writeMode="a") FITS.Write(data["rtcActuatorBuf"][1],fname,writeMode="a") FITS.Write(data["rtcActuatorBuf"][2],fname,writeMode="a") errList.append(err) freqOffset+=nactDm//nRepeats d.Set("actuators",actOrig) return dataList,errList
import sys import darc gain=0.5 if len(sys.argv)>1: gain=float(sys.argv[1]) d=darc.Control("main") g=d.Get("gain") g[:]=gain d.Set("gain",g) d.Set("addActuators",1)
def closeLoop(self, prefix=""): d = darc.Control(prefix) d.Set("addActuators", 1)