예제 #1
0
    def saveSamps(self,
                  src,
                  vol,
                  dil,
                  tgt=None,
                  dilutant=None,
                  plate=None,
                  mix=(True, False)):
        [src, vol, dil] = listify([src, vol, dil])
        if plate is None:
            plate = decklayout.REAGENTPLATE
        if tgt is None:
            tgt = [
                Sample(diluteName(src[i].name, dil[i]), plate)
                for i in range(len(src))
            ]

        if any([d != 1.0 for d in dil]):
            if dilutant is None:
                dilutant = decklayout.WATER
            self.e.multitransfer(
                [vol[i] * (dil[i] - 1) for i in range(len(vol))], dilutant,
                tgt, (False, False))

        self.e.shakeSamples(src, returnPlate=True)
        for i in range(len(src)):
            self.e.transfer(vol[i], src[i], tgt[i], mix)
            tgt[i].conc = Concentration(1.0 / dil[i])

        return tgt
예제 #2
0
    def runIncubation(self,
                      src=None,
                      vol=None,
                      srcdil=None,
                      tgt=None,
                      enzymes=None,
                      incTemp=37,
                      incTime=15,
                      hiTemp=None,
                      hiTime=0,
                      inPlace=False):
        if len(enzymes) != 1:
            print "ERROR: runIncubation only supports a single master mix"
            assert False
        if inPlace:
            if tgt is not None:
                print "ERROR: tgt specified for in-place incubation"
                assert False
        elif tgt is None:
            tgt = [
                Sample("%s.%s" % (src[i].name, enzymes[0].name),
                       decklayout.SAMPLEPLATE) for i in range(len(src))
            ]

        if srcdil == None:
            # Minimum dilution (no water)
            srcdil = 1 / (1 -
                          sum([1 / e.conc.dilutionneeded() for e in enzymes]))

        if vol is None and inPlace:
            vol = [s.volume * srcdil for s in src]

        [src, tgt, vol, srcdil] = listify([src, tgt, vol, srcdil])

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc = Concentration(srcdil[i], 1)

        if inPlace:
            self.runRxInPlace(src, vol, enzymes[0], returnPlate=False)
            tgt = src
        else:
            self.e.stage('User', enzymes, src, tgt, vol, destMix=False)
            self.e.shakeSamples(tgt, returnPlate=False)

        if hiTemp is None:
            worklist.pyrun('PTC\\ptcsetpgm.py INC TEMP@%.0f,%.0f TEMP@25,30' %
                           (incTemp, incTime * 60))
        else:
            assert (hiTime > 0)
            worklist.pyrun(
                'PTC\\ptcsetpgm.py INC TEMP@%.0f,%.0f TEMP@%.0f,%.0f TEMP@25,30'
                % (incTemp, incTime * 60, hiTemp, hiTime * 60))
        self.e.runpgm("INC",
                      incTime + hiTime + 2,
                      False,
                      max(vol),
                      hotlidmode="TRACKING",
                      hotlidtemp=10)
        return tgt
예제 #3
0
    def runRTSetup(self, src, vol, srcdil, tgt=None, rtmaster=None):
        if rtmaster is None:
            rtmaster = reagents.getsample("MPosRT")
        if tgt is None:
            tgt = [
                Sample(s.name + ".RT+", decklayout.SAMPLEPLATE) for s in src
            ]

        [src, tgt, vol, srcdil] = listify([src, tgt, vol, srcdil])

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc = Concentration(srcdil[i], 1)

        self.e.stage('RTPos', [rtmaster], [src[i] for i in range(len(src))],
                     [tgt[i] for i in range(len(tgt))],
                     [vol[i] for i in range(len(vol))],
                     destMix=False)
        #self.e.shakeSamples(tgt,returnPlate=True)
        return tgt
예제 #4
0
    def runT7Stop(self, theo, tgt, stopmaster=None, srcdil=2):
        [theo, tgt, stopmaster,
         srcdil] = listify([theo, tgt, stopmaster, srcdil])
        if stopmaster is None:
            stopmaster = ["MStpS_NT" if t == 0 else "MStpS_WT" for t in theo]

        # Adjust source dilution
        for i in range(len(tgt)):
            tgt[i].conc = Concentration(srcdil[i], 1)

        ## Stop
        sstopmaster = [reagents.getsample(s) for s in stopmaster]
        for i in range(len(tgt)):
            stopvol = tgt[i].volume / (sstopmaster[i].conc.dilutionneeded() -
                                       1)
            finalvol = tgt[i].volume + stopvol
            self.e.transfer(finalvol - tgt[i].volume, sstopmaster[i], tgt[i])

        self.e.shakeSamples(tgt, returnPlate=True)

        return tgt
예제 #5
0
    def addTemplates(self,
                     names,
                     stockconc,
                     finalconc=None,
                     units="nM",
                     plate=decklayout.EPPENDORFS):
        'Add templates as "reagents", return the list of them'
        if finalconc is None:
            print "WARNING: final concentration of template not specified, assuming 0.6x (should add to addTemplates() call"
            [names, stockconc] = listify([names, stockconc])
            finalconc = [0.6 * x for x in stockconc]
        else:
            [names, stockconc,
             finalconc] = listify([names, stockconc, finalconc])

        r = []
        for i in range(len(names)):
            r.append(
                reagents.add(names[i],
                             plate=plate,
                             conc=Concentration(stockconc[i], finalconc[i],
                                                units),
                             extraVol=30))
        return r
