Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
timoast committed May 11, 2021
2 parents 67deb62 + f992267 commit 342199d
Show file tree
Hide file tree
Showing 14 changed files with 289 additions and 18 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: Signac
Title: Analysis of Single-Cell Chromatin Data
Version: 1.2.0
Date: 2021-04-28
Version: 1.2.1
Date: 2021-05-11
Authors@R: c(
person(given = 'Tim', family = 'Stuart', email = 'tstuart@nygenome.org', role = c('aut', 'cre'), comment = c(ORCID = '0000-0002-3044-0897')),
person(given = 'Avi', family = 'Srivastava', email = 'asrivastava@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0001-9798-2079')),
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ S3method(SetMotifData,Seurat)
S3method(as.ChromatinAssay,Assay)
S3method(dim,Motif)
S3method(dimnames,Motif)
S3method(head,Fragment)
S3method(merge,ChromatinAssay)
S3method(subset,ChromatinAssay)
S3method(subset,Motif)
Expand Down
14 changes: 14 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Signac 1.2.1

New functionality:

* Added `head()` method for `Fragment`-class objects.

Bug fixes:

* Fixed bug in `ChromatinAssay` merging ([#596](https://github.com/timoast/signac/pull/596))

Other changes:

* Added support for fragment files containing headers (cellranger-atac v2; [#609](https://github.com/timoast/signac/issues/609))

# Signac 1.2.0

New functionality:
Expand Down
26 changes: 26 additions & 0 deletions R/fragments.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@
#'
NULL

#' Return the first rows of a fragment file
#'
#' Returns the first \code{n} rows of a fragment file. This allows the content
#' of a fragment file to be inspected.
#'
#' @param x a \code{Fragment} object
#' @param n an integer specifying the number of rows to return from the fragment
#' file
#' @param ... additional arguments passed to \code{\link[utils]{read.table}}
#'
#' @return The first \code{n} rows of a fragment file as a \code{data.frame}
#' with the following columns: chrom, start, end, barcode, readCount.
#'
#' @export
#' @method head Fragment
#' @concept fragments
#'
head.Fragment <- function(x, n = 6L, ...) {
fpath <- GetFragmentData(object = x, slot = "path")
df <- read.table(file = fpath, nrows = n, ...)
if (ncol(x = df) == 5) {
colnames(x = df) <- c("chrom", "start", "end", "barcode", "readCount")
}
return(df)
}

#' Count fragments
#'
#' Count total fragments per cell barcode present in a fragment file.
Expand Down
4 changes: 2 additions & 2 deletions R/objects.R
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,7 @@ merge.ChromatinAssay <- function(
if (all(count_nonzero > 0)) {
merged.counts <- RowMergeSparseMatrices(
mat1 = all.counts[[1]],
mat2 = all.counts[[2:length(x = all.counts)]]
mat2 = all.counts[2:length(x = all.counts)]
)
reduced.ranges <- StringToGRanges(regions = rownames(x = merged.counts))
} else {
Expand All @@ -1157,7 +1157,7 @@ merge.ChromatinAssay <- function(
if (all(data_nonzero > 0)) {
merged.data <- RowMergeSparseMatrices(
mat1 = all.data[[1]],
mat2 = all.data[[2:length(x = all.data)]]
mat2 = all.data[2:length(x = all.data)]
)
reduced.ranges <- SetIfNull(
x = reduced.ranges,
Expand Down
9 changes: 8 additions & 1 deletion R/preprocessing.R
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ CreateMotifMatrix <- function(
}
}
rownames(motif.matrix) <- GRangesToString(grange = features, sep = sep)
if (is.null(x = names(x = pwm))) {
warning("No 'names' attribute found in PFMatrixList. ",
"Extracting names from individual entries.")
colnames(x = motif.matrix) <- vapply(
X = pwm, FUN = slot, FUN.VALUE = "character", "name"
)
}
return(motif.matrix)
}

Expand Down Expand Up @@ -752,7 +759,7 @@ TSSEnrichment <- function(

# exclude chrM
sn <- seqnames(x = tss.positions)
tss.positions <- tss.positions[!as.character(sn) %in% c("chrM", "Mt")]
tss.positions <- tss.positions[!as.character(sn) %in% c("chrM", "Mt", "MT")]

if (fast) {
# just compute the TSS enrichment score without storing the full matrix
Expand Down
Binary file added inst/extdata/fragments_header.tsv.gz
Binary file not shown.
Binary file added inst/extdata/fragments_header.tsv.gz.tbi
Binary file not shown.
25 changes: 25 additions & 0 deletions man/head.Fragment.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 20 additions & 4 deletions src/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,27 @@ int filterCells(
cb_seq.reserve(32);
line_seq.reserve(buffer_length);

// looping over the fragments file
while(gzgets(ifileHandler, buffer, buffer_length) !=0 ){
bool eof_check;
while ((eof_check = gzgets(ifileHandler, buffer, buffer_length)) !=0) {
line_seq.clear();
line_seq.append(buffer);

cb_char = strtok ( buffer, "\t" );
if (line_seq.at(0) != '#') {
break;
}
}

if (!eof_check) {
Rcpp::Rcerr << "Error: fragment file contains header only\n" << std::flush;
gzclose(ifileHandler);
return 1;
}

// looping over the fragments file
do {
line_seq.append(buffer);

cb_char = strtok ( buffer, "\t" );
for (auto i=1; i<=3; i++) {
cb_char = strtok (NULL, "\t");

Expand Down Expand Up @@ -82,7 +96,9 @@ int filterCells(
if (is_ten_mil) {
Rcpp::checkUserInterrupt();
}
}

line_seq.clear();
} while(gzgets(ifileHandler, buffer, buffer_length) !=0 );

//Cleanup
gzclose(ifileHandler);
Expand Down
25 changes: 22 additions & 3 deletions src/group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ SEXP groupCommand(
}

// char * to string extraction
std::string cb_seq;
std::string cb_seq, line_seq;
cb_seq.reserve(32);
line_seq.reserve(buffer_length);

// metadata from fragments file
size_t start, end, reads;
Expand All @@ -64,8 +65,25 @@ SEXP groupCommand(
read_count.assign(num_whitelist_cells, 0);
}

// skip header if present
bool eof_check;
while ((eof_check = gzgets(fileHandler, buffer, buffer_length)) !=0) {
line_seq.clear();
line_seq.append(buffer);

if (line_seq.at(0) != '#') {
break;
}
}

if (!eof_check) {
Rcpp::Rcerr << "Error: fragment file contains header only" << std::flush;
gzclose(fileHandler);
return (Rcpp::DataFrame::create());
}

// looping over the fragments file
while(gzgets(fileHandler, buffer, buffer_length) !=0 ){
do {
cb_char = strtok ( buffer, "\t" );

for (auto i=1; i<=4; i++) {
Expand Down Expand Up @@ -136,7 +154,8 @@ SEXP groupCommand(
if (line_counter % 2000000 == 0) {
Rcpp::checkUserInterrupt();
}
}
line_seq.clear();
} while(gzgets(fileHandler, buffer, buffer_length) !=0 );

//Cleanup
gzclose(fileHandler);
Expand Down
23 changes: 20 additions & 3 deletions src/split.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int splitFragments(
} else {
out->open( fileName.c_str() );
}

streams.push_back(out);
}

Expand Down Expand Up @@ -80,8 +80,25 @@ int splitFragments(
cb_seq.reserve(32);
line_seq.reserve(buffer_length);

// skip header if present
bool eof_check;
while ((eof_check = gzgets(ifileHandler, buffer, buffer_length)) !=0) {
line_seq.clear();
line_seq.append(buffer);

if (line_seq.at(0) != '#') {
break;
}
}

if (!eof_check) {
Rcpp::Rcerr << "Error: fragment file contains header only\n" << std::flush;
gzclose(ifileHandler);
return 1;
}

// looping over the fragments file
while(gzgets(ifileHandler, buffer, buffer_length) !=0 ){
do {
line_seq.clear();
line_seq.append(buffer);

Expand Down Expand Up @@ -124,7 +141,7 @@ int splitFragments(
if (is_ten_mil) {
Rcpp::checkUserInterrupt();
}
}
} while(gzgets(ifileHandler, buffer, buffer_length) !=0 );

// Cleanup
gzclose(ifileHandler);
Expand Down
24 changes: 21 additions & 3 deletions src/validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,29 @@ bool validateCells(
}

// char * to string extraction
std::string cb_seq;
std::string cb_seq, line_seq;
cb_seq.reserve(32);
line_seq.reserve(buffer_length);

// skip header if present
bool eof_check;
while ((eof_check = gzgets(fileHandler, buffer, buffer_length)) !=0) {
line_seq.clear();
line_seq.append(buffer);

if (line_seq.at(0) != '#') {
break;
}
}

if (!eof_check) {
Rcpp::Rcerr << "Error: fragment file contains header only\n" << std::flush;
gzclose(fileHandler);
return (false);
}

// looping over the fragments file
while(gzgets(fileHandler, buffer, buffer_length) !=0 ){
do {
cb_char = strtok ( buffer, "\t" );

for (auto i=1; i<=3; i++) {
Expand Down Expand Up @@ -83,7 +101,7 @@ bool validateCells(
if (line_counter % 2000000 == 0) {
Rcpp::checkUserInterrupt();
}
}
} while(gzgets(fileHandler, buffer, buffer_length) !=0 );

//Cleanup
gzclose(fileHandler);
Expand Down
Loading

0 comments on commit 342199d

Please sign in to comment.