8149f2d63d04238813b626ab194b45eeaa91e32f hiram Tue Sep 29 15:20:22 2026 -0700 fixup swap directory recognition refs #34360 diff --git src/hg/utils/automation/asmHubMiniMap2ChainNetComposite.pl src/hg/utils/automation/asmHubMiniMap2ChainNetComposite.pl index 92fbce829e5..9ab906bc525 100755 --- src/hg/utils/automation/asmHubMiniMap2ChainNetComposite.pl +++ src/hg/utils/automation/asmHubMiniMap2ChainNetComposite.pl @@ -1,297 +1,302 @@ #!/usr/bin/env perl use strict; use warnings; use FindBin qw($Bin); use lib "$Bin"; use AsmHub; use HgAutomate; use File::Basename; my $argc = scalar(@ARGV); if ($argc != 3) { printf STDERR "usage: asmHubMiniMap2ChainNetComposite.pl asmId ncbiAsmId asmId.names.tab > asmId.miniMap2ChainNet.html\n"; printf STDERR "where asmId is the assembly identifier,\n"; printf STDERR "and asmId.names.tab is naming file for this assembly,\n"; printf STDERR "for UCSC database assemblies, use the third argument asmId.names.tab\n"; printf STDERR " as the Scientific_name for the organism.\n"; exit 255; } # specific to UCSC environment my $dbHost = "hgwdev"; my $asmId = shift; my $ncbiAsmId = shift; my $namesFile = shift; my $targetBuildDir = ""; if ($asmId =~ m/^GC/) { my $gcX = substr($asmId,0,3); my $d0 = substr($asmId,4,3); my $d1 = substr($asmId,7,3); my $d2 = substr($asmId,10,3); my $hubBuildDir = "refseqBuild"; $hubBuildDir = "genbankBuild" if ($gcX eq "GCA"); $targetBuildDir = "/hive/data/genomes/asmHubs/$hubBuildDir/$gcX/$d0/$d1/$d2/$asmId"; } else { $targetBuildDir = "/hive/data/genomes/$asmId"; } # doMiniMap2.pl names buildDir/trackData/miniMap2.$QDb where $QDb is # ucfirst() of the actual query db/accession. Reconstruct the actual # db name/accession, except for a GenArk accession (already starts with # the uppercase 'GC', ucfirst is a no-op there). sub queryDbFromQDb($) { my ($qDb) = @_; return $qDb if ($qDb =~ m/^GC/); return lcfirst($qDb); } my %queryDates; # key is asmId, value is assembly date my %queryCommonName; # key is asmId, value is assembly common name my %querySubmitter; # key is asmId, value is assembly submitter my %fbStats; # key is asmId, value is featureBits measure for chains my %loStats; # key is asmId, value is featureBits measure for lift over open (TD, "ls -d ${targetBuildDir}/trackData/miniMap2.*|") or die "can not ls -d ${targetBuildDir}/trackData/miniMap2.*"; while (my $mm2Dir = ) { chomp $mm2Dir; + # a -swap run's default swapDir is itself named 'miniMap2..swap', + # which also matches this glob alongside its own dateless symlink + # 'miniMap2.' -- skip that real *.swap work directory so this + # query genome is only processed once, via its dateless symlink. + next if ($mm2Dir =~ m/\.swap$/); my $Qdb = basename($mm2Dir); # the hubDateName will translate the accessionId into an asmId # side effect it also returns the date my $accession = &queryDbFromQDb($Qdb); my ($qDate, $qAsmName) = &HgAutomate::hubDateName($accession); my $qAsmId = "${accession}"; if ($accession =~ m/^GC/) { $qAsmId = "${accession}${qAsmName}"; } $queryDates{$qAsmId} = $qDate; my ($qCommonName, undef, $qSubmitter) = &HgAutomate::getAssemblyInfo($dbHost, $qAsmId); $queryCommonName{$qAsmId} = $qCommonName; $querySubmitter{$qAsmId} = $qSubmitter; my $fbTxt = `ls ${targetBuildDir}/trackData/miniMap2.${Qdb}/fb.*chain${Qdb}Link.txt 2> /dev/null`; chomp $fbTxt; if ( -s "${fbTxt}" ) { my $fBits = `cut -d' ' -f5 $fbTxt | tr -d '()%'`; chomp $fBits; $fbStats{$qAsmId} = $fBits; } else { $fbStats{$qAsmId} = "n/a"; } $fbTxt = `ls ${targetBuildDir}/trackData/miniMap2.${Qdb}/fb.*chainLiftOver${Qdb}.txt 2> /dev/null`; chomp $fbTxt; if ( -s "${fbTxt}" ) { my $fBits = `cut -d' ' -f5 $fbTxt | tr -d '()%'`; chomp $fBits; $loStats{$qAsmId} = $fBits; } else { $loStats{$qAsmId} = "n/a"; } } close (TD); my $ncbiAssemblyId = $ncbiAsmId; if ( -s "${namesFile}" ) { $ncbiAssemblyId = `grep -v "^#" $namesFile | cut -f10`; chomp $ncbiAssemblyId; } my $sciName = ${namesFile}; if ( -s "${namesFile}" ) { my $sciName = `grep -v "^#" $namesFile | cut -f5`; chomp $sciName; } my ($tGenome, $tDate, $tSource) = &HgAutomate::getAssemblyInfo($dbHost, $asmId); print <<_EOF_

