CGEM BOSS 6.6.5.h
BESIII Offline Software System
Loading...
Searching...
No Matches
TCurlFinder.cxx
Go to the documentation of this file.
1//
2// ... Section of Include Files
3//
4#include <iostream>
5#include <fstream>
6#include <math.h>
7#include <stdlib.h>
8//#include "panther/panther.h"
9#include "CLHEP/String/Strings.h"
10#include "TrkReco/TCurlFinder.h"
11#include "TrkReco/TMDCWire.h"
12#include "TrkReco/TMDCWireHit.h"
13#include "TrkReco/TMLink.h"
14#include "TrkReco/TCircle.h"
15#include "TrkReco/TTrack.h"
17//#include "TrkReco/TSvdFinder.h"
18//#include "TrkReco/TSvdHit.h"
19//#include MDC_H
20//#include SVD_H
21
22#include "MdcTables/MdcTables.h"
23
24// Following 3 parameters : (0,0,0,0) is best!
25// Other cases are for the development.
26#define DEBUG_CURL_DUMP 0
27#define DEBUG_CURL_SEGMENT 0
28#define DEBUG_CURL_GNUPLOT 0
29#define DEBUG_CURL_MC 0
30
31#if (DEBUG_CURL_DUMP+DEBUG_CURL_GNUPLOT+DEBUG_CURL_MC)
33#include "TrkReco/TTrackHEP.h"
34#include <set>
35#include <algo.h>
36//#include "tables/belletdf.h"
37static int debugMcFlag = 1;
38#endif
39
40//
41// ... Constructor and Destructor Section ...
42//
44 : m_builder("CurlBuilder"),
45 m_fitter("TCurlFinder Fitter"),
46 m_debugCdcFrame(false),
47 m_debugPlotFlag(0),
48 m_debugFileNumber(0) {
49 // *****NOTE*****
50 // Do not use this!!!!!
51 // Because parameters can not be set correctly.
52}
53
54TCurlFinder::TCurlFinder(const unsigned min_segment,
55 const unsigned min_salvage,
56 const double bad_distance_for_salvage,
57 const double good_distance_for_salvage,
58 const unsigned min_sequence,
59 const unsigned min_fullwire,
60 const double range_for_axial_search,
61 const double range_for_stereo_search,
62 const unsigned superlayer_for_stereo_search,
63 const double range_for_axial_last2d_search,
64 const double range_for_stereo_last2d_search,
65 const double trace2d_distance,
66 const double trace2d_first_distance,
67 const double trace3d_distance,
68 const unsigned determine_one_track,
69 //
70 const double selector_max_impact,
71 const double selector_max_sigma,
72 const double selector_strange_pz,
73 const double selector_replace_dz,
74 //
75 const unsigned stereo_2dfind,
76 const unsigned merge_exe,
77 const double merge_ratio,
78 const double merge_z_diff,
79 const double mask_distance,
80 const double ratio_used_wire,
81 const double range_for_stereo1,
82 const double range_for_stereo2,
83 const double range_for_stereo3,
84 const double range_for_stereo4,
85 const double range_for_stereo5,
86 const double range_for_stereo6,
87 //
88 const double z_cut,
89 const double z_diff_for_last_attend,
90 const unsigned svd_reconstruction,
91 const double min_svd_electrons,
92 const unsigned on_correction,
93 const unsigned output_2dtracks,
94 const unsigned curl_version,
95
96 //jialk
97 const double minimum_seedLength,
98 const double minimum_2DTrackLength,
99 const double minimum_3DTrackLength,
100 const double minimum_closeHitsLength,
101 const double MIN_RADIUS_OF_STRANGE_TRACK,
102 const double ULTIMATE_MIN_RADIUS_OF_STRANGE_TRACK)
103 : m_builder("CurlBuilder"),
104 m_fitter("TCurlFinder Fitter"),
105 m_debugCdcFrame(false),
106 m_debugPlotFlag(0),
107 m_debugFileNumber(0) {
108 StatusCode scmgn = Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF);
109 if(scmgn!=StatusCode::SUCCESS) {
110 std::cout<< __FILE__<<" Unable to open Magnetic field service"<<std::endl;
111 }
112 //...Set Parameter
113 m_param.MIN_SEGMENT = min_segment;
114 m_param.MIN_SALVAGE = min_salvage;
115 m_param.BAD_DISTANCE_FOR_SALVAGE = bad_distance_for_salvage;
116 m_param.GOOD_DISTANCE_FOR_SALVAGE = good_distance_for_salvage;
117 m_param.MIN_SEQUENCE = min_sequence;
118 m_param.MAX_FULLWIRE = min_fullwire;
119 m_param.RANGE_FOR_AXIAL_SEARCH = range_for_axial_search;
120 m_param.RANGE_FOR_STEREO_SEARCH = range_for_stereo_search;
121 m_param.SUPERLAYER_FOR_STEREO_SEARCH = superlayer_for_stereo_search;
122 m_param.RANGE_FOR_AXIAL_LAST2D_SEARCH = range_for_axial_last2d_search;
123 m_param.RANGE_FOR_STEREO_LAST2D_SEARCH = range_for_stereo_last2d_search;
124 m_param.TRACE2D_DISTANCE = trace2d_distance;
125 m_param.TRACE2D_FIRST_SUPERLAYER = trace2d_first_distance;
126 m_param.TRACE3D_DISTANCE = trace3d_distance;
127 m_param.DETERMINE_ONE_TRACK = determine_one_track;
128 //
129 m_param.SELECTOR_MAX_IMPACT = selector_max_impact;
130 m_param.SELECTOR_MAX_SIGMA = selector_max_sigma;
131 m_param.SELECTOR_STRANGE_PZ = selector_strange_pz;
132 m_param.SELECTOR_REPLACE_DZ = selector_replace_dz;
133 //
134 m_param.STEREO_2DFIND = stereo_2dfind;
135 m_param.MERGE_EXE = merge_exe;
136 m_param.MERGE_RATIO = merge_ratio;
137 m_param.MERGE_Z_DIFF = merge_z_diff;
138 m_param.MASK_DISTANCE = mask_distance;
139 m_param.RATIO_USED_WIRE = ratio_used_wire;
140 m_param.RANGE_FOR_STEREO_FIRST = range_for_stereo1;
141 m_param.RANGE_FOR_STEREO_SECOND = range_for_stereo2;
142 m_param.RANGE_FOR_STEREO_THIRD = range_for_stereo3;
143 m_param.RANGE_FOR_STEREO_FORTH = range_for_stereo4;
144 m_param.RANGE_FOR_STEREO_FIFTH = range_for_stereo5;
145 m_param.RANGE_FOR_STEREO_SIXTH = range_for_stereo6;
146 //
147 m_param.Z_CUT = z_cut;
148 m_param.Z_DIFF_FOR_LAST_ATTEND = z_diff_for_last_attend;
149 m_param.SVD_RECONSTRUCTION = svd_reconstruction;
150 m_param.MIN_SVD_ELECTRONS = min_svd_electrons;
151 m_param.ON_CORRECTION = on_correction;
152 m_param.OUTPUT_2DTRACKS = output_2dtracks;
153 m_param.CURL_VERSION = curl_version;
154 m_param.now();
155 //jialk
156 m_param.minimum_seedLength = minimum_seedLength;
157 m_param.minimum_2DTrackLength = minimum_2DTrackLength;
158 m_param.minimum_3DTrackLength = minimum_3DTrackLength;
159 m_param.minimum_closeHitsLength = minimum_closeHitsLength;
160 m_param.MIN_RADIUS_OF_STRANGE_TRACK = MIN_RADIUS_OF_STRANGE_TRACK;
161 m_param.ULTIMATE_MIN_RADIUS_OF_STRANGE_TRACK = ULTIMATE_MIN_RADIUS_OF_STRANGE_TRACK;
162
163
164 //...Set up TBuilder...
165 m_builder.setParam(m_param);
166}
167
170
171//
172// ... Version and Name Section ...
173//
174std::string
175TCurlFinder::name(void) const {
176 return std::string("Curling Track Finder");
177}
178
179std::string
181 return std::string("3.00");
182}
183
184//
185// ... AList Sorter Section...
186//
187#if defined(__GNUG__)
188int
189sortBySequentialLength( const TSegmentCurl **a, const TSegmentCurl **b ) {
190 if( (*a)->maxSeq() < (*b)->maxSeq() ){
191 return 1;
192 }else if( (*a)->maxSeq() == (*b)->maxSeq() ){
193 return 0;
194 }else{
195 return -1;
196 }
197}
198#else
199extern "C" int
200sortBySequentialLength( const void *av, const void *bv ) {
201 const TSegmentCurl **a((const TSegmentCurl**)av);
202 const TSegmentCurl **b((const TSegmentCurl**)bv);
203 if( (*a)->maxSeq() < (*b)->maxSeq() ){
204 return 1;
205 }else if( (*a)->maxSeq() == (*b)->maxSeq() ){
206 return 0;
207 }else{
208 return -1;
209 }
210}
211#endif
212
213#if defined(__GNUG__)
214int
215sortByArcLength( const TMLink **a, const TMLink **b ) {
216 if( (*a)->position().x() > (*b)->position().x() ){
217 return 1;
218 }else if( (*a)->position().x() == (*b)->position().x() ){
219 return 0;
220 }else{
221 return -1;
222 }
223}
224#else
225int
226sortByArcLength( const void*av, const void*bv ) {
227 const TMLink **a((const TMLink**)av);
228 const TMLink **b((const TMLink**)bv);
229 if( (*a)->position().x() > (*b)->position().x() ){
230 return 1;
231 }else if( (*a)->position().x() == (*b)->position().x() ){
232 return 0;
233 }else{
234 return -1;
235 }
236}
237#endif
238//
239// ... Utility Section ...
240//
241double
242TCurlFinder::distance(const double x, const double y) const {
243 return sqrt(x*x+y*y);
244}
245
246unsigned
247TCurlFinder::offset(const unsigned layerId) const {
248 // input - layer id#(0-49)
249 // output - offset of its layer
250 if( layerId == 0 || layerId == 2 || layerId == 4 ||
251 layerId == 6 || layerId == 8 || layerId == 9 ||
252 layerId == 11 || layerId == 13 || layerId == 15 ||
253 layerId == 17 || layerId == 18 || layerId == 20 ||
254 layerId == 22 || layerId == 24 || layerId == 26 ||
255 layerId == 27 || layerId == 29 || layerId == 31 ||
256 layerId == 33 || layerId == 35 || layerId == 36 ||
257 layerId == 38 || layerId == 40 || layerId == 42 ||
258 layerId == 44 || layerId == 45 || layerId == 47 ||
259 layerId == 49 ) return 1; // off set is 0.5
260 return 0; // off set is 0
261}
262
263unsigned
264TCurlFinder::layerId(const double &R) const {
265 // R is radius for MDC but is 2*radius for track
266 double r = R*10.;// cm -> mm
267/* if(r < 83.0 || r > 874.)return 50;
268 if(r <= 93.0)return 0; if(r <= 103.25)return 1; if(r <= 113.5)return 2;
269 if(r <= 136.0)return 3; if(r <= 152.0)return 4; if(r <= 169.0)return 5;
270 if(r <= 186.0)return 6; if(r <= 202.0)return 7; if(r <= 217.0)return 8;
271 if(r <= 232.0)return 9; if(r <= 248.0)return 10; if(r <= 264.0)return 11;
272 if(r <= 280.0)return 12; if(r <= 297.0)return 13; if(r <= 313.0)return 14;
273 if(r <= 330.0)return 15; if(r <= 346.0)return 16; if(r <= 361.0)return 17;
274 if(r <= 376.0)return 18; if(r <= 392.0)return 19; if(r <= 408.0)return 20;
275 if(r <= 424.0)return 21; if(r <= 441.0)return 22; if(r <= 458.0)return 23;
276 if(r <= 474.0)return 24; if(r <= 490.0)return 25; if(r <= 505.0)return 26;
277 if(r <= 520.0)return 27; if(r <= 536.0)return 28; if(r <= 552.0)return 29;
278 if(r <= 568.0)return 30; if(r <= 585.0)return 31; if(r <= 602.0)return 32;
279 if(r <= 618.0)return 33; if(r <= 634.0)return 34; if(r <= 649.0)return 35;
280 if(r <= 664.0)return 36; if(r <= 680.0)return 37; if(r <= 696.0)return 38;
281 if(r <= 712.0)return 39; if(r <= 729.0)return 40; if(r <= 746.0)return 41;
282 if(r <= 762.0)return 42; if(r <= 778.0)return 43; if(r <= 793.0)return 44;
283 if(r <= 808.0)return 45; if(r <= 824.0)return 46; if(r <= 840.0)return 47;
284 if(r <= 856.0)return 48; if(r <= 874.0)return 49;
285*/
286//Liuqg 060915
287 if(r < 73.0 || r > 772.2)return 43;
288 if(r <= 85.0)return 0; if(r <= 97.0)return 1; if(r <= 109.0)return 2;
289 if(r <= 121.0)return 3; if(r <= 133.0)return 4; if(r <= 145.0)return 5;
290 if(r <= 157.0)return 6; if(r <= 179.0)return 7; if(r <= 205.2)return 8;
291 if(r <= 221.4)return 9; if(r <= 237.6)return 10; if(r <= 253.8)return 11;
292 if(r <= 270.0)return 12; if(r <= 286.2)return 13; if(r <= 302.4)return 14;
293 if(r <= 318.6)return 15; if(r <= 334.8)return 16; if(r <= 351.0)return 17;
294 if(r <= 367.2)return 18; if(r <= 387.45)return 19; if(r <= 407.7)return 20;
295 if(r <= 423.9)return 21; if(r <= 440.1)return 22; if(r <= 456.3)return 23;
296 if(r <= 472.5)return 24; if(r <= 488.7)return 25; if(r <= 504.9)return 26;
297 if(r <= 521.1)return 27; if(r <= 537.3)return 28; if(r <= 554.5)return 29;
298 if(r <= 569.7)return 30; if(r <= 585.9)return 31; if(r <= 602.1)return 32;
299 if(r <= 618.3)return 33; if(r <= 634.5)return 34; if(r <= 654.75)return 35;
300 if(r <= 675.0)return 36; if(r <= 691.2)return 37; if(r <= 707.4)return 38;
301 if(r <= 723.6)return 39; if(r <= 739.8)return 40; if(r <= 756.0)return 41;
302 if(r <= 772.2)return 42;
303}
304
305unsigned
306TCurlFinder::maxLocalLayerId(const unsigned superLayerId) const {
307 // input - superlayer id#(0-10)
308 // output - max# id of locallayer in its superlayer.
309//Liuqg 060926, change to BES, superLayerId means the max num of layers in each superlayers.
310/* if(superLayerId == 1 || superLayerId == 3)return 2;
311 if(superLayerId == 5 || superLayerId == 7 ||
312 superLayerId == 9)return 3;
313 if(superLayerId == 4 || superLayerId == 6 ||
314 superLayerId == 8 || superLayerId == 10)return 4;
315 if(superLayerId == 0 || superLayerId == 2)return 5; */
316 if(superLayerId == 10)return 2;
317 if(superLayerId >= 0 && superLayerId < 10)return 3;
318
319 std::cerr << "Error in the CurlFinder(maxLocalLayerId). superLayerId = "
320 << superLayerId << std::endl;
321 return 0;
322}
323
324int
325TCurlFinder::nextSuperAxialLayerId(const unsigned superLayerId, const int in) const {
326 // This function is to find next axial superlayer!
327 // input - superLayerId = superlayer id#(0-10)
328 // - in = find inner axial superlayer from "superLayerID"
329 // This is depth of it.
330 // ex1. If superLayerID = 2, in = 1, return 0
331 // ex2. If superLayerID = 2, in = -1, return 4
332 // output - return 0, 2, 4, 6, 8, 10 = no error
333 // -1 = error
334 if(superLayerId > 10 || superLayerId < 0){
335 std::cerr << "Error in the CurlFinder(nextSuperAxialLayerId)." << std::endl;
336 return -1;
337 }
338//Liuqg 060920, the following numbers have been changed from belle to besiii
339 if(in == 0){
340 if(superLayerId == 2 || superLayerId == 3 ||
341 superLayerId == 4 || superLayerId == 9 ||
342 superLayerId == 10){
343 return superLayerId;
344 }else{
345 //return superLayerId - 1;
346 return -1;
347 }
348 }
349 // almost case --> inner type
350 if((superLayerId == 3 ) && in == 1)return 2;
351 if(superLayerId == 4){
352 if(in == 1)return 3; if(in == 2)return 2;
353 }
354 if(superLayerId == 5 || superLayerId == 6 ||
355 superLayerId == 7 || superLayerId == 8 ||
356 superLayerId == 9){
357 if(in == 1)return 4; if(in == 2)return 3;
358 if(in == 3)return 2;
359 }
360 if(superLayerId == 10){
361 if(in == 1)return 9; if(in == 2)return 4;
362 if(in == 3)return 3; if(in == 4)return 2;
363 }
364 // rare case --> outer type
365 if(superLayerId == 0 || superLayerId == 1){
366 if(in == -1)return 2; if(in == -2)return 3;
367 if(in == -3)return 4; if(in == -4)return 9;
368 if(in == -5)return 10;
369 }
370 if( superLayerId == 2){
371 if(in == -1)return 3; if(in == -2)return 4;
372 if(in == -3)return 9; if(in == -4)return 10;
373 }
374 if(superLayerId == 3){
375 if(in == -1)return 4; if(in == -2)return 9;
376 if(in == -3)return 10;
377 }
378 if(superLayerId == 4){
379 if(in == -1)return 9; if(in == -2)return 10;
380 }
381 if(superLayerId == 5 || superLayerId == 6 ||
382 superLayerId == 7 || superLayerId == 8 ||
383 superLayerId == 9){
384 if(in == -1)return 10;
385 }
386
387 return -1;
388}
389
390int
391TCurlFinder::nextSuperStereoLayerId(const unsigned superLayerId, const int in) const {
392 // This function is to find next stereo superlayer!
393 // input - superLayerId = superlayer id#(0-10)
394 // - in = find inner stereo superlayer from "superLayerID"
395 // This is depth of it.
396 // ex1. If superLayerID = 2, in = 1, return 1
397 // ex2. If superLayerID = 2, in = -1, return 3
398 // output - return 1, 3, 5, 7, 9 = no error
399 // -1 = error
400 if(superLayerId > 10 || superLayerId < 0){
401 std::cerr << "Error in the CurlFinder(nextSuperStereoLayerId)." << std::endl;
402 return -1;
403 }
404//Liuqg 060920, the following numbers have been changed from belle to besiii
405 if(in == 0){
406 if(superLayerId == 0 || superLayerId == 1 ||
407 superLayerId == 5 || superLayerId == 6 ||
408 superLayerId == 7 || superLayerId == 8){
409 return superLayerId;
410 }else{
411 return -1;
412 }
413 }
414 // almost case --> inner type
415 if((superLayerId == 1 || superLayerId == 2 ||
416 superLayerId == 3 || superLayerId == 4) && in == 1)return 0;
417 if(superLayerId == 5){
418 if(in == 1)return 1; if(in == 2)return 0;
419 }
420 if(superLayerId == 6){
421 if(in == 1)return 5; if(in == 2)return 1;
422 if(in == 3)return 0;
423 }
424 if(superLayerId == 7){
425 if(in == 1)return 6; if(in == 2)return 5;
426 if(in == 3)return 1; if(in == 4)return 0;
427 }
428 if(superLayerId == 8){
429 if(in == 1)return 7; if(in == 2)return 6;
430 if(in == 3)return 5; if(in == 4)return 1;
431 if(in == 5)return 0;
432 }
433 if(superLayerId == 9 || superLayerId == 10){
434 if(in == 1)return 8; if(in == 2)return 7;
435 if(in == 3)return 6; if(in == 4)return 5;
436 if(in == 5)return 1; if(in == 6)return 0;
437 }
438 // rare case --> outer type
439 if(superLayerId == 0){
440 if(in == -1)return 1; if(in == -2)return 5;
441 if(in == -3)return 6; if(in == -4)return 7;
442 if(in == -5)return 8;
443 }
444 if(superLayerId == 1 || superLayerId == 2 ||
445 superLayerId == 3 || superLayerId == 4){
446 if(in == -1)return 5; if(in == -2)return 6;
447 if(in == -3)return 7; if(in == -4)return 8;
448 }
449 if(superLayerId == 5){
450 if(in == -1)return 6; if(in == -2)return 7;
451 if(in == -3)return 8;
452 }
453 if(superLayerId == 6){
454 if(in == -1)return 7; if(in == -2)return 8;
455 }
456 if(superLayerId == 7){
457 if(in == -1)return 8;
458 }
459
460 return -1;
461}
462
463unsigned
464TCurlFinder::nAxialHits(const double &r) const {
465 // r is radius for MDC but is 2*radius for track
466 const double eps = 0.2;
467//changed to BESIII, Liuqg 060921
468/* if(r < 8.8-eps) return 0;
469 else if(r < 9.8-eps) return 1;
470 else if(r < 10.85-eps) return 2;
471 else if(r < 12.8-eps) return 3;
472 else if(r < 14.4-eps) return 4;
473 else if(r < 15.95-eps) return 5;
474 else if(r < 22.45-eps) return 6;
475 else if(r < 24.0-eps) return 7;
476 else if(r < 25.6-eps) return 8;
477 else if(r < 27.2-eps) return 9;
478 else if(r < 28.8-eps) return 10;
479 else if(r < 30.4-eps) return 11;
480 else if(r < 36.85-eps) return 12;
481 else if(r < 38.4-eps) return 13;
482 else if(r < 40.0-eps) return 14;
483 else if(r < 41.6-eps) return 15;
484 else if(r < 43.15-eps) return 16;
485 else if(r < 51.25-eps) return 17;
486 else if(r < 52.8-eps) return 18;
487 else if(r < 54.4-eps) return 19;
488 else if(r < 56.0-eps) return 20;
489 else if(r < 57.55-eps) return 21;
490 else if(r < 65.65-eps) return 22;
491 else if(r < 67.2-eps) return 23;
492 else if(r < 68.8-eps) return 24;
493 else if(r < 70.4-eps) return 25;
494 else if(r < 71.9-eps) return 26;
495 else if(r < 80.05-eps) return 27;
496 else if(r < 81.6-eps) return 28;
497 else if(r < 83.2-eps) return 29;
498 else if(r < 84.8-eps) return 30;
499 else if(r < 86.3-eps) return 31;
500 else return 32;
501*/
502 if(r < 20.52-eps) return 0;
503 else if(r < 22.14-eps) return 1;
504 else if(r < 23.76-eps) return 2;
505 else if(r < 25.38-eps) return 3;
506 else if(r < 27.0-eps) return 4;
507 else if(r < 28.62-eps) return 5;
508 else if(r < 30.24-eps) return 6;
509 else if(r < 31.86-eps) return 7;
510 else if(r < 33.48-eps) return 8;
511 else if(r < 35.1-eps) return 9;
512 else if(r < 36.72-eps) return 10;
513 else if(r < 38.34-eps) return 11;
514 else if(r < 67.5-eps) return 12;
515 else if(r < 69.12-eps) return 13;
516 else if(r < 70.74-eps) return 14;
517 else if(r < 72.36-eps) return 15;
518 else if(r < 73.98-eps) return 16;
519 else if(r < 75.6-eps) return 17;
520 else if(r < 77.22-eps) return 18;
521}
522
523//
524// ... Clean or Remove Section ...
525//
526void
527TCurlFinder::makeList(AList<TMLink> &madeList,
528 const AList<TSegmentCurl> &originalList,
529 const AList<TMLink> &removeList) {
530 // This is to make "madeList" from "originalList",
531 // but remove "removeList" from this "madeList", that is,
532 // madeList = originalList - removeList.
533 madeList.removeAll();
534 for(unsigned i = 0, size = originalList.length(); i < size; ++i)
535 madeList.append(originalList[i]->list());
536 madeList.remove(removeList);
537}
538
539void
540TCurlFinder::makeList(AList<TMLink> &madeList,
541 const AList<TMLink> &originalList,
542 const AList<TMLink> &removeList) {
543 // This is to make "madeList" from "originalList",
544 // but remove "removeList" from this "madeList", that is,
545 // madeList = originalList - removeList.
546 madeList.removeAll();
547 madeList.append(originalList);
548 madeList.remove(removeList);
549}
550
551void
553 // This is to clear this Class(TCurlFinder) in TrkReco.cc .
554 // Private members are cleaned.
555 HepAListDeleteAll(m_allAxialHitsOriginal);
556 HepAListDeleteAll(m_allStereoHitsOriginal);
557 HepAListDeleteAll(m_segmentList);
558 HepAListDeleteAll(m_allCircles);
559 HepAListDeleteAll(m_allTracks);
560
561 m_unusedAxialHitsOriginal.removeAll();
562 m_unusedStereoHitsOriginal.removeAll();
563 m_unusedAxialHits.removeAll();
564 m_unusedStereoHits.removeAll();
565 m_removedHits.removeAll();
566 m_circles.removeAll();
567 m_tracks.removeAll();
568 m_2dTracks.removeAll();
569//Liuqg 060917
570 for(int i=0;i<19;++i)
571 m_unusedAxialHitsOnEachLayer[i].removeAll();
572 for(int i=0;i<24;++i)
573 m_unusedStereoHitsOnEachLayer[i].removeAll();
574 for(int i=0;i<5;++i)
575 m_unusedAxialHitsOnEachSuperLayer[i].removeAll();
576 for(int i=0;i<6;++i)
577 m_unusedStereoHitsOnEachSuperLayer[i].removeAll();
578 m_hitsOnInnerSuperLayer.removeAll();
579}
580
581//
582// ... doit .. Section ... This is a main section.
583//
584int
586 const AList<TMDCWireHit> & stereoHits,
587 AList<TTrack> & tracks,
588 AList<TTrack> & tracks2D) {
589#if (DEBUG_CURL_DUMP+DEBUG_CURL_GNUPLOT+DEBUG_CURL_MC)
590 Belle_event_Manager &evtMgr = Belle_event_Manager::get_manager();
591 debugMcFlag = 1;
592 if(evtMgr.count() != 0 &&
593 evtMgr[0].ExpMC() != 2)debugMcFlag = 0;// not MC
594 m_debugCdcFrame = false;
595#endif
596#if !(DEBUG_CURL_MC)
597#if DEBUG_CURL_DUMP
598 std::cout << "(TCurlFinder)Plot Menu : All Off = 0, Interactive = 1, All On = 2" << std::endl;
599 cin >> m_debugPlotFlag;
600#endif
601 // sub main functions #1, #2, #3
602 //...#1
603 makeWireHitsListsSegments(axialHits, stereoHits);
604#if DEBUG_CURL_SEGMENT
605 std::cout << "(TCurlFinder)# of segment = " << m_segmentList.length() << std::endl;
606 debugCheckSegments0();
607 debugCheckSegments1();
608 debugCheckSegments2();
609#endif
610 //...#2
611 if(checkSortSegments() == 0)return 0;
612#if DEBUG_CURL_DUMP
613 if(m_debugPlotFlag){
614 int noPlot = 1;
615 if(m_debugPlotFlag == 1){
616 std::cout << "(TCurlFinder) Do you want to see Segment Plot? : yes = 1, no = other #" << std::endl;
617 cin >> noPlot;
618 }
619 if(noPlot == 1){
620 for(int i=0;i<m_segmentList.length();++i)
621 plotSegment(m_segmentList[i]->list(),0);
622 }
623 }
624#endif
625 //...#3
626 makeCurlTracks(tracks,tracks2D);
627#else
628 makeWithMC(axialHits, stereoHits, tracks);
629#endif
630
631 //...iw 2001/01/26...
632 unsigned n = tracks2D.length();
633 for (unsigned i = 0; i < n; i++)
634 tracks2D[i]->quality(TrackQuality2D);
635 //...iw end...
636 return 0;
637}
638
639//
640// ... Sub Section #1 -- makes segments --
641// ... fuction name = "TMakeUnusedWireHitsList"
642//
643void
644TCurlFinder::makeWireHitsListsSegments(const AList<TMDCWireHit> &axialList,
645 const AList<TMDCWireHit> &stereoList) {
646 // A sub main function ... called by "doit".
647 // #0 makes lists.
648 // #1 makes segments.
649
650 //...makes original lists(axial and stereo)
651 //
652 //......axial
653 unsigned size = axialList.length();
654 for(unsigned i=0;i<size;++i){
655 if(axialList[i]->reccdc()->tdc > 500) continue; //Liuqg, tmp
656 if(axialList[i]->state() & WireHitFindingValid){
657 m_allAxialHitsOriginal.append(new TMLink(0,axialList[i]));
658 if(axialList[i]->wire()->superLayerId() <= 3) //origin is 2, Liuqg
659 m_hitsOnInnerSuperLayer.append(axialList[i]);
660
661 }
662 }
663 size = m_allAxialHitsOriginal.length();
664 for(unsigned i=0;i<size;++i){
665 if(!(m_allAxialHitsOriginal[i]->hit()->state() & WireHitUsed)){
666 if(m_allAxialHitsOriginal[i]->hit()->state() & WireHitInvalidForFit){
667 unsigned newState = m_allAxialHitsOriginal[i]->hit()->state()&(~WireHitInvalidForFit);
668 m_allAxialHitsOriginal[i]->hit()->state(newState);
669 }
670 m_unusedAxialHitsOriginal.append(m_allAxialHitsOriginal[i]);
671 }
672 }
673 m_unusedAxialHits = m_unusedAxialHitsOriginal;
674 //......stereo
675 size = stereoList.length();
676 for(unsigned i=0;i<size;++i){
677 if (stereoList[i]->reccdc()->tdc > 500) continue; //Liuqg, tmp to exclude looping tracks
678 if(stereoList[i]->state() & WireHitFindingValid){
679 m_allStereoHitsOriginal.append(new TMLink(0,stereoList[i]));
680 if(stereoList[i]->wire()->superLayerId() <= 3) //origin is 2, Liuqg
681 m_hitsOnInnerSuperLayer.append(stereoList[i]);
682 }
683 }
684 size = m_allStereoHitsOriginal.length();
685 for(unsigned i=0;i<size;++i){
686 if(!(m_allStereoHitsOriginal[i]->hit()->state() & WireHitUsed)){
687 if(m_allStereoHitsOriginal[i]->hit()->state() & WireHitInvalidForFit){
688 unsigned newState = m_allStereoHitsOriginal[i]->hit()->state()&(~WireHitInvalidForFit);
689 m_allStereoHitsOriginal[i]->hit()->state(newState);
690 }
691 m_unusedStereoHitsOriginal.append(m_allStereoHitsOriginal[i]);
692 }
693 }
694 m_unusedStereoHits = m_unusedStereoHitsOriginal;
695
696 //...shares unsed hit wires to each layer.
697 size = m_unusedAxialHitsOriginal.length();
698 for(unsigned i=0;i<size;++i){
699 m_unusedAxialHitsOnEachLayer[m_unusedAxialHitsOriginal[i]->hit()->wire()->
700 axialStereoLayerId()].append(m_unusedAxialHitsOriginal[i]);
701 }
702 size = m_unusedStereoHitsOriginal.length();
703 for(unsigned i=0;i<size;++i){
704 m_unusedStereoHitsOnEachLayer[m_unusedStereoHitsOriginal[i]->hit()->wire()->
705 axialStereoLayerId()].append(m_unusedStereoHitsOriginal[i]);
706 }
707
708 //...sets pointers to neighboring hit wires of each TMLink
709 linkNeighboringWires(m_unusedAxialHitsOnEachLayer,19); //Belle 32
710 linkNeighboringWires(m_unusedStereoHitsOnEachLayer,24); //Belle 18
711
712 //...makes _unusedSuperAxialHits and _unusedSuperStereoHits
713 createSuperLayer();
714 //...makes segments by linking neighboring hit wires in the same super layer
715 m_segmentList.removeAll();
716 for(unsigned i=0;i<5;++i) //Belle 6
717 if(m_unusedAxialHitsOnEachSuperLayer[i].length() > 0)
718 createSegments(m_unusedAxialHitsOnEachSuperLayer[i]);
719 for(unsigned i=0;i<6;++i) //Belle 5
720 if(m_unusedStereoHitsOnEachSuperLayer[i].length() > 0)
721 createSegments(m_unusedStereoHitsOnEachSuperLayer[i]);
722
723}
724
725void
726TCurlFinder::linkNeighboringWires(AList<TMLink> *list, const unsigned num) {
727 // Axial(num == 19) and Stereo(num == 24).
728 // ...sets pointers to neighboring wires
729 // in "neighbor" of "AList<TMLink> *list" element
730
731 for(int i=0;i<num;++i){
732 if(list[i].length() == 0)continue;
733 for(int j=0;j<list[i].length();++j){
734 //find two links of list[i][j]
735 //...inner layer
736 if(num == 19){
737 if( i == 0 || i == 4 || i == 8 ||
738 i == 12 || i == 16)goto outer;
739 }else if(num == 24){
740 if( i == 0 || i == 4 ||
741 i == 8 || i == 12 || i == 16 || i == 20 )goto outer;
742 }
743
744 for(int k=0;k<list[i-1].length();++k){
745 if(list[i-1][k]->hit()->wire()->localId() ==
746 list[i][j]->wire()->neighbor(1)->localId())
747 setNeighboringWires(list[i][j], list[i-1][k]);
748 else if(list[i-1][k]->hit()->wire()->localId() ==
749 list[i][j]->wire()->neighbor(0)->localId())
750 setNeighboringWires(list[i][j], list[i-1][k]);
751 }//k
752 outer:
753 //...outer layer
754 if(num == 19){
755 if( i == 3 || i == 7 || i == 11 ||
756 i == 15 || i == 18)goto same;
757 }else if(num == 24){
758 if( i == 3 || i == 7 || i == 11 ||
759 i == 15 || i == 19 || i == 23 )goto same;
760 }
761 for(int k=0;k<list[i+1].length();++k){
762 if(list[i+1][k]->hit()->wire()->localId() ==
763 list[i][j]->hit()->wire()->neighbor(4)->localId())
764 setNeighboringWires(list[i][j], list[i+1][k]);
765 else if(list[i+1][k]->wire()->localId() ==
766 list[i][j]->wire()->neighbor(5)->localId())
767 setNeighboringWires(list[i][j], list[i+1][k]);
768 }//k
769 same:
770 //...same layer
771 for(int k=0;k<list[i].length();++k){
772 if(list[i][k]->hit()->wire()->localId() ==
773 list[i][j]->hit()->wire()->localIdForPlus()+1){
774 setNeighboringWires(list[i][j], list[i][k]);
775 }else if(list[i][k]->hit()->wire()->localId() ==
776 list[i][j]->hit()->wire()->localIdForMinus()-1){
777 setNeighboringWires(list[i][j], list[i][k]);
778 }
779 }//k
780 }//j
781 }//i
782}
783
784void
785TCurlFinder::setNeighboringWires(TMLink *list, const TMLink *next) {
786 // ...sets a neighboring wire of "list".
787 // Its candidate is "next".
788 for(int i=0;i<6;++i){
789 if(!list->neighbor(i)){
790 list->neighbor(i,const_cast<TMLink*>(next));
791 break;
792 }
793 }
794}
795
796void
797TCurlFinder::createSuperLayer(void) {
798//Liuqg
799 for(int i=0;i<4;++i){
800 if(m_unusedAxialHitsOnEachLayer[i].length() > 0)
801 m_unusedAxialHitsOnEachSuperLayer[0].append(m_unusedAxialHitsOnEachLayer[i]);
802 if(m_unusedAxialHitsOnEachLayer[i+4].length() > 0)
803 m_unusedAxialHitsOnEachSuperLayer[1].append(m_unusedAxialHitsOnEachLayer[i+4]);
804 if(m_unusedAxialHitsOnEachLayer[i+8].length() > 0)
805 m_unusedAxialHitsOnEachSuperLayer[2].append(m_unusedAxialHitsOnEachLayer[i+8]);
806 if(m_unusedAxialHitsOnEachLayer[i+12].length() > 0)
807 m_unusedAxialHitsOnEachSuperLayer[3].append(m_unusedAxialHitsOnEachLayer[i+12]);
808 if(m_unusedAxialHitsOnEachLayer[i+16].length() > 0 && i+16 < 19)
809 m_unusedAxialHitsOnEachSuperLayer[4].append(m_unusedAxialHitsOnEachLayer[i+16]);
810 }
811 for(int i=0;i<4;++i){
812 if(m_unusedStereoHitsOnEachLayer[i].length() > 0)
813 m_unusedStereoHitsOnEachSuperLayer[0].append(m_unusedStereoHitsOnEachLayer[i]);
814 if(m_unusedStereoHitsOnEachLayer[i+4].length() > 0)
815 m_unusedStereoHitsOnEachSuperLayer[1].append(m_unusedStereoHitsOnEachLayer[i+4]);
816 if(m_unusedStereoHitsOnEachLayer[i+8].length() > 0)
817 m_unusedStereoHitsOnEachSuperLayer[2].append(m_unusedStereoHitsOnEachLayer[i+8]);
818 if(m_unusedStereoHitsOnEachLayer[i+12].length() > 0)
819 m_unusedStereoHitsOnEachSuperLayer[3].append(m_unusedStereoHitsOnEachLayer[i+12]);
820 if(m_unusedStereoHitsOnEachLayer[i+16].length() > 0)
821 m_unusedStereoHitsOnEachSuperLayer[4].append(m_unusedStereoHitsOnEachLayer[i+16]);
822 if(m_unusedStereoHitsOnEachLayer[i+20].length() > 0)
823 m_unusedStereoHitsOnEachSuperLayer[5].append(m_unusedStereoHitsOnEachLayer[i+20]);
824 }
825}
826
827void
828TCurlFinder::createSegments(AList<TMLink> &list) {
829 // ...makes segments from AList<TMLink> &list, in every superlayer.
830 // These segments are add to _segmentList.(# of segments >= MIN_SEGMENT)
831 AList<TMLink> seedStock;
832 do{
833 TSegmentCurl *segment = new TSegmentCurl(list[0]->hit()->wire()->superLayerId(),
834 maxLocalLayerId(list[0]->hit()->wire()
835 ->superLayerId()));
836
837 segment->append(list[0]);
838 TMLink *seed = list[0];
839 list.remove(seed);
840 next:
841 searchSegment(seed, list, seedStock, segment);
842 if(seedStock.length() > 0){
843 seed = seedStock[0];
844 seedStock.remove(seed);
845 goto next;
846 }else if(segment->size() >= m_param.MIN_SEGMENT){
847 segment->update();
848 m_segmentList.append(segment);
849#if DEBUG_CURL_DUMP
850 std::cout << "Segment # = " << m_segmentList.length() << std::endl;
851 segment->dump();
852#endif
853 }else{
854 delete segment;
855 }
856 }while(list.length() > 0);
857}
858
859void
860TCurlFinder::searchSegment(TMLink *seed, AList<TMLink> &list,
861 AList<TMLink> &seedStock, TSegmentCurl *segment) {
862 for(int i=0;i<6;++i){
863 if(seed->neighbor(i)){
864 if(!findLink(seed->neighbor(i),list))continue;
865 segment->append(seed->neighbor(i));
866 seedStock.append(seed->neighbor(i));
867 list.remove(seed->neighbor(i));
868 }else{
869 break;
870 }
871 }
872}
873
874TMLink *
875TCurlFinder::findLink(const TMLink *seed, const AList<TMLink> &list) {
876 // This is to search "TMLink *seed" in "AList<TMLink> &list".
877 // Return is when found, the "TMLink *list[i]"
878 // when not found, NULL.
879 unsigned size = list.length();
880 if(size == 0)return NULL;
881 for(unsigned i=0;i<size;++i){
882 if(seed == list[i])return list[i];
883 }
884 return NULL;
885}
886
887//
888// ... Sub Section #2 -- checks and sorts segments --
889// ... fuction name = "checkSortSegments"
890//
891int
892TCurlFinder::checkSortSegments(void) {
893 // A sub main function ...called by "doit".
894#if DEBUG_CURL_DUMP
895 std::cout << "(TCurlFinder)checking and sorting segments..." << std::endl;
896#endif
897 unsigned length = m_segmentList.length();
898 if(length == 0)return 0;
899 checkExceptionalSegmentsType03();//...exception #3
900 //checkExceptionalSegmentsType02();//...exception #2
901 checkExceptionalSegmentsType01();//...exception #1
902 m_segmentList.sort(sortBySequentialLength);
903#if DEBUG_CURL_DUMP
904 std::cout << "(TCurlFinder)...done check and sort of segments." << std::endl;
905#endif
906 return 1;
907}
908
909void
910TCurlFinder::checkExceptionalSegmentsType03(void) {
911 int max = m_param.MAX_FULLWIRE;
912 int nMinWires;
913 if(max == 7)nMinWires = 21;
914 else if(max == 6)nMinWires = 19;
915 else if(max == 5)nMinWires = 18;
916 else if(max == 4)nMinWires = 16;
917 else if(max == 3)nMinWires = 14;
918 else if(max == 2)nMinWires = 12;
919 else if(max == 1)nMinWires = 10;
920 else if(max == 0)nMinWires = 7;
921
922 AList<TSegmentCurl> removeList;
923 for(unsigned i = 0, length = m_segmentList.length(); i < length; ++i){
924 if(m_segmentList[i]->size() >= nMinWires){
925 unsigned nWires = m_segmentList[i]->size();
926 unsigned n6Wires = 0;
927 for(unsigned j=0;j<nWires;++j){
928 if(((m_segmentList[i]->list())[j])->neighbor(5))++n6Wires;
929 if(n6Wires > max)break;
930 }
931 if(n6Wires <= max)continue;
932 removeList.append(m_segmentList[i]);
933#if DEBUG_CURL_SEGMENT
934 writeSegment(m_segmentList[i]->list(),3);
935#endif
936 }
937 }
938 if(removeList.length() >= 1){
939#if DEBUG_CURL_DUMP
940 std::cout << "(TCurlFinder)removing large segments: # = " << removeList.length() << std::endl;
941#endif
942 m_segmentList.remove(removeList);
943 HepAListDeleteAll(removeList);
944 }
945}
946
947void
948TCurlFinder::checkExceptionalSegmentsType02(void) {
949 int max = 10;
950 int hmax = 5;
951 AList<TSegmentCurl> removeList;
952 for(unsigned i = 0, length = m_segmentList.length(); i < length; ++i){
953 int lSize = max*3+hmax*3;
954 int lNum = 3;
955 if(m_segmentList[i]->superLayerId() == 1 ||
956 m_segmentList[i]->superLayerId() == 3){
957 lSize = max*2+hmax;
958 lNum = 2;
959 }
960 if(m_segmentList[i]->superLayerId() == 5 ||
961 m_segmentList[i]->superLayerId() == 7 ||
962 m_segmentList[i]->superLayerId() == 9){
963 lSize = max*2+hmax*2;
964 lNum = 2;
965 }
966 if(m_segmentList[i]->superLayerId() == 4 ||
967 m_segmentList[i]->superLayerId() == 6 ||
968 m_segmentList[i]->superLayerId() == 8 ||
969 m_segmentList[i]->superLayerId() == 10)lSize = max*3+hmax*2;
970 if(m_segmentList[i]->size() < lSize)continue;
971 int nL = 0;
972 for(unsigned j=0,size=m_segmentList[i]->maxLocalLayerId();j<size;++j){
973 if(m_segmentList[i]->sizeOfLayer(j) >= max)++nL;
974 }
975 if(nL < lNum)continue;
976 removeList.append(m_segmentList[i]);
977 //plotSegment(m_segmentList[i]->list(),0);
978#if DEBUG_CURL_SEGMENT
979 //writeSegment(m_segmentList[i]->list(),2);
980#endif
981 }
982 if(removeList.length() >= 1){
983#if DEBUG_CURL_DUMP
984 std::cout << "(TCurlFinder)removing large segments: # = " << removeList.length() << std::endl;
985#endif
986 m_segmentList.remove(removeList);
987 HepAListDeleteAll(removeList);
988 }
989}
990
991void
992TCurlFinder::checkExceptionalSegmentsType01(void) {
993 for(unsigned i = 0, length = m_segmentList.length(); i < length; ++i){
994 if(m_segmentList[i]->maxLocalLayerId() != m_segmentList[i]->layerIdOfMaxSeq() &&
995 m_segmentList[i]->maxSeq() >= m_param.MIN_SEQUENCE){
996 unsigned innerHits = 0;
997 if(m_segmentList[i]->layerIdOfMaxSeq() == 0)continue;
998 TSegmentCurl *outer = new TSegmentCurl(m_segmentList[i]->superLayerId(),
999 m_segmentList[i]->maxLocalLayerId());
1000 for(unsigned j = 0, size = m_segmentList[i]->size(); j < size; ++j){
1001 if(m_segmentList[i]->layerIdOfMaxSeq()+1 <=
1002 (m_segmentList[i]->list())[j]->hit()->wire()->localLayerId() &&
1003 (m_segmentList[i]->list())[j]->hit()->wire()->localLayerId() <=
1004 m_segmentList[i]->maxLocalLayerId()){
1005 outer->append((m_segmentList[i]->list())[j]);
1006 }else if(m_segmentList[i]->layerIdOfMaxSeq()-1 >=
1007 (m_segmentList[i]->list())[j]->hit()->wire()->localLayerId()){
1008 ++innerHits;
1009 }
1010 }
1011 if(innerHits != 0 && outer->size() != 0){
1012#if DEBUG_CURL_DUMP
1013 std::cout << "(TCurlFinder)removing some wires in the segment." << std::endl;
1014#endif
1015#if DEBUG_CURL_SEGMENT
1016 //writeSegment(m_segmentList[i]->list(),1);
1017#endif
1018 m_segmentList[i]->remove(const_cast< AList<TMLink>& >(outer->list()));
1019 outer->removeAll();
1020 delete outer;
1021 }else{
1022 outer->removeAll();
1023 delete outer;
1024 }
1025 }
1026 }
1027}
1028
1029//
1030// ... Sub Section #3 -- makes curl tracks --
1031// ... fuction name = "makeCurlTracks"
1032//
1033
1034//............................................
1035//..............2D+3D Manage Parts............
1036//............................................
1037
1038void
1039TCurlFinder::makeCurlTracks(AList<TTrack> &tracks,
1040 AList<TTrack> &tracks2D) {
1041 AList<TSegmentCurl> segmentList = m_segmentList;
1042 //cout<<"segments: "<<m_segmentList.length()<<endl;
1043// if(m_param.SVD_RECONSTRUCTION)m_builder.setSvdClusters();
1044 for(unsigned i = 0, size = m_segmentList.length(); i < size; ++i){
1045 TCircle *circle = make2DTrack(segmentList[i]->list(), segmentList, 1); //order by sequential num
1046 if(circle){
1047 AList<TMLink> tmp(circle->links());
1048#if DEBUG_CURL_DUMP
1049 std::cout << "(TCurlFinder) 2D:Created Circle!!!" << std::endl;
1050 if(m_debugPlotFlag){
1051 int noPlot = 1;
1052 if(m_debugPlotFlag == 1){
1053 std::cout << "(TCurlFinder) Do you want to see Circle Plot(2D)? : yes = 1, no = other #" << std::endl;
1054 cin >> noPlot;
1055 }
1056 if(noPlot == 1)plotCircle(*circle,0);
1057 }
1058#endif
1059
1060/* if (tmp.length()>0) {
1061 cout<<"circle ok.............."<<endl;
1062 for(int j = 0; j < tmp.length(); ++j){
1063 TMLink *ll = tmp[j];
1064 cout<<"layerId: "<<ll->wire()->layerId()
1065 <<" localId: "<<ll->wire()->localId()<<endl;
1066 }
1067 }
1068*/
1069 if(TCircle *dividedCircle = dividing2DTrack(circle)){
1070#if DEBUG_CURL_DUMP
1071 std::cout << "(TCurlFinder) 2D:dividing...good...2 Circles!!!" << std::endl;
1072#endif
1073 TTrack *track1(NULL), *track2(NULL);
1074 int ok2d[2] = { 0, 0 };
1075 int ok3d[2] = { 0, 0 };
1076 //cout<<"trac2D: "<<trace2DTrack(circle)<<" check2D: "<< check2DCircle(circle)
1077 //<<" fit: "<< circle->fitForCurl(1)<<endl;
1078 if(trace2DTrack(circle) &&
1079 check2DCircle(circle) &&
1080 circle->fitForCurl(1) != -1){
1081 ok2d[0] = 1;
1082#if DEBUG_CURL_DUMP
1083 std::cout << "(TCurlFinder) 2D:Success Circle Fit!!!" << std::endl;
1084#endif
1085 track1 = make3DTrack(circle, segmentList);
1086 }
1087 //cout<<"trac2D: "<<trace2DTrack(dividedCircle)<<" check2D: "<< check2DCircle(dividedCircle)
1088 //<<" fit: "<< dividedCircle->fitForCurl(1)<<endl;
1089 if(trace2DTrack(dividedCircle) &&
1090 check2DCircle(dividedCircle) &&
1091 dividedCircle->fitForCurl(1) != -1){
1092 ok2d[1] = 1;
1093#if DEBUG_CURL_DUMP
1094 std::cout << "(TCurlFinder) 2D:Success Circle Fit!!!" << std::endl;
1095#endif
1096 track2 = make3DTrack(dividedCircle, segmentList);
1097 }
1098 if(track1 && track2){
1099#if DEBUG_CURL_DUMP
1100 std::cout << "(TCurlFinder) 3D:Create Track!!! in track1 && track2" << std::endl;
1101#endif
1102 salvage3DTrack(track1,true);
1103 salvage3DTrack(track2,true);
1104#if DEBUG_CURL_DUMP
1105 std::cout << "(TCurlFinder) 1:dz = " << track1->helix().dz()
1106 << ", 2:dz = " << track2->helix().dz() << std::endl;
1107#endif
1108 if(m_param.DETERMINE_ONE_TRACK){
1109 if(fabs(track1->helix().dz()) < fabs(track2->helix().dz())){
1110 m_tracks.remove(track2);
1111 if(merge3DTrack(track1, tracks))
1112 if(check3DTrack(track1) &&
1113 trace3DTrack(track1)){
1114 ok3d[0] = 1;
1115 ok3d[1] = 1;
1116 mask3DTrack(track1,tmp);
1117 tmp.append(track1->links());
1118 }
1119 }else{
1120 m_tracks.remove(track1);
1121 if(merge3DTrack(track2, tracks))
1122 if(check3DTrack(track2) &&
1123 trace3DTrack(track2)){
1124 ok3d[0] = 1;
1125 ok3d[1] = 1;
1126 mask3DTrack(track2,tmp);
1127 tmp.append(track2->links());
1128 }
1129 }
1130 }else{
1131 int isSaved[2] = { 0, 0 };
1132 if(merge3DTrack(track1, tracks)){
1133 if(check3DTrack(track1) &&
1134 trace3DTrack(track1)){
1135 ok3d[0] = 1;
1136 mask3DTrack(track1,tmp);
1137 tmp.append(track1->links());
1138 isSaved[0] = 1;
1139 }
1140 }
1141 if(merge3DTrack(track2, tracks)){
1142 if(check3DTrack(track2) &&
1143 trace3DTrack(track2)){
1144 ok3d[1] = 1;
1145 mask3DTrack(track2,tmp);
1146 tmp.append(track2->links());
1147 isSaved[1] = 1;
1148 }
1149 }
1150 if(isSaved[0] == 1 && isSaved[1] == 1){
1151 track1->daughter(track2);
1152 track2->daughter(track1);
1153 }
1154 }
1155 }else if(track1){
1156#if DEBUG_CURL_DUMP
1157 std::cout << "(TCurlFinder) 3D:Create Track!!! in track1" << std::endl;
1158#endif
1159 salvage3DTrack(track1,true);
1160 if(merge3DTrack(track1, tracks))
1161 if(check3DTrack(track1) &&
1162 trace3DTrack(track1)){
1163 ok3d[0] = 1;
1164 mask3DTrack(track1,tmp);
1165 tmp.append(track1->links());
1166 }
1167 }else if(track2){
1168#if DEBUG_CURL_DUMP
1169 std::cout << "(TCurlFinder) 3D:Create Track!!! in track2" << std::endl;
1170#endif
1171 salvage3DTrack(track2,true);
1172 if(merge3DTrack(track2, tracks))
1173 if(check3DTrack(track2) &&
1174 trace3DTrack(track2)){
1175 ok3d[1] = 1;
1176 mask3DTrack(track2,tmp);
1177 tmp.append(track2->links());
1178 }
1179 }
1180
1181 if(m_param.OUTPUT_2DTRACKS){
1182 // When 2d is OK but 3d is BAD, a 2dtrk is saved.
1183 if(ok2d[0] == 1 && ok3d[0] == 0){
1184 removeStereo(*circle);
1185 double chi2_2d;
1186 int ndf_2d;
1187 if(fitWDD(*circle,chi2_2d,ndf_2d)){
1188 TTrack *trk2d = new TTrack(*circle);
1189 trk2d->_ndf = ndf_2d;
1190 trk2d->_chi2 = chi2_2d;
1191 m_2dTracks.append(trk2d);
1192 m_allTracks.append(trk2d);
1193 }
1194#if DEBUG_CURL_DUMP
1195 else{
1196 std::cout << "(TCurlFinder) 2D:fit with drift information!!!" << std::endl;
1197 }
1198#endif
1199 }
1200 if(ok2d[1] == 1 && ok3d[1] == 0){
1201 removeStereo(*dividedCircle);
1202 double chi2_2d;
1203 int ndf_2d;
1204 if(fitWDD(*dividedCircle,chi2_2d,ndf_2d)){
1205 TTrack *trk2d = new TTrack(*dividedCircle);
1206 trk2d->_ndf = ndf_2d;
1207 trk2d->_chi2 = chi2_2d;
1208 m_2dTracks.append(trk2d);
1209 m_allTracks.append(trk2d);
1210 }
1211#if DEBUG_CURL_DUMP
1212 else{
1213 std::cout << "(TCurlFinder) 2D:fit with drift information!!!" << std::endl;
1214 }
1215#endif
1216 }
1217 }
1218
1219 }else{
1220#if DEBUG_CURL_DUMP
1221 std::cout << "(TCurlFinder) 2D:dividing...no good...1 Circles!!!" << std::endl;
1222#endif
1223 int ok2d = 0;
1224 int ok3d = 0;
1225 //cout<<"trac2D: "<<trace2DTrack(circle)<<" check2D: "<< check2DCircle(circle)
1226 //<<" fit: "<< circle->fitForCurl(1)<<endl;
1227 if(trace2DTrack(circle) &&
1228 check2DCircle(circle) &&
1229 circle->fitForCurl(1) != -1){
1230#if DEBUG_CURL_DUMP
1231 std::cout << "(TCurlFinder) 2D:Success Circle Fit!!!" << std::endl;
1232#endif
1233 ok2d = 1;
1234 TTrack *track3 = make3DTrack(circle, segmentList);
1235 if(track3){
1236#if DEBUG_CURL_DUMP
1237 std::cout << "(TCurlFinder) 3D:Create Track!!! in track3" << std::endl;
1238#endif
1239 salvage3DTrack(track3,true);
1240 if(merge3DTrack(track3, tracks))
1241 if(check3DTrack(track3) &&
1242 trace3DTrack(track3)){
1243 ok3d = 1;
1244 mask3DTrack(track3,tmp);
1245 tmp.append(track3->links());
1246 }
1247 }
1248
1249 if(m_param.OUTPUT_2DTRACKS){
1250 // When 2d is OK but 3d is BAD, a 2dtrk is saved.
1251 if(ok2d == 1 && ok3d == 0){
1252 removeStereo(*circle);
1253 double chi2_2d;
1254 int ndf_2d;
1255 if(fitWDD(*circle,chi2_2d,ndf_2d)){
1256 TTrack *trk2d = new TTrack(*circle);
1257 trk2d->_ndf = ndf_2d;
1258 trk2d->_chi2 = chi2_2d;
1259 m_2dTracks.append(trk2d);
1260 m_allTracks.append(trk2d);
1261 }
1262#if DEBUG_CURL_DUMP
1263 else{
1264 std::cout << "(TCurlFinder) 2D:fit with drift information!!!" << std::endl;
1265 }
1266#endif
1267 }
1268 }
1269 }
1270 }
1271 m_unusedAxialHits.remove(tmp);
1272 m_unusedStereoHits.remove(tmp);
1273 for(unsigned ii=0, nsize=m_segmentList.length();ii<nsize;++ii){
1274 m_segmentList[ii]->remove(tmp);
1275 if(m_segmentList[ii]->list().length() < m_param.MIN_SEGMENT)
1276 m_segmentList[ii]->removeAll();
1277 }
1278 }
1279 segmentList[i]->removeAll();
1280 }
1281
1282 // Check 2D trk's wires
1283 //check2DTracks(); // ... not need because of the current algorithm
1284
1285 // 3D & 2D trks information
1286 assignTracks();
1287
1288#if DEBUG_CURL_DUMP
1289 std::cout << "(TCurlFinder)MDC Rec Track # 3D = " << m_tracks.length()
1290 << ", 2D = " << m_2dTracks.length() << std::endl;
1291 std::cout << "3D Track List" << std::endl;
1292 for(int j=0;j<m_tracks.length();++j){
1293 m_tracks[j]->setFinderType(3);
1294 unsigned nA = 0, nS = 0;
1295 unsigned nAOK = 0, nSOK = 0;
1296 for(unsigned i=0,size=m_tracks[j]->nLinks();i<size;++i){
1297 if(m_tracks[j]->links()[i]->wire()->stereo())++nS;
1298 else ++nA;
1299 if(/*!(m_tracks[j]->links()[i]->hit()->state() & WireHitInvalidForFit) &&*/
1300 (m_tracks[j]->links()[i]->hit()->state() & WireHitFittingValid)){
1301 if(m_tracks[j]->links()[i]->wire()->stereo())++nSOK;
1302 else ++nAOK;
1303 }
1304 }
1305 std::cout << "(TCurlFinder) #" << j << ": wire info...A+S: " << m_tracks[j]->nLinks()
1306 << ", A: " << nAOK << "/" << nA
1307 << ", S: " << nSOK << "/" << nS << std::endl;
1308 if(m_tracks[j]->daughter())
1309 std::cout << "(TCurlFinder) Relation = EXIST" << std::endl;
1310 else
1311 std::cout << "(TCurlFinder) Relation = NO EXIST" << std::endl;
1312 }
1313 std::cout << "2D Track List" << std::endl;
1314 for(int j=0;j<m_2dTracks.length();++j){
1315 unsigned nA = 0, nS = 0;
1316 unsigned nAOK = 0, nSOK = 0;
1317 for(unsigned i=0,size=m_2dTracks[j]->nLinks();i<size;++i){
1318 if(m_2dTracks[j]->links()[i]->wire()->stereo())++nS;
1319 else ++nA;
1320 if(/*!(m_2dTracks[j]->links()[i]->hit()->state() & WireHitInvalidForFit) &&*/
1321 (m_2dTracks[j]->links()[i]->hit()->state() & WireHitFittingValid)){
1322 if(m_2dTracks[j]->links()[i]->wire()->stereo())++nSOK;
1323 else ++nAOK;
1324 }
1325 }
1326 std::cout << "(TCurlFinder) #" << j << ": wire info...A+S: " << m_2dTracks[j]->nLinks()
1327 << ", A: " << nAOK << "/" << nA
1328 << ", S: " << nSOK << "/" << nS
1329 << ", Chi2: " << m_2dTracks[j]->chi2()
1330 << ", Ndf: " << m_2dTracks[j]->ndf() << std::endl;
1331 if(m_2dTracks[j]->daughter())
1332 std::cout << "(TCurlFinder) Relation = EXIST" << std::endl;
1333 else
1334 std::cout << "(TCurlFinder) Relation = NO EXIST" << std::endl;
1335 }
1336#endif
1337
1338 // 3D trks
1339 m_allTracks.remove(m_tracks);
1340 checkRelation(m_tracks);
1341 tracks.append(m_tracks);
1342 if(m_param.OUTPUT_2DTRACKS){
1343 // 2D trks
1344 m_allTracks.remove(m_2dTracks);
1345 tracks2D.append(m_2dTracks);
1346 }
1347}
1348
1349void
1350TCurlFinder::check2DTracks(void)
1351{
1352 if(m_2dTracks.length() == 0)return;
1353 AList<TMLink> allWires_3Dtrks;
1354 for(int i=0;i<m_tracks.length();++i){
1355 allWires_3Dtrks.append(m_tracks[i]->links());
1356 }
1357 //cout << "ALL Wire(3D) " << allWires_3Dtrks.length() << endl;
1358
1359 for(int i=0;i<m_2dTracks.length();++i){
1360 AList<TMLink> usedWires;
1361 for(int j=0;j<m_2dTracks[i]->nLinks();++j){
1362 int ok = 1;
1363 for(int k=0;k<allWires_3Dtrks.length();++k){
1364 if(m_2dTracks[i]->links()[j]->wire()->id() ==
1365 allWires_3Dtrks[k]->wire()->id()){
1366 ok = 0;
1367 break;
1368 }
1369 }
1370 if(ok == 0){
1371 usedWires.append(m_2dTracks[i]->links()[j]);
1372 }
1373 }
1374 //cout << i << " : used # " << usedWires.length()
1375 // << ", all # " << m_2dTracks[i]->nLinks() << endl;
1376 m_2dTracks[i]->remove(usedWires);
1377 }
1378}
1379
1380void
1381TCurlFinder::checkRelation(AList<TTrack> &list) {
1382 unsigned nT = list.length();
1383 if(nT <= 1)return;
1384 for(unsigned i=0;i<nT;++i){
1385 if(list[i]->daughter()){
1386 int isHere = 0;
1387 for(unsigned j=0;j<nT;++j){
1388 if(i != j &&
1389 list[i]->daughter() == list[j]){
1390 isHere = 1;
1391 break;
1392 }
1393 }
1394 if(isHere == 0){
1395 list[i]->daughter(NULL);
1396 }
1397 }
1398 }
1399}
1400
1401TCircle *
1402TCurlFinder::dividing2DTrack(TCircle *circle) {
1403 AList<TMLink> positive, negative;
1404 for(unsigned i = 0, size = circle->nLinks(); i < size; ++i){
1405 if(circle->center().x()*circle->links()[i]->hit()->wire()->xyPosition().y() -
1406 circle->center().y()*circle->links()[i]->hit()->wire()->xyPosition().x() > 0.){
1407 positive.append(circle->links()[i]);
1408 }else{
1409 negative.append(circle->links()[i]);
1410 }
1411 }
1412 if(positive.length() > negative.length()){
1413 circle->remove(negative);
1414 circle->property(1.,fabs(circle->radius()),circle->center());
1415 if(negative.length() >= 3){
1416 TCircle *new_circle = new TCircle(negative);
1417 m_allCircles.append(new_circle);
1418 new_circle->property(-1.,-1.*fabs(circle->radius()),circle->center());
1419 return new_circle;
1420 }else{
1421 return NULL;
1422 }
1423 }else{
1424 circle->remove(positive);
1425 circle->property(-1.,-1.*fabs(circle->radius()),circle->center());
1426 if(positive.length() >= 3){
1427 TCircle *new_circle = new TCircle(positive);
1428 m_allCircles.append(new_circle);
1429 new_circle->property(1.,fabs(circle->radius()),circle->center());
1430 return new_circle;
1431 }else{
1432 return NULL;
1433 }
1434 }
1435}
1436
1437void
1438TCurlFinder::assignTracks(void) {
1439 // 3D trks
1440 for(int i=0,size=m_tracks.length();i<size;++i) {
1441 m_tracks[i]->assign(WireHitCurlFinder);
1442 m_tracks[i]->finder(TrackCurlFinder);
1443// m_tracks[i]->assign(WireHitCurlFinder, TrackCurlFinder | TrackValid | Track3D);
1444 }
1445
1446 // 2D trks
1447 for(int i=0,size=m_2dTracks.length();i<size;++i) {
1448 m_2dTracks[i]->assign(WireHitCurlFinder);
1449 m_2dTracks[i]->finder(TrackCurlFinder);
1450 }
1451}
1452
1453extern "C" int
1454TCurlFinder_doubleCompare(const void *i, const void *j){
1455 if(*(static_cast<const double*>(i)) > *(static_cast<const double*>(j)))return 1;
1456 if(*(static_cast<const double*>(i)) < *(static_cast<const double*>(j)))return -1;
1457 return 0;
1458}
1459
1460int
1461TCurlFinder::trace2DTrack(TCircle *circle) {
1462 // 0 is bad, 1 is good
1463 unsigned nSize = circle->links().length();
1464 if(nSize == 0)return 0;
1465 double r = fabs(circle->radius());
1466 if(r < 0.01)return 0; // to reject "r=0cm" circles.
1467 double cx = circle->center().x();
1468 double cy = circle->center().y();
1469 double th = atan2(-cy,-cx);
1470 if(th < 0.)th += 2.*M_PI;
1471
1472 unsigned innerOK = 0;
1473 double *angle = new double [circle->links().length()];
1474 for(unsigned i=0,size=nSize;i<size;++i){
1475 double th_r = atan2(circle->links()[i]->wire()->xyPosition().y()-cy,
1476 circle->links()[i]->wire()->xyPosition().x()-cx);
1477 if(th_r < 0.)th_r += 2.*M_PI;
1478 double diff = th_r-th+2.*M_PI;
1479 if(th_r > th)diff = th_r-th;
1480 if(circle->links()[i]->wire()->superLayerId() <= 2)innerOK = 1;
1481 angle[i] = diff;
1482 }
1483 qsort(angle,nSize,sizeof(double),TCurlFinder_doubleCompare);//chiisai-jun
1484 double maxDiffAngle = 0.;
1485 unsigned maxIndex = 0;
1486 for(unsigned i=0,size=nSize;i<size-1;++i){
1487 if(angle[i+1]-angle[i] > maxDiffAngle){
1488 maxDiffAngle = angle[i+1]-angle[i];
1489 maxIndex = i;
1490 }
1491 }
1492 delete [] angle;
1493 //std::cout << "2D TRACE : maxDifAngle = " << maxDiffAngle
1494 // << ", r = " << r << ", dist = " << r*maxDiffAngle << std::endl;
1495
1496// if(r*maxDiffAngle > m_param.TRACE2D_DISTANCE)return 0; //Liuqg, tmp. BES layer distribution is not uniform.
1497 if(innerOK == 1)return 1;
1498
1499 double q = circle->radius() > 0. ? 1. : -1;
1500 for(unsigned i=0,size=m_hitsOnInnerSuperLayer.length();i<size;++i){
1501 double mag = distance(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().x()-cx,
1502 m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().y()-cy);
1503 if(fabs(mag-r) < m_param.TRACE2D_FIRST_SUPERLAYER &&
1504 q*(cx*m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().y()-
1505 cy*m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().x()) > 0.){
1506 return 1;
1507 }
1508 }
1509 return 0;
1510}
1511
1512bool
1513TCurlFinder::check2DCircle(TCircle *circle) {
1514 unsigned nA(nAxialHits(fabs(circle->radius())*2.0));
1515
1516 unsigned nMA = static_cast<unsigned>(floor(m_param.RATIO_USED_WIRE*static_cast<double>(nA)));
1517 if(nMA < 3)nMA = 3;
1518
1519 unsigned nAhits(0), nShits(0);
1520 for(unsigned i=0,size=circle->nLinks();i<size;++i){
1521 if((circle->links()[i])->wire()->axial())++nAhits;
1522 else ++nShits;
1523 }
1524#if DEBUG_CURL_DUMP
1525 if(nAhits < nMA){
1526 std::cout << "(TCurlFinder) 2D:Fail...checking axial wires # = "
1527 << nAhits << " < " << nMA << std::endl;
1528 }
1529#endif
1530 if(nAhits >= nMA)return true;
1531 return false;
1532}
1533
1534bool
1535TCurlFinder::check3DTrack(TTrack *track) {
1536 trace3DTrack(track);
1537 unsigned nA = 0, nS = 0;
1538 for(unsigned i=0,size=track->nLinks();i<size;++i){
1539 if(!(track->links()[i]->hit()->state() & WireHitFittingValid))continue;
1540 if(track->links()[i]->wire()->stereo())++nS;
1541 else ++nA;
1542 if(nA >= 3 && nS >= 2)return true;
1543 }
1544 m_tracks.remove(track);
1545#if DEBUG_CURL_DUMP
1546 std::cout << "(TCurlFinder) 3D:Checked...Fail...removing this track. Valid Axial # = "
1547 << nA << ", Stereo # = " << nS << std::endl;
1548#endif
1549 return false;
1550}
1551
1552int
1553TCurlFinder::trace3DTrack(TTrack *track) {
1554 // 0 is bad, 1 is good
1555 unsigned nSize = track->links().length();
1556 if(nSize == 0){
1557 m_tracks.remove(track);
1558 return 0;
1559 }
1560 double r = fabs(track->helix().radius());
1561 if(r < 0.01){
1562 m_tracks.remove(track);
1563 return 0; // to reject "r=0cm" circles.
1564 }
1565 double cx = track->helix().center().x();
1566 double cy = track->helix().center().y();
1567 double th = atan2(-cy,-cx);
1568 if(th < 0.)th += 2.*M_PI;
1569
1570 double *angle = new double [track->links().length()];
1571 for(unsigned i=0,size=nSize;i<size;++i){
1572 double th_r = atan2(track->links()[i]->positionOnTrack().y()-cy,
1573 track->links()[i]->positionOnTrack().x()-cx);
1574 if(th_r < 0.)th_r += 2.*M_PI;
1575 double diff = th_r-th+2.*M_PI;
1576 if(th_r > th)diff = th_r-th;
1577 angle[i] = diff;
1578 }
1579 qsort(angle,nSize,sizeof(double),TCurlFinder_doubleCompare);//chiisai-jun
1580 double maxDiffAngle = 0.;
1581 unsigned maxIndex = 0;
1582 for(unsigned i=0,size=nSize;i<size-1;++i){
1583 if(angle[i+1]-angle[i] > maxDiffAngle){
1584 maxDiffAngle = angle[i+1]-angle[i];
1585 maxIndex = i;
1586 }
1587 }
1588 delete [] angle;
1589 /* std::cout << "3D TRACE : maxDifAngle = " << maxDiffAngle
1590 << ", r = " << r << ", dist = " << r*maxDiffAngle << std::endl; */
1591 if(r*maxDiffAngle > m_param.TRACE3D_DISTANCE){
1592 m_tracks.remove(track);
1593 return 0;
1594 }else{
1595 return 1;
1596 }
1597}
1598
1599void
1600TCurlFinder::mask3DTrack(TTrack *track,
1601 AList<TMLink> &maskList) {
1602 double r(fabs(track->helix().radius()));
1603 double cx(track->helix().center().x());
1604 double cy(track->helix().center().y());
1605
1606 AList<TMLink> list(m_unusedAxialHits);
1607 list.append(m_unusedStereoHits);
1608 list.remove(track->links());
1609 list.sort(SortByWireId);
1610
1611 AList<TMLink> removeList;
1612 for(unsigned i=0,size=list.length();i<size;++i){
1613 double d = distance(*track, *(list[i]));
1614 if(d < m_param.MASK_DISTANCE){
1615 HepPoint3D tmp(d, 0., 0.);
1616 list[i]->position(tmp);
1617 removeList.append(list[i]);
1618 }
1619 }
1620
1621 int pLayerId1 = static_cast<int>(layerId(2.*r));
1622 if(pLayerId1 != 50)pLayerId1 -= 1;//hard coding parameter
1623 int pLayerId2 = pLayerId1+2; //hard coding parameter
1624
1625 AList<TMLink> preCand, cand;
1626 while(removeList.length()){
1627 preCand.removeAll();
1628 preCand.append(removeList[0]);
1629 if(removeList.length() >= 2){
1630 for(unsigned j=1,size=removeList.length();j<size;++j){
1631 if(removeList[0]->wire()->layerId() == removeList[j]->wire()->layerId()){
1632 for(unsigned k=0,num=preCand.length();k<num;++k){
1633 if(preCand[k]->wire()->localIdForPlus()+1 == removeList[j]->wire()->localId()){
1634 preCand.append(removeList[j]);
1635 break;
1636 }
1637 }
1638 }
1639 }
1640#if 1
1641 // new
1642 if(preCand[0]->wire()->layerId() >= pLayerId1 &&
1643 preCand[0]->wire()->layerId() <= pLayerId2){
1644 cand.append(preCand);
1645 }else if(preCand.length() == 2){//hard coding parameter
1646 cand.append(preCand);
1647 }else if(preCand.length() == 1){
1648 cand.append(preCand[0]);
1649 }
1650#else
1651 if(preCand.length() == 1){
1652 if(preCand[0]->position().x() < MASK_DISTANCE)cand.append(preCand[0]);
1653 }else{
1654 if(preCand[0]->wire()->layerId() >= pLayerId1 &&
1655 preCand[0]->wire()->layerId() <= pLayerId2){
1656 cand.append(preCand);
1657 }else if(preCand.length() == 2){//hard coding parameter
1658 cand.append(preCand);
1659 }
1660 }
1661#endif
1662 }else{
1663 cand.append(removeList[0]);
1664 }
1665 removeList.remove(removeList[0]);
1666 removeList.remove(cand);
1667 }
1668 maskList.append(cand);
1669}
1670
1671TTrack*
1672TCurlFinder::merge3DTrack(TTrack *track, AList<TTrack> &confTracks) {
1673 if(!m_param.MERGE_EXE)return track;
1674
1675 AList<TTrack> tracks(confTracks);
1676 tracks.append(m_tracks);
1677 tracks.remove(track);
1678 if(tracks.length() == 0)return track;
1679
1680 double r = track->helix().radius();
1681 double cx = track->helix().center().x();
1682 double cy = track->helix().center().y();
1683
1684 unsigned bestIndex = 0;
1685 double bestDiff = 1.0e+20;
1686 double R, cX, cY;
1687 for(unsigned i=0,size=tracks.length();i<size;++i){
1688 R = fabs(tracks[i]->helix().radius());
1689 cX = tracks[i]->helix().center().x();
1690 cY = tracks[i]->helix().center().y();
1691 if(fabs(r)*(1.-m_param.MERGE_RATIO) <= R && R <= fabs(r)*(1.+m_param.MERGE_RATIO)){
1692 if(fabs(cx-cX) <= fabs(r)*m_param.MERGE_RATIO && fabs(cy-cY) <= fabs(r)*m_param.MERGE_RATIO){
1693 double diff = fabs((fabs(r)-fabs(R))*(cx-cX)*(cy-cY));
1694 if(diff < bestDiff){
1695 bestDiff = diff;
1696 bestIndex = i;
1697 }
1698 }
1699 }
1700 }
1701 if(bestDiff == 1.0e20)return track;
1702 R = tracks[bestIndex]->helix().radius();
1703 cX = tracks[bestIndex]->helix().center().x();
1704 cY = tracks[bestIndex]->helix().center().y();
1705 if(r*R >= 0.){
1706 if(fabs(track->helix().dz()-tracks[bestIndex]->helix().dz()) < m_param.MERGE_Z_DIFF){
1707 if(track->nLinks() > tracks[bestIndex]->nLinks()){
1708 m_tracks.remove(tracks[bestIndex]);
1709 return track;
1710 }else{
1711 m_tracks.remove(track);
1712#if DEBUG_CURL_DUMP
1713 std::cout << "(TCurlFinder) 3D:Merged...removing this track.(type1)" << std::endl;
1714#endif
1715 return NULL;
1716 }
1717 }
1718 }else{
1719 bool newTrack(false), oldTrack(false);
1720 unsigned newCounter(0), oldCounter(0);
1721 for(unsigned i=0, size=m_hitsOnInnerSuperLayer.length();
1722 i<size;++i){
1723 if(!oldTrack){
1724 if((R > 0. &&
1725 cX*(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().y()-cY)-
1726 cY*(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().x()-cX) > 0.) ||
1727 (R < 0. &&
1728 cX*(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().y()-cY)-
1729 cY*(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().x()-cX) < 0.)){
1730 double dist = distance(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().x()-cX,
1731 m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().y()-cY);
1732 if(dist < fabs(R)){
1733 if(fabs(fabs(R)-dist-m_hitsOnInnerSuperLayer[i]->drift()) < 0.5){
1734 ++oldCounter;
1735 if(oldCounter >= 3)oldTrack = true;
1736 }
1737 }else{
1738 if(fabs(dist-fabs(R)-m_hitsOnInnerSuperLayer[i]->drift()) < 0.5){
1739 ++oldCounter;
1740 if(oldCounter >= 3)oldTrack = true;
1741 }
1742 }
1743 }
1744 }
1745 if(!newTrack){
1746 if((r > 0. &&
1747 cx*(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().y()-cy)-
1748 cy*(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().x()-cx) > 0.) ||
1749 (r < 0. &&
1750 cx*(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().y()-cy)-
1751 cy*(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().x()-cx) < 0.)){
1752 double dist = distance(m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().x()-cx,
1753 m_hitsOnInnerSuperLayer[i]->wire()->xyPosition().y()-cy);
1754 if(dist < fabs(r)){
1755 if(fabs(fabs(r)-dist-m_hitsOnInnerSuperLayer[i]->drift()) < 0.5){
1756 ++newCounter;
1757 if(newCounter >= 3)newTrack = true;
1758 }
1759 }else{
1760 if(fabs(dist-fabs(r)-m_hitsOnInnerSuperLayer[i]->drift()) < 0.5){
1761 ++newCounter;
1762 if(newCounter >= 3)newTrack = true;
1763 }
1764 }
1765 }
1766 }
1767 if(oldTrack && newTrack)break;
1768 }
1769 if(oldTrack && !newTrack){
1770 m_tracks.remove(track);
1771#if DEBUG_CURL_DUMP
1772 std::cout << "(TCurlFinder) 3D:Merged...removing this track.(type2)" << std::endl;
1773#endif
1774 return NULL;
1775 }else if(!oldTrack && newTrack){
1776 m_tracks.remove(tracks[bestIndex]);
1777 return track;
1778 }else if(!oldTrack && !newTrack){
1779 m_tracks.remove(track);
1780 m_tracks.remove(tracks[bestIndex]);
1781#if DEBUG_CURL_DUMP
1782 std::cout << "(TCurlFinder) 3D:Merged...removing this track.(type3)" << std::endl;
1783#endif
1784 return NULL;
1785 }else if(oldTrack && newTrack){
1786 if(fabs(track->helix().dz()) > fabs(tracks[bestIndex]->helix().dz()) &&
1787 fabs(track->helix().dz()) > fabs(tracks[bestIndex]->helix().dz())+m_param.MERGE_Z_DIFF){
1788 m_tracks.remove(track);
1789#if DEBUG_CURL_DUMP
1790 std::cout << "(TCurlFinder) 3D:Merged...removing this track.(type4)" << std::endl;
1791#endif
1792 return NULL;
1793 }else if(fabs(tracks[bestIndex]->helix().dz()) > fabs(track->helix().dz()) &&
1794 fabs(tracks[bestIndex]->helix().dz()) > fabs(track->helix().dz())+m_param.MERGE_Z_DIFF){
1795 m_tracks.remove(tracks[bestIndex]);
1796 return track;
1797 }
1798 }
1799 }
1800 return track;
1801}
1802
1803void
1804TCurlFinder::salvage3DTrack(TTrack *track, bool half) {
1805 if(track->nLinks() >= m_param.MIN_SALVAGE){
1806 AList<TMLink> list = m_unusedAxialHits;
1807 list.append(m_unusedStereoHits);
1808 list.remove(track->links());
1809
1810 if(half){
1811 double q = track->charge();
1812 double x = track->helix().center().x();
1813 double y = track->helix().center().y();
1814 AList<TMLink> removeList;
1815 const double Bz = -1000*m_pmgnIMF->getReferField();
1816 for(unsigned i = 0, size = list.length(); i < size; ++i){
1817 if(q*Bz*(x*list[i]->wire()->xyPosition().y()-y*list[i]->wire()->xyPosition().x())<0.){
1818 //if(q*(x*list[i]->wire()->xyPosition().y()-y*list[i]->wire()->xyPosition().x())<0.)
1819#ifdef TRKRECO_DEBUG_DETAIL
1820 std::cout<<" "<<__FILE__<<" "<<__LINE__<<" removeList append "<<i<<std::endl;
1821#endif
1822 removeList.append(list[i]);
1823 }
1824 }
1825 list.remove(removeList);
1826 }
1827
1828 AList<TMLink> badCand, goodCand;
1829 double dist;
1830 for(unsigned j=0, nLinks=track->nLinks();j<nLinks;++j){
1831 dist = distance(*track, *(track->links()[j]));
1832#ifdef TRKRECO_DEBUG_DETAIL
1833 std::cout<<" "<<__FILE__<<" "<<__LINE__<<" "<<j<<" distance "<<dist<<std::endl;
1834#endif
1835 if(dist > m_param.BAD_DISTANCE_FOR_SALVAGE)badCand.append(track->links()[j]);
1836 }
1837 for(unsigned j=0, nList=list.length();j<nList;++j){
1838 dist = distance(*track, *(list[j]));
1839#ifdef TRKRECO_DEBUG_DETAIL
1840 std::cout<<" "<<__FILE__<<" "<<__LINE__<<" "<<j<<" distance "<<dist<<std::endl;
1841#endif
1842 if(dist < m_param.GOOD_DISTANCE_FOR_SALVAGE)goodCand.append(list[j]);
1843 }
1844 track->TTrackBase::remove(badCand);
1845 track->TTrackBase::append(goodCand);
1846 if(m_fitter.fit(*track) < 0){
1847 track->TTrackBase::remove(goodCand);
1848 track->TTrackBase::append(badCand);
1849 m_fitter.fit(*track);
1850 }
1851 }
1852 return;
1853}
1854
1855double
1856TCurlFinder::distance(const TTrack &track, const TMLink &link) const {
1857// if(link.wire()->axial()){ Liuqg 060926
1858 if((link.wire()->superLayerId() > 1 && link.wire()->superLayerId() <5) || link.wire()->superLayerId() >8 ){
1859 //...axial
1860 double d = distance(track.helix().center().x()-link.xyPosition().x(),
1861 track.helix().center().y()-link.xyPosition().y());
1862 double diff = fabs(d - fabs(track.helix().radius()));
1863 return fabs(link.hit()->drift()-diff);
1864 }
1865 //...stereo
1866 HepPoint3D xc(track.helix().center());
1867 HepPoint3D xw(link.xyPosition());
1868 HepPoint3D xt(track.helix().x());
1869 HepVector3D v0(xt-xc), v1(xw-xc);
1870 double vCrs(v0.x() * v1.y() - v0.y() * v1.x());
1871 double vDot(v0.x() * v1.x() + v0.y() * v1.y());
1872 double dPhi = atan2(vCrs, vDot);
1873 Vector a(track.helix().a());
1874 double kappa = a[2];
1875 double phi0 = a[1];
1876
1877 const double Bz = -1000*m_pmgnIMF->getReferField();
1878 //yzhang 2012-05-03
1879 double rho = m_param.ALPHA_SAME_WITH_HELIX/kappa/Bz;
1880 double tanLambda = a[4];
1881 HepVector3D v = link.wire()->direction();
1882 Vector c(3);
1883 c = HepPoint3D(link.wire()->backwardPosition()-(v*link.wire()->backwardPosition())*v);
1884
1885 HepDiagMatrix e(3,1);
1886 Matrix t(3, 3);
1887 t[0][0] = v.x() * v.x();
1888 t[0][1] = v.x() * v.y();
1889 t[0][2] = v.x() * v.z();
1890 t[1][0] = t[0][1];
1891 t[1][1] = v.y() * v.y();
1892 t[1][2] = v.y() * v.z();
1893 t[2][0] = t[0][2];
1894 t[2][1] = t[1][2];
1895 t[2][2] = v.z() * v.z();
1896 t -= e;
1897
1898 double factor = 1.;
1899 unsigned nTrial = 0;
1900
1901 //...Cal. closest point(Newton method)...
1902 Vector x(3);
1903 Vector dXdPhi(3);
1904 Vector d2Xd2Phi(3);
1905 double fOld = 0.; // The initialization is not needed.
1906 const double convergence = 1.0e-5;
1907 while(nTrial < 100){
1908 x = track.helix().x(dPhi);
1909 double cosPhi = cos(phi0+dPhi);
1910 double sinPhi = sin(phi0+dPhi);
1911 dXdPhi[0] = rho*sinPhi;
1912 dXdPhi[1] = - rho*cosPhi;
1913 dXdPhi[2] = - rho*tanLambda;
1914
1915 //...f = d(Distance) / d phi...
1916 double f = dot(c,dXdPhi)+dot(x,(t*dXdPhi));
1917
1918 if(fabs(f) < convergence)break;
1919 if(nTrial > 0){
1920 double eval = (1.-0.25*factor)*fabs(fOld)-fabs(f);
1921 if(eval <= 0.)factor *= 0.5;
1922 }
1923 //...Cal. next phi...
1924 d2Xd2Phi[0] = rho*cosPhi;
1925 d2Xd2Phi[1] = rho*sinPhi;
1926 d2Xd2Phi[2] = 0.;
1927 double df = dot(c, d2Xd2Phi)+
1928 dot(dXdPhi, (t * dXdPhi))+
1929 dot(x, (t * d2Xd2Phi));
1930 dPhi -= factor * f / df;
1931
1932 fOld = f;
1933 ++nTrial;
1934 }
1935
1936 double beta = v*(track.helix().x(dPhi)-link.wire()->backwardPosition());
1937 return fabs((link.wire()->backwardPosition()+beta*v-track.helix().x(dPhi)).mag()-
1938 link.hit()->drift());
1939}
1940
1941//............................................
1942//.................2D Parts...................
1943//............................................
1944
1945TCircle *
1946TCurlFinder::make2DTrack(const AList<TMLink> &seed,
1947 const AList<TSegmentCurl> &segmentList,
1948 const unsigned ip) {
1949 //jialk origin is 3
1950 if(seed.length() < m_param.minimum_seedLength)return NULL;
1951 TCircle *circle = new TCircle(seed);
1952 m_allCircles.append(circle);
1953 int errorFlag = circle->fitForCurl(ip);
1954 //jialk add a limitation of ULTIMATE_MIN_RADIUS_OF_STRANGE_TRACK
1955 //if(fabs(circle->radius()) > m_param.MIN_RADIUS_OF_STRANGE_TRACK)return NULL;
1956 if( (fabs(circle->radius()) > m_param.MIN_RADIUS_OF_STRANGE_TRACK) || (fabs(circle->radius()) < m_param.ULTIMATE_MIN_RADIUS_OF_STRANGE_TRACK) )return NULL;
1957 int searchDirection = 1;//[ 1 : inner ], [ -1 : outer ]
1958 int searchPath(searchDirection);
1959 bool searchZero(false);
1960 bool changeDirection(false);
1961 unsigned superLayerId = seed[0]->hit()->wire()->superLayerId();
1962
1963 AList<TMLink> cand, tmpList;
1964 AList<TMLink> preAxialCand, preStereoCand;
1965 makeList(tmpList, segmentList, seed);
1966 for(unsigned i=0, size=tmpList.length();i<size;++i){
1967 if(tmpList[i]->wire()){
1968 if(tmpList[i]->wire()->axial()) preAxialCand.append(tmpList[i]);
1969 else preStereoCand.append(tmpList[i]);
1970 }
1971 }
1972#if DEBUG_CURL_DUMP
1973 std::cout << "(TCurlFinder) 2D: Superlayer of seed = " << superLayerId << std::endl;
1974#endif
1975
1976 bool appendFlag = false;
1977nextStep:
1978#if DEBUG_CURL_DUMP
1979 std::cout << "(TCurlFinder) 2D: SearchPath = " << searchPath
1980 << " Search SelfSuperlayer = " << (int)(searchZero)
1981 << " Change Direction of Search = " << (int)(changeDirection) << std::endl;
1982#endif
1983 if(preAxialCand.length() == 0 && preStereoCand.length() == 0){
1984 if(circle->links().length() >= 3){
1985 if(m_unusedAxialHits.length() == 0)
1986 if(errorFlag == -1)return NULL;
1987 else return circle;
1988 else goto salvage;
1989 }else{
1990 if(m_unusedAxialHits.length() == 0)return NULL;
1991 else goto salvage;
1992 }
1993 }
1994 searchAxialCand(cand, preAxialCand, circle,
1995 searchPath, superLayerId, m_param.RANGE_FOR_AXIAL_SEARCH);
1996 if(cand.length() > 0){
1997 appendFlag = true;
1998 for(unsigned i = 0, size = cand.length(); i < size; ++i)circle->append(*cand[i]);
1999 errorFlag = circle->fitForCurl(ip);
2000 preAxialCand.remove(circle->links());
2001 if(m_param.STEREO_2DFIND){
2002 searchStereoCand(cand, preStereoCand, circle,
2003 searchPath, superLayerId, m_param.RANGE_FOR_STEREO_SEARCH);
2004 if(cand.length() > 0){
2005 appendFlag = true;
2006 for(unsigned i = 0, size = cand.length(); i < size; ++i)circle->append(*cand[i]);
2007 errorFlag = circle->fitForCurl(ip);
2008 preStereoCand.remove(circle->links());
2009 }
2010 }
2011 if(searchDirection == 1)++searchPath;
2012 else --searchPath;
2013 goto nextStep;
2014 }else{
2015 if(m_param.STEREO_2DFIND){
2016 searchStereoCand(cand, preStereoCand, circle,
2017 searchPath, superLayerId, m_param.RANGE_FOR_STEREO_SEARCH);
2018 if(cand.length() > 0){
2019 appendFlag = true;
2020 for(unsigned i = 0, size = cand.length(); i < size; ++i)circle->append(*cand[i]);
2021 errorFlag = circle->fitForCurl(ip);
2022 preStereoCand.remove(circle->links());
2023 if(searchDirection == 1)++searchPath;
2024 else --searchPath;
2025 goto nextStep;
2026 }else if((searchPath == 1 || searchPath == -1) && !searchZero){
2027 searchPath = 0;
2028 searchZero = true;
2029 goto nextStep;
2030 }else if((searchPath == 1 || searchPath == -1) && searchZero && !changeDirection){
2031 searchPath *= -1;
2032 searchDirection *= -1;
2033 changeDirection = true;
2034 goto nextStep;
2035 }else{
2036 if(circle->links().length() >= 3){
2037 if(m_unusedAxialHits.length() == 0)
2038 if(errorFlag == -1)return NULL;
2039 else return circle;
2040 else goto salvage;
2041 }else{
2042 if(m_unusedAxialHits.length() == 0)return NULL;
2043 else goto salvage;
2044 }
2045 }
2046 }else{
2047 if((searchPath == 1 || searchPath == -1) && !searchZero){
2048 searchPath = 0;
2049 searchZero = true;
2050 goto nextStep;
2051 }else if((searchPath == 1 || searchPath == -1) && searchZero && !changeDirection){
2052 searchPath *= -1;
2053 searchDirection *= -1;
2054 changeDirection = true;
2055 goto nextStep;
2056 }else{
2057 if(circle->links().length() >= 3){
2058 if(m_unusedAxialHits.length() == 0)
2059 if(errorFlag == -1)return NULL;
2060 else return circle;
2061 else goto salvage;
2062 }else{
2063 if(m_unusedAxialHits.length() == 0)return NULL;
2064 else goto salvage;
2065 }
2066 }
2067 }
2068 }
2069
2070salvage:
2071 cand.removeAll();
2072 searchHits(cand, m_unusedAxialHits, circle, m_param.RANGE_FOR_AXIAL_LAST2D_SEARCH);
2073 if(m_param.STEREO_2DFIND){
2074 searchHits(cand, m_unusedStereoHits, circle, m_param.RANGE_FOR_STEREO_LAST2D_SEARCH);
2075 }
2076 if(checkAppendHits(circle->links(), cand)){
2077 circle->append(cand);
2078 if(circle->nLinks() >= 3)
2079 if(circle->fitForCurl(ip) == -1)return NULL;
2080 else return circle;
2081 else return NULL;
2082 }else if(circle->nLinks() >= 3){
2083 return circle;
2084 }else return NULL;
2085}
2086
2087TMLink *
2089
2090void
2091TCurlFinder::searchAxialCand(AList<TMLink> &cand,
2092 const AList<TMLink> &preCand,
2093 const TCircle *circle,
2094 const int depth,
2095 const unsigned superLayerID,
2096 const double searchError) {
2097 cand.removeAll();
2098 int innerSuperLayerId = nextSuperAxialLayerId(superLayerID, depth);
2099 if(innerSuperLayerId < 0)return;
2100 for(unsigned i = 0, size = preCand.length(); i < size; ++i){
2101 if(preCand[i]->hit()->wire()->superLayerId() ==
2102 (static_cast<unsigned>(innerSuperLayerId))){
2103#if 0
2104 if(searchHits(preCand[i], circle, searchError))cand.append(preCand[i]);
2105#else
2106 if(searchHits(preCand[i], circle, searchError)){
2107 cand.remove(preCand[i]);
2108 cand.append(preCand[i]);
2109 TMLink * cand2 = findIsolatedCloseHits(preCand[i]);
2110 if(cand2){
2111 for(unsigned j = 0; j < size; ++j){
2112 if(preCand[j]->wire()->id() == cand2->wire()->id()){
2113 cand.remove(cand2);
2114 cand.append(cand2);
2115#if 0
2116 std::cout << "Axial Appending....";
2117 std::cout << " layerID = " << cand2->wire()->layerId();
2118 std::cout << " localID = " << cand2->wire()->localId() << std::endl;
2119 if(searchHits(cand2, circle, searchError)){
2120 std::cout << " But this can be added by default!" << std::endl;
2121 }else{
2122 std::cout << " Good!! this cannot be added by default!" << std::endl;
2123 }
2124#endif
2125 break;
2126 }
2127 }
2128 }
2129 }
2130#endif
2131 }
2132 }
2133}
2134
2135void
2136TCurlFinder::searchStereoCand(AList<TMLink> &cand,
2137 const AList<TMLink> &preCand,
2138 const TCircle *circle,
2139 const int depth,
2140 const unsigned superLayerID,
2141 const double searchError) {
2142 cand.removeAll();
2143 int innerSuperLayerId = nextSuperStereoLayerId(superLayerID, depth);
2144 if(innerSuperLayerId < 0 || innerSuperLayerId > m_param.SUPERLAYER_FOR_STEREO_SEARCH)return;
2145 for(unsigned i = 0, size = preCand.length(); i < size; ++i){
2146 if(preCand[i]->hit()->wire()->superLayerId() ==
2147 (static_cast<unsigned>(innerSuperLayerId))){
2148 if(searchHits(preCand[i], circle, searchError))cand.append(preCand[i]);
2149 }
2150 }
2151}
2152
2153unsigned
2154TCurlFinder::searchHits(const TMLink *link, const TCircle *circle,
2155 const double searchError) const {
2156 // ...checks whether "link" can be added to circle.
2157 // ..."searchError" is length for checking.
2158 // ...returns 0 = error
2159 // 1 = no error
2160 double dist = distance(link->hit()->wire()->xyPosition().x() - circle->center().x(),
2161 link->hit()->wire()->xyPosition().y() - circle->center().y());
2162 double radius = fabs(circle->radius());
2163 //std::cout << link->wire()->localId() << " " << link->wire()->layerId() << " r="
2164 // << radius << " e=" << searchError << " d=" << dist << std::endl;
2165 if(radius - searchError < dist &&
2166 radius + searchError > dist)return 1;
2167 return 0;
2168}
2169
2170unsigned
2171TCurlFinder::searchHits(AList<TMLink> &cand,
2172 const AList<TMLink> &preCand,
2173 const TCircle *circle,
2174 const double searchError) const {
2175 unsigned numBefore = cand.length();
2176 for(unsigned i = 0, size = preCand.length(); i < size; ++i){
2177 if(searchHits(preCand[i], circle, searchError)){
2178#if 0
2179 cand.append(preCand[i]);
2180#else
2181 cand.remove(preCand[i]);
2182 cand.append(preCand[i]);
2183 TMLink * cand2 = findIsolatedCloseHits(preCand[i]);
2184 if(cand2){
2185 for(unsigned j = 0; j < size; ++j){
2186 if(preCand[j]->wire()->id() == cand2->wire()->id()){
2187 cand.remove(cand2);
2188 cand.append(cand2);
2189 break;
2190 }
2191 }
2192 }
2193#endif
2194 }
2195 }
2196 if(numBefore == cand.length())return 0;
2197 return 1;
2198}
2199
2200unsigned
2201TCurlFinder::checkAppendHits(const AList<TMLink> &link,
2202 AList<TMLink> &cand) const {
2203 if(cand.length() == 0)return 0;
2204 AList<TMLink> tmp;
2205 for(unsigned i = 0, size1 = cand.length(), size2 = link.length(); i < size1; ++i){
2206 for(unsigned j = 0; j < size2; ++j){
2207 if((cand[i])->wire()->id() == (link[j])->wire()->id()){
2208 tmp.append(cand[i]);
2209 break;
2210 }
2211 }
2212 }
2213 cand.remove(tmp);
2214 if(cand.length() > 0)return 1;
2215 return 0;
2216}
2217
2218void
2219TCurlFinder::removeStereo(TCircle &c) const
2220{
2221 AList<TMLink> stereoList;
2222 for(int i=0;i<c.links().length();++i){
2223 if(c.links()[i]->wire()->stereo()){
2224 stereoList.append(c.links()[i]);
2225 }
2226 }
2227 if(stereoList.length()>0)c.remove(stereoList);
2228}
2229
2230bool
2231TCurlFinder::fitWDD(TCircle &c,
2232 double &chi2,
2233 int &ndf) const
2234{
2235 if(c.links().length() <= 3)return false;
2236 Lpav circle;
2237 // MDC
2238 for(int i=0;i<c.links().length();++i){
2239 circle.add_point((c.links()[i])->wire()->xyPosition().x(),
2240 (c.links()[i])->wire()->xyPosition().y(),1.0);
2241 }
2242 circle.add_point(0.,0.,1.0); // IP Constraint
2243 if (circle.fit() < 0.0 || circle.kappa() == 0.0) return false;
2244 double xc = circle.center()[0];
2245 double yc = circle.center()[1];
2246 double r = circle.radius();
2247 const int maxIte = 2;
2248 for(int ite=0;ite<maxIte;++ite){
2249 Lpav circle2;
2250 circle2.clear();
2251 // MDC
2252 for(int i=0;i<c.links().length();++i){
2253 if(!((c.links()[i])->hit()->state() & WireHitFittingValid))continue;
2254 double R = sqrt(((c.links()[i])->wire()->xyPosition().x()-xc)*((c.links()[i])->wire()->xyPosition().x()-xc)+
2255 ((c.links()[i])->wire()->xyPosition().y()-yc)*((c.links()[i])->wire()->xyPosition().y()-yc));
2256 if(R == 0.)continue;
2257 double U = 1./R;
2258 double dir = R > r ? -1. : 1.;
2259 double X = xc+((c.links()[i])->wire()->xyPosition().x()-xc)*U*(R+dir*(c.links()[i])->hit()->drift());
2260 double Y = yc+((c.links()[i])->wire()->xyPosition().y()-yc)*U*(R+dir*(c.links()[i])->hit()->drift());
2261 circle2.add_point(X,Y,1.0);
2262 }
2263 circle2.add_point(0.,0.,1.0); // IP Constraint
2264 if (circle2.fit() < 0.0 || circle2.kappa() == 0.0) return false;
2265 xc = circle2.center()[0];
2266 yc = circle2.center()[1];
2267 r = circle2.radius();
2268 //cout << xc << ", " << yc << " : " << r << endl;
2269 }
2270
2271 // update of point information
2272 double totalChi2 = 0.;
2273 int totalNHit = 0;
2274 for(int i=0;i<c.links().length();++i){
2275 if(!((c.links()[i])->hit()->state() & WireHitFittingValid))continue;
2276 double xw = (c.links()[i])->wire()->xyPosition().x();
2277 double yw = (c.links()[i])->wire()->xyPosition().y();
2278 double R = sqrt((xw-xc)*(xw-xc)+(yw-yc)*(yw-yc));
2279 if(R == 0.)continue;
2280 double U = 1./R;
2281 double X = xc+(xw-xc)*U*r;
2282 double Y = yc+(yw-yc)*U*r;
2283 double zlr = xw*Y-yw*X;
2284 unsigned leftRight = zlr > 0. ? WireHitRight : WireHitLeft;
2285 double pChi2 = sqrt((X-xw)*(X-xw)+(Y-yw)*(Y-yw))-(c.links()[i])->hit()->drift();
2286 //cout << sqrt((X-xw)*(X-xw)+(Y-yw)*(Y-yw)) << " - " << (c.links()[i])->hit()->drift() << endl;
2287 //cout << i << ": " << pChi2 << endl;
2288 if((c.links()[i])->hit()->dDrift() != 0.){
2289 pChi2 *= pChi2/((c.links()[i])->hit()->dDrift()*(c.links()[i])->hit()->dDrift());
2290 totalChi2 += pChi2;
2291 //cout << pChi2 << ", " << c.links()[i]->hit()->dDrift() << endl;
2292 ++totalNHit;
2293 }else pChi2 = 1.0e+10;
2294 (c.links()[i])->update(HepPoint3D(X,Y,0.),HepPoint3D(xw,yw,0.),leftRight,pChi2);
2295 //cout << i << ": trk(" << X << "," << Y << "), wir(" << xw << "," << yw << ")" << endl;
2296 }
2297 chi2 = totalChi2;
2298 if(totalNHit <= 3)return false;
2299 ndf = totalNHit-3;
2300
2301 HepPoint3D center(xc,yc,0.);
2302 double charge = 0.;
2303 //...Determine charge...Better way???
2304 int qSum = 0;
2305 for(int i=0;i<c.links().length();++i){
2306 TMLink * l = c.links()[i];
2307 if(l == 0)continue;
2308 const TMDCWireHit * h = l->hit();
2309 if(h == 0)continue;
2310 double q = (center.cross(h->xyPosition())).z();
2311 if(q > 0.)qSum += 1;
2312 else qSum -= 1;
2313 }
2314 if(qSum >= 0)charge = +1.;
2315 else charge = -1.;
2316 r *= charge;
2317 //cout << "B q = " << c.charge() << ", r = " << c.radius() << ", center = " << c.center() << endl;
2318 c.property(charge,r,center);
2319 //cout << "A q = " << c.charge() << ", r = " << c.radius() << ", center = " << c.center() << endl;
2320 return true;
2321}
2322
2323//............................................
2324//.................3D Parts...................
2325//............................................
2326
2327TTrack *
2328TCurlFinder::make3DTrack(const TCircle *circle, AList<TSegmentCurl> &segmentList) {
2329 unsigned size = segmentList.length();
2330 if(TTrack *track = make3DTrack(circle)){
2331 m_tracks.append(track);
2332#if 0
2333 std::cout << "MDC Helix+Pt: " << track->helix().dr() << ", "
2334 << track->helix().phi0() << ", "
2335 << track->helix().kappa() << ", "
2336 << track->helix().dz() << ", "
2337 << track->helix().tanl()
2338 << ": " << 10000./2.9979258/15./track->helix().kappa() << std::endl;
2339#endif
2340 return track;
2341 }
2342 return NULL;
2343}
2344
2345TTrack *
2346TCurlFinder::make3DTrack(const TCircle *circle) {
2347 TTrack *track = new TTrack(*circle);
2348 m_allTracks.append(track);
2349 //cout<<"2D: nAHits: "<<track->links().length()<<endl;
2350 //jialk caution origin is 3
2351 if(track->links().length() < m_param.minimum_2DTrackLength){
2352#if DEBUG_CURL_DUMP
2353 std::cout << "(TCurlFinder) 3D:Fail...inital hit wire # < 3." << std::endl;
2354#endif
2355 return NULL;
2356 }
2357 AList<TMLink> allStereoHits(m_unusedStereoHits);
2358 allStereoHits.remove(track->links());
2359 AList<TMLink> closeHits;
2360 findCloseHits(allStereoHits, *track, closeHits);
2361 //if(!m_builder.buildStereo(*track, closeHits)){
2362 //jialk inorder to improve track robustness
2363 if ( closeHits.length() < m_param.minimum_closeHitsLength ){
2364#if DEBUG_CURL_DUMP
2365 std::cout << "(TCurlFinder) 3D:Fail...stereohit wire # < 5." << std::endl;
2366#endif
2367 return NULL;
2368 }
2369 //if(!m_builder.buildStereo(*track, closeHits)){
2370 if(!m_builder.buildStereo(*track, closeHits, m_allStereoHitsOriginal)){
2371#if DEBUG_CURL_DUMP
2372 std::cout << "(TCurlFinder) 3D:Fail...can not build stereo." << std::endl;
2373#endif
2374 return NULL;
2375 }
2376 //jialk add a limitation ULTIMATE_MIN_RADIUS_OF_STRANGE_TRACK
2377 //if(fabs(track->helix().radius()) > m_param.MIN_RADIUS_OF_STRANGE_TRACK){
2378 if( (fabs(circle->radius()) > m_param.MIN_RADIUS_OF_STRANGE_TRACK) || (fabs(circle->radius()) < m_param.ULTIMATE_MIN_RADIUS_OF_STRANGE_TRACK) ){
2379#if DEBUG_CURL_DUMP
2380 std::cout << "(TCurlFinder) 3D:Fail...success 3D fit, but large radius > "
2381 << m_param.MIN_RADIUS_OF_STRANGE_TRACK << "." << std::endl;
2382#endif
2383 return NULL;
2384 }
2385 //jialk caution origin is 5
2386 if(track->links().length() >= m_param.minimum_3DTrackLength){
2387#if DEBUG_CURL_DUMP
2388 std::cout << "(TCurlFinder) 3D:Success...can build stereo!!!" << std::endl;
2389#endif
2390 return track;
2391 }else{
2392#if DEBUG_CURL_DUMP
2393 std::cout << "(TCurlFinder) 3D:Fail...success 3D fit, but final hit wire # < 3." << std::endl;
2394#endif
2395 return NULL;
2396 }
2397}
2398
2399TMLink *
2401{
2402 int nNeighbor = 0;
2403 int nIsolated = 0;
2404 TMLink * isolatedLink[2] = {NULL,NULL};
2405 unsigned layerID = link->wire()->layerId();
2406 unsigned localID = link->wire()->localId();
2407 for(int i=0;i<6;++i){
2408 if(link->neighbor(i)){
2409 if(link->neighbor(i)->wire()->layerId() == layerID){
2410 ++nNeighbor;
2411 int isolated = 1;
2412 int testEach = 0; // for test
2413 for(int j=0;j<6;++j){
2414 if(link->neighbor(i)->neighbor(j)){
2415 if(link->neighbor(i)->neighbor(j)->wire()->layerId() == layerID &&
2416 link->neighbor(i)->neighbor(j)->wire()->localId() != localID){
2417 isolated = 0;
2418 }
2419#if 1
2420 else if(link->neighbor(i)->neighbor(j)->wire()->layerId() == layerID &&
2421 link->neighbor(i)->neighbor(j)->wire()->localId() == localID){
2422 testEach = 1;
2423 }
2424#endif
2425 }else break;
2426 }
2427 if(isolated == 1){
2428 if(nIsolated < 2)
2429 isolatedLink[nIsolated] = link->neighbor(i);
2430 ++nIsolated;
2431 }
2432#if 1
2433 if(testEach == 0){
2434 std::cout << "Why?? Neighborhood info. dose not exist!!" << std::endl;
2435 }
2436#endif
2437 }
2438 }else break;
2439 }
2440#if 0
2441 std::cout << "isolated/neighbor # = " << nIsolated << "/" << nNeighbor << std::endl;
2442 std::cout << "layer ID = " << layerID << " ";
2443 std::cout << "local ID = " << localID << " --> ";
2444 if(isolatedLink[0])std::cout << isolatedLink[0]->wire()->localId() << " ";
2445 if(isolatedLink[1])std::cout << isolatedLink[1]->wire()->localId() << " ";
2446 std::cout << std::endl;
2447#endif
2448 if(nIsolated == 1 &&
2449 nNeighbor == 1 && isolatedLink[0])return isolatedLink[0];
2450 else return NULL;
2451}
2452
2453void
2454TCurlFinder::findCloseHits(AList<TMLink> &links,
2455 TTrack &track, AList<TMLink> &list) {
2456 // ...finds candidates in the "links".
2457 // ...Candidates mean |"track" - wire(from "links" elements)| < dRcut
2458 // ...returns these candidates("list").
2459 double dRcut[11] = {m_param.RANGE_FOR_STEREO_FIRST, m_param.RANGE_FOR_STEREO_SECOND,
2460 0., 0.,
2461 0., m_param.RANGE_FOR_STEREO_THIRD,
2463 m_param.RANGE_FOR_STEREO_SIXTH, 0.,
2464 0.};
2465 double r = fabs(track.helix().curv());
2466 double q = track.charge();
2467 double x = track.helix().center().x();
2468 double y = track.helix().center().y();
2469 for(unsigned i = 0, size = links.length(); i < size; ++i){
2470 if(fabs((links[i]->wire()->xyPosition() - track.helix().center()).mag() - r) <
2471 dRcut[links[i]->wire()->superLayerId()]){
2472 if(q*(x*links[i]->wire()->xyPosition().y()-y*links[i]->wire()->xyPosition().x()) > 0.){
2473 list.remove(links[i]);
2474 list.append(links[i]);
2475 TMLink *cand = findIsolatedCloseHits(links[i]);
2476 if(cand){
2477 list.remove(cand);
2478 list.append(cand);
2479 }
2480 }
2481 }
2482 }
2483 return;
2484}
2485
2486//..................................................
2487//..................................................
2488//..................................................
2489//..................................................
2490//..................................................
2491
2492int
2493TCurlFinder::makeWithMC(const AList<TMDCWireHit> & axialHits,
2494 const AList<TMDCWireHit> & stereoHits,
2495 AList<TTrack> & tracks) {
2496#if DEBUG_CURL_MC
2497#define MAX_INDEX_MAKEMC 100
2498#if DEBUG_CURL_DUMP
2499 std::cout << "(TCurlFinder)Now making tracks using MC info..." << std::endl;
2500#endif
2501 int index[MAX_INDEX_MAKEMC];
2502 for(unsigned i = 0; i < MAX_INDEX_MAKEMC; ++i)index[i] = 9999;
2503
2504 int counter(0);
2505 bool first(true);
2506
2507 for(unsigned i = 0, size = axialHits.length(); i < size; ++i){
2508 if(axialHits[i]->mc() &&
2509 axialHits[i]->mc()->hep() &&
2510 !(axialHits[i]->state() & WireHitUsed)){
2511 int flag(1);
2512 for(unsigned j = 0; j < MAX_INDEX_MAKEMC; ++j){
2513 if(index[j] != 9999 && index[j] == axialHits[i]->mc()->hep()->id()){
2514 flag = 0;
2515 break;
2516 }
2517 }
2518 if(flag){
2519 index[counter] = axialHits[i]->mc()->hep()->id();
2520 ++counter;
2521 }
2522 }
2523 }
2524#if DEBUG_CURL_DUMP
2525 std::cout << "(TCurlFinder)Found " << counter
2526 << " tracks with MC information." << std::endl;
2527#endif
2528 for(unsigned j = 0; j < counter; ++j){
2529 AList<TMLink> axialList;
2530 AList<TMLink> stereoList;
2531 int axialCounter(0);
2532 int stereoCounter(0);
2533 //...axial
2534 for(unsigned i = 0, size = axialHits.length(); i < size; ++i){
2535 if(index[j] == axialHits[i]->mc()->hep()->id() &&
2536 !(axialHits[i]->state() & WireHitUsed)){
2537 axialList.append(new TMLink(0, axialHits[i]));
2538 ++axialCounter;
2539 }
2540 }
2541 if(axialCounter < 3){
2542 HepAListDeleteAll(axialList);
2543 continue;
2544 }
2545 //...stereo
2546 for(unsigned i = 0, size = stereoHits.length(); i < size; ++i){
2547 if(index[j] == stereoHits[i]->mc()->hep()->id() &&
2548 !(stereoHits[i]->state() & WireHitUsed)){
2549 stereoList.append(new TMLink(0, stereoHits[i]));
2550 ++stereoCounter;
2551 }
2552 }
2553 if(stereoCounter < 2){
2554 HepAListDeleteAll(axialList);
2555 HepAListDeleteAll(stereoList);
2556 continue;
2557 }
2558#if DEBUG_CURL_DUMP
2559 std::cout << "(TCurlFinder)#" << j << " : Use "
2560 << axialCounter << " axial hit wires and "
2561 << stereoCounter << " stereo hit wires" << std::endl;
2562 std::cout << "(TCurlFinder)Particle Type(LUND) = "
2563 << axialList[0]->hit()->mc()->hep()->pType() << std::endl;
2564#endif
2565
2566 m_unusedAxialHitsOriginal.append(axialList);
2567 m_unusedAxialHitsOriginal.append(stereoList);
2568 TCircle *circle = new TCircle(axialList);
2569 m_allCircles.append(circle);
2570 circle->fitForCurl();
2571 double charge = 1.;
2572 if(axialList[0]->hit()->mc()->hep()->pType() < 0)charge = -1.;
2573 if(fabs(axialList[0]->hit()->mc()->hep()->pType()) == 11 ||
2574 fabs(axialList[0]->hit()->mc()->hep()->pType()) == 13 ||
2575 fabs(axialList[0]->hit()->mc()->hep()->pType()) == 15)charge *= -1.;
2576 circle->property(charge, charge*fabs(circle->radius()), circle->center());
2577
2578 AList<TMLink> removeList;
2579 double x = circle->center().x();
2580 double y = circle->center().y();
2581 //...axial
2582 for(unsigned i = 0, size = axialList.length();
2583 i < size; ++i){
2584 if(charge*(x*axialList[i]->xyPosition().y()-
2585 y*axialList[i]->xyPosition().x())< 0.){
2586 removeList.append(axialList[i]);
2587
2588 }
2589 }
2590 circle->remove(removeList);
2591 if(circle->nLinks() < 3)continue;
2592 //...refits
2593 circle->fitForCurl(1);
2594 x = circle->center().x();
2595 y = circle->center().y();
2596 removeList.removeAll();
2597 ///...stereo
2598 for(unsigned i = 0, size = stereoList.length();
2599 i < size; ++i){
2600 if(charge*(x*stereoList[i]->xyPosition().y()-
2601 y*stereoList[i]->xyPosition().x())< 0.){
2602 removeList.append(stereoList[i]);
2603 }
2604 }
2605 stereoList.remove(removeList);
2606 if(stereoList.length() < 2)continue;
2607
2608 TTrack *track = new TTrack(*circle);
2609 m_allTracks.append(track);
2610 if(m_builder.buildStereoMC(*track, stereoList)){
2611 if(track->links().length() >= 5){
2612 track->assign(WireHitCurlFinder, TrackCurlFinder | TrackValid | Track3D);
2613 tracks.append(track);
2614 m_allTracks.remove(track);
2615 }else{
2616 std::cout << "Can not reconstruct with MC information!" << std::endl;
2617 }
2618 }else{
2619 std::cout << "Can not reconstruct with MC information!" << std::endl;
2620 }
2621 }
2622#endif
2623 return 0;
2624}
2625
2626void
2627TCurlFinder::makeCdcFrame(void) {
2628#if DEBUG_CURL_GNUPLOT+DEBUG_CURL_SEGMENT
2629 //#if 1
2630 double X = 0.;
2631 double Y = 0.;
2632 double R[12] = {8.3, 16.9, 21.7, 31.3, 36.1, 44.1,
2633 50.5, 58.5, 64.9, 72.9, 79.3, 87.4};
2634 double step = 300.;
2635 double dStep = 2.*M_PI/step;
2636 FILE *data;
2637 std::string nameHead = "tmp.cdc_";
2638 for(int j=0;j<12;++j){
2639 std::string nameFile = nameHead+"0"+itostring(j);
2640 if(j>=10)nameFile = nameHead+itostring(j);
2641 if((data = fopen(nameFile,"w")) != NULL){
2642 for(int i=0;i<step;++i){
2643 double x = X + R[j] * cos(dStep*static_cast<double>(i));
2644 double y = Y + R[j] * sin(dStep*static_cast<double>(i));
2645 fprintf(data,"%lf, %lf\n",x,y);
2646 }
2647 fclose(data);
2648 }
2649 }
2650
2651 if((data = fopen("tmp_wires.dat","w")) != NULL){
2652 AList<TMLink> list = m_unusedAxialHitsOriginal;
2653 list.append(m_unusedStereoHitsOriginal);
2654 for(int i=0;i<list.length();i++){
2655 double x = list[i]->hit()->wire()->xyPosition().x();
2656 double y = list[i]->hit()->wire()->xyPosition().y();
2657 fprintf(data,"%lf, %lf\n",x,y);
2658 }
2659 fclose(data);
2660 }
2661#endif
2662 return;
2663}
2664
2665void
2666TCurlFinder::plotSegment(const AList<TMLink>& list, const int flag) {
2667#if DEBUG_CURL_GNUPLOT
2668 if(!m_debugCdcFrame){
2669 makeCdcFrame();
2670 m_debugCdcFrame = true;
2671 }
2672 double gmaxX = 90. ,gminX = -90.;
2673 double gmaxY = 90. ,gminY = -90.;
2674 FILE *gnuplot, *data;
2675 if((data = fopen("tmp.dat","w")) != NULL){
2676 if(flag)std::cout << "Wire ID = ";
2677 for(int i=0;i<list.length();i++){
2678 double x = list[i]->hit()->wire()->xyPosition().x();
2679 double y = list[i]->hit()->wire()->xyPosition().y();
2680 fprintf(data,"%lf, %lf\n",x,y);
2681 if(flag)std::cout << list[i]->hit()->wire()->id() << ", ";
2682 }
2683 if(flag)std::cout << std::endl;
2684 fclose(data);
2685 }
2686 if((gnuplot = popen("gnuplot","w")) != NULL){
2687 fprintf(gnuplot,"set nokey \n");
2688 fprintf(gnuplot,"set size 0.721,1.0 \n");
2689 fprintf(gnuplot,"set xrange [%f:%f] \n",gminX,gmaxX);
2690 fprintf(gnuplot,"set yrange [%f:%f] \n",gminY,gmaxY);
2691 std::string longName = "plot \"tmp_wires.dat\", \"tmp.dat\"";
2692 std::string nameHead = ",\"tmp.cdc_";
2693 for(int j=0;j<12;++j){
2694 std::string nameFile = nameHead+"0"+itostring(j)+"\"w l 0";
2695 if(j>=10)nameFile = nameHead+itostring(j)+"\"w l 0";
2696 longName += nameFile;
2697 }
2698 longName += " \n";
2699 fprintf(gnuplot,longName);
2700 fflush(gnuplot);
2701 char tmp[8];
2702 gets(tmp);
2703 pclose(gnuplot);
2704 }
2705#endif
2706 return;
2707}
2708
2709void
2710TCurlFinder::plotCircle(const TCircle& circle, const int flag) {
2711#if DEBUG_CURL_GNUPLOT
2712 //#if 1
2713 if(!m_debugCdcFrame){
2714 makeCdcFrame();
2715 m_debugCdcFrame = true;
2716 }
2717 double gmaxX = 90. ,gminX = -90.;
2718 double gmaxY = 90. ,gminY = -90.;
2719 FILE *gnuplot, *data;
2720 if((data = fopen("tmp.dat1","w")) != NULL){
2721 if(flag)std::cout << "Axial Wire ID ==> " << std::endl;
2722 for(int i=0;i<circle.nLinks();++i){
2723 if(circle.links()[i]->hit()->wire()->axial()){
2724 double x = circle.links()[i]->hit()->wire()->xyPosition().x();
2725 double y = circle.links()[i]->hit()->wire()->xyPosition().y();
2726 fprintf(data,"%lf, %lf\n",x,y);
2727 if(flag){
2728 /*if(debugMcFlag){
2729 std::cout << " A:" << circle.links()[i]->hit()->wire()->id() << ", ";
2730 std::cout << ", HepTrackID = " << circle.links()[i]->hit()->mc()->hep()->id();
2731 std::cout << ", HepLundID = " << circle.links()[i]->hit()->mc()->hep()->pType() << std::endl;
2732 }else std::cout << " A:" << circle.links()[i]->hit()->wire()->id() << std::endl;*/
2733 }
2734 }
2735 }
2736 if(flag)std::cout << std::endl;
2737 fclose(data);
2738 }
2739 if((data = fopen("tmp.dat2","w")) != NULL){
2740 if(flag)std::cout << "Stereo Wire ID ==> " << std::endl;
2741 for(int i=0;i<circle.nLinks();++i){
2742 if(circle.links()[i]->hit()->wire()->stereo()){
2743 double x = circle.links()[i]->hit()->wire()->xyPosition().x();
2744 double y = circle.links()[i]->hit()->wire()->xyPosition().y();
2745 fprintf(data,"%lf, %lf\n",x,y);
2746 if(flag){
2747 /*if(debugMcFlag){
2748 std::cout << " S:" << circle.links()[i]->hit()->wire()->id() << ", ";
2749 std::cout << ", HepTrackID = " << circle.links()[i]->hit()->mc()->hep()->id();
2750 std::cout << ", HepLundID = " << circle.links()[i]->hit()->mc()->hep()->pType() << std::endl;
2751 }else std::cout << " S:" << circle.links()[i]->hit()->wire()->id() << std::endl;*/
2752 }
2753 }
2754 }
2755 if(flag)std::cout << std::endl;
2756 fclose(data);
2757 }
2758 double X = circle.center().x();
2759 double Y = circle.center().y();
2760 double R = fabs(circle.radius());
2761 double step = 300.;
2762 double dStep = 2.*M_PI/step;
2763 if((data = fopen("tmp.dat3","w")) != NULL){
2764 for(int i=0;i<step;++i){
2765 double x = X + R * cos(dStep*static_cast<double>(i));
2766 double y = Y + R * sin(dStep*static_cast<double>(i));
2767 fprintf(data,"%lf, %lf\n",x,y);
2768 }
2769 fclose(data);
2770 }
2771 if((gnuplot = popen("gnuplot","w")) != NULL){
2772 fprintf(gnuplot,"set nokey \n");
2773 fprintf(gnuplot,"set size 0.721,1.0 \n");
2774 fprintf(gnuplot,"set xrange [%f:%f] \n",gminX,gmaxX);
2775 fprintf(gnuplot,"set yrange [%f:%f] \n",gminY,gmaxY);
2776 std::string longName = "plot \"tmp_wires.dat\", \"tmp.dat1\", \"tmp.dat3\" w l, \"tmp.dat2\"";
2777 std::string nameHead = ",\"tmp.cdc_";
2778 for(int j=0;j<12;++j){
2779 std::string nameFile = nameHead+"0"+std::string(j)+"\"w l 0";
2780 if(j>=10)nameFile = nameHead+std::string(j)+"\"w l 0";
2781 longName += nameFile;
2782 }
2783 longName += " \n";
2784 fprintf(gnuplot,longName);
2785 fflush(gnuplot);
2786 char tmp[8];
2787 gets(tmp);
2788 pclose(gnuplot);
2789 }
2790#endif
2791 return;
2792}
2793
2794void
2795TCurlFinder::plotTrack(const TTrack& track, const int flag) {
2796#if DEBUG_CURL_GNUPLOT
2797 if(!m_debugCdcFrame){
2798 makeCdcFrame();
2799 m_debugCdcFrame = true;
2800 }
2801 double gmaxX = 90. ,gminX = -90.;
2802 double gmaxY = 90. ,gminY = -90.;
2803 FILE *gnuplot, *data;
2804 if((data = fopen("tmp.dat1","w")) != NULL){
2805 if(flag)std::cout << "Axial Wire ID ==> " << std::endl;
2806 for(int i=0;i<track.nLinks();++i){
2807 if(track.links()[i]->hit()->wire()->axial()){
2808 double x = track.links()[i]->hit()->wire()->xyPosition().x();
2809 double y = track.links()[i]->hit()->wire()->xyPosition().y();
2810 fprintf(data,"%lf, %lf\n",x,y);
2811 if(flag){
2812 if(debugMcFlag){
2813 std::cout << " A:" << track.links()[i]->hit()->wire()->id() << ", ";
2814 std::cout << ", HepTrackID = " << track.links()[i]->hit()->mc()->hep()->id();
2815 std::cout << ", HepLundID = " << track.links()[i]->hit()->mc()->hep()->pType() << std::endl;
2816 }else std::cout << " A:" << track.links()[i]->hit()->wire()->id() << std::endl;
2817 }
2818 }
2819 }
2820 if(flag)std::cout << std::endl;
2821 fclose(data);
2822 }
2823 if((data = fopen("tmp.dat2","w")) != NULL){
2824 if(flag)std::cout << "Stereo Wire ID ==> " << std::endl;
2825 for(int i=0;i<track.nLinks();++i){
2826 if(track.links()[i]->hit()->wire()->stereo()){
2827 double x = track.links()[i]->hit()->wire()->xyPosition().x();
2828 double y = track.links()[i]->hit()->wire()->xyPosition().y();
2829 fprintf(data,"%lf, %lf\n",x,y);
2830 if(flag){
2831 if(debugMcFlag){
2832 std::cout << " S:" << track.links()[i]->hit()->wire()->id() << ", ";
2833 std::cout << ", HepTrackID = " << track.links()[i]->hit()->mc()->hep()->id();
2834 std::cout << ", HepLundID = " << track.links()[i]->hit()->mc()->hep()->pType() << std::endl;
2835 }else std::cout << " S:" << track.links()[i]->hit()->wire()->id() << std::endl;
2836 }
2837 }
2838 }
2839 if(flag)std::cout << std::endl;
2840 fclose(data);
2841 }
2842 double X = track.helix().center().x();
2843 double Y = track.helix().center().y();
2844 double R = fabs(track.helix().radius());
2845 double step = 300.;
2846 double dStep = 2.*M_PI/step;
2847 if((data = fopen("tmp.dat3","w")) != NULL){
2848 for(int i=0;i<step;++i){
2849 double x = X + R * cos(dStep*static_cast<double>(i));
2850 double y = Y + R * sin(dStep*static_cast<double>(i));
2851 fprintf(data,"%lf, %lf\n",x,y);
2852 }
2853 fclose(data);
2854 }
2855 if((gnuplot = popen("gnuplot","w")) != NULL){
2856 fprintf(gnuplot,"set nokey \n");
2857 fprintf(gnuplot,"set size 0.721,1.0 \n");
2858 fprintf(gnuplot,"set xrange [%f:%f] \n",gminX,gmaxX);
2859 fprintf(gnuplot,"set yrange [%f:%f] \n",gminY,gmaxY);
2860 std::string longName = "plot \"tmp_wires.dat\", \"tmp.dat1\", \"tmp.dat3\" w l, \"tmp.dat2\"";
2861 std::string nameHead = ",\"tmp.cdc_";
2862 for(int j=0;j<12;++j){
2863 std::string nameFile = nameHead+"0"+itostring(j)+"\"w l 0";
2864 if(j>=10)nameFile = nameHead+itostring(j)+"\"w l 0";
2865 longName += nameFile;
2866 }
2867 longName += " \n";
2868 fprintf(gnuplot,longName);
2869 fflush(gnuplot);
2870 char tmp[8];
2871 gets(tmp);
2872 pclose(gnuplot);
2873 }
2874#endif
2875 return;
2876}
2877
2878void
2879TCurlFinder::writeSegment(const AList<TMLink>& list, const int type) {
2880#if DEBUG_CURL_SEGMENT
2881 if(!m_debugCdcFrame){
2882 makeCdcFrame();
2883 m_debugCdcFrame = true;
2884 }
2885 double gmaxX = 90. ,gminX = -90.;
2886 double gmaxY = 90. ,gminY = -90.;
2887
2888 FILE *data;
2889 std::string nameHead = "tmp.segment_";
2890 std::string nameFile = nameHead+itostring(type)+"_"+itostring(m_debugFileNumber);
2891 ++m_debugFileNumber;
2892 if((data = fopen(nameFile,"w")) != NULL){
2893 for(int i=0;i<list.length();i++){
2894 double x = list[i]->hit()->wire()->xyPosition().x();
2895 double y = list[i]->hit()->wire()->xyPosition().y();
2896 fprintf(data,"%lf, %lf\n",x,y);
2897 }
2898 fclose(data);
2899 }
2900#endif
2901 return;
2902}
2903
2904void
2905TCurlFinder::dumpType1(TTrack *track) {
2906#if DEBUG_CURL_DUMP
2907 for(int j=0;j<track->nLinks();++j){
2908 std::cout << "Used Wire Info...";
2909 if(track->links()[j]->hit()->wire()->axial()){
2910 std::cout << "A:" << track->links()[j]->hit()->wire()->id() << ", ";
2911 }else{
2912 std::cout << "S:" << track->links()[j]->hit()->wire()->id() << ", ";
2913 }
2914 if(debugMcFlag){
2915 std::cout << ", HepTrackID = " << track->links()[j]->hit()->mc()->hep()->id();
2916 std::cout << ", HepLundID = " << track->links()[j]->hit()->mc()->hep()->pType();
2917 }
2918 double dist = distance(*track, *(track->links()[j]));
2919 if(dist > 2.)std::cout << ": Large Distance( >2cm ) = " << dist;
2920 std::cout << std::endl;
2921 }
2922 AList<TMLink> list=m_unusedAxialHits;
2923 list.append(m_unusedStereoHits);
2924 for(unsigned j=0, nList=list.length();j<nList;++j){
2925 double dist = distance(*track, *(list[j]));
2926 std::cout << "Close Wire Info in ALL( <0.5cm )...";
2927 if(dist < 0.5){
2928 if(list[j]->hit()->wire()->axial())
2929 std::cout << "CA:" << list[j]->hit()->wire()->id() << ", ";
2930 else
2931 std::cout << "CS:" << list[j]->hit()->wire()->id() << ", ";
2932 if(debugMcFlag){
2933 std::cout << ", HepTrackID = " << list[j]->hit()->mc()->hep()->id();
2934 std::cout << ", HepLundID = " << list[j]->hit()->mc()->hep()->pType();
2935 }
2936 std::cout << ", Distance = " << dist << std::endl;
2937 }
2938 }
2939#endif
2940 return;
2941}
2942
2943void
2944TCurlFinder::dumpType2(TTrack *track) {
2945#if DEBUG_CURL_DUMP
2946 unsigned size = track->nLinks();
2947 if(size == 0)return;
2948
2949 set< int, less<int> > uniqueHepID;
2950 vector<int> hepID;
2951 vector<double> ratio;
2952 for(int i=0;i<size;++i){
2953 uniqueHepID.insert(track->links()[i]->hit()->mc()->hep()->id());
2954 hepID.push_back(track->links()[i]->hit()->mc()->hep()->id());
2955 //std::cout << i << " : " << track->links()[i]->hit()->mc()->hep()->id() << std::endl;
2956 }
2957
2958 set< int, less<int> >::iterator u = uniqueHepID.begin();
2959 vector<int>::size_type sizeInt;
2960 for(unsigned i=0;i<uniqueHepID.size();++i){
2961 sizeInt = 0;
2962 count(hepID.begin(), hepID.end(), *u, sizeInt);
2963 ratio.push_back((static_cast<double>(sizeInt)/static_cast<double>(size)));
2964 //std::cout << "HepID = " << *u << ", Ratio = " << ratio[i] << " = " << sizeInt << "/" << size << std::endl;
2965 ++u;
2966 }
2967
2968 vector<double>::iterator m = max_element(ratio.begin(), ratio.end());
2969 int maxIndex = 0;
2970 ::distance(ratio.begin(), m, maxIndex);
2971 u = uniqueHepID.begin();
2972 advance(u,maxIndex);
2973 //std::cout << "MAX HepID = " << *u << ", Ratio = " << ratio[maxIndex] << std::endl;
2974 std::cout << "Ratio " << ratio[maxIndex] << std::endl;
2975 for(int i=0;i<size;++i){
2976 if(track->links()[i]->hit()->wire()->axial())std::cout << "A ";
2977 else std::cout << "S ";
2978
2979 double dist = distance(*track, *(track->links()[i]));
2980 if(*u != track->links()[i]->hit()->mc()->hep()->id()){
2981 std::cout << "Bad " << dist << std::endl;
2982 }else{
2983 std::cout << "Good " << dist << std::endl;
2984 }
2985 }
2986#endif
2987 return;
2988}
2989
2990//#if DEBUG_CURL_MC
2991#if 0
2992// --> TSegmentUtil.h
2993/*
2994sortBySvdRLA( const Datsvd_hit **a, const Datsvd_hit **b ) {
2995 if( (*a)->rla() < (*b)->rla() ){
2996 return -1;
2997 }else if( (*a)->rla() == (*b)->rla() ){
2998 return 0;
2999 }else{
3000 return 1;
3001 }
3002}
3003*/
3004
3005Gen_hepevt *
3006cluster2hep(Recsvd_cluster *clus) {
3007 AList<Datsvd_hit> m_datsvd_hit;
3008 Datsvd_hit_Manager& svdHitMgr = Datsvd_hit_Manager::get_manager();
3009 for(Datsvd_hit_Manager::iterator
3010 it = svdHitMgr.begin(),
3011 end = svdHitMgr.end();
3012 it != end; ++it){
3013 m_datsvd_hit.append(it);
3014 }
3015// m_datsvd_hit.sort(sortBySvdRLA);
3016
3017 unsigned size = m_datsvd_hit.length();
3018 int startPosition = -1;
3019 int direction = 1;
3020#if 0
3021 for(unsigned i=0;i<size;++i){
3022 //if(clus->width() == 1)
3023 std::cout << i << ": " << clus->hit().get_ID() << " <--> " << m_datsvd_hit[i]->get_ID()
3024 << ", RLA = " << m_datsvd_hit[i]->rla() << ", LSA = " << m_datsvd_hit[i]->amp()
3025 << ", Width = " << clus->width()
3026 << ", Cluster LSA = " << clus->lsa() << std::endl;
3027 }
3028#endif
3029 for(unsigned i=0;i<size;++i){
3030 if(m_datsvd_hit[i]->amp() == 0)std::cout << "DatSVD_Hit:amp == 0" << std::endl;
3031 //if(m_datsvd_hit[i]->amp() == 640)std::cout << "DatSVD_Hit:amp == 640" << std::endl;
3032 if(m_datsvd_hit[i]->rla() == 0)std::cout << "DatSVD_Hit:rla == 0" << std::endl;
3033 if(m_datsvd_hit[i]->rla() == 81920)std::cout << "DatSVD_Hit:rla == 81920" << std::endl;
3034 if(clus->hit().get_ID() == m_datsvd_hit[i]->get_ID()){
3035 startPosition = i;
3036 if(static_cast<double>(m_datsvd_hit[i]->amp()-1) > clus->lsa())direction = -1;
3037 break;
3038 }
3039 }
3040 if(startPosition == -1)return NULL;
3041 int width = clus->width();
3042#if 0
3043 std::cout << "Start # = " << startPosition
3044 << ", Width = " << width
3045 << ", Direction = " << direction <<std::endl;
3046#endif
3047
3048 int* hepID = new int[width];
3049 set< int, less<int> > uniqueHepID;
3050
3051 for(int i=startPosition;i<startPosition+width;++i)hepID[i-startPosition] = 0;
3052 //Datsvd_mchit_Manager& svdMcHitMgr = Datsvd_mchit_Manager::get_manager();
3053 Datsvd_mcdata_Manager& svdMcHitMgr = Datsvd_mcdata_Manager::get_manager();
3054 //std::cout << "SVD MC# = " << svdMcHitMgr.count() << std::endl;
3055 if(direction == 1){
3056 for(int i=startPosition;i<startPosition+width;++i){
3057 for(Datsvd_mcdata_Manager::iterator
3058 it = svdMcHitMgr.begin(),
3059 end = svdMcHitMgr.end();
3060 it != end; ++it){
3061 if(it->Hep()){
3062 if(m_datsvd_hit[i]->rla() == it->rla() &&
3063 it->Hep().get_ID() != 0){
3064 hepID[i-startPosition] = it->Hep().get_ID();
3065 uniqueHepID.insert(it->Hep().get_ID());
3066 break;
3067 }
3068 }
3069 }
3070 }
3071 }else{
3072 int reverse = 0;
3073 for(int i=startPosition;i<startPosition+width;++i){
3074 ++reverse;
3075 //std::cout << startPosition+1-reverse << " --- "
3076 // << i << std::endl;
3077 for(Datsvd_mcdata_Manager::iterator
3078 it = svdMcHitMgr.begin(),
3079 end = svdMcHitMgr.end();
3080 it != end; ++it){
3081 if(it->Hep()){
3082 if(m_datsvd_hit[startPosition+1-reverse]->rla() == it->rla() &&
3083 it->Hep().get_ID() != 0){
3084 hepID[i-startPosition] = it->Hep().get_ID();
3085 uniqueHepID.insert(it->Hep().get_ID());
3086 break;
3087 }
3088 }
3089 }
3090 }
3091 }
3092
3093 unsigned num = uniqueHepID.size();
3094 int* counter = new int[num];
3095 set< int, less<int> >::iterator u = uniqueHepID.begin();
3096 for(int i=0;i<num;++i) counter[i] = 0;
3097
3098 for(int i=0;i<num;++i){
3099 for(int j=0;j<width;++j){
3100 if(*u == hepID[j]){
3101 counter[i] += 1;
3102 }
3103 }
3104 ++u;
3105 }
3106
3107 Gen_hepevt_Manager& genMgr = Gen_hepevt_Manager::get_manager();
3108#if 0
3109 u = uniqueHepID.begin();
3110 for(int i=0;i<num;++i){
3111 std::cout << i << ": TrackID = "<< *u - 1
3112 << ", Count = " << counter[i]
3113 << ", LundID = " << genMgr[*u-1].idhep() << std::endl;
3114 ++u;
3115 }
3116#endif
3117
3118 delete [] hepID;
3119 delete [] counter;
3120 if(num == 1){
3121 //std::cout << *(uniqueHepID.begin())-1 << std::endl;
3122 return &(genMgr[*(uniqueHepID.begin())-1]);
3123 }else if(num >= 2){
3124 //std::cout << "A svd cluster is not unique." << std::endl;
3125 return NULL;
3126 }else{
3127 return NULL;
3128 }
3129}
3130#endif
3131
3132void
3133TCurlFinder::debugCheckSegments1(void) {
3134#if DEBUG_CURL_SEGMENT
3135 // Slow Checker(CPU time increases!!)
3136 // Neighboring wires should be included in the same segement.
3137 std::cout << "(TCurlFinder)checking consistency of segement..." << std::endl;
3138 unsigned nA = m_unusedAxialHitsOriginal.length();
3139 if(nA >= 2){
3140 for(unsigned i=0;i<nA-1;++i){
3141 int superLayerId = (int)(m_unusedAxialHitsOriginal[i]->wire()->superLayerId());
3142 int layerId = (int)(m_unusedAxialHitsOriginal[i]->wire()->layerId());
3143 int localId = (int)(m_unusedAxialHitsOriginal[i]->wire()->localId());
3144 int localIdP = (int)(m_unusedAxialHitsOriginal[i]->wire()->localIdForPlus());
3145 int localIdM = (int)(m_unusedAxialHitsOriginal[i]->wire()->localIdForMinus());
3146 for(unsigned j=i+1;j<nA;++j){
3147 int superLayerId2 = (int)(m_unusedAxialHitsOriginal[j]->wire()->superLayerId());
3148 int layerId2 = (int)(m_unusedAxialHitsOriginal[j]->wire()->layerId());
3149 int localId2 = (int)(m_unusedAxialHitsOriginal[j]->wire()->localId());
3150 if(superLayerId == superLayerId2){
3151 if(layerId2 == layerId){
3152 if(localIdP+1 == localId2 || localIdM-1 == localId2)
3153 debugCheckSegments(localId, layerId,
3154 localId2,layerId2);
3155 }else if(layerId2 == layerId-1 || layerId2 == layerId+1){
3156 if(offset(layerId) == offset(layerId2)){
3157 std::cout << "(TCurlFinder: Waring) Offset is same at the same superlayer!!" << std::endl;
3158 }else if(offset(layerId) > offset(layerId2)){
3159 if(localId == localId2 || localIdP+1 == localId2)
3160 debugCheckSegments(localId, layerId,
3161 localId2,layerId2);
3162 }else{
3163 if(localId == localId2 || localIdM-1 == localId2)
3164 debugCheckSegments(localId, layerId,
3165 localId2,layerId2);
3166 }
3167 }
3168 }
3169 }
3170 }
3171 }
3172 unsigned nS = m_unusedStereoHitsOriginal.length();
3173 if(nS >= 2){
3174 for(unsigned i=0;i<nS-1;++i){
3175 int superLayerId = (int)(m_unusedStereoHitsOriginal[i]->wire()->superLayerId());
3176 int layerId = (int)(m_unusedStereoHitsOriginal[i]->wire()->layerId());
3177 int localId = (int)(m_unusedStereoHitsOriginal[i]->wire()->localId());
3178 int localIdP = (int)(m_unusedStereoHitsOriginal[i]->wire()->localIdForPlus());
3179 int localIdM = (int)(m_unusedStereoHitsOriginal[i]->wire()->localIdForMinus());
3180 for(unsigned j=i+1;j<nS;++j){
3181 int superLayerId2 = (int)(m_unusedStereoHitsOriginal[j]->wire()->superLayerId());
3182 int layerId2 = (int)(m_unusedStereoHitsOriginal[j]->wire()->layerId());
3183 int localId2 = (int)(m_unusedStereoHitsOriginal[j]->wire()->localId());
3184 if(superLayerId == superLayerId2){
3185 if(layerId2 == layerId){
3186 if(localIdP+1 == localId2 || localIdM-1 == localId2)
3187 debugCheckSegments(localId, layerId,
3188 localId2,layerId2);
3189 }else if(layerId2 == layerId-1 || layerId2 == layerId+1){
3190 if(offset(layerId) == offset(layerId2)){
3191 std::cout << "(TCurlFinder: Waring) Offset is same at the same superlayer!!" << std::endl;
3192 }else if(offset(layerId) > offset(layerId2)){
3193 if(localId == localId2 || localIdP+1 == localId2)
3194 debugCheckSegments(localId, layerId,
3195 localId2,layerId2);
3196 }else{
3197 if(localId == localId2 || localIdM-1 == localId2)
3198 debugCheckSegments(localId, layerId,
3199 localId2,layerId2);
3200 }
3201 }
3202 }
3203 }
3204 }
3205 }
3206 std::cout << "(TCurlFinder)...done check of segement!" << std::endl;
3207 std::cout << "(TCurlFinder)...If no warning message exists, check of segement is complete!" << std::endl;
3208 std::cout << "(TCurlFinder)...Note: a segment size should be 1 or 2 to use this debugger." << std::endl;
3209#endif
3210 return;
3211}
3212
3213void
3214TCurlFinder::debugCheckSegments(const double localId, const double layerId,
3215 const double localId2,const double layerId2) {
3216#if DEBUG_CURL_DUMP
3217 unsigned nSeg = m_segmentList.length();
3218 unsigned nFound = 0;
3219 for(unsigned i=0;i<nSeg;++i){
3220 unsigned nWire = m_segmentList[i]->list().length();
3221 unsigned mFound = 0;
3222 for(unsigned j=0;j<nWire;++j){
3223 if(((m_segmentList[i]->list())[j])->wire()->layerId() == layerId &&
3224 ((m_segmentList[i]->list())[j])->wire()->localId() == localId)++mFound;
3225 if(((m_segmentList[i]->list())[j])->wire()->layerId() == layerId2 &&
3226 ((m_segmentList[i]->list())[j])->wire()->localId() == localId2)++mFound;
3227 }
3228 if(mFound != 0 && mFound != 2){
3229 std::cout << "(TCurlFinder: Warning) Segment is inconsistency(0)!! mFound = " << mFound << std::endl;
3230 }
3231 if(mFound == 2)++nFound;
3232 }
3233 if(nFound != 1)
3234 std::cout << "(TCurlFinder: Warning) Segment is inconsistency(1)!! nFound = " << nFound << std::endl;
3235#endif
3236 return;
3237}
3238
3239void
3240TCurlFinder::debugCheckSegments0(void) {
3241#if DEBUG_CURL_SEGMENT
3242 unsigned nSeg = m_segmentList.length();
3243 unsigned nWire = 0;
3244 for(unsigned i=0;i<nSeg;++i)nWire += m_segmentList[i]->list().length();
3245
3246 unsigned nWireOriginal = m_unusedAxialHitsOriginal.length()+
3247 m_unusedStereoHitsOriginal.length();
3248
3249 std::cout << "(TCurlFinder: SelfChecker) Segment Parts" << std::endl;
3250 std::cout << " MIN_SEGMENT = " << m_param.MIN_SEGMENT << std::endl;
3251 std::cout << " Wire # of Orinal List = " << nWireOriginal << std::endl;
3252 std::cout << " Wire # of Segments = " << nWire << std::endl;
3253 std::cout << " If MIN_SEGMENT <= 1, above numbers should be same." << std::endl;
3254 std::cout << " If MIN_SEGMENT > 1, former >= latter." << std::endl;
3255#endif
3256 return;
3257}
3258
3259void
3260TCurlFinder::debugCheckSegments2(void) {
3261#if DEBUG_CURL_SEGMENT
3262
3263#define DEBUG_TMP_N_CURL 50
3264
3265 unsigned nSeg = m_segmentList.length();
3266 unsigned nWire[DEBUG_TMP_N_CURL] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3267 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3269 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3271 for(unsigned i=0;i<nSeg;++i){
3272 if(m_segmentList[i]->list().length() < DEBUG_TMP_N_CURL)
3273 ++(nWire[m_segmentList[i]->list().length()]);
3274 else
3275 ++(nWire[DEBUG_TMP_N_CURL-1]);
3276 }
3277 std::ifstream fin("tmp.wire.data");
3278 unsigned nTotalWire[DEBUG_TMP_N_CURL] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3283 if(fin){
3284 for(int i=0;i<DEBUG_TMP_N_CURL;++i)fin >> nTotalWire[i];
3285 }else{
3286 std::cout << "(TCurlFinder) tmp.wire.data does not exist!" << std::endl;
3287 }
3288 for(int i=0;i<DEBUG_TMP_N_CURL;++i)nTotalWire[i] += nWire[i];
3289 std::ofstream fout("tmp.wire.data");
3290 if(fout){
3291 fout << nTotalWire[0];
3292 for(int i=1;i<DEBUG_TMP_N_CURL;++i)fout << " " << nTotalWire[i];
3293 }else{
3294 std::cout << "(TCurlFinder) tmp.wire.data can not be made!" << std::endl;
3295 }
3296#endif
3297 return;
3298}
3299
3300#undef DEBUG_CURL_DUMP
3301#undef DEBUG_CURL_SEGMENT
3302#undef DEBUG_CURL_GNUPLOT
3303#undef DEBUG_CURL_MC
double sin(const BesAngle a)
Definition BesAngle.h:210
double cos(const BesAngle a)
Definition BesAngle.h:213
double length
const Int_t n
TTree * data
Double_t x[10]
EvtTensor3C eps(const EvtVector3R &v)
HepGeom::Point3D< double > HepPoint3D
Definition Gam4pikp.cxx:37
****INTEGER imax DOUBLE PRECISION m_pi *DOUBLE PRECISION m_amfin DOUBLE PRECISION m_Chfin DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_sinw2 DOUBLE PRECISION m_GFermi DOUBLE PRECISION m_MfinMin DOUBLE PRECISION m_ta2 INTEGER m_out INTEGER m_KeyFSR INTEGER m_KeyQCD *COMMON c_Semalib $ !copy of input $ !CMS energy $ !beam mass $ !final mass $ !beam charge $ !final charge $ !smallest final mass $ !Z mass $ !Z width $ !EW mixing angle $ !Gmu Fermi $ alphaQED at q
Definition KKsem.h:33
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
Definition KarLud.h:35
#define M_PI
Definition TConstant.h:4
int sortByArcLength(const void *av, const void *bv)
TMLink * findIsolatedCloseHits(TMLink *link)
int sortBySequentialLength(const void *av, const void *bv)
int TCurlFinder_doubleCompare(const void *i, const void *j)
#define WireHitFindingValid
Definition TMDCWireHit.h:28
#define WireHitFittingValid
Definition TMDCWireHit.h:29
#define WireHitLeft
Definition TMDCWireHit.h:21
#define WireHitRight
Definition TMDCWireHit.h:22
#define WireHitUsed
Definition TMDCWireHit.h:47
#define WireHitCurlFinder
Definition TMDCWireHit.h:52
#define WireHitInvalidForFit
Definition TMDCWireHit.h:55
#define TrackCurlFinder
Definition TTrack.h:26
#define TrackQuality2D
Definition TTrack.h:47
const HepPoint3D & center(void) const
returns position of helix center(z = 0.);
HepPoint3D x(double dPhi=0.) const
returns position after rotating angle dPhi in phi direction.
double radius(void) const
returns radious of helix.
double dr(void) const
returns an element of parameters.
const HepVector & a(void) const
returns helix parameters.
virtual double getReferField()=0
void add_point(double x, double y, double w=1)
TTrack * buildStereo(TTrack &track, const AList< TMLink > &) const
appends stereo hits to a track.
TTrack * buildStereoMC(TTrack &track, const AList< TMLink > &) const
void setParam(const TCurlFinderParameter &)
A class to represent a circle in tracking.
Definition TCircle.h:42
double radius(void) const
returns radius.
Definition TCircle.h:117
const HepPoint3D & center(void) const
returns position of center.
Definition TCircle.h:108
void property(double charge, double radius, HepPoint3D center)
sets circle properties.
Definition TCircle.h:157
int fitForCurl(int ipConst=0)
fits itself. Error was happened if return value is not zero.
Definition TCircle.cxx:136
std::string name(void) const
returns name.
int doit(const AList< TMDCWireHit > &axialHits, const AList< TMDCWireHit > &stereoHits, AList< TTrack > &tracks, AList< TTrack > &tracks2D)
main function
std::string version(void) const
returns version.
void clear(void)
cleans all members of this class
TCurlFinder(void)
int fit(TTrackBase &) const
float drift(unsigned) const
returns drift distance.
const TMDCWire *const wire(void) const
returns a pointer to a TMDCWire.
const HepPoint3D & xyPosition(void) const
returns drift time
unsigned id(void) const
returns id.
Definition TMDCWire.h:207
unsigned localId(void) const
returns local id in a wire layer.
Definition TMDCWire.h:213
unsigned layerId(void) const
returns layer id.
Definition TMDCWire.h:219
const HepVector3D & direction(void) const
returns direction vector of the wire.
Definition TMDCWire.h:342
const HepPoint3D & xyPosition(void) const
returns middle position of a wire. z componet is 0.
Definition TMDCWire.h:327
unsigned superLayerId(void) const
returns super layer id.
Definition TMDCWire.h:225
const HepPoint3D & backwardPosition(void) const
returns position in backward endplate.
Definition TMDCWire.h:306
void append(TMLink &)
const AList< TMLink > & list(void)
void dump(void)
const unsigned size(void)
void update(void)
void removeAll(void)
void append(TMLink &)
appends a TMLink.
const AList< TMLink > & links(unsigned mask=0) const
returns a list of masked TMLinks assigned to this track. 'mask' will be applied if mask is not 0.
void remove(TMLink &a)
removes a TMLink.
Definition TTrackBase.h:204
unsigned nLinks(unsigned mask=0) const
returns # of masked TMLinks assigned to this track object.
A class to represent a track in tracking.
Definition TTrack.h:129
void assign(unsigned maskForWireHit)
assigns wire hits to this track.
Definition TTrack.cxx:3635
const Helix & helix(void) const
returns helix parameter.
Definition TTrack.h:477
double charge(void) const
returns charge.
Definition TTrack.h:504
Index next(Index i)
Index first(Pair i)
uint32_t count(const node_t &list)
Definition node.cxx:42
complex_t R(double Q2, double M2, double G, double Mp2, double Mm2)
Definition TUtil.h:27
int num[96]
Definition ranlxd.c:373
int t()
Definition t.c:1