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,
};
}