1 added + 6 modified, total 7 files
lcsim/src/org/lcsim/contrib/onoprien/tracking
diff -u -r1.4 -r1.5
--- ExampleDriver.java 10 May 2007 21:17:12 -0000 1.4
+++ ExampleDriver.java 20 May 2007 03:33:24 -0000 1.5
@@ -7,6 +7,7 @@
import org.lcsim.recon.cat.util.Const;
import org.lcsim.util.Driver;
+import org.lcsim.contrib.onoprien.tracking.clustering.ClusteringDriver;
import org.lcsim.contrib.onoprien.tracking.digitization.DigitizationDriver;
import org.lcsim.contrib.onoprien.tracking.digitization.Digitizer;
import org.lcsim.contrib.onoprien.tracking.digitization.digitizers.DigitizerSmear;
@@ -20,7 +21,7 @@
/**
*
* @author D.Onoprienko
- * @version $Id: ExampleDriver.java,v 1.4 2007/05/10 21:17:12 onoprien Exp $
+ * @version $Id: ExampleDriver.java,v 1.5 2007/05/20 03:33:24 onoprien Exp $
*/
public class ExampleDriver extends Driver {
@@ -65,9 +66,13 @@
DigitizationDriver digitizationDriver = new DigitizationDriver(digitizer);
digitizationDriver.setOutputCollection("DigiHits");
add(digitizationDriver);
-
+
+ ClusteringDriver clusteringDriver = new ClusteringDriver();
+ clusteringDriver.set("INPUT_MAP_NAME","DigiHits");
+ clusteringDriver.set("OUTPUT_MAP_NAME","ClusterData");
+ add(clusteringDriver);
}
-
+
public void process(EventHeader event) {
super.process(event);
lcsim/src/org/lcsim/contrib/onoprien/tracking/digitization
diff -u -r1.2 -r1.3
--- DigitizationDriver.java 10 May 2007 21:13:42 -0000 1.2
+++ DigitizationDriver.java 20 May 2007 03:33:24 -0000 1.3
@@ -33,7 +33,7 @@
* in the constructor.
*
* @author D.Onoprienko
- * @version $Id: DigitizationDriver.java,v 1.2 2007/05/10 21:13:42 onoprien Exp $
+ * @version $Id: DigitizationDriver.java,v 1.3 2007/05/20 03:33:24 onoprien Exp $
*/
public class DigitizationDriver extends Driver {
@@ -191,7 +191,7 @@
compHit.addHit(hit);
} else {
if (compHit == null) {
- dList.add(previousHit);
+ if (previousHit != null) dList.add(previousHit);
} else {
compHit.trimToSize();
dList.add(compHit);
lcsim/src/org/lcsim/contrib/onoprien/tracking/geom
diff -u -r1.1 -r1.2
--- SensorType.java 7 May 2007 19:02:42 -0000 1.1
+++ SensorType.java 20 May 2007 03:33:24 -0000 1.2
@@ -1,5 +1,7 @@
package org.lcsim.contrib.onoprien.tracking.geom;
+import java.util.List;
+
import hep.physics.vec.Hep3Vector;
/**
@@ -12,12 +14,9 @@
* right-nahded system.
*
* @author D.Onoprienko
- * @version $Id: SensorType.java,v 1.1 2007/05/07 19:02:42 onoprien Exp $
+ * @version $Id: SensorType.java,v 1.2 2007/05/20 03:33:24 onoprien Exp $
*/
public interface SensorType {
-
- /** Returns maximum channel ID on this sensor. */
- public int getMaxChannelID();
/**
* Converts a point in local sensor coordinates to channel ID.
@@ -30,13 +29,27 @@
*/
public Hep3Vector getChannelPosition(int channelID);
+ /** Returns maximum channel ID on this sensor. */
+ public int getMaxChannelID();
+
+ /** Returns dimensions of a given channel along U, V, W. */
+ public Hep3Vector getChannelDimensions(int channelID);
+
/**
- * Returns dimensions of a given channel along U, V, W.
+ * Returns the dimension of a measurement by this type of sensor
+ * (1 for strips, 2 for pixels, etc). Note that algorithms can ignore this method
+ * and use {@link #getChannelDimensions(int)} to decide how to treat measurements
+ * by the given sensor. However, {@link #getNeighbors(int)} should only look for
+ * neighbors in <tt>U</tt> direction if this method returns <tt>1</tt>.
*/
- public Hep3Vector getChannelDimensions(int channelID);
+ public int getHitDimension();
/**
- * Returns channel ID of a neighbor channel.
+ * Returns ID of a channel obtained by shifting the given channel by the given
+ * number of channels in the given direction along the local reference frame axis.
+ * Returns <tt>-1</tt> if shifting puts the point outside of the sensor boundaries.
+ * Throws <tt>IllegalArgumentException</tt> if this type of sensor does not have a
+ * concept of a neighbor in the given direction.
*
* @param channelID ID of the original channel
* @param shiftV move in <tt>V</tt> direction by <tt>shiftV</tt> channels
@@ -44,4 +57,9 @@
*/
public int getNeighbor(int channelID, int shiftU, int shiftV);
+ /**
+ * Returns array of IDs of all immediate neighbor channels.
+ */
+ public List<Integer> getNeighbors(int channelID);
+
}
lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/sensortype
diff -u -r1.2 -r1.3
--- Cylinder.java 10 May 2007 21:13:42 -0000 1.2
+++ Cylinder.java 20 May 2007 03:33:24 -0000 1.3
@@ -1,5 +1,8 @@
package org.lcsim.contrib.onoprien.tracking.geom.sensortype;
+import java.util.ArrayList;
+import java.util.List;
+
import hep.physics.vec.BasicHep3Vector;
import hep.physics.vec.Hep3Vector;
@@ -11,7 +14,7 @@
* center of the cylinder.
*
* @author D.Onoprienko
- * @version $Id: Cylinder.java,v 1.2 2007/05/10 21:13:42 onoprien Exp $
+ * @version $Id: Cylinder.java,v 1.3 2007/05/20 03:33:24 onoprien Exp $
*/
public class Cylinder implements SensorType {
@@ -36,8 +39,9 @@
_radius = radius;
_nDivV = nLength;
_nDivU = nPhi;
- _pitch = TWOPI/_nDivU;
- _length = length/_nDivV;
+ _stripWidth = TWOPI/_nDivU;
+ _stripLength = length/_nDivV;
+ _hitDim = (_stripLength/_stripWidth < 4.) ? 2 : 1;
}
/**
@@ -58,8 +62,9 @@
_radius = radius;
_nDivV = nLength;
_nDivU = (int) Math.round((TWOPI*radius)/stripPitch);
- _pitch = TWOPI/_nDivU;
- _length = length/_nDivV;
+ _stripWidth = TWOPI/_nDivU;
+ _stripLength = length/_nDivV;
+ _hitDim = (_stripLength/_stripWidth < 4.) ? 2 : 1;
}
/**
@@ -80,16 +85,21 @@
_radius = radius;
_nDivV = (int) Math.round(length/stripLength);
_nDivU = (int) Math.round((TWOPI*radius)/stripPitch);
- _pitch = TWOPI/_nDivU;
- _length = length/_nDivV;
+ _stripWidth = TWOPI/_nDivU;
+ _stripLength = length/_nDivV;
+ _hitDim = (stripLength/stripPitch < 4.) ? 2 : 1;
}
+
+// -- Setters : ---------------------------------------------------------------
-// -----------------------------------------------------------------------------
-
- /** Returns maximum possible channel ID on this sensor. */
- public int getMaxChannelID() {
- return _nDivU * _nDivV;
+ /**
+ * Set the dimension of a measurement by this type of sensor (1 for strips, 2 for pixels, etc).
+ */
+ public void setHitDimension(int dim) {
+ _hitDim = dim;
}
+
+// -----------------------------------------------------------------------------
/**
* Converts a point in local sensor coordinates to channel ID.
@@ -97,16 +107,14 @@
*/
public int getChannelID(Hep3Vector point) {
- //System.out.println("Point: phi "+ point.x() +" z "+ point.y() +" r "+ point.z());
-
if (Math.abs(point.z()-_radius) > _halfThick) return -1;
double u = point.x();
double v = point.y();
if (u < 0. || u > TWOPI || Math.abs(v) > _halfLength) return -1;
- int nU = (int) Math.floor(u/_pitch); if (nU == _nDivU) nU--;
- int nV = (int) Math.floor((v+_halfLength)/_length); if (nV == _nDivV) nV--;
+ int nU = (int) Math.floor(u/_stripWidth); if (nU == _nDivU) nU--;
+ int nV = (int) Math.floor((v+_halfLength)/_stripLength); if (nV == _nDivV) nV--;
return nV*_nDivU + nU + 1;
}
@@ -115,17 +123,33 @@
*/
public Hep3Vector getChannelPosition(int channelID) {
int nU = --channelID % _nDivU;
- int nV = channelID / _nDivV;
- double u = (nU + .5) * _pitch;
- double v = (nV + .5) * _length - _halfLength;
- return new BasicHep3Vector(u,v,0.);
+ int nV = channelID / _nDivU;
+ double u = (nU + .5) * _stripWidth;
+ double v = (nV + .5) * _stripLength - _halfLength;
+ return new BasicHep3Vector(u,v,_radius);
+ }
+
+ /** Returns maximum possible channel ID on this sensor. */
+ public int getMaxChannelID() {
+ return _nDivU * _nDivV;
}
/**
* Returns dimensions of the given channel along U, V, W.
*/
public Hep3Vector getChannelDimensions(int channelID) {
- return new BasicHep3Vector(_pitch, _length, 2.*_halfThick);
+ return new BasicHep3Vector(_stripWidth, _stripLength, 2.*_halfThick);
+ }
+
+ /**
+ * Returns the dimension of a measurement by this type of sensor
+ * (1 for strips, 2 for pixels, etc).
+ * By default, this method returns <tt>1</tt> if strip length is at least 4 times
+ * bigger than strip pitch. The return value can also be set explicitly through a call
+ * to {@link #setHitDimension(int)}.
+ */
+ public int getHitDimension() {
+ return _hitDim;
}
/**
@@ -138,25 +162,57 @@
*/
public int getNeighbor(int channelID, int shiftU, int shiftV) {
int nU = (--channelID % _nDivU) + shiftU;
- int nV = (channelID / _nDivV) + shiftV;
- if (nU < 0 || nV < 0 || nU >= _nDivU || nV >= _nDivV) {
+ if (nU < 0) {
+ nU += _nDivU;
+ } else if (nU >= _nDivU) {
+ nU -= _nDivU;
+ }
+ int nV = (channelID / _nDivU) + shiftV;
+ if (nV < 0 || nV >= _nDivV) {
return -1;
} else {
return nV*_nDivU + nU + 1;
}
}
+ /**
+ * Returns array of IDs of all immediate neighbor channels.
+ * For strips ({@link #getHitDimension()} returns 1), this method looks for neighbors
+ * in U direction only. Therefore, each strip has 1 or 2 neighbors. For pixels
+ * ({@link #getHitDimension()} returns 2), up to 8 neighbors can be found.
+ */
+ public List<Integer> getNeighbors(int channelID) {
+ int nU = ((channelID -1) % _nDivU);
+ int nV = ((channelID -1) / _nDivU);
+ ArrayList<Integer> out = new ArrayList<Integer>(8);
+ if ((_hitDim == 2) && (nV > 0)) {
+ out.add((nU > 0) ? (channelID - _nDivU - 1) : (channelID - 1) );
+ out.add( channelID - _nDivU );
+ out.add( (nU < _nDivU - 1) ? (channelID - _nDivU + 1) : (channelID - 2*_nDivU + 1) );
+ }
+ out.add( (nU > 0) ? (channelID - 1) : (channelID - 1 + _nDivU) );
+ out.add( (nU < _nDivU - 1) ? (channelID +1) : (channelID - _nDivU + 1) );
+ if ((_hitDim == 2) && (nV < _nDivV-1)) {
+ out.add( (nU > 0) ? (channelID + _nDivU -1) : (channelID - 1 + 2*_nDivU) );
+ out.add(channelID + _nDivU);
+ out.add( (nU < _nDivU - 1) ? (channelID + _nDivU + 1) : (channelID + 1) );
+ }
+ return out;
+ }
+
// -- Private parts : ---------------------------------------------------------
protected double _halfLength;
protected double _halfThick;
protected double _radius;
- protected double _pitch;
- protected double _length;
+ protected double _stripWidth;
+ protected double _stripLength;
+
+ protected int _hitDim;
protected int _nDivU;
protected int _nDivV;
- protected final double TWOPI = 2.*Math.PI;
+ static final double TWOPI = 2.*Math.PI;
}
lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/sensortype
diff -u -r1.1 -r1.2
--- Rectangle.java 7 May 2007 19:02:42 -0000 1.1
+++ Rectangle.java 20 May 2007 03:33:24 -0000 1.2
@@ -1,5 +1,8 @@
package org.lcsim.contrib.onoprien.tracking.geom.sensortype;
+import java.util.ArrayList;
+import java.util.List;
+
import hep.physics.vec.BasicHep3Vector;
import hep.physics.vec.Hep3Vector;
@@ -10,7 +13,7 @@
* The reference frame origin is at the center of the sensor.
*
* @author D.Onoprienko
- * @version $Id: Rectangle.java,v 1.1 2007/05/07 19:02:42 onoprien Exp $
+ * @version $Id: Rectangle.java,v 1.2 2007/05/20 03:33:24 onoprien Exp $
*/
public class Rectangle implements SensorType {
@@ -37,14 +40,19 @@
_nDivU = nWidth;
_pitch = width/nWidth;
_length = length/nLength;
+ _hitDim = (_length/_pitch < 4.) ? 2 : 1;
}
+
+// -- Setters : ---------------------------------------------------------------
-// -----------------------------------------------------------------------------
-
- /** Returns maximum possible channel ID on this sensor. */
- public int getMaxChannelID() {
- return _nDivU * _nDivV;
+ /**
+ * Set the dimension of a measurement by this type of sensor (1 for strips, 2 for pixels, etc).
+ */
+ public void setHitDimension(int dim) {
+ _hitDim = dim;
}
+
+// -----------------------------------------------------------------------------
/**
* Converts a point in local sensor coordinates to channel ID.
@@ -68,11 +76,16 @@
*/
public Hep3Vector getChannelPosition(int channelID) {
int nU = --channelID % _nDivU;
- int nV = channelID / _nDivV;
+ int nV = channelID / _nDivU;
double u = (nU + .5) * _pitch - _halfWidth;
double v = (nV + .5) * _length - _halfLength;
return new BasicHep3Vector(u,v,0.);
}
+
+ /** Returns maximum possible channel ID on this sensor. */
+ public int getMaxChannelID() {
+ return _nDivU * _nDivV;
+ }
/**
* Returns dimensions of the given channel along U, V, W.
@@ -82,6 +95,17 @@
}
/**
+ * Returns the dimension of a measurement by this type of sensor
+ * (1 for strips, 2 for pixels, etc).
+ * By default, this method returns <tt>1</tt> if strip length is at least 4 times
+ * bigger than strip pitch. Alternatively, the return value can be set explicitly
+ * through a call to {@link #setHitDimension(int)}.
+ */
+ public int getHitDimension() {
+ return _hitDim;
+ }
+
+ /**
* Returns channel ID of a neighbor channel.
* Returns -1 if the channel defined by shifts does not exist on this sensor.
*
@@ -91,7 +115,7 @@
*/
public int getNeighbor(int channelID, int shiftU, int shiftV) {
int nU = (--channelID % _nDivU) + shiftU;
- int nV = (channelID / _nDivV) + shiftV;
+ int nV = (channelID / _nDivU) + shiftV;
if (nU < 0 || nV < 0 || nU >= _nDivU || nV >= _nDivV) {
return -1;
} else {
@@ -99,6 +123,26 @@
}
}
+ /** Returns array of IDs of all immediate neighbor channels. */
+ public List<Integer> getNeighbors(int channelID) {
+ int nU = (channelID -1) % _nDivU;
+ int nV = (channelID -1) / _nDivU;
+ ArrayList<Integer> out = new ArrayList<Integer>(8);
+ if ((_hitDim == 2) && (nV > 0)) {
+ if (nU > 0) out.add(channelID - _nDivU - 1);
+ out.add( channelID - _nDivU );
+ if (nU < _nDivU - 1) out.add(channelID - _nDivU + 1);
+ }
+ if (nU > 0) out.add(channelID - 1);
+ if (nU < _nDivU - 1) out.add(channelID +1);
+ if ((_hitDim == 2) && (nV < _nDivV-1)) {
+ if (nU > 0) out.add(channelID + _nDivU -1);
+ out.add( channelID + _nDivU );
+ if (nU < _nDivU - 1) out.add(channelID + _nDivU + 1);
+ }
+ return out;
+ }
+
// -- Private parts : ---------------------------------------------------------
protected double _halfLength;
@@ -108,6 +152,8 @@
protected double _pitch;
protected double _length;
+ protected int _hitDim;
+
protected int _nDivU;
protected int _nDivV;
}
lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/sensortype
diff -u -r1.1 -r1.2
--- Ring.java 7 May 2007 19:02:42 -0000 1.1
+++ Ring.java 20 May 2007 03:33:24 -0000 1.2
@@ -4,11 +4,17 @@
import hep.physics.vec.Hep3Vector;
/**
- * Class to represent a disk sensor tiled with strips.
+ * Class to represent a disk sensor divided into rectangular strips or pixels.
* Reference frame origin is at the center of the disk.
*
+ * Note that {@link #getNeighbors(int)} method of an instance of this class can
+ * return non-existing channel IDs - for the sake of speed, no ckecking is done
+ * to verify that returned IDs belong to channels inside the ring.
+ * {@link #getChannelID(Hep3Vector)} method returns <tt>-1</tt> if and only if the
+ * center of the rectangle (strip) to which the point belongs is ouside the ring.
+ *
* @author D.Onoprienko
- * @version $Id: Ring.java,v 1.1 2007/05/07 19:02:42 onoprien Exp $
+ * @version $Id: Ring.java,v 1.2 2007/05/20 03:33:24 onoprien Exp $
*/
public class Ring extends Rectangle {
@@ -37,6 +43,8 @@
_pitch = pitch;
_length = length;
+
+ _hitDim = (_length/_pitch < 4.) ? 2 : 1;
}
// -----------------------------------------------------------------------------
@@ -73,7 +81,7 @@
*/
public int getNeighbor(int channelID, int shiftU, int shiftV) {
int nU = (--channelID % _nDivU) + shiftU;
- int nV = (channelID / _nDivV) + shiftV;
+ int nV = (channelID / _nDivU) + shiftV;
double r = Math.hypot((nU + .5) * _pitch - _halfWidth, (nV + .5) * _length - _halfLength);
if (r < _rMin || r > _rMax) {
return -1;
@@ -81,7 +89,7 @@
return nV*_nDivU + nU + 1;
}
}
-
+
// -- Private parts : ---------------------------------------------------------
protected double _rMin;
lcsim/src/org/lcsim/contrib/onoprien/tracking/clustering
diff -N ClusteringDriver.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ClusteringDriver.java 20 May 2007 03:33:25 -0000 1.1
@@ -0,0 +1,123 @@
+package org.lcsim.contrib.onoprien.tracking.clustering;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+import hep.physics.vec.Hep3Vector;
+import org.lcsim.event.EventHeader;
+import org.lcsim.recon.cat.util.Const;
+import org.lcsim.recon.cat.util.NoSuchParameterException;
+import org.lcsim.util.Driver;
+
+import org.lcsim.contrib.onoprien.tracking.geom.Sensor;
+import org.lcsim.contrib.onoprien.tracking.geom.SensorType;
+import org.lcsim.contrib.onoprien.tracking.hit.DigiTrackerHit;
+import org.lcsim.contrib.onoprien.tracking.hit.TrackerClusterData;
+import org.lcsim.contrib.onoprien.tracking.hit.TrackerHitMaker;
+import org.lcsim.contrib.onoprien.tracking.hit.base.TrackerClusterDataBasic;
+
+/**
+ * Driver that handles clustering of {@link DigiTrackerHit} objects.
+ * The driver fetches a map of digitized hits from the event, and
+ * creates a map of clusters.
+ *
+ * @author D.Onoprienko
+ * @version $Id: ClusteringDriver.java,v 1.1 2007/05/20 03:33:25 onoprien Exp $
+ */
+public class ClusteringDriver extends Driver {
+
+// -- Constructors : ----------------------------------------------------------
+
+ public ClusteringDriver() {
+ _inMapName = "DigiTrackerHit";
+ _outMapName = "TrackerClusterData";
+ }
+
+// -- Setters : ---------------------------------------------------------------
+
+ /**
+ * Set any <tt>String</tt> parameter.
+ * The following parameters can be set with this method:<br>
+ * <tt>"INPUT_MAP_NAME"</tt> - Name of input collection of digitized hits
+ * (type <tt>HashMap<Sensor, ArrayList<DigiTrackerHit>></tt>).
+ * Default: "DigiTrackerHit".<br>
+ * <tt>"OUTPUT_MAP_NAME"</tt> - Name of ouitput collection of clusters
+ * (type <tt>HashMap<Sensor, ArrayList<TrackerClusterData>></tt>).
+ * Default: "TrackerClusterData".<br>
+ * @param name Name of parameter to be set. Case is ignored.
+ * @param value Value to be assigned to the parameter.
+ * @throws NoSuchParameterException Thrown if the supplied parameter name is unknown.
+ * Subclasses may catch this exception after a call to <tt>super.set()</tt>
+ * and set their own parameters.
+ */
+ public void set(String name, String value) {
+ if (name.equalsIgnoreCase("INPUT_MAP_NAME")) {
+ _inMapName = value;
+ } else if (name.equalsIgnoreCase("OUTPUT_MAP_NAME")) {
+ _outMapName = value;
+ } else {
+ throw new NoSuchParameterException(name, this.getClass());
+ }
+ }
+
+// -- Event processing : ------------------------------------------------------
+
+ public void process(EventHeader event) {
+
+ super.process(event);
+
+ HashMap<Sensor, ArrayList<DigiTrackerHit>> inMap = (HashMap<Sensor, ArrayList<DigiTrackerHit>>) event.get(_inMapName);
+ HashMap<Sensor, ArrayList<TrackerClusterData>> outMap = new HashMap<Sensor, ArrayList<TrackerClusterData>>();
+
+ for (Sensor sensor : inMap.keySet()) {
+ ArrayList<TrackerClusterData> clusterList = findClusters(sensor, inMap.get(sensor));
+ if ( ! clusterList.isEmpty()) outMap.put(sensor, clusterList);
+ }
+
+ event.put(_outMapName, outMap);
+ }
+
+ /**
+ * Returns a list of found clusters on the sensor.
+ * Default implementation uses simple nearest neighbor clustering.
+ */
+ public ArrayList<TrackerClusterData> findClusters(Sensor sensor, List<DigiTrackerHit> hits) {
+ SensorType senType = sensor.getType();
+ //System.out.println("size fo list given to findClusters "+hits.size());
+ LinkedList<DigiTrackerHit> hitList = (hits instanceof LinkedList) ?
+ (LinkedList<DigiTrackerHit>) hits : new LinkedList<DigiTrackerHit>(hits);
+ ArrayList<TrackerClusterData> clusterList = new ArrayList<TrackerClusterData>();
+ while (! hitList.isEmpty()) {
+ ArrayList<DigiTrackerHit> hitsInCluster = new ArrayList<DigiTrackerHit>();
+ DigiTrackerHit seed = hitList.pop();
+ hitsInCluster.add(seed);
+ List<Integer> newChannels = senType.getNeighbors(seed.getChannel());
+ while (!newChannels.isEmpty()) {
+ List<Integer> oldChannels = newChannels;
+ newChannels = new ArrayList<Integer>(30);
+ ListIterator<DigiTrackerHit> it = hitList.listIterator();
+ while (it.hasNext()) {
+ DigiTrackerHit hit = it.next();
+ int channel = hit.getChannel();
+ if ( newChannels.contains(channel) ) {
+ hitsInCluster.add(hit);
+ newChannels.addAll(senType.getNeighbors(channel));
+ it.remove();
+ }
+ }
+ }
+ hitsInCluster.trimToSize();
+ clusterList.add(new TrackerClusterDataBasic(hitsInCluster,sensor));
+ }
+ clusterList.trimToSize();
+ return clusterList;
+ }
+
+// -- Private parts : ---------------------------------------------------------
+
+ protected String _inMapName;
+ protected String _outMapName;
+}
CVSspam 0.2.8