### Install lecroyscope Package Source: https://github.com/lobis/lecroy-scope/blob/main/README.md Instructions for installing the lecroyscope Python package using pip. This includes installing the latest published version or installing from source with test dependencies. ```bash pip install lecroyscope ``` ```bash pip install .[test] ``` -------------------------------- ### Create and Write to ROOT Tree with Uproot Source: https://context7.com/lobis/lecroy-scope/llms.txt This snippet demonstrates how to create a ROOT file and tree using uproot, define custom metadata branches, add data matching these definitions, and then extend the tree with the data. It also includes reading back the data to verify its structure and content. ```python import uproot # Assuming trace_group is defined elsewhere and contains necessary data # Example placeholder for trace_group: trace_group = { "time": [0.0, 1.0, 2.0], "CH1": [1.1, 2.2, 3.3] } def get_tree_branch_definitions(trace_group, **kwargs): # This is a placeholder function. In a real scenario, it would define branches based on trace_group and kwargs. # For this example, we'll define simple branches. branches = {} for name, (dtype, shape) in kwargs.items(): branches[name] = dtype # Add default branches if they exist in trace_group if 'time' in trace_group: branches['time'] = 'f8' # Assuming time is float64 if 'CH1' in trace_group: branches['CH1'] = 'f8' # Assuming CH1 is float64 return branches def get_tree_extend_data(trace_group, **kwargs): # This is a placeholder function. It should return data formatted for tree.extend(). # For this example, we'll return a dictionary matching the expected structure. data_to_extend = {} if 'time' in trace_group: data_to_extend['time'] = trace_group['time'] if 'CH1' in trace_group: data_to_extend['CH1'] = trace_group['CH1'] # Add custom data from kwargs for key, value in kwargs.items(): data_to_extend[key] = value return data_to_extend # Add custom metadata branches branches = get_tree_branch_definitions( trace_group, temperature=("f4", (வுகளில்)), # scalar float run_number=("i4", (வுகளில்)) # scalar int ) # Create ROOT file and tree with uproot.recreate("output.root") as file: # Create tree with branch definitions file.mktree("waveforms", branches) # Get data formatted for tree.extend() data = get_tree_extend_data(trace_group) # Add custom data (must match branch definitions) data = get_tree_extend_data( trace_group, temperature=25.0, run_number=1 ) # Write data to tree file["waveforms"].extend(data) # Read back and verify with uproot.open("output.root") as file: tree = file["waveforms"] print(f"Entries: {tree.num_entries}") time = tree["time"].array() ch1 = tree["CH1"].array() print(f"Time shape: {time.shape}") print(f"CH1 shape: {ch1.shape}") ``` -------------------------------- ### Manage Multi-Channel Data with TraceGroup (Python) Source: https://context7.com/lobis/lecroy-scope/llms.txt Shows how to use the TraceGroup class to handle multiple trace channels from the same acquisition. It supports loading traces from files or glob patterns and provides synchronized access to multi-channel data. Dependencies include pathlib. ```Python from lecroyscope import Trace, TraceGroup from pathlib import Path # Create TraceGroup from multiple trace files trace_group = TraceGroup( "data/C1Trace00001.trc", "data/C2Trace00001.trc", "data/C3Trace00001.trc" ) ``` -------------------------------- ### Acquire Data from LeCroy Oscilloscope Source: https://github.com/lobis/lecroy-scope/blob/main/README.md Shows how to connect to a LeCroy oscilloscope, configure acquisition settings like sample mode and number of segments, acquire data, and read traces from specific channels. It also demonstrates using `TraceGroup` for reading multiple channels. ```python import lecroyscope scope = lecroyscope.Scope("192.168.1.10") # IP address of the scope print(f"Scope ID: {scope.id}") scope.sample_mode = "Sequence" scope.num_segments = 200 print(f"Sample mode: '{scope.sample_mode}' with {scope.num_segments} segments") scope.acquire(timeout=60) trace_channel2: lecroyscope.Trace = scope.read(2) trace_channel3: lecroyscope.Trace = scope.read(3) trace_group: lecroyscope.TraceGroup = scope.read(2, 3) trace_channel2 = trace_group[2] trace_channel3 = trace_group[3] time = trace_group.time ``` -------------------------------- ### Exporting Trace Data to ROOT Files Source: https://context7.com/lobis/lecroy-scope/llms.txt Utilizes the `writing.root` module to export trace data into ROOT file format, leveraging the `uproot` library. This facilitates integration with particle physics analysis workflows by defining ROOT tree branches and preparing data for extension. ```python import uproot from lecroyscope import Trace, TraceGroup from lecroyscope.writing.root import get_tree_branch_definitions, get_tree_extend_data # Load trace data trace = Trace("data/pulse_sequence.trc") # Or use TraceGroup for multiple channels trace_group = TraceGroup( "data/C1Trace00001.trc", "data/C2Trace00001.trc" ) # Define ROOT tree branches based on trace structure # Includes "time" and "CHx" branches for each channel branches = get_tree_branch_definitions(trace_group) print(f"Branch definitions: {branches}") ``` -------------------------------- ### Read LeCroy TRC Trace Files Source: https://github.com/lobis/lecroy-scope/blob/main/README.md Demonstrates how to read binary trace files (*.trc) using the `lecroyscope.Trace` class. It shows how to access header information and the time and voltage data from the trace. ```python from lecroyscope import Trace trace = Trace("path/to/trace.trc") header = trace.header print("Instrument name: ", header.instrument_name) print("Instrument name: ", header["instrument_name"]) header_dict = dict(header) print("Header keys: ", list(header_dict.keys())) time = trace.time # trace.x is an alias for trace.time voltage = trace.voltage # trace.y is an alias for trace.voltage ``` -------------------------------- ### Create and Access TraceGroup Data Source: https://context7.com/lobis/lecroy-scope/llms.txt Demonstrates creating TraceGroup objects from glob patterns or existing Trace objects. It also shows how to access individual channels, shared time vectors, trace lengths, and iterate over traces within a group. Slicing a TraceGroup returns a new TraceGroup. ```python from lecroyscope import Trace, TraceGroup # Create TraceGroup using glob pattern (matches C*Trace*.trc) trace_group = TraceGroup("data/C*Trace00001.trc") # Create TraceGroup from existing Trace objects trace1 = Trace("data/C1Trace00001.trc") trace2 = Trace("data/C2Trace00001.trc") trace_group = TraceGroup(trace1, trace2) # Access channels in the group print(f"Available channels: {trace_group.channels}") # e.g., [1, 2, 3] print(f"Number of channels: {len(trace_group)}") # Access individual channels by channel number channel1_trace = trace_group[1] channel2_trace = trace_group[2] print(f"Channel 1 peak voltage: {channel1_trace.voltage.max():.3f} V") # Get shared time vector (same for all channels from same trigger) time = trace_group.time # or trace_group.x if time is not None: print(f"Time samples: {len(time)}") else: print("Traces have different time bases") # Get trace length if uniform across channels trace_length = trace_group.trace_length print(f"Trace length: {trace_length}") # Iterate over all traces in the group for trace in trace_group: print(f"Channel {trace.channel}: {trace.voltage.shape}") # Slice the trace group (returns new TraceGroup) first_two_channels = trace_group[:2] ``` -------------------------------- ### Low-Level Reading of LeCroy TRC Files with Lecroyscope Source: https://context7.com/lobis/lecroy-scope/llms.txt This snippet shows how to use the `lecroyscope.reading.read()` function for low-level access to LeCroy trace files. It covers reading the complete file, reading only the header for faster metadata inspection, and handling data from bytes. It also demonstrates manual voltage conversion. ```python from lecroyscope.reading import read import numpy as np # Read complete trace file # Assuming 'data/pulse.trc' exists and is a valid LeCroy trace file # header, trigger_times, values = read("data/pulse.trc", header_only=False) # Read header only (faster for metadata inspection) # header, trigger_times, values = read("data/pulse.trc", header_only=True) # print(f"Values empty when header_only=True: {values.size == 0}") # Header is a dictionary with all metadata # print(f"Instrument: {header['instrument_name']}") # print(f"Sample interval: {header['horiz_interval']} s") # print(f"Vertical gain: {header['vertical_gain']}") # print(f"Vertical offset: {header['vertical_offset']}") # Values are raw ADC values (int8 or int16) # print(f"Values dtype: {values.dtype}") # print(f"Values shape: {values.shape}") # For sequence mode, values are 2D: (num_segments, samples_per_segment) # if header['subarray_count'] > 1: # print(f"Sequence mode: {header['subarray_count']} segments") # Trigger times array shape: (2, num_segments) # Row 0: trigger time offsets, Row 1: trigger time fractions # print(f"Trigger times shape: {trigger_times.shape}") # Read from bytes # with open("data/pulse.trc", "rb") as f: # file_bytes = f.read() # header, trigger_times, values = read(file_bytes, header_only=False) # Manual voltage conversion (what Trace class does internally) # voltage = values * header['vertical_gain'] - header['vertical_offset'] # time = np.arange(values.shape[-1]) * header['horiz_interval'] + header['horiz_offset'] # Placeholder for demonstration purposes as the file is not available print("Low-level reading functions demonstrated. Uncomment and provide file path to run.") header_example = { 'instrument_name': 'HDO4054', 'horiz_interval': 1e-6, 'vertical_gain': [0.01, 0.01, 0.01], 'vertical_offset': [0.1, 0.1, 0.1], 'subarray_count': 1 } values_example = np.array([10, 20, 30], dtype=np.int16) trigger_times_example = np.array([[0.0], [0.0]]) print(f"Instrument: {header_example['instrument_name']}") print(f"Sample interval: {header_example['horiz_interval']} s") print(f"Values dtype: {values_example.dtype}") print(f"Values shape: {values_example.shape}") print(f"Trigger times shape: {trigger_times_example.shape}") voltage_example = values_example * header_example['vertical_gain'][0] - header_example['vertical_offset'][0] time_example = np.arange(values_example.shape[-1]) * header_example['horiz_interval'] + header_example['horiz_offset'] print(f"Example voltage conversion: {voltage_example}") print(f"Example time conversion: {time_example}") ``` -------------------------------- ### Access Header Metadata with Header Class (Python) Source: https://context7.com/lobis/lecroy-scope/llms.txt Illustrates how to access metadata from LeCroy trace files using the Header class, which is part of the Trace object. It shows accessing fields as properties, dictionary keys, and iterating through all header information. No external dependencies beyond the lecroyscope package. ```Python from lecroyscope import Trace trace = Trace("path/to/trace.trc") header = trace.header # Access header fields as properties print(f"Instrument name: {header.instrument_name}") print(f"Instrument number: {header.instrument_number}") print(f"Trace label: {header.trace_label}") # Access fields using dictionary-style indexing print(f"Trigger time: {header['trigger_time']}") print(f"Vertical coupling: {header['vert_coupling']}") # e.g., "DC 50 Ohm", "AC 1 MOhm" print(f"Time base: {header['time_base']}") # e.g., "100 ns / div" # Vertical scaling parameters print(f"Vertical gain: {header['vertical_gain']}") print(f"Vertical offset: {header['vertical_offset']}") print(f"Fixed vertical gain: {header['fixed_vert_gain']}") # e.g., "500 mV / div" # Horizontal (time) parameters print(f"Horizontal interval: {header['horiz_interval']} seconds") print(f"Horizontal offset: {header['horiz_offset']} seconds") # Array information print(f"Wave array count: {header['wave_array_count']}") print(f"Subarray count: {header['subarray_count']}") # >1 for sequence mode print(f"Nominal bits: {header['nominal_bits']}") # Processing and record type print(f"Record type: {header['record_type']}") # e.g., "single sweep", "sequence obsolete" print(f"Processing done: {header['processing_done']}") # e.g., "no processing" # Check if sequence mode print(f"Is sequence mode: {header.sequence}") # Convert header to dictionary header_dict = dict(header) print(f"All header fields: {list(header_dict.keys())}") # Iterate over header fields for field_name, field_value in header: print(f"{field_name}: {field_value}") ``` -------------------------------- ### Channel-Specific Control and Configuration Source: https://context7.com/lobis/lecroy-scope/llms.txt Provides control over individual oscilloscope channels for vertical scale, offset, and coupling. It allows accessing channels via `Scope.channel()`, configuring these parameters, performing auto-scaling, and reading waveforms specific to a channel. It also demonstrates configuring multiple channels simultaneously. ```python import lecroyscope scope = lecroyscope.Scope("192.168.1.10") # Get channel object for channel 2 ch2 = scope.channel(2) # Configure vertical scale (V/div) ch2.vertical_scale = 0.5 # 500 mV/div print(f"Vertical scale: {ch2.vertical_scale} V/div") # Configure vertical offset ch2.vertical_offset = 0.0 # 0V offset print(f"Vertical offset: {ch2.vertical_offset} V") # Query vertical coupling print(f"Vertical coupling: {ch2.vertical_coupling}") # Auto-scale the channel ch2.find_scale() # Read trace from this channel trace = ch2.read() print(f"Channel {trace.channel}: {trace.voltage.shape}") # Work with multiple channels channels = [scope.channel(i) for i in [1, 2, 3, 4]] for ch in channels: ch.vertical_scale = 1.0 # Set all to 1V/div print(f"C{ch.channel}: scale={ch.vertical_scale}, offset={ch.vertical_offset}") ``` -------------------------------- ### Remote Oscilloscope Control with Scope Class Source: https://context7.com/lobis/lecroy-scope/llms.txt Enables remote control of Teledyne LeCroy oscilloscopes over the network using the VXI-11 protocol. This includes connecting, querying instrument details, configuring acquisition parameters (sample mode, segments, trigger mode), setting timeouts, triggering acquisitions, reading waveform data for single or multiple channels, and using generic VBS commands. ```python import lecroyscope # Connect to oscilloscope by IP address scope = lecroyscope.Scope("192.168.1.10") # Query instrument identification print(f"Scope ID: {scope.id}") # List all available execution names (channels, math traces, etc.) print(f"Available names: {scope.name_all}") # Configure sample mode scope.sample_mode = "RealTime" # or "Sequence", "RIS" print(f"Current sample mode: {scope.sample_mode}") # Configure sequence mode with multiple segments scope.sample_mode = "Sequence" scope.num_segments = 200 print(f"Number of segments: {scope.num_segments}") # Configure trigger mode scope.trigger_mode = "Single" # Options: "Stopped", "Single", "Normal", "Auto" print(f"Trigger mode: {scope.trigger_mode}") # Set communication timeout (in seconds) scope.timeout = 60.0 # Trigger acquisition and wait for completion # Returns True if successful, False if timeout success = scope.acquire(timeout=60) if success: print("Acquisition completed successfully") else: print("Acquisition timed out") # Force acquisition (ignore trigger conditions) scope.acquire(force=True) # Read single channel trace trace_ch1 = scope.read(1) print(f"Channel 1: {len(trace_ch1)} samples") # Read multiple channels at once (returns TraceGroup) trace_group = scope.read(1, 2, 3, 4) for trace in trace_group: print(f"Channel {trace.channel}: peak = {trace.voltage.max():.3f} V") # Use generic get/set for any VBS parameter value = scope.get("Acquisition.Horizontal.SampleRate") print(f"Sample rate: {value}") scope.set("Acquisition.Horizontal.SampleRate", 1e9) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.