11import { PhoenixLoader } from './phoenix-loader' ;
22import { CoordinateHelper } from '../helpers/coordinate-helper' ;
3+ import { RKHelper } from '../helpers/rk-helper' ;
4+
5+ /**
6+ * Configuration options for JiveXML track extension.
7+ */
8+ export interface JiveXMLTrackExtensionConfig {
9+ /** Enable using extra hits for truncated tracks */
10+ useExtraHits : boolean ;
11+ /** Minimum delta distance for filtering extra hits (in mm) */
12+ extraHitsMinDelta : number ;
13+ /** Enable RK extrapolation for truncated tracks */
14+ useRKExtrapolation : boolean ;
15+ /** Radius for RK extrapolation (in mm) */
16+ rkExtrapolationRadius : number ;
17+ /** Track collections to apply extension to (empty means all) */
18+ trackCollectionsToExtend : string [ ] ;
19+ }
320
421/**
522 * PhoenixLoader for processing and loading an event from the JiveXML data format.
@@ -9,15 +26,48 @@ export class JiveXMLLoader extends PhoenixLoader {
926 private data : any ;
1027 /** List of tracks to draw with thicker tubes */
1128 thickTrackCollections : string [ ] ;
29+ /** Configuration for track extension options */
30+ private trackExtensionConfig : JiveXMLTrackExtensionConfig ;
1231
1332 /**
1433 * Constructor for the JiveXMLLoader.
1534 * @param thickTrackCollections A list of names of track collections which should be drawn thicker
35+ * @param trackExtensionConfig Configuration for track extension behavior
1636 */
17- constructor ( thickTrackCollections : string [ ] = [ ] ) {
37+ constructor (
38+ thickTrackCollections : string [ ] = [ ] ,
39+ trackExtensionConfig ?: Partial < JiveXMLTrackExtensionConfig > ,
40+ ) {
1841 super ( ) ;
1942 this . data = { } ;
2043 this . thickTrackCollections = thickTrackCollections ;
44+ // Set default configuration
45+ this . trackExtensionConfig = {
46+ useExtraHits : false , // Disabled by default as per issue
47+ extraHitsMinDelta : 250 , // Current default value
48+ useRKExtrapolation : false ,
49+ rkExtrapolationRadius : 1500 ,
50+ trackCollectionsToExtend : [ ] , // Empty means all collections
51+ ...trackExtensionConfig , // Override with provided config
52+ } ;
53+ }
54+
55+ /**
56+ * Update track extension configuration.
57+ * @param config Partial configuration to update
58+ */
59+ public setTrackExtensionConfig (
60+ config : Partial < JiveXMLTrackExtensionConfig > ,
61+ ) : void {
62+ this . trackExtensionConfig = { ...this . trackExtensionConfig , ...config } ;
63+ }
64+
65+ /**
66+ * Get current track extension configuration.
67+ * @returns Current configuration
68+ */
69+ public getTrackExtensionConfig ( ) : JiveXMLTrackExtensionConfig {
70+ return { ...this . trackExtensionConfig } ;
2171 }
2272
2373 /**
@@ -367,14 +417,22 @@ export class JiveXMLLoader extends PhoenixLoader {
367417 polylineCounter += numPolyline [ i ] ;
368418 track . pos = pos ;
369419 }
420+
421+ // Check if we should extend this track collection
422+ const shouldExtendTrack =
423+ ( this . trackExtensionConfig . useExtraHits ||
424+ this . trackExtensionConfig . useRKExtrapolation ) &&
425+ ( this . trackExtensionConfig . trackCollectionsToExtend . length === 0 ||
426+ this . trackExtensionConfig . trackCollectionsToExtend . includes (
427+ trackCollectionName ,
428+ ) ) ;
429+
430+ // IMPROVED: Extra hits extension with better filtering
370431 if (
371- // eslint-disable-next-line
372- false &&
373- numHits . length > 0 &&
374- trackCollectionName ?. includes ( 'Muon' )
432+ shouldExtendTrack &&
433+ this . trackExtensionConfig . useExtraHits &&
434+ numHits . length > 0
375435 ) {
376- // Disable for the moment.
377-
378436 // Now loop over hits, and if possible, see if we can extend the track
379437 const measurementPositions = [ ] ;
380438 if ( numHits . length > 0 ) {
@@ -400,35 +458,84 @@ export class JiveXMLLoader extends PhoenixLoader {
400458 track . hits = listOfHits ;
401459 }
402460
403- // This seems to give pretty poor results, so try to filter.
461+ // IMPROVED: Better filtering logic
404462 // Sort radially (sorry cosmics!)
405463 const sortedMeasurements = measurementPositions . sort (
406464 ( a , b ) => a [ 3 ] - b [ 3 ] ,
407465 ) ;
408- const minDelta = 250 ; // tweaked by trial and error
466+ const minDelta = this . trackExtensionConfig . extraHitsMinDelta ;
409467 let newHitCount = 0 ;
410468 let rejectedHitCount = 0 ;
411469 let lastDistance = maxR + minDelta ;
470+
412471 if ( sortedMeasurements . length ) {
413472 for ( const meas of sortedMeasurements ) {
473+ // Better filtering: check distance AND angular consistency
414474 if ( meas [ 3 ] > lastDistance + minDelta ) {
415- track . pos . push ( [ meas [ 0 ] , meas [ 1 ] , meas [ 2 ] ] ) ;
416- lastDistance = meas [ 3 ] + minDelta ;
417- newHitCount ++ ;
475+ // Check angular consistency with track direction
476+ const measTheta = Math . acos ( meas [ 2 ] / meas [ 3 ] ) ;
477+ const measPhi = Math . atan2 ( meas [ 1 ] , meas [ 0 ] ) ;
478+ const thetaDiff = Math . abs ( measTheta - theta ) ;
479+ const phiDiff = Math . abs ( measPhi - track . phi ) ;
480+
481+ // Only add if angles are reasonably close (within 0.5 radians ~= 28 degrees)
482+ if ( thetaDiff < 0.5 && phiDiff < 0.5 ) {
483+ track . pos . push ( [ meas [ 0 ] , meas [ 1 ] , meas [ 2 ] ] ) ;
484+ lastDistance = meas [ 3 ] ;
485+ newHitCount ++ ;
486+ } else {
487+ rejectedHitCount ++ ;
488+ }
418489 } else {
419490 rejectedHitCount ++ ;
420491 }
421492 }
422493 }
423- console . log (
424- 'Added ' +
425- newHitCount +
426- ' hits to ' +
427- trackCollectionName +
428- ' (and rejected ' +
429- rejectedHitCount +
430- ')' ,
494+
495+ if ( newHitCount > 0 ) {
496+ console . log (
497+ `Extended ${ trackCollectionName } with ${ newHitCount } extra hits (rejected ${ rejectedHitCount } )` ,
498+ ) ;
499+ }
500+ }
501+
502+ // NEW: RK Extrapolation for truncated tracks
503+ if (
504+ shouldExtendTrack &&
505+ this . trackExtensionConfig . useRKExtrapolation &&
506+ track . pos . length > 0 &&
507+ track . dparams . length === 5
508+ ) {
509+ const lastPos = track . pos [ track . pos . length - 1 ] ;
510+ const currentRadius = Math . sqrt (
511+ lastPos [ 0 ] * lastPos [ 0 ] +
512+ lastPos [ 1 ] * lastPos [ 1 ] +
513+ lastPos [ 2 ] * lastPos [ 2 ] ,
431514 ) ;
515+ const targetRadius = this . trackExtensionConfig . rkExtrapolationRadius ;
516+
517+ // Only extrapolate if we're not already beyond target radius
518+ if ( currentRadius < targetRadius ) {
519+ try {
520+ const extrapolatedPoints = RKHelper . extrapolateFromLastPosition (
521+ track ,
522+ targetRadius ,
523+ ) ;
524+
525+ if ( extrapolatedPoints . length > 0 ) {
526+ // Add extrapolated points to track
527+ track . pos . push ( ...extrapolatedPoints ) ;
528+ console . log (
529+ `Extended ${ trackCollectionName } with ${ extrapolatedPoints . length } RK extrapolated points to radius ${ targetRadius } mm` ,
530+ ) ;
531+ }
532+ } catch ( error ) {
533+ console . warn (
534+ `Failed to RK extrapolate track in ${ trackCollectionName } :` ,
535+ error ,
536+ ) ;
537+ }
538+ }
432539 }
433540
434541 if ( storeTrack ) jsontracks . push ( track ) ;
0 commit comments