Skip to content

Commit 06cd6a1

Browse files
committed
Fine tuned server-side behavior of some parameters.
Added a sample analysis folder. Added new executable for converting SIF files to json.
1 parent b003bf0 commit 06cd6a1

File tree

4 files changed

+198
-25
lines changed

4 files changed

+198
-25
lines changed

src/main/java/org/panda/causalpath/network/GraphWriter.java

Lines changed: 130 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.panda.causalpath.analyzer.NSCForNonCorr;
55
import org.panda.causalpath.analyzer.NetworkSignificanceCalculator;
66
import org.panda.causalpath.data.*;
7+
import org.panda.utility.ArrayUtil;
78
import org.panda.utility.CollectionUtil;
89
import org.panda.utility.FileUtil;
910
import org.panda.utility.ValToColor;
@@ -477,18 +478,7 @@ else if (data instanceof ActivityData)
477478

478479
for (String sym : data.getGeneSymbols())
479480
{
480-
if (!geneMap.containsKey(sym))
481-
{
482-
HashMap<String, Object> node = new HashMap<>();
483-
geneMap.put(sym, node);
484-
nodes.add(node);
485-
Map<String, Object> d = new HashMap<>();
486-
node.put("data", d);
487-
d.put("id", sym);
488-
d.put("text", sym);
489-
List<Map> sites = new ArrayList<>();
490-
d.put("sites", sites);
491-
}
481+
initJsonNode(geneMap, nodes, sym);
492482

493483
Map node = geneMap.get(sym);
494484

@@ -541,6 +531,134 @@ else if (data instanceof ActivityData)
541531
writer.close();
542532
}
543533

534+
/**
535+
* This method takes in a SIF graph defined by two files (.sif and .format), and generates a corresponding .json
536+
* file that the webserver can display.
537+
*
538+
* @param sifFileanme SIF filename
539+
* @param formatFilename Format filename
540+
* @param outJasonFilename JASON filename to produce
541+
*/
542+
public static void convertSIFToJSON(String sifFileanme, String formatFilename, String outJasonFilename) throws IOException
543+
{
544+
Map<String, Object> map = new HashMap<>();
545+
List<Map> nodes = new ArrayList<>();
546+
List<Map> edges = new ArrayList<>();
547+
map.put("nodes", nodes);
548+
map.put("edges", edges);
549+
550+
Map<String, Map> nodeMap = new HashMap<>();
551+
Set<String> relMem = new HashSet<>();
552+
553+
Files.lines(Paths.get(sifFileanme)).map(l -> l.split("\t")).forEach(t ->
554+
{
555+
if (t.length > 2)
556+
{
557+
String key = t[0] + "\t" + t[1] + "\t" + t[2];
558+
if (relMem.contains(key)) return;
559+
else relMem.add(key);
560+
561+
Map<String, Object> edge = new HashMap<>();
562+
edges.add(edge);
563+
Map<String, Object> dMap = new HashMap<>();
564+
edge.put("data", dMap);
565+
dMap.put("source", t[0]);
566+
dMap.put("target", t[2]);
567+
dMap.put("edgeType", t[1]);
568+
if (t.length > 4 && !t[4].trim().isEmpty())
569+
{
570+
dMap.put("tooltipText", t[2] + "-" + CollectionUtil.merge(Arrays.asList(t[4].split(";")), "-"));
571+
}
572+
573+
if (t.length > 3 && !t[3].trim().isEmpty())
574+
{
575+
List<String> medList = Arrays.asList(t[3].split(";| "));
576+
if (!medList.isEmpty())
577+
{
578+
dMap.put("pcLinks", medList);
579+
}
580+
}
581+
initJsonNode(nodeMap, nodes, t[2]);
582+
}
583+
584+
if (t.length > 0 && !t[0].isEmpty()) initJsonNode(nodeMap, nodes, t[0]);
585+
});
586+
587+
Map<String, String> defaultColors = new HashMap<>();
588+
String defBGCKey = "node BG color";
589+
String defBorCKey = "node border color";
590+
591+
Files.lines(Paths.get(formatFilename)).map(l -> l.split("\t")).filter(t -> t.length > 3).forEach(t ->
592+
{
593+
if (t[1].equals("all-nodes"))
594+
{
595+
if (t[2].equals("color")) defaultColors.put(defBGCKey, jasonizeColor(t[3]));
596+
else if (t[2].equals("bordercolor")) defaultColors.put(defBorCKey, jasonizeColor(t[3]));
597+
}
598+
599+
if (t[0].equals("node"))
600+
{
601+
String name = t[1];
602+
Map node = nodeMap.get(name);
603+
if (node != null)
604+
{
605+
if (!node.containsKey("css")) node.put("css", new HashMap<>());
606+
607+
switch (t[2])
608+
{
609+
case "rppasite":
610+
String[] x = t[3].split("\\|");
611+
Map site = new HashMap();
612+
((List) ((Map) node.get("data")).get("sites")).add(site);
613+
site.put("siteText", x[1]);
614+
site.put("siteInfo", x[0] + (x.length > 4 ? (" " + x[4]) : ""));
615+
site.put("siteBackgroundColor", jasonizeColor(x[2]));
616+
site.put("siteBorderColor", jasonizeColor(x[3]));
617+
break;
618+
case "color":
619+
((Map) node.get("css")).put("backgroundColor", jasonizeColor(t[3]));
620+
break;
621+
case "bordercolor":
622+
((Map) node.get("css")).put("borderColor", jasonizeColor(t[3]));
623+
break;
624+
case "borderwidth":
625+
((Map) node.get("css")).put("borderWidth", t[3] + "px");
626+
break;
627+
case "tooltip":
628+
((Map) node.get("data")).put("tooltipText", t[3]);
629+
break;
630+
}
631+
}
632+
}
633+
});
634+
635+
BufferedWriter writer = Files.newBufferedWriter(Paths.get(outJasonFilename));
636+
JsonUtils.writePrettyPrint(writer, map);
637+
writer.close();
638+
}
639+
640+
private static void initJsonNode(Map<String, Map> nodeMap, List<Map> nodes, String name)
641+
{
642+
if (!nodeMap.containsKey(name))
643+
{
644+
HashMap<String, Object> node = new HashMap<>();
645+
nodeMap.put(name, node);
646+
nodes.add(node);
647+
Map<String, Object> d = new HashMap<>();
648+
node.put("data", d);
649+
d.put("id", name);
650+
d.put("text", name);
651+
List<Map> sites = new ArrayList<>();
652+
d.put("sites", sites);
653+
}
654+
}
655+
656+
private static String jasonizeColor(String c)
657+
{
658+
String[] t = c.split(" ");
659+
return "rgb(" + ArrayUtil.getString(",", t[0], t[1], t[2]) + ")";
660+
}
661+
544662
private Set<ExperimentData> getExperimentDataToDraw()
545663
{
546664
if (experimentDataToDraw != null) return experimentDataToDraw;

src/main/java/org/panda/causalpath/run/CausalPath.java

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,9 +1035,8 @@ enum ValueTransformation
10351035
"detection, using the threshold-for-data-significance.", false),
10361036

10371037
MAX("max", "The value with maximum absolute is used for the analysis. There should only be one group of " +
1038-
"values (marked with value-column), the values have to be distributed around " +
1039-
"zero, and a threshold value should be provided for significance detection, using the " +
1040-
"threshold-for-data-significance.", false),
1038+
"values (marked with value-column), the values have to be distributed around zero, and a threshold value " +
1039+
"should be provided for significance detection, using the threshold-for-data-significance.", false),
10411040

10421041
DIFFERENCE_OF_MEANS("difference-of-means", "There should be control and test values, whose difference would " +
10431042
"be used for significance detection. The threshold for significance (threshold-for-data-significance) " +
@@ -1052,13 +1051,13 @@ enum ValueTransformation
10521051
SIGNIFICANT_CHANGE_OF_MEAN("significant-change-of-mean", "There should be sufficient amount of control and " +
10531052
"test values to detect the significance of change with a t-test. Technically there should be more than 3" +
10541053
" controls and 3 tests, practically, they should be much more to provide statistical power. The " +
1055-
"threshold-for-data-significance should be used for a p-value threshold, or " +
1056-
"alternatively, fdr-threshold-for-data-significance should be used for " +
1057-
"controlling significance at the false discovery rate level.", true),
1054+
"threshold-for-data-significance should be used for a p-value threshold, or alternatively, " +
1055+
"fdr-threshold-for-data-significance should be used for controlling significance at the false discovery " +
1056+
"rate level.", true),
10581057

10591058
SIGNIFICANT_CHANGE_OF_MEAN_PAIRED("significant-change-of-mean-paired", "There should be sufficient amount of " +
10601059
"control and test values to detect the significance of change with a paired t-test. Technically there " +
1061-
"should be more than 3 controls and 3 tests, practically, they should be much more to provide statistical" +
1060+
"should be at least 3 controls and 3 tests, practically, they should be much more to provide statistical" +
10621061
" power. The order of control and test value columns indicate the pairing. First control column in the " +
10631062
"parameters file is paired with first test column, second is paired with second, etc. The " +
10641063
"threshold-for-data-significance should be used for a p-value threshold, or alternatively, " +
@@ -1068,11 +1067,18 @@ enum ValueTransformation
10681067
SIGNED_P_VALUES("signed-p-values", "If the dataset has its own calculation of p-values desired to be used " +
10691068
"directly, then for each comparison, there must be a column in the dataset that has these p-values " +
10701069
"multiplied with the sign of the change. For instance a value -0.001 means downregulation with a p-value " +
1071-
"of 0.001. If an FDR control is desired, then the p-values should not be adjusted.", false),
1070+
"of 0.001. Don't use 0 and -0 values in the data file with this option. Java cannot distinguish between " +
1071+
"the two. Instead, convert 0 values to very small but nonzero values, such as 1e-10 or -1e-10. " +
1072+
"If an FDR control is desired, there are two ways to have it. First way is to use unadjusted p-values in " +
1073+
"the data file and then use the fdr-threshold-for-data-significance parameter to set the desired FDR " +
1074+
"level. Second way is to use adjusted p-values in the data file and use the " +
1075+
"threshold-for-data-significance parameter to set the FDR level. Don't mix these two ways. " +
1076+
"If fdr-threshold-for-data-significance is used over already-adjusted p-values, then the code will apply " +
1077+
"the Benjamini-Hochberg procedure over those already-adjusted p-values.", false),
10721078

10731079
CORRELATION("correlation", "There should be one group of values (marked with value-column). There must be at " +
1074-
"least 3 value columns technically, but many more " +
1075-
"than that practically to have some statistical power for significant correlation. ", false);
1080+
"least 3 value columns technically, but many more than that practically to have some statistical power " +
1081+
"for significant correlation. ", false);
10761082

10771083
ValueTransformation(String name, String description, boolean twoGroupComparison)
10781084
{
@@ -1332,7 +1338,9 @@ enum Parameter
13321338
CALCULATE_NETWORK_SIGNIFICANCE((value, cp) -> cp.calculateNetworkSignificance = webServerMode ? false : Boolean.valueOf(value),
13331339
"Calculate network significance",
13341340
"Whether to calculate significances of the properties of the graph. When turned on, a p-value for network" +
1335-
" size, and also downstream activity enrichment p-values for each gene on the graph are calculated.",
1341+
" size, and also downstream activity enrichment p-values for each gene on the graph are calculated. " +
1342+
"This parameter is ignored by webserver due to resource limitations. To calculate network significance, " +
1343+
"please run CausalPath locally from its JAR file.",
13361344
new EntryType(Boolean.class), new Boolean[][]{{Boolean.FALSE}}, true, false, new Cond(Logical.NOT)),
13371345
PERMUTATIONS_FOR_SIGNIFICANCE((value, cp) -> cp.permutationCount = Integer.valueOf(value),
13381346
"Number of permutations for calculating network significance",
@@ -1410,7 +1418,7 @@ enum Parameter
14101418
new String[]{NetworkLoader.ResourceType.PC.name()},
14111419
new String[]{NetworkLoader.ResourceType.PhosphoNetworks.name()},
14121420
new String[]{NetworkLoader.ResourceType.IPTMNet.name()}},
1413-
true, true, null),
1421+
false, true, null),
14141422
RELATION_FILTER_TYPE((value, cp) ->
14151423
{
14161424
if (!cp.cs.hasGraphFilter())
@@ -1453,7 +1461,7 @@ enum Parameter
14531461
"Specifies the value where node colors reach most intense color. Has to be a positive value, and used " +
14541462
"symmetrically. In the case of value-transformation is significant-change-of-mean, the value is " +
14551463
"-log(p) with a sign associated to it.",
1456-
new EntryType(Double.class), new String[][]{{"1"}}, false, false,
1464+
new EntryType(Double.class), new String[][]{{"10"}}, false, false,
14571465
new Cond( Logical.NOT, new Cond(VALUE_TRANSFORMATION.getText(), ValueTransformation.CORRELATION.name))),
14581466
SHOW_ALL_GENES_WITH_PROTEOMIC_DATA((value, cp) -> cp.showAllGenesWithProteomicData = Boolean.valueOf(value),
14591467
"Show all genes with significant proteomic data",
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.panda.causalpath.run;
2+
3+
import org.panda.causalpath.network.GraphWriter;
4+
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.nio.file.Files;
8+
import java.nio.file.Paths;
9+
10+
/**
11+
* This class is used for converting SIF and format files to json files that can be uploaded to the webserver for
12+
* visualization.
13+
*
14+
* Usage: java -jar causalpath.jar <in-dir> <sif-name> <out-dir> <json-name>
15+
*
16+
*/
17+
public class JasonizeResultGraphsRecursively
18+
{
19+
public static void main(String[] args) throws IOException
20+
{
21+
String inBase = new File(args[0]).getPath();
22+
String sifNameWOExtension = args[1];
23+
String outBase = new File(args[2]).getPath();
24+
String jsonName = args.length > 3 ? args[3] : "causative.json";
25+
26+
generate(inBase, inBase, sifNameWOExtension, outBase, jsonName);
27+
}
28+
29+
private static void generate(String inBase, String inDir, String sifName, String outBase, String jsonName) throws IOException
30+
{
31+
String sifPath = inDir + File.separator + sifName + ".sif";
32+
String formatPath = inDir + File.separator + sifName + ".format";
33+
34+
if (Files.exists(Paths.get(sifPath)) && Files.exists(Paths.get(formatPath)))
35+
{
36+
String outDir = inDir.replace(inBase, outBase);
37+
Files.createDirectories(Paths.get(outDir));
38+
39+
GraphWriter.convertSIFToJSON(sifPath, formatPath, outDir + File.separator + jsonName);
40+
}
41+
42+
for (File sub : new File(inDir).listFiles())
43+
{
44+
if (sub.isDirectory()) generate(inBase, sub.getPath(), sifName, outBase, jsonName);
45+
}
46+
}
47+
}

wiki/sample-data-and-parameters.zip

27 KB
Binary file not shown.

0 commit comments

Comments
 (0)