...
No Format |
---|
package org.lcsim.geometry;
import hep.physics.vec.Hep3Vector;
/**
*
* A preliminary proposal of an interface to Calorimeter hit data
* based on methods from @IDDecoder, @Subdetector, @Calorimeter, @CalorimeterType,
* @CalorimeterHit, @Segmentation, @SegmentationBase (and its 4 subclasses), and
* @BarrelEndcapFlag. For convenience, CalorimeterCell would combine functionality
* from these classes into a single "flattened" API so that users can avoid
* lots of subcasting and/or method chaining in order to access the information
* required for their analysis. It also replaces calls using "magic" field
* names (primarily in IDDecoder) with proper interface methods.
*
* Measurements, such as the position, are within a global coordinate
* system based at (0,0,0), unless otherwise noted. Indices, however,
* may refer to a local or global system. For instance, ix would probably
* translate to local coordinates in a readout plate, while iphi is most
* likely a global phi index.
*
* Any method that does not apply to a given subclass of CalorimeterCell may
* either throw an exception from an unimplemented method (preferred way) or
* just return an invalid or dummy value. For some values, e.g. layer, an
* invalid value like -1 would be fairly obvious. For others, like phi or
* theta indices, an invalid value may be unclear so the method should probably
* just throw an exception.
*
* The list of MCParticles from SimCalorimeterHit has not been included.
* The MCParticle associations should be held externally
* in a CalorimeterCell => MCParticle relation map based on data from
* the input CalorimeterHits. (It is done this way in ATLAS, LHCb, et al.)
* This approach eliminates an explicit dependency on the MCParticle interface,
* and it would also make the relationship between CalorimeterCells and
* MCParticles a lot more flexible. Additionally, the approach can be
* applied generically so that a specialized hit interface using the
* Monte Carlo is not required and any hit object could be associated
* with a particle in the MC truth.
*
* @author Jeremy McCormick
*
*/
public interface CalorimeterCell
{
/**
* 64-bit identifier of this cell
*
* @see CalorimeterHit.getCellId()
*/
long cellId();
/**
* Hash code uniquely identifying the CalorimeterCell object
*
* NOTE: Could be different from cellId()
*
* FIXME: Java provides this already automatically?
*
*/
long hashcode();
/**
* Raw energy in GeV
*
* @see CalorimeterHit.getRawEnergy()
*/
double energyRaw();
/**
* Corrected energy in GeV
*
* @see CalorimeterHit.getCorrectedEnergy()
*
*/
double energyCorrected();
/**
* Shortcut for energy != 0
*/
boolean isHit();
/**
* Time in nanoseconds
*
* @see CalorimeterHit.getTime()
*
*/
double time();
/**
* Center position in mm
*
* @see CalorimeterHit.getPosition()
* @see IDDecoder.getPosition()
*/
Hep3Vector position();
/**
* x at cell center in mm
*
* @see IDDecoder.getX()
*
*/
double x();
/**
* y at cell center in mm
*
* @see IDDecoder.getY()
*
*/
double y();
/**
* z at cell center in mm
*
* @see IDDecoder.getZ()
*
*/
double z();
/**
* Is the given point within tolerance of the cell center?
*/
boolean isNear(Hep3Vector point, double tolerance);
/**
* Distance to center of cell from point
*/
double howNear(Hep3Vector point);
/**
* Is the given point inside this cell?
*/
boolean isInside(Hep3Vector point);
/**
* Theta at cell center in radians
*
* @see IDDecoder.getTheta()
*
*/
double theta();
/**
* Minimum theta extent at edge of cell in radians
*/
double thetaMin();
/**
* Maximum theta extent at edge of cell in radians
*/
double thetaMax();
/**
* Size of the cell in theta, i.e. thetaMax() - thetaMin(), in radians
*/
double thetaSize();
/**
* Phi at cell center, in radians
*
* @see IDDecoder.getPhi()
*
*/
double phi();
/**
* Minimum phi measurement at one edge of the cell in radians
*/
double phiMin();
/**
* Maximum phi measurement at one edge of the cell in radians
*/
double phiMax();
/**
* Size of the cell in phi, i.e. phiMax - phiMin, in radians
*/
double phiSize();
/**
* Radius to the cell midpoint in mm
*/
double rho();
/**
* Minimum radius, i.e. inner radius, in mm
*/
double rhoMin();
/**
* Maximum radius, i.e. outer radius, in mm
*/
double rhoMax();
/**
* Size of the cell in rho, i.e. rhoMax - rhoMin, in mm
*
* NOTE: This method could also be called thickness() or width().
*
*/
double rhoSize();
/**
* X index
*
* @see IDDecoder.getValue()
* @see GridXYZ.getXBin()
*
*/
int ix();
/**
* Y index
*
* @see IDDecoder.getValue()
* @see GridXYZ.getYBin()
*
*/
int iy();
/**
* Z index
*
* @see IDDecoder.getValue()
* @see GridXYZ.getZBin()
*
*/
int iz();
/**
* Theta index
*/
int itheta();
/**
* Phi index
*/
int iphi();
/**
* System number uniquely identifying the Subdetector of this cell
*
* @see IDDecoder.getSystemID()
*
*/
int system();
/**
* Section of the calorimeter along the z axis
*
* NOTE: See Mokka's HCAL models for an example of calorimeter's with sections along z.
*
* NOTE: Only applies to calorimeter's that are subdivided in z, though other types
* could "fake it" based on iz() or z().
*
*/
int section();
/**
* Module number in the section
*
* NOTE: Usually there are as many modules as sides to the calorimeter's polyhedra envelope.
*
* NOTE: Only applies to realistic polyhedra calorimeters, though cylindrical types
* could "fake it" based on iphi() or phi().
*
*/
int module();
/**
* Stave number in the module
*
* NOTE: Mokka's HCAL is an example of a calorimeter with multiple staves per module.
*
*/
int stave();
/**
* Layer number
*
* @see IDDecoder.getLayer()
*
*/
int layer();
/**
* Row number in a plate of cells
*
* NOTE: This is primarily applicable to calorimeters with planar readout volumes,
* such as those within trapezoidal staves. It could also apply to testbeams.
*/
int row();
/**
* Column number in a plate of cells
*
* NOTE: This is primarily applicable to calorimeters with planar readout volumes,
* such as those within trapezoidal staves. It could also apply to testbeams.
*
*/
int column();
/**
* Tower number
*
* NOTE: The tower number identifies a projective tower spanning calorimeter subsystems.
*
* FIXME: Possibly a deprecated/superceded concept?
*
*/
int tower();
/**
* Is the cell flagged as an absorber layer that has been made sensitive for debugging?
*
* NOTE: There are possibly other ways to know whether a cell is actually from an absorber,
* but an interface method is the most straightforward way for user's to access this
* information.
*
*/
boolean isAbsorber();
/**
* Is the cell in a barrel?
*
* @see IDDecoder.getBarrelEndcapFlag()
* @see BarrelEndcapFlag.isBarrel()
*
*/
boolean isBarrel();
/**
* Is the cell in an endcap?
*
* @see IDDecoder.getBarrelEndcapFlag()
* @see BarrelEndcapFlag.isEndcap()
*/
boolean isEndcap();
/**
* Does the cell have a positive z measurement?
*
* NOTE: This function may use the encoded setting from the barrel field
* or just examine the sign of CalorimeterCell.z().
*
* @see IDDecoder.getBarrelEndcapFlag()
* @see BarrelEndcapFlag.isEndcapNorth()
*
*/
boolean isNorth();
/**
* Does the cell have a negative z measurement?
*
* NOTE: This function may use the encoded setting from the barrel field
* or just examine the sign of CalorimeterCell.z().
*
* @see IDDecoder.getBarrelEndcapFlag()
* @see BarrelEndcapFlag.isEndcapSouth()
*
*/
boolean isSouth();
/**
* Is the cell from an ECAL subdetector?
*
* @see Calorimeter.getCalorimeterType()
* @see CalorimeterType
*
*/
boolean isECAL();
/**
* Is the cell from an HCAL subdetector?
*
* @see Calorimeter.getCalorimeterType()
* @see CalorimeterType
*
*/
boolean isHCAL();
/**
* Is the cell from a MUON subdetector?
*
* @see Calorimeter.getCalorimeterType()
* @see CalorimeterType
*
*/
boolean isMUON();
/**
* Is the cell from a FWD subdetector? (forward calorimeter)
*
* @see Calorimeter.getCalorimeterType()
* @see CalorimeterType
*
*/
boolean isFWD();
/**
* Subdetector associated with this CalorimeterCell
*
* @see CalorimeterHit.getSubdetector()
* @see IDDecoder.getSubdetector()
*
* FIXME: This breaks the usual OO heuristic that a contained object should not
* reference its container.
*
* FIXME: Need to make sure that a Subdetector reference is not stored with each CalorimeterCell.
*
*/
Subdetector subdetector();
/**
* IDDecoder associated with this CalorimeterCell
*
* @see CalorimeterHit.getIDDecoder()
*
* FIXME: Need to make sure that an IDDecoder reference is not stored with each CalorimeterCell.
*
*/
IDDecoder decoder();
/**
* Neighbor indices
*
* @see Calorimeter.getNeighbors()
*
* FIXME: This should be spelled "neighbors". Oh, well!
*
* FIXME: Neighbor-finding should return a Neighborhood class rather
* than double array.
*
* FIXME: It should be possible to specifiy the type of neighbors.
* For instance, crosstalk is usually only applied to cardinal
* neighbors, rather than the Moore Neighborhood (i.e. cardinal
* and ordinal neighbors).
*
* FIXME: In my opinion, neighbor-finding should be completely externalized
* to allow for greater flexibility and functionality, though
* removal of neighbor-finding from IDDecoder would break a
* lot of existing code.
*/
long[] neighbours(int deltaLayer, int deltaTheta, int deltaPhi);
/**
* Does this cell type support neighbor-finding?
*
* @see IDDecoder.supportsNeighbours()
*
* FIXME: This is a superfluous function, because the IDDecoder
* interface has a neighbor-finding function. Shouldn't
* it just throw an exception if not implemented?
*/
boolean supportsNeighbours();
/**
*
* Get the generic DetectorElement for this cell.
*
* NOTE: For the future!
*
* FIXME: Need a DetectorElement interface, first.
*
*/
DetectorElement detectorElement();
}
|