Description

This track shows regions of this target genome ($tGenome - $tDate - $tSource) that has alignment to other very similar query genomes ("chain" subtracks), and the subset of each chain used to lift over coordinates to that query ("lift over" subtracks). The alignable parts are shown with thick blocks that look like exons. Non-alignable parts between these are shown like introns.

These alignments were made with minimap2 rather than lastz. They are intended for pairs of very similar same-species/same-individual assemblies -- for example the haplotypes of a trio-binned or hifiasm/verkko diploid assembly, or closely related strain assemblies -- where minimap2's splice-free asm5/asm10/asm20 presets do a better job with the larger indels and structural differences seen between such assemblies than lastz's general-purpose scoring does.

Other query genome assemblies aligning to this target genome assembly:

\n"; printf "

Alignments identity

\n"; printf "\n"; printf "\n"; printf "\n"; printf "\n"; printf "\n"; foreach my $oAsmId (@orderedByFBits) { printf ""; if (defined($fbStats{$oAsmId})) { printf "", $fbStats{$oAsmId}; } else { printf ""; } if (defined($loStats{$oAsmId})) { printf "", $loStats{$oAsmId}; } else { printf ""; } printf "\n", $queryCommonName{$oAsmId}, $oAsmId; } printf "
showing percent identity, how much of the target is matched by the query
chainslift
over
common
name
assembly
%s %s %s%s
\n"; print <<_EOF_

Chain Track

The chain tracks shows alignments of the other genome assemblies to the $tGenome/$sciName/$ncbiAssemblyId/$tDate genome using a gap scoring system that allows longer gaps than traditional affine gap scoring systems. It can also tolerate gaps in both query and target genomes simultaneously. These "double-sided" gaps can be caused by local inversions and overlapping deletions in both species.

The chain track displays boxes joined together by either single or double lines. The boxes represent aligning regions. Single lines indicate gaps that are largely due to a deletion in the query assembly or an insertion in the target assembly. Double lines represent more complex gaps that involve substantial sequence in both species. This may result from inversions, overlapping deletions, an abundance of local mutation, or an unsequenced gap in one species.

In the "pack" and "full" display modes, the individual feature names indicate the chromosome, strand, and location (in thousands) of the match for each matching alignment.

There are two different types of chain tracks:

Display Conventions and Configuration

By default, the chains to chromosome-based assemblies are colored based on which chromosome they map to in the aligning organism. To turn off the coloring, check the "off" button next to: Color track based on chromosome.

To display only the chains of one chromosome in the aligning organism, enter the name of that chromosome (e.g. chr4) in box next to: Filter by chromosome.

Methods

Chain track

Each query genome was aligned to the target genome with minimap2, one job per target sequence against the whole query genome. The resulting PAF alignments were converted into PSL format using the pafToPsl program. The PSL alignments were fed into axtChain, which organizes all alignments between a single query chromosome and a single target chromosome into a group and creates a kd-tree out of the gapless subsections (blocks) of the alignments. A dynamic program was then run over the kd-trees to find the maximally scoring chains of these blocks.

Lift over chain track

Each chain was placed with chainNet, trimming it as necessary to fit into sections not already covered by a higher-scoring part of the chain, then classified with netSyntenic and netClass. The program netChainSubset was then used to extract the best/longest syntenic part of that net back out of the chain, giving the chain used to lift over coordinates between the two assemblies.

Credits

minimap2 was developed by Heng Li.

The mash program, used to estimate the divergence between the target and each query assembly and automatically select the minimap2 alignment preset, was developed by Brian Ondov, Todd Treangen, and colleagues at the National Biodefense Analysis and Countermeasures Center and the University of Maryland.

The axtChain program was developed at the University of California at Santa Cruz by Jim Kent with advice from Webb Miller and David Haussler.

The chainNet, netSyntenic, and netClass programs were developed at the University of California Santa Cruz by Jim Kent.

References

Li H. Minimap2: pairwise alignment for nucleotide sequences. Bioinformatics. 2018 Sep 15;34(18):3094-3100. PMID: 29750242; PMC: PMC6137996

Ondov BD, Treangen TJ, Melsted P, Mallonee AB, Bergman NH, Koren S, Phillippy AM. Mash: fast genome and metagenome distance estimation using MinHash. Genome Biol. 2016 Jun 20;17(1):132. PMID: 27323842; PMC: PMC4915045

Kent WJ, Baertsch R, Hinrichs A, Miller W, Haussler D. Evolution's cauldron: duplication, deletion, and rearrangement in the mouse and human genomes. Proc Natl Acad Sci U S A. 2003 Sep 30;100(20):11484-9. PMID: 14500911; PMC: PMC208784

_EOF_ ;