@@ -437,6 +437,36 @@ def shift_h(self, data, h_axis):
437437 this_h = np .interp (h_axis , xi , this_h )
438438 return this_h
439439
440+ def _count_photo_electrons (self , tof_part , parallel ):
441+ """
442+ Given an `AdqRawChannel` object with monochromated data, count photo-electrons
443+ and build a response function.
444+
445+ Args:
446+ tof_part: The `AdqRawChannel` object to use for counting the electrons.
447+ parallel: Argument used to parallelize `pulse_edges`.
448+
449+ Returns: The response function aligned to this monochromated peak.
450+ """
451+ logging .info ("Calling pulse_edges for selected trains ..." )
452+ # get peak positions where photo-electrons were found
453+ tof_data = tof_part .pulse_edges (pulse_dim = 'pulseIndex' ,
454+ threshold = self .count_threshold ,
455+ parallel = parallel ).reset_index ()
456+ # use the peaks identified to select trains
457+ good_trains = np .unique (tof_data .loc [:,'trainId' ].to_numpy ())
458+ # create an index of good elements
459+ idx = tof_data .loc [:, ['trainId' , 'pulseIndex' ]].set_index (['trainId' , 'pulseIndex' ]).index
460+ logging .info ("Summing good trains ..." )
461+ # select only trains with a photo-electron detected ("good trains") to do this faster
462+ analog_data = - tof_part .select_trains (by_id [good_trains ]).pulse_data (pulse_dim = "pulseIndex" , parallel = parallel )
463+ # select the train-pulses of interest
464+ this_tof_data = analog_data .sel (pulse = idx ).mean ("pulse" )
465+ # apply an roi
466+ if self .roi is not None :
467+ this_tof_data = this_tof_data .isel (sample = self .roi )
468+ return this_tof_data
469+
440470 def setup (self ,
441471 tof : AdqRawChannel ,
442472 scan : Scan = None ,
@@ -466,25 +496,23 @@ def setup(self,
466496 this_tof_data = - tof .pulse_data (pulse_dim = "pulseIndex" , parallel = parallel ).unstack ("pulse" )
467497 logging .info ("Averaging over mono settings ..." )
468498 for k , e in enumerate (scan .positions ):
469- data += [this_tof_data .sel (trainId = scan .positions_train_ids [k ]).mean ("trainId" ).mean ("pulseIndex" ).to_numpy ()]
499+ d = this_tof_data .sel (trainId = scan .positions_train_ids [k ])
500+ if self .roi is not None :
501+ d = d .isel (sample = self .roi )
502+ d = d .mean ("trainId" ).mean ("pulseIndex" ).to_numpy ()
503+ data += [d ]
470504 else :
471505 # count photo-electrons by histogramming peak positions
472- for k , e in enumerate (scan .positions ):
473- tof_data = tof .select_trains (by_id [scan .positions_train_ids [k ]]).pulse_edges (pulse_dim = 'pulseIndex' , threshold = self .count_threshold , parallel = parallel ).reset_index ()
474- this_tof_data , _ = np .histogram (tof_data .edge , bins = bins , weights = - tof_data .amplitude )
475- this_tof_data = xr .DataArray (this_tof_data , dims = ('sample' ), coords = {'sample' : bins [:- 1 ]})
476- if self .roi is not None :
477- this_tof_data = this_tof_data .isel (sample = self .roi )
478- data += [this_tof_data .to_numpy ()]
506+ for tof_part in scan .split_by_steps (tof ):
507+ this_tof_data = self ._count_photo_electrons (tof_part , parallel = parallel )
508+ data += [this_tof_data .to_numpy ()]
479509 else :
480510 if self .count_threshold is None or self .count_threshold >= 0 :
481511 this_tof_data = - tof .pulse_data (pulse_dim = "pulseIndex" , parallel = parallel ).mean ('pulse' )
512+ if self .roi is not None :
513+ this_tof_data = this_tof_data .isel (sample = self .roi )
482514 else :
483- tof_data = tof .pulse_edges (pulse_dim = 'pulseIndex' , threshold = self .count_threshold , parallel = parallel ).reset_index ()
484- this_tof_data , _ = np .histogram (tof_data .edge , bins = bins , weights = - tof_data .amplitude )
485- this_tof_data = xr .DataArray (this_tof_data , dims = ('sample' ), coords = {'sample' : bins [:- 1 ]})
486- if self .roi is not None :
487- this_tof_data = this_tof_data .isel (sample = self .roi )
515+ this_tof_data = self ._count_photo_electrons (tof , parallel = parallel )
488516 data += [this_tof_data .to_numpy ()]
489517
490518 for d in data :
0 commit comments