Skip to content

Commit 11b3eca

Browse files
authored
Merge pull request #18 from PROBIC/v1.6.2
mSWEEP-v1.6.2 (12 August 2022)
2 parents 52446f8 + c5ef9a9 commit 11b3eca

11 files changed

Lines changed: 112 additions & 40 deletions

CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ set (CMAKE_CXX_STANDARD 11)
3636
set (CMAKE_CXX_STANDARD_REQUIRED ON)
3737

3838
### MPI
39-
find_package(MPI)
40-
if (MPI_FOUND)
39+
if (CMAKE_ENABLE_MPI_SUPPORT)
40+
find_package(MPI REQUIRED)
4141
set(MSWEEP_MPI_SUPPORT 1)
4242
include_directories(MPI_C_INCLUDE_DIRS)
4343
if (CMAKE_MPI_MAX_PROCESSES)
@@ -209,8 +209,9 @@ else()
209209
set_target_properties(telescope PROPERTIES EXCLUDE_FROM_ALL 1)
210210
target_link_libraries(mSWEEP libtelescope)
211211
set(CMAKE_TELESCOPE_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/external/telescope/include)
212+
set(CMAKE_BITMAGIC_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/external/telescope/external/BitMagic-7.12.3/src)
212213
endif()
213-
include_directories(${CMAKE_TELESCOPE_HEADERS})
214+
include_directories(${CMAKE_TELESCOPE_HEADERS} ${CMAKE_BITMAGIC_HEADERS})
214215

215216
## rcgpar
216217
if (DEFINED CMAKE_RCGPAR_LIBRARY AND DEFINED CMAKE_RCGPAR_HEADERS)
@@ -255,6 +256,11 @@ endif()
255256
add_library(msweeptools ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/matchfasta.cpp)
256257
add_executable(matchfasta ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/main.cpp)
257258

