OSCR

CDK12/CDK13 inhibition disrupts transcriptional elongation and replication fork progression in glioblastoma.

Code ↔ Paper

3 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 3 matches
  1. [1] § Methods › SLAM-seq data processing ↔ slamdunk/slamdunk.py, lines 376 to 432 · score 0.63 · SLAMdunk, variant fraction, trimmed, quality, bp, alignment · Report a mismatch
  2. [2] § Methods › SLAM-seq data processing ↔ slamdunk/dunks/filter.py, lines 213 to 315 · score 0.57 · retention strategy, quality, alignment, SlamDunk, filtering, mapping · Report a mismatch
  3. [3] § Methods › Cut&Run data processing ↔ slamdunk/dunks/simulator.py, lines 304 to 372 · score 0.52 · samtools view Sb, mapping, sequenced · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 527 lines · 27 KB · AGPL-3.0 · 1 match

  1. #!/usr/bin/env python
  2. # Copyright (c) 2015 Tobias Neumann, Philipp Rescheneder.
  3. #
  4. # This file is part of Slamdunk.
  5. #
  6. # Slamdunk is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU Affero General Public License as
  8. # published by the Free Software Foundation, either version 3 of the
  9. # License, or (at your option) any later version.
  10. #
  11. # Slamdunk is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU Affero General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Affero General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. #########################################################################
  19. # Main routine for the SLAMdunk analyzer
  20. #########################################################################
  21. # Imports
  22. #########################################################################
  23. from __future__ import print_function
  24. import sys, os, random
  25. from time import sleep
  26. from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, SUPPRESS
  27. from os.path import basename
  28. from joblib import Parallel, delayed
  29. from slamdunk.dunks import tcounter, mapper, filter, deduplicator, snps
  30. from slamdunk.utils.misc import replaceExtension, estimateMaxReadLength
  31. from slamdunk.version import __version__
  32. ########################################################################
  33. # Global variables
  34. ########################################################################
  35. printOnly = False
  36. verbose = False
  37. mainOutput = sys.stderr
  38. logToMainOutput = False
  39. ########################################################################
  40. # Routine definitions
  41. ########################################################################
  42. def getLogFile(path):
  43. if(logToMainOutput):
  44. return mainOutput
  45. else:
  46. log = open(path, "a")
  47. return log
  48. def closeLogFile(log):
  49. if(not logToMainOutput):
  50. log.close()
  51. def message(msg):
  52. print(msg, file=mainOutput)
  53. def error(msg, code=-1):
  54. print(msg, file=mainOutput)
  55. sys.exit(code)
  56. def stepFinished():
  57. print(".", end="", file=mainOutput)
  58. def dunkFinished():
  59. print("", file=mainOutput)
  60. def createDir(directory):
  61. if not os.path.exists(directory):
  62. message("Creating output directory: " + directory)
  63. os.makedirs(directory)
  64. def readSampleFile(fileName):
  65. samples = []
  66. infos = []
  67. with open(fileName, "r") as ins:
  68. for line in ins:
  69. line = line.strip()
  70. if(len(line) > 1):
  71. if(fileName.endswith(".tsv")):
  72. cols = line.split("\t")
  73. elif(fileName.endswith(".csv")):
  74. cols = line.split(",")
  75. else:
  76. raise RuntimeError("Unknown file extension found: " + fileName)
  77. if(len(cols) < 4):
  78. raise RuntimeError("Invalid sample file found: " + fileName)
  79. samples.append(cols[0])
  80. infos.append(cols[1] + ":" + cols[2] + ":" + cols[3])
  81. return samples, infos
  82. def getSamples(bams, runOnly=-1):
  83. samples = []
  84. samplesInfos = []
  85. if len(bams) == 1 and (bams[0].endswith(".tsv") or bams[0].endswith(".csv")):
  86. # Sample file specified
  87. samples, samplesInfos = readSampleFile(bams[0])
  88. else:
  89. # List of BAM files specified
  90. samples = bams
  91. samplesInfos = [""] * len(samples)
  92. if(runOnly > 0):
  93. if(runOnly > len(samples)):
  94. raise RuntimeError("Sample index out of range. " + str(runOnly) + " > " + str(len(samples)) + ". Check -i/--sample-index")
  95. message("Running only job " + str(runOnly))
  96. samples = [ samples[runOnly - 1] ]
  97. samplesInfos = [ samplesInfos[runOnly - 1] ]
  98. elif(runOnly == 0):
  99. raise RuntimeError("Sample index (" + str(runOnly) + ") out of range. Starts with 1. Check -i/--sample-index")
  100. return samples, samplesInfos
  101. def runMap(tid, inputBAM, referenceFile, threads, trim5p, maxPolyA, quantseqMapping, endtoendMapping, topn, sampleDescription, outputDirectory, skipSAM) :
  102. if skipSAM:
  103. outputSAM = os.path.join(outputDirectory, replaceExtension(basename(inputBAM), ".bam", "_slamdunk_mapped"))
  104. else:
  105. outputSAM = os.path.join(outputDirectory, replaceExtension(basename(inputBAM), ".sam", "_slamdunk_mapped"))
  106. outputLOG = os.path.join(outputDirectory, replaceExtension(basename(inputBAM), ".log", "_slamdunk_mapped"))
  107. #sampleName = "sample_" + str(tid)
  108. sampleName = replaceExtension(basename(inputBAM), ".bam", "")
  109. sampleType = "NA"
  110. sampleTime = "-1"
  111. if(sampleDescription != ""):
  112. sampleDescriptions = sampleDescription.split(":")
  113. if(len(sampleDescriptions) >= 1):
  114. sampleName = sampleDescriptions[0]
  115. if(len(sampleDescriptions) >= 2):
  116. typeDict = { 'p': 'pulse', 'c':'chase', 'pulse':'pulse', 'chase':'chase', '':'NA'}
  117. if sampleDescriptions[1] in typeDict:
  118. sampleType = typeDict[sampleDescriptions[1]]
  119. else:
  120. sampleType = sampleDescriptions[1]
  121. if(len(sampleDescriptions) >= 3):
  122. sampleTime = sampleDescriptions[2]
  123. mapper.Map(inputBAM, referenceFile, outputSAM, getLogFile(outputLOG), quantseqMapping, endtoendMapping, threads=threads, trim5p=trim5p, maxPolyA=maxPolyA, topn=topn, sampleId=tid, sampleName=sampleName, sampleType=sampleType, sampleTime=sampleTime, printOnly=printOnly, verbose=verbose)
  124. stepFinished()
  125. def runSam2Bam(tid, bam, threads, outputDirectory):
  126. inputSAM = os.path.join(outputDirectory, replaceExtension(basename(bam), ".sam", "_slamdunk_mapped"))
  127. outputBAM = os.path.join(outputDirectory, replaceExtension(basename(bam), ".bam", "_slamdunk_mapped"))
  128. outputLOG = os.path.join(outputDirectory, replaceExtension(basename(bam), ".log", "_slamdunk_mapped"))
  129. mapper.sort(inputSAM, outputBAM, getLogFile(outputLOG), threads, False, printOnly, verbose)
  130. stepFinished()
  131. def runDedup(tid, bam, outputDirectory) :
  132. outputBAM = os.path.join(outputDirectory, replaceExtension(basename(bam), ".bam", "_dedup"))
  133. outputLOG = os.path.join(outputDirectory, replaceExtension(basename(bam), ".log", "_dedup"))
  134. log = getLogFile(outputLOG)
  135. deduplicator.Dedup(bam, outputBAM, log)
  136. closeLogFile(log)
  137. stepFinished()
  138. def runFilter(tid, bam, bed, mq, minIdentity, maxNM, outputDirectory):
  139. outputBAM = os.path.join(outputDirectory, replaceExtension(basename(bam), ".bam", "_filtered"))
  140. outputLOG = os.path.join(outputDirectory, replaceExtension(basename(bam), ".log", "_filtered"))
  141. filter.Filter(bam, outputBAM, getLogFile(outputLOG), bed, mq, minIdentity, maxNM, printOnly, verbose)
  142. stepFinished()
  143. def runSnp(tid, referenceFile, minCov, minVarFreq, minQual, inputBAM, outputDirectory) :
  144. outputSNP = os.path.join(outputDirectory, replaceExtension(basename(inputBAM), ".vcf", "_snp"))
  145. outputLOG = os.path.join(outputDirectory, replaceExtension(basename(inputBAM), ".log", "_snp"))
  146. snps.SNPs(inputBAM, outputSNP, referenceFile, minVarFreq, minCov, minQual, getLogFile(outputLOG), printOnly, verbose, False)
  147. stepFinished()
  148. def runCount(tid, bam, ref, bed, maxLength, minQual, conversionThreshold, outputDirectory, snpDirectory, vcfFile) :
  149. outputCSV = os.path.join(outputDirectory, replaceExtension(basename(bam), ".tsv", "_tcount"))
  150. outputBedgraphPlus = os.path.join(outputDirectory, replaceExtension(basename(bam), ".bedgraph", "_tcount_plus"))
  151. outputBedgraphMinus = os.path.join(outputDirectory, replaceExtension(basename(bam), ".bedgraph", "_tcount_mins"))
  152. outputLOG = os.path.join(outputDirectory, replaceExtension(basename(bam), ".log", "_tcount"))
  153. if (vcfFile != None) :
  154. inputSNP = vcfFile
  155. elif(snpDirectory != None):
  156. inputSNP = os.path.join(snpDirectory, replaceExtension(basename(bam), ".vcf", "_snp"))
  157. else:
  158. inputSNP = None
  159. if (maxLength == None) :
  160. maxLength = estimateMaxReadLength(bam)
  161. if (maxLength < 0) :
  162. print("Difference between minimum and maximum read length is > 10. Please specify --max-read-length parameter.")
  163. sys.exit(0)
  164. log = getLogFile(outputLOG)
  165. print("Using " + str(maxLength) + " as maximum read length.",file=log)
  166. tcounter.computeTconversions(ref, bed, inputSNP, bam, maxLength, minQual, outputCSV, outputBedgraphPlus, outputBedgraphMinus, conversionThreshold, log)
  167. stepFinished()
  168. return outputCSV
  169. def runAll(args) :
  170. message("slamdunk all")
  171. if args.sampleIndex > -1:
  172. sec = random.randrange(200,2000) / 1000.0
  173. message("Waiting " + str(sec) + " seconds")
  174. sleep(sec)
  175. # Setup slamdunk run folder
  176. outputDirectory = args.outputDir
  177. createDir(outputDirectory)
  178. n = args.threads
  179. referenceFile = args.referenceFile
  180. # Run mapper dunk
  181. dunkPath = os.path.join(outputDirectory, "map")
  182. createDir(dunkPath)
  183. samples, samplesInfos = getSamples(args.files, runOnly=args.sampleIndex)
  184. message("Running slamDunk map for " + str(len(samples)) + " files (" + str(n) + " threads)")
  185. for i in range(0, len(samples)):
  186. bam = samples[i]
  187. if not args.sampleName or len(samples) > 1:
  188. sampleName = replaceExtension(basename(bam), "", "")
  189. else :
  190. sampleName = args.sampleName
  191. sampleInfo = samplesInfos[i]
  192. if sampleInfo == "":
  193. sampleInfo = sampleName + ":" + args.sampleType + ":" + str(args.sampleTime)
  194. tid = i
  195. if args.sampleIndex > -1:
  196. tid = args.sampleIndex
  197. runMap(tid, bam, referenceFile, n, args.trim5, args.maxPolyA, args.quantseq, args.endtoend, args.topn, sampleInfo, dunkPath, args.skipSAM)
  198. dunkFinished()
  199. if(not args.skipSAM):
  200. message("Running slamDunk sam2bam for " + str(len(samples)) + " files (" + str(n) + " threads)")
  201. results = Parallel(n_jobs=1, verbose=verbose)(delayed(runSam2Bam)(tid, samples[tid], n, dunkPath) for tid in range(0, len(samples)))
  202. dunkFinished()
  203. dunkbufferIn = []
  204. for file in samples :
  205. dunkbufferIn.append(os.path.join(dunkPath, replaceExtension(basename(file), ".bam", "_slamdunk_mapped")))
  206. # Run filter dunk
  207. bed = args.bed
  208. if args.filterbed:
  209. bed = args.filterbed
  210. args.multimap = True
  211. if (not args.multimap) :
  212. bed = None
  213. dunkPath = os.path.join(outputDirectory, "filter")
  214. createDir(dunkPath)
  215. message("Running slamDunk filter for " + str(len(samples)) + " files (" + str(n) + " threads)")
  216. results = Parallel(n_jobs=n, verbose=verbose)(delayed(runFilter)(tid, dunkbufferIn[tid], bed, args.mq, args.identity, args.nm, dunkPath) for tid in range(0, len(samples)))
  217. dunkFinished()
  218. # Run filter dunk
  219. dunkbufferOut = []
  220. for file in dunkbufferIn :
  221. dunkbufferOut.append(os.path.join(dunkPath, replaceExtension(basename(file), ".bam", "_filtered")))
  222. dunkbufferIn = dunkbufferOut
  223. dunkbufferOut = []
  224. dunkFinished()
  225. # Run snps dunk only if vcf not specified
  226. snpDirectory = None
  227. vcfFile = None
  228. if not "vcfFile" in args:
  229. dunkPath = os.path.join(outputDirectory, "snp")
  230. createDir(dunkPath)
  231. minCov = args.cov
  232. minVarFreq = args.var
  233. snpThread = n
  234. if(snpThread > 1):
  235. snpThread = int(snpThread / 2)
  236. #if (args.minQual == 0) :
  237. # snpqual = 13
  238. #else :
  239. snpqual = args.minQual
  240. message("Running slamDunk SNP for " + str(len(samples)) + " files (" + str(snpThread) + " threads)")
  241. results = Parallel(n_jobs=snpThread, verbose=verbose)(delayed(runSnp)(tid, referenceFile, minCov, minVarFreq, snpqual, dunkbufferIn[tid], dunkPath) for tid in range(0, len(samples)))
  242. snpDirectory = os.path.join(outputDirectory, "snp")
  243. dunkFinished()
  244. else :
  245. vcfFile = args.vcfFile
  246. # Run count dunk
  247. dunkPath = os.path.join(outputDirectory, "count")
  248. createDir(dunkPath)
  249. message("Running slamDunk tcount for " + str(len(samples)) + " files (" + str(n) + " threads)")
  250. results = Parallel(n_jobs=n, verbose=verbose)(delayed(runCount)(tid, dunkbufferIn[tid], referenceFile, args.bed, args.maxLength, args.minQual, args.conversionThreshold, dunkPath, snpDirectory, vcfFile) for tid in range(0, len(samples)))
  251. dunkFinished()
  252. def run():
  253. ########################################################################
  254. # Argument parsing
  255. ########################################################################
  256. # Info
  257. usage = "SLAMdunk software for analyzing SLAM-seq data"
  258. # Main Parsers
  259. parser = ArgumentParser(description=usage, formatter_class=ArgumentDefaultsHelpFormatter)
  260. parser.add_argument('--version', action='version', version='%(prog)s ' + __version__)
  261. # Initialize Subparsers
  262. subparsers = parser.add_subparsers(help="", dest="command")
  263. # map command
  264. mapparser = subparsers.add_parser('map', help='Map SLAM-seq read data', formatter_class=ArgumentDefaultsHelpFormatter)
  265. mapparser.add_argument('files', action='store', help='Single csv/tsv file (recommended) containing all sample files and sample info or a list of all sample BAM/FASTA(gz)/FASTQ(gz) files' , nargs="+")
  266. mapparser.add_argument("-r", "--reference", type=str, required=True, dest="referenceFile", default=SUPPRESS, help="Reference fasta file")
  267. mapparser.add_argument("-o", "--outputDir", type=str, required=True, dest="outputDir", default=SUPPRESS, help="Output directory for mapped BAM files.")
  268. mapparser.add_argument("-5", "--trim-5p", type=int, required=False, dest="trim5", default=12, help="Number of bp removed from 5' end of all reads.")
  269. mapparser.add_argument("-n", "--topn", type=int, required=False, dest="topn", default=1, help="Max. number of alignments to report per read")
  270. mapparser.add_argument("-a", "--max-polya", type=int, required=False, dest="maxPolyA", default=4, help="Max number of As at the 3' end of a read.")
  271. mapparser.add_argument("-t", "--threads", type=int, required=False, dest="threads", default = 1, help="Thread number")
  272. mapparser.add_argument("-q", "--quantseq", dest="quantseq", action='store_true', required=False, help="Run plain Quantseq alignment without SLAM-seq scoring")
  273. mapparser.add_argument('-e', "--endtoend", action='store_true', dest="endtoend", help="Use a end to end alignment algorithm for mapping.")
  274. mapparser.add_argument('-sn', "--sampleName", type=str, dest="sampleName", required = False, help="Use this sample name for all supplied samples")
  275. mapparser.add_argument('-sy', "--sampleType", type=str, dest="sampleType", required = False, default = "pulse", help="Use this sample type for all supplied samples")
  276. mapparser.add_argument('-st', "--sampleTime", type=int, dest="sampleTime", required = False, default = 0, help="Use this sample time for all supplied samples")
  277. mapparser.add_argument("-i", "--sample-index", type=int, required=False, default=-1, dest="sampleIndex", help="Run analysis only for sample <i>. Use for distributing slamdunk analysis on a cluster (index is 1-based).")
  278. mapparser.add_argument('-ss', "--skip-sam", action='store_true', dest="skipSAM", help="Output BAM while mapping. Slower but, uses less hard disk.")
  279. # filter command
  280. filterparser = subparsers.add_parser('filter', help='Filter SLAM-seq aligned data')
  281. filterparser.add_argument('bam', action='store', help='Bam file(s)' , nargs="+")
  282. filterparser.add_argument("-o", "--outputDir", type=str, required=True, dest="outputDir", help="Output directory for mapped BAM files.")
  283. filterparser.add_argument("-b", "--bed", type=str, required=False, dest="bed", help="BED file, overrides MQ filter to 0")
  284. filterparser.add_argument("-mq", "--min-mq", type=int, required=False, default=2, dest="mq", help="Minimum mapping quality (default: %(default)d)")
  285. filterparser.add_argument("-mi", "--min-identity", type=float, required=False, default=0.95, dest="identity", help="Minimum alignment identity (default: %(default)s)")
  286. filterparser.add_argument("-nm", "--max-nm", type=int, required=False, default=-1, dest="nm", help="Maximum NM for alignments (default: %(default)d)")
  287. filterparser.add_argument("-t", "--threads", type=int, required=False, dest="threads", default=1, help="Thread number (default: %(default)d)")
  288. # snp command
  289. snpparser = subparsers.add_parser('snp', help='Call SNPs on SLAM-seq aligned data', formatter_class=ArgumentDefaultsHelpFormatter)
  290. snpparser.add_argument('bam', action='store', help='Bam file(s)' , nargs="+")
  291. snpparser.add_argument("-o", "--outputDir", type=str, required=True, dest="outputDir", default=SUPPRESS, help="Output directory for mapped BAM files.")
  292. snpparser.add_argument("-r", "--reference", required=True, dest="fasta", type=str, default=SUPPRESS, help="Reference fasta file")
  293. snpparser.add_argument("-c", "--min-coverage", required=False, dest="cov", type=int, help="Minimimum coverage to call variant", default=10)
  294. #snpparser.add_argument("-q", "--min-base-qual", type=int, default=13, required=False, dest="minQual", help="Min base quality for T -> C conversions (default: %(default)d)")
  295. snpparser.add_argument("-f", "--var-fraction", required=False, dest="var", type=float, help="Minimimum variant fraction to call variant", default=0.8)
  296. snpparser.add_argument("-t", "--threads", type=int, required=False, default=1, dest="threads", help="Thread number")
  297. # count command
  298. countparser = subparsers.add_parser('count', help='Count T/C conversions in SLAM-seq aligned data')
  299. countparser.add_argument('bam', action='store', help='Bam file(s)' , nargs="+")
  300. countparser.add_argument("-o", "--outputDir", type=str, required=True, dest="outputDir", default=SUPPRESS, help="Output directory for mapped BAM files.")
  301. countparser.add_argument("-s", "--snp-directory", type=str, required=False, dest="snpDir", default=SUPPRESS, help="Directory containing SNP files.")
  302. countparser.add_argument("-v", "--vcf", type=str, required=False, dest="vcfFile", default=SUPPRESS, help="Externally provided custom variant file.")
  303. countparser.add_argument("-r", "--reference", type=str, required=True, dest="ref", default=SUPPRESS, help="Reference fasta file")
  304. countparser.add_argument("-b", "--bed", type=str, required=True, dest="bed", default=SUPPRESS, help="BED file")
  305. countparser.add_argument("-c", "--conversion-threshold", type=int, dest="conversionThreshold", required=False, default=1,help="Number of T>C conversions required to count read as T>C read (default: %(default)d)")
  306. countparser.add_argument("-l", "--max-read-length", type=int, required=False, dest="maxLength", help="Max read length in BAM file")
  307. countparser.add_argument("-q", "--min-base-qual", type=int, default=27, required=False, dest="minQual", help="Min base quality for T -> C conversions (default: %(default)d)")
  308. countparser.add_argument("-t", "--threads", type=int, required=False, default=1, dest="threads", help="Thread number (default: %(default)d)")
  309. # all command
  310. allparser = subparsers.add_parser('all', help='Run entire SLAMdunk analysis')
  311. allparser.add_argument('files', action='store', help='Single csv/tsv file (recommended) containing all sample files and sample info or a list of all sample BAM/FASTA(gz)/FASTQ(gz) files' , nargs="+")
  312. allparser.add_argument("-r", "--reference", type=str, required=True, dest="referenceFile", help="Reference fasta file")
  313. allparser.add_argument("-b", "--bed", type=str, required=True, dest="bed", help="BED file with 3'UTR coordinates")
  314. allparser.add_argument("-fb", "--filterbed", type=str, required=False, dest="filterbed", help="BED file with 3'UTR coordinates to filter multimappers (activates -m)")
  315. allparser.add_argument("-v", "--vcf", type=str, required=False, dest="vcfFile", default=SUPPRESS, help="Skip SNP step and provide custom variant file.")
  316. allparser.add_argument("-o", "--outputDir", type=str, required=True, dest="outputDir", help="Output directory for slamdunk run.")
  317. allparser.add_argument("-5", "--trim-5p", type=int, required=False, dest="trim5", default=12, help="Number of bp removed from 5' end of all reads (default: %(default)s)")
  318. allparser.add_argument("-a", "--max-polya", type=int, required=False, dest="maxPolyA", default=4, help="Max number of As at the 3' end of a read (default: %(default)s)")
  319. allparser.add_argument("-n", "--topn", type=int, required=False, dest="topn", default=1, help="Max. number of alignments to report per read (default: %(default)s)")
  320. allparser.add_argument("-t", "--threads", type=int, required=False, default=1, dest="threads", help="Thread number (default: %(default)s)")
  321. allparser.add_argument("-q", "--quantseq", dest="quantseq", action='store_true', required=False, help="Run plain Quantseq alignment without SLAM-seq scoring")
  322. allparser.add_argument('-e', "--endtoend", action='store_true', dest="endtoend", help="Use a end to end alignment algorithm for mapping.")
  323. allparser.add_argument('-m', "--multimap", action='store_true', dest="multimap", help="Use reference to resolve multimappers (requires -n > 1).")
  324. allparser.add_argument("-mq", "--min-mq", type=int, required=False, default=2, dest="mq", help="Minimum mapping quality (default: %(default)s)")
  325. allparser.add_argument("-mi", "--min-identity", type=float, required=False, default=0.95, dest="identity", help="Minimum alignment identity (default: %(default)s)")
  326. allparser.add_argument("-nm", "--max-nm", type=int, required=False, default=-1, dest="nm", help="Maximum NM for alignments (default: %(default)s)")
  327. allparser.add_argument("-mc", "--min-coverage", required=False, dest="cov", type=int, help="Minimimum coverage to call variant (default: %(default)s)", default=10)
  328. allparser.add_argument("-mv", "--var-fraction", required=False, dest="var", type=float, help="Minimimum variant fraction to call variant (default: %(default)s)", default=0.8)
  329. allparser.add_argument("-c", "--conversion-threshold", type=int, dest="conversionThreshold", required=False, default=1,help="Number of T>C conversions required to count read as T>C read (default: %(default)d)")
  330. allparser.add_argument("-rl", "--max-read-length", type=int, required=False, dest="maxLength", help="Max read length in BAM file")
  331. allparser.add_argument("-mbq", "--min-base-qual", type=int, default=27, required=False, dest="minQual", help="Min base quality for T -> C conversions (default: %(default)d)")
  332. allparser.add_argument('-sn', "--sampleName", type=str, dest="sampleName", required = False, help="Use this sample name for all supplied samples")
  333. allparser.add_argument('-sy', "--sampleType", type=str, dest="sampleType", required = False, default = "pulse", help="Use this sample type for all supplied samples")
  334. allparser.add_argument('-st', "--sampleTime", type=int, dest="sampleTime", required = False, default = 0, help="Use this sample time for all supplied samples")
  335. allparser.add_argument("-i", "--sample-index", type=int, required=False, default=-1, dest="sampleIndex", help="Run analysis only for sample <i>. Use for distributing slamdunk analysis on a cluster (index is 1-based).")
  336. allparser.add_argument("-ss", "--skip-sam", action='store_true', dest="skipSAM", help="Output BAM while mapping. Slower but, uses less hard disk.")
  337. args = parser.parse_args()
  338. ########################################################################
  339. # Routine selection
  340. ########################################################################
  341. command = args.command
  342. if (command == "map") :
  343. mapper.checkNextGenMapVersion()
  344. outputDirectory = args.outputDir
  345. if args.sampleIndex > -1:
  346. sec = random.randrange(0,2000) / 1000
  347. message("Waiting " + str(sec) + " seconds")
  348. sleep(sec)
  349. createDir(outputDirectory)
  350. n = args.threads
  351. referenceFile = args.referenceFile
  352. samples, samplesInfos = getSamples(args.files, runOnly=args.sampleIndex)
  353. message("Running slamDunk map for " + str(len(samples)) + " files (" + str(n) + " threads)")
  354. for i in range(0, len(samples)):
  355. bam = samples[i]
  356. if not args.sampleName or len(samples) > 1:
  357. sampleName = replaceExtension(basename(bam), "", "")
  358. else :
  359. sampleName = args.sampleName
  360. sampleInfo = samplesInfos[i]
  361. if sampleInfo == "":
  362. sampleInfo = sampleName + ":" + args.sampleType + ":" + str(args.sampleTime)
  363. tid = i
  364. if args.sampleIndex > -1:
  365. tid = args.sampleIndex
  366. runMap(tid, bam, referenceFile, n, args.trim5, args.maxPolyA, args.quantseq, args.endtoend, args.topn, sampleInfo, outputDirectory, args.skipSAM)
  367. dunkFinished()
  368. if not args.skipSAM:
  369. message("Running slamDunk sam2bam for " + str(len(samples)) + " files (" + str(n) + " threads)")
  370. results = Parallel(n_jobs=1, verbose=verbose)(delayed(runSam2Bam)(tid, samples[tid], n, outputDirectory) for tid in range(0, len(samples)))
  371. dunkFinished()
  372. elif (command == "filter") :
  373. outputDirectory = args.outputDir
  374. createDir(outputDirectory)
  375. n = args.threads
  376. message("Running slamDunk filter for " + str(len(args.bam)) + " files (" + str(n) + " threads)")
  377. results = Parallel(n_jobs=n, verbose=verbose)(delayed(runFilter)(tid, args.bam[tid], args.bed, args.mq, args.identity, args.nm, outputDirectory) for tid in range(0, len(args.bam)))
  378. dunkFinished()
  379. elif (command == "snp") :
  380. outputDirectory = args.outputDir
  381. createDir(outputDirectory)
  382. fasta = args.fasta
  383. minCov = args.cov
  384. minVarFreq = args.var
  385. #minQual = args.minQual
  386. minQual = 15
  387. n = args.threads
  388. if(n > 1):
  389. n = int(n / 2)
  390. message("Running slamDunk SNP for " + str(len(args.bam)) + " files (" + str(n) + " threads)")
  391. results = Parallel(n_jobs=n, verbose=verbose)(delayed(runSnp)(tid, fasta, minCov, minVarFreq, minQual, args.bam[tid], outputDirectory) for tid in range(0, len(args.bam)))
  392. dunkFinished()
  393. elif (command == "count") :
  394. outputDirectory = args.outputDir
  395. createDir(outputDirectory)
  396. if "snpDir" in args:
  397. snpDirectory = args.snpDir
  398. else :
  399. snpDirectory = None
  400. if "vcfFile" in args:
  401. vcfFile = args.vcfFile
  402. else :
  403. vcfFile = None
  404. n = args.threads
  405. message("Running slamDunk tcount for " + str(len(args.bam)) + " files (" + str(n) + " threads)")
  406. results = Parallel(n_jobs=n, verbose=verbose)(delayed(runCount)(tid, args.bam[tid], args.ref, args.bed, args.maxLength, args.minQual, args.conversionThreshold, outputDirectory, snpDirectory, vcfFile) for tid in range(0, len(args.bam)))
  407. dunkFinished()
  408. elif (command == "all") :
  409. runAll(args)
  410. dunkFinished()
  411. else:
  412. parser.error("Too few arguments.")
  413. if __name__ == '__main__':
  414. run()

