@ccp-nc/crystvis-js 0.6.1 → 0.7.1

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.
Files changed (64) hide show
  1. package/.mocharc.yml +4 -0
  2. package/.vscode/settings.json +5 -1
  3. package/CHANGELOG.md +54 -16
  4. package/README.md +75 -2
  5. package/audit.txt +12 -25
  6. package/changes.txt +1 -26
  7. package/demo/demo.css +15 -10
  8. package/demo/index.html +32 -5
  9. package/demo/main.js +149 -42
  10. package/lib/formats/magres.js +156 -1
  11. package/lib/model.js +31 -0
  12. package/lib/modelview.js +24 -0
  13. package/lib/render.js +97 -2
  14. package/lib/selbox.js +18 -4
  15. package/lib/visualizer.js +237 -1
  16. package/outdated.txt +9 -12
  17. package/package.json +7 -5
  18. package/test/data/hf_mu_test.magres +62 -0
  19. package/test/data/hf_test.magres +61 -0
  20. package/test/data/optimized_muon_65-hf.magres +1424 -0
  21. package/test/loader.js +115 -1
  22. package/test/model.js +118 -0
  23. package/test/setup-dom.cjs +147 -0
  24. package/test/visualizer.js +475 -0
  25. package/docs/data/search.json +0 -1
  26. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  27. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  28. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  29. package/docs/index.html +0 -10
  30. package/docs/lib_model.module_js-AtomImage.html +0 -3
  31. package/docs/lib_model.module_js-BondImage.html +0 -3
  32. package/docs/lib_model.module_js-Model.html +0 -3
  33. package/docs/lib_model.module_js.html +0 -3
  34. package/docs/lib_modelview.module_js-ModelView.html +0 -12
  35. package/docs/lib_modelview.module_js.html +0 -3
  36. package/docs/lib_visualizer.module_js-CrystVis.html +0 -3
  37. package/docs/lib_visualizer.module_js.html +0 -3
  38. package/docs/model.js.html +0 -2160
  39. package/docs/modelview.js.html +0 -449
  40. package/docs/scripts/core.js +0 -726
  41. package/docs/scripts/core.min.js +0 -23
  42. package/docs/scripts/resize.js +0 -90
  43. package/docs/scripts/search.js +0 -265
  44. package/docs/scripts/search.min.js +0 -6
  45. package/docs/scripts/third-party/Apache-License-2.0.txt +0 -202
  46. package/docs/scripts/third-party/fuse.js +0 -9
  47. package/docs/scripts/third-party/hljs-line-num-original.js +0 -369
  48. package/docs/scripts/third-party/hljs-line-num.js +0 -1
  49. package/docs/scripts/third-party/hljs-original.js +0 -5171
  50. package/docs/scripts/third-party/hljs.js +0 -1
  51. package/docs/scripts/third-party/popper.js +0 -5
  52. package/docs/scripts/third-party/tippy.js +0 -1
  53. package/docs/scripts/third-party/tocbot.js +0 -672
  54. package/docs/scripts/third-party/tocbot.min.js +0 -1
  55. package/docs/styles/clean-jsdoc-theme-base.css +0 -1159
  56. package/docs/styles/clean-jsdoc-theme-dark.css +0 -412
  57. package/docs/styles/clean-jsdoc-theme-light.css +0 -482
  58. package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -30
  59. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -1
  60. package/docs/styles/clean-jsdoc-theme.min.css +0 -1
  61. package/docs/tutorial-Events.html +0 -13
  62. package/docs/tutorial-Queries.html +0 -16
  63. package/docs/tutorial-ThreejsMigration.html +0 -25
  64. package/docs/visualizer.js.html +0 -574
package/lib/visualizer.js CHANGED
@@ -85,6 +85,34 @@ class CrystVis {
85
85
  // Vanilla (no get/set needed)
86
86
  this.cifsymtol = 1e-2; // Parameter controlling the tolerance to symmetry when loading CIF files
87
87
 
88
+ // Disposal state
89
+ this._isDisposed = false;
90
+
91
+ // Model source / parameter / metadata stores (keyed by model name)
92
+ this._model_sources = {}; // { text, extension }
93
+ this._model_parameters = {}; // parameters passed to loadModels / reloadModel
94
+ this._model_meta = {}; // { prefix, originalName }
95
+
96
+ // Lifecycle / camera-change callbacks
97
+ this._model_list_change_cbs = [];
98
+ this._display_change_cbs = [];
99
+ this._camera_change_cbs = [];
100
+
101
+ // Subscribe to camera changes from the renderer
102
+ this._camera_unsub = this._renderer.onCameraChange((state) => {
103
+ this._camera_change_cbs.forEach(cb => cb(state));
104
+ });
105
+
106
+ }
107
+
108
+ /**
109
+ * Whether this instance has been disposed.
110
+ * Once true, most methods will throw rather than silently fail.
111
+ * @readonly
112
+ * @type {boolean}
113
+ */
114
+ get isDisposed() {
115
+ return this._isDisposed;
88
116
  }
