File size: 6,351 Bytes
654bfe6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import React, { useState } from 'react';
import { OrganType } from '../types';
import { GTEX_ORGAN_PROFILES } from '../utils/siderDataset';
import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, Tooltip, CartesianGrid } from 'recharts';
import { Database, Dna, Activity, Cpu, Layers, Info, BarChart2 } from 'lucide-react';

export const OrganProfilesPanel: React.FC = () => {
  const [selectedOrgan, setSelectedOrgan] = useState<OrganType>('liver');

  const profile = GTEX_ORGAN_PROFILES[selectedOrgan];

  // Map 128-dim gene expression vector to 20 sampled feature buckets for clean visualization
  const sampledExpressionData = profile.geneExpressionValues.slice(0, 20).map((val, idx) => ({
    geneDim: `Dim ${idx + 1}`,
    expression: Number(val.toFixed(2))
  }));

  const organList: { id: OrganType; icon: string; title: string }[] = [
    { id: 'liver', icon: '🫀', title: 'Liver (Hepatic)' },
    { id: 'heart', icon: '❤️', title: 'Heart (Cardiac)' },
    { id: 'kidney', icon: '🩺', title: 'Kidney (Renal)' },
    { id: 'brain', icon: '🧠', title: 'Brain (Central Nervous)' },
    { id: 'lung', icon: '🫁', title: 'Lung (Pulmonary)' },
  ];

  return (
    <div className="space-y-6">
      
      {/* Header */}
      <div className="bg-slate-900 border border-slate-800 rounded-2xl p-5 shadow-lg space-y-3">
        <div className="flex items-center space-x-2 border-b border-slate-800 pb-3">
          <Dna className="w-5 h-5 text-indigo-400" />
          <div>
            <h2 className="text-base font-bold text-white">GTEx V8 Human Organ Transcriptomic Profiles</h2>
            <p className="text-xs text-slate-400">RNA-Seq Gene Expression Profiles across 5 Primary Human Organs</p>
          </div>
        </div>

        {/* Organ Selector Chips */}
        <div className="flex overflow-x-auto space-x-2 pt-1 no-scrollbar">
          {organList.map((item) => (
            <button
              key={item.id}
              onClick={() => setSelectedOrgan(item.id)}
              className={`whitespace-nowrap px-4 py-2.5 rounded-xl text-xs font-bold transition-all border flex items-center space-x-2 ${
                selectedOrgan === item.id
                  ? 'bg-indigo-600 text-white border-indigo-400 shadow-lg shadow-indigo-600/30'
                  : 'bg-slate-950 border-slate-800 text-slate-300 hover:bg-slate-800'
              }`}
            >
              <span>{item.icon}</span>
              <span>{item.title}</span>
            </button>
          ))}
        </div>
      </div>

      {/* Main Organ Details Grid */}
      <div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
        
        {/* Left Column: Marker Genes & Details */}
        <div className="lg:col-span-5 bg-slate-900 border border-slate-800 rounded-2xl p-5 shadow-lg space-y-4">
          
          <div className="flex items-center space-x-3">
            <div className="p-3 bg-indigo-600/20 text-indigo-300 rounded-2xl border border-indigo-500/30 text-xl">
              {selectedOrgan === 'liver' ? '🫀' : selectedOrgan === 'heart' ? '❤️' : selectedOrgan === 'kidney' ? '🩺' : selectedOrgan === 'brain' ? '🧠' : '🫁'}
            </div>
            <div>
              <h3 className="text-base font-bold text-white">{profile.name}</h3>
              <span className="text-xs text-indigo-400 font-mono font-semibold">GTEx V8 ID: gtex_{profile.id}_v8</span>
            </div>
          </div>

          <p className="text-xs text-slate-300 leading-relaxed bg-slate-950 p-3 rounded-xl border border-slate-800/80">
            {profile.description}
          </p>

          {/* Key Marker Genes */}
          <div className="space-y-2">
            <span className="text-xs font-bold text-slate-300 block">Top GTEx Marker & Target Genes:</span>
            <div className="flex flex-wrap gap-1.5">
              {profile.markerGenes.map((gene, idx) => (
                <span
                  key={idx}
                  className="text-xs font-mono font-bold bg-indigo-950/80 text-indigo-300 border border-indigo-800/80 px-2.5 py-1 rounded-lg"
                >
                  {gene}
                </span>
              ))}
            </div>
          </div>

          <div className="bg-slate-950 p-3 rounded-xl border border-slate-800 space-y-1 text-xs">
            <span className="font-bold text-emerald-400 block">16-Head Cross-Attention Mechanism:</span>
            <p className="text-slate-400 text-[11px] leading-normal">
              EpiADR-Net projects the 128-dimensional expression vector of this organ into key/value attention heads, cross-querying SMILES atomic feature embeddings to predict tissue-conditioned toxicity.
            </p>
          </div>

        </div>

        {/* Right Column: 128-dim Expression Vector Visualizer */}
        <div className="lg:col-span-7 bg-slate-900 border border-slate-800 rounded-2xl p-5 shadow-lg space-y-4">
          <div className="flex items-center justify-between border-b border-slate-800 pb-3">
            <div className="flex items-center space-x-2">
              <BarChart2 className="w-5 h-5 text-indigo-400" />
              <h3 className="text-base font-bold text-white">RNA-Seq Expression Vector Distribution</h3>
            </div>
            <span className="text-xs text-slate-400 font-mono">128-Dim Vector</span>
          </div>

          <div className="h-64 bg-slate-950 p-3 rounded-xl border border-slate-800">
            <ResponsiveContainer width="100%" height="100%">
              <BarChart data={sampledExpressionData}>
                <CartesianGrid strokeDasharray="3 3" stroke="#1e293b" />
                <XAxis dataKey="geneDim" stroke="#64748b" fontSize={9} />
                <YAxis stroke="#64748b" fontSize={10} />
                <Tooltip contentStyle={{ backgroundColor: '#0f172a', borderColor: '#334155', borderRadius: '8px', fontSize: '11px' }} />
                <Bar dataKey="expression" fill="#6366f1" radius={[4, 4, 0, 0]} name="Log2 (TPM + 1)" />
              </BarChart>
            </ResponsiveContainer>
          </div>

          <p className="text-[11px] text-slate-400 text-center font-mono">
            Showing sampled dimensions 1-20 of 128-dim normalized GTEx V8 transcriptomic organ expression vector.
          </p>
        </div>

      </div>

    </div>
  );
};