tbtools-cli 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. tbtools_cli/__init__.py +18 -0
  2. tbtools_cli/auto_commands.py +1149 -0
  3. tbtools_cli/cli.py +528 -0
  4. tbtools_cli/cli_load.py +352 -0
  5. tbtools_cli/cli_rpc.py +303 -0
  6. tbtools_cli/cli_tools_registry.py +93 -0
  7. tbtools_cli/cli_top.py +1160 -0
  8. tbtools_cli/command_metadata.json +4606 -0
  9. tbtools_cli/command_spec.py +382 -0
  10. tbtools_cli/config.example.toml +19 -0
  11. tbtools_cli/config.py +43 -0
  12. tbtools_cli/core.py +508 -0
  13. tbtools_cli/errors.py +38 -0
  14. tbtools_cli/presets.py +100 -0
  15. tbtools_cli/scenarios.py +92 -0
  16. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/AdmixtureCli.java +91 -0
  17. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/AmazingMetaCli.java +78 -0
  18. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/AssemblyRecommandCli.java +47 -0
  19. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/BamIndexCli.java +31 -0
  20. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/BamSortCli.java +43 -0
  21. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/BamStateCli.java +49 -0
  22. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/BarPlotterCli.java +18 -0
  23. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/BarplotCli.java +168 -0
  24. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/BatchVizMotifsCli.java +47 -0
  25. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/BlastXmlConvertCli.java +45 -0
  26. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/BlatExecutorCli.java +66 -0
  27. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/CalcRepeatCli.java +62 -0
  28. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/CalculateSimilarityCli.java +34 -0
  29. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/CddMotifCli.java +46 -0
  30. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/CircleGeneViewerCli.java +81 -0
  31. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/CircosCli.java +76 -0
  32. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/ColorSchemeCli.java +29 -0
  33. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/CtgGroupCli.java +29 -0
  34. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/CubeHeatmapCli.java +70 -0
  35. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/DeHistCli.java +46 -0
  36. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/DegramdomCli.java +33 -0
  37. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/DiffExpCli.java +44 -0
  38. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/DistanceCli.java +53 -0
  39. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/DualSynCli.java +147 -0
  40. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/EggnogCli.java +39 -0
  41. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/ExprCorrCli.java +27 -0
  42. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/FastaMergerCli.java +36 -0
  43. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/FastaTableConvertCli.java +38 -0
  44. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/FileCleanerCli.java +31 -0
  45. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/FileSplitCli.java +15 -0
  46. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/FindBlockDualCli.java +71 -0
  47. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/FindBlockMultipleCli.java +67 -0
  48. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/FindPathCli.java +15 -0
  49. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GSEAWrapperCli.java +33 -0
  50. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GenBank2FastaCli.java +32 -0
  51. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GeneDensityCli.java +38 -0
  52. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GeneLocGffCli.java +140 -0
  53. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GeneStructureCli.java +90 -0
  54. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GenericCli.java +177 -0
  55. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GetENALinksCli.java +36 -0
  56. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GetSubNewickTreeCli.java +50 -0
  57. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GoEnrichCli.java +42 -0
  58. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GoLevelCli.java +59 -0
  59. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GroupedBarCli.java +95 -0
  60. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GsaDiagCli.java +45 -0
  61. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GxfFilterCli.java +39 -0
  62. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/GxfSortCli.java +23 -0
  63. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/HclustCli.java +43 -0
  64. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/HeatmapCli.java +89 -0
  65. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/HmmerSuiteCli.java +47 -0
  66. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/JgblocksCli.java +65 -0
  67. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/KeggEnrichCli.java +31 -0
  68. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/LayoutHeatmapCli.java +90 -0
  69. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MCScanXCli.java +80 -0
  70. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MCScanXFastCli.java +41 -0
  71. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MSACli.java +46 -0
  72. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MakeMotifCli.java +39 -0
  73. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MarkerDesignCli.java +62 -0
  74. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MarkerToolsCli.java +57 -0
  75. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/Mast2TabCli.java +27 -0
  76. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MastCli.java +54 -0
  77. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MastRunCli.java +39 -0
  78. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/Meme2TabCli.java +26 -0
  79. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MemeCli.java +74 -0
  80. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MemeRunCli.java +40 -0
  81. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MgGxfCli.java +35 -0
  82. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MicroSynCli.java +118 -0
  83. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MirIdentifyCli.java +55 -0
  84. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MotifCli.java +75 -0
  85. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MotifPatternCli.java +67 -0
  86. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MotifShiftCli.java +30 -0
  87. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MountainPlotCli.java +44 -0
  88. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/MultiSuperHeatCli.java +64 -0
  89. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/NeedlemanWunschCli.java +76 -0
  90. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/PafGC.java +15 -0
  91. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/PafVizCli.java +67 -0
  92. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/PeakDistCli.java +58 -0
  93. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/Pep2CodonCli.java +26 -0
  94. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/PfamMotifCli.java +43 -0
  95. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/PhyloTreeCli.java +92 -0
  96. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/PileUpCli.java +55 -0
  97. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/PlantCAREResultClassifyCli.java +36 -0
  98. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/PubmedSearchCli.java +25 -0
  99. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/QpcrCli.java +69 -0
  100. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/QpcrDdctCli.java +28 -0
  101. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/QpcrProcCli.java +28 -0
  102. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/QuickGenomeDotCli.java +66 -0
  103. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/QuickProteinAnnoCli.java +34 -0
  104. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/QuickRunIQtreeCli.java +69 -0
  105. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/QuickTrimALCli.java +67 -0
  106. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/RNAplotCli.java +129 -0
  107. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/RegionBedToGFF3Cli.java +43 -0
  108. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/RegionDepthCli.java +29 -0
  109. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SamBamCovCli.java +33 -0
  110. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SeqConverterCli.java +17 -0
  111. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SeqLenTrackCli.java +41 -0
  112. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SeveralSpeciesCli.java +132 -0
  113. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SimpleEnricherCli.java +44 -0
  114. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SimpleHmmscanCli.java +32 -0
  115. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SixFrameTranlaterCli.java +35 -0
  116. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/StructAnnoCompareCli.java +66 -0
  117. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SubmitSMARTCli.java +30 -0
  118. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/SuperCircosCli.java +330 -0
  119. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/TableColManipCli.java +56 -0
  120. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/TableCollapseCli.java +33 -0
  121. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/TargetScoreCli.java +47 -0
  122. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/TauCalcCli.java +28 -0
  123. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/TaxonomyBatchCli.java +72 -0
  124. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/TreeCli.java +75 -0
  125. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/TreeRootingCli.java +30 -0
  126. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/TrimMSACli.java +33 -0
  127. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/UnrootedTreeCli.java +44 -0
  128. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/UpSetCli.java +90 -0
  129. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/Venn5Cli.java +60 -0
  130. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/Venn6Cli.java +65 -0
  131. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/ViolinCli.java +66 -0
  132. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/VisualizeCli.java +57 -0
  133. tbtools_cli-1.2.0.data/data/tbtools_cli/bridges/VizGFACli.java +39 -0
  134. tbtools_cli-1.2.0.dist-info/METADATA +504 -0
  135. tbtools_cli-1.2.0.dist-info/RECORD +139 -0
  136. tbtools_cli-1.2.0.dist-info/WHEEL +5 -0
  137. tbtools_cli-1.2.0.dist-info/entry_points.txt +2 -0
  138. tbtools_cli-1.2.0.dist-info/licenses/LICENSE +21 -0
  139. tbtools_cli-1.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,47 @@
