Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

#!/usr/bin/env python3 

 

class Protocol: 

 

    def __init__(self): 

        self.steps = [] 

 

    def __iadd__(self, step_or_steps): 

        from nonstdlib import MagicFormatter 

 

        if isinstance(step_or_steps, str): 

            step_or_steps = (step_or_steps,) 

 

        for step in step_or_steps: 

            self.steps.append(str(step) | MagicFormatter(level=2)) 

 

        return self 

 

    def __str__(self): 

        from textwrap import indent 

        formatted_steps = [] 

 

        for i, step in enumerate(self.steps, 1): 

            number = "{}. ".format(i) 

            padding = ' ' * len(number) 

            formatted_steps.append( 

                    indent(number + step, ' ' * len(number)).strip()) 

 

        return '\n\n'.join(formatted_steps) 

 

 

class Pcr: 

 

    def __init__(self, num_reactions=1, ta=60, tx=120, nc=35): 

        from .reaction import Reaction 

        self.reaction = Reaction() 

        self.num_reactions = num_reactions 

        self.extra_master_mix = 0 

        self.annealing_temp = ta 

        self.extension_time = tx 

        self.num_cycles = nc 

 

        self.reaction['Q5 master mix'].std_volume = 25, 'μL' 

        self.reaction['Q5 master mix'].std_stock_conc = '2x' 

        self.reaction['Q5 master mix'].master_mix = True 

 

        self.reaction['primer mix'].std_volume = 5, 'μL' 

        self.reaction['primer mix'].std_stock_conc = '10x' 

        self.reaction['primer mix'].master_mix = False 

 

        self.reaction['template DNA'].std_volume = 1, 'μL' 

        self.reaction['template DNA'].std_stock_conc = 100, 'pg/μL' 

        self.reaction['template DNA'].master_mix = True 

 

        self.reaction['water'].std_volume = 19 

        self.reaction['water'].volume_unit = 'μL' 

        self.reaction['water'].master_mix = True 

 

    def __iter__(self): 

        yield from self.steps 

 

    def __getitem__(self, key): 

        return self.reaction[key] 

 

    @property 

    def steps(self): 

        s = 's' if self.num_reactions != 1 else '' 

        ta = self.annealing_temp 

        tx = self.extension_time 

        tx = '{}:{:02d}'.format(tx // 60, tx % 60) 

        pad = ' ' * (7 - len(tx)) 

        nc = self.num_cycles 

 

        setup_step = """\ 

Setup {self.num_reactions} PCR reaction{s} and 1 negative control: 

 

{self.reaction}""".format(**locals()) 

 

        thermocycler_step = """\ 

Run the following thermocycler protocol: 

 

98°C → 98°C → {ta}°C → 72°C → 72°C → 12°C 

0:30   0:10   0:20   {tx}{pad}2:00    ∞ 

      └──────────────────┘ 

               {nc}x""".format(**locals()) 

 

        return [setup_step, thermocycler_step] 

 

    @property 

    def num_reactions(self): 

        return self.reaction.num_reactions - 1 

 

    @num_reactions.setter 

    def num_reactions(self, value): 

        self.reaction.num_reactions = value + 1 

 

    @property 

    def extra_master_mix(self): 

        return self.reaction.extra_master_mix 

 

    @extra_master_mix.setter 

    def extra_master_mix(self, value): 

        self.reaction.extra_master_mix = value 

 

    @property 

    def template_in_master_mix(self): 

        return self.reaction['template DNA'].master_mix 

 

    @template_in_master_mix.setter 

    def template_in_master_mix(self, value): 

        self.reaction['template DNA'].master_mix = value 

 

    @property 

    def primers_in_master_mix(self): 

        return self.reaction['primer mix'].master_mix 

 

    @primers_in_master_mix.setter 

    def primers_in_master_mix(self, value): 

        self.reaction['primer mix'].master_mix = value