Skip to content

Instantly share code, notes, and snippets.

@ZGainsforth
Created May 11, 2023 23:08
Show Gist options
  • Save ZGainsforth/9082e6be0dab39effc9455e0b6b1e21c to your computer and use it in GitHub Desktop.
Save ZGainsforth/9082e6be0dab39effc9455e0b6b1e21c to your computer and use it in GitHub Desktop.
Using Tescan SharkSEM interface, acquire a stack of images rapidly in sequence.
import pdb
import os
import sys
sys.path.append(os.path.join('..', 'remote'))
import time
import sem
import struct
import base64
from sem_v3_lib import *
print("Script Starting")
xpixels = 512 # pixels
ypixels = 512
ViewField = 20
# microns
NumFrames = 50
ScanSpeed = 6
SampleName = 'Track 220 TP2'
BitsPerPixel = 16
AcquireBSE = True
AcquireSE = False
TimeoutSeconds = 100 # Maximum number of seconds to wait in infinite loop before bailing.
if AcquireBSE == True and AcquireSE == True:
print('For now, you must choose only BSE or SE. Later write code to branch the output based on the channel (str[v[1] in WriteImage).')
sys.exit()
#
# read SharkSEM message from data connection (callbacks)
#
# return: (message name, message body)
#
def ReadMessage(conn):
# receive the message header
msg_name = conn._RecvStrD(16)
hdr = conn._RecvStrD(16)
v = struct.unpack("<IIHHI", hdr)
body_size = v[0]
# get fn name
cb_name = DecodeString(msg_name)
# receive the body
cb_body = conn._RecvStrD(body_size)
# finished reading message
return (cb_name, cb_body)
def WriteImage(m, file):
#pdb.set_trace()
bytes_read = 0
ReadTimeStart = time.time()
while bytes_read < xpixels*ypixels*BitsPerPixel/8:
#print(time.time() - ReadTimeStart)
if (time.time() - ReadTimeStart) > TimeoutSeconds:
print('Timeout is getting image data.')
return
#print("Read...")
try:
(cb_name, cb_body) = ReadMessage(m.connection)
except e:
print(e)
#time.sleep(0.002)
#print(cb_name)
#print(cb_body)
v = struct.unpack("<IiIiI", cb_body[0:20])
#print("Frame: " + str(v[0]))
#print("Channel: " + str(v[1]))
#print("Index: " + str(v[2]))
#print("BPP: " + str(v[3]))
#print("Writing " + str(v[4]) + " bytes")
#pdb.set_trace()
bytes_read = bytes_read + file.write(cb_body[20:])
#print("Bytes read: " + str(bytes_read))
if bytes_read >= xpixels*ypixels*BitsPerPixel/8:
return
def main():
m = sem.Sem()
conn = m.Connect('localhost', 8300)
if conn<0:
print("Error: Unable to connect to SEM")
return
# Make sure channel 0 is BSE
m.DtSelect(0,1)
time.sleep(0.2)
# Make sure channel 1 is SE
m.DtSelect(1,0)
time.sleep(0.2)
if AcquireSE == True:
m.DtEnable(1, 1, BitsPerPixel)
else:
m.DtEnable(1, 0)
if AcquireBSE == True:
m.DtEnable(0, 1, BitsPerPixel)
else:
m.DtEnable(0, 0)
time.sleep(0.2)
print(m.DtEnumDetectors())
print('Detector 0 [enable, bpp] = ' + str(m.DtGetEnabled(0)))
print('Detector 1 [enable, bpp] = ' + str(m.DtGetEnabled(1)))
#print(m.DtGetEnabled(1))
#return
# make sure scanning is inactive
m.ScStopScan()
time.sleep(0.5)
# Scan Speed.
print('Setting scan speed to '+str(ScanSpeed))
m.ScSetSpeed(ScanSpeed)
time.sleep(0.5)
# Get the view field
print('Setting view field to '+str(ViewField)+' microns.')
m.SetViewField(ViewField/1000)
time.sleep(1.0)
FileName = SampleName+' - '+str(xpixels)+'x'+str(ypixels)+'x'+str(NumFrames)+', ViewField='+str(ViewField)+' um, BSE='+str(AcquireBSE)+', SE='+str(AcquireSE)+', BPP='+str(BitsPerPixel)+', Little Endian.raw'
print('Saving to '+FileName)
# Open output file and start saving
if os.path.exists(FileName):
os.remove(FileName)
file = open(FileName, "wb")
try:
for i in range(NumFrames):
print("Scanning "+str(i+1)+" of "+str(NumFrames)+".")
# Scan the image
m.ScScanXY(1, xpixels, ypixels, 0, 0, xpixels-1, ypixels-1, 1)
time.sleep(0.2)
# And save it.
WriteImage(m, file)
time.sleep(0.2)
finally:
file.close()
print("Done")
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment