Skip to content

Commit 2748c00

Browse files
authored
Merge pull request #75 from CAnBioNet/correlation-coefficient-thresholds
Add option to filter on correlation coefficients
2 parents 59d8c1c + faf6f78 commit 2748c00

File tree

5 files changed

+61
-20
lines changed

5 files changed

+61
-20
lines changed

reconstruction/reconstruction/NetworkReconstructorAggregate.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -550,27 +550,34 @@ def filterDiagonals(pValues):
550550
diagonalFilter = xarray.DataArray(diagonalFilter, dims=pValues.dims, coords=pValues.coords)
551551
return diagonalFilter
552552

553-
def filterOnCorrelationPValues(config, pValues, pValueType):
554-
threshold = config["correlationPValueThresholds"][pValueType]
555-
553+
def filterUsingThreshold(values, threshold, valueType):
556554
if isinstance(threshold, dict):
557-
def filterTypeCombo(typeComboPValues):
558-
measurableTypes = [str(typeComboPValues.coords[typeCoord][0].values) for typeCoord in ["measurableType1", "measurableType2"]]
555+
def filterTypeCombo(typeComboValues):
556+
measurableTypes = [str(typeComboValues.coords[typeCoord][0].values) for typeCoord in ["measurableType1", "measurableType2"]]
559557
measurableTypeString = "({}, {})".format(*measurableTypes)
560558
measurableTypeStringReversed = "({1}, {0})".format(*measurableTypes)
561559
if measurableTypeString in threshold:
562560
typeComboThreshold = threshold[measurableTypeString]
563561
elif measurableTypeStringReversed in threshold:
564562
typeComboThreshold = threshold[measurableTypeStringReversed]
565563
else:
566-
raise Exception("No threshold for {} specified in correlation p-value thresholds".format(measurableTypeString))
567-
return typeComboPValues <= typeComboThreshold
568-
filterTable = pValues.groupby("measurableType1").map(lambda measurableType1Data: measurableType1Data.groupby("measurableType2").map(filterTypeCombo))
564+
raise Exception(f"No threshold for {measurableTypeString} specified in {valueType} thresholds")
565+
return typeComboValues <= typeComboThreshold
566+
filterTable = values.groupby("measurableType1").map(lambda measurableType1Data: measurableType1Data.groupby("measurableType2").map(filterTypeCombo))
569567
else:
570-
filterTable = pValues <= threshold
568+
filterTable = values <= threshold
571569

572570
return filterTable
573571

572+
def filterOnCorrelationCoefficients(config, coefficients):
573+
threshold = config["correlationCoefficientThresholds"]
574+
maxCoefficients = coefficients.max(dim="metatreatment")
575+
return filterUsingThreshold(maxCoefficients, threshold, "correlation coefficient")
576+
577+
def filterOnCorrelationPValues(config, pValues, pValueType):
578+
threshold = config["correlationPValueThresholds"][pValueType]
579+
return filterUsingThreshold(pValues, threshold, "correlation p-value")
580+
574581
def filterOnIndividualCorrelationPValues(config, pValues):
575582
maxPValues = pValues.max(dim="metatreatment")
576583
return filterOnCorrelationPValues(config, maxPValues, "individual")
@@ -692,12 +699,17 @@ def filterOnCorrelations(allData):
692699
return
693700

694701
allData["diagonalFilter"] = filterDiagonals(allData["correctedCorrelationPValues"])
702+
695703
allData["individualCorrelationPValueFilter"] = filterOnIndividualCorrelationPValues(config, allData["correlationPValues"])
696704
allData["combinedCorrelationPValueFilter"] = filterOnCombinedCorrelationPValues(config, allData["combinedCorrelationPValues"])
697705
allData["correctedCorrelationPValueFilter"] = filterOnCorrectedCorrelationPValues(config, allData["correctedCorrelationPValues"])
698706

699707
allData["edgeFilter"] = allData["diagonalFilter"] & allData["individualCorrelationPValueFilter"] & allData["combinedCorrelationPValueFilter"] & allData["correctedCorrelationPValueFilter"] & allData["correlationFilter"]
700708

