从ImageJ / Fiji脚本导入外部库/包

时间:2014-06-19 17:00:07

标签: jython imagej java

我正在使用斐济脚本编辑器在Jython中编写一个imageJ / Fiji插件。我需要导入外部数值库,如ParallelColt,以帮助我处理多维矩阵。

我开始使用ParallelColt,将其jar文件放在斐济境内的java文件夹中: " Fiji.app/java/macosx-java3d/Home/lib/ext” 然后我尝试通过写入来导入它: "从ParallelColt导入jplasma"导入ParallelColt“或更具体地说" 我收到错误的模块未找到。

我尝试将jar放在斐济插件文件夹中,而不是使用 仍然没有成功。我也尝试使用所有java类的文件夹 ParallelColt而不是jar文件,我仍然无法导入 我脚本中的类。

或许我只想问的问题是如何从Jython脚本导入java库。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

这里有两个问题。

1。依赖

为了依赖具有多个JAR文件的复杂第三方软件项目,您需要确保已经所有项目的依赖项(即,它需要的所有JAR文件)进入ImageJ.app/jars

一种方法是find the dependencies on Maven Central,然后使用Maven或Gradle等构建工具下载它们。

在您的情况下,您可以通过制作以下pom.xml文件来使用Maven执行此操作:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>dummy</groupId>
  <artifactId>dummy</artifactId>
  <version>0.0.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>net.sourceforge.parallelcolt</groupId>
      <artifactId>parallelcolt</artifactId>
      <version>0.10.1</version>
    </dependency>
    <dependency>
      <groupId>net.mikera</groupId>
      <artifactId>vectorz</artifactId>
      <version>0.34.0</version>
    </dependency>
  </dependencies>

</project>

然后执行:

mvn dependency:copy-dependencies

这将导致target/dependencies文件夹中的以下文件:

  29087 AMDJ-1.0.1.jar
   8687 BTFJ-1.0.1.jar
  19900 COLAMDJ-1.0.1.jar
  55638 JKLU-1.0.0.jar
1194003 arpack_combined_all-0.1.jar
  31162 core-lapack-0.1.jar
 212836 csparsej-1.1.1.jar
  88639 edn-java-0.4.4.jar
  91793 jplasma-1.2.0.jar
 762778 jtransforms-2.4.0.jar
 237344 junit-4.8.2.jar
   8693 mathz-0.3.0.jar
 131210 netlib-java-0.9.3.jar
  66134 optimization-1.0.jar
4111744 parallelcolt-0.10.1.jar
  14028 randomz-0.3.0.jar
 593015 vectorz-0.34.0.jar

将它们移到你的ImageJ.app/jars文件夹中,你应该好好去 - 虽然要注意同一个库的多个版本,因为ImageJ现在无法处理它。

2。类引用

from ParallelColt import jplasma行无效。也就是说,没有ParallelColt.jplasma Java类或包。您可以从命令行自行验证:

$ find-class() { for f in *.jar; do result=$(jar tf "$f" | grep -l "$@"); if [ "$result" != "" ]; then echo $f; fi; done; }
$ cd ImageJ.app/jars
$ find-class jplasma

两个JAR文件包含包含该字符串的类:

core-lapack-0.1.jar
jplasma-1.2.0.jar

快速浏览一下它们会发现包名不是以ParallelColt开头的:

$ jar tf jplasma-1.2.0.jar | grep jplasma
edu/emory/mathcs/jplasma/
edu/emory/mathcs/jplasma/benchmark/
edu/emory/mathcs/jplasma/test/
edu/emory/mathcs/jplasma/tdouble/
edu/emory/mathcs/jplasma/example/
edu/emory/mathcs/jplasma/benchmark/DgelsBenchmark.class
edu/emory/mathcs/jplasma/benchmark/DposvBenchmark.class
edu/emory/mathcs/jplasma/benchmark/DgesvBenchmark.class
edu/emory/mathcs/jplasma/Barrier.class
edu/emory/mathcs/jplasma/test/DposvTest.class
edu/emory/mathcs/jplasma/test/DgelsTest.class
edu/emory/mathcs/jplasma/test/DgesvTest.class
edu/emory/mathcs/jplasma/tdouble/Dgels.class
edu/emory/mathcs/jplasma/tdouble/Dgeqrf.class
edu/emory/mathcs/jplasma/tdouble/Dglobal$Dplasma_cntrl.class
edu/emory/mathcs/jplasma/tdouble/Dplasma.class
...
edu/emory/mathcs/jplasma/tdouble/Dglobal$Dplasma_aux.class
edu/emory/mathcs/jplasma/tdouble/Pdormqr.class
edu/emory/mathcs/jplasma/example/DposvExample.class
edu/emory/mathcs/jplasma/example/DgesvExample.class
edu/emory/mathcs/jplasma/example/DgelsExample.class

相反,如果您想使用,例如edu.emory.mathcs.jplasma.tdouble.Dplasma,则需要将其导入为:

from edu.emory.mathcs.jplasma.tdouble import Dplasma

以下是DgelsExample.java分发中JPlasma的端口,该分发在ImageJ脚本编辑器中有效:

from edu.emory.mathcs.jplasma.tdouble import Dplasma
from java.lang import Math
import jarray

M = 15;
N = 10;
NRHS = 5;

A = jarray.zeros(M * N, 'd')
B = jarray.zeros(M * NRHS, 'd')

# Initialize A
for i in range(0, M):
    for j in range(0, N):
        A[M * j + i] = 0.5 - Math.random()

# Initialize B
for i in range(0, M):
    for j in range(0, NRHS):
        B[M * j + i] = Math.random()

# Plasma Initialize
Dplasma.plasma_Init(M, N, NRHS)

# Allocate T
T = Dplasma.plasma_Allocate_T(M, N)

# Solve the problem
INFO = Dplasma.plasma_DGELS(Dplasma.PlasmaNoTrans, M, N, NRHS, A, 0, M, T, 0, B, 0, M)

# Plasma Finalize
Dplasma.plasma_Finalize()

if INFO < 0:
    print("-- Error in DgelsExample example !")
else:
    print("-- Run successfull !")

有关编写Jython脚本的更多信息,请参阅ImageJ Wiki的Jython Scripting页面。

最后一个分离评论:ImageJ脚本编辑器实际上被设计为开发依赖于安装中已存在的组件的单类脚本和插件的工具。我对这样一个具有许多依赖关系的项目的建议是使用IDE(例如Eclipse)在Java中进行编码,因为这样的IDE提供了更多的生产力增强功能。您可以使用基于AST的自动完成来探索您正在使用的库的API,并轻松浏览javadoc和源代码而无需进行网络搜索。