{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":87793,"databundleVersionId":12024591,"sourceType":"competition"}],"dockerImageVersionId":31012,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Third Notebook for the Stanford RNA Kaggle\n\n## Dummy model to generate RNA chain of length 10\n\n### C-1 distances are set to 6 Angstroms angles to 140 degrees between three consecutive C-3 atoms","metadata":{}},{"cell_type":"code","source":"### Loading Relevant Packages\n\nimport os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib import colormaps\nfrom mpl_toolkits.mplot3d import Axes3D","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:08.816452Z","iopub.execute_input":"2025-05-02T14:16:08.816810Z","iopub.status.idle":"2025-05-02T14:16:08.824123Z","shell.execute_reply.started":"2025-05-02T14:16:08.816782Z","shell.execute_reply":"2025-05-02T14:16:08.822510Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def initial_RNA_input():\n    n_vectors = 10\n    angle_deg = 140\n    length = 6\n    return n_vectors, angle_deg, length\n\nn_vectors, angle_deg, length = initial_RNA_input()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:08.826167Z","iopub.execute_input":"2025-05-02T14:16:08.826720Z","iopub.status.idle":"2025-05-02T14:16:08.832594Z","shell.execute_reply.started":"2025-05-02T14:16:08.826685Z","shell.execute_reply":"2025-05-02T14:16:08.831489Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Helper function to generate a new vector at a fixed angle to the previous one\n# This new vector is not influenced by the center of all the vectors\n\ndef generate_next_vector(v_prev, angle_deg, length_vector = length):\n    # Conver v_prev to a unit vector\n    v_prev = v_prev / np.linalg.norm(v_prev)  \n\n    # Step 1: Create a random vector\n    rand_vec = np.random.randn(3)\n\n    # Step 2: Make it orthogonal to v_prev\n    rand_vec -= np.dot(rand_vec, v_prev) * v_prev\n    rand_vec /= np.linalg.norm(rand_vec)\n\n    # Step 3: Rotate v_prev toward rand_vec by angle_rad\n    # The 180 - angle_deg is to correctly calculate the angle based on how the vectors are pointing\n    v_new = np.cos(np.deg2rad(180 - angle_deg)) * v_prev + np.sin(np.deg2rad(180 - angle_deg)) * rand_vec\n\n    # Step 4: Ensure the length of the new vector is correct\n    v_new_final = length_vector * (v_new / np.linalg.norm(v_new)) \n\n    # Step 4: Normalize and scale to desired length\n    return v_new_final\n\nrandom_vector = generate_next_vector([6, 0, 0], angle_deg, length_vector = length)\nrandom_vector","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:08.833792Z","iopub.execute_input":"2025-05-02T14:16:08.834130Z","iopub.status.idle":"2025-05-02T14:16:08.845336Z","shell.execute_reply.started":"2025-05-02T14:16:08.834096Z","shell.execute_reply":"2025-05-02T14:16:08.844112Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Initialization\n\ndef initialization():\n    vectors = []\n    v0 = np.array([length, 0, 0])\n    vectors.append(v0)\n    return vectors\n\nvectors_initialized = initialization() \nvectors_initialized","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:08.846359Z","iopub.execute_input":"2025-05-02T14:16:08.846638Z","iopub.status.idle":"2025-05-02T14:16:08.853830Z","shell.execute_reply.started":"2025-05-02T14:16:08.846616Z","shell.execute_reply":"2025-05-02T14:16:08.852709Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Generate the vectors between the C-1 atoms\n\ndef generate_vectors(n_vectors, vectors, angle_deg):\n    for _ in range(n_vectors - 1):\n        new_v = generate_next_vector(vectors[-1], angle_deg)\n        vectors.append(new_v)\n    return vectors \n\nvectors = generate_vectors(n_vectors, vectors_initialized, angle_deg)\nvectors","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:08.856376Z","iopub.execute_input":"2025-05-02T14:16:08.856728Z","iopub.status.idle":"2025-05-02T14:16:08.867003Z","shell.execute_reply.started":"2025-05-02T14:16:08.856699Z","shell.execute_reply":"2025-05-02T14:16:08.865929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Compute the cumulative positions for the generated vectors of C-1 atoms\n\ndef consecutive_positions(vectors):\n    positions = [np.zeros(3)]\n    for v in vectors:\n        positions.append(positions[-1] + v)\n    positions = np.array(positions)\n    return positions\n\npositions = consecutive_positions(vectors)\npositions","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:08.867993Z","iopub.execute_input":"2025-05-02T14:16:08.868300Z","iopub.status.idle":"2025-05-02T14:16:08.877670Z","shell.execute_reply.started":"2025-05-02T14:16:08.868271Z","shell.execute_reply":"2025-05-02T14:16:08.876689Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot3D(positions):\n    # Plotting\n    fig = plt.figure()\n    ax = fig.add_subplot(111, projection='3d')\n    ax.plot(positions[:, 0], positions[:, 1], positions[:, 2], marker='o')\n    \n    ax.set_xlabel('X')\n    ax.set_ylabel('Y')\n    ax.set_zlabel('Z')\n    ax.set_title('Chain of 3D Vectors with 140° Between Each')\n    \n    return plt.show()\n\nplot3D(positions)\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:08.878721Z","iopub.execute_input":"2025-05-02T14:16:08.879044Z","iopub.status.idle":"2025-05-02T14:16:09.066331Z","shell.execute_reply.started":"2025-05-02T14:16:08.879009Z","shell.execute_reply":"2025-05-02T14:16:09.065275Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Check lengths and angles\n\ndef angle_between(v1, v2):\n    cos_theta = np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))\n    cos_theta = np.clip(cos_theta, -1.0, 1.0)  # numerical safety\n    return np.rad2deg(np.arccos(cos_theta))\n\ndef check_angles(vectors):\n    # Compute and print all angles\n    for i in range(len(vectors) - 1):\n        angle = angle_between(vectors[i], -1 * vectors[i + 1])\n        print(f\"Angle between vector {i} and {i+1}: {angle:.2f} degrees\")\n\ndef check_lengths(vectors):\n    for i, v in enumerate(vectors):\n        length = np.linalg.norm(v)\n        print(f\"Vector {i} length: {length:.6f} {'✅' if np.isclose(length, 6.0, atol=1e-6) else '❌'}\")\n\n\ncheck_angles(vectors)\ncheck_lengths(vectors)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:09.067456Z","iopub.execute_input":"2025-05-02T14:16:09.067746Z","iopub.status.idle":"2025-05-02T14:16:09.078713Z","shell.execute_reply.started":"2025-05-02T14:16:09.067724Z","shell.execute_reply":"2025-05-02T14:16:09.077743Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Recap of the entire code\n\n## Dummy model to generate RNA chain of length 10\n\n### C-1 distances are set to 6 Angstroms angles to 140 degrees between three consecutive C-3 atoms","metadata":{}},{"cell_type":"code","source":"## Recap of the entire code\n\n### Initial RNA input\nn_vectors, angle_deg, length = initial_RNA_input()\n\n### Initialize\nvectors_initialized = initialization()\n\n# Generate the new vectors\nvectors = generate_vectors(n_vectors, vectors_initialized, angle_deg)\n\n# Compute the cumulative positions\npositions = consecutive_positions(vectors)\n\n# Plotting\nplot3D(positions)\n\n# Check angles and lengths\ncheck_angles(vectors)\ncheck_lengths(vectors)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T14:16:09.079721Z","iopub.execute_input":"2025-05-02T14:16:09.079991Z","iopub.status.idle":"2025-05-02T14:16:09.241309Z","shell.execute_reply.started":"2025-05-02T14:16:09.079969Z","shell.execute_reply":"2025-05-02T14:16:09.240093Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}