async analyzeStructuralVariant()

in client/client/app/shared/components/ngbVariantDetails/ngbVariantVisualizer/ngbVariantVisualizer.service.js [134:309]


    async analyzeStructuralVariant(variant, selectedGeneFile) {
        const supportedVariants = ['inv', 'bnd', 'del', 'dup'];

        if (supportedVariants.indexOf(variant.type.toLowerCase()) === -1) {
            return {error: `'${  variant.type  }' variant visualization is not supported.`};
        }
        let breakpoints = [];
        const chromosomes = [];
        const genes = {};
        const geneNames = [];
        const domainNames = [];
        const domainColors = {};
        const variantConnections = [];
        let duplicatedGenes = null; // for 'dup' variant only
        if (!variant.interChromosome && variant.type.toLowerCase() === 'inv') {
            breakpoints = [
                {position: variant.startIndex, chromosome: this.chromosome},
                {position: variant.endIndex, chromosome: this.chromosome}
            ];
            variantConnections.push({
                start: {breakpointIndex: 0, attachedAtRight: true},
                end: {breakpointIndex: 1, attachedAtRight: true}
            });
            variantConnections.push({
                start: {breakpointIndex: 1, attachedAtRight: false},
                end: {breakpointIndex: 0, attachedAtRight: false}
            });
        }
        else if (!variant.interChromosome && variant.type.toLowerCase() === 'dup') {
            breakpoints = [
                {position: variant.startIndex, chromosome: this.chromosome},
                {position: variant.endIndex, chromosome: this.chromosome}
            ];
            variantConnections.push({
                start: {breakpointIndex: 0, attachedAtRight: false},
                end: {breakpointIndex: 1, attachedAtRight: true}
            });
            const duplicatedGenesRequestThresholdRange = 100000000;
            const endIndexCorrected = Math.min(variant.endIndex, variant.startIndex + duplicatedGenesRequestThresholdRange);
            const genesInRange = await this._geneDataService.loadGeneTrack({
                startIndex: variant.startIndex,
                endIndex: endIndexCorrected,
                scaleFactor: 0.001,
                chromosomeId: this.chromosome.id,
                id: selectedGeneFile.id
            }, this.referenceId);
            duplicatedGenes = genesInRange.filter(gene => gene.feature.toLowerCase() === 'gene').map(gene => GeneFeatureAnalyzer.updateFeatureName(gene).name);
        }
        else if (!variant.interChromosome && variant.type.toLowerCase() === 'del') {
            breakpoints = [
                {position: variant.startIndex, chromosome: this.chromosome},
                {position: variant.endIndex, chromosome: this.chromosome}
            ];
            variantConnections.push({
                start: {breakpointIndex: 0, attachedAtRight: true},
                end: {breakpointIndex: 1, attachedAtRight: false}
            });
        }
        else {
            breakpoints.push({position: variant.startIndex, chromosome: this.chromosome});
            for (let i = 0; i < variant.alternativeAllelesInfo.length; i++) {
                const altAll = variant.alternativeAllelesInfo[i];
                if (altAll.mate) {
                    breakpoints.push({
                        position: altAll.mate.position,
                        chromosome: {name: altAll.mate.chromosome}
                    });
                    variantConnections.push({
                        start: {
                            breakpointIndex: 0,
                            attachedAtRight: altAll.mate.attachedAt === 'right'
                        }, end: {breakpointIndex: breakpoints.length - 1, attachedAtRight: altAll.mate.reverseComp}
                    });
                }
            }
        }
        breakpoints = Sorting.quickSort(breakpoints, true, x => x.position);

        if (selectedGeneFile) {
            for (let i = 0; i < breakpoints.length; i++) {
                breakpoints[i].affectedGenes = await this.getAffectedGenes(
                    breakpoints[i],
                    selectedGeneFile.id,
                    null,
                    selectedGeneFile.projectIdNumber
                );
                if (!breakpoints[i].affectedGenes || breakpoints[i].affectedGenes.length === 0) {
                    breakpoints[i].affectedGenes = this.getEmptyAffectedGenes(i);
                }
                if (breakpoints[i].affectedGenes.length > 0) {
                    breakpoints[i].affectedGene = breakpoints[i].affectedGenes[0];
                    breakpoints[i].affectedGeneTranscript = breakpoints[i].affectedGene.transcripts[0];
                }
                breakpoints[i].affectedGeneTranscripts = [];
                for (let j = 0; j < breakpoints[i].affectedGenes.length; j++) {
                    const affectedGene = breakpoints[i].affectedGenes[j];
                    if (!affectedGene.empty && affectedGene.transcripts) {
                        breakpoints[i].affectedGeneTranscripts.push(...affectedGene.transcripts);
                    }
                }
            }
        }

        if (duplicatedGenes) {
            for (let i = 0; i < breakpoints.length; i++) {
                if (breakpoints[i].affectedGenes) {
                    for (let j = 0; j < breakpoints[i].affectedGenes.length; j++) {
                        const geneName = breakpoints[i].affectedGenes[j].name || GeneFeatureAnalyzer.updateFeatureName(breakpoints[i].affectedGenes[j]).name;
                        const ind = duplicatedGenes.indexOf(geneName);
                        if (ind >= 0) {
                            duplicatedGenes.splice(ind, 1);
                        }
                    }
                }
            }
        }
        for (let i = 0; i < breakpoints.length; i++) {
            if (chromosomes.indexOf(breakpoints[i].chromosome.name.toLowerCase()) === -1) {
                chromosomes.push(breakpoints[i].chromosome.name.toLowerCase());
            }
            if (breakpoints[i].affectedGene && !breakpoints[i].affectedGene.empty) {
                for (let t = 0; t < breakpoints[i].affectedGene.transcripts.length; t++) {
                    if (breakpoints[i].affectedGene.transcripts[t].domain) {
                        for (let d = 0; d < breakpoints[i].affectedGene.transcripts[t].domain.length; d++) {
                            if (domainNames.indexOf(breakpoints[i].affectedGene.transcripts[t].domain[d].name) === -1) {
                                domainNames.push(breakpoints[i].affectedGene.transcripts[t].domain[d].name);
                                domainColors[breakpoints[i].affectedGene.transcripts[t].domain[d].name] = {
                                    index: domainNames.length - 1
                                };
                            }
                        }
                    }
                }
            }
            if (breakpoints[i].affectedGene !== undefined && breakpoints[i].affectedGene !== null) {
                if (geneNames.indexOf(breakpoints[i].affectedGene.name) === -1) {
                    geneNames.push(breakpoints[i].affectedGene.name);
                    genes[breakpoints[i].affectedGene.name] = {
                        gene: breakpoints[i].affectedGene,
                        chromosome: breakpoints[i].chromosome
                    };
                }
            }
        }

        const altInfos = [];

        if (variant.type.toLowerCase() === 'inv') {
            altInfos.push(this.recoverAlternativeExonStructure(variantConnections[0], breakpoints));
            altInfos.push(this.recoverAlternativeExonStructure(variantConnections[1], breakpoints, true));
        }
        else if (variant.type.toLowerCase() === 'dup') {
            altInfos.push(...this.recoverAlternativeExonStructureForDuplication(breakpoints, variantConnections[0]));
        }
        else {
            for (let i = 0; i < variantConnections.length; i++) {
                altInfos.push(this.recoverAlternativeExonStructure(variantConnections[i], breakpoints));
            }
        }

        return {
            variantInfo: variant,
            chromosomes,
            analysisResult: {
                breakpoints,
                chromosomes,
                genes,
                geneNames,
                duplicatedGeneNames: (duplicatedGenes && duplicatedGenes.length > 0) ? utilities.trimArray(duplicatedGenes) : null,
                variantConnections,
                altInfos,
                domainColors
            },
            geneFile: selectedGeneFile,
        };
    }