709+
if config["correlationCoefficientThresholds"] is not None:
710+
allData["correlationCoefficientFilter"] = filterOnCorrelationCoefficients(config, allData["correlationCoefficients"])
711+
allData["edgeFilter"] &= allData["correlationCoefficientFilter"]
712+
701713
def filterToExpectedEdges(allData):
702714
nonlocal skip
703715
if skip:

reconstruction/reconstruction/NetworkReconstructorSingleCell.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -418,28 +418,35 @@ def filterDiagonals(pValues):
418418
diagonalFilter = xarray.DataArray(diagonalFilter, dims=pValues.dims, coords=pValues.coords)
419419
return diagonalFilter
420420

421-
def filterOnCorrelationPValues(config, pValues, pValueType):
421+
def filterUsingThreshold(values, threshold, valueType):
422422
# TODO: Thresholds for measurableType combinations as well
423-
threshold = config["correlationPValueThresholds"][pValueType]
424-
425423
if isinstance(threshold, dict):
426-
def filterTypeCombo(typeComboPValues):
427-
cellTypes = [str(typeComboPValues.coords[typeCoord][0].values) for typeCoord in ["cellType1", "cellType2"]]
424+
def filterTypeCombo(typeComboValues):
425+
cellTypes = [str(typeComboValues.coords[typeCoord][0].values) for typeCoord in ["cellType1", "cellType2"]]
428426
cellTypeString = "({}, {})".format(*cellTypes)
429427
cellTypeStringReversed = "({1}, {0})".format(*cellTypes)
430428
if cellTypeString in threshold:
431429
typeComboThreshold = threshold[cellTypeString]
432430
elif cellTypeStringReversed in threshold:
433431
typeComboThreshold = threshold[cellTypeStringReversed]
434432
else:
435-
raise Exception("No threshold for {} specified in correlation p-value thresholds".format(cellTypeString))
436-
return typeComboPValues <= typeComboThreshold
437-
filterTable = pValues.groupby("cellType1").map(lambda cellType1Data: cellType1Data.groupby("cellType2").map(filterTypeCombo))
433+
raise Exception(f"No threshold for {cellTypeString} specified in {valueType} thresholds")
434+
return typeComboValues <= typeComboThreshold
435+
filterTable = values.groupby("cellType1").map(lambda cellType1Data: cellType1Data.groupby("cellType2").map(filterTypeCombo))
438436
else:
439-
filterTable = pValues <= threshold
437+
filterTable = values <= threshold
440438

441439
return filterTable
442440

441+
def filterOnCorrelationCoefficients(config, coefficients):
442+
threshold = config["correlationCoefficientThresholds"]
443+
maxCoefficients = coefficients.max(dim="metatreatment")
444+
return filterUsingThreshold(maxCoefficients, threshold, "correlation coefficient")
445+
446+
def filterOnCorrelationPValues(config, pValues, pValueType):
447+
threshold = config["correlationPValueThresholds"][pValueType]
448+
return filterUsingThreshold(pValues, threshold, "correlation p-value")
449+
443450
def filterOnIndividualCorrelationPValues(config, pValues):
444451
maxPValues = pValues.max(dim="metatreatment")
445452
return filterOnCorrelationPValues(config, maxPValues, "individual")
@@ -530,6 +537,10 @@ def stageFilterOnCorrelations(allData):
530537
allData["correctedCorrelationPValueFilter"] = filterOnCorrectedCorrelationPValues(config, allData["correctedCorrelationPValues"])
531538
allData["edgeFilter"] = allData["diagonalFilter"] & allData["individualCorrelationPValueFilter"] & allData["combinedCorrelationPValueFilter"] & allData["correctedCorrelationPValueFilter"] & allData["correlationFilter"]
532539

540+
if config["correlationCoefficientThresholds"] is not None:
541+
allData["correlationCoefficientFilter"] = filterOnCorrelationCoefficients(config, allData["correlationCoefficients"])
542+
allData["edgeFilter"] &= allData["correlationCoefficientFilter"]
543+
533544
def stageFilterToExpectedEdges(allData):
534545
allData["expectedEdgeFilter"], allData["foldChangeSignProducts"] = filterOnExpectedEdges(config, allData["combinedFoldChangeSigns"], allData["combinedCorrelationSigns"], allData["measurableFilterStacked"])
535546
allData["edgeFilter"] &= allData["expectedEdgeFilter"]