예제 #6
0
    def pgm(self):
        q = QSetup(self, maxdil=16, debug=False, mindilvol=60)
        self.e.addIdleProgram(q.idler)
        input = [s.getsample() for s in self.srcs]

        # Save RT product from first (uncleaved) round and then use it during 2nd (cleaved) round for ligation and qPCR measurements
        prefixIn = [inp['prefix'] for inp in self.inputs]
        prefixOut = [
            "A" if p == "W" else
            "B" if p == "A" else "W" if p == "B" else "BADPREFIX"
            for p in prefixIn
        ]

        qpcrPrimers = ["REF", "MX", "T7X"]
        if "W" in prefixIn + prefixOut:
            qpcrPrimers += ["T7WX"]
        if "A" in prefixIn + prefixOut:
            qpcrPrimers += ["T7AX"]
        if "B" in prefixIn + prefixOut:
            qpcrPrimers += ["T7BX"]
        q.addSamples(decklayout.SSDDIL, 1, qpcrPrimers,
                     save=False)  # Negative controls

        print "Starting new cleavage round, will add prefix: ", prefixOut

        names = [i.name for i in input]

        print "######## T7 ###########"
        print "Inputs:  (t7vol=%.2f)" % self.t7vol
        for inp in input:
            print "    %s:  %.1ful@%.1f nM, use %.1f ul (%.3f pmoles)" % (
                inp.name, inp.volume, inp.conc.stock, self.t7vol /
                inp.conc.dilutionneeded(), self.t7vol * inp.conc.final / 1000)

        print "input[0]=", input[0]
        needDil = max([inp.conc.final for inp in input]) * 1.0 / self.qConc
        if self.directT7:
            # Just add MT7 and possibly water to each well
            mconc = reagents.getsample("MT7").conc.dilutionneeded()
            for i in range(len(input)):
                watervol = self.t7vol * (1 - 1 / mconc) - input[i].volume
                if watervol > 0.1:
                    self.e.transfer(watervol,
                                    decklayout.WATER,
                                    input[i],
                                    mix=(False, False))
                self.e.transfer(self.t7vol / mconc,
                                reagents.getsample("MT7"),
                                input[i],
                                mix=(False, False))
                assert (input[i].volume == self.t7vol)
            rxs = input
        else:
            rxs = self.runT7Setup(
                src=input,
                vol=self.t7vol,
                srcdil=[inp.conc.dilutionneeded() for inp in input])
        print "input[0]=", input[0]

        #for i in range(len(rxs)):
        #   q.addSamples(src=rxs],needDil=needDil,primers=["T7"+prefixIn[i]+"X","MX","T7X","REF"],names=["%s.T-"%names[i]])

        self.runT7Pgm(dur=self.t7dur, vol=self.t7vol)
        print "Template conc=%.1f nM, estimated RNA concentration in T7 reaction at %.0f nM" % (
            self.tmplFinalConc, self.rnaConc)

        print "######## Stop ###########"
        self.e.lihahome()

        print "Have %.1f ul before stop" % rxs[0].volume
        preStopVolume = rxs[0].volume
        self.addEDTA(tgt=rxs, finalconc=2)  # Stop to 2mM EDTA final

        stopDil = rxs[0].volume / preStopVolume

        if self.saveRNA:
            self.saveSamps(
                src=rxs,
                vol=5,
                dil=2,
                plate=decklayout.DILPLATE,
                dilutant=reagents.getsample("TE8"),
                mix=(False,
                     False))  # Save to check [RNA] on Qubit, bioanalyzer

        stop = [
            "A-Stop" if n == "A" else
            "B-Stop" if n == "B" else "W-Stop" if n == "W" else "BADPREFIX"
            for n in prefixOut
        ]

        for i in range(len(rxs)):
            rxs[i].name = rxs[i].name + "." + stop[i]

        needDil = self.rnaConc / self.qConc / stopDil
        #q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","MX","T7X","REF"],names=["%s.stopped"%r.name for r in rxs])

        print "######## RT  Setup ###########"
        rtDil = 4
        hiTemp = 95
        rtDur = 20

        rxin = rxs
        rxs = self.runRT(src=rxs,
                         vol=self.rtvol,
                         srcdil=rtDil,
                         heatInactivate=True,
                         hiTemp=hiTemp,
                         dur=rtDur,
                         incTemp=50,
                         stop=[reagents.getsample(s) for s in stop
                               ])  # Heat inactivate also allows splint to fold
        print "RT volume= ", [x.volume for x in rxs]
        for r in rxin:
            if r.volume > 20:
                print "Have more T7 reaction remaining than needed: %s has %.1f ul" % (
                    r.name, r.volume)

        needDil /= rtDil
        rtPostDil = 5
        if rtPostDil != 1:
            self.diluteInPlace(tgt=rxs, dil=rtPostDil)
            needDil /= rtPostDil
        #q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","MX","REF"],names=["%s.rt"%r.name for r in rxs])

        print "######## Ligation setup  ###########"
        extdil = 5.0 / 4
        reagents.getsample("MLigase").conc = Concentration(5)
        extvol = 20
        print "Extension volume=", extvol
        rxs = self.runLig(rxs, vol=extvol)

        print "Ligation volume= ", [x.volume for x in rxs]
        needDil = needDil / extdil
        extpostdil = 4
        if extpostdil > 1:
            print "Dilution after extension: %.2f" % extpostdil
            self.diluteInPlace(tgt=rxs, dil=extpostdil)
            needDil = needDil / extpostdil
            if not self.doexo:
                self.pcrdil = self.pcrdil / extpostdil

        if self.saveDil is not None:
            ext = self.saveSamps(
                src=rxs,
                vol=3,
                dil=self.saveDil,
                dilutant=reagents.getsample("TE8"),
                tgt=[Sample("%s.ext" % n, decklayout.DILPLATE) for n in names],
                mix=(False, True))  # Save cDNA product for subsequent NGS
            for i in range(len(rxs)):
                q.addSamples(src=[ext[i]],
                             needDil=needDil / self.saveDil,
                             primers=[
                                 "T7" + prefixIn[i] + "X",
                                 "T7" + prefixOut[i] + "X", "MX", "T7X", "REF"
                             ],
                             names=["%s.ext" % names[i]])
        else:
            for i in range(len(rxs)):
                q.addSamples(src=[rxs[i]],
                             needDil=needDil,
                             primers=[
                                 "T7" + prefixIn[i] + "X",
                                 "T7" + prefixOut[i] + "X", "MX", "T7X", "REF"
                             ],
                             names=["%s.ext" % names[i]])

        if self.doexo:
            print "######## Exo ###########"
            prevvol = rxs[0].volume
            rxs = self.runExo(rxs, incTime=30, inPlace=True)
            exoDil = rxs[0].volume / prevvol
            needDil /= exoDil
            needDil /= 7  #  Anecdotal based on Ct's -- large components (MX) reduced by exo digestion
            q.addSamples(src=rxs,
                         needDil=needDil,
                         primers=["T7AX", "T7BX", "MX", "T7X", "REF"],
                         names=["%s.exo" % names[i] for i in range(len(rxs))])
            #exo=self.saveSamps(src=rxs,vol=10*exoDil,dil=2/exoDil,dilutant=reagents.getsample("TE8"),tgt=[Sample("%s.exo"%n,decklayout.SAMPLEPLATE) for n in names])   # Save cDNA product
        else:
            exoDil = 1
            exo = []

        if self.doampure:
            print "######## Ampure Cleanup ###########"
            ratio = 1.5
            elutionVol = 30
            cleanIn = ext + exo + user
            needDil = needDil * cleanIn[0].volume / elutionVol
            clean = self.runAmpure(src=cleanIn,
                                   ratio=ratio,
                                   elutionVol=elutionVol)
            q.addSamples(src=[clean[i] for i in range(len(rxs))],
                         needDil=needDil,
                         primers=["T7AX", "MX", "T7X", "REF"])
            rxs = rxs + clean  # Use the cleaned products for PCR

        totalDil = stopDil * rtDil * rtPostDil * extdil * extpostdil * exoDil
        fracRetained = rxs[0].volume / (self.t7vol * totalDil)
        print "Total dilution from T7 to Pre-pcr Product = %.2f*%.2f*%.2f*%.2f*%.2f*%.2f = %.2f, fraction retained=%.0f%%" % (
            stopDil, rtDil, rtPostDil, extdil, extpostdil, exoDil, totalDil,
            fracRetained * 100)

        if self.dopcr:
            print "######### PCR #############"
            print "PCR Volume: %.1f, Dilution: %.1f, volumes available for PCR: [%s]" % (
                self.pcrvol, self.pcrdil, ",".join(
                    ["%.1f" % r.volume for r in rxs]))
            maxSampleVolume = 100  # Maximum sample volume of each PCR reaction (thermocycler limit, and mixing limit)

            initConc = needDil * self.qConc / self.pcrdil
            if self.doexo:
                initConc = initConc * 7 * self.cleavage  # Back out 7x dilution in exo step, but only use cleaved as input conc
            else:
                initConc = initConc * self.cleavage  # Only use cleaved as input conc

            gain = pcrgain(initConc, 400, self.pcrcycles)
            finalConc = initConc * gain
            print "Estimated starting concentration in PCR = %.1f nM, running %d cycles -> %.0f nM\n" % (
                needDil * self.qConc, self.pcrcycles, finalConc)
            pcr = self.runPCR(src=rxs,
                              vol=self.pcrvol,
                              srcdil=self.pcrdil,
                              ncycles=self.pcrcycles,
                              primers=["T7%sX" % x for x in prefixOut],
                              usertime=self.usertime,
                              fastCycling=True)

            needDil = finalConc / self.qConc
            pcrpostdil = 2
            if pcrpostdil > 1:
                self.diluteInPlace(pcr, pcrpostdil)
                needDil = needDil / pcrpostdil
            print "Projected final concentration = %.0f nM (after %.1fx dilution)" % (
                needDil * self.qConc, pcrpostdil)
            for i in range(len(pcr)):
                pcr[i].conc = Concentration(stock=finalConc / pcrpostdil,
                                            final=None,
                                            units='nM')

            if self.pcrSave:
                # Save samples at 1x
                if self.savedilplate:
                    sv = self.saveSamps(
                        src=pcr[:len(rxs)],
                        vol=[x.volume - 16.4 for x in pcr[:len(rxs)]],
                        dil=1,
                        plate=decklayout.DILPLATE)
                else:
                    sv = self.saveSamps(
                        src=pcr[:len(rxs)],
                        vol=[x.volume - 16.4 for x in pcr[:len(rxs)]],
                        dil=1,
                        plate=decklayout.EPPENDORFS)

                # for i in range(len(pcr)):
                #     q.addSamples(pcr,needDil,["T7%sX"%prefixOut[i]])

                processEff = 0.5  # Estimate of overall efficiency of process
                print "Saved %.2f pmoles of product (%.0f ul @ %.1f nM)" % (
                    sv[0].volume * sv[0].conc.stock / 1000, sv[0].volume,
                    sv[0].conc.stock)

        print "######### qPCR ###########"
        #q.addReferences(mindil=4,nsteps=6,primers=["T7X","MX","T7AX"])
        q.run(confirm=False)
