TmCalculator: A Comprehensive Tool for Melting Temperature Calculations

Junhui Li

2026-03-19

Introduction

The TmCalculator package provides comprehensive options for calculating melting temperatures (Tm) of DNA/RNA sequences. This vignette demonstrates the package’s functionality, including:

Installation

# Install required packages
suppressMessages({
  library(BiocManager)
  BiocManager::install(c("Biostrings", "BSgenome", "BSgenome.Hsapiens.UCSC.hg38"))
})
install.packages("TmCalculator")
pak::pkg_install("Gviz")
pak::pkg_install("JunhuiLi1017/TmCalculator@dev")

Basic Usage

Simple Sequence Input with Wallace rule method

# Calculate Tm for simple sequences
seqs <- c("ATGCGCGAAAT", "GCTAGCTAGCT")
names(seqs) <- c("chr1:1-11:+:seq1", "chr2:1-11:+:seq2")
result <- tm_calculate(seqs, method = "tm_wallace")
print(result)
#> $tm
#> GRanges object with 2 ranges and 3 metadata columns:
#>     seqnames    ranges strand |    sequence  complement        Tm
#>        <Rle> <IRanges>  <Rle> | <character> <character> <numeric>
#>   1     chr1      1-11      + | ATGCGCGAAAT TACGCGCTTTA        32
#>   2     chr2      1-11      + | GCTAGCTAGCT CGATCGATCGA        34
#>   -------
#>   seqinfo: 2 sequences from an unspecified genome; no seqlengths

Genomic Coordinate Input with nearest neighbor method

In this example, we calculate the melting temperature of the sequences in the hg38 genome with nearest neighbor method. The coordinates should be in the format of “chr:start-end:+:genome_name:seq_name”

# Example with genomic coordinates
coords <- c(
  "chr1:1898000-1898050:+:BSgenome.Hsapiens.UCSC.hg38:seq1",
  "chr2:2563000-2563050:-:BSgenome.Hsapiens.UCSC.hg38:seq2"
)
result <- tm_calculate(coords)
result
#> $tm
#> GRanges object with 2 ranges and 4 metadata columns:
#>        seqnames          ranges strand |               sequence
#>           <Rle>       <IRanges>  <Rle> |            <character>
#>   seq1     chr1 1898000-1898050      + | AAAAACCCCACAAACCTCCC..
#>   seq2     chr2 2563000-2563050      - | GCAGCCTTTTGAGGAGCCCA..
#>                        genome             complement        Tm
#>                   <character>            <character> <numeric>
#>   seq1 BSgenome.Hsapiens.UC.. TTTTTGGGGTGTTTGGAGGG..   66.2586
#>   seq2 BSgenome.Hsapiens.UC.. CGTCGGAAAACTCCTCGGGT..   78.8140
#>   -------
#>   seqinfo: 2 sequences from an unspecified genome; no seqlengths

The options of the nearest neighbor method are:

result$tm$Options
#> $Ambiguous
#> [1] FALSE
#> 
#> $Shift
#> [1] 0
#> 
#> $`Thermodynamic NN values`
#> [1] "DNA_NN_SantaLucia_2004: SantaLucia J (2004) <doi:10.1146/annurev.biophys.32.110601.141800>"
#> 
#> $`Thermodynamic values for terminal mismatches`
#> [1] "DNA_TMM_Bommarito_2000: Bommarito S (2000)  <doi:10.1093/nar/28.9.1929>"
#> 
#> $`Thermodynamic values for internal mismatches`
#> [1] "DNA_IMM_Peyret_1999: Peyret N (1999) <doi:10.1021/bi9825091> & Allawi H T (1997) <doi:10.1021/bi962590c> & Santalucia N (2005) <doi:10.1093/nar/gki918>"
#> 
#> $`Thermodynamic values for dangling ends`
#> [1] "DNA_DE_Bommarito_2000: Bommarito S (2000) <doi:10.1093/nar/28.9.1929>"
#> 
#> $`Concentration of the higher concentrated strand`
#> [1] 25
#> 
#> $`Concentration of the lower concentrated strand`
#> [1] 25
#> 
#> $`Sequence self-complementary`
#> [1] FALSE
#> 
#> $Na
#> [1] 50
#> 
#> $K
#> [1] 0
#> 
#> $Tris
#> [1] 0
#> 
#> $Mg
#> [1] 0
#> 
#> $dNTPs
#> [1] 0
#> 
#> $`Salt correction method`
#> [1] "Schildkraut2010"
#> 
#> $`Percent of DMSO`
#> [1] 0
#> 
#> $`Formamide concentration`
#> [1] 0
#> 
#> $`Coeffecient of Tm decreases per percent DMSO`
#> [1] 0.75
#> 
#> $`Method for formamide concentration`
#> [1] "percent"
#> 
#> $`Coefficient of Tm decrease per percent formamide`
#> [1] 0.65

FASTA File Processing

In this example, we calculate the melting temperature of the sequences in the fasta file with nearest neighbor method.