reconstruction/to_csv.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ def setupEdgeCsv(data, config):
164164
if not config["noPUC"]:
165165
data["expectedEdgeFilterInt"] = data["expectedEdgeFilter"].astype(int)
166166
data["nonPucPassed"] = data["diagonalFilter"] & data["individualCorrelationPValueFilter"] & data["combinedCorrelationPValueFilter"] & data["correctedCorrelationPValueFilter"] & data["correlationFilter"]
167+
if "correlationCoefficientFilter" in data:
168+
data["nonPucPassed"] &= data["correlationCoefficientFilter"]
167169
data["meanValue"] = data["originalData"].groupby("experiment").map(lambda a: a.mean(dim="organism"))
168170
data["medianValue"] = data["originalData"].groupby("experiment").map(lambda a: a.median(dim="organism"))
169171

@@ -308,6 +310,11 @@ def writeConfigValues(config, outDir):
308310

309311
def writeThresholds(thresholdKey):
310312
pValueThresholds = config[thresholdKey]
313+
314+
if not isinstance(pValueThresholds, dict):
315+
configValuesFile.write("\tall: {}\n".format(pValueThresholds))
316+
return
317+
311318
arePerTypeThresholds = False
312319
types = []
313320
for threshold in pValueThresholds.values():
@@ -332,14 +339,23 @@ def writeThresholds(thresholdKey):
332339
for thresholdType, threshold in pValueThresholds.items():
333340
configValuesFile.write("\t{}: {}\n".format(thresholdType, threshold))
334341

335-
configValuesFile.write("Comparison thresholds:\n")
342+
configValuesFile.write("Comparison p-value thresholds:\n")
336343
writeThresholds("differencePValueThresholds")
337344

338345
configValuesFile.write("\n")
339346

340-
configValuesFile.write("Correlation thresholds:\n")
347+
configValuesFile.write("Correlation p-value thresholds:\n")
341348
writeThresholds("correlationPValueThresholds")
342349

350+
coefficientThresholds = config["correlationCoefficientThresholds"]
351+
if coefficientThresholds is not None:
352+
configValuesFile.write("\nCorrelation coefficient thresholds:\n")
353+
if not isinstance(coefficientThresholds, dict):
354+
configValuesFile.write("\tall: {}\n".format(coefficientThresholds))
355+
else:
356+
for type_, threshold in coefficientThresholds.items():
357+
configValuesFile.write("\t{}: {}\n".format(type_, threshold))
358+
343359
configValuesFile.close()
344360

345361
if __name__ == "__main__":

reconstruction/util/configs/Aggregate.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def validateConfig(config):
5757
MultiTypeConfigItem("combined", [Number, dict], default=0.05),
5858
MultiTypeConfigItem("corrected", [Number, dict], default=0.1)
5959
]), default=UseSubDefaults()),
60+
MultiTypeConfigItem("correlationCoefficientThresholds", [Number, dict], default=None),
6061
TypedConfigItem("correlationFilterMethod", str, default="allsamesign"),
6162
TypedConfigItem("correlationFilterPercentAgreementThreshold", Number, default=0.75),
6263
TypedConfigItem("metatreatments", dict, default=None),

reconstruction/util/configs/SingleCell.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def validateConfig(config):
5353
MultiTypeConfigItem("combined", [Number, dict], default=0.05),
5454
MultiTypeConfigItem("corrected", [Number, dict], default=0.1)
5555
]), default=UseSubDefaults()),
56+
MultiTypeConfigItem("correlationCoefficientThresholds", [Number, dict], default=None),
5657
TypedConfigItem("correlationFilterMethod", str, default="allsamesign"),
5758
TypedConfigItem("correlationFilterPercentAgreementThreshold", Number, default=0.75),
5859
TypedConfigItem("correctCorrelationPValuesAfterConsistencyFiltering", bool, default=False),

0 commit comments

Comments
 (0)