diff --git a/ptychodus/api/patterns.py b/ptychodus/api/patterns.py index 3539ae3b..877f0446 100644 --- a/ptychodus/api/patterns.py +++ b/ptychodus/api/patterns.py @@ -13,6 +13,7 @@ from .observer import Observable from .tree import SimpleTreeNode +BooleanArrayType: TypeAlias = numpy.typing.NDArray[numpy.bool_] DiffractionPatternArrayType: TypeAlias = numpy.typing.NDArray[numpy.integer[Any]] DiffractionPatternIndexes: TypeAlias = numpy.typing.NDArray[numpy.integer[Any]] diff --git a/ptychodus/api/product.py b/ptychodus/api/product.py index aeb80cc7..73b660d4 100644 --- a/ptychodus/api/product.py +++ b/ptychodus/api/product.py @@ -4,6 +4,7 @@ from pathlib import Path from sys import getsizeof +from .constants import ELECTRON_VOLT_J, LIGHT_SPEED_M_PER_S, PLANCK_CONSTANT_J_PER_HZ from .object import Object from .probe import Probe from .scan import Scan @@ -18,6 +19,19 @@ class ProductMetadata: probePhotonsPerSecond: float exposureTimeInSeconds: float + @property + def probeEnergyInJoules(self) -> float: + return self.probeEnergyInElectronVolts * ELECTRON_VOLT_J + + @property + def probeWavelengthInMeters(self) -> float: + hc_Jm = PLANCK_CONSTANT_J_PER_HZ * LIGHT_SPEED_M_PER_S + + try: + return hc_Jm / self.probeEnergyInJoules + except ZeroDivisionError: + return 0.0 + @property def sizeInBytes(self) -> int: sz = getsizeof(self.name) diff --git a/ptychodus/api/reconstructor.py b/ptychodus/api/reconstructor.py index a23acb11..ad5eb67e 100644 --- a/ptychodus/api/reconstructor.py +++ b/ptychodus/api/reconstructor.py @@ -5,12 +5,13 @@ from pathlib import Path from .product import Product -from .patterns import DiffractionPatternArrayType +from .patterns import BooleanArrayType, DiffractionPatternArrayType @dataclass(frozen=True) class ReconstructInput: patterns: DiffractionPatternArrayType + goodPixelMask: BooleanArrayType product: Product diff --git a/ptychodus/model/analysis/core.py b/ptychodus/model/analysis/core.py index 5091b365..7225d657 100644 --- a/ptychodus/model/analysis/core.py +++ b/ptychodus/model/analysis/core.py @@ -49,7 +49,7 @@ def __init__( self._fluorescenceSettings = FluorescenceSettings(settingsRegistry) self.fluorescenceEnhancer = FluorescenceEnhancer( self._fluorescenceSettings, - dataMatcher, + productRepository, upscalingStrategyChooser, deconvolutionStrategyChooser, fluorescenceFileReaderChooser, diff --git a/ptychodus/model/analysis/fluorescence.py b/ptychodus/model/analysis/fluorescence.py index 57966c9b..19a18998 100644 --- a/ptychodus/model/analysis/fluorescence.py +++ b/ptychodus/model/analysis/fluorescence.py @@ -22,7 +22,7 @@ from ptychodus.api.product import Product from ptychodus.api.typing import RealArrayType -from ..reconstructor import DiffractionPatternPositionMatcher +from ..product import ProductRepository from .settings import FluorescenceSettings logger = logging.getLogger(__name__) @@ -63,7 +63,7 @@ def get_axis_weights_and_indexes( class VSPILinearOperator(LinearOperator): - def __init__(self, product: Product, xrf_nchannels: int) -> None: + def __init__(self, product: Product) -> None: """ M: number of XRF positions N: number of ptychography object pixels @@ -71,11 +71,11 @@ def __init__(self, product: Product, xrf_nchannels: int) -> None: A[M,N] * X[N,P] = B[M,P] """ - super().__init__(float, (len(product.scan), xrf_nchannels)) + super().__init__(float, (len(product.scan), len(product.scan))) self._product = product - def matmat(self, X: RealArrayType) -> RealArrayType: - AX = numpy.zeros(self.shape, dtype=self.dtype) + def _matvec(self, X: RealArrayType) -> RealArrayType: + AX = numpy.zeros(X.shape, dtype=self.dtype) probeGeometry = self._product.probe.getGeometry() dx_p_m = probeGeometry.pixelWidthInMeters @@ -103,7 +103,7 @@ def matmat(self, X: RealArrayType) -> RealArrayType: i_nz = numpy.ravel_multi_index(list(zip(IY.flat, IX.flat)), objectShape) X_nz = X.take(i_nz, axis=0) - AX[index, :] = numpy.matmul(numpy.outer(wy, wx).ravel(), X_nz) + AX[index] = numpy.matmul(numpy.outer(wy, wx).ravel(), X_nz) return AX @@ -115,7 +115,7 @@ class FluorescenceEnhancer(Observable, Observer): def __init__( self, settings: FluorescenceSettings, - dataMatcher: DiffractionPatternPositionMatcher, # FIXME match XRF too + productRepository: ProductRepository, upscalingStrategyChooser: PluginChooser[UpscalingStrategy], deconvolutionStrategyChooser: PluginChooser[DeconvolutionStrategy], fileReaderChooser: PluginChooser[FluorescenceFileReader], @@ -124,7 +124,7 @@ def __init__( ) -> None: super().__init__() self._settings = settings - self._dataMatcher = dataMatcher + self._productRepository = productRepository self._upscalingStrategyChooser = upscalingStrategyChooser self._deconvolutionStrategyChooser = deconvolutionStrategyChooser self._fileReaderChooser = fileReaderChooser @@ -152,7 +152,7 @@ def setProduct(self, productIndex: int) -> None: self.notifyObservers() def getProductName(self) -> str: - return self._dataMatcher.getProductName(self._productIndex) + return self._productRepository[self._productIndex].getName() def getOpenFileFilterList(self) -> Sequence[str]: return self._fileReaderChooser.getDisplayNameList() @@ -222,14 +222,12 @@ def enhanceFluorescence(self) -> None: if self._measured is None: raise ValueError('Fluorescence dataset not loaded!') - reconstructInput = self._dataMatcher.matchDiffractionPatternsWithPositions( - self._productIndex - ) + product = self._productRepository[self._productIndex].getProduct() element_maps: list[ElementMap] = list() if self._settings.useVSPI.getValue(): measured_emaps = self._measured.element_maps - A = VSPILinearOperator(reconstructInput.product, len(measured_emaps)) + A = VSPILinearOperator(product) B = numpy.stack([b.counts_per_second.flatten() for b in measured_emaps]).T X, info = gmres(A, B, atol=1e-5) # TODO expose atol @@ -246,8 +244,8 @@ def enhanceFluorescence(self) -> None: for emap in self._measured.element_maps: logger.info(f'Enhancing "{emap.name}"') - emap_upscaled = upscaler(emap, reconstructInput.product) - emap_enhanced = deconvolver(emap_upscaled, reconstructInput.product) + emap_upscaled = upscaler(emap, product) + emap_enhanced = deconvolver(emap_upscaled, product) element_maps.append(emap_enhanced) self._enhanced = FluorescenceDataset( @@ -258,7 +256,7 @@ def enhanceFluorescence(self) -> None: self.notifyObservers() def getPixelGeometry(self) -> PixelGeometry: - return self._dataMatcher.getObjectPlanePixelGeometry(self._productIndex) + return self._productRepository[self._productIndex].getGeometry().getPixelGeometry() def getEnhancedElementMap(self, channelIndex: int) -> ElementMap: if self._enhanced is None: diff --git a/ptychodus/model/patterns/active.py b/ptychodus/model/patterns/active.py index 0a81d618..b43cdaa2 100644 --- a/ptychodus/model/patterns/active.py +++ b/ptychodus/model/patterns/active.py @@ -10,6 +10,7 @@ from ptychodus.api.geometry import ImageExtent from ptychodus.api.patterns import ( + BooleanArrayType, DiffractionDataset, DiffractionMetadata, DiffractionPatternArray, @@ -141,6 +142,15 @@ def insertArray(self, array: DiffractionPatternArray) -> None: self._changedEvent.set() + def getGoodPixelMask(self) -> BooleanArrayType: # FIXME + return numpy.full( + ( + self._diffractionPatternSizer.getHeightInPixels(), + self._diffractionPatternSizer.getWidthInPixels(), + ), + True, + ) + def getAssembledIndexes(self) -> Sequence[int]: indexes: list[int] = list() diff --git a/ptychodus/model/product/api.py b/ptychodus/model/product/api.py index 411c088b..ee7aefe5 100644 --- a/ptychodus/model/product/api.py +++ b/ptychodus/model/product/api.py @@ -112,7 +112,7 @@ def copyScan(self, sourceIndex: int, destinationIndex: int) -> None: logger.warning(f'Failed to access destination scan {destinationIndex} for copying!') return - destinationItem.assign(sourceItem) + destinationItem.assignItem(sourceItem) def getSaveFileFilterList(self) -> Sequence[str]: return self._builderFactory.getSaveFileFilterList() @@ -220,7 +220,7 @@ def copyProbe(self, sourceIndex: int, destinationIndex: int) -> None: logger.warning(f'Failed to access destination probe {destinationIndex} for copying!') return - destinationItem.assign(sourceItem) + destinationItem.assignItem(sourceItem) def getSaveFileFilterList(self) -> Sequence[str]: return self._builderFactory.getSaveFileFilterList() @@ -328,7 +328,7 @@ def copyObject(self, sourceIndex: int, destinationIndex: int) -> None: logger.warning(f'Failed to access destination object {destinationIndex} for copying!') return - destinationItem.assign(sourceItem) + destinationItem.assignItem(sourceItem) def getSaveFileFilterList(self) -> Sequence[str]: return self._builderFactory.getSaveFileFilterList() @@ -370,7 +370,7 @@ def insertNewProduct( likeIndex: int = -1, ) -> int: return self._repository.insertNewProduct( - name, + name=name, comments=comments, detectorDistanceInMeters=detectorDistanceInMeters, probeEnergyInElectronVolts=probeEnergyInElectronVolts, diff --git a/ptychodus/model/product/item.py b/ptychodus/model/product/item.py index 52b3ec4e..096dbbbe 100644 --- a/ptychodus/model/product/item.py +++ b/ptychodus/model/product/item.py @@ -66,6 +66,24 @@ def __init__( self._addGroup('probe', self._probe, observe=True) self._addGroup('object', self._object, observe=True) + def assignItem(self, item: ProductRepositoryItem, *, notify: bool = True) -> None: + self._metadata.assignItem(item.getMetadata()) + self._scan.assignItem(item.getScan()) + self._probe.assignItem(item.getProbe()) + self._object.assignItem(item.getObject()) + self._costs = list(item.getCosts()) + + if notify: + self._parent.handleCostsChanged(self) + + def assign(self, product: Product) -> None: + self._metadata.assign(product.metadata) + self._scan.assign(product.scan) + self._probe.assign(product.probe) + self._object.assign(product.object_) + self._costs = list(product.costs) + self._parent.handleCostsChanged(self) + def syncToSettings(self) -> None: self._metadata.syncToSettings() self._scan.syncToSettings() diff --git a/ptychodus/model/product/metadata.py b/ptychodus/model/product/metadata.py index 74903c6f..7cd517b3 100644 --- a/ptychodus/model/product/metadata.py +++ b/ptychodus/model/product/metadata.py @@ -68,7 +68,7 @@ def __init__( self._index = -1 - def assign(self, item: MetadataRepositoryItem) -> None: + def assignItem(self, item: MetadataRepositoryItem, *, notify: bool = True) -> None: self.setName(item.getName()) self.comments.setValue(item.comments.getValue()) self.detectorDistanceInMeters.setValue(item.detectorDistanceInMeters.getValue()) @@ -76,6 +76,14 @@ def assign(self, item: MetadataRepositoryItem) -> None: self.probePhotonsPerSecond.setValue(item.probePhotonsPerSecond.getValue()) self.exposureTimeInSeconds.setValue(item.exposureTimeInSeconds.getValue()) + def assign(self, metadata: ProductMetadata) -> None: + self.setName(metadata.name) + self.comments.setValue(metadata.comments) + self.detectorDistanceInMeters.setValue(metadata.detectorDistanceInMeters) + self.probeEnergyInElectronVolts.setValue(metadata.probeEnergyInElectronVolts) + self.probePhotonsPerSecond.setValue(metadata.probePhotonsPerSecond) + self.exposureTimeInSeconds.setValue(metadata.exposureTimeInSeconds) + def syncToSettings(self) -> None: for parameter in self.parameters().values(): parameter.syncValueToParent() diff --git a/ptychodus/model/product/object/builder.py b/ptychodus/model/product/object/builder.py index e349395e..7a63de7b 100644 --- a/ptychodus/model/product/object/builder.py +++ b/ptychodus/model/product/object/builder.py @@ -63,8 +63,10 @@ def __init__( super().__init__(settings, 'from_file') self._settings = settings self.filePath = settings.filePath.copy() + self.filePath.setValue(filePath) self._addParameter('file_path', self.filePath) self.fileType = settings.fileType.copy() + self.fileType.setValue(fileType) self._addParameter('file_type', self.fileType) self._fileReader = fileReader diff --git a/ptychodus/model/product/object/item.py b/ptychodus/model/product/object/item.py index f2fd3e44..d4e02bce 100644 --- a/ptychodus/model/product/object/item.py +++ b/ptychodus/model/product/object/item.py @@ -7,7 +7,7 @@ from ptychodus.api.observer import Observable from ptychodus.api.parametric import ParameterGroup -from .builder import ObjectBuilder +from .builder import FromMemoryObjectBuilder, ObjectBuilder from .settings import ObjectSettings logger = logging.getLogger(__name__) @@ -32,10 +32,14 @@ def __init__( self._rebuild() - def assign(self, item: ObjectRepositoryItem) -> None: + def assignItem(self, item: ObjectRepositoryItem) -> None: self.layerDistanceInMeters.setValue(item.layerDistanceInMeters.getValue(), notify=False) self.setBuilder(item.getBuilder().copy()) + def assign(self, object_: Object) -> None: + builder = FromMemoryObjectBuilder(self._settings, object_) + self.setBuilder(builder) + def syncToSettings(self) -> None: for parameter in self.parameters().values(): parameter.syncValueToParent() diff --git a/ptychodus/model/product/probe/builder.py b/ptychodus/model/product/probe/builder.py index 87fc2d61..b8fec604 100644 --- a/ptychodus/model/product/probe/builder.py +++ b/ptychodus/model/product/probe/builder.py @@ -91,8 +91,10 @@ def __init__( super().__init__(settings, 'from_file') self._settings = settings self.filePath = settings.filePath.copy() + self.filePath.setValue(filePath) self._addParameter('file_path', self.filePath) self.fileType = settings.fileType.copy() + self.fileType.setValue(fileType) self._addParameter('file_type', self.fileType) self._fileReader = fileReader diff --git a/ptychodus/model/product/probe/item.py b/ptychodus/model/product/probe/item.py index 214a1699..b3f58615 100644 --- a/ptychodus/model/product/probe/item.py +++ b/ptychodus/model/product/probe/item.py @@ -5,8 +5,9 @@ from ptychodus.api.parametric import ParameterGroup from ptychodus.api.probe import Probe, ProbeGeometryProvider -from .builder import ProbeBuilder +from .builder import FromMemoryProbeBuilder, ProbeBuilder from .multimodal import MultimodalProbeBuilder +from .settings import ProbeSettings logger = logging.getLogger(__name__) @@ -15,11 +16,13 @@ class ProbeRepositoryItem(ParameterGroup): def __init__( self, geometryProvider: ProbeGeometryProvider, + settings: ProbeSettings, builder: ProbeBuilder, additionalModesBuilder: MultimodalProbeBuilder, ) -> None: super().__init__() self._geometryProvider = geometryProvider + self._settings = settings self._builder = builder self._additionalModesBuilder = additionalModesBuilder self._probe = Probe() @@ -29,7 +32,7 @@ def __init__( self._rebuild() - def assign(self, item: ProbeRepositoryItem) -> None: + def assignItem(self, item: ProbeRepositoryItem) -> None: self._removeGroup('additional_modes') self._additionalModesBuilder.removeObserver(self) self._additionalModesBuilder = item.getAdditionalModesBuilder().copy() @@ -37,6 +40,11 @@ def assign(self, item: ProbeRepositoryItem) -> None: self._addGroup('additional_modes', self._additionalModesBuilder, observe=True) self.setBuilder(item.getBuilder().copy()) + self._rebuild() + + def assign(self, probe: Probe) -> None: + builder = FromMemoryProbeBuilder(self._settings, probe) + self.setBuilder(builder) def syncToSettings(self) -> None: for parameter in self.parameters().values(): @@ -57,7 +65,6 @@ def setBuilder(self, builder: ProbeBuilder) -> None: self._builder = builder self._builder.addObserver(self) self._addGroup('builder', self._builder, observe=True) - self._rebuild() def _rebuild(self) -> None: try: diff --git a/ptychodus/model/product/probe/itemFactory.py b/ptychodus/model/product/probe/itemFactory.py index c29ba77e..bf49109a 100644 --- a/ptychodus/model/product/probe/itemFactory.py +++ b/ptychodus/model/product/probe/itemFactory.py @@ -33,7 +33,7 @@ def create( else FromMemoryProbeBuilder(self._settings, probe) ) multimodalBuilder = MultimodalProbeBuilder(self._rng, self._settings) - return ProbeRepositoryItem(geometryProvider, builder, multimodalBuilder) + return ProbeRepositoryItem(geometryProvider, self._settings, builder, multimodalBuilder) def createFromSettings(self, geometryProvider: ProbeGeometryProvider) -> ProbeRepositoryItem: try: @@ -43,4 +43,4 @@ def createFromSettings(self, geometryProvider: ProbeGeometryProvider) -> ProbeRe builder = self._builderFactory.createDefault() multimodalBuilder = MultimodalProbeBuilder(self._rng, self._settings) - return ProbeRepositoryItem(geometryProvider, builder, multimodalBuilder) + return ProbeRepositoryItem(geometryProvider, self._settings, builder, multimodalBuilder) diff --git a/ptychodus/model/product/probe/multimodal.py b/ptychodus/model/product/probe/multimodal.py index 1563ad6e..22c614ed 100644 --- a/ptychodus/model/product/probe/multimodal.py +++ b/ptychodus/model/product/probe/multimodal.py @@ -119,6 +119,8 @@ def _adjustRelativePower(self, probe: WavefieldArrayType) -> WavefieldArrayType: def build(self, probe: Probe) -> Probe: if self.numberOfModes.getValue() <= 1: return probe + elif self.numberOfModes.getValue() == probe.numberOfModes: + return probe array = self._initializeModes(probe.array) diff --git a/ptychodus/model/product/productGeometry.py b/ptychodus/model/product/productGeometry.py index 93c431d1..04a744cb 100644 --- a/ptychodus/model/product/productGeometry.py +++ b/ptychodus/model/product/productGeometry.py @@ -1,13 +1,14 @@ import numpy -from ptychodus.api.object import ObjectGeometry, ObjectGeometryProvider -from ptychodus.api.observer import Observable, Observer -from ptychodus.api.probe import ProbeGeometry, ProbeGeometryProvider from ptychodus.api.constants import ( ELECTRON_VOLT_J, LIGHT_SPEED_M_PER_S, PLANCK_CONSTANT_J_PER_HZ, ) +from ptychodus.api.geometry import PixelGeometry +from ptychodus.api.object import ObjectGeometry, ObjectGeometryProvider +from ptychodus.api.observer import Observable, Observer +from ptychodus.api.probe import ProbeGeometry, ProbeGeometryProvider from ..patterns import PatternSizer from .metadata import MetadataRepositoryItem @@ -63,6 +64,12 @@ def objectPlanePixelWidthInMeters(self) -> float: def objectPlanePixelHeightInMeters(self) -> float: return self._lambdaZInSquareMeters / self._patternSizer.getHeightInMeters() + def getPixelGeometry(self) -> PixelGeometry: + return PixelGeometry( + widthInMeters=self.objectPlanePixelWidthInMeters, + heightInMeters=self.objectPlanePixelHeightInMeters, + ) + @property def fresnelNumber(self) -> float: widthInMeters = self._patternSizer.getWidthInMeters() diff --git a/ptychodus/model/product/productRepository.py b/ptychodus/model/product/productRepository.py index 632b31b4..71e7751c 100644 --- a/ptychodus/model/product/productRepository.py +++ b/ptychodus/model/product/productRepository.py @@ -70,8 +70,8 @@ def _insertProduct(self, item: ProductRepositoryItem) -> int: def insertNewProduct( self, - name: str, *, + name: str = '', comments: str = '', detectorDistanceInMeters: float | None = None, probeEnergyInElectronVolts: float | None = None, @@ -92,13 +92,6 @@ def insertNewProduct( probeItem = self._probeRepositoryItemFactory.create(geometry) objectItem = self._objectRepositoryItemFactory.create(geometry) - if likeIndex >= 0: - sourceItem = self._itemList[likeIndex] - metadataItem.assign(sourceItem.getMetadata()) - scanItem.assign(sourceItem.getScan()) - probeItem.assign(sourceItem.getProbe()) - objectItem.assign(sourceItem.getObject()) - item = ProductRepositoryItem( parent=self, metadata=metadataItem, @@ -110,6 +103,9 @@ def insertNewProduct( costs=list(), ) + if likeIndex >= 0: + item.assignItem(self._itemList[likeIndex], notify=False) + return self._insertProduct(item) def insertProductFromSettings(self) -> int: diff --git a/ptychodus/model/product/scan/builder.py b/ptychodus/model/product/scan/builder.py index f1e8c93c..1be11dfe 100644 --- a/ptychodus/model/product/scan/builder.py +++ b/ptychodus/model/product/scan/builder.py @@ -55,8 +55,10 @@ def __init__( super().__init__(settings, 'from_file') self._settings = settings self.filePath = settings.filePath.copy() + self.filePath.setValue(filePath) self._addParameter('file_path', self.filePath) self.fileType = settings.fileType.copy() + self.fileType.setValue(fileType) self._addParameter('file_type', self.fileType) self._fileReader = fileReader diff --git a/ptychodus/model/product/scan/item.py b/ptychodus/model/product/scan/item.py index be81986b..3585df04 100644 --- a/ptychodus/model/product/scan/item.py +++ b/ptychodus/model/product/scan/item.py @@ -9,7 +9,7 @@ from ptychodus.api.scan import Scan, ScanBoundingBox, ScanPoint from .boundingBox import ScanBoundingBoxBuilder -from .builder import ScanBuilder +from .builder import FromMemoryScanBuilder, ScanBuilder from .settings import ScanSettings from .transform import ScanPointTransform @@ -24,6 +24,7 @@ def __init__( transform: ScanPointTransform, ) -> None: super().__init__() + self._settings = settings self._builder = builder self._transform = transform @@ -60,7 +61,7 @@ def __init__( self._rebuild() - def assign(self, item: ScanRepositoryItem) -> None: + def assignItem(self, item: ScanRepositoryItem) -> None: self._removeGroup('transform') self._transform.removeObserver(self) self._transform = item.getTransform().copy() @@ -69,6 +70,10 @@ def assign(self, item: ScanRepositoryItem) -> None: self.setBuilder(item.getBuilder().copy()) + def assign(self, scan: Scan) -> None: + builder = FromMemoryScanBuilder(self._settings, scan) + self.setBuilder(builder) + def syncToSettings(self) -> None: for parameter in self.parameters().values(): parameter.syncValueToParent() diff --git a/ptychodus/model/reconstructor/api.py b/ptychodus/model/reconstructor/api.py index d657961a..c04fd699 100644 --- a/ptychodus/model/reconstructor/api.py +++ b/ptychodus/model/reconstructor/api.py @@ -37,12 +37,16 @@ def reconstruct( inputProductIndex, indexFilter ) + outputProductIndex = self._productRepository.insertNewProduct(likeIndex=inputProductIndex) + outputProduct = self._productRepository[outputProductIndex] + tic = time.perf_counter() result = reconstructor.reconstruct(parameters) toc = time.perf_counter() logger.info(f'Reconstruction time {toc - tic:.4f} seconds. (code={result.result})') - outputProductIndex = self._productRepository.insertProduct(result.product) + outputProduct.assign(result.product) + return outputProductIndex def reconstructSplit(self, inputProductIndex: int, outputProductName: str) -> tuple[int, int]: diff --git a/ptychodus/model/reconstructor/matcher.py b/ptychodus/model/reconstructor/matcher.py index 5ccd2a5d..a3c47c7f 100644 --- a/ptychodus/model/reconstructor/matcher.py +++ b/ptychodus/model/reconstructor/matcher.py @@ -52,6 +52,8 @@ def getObjectPlanePixelGeometry(self, inputProductIndex: int) -> PixelGeometry: def matchDiffractionPatternsWithPositions( self, inputProductIndex: int, indexFilter: ScanIndexFilter = ScanIndexFilter.ALL ) -> ReconstructInput: + goodPixelMask = self._diffractionDataset.getGoodPixelMask() + inputProductItem = self._productRepository[inputProductIndex] inputProduct = inputProductItem.getProduct() dataIndexes = self._diffractionDataset.getAssembledIndexes() @@ -85,4 +87,4 @@ def matchDiffractionPatternsWithPositions( costs=inputProduct.costs, ) - return ReconstructInput(patterns, product) + return ReconstructInput(patterns, goodPixelMask, product) diff --git a/ptychodus/model/tike/settings.py b/ptychodus/model/tike/settings.py index 6878dd43..0b410dbe 100644 --- a/ptychodus/model/tike/settings.py +++ b/ptychodus/model/tike/settings.py @@ -1,4 +1,3 @@ -from __future__ import annotations from collections.abc import Sequence import logging