package com.plectix.simulator.smiles;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class FullereneCreator {
private static final String TEST_DATA_DIRECTORY = "test.data"
+ File.separator + "smiles" + File.separator + "fullerenes-ccd1";
private static final String OUTPUT_FILENAME = "Fullerenes.txt";
private static final String[] AGENT_NAMES = { "A", "B", "C", "D", "E", "F" };
private static final String[] SITE_NAMES = { "x", "y", "z", "t", "q", "r",
"p", "m", "h", "g", "f", "s", "w", "k", "j", "n", "b", "c", "a",
"d" };
public static void main(String[] args) throws IOException {
List<String> ccd1Files = crawlFolder(TEST_DATA_DIRECTORY,
new ArrayList<String>());
PrintStream outputStream = new PrintStream(new FileOutputStream(
OUTPUT_FILENAME));
int counter = 0;
for (String file : ccd1Files) {
BufferedReader reader = new BufferedReader(new FileReader(file));
outputStream.println(createFullerene(reader));
reader.close();
counter++;
}
outputStream.close();
System.err.println("Created " + counter + " fullerenes");
}
private static final String createFullerene(BufferedReader reader)
throws IOException {
String line = reader.readLine();
int numberOfVertices = Integer.parseInt(line.trim());
List<FullereneVertex> vertices = new ArrayList<FullereneVertex>(
numberOfVertices);
line = reader.readLine();
while (line != null) {
vertices.add(new FullereneVertex(AGENT_NAMES[0], line));
line = reader.readLine();
}
if (vertices.size() != numberOfVertices) {
throw new RuntimeException("Unexpected number of vertices: "
+ vertices.size() + " != " + numberOfVertices);
}
StringBuffer kappaStringBuffer = new StringBuffer();
int lastLinkIndex = 1;
for (FullereneVertex vertix : vertices) {
vertix.sanityCheckNeighbors(vertices);
lastLinkIndex = vertix.computeKappaString(vertices, lastLinkIndex);
kappaStringBuffer.append(vertix.getKappaString() + ", ");
}
kappaStringBuffer.deleteCharAt(kappaStringBuffer.length() - 2);
return kappaStringBuffer.toString();
}
private static final List<String> crawlFolder(String testDataDirectory,
List<String> ccd1Files) {
File file = new File(testDataDirectory);
if (!file.exists()) {
throw new RuntimeException("File " + file.getName()
+ " does not exist!");
}
if (file.isFile()) {
ccd1Files.add(file.getAbsolutePath());
} else if (file.isDirectory()) {
for (String f : file.list()) {
crawlFolder(testDataDirectory + File.separator + f, ccd1Files);
}
} else {
throw new RuntimeException("Don't know how to deal with file "
+ file.getName());
}
return ccd1Files;
}
private static final class FullereneVertex {
private static final int NUMBER_OF_FIELDS = 10;
private String kappaString = null;
private String agentName = null;
private int[] neighbors = new int[3];
private int[] agentLinks = new int[3];
private int id = -1;
private double x = Double.NaN;
private double y = Double.NaN;
private double z = Double.NaN;
public FullereneVertex(String agentName, String line) {
super();
this.agentName = agentName;
Arrays.fill(agentLinks, 0);
Arrays.fill(neighbors, -1);
String[] fields = line.split(" ");
String[] data = new String[NUMBER_OF_FIELDS];
int i = 0;
for (String field : fields) {
if (field.length() > 0) {
// System.err.println("|" + field.trim() + "|" + " where " +
// line);
data[i++] = field.trim();
}
}
i = 1;
id = Integer.parseInt(data[i++]);
x = Double.parseDouble(data[i++]);
y = Double.parseDouble(data[i++]);
z = Double.parseDouble(data[i++]);
i++;
neighbors[0] = Integer.parseInt(data[i++]);
neighbors[1] = Integer.parseInt(data[i++]);
neighbors[2] = Integer.parseInt(data[i++]);
}
public final String getKappaString() {
return kappaString;
}
public final int computeKappaString(List<FullereneVertex> vertices,
int lastLinkIndex) {
StringBuffer kappaStringBuffer = new StringBuffer(agentName + "(");
for (int i = 0; i < agentLinks.length; i++) {
int linkIndex = agentLinks[i];
if (linkIndex == 0) {
linkIndex = lastLinkIndex++;
vertices.get(neighbors[i] - 1)
.setLinkIndex(this, linkIndex);
}
kappaStringBuffer.append(SITE_NAMES[i] + "!" + linkIndex + ",");
}
kappaStringBuffer.replace(kappaStringBuffer.length() - 1,
kappaStringBuffer.length(), ")");
kappaString = kappaStringBuffer.toString();
return lastLinkIndex;
}
private final void setLinkIndex(FullereneVertex fullereneVertex,
int linkIndex) {
for (int i = 0; i < neighbors.length; i++) {
if (fullereneVertex.id == neighbors[i]) {
agentLinks[i] = linkIndex;
return;
}
}
throw new RuntimeException("Could not find the neighbor!");
}
public final void sanityCheckNeighbors(List<FullereneVertex> vertices) {
List<FullereneVertex> verticesCopy = new ArrayList<FullereneVertex>(
vertices);
final FullereneVertex thisVertex = this;
Collections.sort(verticesCopy, new Comparator<FullereneVertex>() {
public int compare(final FullereneVertex o1,
final FullereneVertex o2) {
return Double.compare(thisVertex
.computeDistanceSquareTo(o1), thisVertex
.computeDistanceSquareTo(o2));
}
});
for (int i = 0; i < neighbors.length; i++) {
boolean found = false;
// we are number 0 on the list!
for (int j = 1; j < 1 + neighbors.length; j++) {
if (neighbors[i] == verticesCopy.get(j).id) {
found = true;
break;
}
}
if (!found) {
StringBuffer sb = new StringBuffer();
for (int j = 0; j < verticesCopy.size(); j++) {
FullereneVertex o1 = verticesCopy.get(j);
sb.append(o1.id + " -> " + computeDistanceSquareTo(o1)
+ "\n");
}
throw new RuntimeException(
"sanityCheckNeighbors failed for vertix: " + id
+ " (" + x + ", " + y + ", " + z + ") ["
+ neighbors[0] + " " + neighbors[1] + " "
+ neighbors[2] + "] ["
+ verticesCopy.get(0).id + " "
+ verticesCopy.get(1).id + " "
+ verticesCopy.get(2).id + "]\n"
+ sb.toString());
}
}
}
private final double computeDistanceSquareTo(final FullereneVertex o) {
return (o.x - x) * (o.x - x) + (o.y - y) * (o.y - y) + (o.z - z)
* (o.z - z);
}
}
}