slamdunk.py at commit 14270e5, under AGPL-3.0 · at the source

Overview

Authors: Silje Lier1,2, Sara B Markusson1,2,3, Anja Kocijancic1, Martine Narum2, Solveig O Lund1,3, Bianka Böllering4, Anuja Lipsa5, Mirra L C Søegaard3,6, Idun D Rein7, Petra Santha1,3, Preeti Jain1,3, Anna Lång1,3, Emma Lång1,3, Niklas Meyer1,2, Aparajita Dutta8, Santosh Anand9, Sugith B Badugu10, Gaute J Nesse1,3, Rune J Forstrøm1,3, Arne Klungland1,3
and 10 other authorsAshish Anand11, Steven M Pollard12, Stig O Bøe1,3, Johanne E Rinholm1,2, Katrin B M Frauenknecht4,13, Anna Golebiewska5, Simone P Niclou5,14, Kumar Somyajit10, Mads Lerdrup3,6, Deo P Pandey1,3
14 affiliations
  1. Department of Microbiology, Rikshospitalet, Oslo University Hospital, Oslo, Norway
  2. Institute of Basic Medical Sciences and Institute of Clinical Medicine, University of Oslo, Oslo, Norway
  3. CRESCO, Centre for Embryology and Healthy Development, University of Oslo, Oslo, Norway
  4. Institute of Neuropathology, University Medical Center, Johannes Gutenberg University Mainz, Mainz, Germany
  5. NORLUX Neuro-Oncology Laboratory, Department of Cancer Research, Luxembourg Institute of Health, Strassen, Luxembourg
  6. Center for Chromosome Stability, Department of Cellular and Molecular Medicine, University of Copenhagen, Copenhagen, Denmark
  7. Department of Core Facilities, Institute for Cancer Research, Oslo University Hospital, Oslo, Norway
  8. National Institute of technology, Silchar, India
  9. Division of Biological Sciences, University of Missouri, Columbia, 65211 MO USA
  10. Department of Biochemistry and Molecular Biology, University of Southern Denmark, Odense, Denmark
  11. Department of Computer Science and Engineering, Indian Institute of Technology, Guwahati, Assam India
  12. Institute for Regeneration and Repair & Cancer Research UK Scotland Centre, Edinburgh, United Kingdom
  13. National Center of Pathology, Laboratoire national de santé, Dudelange, Luxembourg
  14. Department of Life Sciences and Medicine, University of Luxembourg, Belval, Luxembourg