1
+ import jigplot.engine.JIGBasePanel;
2
+ import jigplot.engine.JIGSubPanel;
3
+
4
+ import java.io.File;
5
+ import java.lang.reflect.Method;
6
+
7
+ /**
8
+ * tbplot memeViz — MEME motif 批量可视化 CLI(插件 P00700 CLI 化)
9
+ *
10
+ * 用法: BatchVizMotifsCli <meme.xml> <out.svg> [width] [height]
11
+ * meme.xml: MEME suite 输出(meme.xml 格式)
12
+ * out: SVG/PNG/PDF 图
13
+ *
14
+ * 引擎: BatchVizMotifs.BatchVizMotifs(插件 jar),setInMEMEXml + process()
15
+ * → JIGSubPanel[](每个 motif 一个面板)→ JIGBasePanel 保存。
16
+ */
17
+ public class BatchVizMotifsCli {
18
+ public static void main(String[] args) throws Exception {
19
+ if (args.length < 2) {
20
+ System.err.println("用法: BatchVizMotifsCli <meme.xml> <out.svg> [width] [height]");
21
+ System.exit(1);
22
+ }
23
+ int width = args.length > 2 ? Integer.parseInt(args[2]) : 1000;
24
+ int height = args.length > 3 ? Integer.parseInt(args[3]) : 800;
25
+
26
+ Object engine = Class.forName("BatchVizMotifs.BatchVizMotifs")
27
+ .getDeclaredConstructor().newInstance();
28
+ Class<?> c = engine.getClass();
29
+ c.getMethod("setInMEMEXml", File.class).invoke(engine, new File(args[0]));
30
+ Method process = c.getMethod("process");
31
+ Object result = process.invoke(engine);
32
+ if (!(result instanceof JIGSubPanel[])) {
33
+ System.err.println("❌ process 未返回 JIGSubPanel[]");
34
+ System.exit(1);
35
+ }
36
+ JIGSubPanel[] panels = (JIGSubPanel[]) result;
37
+ JIGBasePanel base = new JIGBasePanel(width, height);
38
+ for (JIGSubPanel p : panels) base.addSubPanel(p);
39
+ File outf = new File(args[1]);
40
+ String low = args[1].toLowerCase();
41
+ if (low.endsWith(".png")) base.save2PNG(outf);
42
+ else if (low.endsWith(".pdf")) base.save2PDF(outf);
43
+ else base.save2SVG(outf);
44
+ System.err.println("[tbplot] 已保存: " + args[1] + " (" + panels.length + " motif 面板)");
45
+ System.exit(0);
46
+ }
47
+ }
@@ -0,0 +1,45 @@
1
+ import biocjava.bioIO.BlastXml.BlastXMLToPairwise;
2
+ import biocjava.bioIO.BlastXml.BlastXmlToBlastFoolTable;
3
+
4
+ import java.io.File;
5
+
6
+ /**
7
+ * tbplot xml2blasttab / xml2pairwise — BLAST XML 转表 CLI(GUI 逆向 #25,09/20)
8
+ *
9
+ * 用法: BlastXmlConvertCli <mode> <in.xml> <out.txt>
10
+ * mode: blasttab → BlastXmlToBlastFoolTable.xml2ShowerTable(BLAST 标准 m7 风格表)
11
+ * pairwise → BlastXMLToPairwise.parse(BLAST 网页 pairwise 对齐文本)
12
+ *
13
+ * 引擎: GUI 逆向 BlastXML2TableGUIPanel $3 四模式单选:
14
+ * OutBlastTab→FoolTable / OutTBtoolsTab→SelfDefined(已有 blastXmlToTable)/
15
+ * Summary→SummaryTable(已有 blastXmlSummaryTable)/ 默认→Pairwise
16
+ * 本桥补齐前两者缺的 FoolTable 和 Pairwise
17
+ */
18
+ public class BlastXmlConvertCli {
19
+ public static void main(String[] args) throws Exception {
20
+ if (args.length < 3) {
21
+ System.err.println("用法: BlastXmlConvertCli <blasttab|pairwise> <in.xml> <out.txt>");
22
+ System.exit(1);
23
+ }
24
+ String mode = args[0];
25
+ File inXml = new File(args[1]);
26
+ File outTxt = new File(args[2]);
27
+ if (!inXml.exists()) {
28
+ System.err.println("错误: 输入文件不存在: " + inXml.getAbsolutePath());
29
+ System.exit(2);
30
+ }
31
+ switch (mode) {
32
+ case "blasttab":
33
+ BlastXmlToBlastFoolTable.xml2ShowerTable(inXml, outTxt);
34
+ break;
35
+ case "pairwise":
36
+ BlastXMLToPairwise.parse(inXml, outTxt);
37
+ break;
38
+ default:
39
+ System.err.println("错误: 未知模式 " + mode + "(可选 blasttab|pairwise)");
40
+ System.exit(1);
41
+ }
42
+ System.err.println("[tbplot] BLAST XML 转换完成(" + mode + "): " + outTxt.getAbsolutePath());
43
+ System.exit(0);
44
+ }
45
+ }
@@ -0,0 +1,66 @@
1
+ import biocjava.bioDoer.BLAT.BlatExecutor;
2
+ import org.ucsc.blat.api.BlatRunResult;
3
+
4
+ import java.io.File;
5
+
6
+ /**
7
+ * tbplot blat — BLAT 序列比对 CLI(GUI 逆向 #42,09/21)
8
+ *
9
+ * 用法: BlatExecutorCli <db.fa> <query.fa> <out> [--format blast9|psl|pslx|axt|maf|sim4|wublast|blast|blast8]
10
+ * [--minScore N] [--minIdentity 0.x] [--noHead] [--mode auto|dnadna|dnarna]
11
+ * [--tileSize N] [--stepSize N] [--maxGap N] [--maxIntron N] [--extra "opts"]
12
+ *
13
+ * 引擎: BlatExecutor(GUI 逆向:BlatGUIPanel runBlatInBackground;
14
+ * **org.ucsc.blat 纯 Java BLAT 实现内嵌 jar,无需外部二进制**;
15
+ * main() 无 ArgsParser → 桥)
16
+ */
17
+ public class BlatExecutorCli {
18
+ public static void main(String[] args) throws Exception {
19
+ if (args.length < 3) {
20
+ System.err.println("用法: BlatExecutorCli <db.fa> <query.fa> <out> [--format blast9] [--minScore N] [--minIdentity 0.x] [--noHead] [--mode auto|dnadna|dnarna] [--tileSize N] [--stepSize N] [--maxGap N] [--maxIntron N] [--extra \"opts\"]");
21
+ System.exit(1);
22
+ }
23
+ File dbFile = new File(args[0]);
24
+ File queryFile = new File(args[1]);
25
+ File outFile = new File(args[2]);
26
+ BlatExecutor executor = new BlatExecutor();
27
+ executor.setDatabaseFile(dbFile);
28
+ executor.setQueryFile(queryFile);
29
+ executor.setOutputFile(outFile);
30
+ executor.setOutFormat("blast9");
31
+ executor.setAutoDetectMode(true);
32
+ StringBuilder extra = new StringBuilder();
33
+ for (int i = 3; i < args.length; i++) {
34
+ switch (args[i]) {
35
+ case "--format": executor.setOutFormat(args[++i]); break;
36
+ case "--minScore": executor.setMinScore(Integer.parseInt(args[++i])); break;
37
+ case "--minIdentity": executor.setMinIdentity(Double.parseDouble(args[++i])); break;
38
+ case "--noHead": executor.setNoHead(true); break;
39
+ case "--mode":
40
+ String m = args[++i].toLowerCase();
41
+ if (m.equals("dnadna")) { executor.setAutoDetectMode(false); extra.append("-t=dna -q=dna "); }
42
+ else if (m.equals("dnarna")) { executor.setAutoDetectMode(false); extra.append("-t=dna -q=rna "); }
43
+ else executor.setAutoDetectMode(true);
44
+ break;
45
+ case "--tileSize": executor.setTileSize(Integer.parseInt(args[++i])); break;
46
+ case "--stepSize": executor.setStepSize(Integer.parseInt(args[++i])); break;
47
+ case "--maxGap": executor.setMaxGap(Integer.parseInt(args[++i])); break;
48
+ case "--maxIntron": executor.setMaxIntron(Integer.parseInt(args[++i])); break;
49
+ case "--extra": extra.append(args[++i]); break;
50
+ default:
51
+ System.err.println("警告: 忽略未知参数 " + args[i]);
52
+ }
53
+ }
54
+ if (!dbFile.exists() || !queryFile.exists()) {
55
+ System.err.println("错误: 输入文件不存在");
56
+ System.exit(2);
57
+ }
58
+ if (extra.length() > 0) {
59
+ executor.setExtraOptionsRaw(extra.toString().trim());
60
+ }
61
+ BlatRunResult result = executor.run();
62
+ System.err.println("[tbplot] BLAT 比对完成: " + outFile.getAbsolutePath()
63
+ + (result != null ? "(" + result + ")" : ""));
64
+ System.exit(0);
65
+ }
66
+ }
@@ -0,0 +1,62 @@
1
+ import biocjava.bioDoer.repeatScoreCompute.calcRepeatScore;
2
+
3
+ import java.io.File;
4
+
5
+ /**
6
+ * tbplot calcRepeat — TBtools 重复序列得分计算 CLI(tool 39,08/31 攻克)
7
+ *
8
+ * 用法: CalcRepeatCli <genome.fa> <outRepeat.txt> [--kmerSize N] [--minFreq N] [--threads N]
9
+ * genome.fa: 基因组 FASTA
10
+ * outRepeat.txt: 输出重复得分(chr\tstart\tend\tscore)
11
+ *
12
+ * 引擎: calcRepeatScore(需 jellyfish 可执行)
13
+ * process() 内部用默认 numOfThreads=60 + -s 2000M 调 jellyfish count → 小数据/慢环境易挂
14
+ * 破解: 预生成 <genome>.<kmer>.kmer.jf 文件(ProcessBuilder 用合理线程数,参数 -m -L -C 同引擎),
15
+ * process() 检测 .jf 已存在 → 跳过内部 jellyfish count → JellyfishServer 直接 query → 输出得分
16
+ */
17
+ public class CalcRepeatCli {
18
+ public static void main(String[] args) throws Exception {
19
+ if (args.length < 2) {
20
+ System.err.println("用法: CalcRepeatCli <genome.fa> <outRepeat.txt> [--kmerSize N] [--minFreq N] [--threads N]");
21
+ System.exit(1);
22
+ }
23
+ String inFa = args[0];
24
+ String outFile = args[1];
25
+ int kmerSize = 15, minFreq = 2, threads = 4;
26
+ for (int i = 2; i < args.length; i++) {
27
+ if (args[i].equals("--kmerSize") && i+1<args.length) kmerSize = Integer.parseInt(args[++i]);
28
+ else if (args[i].equals("--minFreq") && i+1<args.length) minFreq = Integer.parseInt(args[++i]);
29
+ else if (args[i].equals("--threads") && i+1<args.length) threads = Integer.parseInt(args[++i]);
30
+ }
31
+
32
+ // 预生成 .jf(引擎命名: <genome>.<kmer>.kmer.jf)
33
+ File jf = new File(inFa + "." + kmerSize + ".kmer.jf");
34
+ if (!jf.exists()) {
35
+ System.err.println("[tbplot] 生成 jellyfish 计数: " + jf.getAbsolutePath());
36
+ ProcessBuilder pb = new ProcessBuilder("jellyfish", "count",
37
+ "-m", String.valueOf(kmerSize),
38
+ "-s", "100M",
39
+ "-t", String.valueOf(threads),
40
+ "-L", String.valueOf(minFreq),
41
+ "-C",
42
+ inFa, "-o", jf.getAbsolutePath());
43
+ pb.redirectErrorStream(true);
44
+ Process p = pb.start();
45
+ p.waitFor();
46
+ if (!jf.exists()) {
47
+ System.err.println("错误: jellyfish count 失败");
48
+ System.exit(1);
49
+ }
50
+ }
51
+
52
+ // 调引擎 process()
53
+ calcRepeatScore c = new calcRepeatScore();
54
+ c.setInGenomeSequence(new File(inFa));
55
+ c.setOutRepeatFile(new File(outFile));
56
+ c.setKmerSize(kmerSize);
57
+ c.setMinFreq(minFreq);
58
+ c.process();
59
+ System.err.println("[tbplot] 已保存: " + outFile);
60
+ System.exit(0);
61
+ }
62
+ }
@@ -0,0 +1,34 @@
1
+ import biocjava.bioDoer.Aligner.SequenceSimilarityMatrix.CalculateSimilarity;
2
+
3
+ import java.io.File;
4
+
5
+ /**
6
+ * tbplot protsim — 蛋白两两相似度矩阵 CLI(GUI 逆向 #24,09/20)
7
+ *
8
+ * 用法: CalculateSimilarityCli <pep.fa> <out.matrix>
9
+ * in: 蛋白 FASTA(多条序列)
10
+ * out: 两两相似度矩阵(百分比)
11
+ *
12
+ * 引擎: CalculateSimilarity(GUI 逆向:ProteinPairwiseSimilarityMatrixGUIPanel $1
13
+ * → setInFile/setOutSimMat/process,main() 硬编码路径无 ArgsParser)
14
+ */
15
+ public class CalculateSimilarityCli {
16
+ public static void main(String[] args) throws Exception {
17
+ if (args.length < 2) {
18
+ System.err.println("用法: CalculateSimilarityCli <pep.fa> <out.matrix>");
19
+ System.exit(1);
20
+ }
21
+ File inFile = new File(args[0]);
22
+ File outFile = new File(args[1]);
23
+ if (!inFile.exists()) {
24
+ System.err.println("错误: 输入文件不存在: " + inFile.getAbsolutePath());
25
+ System.exit(2);
26
+ }
27
+ CalculateSimilarity cs = new CalculateSimilarity();
28
+ cs.setInFile(inFile);
29
+ cs.setOutSimMat(outFile);
30
+ cs.process();
31
+ System.err.println("[tbplot] 相似度矩阵完成: " + outFile.getAbsolutePath());
32
+ System.exit(0);
33
+ }
34
+ }
@@ -0,0 +1,46 @@
1
+ import biocjava.bioDoer.MEME.DrawMotifPattern.DrawMotifPatternFromCDDResult;
2
+ import jigplot.engine.JIGBasePanel;
3
+ import jigplot.engine.JIGSubPanel;
4
+
5
+ import java.io.File;
6
+
7
+ /**
8
+ * tbcli cddmotif — CDD 保守域模式图 CLI(08/31 第七十九波,引擎 121)
9
+ *
10
+ * 用法: CddMotifCli <cdd.hitdata.txt> <in.fasta> <out.svg|png|pdf> [newick.treefile]
11
+ * cdd.hitdata.txt: NCBI Batch CD-search hitsConcise 结果(# 注释头 + Query/Hit type/PSSM-ID/From/To/... 表)
12
+ * in.fasta: 蛋白序列(ID 与 hitdata 的 Query 一致)
13
+ * newick.treefile: 可选进化树(排序基因)
14
+ *
15
+ * 引擎: DrawMotifPatternFromCDDResult.setInFile/setInFasta + postGraph(newick, jigPanel) → JIGSubPanel
16
+ * (论文级 CDD 保守域模式图;GRAS 真实 hitdata.txt 验证)
17
+ */
18
+ public class CddMotifCli {
19
+ public static void main(String[] args) throws Exception {
20
+ if (args.length < 3) {
21
+ System.err.println("用法: CddMotifCli <cdd.hitdata.txt> <in.fasta> <out.svg|png|pdf> [newick.treefile]");
22
+ System.exit(1);
23
+ }
24
+ String newick = "";
25
+ if (args.length > 3) {
26
+ File tf = new File(args[3]);
27
+ if (tf.exists()) newick = new String(java.nio.file.Files.readAllBytes(tf.toPath()), "UTF-8").trim();
28
+ }
29
+
30
+ DrawMotifPatternFromCDDResult dmp = new DrawMotifPatternFromCDDResult();
31
+ dmp.setInFile(new File(args[0]));
32
+ dmp.setInFasta(new File(args[1]));
33
+
34
+ JIGBasePanel jigPanel = new JIGBasePanel(1200, 1000);
35
+ JIGSubPanel sp = dmp.postGraph(newick, jigPanel);
36
+ jigPanel.addSubPanel(sp);
37
+
38
+ String out = args[2];
39
+ String low = out.toLowerCase();
40
+ if (low.endsWith(".png")) jigPanel.save2PNG(new File(out));
41
+ else if (low.endsWith(".pdf")) jigPanel.save2PDF(new File(out));
42
+ else jigPanel.save2SVG(new File(out));
43
+ System.err.println("[tbplot] 已保存: " + out);
44
+ System.exit(0);
45
+ }
46
+ }
@@ -0,0 +1,81 @@
1
+ import biocjava.bioDoer.JIGplotToolkit.Circos.CircleGeneViewer;
2
+ import jigplot.engine.JIGBasePanel;
3
+
4
+ import java.awt.Component;
5
+ import java.awt.Container;
6
+ import java.awt.Window;
7
+ import java.io.File;
8
+
9
+ /**
10
+ * tbplot circlegene — TBtools 环形基因位置图 CLI(08/29 重建)
11
+ *
12
+ * 用法: CircleGeneViewerCli <gff> <geneID.txt> <out> [--rename f] [--link f] [--rankedChr f] [--onlyMapped true|false]
13
+ * gff: 基因注释 GFF(含 mRNA 行)
14
+ * geneID.txt: mRNA ID 列表(每行一个,可第二列 1/0 控制颜色)
15
+ * --rename: 基因重命名文件(可选)
16
+ * --link: 基因对文件 (GeneA\tGeneB\t[r,g,b]) 绘制共线性链接(可选)
17
+ * --rankedChr: 染色体排序列表(可选)
18
+ *
19
+ * 引擎: CircleGeneViewer(process() 内部 JFrame 弹窗;核心 JIGCircos.plot() 返回 JIGSubPanel)
20
+ * 方案: 窗口遍历 —— process() 后遍历 Window 找 JIGBasePanel 再保存
21
+ * (GRAS 13 染色体+40 基因+6 同源 link 验证 SVG 25KB,08/28)
22
+ */
23
+ public class CircleGeneViewerCli {
24
+ public static void main(String[] args) throws Exception {
25
+ if (args.length < 3) {
26
+ System.err.println("用法: CircleGeneViewerCli <gff> <geneID.txt> <out> [--rename f] [--link f] [--rankedChr f] [--onlyMapped true|false]");
27
+ System.exit(1);
28
+ }
29
+ String gffFile = args[0];
30
+ String idFile = args[1];
31
+ String outFile = args[2];
32
+ File renameFile = null, linkFile = null, rankedChrFile = null;
33
+ boolean onlyMapped = false, showLabel = true;
34
+ for (int i = 3; i < args.length; i++) {
35
+ if (args[i].equals("--rename") && i+1<args.length) renameFile = new File(args[++i]);
36
+ else if (args[i].equals("--link") && i+1<args.length) linkFile = new File(args[++i]);
37
+ else if (args[i].equals("--rankedChr") && i+1<args.length) rankedChrFile = new File(args[++i]);
38
+ else if (args[i].equals("--onlyMapped") && i+1<args.length) onlyMapped = Boolean.parseBoolean(args[++i]);
39
+ }
40
+
41
+ CircleGeneViewer cgv = new CircleGeneViewer();
42
+ cgv.setGffFile(new File(gffFile));
43
+ cgv.setGeneIDFile(new File(idFile));
44
+ if (renameFile != null && renameFile.exists()) cgv.setGeneRenameFile(renameFile);
45
+ if (linkFile != null && linkFile.exists()) cgv.setDupGenePairInfoFile(linkFile);
46
+ if (rankedChrFile != null && rankedChrFile.exists()) cgv.setRankedChrListFile(rankedChrFile);
47
+ cgv.setOnlyShowChrContainGenes(onlyMapped);
48
+ cgv.process(); // 内部 JFrame 弹窗 + JIGBasePanel
49
+
50
+ // 窗口遍历
51
+ JIGBasePanel panel = null;
52
+ Window[] windows = Window.getWindows();
53
+ System.err.println("[tbplot] 窗口数: " + windows.length);
54
+ for (Window w : windows) {
55
+ JIGBasePanel found = findBasePanel(w);
56
+ if (found != null) { panel = found; break; }
57
+ }
58
+ if (panel == null) {
59
+ System.err.println("错误: 未找到 JIGBasePanel");
60
+ System.exit(1);
61
+ }
62
+ String low = outFile.toLowerCase();
63
+ if (low.endsWith(".png")) panel.save2PNG(new File(outFile));
64
+ else if (low.endsWith(".pdf")) panel.save2PDF(new File(outFile));
65
+ else panel.save2SVG(new File(outFile));
66
+ System.err.println("[tbplot] 已保存: " + outFile);
67
+ System.exit(0);
68
+ }
69
+
70
+ static JIGBasePanel findBasePanel(Component c) {
71
+ if (c instanceof JIGBasePanel) return (JIGBasePanel) c;
72
+ if (c instanceof Container) {
73
+ Component[] comps = ((Container) c).getComponents();
74
+ for (Component comp : comps) {
75
+ JIGBasePanel found = findBasePanel(comp);
76
+ if (found != null) return found;
77
+ }
78
+ }
79
+ return null;
80
+ }
81
+ }
@@ -0,0 +1,76 @@
1
+ import biocjava.bioDoer.JIGplotToolkit.Circos.AmazingSimpleCircos;
2
+ import jigplot.engine.JIGBasePanel;
3
+
4
+ import java.awt.Component;
5
+ import java.awt.Container;
6
+ import java.awt.Window;
7
+ import java.io.File;
8
+
9
+ /**
10
+ * tbplot circos — TBtools Circos 共线性环形图 CLI(08/29 重建)
11
+ *
12
+ * 用法: CircosCli <chrLen.txt> <link.txt> <genePos.txt> <out> [width] [height]
13
+ * chrLen.txt: ChrID\tLength(每行一条染色体)
14
+ * link.txt: chrA sA eA chrB sB eB [color](共线性连线,可空文件)
15
+ * genePos.txt: Chr\tGene\tStart\tEnd [color](基因位置,可空文件)
16
+ * out: 输出 SVG/PNG
17
+ *
18
+ * 引擎: AmazingSimpleCircos(process() 内部解析 3 文件 → JIGCircosAdvanced.plot() → JFrame)
19
+ * 方案: 窗口遍历 —— process() 后遍历 Window 找 JIGBasePanel 再保存
20
+ * (08/28 原 CircosCli:JIGCircosAdvanced.plot,30 连线验证)
21
+ */
22
+ public class CircosCli {
23
+ public static void main(String[] args) throws Exception {
24
+ if (args.length < 4) {
25
+ System.err.println("用法: CircosCli <chrLen.txt> <link.txt> <genePos.txt> <out> [width] [height]");
26
+ System.exit(1);
27
+ }
28
+ String chrLenFile = args[0];
29
+ String linkFile = args[1];
30
+ String genePosFile = args[2];
31
+ String outFile = args[3];
32
+
33
+ File linkF = new File(linkFile);
34
+ File geneF = new File(genePosFile);
35
+ if (!linkF.exists()) { linkF = File.createTempFile("empty_link", ".txt"); linkF.deleteOnExit(); }
36
+ if (!geneF.exists()) { geneF = File.createTempFile("empty_gene", ".txt"); geneF.deleteOnExit(); }
37
+
38
+ AmazingSimpleCircos circos = new AmazingSimpleCircos();
39
+ circos.setInChrInfo(new File(chrLenFile));
40
+ circos.setLinkInfo(linkF);
41
+ circos.setGeneInfo(geneF);
42
+ circos.setLeftUpSpace(30);
43
+ circos.process(); // 内部 JFrame 弹窗 + JIGBasePanel
44
+
45
+ // 窗口遍历
46
+ JIGBasePanel panel = null;
47
+ Window[] windows = Window.getWindows();
48
+ System.err.println("[tbplot] 窗口数: " + windows.length);
49
+ for (Window w : windows) {
50
+ JIGBasePanel found = findBasePanel(w);
51
+ if (found != null) { panel = found; break; }
52
+ }
53
+ if (panel == null) {
54
+ System.err.println("错误: 未找到 JIGBasePanel(检查输入文件格式)");
55
+ System.exit(1);
56
+ }
57
+ String low = outFile.toLowerCase();
58
+ if (low.endsWith(".png")) panel.save2PNG(new File(outFile));
59
+ else if (low.endsWith(".pdf")) panel.save2PDF(new File(outFile));
60
+ else panel.save2SVG(new File(outFile));
61
+ System.err.println("[tbplot] 已保存: " + outFile);
62
+ System.exit(0);
63
+ }
64
+
65
+ static JIGBasePanel findBasePanel(Component c) {
66
+ if (c instanceof JIGBasePanel) return (JIGBasePanel) c;
67
+ if (c instanceof Container) {
68
+ Component[] comps = ((Container) c).getComponents();
69
+ for (Component comp : comps) {
70
+ JIGBasePanel found = findBasePanel(comp);
71
+ if (found != null) return found;
72
+ }
73
+ }
74
+ return null;
75
+ }
76
+ }
@@ -0,0 +1,29 @@
1
+ import biocjava.bioDoer.JIGplotToolkit.ColorSchemeGenerator.ColorSchemeGenerator;
2
+
3
+ import java.io.File;
4
+
5
+ /**
6
+ * tbcli colorscheme — 表格分组着色 CLI(08/31 第七十四波)
7
+ *
8
+ * 用法: ColorSchemeCli <in.tab> <out.tab> <refColIndex(1-based)>
9
+ * in.tab: 输入表(任意列,取第 refColIndex 列为分组键)
10
+ * out.tab: 输出 = 原表 + RGB 颜色列(如 255,0,0)
11
+ *
12
+ * 引擎: ColorSchemeGenerator.setInTab/setOutTab/setRefColIndex + process()
13
+ * (⚠️ isContinue/predifinedColorFile 无 setter——固定走随机色板分支)
14
+ */
15
+ public class ColorSchemeCli {
16
+ public static void main(String[] args) throws Exception {
17
+ if (args.length < 3) {
18
+ System.err.println("用法: ColorSchemeCli <in.tab> <out.tab> <refColIndex(1-based)>");
19
+ System.exit(1);
20
+ }
21
+ ColorSchemeGenerator csg = new ColorSchemeGenerator();
22
+ csg.setInTab(new File(args[0]));
23
+ csg.setOutTab(new File(args[1]));
24
+ csg.setRefColIndex(Integer.parseInt(args[2]) - 1);
25
+ csg.process();
26
+ System.err.println("[tbplot] 已保存: " + args[1]);
27
+ System.exit(0);
28
+ }
29
+ }
@@ -0,0 +1,29 @@
1
+ import java.io.File;
2
+
3
+ /**
4
+ * tbplot ctgGroup — miniprot 等位基因 contig 分组 CLI(08/29,第 72 引擎)
5
+ *
6
+ * 用法: CtgGroupCli <in.miniprot.gff> <polyPoid> <outContigGrpMap>
7
+ * in.miniprot.gff: miniprot --gff 输出(蛋白→contigs)
8
+ * polyPoid: 目标倍性;outContigGrpMap: contig → 同源组
9
+ *
10
+ * 组装辅助链: miniprot → CtgGroupCli → HomoConflictBasedPartition(自带CLI) → SeperateChrByAlleles
11
+ * ⚠️ main() 硬编码路径——改走 setInMiniprotGff/setPloyPoid/setOutContigGrpMap + process()。
12
+ */
13
+ public class CtgGroupCli {
14
+ public static void main(String[] args) throws Exception {
15
+ if (args.length < 3) {
16
+ System.err.println("用法: CtgGroupCli <in.miniprot.gff> <polyPoid> <outContigGrpMap>");
17
+ System.exit(1);
18
+ }
19
+ Object o = Class.forName("biocjava.bioDoer.GenomeAssembly.ContigGroupByAlleleMap")
20
+ .getDeclaredConstructor().newInstance();
21
+ Class<?> c = o.getClass();
22
+ c.getMethod("setInMiniprotGff", File.class).invoke(o, new File(args[0]));
23
+ c.getMethod("setPloyPoid", int.class).invoke(o, Integer.parseInt(args[1]));
24
+ c.getMethod("setOutContigGrpMap", File.class).invoke(o, new File(args[2]));
25
+ c.getMethod("process").invoke(o);
26
+ System.err.println("[tbplot] contig 等位分组完成: " + args[2]);
27
+ System.exit(0);
28
+ }
29
+ }
@@ -0,0 +1,70 @@
1
+ import biocjava.bioDoer.JIGplotToolkit.HeatMap.CubeHeatMap;
2
+ import jigplot.engine.JIGBasePanel;
3
+
4
+ import java.awt.Component;
5
+ import java.awt.Container;
6
+ import java.awt.Window;
7
+ import java.io.File;
8
+
9
+ /**
10
+ * tbplot cubeheatmap — TBtools 3D 立方体热图 CLI(08/29 重建)
11
+ *
12
+ * 用法: CubeHeatmapCli <expr.tsv> <group.tsv> <out> [--log10] [--minColor r,g,b] [--midColor r,g,b] [--maxColor r,g,b]
13
+ * expr.tsv: 表达矩阵(首列基因名 + 样本名表头 + 数值)
14
+ * group.tsv: Sample\tFirstDim\tSecondDim(定义 3D 三面维度)
15
+ *
16
+ * 引擎: CubeHeatMap(plot() 内部 JIGUtils.quickShow 创建窗口,不返回 panel)
17
+ * 方案: 窗口遍历 —— plot() 后遍历 Window 找 JIGBasePanel 再保存
18
+ * (08/28 原 CubeHeatmapCli 同方案,需 -Xmx4g 避免 quickShow OOM)
19
+ */
20
+ public class CubeHeatmapCli {
21
+ public static void main(String[] args) throws Exception {
22
+ if (args.length < 3) {
23
+ System.err.println("用法: CubeHeatmapCli <expr.tsv> <group.tsv> <out> [--log10] [--minColor r,g,b] [--midColor r,g,b] [--maxColor r,g,b]");
24
+ System.exit(1);
25
+ }
26
+ String exprFile = args[0];
27
+ String groupFile = args[1];
28
+ String outFile = args[2];
29
+ boolean log10 = false;
30
+ for (int i = 3; i < args.length; i++) {
31
+ if (args[i].equals("--log10")) log10 = true;
32
+ }
33
+
34
+ CubeHeatMap cube = new CubeHeatMap();
35
+ cube.setInExpFile(new File(exprFile));
36
+ cube.setInGroupFile(new File(groupFile));
37
+ cube.plot(); // 内部 quickShow 创建窗口
38
+
39
+ // 窗口遍历
40
+ JIGBasePanel panel = null;
41
+ Window[] windows = Window.getWindows();
42
+ System.err.println("[tbplot] 窗口数: " + windows.length);
43
+ for (Window w : windows) {
44
+ JIGBasePanel found = findBasePanel(w);
45
+ if (found != null) { panel = found; break; }
46
+ }
47
+ if (panel == null) {
48
+ System.err.println("错误: 未找到 JIGBasePanel");
49
+ System.exit(1);
50
+ }
51
+ String low = outFile.toLowerCase();
52
+ if (low.endsWith(".png")) panel.save2PNG(new File(outFile));
53
+ else if (low.endsWith(".pdf")) panel.save2PDF(new File(outFile));
54
+ else panel.save2SVG(new File(outFile));
55
+ System.err.println("[tbplot] 已保存: " + outFile);
56
+ System.exit(0);
57
+ }
58
+
59
+ static JIGBasePanel findBasePanel(Component c) {
60
+ if (c instanceof JIGBasePanel) return (JIGBasePanel) c;
61
+ if (c instanceof Container) {
62
+ Component[] comps = ((Container) c).getComponents();
63
+ for (Component comp : comps) {
64
+ JIGBasePanel found = findBasePanel(comp);
65
+ if (found != null) return found;
66
+ }
67
+ }
68
+ return null;
69
+ }
70
+ }
@@ -0,0 +1,46 @@
1
+ import jigplot.engine.JIGBasePanel;
2
+ import jigplot.engine.JIGSubPanel;
3
+
4
+ import java.io.File;
5
+ import java.lang.reflect.Method;
6
+
7
+ /**
8
+ * tbplot dehist — 差异表达双直方图 CLI(G5 死命令修复)
9
+ *
10
+ * 用法: DeHistCli <deg.tsv> <out.svg> [width] [height]
11
+ * deg.tsv: 差异表达统计表(gene + log2FC 等数值列)
12
+ *
13
+ * 背景: cli.py 原注册类 biocjava...DiffExp.DualHistPlot.DiffExpDualHistPlot
14
+ * 在 2.535 jar 中不存在(tbtools doctor 死命令探测发现);真实类为
15
+ * biocjava.bioDoer.JIGplotToolkit.RNAseqViz.DiffExpDualHistPlot,
16
+ * 其 main() 硬编码作者机器路径 → 走 process(File)→JIGSubPanel[] 桥。
17
+ */
18
+ public class DeHistCli {
19
+ public static void main(String[] args) throws Exception {
20
+ if (args.length < 2) {
21
+ System.err.println("用法: DeHistCli <deg.tsv> <out.svg> [width] [height]");
22
+ System.exit(1);
23
+ }
24
+ int width = args.length > 2 ? Integer.parseInt(args[2]) : 1000;
25
+ int height = args.length > 3 ? Integer.parseInt(args[3]) : 800;
26
+
27
+ Object engine = Class.forName("biocjava.bioDoer.JIGplotToolkit.RNAseqViz.DiffExpDualHistPlot")
28
+ .getDeclaredConstructor().newInstance();
29
+ Method process = engine.getClass().getMethod("process", File.class);
30
+ Object result = process.invoke(engine, new File(args[0]));
31
+ if (!(result instanceof JIGSubPanel[])) {
32
+ System.err.println("❌ process 未返回 JIGSubPanel[]");
33
+ System.exit(1);
34
+ }
35
+ JIGSubPanel[] panels = (JIGSubPanel[]) result;
36
+ JIGBasePanel base = new JIGBasePanel(width, height);
37
+ for (JIGSubPanel p : panels) base.addSubPanel(p);
38
+ File outf = new File(args[1]);
39
+ String low = args[1].toLowerCase();
40
+ if (low.endsWith(".png")) base.save2PNG(outf);
41
+ else if (low.endsWith(".pdf")) base.save2PDF(outf);
42
+ else base.save2SVG(outf);
43
+ System.err.println("[tbplot] 已保存: " + args[1] + " (" + panels.length + " 面板)");
44
+ System.exit(0);
45
+ }
46
+ }