@datagrok/bio 2.11.7 → 2.11.8

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,51 @@
1
+ HELM,Activity
2
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Aze.dV.E.N.dV.Phe_4Me}$$$$,2.1058521
3
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.meM.D-Chg.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$,4.4416509
4
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.D-Cit.N.D-Orn.D-aThr.Phe_4Me}$$$$,5.0234375
5
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Dsu.N.D-Orn.D-aThr.Phe_4Me}$$$$,5.0660219
6
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Tyr_tBu.N.D-Orn.D-aThr.Phe_4Me}$$$$,5.6578050
7
+ PEPTIDE1{aHyp.Hcy.N.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Cys_SEt.N.D-Orn.D-aThr.Phe_4Me}$$$$,7.9036875
8
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.A.D-aThr.Phe_4Me}$$$$,3.8863654
9
+ PEPTIDE1{meI.hHis.Aca.N.T.Tyr_Me.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.dV.Phe_4Me}$$$$,4.6697459
10
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.A.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$,2.7280300
11
+ "PEPTIDE1{meI.Pip.dK.Thr_PO3H2.[L-hArg(Et,Et)].D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$",4.4462886
12
+ PEPTIDE1{meI.hHis.D-Hyp.N.T.dK.Thr_PO3H2.Trp_Ome.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$,4.3900189
13
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.Phe_3Cl.meK.Phe_4Me}$$$$,3.6875632
14
+ PEPTIDE1{Gly_allyl.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Thr_PO3H2.N.D-Orn.D-aThr.Phe_4Me}$$$$,6.1076937
15
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.Nle.D-aThr.Phe_4Me}$$$$,3.2512414
16
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.D-Orn.dF.Phe_4Me}$$$$,7.2294617
17
+ PEPTIDE1{meI.hHis.Aca.N.T.D-Orn.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.pnG.Phe_4Me}$$$$,0.6217819
18
+ PEPTIDE1{meI.Pip.dK.Thr_PO3H2.D-Thz.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.D-Thz.N.D-Orn.D-aThr.Phe_4Me}$$$$,4.4476070
19
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.Nle.aIle.Phe_4Me}$$$$,4.9557114
20
+ PEPTIDE1{meY.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.pnG.Phe_4Me}$$$$,1.3188239
21
+ PEPTIDE1{meI.Aca.N.T.W.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$,7.6897125
22
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.hHis.D-aThr.Phe_4Me}$$$$,4.0970631
23
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.3Pal.D-aThr.Phe_4Me}$$$$,2.7782860
24
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.Thr_PO3H2.D-aThr.Phe_4Me}$$$$,4.9825664
25
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.D-Nle.Phe_4Me}$$$$,4.0829563
26
+ PEPTIDE1{D-Nva.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.pnG.Phe_4Me}$$$$,2.7203233
27
+ PEPTIDE1{meI.Thr_PO3H2.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Cys_SEt.N.Phe_3Cl.aIle.Phe_4Me}$$$$,0.7954721
28
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.seC.Tyr_ab-dehydroMe.meN.E.N.dV.Phe_4Me}$$$$,5.0775967
29
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.meN.E.N.3Pal.D-aThr.Phe_4Me}$$$$,4.1724143
30
+ PEPTIDE1{D-Tic.Hcy.N.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Cys_SEt.N.dV.Phe_4Me}$$$$,3.1429222
31
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.meN.E.N.dV.meF}$$$$,3.1327622
32
+ PEPTIDE1{meI.Aca.N.T.Ser_PO3H2.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.pnG.Phe_4Me}$$$$,3.8640671
33
+ PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.H.P.Phe_4Me}$$$$,4.1827374
34
+ PEPTIDE1{Phe_4Sdihydroorotamido.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.pnG.Phe_4Me}$$$$,2.6165285
35
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.D-Thz.Phe_4Me}$$$$,3.2189791
36
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Met_O2.dV.E.N.H.D-aThr.Phe_4Me}$$$$,1.0362210
37
+ PEPTIDE1{meI.Aca.N.T.D-1Nal.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.H.D-aThr.Phe_4Me}$$$$,3.8830254
38
+ PEPTIDE1{meI.Aca.N.T.meV.Thr_PO3H2.Aca.D-Tyr_Et.Met_O2.D-Dap.Thr_PO3H2.N.H.D-aThr.Phe_4Me}$$$$,5.1701312
39
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.pnG.Phe_4Br.Phe_4Me}$$$$,3.1820068
40
+ PEPTIDE1{meI.Aca.N.T.dK.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.dV.Phe_4Me}$$$$,4.4652672
41
+ PEPTIDE1{meI.Aca.Q.T.W.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.dV.Phe_4Me}$$$$,2.8669512
42
+ PEPTIDE1{meI.hHis.Hcy.Q.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.pnG.N.aMePhe.Phe_4Me}$$$$,3.2571971
43
+ PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.V.Phe_4Me}$$$$,4.4447875
44
+ PEPTIDE1{meI.Aca.Aca.T.dK.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.Thr_PO3H2.Phe_4Me}$$$$,2.4899697
45
+ PEPTIDE1{meI.hHis.Aca.Q.T.W.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Cya.N.F.Phe_4Me}$$$$,0.3957288
46
+ PEPTIDE1{meI.hHis.Aca.Q.T.W.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.pnG.N.F.aIle.Phe_4Me}$$$$,2.9058776
47
+ PEPTIDE1{meI.hHis.Hcy.Q.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.pnG.N.dV.Phe_4Me}$$$$,2.1254258
48
+ PEPTIDE1{meI.Bux.Hcy.Q.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Cys_SEt.N.Bmt.Phe_4Me}$$$$,1.7159123
49
+ PEPTIDE1{D-Tyr_Et.hHis.Aca.Q.T.W.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.dV.Phe_4Me}$$$$,1.5285099
50
+ PEPTIDE1{meI.hHis.Hcy.Q.T.W.Q.Phe_4NH2.dP.Tyr_ab-dehydroMe.dV.E.N.Bmt.Phe_4Me}$$$$,3.9470999
51
+ PEPTIDE1{meI.hHis.Hcy.Q.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.pnG.N.Bmt.Phe_4Me}$$$$,3.7495575
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "Leonid Stolbov",
6
6
  "email": "lstolbov@datagrok.ai"
