diff --git a/Detector/DetDriftChamber/CMakeLists.txt b/Detector/DetDriftChamber/CMakeLists.txt
index b680276955849c32df5af4e92216e9cab21accf9..0c1cc85b2d26105a245427a369270ad4027769a5 100644
--- a/Detector/DetDriftChamber/CMakeLists.txt
+++ b/Detector/DetDriftChamber/CMakeLists.txt
@@ -27,9 +27,9 @@ gaudi_add_module(DetDriftChamber
${DetDriftChamber_src}
INCLUDE_DIRS
# DD4hep ROOT Geant4 src/include
- LINK_LIBRARIES
+ LINK_LIBRARIES GaudiKernel DD4hep ROOT DetSegmentation
# GaudiKernel
- DD4hep ${DD4hep_COMPONENT_LIBRARIES}
+ #DD4hep ${DD4hep_COMPONENT_LIBRARIES}
# ROOT Geant4
)
diff --git a/Detector/DetDriftChamber/compact/det.xml b/Detector/DetDriftChamber/compact/det.xml
index 84a1ec7b05d00220ac3fda86c50f4d0111b550b7..b791565dba6598a8c2edc8a178b30afd2c30e25a 100644
--- a/Detector/DetDriftChamber/compact/det.xml
+++ b/Detector/DetDriftChamber/compact/det.xml
@@ -38,6 +38,7 @@
<constant name="SDT_inner_chamber_layer_number" value="67"/>
<constant name="SDT_outer_chamber_layer_number" value="63"/>
<constant name="SDT_chamber_layer_width" value="10*mm"/>
+ <constant name="Epsilon" value="0*deg"/>
</define>
@@ -52,14 +53,15 @@
<detectors>
<detector id="1" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true">
<!-- Use cm as unit if you want to use Pandora for reconstruction -->
+ <sensitive type="SimpleDriftChamber"/>
</detector>
</detectors>
<readouts>
<readout name="DriftChamberHitsCollection">
- <segmentation type="GridDriftChamber" delta_phi="8*deg" identifier_phi="phi"/>
+ <segmentation type="GridDriftChamber" cell_size="10*mm" offset_phi="0." epsilon0="Epsilon" detector_length="SDT_half_length" identifier_phi="cellID" />
- <id>system:8,chamber:1,layer:8,phi:16</id>
+ <id>system:8,chamber:1,layer:8,cellID:16</id>
</readout>
</readouts>
diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
index c71012156662c8b053567bf2667d535c097016a6..07b95b983df469f822a61b22d7ba2827e27b50eb 100644
--- a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
+++ b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
@@ -8,8 +8,10 @@
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/Printout.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
+#include "XML/XMLElements.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/Segmentation.h"
#include "DetSegmentation/GridDriftChamber.h"
@@ -24,6 +26,9 @@ using namespace dd4hep::rec ;
static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
xml_h e,
dd4hep::SensitiveDetector sens) {
+ // ------- Lambda functions ---- //
+ auto delta_a_func = [](auto x, auto y) { return 0.5 * ( x + y ); };
+
// =======================================================================
// Parameter Definition
// =======================================================================
@@ -33,6 +38,8 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
std::string det_name = x_det.nameStr();
std::string det_type = x_det.typeStr();
+ dd4hep::SensitiveDetector sd = sens;
+
// - global
double chamber_radius_min = theDetector.constant<double>("SDT_radius_min");
double chamber_radius_max = theDetector.constant<double>("SDT_radius_max");
@@ -53,6 +60,8 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
int outer_chamber_layer_number = theDetector.constant<int>("SDT_outer_chamber_layer_number");
double chamber_layer_width = theDetector.constant<double>("SDT_chamber_layer_width");
+ double epsilon = theDetector.constant<double>("Epsilon");
+
// =======================================================================
// Detector Construction
// =======================================================================
@@ -75,36 +84,55 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
dd4hep::Tube det_outer_chamber_solid(outer_chamber_radius_min, outer_chamber_radius_max, outer_chamber_length*0.5);
dd4hep::Volume det_outer_chamber_vol(det_name+"_outer_chamber_vol", det_outer_chamber_solid, det_mat);
+ //Initialize the segmentation
+ dd4hep::Readout readout = sd.readout();
+ dd4hep::Segmentation geomseg = readout.segmentation();
+ dd4hep::Segmentation* _geoSeg = &geomseg;
+
+ auto DCHseg = dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*>(_geoSeg->segmentation());
// - layer
- for(int layer_id=0; layer_id<(inner_chamber_layer_number+outer_chamber_layer_number-1);layer_id++) {
- double rmin,rmax;
- std::string layer_name;
- dd4hep::Volume* current_vol_ptr = nullptr;
-
- if(layer_id<inner_chamber_layer_number){
- current_vol_ptr = &det_inner_chamber_vol;
- rmin = inner_chamber_radius_min+(layer_id*chamber_layer_width);
- rmax = rmin+chamber_layer_width;
- layer_name = det_name+"_inner_chamber_vol"+_toString(layer_id,"_layer%d");
- }else{
- current_vol_ptr = &det_outer_chamber_vol;
- rmin = outer_chamber_radius_min+((layer_id-inner_chamber_layer_number)*chamber_layer_width);
- rmax = rmin+chamber_layer_width;
- layer_name = det_name+"_outer_chamber_vol"+_toString(layer_id,"_layer%d");
+ for(int layer_id = 0; layer_id < (inner_chamber_layer_number+outer_chamber_layer_number); layer_id++) {
+ double rmin,rmax,offset;
+ std::string layer_name;
+ dd4hep::Volume* current_vol_ptr = nullptr;
+
+ if( layer_id < inner_chamber_layer_number ) {
+ current_vol_ptr = &det_inner_chamber_vol;
+ rmin = inner_chamber_radius_min+(layer_id*chamber_layer_width);
+ rmax = rmin+chamber_layer_width;
+ layer_name = det_name+"_inner_chamber_vol"+_toString(layer_id,"_layer%d");
+ }
+ else {
+ current_vol_ptr = &det_outer_chamber_vol;
+ rmin = outer_chamber_radius_min+((layer_id-inner_chamber_layer_number)*chamber_layer_width);
+ rmax = rmin+chamber_layer_width;
+ layer_name = det_name+"_outer_chamber_vol"+_toString(layer_id,"_layer%d");
+ }
+
+ //Construction of drift chamber layers
+ double rmid = delta_a_func(rmin,rmax);
+ double ilayer_cir = 2 * M_PI * rmid;
+ double ncell = ilayer_cir / chamber_layer_width;
+ int ncell_layer = ceil(ncell);
+ int numWire = ncell_layer;
+ double layer_Phi = 2*M_PI / ncell_layer;
+ if(layer_id %2 ==0){ offset = 0.; }
+ else { offset = 0.5 * layer_Phi; }
+
+ DCHseg->setGeomParams(layer_id, layer_Phi, rmid, epsilon, offset);
+ DCHseg->setWiresInLayer(layer_id, numWire);
+
+ dd4hep::Tube layer_solid(rmin,rmax,chamber_length*0.5);
+ dd4hep::Volume layer_vol(layer_name,layer_solid,det_mat);
+ dd4hep::Transform3D transform_layer(dd4hep::Rotation3D(),dd4hep::Position(0.,0.,0.));
+ dd4hep::PlacedVolume layer_phy = (*current_vol_ptr).placeVolume(layer_vol, transform_layer);
+ layer_phy.addPhysVolID("layer",layer_id);
+
+ //Set drift chamber layers to sensitive detector
+ layer_vol.setSensitiveDetector(sens);
+ sd.setType("tracker");
}
- /// Construction of drift chamber layers
- dd4hep::Tube layer_solid(rmin,rmax,chamber_length*0.5);
- dd4hep::Volume layer_vol(layer_name,layer_solid,det_mat);
- dd4hep::Transform3D transform_layer(dd4hep::Rotation3D(),dd4hep::Position(0.,0.,0.));
- dd4hep::PlacedVolume layer_phy = (*current_vol_ptr).placeVolume(layer_vol, transform_layer);
- layer_phy.addPhysVolID("layer",layer_id);
-
- /// Set drift chamber layers to sensitive detector
- dd4hep::SensitiveDetector sd = sens;
- layer_vol.setSensitiveDetector(sens);
- sd.setType("tracker");
- }
// - place in det
// inner
diff --git a/Detector/DetSegmentation/DetSegmentation/GridDriftChamber.h b/Detector/DetSegmentation/DetSegmentation/GridDriftChamber.h
index 379ad4a19fdbce33a63f009577970534f3f995c3..fc01bf114d8d1780690ecbc9db2c23a82cc8cbe5 100644
--- a/Detector/DetSegmentation/DetSegmentation/GridDriftChamber.h
+++ b/Detector/DetSegmentation/DetSegmentation/GridDriftChamber.h
@@ -6,6 +6,7 @@
#include "TVector3.h"
#include <cmath>
#include <iostream>
+#include <map>
/** GridDriftChamber Detector/DetSegmentation/DetSegmentation/GridDriftChamber.h GridDriftChamber.h
*
@@ -14,6 +15,21 @@
* @author nalipour
*/
+
+typedef struct Layer
+ {
+ double layerphi;
+ double R;
+ double eps;
+ double offset;
+ Layer(){};
+ Layer(double x, double y, double z, double k):layerphi(x),R(y),eps(z),offset(k){};
+ bool operator < (const Layer &a) const
+ {
+ return layerphi < a.layerphi;
+ }
+ } LAYER;
+
namespace dd4hep {
namespace DDSegmentation {
class GridDriftChamber : public Segmentation {
@@ -28,62 +44,102 @@ public:
virtual Vector3D position(const CellID& aCellID) const;
virtual CellID cellID(const Vector3D& aLocalPosition, const Vector3D& aGlobalPosition,
const VolumeID& aVolumeID) const;
+ virtual double distanceTrackWire(const CellID& cID, const TVector3& hit_start, const TVector3& hit_end) const;
-// inline double innerRadius() const { return m_innerRadius; }
-// inline double detectorLength() const { return m_detectorLength; }
- inline double offsetPhi() const { return m_offsetPhi; }
- inline double delta_phi() const{ return m_delta_phi; }
+ inline double cell_Size() const { return m_cellSize; }
+ inline double offset_phi() const { return m_offsetPhi; }
+ inline double epsilon0() const { return m_epsilon0; }
+ inline double detectorLength() const { return m_detectorLength; }
inline const std::string& fieldNamePhi() const { return m_phiID; }
// Setters
-// inline void setGeomParams(int layer, double sizePhi) {
-// layer_params[layer] = {sizePhi};
-// }
-
-// void updateParams(int layer) const {
-// auto it_end = layer_params.cend();
-// --it_end;
-// double size = it_end->second[0];
-// double radius = it_end->second[1];
-// double eps = it_end->second[2];
-//
-// auto map_it = layer_params.find(layer);
-// if (map_it != layer_params.cend()) {
-// size = map_it->second[0];
-// radius = map_it->second[1];
-// eps = map_it->second[2];
-// }
-//
-// _currentGridSizePhi = size;
-// _currentRadius = radius;
-// m_epsilon = eps;
-// }
-
inline double phiFromXY(const Vector3D& aposition) const {
return std::atan2(aposition.Y, aposition.X) + M_PI ;
}
-// inline int returnLayer(double x, double y) const {
-// // Hit R position
-// double R = std::sqrt(x * x + y * y);
-// // Layer
-// int layer = int((R - m_innerRadius) / m_cellSize);
-// return layer;
-// }
+ inline void setGeomParams(int layer, double layerphi, double R, double eps, double offset ) {
+ // layer_params[layer] = {layerphi,R,eps};
+ layer_params.insert(std::pair<int,LAYER>(layer,LAYER(layerphi,R,eps,offset)));
+ }
+
+ inline void setWiresInLayer(int layer, int numWires)
+ {
+ double phi0;
+ updateParams(layer);
+ for (int i = 0; i<numWires; ++i) {
+
+// if(layer % 2 == 0) { phi0 = 0.; }
+// else { phi0 = 0.5 * _currentLayerphi; }
+ double phi0 = m_offset;
+
+ auto phi_start = _currentLayerphi * i + phi0;
+ if(phi_start > 2 * M_PI) { phi_start = phi_start - 2 * M_PI; }
+ auto phi_end = phi_start + _currentLayerphi;
+
+ TVector3 Wstart = returnWirePosition(phi_start, 1);
+ TVector3 Wend = returnWirePosition(phi_end, -1);
+
+ TVector3 Wmid = (Wstart+Wend)*(1/2.0);
+ TVector3 Wdirection = (Wend - Wstart);
+
+ m_wiresPositions[layer].push_back(std::make_pair(Wmid, Wdirection));
+ }
+ }
+
+ inline auto returnAllWires() const { return m_wiresPositions; }
+
+ inline TVector3 returnWirePosition(double angle, int sign) const {
+ TVector3 w(0, 0, 0);
+ w.SetX(_currentRadius * std::cos(angle));
+ w.SetY(_currentRadius * std::sin(angle));
+ w.SetZ(sign * m_detectorLength / 2.0);
+ return w;
+ }
+
+ void updateParams(int layer) const{
+ auto it_end = layer_params.cend();
+ --it_end;
+ double layerphi = it_end->second.layerphi;
+ double radius = it_end->second.R;
+ double eps = it_end->second.eps;
+ double offset = it_end->second.offset;
+
+ auto map_it = layer_params.find(layer);
+ if (map_it != layer_params.cend()) {
+ layerphi = map_it->second.layerphi;
+ radius = map_it->second.R;
+ eps = map_it->second.eps;
+ offset = map_it->second.offset;
+ }
+ _currentLayerphi = layerphi;
+ _currentRadius = radius;
+ m_epsilon = eps;
+ m_offset = offset;
+ }
+
+ inline double returnAlpha() const {
+ double alpha = 2 * std::asin(m_detectorLength * std::tan(m_epsilon0)/(2 * _currentRadius));
+ return alpha;
+ }
protected:
/* *** nalipour *** */
double phi(const CellID& cID) const;
+ std::map<int,LAYER> layer_params; // <layer, {layerphi, R, eps, offset}>
+ std::map<int, std::vector<std::pair<TVector3, TVector3> >> m_wiresPositions; // < layer, vec<WireMidpoint, WireDirection> >
-
+ double m_cellSize;
double m_offsetPhi;
- double m_delta_phi;
+ double m_epsilon0;
+ double m_detectorLength;
std::string m_phiID;
// Current parameters of the layer: sizePhi
-// mutable double _currentGridSizePhi; // current size Phi
-// mutable double _currentRadius; // current size radius
-// mutable double m_epsilon;
+ mutable double _currentLayerphi;
+ mutable double _currentRadius;
+ mutable double m_epsilon;
+ mutable double m_offset;
+
};
}
}
diff --git a/Detector/DetSegmentation/src/GridDriftChamber.cpp b/Detector/DetSegmentation/src/GridDriftChamber.cpp
index 4b1ed216fb0825e1b41a210871ca2451954ee22e..57a6d7ebacd9fb221dbb7e59dfedd2a14a52894b 100644
--- a/Detector/DetSegmentation/src/GridDriftChamber.cpp
+++ b/Detector/DetSegmentation/src/GridDriftChamber.cpp
@@ -1,4 +1,5 @@
#include "DetSegmentation/GridDriftChamber.h"
+#include <map>
namespace dd4hep {
namespace DDSegmentation {
@@ -9,17 +10,22 @@ GridDriftChamber::GridDriftChamber(const std::string& cellEncoding) : Segmentati
_type = "GridDriftChamber";
_description = "Drift chamber segmentation in the global coordinates";
- registerIdentifier("identifier_phi", "Cell ID identifier for phi", m_phiID, "phi");
- registerParameter("delta_phi", "delta phi", m_delta_phi, 0., SegmentationParameter::LengthUnit);
+ registerParameter("cell_size", "cell size", m_cellSize, 0., SegmentationParameter::LengthUnit);
+ registerParameter("offset_phi", "offset in phi", m_offsetPhi, 0., SegmentationParameter::LengthUnit, true);
+ registerParameter("detector_length", "Length of the wire", m_detectorLength, 1., SegmentationParameter::LengthUnit);
+ registerIdentifier("identifier_phi", "Cell ID identifier for phi", m_phiID, "cellID");
}
GridDriftChamber::GridDriftChamber(const BitFieldCoder* decoder) : Segmentation(decoder) {
- // define type and description
+
_type = "GridDriftChamber";
_description = "Drift chamber segmentation in the global coordinates";
- registerIdentifier("identifier_phi", "Cell ID identifier for phi", m_phiID, "phi");
- registerParameter("delta_phi", "delta phi", m_delta_phi, 0., SegmentationParameter::LengthUnit);
+ registerParameter("cell_size", "cell size", m_cellSize, 1., SegmentationParameter::LengthUnit);
+ registerParameter("offset_phi", "offset in phi", m_offsetPhi, 0., SegmentationParameter::LengthUnit, true);
+ registerParameter("epsilon0", "epsilon", m_epsilon0, 0., SegmentationParameter::AngleUnit, true);
+ registerParameter("detector_length", "Length of the wire", m_detectorLength, 1., SegmentationParameter::LengthUnit);
+ registerIdentifier("identifier_phi", "Cell ID identifier for phi", m_phiID, "cellID");
}
Vector3D GridDriftChamber::position(const CellID& /*cID*/) const {
@@ -27,28 +33,78 @@ Vector3D GridDriftChamber::position(const CellID& /*cID*/) const {
return cellPosition;
}
+
CellID GridDriftChamber::cellID(const Vector3D& /*localPosition*/, const Vector3D& globalPosition,
const VolumeID& vID) const {
CellID cID = vID;
+ unsigned int layerID = _decoder->get(vID, "layer");
+ updateParams(layerID);
double phi_hit = phiFromXY(globalPosition);
double posx = globalPosition.X;
double posy = globalPosition.Y;
-
- int lphi = (int) (phi_hit/m_delta_phi);
+ double offsetphi= m_offset;
+ int _lphi;
+// if(layerID % 2 == 0) {
+// offsetphi = 0.;
+// _lphi = (int) (phi_hit / _currentLayerphi);
+// }
+// else {
+// offsetphi = _currentLayerphi / 2.;
+ if(phi_hit >= offsetphi) {
+ _lphi = (int) ((phi_hit - offsetphi)/ _currentLayerphi);
+ }
+ else {
+ _lphi = (int) ((phi_hit - offsetphi + 2 * M_PI)/ _currentLayerphi);
+ }
+ int lphi = _lphi;
_decoder->set(cID, m_phiID, lphi);
-// std::cout << " myliu: "
-// << " x: " << posx
-// << " y: " << posy
-//// << " pre: " << phi_pre
-// << " phi_hit: " << phi_hit
-// << " lphi: " << lphi
-// << std::endl;
+//std::cout << "#######################################: "
+// << " offset : " << m_offset
+// << " offsetphi: " << offsetphi
+// << " layerID: " << layerID
+// << " r: " << _currentRadius
+// << " layerphi: " << _currentLayerphi
+// << std::endl;
+
return cID;
}
+double GridDriftChamber::phi(const CellID& cID) const {
+ CellID phiValue = _decoder->get(cID, m_phiID);
+ return binToPosition(phiValue, _currentLayerphi, m_offsetPhi);
+}
+
+double GridDriftChamber::distanceTrackWire(const CellID& cID, const TVector3& hit_start,
+ const TVector3& hit_end) const {
+
+ auto layerIndex = _decoder->get(cID, "layer");
+ updateParams(layerIndex);
+
+ double phi_start = phi(cID);
+ double phi_end = phi_start + returnAlpha();
+
+ TVector3 Wstart = returnWirePosition(phi_start, 1);
+ TVector3 Wend = returnWirePosition(phi_end, -1);
+
+ TVector3 a = hit_end - hit_start;
+ TVector3 b = Wend - Wstart;
+ TVector3 c = Wstart - hit_start;
+
+ double num = std::abs(c.Dot(a.Cross(b)));
+ double denum = (a.Cross(b)).Mag();
+
+ double DCA = 0;
+
+ if (denum) {
+ DCA = num / denum;
+ }
+
+ return DCA;
+}
+
REGISTER_SEGMENTATION(GridDriftChamber)
}