Journal: EMBO molecular medicine, volume 18, issue 5, pages 1592-1624
Dates: received 21 August 2025; accepted 9 February 2026; published online 25 March 2026; in print May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s44321-026-00393-w · PMID 41882177 · PMCID PMC13179391 · OpenAlex W7140329029
Open access: gold, a free copy (OpenAlex)
Status: code verified (how the code is found and verified)
Categories: human (organism), mouse (organism), other condition (population), cellular / molecular (subfield)
Methods: Statistics, Machine learning, Evoked potentials, Connectivity, fMRI & imaging, Smoothing, state filtering, decompositions
Keywords: Transcriptional Addiction, Transcriptional Cycle, Transcriptional Cyclin-Dependent Kinases (tCDKs), DNA Replication, Glioblastoma, Cancer, Neuroscience
MeSH: Brain Neoplasms*, CDC2 Protein Kinase*, Cyclin-Dependent Kinases*, DNA Replication*, Glioblastoma*, Transcription Elongation, Genetic*, Animals, Cell Line, Tumor, Cyclin-Dependent Kinase-Activating Kinase, Humans, Mice, RNA Polymerase II (* major topic)
Topic: Cancer-related Molecular Pathways (Oncology, Medicine), according to OpenAlex
Funding: EC | European Health and Digital Executive Agency (HaDEA) (101156161); Norges Forskningsråd (332713); HOD | Helse Sør-Øst RHF (sorost) (HSØ 2018045,HSØ 2021037, HSØ 2024022, HSØ 2025082); UiO | Livsvitenskap, Universitetet i Oslo (SPARK Program); Danmarks Grundforskningsfond (DNRF) (DNRF115); UNIFOR; Fonds National de la Recherche Luxembourg (C20/BM/14646004/GLASS-LUX)
Citations: cited by 4 papers (Europe PMC); 76 references in the paper

