Skip to content

Commit

Permalink
pgenlibr Windows linking fix
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchang committed May 1, 2024
1 parent 8b4f3f5 commit 489360b
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 17 deletions.
4 changes: 2 additions & 2 deletions 2.0/pgenlibr/DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Package: pgenlibr
Type: Package
Title: PLINK 2 Binary (.pgen) Reader
Version: 0.3.6
Date: 202x-xx-xx
Date: 2024-04-30
Authors@R: c(person(given = "Christopher",
family = "Chang",
role = c("aut", "cre"),
Expand Down Expand Up @@ -32,7 +32,7 @@ Authors@R: c(person(given = "Christopher",
comment = "Author of included Zstd library"))
Description: A thin wrapper over PLINK 2's core libraries which provides an R
interface for reading .pgen files. A minimal .pvar loader is also
included. Chang et al. (2015) <doi:10.1186/s13742-015-0047-8>.
included. Chang et al. (2015) \doi{10.1186/s13742-015-0047-8}.
License: LGPL (>= 3)
Copyright: This package includes sources of the libdeflate library owned by
Eric Biggers, sources of the SIMDe library owned by Evan Nemerson, sources
Expand Down
22 changes: 17 additions & 5 deletions 2.0/plink2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static const char ver_str[] = "PLINK v2.00a6"
#elif defined(USE_AOCL)
" AMD"
#endif
" (18 Apr 2024)";
" (28 Apr 2024)";
static const char ver_str2[] =
// include leading space if day < 10, so character length stays the same
""
Expand Down Expand Up @@ -864,7 +864,7 @@ PglErr Plink2Core(const Plink2Cmdline* pcp, MakePlink2Flags make_plink2_flags, c
}
// update (26 Nov 2017): change --no-pheno to also apply to .psam file
const uint32_t ignore_psam_phenos = (!(pcp->fam_cols & kfFamCol6)) || (pcp->pheno_fname && pcp->pheno_range_list.name_ct);
reterr = LoadPsam(psamname, pcp->pheno_fname? nullptr : &(pcp->pheno_range_list), pcp->missing_catname, pcp->fam_cols, ignore_psam_phenos? 0 : 0x7fffffff, pcp->missing_pheno, (pcp->misc_flags / kfMiscAffection01) & 1, (pcp->misc_flags / kfMiscNoCategorical) & 1, pcp->max_thread_ct, &pii, &sample_include, &founder_info, &sex_nm, &sex_male, &pheno_cols, &pheno_names, &raw_sample_ct, &pheno_ct, &max_pheno_name_blen);
reterr = LoadPsam(psamname, pcp->pheno_fname? nullptr : &(pcp->pheno_range_list), pcp->missing_catname, pcp->fam_cols, ignore_psam_phenos? 0 : 0x7fffffff, pcp->missing_pheno, (pcp->misc_flags / kfMiscAffection01) & 1, (pcp->misc_flags / kfMiscNoCategorical) & 1, (pcp->misc_flags / kfMiscNeg9PhenoReallyMissing) & 1, pcp->max_thread_ct, &pii, &sample_include, &founder_info, &sex_nm, &sex_male, &pheno_cols, &pheno_names, &raw_sample_ct, &pheno_ct, &max_pheno_name_blen);
if (unlikely(reterr)) {
goto Plink2Core_ret_1;
}
Expand Down Expand Up @@ -1161,7 +1161,7 @@ PglErr Plink2Core(const Plink2Cmdline* pcp, MakePlink2Flags make_plink2_flags, c
}
}
if (pcp->pheno_fname) {
reterr = LoadPhenos(pcp->pheno_fname, &(pcp->pheno_range_list), sample_include, &pii.sii, pcp->missing_catname, raw_sample_ct, sample_ct, pcp->missing_pheno, (pcp->misc_flags / kfMiscAffection01) & 1, (pcp->misc_flags / kfMiscNoCategorical) & 1, (pcp->misc_flags / kfMiscPhenoIidOnly) & 1, (pcp->misc_flags / kfMiscPhenoColNums) & 1, pcp->max_thread_ct, &pheno_cols, &pheno_names, &pheno_ct, &max_pheno_name_blen);
reterr = LoadPhenos(pcp->pheno_fname, &(pcp->pheno_range_list), sample_include, &pii.sii, pcp->missing_catname, raw_sample_ct, sample_ct, pcp->missing_pheno, (pcp->misc_flags / kfMiscAffection01) & 1, (pcp->misc_flags / kfMiscNoCategorical) & 1, (pcp->misc_flags / kfMiscPhenoIidOnly) & 1, (pcp->misc_flags / kfMiscPhenoColNums) & 1, (pcp->misc_flags / kfMiscNeg9PhenoReallyMissing) & 1, pcp->max_thread_ct, &pheno_cols, &pheno_names, &pheno_ct, &max_pheno_name_blen);
if (unlikely(reterr)) {
goto Plink2Core_ret_1;
}
Expand Down Expand Up @@ -1581,7 +1581,7 @@ PglErr Plink2Core(const Plink2Cmdline* pcp, MakePlink2Flags make_plink2_flags, c
}
if (pcp->covar_fname || pcp->covar_range_list.name_ct) {
const char* cur_covar_fname = pcp->covar_fname? pcp->covar_fname : (pcp->pheno_fname? pcp->pheno_fname : psamname);
reterr = LoadPhenos(cur_covar_fname, &(pcp->covar_range_list), sample_include, &pii.sii, pcp->missing_catname, raw_sample_ct, sample_ct, pcp->missing_pheno, 2, (pcp->misc_flags / kfMiscNoCategorical) & 1, (pcp->misc_flags / kfMiscCovarIidOnly) & 1, (pcp->misc_flags / kfMiscCovarColNums) & 1, pcp->max_thread_ct, &covar_cols, &covar_names, &covar_ct, &max_covar_name_blen);
reterr = LoadPhenos(cur_covar_fname, &(pcp->covar_range_list), sample_include, &pii.sii, pcp->missing_catname, raw_sample_ct, sample_ct, pcp->missing_pheno, 2, (pcp->misc_flags / kfMiscNoCategorical) & 1, (pcp->misc_flags / kfMiscCovarIidOnly) & 1, (pcp->misc_flags / kfMiscCovarColNums) & 1, (pcp->misc_flags / kfMiscNeg9PhenoReallyMissing) & 1, pcp->max_thread_ct, &covar_cols, &covar_names, &covar_ct, &max_covar_name_blen);
if (unlikely(reterr)) {
goto Plink2Core_ret_1;
}
Expand Down Expand Up @@ -6699,6 +6699,11 @@ int main(int argc, char** argv) {
snprintf(g_logbuf, kLogbufSize, "Error: Invalid --input-missing-phenotype argument '%s' (must be an integer in [-2147483647, -1] or [3, 2147483647]).\n", cur_modif);
goto main_ret_INVALID_CMDLINE_WWA;
}
if (pc.missing_pheno == -9) {
// No reason to require --neg9-pheno-really-missing when user
// explicitly sets --input-missing-phenotype to -9.
pc.misc_flags |= kfMiscNeg9PhenoReallyMissing;
}
} else if (strequal_k_unsafe(flagname_p2, "mport-dosage-certainty")) {
if (unlikely(EnforceParamCtRange(argvk[arg_idx], param_ct, 1, 1))) {
goto main_ret_INVALID_CMDLINE_2A;
Expand Down Expand Up @@ -8905,10 +8910,14 @@ int main(int argc, char** argv) {
pc.fa_flags |= kfFaNormalize;
pc.dependency_flags |= kfFilterPvarReq;
} else if (strequal_k_unsafe(flagname_p2, "o-input-missing-phenotype")) {
if (pc.missing_pheno != -9) {
if (unlikely(pc.missing_pheno != -9)) {
logerrputs("Error: --input-missing-phenotype and --no-input-missing-phenotype don't make\nsense together.\n");
goto main_ret_INVALID_CMDLINE;
}
if (unlikely(pc.misc_flags & kfMiscNeg9PhenoReallyMissing)) {
logerrputs("Error: --neg9-pheno-really-missing and --no-input-missing-phenotype don't make\nsense together.\n");
goto main_ret_INVALID_CMDLINE;
}
pc.missing_pheno = 0;
goto main_param_zero;
} else if (strequal_k_unsafe(flagname_p2, "ative")) {
Expand All @@ -8935,6 +8944,9 @@ int main(int argc, char** argv) {
} else if (strequal_k_unsafe(flagname_p2, "o-categorical")) {
pc.misc_flags |= kfMiscNoCategorical;
goto main_param_zero;
} else if (strequal_k_unsafe(flagname_p2, "eg9-pheno-really-missing")) {
pc.misc_flags |= kfMiscNeg9PhenoReallyMissing;
goto main_param_zero;
} else if (likely(strequal_k_unsafe(flagname_p2, "o-id-header"))) {
if (unlikely(EnforceParamCtRange(argvk[arg_idx], param_ct, 0, 1))) {
goto main_ret_INVALID_CMDLINE_2A;
Expand Down
3 changes: 2 additions & 1 deletion 2.0/plink2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ FLAGSET64_DEF_START()
kfMiscMakeFoundersFirst = (1LLU << 46),
kfMiscMakeFoundersNotfirst = (1LLU << 47),
kfMiscMakeFoundersRequire2Missing = (1LLU << 48),
kfMiscYNosexMissingStats = (1LLU << 49)
kfMiscYNosexMissingStats = (1LLU << 49),
kfMiscNeg9PhenoReallyMissing = (1LLU << 50)
FLAGSET64_DEF_END(MiscFlags);

FLAGSET64_DEF_START()
Expand Down
11 changes: 10 additions & 1 deletion 2.0/plink2_help.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1872,12 +1872,21 @@ PglErr DispHelp(const char* const* argvk, uint32_t param_ct) {
);
// bugfix (27 Feb 2019): "\01" is interpreted as a single character, not a
// null followed by a '1'...
HelpPrint("input-missing-phenotype\0no-input-missing-phenotype\0\061\0missing-catname\0missing-phenotype\0", &help_ctrl, 0,
HelpPrint("input-missing-phenotype\0no-input-missing-phenotype\0neg9-pheno-really-missing\0\061\0missing-catname\0missing-phenotype\0", &help_ctrl, 0,
" --input-missing-phenotype <v> : Set nonzero number to treat as a missing\n"
" pheno/covar in input files (default -9).\n"
" --no-input-missing-phenotype : Don't treat any nonzero number as a missing\n"
" pheno/covar. ('NA'/'nan' are still treated\n"
" as missing.)\n"
" --neg9-pheno-really-missing : When neither --input-missing-phenotype nor\n"
" --no-input-missing-phenotype are specified,\n"
" and a pheno/covar value in [-8, -9) or\n"
" (-9, -10] is present, PLINK 2 now errors out\n"
" when -9 is also present: in this context it\n"
" is too likely that -9 does not represent a\n"
" missing value.\n"
" --neg9-pheno-really-missing suppresses the\n"
" error.\n"
" --1 : Expect case/control phenotypes in input files\n"
" to be coded as 0 = control, 1 = case, instead\n"
" of the usual 0 = missing, 1 = ctrl, 2 = case.\n"
Expand Down
13 changes: 10 additions & 3 deletions 2.0/plink2_import.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3141,9 +3141,8 @@ PglErr VcfToPgen(const char* vcfname, const char* preexisting_psamname, const ch
goto VcfToPgen_ret_MISSING_TOKENS;
}
if (unlikely(S_CAST(uintptr_t, id_end - pos_end) > kMaxIdBlen)) {
putc_unlocked('\n', stdout);
snprintf(g_logbuf, kLogbufSize, "Error: Invalid ID on line %" PRIuPTR " of --vcf file (max " MAX_ID_SLEN_STR " chars).\n", line_idx);
goto VcfToPgen_ret_MALFORMED_INPUT_WW;
goto VcfToPgen_ret_MALFORMED_INPUT_WWN;
}

// note REF length
Expand All @@ -3153,6 +3152,10 @@ PglErr VcfToPgen(const char* vcfname, const char* preexisting_psamname, const ch
goto VcfToPgen_ret_MISSING_TOKENS;
}
uint32_t cur_max_allele_slen = linebuf_iter - ref_allele_start;
if (unlikely(memchr(ref_allele_start, ',', cur_max_allele_slen) != nullptr)) {
snprintf(g_logbuf, kLogbufSize, "Error: Invalid REF allele on line %" PRIuPTR " of --vcf file.\n", line_idx);
goto VcfToPgen_ret_MALFORMED_INPUT_WWN;
}

uint32_t alt_ct = 1;
unsigned char ucc;
Expand Down Expand Up @@ -3870,6 +3873,10 @@ PglErr VcfToPgen(const char* vcfname, const char* preexisting_psamname, const ch
goto VcfToPgen_load_start;
}
if ((!vic.vibc.gt_exists) && (!format_dosage_relevant) && (!format_hds_search)) {
line_iter = AdvToDelim(format_start, '\n');
if (unlikely(CountByte(format_start, '\t', line_iter - format_start) != sample_ct)) {
goto VcfToPgen_ret_MISSING_TOKENS;
}
gparse_flags = kfGparseNull;
genotext_byte_ct = 1;
} else {
Expand Down Expand Up @@ -14868,7 +14875,7 @@ PglErr Plink1DosageToPgen(const char* dosagename, const char* famname, const cha
uintptr_t* sex_male = nullptr;
uintptr_t* founder_info = nullptr;
uintptr_t max_pheno_name_blen = 0;
reterr = LoadPsam(famname, nullptr, missing_catname, fam_cols, 0x7fffffff, missing_pheno, (misc_flags / kfMiscAffection01) & 1, (misc_flags / kfMiscNoCategorical) & 1, max_thread_ct, &pii, &sample_include, &founder_info, &sex_nm, &sex_male, &pheno_cols, &pheno_names, &raw_sample_ct, &pheno_ct, &max_pheno_name_blen);
reterr = LoadPsam(famname, nullptr, missing_catname, fam_cols, 0x7fffffff, missing_pheno, (misc_flags / kfMiscAffection01) & 1, (misc_flags / kfMiscNoCategorical) & 1, (misc_flags / kfMiscNeg9PhenoReallyMissing) & 1, max_thread_ct, &pii, &sample_include, &founder_info, &sex_nm, &sex_male, &pheno_cols, &pheno_names, &raw_sample_ct, &pheno_ct, &max_pheno_name_blen);
if (unlikely(reterr)) {
goto Plink1DosageToPgen_ret_1;
}
Expand Down
2 changes: 1 addition & 1 deletion 2.0/plink2_import_legacy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ PglErr RewritePsam(const char* in_psamname, const char* missing_catname, MiscFla
uintptr_t* sex_male = nullptr;
uintptr_t* founder_info = nullptr;
uintptr_t max_pheno_name_blen = 0;
reterr = LoadPsam(in_psamname, nullptr, missing_catname, fam_cols, 0x7fffffff, missing_pheno, (misc_flags / kfMiscAffection01) & 1, (misc_flags / kfMiscNoCategorical) & 1, max_thread_ct, &pii, &sample_include, &founder_info, &sex_nm, &sex_male, &pheno_cols, &pheno_names, &raw_sample_ct, &pheno_ct, &max_pheno_name_blen);
reterr = LoadPsam(in_psamname, nullptr, missing_catname, fam_cols, 0x7fffffff, missing_pheno, (misc_flags / kfMiscAffection01) & 1, (misc_flags / kfMiscNoCategorical) & 1, (misc_flags / kfMiscNeg9PhenoReallyMissing) & 1, max_thread_ct, &pii, &sample_include, &founder_info, &sex_nm, &sex_male, &pheno_cols, &pheno_names, &raw_sample_ct, &pheno_ct, &max_pheno_name_blen);
if (unlikely(reterr)) {
goto RewritePsam_ret_1;
}
Expand Down
42 changes: 40 additions & 2 deletions 2.0/plink2_psam.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ typedef struct CatnameLl2Struct {
char str[];
} CatnameLl2;

PglErr LoadPsam(const char* psamname, const RangeList* pheno_range_list_ptr, const char* missing_catname, FamCol fam_cols, uint32_t pheno_ct_max, int32_t missing_pheno, uint32_t affection_01, uint32_t no_categorical, uint32_t max_thread_ct, PedigreeIdInfo* piip, uintptr_t** sample_include_ptr, uintptr_t** founder_info_ptr, uintptr_t** sex_nm_ptr, uintptr_t** sex_male_ptr, PhenoCol** pheno_cols_ptr, char** pheno_names_ptr, uint32_t* raw_sample_ct_ptr, uint32_t* pheno_ct_ptr, uintptr_t* max_pheno_name_blen_ptr) {
PglErr LoadPsam(const char* psamname, const RangeList* pheno_range_list_ptr, const char* missing_catname, FamCol fam_cols, uint32_t pheno_ct_max, int32_t missing_pheno, uint32_t affection_01, uint32_t no_categorical, uint32_t neg9_pheno_really_missing, uint32_t max_thread_ct, PedigreeIdInfo* piip, uintptr_t** sample_include_ptr, uintptr_t** founder_info_ptr, uintptr_t** sex_nm_ptr, uintptr_t** sex_male_ptr, PhenoCol** pheno_cols_ptr, char** pheno_names_ptr, uint32_t* raw_sample_ct_ptr, uint32_t* pheno_ct_ptr, uintptr_t* max_pheno_name_blen_ptr) {
// outparameter pointers assumed to be initialized to nullptr
//
// pheno_ct_max should default to something like 0x7fffffff, not UINT32_MAX
Expand Down Expand Up @@ -726,7 +726,10 @@ PglErr LoadPsam(const char* psamname, const RangeList* pheno_range_list_ptr, con
uintptr_t* founder_info = *founder_info_ptr;
uintptr_t* sex_nm = *sex_nm_ptr;
uintptr_t* sex_male = *sex_male_ptr;
const uint32_t check_neg8_to_10_pheno = (missing_pheno == -9) && (!neg9_pheno_really_missing);
uint32_t sample_uidx = raw_sample_ct;
uint32_t neg9_seen = 0;
uint32_t other_neg8_to_10_seen = 0;
while (sample_uidx) {
--sample_uidx;
unsigned char* cur_vardata = psam_info_reverse_ll->vardata;
Expand All @@ -746,6 +749,15 @@ PglErr LoadPsam(const char* psamname, const RangeList* pheno_range_list_ptr, con
SetBit(sample_uidx, pheno_cols[pheno_idx].nonmiss);
pheno_cols[pheno_idx].data.qt[sample_uidx] = dxx;
}
if (check_neg8_to_10_pheno) {
if ((dxx <= -8.0) && (dxx >= -10.0)) {
if (dxx == -9.0) {
neg9_seen = 1;
} else {
other_neg8_to_10_seen = 1;
}
}
}
} else {
if (dxx == pheno_cased) {
SetBit(sample_uidx, pheno_cols[pheno_idx].data.cc);
Expand Down Expand Up @@ -783,6 +795,13 @@ PglErr LoadPsam(const char* psamname, const RangeList* pheno_range_list_ptr, con
}
psam_info_reverse_ll = psam_info_reverse_ll->next;
}
if (check_neg8_to_10_pheno && other_neg8_to_10_seen) {
if (unlikely(neg9_seen)) {
logerrputs("Error: Distinct phenotype values in [-8, -10] present, including -9, when -9 is\ntreated as missing.\n* Usually, this means -9 should be treated as an ordinary numeric value; use\n--no-input-missing-phenotype to specify this.\n* If -9 really does still mean missing, use --neg9-pheno-really-missing.\n");
goto LoadPsam_ret_INCONSISTENT_INPUT;
}
logerrputs("Warning: Phenotype value in [-8, -9) or (-9, -10] present, when -9 is treated\nas missing. Use --no-input-missing-phenotype to treat -9 as a numeric value\n(missing values can be indicated by 'NA'), or --neg9-pheno-really-missing to\nsuppress this warning.\n");
}
if (fid_present) {
piip->sii.flags |= kfSampleIdFidPresent;
}
Expand Down Expand Up @@ -856,7 +875,7 @@ typedef struct PhenoInfoLlStruct {

// also for loading covariates. set affection_01 to 2 to prohibit case/control
// and make unnamed variables start with "COVAR" instead of "PHENO"
PglErr LoadPhenos(const char* pheno_fname, const RangeList* pheno_range_list_ptr, const uintptr_t* sample_include, const SampleIdInfo* siip, const char* missing_catname, uint32_t raw_sample_ct, uint32_t sample_ct, int32_t missing_pheno, uint32_t affection_01, uint32_t no_categorical, uint32_t iid_only, uint32_t numeric_ranges, uint32_t max_thread_ct, PhenoCol** pheno_cols_ptr, char** pheno_names_ptr, uint32_t* pheno_ct_ptr, uintptr_t* max_pheno_name_blen_ptr) {
PglErr LoadPhenos(const char* pheno_fname, const RangeList* pheno_range_list_ptr, const uintptr_t* sample_include, const SampleIdInfo* siip, const char* missing_catname, uint32_t raw_sample_ct, uint32_t sample_ct, int32_t missing_pheno, uint32_t affection_01, uint32_t no_categorical, uint32_t iid_only, uint32_t numeric_ranges, uint32_t neg9_pheno_really_missing, uint32_t max_thread_ct, PhenoCol** pheno_cols_ptr, char** pheno_names_ptr, uint32_t* pheno_ct_ptr, uintptr_t* max_pheno_name_blen_ptr) {
unsigned char* bigstack_mark = g_bigstack_base;
unsigned char* bigstack_end_mark = g_bigstack_end;
char* pheno_names = nullptr;
Expand Down Expand Up @@ -1378,8 +1397,11 @@ PglErr LoadPhenos(const char* pheno_fname, const RangeList* pheno_range_list_ptr
goto LoadPhenos_ret_NOMEM;
}
}
const uint32_t check_neg8_to_10_pheno = (missing_pheno == -9) && (!neg9_pheno_really_missing);
const uintptr_t nonmiss_vec_ct = BitCtToVecCt(raw_sample_ct);
uint32_t cat_pheno_idx = 0;
uint32_t neg9_seen = 0;
uint32_t other_neg8_to_10_seen = 0;
PhenoCol* pheno_cols_iter = &(new_pheno_cols[old_pheno_ct]);
for (uint32_t new_pheno_idx = 0; new_pheno_idx != new_pheno_ct; ++new_pheno_idx) {
const uint32_t is_categorical = IsSet(categorical_phenos, new_pheno_idx);
Expand Down Expand Up @@ -1472,6 +1494,15 @@ PglErr LoadPhenos(const char* pheno_fname, const RangeList* pheno_range_list_ptr
SetBit(sample_uidx, pheno_cols_iter->nonmiss);
pheno_cols_iter->data.qt[sample_uidx] = dxx;
}
if (check_neg8_to_10_pheno) {
if ((dxx <= -8.0) && (dxx >= -10.0)) {
if (dxx == -9.0) {
neg9_seen = 1;
} else {
other_neg8_to_10_seen = 1;
}
}
}
} else {
if (dxx == pheno_cased) {
SetBit(sample_uidx, pheno_cols_iter->data.cc);
Expand All @@ -1485,6 +1516,13 @@ PglErr LoadPhenos(const char* pheno_fname, const RangeList* pheno_range_list_ptr
}
pheno_info_reverse_ll = pheno_info_reverse_ll->next;
}
if (check_neg8_to_10_pheno && other_neg8_to_10_seen) {
if (unlikely(neg9_seen)) {
logerrputs("Error: Distinct phenotype/covariate values in [-8, -10] present, including -9,\nwhen -9 is treated as missing. Use --no-input-missing-phenotype to treat -9 as\na numeric value (missing values can be indicated by 'NA'), or\n--neg9-pheno-really-missing to suppress this error.\n");
goto LoadPhenos_ret_INCONSISTENT_INPUT;
}
logerrputs("Warning: Phenotype/covariate value in [-8, -9) or (-9, -10] present, when -9\nis treated as missing. Use --no-input-missing-phenotype to treat -9 as a\nnumeric value (missing values can be indicated by 'NA'), or\n--neg9-pheno-really-missing to suppress this warning.\n");
}
}
*pheno_names_ptr = pheno_names;
*max_pheno_name_blen_ptr = max_pheno_name_blen;
Expand Down
Loading

0 comments on commit 489360b

Please sign in to comment.