1
2
3
4
5
6 package org.lcsim.recon.tracking.seedtracker.strategybuilder;
7
8 import java.io.File;
9 import java.util.ArrayList;
10 import java.util.Collections;
11 import java.util.Comparator;
12 import java.util.Date;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.LinkedList;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Random;
20 import java.util.Set;
21 import org.lcsim.recon.tracking.seedtracker.SeedLayer;
22 import org.lcsim.recon.tracking.seedtracker.SeedLayer.SeedType;
23 import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
24 import org.lcsim.recon.tracking.seedtracker.StrategyXMLMetadata;
25 import org.lcsim.recon.tracking.seedtracker.StrategyXMLUtils;
26 import org.lcsim.detector.DetectorElementStore;
27 import org.lcsim.detector.IDetectorElement;
28 import org.lcsim.detector.IDetectorElementContainer;
29 import org.lcsim.event.EventHeader;
30 import org.lcsim.event.MCParticle;
31 import org.lcsim.event.SimTrackerHit;
32 import org.lcsim.fit.helicaltrack.HitIdentifier;
33 import org.lcsim.geometry.Detector;
34 import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
35
36
37
38
39
40
41
42
43
44 public class StrategyBuilder extends AbstractStrategyBuilder implements IStrategyBuilder {
45
46 public static final String defaultOutputFile = System.getProperties().getProperty("java.io.tmpdir")+
47 System.getProperties().getProperty("file.separator")+
48 "BuiltStrategies.xml";
49
50 public static final int RandomSeed = 1234;
51
52
53 public static final boolean defaultVerbose = false;
54 public static final int defaultMinLayers = 7;
55 public static final int defaultConfirmLayers =1;
56 public static final int defaultSeedLayers =3;
57 public static final int defaultMinUnweightedScore = 1;
58 public static final boolean defaultSymmetrize = true;
59
60 private boolean verbose = defaultVerbose;
61 private boolean symmetrize = defaultSymmetrize;
62 private int min_layers = defaultMinLayers;
63 private int confirm_layers = defaultConfirmLayers;
64 private int seed_layers = defaultSeedLayers;
65 private String outputFile = defaultOutputFile;
66 private int minUnweightedScore = defaultMinUnweightedScore;
67 private boolean oldConfirm = false;
68 private List<SeedStrategy> startingStrategies = new ArrayList<SeedStrategy>();
69 private Set<Set<DumbLayer>> startingSet = new HashSet<Set<DumbLayer>>();
70 private SeedStrategy prototype = new SeedStrategy("null", new ArrayList<SeedLayer>());
71 private LayerWeight weighter = null;
72 private HitIdentifier ID = new HitIdentifier();
73
74 private List<Set<DumbLayer>> setlist = new ArrayList<Set<DumbLayer>>();
75 private String detectorName;
76 private IParticleFilter filter;
77 private List<List<DumbLayer>> adjacentlist = new ArrayList<List<DumbLayer>>();
78
79 private Random random = new Random(RandomSeed);
80 private Map<Set<DumbLayer>,SubsetScore> scoremap;
81
82 @Override
83 protected void startOfData(){
84
85 if (filter==null) {
86 filter = new StrategyBasedFilter(prototype);
87 }
88 }
89
90
91
92
93 @Override
94 protected void process(EventHeader event){
95
96 super.process(event);
97
98 if (verbose) {
99 if (event.getEventNumber() % 100 == 0)
100 System.out.println("Processed "+event.getEventNumber()+" events.");
101 }
102
103 filter.setEvent(event);
104
105
106 Map<MCParticle, List<SimTrackerHit>> mcmap = buildMCMap(event);
107
108
109 Iterator<MCParticle> mciter = mcmap.keySet().iterator();
110 while (mciter.hasNext()){
111 MCParticle next = mciter.next();
112 if (!filter.passes(next)){
113 mciter.remove();
114 }
115 }
116
117
118 for(List<SimTrackerHit> l : mcmap.values()) {
119 Set<DumbLayer> set = new HashSet<DumbLayer>();
120
121
122 Collections.sort(l, new Comparator() {
123
124 public int compare(Object o1, Object o2) {
125 SimTrackerHit h1 = (SimTrackerHit) o1;
126 SimTrackerHit h2 = (SimTrackerHit) o2;
127 return Double.compare(h1.getTime(), h2.getTime());
128 }
129 });
130
131
132 LinkedList<List<DumbLayer>> tempAdjacentLayersList = new LinkedList<List<DumbLayer>>();
133 LinkedList<List<DumbLayer>> pendingAdjacentLayersList = new LinkedList<List<DumbLayer>>();
134 for (SimTrackerHit h : l) {
135 IDetectorElementContainer cont = DetectorElementStore.getInstance().find(h.getIdentifier());
136 if(cont.isEmpty()) continue;
137 IDetectorElement de = cont.get(0);
138 String detname = ID.getName(de);
139 int lyr = ID.getLayer(de);
140 BarrelEndcapFlag be = ID.getBarrelEndcapFlag(de);
141
142
143 if (weighter.isDivideByTwoInTrackerForward() && be.isEndcap() &&
144 (detname.indexOf("TrackerForward") > -1 || detname.indexOf("TkrForward") > -1) ) {
145 lyr/=2;
146 } else if (weighter.isDivideByTwoInTrackerEndcap() && be.isEndcap() &&
147 (detname.indexOf("TrackerEndcap") > -1 || detname.indexOf("TkrEndcap") > -1) ) {
148 lyr/=2;
149 }
150
151
152 if (symmetrize && be.isEndcap()) be = BarrelEndcapFlag.ENDCAP;
153 DumbLayer dl = new DumbLayer(detname, lyr, be);
154 set.add(dl);
155
156
157
158 if (tempAdjacentLayersList.isEmpty() || !tempAdjacentLayersList.getLast().contains(dl)) {
159 List<DumbLayer> adjacentLayers = new ArrayList<DumbLayer>();
160 tempAdjacentLayersList.addLast(adjacentLayers);
161 }
162
163
164 Iterator<List<DumbLayer>> it = tempAdjacentLayersList.iterator();
165 while (it.hasNext()) {
166 List<DumbLayer> s = it.next();
167 if(!s.contains(dl)) s.add(dl);
168 if (s.size() == confirm_layers + seed_layers) {
169 pendingAdjacentLayersList.add(s);
170 it.remove();
171 }
172 }
173 }
174
175
176 if (set.size() >= min_layers) {
177 setlist.add(set);
178 adjacentlist.addAll(pendingAdjacentLayersList);
179 }
180 }
181 }
182
183 @Override
184 protected void suspend(){
185
186 if (verbose) System.out.println("Finished processing. Beginning analysis.");
187 Set<DumbLayer> allLayers = new HashSet<DumbLayer>();
188
189
190 for (Set<DumbLayer> set : setlist)
191 allLayers.addAll(set);
192 if (verbose) System.out.println(allLayers.size()+" total layers.");
193
194
195 for (SeedStrategy strategy : startingStrategies){
196 Set<DumbLayer> subset = StrategyBuilderUtils.getRelevantSet(strategy, true);
197 startingSet.add(subset);
198 }
199 if (verbose) System.out.println(startingStrategies.size()+" starting strategies defined.");
200
201
202 SubsetScorer scorer = new SubsetScorer(setlist,adjacentlist);
203 scorer.setLayerWeight(weighter);
204 scoremap = new HashMap<Set<DumbLayer>,SubsetScore>();
205
206
207 for (Set<DumbLayer> starter : startingSet) {
208 scoremap.put(starter, scorer.getScoreObject(starter));
209 scorer.markUsed(starter);
210 }
211
212
213 List<Set<DumbLayer>> all_subsets = StrategyBuilderUtils.generateAllPossibleDumbLayerSubsetsList(allLayers, confirm_layers+seed_layers);
214 if (verbose) System.out.println(all_subsets.size() + " possible subsets of size "+(confirm_layers+seed_layers));
215
216
217 Set<Set<DumbLayer>> setset = new HashSet<Set<DumbLayer>>(setlist.size());
218 setset.addAll(setlist);
219
220
221 Set<Set<DumbLayer>> usedSets = new HashSet<Set<DumbLayer>>(setset.size());
222
223
224 Set<Set<DumbLayer>> final_sets = new HashSet<Set<DumbLayer>>();
225 if (verbose) System.out.println("Layer set has "+setset.size()+" entries.");
226
227 Map<Set<DumbLayer>, Set<DumbLayer>> extendmap = new HashMap<Set<DumbLayer>,Set<DumbLayer>>();
228
229
230 SubsetScore score = new SubsetScore(0,0,0);
231
232
233 while (true){
234 if (verbose) System.out.println(setset.size() - usedSets.size() + " entries left to be covered.");
235 if (usedSets.size() == setset.size()) break;
236
237 Set<DumbLayer> max = all_subsets.get(0);
238 SubsetScore maxScore = new SubsetScore(0,0,0);
239
240
241 for (Set<DumbLayer> trial : all_subsets){
242 score = scorer.getScoreObject(trial);
243 if (score.score() > maxScore.score()) {
244 maxScore = score;
245 max = trial;
246 }
247 }
248
249
250 if (maxScore.numTracks() <= minUnweightedScore) break;
251
252 scorer.markUsed(max);
253 final_sets.add(max);
254 extendmap.put(max, new HashSet<DumbLayer>());
255 scoremap.put(max,maxScore);
256 for (Set<DumbLayer> this_set : setset) {
257 if (this_set.containsAll(max)) {
258
259
260 Set<DumbLayer> nw = new HashSet<DumbLayer>();
261 for (DumbLayer dumb : this_set){
262 if(!max.contains(dumb)) nw.add(dumb);
263 }
264 Set<DumbLayer> old = extendmap.get(max);
265 old.addAll(nw);
266 extendmap.put(max, old);
267
268
269 usedSets.add(this_set);
270 }
271 }
272
273
274 }
275 if(verbose) System.out.println("Done finding strategies");
276 if(verbose) System.out.println(final_sets.toString());
277
278
279 int counter = 0;
280
281 StrategyXMLMetadata meta = new StrategyXMLMetadata();
282
283 List<SeedStrategy> strat_list = new ArrayList<SeedStrategy>();
284 strat_list.addAll(startingStrategies);
285
286
287 for (SeedStrategy starter : startingStrategies) {
288 int unw_score = scoremap.get(StrategyBuilderUtils.getRelevantSet(starter,true)).numTracks();
289 meta.strategyComments.put(starter, "Num findable tracks (total, not additional): "+unw_score);
290 }
291
292
293 for (Set<DumbLayer> s : final_sets) {
294
295 List<DumbLayer> dlyrlst = new ArrayList<DumbLayer>();
296 dlyrlst.addAll(s);
297
298
299
300
301
302
303
304
305 List<DumbLayer> adjacenceInfo = null;
306 for (List<DumbLayer> l : adjacentlist) {
307 if (s.containsAll(l) && l.containsAll(s)) {
308 adjacenceInfo = l;
309 break;
310 }
311 }
312
313
314 if (adjacenceInfo == null) {
315 for (Set<DumbLayer> ss : StrategyBuilderUtils.generateAllPossibleDumbLayerSubsetsList(s, seed_layers)){
316 for (List<DumbLayer> l : adjacentlist) {
317 if (ss.containsAll(l) && l.containsAll(ss)) {
318 adjacenceInfo = l;
319 break;
320 }
321 }
322 }
323 }
324
325
326
327
328
329
330
331
332
333 if (adjacenceInfo == null || oldConfirm) {
334
335 Collections.sort(dlyrlst, weighter.getComparator());
336 }
337
338
339 else if (adjacenceInfo.size() == dlyrlst.size()) {
340 dlyrlst = adjacenceInfo;
341 if (weighter.getWeight(dlyrlst.get(0)) > weighter.getWeight(dlyrlst.get(dlyrlst.size()-1)))
342 Collections.reverse(dlyrlst);
343
344
345 } else {
346 dlyrlst.removeAll(adjacenceInfo);
347 dlyrlst.addAll(adjacenceInfo);
348 }
349
350 int confirmed = 0;
351
352 List<SeedLayer> lyrlst = new ArrayList<SeedLayer>();
353
354
355
356 List<SeedLayer> extendlyr = new ArrayList<SeedLayer>();
357 List<DumbLayer> dumbextendlyr = new ArrayList<DumbLayer>();
358 dumbextendlyr.addAll(extendmap.get(s));
359 Collections.sort(dumbextendlyr, weighter.getComparator());
360
361 for (DumbLayer lyr : dumbextendlyr) {
362 extendlyr.add(new SeedLayer(lyr.detectorName, lyr.layer, lyr.be, SeedType.Extend));
363 }
364
365 lyrlst.addAll(extendlyr);
366
367 for (DumbLayer lyr : dlyrlst){
368 SeedType type;
369
370 if (confirmed < confirm_layers) {
371 type = SeedType.Confirm;
372 confirmed++;
373 }
374 else type = SeedType.Seed;
375 lyrlst.add(new SeedLayer(lyr.detectorName, lyr.layer, lyr.be, type));
376 }
377 Collections.reverse(lyrlst);
378
379 String name = "AUTOGEN" + counter++ +"_"+lyrlst.hashCode();
380
381
382 SeedStrategy stgy = new SeedStrategy(name,lyrlst);
383 stgy.copyCutoffsFromStrategy(prototype);
384 strat_list.add(stgy);
385
386
387 score = scoremap.get(s);
388 String comment = "AUTOGEN STATISTICS: \n\t\t\tScore: "+score.score() + "\n";
389 comment += "\t\t\tUnweighted Score (num new tracks): "+score.numTracks() + "\n";
390 comment += "\t\t\tAdjacency: "+score.adjacency() +"\n\t\t";
391 meta.strategyComments.put(stgy, comment);
392 }
393
394
395 String comment = "Strategy list Autogenerated by Strategy Builder on "+new Date()+".";
396 meta.targetDetector = detectorName;
397 meta.comment = comment;
398
399
400 if (symmetrize) {
401 if (verbose) System.out.println("Symmetrizing...");
402 StrategyBuilderUtils.symmetrizeStrategies(strat_list, meta);
403 }
404
405
406 if (verbose) System.out.println("Sorting output");
407 Collections.sort(strat_list, new Comparator() {
408
409 public int compare(Object o1, Object o2) {
410 SeedStrategy one = (SeedStrategy) o1;
411 SeedStrategy two = (SeedStrategy) o2;
412 return Double.compare(scoremap.get(StrategyBuilderUtils.getRelevantSet(two,true)).numTracks(),
413 scoremap.get(StrategyBuilderUtils.getRelevantSet(one,true)).numTracks());
414 }
415 });
416
417 StrategyXMLUtils.writeStrategyListToFile(strat_list, new File(outputFile), meta);
418 if (verbose) System.out.println(strat_list.size()+" strategies generated.");
419 if (verbose) System.out.println("Strategies XML file written at "+outputFile);
420 }
421
422 @Override
423 protected void detectorChanged(Detector detector){
424 detectorName = detector.getDetectorName();
425
426
427 if (weighter==null) {
428 setLayerWeight(new DefaultLayerWeight(detectorName).getWeight());
429 }
430
431
432 if(!weighter.getTargetDetector().equals("None Specified") && !weighter.getTargetDetector().equals(detectorName)) {
433 throw new DetectorMismatchException(detectorName, weighter.getTargetDetector());
434 }
435 }
436
437
438
439 public void setOutput(String filename){
440 outputFile = filename;
441 }
442
443 public void setLayerWeight(LayerWeight lw){
444 weighter = lw;
445 }
446
447 public void setMinLayers(int min){
448 min_layers = min;
449 }
450
451 public void setNumConfirmLayers(int clayers){
452 confirm_layers = clayers;
453 }
454
455 public void setNumSeedLayers(int slayers){
456 seed_layers = slayers;
457 }
458
459 public void setStrategyPrototype(SeedStrategy proto){
460 prototype = proto;
461 }
462
463 public void setStartingStrategyList(List<SeedStrategy> slist){
464 startingStrategies = slist;
465 }
466
467 public void setVerbose(boolean v){
468 verbose = true;
469 }
470
471 public void setMinimumUnweightedScore(int sc){
472 minUnweightedScore = sc;
473 }
474
475 public void setParticleFilter(IParticleFilter pfilter){
476 filter = pfilter;
477 }
478
479 public void setSymmetrize(boolean set){
480 symmetrize = set;
481 }
482
483
484 private Map<MCParticle, List<SimTrackerHit>> buildMCMap(final EventHeader event) {
485
486
487 Map<MCParticle, List<SimTrackerHit>> mcmap = new HashMap<MCParticle, List<SimTrackerHit>>();
488 List<SimTrackerHit> allhits = new ArrayList<SimTrackerHit>();
489
490
491
492
493 List<List<SimTrackerHit>> simhits = event.get(SimTrackerHit.class);
494
495
496
497 Collections.sort(simhits, new Comparator() {
498
499 public int compare(Object o1, Object o2) {
500 List<SimTrackerHit> l1 = (List<SimTrackerHit>)o1;
501 List<SimTrackerHit> l2 = (List<SimTrackerHit>)o2;
502
503 return String.CASE_INSENSITIVE_ORDER.compare(event.getMetaData(l1).getName(), event.getMetaData(l2).getName());
504 }
505 });
506
507 for (List<SimTrackerHit> l : simhits) {
508
509 Collections.sort(l, new Comparator() {
510
511
512
513 public int compare(Object o1, Object o2) {
514 SimTrackerHit h1 = (SimTrackerHit) o1;
515 SimTrackerHit h2 = (SimTrackerHit) o2;
516
517 if (h1.getTime()!=h2.getTime()) {
518 return Double.compare(h1.getTime(), h2.getTime());
519 }
520
521 if (h1.getCellID()!=h2.getCellID()) {
522 return Double.compare(h1.getCellID(), h2.getCellID());
523 }
524
525 if (h1.getdEdx()!=h2.getdEdx()) {
526 return Double.compare(h1.getdEdx(), h2.getdEdx());
527 }
528
529 return Double.compare(h1.getPathLength(), h2.getPathLength());
530 }
531 });
532
533
534
535
536
537
538 EventHeader.LCMetaData meta = event.getMetaData(l);
539 String readout = meta.getName();
540 double efficiency = weighter.getReadoutEfficiency(readout);
541 for (SimTrackerHit h : l) {
542 if (random.nextDouble() < efficiency) {
543 allhits.add(h);
544 }
545 }
546 }
547
548 for (SimTrackerHit h : allhits) {
549 MCParticle p = h.getMCParticle();
550 List<SimTrackerHit> these_hits;
551 if (mcmap.containsKey(p)) {
552 these_hits = mcmap.get(p);
553 } else {
554 these_hits = new ArrayList<SimTrackerHit>();
555 }
556
557 these_hits.add(h);
558 mcmap.put(p, these_hits);
559 }
560
561 return mcmap;
562 }
563
564 }