analyze_ld_structure
Analyze linkage disequilibrium structure around eQTL variants to understand genetic correlations in GTEx genomics data. Specify chromosome, position, window size, and population for LD analysis.
Instructions
Analyze linkage disequilibrium structure around eQTL variants
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chr | Yes | Chromosome (e.g., chr1, chr2, chrX) | |
| position | Yes | Genomic position (1-based) | |
| windowSize | No | Window size around position (default: 100000) | |
| population | No | Population for LD analysis (default: EUR) | EUR |
Implementation Reference
- The core handler function that implements the LD structure analysis by querying variants in a genomic window around the given position, finding the closest variant, calculating variant density bins, and summarizing nearby common variants for LD assessment.async analyzeLDStructure(args: any) { if (!args.chr || !args.position) { throw new Error('chr and position parameters are required for LD analysis'); } if (typeof args.position !== 'number') { throw new Error('position parameter must be a number'); } const windowSize = args.windowSize || 100000; const population = args.population || 'EUR'; // For LD analysis, we need to get variants in the region first const variantResult = await this.apiClient.getVariants({ chromosome: args.chr, pos: [Math.max(1, args.position - windowSize), args.position + windowSize], datasetId: 'gtex_v8', page: 0, itemsPerPage: 100 }); if (variantResult.error) { return { content: [{ type: "text", text: `Error retrieving variants for LD analysis: ${variantResult.error}` }], isError: true }; } const variants = variantResult.data || []; if (variants.length === 0) { return { content: [{ type: "text", text: `No variants found in region ${args.chr}:${args.position - windowSize}-${args.position + windowSize}` }] }; } // Find the closest variant to the query position let closestVariant = variants[0]; let minDistance = Math.abs(closestVariant.pos - args.position); variants.forEach(variant => { const distance = Math.abs(variant.pos - args.position); if (distance < minDistance) { minDistance = distance; closestVariant = variant; } }); let output = `**Linkage Disequilibrium Structure Analysis**\n`; output += `Query Position: ${args.chr}:${args.position.toLocaleString()}\n`; output += `Analysis Window: ±${windowSize.toLocaleString()} bp\n`; output += `Population: ${population}\n`; output += `Variants Found: ${variants.length}\n\n`; output += `**Closest Variant to Query:**\n`; output += `• **${closestVariant.variantId}**\n`; output += ` - Position: ${args.chr}:${closestVariant.pos.toLocaleString()}\n`; output += ` - Distance: ${minDistance.toLocaleString()} bp\n`; output += ` - Alleles: ${closestVariant.ref} → ${closestVariant.alt}\n`; if (closestVariant.snpId && closestVariant.snpId !== 'nan') { output += ` - rsID: ${closestVariant.snpId}\n`; } output += ` - MAF ≥1%: ${closestVariant.maf01 ? 'Yes' : 'No'}\n\n`; // Group variants by distance from query const distanceBins = { '<1kb': variants.filter(v => Math.abs(v.pos - args.position) < 1000).length, '1-10kb': variants.filter(v => Math.abs(v.pos - args.position) >= 1000 && Math.abs(v.pos - args.position) < 10000).length, '10-50kb': variants.filter(v => Math.abs(v.pos - args.position) >= 10000 && Math.abs(v.pos - args.position) < 50000).length, '50kb+': variants.filter(v => Math.abs(v.pos - args.position) >= 50000).length }; output += `**Variant Density by Distance:**\n`; Object.entries(distanceBins).forEach(([bin, count]) => { output += `• ${bin}: ${count} variants\n`; }); // Show nearby high-quality variants const nearbyVariants = variants .filter(v => Math.abs(v.pos - args.position) <= 50000) .filter(v => v.maf01) // Only common variants .sort((a, b) => Math.abs(a.pos - args.position) - Math.abs(b.pos - args.position)) .slice(0, 10); if (nearbyVariants.length > 0) { output += `\n**Nearby Common Variants (MAF ≥1%, within 50kb):**\n`; nearbyVariants.forEach((variant, index) => { const distance = Math.abs(variant.pos - args.position); output += `${(index + 1).toString().padStart(2)}. **${variant.variantId}**\n`; output += ` • Distance: ${distance.toLocaleString()} bp\n`; output += ` • Alleles: ${variant.ref} → ${variant.alt}\n`; if (variant.snpId && variant.snpId !== 'nan') { output += ` • rsID: ${variant.snpId}\n`; } }); } output += `\n**LD Analysis Notes:**\n`; output += `• This analysis identifies variants in the region for LD structure assessment\n`; output += `• True LD calculations require population genetics data (r² values)\n`; output += `• Consider using 1000 Genomes or gnomAD data for detailed LD analysis\n`; output += `• Variants with MAF ≥1% are generally suitable for LD calculations\n`; return { content: [{ type: "text", text: output }] }; }
- src/index.ts:343-370 (schema)Input schema and description for the 'analyze_ld_structure' tool, defining required parameters (chr, position) and optional parameters (windowSize, population).name: "analyze_ld_structure", description: "Analyze linkage disequilibrium structure around eQTL variants", inputSchema: { type: "object", properties: { chr: { type: "string", description: "Chromosome (e.g., chr1, chr2, chrX)" }, position: { type: "integer", description: "Genomic position (1-based)" }, windowSize: { type: "integer", description: "Window size around position (default: 100000)", default: 100000 }, population: { type: "string", description: "Population for LD analysis (default: EUR)", enum: ["EUR", "AFR", "AMR", "EAS", "SAS"], default: "EUR" } }, required: ["chr", "position"] } },
- src/index.ts:705-712 (registration)Dispatch logic in the CallToolRequestHandler that maps incoming tool calls for 'analyze_ld_structure' to the associationHandlers.analyzeLDStructure method, passing validated arguments.if (name === "analyze_ld_structure") { return await associationHandlers.analyzeLDStructure({ chr: args?.chr, position: args?.position, windowSize: args?.windowSize, population: args?.population }); }
- src/index.ts:43-44 (registration)Instantiation of the AssociationHandlers class instance used to invoke the analyzeLDStructure method.const associationHandlers = new AssociationHandlers(); const referenceHandlers = new ReferenceHandlers();