7
7
  },
8
- "version": "2.11.7",
8
+ "version": "2.11.8",
9
9
  "description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
10
10
  "repository": {
11
11
  "type": "git",
@@ -34,9 +34,9 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@biowasm/aioli": "^3.1.0",
37
- "@datagrok-libraries/bio": "^5.39.2",
37
+ "@datagrok-libraries/bio": "^5.39.5",
38
38
  "@datagrok-libraries/chem-meta": "^1.0.1",
39
- "@datagrok-libraries/ml": "^6.3.53",
39
+ "@datagrok-libraries/ml": "^6.3.55",
40
40
  "@datagrok-libraries/tutorials": "^1.3.6",
41
41
  "@datagrok-libraries/utils": "^4.0.17",
42
42
  "cash-dom": "^8.0.0",
@@ -99,16 +99,23 @@ export async function getEncodedSeqSpaceCol(
99
99
  // sets distance function args in place.
100
100
  options = {scoringMatrix: monomerRes.scoringMatrix,
101
101
  alphabetIndexes: monomerHashToMatrixMap} satisfies mmDistanceFunctionArgs;
102
+ } else if (similarityMetric === MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH) {
103
+ const monomers = Array.from(charCodeMap.keys());
104
+ const monomerRes = await calculateMonomerSimilarity(monomers);
105
+ // the susbstitution matrix contains similarity, but we need distances
106
+ // monomerRes.scoringMatrix.forEach((row, i) => {
107
+ // row.forEach((val, j) => {
108
+ // monomerRes.scoringMatrix[i][j] = 1 - val;
109
+ // });
110
+ // });
111
+ const monomerHashToMatrixMap: {[_: string]: number} = {};
112
+ Object.entries(monomerRes.alphabetIndexes).forEach(([key, value]) => {
113
+ monomerHashToMatrixMap[charCodeMap.get(key)!] = value;
114
+ });
115
+ // sets distance function args in place.
116
+ options = {scoringMatrix: monomerRes.scoringMatrix,
117
+ alphabetIndexes: monomerHashToMatrixMap} satisfies mmDistanceFunctionArgs;
102
118
  }
103
- // else if (similarityMetric === MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH) {
104
- // const alphabetIndexes: any = {};
105
- // let i = 0;
106
- // charCodeMap.forEach((value) => {
107
- // alphabetIndexes[value] = i;
108
- // i++;
109
- // });
110
- // options = {alphabetIndexes};
111
- // }
112
119
  return {seqList, options};
113
120
  }