예제 #7
0
    def oneround(self, q, input, prefixOut, stop, prefixIn, keepCleaved, t7vol,
                 rtvol, pcrdil, cycles, pcrvol, dolig):
        primerSet = [
            set(["MX", "REF", "T7X", prefixIn[i] + "X", prefixOut[i] + "X"])
            for i in range(len(prefixIn))
        ]

        if keepCleaved:
            print "Starting new cleavage round, will add prefix: ", prefixOut
            assert (dolig)
        else:
            print "Starting new uncleaved round, will retain prefix: ", prefixIn
        print "stop=", stop, "prefixOut=", prefixOut, ", prefixIn=", prefixIn, ",t7vol=", t7vol, ",rtvol=", rtvol, ",pcrdil=", pcrdil, ",cycles=", cycles, ",dolig=", dolig
        if self.rtCarryForward:
            assert (dolig)

        names = [i.name for i in input]

        if self.rnaInput:
            rxs = input
            stopDil = 1
        else:
            print "######## T7 ########### %.0f min" % (clock.elapsed() / 60)
            print "Inputs:  (t7vol=%.2f)" % t7vol
            inconc = [inp.conc.final for inp in input]
            for inp in input:
                if inp.conc.units == 'nM':
                    print "    %s:  %.1ful@%.1f %s, use %.1f ul (%.3f pmoles)" % (
                        inp.name, inp.volume, inp.conc.stock, inp.conc.units,
                        t7vol / inp.conc.dilutionneeded(),
                        t7vol * inp.conc.final / 1000)
                    needDil = max([inp.conc.stock
                                   for inp in input]) * 1.0 / self.qConc
                else:
                    print "    %s:  %.1ful@%.1f %s, use %.1f ul" % (
                        inp.name, inp.volume, inp.conc.stock, inp.conc.units,
                        t7vol / inp.conc.dilutionneeded())
                    needDil = 100 / self.qConc  # Assume 100nM
                # inp.conc.final=inp.conc.stock*self.templateDilution
            if self.directT7 and self.rndNum == 1:
                # Just add ligands and MT7 to each well
                if not keepCleaved:
                    for i in range(len(input)):
                        if self.inputs[i]['ligand'] is not None:
                            ligand = reagents.getsample(
                                self.inputs[i]['ligand'])
                            self.e.transfer(t7vol /
                                            ligand.conc.dilutionneeded(),
                                            ligand,
                                            input[i],
                                            mix=(False, False))
                            names[i] += "+"
                mconc = reagents.getsample("MT7").conc.dilutionneeded()
                for i in range(len(input)):
                    watervol = t7vol * (1 - 1 / mconc) - input[i].volume
                    if watervol > 0.1:
                        self.e.transfer(watervol,
                                        decklayout.WATER,
                                        input[i],
                                        mix=(False, False))
                    self.e.transfer(t7vol / mconc,
                                    reagents.getsample("MT7"),
                                    input[i],
                                    mix=(False, False))
                    assert (abs(input[i].volume - t7vol) < 0.1)
                rxs = input
            elif self.rndNum == len(
                    self.rounds) and self.finalPlus and keepCleaved:
                rxs = self.runT7Setup(
                    src=input,
                    vol=t7vol,
                    srcdil=[inp.conc.dilutionneeded() for inp in input])
                for i in range(len(input)):
                    inp = input[i]
                    if self.inputs[i]['ligand'] is not None:
                        rxs += self.runT7Setup(
                            ligands=[
                                reagents.getsample(self.inputs[i]['ligand'])
                            ],
                            src=[inp],
                            vol=t7vol,
                            srcdil=[inp.conc.dilutionneeded()])
                        prefixIn += [prefixIn[i]]
                        prefixOut += [prefixOut[i]]
                        stop += [stop[i]]
                        primerSet += [primerSet[i]]
                        names += ["%s+" % names[i]]
            elif keepCleaved:
                rxs = self.runT7Setup(
                    src=input,
                    vol=t7vol,
                    srcdil=[inp.conc.dilutionneeded() for inp in input])
            else:
                rxs = self.runT7Setup(
                    ligands=[
                        reagents.getsample(inp['ligand'])
                        for inp in self.inputs
                    ],
                    src=input,
                    vol=t7vol,
                    srcdil=[inp.conc.dilutionneeded() for inp in input])

            if self.rndNum == 1 and "template" in self.qpcrStages:
                # Initial input
                for i in range(len(rxs)):
                    q.addSamples(src=rxs[i],
                                 needDil=needDil,
                                 primers=primerSet[i],
                                 names=["%s.T" % names[i]])

            needDil = needDil * max(
                [inp.conc.dilutionneeded() for inp in input])
            self.runT7Pgm(dur=self.t7dur, vol=t7vol)
            for i in range(len(rxs)):
                rxs[i].name = "%s.t7" % names[i]

            print "Estimate usable RNA concentration in T7 reaction at %.0f nM" % self.rnaConc

            print "######## Stop ########### %.0f min" % (clock.elapsed() / 60)
            self.e.lihahome()

            print "Have %.1f ul before stop" % rxs[0].volume
            preStopVolume = rxs[0].volume
            self.addEDTA(tgt=rxs, finalconc=2)  # Stop to 2mM EDTA final

            stopDil = rxs[0].volume / preStopVolume

            if self.saveRNA:
                self.saveSamps(
                    src=rxs,
                    vol=5,
                    dil=self.saveRNADilution,
                    plate=decklayout.DILPLATE,
                    dilutant=reagents.getsample("TE8"),
                    mix=(False,
                         False))  # Save to check [RNA] on Qubit, bioanalyzer

        needDil = self.rnaConc / self.qConc / stopDil

        if "stopped" in self.qpcrStages:
            for i in range(len(rxs)):
                q.addSamples(src=rxs[i:i + 1],
                             needDil=needDil,
                             primers=primerSet[i],
                             names=["%s.stopped" % names[i]])

        print "######## RT  Setup ########### %.0f min" % (clock.elapsed() /
                                                           60)
        hiTemp = 95

        stop = ["%s-Stop" % n for n in stop]
        rt = self.runRT(src=rxs,
                        vol=rtvol,
                        srcdil=self.rtDil,
                        heatInactivate=self.rtHI,
                        hiTemp=hiTemp,
                        dur=self.rtdur,
                        incTemp=50,
                        stop=[reagents.getsample(s) for s in stop],
                        stopConc=self.stopConc
                        )  # Heat inactivate also allows splint to fold

        rxs = rt
        for i in range(len(rxs)):
            if dolig and not self.singlePrefix:
                rxs[i].name = names[i] + "." + prefixOut[i] + ".rt"
            else:
                rxs[i].name = names[i] + ".rt"

        print "RT volume= [", ",".join(["%.1f " % x.volume for x in rxs]), "]"

        needDil /= self.rtDil
        if self.rtpostdil[self.rndNum - 1] > 1:
            print "Dilution after RT: %.2f" % self.rtpostdil[self.rndNum - 1]
            self.diluteInPlace(tgt=rxs, dil=self.rtpostdil[self.rndNum - 1])
            needDil = needDil / self.rtpostdil[self.rndNum - 1]

        if self.rtSave:
            rtsv = self.saveSamps(
                src=rxs,
                vol=self.rtSaveVol,
                dil=self.rtSaveDil,
                plate=decklayout.DILPLATE,
                dilutant=reagents.getsample("TE8"),
                mix=(False, False))  # Save to check RT product on gel (2x dil)

            if "rt" in self.qpcrStages:
                for i in range(len(rxs)):
                    q.addSamples(src=rtsv[i:i + 1],
                                 needDil=needDil / 2,
                                 primers=self.rtprimers[self.rndNum - 1] if
                                 hasattr(self, 'rtprimers') else primerSet[i],
                                 names=["%s.rt" % names[i]])
        else:
            if "rt" in self.qpcrStages:
                for i in range(len(rxs)):
                    q.addSamples(src=rxs[i:i + 1],
                                 needDil=needDil,
                                 primers=self.rtprimers[self.rndNum - 1] if
                                 hasattr(self, 'rtprimers') else primerSet[i],
                                 names=["%s.rt" % names[i]])

        rtCarryForwardDil = 10
        rtCarryForwardVol = 3.5

        if self.rtCarryForward and not keepCleaved:
            # Also include RT from a prior round from here on
            for r in self.lastSaved:
                newsamp = Sample("%s.samp" % r.name, decklayout.SAMPLEPLATE)
                self.e.transfer(rxs[0].volume, r, newsamp, (False, False))
                rxs.append(newsamp)

        if dolig:
            print "######## Ligation setup  ########### %.0f min" % (
                clock.elapsed() / 60)
            extdil = 5.0 / 4
            reagents.getsample("MLigase").conc = Concentration(5)
            if self.ligInPlace:
                rxs = self.runLig(rxs,
                                  inPlace=True,
                                  srcdil=extdil,
                                  incTime=self.ligdur)
            else:
                rxs = self.runLig(rxs,
                                  inPlace=False,
                                  srcdil=extdil,
                                  vol=20,
                                  incTime=self.ligdur)

            print "Ligation volume= ", [x.volume for x in rxs]
            needDil = needDil / extdil
            if self.extpostdil[self.rndNum - 1] > 1:
                print "Dilution after extension: %.2f" % self.extpostdil[
                    self.rndNum - 1]
                self.diluteInPlace(tgt=rxs,
                                   dil=self.extpostdil[self.rndNum - 1])
                needDil = needDil / self.extpostdil[self.rndNum - 1]
                pcrdil = pcrdil * 1.0 / self.extpostdil[self.rndNum - 1]

            if self.saveDil is not None:
                ext = self.saveSamps(
                    src=rxs,
                    vol=3,
                    dil=self.saveDil,
                    dilutant=reagents.getsample("TE8"),
                    tgt=[
                        Sample("%s.ext" % n, decklayout.DILPLATE)
                        for n in names
                    ],
                    mix=(False, True))  # Save cDNA product for subsequent NGS
                if "ext" in self.qpcrStages:
                    for i in range(len(ext)):
                        # Make sure we don't take more than 2 more steps
                        maxdil = q.MAXDIL * q.MAXDIL
                        if needDil / self.saveDil > maxdil:
                            logging.notice(
                                "Diluting ext by %.0fx instead of needed %.0f to save steps"
                                % (maxdil, needDil / self.saveDil))
                        q.addSamples(src=[ext[i]],
                                     needDil=min(maxdil,
                                                 needDil / self.saveDil),
                                     primers=primerSet[i],
                                     names=["%s.ext" % names[i]],
                                     save=False)
            else:
                if "ext" in self.qpcrStages:
                    print "needDil=", needDil
                    for i in range(len(names)):
                        q.addSamples(src=[rxs[i]],
                                     needDil=needDil,
                                     primers=primerSet[i],
                                     names=["%s.ext" % names[i]])
                        isave = i + len(names)
                        if isave < len(rxs):
                            # samples restored
                            q.addSamples(src=[rxs[isave]],
                                         needDil=needDil / rtCarryForwardDil,
                                         primers=primerSet[isave])
        else:
            extdil = 1
            self.extpostdil[self.rndNum - 1] = 1
            if self.rtpostdil[self.rndNum - 1] > 1:
                pcrdil = pcrdil * 1.0 / self.rtpostdil[self.rndNum - 1]

        totalDil = stopDil * self.rtDil * self.rtpostdil[
            self.rndNum - 1] * extdil * self.extpostdil[self.rndNum - 1]
        fracRetained = rxs[0].volume / (t7vol * totalDil)
        print "Total dilution from T7 to Pre-pcr Product = %.2f*%.2f*%.2f*%.2f*%.2f = %.2f, fraction retained=%.0f%%" % (
            stopDil, self.rtDil, self.rtpostdil[self.rndNum - 1], extdil,
            self.extpostdil[self.rndNum - 1], totalDil, fracRetained * 100)

        if self.rtCarryForward and not keepCleaved:
            # Remove the extra samples
            assert (len(self.lastSaved) > 0)
            rxs = rxs[:len(rxs) - len(self.lastSaved)]
            self.lastSaved = []

        if len(rxs) > len(input):
            # Have extra samples due when self.finalPlus is True
            rxs = rxs[0:len(input)]  # Only keep -target products
            prefixOut = prefixOut[0:len(input)]
            prefixIn = prefixIn[0:len(input)]
            stop = stop[0:len(input)]

        if self.dopcr and not (keepCleaved and self.noPCRCleave):
            print "######### PCR ############# %.0f min" % (clock.elapsed() /
                                                            60)
            maxvol = max([r.volume for r in rxs])
            print "PCR Volume: %.1f, Dilution: %.1f, volumes available for PCR: [%s]" % (
                pcrvol, pcrdil, ",".join(["%.1f" % r.volume for r in rxs]))

            initConc = needDil * self.qConc / pcrdil
            if keepCleaved:
                initConc = initConc * self.cleavage  # Only use cleaved as input conc
            else:
                initConc = initConc * (1 - self.cleavage)

            gain = pcrgain(initConc, 400, cycles)
            finalConc = min(200, initConc * gain)
            print "Estimated starting concentration in PCR = %.1f nM, running %d cycles -> %.0f nM\n" % (
                needDil * self.qConc / pcrdil, cycles, finalConc)
            nsplit = int(math.ceil(pcrvol * 1.0 / self.maxPCRVolume))
            print "Split each PCR into %d reactions" % nsplit
            minsrcdil = 1 / (1 - 1.0 / 3 - 1.0 / 4)
            sampNeeded = pcrvol / pcrdil
            if self.rtCarryForward and keepCleaved:
                sampNeeded += rtCarryForwardVol
            maxvol = max([r.volume for r in rxs])
            minvol = min([r.volume for r in rxs])
            if keepCleaved and self.rtCarryForward:
                assert (len(rxs) == len(rtCarryForward))
                print "Saving %.1f ul of each pre-PCR sample" % (
                    rtCarryForwardVol)
                self.lastSaved = [
                    Sample("%s.sv" % x.name, decklayout.DILPLATE) for x in rxs
                ]
                for i in range(len(rxs)):
                    # Save with rtCarryForwardDil dilution to reduce amount of RT consumed (will have Ct's 2-3 lower than others)
                    self.e.transfer(rtCarryForwardVol, rxs[i],
                                    self.lastSaved[i], (False, False))
                    self.e.transfer(
                        rtCarryForwardVol * (rtCarryForwardDil - 1),
                        decklayout.WATER, self.lastSaved[i], (False, True)
                    )  # Use pipette mixing -- shaker mixing will be too slow

            #print "NSplit=",nsplit,", PCR vol=",pcrvol/nsplit,", srcdil=",pcrdil,", input vol=",pcrvol/nsplit/pcrdil
            minvol = min([r.volume for r in rxs])
            maxpcrvol = (minvol - 15 - 1.4 * nsplit) * pcrdil
            if maxpcrvol < pcrvol:
                print "Reducing PCR volume from %.1ful to %.1ful due to limited input" % (
                    pcrvol, maxpcrvol)
                pcrvol = maxpcrvol

            if keepCleaved:
                master = "MTaqC"
            else:
                master = "MTaqU"

            if self.barcoding:
                primers = self.bcprimers[self.rndNum - 1]
                if primers is not None and nsplit > 1:
                    primers = primers * nsplit
            else:
                primers = None

            if primers is None:
                primers = [("T7%sX" % x).replace("T7T7", "T7")
                           for x in prefixOut] * nsplit

            print "Running PCR with master=", master, ", primers=", primers
            pcr = self.runPCR(src=rxs * nsplit,
                              vol=pcrvol / nsplit,
                              srcdil=pcrdil,
                              ncycles=cycles,
                              primers=primers,
                              usertime=self.usertime if keepCleaved else None,
                              fastCycling=False,
                              inPlace=False,
                              master=master,
                              lowhi=self.lowhi,
                              annealTemp=57)
            if keepCleaved and self.regenPCRCycles is not None:
                # Regenerate prefix
                pcr2 = self.runPCR(src=pcr,
                                   vol=self.regenPCRVolume,
                                   srcdil=self.regenPCRDilution,
                                   ncycles=self.regenPCRCycles,
                                   primers=None,
                                   usertime=None,
                                   fastCycling=False,
                                   inPlace=False,
                                   master="MTaqR",
                                   lowhi=self.lowhi,
                                   annealTemp=55)
                # Add BT575p for 1 more cycle
                for p in pcr2:
                    self.e.transfer(p.volume * 0.5 / 10,
                                    reagents.getsample("Unclvd-Stop"), p,
                                    (False, False))
                # One more cycle
                cycling = ' TEMP@95,30 TEMP@55,30 TEMP@68,30 TEMP@25,2'
                worklist.pyrun('PTC\\ptcsetpgm.py rfin %s' % (cycling))
                self.e.runpgm("rfin",
                              5.0,
                              False,
                              max([p.volume for p in pcr2]),
                              hotlidmode="CONSTANT",
                              hotlidtemp=100)
                pcr = pcr2  # Use 2nd PCR as actual output

            if len(pcr) <= len(names):
                # Don't relabel if we've split
                for i in range(len(pcr)):
                    pcr[i].name = names[i] + ".pcr"

            #print "Volume remaining in PCR input source: [",",".join(["%.1f"%r.volume for r in rxs]),"]"
            needDil = finalConc / self.qConc
            print "Projected final concentration = %.0f nM" % (needDil *
                                                               self.qConc)
            for i in range(len(pcr)):
                pcr[i].conc = Concentration(stock=finalConc,
                                            final=None,
                                            units='nM')

            if self.pcrSave:
                # Save samples at 1x (move all contents -- can ignore warnings)
                maxSaveVol = (100
                              if self.savedilplate else 1500) * 1.0 / nsplit

                if self.finalRound and nsplit == 1 and self.savedilplate:
                    print "Skipping save of final PCR"
                    sv = pcr
                else:
                    sv = self.saveSamps(
                        src=pcr[:len(rxs)],
                        vol=[
                            min([maxSaveVol, x.volume]) for x in pcr[:len(rxs)]
                        ],
                        dil=1,
                        plate=(decklayout.DILPLATE if self.savedilplate else
                               decklayout.EPPENDORFS),
                        atEnd=self.savePCRAtEnd)
                    if nsplit > 1:
                        # Combine split
                        for i in range(len(rxs), len(rxs) * nsplit):
                            self.e.transfer(min([maxSaveVol, pcr[i].volume]),
                                            pcr[i],
                                            sv[i % len(sv)],
                                            mix=(False,
                                                 i >= len(rxs) * (nsplit - 1)))
                        # Correct concentration (above would've assumed it was diluted)
                        for i in range(len(sv)):
                            sv[i].conc = pcr[i].conc

                if "pcr" in self.qpcrStages:
                    for i in range(len(sv)):
                        q.addSamples(sv[i],
                                     needDil,
                                     primers=primerSet[i],
                                     names=["%s.pcr" % names[i]])

                processEff = 0.5  # Estimate of overall efficiency of process
                print "Have %.2f pmoles of product (%.0f ul @ %.1f nM)" % (
                    sv[0].volume * sv[0].conc.stock / 1000, sv[0].volume,
                    sv[0].conc.stock)
                return sv
            else:
                assert "pcr" not in self.qpcrStages  ## Not implemented
                return pcr[:len(rxs)]
        elif self.noPCRCleave:
            print "Dilution instead of PCR: %.2f" % self.nopcrdil
            # Need to add enough t7prefix to compensate for all of the Stop primer currently present, regardless of whether it is for cleaved or uncleaved
            # Will result in some short transcripts corresponding to the stop primers that are not used for cleaved product, producing just GGG_W_GTCTGC in the next round.  These would be reverse-trancribed, but may compete for T7 yield
            t7prefix = reagents.getsample("BT88")
            dil = self.extpostdil[self.rndNum - 1] * userDil
            stopconc = 1000.0 / dil
            bt88conc = t7prefix.conc.stock
            relbt88 = stopconc / bt88conc
            print "Using EXT with %.0fnM of stop oligo as input to next T7, need %.2ful of BT88@%.0fnM per ul of sample" % (
                stopconc, relbt88, bt88conc)
            for r in rxs:
                vol = r.volume * relbt88
                t7prefix.conc.final = t7prefix.conc.stock * vol / (r.volume +
                                                                   vol)
                r.conc.final = r.conc.stock * r.volume / (r.volume + vol)
                self.e.transfer(vol, t7prefix, r, mix=(False, False))

            if self.nopcrdil > (1 + relbt88):
                self.diluteInPlace(tgt=rxs,
                                   dil=self.nopcrdil / (1.0 + relbt88))
                needDil = needDil / self.nopcrdil
                print "Dilution of EXT product: %.2fx * %.2fx = %2.fx\n" % (
                    1 + relbt88, self.nopcrdil / (1 + relbt88), self.nopcrdil)
            else:
                print "Dilution of EXT product: %.2fx\n" % (1 + relbt88)

            return rxs
        else:
            return rxs