# Process sequences from a FASTA file
fasta_file <- system.file("extdata", "example1.fasta", package = "TmCalculator")
result_fa <- tm_calculate(fasta_file)
result_fa
#> $tm
#> GRanges object with 3 ranges and 3 metadata columns:
#>     seqnames            ranges strand |               sequence
#>        <Rle>         <IRanges>  <Rle> |            <character>
#>   1    chr22 13209021-13209099      + | ATGCGATCGATCGATCGATC..
#>   2     chr1              1-76      * | GCAACGACGACGACGACGAC..
#>   3    chr14       13200-13222      * | GCGATCGATCGATCGATCGA..
#>                 complement        Tm
#>                <character> <numeric>
#>   1 TACGCTAGCTAGCTAGCTAG..   69.1147
#>   2 CGTTGCTGCTGCTGCTGCTG..   71.1160
#>   3 CGCTAGCTAGCTAGCTAGCT..   50.7169
#>   -------
#>   seqinfo: 3 sequences from an unspecified genome; no seqlengths

Complementary Sequence with a mismatch

In this example, we calculate the melting temperature of the complementary sequences with nearest neighbor method. there is a mismatch between the two sequences.

GCTAGCCGA[C]AATGGGCAGATAGTAGAAA CGATCGGCT[A]TTACCCGTCTATCATCTTT

# Example with provided complementary sequences
seqs <- c("GCTAGCCGACAATGGGCAGATAGTAGAAA")
comp_seqs <- c("CGATCGGCTATTACCCGTCTATCATCTTT")
result <- tm_calculate(input_seq=seqs,complement_seq=comp_seqs, method="tm_nn")
result
#> $tm
#> GRanges object with 1 range and 3 metadata columns:
#>     seqnames    ranges strand |               sequence             complement
#>        <Rle> <IRanges>  <Rle> |            <character>            <character>
#>   1     chr1      1-29      * | GCTAGCCGACAATGGGCAGA.. CGATCGGCTATTACCCGTCT..
#>            Tm
#>     <numeric>
#>   1   54.2609
#>   -------
#>   seqinfo: 1 sequence from an unspecified genome; no seqlengths

Complementary Sequence with a dangling end and a mismatch

In this example, we calculate the melting temperature of the complementary sequences with nearest neighbor method. there is a dangling end between the two sequences.

GCTAGCCGA[C]AATGGGCAGATAGTAGAAA GATCGGCT[A]TTACCCGTCTATCATCTTT

seqs <- c("GCTAGCCGACAATGGGCAGATAGTAGAAA")
comp_seqs <- c("GATCGGCTATTACCCGTCTATCATCTTT")
result <- tm_calculate(input_seq=seqs,
                       complement_seq=comp_seqs,
                       method="tm_nn",
                       shift=-1)
result
#> $tm
#> GRanges object with 1 range and 3 metadata columns:
#>     seqnames    ranges strand |               sequence             complement
#>        <Rle> <IRanges>  <Rle> |            <character>            <character>
#>   1     chr1      1-29      * | GCTAGCCGACAATGGGCAGA.. GATCGGCTATTACCCGTCTA..
#>            Tm
#>     <numeric>
#>   1   52.3654
#>   -------
#>   seqinfo: 1 sequence from an unspecified genome; no seqlengths

Visualization of Tm values

# Generate sample data with 150 sequences
set.seed(123)

# Generate 100 sequences for chr1
chr1_starts <- sort(sample(1:249250621, 100))  # chr1 length in hg19
chr1_lengths <- sample(50:200, 100, replace=TRUE)
chr1_ends <- chr1_starts + chr1_lengths
chr1_tms <- runif(100, min=60, max=80)

# Generate 50 sequences for chr2
chr2_starts <- sort(sample(1:243199373, 50))   # chr2 length in hg19
chr2_lengths <- sample(50:200, 50, replace=TRUE)
chr2_ends <- chr2_starts + chr2_lengths
chr2_tms <- runif(50, min=60, max=80)

# Create GRanges object
tm_results <- GRanges(
  seqnames = Rle(c(rep("chr1", 100), rep("chr2", 50))),
  ranges = IRanges(
    start = c(chr1_starts, chr2_starts),
    end = c(chr1_ends, chr2_ends)
  ),
  strand = Rle(sample(c("+", "-"), 150, replace=TRUE)),
  Tm = c(chr1_tms, chr2_tms)
)
genome(seqinfo(tm_results)) <- "hg38"

# Example usage by plot_tm_karyotype
plot_tm_karyotype(tm_results, genome_assembly = "hg38")


# Example usage by plot_tm_genome_tracks with custom settings (plot_type=4)
plot_tm_karyotype(tm_results,
                  genome_assembly = "hg38",
                  plot_type = 4,
                  xaxis_cex = 0.5
                  )


# Example usage by plot_tm_genome_tracks with default settings (plot_type=1)
plot_tm_genome_tracks(tm_results, chromosome_to_plot = "chr1", genome_assembly = "hg38")


# Create example GRanges object  
gr_tm <- GenomicRanges::GRanges(
  seqnames = c("chr1", "chr2", "chr1", "chr2", "chr1"),
  ranges = IRanges::IRanges(
    start = c(100, 200, 300, 400, 150),
    end = c(150, 250, 350, 450, 200)
  ),
  Tm = c(65.5, 68.2, 70.1, 63.8, 72.0)
)

# Plot with ideograms
plot_tm_heatmap(gr_tm, genome_assembly = "hg19", plot_type = "karyogram")

# Faceted plot by chromosome
plot_tm_heatmap(gr_tm, genome_assembly = "hg19", plot_type = "faceted")

launch the shiny application

TmCalculatorShiny::TmCalculator_shiny()

Conclusion

The TmCalculator package provides a comprehensive suite of tools for calculating and analyzing melting temperatures of DNA/RNA sequences. The visualization tools help in understanding the genomic context and comparing Tm values across different sequences.

For more information, please refer to the package documentation and examples.