// Copyright 2000, CERN, Geneva, Switzerland
package hep.physics.yappi.io;
import java.io.*;
import java.util.*;
import org.freehep.util.*;
import org.freehep.xml.util.*;
import hep.physics.yappi.*;
/**
* @author Mark Donszelmann
* @version $Id: HTMLYappiWriter.java 8584 2006-08-10 23:06:37Z duns $
*/
public class HTMLYappiWriter extends XHTMLWriter {
private static final String minus = "";
private static final String plus = "+";
private static final String plusorminus = "±";
public HTMLYappiWriter(Writer out) {
super(out);
}
public void close() throws IOException {
super.close();
}
public void write(Object object) {
if (object instanceof ParticleType) {
write((ParticleType)object);
} else if (object instanceof Family) {
write((Family)object);
} else {
System.err.println("HTMLYappiWriter: do not know how to write object of type: "+object.getClass());
}
}
public void writeHead(String title) {
printComment(" WARNING: This file was generated by a program, do NOT edit ");
openTag("head");
setAttribute("name", "keywords");
setAttribute("content", "hep, particle property, pdg, yappi");
printTag("meta");
setAttribute("name", "Author");
setAttribute("content", "Auto-Generated by YaPPI: see http://yappi.freehep.org/");
printTag("meta");
openTag("title");
println("Particle: "+title);
closeTag(); // title
setAttribute("rel", "stylesheet");
setAttribute("type", "text/css");
setAttribute("href", "hep/physics/yappi/io/yappi.css");
printTag("link");
closeTag(); // head
}
public void write(Family family) {
if (family != null) {
setAttribute("class", "family");
openTag("div");
encode(family.getName(), "family");
closeTag(); // div
printTag("hr");
}
}
public void write(ParticleType particle) {
setAttribute("class", "particle");
openTag("div");
// top table (name, spec)
setAttribute("border",0);
setAttribute("width", "100%");
setAttribute("summary", "Particle name and definition");
openTag("table");
openTag("tr");
setAttribute("nowrap", true);
setAttribute("width", "20%");
setAttribute("class", "particle-name");
openTag("td");
encode(particle.getName(), "particlename");
closeTag(); // td
setAttribute("nowrap", true);
setAttribute("width", "20%");
setAttribute("class", "particle-asciiname");
openTag("td");
println(particle.getName());
closeTag(); // td
setAttribute("nowrap", true);
openTag("td");
closeTag(); // td
// FIXME: this is hardcoded info
setAttribute("nowrap", true);
setAttribute("width", "30%");
setAttribute("class", "particle-info");
openTag("td");
printPlain("I<sup class=\"particle\">G</sup>");
printPlain("(J<sup class=\"particle\">PC</sup>) = ");
printPlain("0<sup class=\"particle\">"+plus+"</sup>");
printPlain("(0<sup class=\"particle\">"+minus+plus+"</sup>)");
closeTag(); // td
closeTag(); // tr
closeTag(); // table
closeTag(); // div
// small vertical space
openTag("p");
print(" ");
closeTag(); // p
// center table
setAttribute("class", "property");
openTag("div");
setAttribute("border", 0);
setAttribute("summary", "Particle data");
setAttribute("class", "property");
openTag("table");
Iterator iterator = particle.getData();
while (iterator.hasNext()) {
Data data = (Data)iterator.next();
write(data);
}
closeTag(); // table
closeTag(); // div
// small vertical space
openTag("p");
print(" ");
closeTag(); // p
// decay mode table
setAttribute("class", "decay");
openTag("div");
writeDecayModes(particle);
closeTag(); // div
// bottom line
printTag("hr");
// address
setAttribute("class", "footer");
openTag("address");
println("Generated by ");
setAttribute("href", "http://yappi.freehep.org");
setAttribute("class", "footer");
openTag("a");
print("YaPPI, Yet another Particle Property Interface");
closeTag(); // a
println(", ");
setAttribute("href", "http://www.cern.ch");
setAttribute("class", "footer");
openTag("a");
print("CERN");
closeTag(); // a
println(", Copyright 2000, 2001.");
closeTag(); // address
setAttribute("class", "footer");
openTag("address");
println("Data provided by the ");
setAttribute("href", "http://pdg.lbl.gov");
setAttribute("class", "footer");
openTag("a");
print("PDG, Particle Data Group");
closeTag(); // a
println(", Copyright 2000.");
closeTag(); // address
}
private void write(Data data) {
String posError = data.getPosErrorAsString();
String negError = data.getNegErrorAsString();
int rowspan = ((posError == null) || (posError.equals(negError))) ? 1 : 2;
setAttribute("class", "property");
openTag("tr");
// name
setAttribute("rowspan", rowspan);
setAttribute("nowrap", true);
setAttribute("class", "property");
openTag("td");
println(data.getName());
closeTag(); // td
// value
setAttribute("align", "right");
setAttribute("rowspan", rowspan);
setAttribute("nowrap", true);
setAttribute("class", "property");
openTag("td");
int mantissa = writeValue(data.getValueAsString());
closeTag(); // td
// posError
printPlain("<td nowrap=\"nowrap\"");
if (posError != null) {
if (rowspan == 1) {
printPlain(" class=\"property\">");
printPlain(plusorminus+" ");
writeValue(posError);
} else {
printPlain(" class=\"property-poserror\">");
printPlain(plus+" ");
writeValue(posError);
}
} else {
printPlain(" class=\"property\">");
}
printPlain("</td>");
// x 10^-3
setAttribute("rowspan", rowspan);
setAttribute("nowrap", true);
setAttribute("class", "property");
openTag("td");
if (mantissa != 0) {
writeMantissa(mantissa);
} else {
print(" ");
}
closeTag(); // td
// unit
setAttribute("rowspan", rowspan);
setAttribute("nowrap", true);
setAttribute("class", "property");
openTag("td");
println(data.getUnit());
closeTag(); // td
// scalefactor
setAttribute("rowspan", rowspan);
setAttribute("nowrap", true);
setAttribute("class", "property");
openTag("td");
double scaleFactor = data.getScaleFactor();
if (scaleFactor > 0) {
println("(S = "+scaleFactor+")");
}
closeTag(); // td
closeTag(); // tr
if (rowspan == 2) {
// negError
openTag("tr");
printPlain("<td valign=\"bottom\" nowrap=\"nowrap\" class=\"property-negerror\">");
printPlain(minus+" ");
writeValue(negError);
printPlain("</td>");
closeTag(); // tr
}
}
private void writeDecayModes(ParticleType particle) {
setAttribute("width","100%");
setAttribute("border",0);
setAttribute("cellpadding",2);
setAttribute("cellspacing",0);
setAttribute("summary", "Particle Decay Modes");
setAttribute("class", "decay");
openTag("table");
// heading row
setAttribute("class", "decay-header");
openTag("tr");
// name
setAttribute("nowrap", true);
setAttribute("colspan", 2);
setAttribute("align", "left");
setAttribute("class", "decay-header");
openTag("th");
encode(particle.getName(), "decayheader");
println(" Decay Modes");
closeTag(); // th
// fraction
setAttribute("nowrap", true);
setAttribute("colspan", 4);
setAttribute("align", "left");
setAttribute("class", "decay-header");
openTag("th");
print("Fraction (");
setAttribute("class", "symbol");
openTag("span");
print("G");
closeTag(); // span
setAttribute("class", "decay-header");
openTag("sub");
print("i");
closeTag(); // sub
print("/");
setAttribute("class", "symbol");
openTag("span");
print("G");
closeTag(); // span
println(")");
closeTag(); // th
// confidence level
setAttribute("nowrap", true);
setAttribute("class", "decay-header");
openTag("th");
print("Confidence");
printTag("br");
println("Level");
closeTag(); // th
// p(MeV/c), using extra table to keep "p" centered
setAttribute("nowrap", true);
setAttribute("align", "right");
setAttribute("class", "decay-header");
openTag("th");
setAttribute("border", 0);
setAttribute("cellspacing", 0);
setAttribute("cellpadding", 0);
setAttribute("class", "decay");
openTag("table");
setAttribute("nowrap", true);
setAttribute("class", "decay-header");
openTag("th");
print("p");
printTag("br");
println("(MeV/c)");
closeTag(); // th
closeTag(); // table
closeTag(); // th
closeTag(); // tr
// decay channel entries without a group
Iterator decayIterator = particle.getDecayChannels();
while (decayIterator.hasNext()) {
DecayChannel decay = (DecayChannel)decayIterator.next();
if (decay.getDecayGroup() == null) {
write(decay);
}
}
// decay group entries
Iterator groupIterator = particle.getDecayGroups();
while (groupIterator.hasNext()) {
DecayGroup group = (DecayGroup)groupIterator.next();
write(group);
// decay channel entries of this group
Iterator iterator = particle.getDecayChannels();
while (iterator.hasNext()) {
DecayChannel decay = (DecayChannel)iterator.next();
if (decay.getDecayGroup() == group) {
write(decay);
}
}
}
closeTag(); // table
}
private void write(DecayGroup group) {
setAttribute("class", "decay-group");
openTag("tr");
setAttribute("nowrap", true);
setAttribute("colspan", 20);
setAttribute("class", "decay-group");
openTag("th");
encode(group.getName(), "decay-group");
closeTag(); // th
closeTag(); // tr
}
private int bgRow = 0;
private void write(DecayChannel decay) {
String posError = decay.getPosErrorAsString();
String negError = decay.getNegErrorAsString();
int rowspan = ((posError == null) || (posError.equals(negError))) ? 1 : 2;
setAttribute("class", "decay-"+(((bgRow % 2) == 0) ? "even" : "odd"));
openTag("tr");
// name
setAttribute("nowrap", true);
setAttribute("rowspan", rowspan);
setAttribute("class", "decay");
openTag("td");
encode(decay.getName(), "decay");
closeTag(); // td
// FIXME: to be added
// comment
setAttribute("nowrap", true);
setAttribute("rowspan", rowspan);
setAttribute("class", "decay");
openTag("td");
print(" ");
closeTag(); // td
// value
setAttribute("nowrap", true);
setAttribute("rowspan", rowspan);
setAttribute("char", ".");
setAttribute("align", "char");
setAttribute("class", "decay");
openTag("td");
int mantissa = writeValue(decay.getFractionAsString());
closeTag(); // td
// posError
printPlain("<td nowrap=\"nowrap\" char=\".\" align=\"char\"");
if (posError != null) {
if (rowspan == 1) {
printPlain(" class=\"decay\">");
printPlain(plusorminus+" ");
writeValue(posError);
} else {
printPlain(" class=\"decay-poserror\">");
printPlain(plus+" ");
writeValue(posError);
}
} else {
printPlain(" class=\"decay\"> ");
}
printPlain("</td>");
// FIXME: to be added
// closing brace
setAttribute("nowrap", true);
setAttribute("rowspan", rowspan);
setAttribute("align", "right");
setAttribute("class", "decay");
openTag("td");
print(" ");
closeTag(); // td
// FIXME: to be added
// unit
setAttribute("nowrap", true);
setAttribute("rowspan", rowspan);
setAttribute("class", "decay");
openTag("td");
if (mantissa != 0) {
writeMantissa(mantissa);
} else {
print("%");
}
closeTag(); // td
// FIXME: to be added
// confidence level/ scalefactor
setAttribute("nowrap", true);
setAttribute("rowspan", rowspan);
setAttribute("align", "right");
setAttribute("class", "decay");
openTag("td");
print(" ");
closeTag(); // td
// p
setAttribute("nowrap", true);
setAttribute("rowspan", rowspan);
setAttribute("align", "right");
setAttribute("class", "decay");
openTag("td");
String p = decay.getP();
if (p != null) {
print(""+decay.getP());
} else {
print(minus+" ");
}
closeTag(); // td
closeTag(); // tr
// negError
if (rowspan == 2) {
// negError
setAttribute("class", "decay-"+(((bgRow % 2) == 0) ? "even" : "odd"));
openTag("tr");
printPlain("<td valign=\"bottom\" nowrap=\"nowrap\" char=\".\" align=\"char\" class=\"decay-negerror\">");
printPlain(minus+" ");
writeValue(negError);
printPlain("</td>");
closeTag(); // tr
}
// change color for next row
bgRow++;
}
/**
* @return mantissa
*/
private int writeValue(String value) {
String v = value;
int m = 0;
// handle special strings here
if (!value.equals("seen")) {
// find the mantissa
int e = (value.indexOf("E") >= 0) ? value.indexOf("E") : value.indexOf("e");
if (e > 0) {
v = value.substring(0, e);
try {
m = Integer.parseInt(value.substring(e+1));
} catch (NumberFormatException nfe) {
System.err.println("Problem getting mantissa from string: "+value);
}
} else {
v = value;
}
}
printPlain(normalize(v));
return m;
}
private void writeMantissa(int m) {
print("x 10");
setAttribute("class", "decay");
openTag("sup");
print(""+m);
closeTag(); // sup
}
// FIXME: add others
private static HashMap greekTable = new HashMap();
static {
greekTable.put("Delta", "D");
greekTable.put("Gamma", "G");
greekTable.put("Lambda", "L");
greekTable.put("Omega", "W");
greekTable.put("Sigma", "S");
greekTable.put("Upsilon", "U");
greekTable.put("Xi", "X");
greekTable.put("alpha", "a");
greekTable.put("beta", "b");
greekTable.put("chi", "c");
greekTable.put("delta", "d");
greekTable.put("eta", "h");
greekTable.put("gamma", "g");
greekTable.put("mu", "m");
greekTable.put("nu", "n");
greekTable.put("omega", "w");
greekTable.put("phi", "f");
greekTable.put("pi", "p");
greekTable.put("psi", "y");
greekTable.put("rho", "r");
greekTable.put("sigma", "s");
greekTable.put("tau", "t");
greekTable.put("upsilon", "u");
greekTable.put("xi", "x");
greekTable.put("arrowright", "->");
}
/**
* Encode string with format
* <pre>
* - * 0
* Kbar(2)*[(1430)0] as K (1430) [] shows optional part
* 2
* </pre>
*/
private void encode(String s, String cls) {
char c;
while (!s.equals("")) {
String particleName = "";
// look for greek characters
Iterator iterator = greekTable.keySet().iterator();
boolean found = false;
while (!found && iterator.hasNext()) {
String greek = (String)iterator.next();
if (s.startsWith(greek)) {
found = true;
particleName = "<span class=\"symbol\">"+greekTable.get(greek)+"</span>";
s = s.substring(greek.length());
}
}
// normal character and no digit
if (!found && !Character.isDigit(s.charAt(0))) {
particleName = s.substring(0, 1);
s = s.substring(1);
}
// check for bar
if (s.startsWith("bar")) {
printPlain("<span class=\"overline\">");
printPlain(particleName);
printPlain("</span>");
s = s.substring(3);
} else {
printPlain(particleName);
}
// eat digits
if (!found) {
int pos = 0;
int len = s.length();
while ((pos < len) && Character.isDigit(s.charAt(pos))) {
pos++;
}
// if (pos == 0) pos = 1;
printPlain(s.substring(0,pos));
s = s.substring(pos);
}
// check for sub
if ((s.length() >= 3) && (s.charAt(0)=='(') && (s.charAt(2)==')')) {
// (c)
printPlain("<sub class=\""+cls+"\">");
printPlain(normalize(s.substring(1,2)));
printPlain("</sub>");
s = s.substring(3);
}
// look for 0, +, - or *
if (s.length() > 0) {
if (s.startsWith("0")) {
printPlain("<sup class=\""+cls+"\">");
printPlain("0");
printPlain("</sup>");
s = s.substring(1);
} else if (s.startsWith("+")) {
printPlain("<sup class=\""+cls+"\">");
printPlain(plus);
printPlain("</sup>");
s = s.substring(1);
} else if (s.startsWith("-")) {
printPlain("<sup class=\""+cls+"\">");
printPlain(minus);
printPlain("</sup>");
s = s.substring(1);
} else if (s.startsWith("*")) {
printPlain("<sup class=\""+cls+"\">");
printPlain("*");
printPlain("</sup>");
s = s.substring(1);
} else if (s.startsWith("'")) {
printPlain("<sup class=\""+cls+"\">");
printPlain("'");
printPlain("</sup>");
s = s.substring(1);
} else if (s.startsWith("pm")) {
printPlain("<sup class=\""+cls+"\">");
printPlain(plusorminus);
printPlain("</sup>");
s = s.substring(2);
} else if (s.startsWith("mp")) {
printPlain("<sup class=\""+cls+"\">");
printPlain(minus+"/"+plus);
printPlain("</sup>");
s = s.substring(2);
} else {
}
}
// look for (1650)
if ((s.length() >= 3) && (s.charAt(0) == '(')) {
int pos = s.indexOf(')');
if (pos < 0) {
System.err.println("Error: non matching braces in: "+s);
s = s.substring(1);
} else {
// (1650) or (K+K-)
printPlain("(");
encode(normalize(s.substring(1,pos)), cls);
printPlain(")");
s = s.substring(pos+1);
}
// look for 0, +, -, ' or *
if (s.length() > 0) {
c = s.charAt(0);
if ((c == '0') || (c =='+') || (c == '-') || (c == '\'') || (c == '*')) {
printPlain("<sup class=\""+cls+"\">");
if (c == '-') {
printPlain(minus);
} else {
printPlain(s.substring(0, 1));
}
printPlain("</sup>");
s = s.substring(1);
}
}
}
// eat up all white space (avoids "K + c.c." to become "K+c.c."
while ((s.length() > 0) && (Character.isWhitespace(s.charAt(0)))) {
printPlain(" ");
s = s.substring(1);
}
}
}
}