예제 #8
0
# Generic selection progam
import debughook
import math

from Experiment.concentration import Concentration
from Experiment.sample import Sample
from Experiment import worklist, reagents, decklayout, logging, clock
from TRPLib.TRP import TRP
from TRPLib.QSetup import QSetup
from pcrgain import pcrgain

reagents.add("BT5310", well="B5", conc=Concentration(20, 20, "pM"))


class PGMSelect(TRP):
    '''Selection experiment'''
    def __init__(self,
                 inputs,
                 rounds,
                 firstID,
                 pmolesIn,
                 directT7=True,
                 templateDilution=0.3,
                 tmplFinalConc=50,
                 saveDil=24,
                 qpcrWait=False,
                 allLig=False,
                 qpcrStages=["negative", "template", "ext", "finalpcr"],
                 finalPlus=True,
                 t7dur=30,
                 usertime=10,
예제 #9
0
    def runPCR(self,
               prefix,
               src,
               vol,
               srcdil,
               tgt=None,
               ncycles=20,
               suffix='S',
               sepPrimers=True,
               primerDil=4):
        ## PCR
        [prefix, src, tgt, vol, srcdil,
         suffix] = listify([prefix, src, tgt, vol, srcdil, suffix])
        for i in range(len(tgt)):
            if tgt[i] is None:
                tgt[i] = Sample(
                    "%s.P%s%s" % (src[i].name, prefix[i], suffix[i]),
                    src[i].plate)

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc = Concentration(srcdil[i], 1)

        if sepPrimers:
            sampvols = [vol[i] / srcdil[i] for i in range(len(src))]
            mm = reagents.getsample("MPCR")
            mmvols = [
                vol[i] / mm.conc.dilutionneeded() for i in range(len(src))
            ]
            for s in prefix + suffix:
                if not reagents.isReagent(s):
                    reagents.add(name=s, conc=primerDil, extraVol=30)

            sprefix = [reagents.getsample(p) for p in prefix]
            ssuffix = [reagents.getsample(p) for p in suffix]

            prefixvols = [
                vol[i] / sprefix[i].conc.dilutionneeded()
                for i in range(len(src))
            ]
            suffixvols = [
                vol[i] / ssuffix[i].conc.dilutionneeded()
                for i in range(len(src))
            ]
            watervols = [
                vol[i] - mmvols[i] - prefixvols[i] - suffixvols[i] -
                sampvols[i] for i in range(len(src))
            ]

            print "water=", watervols, ", mm=", mmvols, ", prefix=", prefixvols, ", suffix=", suffixvols, ", samp=", sampvols
            self.e.multitransfer(watervols, decklayout.WATER, tgt,
                                 (False, False))  # Transfer water
            self.e.multitransfer(mmvols, mm, tgt,
                                 (False, False))  # PCR master mix
            sprefixset = set(sprefix)
            ssuffixset = set(ssuffix)
            if len(sprefixset) < len(ssuffixset):
                # Distribute sprefix first
                for p in sprefixset:
                    self.e.multitransfer([
                        prefixvols[i]
                        for i in range(len(src)) if sprefix[i] == p
                    ], p, [tgt[i] for i in range(len(src)) if sprefix[i] == p],
                                         (False, False))
                # Then individually add ssuffix
                for i in range(len(src)):
                    self.e.transfer(suffixvols[i], ssuffix[i], tgt[i],
                                    (False, False))
            else:
                # Distribute ssuffix first
                for p in ssuffixset:
                    self.e.multitransfer([
                        suffixvols[i]
                        for i in range(len(src)) if ssuffix[i] == p
                    ], p, [tgt[i] for i in range(len(src)) if ssuffix[i] == p],
                                         (False, False))
                # Then individually add sprefix
                for i in range(len(src)):
                    self.e.transfer(prefixvols[i], sprefix[i], tgt[i],
                                    (False, False))
            # Now add templates
            for i in range(len(src)):
                self.e.transfer(sampvols[i], src[i], tgt[i], (False, False))

        else:
            primer = [prefix[i] + suffix[i] for i in range(len(prefix))]
            print "primer=", primer
            for up in set(primer):
                s = "MPCR%s" % up
                if not reagents.isReagent(s):
                    reagents.add(name=s, conc=4 / 3.0, extraVol=30)
                self.e.stage(
                    'PCR%s' % up, [reagents.getsample("MPCR%s" % up)],
                    [src[i] for i in range(len(src)) if primer[i] == up],
                    [tgt[i] for i in range(len(tgt)) if primer[i] == up],
                    [vol[i] for i in range(len(vol)) if primer[i] == up],
                    destMix=False)
        pgm = "PCR%d" % ncycles
        self.e.shakeSamples(tgt, returnPlate=False)
        #        worklist.pyrun('PTC\\ptcsetpgm.py %s TEMP@95,120 TEMP@95,30 TEMP@55,30 TEMP@72,25 GOTO@2,%d TEMP@72,180 TEMP@16,2'%(pgm,ncycles-1))
        worklist.pyrun(
            'PTC\\ptcsetpgm.py %s TEMP@95,120 TEMP@95,10 TEMP@57,10 GOTO@2,%d TEMP@72,120 TEMP@25,2'
            % (pgm, ncycles - 1))
        self.e.runpgm(pgm,
                      4.80 + 1.55 * ncycles,
                      False,
                      max(vol),
                      hotlidmode="CONSTANT",
                      hotlidtemp=100)
        return tgt
예제 #10
0
    def runLig(self,
               prefix=None,
               src=None,
               vol=None,
               srcdil=None,
               tgt=None,
               master=None,
               anneal=True,
               ligtemp=25):
        if master is None:
            master = [
                reagents.getsample("MLigAN7")
                if p == 'A' else reagents.getsample("MLigBN7") for p in prefix
            ]

        #Extension
        [src, tgt, vol, srcdil,
         master] = listify([src, tgt, vol, srcdil, master])
        if tgt is None:
            tgt = [
                Sample("%s.%s" % (src[i].name, master[i].name),
                       decklayout.SAMPLEPLATE) for i in range(len(src))
            ]

        # Need to check since an unused ligation master mix will not have a concentration
        minsrcdil = 1 / (1 - 1 / master[0].conc.dilutionneeded() - 1 /
                         reagents.getsample("MLigase").conc.dilutionneeded())
        for i in srcdil:
            if i < minsrcdil:
                print "runLig: srcdil=%.2f, but must be at least %.2f based on concentrations of master mixes" % (
                    i, minsrcdil)
                assert (False)

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc = Concentration(srcdil[i], 1)

        i = 0
        while i < len(tgt):
            lasti = i + 1
            while lasti < len(tgt) and master[i] == master[lasti]:
                lasti = lasti + 1
            self.e.stage('LigAnneal', [master[i]],
                         src[i:lasti],
                         tgt[i:lasti], [vol[j] / 1.5 for j in range(i, lasti)],
                         1.5,
                         destMix=False)
            i = lasti

        if anneal:
            self.e.shakeSamples(tgt, returnPlate=False)
            self.e.runpgm("TRPANN",
                          5,
                          False,
                          max(vol),
                          hotlidmode="CONSTANT",
                          hotlidtemp=100)
        self.e.stage('Ligation', [reagents.getsample("MLigase")], [],
                     tgt,
                     vol,
                     destMix=False)
        self.e.shakeSamples(tgt, returnPlate=False)
        self.runLigPgm(max(vol), ligtemp)
        return tgt
예제 #11
0
reagents.add("MStpX", well="C2", conc=2)
reagents.add("MStopXSelfExtendB", well="C2", conc=5)
reagents.add("MQREF", well="D2", conc=10.0 / 6)
reagents.add("MQAX", well="E2", conc=10.0 / 6)
reagents.add("MQBX", well="A3", conc=10.0 / 6)
reagents.add("MPCRAX", well="B3", conc=4.0 / 3)
reagents.add("MPCRBX", well="C3", conc=4.0 / 3)
reagents.add("MQMX", well="D3", conc=10.0 / 6)
reagents.add("MQWX", well="E3", conc=10.0 / 6)
reagents.add("SSD", well="A4", conc=10.0)
reagents.add("MLigAT7W", well="B4", conc=3)
reagents.add("BeadBuffer", well="C4", conc=1)
reagents.add("Dynabeads", well="D4", conc=2, hasBeads=True)
reagents.add("MQT7X", well="E4", conc=15.0 / 9)
reagents.add("MStpBeads", well="A5", conc=3.7)
reagents.add("QPCRREF", well="B5", conc=Concentration(50, 50, 'pM'))
reagents.add("MPCRT7X", well="C5", conc=4.0 / 3)
reagents.add("NaOH", well="D5", conc=1.0)
reagents.add("TE8", well="E5", conc=None)

reagents.add("MLigBT7WBio", well=None, conc=3)
reagents.add("MLigBT7Bio", well=None, conc=3)
reagents.add("MLigBT7", well=None, conc=3)
reagents.add("MPCR", well=None, conc=4)
reagents.add("MLigB", well=None, conc=3)
reagents.add("MNegRT", well=None, conc=2)
reagents.add("MLigAT7", well=None,
             conc=3)  # Conc is relative to annealing time (not to post-ligase)
reagents.add("Theo", well=None, conc=Concentration(25, 7.5, 'mM'))