Spaces:
Running
Running
File size: 4,109 Bytes
3bb804c |
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 |
"""
Bio-Tools: Utilities for the Artificial Life Ecosystem
------------------------------------------------------
1. Genomic Noise: Generates organic 1/f noise vectors for DNA seeding.
2. Vector Blender: Manually mix two DNA strands.
"""
import numpy as np
# --- STRICT COMPATIBILITY IMPORTS ---
import __main__
try:
BaseNode = __main__.BaseNode
QtGui = __main__.QtGui
except AttributeError:
from PyQt6 import QtGui
class BaseNode:
def get_blended_input(self, name, mode): return None
class GenomicNoiseNode(BaseNode):
"""
Generates 'Pink Noise' (1/f) vectors.
Biological systems are rarely random; they are correlated.
This creates DNA that looks more 'organic' and less like static.
"""
NODE_CATEGORY = "Artificial Life"
NODE_COLOR = QtGui.QColor(100, 150, 100) # Sage Green
def __init__(self):
super().__init__()
self.node_title = "Genomic Noise"
self.inputs = {
'volatility': 'signal', # How fast the noise changes
'roughness': 'signal' # High frequency content
}
self.outputs = {
'dna_spectrum': 'spectrum', # Vector output
'value': 'signal' # Single value
}
self.length = 128
self.state = np.zeros(self.length)
self.smooth_state = np.zeros(self.length)
# Buffers
self.out_spectrum = np.zeros(self.length)
self.out_value = 0.0
def step(self):
vol = self.get_blended_input('volatility', 'mean')
rough = self.get_blended_input('roughness', 'mean')
if vol is None: vol = 0.1
if rough is None: rough = 0.5
# Generate new target noise
target = np.random.randn(self.length) * rough
# Smoothly interpolate (Brownian motion-ish)
self.state = self.state * (1.0 - vol) + target * vol
# Apply smoothing for "structure"
# Simple moving average to simulate correlations
kernel_size = 3
self.smooth_state = np.convolve(self.state, np.ones(kernel_size)/kernel_size, mode='same')
# Normalize to 0..1 range typically expected by DNA,
# but centered around 0 is also fine for phases.
# Let's keep it raw but bounded slightly
self.out_spectrum = np.clip(self.smooth_state, -2.0, 2.0)
self.out_value = float(np.mean(np.abs(self.out_spectrum)))
def get_output(self, name):
if name == 'dna_spectrum': return self.out_spectrum
if name == 'value': return self.out_value
return None
class VectorMathNode(BaseNode):
"""
Simple math for DNA vectors.
"""
NODE_CATEGORY = "Artificial Life"
NODE_COLOR = QtGui.QColor(100, 100, 150)
def __init__(self):
super().__init__()
self.node_title = "Vector Math"
self.inputs = {
'vec_a': 'spectrum',
'vec_b': 'spectrum',
'op_mode': 'signal' # 0=Add, 1=Sub, 2=Mult
}
self.outputs = {
'result': 'spectrum'
}
self.out_result = np.zeros(128)
def step(self):
a = self.get_blended_input('vec_a', 'mean')
b = self.get_blended_input('vec_b', 'mean')
mode = self.get_blended_input('op_mode', 'mean')
if a is None: a = np.zeros(128)
if b is None: b = np.zeros(128)
# Resize to match
target_len = max(len(a), len(b))
if len(a) < target_len: a = np.resize(a, target_len)
if len(b) < target_len: b = np.resize(b, target_len)
if mode is None: mode = 0
if mode < 0.5: # ADD
res = a + b
elif mode < 1.5: # SUB
res = a - b
else: # MULT
res = a * b
self.out_result = res
def get_output(self, name):
if name == 'result': return self.out_result
return None |