89
117
 
90
118
  /**
@@ -253,6 +281,146 @@ class CrystVis {
253
281
  this._atom_box_event = this._defaultAtomBox.bind(this);
254
282
  }
255
283
 
284
+ // ─── Private event emitters ─────────────────────────────────────────────────
285
+
286
+ _emitModelListChange() {
287
+ const names = Object.keys(this._models);
288
+ this._model_list_change_cbs.forEach(cb => cb(names));
289
+ }
290
+
291
+ _emitDisplayChange() {
292
+ this._display_change_cbs.forEach(cb => cb(this._current_mname));
293
+ }
294
+
295
+ // ─── Camera state API ────────────────────────────────────────────────────────
296
+
297
+ /**
298
+ * Return a plain serialisable snapshot of the current camera state.
299
+ *
300
+ * @return {{ position: {x,y,z}, target: {x,y,z}, zoom: number }}
301
+ */
302
+ getCameraState() {
303
+ return this._renderer.getCameraState();
304
+ }
305
+
306
+ /**
307
+ * Restore a camera snapshot produced by {@link CrystVis#getCameraState}.
308
+ * Safe to call after `displayModel()`.
309
+ *
310
+ * @param {{ position?: {x,y,z}, target?: {x,y,z}, zoom?: number }} state
311
+ */
312
+ setCameraState(state) {
313
+ this._renderer.setCameraState(state);
314
+ }
315
+
316
+ /**
317
+ * Subscribe to camera-change events (rotate, pan, zoom).
318
+ * The callback receives a snapshot identical to {@link CrystVis#getCameraState}.
319
+ *
320
+ * @param {Function} callback `callback(cameraState)`
321
+ * @return {Function} Unsubscribe function
322
+ */
323
+ onCameraChange(callback) {
324
+ this._camera_change_cbs.push(callback);
325
+ return () => {
326
+ this._camera_change_cbs = this._camera_change_cbs.filter(cb => cb !== callback);
327
+ };
328
+ }
329
+
330
+ // ─── Lifecycle event APIs ────────────────────────────────────────────────────
331
+
332
+ /**
333
+ * Subscribe to model-list change events (model added or deleted).
334
+ * The callback receives the new list of model names.
335
+ *
336
+ * @param {Function} callback `callback(modelNames: string[])`
337
+ * @return {Function} Unsubscribe function
338
+ */
339
+ onModelListChange(callback) {
340
+ this._model_list_change_cbs.push(callback);
341
+ return () => {
342
+ this._model_list_change_cbs = this._model_list_change_cbs.filter(cb => cb !== callback);
343
+ };
344
+ }
345
+
346
+ /**
347
+ * Subscribe to display-change events fired whenever `displayModel()` completes.
348
+ * The callback receives the name of the newly displayed model (or `null` when cleared).
349
+ *
350
+ * @param {Function} callback `callback(modelName: string|null)`
351
+ * @return {Function} Unsubscribe function
352
+ */
353
+ onDisplayChange(callback) {
354
+ this._display_change_cbs.push(callback);
355
+ return () => {
356
+ this._display_change_cbs = this._display_change_cbs.filter(cb => cb !== callback);
357
+ };
358
+ }
359
+
360
+ // ─── Model source / parameter / metadata APIs ────────────────────────────────
361
+
362
+ /**
363
+ * Return the raw file text and format extension originally passed to
364
+ * `loadModels()` for the named model.
365
+ *
366
+ * @param {String} name Model name
367
+ * @return {{ text: string, extension: string }|null}
368
+ */
369
+ getModelSource(name) {
370
+ const src = this._model_sources[name];
371
+ return src ? { ...src } : null;
372
+ }
373
+
374
+ /**
375
+ * Return the loading parameters that were used when the named model was
376
+ * last loaded / reloaded (a clone of the merged parameter object).
377
+ *
378
+ * @param {String} name Model name
379
+ * @return {Object|null}
380
+ */
381
+ getModelParameters(name) {
382
+ const p = this._model_parameters[name];
383
+ return p ? JSON.parse(JSON.stringify(p)) : null;
384
+ }
385
+
386
+ /**
387
+ * Return metadata stored alongside the named model:
388
+ * `{ prefix, originalName }`.
389
+ *
390
+ * @param {String} name Model name
391
+ * @return {{ prefix: string, originalName: string }|null}
392
+ */
393
+ getModelMeta(name) {
394
+ const m = this._model_meta[name];
395
+ return m ? { ...m } : null;
396
+ }
397
+
398
+ // ─── Atomic unload ───────────────────────────────────────────────────────────
399
+
400
+ /**
401
+ * Remove *all* loaded models and reset the view in a single atomic operation
402
+ * (only one render pass after everything is cleared, unlike calling
403
+ * `deleteModel()` in a loop).
404
+ */
405
+ unloadAll() {
406
+ if (this._isDisposed) {
407
+ throw new Error('CrystVis: cannot call unloadAll() on a disposed instance');
408
+ }
409
+
410
+ // Clear the displayed model (handles renderer.clear(), selection reset, etc.)
411
+ // displayModel() with no args also emits _emitDisplayChange()
412
+ this.displayModel();
413
+
414
+ this._models = {};
415
+ this._model_sources = {};
416
+ this._model_parameters = {};
417
+ this._model_meta = {};
418
+
419
+ this._emitModelListChange();
420
+ }
421
+
422
+ // ─── Internal atom-click/box defaults ────────────────────────────────────────
423
+
256
424
  _defaultAtomLeftClick(atom, event) {
257
425
  var i = atom.imgIndex;
258
426
  this.selected = new ModelView(this._current_model, [i]);
@@ -315,6 +483,50 @@ class CrystVis {
315
483
  * which the center of the camera should be rendered with
316
484
  * respect to the center of the canvas
317
485
  */
486
+ /**
487
+ * Release all resources held by this instance: cancels the animation loop,
488
+ * removes all canvas event listeners, disposes OrbitControls and the
489
+ * THREE.WebGLRenderer, and nulls internal references. After calling this
490
+ * method the instance must not be used again.
491
+ */
492
+ dispose() {
493
+ if (this._isDisposed) {
494
+ return;
495
+ }
496
+ this._isDisposed = true;
497
+
498
+ // Unsubscribe camera-change listener before tearing down the renderer
499
+ if (this._camera_unsub) {
500
+ this._camera_unsub();
501
+ this._camera_unsub = null;
502
+ }
503
+
504
+ // Tear down the renderer (animation loop, orbit controls, WebGL context)
505
+ if (this._renderer) {
506
+ this._renderer.dispose();
507
+ this._renderer = null;
508
+ }
509
+
510
+ // Drop model and view references
511
+ this._current_model = null;
512
+ this._current_mname = null;
513
+ this._displayed = null;
514
+ this._selected = null;
515
+ this._models = {};
516
+ this._model_sources = {};
517
+ this._model_parameters = {};
518
+ this._model_meta = {};
519
+
520
+ // Drop event callbacks
521
+ this._atom_click_events = {};
522
+ this._atom_click_defaults = {};
523
+ this._atom_box_event = null;
524
+ this._notifications = [];
525
+ this._model_list_change_cbs = [];
526
+ this._display_change_cbs = [];
527
+ this._camera_change_cbs = [];
528
+ }
529
+
318
530
  centerCamera(center = [0, 0, 0], shift = [0, 0]) {
319
531
  const renderer = this._renderer;
320
532
 
@@ -336,9 +548,16 @@ class CrystVis {
336
548
  * - `vdwScaling`: scale van der Waals radii by a constant factor
337
549
  * - `vdwElementScaling`: table of per-element factors to scale VdW radii by
338
550
  *
339
- * @return {Object} Names of the models we tried to load, and values of true/false for successful loading or not
551
+ * @return {Object} Status map of the models we tried to load. Keys are the model names (strings that can be
552
+ * passed directly to `displayModel()`). Values are `0` for a successful load, or an error
553
+ * message string if loading failed. Example: to display the first loaded model, use
554
+ * `visualizer.displayModel(Object.keys(loaded)[0])` and check
555
+ * `loaded[modelName] !== 0` to detect errors.
340
556
  */
341
557
  loadModels(contents, format = 'cif', prefix = null, parameters = {}) {
558
+ if (this._isDisposed) {
559
+ throw new Error('CrystVis: cannot call loadModels() on a disposed instance');
560
+ }
342
561
  // clear existing notifications
343
562
  this.clearNotifications();
344
563
 
@@ -379,9 +598,13 @@ class CrystVis {
379
598
  continue;
380
599
  }
381
600
  this._models[nn] = new Model(s, parameters);
601
+ this._model_sources[nn] = { text: contents, extension: format };
602
+ this._model_parameters[nn] = JSON.parse(JSON.stringify(parameters));
603
+ this._model_meta[nn] = { prefix: prefix, originalName: n };
382
604
  status[nn] = 0; // Success
383
605
  }
384
606
 
607
+ this._emitModelListChange();
385
608
  return status;
386
609
  }
387
610
 
@@ -392,6 +615,9 @@ class CrystVis {
392
615
  * @param {Object} parameters Loading parameters as in .loadModels()
393
616
  */
394
617
  reloadModel(name, parameters = {}) {
618
+ if (this._isDisposed) {
619
+ throw new Error('CrystVis: cannot call reloadModel() on a disposed instance');
620
+ }
395
621
  // clear existing notifications from scene
396
622
  this.clearNotifications();
397
623
 
@@ -409,6 +635,7 @@ class CrystVis {
409
635
  parameters = _.merge(model_parameter_defaults, parameters);
410
636
 
411
637
  this._models[name] = new Model(s, parameters);
638
+ this._model_parameters[name] = JSON.parse(JSON.stringify(parameters));
412
639
 
413
640
  if (current) {
414
641
  this.displayModel(name);
@@ -422,6 +649,9 @@ class CrystVis {
422
649
  * clear the renderer window.
423
650
  */
424
651
  displayModel(name = null) {
652
+ if (this._isDisposed) {
653
+ throw new Error('CrystVis: cannot call displayModel() on a disposed instance');
654
+ }
425
655
 
426
656
  if (this._current_model) {
427
657
  // clear notifications from previous model
@@ -435,6 +665,7 @@ class CrystVis {
435
665
 
436
666
  if (!name) {
437
667
  // If called with nothing, just quit here
668
+ this._emitDisplayChange();
438
669
  return;
439
670
  }
440
671
 
@@ -464,6 +695,7 @@ class CrystVis {
464
695
  this._renderer.resetOrbitCenter(c[0], c[1], c[2]);
465
696
 
466
697
  this._displayed.show();
698
+ this._emitDisplayChange();
467
699
  }
468
700
 
469
701
  /**
@@ -482,6 +714,10 @@ class CrystVis {
482
714
  }
483
715
 
484
716
  delete this._models[name];
717
+ delete this._model_sources[name];
718
+ delete this._model_parameters[name];
719
+ delete this._model_meta[name];
720
+ this._emitModelListChange();
485
721
  }
486
722
 
487
723
  /**
package/outdated.txt CHANGED
@@ -1,12 +1,9 @@
1
- Package Current Wanted Latest Location Depended by
2
- @babel/eslint-parser 7.28.0 7.28.6 7.28.6 node_modules/@babel/eslint-parser crystvis-js
3
- chai 5.2.1 5.3.3 6.2.2 node_modules/chai crystvis-js
4
- chroma-js 3.1.2 3.2.0 3.2.0 node_modules/chroma-js crystvis-js
5
- esbuild 0.25.6 0.25.12 0.27.2 node_modules/esbuild crystvis-js
6
- eslint 9.31.0 9.39.2 9.39.2 node_modules/eslint crystvis-js
7
- glob 11.1.0 11.1.0 13.0.0 node_modules/glob crystvis-js
8
- jquery 3.7.1 3.7.1 4.0.0 node_modules/jquery crystvis-js
9
- jsdoc 4.0.4 4.0.5 4.0.5 node_modules/jsdoc crystvis-js
10
- mathjs 14.5.3 14.9.1 15.1.0 node_modules/mathjs crystvis-js
11
- mocha 11.7.1 11.7.5 11.7.5 node_modules/mocha crystvis-js
12
- three 0.178.0 0.178.0 0.182.0 node_modules/three crystvis-js
1
+ Package Current Wanted Latest Location Depended by
2
+ chai 5.3.3 5.3.3 6.2.2 node_modules/chai crystvis-js
3
+ esbuild 0.25.12 0.25.12 0.27.3 node_modules/esbuild crystvis-js
4
+ eslint 9.39.2 9.39.4 10.0.3 node_modules/eslint crystvis-js
5
+ glob 11.1.0 11.1.0 13.0.6 node_modules/glob crystvis-js
6
+ jquery 3.7.1 3.7.1 4.0.0 node_modules/jquery crystvis-js
7
+ mathjs 14.9.1 14.9.1 15.1.1 node_modules/mathjs crystvis-js
8
+ serve 14.2.5 14.2.6 14.2.6 node_modules/serve crystvis-js
9
+ three 0.178.0 0.178.0 0.183.2 node_modules/three crystvis-js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ccp-nc/crystvis-js",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "A Three.js based crystallographic visualisation tool",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -69,15 +69,16 @@
69
69
  },
70
70
  "homepage": "https://github.com/ccp-nc/crystvis-js#readme",
71
71
  "dependencies": {
72
- "@ccp-nc/crystcif-parse": "^0.2.9",
72
+ "@ccp-nc/crystcif-parse": "^0.3.0",
73
73
  "@jkshenton/three-bmfont-text": "^4.0.1",
74
74
  "buffer": "^6.0.3",
75
75
  "chroma-js": "^3.2.0",
76
76
  "isosurface": "^1.0.0",
77
77
  "jquery": "^3.7.1",
78
78
  "load-bmfont": "^1.4.2",
79
- "lodash": "^4.17.21",
79
+ "lodash": "^4.17.23",
80
80
  "mathjs": "^14.9.1",
81
+ "mendeleev": "^1.2.2",
81
82
  "three": "^0.178.0",
82
83
  "yargs-parser": "^22.0.0"
83
84
  },
@@ -88,16 +89,17 @@
88
89
  "clean-jsdoc-theme": "^4.3.0",
89
90
  "datauri": "^4.1.0",
90
91
  "esbuild": "^0.25.12",
91
- "eslint": "^9.39.2",
92
+ "eslint": "^9.39.4",
92
93
  "gh-pages": "^6.3.0",
93
94
  "glob": "^11.1.0",
94
95
  "jpeg-js": "^0.4.4",
95
96
  "jsdoc": "^4.0.5",
97
+ "jsdom": "^27.0.1",
96
98
  "minimist": "^1.2.8",
97
99
  "mocha": "^11.7.5",
98
100
  "msdf-bmfont-xml": "^2.8.0",
99
101
  "npm-watch": "^0.13.0",
100
- "serve": "^14.2.5"
102
+ "serve": "^14.2.6"
101
103
  },
102
104
  "overrides": {
103
105
  "minimist": "$minimist"
@@ -0,0 +1,62 @@
1
+ #$magres-abinitio-v1.0
2
+ # Synthetic magres file for testing H:Mu custom-species handling
3
+ [calculation]
4
+ calc_code CASTEP
5
+ calc_code_version 25.1
6
+ calc_pspot H:Mu 1|0.6|13|15|17|10(qc=8)
7
+ [/calculation]
8
+ [atoms]
9
+ units lattice Angstrom
10
+ lattice 1.0000000000000000E+01 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 1.0000000000000000E+01 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 1.0000000000000000E+01
11
+ units atom Angstrom
12
+ atom H H 1 1.0000000000000000E+00 2.0000000000000000E+00 3.0000000000000000E+00
13
+ atom H:Mu H:Mu 1 4.0000000000000000E+00 5.0000000000000000E+00 6.0000000000000000E+00
14
+ [/atoms]
15
+ [magres]
16
+ [/magres]
17
+ [magres_old]
18
+ ==========================================================================
19
+ Using the following values of the magnetogyric ratio
20
+ H Isotope 1 GAMMA = 2.6752E+08 rad T-1 s-1
21
+ H:Mu User defined. GAMMA = 8.5162E+08 rad T-1 s-1
22
+ ==========================================================================
23
+
24
+ ============
25
+ Atom: H 1
26
+ ============
27
+ H 1 Coordinates 1.000 2.000 3.000 A
28
+
29
+ TOTAL tensor
30
+
31
+ 1.0000 0.0000 0.0000
32
+ 0.0000 2.0000 0.0000
33
+ 0.0000 0.0000 3.0000
34
+
35
+ H 1 Eigenvalue A_xx 1.0000
36
+ H 1 Eigenvector A_xx 1.0000 0.0000 0.0000
37
+ H 1 Eigenvalue A_yy 2.0000
38
+ H 1 Eigenvector A_yy 0.0000 1.0000 0.0000
39
+ H 1 Eigenvalue A_zz 3.0000
40
+ H 1 Eigenvector A_zz 0.0000 0.0000 1.0000
41
+
42
+ H 1 Iso: 2.0000 (MHz)
43
+ ============
44
+ Atom: H:Mu 1
45
+ ============
46
+ H:Mu 1 Coordinates 4.000 5.000 6.000 A
47
+
48
+ TOTAL tensor
49
+
50
+ -10.0000 1.0000 0.0000
51
+ 1.0000 -20.0000 0.0000
52
+ 0.0000 0.0000 -30.0000
53
+
54
+ H:Mu 1 Eigenvalue A_xx -10.0000
55
+ H:Mu 1 Eigenvector A_xx 1.0000 0.0000 0.0000
56
+ H:Mu 1 Eigenvalue A_yy -20.0000
57
+ H:Mu 1 Eigenvector A_yy 0.0000 1.0000 0.0000
58
+ H:Mu 1 Eigenvalue A_zz -30.0000
59
+ H:Mu 1 Eigenvector A_zz 0.0000 0.0000 1.0000
60
+
61
+ H:Mu 1 Iso: -20.0000 (MHz)
62
+ [/magres_old]
@@ -0,0 +1,61 @@
1
+ #$magres-abinitio-v1.0
2
+ # Synthetic magres file for testing HF tensor parsing from magres_old block
3
+ [calculation]
4
+ calc_code CASTEP
5
+ calc_code_version 25.1
6
+ [/calculation]
7
+ [atoms]
8
+ units lattice Angstrom
9
+ lattice 1.0000000000000000E+01 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 1.0000000000000000E+01 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 1.0000000000000000E+01
10
+ units atom Angstrom
11
+ atom H H 1 1.0000000000000000E+00 2.0000000000000000E+00 3.0000000000000000E+00
12
+ atom C C 1 4.0000000000000000E+00 5.0000000000000000E+00 6.0000000000000000E+00
13
+ [/atoms]
14
+ [magres]
15
+ [/magres]
16
+ [magres_old]
17
+ ==========================================================================
18
+ Using the following values of the magnetogyric ratio
19
+ H Isotope 1 GAMMA = 2.6752E+08 rad T-1 s-1
20
+ C Isotope 13 GAMMA = 6.7283E+07 rad T-1 s-1
21
+ ==========================================================================
22
+
23
+ ============
24
+ Atom: H 1
25
+ ============
26
+ H 1 Coordinates 1.000 2.000 3.000 A
27
+
28
+ TOTAL tensor
29
+
30
+ 1.2345 -0.5678 0.1234
31
+ -0.5678 2.3456 0.4567
32
+ 0.1234 0.4567 3.4567
33
+
34
+ H 1 Eigenvalue A_xx 0.9985
35
+ H 1 Eigenvector A_xx 0.9730 0.2304 -0.0220
36
+ H 1 Eigenvalue A_yy 2.4022
37
+ H 1 Eigenvector A_yy -0.2282 0.9623 0.1486
38
+ H 1 Eigenvalue A_zz 3.6361
39
+ H 1 Eigenvector A_zz 0.0530 -0.1432 0.9884
40
+
41
+ H 1 Iso: 2.3456 (MHz)
42
+ ============
43
+ Atom: C 1
44
+ ============
45
+ C 1 Coordinates 4.000 5.000 6.000 A
46
+
47
+ TOTAL tensor
48
+
49
+ 5.0000 1.0000 0.0000
50
+ 1.0000 5.0000 0.0000
51
+ 0.0000 0.0000 3.0000
52
+
53
+ C 1 Eigenvalue A_xx 3.0000
54
+ C 1 Eigenvector A_xx 0.0000 0.0000 1.0000
55
+ C 1 Eigenvalue A_yy 4.0000
56
+ C 1 Eigenvector A_yy -0.7071 0.7071 0.0000
57
+ C 1 Eigenvalue A_zz 6.0000
58
+ C 1 Eigenvector A_zz 0.7071 0.7071 0.0000
59
+
60
+ C 1 Iso: 4.3333 (MHz)
61
+ [/magres_old]