[d6876d]: / src / pages / Simulations / Simulations.tsx

Download this file

245 lines (229 with data), 7.1 kB

import React, { useState, useCallback } from 'react';
import {
  Box,
  Typography,
  Paper,
  Grid,
  Card,
  CardContent,
  LinearProgress,
  Button,
  Stack,
  CircularProgress,
  Alert,
} from '@mui/material';
import {
  LineChart,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  RadarChart,
  PolarGrid,
  PolarAngleAxis,
  PolarRadiusAxis,
  Radar,
} from 'recharts';
import { usePipeline, useSimulationResults } from '../../hooks/usePipeline';
import { mockGeneAssemblies, getRandomColor } from '../../data/mockData';

const Simulations: React.FC = () => {
  const [isSimulating, setIsSimulating] = useState(false);
  const [progress, setProgress] = useState(0);
  const { startPipeline, isProcessing, error, clearError } = usePipeline();
  const simulationResults = useSimulationResults();

  const startSimulation = useCallback(async () => {
    setIsSimulating(true);
    setProgress(0);

    const mockConfig = {
      id: Math.random().toString(36).substr(2, 9),
      name: 'Quantum Simulation',
      environmentalParams: {
        temperature: 25,
        humidity: 60,
        soilConditions: 'Controlled',
      },
      duration: 96,
      samplingFrequency: 24,
      baselineGenotypes: ['WT-Col-0'],
      targetTraits: ['stress_tolerance', 'growth_rate'],
    };

    // Use first gene assembly for simulation
    await startPipeline({
      experimentConfig: mockConfig,
      assembly: mockGeneAssemblies[0],
    });

    const interval = setInterval(() => {
      setProgress((prev) => {
        if (prev >= 100) {
          clearInterval(interval);
          setIsSimulating(false);
          return 100;
        }
        return prev + 10;
      });
    }, 500);
  }, [startPipeline]);

  const renderQuantumMetrics = (result: any) => {
    const data = [
      { name: 'Coherence', value: result.quantumMetrics.coherenceTime },
      { name: 'Gate Error', value: result.quantumMetrics.gateErrors * 100 },
      { name: 'Volume', value: result.quantumMetrics.quantumVolume / 10 },
      { name: 'Circuit', value: result.quantumMetrics.circuitDepth / 2 },
    ];

    return (
      <Box sx={{ height: 300, width: '100%' }}>
        <Typography variant="subtitle2" gutterBottom>
          Quantum Computing Metrics
        </Typography>
        <ResponsiveContainer>
          <RadarChart data={data}>
            <PolarGrid />
            <PolarAngleAxis dataKey="name" />
            <PolarRadiusAxis />
            <Radar
              name="Quantum Metrics"
              dataKey="value"
              stroke="#8884d8"
              fill="#8884d8"
              fillOpacity={0.6}
            />
          </RadarChart>
        </ResponsiveContainer>
      </Box>
    );
  };

  const renderOptimizationResults = (result: any) => {
    const data = result.optimizationMetrics.energyLandscape.map((value: number, index: number) => ({
      step: index,
      energy: value,
    }));

    return (
      <Box sx={{ height: 300, width: '100%' }}>
        <Typography variant="subtitle2" gutterBottom>
          Energy Landscape Optimization
        </Typography>
        <ResponsiveContainer>
          <LineChart data={data}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="step" />
            <YAxis />
            <Tooltip />
            <Legend />
            <Line
              type="monotone"
              dataKey="energy"
              stroke="#82ca9d"
              name="Energy Level"
            />
          </LineChart>
        </ResponsiveContainer>
      </Box>
    );
  };

  const renderPredictions = (result: any) => {
    return (
      <Box sx={{ height: 300, width: '100%' }}>
        <Typography variant="subtitle2" gutterBottom>
          Trait Predictions Over Time
        </Typography>
        <ResponsiveContainer>
          <LineChart data={result.results}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="timepoint" />
            <YAxis />
            <Tooltip />
            <Legend />
            {result.results[0].predictions.map((pred: any) => (
              <Line
                key={pred.trait}
                type="monotone"
                data={result.results.map((r: any) => ({
                  timepoint: r.timepoint,
                  value: r.predictions.find((p: any) => p.trait === pred.trait).value,
                }))}
                dataKey="value"
                name={pred.trait}
                stroke={getRandomColor()}
              />
            ))}
          </LineChart>
        </ResponsiveContainer>
      </Box>
    );
  };

  return (
    <Box>
      <Typography variant="h4" gutterBottom>
        Quantum-Enhanced Simulations
      </Typography>

      {error && (
        <Alert severity="error" onClose={clearError} sx={{ mb: 2 }}>
          {error}
        </Alert>
      )}

      <Grid container spacing={3}>
        <Grid item xs={12} md={4}>
          <Paper sx={{ p: 2 }}>
            <Typography variant="h6" gutterBottom>
              New Simulation
            </Typography>
            <Button
              variant="contained"
              fullWidth
              onClick={startSimulation}
              disabled={isSimulating || isProcessing}
              sx={{ mb: 2 }}
            >
              {isSimulating || isProcessing ? (
                <CircularProgress size={24} />
              ) : (
                'Start Simulation'
              )}
            </Button>
            {(isSimulating || isProcessing) && (
              <Box sx={{ width: '100%' }}>
                <LinearProgress variant="determinate" value={progress} />
                <Typography variant="body2" color="text.secondary" align="center" sx={{ mt: 1 }}>
                  {progress}% Complete
                </Typography>
              </Box>
            )}
          </Paper>
        </Grid>

        <Grid item xs={12} md={8}>
          <Stack spacing={2}>
            {simulationResults.map((result) => (
              <Card key={result.id}>
                <CardContent>
                  <Grid container spacing={3}>
                    <Grid item xs={12}>
                      <Typography variant="h6" gutterBottom>
                        Simulation Results
                      </Typography>
                      <Typography variant="body2" color="text.secondary">
                        {new Date(result.timestamp).toLocaleString()}
                      </Typography>
                    </Grid>
                    <Grid item xs={12}>
                      {renderQuantumMetrics(result)}
                    </Grid>
                    <Grid item xs={12} md={6}>
                      {renderOptimizationResults(result)}
                    </Grid>
                    <Grid item xs={12} md={6}>
                      {renderPredictions(result)}
                    </Grid>
                  </Grid>
                </CardContent>
              </Card>
            ))}
          </Stack>
        </Grid>
      </Grid>
    </Box>
  );
};

export default Simulations;