259+
if(MPI_FOUND)
260+
add_dependencies(mSWEEP rcgmpi bigmpi)
261+
target_link_libraries(mSWEEP rcgmpi ${LIBRARY_OUTPUT_PATH}/libbigmpi.a)
262+
endif()
263+
258264
# Link libraries
259265
target_link_libraries(mSWEEP ${ZLIB} msweeptools)
260266
target_link_libraries(matchfasta msweeptools)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ mSWEEP with the following commands (example case for Open MPI):
7070
> mkdir build
7171
> cd build
7272
> module load mpi/openmpi
73-
> cmake -DCMAKE_C_COMPILER=mpicc -DCMAKE_CXX_COMPILER=mpicxx ..
73+
> cmake -DCMAKE_ENABLE_MPI_SUPPORT=1 -DCMAKE_C_COMPILER=mpicc -DCMAKE_CXX_COMPILER=mpicxx ..
7474
> make
7575
```
7676

config/CMakeLists-rcgpar.txt.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ include(ExternalProject)
55

66
ExternalProject_Add(rcgpar-download
77
GIT_REPOSITORY https://github.com/tmaklin/rcgpar
8-
GIT_TAG v1.0.0
8+
GIT_TAG v1.0.2
99
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/external/rcgpar"
1010
BUILD_IN_SOURCE 0
1111
BUILD_COMMAND ""
12+
CMAKE_ARGS -D CMAKE_ENABLE_MPI_SUPPORT=${MSWEEP_MPI_SUPPORT}
1213
INSTALL_COMMAND ""
1314
TEST_COMMAND ""
1415
UPDATE_COMMAND ""

config/CMakeLists-telescope.txt.in

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ include(ExternalProject)
55

66
ExternalProject_Add(telescope-download
77
GIT_REPOSITORY https://github.com/tmaklin/telescope.git
8-
GIT_TAG v0.2.1
8+
GIT_TAG v0.4.0
99
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/external/telescope"
1010
BUILD_IN_SOURCE 0
1111
BUILD_COMMAND ""
1212
CMAKE_ARGS -D CMAKE_BXZSTR_HEADERS=${CMAKE_BXZSTR_HEADERS}
1313
-D CMAKE_CXXARGS_HEADERS=${CMAKE_CXXARGS_HEADERS}
14+
-D CMAKE_CXXIO_HEADERS=${CMAKE_CXXIO_HEADERS}
15+
-D CMAKE_BITMAGIC_HEADERS=${CMAKE_CURRENT_BINARY_DIR}/external/telescope/external/BitMagic-7.12.3/src
1416
INSTALL_COMMAND ""
1517
TEST_COMMAND ""
1618
UPDATE_COMMAND ""

include/Sample.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Sample {
2727
std::vector<double> relative_abundances;
2828

2929
// Alignments class from telescope
30-
KallistoAlignment pseudos;
30+
telescope::KallistoAlignment pseudos;
3131

3232
// Calculate log_ec_counts and counts_total.
3333
void process_aln(const bool bootstrap_mode);

include/log.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

5-
#ifndef CXXIO_LOG_HPP
6-
#define CXXIO_LOG_HPP
5+
#ifndef MSWEEP_LOG_HPP
6+
#define MSWEEP_LOG_HPP
77

88
#include <chrono>
99
#include <fstream>

include/msweep_log.hpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4+
5+
#ifndef MSWEEP_LOG_HPP
6+
#define MSWEEP_LOG_HPP
7+
8+
#include <chrono>
9+
#include <fstream>
10+
#include <exception>
11+
#include <string>
12+
13+
#include "cxxio.hpp"
14+
#include "mpi_config.hpp"
15+
16+
class Log : public cxxio::Out {
17+
public:
18+
bool verbose;
19+
bool log_time;
20+
std::chrono::time_point<std::chrono::system_clock> start_time;
21+
22+
Log(std::ostream &_stream, bool _verbose = true, bool _log_time = true) : cxxio::Out(_stream), verbose(_verbose), log_time(_log_time) {
23+
if (this->log_time) {
24+
start_time = std::chrono::system_clock::now();
25+
}
26+
}
27+
void flush() {
28+
if (verbose && log_time) {
29+
std::chrono::time_point<std::chrono::system_clock> end_time = std::chrono::system_clock::now();
30+
std::chrono::duration<double> elapsed_seconds = end_time - start_time;
31+
std::time_t end = std::chrono::system_clock::to_time_t(end_time);
32+
std::string end_s(std::ctime(&end));
33+
end_s.pop_back();
34+
*this << end_s << " elapsed_time: " << elapsed_seconds.count() << "s\n";
35+
}
36+
}
37+
};
38+
39+
template <typename T>
40+
Log& operator<<(Log &os, T t) {
41+
int rank = 0;
42+
#if defined(MSWEEP_MPI_SUPPORT) && (MSWEEP_MPI_SUPPORT) == 1
43+
// Only root will log
44+
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
45+
#endif
46+
if (os.verbose && rank == 0) {
47+
if (os.log_time){
48+
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
49+
std::time_t now_t = std::chrono::system_clock::to_time_t(now);
50+
std::string now_s(std::ctime(&now_t));
51+
now_s.pop_back();
52+
os.stream() << now_s << ' ';
53+
}
54+
os.stream () << t;
55+
if (!os.stream().good() && !os.stream().eof()) {
56+
throw std::runtime_error("Error writing type: " + std::string(typeid(T).name()) + " to file " + os.filename());
57+
}
58+
}
59+
return os;
60+
}
61+
62+
#endif

src/BootstrapSample.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void BootstrapSample::init_bootstrap() {
3232
this->bootstrap_results = std::vector<std::vector<double>>();
3333

3434
// Initialize ec_distribution for bootstrapping
35-
ec_distribution = std::discrete_distribution<uint32_t>(pseudos.ec_counts.begin(), pseudos.ec_counts.end());
35+
ec_distribution = std::discrete_distribution<uint32_t>(pseudos.ec_counts_begin(), pseudos.ec_counts_end());
3636
}
3737

3838
void BootstrapSample::write_bootstrap(const std::vector<std::string> &cluster_indicators_to_string,

src/Sample.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,19 @@
99

1010
void Sample::process_aln(const bool bootstrap_mode) {
1111
cell_id = "";
12-
m_num_ecs = pseudos.ec_counts.size();
12+
m_num_ecs = pseudos.compressed_size();
1313
log_ec_counts.resize(m_num_ecs, 0.0);
1414
uint32_t aln_counts_total = 0;
1515
#pragma omp parallel for schedule(static) reduction(+:aln_counts_total)
1616
for (uint32_t i = 0; i < m_num_ecs; ++i) {
17-
log_ec_counts[i] = std::log(pseudos.ec_counts[i]);
18-
aln_counts_total += pseudos.ec_counts[i];
17+
log_ec_counts[i] = std::log(pseudos.reads_in_ec(i));
18+
aln_counts_total += pseudos.reads_in_ec(i);
1919
}
2020
counts_total = aln_counts_total;
2121

2222
if (!bootstrap_mode) {
2323
// EC counts aren't needed when not bootstrapping.
24-
this->pseudos.ec_counts.clear();
25-
this->pseudos.ec_counts.shrink_to_fit();
24+
this->pseudos.clear_counts();
2625
}
2726
}
2827

@@ -31,7 +30,7 @@ std::vector<uint16_t> Sample::group_counts(const std::vector<uint32_t> indicator
3130
std::vector<uint16_t> read_hitcounts(n_groups);
3231
uint32_t m_num_refs = this->pseudos.n_targets();
3332
for (uint32_t j = 0; j < m_num_refs; ++j) {
34-
read_hitcounts[indicators[j]] += pseudos.ec_configs[ec_id][j];
33+
read_hitcounts[indicators[j]] += pseudos(ec_id, j);
3534
}
3635
return read_hitcounts;
3736
}
@@ -125,7 +124,7 @@ void Sample::read_likelihood(const Grouping &grouping, std::istream &infile) {
125124
uint32_t n_groups = grouping.get_n_groups();
126125

127126
std::vector<std::vector<double>> likelihoods(n_groups, std::vector<double>());
128-
this->pseudos = KallistoAlignment();
127+
this->pseudos = telescope::KallistoAlignment();
129128

130129
if (infile.good()) {
131130
std::string newline;
@@ -140,7 +139,7 @@ void Sample::read_likelihood(const Grouping &grouping, std::istream &infile) {
140139
while (std::getline(partition, part, '\t')) {
141140
if (ec_count_col) {
142141
uint32_t ec_count = std::stol(part);
143-
this->pseudos.ec_counts.emplace_back(ec_count);
142+
this->pseudos.add_counts(ec_count);
144143
ec_count_col = false;
145144
} else {
146145
likelihoods[group_id].emplace_back(std::stod(part));

src/mSWEEP.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ void ReadInput(const Arguments &args, std::vector<std::unique_ptr<Sample>> *samp
2828
if (!args.themisto_mode && !args.read_likelihood_mode) {
2929
// Check that the number of reference sequences matches in the grouping and the alignment.
3030
reference->verify_kallisto_alignment(*args.infiles.run_info);
31-
ReadKallisto(reference->get_n_refs(), *args.infiles.ec, *args.infiles.tsv, &samples->back()->pseudos);
31+
samples->back()->pseudos = telescope::KallistoAlignment(reference->get_n_refs());
32+
telescope::read::Kallisto(*args.infiles.ec, *args.infiles.tsv, &samples->back()->pseudos);
3233
} else if (!args.read_likelihood_mode) {
3334
if (!args.themisto_index_path.empty()) {
3435
try {
@@ -43,7 +44,8 @@ void ReadInput(const Arguments &args, std::vector<std::unique_ptr<Sample>> *samp
4344
cxxio::In forward_strand(args.tinfile1);
4445
cxxio::In reverse_strand(args.tinfile2);
4546
std::vector<std::istream*> strands = { &forward_strand.stream(), &reverse_strand.stream() };
46-
ReadThemisto(get_mode(args.themisto_merge_mode), reference->get_n_refs(), strands, &samples->back()->pseudos);
47+
samples->back()->pseudos = telescope::KallistoAlignment(reference->get_n_refs());
48+
telescope::read::ThemistoToKallisto(telescope::get_mode(args.themisto_merge_mode), strands, &samples->back()->pseudos);
4749
} else {
4850
if (reference->get_n_groupings() > 1) {
4951
throw std::runtime_error("Using more than one grouping with --read-likelihood is not yet implemented.");
@@ -63,8 +65,7 @@ void ConstructLikelihood(const Arguments &args, const Grouping &grouping, const
6365
}
6466
if (free_ec_counts) {
6567
// Free memory used by the configs after all likelihood matrices are built.
66-
sample->pseudos.ec_configs.clear();
67-
sample->pseudos.ec_configs.shrink_to_fit();
68+
sample->pseudos.clear_configs();
6869
}
6970
}
7071

@@ -98,24 +99,26 @@ void WriteResults(const Arguments &args, const std::unique_ptr<Sample> &sample,
9899
}
99100

100101
// Relative abundances
101-
std::string abundances_outfile(outfile);
102-
abundances_outfile = (args.outfile.empty() || !args.batch_mode ? abundances_outfile : abundances_outfile + '/' + sample->cell_name());
103-
if (!args.outfile.empty()) {
104-
abundances_outfile += "_abundances.txt";
105-
of.open(abundances_outfile);
106-
}
107-
if (args.bootstrap_mode) {
108-
BootstrapSample* bs = static_cast<BootstrapSample*>(&(*sample));
109-
bs->write_bootstrap(grouping.get_names(), args.iters, (args.outfile.empty() ? std::cout : of.stream()));
110-
} else {
111-
sample->write_abundances(grouping.get_names(), (args.outfile.empty() ? std::cout : of.stream()));
102+
if (!args.optimizer.no_fit_model) {
103+
std::string abundances_outfile(outfile);
104+
abundances_outfile = (args.outfile.empty() || !args.batch_mode ? abundances_outfile : abundances_outfile + '/' + sample->cell_name());
105+
if (!args.outfile.empty()) {
106+
abundances_outfile += "_abundances.txt";
107+
of.open(abundances_outfile);
108+
}
109+
if (args.bootstrap_mode) {
110+
BootstrapSample* bs = static_cast<BootstrapSample*>(&(*sample));
111+
bs->write_bootstrap(grouping.get_names(), args.iters, (args.outfile.empty() ? std::cout : of.stream()));
112+
} else {
113+
sample->write_abundances(grouping.get_names(), (args.outfile.empty() ? std::cout : of.stream()));
114+
}
112115
}
113116

114117
// Probability matrix
115-
if (args.optimizer.print_probs) {
118+
if (args.optimizer.print_probs && !args.optimizer.no_fit_model) {
116119
sample->write_probabilities(grouping.get_names(), std::cout);
117120
}
118-
if (args.optimizer.write_probs) {
121+
if (args.optimizer.write_probs && !args.optimizer.no_fit_model) {
119122
std::string probs_outfile(outfile);
120123
probs_outfile += "_probs.csv";
121124
if (args.optimizer.gzip_probs) {

0 commit comments

Comments
 (0)