[docs]def__init__(self,path:str,requireBidirectionalCorrection:bool=False,)->None:self.logger=logging.getLogger("main")self.availableData=[]try:# loading tile data from JSON before parsingdata=json.load(open(path,'r'))exceptExceptionase:self.logger.error(f"Could not open JSON at provided path {path}.\nERROR:{e}")raiseTileDataError(f"Could not open JSON at provided path {path}.\nERROR:{e}")try:# put all required keys in a try/except# Check if overarching TileData item is found in the JSONtry:tileData=data['TileData']exceptKeyErrorase:self.logger.exception("Required key 'TileData' not found in provided JSON")raiseTileDataError("Required key 'TileData' not found in provided JSON")self.logger.info('Found TileData within provided JSON')# Within TileData, check for known keys and handle any missing keys.try:self.tileID=tileData.pop('tileID',None)self.availableData.append('tileID')exceptKeyErrorase:self.logger.error("Required key 'tileID' not found in tile data JSON")raiseTileDataError("Required key 'tileID' not found in tile data JSON")try:self.tileResolution=np.array(tileData.pop('tileResolution',None),dtype=np.uint16)self.availableData.append('tileResolution')exceptKeyErrorase:self.logger.error("Required key 'tileResolution' not found in tile data JSON")raiseTileDataError("Required key 'tileResolution' not found in tile data JSON")try:self.tileChannelsAvailable=np.array(tileData.pop('tileChannelsAvailable',None),dtype=np.uint8)self.availableData.append('tileChannelsAvailable')exceptKeyErrorase:self.logger.error("Required key 'tileChannelsAvailable' not found in tile data JSON")raiseTileDataError("Required key 'tileChannelsAvailable' not found in tile data JSON")try:self.channelsAcquired=np.array(tileData.pop('channelsAcquired',None),dtype=np.uint8)self.availableData.append('channelsAcquired')exceptKeyErrorase:self.logger.error("Required key 'channelsAcquired' not found in tile data JSON")raiseTileDataError("Required key 'channelsAcquired' not found in tile data JSON")try:self.channelsSaved=np.array(tileData.pop('channelsSaved',None),dtype=np.uint8)self.availableData.append('channelsSaved')exceptKeyErrorase:self.logger.error("Required key 'channelsSaved' not found in tile data JSON")raiseTileDataError("Required key 'channelsSaved' not found in tile data JSON")try:self.framesPerTile=int(tileData.pop('framesPerTile',None))self.availableData.append('framesPerTile')exceptKeyErrorase:self.logger.error("Required key 'framesPerTile' not found in tile data JSON")raiseTileDataError("Required key 'framesPerTile' not found in tile data JSON")try:self.tileScannedThisFile=_int_or_int_array(tileData.pop('tileScannedThisFile'),logger=self.logger)self.availableData.append('tileScannedThisFile')exceptKeyErrorase:self.logger.error("Required key 'tileScannedThisFile' not found in tile data JSON")raiseTileDataError("Required key 'tileScannedThisFile' not found in tile data JSON")try:self.tileZs=_int_or_int_array(tileData.pop('tileZs',None),logger=self.logger)self.availableData.append('tileZs')exceptKeyErrorase:self.logger.error("Required key 'tileZs' not found in tile data JSON")raiseTileDataError("Required key 'tileZs' not found in tile data JSON")exceptExceptionase:# for all non-key error exceptionsself.logger.exception(f"Failed to load required information from tile data JSON.\nEXCEPTION: {e}")raiseTileDataError(f"Failed to load required information from tile data JSON.\nEXCEPTION: {e}")self.logger.info("Successfully loaded all required keys from tile data JSON")# bidirectional correction is optional, but can be required if parameter set to True during TileData obj init.try:self.bidirectionalCorrection=int(tileData.pop('bidirectionalCorrection',None))self.availableData.append('bidirectionalCorrection')exceptExceptionase:ifrequireBidirectionalCorrection:self.logger.exception(f"Failed to load bidirectional correction when it was required.\nEXCEPTION: {e}")raiseTileDataError(f"Failed to load bidirectional correction when it was required.\nEXCEPTION: {e}")self.logger.warning(f"'bidirectionalCorrection' could not be loaded from tile data JSON.\nMSG: {e}")self.bidirectionalCorrection=None# all other known tiledata stuff is not required, so can handle any exceptions with a warning try:self.tileAffine=np.array(tileData.pop('tileAffine',None),dtype=np.float32)self.availableData.append('tileAffine')exceptExceptionase:self.logger.warning("'tileAffine' could not be loaded from tile data JSON")self.tileAffine=Nonetry:self.displayAvgFactor=int(tileData.pop('displayAvgFactor',None))self.availableData.append('displayAvgFactor')exceptExceptionase:self.logger.warning("'displayAvgFactor' could not be loaded from tile data JSON")self.displayAvgFactor=Nonetry:self.tileSamplePointXY=np.array(tileData.pop('tileSamplePointXY',None),dtype=np.float32)self.availableData.append('tileSamplePointXY')exceptExceptionase:# sample point XY is necessary for recognizing how many tiles were actually recordedself.logger.warning("'tileSamplePointXY' could not be loaded from tile data JSON")self.tileSamplePointXY=Nonetry:self.tileSizeUm=np.array(tileData.pop('tileSizeUm',None),dtype=np.uint16)self.availableData.append('tileSizeUm')exceptExceptionase:self.logger.warning("'tileSizeUm' could not be loaded from tile data JSON")self.tileSizeUm=Nonetry:self.tileCornerPtsUm=np.array(tileData.pop('tileCornerPtsUm',None),dtype=np.float32)self.availableData.append('tileCornerPtsUm')exceptExceptionase:self.logger.warning("'tileCornerPtsUm' could not be loaded from tile data JSON")self.tileCornerPtsUm=Nonetry:self.isFastZ=bool(tileData.pop('isFastZ',None))self.availableData.append('isFastZ')exceptExceptionase:self.logger.warning("'isFastZ' could not be loaded from tile data JSON")self.isFastZ=Nonetry:self.numTilesToScan=int(tileData.pop('numTilesToScan',None))self.availableData.append('numTilesToScan')exceptExceptionase:self.logger.warning("'numTilesToScan' could not be loaded from tile data JSON")self.numTilesToScan=None# If there are remaining keys that were not handled, let the user know.iflen(tileData)!=0:self.logger.warning(f"Found {len(tileData)} unrecognized keys in tile data JSON. Continuing...")
def__repr__(self):returnf"TileData object with {len(self.availableData)} available datapoints. Use 'availableData' attribute to see them."def__str__(self):returnf"TileData object with {len(self.availableData)} available datapoints. Use 'availableData' attribute to see them."def__len__(self):returnlen(self.availableData)