Skip to content

Commit e7adc91

Browse files
author
Nathan Baltzell
committed
try ECAL cluster sharing
1 parent 6b302e7 commit e7adc91

7 files changed

Lines changed: 111 additions & 50 deletions

File tree

common-tools/clas-detector/src/main/java/org/jlab/detector/base/DetectorDescriptor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ public DetectorDescriptor(){
3131
public DetectorDescriptor(DetectorType type){
3232
this.detectorType = type;
3333
}
34-
34+
35+
public DetectorDescriptor(DetectorType type, int layer){
36+
this.detectorType = type;
37+
this.dt_LAYER = layer;
38+
}
39+
3540
public DetectorDescriptor(String name){
3641
this.detectorType = DetectorType.getType(name);
3742
}

common-tools/clas-reco/src/main/java/org/jlab/clas/detector/CalorimeterResponse.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public CalorimeterResponse(int sector, int layer, int component){
3838
this.getDescriptor().setSectorLayerComponent(sector, layer, component);
3939
}
4040

41-
public void copy(CalorimeterResponse r) {
41+
public final void copy(CalorimeterResponse r) {
4242
super.copy(r);
4343
widthUVW.copy(r.widthUVW);
4444
coordUVW.copy(r.coordUVW);
@@ -53,6 +53,18 @@ public void copy(CalorimeterResponse r) {
5353
dbStatus[2] = r.dbStatus[2];
5454
}
5555

56+
/**
57+
* Share energy between this and another response.
58+
* @param other The other response to share with
59+
* @param ratio The fraction that goes to the other response
60+
*/
61+
public void shareEnergy(DetectorResponse other, double ratio) {
62+
double energyOther = other.getEnergy() * ratio;
63+
double energyThis = this.getEnergy() * (1-ratio);
64+
other.setEnergy(energyOther);
65+
this.setEnergy(energyThis);
66+
}
67+
5668
public void setWidthUVW(float u,float v,float w) {
5769
widthUVW.setXYZ(u,v,w);
5870
}

common-tools/clas-reco/src/main/java/org/jlab/clas/detector/DetectorEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import java.util.List;
66
import org.jlab.clas.physics.Particle;
77
import org.jlab.clas.physics.PhysicsEvent;
8-
import org.jlab.detector.base.DetectorType;
98
import org.jlab.io.base.DataEvent;
9+
import org.jlab.detector.base.DetectorType;
1010

1111

1212
/**

common-tools/clas-reco/src/main/java/org/jlab/clas/detector/DetectorParticle.java

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.jlab.clas.pdg.PDGDatabase;
1818
import org.jlab.clas.pdg.PhysicsConstants;
19+
import org.jlab.detector.base.DetectorLayer;
1920

2021
/**
2122
*
@@ -41,8 +42,13 @@ public class DetectorParticle implements Comparable {
4142
private DetectorParticleStatus particleStatus = new DetectorParticleStatus();
4243

4344
// let multiple particles share the same hit for these detectors:
44-
private final DetectorType[] sharedDetectors = {DetectorType.FTOF,DetectorType.CTOF};
45-
45+
private final List<DetectorType> sharedDetectors = List.of(DetectorType.FTOF,DetectorType.CTOF);
46+
47+
// special sharing treatment for calorimeters:
48+
private final List<DetectorDescriptor> sharedDescriptors = List.of(
49+
new DetectorDescriptor(DetectorType.ECAL, DetectorLayer.EC_INNER),
50+
new DetectorDescriptor(DetectorType.ECAL, DetectorLayer.EC_OUTER));
51+
4652
protected final List<DetectorResponse> responseStore = new ArrayList<>();
4753

4854
protected DetectorTrack detectorTrack = null;
@@ -97,6 +103,7 @@ public static DetectorParticle createNeutral(DetectorResponse resp){
97103
resp.getPosition().z());
98104
resp.setPath(resp.getPosition().mag());
99105
particle.addResponse(resp);
106+
particle.getTrack().setSector(resp.getSector());
100107
return particle;
101108
}
102109

@@ -114,6 +121,7 @@ public static DetectorParticle createNeutral(DetectorResponse resp,Vector3 verte
114121
final double dz = resp.getPosition().z()-vertex.z();
115122
resp.setPath(Math.sqrt(dx*dx+dy*dy+dz*dz));
116123
particle.addResponse(resp);
124+
particle.getTrack().setSector(resp.getSector());
117125
return particle;
118126
}
119127

@@ -414,22 +422,13 @@ public void setStatus(double minNpheHtcc,double minNpheLtcc) {
414422
public void setCharge(int charge) { this.detectorTrack.setCharge(charge);}
415423

416424
public int getDetectorHit(List<DetectorResponse> hitList, DetectorType type,
417-
int detectorLayer,
418-
double distanceThreshold){
425+
int layer, double distanceThreshold){
419426

420427
Line3D trajectory = this.detectorTrack.getLastCross();
421428
Point3D hitPoint = new Point3D();
422429
double minimumDistance = 500.0;
423430
int bestIndex = -1;
424431

425-
boolean hitSharing=false;
426-
for (int ii=0; ii<sharedDetectors.length && this.getCharge()!=0; ii++) {
427-
if (type == sharedDetectors[ii]) {
428-
hitSharing=true;
429-
break;
430-
}
431-
}
432-
433432
for(int loop = 0; loop < hitList.size(); loop++){
434433

435434
DetectorResponse response = hitList.get(loop);
@@ -440,23 +439,27 @@ public int getDetectorHit(List<DetectorResponse> hitList, DetectorType type,
440439
continue;
441440
}
442441
}
443-
444-
if(response.getDescriptor().getType()==type &&
445-
(detectorLayer<=0 || response.getDescriptor().getLayer()==detectorLayer) &&
446-
(hitSharing || response.getAssociation()<0)) {
447-
448-
hitPoint.set(
449-
response.getPosition().x(),
450-
response.getPosition().y(),
451-
response.getPosition().z()
452-
);
453-
454-
double hitdistance = trajectory.distance(hitPoint).length();
455-
456-
if (hitdistance<distanceThreshold && hitdistance<minimumDistance) {
457-
minimumDistance = hitdistance;
458-
bestIndex = loop;
459-
}
442+
443+
// limit to matching detector type/layer:
444+
if (response.getDescriptor().getType() != type) continue;
445+
if (layer>0 && response.getDescriptor().getLayer() != layer) continue;
446+
447+
// limit sharing to some detectors:
448+
if (response.getAssociation()>=0 &&
449+
!sharedDetectors.contains(type) &&
450+
!sharedDescriptors.contains(new DetectorDescriptor(type,layer))) continue;
451+
452+
hitPoint.set(
453+
response.getPosition().x(),
454+
response.getPosition().y(),
455+
response.getPosition().z()
456+
);
457+
458+
double hitdistance = trajectory.distance(hitPoint).length();
459+
460+
if (hitdistance<distanceThreshold && hitdistance<minimumDistance) {
461+
minimumDistance = hitdistance;
462+
bestIndex = loop;
460463
}
461464
}
462465
return bestIndex;

reconstruction/eb/src/main/java/org/jlab/rec/eb/EBUtil.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import static java.lang.Math.abs;
44
import static java.lang.Math.pow;
5+
import java.util.List;
6+
import org.jlab.clas.detector.CalorimeterResponse;
7+
import org.jlab.clas.detector.DetectorEvent;
58
import org.jlab.clas.detector.DetectorResponse;
69
import org.jlab.clas.detector.DetectorParticle;
710
import org.jlab.clas.detector.ScintillatorResponse;
@@ -10,6 +13,34 @@
1013

1114
public class EBUtil {
1215

16+
/**
17+
* Redistribute energy between shared, neutral calorimeter clusters.
18+
* @param e the event
19+
*/
20+
public void shareCalorimeterEnergies(DetectorEvent e) {
21+
List<DetectorParticle> l = e.getParticles();
22+
for (int i1=0; i1<l.size(); i1++) {
23+
for (int i2=i1+1; i2<l.size(); i2++) {
24+
// ignore charged particles:
25+
if(l.get(i1).getCharge() != 0) continue;
26+
if(l.get(i2).getCharge() != 0) continue;
27+
// PCAL controls the sharing ratio, so both must have PCAL:
28+
DetectorResponse p1 = l.get(i1).getHit(DetectorType.ECAL, DetectorLayer.PCAL);
29+
DetectorResponse p2 = l.get(i2).getHit(DetectorType.ECAL, DetectorLayer.PCAL);
30+
if (p1 == null || p2 == null) continue;
31+
// If they share a ECAL cluster, redistribute their energies:
32+
for (int layer : List.of(DetectorLayer.EC_INNER,DetectorLayer.EC_OUTER)) {
33+
DetectorResponse e1 = l.get(i1).getHit(DetectorType.ECAL, layer);
34+
DetectorResponse e2 = l.get(i2).getHit(DetectorType.ECAL, layer);
35+
if (e1.getHitIndex() == e2.getHitIndex()) {
36+
((CalorimeterResponse)e1).shareEnergy(e2,
37+
p2.getEnergy() / (p1.getEnergy()+p2.getEnergy()));
38+
}
39+
}
40+
}
41+
}
42+
}
43+
1344
/**
1445
* Central neutral veto logic from Adam Hobart.
1546
*

reconstruction/eb/src/main/java/org/jlab/service/eb/EBMatching.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.jlab.clas.detector.DetectorEvent;
1010
import org.jlab.rec.eb.EBCCDBEnum;
1111
import org.jlab.clas.detector.DetectorResponseComparators;
12+
import org.jlab.clas.detector.DetectorResponseFactory;
1213
import org.jlab.clas.detector.matching.MatchCND;
1314

1415
/*
@@ -101,14 +102,19 @@ public void addResponsesECAL(List <DetectorParticle> parts, int[] layers) {
101102
throw new RuntimeException("Invalid ECAL Layer: "+layer);
102103
}
103104

104-
List<DetectorResponse> respECAL = eventBuilder.getUnmatchedResponses(null, DetectorType.ECAL, layer);
105-
106-
int index = part.getDetectorHit(respECAL, DetectorType.ECAL, layer, matching);
105+
List<DetectorResponse> responses = eventBuilder.getSectorResponses(null, part.getTrack().getSector(), DetectorType.ECAL, layer);
106+
int index = part.getDetectorHit(responses, DetectorType.ECAL, layer, matching);
107107
if (index>=0) {
108+
if (responses.get(index).getAssociation() >= 0) {
109+
DetectorResponse copy = DetectorResponseFactory.create(responses.get(index));
110+
copy.clearAssociations();
111+
responses.add(copy);
112+
index = responses.size()-1;
113+
}
108114
int pindex_offset = this.eventBuilder.getPindexMap().get(0)
109115
+ this.eventBuilder.getPindexMap().get(1); //After FD/CD Charged Particles
110-
part.addResponse(respECAL.get(index), true);
111-
respECAL.get(index).setAssociation(ii + pindex_offset);
116+
part.addResponse(responses.get(index), true);
117+
responses.get(index).addAssociation(ii + pindex_offset);
112118
}
113119
}
114120
}
@@ -130,10 +136,10 @@ public List<DetectorParticle> findNeutrals(int ecalLayer) {
130136
otherEcalLayers=new int[]{4,7};
131137
break;
132138
case (4):
133-
otherEcalLayers=new int[]{1,7};
139+
otherEcalLayers=new int[]{7};
134140
break;
135141
case (7):
136-
otherEcalLayers=new int[]{1,4};
142+
otherEcalLayers=new int[]{};
137143
break;
138144
default:
139145
throw new RuntimeException("Invalid ECAL Layer: "+ecalLayer);
@@ -145,7 +151,7 @@ public List<DetectorParticle> findNeutrals(int ecalLayer) {
145151
eventBuilder.getUnmatchedResponses(null, DetectorType.ECAL, ecalLayer);
146152

147153
Vector3 vertex = new Vector3(0,0,0);
148-
if (eventBuilder.getEvent().getParticles().size()>0) {
154+
if (!eventBuilder.getEvent().getParticles().isEmpty()) {
149155
vertex.copy(eventBuilder.getEvent().getParticle(0).vertex());
150156
}
151157

reconstruction/eb/src/main/java/org/jlab/service/eb/EventBuilder.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,6 @@ public boolean findMatchingHit(
199199
if (index>=0) {
200200
// if sharing hits between tracks, duplicate it:
201201
if (responses.get(index).getAssociation() >= 0) {
202-
//System.out.println(responses.get(index).getClass());
203-
//DetectorResponse copy = new DetectorResponse();
204-
//copy.copy(responses.get(index));
205202
DetectorResponse copy = DetectorResponseFactory.create(responses.get(index));
206203
copy.clearAssociations();
207204
responses.add(copy);
@@ -213,17 +210,14 @@ public boolean findMatchingHit(
213210
}
214211
return false;
215212
}
216-
213+
217214
public boolean findMatchingHit(
218215
final int pindex, DetectorParticle particle, List<DetectorResponse> responses,
219216
DetectorType type, final int layer, IMatch matcher) {
220217
int index = matcher.bestMatch(particle, responses, type, layer);
221218
if (index>=0) {
222219
// if sharing hits between tracks, duplicate it:
223220
if (responses.get(index).getAssociation() >= 0) {
224-
//System.out.println(responses.get(index).getClass());
225-
//DetectorResponse copy = new DetectorResponse();
226-
//copy.copy(responses.get(index));
227221
DetectorResponse copy = DetectorResponseFactory.create(responses.get(index));
228222
copy.clearAssociations();
229223
responses.add(copy);
@@ -236,7 +230,6 @@ public boolean findMatchingHit(
236230
return false;
237231
}
238232

239-
240233
public void forwardTaggerIDMatching() {
241234
int np = this.detectorEvent.getParticles().size();
242235
if(this.ftIndices.size()>0 && this.detectorEvent.getParticles().size()>0) {
@@ -394,9 +387,20 @@ public List<DetectorResponse> getUnmatchedResponses(List<DetectorResponse> list,
394387
}
395388
return responses;
396389
}
397-
398390

399-
391+
public List<DetectorResponse> getSectorResponses(List<DetectorResponse> list, int sector, DetectorType type, int layer){
392+
if (list==null) list=detectorResponses;
393+
List<DetectorResponse> responses = new ArrayList<>();
394+
for(DetectorResponse r : list){
395+
if(r.getDescriptor().getType()==type &&
396+
(r.getDescriptor().getLayer()==layer || layer<=0) &&
397+
r.getSector() == sector) {
398+
responses.add(r);
399+
}
400+
}
401+
return responses;
402+
}
403+
400404
public void assignTrigger() {
401405
int i = 0;
402406
boolean hasTrigger=false;

0 commit comments

Comments
 (0)