Skip to content

Commit

Permalink
Merge pull request #6 from hoodlabpurdue/christian-timetagger-refacto…
Browse files Browse the repository at this point in the history
…ring

Christian timetagger refactoring
  • Loading branch information
lange50 authored Jun 4, 2025
2 parents 9759f54 + a03f29a commit b584da1
Show file tree
Hide file tree
Showing 19 changed files with 3,462 additions and 1,107 deletions.
109 changes: 109 additions & 0 deletions notebooks/spectral_wandering.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "9d68bde7",
"metadata": {},
"outputs": [],
"source": [
"from time import time\n",
"import os\n",
"\n",
"\"\"\"\n",
"This script runs a series of scans using the terascan_logic module.\n",
"Set the start and stop wavelengths in the gui, as well as the number of scans.\n",
"\"\"\"\n",
"\n",
"tl = terascan_logic"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7f66367e",
"metadata": {},
"outputs": [
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[24], line 12\u001b[0m\n\u001b[0;32m 9\u001b[0m started_scans \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[0;32m 11\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m---> 12\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mtl\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodule_state\u001b[49m() \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124midle\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;66;03m# i.e. the scan is not running yet\u001b[39;00m\n\u001b[0;32m 13\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m started_scans \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m 14\u001b[0m time_list\u001b[38;5;241m.\u001b[39mappend(time() \u001b[38;5;241m-\u001b[39m start_time)\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\core\\netref.py:148\u001b[0m, in \u001b[0;36mBaseNetref.__getattribute__\u001b[1;34m(self, name)\u001b[0m\n\u001b[0;32m 146\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mobject\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__getattribute__\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m__array__\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 147\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 148\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msyncreq\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconsts\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mHANDLE_GETATTR\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\core\\netref.py:63\u001b[0m, in \u001b[0;36msyncreq\u001b[1;34m(proxy, handler, *args)\u001b[0m\n\u001b[0;32m 51\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Performs a synchronous request on the given proxy object.\u001b[39;00m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;124;03mNot intended to be invoked directly.\u001b[39;00m\n\u001b[0;32m 53\u001b[0m \n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 60\u001b[0m \u001b[38;5;124;03m:returns: the result of the operation\u001b[39;00m\n\u001b[0;32m 61\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 62\u001b[0m conn \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mobject\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__getattribute__\u001b[39m(proxy, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m____conn__\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m---> 63\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msync_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mhandler\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mproxy\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\core\\protocol.py:718\u001b[0m, in \u001b[0;36mConnection.sync_request\u001b[1;34m(self, handler, *args)\u001b[0m\n\u001b[0;32m 715\u001b[0m _async_res \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39masync_request(handler, \u001b[38;5;241m*\u001b[39margs, timeout\u001b[38;5;241m=\u001b[39mtimeout)\n\u001b[0;32m 716\u001b[0m \u001b[38;5;66;03m# _async_res is an instance of AsyncResult, the value property invokes Connection.serve via AsyncResult.wait\u001b[39;00m\n\u001b[0;32m 717\u001b[0m \u001b[38;5;66;03m# So, the _recvlock can be acquired multiple times by the owning thread and warrants the use of RLock\u001b[39;00m\n\u001b[1;32m--> 718\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_async_res\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalue\u001b[49m\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\core\\async_.py:106\u001b[0m, in \u001b[0;36mAsyncResult.value\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 98\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[0;32m 99\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mvalue\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 100\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Returns the result of the operation. If the result has not yet\u001b[39;00m\n\u001b[0;32m 101\u001b[0m \u001b[38;5;124;03m arrived, accessing this property will wait for it. If the result does\u001b[39;00m\n\u001b[0;32m 102\u001b[0m \u001b[38;5;124;03m not arrive before the expiry time elapses, :class:`AsyncResultTimeout`\u001b[39;00m\n\u001b[0;32m 103\u001b[0m \u001b[38;5;124;03m is raised. If the returned result is an exception, it will be raised\u001b[39;00m\n\u001b[0;32m 104\u001b[0m \u001b[38;5;124;03m here. Otherwise, the result is returned directly.\u001b[39;00m\n\u001b[0;32m 105\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 106\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 107\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_is_exc:\n\u001b[0;32m 108\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_obj\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\core\\async_.py:51\u001b[0m, in \u001b[0;36mAsyncResult.wait\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 44\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Waits for the result to arrive. If the AsyncResult object has an\u001b[39;00m\n\u001b[0;32m 45\u001b[0m \u001b[38;5;124;03mexpiry set, and the result did not arrive within that timeout,\u001b[39;00m\n\u001b[0;32m 46\u001b[0m \u001b[38;5;124;03man :class:`AsyncResultTimeout` exception is raised\"\"\"\u001b[39;00m\n\u001b[0;32m 47\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_is_ready \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexpired):\n\u001b[0;32m 48\u001b[0m \u001b[38;5;66;03m# Serve the connection since we are not ready. Suppose\u001b[39;00m\n\u001b[0;32m 49\u001b[0m \u001b[38;5;66;03m# the reply for our seq is served. The callback is this class\u001b[39;00m\n\u001b[0;32m 50\u001b[0m \u001b[38;5;66;03m# so __call__ sets our obj and _is_ready to true.\u001b[39;00m\n\u001b[1;32m---> 51\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_conn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mserve\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_ttl\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 53\u001b[0m \u001b[38;5;66;03m# Check if we timed out before result was ready\u001b[39;00m\n\u001b[0;32m 54\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_is_ready:\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\core\\protocol.py:438\u001b[0m, in \u001b[0;36mConnection.serve\u001b[1;34m(self, timeout, wait_for_lock)\u001b[0m\n\u001b[0;32m 436\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 437\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;66;03m# Ensure data is initialized\u001b[39;00m\n\u001b[1;32m--> 438\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_channel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpoll\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_channel\u001b[38;5;241m.\u001b[39mrecv()\n\u001b[0;32m 439\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[0;32m 440\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_recvlock\u001b[38;5;241m.\u001b[39mrelease()\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\core\\channel.py:47\u001b[0m, in \u001b[0;36mChannel.poll\u001b[1;34m(self, timeout)\u001b[0m\n\u001b[0;32m 45\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mpoll\u001b[39m(\u001b[38;5;28mself\u001b[39m, timeout):\n\u001b[0;32m 46\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"polls the underlying steam for data, waiting up to *timeout* seconds\"\"\"\u001b[39;00m\n\u001b[1;32m---> 47\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpoll\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\core\\stream.py:48\u001b[0m, in \u001b[0;36mStream.poll\u001b[1;34m(self, timeout)\u001b[0m\n\u001b[0;32m 46\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m 47\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m---> 48\u001b[0m rl \u001b[38;5;241m=\u001b[39m \u001b[43mp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpoll\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtimeleft\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 49\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m select_error:\n\u001b[0;32m 50\u001b[0m ex \u001b[38;5;241m=\u001b[39m sys\u001b[38;5;241m.\u001b[39mexc_info()[\u001b[38;5;241m1\u001b[39m]\n",
"File \u001b[1;32m~\\anaconda3\\envs\\qudi-env\\lib\\site-packages\\rpyc\\lib\\compat.py:164\u001b[0m, in \u001b[0;36mSelectingPoll.poll\u001b[1;34m(self, timeout)\u001b[0m\n\u001b[0;32m 162\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m [] \u001b[38;5;66;03m# need to return an empty array in this case\u001b[39;00m\n\u001b[0;32m 163\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 164\u001b[0m rl, wl, _ \u001b[38;5;241m=\u001b[39m \u001b[43mselect\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrlist\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwlist\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 165\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m [(fd, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m fd \u001b[38;5;129;01min\u001b[39;00m rl] \u001b[38;5;241m+\u001b[39m [(fd, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mw\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m fd \u001b[38;5;129;01min\u001b[39;00m wl]\n",
"\u001b[1;31mKeyboardInterrupt\u001b[0m: "
]
}
],
"source": [
"start_time = time()\n",
"\n",
"data_save_dir = os.path.join('D:', 'qudi_data', 'multi_scan', '00000')\n",
"\n",
"time_list = []\n",
"data_file_list = []\n",
"\n",
"n_scans = 2\n",
"started_scans = 0\n",
"tl.clear_data()\n",
"\n",
"while True:\n",
" if tl.module_state() == 'idle': # i.e. the scan is not running yet\n",
" if started_scans > 0:\n",
" time_list.append(time() - start_time)\n",
" data_file_list.append(tl.save_data(data_save_dir))\n",
" tl.clear_data()\n",
" \n",
" \n",
" if started_scans < n_scans:\n",
" tl.start_scan()\n",
" started_scans += 1\n",
" else:\n",
" print(f\"Completed {n_scans} scans.\")\n",
" break\n",
" \n",
" elif tl.module_state() == 'locked':\n",
" continue"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "73f3c420",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "qudi",
"language": "python",
"name": "qudi"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading

0 comments on commit b584da1

Please sign in to comment.