Skip to content

Commit 0aec665

Browse files
committed
fix: anchor action discovery at Bias_Set
1 parent 4c9b556 commit 0aec665

File tree

5 files changed

+131
-496
lines changed

5 files changed

+131
-496
lines changed

config/parameters.yaml

Lines changed: 5 additions & 243 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ defaults:
44
ramp_default_interval_s: 0.05
55
meta:
66
generated_by: scripts/generate_parameters_manifest.py
7-
generated_at_utc: '2026-02-24T05:05:10Z'
7+
generated_at_utc: '2026-02-24T05:39:57Z'
88
source_package: nanonis-spm/1.0.9
9-
methods_seen: 684
9+
methods_seen: 667
1010
get_set_commands_imported: 551
11-
action_commands_imported: 133
11+
action_commands_imported: 116
1212
parameters_emitted: 327
13-
actions_emitted: 133
13+
actions_emitted: 116
1414
with_description_count: 326
15-
actions_with_description_count: 117
15+
actions_with_description_count: 116
1616
writable_count: 257
1717
parameters:
1818
aprfgen_freq:
@@ -9316,241 +9316,3 @@ actions:
93169316
description: ZSpectr.Stop Stops the current Z Spectroscopy measurement.
93179317
safety:
93189318
mode: guarded
9319-
close:
9320-
action_cmd:
9321-
command: close
9322-
args: {}
9323-
arg_types: {}
9324-
description: ''
9325-
safety:
9326-
mode: guarded
9327-
correctType:
9328-
action_cmd:
9329-
command: correctType
9330-
args:
9331-
BodyType: 0.0
9332-
Body: 0.0
9333-
arg_types:
9334-
BodyType: float
9335-
Body: float
9336-
description: ''
9337-
safety:
9338-
mode: guarded
9339-
decodeArray:
9340-
action_cmd:
9341-
command: decodeArray
9342-
args:
9343-
response: 0.0
9344-
index: 0.0
9345-
numOfElements: 0.0
9346-
responseType: 0.0
9347-
arg_types:
9348-
response: float
9349-
index: float
9350-
numOfElements: float
9351-
responseType: float
9352-
description: ''
9353-
safety:
9354-
mode: guarded
9355-
decodeArrayPrepended:
9356-
action_cmd:
9357-
command: decodeArrayPrepended
9358-
args:
9359-
response: 0.0
9360-
index: 0.0
9361-
numOfElements: 0.0
9362-
responseType: 0.0
9363-
arg_types:
9364-
response: float
9365-
index: float
9366-
numOfElements: float
9367-
responseType: float
9368-
description: ''
9369-
safety:
9370-
mode: guarded
9371-
decodeSingularString:
9372-
action_cmd:
9373-
command: decodeSingularString
9374-
args:
9375-
response: 0.0
9376-
index: 0.0
9377-
stringLength: 0.0
9378-
arg_types:
9379-
response: float
9380-
index: float
9381-
stringLength: float
9382-
description: ''
9383-
safety:
9384-
mode: guarded
9385-
decodeStringPrepended:
9386-
action_cmd:
9387-
command: decodeStringPrepended
9388-
args:
9389-
response: 0.0
9390-
index: 0.0
9391-
numOfStrings: 0.0
9392-
arg_types:
9393-
response: float
9394-
index: float
9395-
numOfStrings: float
9396-
description: ''
9397-
safety:
9398-
mode: guarded
9399-
handle2DArray:
9400-
action_cmd:
9401-
command: handle2DArray
9402-
args:
9403-
Array: 0.0
9404-
BodyType: 0.0
9405-
BodyPart: 0.0
9406-
arg_types:
9407-
Array: float
9408-
BodyType: float
9409-
BodyPart: float
9410-
description: ''
9411-
safety:
9412-
mode: guarded
9413-
handleArray:
9414-
action_cmd:
9415-
command: handleArray
9416-
args:
9417-
Array: 0.0
9418-
BodyType: 0.0
9419-
BodyPart: 0.0
9420-
arg_types:
9421-
Array: float
9422-
BodyType: float
9423-
BodyPart: float
9424-
description: ''
9425-
safety:
9426-
mode: guarded
9427-
handleArrayPrepend:
9428-
action_cmd:
9429-
command: handleArrayPrepend
9430-
args:
9431-
Array: 0.0
9432-
BodyType: 0.0
9433-
BodyPart: 0.0
9434-
arg_types:
9435-
Array: float
9436-
BodyType: float
9437-
BodyPart: float
9438-
description: ''
9439-
safety:
9440-
mode: guarded
9441-
handleArrayString:
9442-
action_cmd:
9443-
command: handleArrayString
9444-
args:
9445-
Array: 0.0
9446-
BodyType: 0.0
9447-
BodyPart: 0.0
9448-
arg_types:
9449-
Array: float
9450-
BodyType: float
9451-
BodyPart: float
9452-
description: ''
9453-
safety:
9454-
mode: guarded
9455-
handleString:
9456-
action_cmd:
9457-
command: handleString
9458-
args:
9459-
BodyElement: 0.0
9460-
BodyType: 0.0
9461-
BodyPart: 0.0
9462-
arg_types:
9463-
BodyElement: float
9464-
BodyType: float
9465-
BodyPart: float
9466-
description: ''
9467-
safety:
9468-
mode: guarded
9469-
parseError:
9470-
action_cmd:
9471-
command: parseError
9472-
args:
9473-
response: 0.0
9474-
index: 0.0
9475-
arg_types:
9476-
response: float
9477-
index: float
9478-
description: ''
9479-
safety:
9480-
mode: guarded
9481-
parseGeneralResponse:
9482-
action_cmd:
9483-
command: parseGeneralResponse
9484-
args:
9485-
Response: 0.0
9486-
ResponseTypes: 0.0
9487-
arg_types:
9488-
Response: float
9489-
ResponseTypes: float
9490-
description: ''
9491-
safety:
9492-
mode: guarded
9493-
printDebugInfo:
9494-
action_cmd:
9495-
command: printDebugInfo
9496-
args:
9497-
responseTypes: 0.0
9498-
bodyParts: 0.0
9499-
arg_types:
9500-
responseTypes: float
9501-
bodyParts: float
9502-
description: ''
9503-
safety:
9504-
mode: guarded
9505-
quickSend:
9506-
action_cmd:
9507-
command: quickSend
9508-
args:
9509-
Command: 0.0
9510-
Body: 0.0
9511-
BodyType: 0.0
9512-
ResponseTypes: 0.0
9513-
arg_types:
9514-
Command: float
9515-
Body: float
9516-
BodyType: float
9517-
ResponseTypes: float
9518-
description: 'quickSend(self, Command, Body, BodyType,ResponseTypes) Parameters
9519-
for quicksend: Command : as written in documentation Body: Body to send as
9520-
array [] - use [] when no argument should be sent! BodyType: Array of [Type
9521-
of data] - see also ResponseTypes ResponseTypes: Array of Types to decode
9522-
response IDENTIFIERS: H : unsigned int16 h : int16 I : unsigned int32 i :
9523-
int32 f : float32 d : float64 (double) Arrays (1D): Start with * length taken
9524-
from directly before the array (+ or -) *I : array of unsigned int32 (+ or
9525-
-) *i : array of int32 (+ or -) *f : array of float32 (+ or -) *d : array
9526-
of float64 (+ or -) *c : String! (Array of chars - interpreted as string!)
9527-
NEED TO UPDATE WITHOUT "*"!!!! Arrays (2D): start with 2 width and height
9528-
taken from the two variables before the array (+ or -) 2f : 2d array of float32
9529-
UNIQUE FOR RETURN TYPES: "**" Identifier for arrays whose size is defined
9530-
by the first returned argument'
9531-
safety:
9532-
mode: guarded
9533-
returnDebugInfo:
9534-
action_cmd:
9535-
command: returnDebugInfo
9536-
args:
9537-
displayInfo: 0.0
9538-
arg_types:
9539-
displayInfo: float
9540-
description: ''
9541-
safety:
9542-
mode: guarded
9543-
send:
9544-
action_cmd:
9545-
command: send
9546-
args:
9547-
Command: 0.0
9548-
Body: 0.0
9549-
BodyType: 0.0
9550-
arg_types:
9551-
Command: float
9552-
Body: float
9553-
BodyType: float
9554-
description: ''
9555-
safety:
9556-
mode: guarded

