rf-touchstone 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,585 @@
1
+ # RF-Touchstone AI Usage Guide
2
+
3
+ > **For AI Coding Assistants**: This guide helps you understand how to integrate and use the `rf-touchstone` library in user projects.
4
+
5
+ ## Quick Start
6
+
7
+ ### Installation
8
+
9
+ **Via NPM/Yarn:**
10
+
11
+ ```bash
12
+ npm install rf-touchstone
13
+ # or
14
+ yarn add rf-touchstone
15
+ ```
16
+
17
+ **Via CDN:**
18
+
19
+ ```html
20
+ <script src="https://unpkg.com/rf-touchstone"></script>
21
+ <script>
22
+ const { Touchstone, abs, arg, pi } = window.Touchstone
23
+ </script>
24
+ ```
25
+
26
+ ### Basic Import Pattern
27
+
28
+ ```typescript
29
+ import { Touchstone } from 'rf-touchstone'
30
+ // Optional math helpers from mathjs
31
+ import { abs, arg, pi, complex } from 'rf-touchstone'
32
+ ```
33
+
34
+ ## Core Concepts
35
+
36
+ ### 1. **Touchstone Class** - Main API Entry Point
37
+
38
+ The `Touchstone` class is the primary interface for working with .snp files.
39
+
40
+ #### Creating Touchstone Objects
41
+
42
+ **From URL (Browser or Node.js with fetch):**
43
+
44
+ ```typescript
45
+ // Auto-detect nports from filename (.s2p → 2-port)
46
+ const ts = await Touchstone.fromUrl('https://example.com/device.s2p')
47
+
48
+ // Explicit nports if filename doesn't indicate
49
+ const ts = await Touchstone.fromUrl('https://example.com/data.txt', 2)
50
+ ```
51
+
52
+ **From File Object (Browser file input):**
53
+
54
+ ```typescript
55
+ // In any framework with file input
56
+ const handleFileUpload = async (file: File) => {
57
+ const touchstone = await Touchstone.fromFile(file)
58
+ // Use touchstone object
59
+ }
60
+ ```
61
+
62
+ **From Text Content (Universal - works in any environment):**
63
+
64
+ ```typescript
65
+ import { Touchstone } from 'rf-touchstone'
66
+
67
+ // Example S2P file content (could come from any source: upload, API, database, etc.)
68
+ const s2pContent = `! 2-port S-parameter data
69
+ # GHz S MA R 50
70
+ 1.0 0.50 -45 0.95 10 0.05 85 0.60 -30
71
+ 2.0 0.45 -60 0.90 15 0.10 80 0.55 -45
72
+ 3.0 0.40 -75 0.85 20 0.15 75 0.50 -60`
73
+
74
+ // Parse the text content
75
+ const touchstone = Touchstone.fromText(s2pContent, 2) // 2 = 2-port network
76
+
77
+ // Now you can use the parsed data
78
+ console.log(touchstone.frequency.f_scaled) // [1.0, 2.0, 3.0]
79
+ console.log(touchstone.format) // 'MA'
80
+ console.log(touchstone.parameter) // 'S'
81
+ ```
82
+
83
+ ### 2. **Accessing Touchstone Data**
84
+
85
+ ```typescript
86
+ const ts = await Touchstone.fromUrl('device.s2p')
87
+
88
+ // Frequency data
89
+ const frequencies = ts.frequency.f_scaled // Array of numbers in specified unit
90
+ const unit = ts.frequency.unit // 'Hz' | 'kHz' | 'MHz' | 'GHz'
91
+
92
+ // Options line data
93
+ const format = ts.format // 'RI' | 'MA' | 'DB'
94
+ const parameter = ts.parameter // 'S' | 'Y' | 'Z' | 'G' | 'H'
95
+ const impedance = ts.impedance // typically 50
96
+ const nports = ts.nports // Number of ports (1, 2, 3, 4, etc.)
97
+
98
+ // Network parameter matrix
99
+ // IMPORTANT: matrix is 3D array [outPort][inPort][frequencyIndex]
100
+ const matrix = ts.matrix // Complex number matrix
101
+ ```
102
+
103
+ ### 3. **Understanding Matrix Indexing** ⚠️ CRITICAL
104
+
105
+ **Matrix Structure:**
106
+
107
+ ```typescript
108
+ // matrix[i][j][k]
109
+ // - i: Output port index (0 to nports-1) - where the signal exits
110
+ // - j: Input port index (0 to nports-1) - where the signal enters
111
+ // - k: Frequency point index (0 to numFrequencies-1)
112
+ //
113
+ // Sij = matrix[i-1][j-1][k] means: signal enters at port j, exits at port i
114
+ ```
115
+
116
+ **Accessing S-parameters (consistent for ALL port counts):**
117
+
118
+ ```typescript
119
+ // For 2-port network:
120
+ const s11 = ts.matrix[0][0][freqIdx] // S11
121
+ const s12 = ts.matrix[0][1][freqIdx] // S12
122
+ const s21 = ts.matrix[1][0][freqIdx] // S21
123
+ const s22 = ts.matrix[1][1][freqIdx] // S22
124
+
125
+ // For 4-port network (same pattern):
126
+ const s11 = ts.matrix[0][0][freqIdx] // S11
127
+ const s21 = ts.matrix[1][0][freqIdx] // S21
128
+ const s31 = ts.matrix[2][0][freqIdx] // S31
129
+ const s41 = ts.matrix[3][0][freqIdx] // S41
130
+ const s12 = ts.matrix[0][1][freqIdx] // S12
131
+ // ... and so on
132
+
133
+ // General pattern: Sij = ts.matrix[i-1][j-1][freqIdx]
134
+ ```
135
+
136
+ ### 4. **Format Conversion**
137
+
138
+ To convert between formats (RI, MA, DB):
139
+
140
+ ```typescript
141
+ const ts = await Touchstone.fromUrl('device.s2p')
142
+
143
+ // Method 1: Change format and regenerate content
144
+ ts.format = 'DB' // Change to Decibel/Angle
145
+ const dbContent = ts.writeContent() // Generate new file content
146
+ // Now you can save dbContent or parse it as a new Touchstone object
147
+
148
+ // Method 2: Create new instance with different format
149
+ const dbTs = Touchstone.fromText(dbContent, ts.nports)
150
+ ```
151
+
152
+ ### 5. **Writing Touchstone Content**
153
+
154
+ ```typescript
155
+ const ts = await Touchstone.fromUrl('device.s2p')
156
+
157
+ // Generate Touchstone file content in current format
158
+ const content = ts.writeContent()
159
+
160
+ // In Browser - Download as file
161
+ const blob = new Blob([content], { type: 'text/plain' })
162
+ const url = URL.createObjectURL(blob)
163
+ const a = document.createElement('a')
164
+ a.href = url
165
+ a.download = 'modified-device.s2p'
166
+ a.click()
167
+
168
+ // In Node.js - Save to file
169
+ import fs from 'fs/promises'
170
+ await fs.writeFile('modified-device.s2p', content)
171
+ ```
172
+
173
+ ### 6. **Working with Complex Numbers**
174
+
175
+ The library uses mathjs Complex type `{ re: number, im: number }`:
176
+
177
+ ```typescript
178
+ import { abs, arg, pi } from 'rf-touchstone'
179
+
180
+ // Get S11 at first frequency for 2-port
181
+ const s11 = ts.matrix[0][0][0] // Complex { re: ..., im: ... }
182
+
183
+ // Calculate magnitude
184
+ const magnitude = abs(s11) // |S11|
185
+
186
+ // Calculate phase (in radians)
187
+ const phase = arg(s11) // ∠S11
188
+
189
+ // Convert to dB
190
+ const magnitudeDB = 20 * Math.log10(magnitude)
191
+
192
+ // Convert phase to degrees
193
+ const phaseDegrees = (phase * 180) / pi
194
+ ```
195
+
196
+ ## Common Use Cases
197
+
198
+ ### Example 1: File Upload in Browser (Vanilla JavaScript)
199
+
200
+ ```typescript
201
+ import { Touchstone, abs, arg, pi } from 'rf-touchstone'
202
+
203
+ // HTML: <input type="file" id="fileInput" accept=".s*p">
204
+ const fileInput = document.getElementById('fileInput') as HTMLInputElement
205
+
206
+ fileInput.addEventListener('change', async (event) => {
207
+ const file = (event.target as HTMLInputElement).files?![0]
208
+ if (!file) return
209
+
210
+ try {
211
+ const ts = await Touchstone.fromFile(file)
212
+
213
+ console.log(`${ts.nports}-Port Network`)
214
+ console.log(`Frequencies: ${ts.frequency.f_scaled.length}`)
215
+ console.log(`Unit: ${ts.frequency.unit}`)
216
+ console.log(`Format: ${ts.format}`)
217
+
218
+ // Access S11 at first frequency (works for any port count)
219
+ const s11 = ts.matrix[0][0][0]
220
+ console.log(`S11 Magnitude: ${abs(s11)}`)
221
+ console.log(`S11 Phase (deg): ${(arg(s11) * 180 / pi).toFixed(2)}`)
222
+
223
+ } catch (error) {
224
+ console.error('Error loading Touchstone file:', error)
225
+ }
226
+ })
227
+ ```
228
+
229
+ ### Example 2: Format Converter (Node.js)
230
+
231
+ ```typescript
232
+ import { Touchstone } from 'rf-touchstone'
233
+ import fs from 'fs/promises'
234
+
235
+ async function convertTouchstone(
236
+ inputPath: string,
237
+ outputPath: string,
238
+ targetFormat: 'RI' | 'MA' | 'DB'
239
+ ) {
240
+ // Read input file
241
+ const content = await fs.readFile(inputPath, 'utf-8')
242
+
243
+ // Determine nports from filename
244
+ const nports = Touchstone.parsePorts(inputPath)
245
+ if (nports === null) {
246
+ throw new Error(
247
+ `Cannot determine number of ports from filename: ${inputPath}`
248
+ )
249
+ }
250
+
251
+ // Parse the file
252
+ const ts = Touchstone.fromText(content, nports)
253
+
254
+ console.log(`Original format: ${ts.format}`)
255
+
256
+ // Convert format
257
+ ts.format = targetFormat
258
+ const convertedContent = ts.writeContent()
259
+
260
+ // Write output
261
+ await fs.writeFile(outputPath, convertedContent)
262
+
263
+ console.log(`Converted to ${targetFormat}`)
264
+ }
265
+
266
+ // Usage
267
+ await convertTouchstone('input.s2p', 'output.s2p', 'DB')
268
+ ```
269
+
270
+ ### Example 3: S-Parameter Plotting (Any Framework)
271
+
272
+ ```typescript
273
+ import { Touchstone, abs } from 'rf-touchstone'
274
+
275
+ async function getPlotData(url: string) {
276
+ const ts = await Touchstone.fromUrl(url)
277
+
278
+ const numFreqs = ts.frequency.f_scaled.length
279
+ const frequencies = ts.frequency.f_scaled
280
+
281
+ // Extract S21 magnitude in dB for all frequencies (2-port network)
282
+ const s21_dB: number[] = []
283
+ for (let freqIdx = 0; freqIdx < numFreqs; freqIdx++) {
284
+ const s21 = ts.matrix[1][0][freqIdx] // S21 for 2-port
285
+ const magnitude = abs(s21)
286
+ s21_dB.push(20 * Math.log10(magnitude))
287
+ }
288
+
289
+ return {
290
+ frequencies,
291
+ s21_dB,
292
+ unit: ts.frequency.unit,
293
+ }
294
+ }
295
+
296
+ // Use with any chart library (Chart.js, D3, Plotly, etc.)
297
+ const data = await getPlotData('https://example.com/device.s2p')
298
+ console.log(data)
299
+ // { frequencies: [...], s21_dB: [...], unit: 'GHZ' }
300
+ ```
301
+
302
+ ### Example 4: Data Analysis
303
+
304
+ ```typescript
305
+ import { Touchstone, abs } from 'rf-touchstone'
306
+
307
+ async function analyzeTouchstone(file: File) {
308
+ const ts = await Touchstone.fromFile(file)
309
+
310
+ if (ts.nports !== 2) {
311
+ throw new Error('This example is for 2-port networks only')
312
+ }
313
+
314
+ const numFreqs = ts.frequency.f_scaled.length
315
+
316
+ // Calculate insertion loss (S21)
317
+ let maxS21 = 0
318
+ for (let i = 0; i < numFreqs; i++) {
319
+ const mag = abs(ts.matrix[1][0][i]) // S21
320
+ if (mag > maxS21) maxS21 = mag
321
+ }
322
+ const insertionLoss_dB = -20 * Math.log10(maxS21)
323
+
324
+ // Calculate return loss (S11)
325
+ let maxS11 = 0
326
+ for (let i = 0; i < numFreqs; i++) {
327
+ const mag = abs(ts.matrix[0][0][i]) // S11
328
+ if (mag > maxS11) maxS11 = mag
329
+ }
330
+ const returnLoss_dB = -20 * Math.log10(maxS11)
331
+
332
+ return {
333
+ nports: ts.nports,
334
+ numFrequencies: numFreqs,
335
+ frequencyRange: {
336
+ min: ts.frequency.f_scaled[0],
337
+ max: ts.frequency.f_scaled[numFreqs - 1],
338
+ unit: ts.frequency.unit,
339
+ },
340
+ insertionLoss_dB: insertionLoss_dB.toFixed(2),
341
+ returnLoss_dB: returnLoss_dB.toFixed(2),
342
+ format: ts.format,
343
+ }
344
+ }
345
+ ```
346
+
347
+ ### Example 5: Vue Component
348
+
349
+ ```vue
350
+ <template>
351
+ <div>
352
+ <input type="file" @change="handleFileUpload" accept=".s*p" />
353
+ <div v-if="touchstone">
354
+ <h2>{{ touchstone.nports }}-Port Network</h2>
355
+ <p>Frequencies: {{ touchstone.frequency.f_scaled.length }}</p>
356
+ <p>Unit: {{ touchstone.frequency.unit }}</p>
357
+ <p>Format: {{ touchstone.format }}</p>
358
+ <button @click="convertToDb">Convert to dB</button>
359
+ <button @click="downloadFile">Download</button>
360
+ </div>
361
+ </div>
362
+ </template>
363
+
364
+ <script setup lang="ts">
365
+ import { ref } from 'vue'
366
+ import { Touchstone } from 'rf-touchstone'
367
+
368
+ const touchstone = ref<Touchstone | null>(null)
369
+
370
+ async function handleFileUpload(event: Event) {
371
+ const file = (event.target as HTMLInputElement).files?.[0]
372
+ if (file) {
373
+ touchstone.value = await Touchstone.fromFile(file)
374
+ }
375
+ }
376
+
377
+ function convertToDb() {
378
+ if (touchstone.value) {
379
+ touchstone.value.format = 'DB'
380
+ // Re-parse to get converted matrix
381
+ const content = touchstone.value.writeContent()
382
+ touchstone.value = Touchstone.fromText(content, touchstone.value.nports!)
383
+ }
384
+ }
385
+
386
+ function downloadFile() {
387
+ if (touchstone.value) {
388
+ const content = touchstone.value.writeContent()
389
+ const blob = new Blob([content], { type: 'text/plain' })
390
+ const url = URL.createObjectURL(blob)
391
+ const a = document.createElement('a')
392
+ a.href = url
393
+ a.download = `converted.s${touchstone.value.nports}p`
394
+ a.click()
395
+ }
396
+ }
397
+ </script>
398
+ ```
399
+
400
+ ## TypeScript Types
401
+
402
+ ### Key Interfaces and Types
403
+
404
+ ```typescript
405
+ // Touchstone class
406
+ class Touchstone {
407
+ // Properties
408
+ nports?: number
409
+ frequency?: Frequency
410
+ format?: 'RI' | 'MA' | 'DB'
411
+ parameter?: 'S' | 'Y' | 'Z' | 'G' | 'H'
412
+ impedance: number | number[] // default: 50
413
+ matrix?: Complex[][][] // [outPort][inPort][freqIdx]
414
+ comments: string[]
415
+
416
+ // Static methods
417
+ static fromText(content: string, nports: number): Touchstone
418
+ static fromUrl(url: string, nports?: number): Promise<Touchstone>
419
+ static fromFile(file: File, nports?: number): Promise<Touchstone>
420
+ static getFilename(pathOrUrl: string): string
421
+ static parsePorts(filename: string): number | null
422
+
423
+ // Instance methods
424
+ readContent(content: string, nports: number): void
425
+ writeContent(): string
426
+ validate(): void
427
+ }
428
+
429
+ // Complex number (from mathjs)
430
+ interface Complex {
431
+ re: number // Real part
432
+ im: number // Imaginary part
433
+ }
434
+
435
+ // Frequency class
436
+ class Frequency {
437
+ unit: 'Hz' | 'kHz' | 'MHz' | 'GHz'
438
+ f_scaled: number[] // Frequency values in current unit
439
+
440
+ // Getters/setters for different units
441
+ f_Hz: number[]
442
+ f_kHz: number[]
443
+ f_MHz: number[]
444
+ f_GHz: number[]
445
+ f_THz: number[]
446
+
447
+ // Wavelength getters/setters
448
+ wavelength_m: number[]
449
+ wavelength_cm: number[]
450
+ wavelength_mm: number[]
451
+ wavelength_um: number[]
452
+ wavelength_nm: number[]
453
+ }
454
+
455
+ // Helper Functions (from mathjs)
456
+ // These can be imported: import { abs, arg, pi } from 'rf-touchstone'
457
+ function abs(x: Complex | number): number
458
+ function arg(x: Complex): number // Returns phase in radians
459
+ function complex(re: number, im: number): Complex
460
+ function complex(obj: { r: number; phi: number }): Complex // Polar form
461
+ const pi: number
462
+
463
+ // Other available helpers:
464
+ // add, multiply, pow, log10, round, range, index, subset
465
+ ```
466
+
467
+ ## Important Notes
468
+
469
+ ### Module Formats Support
470
+
471
+ This library supports **multiple module formats** for maximum compatibility:
472
+
473
+ - **UMD (Universal Module Definition)**: `dist/Touchstone.umd.js` - For direct browser `<script>` tags
474
+ - **ESM (ES Modules)**: `dist/Touchstone.es.js` - For modern bundlers and `import` statements
475
+ - **CJS (CommonJS)**: `dist/Touchstone.cjs.js` - For older Node.js projects using `require()`
476
+
477
+ **Using in Browser (UMD):**
478
+
479
+ Via CDN:
480
+
481
+ ```html
482
+ <!-- Using unpkg -->
483
+ <script src="https://unpkg.com/rf-touchstone"></script>
484
+
485
+ <!-- Or using jsDelivr -->
486
+ <script src="https://cdn.jsdelivr.net/npm/rf-touchstone"></script>
487
+
488
+ <script>
489
+ const { Touchstone, abs, arg } = window.Touchstone
490
+ </script>
491
+ ```
492
+
493
+ **Using in Modern Projects (ESM):**
494
+
495
+ ```typescript
496
+ import { Touchstone } from 'rf-touchstone'
497
+ ```
498
+
499
+ **Using in Legacy Node.js (CommonJS):**
500
+
501
+ ```javascript
502
+ const { Touchstone } = require('rf-touchstone')
503
+ ```
504
+
505
+ ### Browser vs Node.js
506
+
507
+ - `Touchstone.fromUrl()` works in both environments (uses `fetch`)
508
+ - `Touchstone.fromFile()` is browser-only (uses `File` API)
509
+ - For Node.js file reading, use `fs` and `Touchstone.fromText()`
510
+
511
+ ### Port Indexing
512
+
513
+ **Matrix indexing is consistent for ALL port counts:**
514
+
515
+ ```typescript
516
+ // General pattern: Sij = matrix[i-1][j-1][freqIdx]
517
+
518
+ // For any N-port network:
519
+ const s11 = matrix[0][0][freqIdx] // S11
520
+ const s21 = matrix[1][0][freqIdx] // S21
521
+ const s12 = matrix[0][1][freqIdx] // S12
522
+ const s22 = matrix[1][1][freqIdx] // S22
523
+ // etc.
524
+ ```
525
+
526
+ ### Memory Considerations
527
+
528
+ Large .snp files (many ports/frequencies) create large matrices:
529
+
530
+ - Processing in chunks
531
+ - Not storing multiple copies simultaneously
532
+
533
+ ## Error Handling
534
+
535
+ ```typescript
536
+ try {
537
+ const ts = await Touchstone.fromUrl('device.s2p')
538
+ } catch (error) {
539
+ if (error instanceof Error) {
540
+ // Common errors:
541
+ // - Network errors (URL fetch failed)
542
+ // - Parse errors (invalid Touchstone format)
543
+ // - File not found
544
+ // - Could not determine nports
545
+ console.error('Failed to load Touchstone:', error.message)
546
+ }
547
+ }
548
+ ```
549
+
550
+ ## Resources
551
+
552
+ - **API Documentation**: https://panz2018.github.io/RF-Touchstone/api/modules
553
+ - **GitHub**: https://github.com/panz2018/RF-Touchstone
554
+ - **NPM**: https://www.npmjs.com/package/rf-touchstone
555
+
556
+ ## Common Patterns Summary
557
+
558
+ ```typescript
559
+ // ✅ DO: Load from URL
560
+ const ts = await Touchstone.fromUrl('file.s2p')
561
+
562
+ // ✅ DO: Access matrix correctly (same for all port counts)
563
+ const s21 = ts.matrix[1][0][freqIdx] // S21
564
+
565
+ // ✅ DO: Convert format properly
566
+ ts.format = 'DB'
567
+ const dbContent = ts.writeContent()
568
+
569
+ // ✅ DO: Iterate frequencies correctly
570
+ for (let freqIdx = 0; freqIdx < ts.frequency.f_scaled.length; freqIdx++) {
571
+ const s11 = ts.matrix[0][0][freqIdx]
572
+ // process s11...
573
+ }
574
+
575
+ // ❌ DON'T: Use non-existent convertFormat method
576
+ // const tsDB = ts.convertFormat('DB') // This doesn't exist!
577
+
578
+ // ❌ DON'T: Use wrong matrix indexing
579
+ // const s11 = ts.matrix[freqIdx][0][0] // WRONG!
580
+ ```
581
+
582
+ ---
583
+
584
+ **Last Updated**: 2026-01-25
585
+ **Library Version**: 0.0.5+
@@ -8834,10 +8834,11 @@ class nu {
8834
8834
  frequency;
8835
8835
  /**
8836
8836
  * 3D array to store the network parameter data
8837
- * - The first dimension is the exits (output) port number
8838
- * - The second dimension is the enters (input) port number
8839
- * - The third dimension is the frequency index
8840
- * For example, data[i][j][k] would be the parameter from j+1 port to i+1 port at frequency index k
8837
+ * - First dimension [i]: Output port index (0 to nports-1) - where signal exits
8838
+ * - Second dimension [j]: Input port index (0 to nports-1) - where signal enters
8839
+ * - Third dimension [k]: Frequency index
8840
+ *
8841
+ * For example: matrix[i][j][k] is the parameter from port j+1 to port i+1 at frequency k
8841
8842
  */
8842
8843
  _matrix;
8843
8844
  /**
@@ -8858,17 +8859,21 @@ class nu {
8858
8859
  *
8859
8860
  * @remarks
8860
8861
  * Matrix Structure:
8861
- * - First dimension [i]: Output (exit) port number (0 to nports-1)
8862
- * - Second dimension [j]: Input (enter) port number (0 to nports-1)
8862
+ * - First dimension [i]: Output port index (0 to nports-1) - where the signal exits
8863
+ * - Second dimension [j]: Input port index (0 to nports-1) - where the signal enters
8863
8864
  * - Third dimension [k]: Frequency point index
8864
8865
  *
8865
- * Example:
8866
- * - matrix[i][j][k] represents the parameter from port j+1 to port i+1 at frequency k
8867
- * - For S-parameters: matrix[1][0][5] is S₂₁ at the 6th frequency point
8866
+ * @example
8867
+ * ```typescript
8868
+ * // For any N-port network (2-port, 4-port, etc.):
8869
+ * const s11 = touchstone.matrix[0][0][freqIdx] // S11: port 1 → port 1
8870
+ * const s21 = touchstone.matrix[1][0][freqIdx] // S21: port 1 → port 2
8871
+ * const s12 = touchstone.matrix[0][1][freqIdx] // S12: port 2 → port 1
8872
+ * const s22 = touchstone.matrix[1][1][freqIdx] // S22: port 2 → port 2
8868
8873
  *
8869
- * Special case for 2-port networks:
8870
- * - Indices are swapped to match traditional Touchstone format
8871
- * - matrix[0][1][k] represents S₁₂ (not S₂₁)
8874
+ * // General pattern: Sij = matrix[i-1][j-1][freqIdx]
8875
+ * // where i is the output port number, j is the input port number
8876
+ * ```
8872
8877
  *
8873
8878
  * @returns The current network parameter matrix, or undefined if not set
8874
8879
  */
@@ -46,17 +46,23 @@ export type TouchstoneImpedance = number | number[];
46
46
  *
47
47
  * @remarks
48
48
  * The matrix is a 3D array with the following dimensions:
49
- * - First dimension: output port index (0 to nports-1)
50
- * - Second dimension: input port index (0 to nports-1)
51
- * - Third dimension: frequency point index
49
+ * - First dimension [i]: Output port index (0 to nports-1) - where the signal exits
50
+ * - Second dimension [j]: Input port index (0 to nports-1) - where the signal enters
51
+ * - Third dimension [k]: Frequency point index
52
52
  *
53
53
  * For example:
54
- * - matrix[i][j][k] represents the parameter from port j+1 to port i+1 at frequency k
55
- * - For S-parameters: matrix[1][0][5] is S₂₁ at the 6th frequency point
54
+ * - `matrix[i][j][k]` represents the parameter from port j+1 to port i+1 at frequency k
55
+ * - For S-parameters: `matrix[1][0][5]` is S₂₁ at the 6th frequency point
56
+ * (signal enters at port 1, exits at port 2)
56
57
  *
57
- * Special case for 2-port networks:
58
- * - Indices are swapped to match traditional Touchstone format
59
- * - matrix[0][1][k] represents S₁₂ (not S₂₁)
58
+ * @example
59
+ * ```typescript
60
+ * // Access S21 (port 1 port 2) at first frequency
61
+ * const s21 = touchstone.matrix[1][0][0]
62
+ *
63
+ * // Access S11 (port 1 → port 1, reflection) at first frequency
64
+ * const s11 = touchstone.matrix[0][0][0]
65
+ * ```
60
66
  */
61
67
  export type TouchstoneMatrix = Complex[][][];
62
68
  /**
@@ -249,10 +255,11 @@ export declare class Touchstone {
249
255
  frequency: Frequency | undefined;
250
256
  /**
251
257
  * 3D array to store the network parameter data
252
- * - The first dimension is the exits (output) port number
253
- * - The second dimension is the enters (input) port number
254
- * - The third dimension is the frequency index
255
- * For example, data[i][j][k] would be the parameter from j+1 port to i+1 port at frequency index k
258
+ * - First dimension [i]: Output port index (0 to nports-1) - where signal exits
259
+ * - Second dimension [j]: Input port index (0 to nports-1) - where signal enters
260
+ * - Third dimension [k]: Frequency index
261
+ *
262
+ * For example: matrix[i][j][k] is the parameter from port j+1 to port i+1 at frequency k
256
263
  */
257
264
  private _matrix;
258
265
  /**
@@ -267,17 +274,21 @@ export declare class Touchstone {
267
274
  *
268
275
  * @remarks
269
276
  * Matrix Structure:
270
- * - First dimension [i]: Output (exit) port number (0 to nports-1)
271
- * - Second dimension [j]: Input (enter) port number (0 to nports-1)
277
+ * - First dimension [i]: Output port index (0 to nports-1) - where the signal exits
278
+ * - Second dimension [j]: Input port index (0 to nports-1) - where the signal enters
272
279
  * - Third dimension [k]: Frequency point index
273
280
  *
274
- * Example:
275
- * - matrix[i][j][k] represents the parameter from port j+1 to port i+1 at frequency k
276
- * - For S-parameters: matrix[1][0][5] is S₂₁ at the 6th frequency point
281
+ * @example
282
+ * ```typescript
283
+ * // For any N-port network (2-port, 4-port, etc.):
284
+ * const s11 = touchstone.matrix[0][0][freqIdx] // S11: port 1 → port 1
285
+ * const s21 = touchstone.matrix[1][0][freqIdx] // S21: port 1 → port 2
286
+ * const s12 = touchstone.matrix[0][1][freqIdx] // S12: port 2 → port 1
287
+ * const s22 = touchstone.matrix[1][1][freqIdx] // S22: port 2 → port 2
277
288
  *
278
- * Special case for 2-port networks:
279
- * - Indices are swapped to match traditional Touchstone format
280
- * - matrix[0][1][k] represents S₁₂ (not S₂₁)
289
+ * // General pattern: Sij = matrix[i-1][j-1][freqIdx]
290
+ * // where i is the output port number, j is the input port number
291
+ * ```
281
292
  *
282
293
  * @returns The current network parameter matrix, or undefined if not set
283
294
  */
package/package.json CHANGED
@@ -1,14 +1,18 @@
1
1
  {
2
2
  "name": "rf-touchstone",
3
3
  "type": "module",
4
- "version": "0.0.4",
4
+ "version": "0.0.5",
5
5
  "description": "A Javascript/TypeScript library for reading, manipulating, and writing Touchstone files (.snp files) used in radio frequency (RF) and microwave engineering.",
6
6
  "main": "dist/Touchstone.cjs.js",
7
7
  "module": "dist/Touchstone.es.js",
8
+ "browser": "dist/Touchstone.umd.js",
9
+ "unpkg": "dist/Touchstone.umd.js",
10
+ "jsdelivr": "dist/Touchstone.umd.js",
8
11
  "types": "dist/index.d.ts",
9
12
  "exports": {
10
13
  ".": {
11
14
  "types": "./dist/index.d.ts",
15
+ "browser": "./dist/Touchstone.umd.js",
12
16
  "import": "./dist/Touchstone.es.js",
13
17
  "require": "./dist/Touchstone.cjs.js"
14
18
  }
@@ -18,7 +22,8 @@
18
22
  "./src",
19
23
  "./readme.md",
20
24
  "./LICENSE.md",
21
- "./coverage/coverage-badge.svg"
25
+ "./coverage/coverage-badge.svg",
26
+ "./.github/AI_USAGE_GUIDE.md"
22
27
  ],
23
28
  "license": "MIT",
24
29
  "author": "https://github.com/panz2018",
package/readme.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A Javascript/TypeScript library for reading, manipulating, and writing Touchstone files (.snp files) used in radio frequency (RF) and microwave engineering.
4
4
 
5
+ <a href="https://deepwiki.com/panz2018/RF-Touchstone" target="_blank"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki" align="right"></a>
6
+
5
7
  [![Tests](https://github.com/panz2018/RF-Touchstone/actions/workflows/test.yml/badge.svg?event=pull_request)](https://github.com/panz2018/RF-Touchstone/actions/workflows/test.yml)
6
8
  [![Coverage](coverage/coverage-badge.svg)](coverage/coverage-badge.svg)
7
9
 
@@ -35,12 +37,29 @@ RF-Touchstone currently supports versions 1.0 and 1.1 of the Touchstone specific
35
37
 
36
38
  ## Installation
37
39
 
40
+ ### Via NPM/Yarn
41
+
38
42
  ```bash
39
43
  npm install rf-touchstone
40
44
  # or
41
45
  yarn add rf-touchstone
42
46
  ```
43
47
 
48
+ ### Via CDN (Browser)
49
+
50
+ ```html
51
+ <!-- Using unpkg -->
52
+ <script src="https://unpkg.com/rf-touchstone"></script>
53
+
54
+ <!-- Or using jsDelivr -->
55
+ <script src="https://cdn.jsdelivr.net/npm/rf-touchstone"></script>
56
+
57
+ <script>
58
+ // Access via global variable
59
+ const { Touchstone } = window.Touchstone
60
+ </script>
61
+ ```
62
+
44
63
  ## Quick Start
45
64
 
46
65
  ```typescript
@@ -83,6 +102,7 @@ This repository includes examples to demonstrate the usage of `rf-touchstone` in
83
102
  For detailed documentation, please visit:
84
103
 
85
104
  - [Project Website](https://panz2018.github.io/RF-Touchstone/)
105
+ - [AI Usage Guide](https://github.com/panz2018/RF-Touchstone/blob/main/.github/AI_USAGE_GUIDE.md) - Comprehensive guide for AI coding assistants and developers integrating this library
86
106
  - [DeepWiki Documentation](https://deepwiki.com/panz2018/RF-Touchstone) - Interactive AI documentation that allows you to converse and ask questions about this repository
87
107
  - [Changelog](https://github.com/panz2018/RF-Touchstone/releases)
88
108
 
package/src/touchstone.ts CHANGED
@@ -67,17 +67,23 @@ export type TouchstoneImpedance = number | number[]
67
67
  *
68
68
  * @remarks
69
69
  * The matrix is a 3D array with the following dimensions:
70
- * - First dimension: output port index (0 to nports-1)
71
- * - Second dimension: input port index (0 to nports-1)
72
- * - Third dimension: frequency point index
70
+ * - First dimension [i]: Output port index (0 to nports-1) - where the signal exits
71
+ * - Second dimension [j]: Input port index (0 to nports-1) - where the signal enters
72
+ * - Third dimension [k]: Frequency point index
73
73
  *
74
74
  * For example:
75
- * - matrix[i][j][k] represents the parameter from port j+1 to port i+1 at frequency k
76
- * - For S-parameters: matrix[1][0][5] is S₂₁ at the 6th frequency point
75
+ * - `matrix[i][j][k]` represents the parameter from port j+1 to port i+1 at frequency k
76
+ * - For S-parameters: `matrix[1][0][5]` is S₂₁ at the 6th frequency point
77
+ * (signal enters at port 1, exits at port 2)
77
78
  *
78
- * Special case for 2-port networks:
79
- * - Indices are swapped to match traditional Touchstone format
80
- * - matrix[0][1][k] represents S₁₂ (not S₂₁)
79
+ * @example
80
+ * ```typescript
81
+ * // Access S21 (port 1 port 2) at first frequency
82
+ * const s21 = touchstone.matrix[1][0][0]
83
+ *
84
+ * // Access S11 (port 1 → port 1, reflection) at first frequency
85
+ * const s11 = touchstone.matrix[0][0][0]
86
+ * ```
81
87
  */
82
88
  export type TouchstoneMatrix = Complex[][][]
83
89
 
@@ -457,10 +463,11 @@ export class Touchstone {
457
463
 
458
464
  /**
459
465
  * 3D array to store the network parameter data
460
- * - The first dimension is the exits (output) port number
461
- * - The second dimension is the enters (input) port number
462
- * - The third dimension is the frequency index
463
- * For example, data[i][j][k] would be the parameter from j+1 port to i+1 port at frequency index k
466
+ * - First dimension [i]: Output port index (0 to nports-1) - where signal exits
467
+ * - Second dimension [j]: Input port index (0 to nports-1) - where signal enters
468
+ * - Third dimension [k]: Frequency index
469
+ *
470
+ * For example: matrix[i][j][k] is the parameter from port j+1 to port i+1 at frequency k
464
471
  */
465
472
  private _matrix: TouchstoneMatrix | undefined
466
473
 
@@ -483,17 +490,21 @@ export class Touchstone {
483
490
  *
484
491
  * @remarks
485
492
  * Matrix Structure:
486
- * - First dimension [i]: Output (exit) port number (0 to nports-1)
487
- * - Second dimension [j]: Input (enter) port number (0 to nports-1)
493
+ * - First dimension [i]: Output port index (0 to nports-1) - where the signal exits
494
+ * - Second dimension [j]: Input port index (0 to nports-1) - where the signal enters
488
495
  * - Third dimension [k]: Frequency point index
489
496
  *
490
- * Example:
491
- * - matrix[i][j][k] represents the parameter from port j+1 to port i+1 at frequency k
492
- * - For S-parameters: matrix[1][0][5] is S₂₁ at the 6th frequency point
497
+ * @example
498
+ * ```typescript
499
+ * // For any N-port network (2-port, 4-port, etc.):
500
+ * const s11 = touchstone.matrix[0][0][freqIdx] // S11: port 1 → port 1
501
+ * const s21 = touchstone.matrix[1][0][freqIdx] // S21: port 1 → port 2
502
+ * const s12 = touchstone.matrix[0][1][freqIdx] // S12: port 2 → port 1
503
+ * const s22 = touchstone.matrix[1][1][freqIdx] // S22: port 2 → port 2
493
504
  *
494
- * Special case for 2-port networks:
495
- * - Indices are swapped to match traditional Touchstone format
496
- * - matrix[0][1][k] represents S₁₂ (not S₂₁)
505
+ * // General pattern: Sij = matrix[i-1][j-1][freqIdx]
506
+ * // where i is the output port number, j is the input port number
507
+ * ```
497
508
  *
498
509
  * @returns The current network parameter matrix, or undefined if not set
499
510
  */