Abstract

Glioblastomas are the most prevalent and aggressive malignant brain tumors, characterized by hypertranscription and dependence on neurodevelopmental transcription factors. The transcriptional cycle is regulated by phosphorylation of the C-terminal domain (CTD) of RNA polymerase II (RNAPII) by transcriptional cyclin-dependent kinases (tCDKs), including CDK7, CDK9, CDK12, and CDK13. Here we find that glioblastoma stem cells (GSCs) are selectively sensitive to CDK12/CDK13 inhibition, whereas CDK7 and CDK9 inhibition cause non-specific cytotoxicity. This selective targeting halts GSC and organoid proliferation, curtails GSC invasion and suppresses tumor growth in a xenograft mouse model. In GSCs, CDK12/CDK13 inhibition leads to a rapid and genome-wide loss of serine-2 phosphorylation (pSer2) of the RNAPII CTD, abolishing transcriptional elongation and a transcriptional program sustained by key neurodevelopmental transcription factors. CDK12/CDK13 inhibition unexpectedly arrests DNA replication and replication fork progression in a manner distinct from the effect of inhibiting other tCDKs. This dramatic arrest precedes DNA damage response activation and cell cycle arrest, directly linking RNAPII elongation to replication fork dynamics and revealing a previously unrecognized dependence of DNA replication on CDK12/CDK13-RNAPII regulation.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 3 matches between paragraphs and lines of code.

