write_path / write_binary_grating.pyon commit add dlw module; clean up for handover (d7cac70)
   1"""
   2write_binary_grating.py
   3Andrew Lorimer, January 2025
   4Monash University
   5
   6Writes a transmission binary grating pattern using
   7the confocal direct laser writing setup on Sb2S3 thin-film PCM.
   8"""
   9
  10import configparser as cp
  11import cv2
  12import numpy as np
  13import sys
  14import matplotlib.pyplot as plt
  15import write_path
  16from pipython import datarectools, pitools
  17import nidaqmx
  18import pipython
  19import time
  20
  21TRANSITION_SPEED = 100   # speed for moving between lines, um/s
  22
  23# Input parameters
  24grating_pitch = 2.7 # Lambda, um
  25beam_width = 0.7
  26writing_speed = 10  # speed for writing crystallised lines, um/s
  27dimensions = (50, 50)   # horizontal * vertical, um
  28origin = (0, 0) # horizontal * vertical, um
  29
  30def wait_target(pidevice, thresh=0.01, axes=[1, 2, 3]):
  31    target = pidevice.qMOV(axes)
  32    on_target = False
  33    while on_target == False:
  34        pos = pidevice.qPOS(axes)
  35        on_target = True
  36        distances = np.abs(np.array(list(pos.values())) - np.array(list(target.values())))
  37        on_target = np.all(distances < thresh)
  38            
  39
  40def main(task, pidevice):
  41
  42    # One block is a solid area with constant refractive index in the 
  43    # diffraction grating
  44    # One line is a single pass of the laser, with many lines making up a 
  45    # block (depending on the beam width)
  46
  47    n_blocks = int(dimensions[0] // grating_pitch)
  48    n_lines = int(grating_pitch // beam_width)
  49
  50    pidevice.VCO({1: True})
  51
  52    updown = 0
  53
  54    for i in range(n_blocks):
  55        if (i % 2 == 0):
  56            # Even number block - crystallise
  57
  58            y_block = origin[0] + i * grating_pitch
  59
  60            for j in range(n_lines):
  61                y_line = y_block + j*beam_width
  62                x_start = origin[1] + int(not updown)*dimensions[1]
  63                x_end = origin[1] + updown*dimensions[1]
  64
  65                # Go to line start position
  66                pidevice.VEL({1: TRANSITION_SPEED})
  67                pidevice.MOV({1: x_start, 2: y_line})
  68                wait_target(pidevice)
  69                time.sleep(0.3)
  70                
  71                # Write line
  72                pidevice.VEL({1: writing_speed})
  73                pidevice.MOV({1: x_end, 2: y_line})
  74                #time.sleep(0.05)   # compensation for acceleration period
  75                task.write(True)
  76                wait_target(pidevice)
  77                task.write(False)
  78                time.sleep(0.3)
  79
  80                updown = int(not updown)
  81        else:
  82            # Odd number line - do nothing
  83            pass        
  84
  85if __name__ == "__main__":
  86    task, pidevice = write_path.setup()
  87    try:
  88        main(task, pidevice)
  89    finally:
  90        print("Exiting")
  91        task.write(False)
  92        task.close()
  93        pidevice.VCO({1: True, 2: True})
  94        pidevice.VEL({1: TRANSITION_SPEED, 2: TRANSITION_SPEED})
  95        pidevice.MOV({1: origin[1], 2: origin[0]})
  96        pitools.waitontarget(pidevice, [1, 2])
  97        pitools.stopall(pidevice)