Skip to content

Commit

Permalink
Add settings for specifying crap sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
pverscha committed Apr 18, 2024
1 parent 47764de commit 36b2200
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 4 deletions.
92 changes: 92 additions & 0 deletions src/components/pages/SettingsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,55 @@
</v-container>
</v-card-text>
</v-card>
<h2 class="mx-auto settings-category-title">Global analysis settings</h2>
<v-card>
<v-card-text>
<v-container fluid>
<v-row>
<v-col cols="11">
<div class="settings-title">Exclude (cRAP) sequences?</div>
<span class="settings-text">
Use this option if you would like to exclude specific peptides that are
known to be associated with cRAP-proteins. You can specify exactly which
protein sequences should be considered using the text area below.
</span>
</v-col>
<v-col cols="1">
<v-checkbox
class="float-end"
v-model="excludeSequences"
/>
</v-col>
</v-row>
<v-row>
<v-col cols="6">
<v-textarea
filled
v-model="crapSequences"
:disabled="!excludeSequences"
clearable
:rows="8"
/>
</v-col>
<v-divider vertical />
<v-col cols="6">
<div class="d-flex flex-column align-center">
<div class="font-weight-bold">
Or, import sequences from a FASTA file...
</div>
<v-btn
class="mt-2"
@click="importCrapFasta"
:disabled="!excludeSequences"
>
Import from file
</v-btn>
</div>
</v-col>
</v-row>
</v-container>
</v-card-text>
</v-card>
<h2 class="mx-auto settings-category-title">Storage</h2>
<v-card>
<v-card-text>
Expand Down Expand Up @@ -264,6 +313,8 @@ import Rules from "./../validation/Rules";
import { NetworkConfiguration, NetworkUtils } from "unipept-web-components";
import DockerCommunicator from "@/logic/communication/docker/DockerCommunicator";
import Utils from "@/logic/Utils";
import { promises as fs } from "fs";
import FastaParser from "./../../logic/filesystem/fasta/FastaParser";
@Component
export default class SettingsPage extends Vue {
Expand Down Expand Up @@ -342,6 +393,25 @@ export default class SettingsPage extends Vue {
return this.configuration.dockerConfigurationSettings;
}
set excludeSequences(val: boolean) {
this.configuration.crapFilteringEnabled = val;
}
get excludeSequences(): boolean {
return this.configuration.crapFilteringEnabled;
}
set crapSequences(val: string) {
if (val == null) {
val = "";
}
this.configuration.crapSequences = val.split("\r?\n");
}
get crapSequences(): string {
return this.configuration.crapSequences.join("\n");
}
set customDbStorageLocation(value: string) {
this.configuration.customDbStorageLocation = value;
}
Expand Down Expand Up @@ -439,6 +509,28 @@ export default class SettingsPage extends Vue {
}
}
public async importCrapFasta(): Promise<void> {
const { dialog } = require("@electron/remote");
const chosenPath: Electron.OpenDialogReturnValue | undefined = await dialog.showOpenDialog({
properties: ["openFile"],
filters: [
{ name: "FASTA files", extensions: ["fasta"] }
]
});
if (chosenPath && chosenPath.filePaths.length > 0) {
const fastaPath = chosenPath.filePaths[0];
const fastaContent = await fs.readFile(fastaPath, "utf8");
// Now, parse the fasta content and extract the protein sequences
const fastaParser = new FastaParser();
const sequences = fastaParser.extractProteinSequences(fastaContent);
this.crapSequences = sequences.join("\n");
}
}
private showError(message: string): void {
this.errorVisible = true;
this.errorMessage = message;
Expand Down
2 changes: 2 additions & 0 deletions src/logic/configuration/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ export default interface Configuration {
configurationAppVersion: string;
// List of custom Unipept endpoints that were provided to this app.
endpoints: string[];
crapFilteringEnabled: boolean;
crapSequences: string[];
}
17 changes: 14 additions & 3 deletions src/logic/configuration/ConfigurationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ export default class ConfigurationManager {
}
},
(config: Configuration) => config.customDbStorageLocation !== "",
(config: Configuration) => config.endpoints.every(e => this.isUrl(e))
]
(config: Configuration) => config.endpoints.every(e => this.isUrl(e)),
(config: Configuration) => Array.isArray(config.crapSequences),
];

private app: App;

Expand Down Expand Up @@ -69,6 +70,14 @@ export default class ConfigurationManager {
data["endpoints"].push(ConfigurationManager.DEFAULT_ENDPOINT);
}

if (!data["crapSequences"] || !Array.isArray(data["crapSequences"])) {
data["crapSequences"] = [];
}

if (!data["crapFilteringEnabled"]) {
data["crapFilteringEnabled"] = false;
}

if (!this.isValidConfiguration(data)) {
ConfigurationManager.currentConfiguration = await this.getDefaultConfiguration();
return ConfigurationManager.currentConfiguration;
Expand All @@ -93,7 +102,9 @@ export default class ConfigurationManager {
Utils.isWindows() ? DockerCommunicator.WINDOWS_DEFAULT_SETTINGS : DockerCommunicator.UNIX_DEFAULT_SETTINGS,
customDbStorageLocation: customDbDir,
configurationAppVersion: this.app.getVersion(),
endpoints: ["https://api.unipept.ugent.be/"]
endpoints: ["https://api.unipept.ugent.be/"],
crapFilteringEnabled: false,
crapSequences: []
}
}

Expand Down
41 changes: 41 additions & 0 deletions src/logic/filesystem/fasta/FastaParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export default class FastaParser {
/**
* This function reads in a FASTA string and extracts all protein sequences from this string and returns them as an
* array of strings.
*
* @param fasta
*/
public extractProteinSequences(fasta: string): string[] {
// Split the input string into lines
const lines = fasta.trim().split("\n");

// Initialize an empty array to hold the sequences
const sequences: string[] = [];

// Initialize an empty string to hold the current sequence
let currentSequence = "";

// Iterate over each line
for (const line of lines) {
// If the line starts with '>', it's a description line
if (line.startsWith(">")) {
// If there's a current sequence, add it to the sequences array
if (currentSequence) {
sequences.push(currentSequence);
}
// Start a new sequence
currentSequence = "";
} else {
// If the line doesn't start with '>', it's a sequence line, so add it to the current sequence
currentSequence += line;
}
}

// If there's a current sequence at the end, add it to the sequences array
if (currentSequence) {
sequences.push(currentSequence);
}

return sequences;
}
}
2 changes: 1 addition & 1 deletion src/logic/filesystem/study/StudyFileSystemDataWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class StudyFileSystemDataWriter extends FileSystemStudyVisitor {
public async visitStudy(study: Study): Promise<void> {
try {
// Make study directory if it does not exist yet...
await mkdirp(`${this.studyPath}`);
await mkdirp(this.studyPath);

await this.dbManager.performQuery<void>((db: Database) => {
db.prepare("REPLACE INTO studies (id, name) VALUES (?, ?)").run(study.getId(), study.getName())
Expand Down

0 comments on commit 36b2200

Please sign in to comment.