t-neumann/slamdunk

License: AGPL-3.0
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Commit: 14270e5794d36270f601a88c0bf369899d8ab4a0, 25 April 2024
Languages: Python (31), R (15), Shell (4)
Size: 73 files, 50 scripts
Software Heritage: archived
Found in: the resources table
Holds: README, license file, environment (Dockerfile, environment.yml, requirements.txt, setup.py), tests, continuous integration
Not found: CITATION.cff, documentation
Tools: pysam (8 files), ggplot2 (4 files), NumPy (4 files), BEDTools (3 files), Biopython (3 files), pandas (1 file), SAMtools (1 file)
Availability: 1 check, the latest on 30 September 2026: the link answers
  • 30 September 2026: the link answers
52 files

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 50 scripts, each with its path and the digest of its content;
  • 3 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Other data links

Data availability

The datasets produced in this study are available in the following databases: Cut&Run and SLAM-seq: NCBI’s Gene Expression Omnibus (Edgar et al, 2002), GSE186311 (https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE186311) (https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE186311).

The source data of this paper are collected in the following database record: biostudies:S-SCDT-10_1038-S44321-026-00393-w (https://www.ebi.ac.uk/biostudies/sourcedata/studies/S-SCDT-10_1038-S44321-026-00393-w).

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 30 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 30 authors, 7 keywords, 12 MeSH terms, 7 funders, 76 references, 4 RRIDs.

Cite

This paper

Lier, S., Markusson, S. B., Kocijancic, A., Narum, M., Lund, S. O., Böllering, B., Lipsa, A., Søegaard, M. L. C., Rein, I. D., Santha, P., Jain, P., Lång, A., Lång, E., Meyer, N., Dutta, A., Anand, S., Badugu, S. B., Nesse, G. J., Forstrøm, R. J., . . . Pandey, D. P. (2026). CDK12/CDK13 inhibition disrupts transcriptional elongation and replication fork progression in glioblastoma. EMBO molecular medicine, 18(5), 1592-1624. https://doi.org/10.1038/s44321-026-00393-w

BibTeX

@article{lier2026cdk12,
author = {Lier, Silje and Markusson, Sara B and Kocijancic, Anja and Narum, Martine and Lund, Solveig O and Böllering, Bianka and Lipsa, Anuja and Søegaard, Mirra L C and Rein, Idun D and Santha, Petra and Jain, Preeti and Lång, Anna and Lång, Emma and Meyer, Niklas and Dutta, Aparajita and Anand, Santosh and Badugu, Sugith B and Nesse, Gaute J and Forstrøm, Rune J and Klungland, Arne and Anand, Ashish and Pollard, Steven M and Bøe, Stig O and Rinholm, Johanne E and Frauenknecht, Katrin B M and Golebiewska, Anna and Niclou, Simone P and Somyajit, Kumar and Lerdrup, Mads and Pandey, Deo P},
title = {{CDK12/CDK13 inhibition disrupts transcriptional elongation and replication fork progression in glioblastoma}},
journal = {EMBO molecular medicine},
year = {2026},
month = mar,
volume = {18},
number = {5},
pages = {1592--1624},
publisher = {Nature Publishing Group},
issn = {1757-4676},
doi = {10.1038/s44321-026-00393-w},
url = {https://doi.org/10.1038/s44321-026-00393-w},
pmid = {41882177},
pmcid = {PMC13179391}
}

RIS

TY - JOUR
AU - Lier, Silje
AU - Markusson, Sara B
AU - Kocijancic, Anja
AU - Narum, Martine
AU - Lund, Solveig O
AU - Böllering, Bianka
AU - Lipsa, Anuja
AU - Søegaard, Mirra L C
AU - Rein, Idun D
AU - Santha, Petra
AU - Jain, Preeti
AU - Lång, Anna
AU - Lång, Emma
AU - Meyer, Niklas
AU - Dutta, Aparajita
AU - Anand, Santosh
AU - Badugu, Sugith B
AU - Nesse, Gaute J
AU - Forstrøm, Rune J
AU - Klungland, Arne
AU - Anand, Ashish
AU - Pollard, Steven M
AU - Bøe, Stig O
AU - Rinholm, Johanne E
AU - Frauenknecht, Katrin B M
AU - Golebiewska, Anna
AU - Niclou, Simone P
AU - Somyajit, Kumar
AU - Lerdrup, Mads
AU - Pandey, Deo P
TI - CDK12/CDK13 inhibition disrupts transcriptional elongation and replication fork progression in glioblastoma
T2 - EMBO molecular medicine
J2 - EMBO Mol Med
PY - 2026
DA - 2026/03/25
VL - 18
IS - 5
SP - 1592
EP - 1624
SN - 1757-4676
PB - Nature Publishing Group
DO - 10.1038/s44321-026-00393-w
UR - https://doi.org/10.1038/s44321-026-00393-w
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s44321-026-00393-w",
"type": "article-journal",
"title": "CDK12/CDK13 inhibition disrupts transcriptional elongation and replication fork progression in glioblastoma",
"container-title": "EMBO molecular medicine",
"author": [
{
"family": "Lier",
"given": "Silje"
},
{
"family": "Markusson",
"given": "Sara B"
},
{
"family": "Kocijancic",
"given": "Anja"
},
{
"family": "Narum",
"given": "Martine"
},
{
"family": "Lund",
"given": "Solveig O"
},
{
"family": "Böllering",
"given": "Bianka"
},
{
"family": "Lipsa",
"given": "Anuja"
},
{
"family": "Søegaard",
"given": "Mirra L C"
},
{
"family": "Rein",
"given": "Idun D"
},
{
"family": "Santha",
"given": "Petra"
},
{
"family": "Jain",
"given": "Preeti"
},
{
"family": "Lång",
"given": "Anna"
},
{
"family": "Lång",
"given": "Emma"
},
{
"family": "Meyer",
"given": "Niklas"
},
{
"family": "Dutta",
"given": "Aparajita"
},
{
"family": "Anand",
"given": "Santosh"
},
{
"family": "Badugu",
"given": "Sugith B"
},
{
"family": "Nesse",
"given": "Gaute J"
},
{
"family": "Forstrøm",
"given": "Rune J"
},
{
"family": "Klungland",
"given": "Arne"
},
{
"family": "Anand",
"given": "Ashish"
},
{
"family": "Pollard",
"given": "Steven M"
},
{
"family": "Bøe",
"given": "Stig O"
},
{
"family": "Rinholm",
"given": "Johanne E"
},
{
"family": "Frauenknecht",
"given": "Katrin B M"
},
{
"family": "Golebiewska",
"given": "Anna"
},
{
"family": "Niclou",
"given": "Simone P"
},
{
"family": "Somyajit",
"given": "Kumar"
},
{
"family": "Lerdrup",
"given": "Mads"
},
{
"family": "Pandey",
"given": "Deo P"
}
],
"container-title-short": "EMBO Mol Med",
"volume": "18",
"issue": "5",
"page": "1592-1624",
"DOI": "10.1038/s44321-026-00393-w",
"PMID": "41882177",
"PMCID": "PMC13179391",
"ISSN": "1757-4676",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s44321-026-00393-w",
"language": "en",
"issued": {
"date-parts": [
[
2026,
3,
25
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s41586-026-10612-6 [code]
Acquired genetic and cell-state changes in IDH-mutant glioma progression.
Journal: Nature
In common: pysam, BEDTools, SAMtools, 3 other tools, other condition, cellular / molecular, 1 reference, 2 authors
[2] doi:10.1186/s13073-024-01321-8 [code]
Glioblastoma-instructed microglia transition to heterogeneous phenotypic states with phagocytic and dendritic cell-like features in patient tumors and patient-derived orthotopic xenografts.
Journal: Genome medicine
In common: ggplot2, other condition, mouse, 4 references, 2 authors
[3] doi:10.1093/neuonc/noab269
Cancer cell heterogeneity and plasticity: A paradigm shift in glioblastoma.
Journal: Neuro-oncology
In common: other condition, 7 references, author Anna Golebiewska
[4] doi:10.1093/jnci/djaf295
Targeting CDK12 disrupts estrogen-receptor chromatin recruitment and ER-MED1 transcription in advanced ER+ breast cancer.
Journal: Journal of the National Cancer Institute
In common: other condition, mouse, cellular / molecular, 7 references
[5] doi:10.1038/s41586-026-10329-6 [code]
Synthetic super-enhancers enable precision viral immunotherapy.
Journal: Nature
In common: BEDTools, SAMtools, ggplot2, other condition, mouse, cellular / molecular, 2 references, author Steven M Pollard
[6] doi:10.1038/s41586-026-10512-9 [code]
Astrocyte glucocorticoid receptor signalling restricts neuronal plasticity.
Journal: Nature
In common: pysam, Biopython, BEDTools, 4 other tools, mouse, cellular / molecular, 3 references
[7] doi:10.1126/sciadv.adx6539
Steroid-dependent metabolic rewiring reveals novel therapeutic and imaging approaches for glioblastoma.
Journal: Science advances
In common: other condition, mouse, 6 references, author Steven M Pollard
[8] doi:10.1186/s12915-025-02127-9 [code]
Mapping chromatin remodelling in glioblastoma identifies epigenetic regulation of key molecular pathways and novel druggable targets.
Journal: BMC biology
In common: pandas, NumPy, other condition, cellular / molecular, 9 references
[9] doi:10.1016/j.celrep.2023.112561
Elevated FOXG1 in glioblastoma stem cells cooperates with Wnt/β-catenin to induce exit from quiescence.
Journal: Cell reports
In common: other condition, cellular / molecular, 4 references, author Steven M Pollard
[10] doi:10.1038/s41467-024-51432-4 [code]
Deep intravital brain tumor imaging enabled by tailored three-photon microscopy and analysis.
Journal: Nature communications
In common: NumPy, other condition, mouse, 4 references, author Anna Golebiewska

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/doi/10.1038/s44321-026-00393-w.svg)](https://openscicode.org/badge/doi/10.1038/s44321-026-00393-w)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/doi/10.1038/s44321-026-00393-w.svg
   :target: https://openscicode.org/badge/doi/10.1038/s44321-026-00393-w
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.1038/s44321-026-00393-w"><img src="https://openscicode.org/badge/doi/10.1038/s44321-026-00393-w.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.