docs/extension_workflow.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,7 @@ nanonis.close()
4646
## Notes
4747
- Core behavior is generic and spec-driven.
4848
- `set` and `ramp` operate on any writable parameter with safety settings.
49-
- The generator imports all discovered `Get`/`Set` methods and keeps per-parameter descriptions from method docstrings.
49+
- Command discovery is anchored at `Bias_Set`; callable members declared before
50+
that method are ignored to avoid importing internal helper methods.
51+
- Discovered `Get`/`Set` methods are emitted under `parameters`, and non-`Get`/`Set`
52+
methods are emitted under `actions` with command-level descriptions.

nanonis_qcodes_controller/qcodes_driver/manifest_generator.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,26 @@ def discover_nanonis_commands(*, match_pattern: str = "") -> tuple[CommandInfo,
7373

7474
compiled_pattern = re.compile(match_pattern, re.IGNORECASE) if match_pattern else None
7575
discovered: list[CommandInfo] = []
76-
77-
for name, member in inspect.getmembers(nanonis_spm.Nanonis, predicate=callable):
76+
ordered_callables: list[tuple[str, Any]] = []
77+
for name, member in nanonis_spm.Nanonis.__dict__.items():
7878
if name.startswith("_"):
7979
continue
80+
callable_member: Any = member
81+
if isinstance(member, (staticmethod, classmethod)):
82+
callable_member = member.__func__
83+
if not callable(callable_member):
84+
continue
85+
ordered_callables.append((name, callable_member))
86+
87+
anchor_index: int | None = None
88+
for index, (name, _member) in enumerate(ordered_callables):
89+
if name == "Bias_Set":
90+
anchor_index = index
91+
break
92+
if anchor_index is None:
93+
raise ValueError("Could not find Bias_Set anchor in nanonis_spm.Nanonis callables.")
94+
95+
for name, member in ordered_callables[anchor_index:]:
8096
if compiled_pattern is not None and compiled_pattern.search(name) is None:
8197
continue
8298

@@ -164,15 +180,12 @@ def build_unified_manifest(
164180
generated_actions[info.command] = _build_generated_action_entry(info=info)
165181

166182
merged_actions: dict[str, Any] = {}
167-
all_action_names = sorted(set(generated_actions).union(curated_actions))
168-
for name in all_action_names:
169-
generated_entry = generated_actions.get(name)
183+
for name in sorted(generated_actions):
184+
generated_entry = generated_actions[name]
170185
curated_entry = curated_actions.get(name)
171-
if generated_entry is not None and curated_entry is not None:
186+
if curated_entry is not None:
172187
merged_actions[name] = _deep_merge(generated_entry, curated_entry)
173-
elif curated_entry is not None:
174-
merged_actions[name] = curated_entry
175-
elif generated_entry is not None:
188+
else:
176189
merged_actions[name] = generated_entry
177190

178191
for _name, parameter in merged_parameters.items():

0 commit comments

Comments
 (0)