Skip to content

Commit

Permalink
Basic Java/Matlab Interface (#2327)
Browse files Browse the repository at this point in the history
* Adding basic Java Interface and example.

* Add basic matlab example

* Update matlab example that generates ellipsoids

* Add Matlab README.md

* Add docs for Java/Matlab
  • Loading branch information
akenmorris authored Sep 21, 2024
1 parent 6fed0eb commit 8885f17
Show file tree
Hide file tree
Showing 15 changed files with 367 additions and 0 deletions.
47 changes: 47 additions & 0 deletions Examples/Java/JavaExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import java.util.List;
import java.util.Map;
import edu.utah.sci.shapeworks.ShapeWorksProject;
import java.io.*;

public class JavaExample {
public static void main(String[] args) {

// Create a new ShapeWorksProject object
ShapeWorksProject project = new ShapeWorksProject();

// Define the list of shapes to be processed
List<String> filenames = List.of("meshes/ellipsoid_00.vtk", "meshes/ellipsoid_01.vtk",
"meshes/ellipsoid_02.vtk", "meshes/ellipsoid_03.vtk");
project.setShapes(filenames);

// Define grooming parameters
Map<String, String> groomingParameters = Map.of(
"alignment_enabled", "true",
"alignment_method", "Center"
// Add more parameters as needed
);
project.setGroomingParameters(groomingParameters);

// Define optimization parameters
Map<String, String> optimizationParameters = Map.of(
"number_of_particles", "128",
"initial_relative_weighting", "0.05"
// Add more parameters as needed
);
project.setOptimizationParameters(optimizationParameters);

System.out.println("Saving project...");
project.save("project.swproj");

// demonstrate loading
System.out.println("Loading project...");
project.load("project.swproj");

System.out.println("Running groom...");
project.groom();
System.out.println("Running optimize...");
project.optimize();
System.out.println("Opening ShapeWorksStudio...");
project.analyze();
}
}
1 change: 1 addition & 0 deletions Examples/Java/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See http://sciinstitute.github.io/ShapeWorks/latest/java/java.html
3 changes: 3 additions & 0 deletions Examples/Java/meshes/ellipsoid_00.vtk
Git LFS file not shown
3 changes: 3 additions & 0 deletions Examples/Java/meshes/ellipsoid_01.vtk
Git LFS file not shown
3 changes: 3 additions & 0 deletions Examples/Java/meshes/ellipsoid_02.vtk
Git LFS file not shown
3 changes: 3 additions & 0 deletions Examples/Java/meshes/ellipsoid_03.vtk
Git LFS file not shown
63 changes: 63 additions & 0 deletions Examples/Matlab/MatlabExample.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
% ShapeWorks Matlab Example

% Add the required directory to MATLAB's dynamic class path
javaaddpath('/Users/amorris/sci/shapeworks/code/Java');

% Add the shapeworks binary directory to the system path
setenv('PATH', [getenv('PATH') ':/Users/amorris/sci/shapeworks/bin/bin']);


import java.util.ArrayList;
import java.util.HashMap;
import edu.utah.sci.shapeworks.ShapeWorksProject;

% Create a new ShapeWorksProject object
project = ShapeWorksProject();

% Create a set of ellipsoid meshes to be processed, save as STL files
for i=0:3
% vary radius using i for one of the ellipsoids directions
[x,y,z]=ellipsoid(0,0,0,50+i*10,50,50);
fv = surf2patch(x, y, z, 'triangles');
TR = triangulation(fv.faces, fv.vertices);
stlwrite(TR, sprintf('ellipsoid_%02d.stl', i));
end


% Define the list of shapes to be processed
filenames = ArrayList();
filenames.add('ellipsoid_00.stl');
filenames.add('ellipsoid_01.stl');
filenames.add('ellipsoid_02.stl');
filenames.add('ellipsoid_03.stl');
project.setShapes(filenames);

% Define grooming parameters (using HashMap)
groomingParameters = HashMap();
groomingParameters.put('alignment_enabled', 'true');
groomingParameters.put('alignment_method', 'Center');
% Add more parameters as needed
project.setGroomingParameters(groomingParameters);

% Define optimization parameters (using HashMap)
optimizationParameters = HashMap();
optimizationParameters.put('number_of_particles', '128');
optimizationParameters.put('initial_relative_weighting', '0.05');
% Add more parameters as needed
project.setOptimizationParameters(optimizationParameters);

% Save the project
disp('Saving project...');
project.save('project.swproj');

% Demonstrate loading the project
disp('Loading project...');
project.load('project.swproj');

% Run the groom, optimize, and analyze steps
disp('Running groom...');
project.groom();
disp('Running optimize...');
project.optimize();
disp('Opening ShapeWorksStudio...');
project.analyze();
1 change: 1 addition & 0 deletions Examples/Matlab/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See http://sciinstitute.github.io/ShapeWorks/latest/java/matlab.html
131 changes: 131 additions & 0 deletions Java/ShapeWorksProject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package edu.utah.sci.shapeworks;

import java.io.*;
import java.util.*;

public class ShapeWorksProject {
private List<String> shapes;
private Map<String, String> groomingParameters;
private Map<String, String> optimizationParameters;

public void setShapes(List<String> filenames) {
this.shapes = filenames;
}

public void setGroomingParameters(Map<String, String> groomingParameters) {
this.groomingParameters = groomingParameters;
}

public void setOptimizationParameters(Map<String, String> optimizationParameters) {
this.optimizationParameters = optimizationParameters;
}

public void save(String filename) {
try (PrintWriter writer = new PrintWriter(new FileOutputStream(filename))) {
writer.println("{");
writer.println("\"data\": [");
for (int i = 0; i < shapes.size(); i++) {
writer.println(
" {\"shape_" + (i + 1) + "\": \"" + shapes.get(i) + "\"}" + (i < shapes.size() - 1 ? "," : ""));
}
writer.println("],");
writer.println("\"groom\": {");
writer.println(" \"1\": {");
int i = 0;
for (Map.Entry<String, String> entry : groomingParameters.entrySet()) {
writer.println(" \"" + entry.getKey() + "\": \"" + entry.getValue() + "\""
+ ((i < groomingParameters.size() - 1) ? "," : ""));
i++;
}
writer.println(" }");
writer.println("},");
writer.println("\"optimize\": {");
i = 0;
for (Map.Entry<String, String> entry : optimizationParameters.entrySet()) {
writer.println(" \"" + entry.getKey() + "\": \"" + entry.getValue() + "\""
+ ((i < optimizationParameters.size() - 1) ? "," : ""));
i++;
}
writer.println("},");
writer.println("\"project\": {");
writer.println(" \"version\": \"2\"");
writer.println("}");
writer.println("}");
} catch (IOException e) {
e.printStackTrace();
}
}

public void load(String filename) {
try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
StringBuilder jsonBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
jsonBuilder.append(line.trim());
}
String json = jsonBuilder.toString();

// Basic JSON parsing (Note: This is a simplistic parser; real-world scenarios
// should use a complete library)
this.shapes = new ArrayList<>();
this.groomingParameters = new HashMap<>();
this.optimizationParameters = new HashMap<>();

// Parse data
int dataStart = json.indexOf("\"data\": [") + 8;
int dataEnd = json.indexOf("]", dataStart);
String dataContent = json.substring(dataStart, dataEnd);
String[] dataEntries = dataContent.split("},\\s*\\{");
for (String entry : dataEntries) {
shapes.add(entry.split(":")[1].replace("\"", "").replace("}", "").replace("{", "").trim());
}

// Parse groom
int groomStart = json.indexOf("\"groom\": {") + 10;
int groomEnd = json.indexOf("}", groomStart) + 1;
String groomContent = json.substring(groomStart, groomEnd);
String[] groomEntries = groomContent.split(",");
for (String entry : groomEntries) {
String[] keyValue = entry.split(":");
if (keyValue.length == 2) {
groomingParameters.put(keyValue[0].replace("\"", "").trim(), keyValue[1].replace("\"", "").trim());
}
}
// Parse optimize
int optimizeStart = json.indexOf("\"optimize\": {") + 12;
int optimizeEnd = json.indexOf("}", optimizeStart);
String optimizeContent = json.substring(optimizeStart, optimizeEnd);
String[] optimizeEntries = optimizeContent.split(",");
for (String entry : optimizeEntries) {
String[] keyValue = entry.split(":");
if (keyValue.length == 2) {
optimizationParameters.put(keyValue[0].replace("\"", "").trim(),
keyValue[1].replace("\"", "").trim());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}

public void groom() {
runSystemCommand("shapeworks groom --name project.swproj");
}

public void optimize() {
runSystemCommand("shapeworks optimize --name project.swproj");
}

public void analyze() {
runSystemCommand("shapeworksstudio project.swproj");
}

private void runSystemCommand(String command) {
try {
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
56 changes: 56 additions & 0 deletions docs/java/java.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Using the ShapeWorks Java Interface

This example Java program demonstrates how to use the ShapeWorks Java interface to perform the following tasks:

1. Create a ShapeWorks project
2. Add a shape to the project
3. Set grooming parameters
4. Set correspondence parameters
5. Save/Load the project
6. Run the ShapeWorks grooming pipeline
7. Run the ShapeWorks correspondence optimization
8. Launch the ShapeWorks Analysis GUI

# Building the ShapeWorks Java Interface

The ShapeWorks Java interface is built using the Java Compiler. To build it:

```
cd shapeworks/Java
javac -d . *.java
```

This will place the compiled classes in the `shapeworks/Java` directory.

# Building the Example Java Program

```
cd shapeworks/Examples/Java
javac -cp ../../Java *.java
```

# Running the Example Java Program

Note: The example Java program assumes that the ShapeWorks executable is in $PATH. Ensure that you can run `shapeworks` from the command line before running the example Java program.

```
java -cp ../../Java:. JavaExample
```

This will run the example Java program. The output should look like this:

```
Saving project...
Loading project...
Running groom...
Running optimize...
Opening ShapeWorksStudio...
```

And the ShapeWorks Analysis GUI will open.

From here you can change to the analysis module and examine the shape model.

![Studio Java Example](java_example.png){: width="600" }


Binary file added docs/java/java_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions docs/java/matlab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Using the ShapeWorks Matlab Interface

This example Matlab program demonstrates how to use the ShapeWorks Matlab interface via Java to perform the following tasks:

1. Create a ShapeWorks project
2. Generate Ellipsoids
3. Add shapes to the project
4. Set grooming parameters
5. Set correspondence parameters
6. Save/Load the project
7. Run the ShapeWorks grooming pipeline
8. Run the ShapeWorks correspondence optimization
9. Launch the ShapeWorks Analysis GUI

# Building the ShapeWorks Java Interface

The ShapeWorks Java interface is built using the Java Compiler. To build it:

```
cd shapeworks/Java
javac -d . *.java
```

This will place the compiled classes in the `shapeworks/Java` directory.

# Building the Example Java Program

```
cd shapeworks/Examples/Java
javac -cp ../../Java *.java
```

# Running the Example Matlab Program

Note: The example Matlab program uses the Java interface and needs the paths to the ShapeWorks executables. Ensure that you update the paths in the start of the script.

# Running the Example Matlab Program

From the Matlab terminal, run the following:

```
cd shapeworks/Examples/Matlab
javaaddpath('../../Java')
MatlabExample
```

![Matlab Example](matlab_example1.png){: width="600" }


![Studio Matlab Example](matlab_example2.png){: width="600" }


Binary file added docs/java/matlab_example1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/java/matlab_example2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ nav:
- Classes: 'api/Classes/index_classes.md'
- Files: 'api/Files/index_files.md'

- Java/Matlab Interface:
- Java Interface: 'java/java.md'
- Matlab Interface: 'java/matlab.md'

- About:
- 'Meet ShapeWorkers!': 'about/team.md'
- 'Release Notes': 'about/release-notes.md'
Expand Down

0 comments on commit 8885f17

Please sign in to comment.