"""PyTorch and TensorFlow dataset classes for orbit prediction.""" import numpy as np import torch from torch.utils.data import Dataset, DataLoader class OrbitDataset(Dataset): """PyTorch Dataset for orbit prediction sequences.""" def __init__(self, inputs: np.ndarray, targets: np.ndarray): """ Args: inputs: (N, input_steps, features) — input sequences targets: (N, horizon_steps, 3) — target positions (x, y, z) """ self.inputs = torch.from_numpy(inputs) self.targets = torch.from_numpy(targets) def __len__(self): return len(self.inputs) def __getitem__(self, idx): return self.inputs[idx], self.targets[idx] class MultiModalDataset(Dataset): """PyTorch Dataset combining orbit positions with solar wind features.""" def __init__( self, orbit_inputs: np.ndarray, solar_inputs: np.ndarray, targets: np.ndarray, ): """ Args: orbit_inputs: (N, input_steps, orbit_features) solar_inputs: (N, input_steps, solar_features) targets: (N, horizon_steps, 3) """ self.orbit_inputs = torch.from_numpy(orbit_inputs) self.solar_inputs = torch.from_numpy(solar_inputs) self.targets = torch.from_numpy(targets) def __len__(self): return len(self.orbit_inputs) def __getitem__(self, idx): return self.orbit_inputs[idx], self.solar_inputs[idx], self.targets[idx] def create_dataloaders( splits: dict[str, tuple[np.ndarray, np.ndarray]], batch_size: int = 64, num_workers: int = 0, ) -> dict[str, DataLoader]: """Create PyTorch DataLoaders from train/val/test splits. Args: splits: Dict from OrbitPreprocessor.temporal_split() batch_size: Batch size num_workers: Number of data loading workers Returns: Dict of DataLoaders keyed by 'train', 'val', 'test' """ loaders = {} for split_name, (inputs, targets) in splits.items(): dataset = OrbitDataset(inputs, targets) loaders[split_name] = DataLoader( dataset, batch_size=batch_size, shuffle=(split_name == "train"), num_workers=num_workers, pin_memory=torch.cuda.is_available(), ) return loaders def create_multimodal_dataloaders( orbit_splits: dict[str, tuple[np.ndarray, np.ndarray]], solar_inputs_splits: dict[str, np.ndarray], batch_size: int = 64, num_workers: int = 0, ) -> dict[str, DataLoader]: """Create DataLoaders for multi-modal (orbit + solar wind) training.""" loaders = {} for split_name in orbit_splits: orbit_in, targets = orbit_splits[split_name] solar_in = solar_inputs_splits[split_name] dataset = MultiModalDataset(orbit_in, solar_in, targets) loaders[split_name] = DataLoader( dataset, batch_size=batch_size, shuffle=(split_name == "train"), num_workers=num_workers, pin_memory=torch.cuda.is_available(), ) return loaders def create_tf_dataset( inputs: np.ndarray, targets: np.ndarray, batch_size: int = 64, shuffle: bool = True, ): """Create a TensorFlow dataset from numpy arrays. Returns a tf.data.Dataset or None if TF is not available. """ try: import tensorflow as tf dataset = tf.data.Dataset.from_tensor_slices((inputs, targets)) if shuffle: dataset = dataset.shuffle(buffer_size=min(len(inputs), 10000)) dataset = dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE) return dataset except ImportError: print("TensorFlow not available, skipping TF dataset creation") return None