114
121
 
package/src/package.ts CHANGED
@@ -569,11 +569,15 @@ export async function sequenceSpaceTopMenu(
569
569
  pg.close();
570
570
  }
571
571
  });
572
- const sequenceSpaceResPromise = new Promise<ISequenceSpaceResult | undefined>(async (resolve) => {
573
- resolveF = resolve;
574
- const res = await getSequenceSpace(chemSpaceParams,
575
- options?.[BYPASS_LARGE_DATA_WARNING] ? undefined : progressFunc);
576
- resolve(res);
572
+ const sequenceSpaceResPromise = new Promise<ISequenceSpaceResult | undefined>(async (resolve, reject) => {
573
+ try {
574
+ resolveF = resolve;
575
+ const res = await getSequenceSpace(chemSpaceParams,
576
+ options?.[BYPASS_LARGE_DATA_WARNING] ? undefined : progressFunc);
577
+ resolve(res);
578
+ } catch (e) {
579
+ reject(e);
580
+ }
577
581
  });
578
582
  const sequenceSpaceRes = await sequenceSpaceResPromise;
579
583
  pg.close();
@@ -585,7 +589,13 @@ export async function sequenceSpaceTopMenu(
585
589
  ui.dialog().add(ui.divText(`Sequence space analysis might take several minutes.
586
590
  Do you want to continue?`))
587
591
  .onOK(async () => {
588
- await getSeqSpace();
592
+ await getSeqSpace().catch((err: any) => {
593
+ pg.close();
594
+ const [errMsg, errStack] = errInfo(err);
595
+ _package.logger.error(errMsg, undefined, errStack);
596
+ if (scatterPlot)
597
+ scatterPlot.close();
598
+ });
589
599
  })
590
600
  .onCancel(() => { pg.close(); })
591
601
  .show();
@@ -619,9 +629,11 @@ export async function sequenceSpaceTopMenu(
619
629
  } catch (e) {
620
630
  console.error(e);
621
631
  pg.close();
632
+ const [errMsg, errStack] = errInfo(e);
633
+ _package.logger.error(errMsg, undefined, errStack);
634
+ if (scatterPlot)
635
+ (scatterPlot as unknown as DG.Viewer).close();
622
636
  }
623
-
624
-
625
637
  /* const encodedCol = encodeMonomers(macroMolecule);
626
638
  if (!encodedCol)
627
639
  return;
@@ -720,7 +732,7 @@ export async function compositionAnalysis(): Promise<void> {
720
732
  'Column', selectedCol ? selectedCol.name : colListNames[0], colListNames);
721
733
  ui.dialog({
722
734
  title: 'Composition Analysis',
723
- helpUrl: '/help/domains/bio/macromolecules.md#composition-analysis',
735
+ helpUrl: 'https://datagrok.ai/help/datagrok/solutions/domains/bio/#sequence-composition',
724
736
  })
725
737
  .add(ui.div([
726
738
  colInput,
@@ -7,21 +7,30 @@ import {readDataframe} from './utils';
7
7
  import {_testActivityCliffsOpen} from './activity-cliffs-utils';
8
8
  import {DimReductionMethods} from '@datagrok-libraries/ml/src/reduce-dimensionality';
9
9
 
10
- import {_package} from '../package-test';
11
10
  import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
12
11
  import {BitArrayMetricsNames} from '@datagrok-libraries/ml/src/typed-metrics';
12
+ import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
13
+ import {LIB_DEFAULT, LIB_STORAGE_NAME} from '../utils/monomer-lib';
13
14
 
15
+ import {_package} from '../package-test';
14
16
 
15
17
  category('activityCliffs', async () => {
16
- let actCliffsTableView: DG.TableView;
17
- let actCliffsDf: DG.DataFrame;
18
- let actCliffsTableViewWithEmptyRows: DG.TableView;
19
- let actCliffsDfWithEmptyRows: DG.DataFrame;
20
-
21
18
  let viewList: DG.ViewBase[] = [];
22
19
  let dfList: DG.DataFrame[] = [];
23
20
 
21
+ let monomerLibHelper: IMonomerLibHelper;
22
+ /** Backup actual user's monomer libraries settings */
23
+ let userLibrariesSettings: {};
24
+
25
+
24
26
  before(async () => {
27
+ monomerLibHelper = await getMonomerLibHelper();
28
+ userLibrariesSettings = await grok.dapi.userDataStorage.get(LIB_STORAGE_NAME, true);
29
+
30
+ // Test 'helm' requires default monomer library loaded
31
+ await grok.dapi.userDataStorage.post(LIB_STORAGE_NAME, LIB_DEFAULT, true);
32
+ await monomerLibHelper.loadLibraries(true); // load default libraries
33
+
25
34
  viewList = [];
26
35
  dfList = [];
27
36
  });
@@ -29,14 +38,18 @@ category('activityCliffs', async () => {
29
38
  after(async () => {
30
39
  // for (const df of dfList) grok.shell.closeTable(df);
31
40
  // for (const view of viewList) view.close();
41
+
42
+ // UserDataStorage.put() replaces existing data
43
+ await grok.dapi.userDataStorage.put(LIB_STORAGE_NAME, userLibrariesSettings, true);
44
+ await monomerLibHelper.loadLibraries(true); // load user settings libraries
32
45
  });
33
46
 
34
47
  test('activityCliffsOpens', async () => {
35
- actCliffsDf = await readDataframe(
48
+ const actCliffsDf = await readDataframe(
36
49
  DG.Test.isInBenchmark ? 'test/peptides_motif-with-random_10000.csv' : 'tests/100_3_clustests.csv',
37
50
  );
38
51
  dfList.push(actCliffsDf);
39
- actCliffsTableView = grok.shell.addTableView(actCliffsDf);
52
+ const actCliffsTableView = grok.shell.addTableView(actCliffsDf);
40
53
  viewList.push(actCliffsTableView);
41
54
  const cliffsNum = DG.Test.isInBenchmark ? 6 : 3;
42
55
 
@@ -45,9 +58,9 @@ category('activityCliffs', async () => {
45
58
  });
46
59
 
47
60
  test('activityCliffsWithEmptyRows', async () => {
48
- actCliffsDfWithEmptyRows = await readDataframe('tests/100_3_clustests_empty_vals.csv');
61
+ const actCliffsDfWithEmptyRows = await readDataframe('tests/100_3_clustests_empty_vals.csv');
49
62
  dfList.push(actCliffsDfWithEmptyRows);
50
- actCliffsTableViewWithEmptyRows = grok.shell.addTableView(actCliffsDfWithEmptyRows);
63
+ const actCliffsTableViewWithEmptyRows = grok.shell.addTableView(actCliffsDfWithEmptyRows);
51
64
  viewList.push(actCliffsTableViewWithEmptyRows);
52
65
 
53
66
  await _testActivityCliffsOpen(actCliffsDfWithEmptyRows, DimReductionMethods.UMAP,
@@ -55,10 +68,10 @@ category('activityCliffs', async () => {
55
68
  });
56
69
 
57
70
  test('Helm', async () => {
58
- const df = await _package.files.readCsv('samples/sample_HELM.csv');
71
+ const df = await _package.files.readCsv('data/sample_HELM_50.csv');
59
72
  const view = grok.shell.addTableView(df);
60
73
 
61
74
  await _testActivityCliffsOpen(df, DimReductionMethods.UMAP,
62
- 'HELM', 'Activity', 90, 53, BitArrayMetricsNames.Tanimoto);
75
+ 'HELM', 'Activity', 65, 4, BitArrayMetricsNames.Tanimoto);
63
76
  });
64
77
  });
@@ -5,11 +5,11 @@ import * as DG from 'datagrok-api/dg';
5
5
 
6
6
  import {before, after, category, test, expectArray} from '@datagrok-libraries/utils/src/test';
7
7
 
8
- import {getMonomerLibHelper, toAtomicLevel} from '../package';
8
+ import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
9
+ import {toAtomicLevel} from '../package';
9
10
  import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
10
11
  import {IMonomerLib} from '@datagrok-libraries/bio/src/types/index';
11
- import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
12
- import {LIB_STORAGE_NAME} from '../utils/monomer-lib';
12
+ import {LIB_STORAGE_NAME, LIB_DEFAULT, getUserLibSettings} from '../utils/monomer-lib';
13
13
 
14
14
  const appPath = 'System:AppData/Bio';
15
15
  const fileSource = new DG.FileSource(appPath);
@@ -45,10 +45,10 @@ category('toAtomicLevel', async () => {
45
45
 
46
46
  before(async () => {
47
47
  monomerLibHelper = await getMonomerLibHelper();
48
- userLibrariesSettings = await grok.dapi.userDataStorage.get(LIB_STORAGE_NAME, true);
49
- // Clear settings to test default
50
- await grok.dapi.userDataStorage.put(LIB_STORAGE_NAME, {}, true);
51
- await monomerLibHelper.loadLibraries(true);
48
+ userLibrariesSettings = {...await grok.dapi.userDataStorage.get(LIB_STORAGE_NAME, true)};
49
+ const defaultLib = Object.values(LIB_DEFAULT)[0];
50
+ await monomerLibHelper.selectSpecifiedLibraries([defaultLib]);
51
+ monomerLibHelper.loadLibraries(true);
52
52
 
53
53
  for (const key in testNames) {
54
54
  sourceDf[key] = await fileSource.readCsv(inputPath[key]);
@@ -307,6 +307,22 @@ export class MonomerLibHelper implements IMonomerLibHelper {
307
307
  return new MonomerLib(monomers);
308
308
  }
309
309
 
310
+ /** Reset user settings to the specified library. WARNING: clears user * settings */
311
+ public async selectSpecifiedLibraries(libFileNameList: string[]): Promise<void> {
312
+ const invalidNames = await this.getInvalidFileNames(libFileNameList);
313
+ if (invalidNames.length > 0)
314
+ throw new Error(`Cannot select libraries ${invalidNames}: no such library in the list`);
315
+ const settings = await getUserLibSettings();
316
+ settings.exclude = (await getLibFileNameList()).filter((fileName) => !libFileNameList.includes(fileName));
317
+ await setUserLibSetting(settings);
318
+ }
319
+
320
+ private async getInvalidFileNames(libFileNameList: string[]): Promise<string[]> {
321
+ const availableFileNames = await getLibFileNameList();
322
+ const invalidNames = libFileNameList.filter((fileName) => !availableFileNames.includes(fileName));
323
+ return invalidNames;
324
+ }
325
+
310
326
  // -- Instance singleton --
311
327
  private static _instance: MonomerLibHelper | null = null;
312
328