def construct(self):

        # Atom level
        adenine = Text(ADENINE_SMILES)

        # Nucleotide level
        dna = Text('ACTGAATATAGACTATA',
                   t2c={
                       'A': RED,
                       'C': BLUE,
                       'T': GREEN,
                       'G': PURPLE
                   })

        # Amino acid level
        aas = 'VQGGAAVQQEVLA'
        aas = Text(aas, t2c=get_aa_hex_color_dict('skylign_protein'))

        # Logo level
        logo = LoLLogo()

        # Animate... from nucleotide to LoL Commons
        self.wait()
        self.play(Write(adenine))
        self.wait()

        if self.add_vector_transform:
            # FIXME: This is not quite pretty / useful at the moment
            numbers = Text(
                '[0.12 0.32 0.01 0.88 0.99 0.22 0.55 0.42 0.13 0.07]')
            replacements = [adenine, dna, aas, numbers, logo.lol]
        else:
            replacements = [adenine, dna, aas, logo.lol]

        for source, target in zip(replacements, replacements[1:]):
            self.play(ReplacementTransform(source, target))
            self.wait()

        self.play(Write(logo.commons), FadeIn(logo.commons_left),
                  FadeIn(logo.commons_right))
        self.wait()
        for replacer in self.replacers:
            logo.replace_left_right(self, replacer, run_time_s=0.8)
            self.wait(0.3)

        # Move logo to left lower corner
        if self.logo_down:
            mini_logo = logo.copy()
            mini_logo.scale(0.5)
            mini_logo.to_corner()
            self.play(Transform(logo, mini_logo))

        # And keep the scene
        # self.play(Write(Text('Corporate info follows...')))
        self.wait(5)
    def construct(self):

        rng = np.random.RandomState(self.seed)

        moleculizer = partial(
            new_molecule,
            colors=lambda: rng.choice(MOLECULE_COLORS, size=3, replace=True))

        proteins = molecule_universe_grid(
            moleculizer, num_molecules=(5, 8)).scale(0.3).center()
        proteins_frame = SurroundingRectangle(proteins,
                                              color=WHITE).round_corners(0.5)
        universe_title = Text('Known proteins').scale(0.7).next_to(
            proteins_frame, UP)
        framed_proteins = VGroup(universe_title, proteins_frame,
                                 proteins).to_edge(LEFT)

        self.play(FadeIn(framed_proteins))
        self.wait(3)

        # --- Sequence -> Number -> MLM

        heavy, hcdr3 = hiv_antibody()
        heavy.next_to(framed_proteins, RIGHT)
        self.play(Transform(proteins[23], heavy))
        self.wait(5)

        mlm = MLM().next_to(framed_proteins, RIGHT)
        self.play(ShrinkToCenter(heavy))  # , mlm.text
        self.wait(5)

        # FIXME: just to break here
        if mlm.text is not None:
            return

        # --- Subsets
        selected_proteins = [
            proteins[i].copy() for i in rng.choice(
                len(proteins), replace=False, size=len(proteins) // 3)
        ]

        antibodies = VGroup(
            *
            [molecule_from_molecule(protein) for protein in selected_proteins])
        antibodies_frame = (SurroundingRectangle(antibodies).match_color(
            proteins_frame).match_width(proteins_frame).match_height(
                proteins_frame)).round_corners(0.5)
        framed_antibodies = VGroup(antibodies_frame, antibodies)

        framed_antibodies.next_to(proteins, RIGHT, buff=MED_LARGE_BUFF)
        self.play(
            *[
                ReplacementTransform(protein, antibody)
                for protein, antibody in zip(selected_proteins, antibodies)
            ], Write(antibodies_frame))
        self.wait(4)
Exemplo n.º 3
0
    def setup_axes(self, animate=False, x_vals=None, y_vals=None, run_time=1):
        self.get_y_axis().shift(
            self.center_point
        )  # Replace with self.shift(self.center_point) once this bug is fixed!
        self.get_x_axis().shift(self.center_point)

        if animate:
            self.play(Write(self.axes, run_time=run_time))
        else:
            self.add(*self.axes)
 def add_to_scene(self,
                  scene,
                  initial_blank_seconds=0.,
                  end_blank_seconds=0.):
     scene.wait(initial_blank_seconds)
     scene.play(FadeIn(self.lol))
     scene.wait()
     scene.play(Write(self.commons), FadeIn(self.commons_left),
                FadeIn(self.commons_right))
     scene.wait(end_blank_seconds)
Exemplo n.º 5
0
    def insert(self,
               bt_node,
               side_offset_multiply: float = 2.5,
               down_offset_multiply: float = 2.5,
               direction=LEFT,
               start_from_root=True) -> BinaryTreeNode:
        if self.is_full():
            raise AttributeError("This node %s is completed" %
                                 str(self.node_id))
        bt_node.parent = self
        if start_from_root:
            parents = [self]
            while parents[-1].parent is not None:
                parents.append(parents[-1].parent)
            self.scene.add(bt_node)
            bt_node.next_to(parents[-1], buff=0, direction=UP)
            parents.pop()
            self.scene.play(FadeIn(bt_node.value),
                            run_time=bt_node.animation_duration)
            while len(parents) > 0:
                elem = parents[-1]
                self.scene.play(bt_node.value.animate.next_to(elem, buff=0),
                                run_time=bt_node.animation_duration)
                parents.pop()
        else:
            bt_node.next_to(self.value, buff=0)
            self.scene.play(Write(bt_node.value),
                            run_time=bt_node.animation_duration)

        if direction is LEFT and self.has_left():
            direction = RIGHT
            self.right = bt_node
        else:
            self.left = bt_node
        child_location = self.value.get_center() + \
                         side_offset_multiply * self.radius * direction + \
                         down_offset_multiply * self.radius * DOWN
        parent_child_vector = normalize(child_location -
                                        self.value.get_center())

        edge_start = (self.value.get_center() +
                      parent_child_vector * self.radius)
        edge_end = child_location - parent_child_vector * self.radius
        edge = Line(edge_start, edge_end)

        self.scene.play(bt_node.value.animate.move_to(child_location),
                        FadeIn(edge),
                        run_time=bt_node.animation_duration)
        return bt_node
Exemplo n.º 6
0
def mark_tex_caption(node, tex) -> Write:
    nd = Tex(tex)
    nd.scale(0.45)
    nd.next_to(node, aligned_edge=UR)
    return Write(nd)
Exemplo n.º 7
0
    def construct(self):
        matrix1 = Matrix(
            m1,
            v_buff=1.3,
            h_buff=0.8,
            bracket_h_buff=SMALL_BUFF,
            bracket_v_buff=SMALL_BUFF)

        matrix1.set_color(DEFAULT_COLOR)

        matrix1.get_entries()[0].set_color(RECT_COLOR)
        matrix1.get_entries()[-1].set_color(RECT_COLOR)

        self.add(matrix1)

        matrix2 = Matrix(
            m2,
            v_buff=1.3,
            h_buff=0.8,
            bracket_h_buff=SMALL_BUFF,
            bracket_v_buff=SMALL_BUFF)
        matrix2.set_color(DEFAULT_COLOR)
        self.add(matrix2)

        equals = MathTex(r'=')
        self.add(equals)

        m3 = (m1@m2)
        matrix3 = Matrix(
            m3,
            v_buff=1.3,
            h_buff=0.8,
            bracket_h_buff=SMALL_BUFF,
            bracket_v_buff=SMALL_BUFF)
        matrix3.set_color(DEFAULT_COLOR)

        # args = [BLACK]*m3.shape[1]
        # matrix3.set_column_colors(*args)

        for i in matrix3.get_entries():
            i.set_opacity(0)

        self.add(matrix3)

        g = Group(matrix1, matrix2, equals, matrix3).arrange(buff=1).shift(UP)
        g.set_color(DEFAULT_COLOR)
        self.add(g)

        i = 0
        for m1_row in matrix1.get_rows():
            for m2_column in matrix2.get_columns():
                rect_1 = SurroundingRectangle(m1_row).set_stroke(color=RECT_COLOR)
                rect_2 = SurroundingRectangle(m2_column).set_stroke(color=RECT_COLOR)

                self.play(Create(rect_1))
                self.wait()

                self.play(ReplacementTransform(rect_1, rect_2))

                math_strings = []
                values_to_sum = []
                for m1_val, m2_val in zip(m1_row, m2_column):
                    val_left = int(m1_val.get_tex_string())
                    val_right = int(m2_val.get_tex_string())
                    values_to_sum.append(val_left * val_right)
                    text_left = m1_val.get_tex_string()
                    text_right = m2_val.get_tex_string()

                    if val_left < 0:
                        text_left = f'({text_left})'

                    if val_right < 0:
                        text_right = f'({text_right})'

                    math_strings.extend([text_left, " \\times ", text_right, " + "])

                math_strings = math_strings[:-1]
                math_strings.extend([" = ", sum(values_to_sum)])

                ds_m = MathTex(*math_strings)
                ds_m.set_color(BLACK)

                offset = 0
                for j in range(m1.shape[0]):
                    pos = j + offset
                    # ds_m[pos].set_color(M1_COLOR)
                    # ds_m[pos + 2].set_color(M2_COLOR)

                    offset += 3

                ds_m[-1].set_opacity(0)
                # ds_m[-1].set_color(CALCULATED_COLOR)

                ds_m.shift(2 * DOWN)

                self.play(ReplacementTransform(rect_1, rect_2), Write(ds_m))

                self.wait()

                rect_3 = SurroundingRectangle(matrix3.get_entries()[i]).set_color(RECT_COLOR)
                # matrix3.get_entries()[i].set_color(CALCULATED_COLOR)
                self.play(
                    ReplacementTransform(rect_2, rect_3),
                    ApplyMethod(matrix3.get_entries()[i].set_opacity, 1),
                    ApplyMethod(ds_m[-1].set_opacity, 1)
                )

                self.wait()

                self.remove(ds_m)
                self.remove(rect_3)

                m1_row.set_color(BLACK)
                m2_column.set_color(BLACK)

                i += 1
        self.wait()
    def construct(self):
        super().construct()

        # Group first row and second row
        use_cases = []
        for use_case1, use_case2 in zip(USE_CASES, USE_CASES[5:]):
            use_case2.next_to(use_case1, DOWN, buff=0.5)
            use_cases.append(VGroup(use_case1, use_case2))
        use_cases = VGroup(*use_cases)

        # Make all use cases same width and height
        widest = sorted(use_cases, key=lambda x: x.width)[-1]
        tallest = sorted(chain.from_iterable(use_cases),
                         key=lambda x: x.height)[-1]
        for use_case_top, use_case_bottom in use_cases:
            use_case_top.frame.stretch_to_fit_width(widest.width)
            use_case_top.frame.stretch_to_fit_height(tallest.height)
            use_case_bottom.frame.stretch_to_fit_width(widest.width)
            use_case_bottom.frame.stretch_to_fit_height(tallest.height)

        use_cases.arrange().scale(0.8).center()

        # Human friendly names for use cases

        antibodies = use_cases[0][0]
        peptides_ppi = use_cases[0][1]

        toxins = use_cases[1][0]
        peptides_sol = use_cases[1][1]

        enzyme_stabilisation = use_cases[2][0]
        microbiome = use_cases[2][1]

        codons = use_cases[3][0]
        detoxification = use_cases[3][1]

        clinical = use_cases[4][0]
        mutation = use_cases[4][1]

        # --- Animate!

        # Create the use cases
        self.play(Write(use_cases))
        self.wait(1)

        # Example setting the camera
        old_width = self.camera.frame_width
        if self.zoom_each_use_case:
            for use_case in chain.from_iterable(use_cases):
                self.play(
                    self.camera.frame.animate.move_to(use_case).set(
                        width=use_case.width * 2))
                self.wait(2)

        self.play(
            self.camera.frame.animate.move_to(ORIGIN).set(width=old_width))
        self.wait(2)

        # Highlight groups with common / synergies
        # Indications to apply to group visually, temporarily, use cases
        # https://docs.manim.community/en/stable/reference/manim.animation.indication.html

        # Similar modalities (some of these are a bit of a stretch to group together)

        if self.all_groups_at_same_time:
            self.play(
                FocusOn(antibodies),
                # Peptides
                Wiggle(peptides_sol),
                Wiggle(peptides_ppi),
                # DNA + RNA
                Indicate(codons),
                Indicate(mutation),
                Indicate(clinical),
                # Proteins
                Circumscribe(toxins.frame),
                Circumscribe(detoxification.frame),
                # Enzyme
                ApplyWave(enzyme_stabilisation),
                ApplyWave(microbiome),
                run_time=3)
            self.wait(6)
    def construct(self):

        a_million_forks = Text('A million forks in the road to our products'
                               )  # to drug development
        a_million_forks.to_edge(UP)

        new_drugs_per_billion_RD = [('1950', 100), ('1960', 50), ('1970', 10),
                                    ('1980', 5), ('1990', 3), ('2000', 2),
                                    ('2010', 1), ('2020', 1)]
        x = [x for x, _ in new_drugs_per_billion_RD]
        y = [y for _, y in new_drugs_per_billion_RD]
        colors = ["#003f5c", "#58508d", "#bc5090", "#ff6361", "#ffa600"]
        chart = BarChart(
            values=y,
            max_value=max(y),
            bar_colors=colors,
            bar_names=x,
            bar_label_scale_val=0.5,
        ).scale(0.8).to_edge(LEFT).shift(0.5 * DOWN)

        # text_top = (
        #     Text('EROOM\'s Law: More expensive, slower drug discovery')
        #     .scale(0.9)
        #     .next_to(chart, UP, buff=0.1)
        # )

        # text_left = (
        #     Text('Number of drugs per billion US$ R&D spending')
        #     .rotate(angle=TAU / 4, axis=OUT)
        #     .scale(0.3)
        #     .next_to(chart, LEFT, buff=0.5)
        # )

        text_top = (
            Text('Number of drugs per billion US$ R&D spending (log-scale)'
                 ).scale(0.3).next_to(chart, UP, buff=0.5))

        text_bottom = (
            Text("Eroom's law: a continuous decline in Pharma R&D productivity"
                 ).scale(0.3).next_to(chart, DOWN, buff=0.5))

        # --- Examples of forks in the road

        icons_text = [
            (SVGMobject(SVGS.ANTIBODY).set_color(BLUE).scale(0.8),
             Text('Is my antibody a potent, functional binder?')),
            (SVGMobject(SVGS.CYCLIC_PEPTIDE).set_color_by_gradient(
                BLUE, GREEN).scale(0.8),
             Text('Can we generate peptides without liabilities?')),
            (SVGMobject(SVGS.DNA).set_color_by_gradient(GREEN,
                                                        BLUE).scale(0.8),
             Text(
                 'Can we optimize DNA to better express traits in plants or humans?'
             )),
            (SVGMobject(SVGS.PACMAN).set_color(RED).scale(0.8),
             Text('What will an enzyme in the human gut do?')),
            # (
            #     SVGMobject(SVGS.PACMAN).set_color_by_gradient(GREEN, BLUE, RED).scale(0.8),
            #     Text('Can we optimize enzymes to better manufacture bioproducts?')
            # ),
            (SVGMobject(SVGS.PROTEIN3D).set_color_by_gradient(
                GREEN, BLUE, RED).scale(0.8),
             Text('What is the 3D structure of my biomolecule?')),
            (SVGMobject(SVGS.PATIENT).set_color_by_gradient(BLUE,
                                                            RED).scale(0.8),
             Text('Will a patient respond to treatment in a clinical trial?')),
            (SVGMobject(SVGS.MUTATION).set_color_by_gradient(BLUE, GREEN,
                                                             RED).scale(0.8),
             Text('...'))
        ]

        # icons_text = icons_text[:1]

        for (icon1, _), (icon2, _) in zip(icons_text, icons_text[1:]):
            icon2.next_to(icon1, DOWN, buff=0.5)

        for icon, text in icons_text:
            text.next_to(icon, RIGHT)

        questions = VGroup(*chain.from_iterable(icons_text))
        questions.scale(0.32)
        questions.next_to(chart, RIGHT, buff=1).shift(0.5 * UP)

        logo = LoLLogo().scale(0.7)
        # logo.next_to(questions, DOWN, buff=0.5)
        logo.move_to(questions)

        # --- Animate

        self.play(FadeIn(text_top))
        self.play(Write(chart), Write(text_bottom), run_time=4)
        self.wait(2)
        self.play(Write(a_million_forks))
        for icon, text in icons_text:
            self.play(FadeIn(icon, text))
            self.wait(3)

        # if we have put the logo under the questions...
        # self.play(FadeIn(logo))

        # if we prefer the logo to morph from the questions
        actionable_insights = (Text(
            'Getting actionable insights from biological sequences').next_to(
                logo, DOWN, buff=0.5).scale(0.4))
        self.play(ReplacementTransform(questions, logo))
        self.play(Write(actionable_insights))
        self.wait(2)