Beispiel #1
0
 def fromStream(self, stream, ownerDoc=None):
     self.initParser()
     self.initState(ownerDoc)
     success = self.parser.ParseFile(stream)
     if not success:
         from xml.dom.ext import FtDomException
         from xml.dom import XML_PARSE_ERR
         if self._rootNode: ReleaseNode(self._rootNode)
         if self._ownerDoc: ReleaseNode(self._ownerDoc)
         raise FtDomException(
             XML_PARSE_ERR,
             (self.parser.ErrorLineNumber, self.parser.ErrorColumnNumber,
              expat.ErrorString(self.parser.ErrorCode)))
     self._completeTextNode()
     return self._rootNode or self._ownerDoc
Beispiel #2
0
    def sciListPage(self, type, singlePages="yes"):
        nightList = []
        document = implementation.createDocument(None, None, None)
        rootElement = document.createElement("document")
        rootElement.setAttribute("title", "%s exposures in run %s" % (string.upper(type), self.run))
        tableNode = AddTableToDoc(document, "List of %s exposures" % (type, ),
                                  ["Exposure", "Object", "Exp. Time/s", "Seeing/\"", "Background/(1/s)", "<e1>", "<e2>", "ZP/mag"],
                                  ["left", "left", "right", "right", "right", "right", "right", "right"])
        sciFrameListList = self.getSciFrames(type)
        for sciFrameList in sciFrameListList:
            recordNode = document.createElement("record")
            for val in sciFrameList:
                if sciFrameList.index(val) == 0:
                    AddTextFieldToRecord(document, recordNode, val,
                                         [("link", os.path.join("science_frames", string.lower(val[:-4]+"html")))])
                    if singlePages == "yes":
                        print "Creating single page for", val
                        self.createSingleSci(type, val)
                else:
                    AddTextFieldToRecord(document, recordNode, val)
            # Add ZP from Image Header
            imgPath = os.path.join(self.runDir, type, sciFrameList[0][:-5]+"_1"+self.extension+".fits")
            zp = GetHeaderVal(imgPath, "ZP")
            coeff = GetHeaderVal(imgPath, "COEFF")
            nightID = GetHeaderVal(imgPath, "GABODSID")
            zpChoice = GetHeaderVal(imgPath, "ZPCHOICE")
            if not nightID:
                continue
            if not nightID in nightList:
                solFile = os.path.join(self.runDir, "STANDARD_%s" % (self.filter,), "calib",
                               "night_%d_%s_result.asc" % (nightID, self.filter))
                if os.path.exists(solFile):
                    self.createPhotPage(nightID, zp, coeff, zpChoice)
                    link = os.path.join("standard", "night_%d.html" % (nightID,))
                else:
                    link = None
                    
                nightList.append(nightID)

            if zp and float(zp) > -0.9:
                AddTextFieldToRecord(document, recordNode, "%.2f" % (round(float(zp), 2), ), [("link", link)])
#                AddTextFieldToRecord(document, recordNode, "%.2f" % (round(float(zp), 2)))
            elif link:
                AddTextFieldToRecord(document, recordNode, "-1", [("link", link)])
            else:
                AddTextFieldToRecord(document, recordNode, "-")
            tableNode.appendChild(recordNode)
        rootElement.appendChild(tableNode)

        footerNode = AddFooterNode(document)
        rootElement.appendChild(footerNode)
        document.appendChild(rootElement)
        ConvertDocument(self.webDir, string.lower(type), document, "calframes.xslt")
        ReleaseNode(document)
        os.chdir(self.cwd)
        return
Beispiel #3
0
    def toString(self):
        if self.detached:
            raise InvalidStateErr()

        df = self.cloneContents()

        res = self.__recurseToString(df)

        from xml.dom.ext import ReleaseNode
        ReleaseNode(df)

        return res
Beispiel #4
0
    def createSingleSci(self, type, frame):
        sciPageDir = os.path.join(self.webDir, "science_frames")
        
        document = implementation.createDocument(None, None, None)
        rootElement = document.createElement("document")
        rootElement.setAttribute("title", frame)
        mosaicNode = document.createElement("mosaic")
        mosaicNode.setAttribute("heading", "Binned Mosaic for %s" % (frame, ))
        status = AddImgNode(self.runDir, document, mosaicNode, type, frame[:-5], sciPageDir)
        if status != "ok":
            ReleaseNode(document)
            print status
            return
        rootElement.appendChild(mosaicNode)

        psfNode = document.createElement("mosaic")
        psfNode.setAttribute("heading", "PSF Pattern for %s" % (frame, ))
        psFile = os.path.join(self.runDir, type, "cat", "PSFcheck", frame[:-5]+".ps")
        status, pngPath = self.convertPSFPlot(psFile)
        if status != "ok":
            ReleaseNode(document)
            print status
            return
        imgNode = document.createElement("img")
        imgPath = os.path.join("images", os.path.split(pngPath)[1])
        imgNode.setAttribute("source", imgPath)
        psfNode.appendChild(imgNode)
        rootElement.appendChild(psfNode)

        footerNode = AddFooterNode(document)
        rootElement.appendChild(footerNode)
        document.appendChild(rootElement)
        ConvertDocument(sciPageDir, string.lower(frame[:-5]), document, "calframes.xslt")
        ReleaseNode(document)

        return
Beispiel #5
0
    def indexPage(self):
        document = implementation.createDocument(None, None, None)
        rootElement = document.createElement("document")
        rootElement.setAttribute("title", "Contents of run %s, filter %s" % (self.run, self.filter))

        for files in ["BIAS", "DARK", "SCIENCE_%s" % (self.filter, ),
                      "SKYFLAT_%s" % (self.filter, ),
                      "DOMEFLAT_%s" % (self.filter, ),
                      "STANDARD_%s" % (self.filter, )]:
            checkPath = os.path.join(self.webDir, string.lower(files)+".html")
            if not os.path.exists(checkPath):
                continue
            filesNode = document.createElement("files")
            filesNode.setAttribute("link", string.lower(files)+".html")
            textNode = document.createTextNode(files)
            filesNode.appendChild(textNode)
            rootElement.appendChild(filesNode)

        footerNode = AddFooterNode(document)
        rootElement.appendChild(footerNode)
        document.appendChild(rootElement)
        ConvertDocument(self.webDir, "index", document, "runindex.xslt")
        ReleaseNode(document)
        return
Beispiel #6
0
 def releaseNode(self, node):
     "Free a DOM tree"
     node and ReleaseNode(node)
Beispiel #7
0
    def calFramePage(self, type):
        document = implementation.createDocument(None, None, None)
        rootElement = document.createElement("document")
        rootElement.setAttribute("title", "%s frames in run %s" % (string.upper(type), self.run))
        mosaicNode = document.createElement("mosaic")
        mosaicNode.setAttribute("heading", "Master %s frame" % (string.upper(type), ))
        status = self.addImgNode(document, mosaicNode, type)
        if status != "ok":
            ReleaseNode(document)
            print status
            return
        rootElement.appendChild(mosaicNode)
        masterFrameNode = AddTableToDoc(document, "Master %s frames" % (type, ),
                                        ["Frame", "mean", "median", "stdev", "min", "max"],
                                        ["left", "right", "right", "right", "right", "right"])
        chipFrameNodes = []
        for chip in range(1, self.noChips+1):
            frameName = "%s_%d.fits" % (type, chip)
            calFrame = os.path.join(self.runDir, type, frameName)
            if not os.path.exists(calFrame):
                print "No such calibration file: ", calFrame
                continue
            fimg=pyfits.open(calFrame)
            dat=fimg[0].data
            recordNode = document.createElement("record")
            AddTextFieldToRecord(document, recordNode, frameName)
            AddTextFieldToRecord(document, recordNode, "%.2f" % (round(dat.mean(), 2)), )
            median = GetMedian(dat)
            AddTextFieldToRecord(document, recordNode, "%.2f" % (round(median, 2)), )
            AddTextFieldToRecord(document, recordNode, "%.2f" % (round(GetCutStdev(dat), 2)), )
            AddTextFieldToRecord(document, recordNode, "%.2f" % (round(dat.min(), 2)), )
            AddTextFieldToRecord(document, recordNode, "%.2f" % (round(dat.max(), 2)), )
            masterFrameNode.appendChild(recordNode)

            calDict = {}
            catFile = os.path.join(self.runDir, type, "cat", "chip_%d_stat.cat" % (chip, ))
            if os.path.exists(catFile):
                ftab = pyfits.open(catFile)
                tabHDU = ftab["STATS"]
                tabDat = tabHDU.data
                for row in range(len(tabDat)):
                    try:
                        exptime = tabDat[row].field("EXPTIME")
                    except:
                        exptime = None
                    calDict[tabDat[row].field("FITSFILE")] = {"mode"   : tabDat[row].field("Mode"),
                                                              "median" : tabDat[row].field("Median"),
                                                              "mean"   : tabDat[row].field("Mean"),
                                                              "stdev"  : tabDat[row].field("Stdev"),
                                                              "exptime": exptime}
                ftab.close()
            singleFrameNode = self.singleFrameTable(type, fimg[0].header, chip, calDict, document)
            chipFrameNodes.append(singleFrameNode)
            fimg.close()
        rootElement.appendChild(masterFrameNode)

        for singleFrameTable in chipFrameNodes:
            rootElement.appendChild(singleFrameTable)

        footerNode = AddFooterNode(document)
        rootElement.appendChild(footerNode)        
        document.appendChild(rootElement)
        ConvertDocument(self.webDir, string.lower(type), document, "calframes.xslt")
        ReleaseNode(document)
        os.chdir(self.cwd)
        return
Beispiel #8
0
    def createPhotPage(self, night, zp, coeff, zpChoice=None):
        stdPageDir = os.path.join(self.webDir, "standard")
        pipe = os.popen("caldate -d 31/12/1998 -i %d" % (night,))
        result = pipe.read()
        pipe.close()
        civNight = string.split(result)[2]

        document = implementation.createDocument(None, None, None)
        rootElement = document.createElement("document")
        rootElement.setAttribute("title", "Photometric solutions for night %d (%s)"
                                 % (night, civNight))
        tableNode = AddTableToDoc(document, "Photometric Solutions",
                                  ["ZP/mag", "Ext. Coeff.", "Col. Term", "Type", "Selected"],
                                  ["right", "right", "right", "left", "left"])
        solFile = os.path.join(self.runDir, "STANDARD_%s" % (self.filter,), "calib",
                               "night_%d_%s_result.asc" % (night, self.filter))
        f = open(solFile, "r")
        i = 0
        solType=["Z-K-C", "Z---C", "Z----"] 
        for sol in f.readlines():
            recordNode = document.createElement("record")
            zpSol, coeffSol, ctSol = string.split(sol)
            if not zpChoice:
                # It's really crappy that we have to find the accepted solution again
                # by comparing with all solutions. This is bound to fail at some point
                try:
                    if fabs(float(zpSol)-zp) < 1e-4 and fabs(float(coeffSol)-coeff) <1e-4:
                        selected = "yes"
                        attr = [("mode", "b")]
                    else:
                        selected = "no"
                        attr = []
                # Older version did not always insert ZP and COEFF, they might be None ...
                except TypeError:
                    selected = "no"
                    attr = []
            else:
                # New version write to the header which solution was chosen
                if zpChoice == i+1:
                    selected = "yes"
                    attr = [("mode", "b")]
                else:
                    selected = "no"
                    attr = []
                    
            AddTextFieldToRecord(document, recordNode,
                                     "%.2f" % (round(float(zpSol), 2), ), attr)
            AddTextFieldToRecord(document, recordNode,
                                     "%.2f" % (round(float(coeffSol), 2), ), attr)
            AddTextFieldToRecord(document, recordNode,
                                     "%.2f" % (round(float(ctSol), 2), ), attr)
            AddTextFieldToRecord(document, recordNode, solType[i], attr)
            AddTextFieldToRecord(document, recordNode, selected, attr)
            i += 1
            tableNode.appendChild(recordNode)
            
        rootElement.appendChild(tableNode)

        plotNode = document.createElement("photcal")
        plotNode.setAttribute("heading", "Plot of photometric solutions")
        psFile = os.path.join(self.runDir, "STANDARD_%s" % (self.filter,), "calib",
                               "night_%d_%s_result.ps" % (night, self.filter))
        status, pngPath = self.convertPhotCalPlot(psFile)
        if status != "ok":
            ReleaseNode(document)
            print status
            return
        imgNode = document.createElement("img")
        imgPath = os.path.join("images", os.path.split(pngPath)[1])
        imgNode.setAttribute("source", imgPath)
        plotNode.appendChild(imgNode)
        rootElement.appendChild(plotNode)
        
        footerNode = AddFooterNode(document)
        rootElement.appendChild(footerNode)
        document.appendChild(rootElement)
        ConvertDocument(stdPageDir, "night_%d" % (night,), document, "calframes.xslt")
        ReleaseNode(document)
        return
Beispiel #9
0
    def makeCoaddPage(self, dir):

        cwd = os.getcwd()
        os.chdir(dir)
        coaddWeb = os.path.join(self.webDir, "coadd_"+self.ident)
        if not os.path.exists(coaddWeb):
            os.makedirs(coaddWeb)
        frameList = glob.glob("*%s.%s.fits" % (self.extension, self.ending))
        fitsFile = os.path.join(dir,
                                "%s_%s.%s.swarp.fits" % (self.field, self.filter, self.ident))
        status, jpgPath = ConvertMosaicLarge(fitsFile, self.webDir, 2)
        if not status == "ok":
            print status

        title = "%s_%s %s" % (self.field, self.filter, self.ident)
        document = implementation.createDocument(None, None, None)
        rootElement = document.createElement("document")
        rootElement.setAttribute("title", title)
        if jpgPath:
            imgNode = document.createElement("img")
            imgPath = os.path.join("../images", os.path.split(jpgPath)[1])
            imgNode.setAttribute("source", imgPath)
            rootElement.appendChild(imgNode)

        fitsFile = os.path.join(dir,
                                "%s_%s.%s.swarp.weight.fits"
                                % (self.field, self.filter, self.ident))
        status, jpgPath = ConvertMosaicLarge(fitsFile, self.webDir, 0, levels=[0, None])

        if not status == "ok":
            print status

        if jpgPath:
            imgNode = document.createElement("img")
            imgPath = os.path.join("../images", os.path.split(jpgPath)[1])
            imgNode.setAttribute("source", imgPath)
            rootElement.appendChild(imgNode)

        diagNode = document.createElement("diagPlots")
        plotList = glob.glob("../postcoadd/plots/%s_%s.%s*" %
                             (self.field, self.filter, self.ident))

        setPlotList = glob.glob("../plots/coadd_%s*.ps" % (self.ident, ))
        print "setPlotList: ", setPlotList
        plotList = setPlotList + plotList
        
        for plot in plotList:
            status, pngPath = self.convertPlot(plot)
            if not status == "ok":
                print status

            if pngPath:
                imgNode = document.createElement("img")
                imgPath = os.path.join("../images", os.path.split(pngPath)[1])
                imgNode.setAttribute("source", imgPath)
                diagNode.appendChild(imgNode)
        rootElement.appendChild(diagNode)
                

        suffix = "*_1%s.%s.fits" % (self.extension, self.ending)
        frameList = glob.glob(suffix)
        sciNode = document.createElement("runList")
        runList = []
        frameDict = {}
        for frame in frameList:
            run = self.getRun(frame)
            if not run in runList:
                runList.append(run)
                frameDict[run] = []
            frameDict[run].append(frame)
        runList.sort()
        tableNode = AddTableToDoc(document, "Runs and Exposures",
                                  ["No.", "Run", "Exposure"],
                                  ["right", "left", "left"])
        i = 1
        for run in runList:
            print run
            recordNode = document.createElement("record")
            AddTextFieldToRecord(document, recordNode, "")
            AddTextFieldToRecord(document, recordNode, run,
                                 [("link", os.path.join("..", "..", "..", self.filter, run))])
            AddTextFieldToRecord(document, recordNode, "")
            tableNode.appendChild(recordNode)
            frameDict[run].sort()
            for frame in frameDict[run]:
                print frame
                print suffix
                frameEntry = frame[:-(len(suffix)-1)]
#                frameEntry = frame[:-12]
                recordNode = document.createElement("record")
                AddTextFieldToRecord(document, recordNode, str(i))
                i += 1
                AddTextFieldToRecord(document, recordNode, "")
                link = os.path.join("..", "..", "..", self.filter, run, "science_frames",
                                    string.lower(frameEntry)+".html")
                AddTextFieldToRecord(document, recordNode, frameEntry,
                                     [("link", link)])
                tableNode.appendChild(recordNode)
        sciNode.appendChild(tableNode)

        footerNode = AddFooterNode(document)
        rootElement.appendChild(footerNode)
        rootElement.appendChild(sciNode)
        document.appendChild(rootElement)
        xmlFile = os.path.join(coaddWeb, "index.xml")
        htmlFile = os.path.join(coaddWeb, "index.html")
        f = open(xmlFile, "w")
        xml.dom.ext.PrettyPrint(document, f)
        f.close()
        ReleaseNode(document)
        cmd = "xsltproc %s/coaddframe.xslt %s > %s" % (PipeWWW, xmlFile, htmlFile)
        os.system(cmd)

        os.chdir(cwd)
        return
Beispiel #10
0
    def makeCoaddIndex(self):

        cwd = os.getcwd()
        os.chdir(self.coaddDir)
        dList = glob.glob("coadd_*")
        dList.sort()
        
        document = implementation.createDocument(None, None, None)
        rootElement = document.createElement("document")
        title = "%s (%s-band) Co-Addition Overview" % (self.field, self.filter)
        rootElement.setAttribute("title", title)
        tableNode = AddTableToDoc(document, "Co-additions for this field",
                                  ["Identifier", "Seeing/arcsec", "ZP/mag", "Exp. Time/s", "Selection criteria"],
                                  ["left", "right", "right", "right", "left"])
        for d in dList:
            dID = string.split(d, "_", 1)[1]
            recordNode = document.createElement("record")
            AddTextFieldToRecord(document, recordNode, d, (("link", d), ))
            fitsFile = "%s/%s_%s.%s.swarp.fits" % (d, self.field, self.filter, dID)
            val = GetHeaderVal(fitsFile, "SEEING")
            if val:
                val = round(val, 2)
            AddTextFieldToRecord(document, recordNode, val)
            val = GetHeaderVal(fitsFile, "MAGZP")
            if val:
                val = round(val, 2)
            AddTextFieldToRecord(document, recordNode, val)
            val = GetHeaderVal(fitsFile, "TEXPTIME")
            if val:
                val = round(val, 1)
            else:
                val = GetHeaderVal(fitsFile, "EXPTIME")
                if val:
                  val = round(val, 1)  
            AddTextFieldToRecord(document, recordNode, val)
            i = 1
            cond = ""
            while 1:
                val = GetHeaderVal(fitsFile, "COND%d" % (i, ))
                if not val:
                    break
                
                cond += val
                i += 1
            AddTextFieldToRecord(document, recordNode, cond)
            tableNode.appendChild(recordNode)
        
        rootElement.appendChild(tableNode)

        diagNode = document.createElement("diagPlots")
        plotList = glob.glob("/%s/%s/plots/%s*.ps" % (self.fieldDir, self.filter, self.filter))
        
        for plot in plotList:
            status, pngPath = self.convertPlot(plot)
            if not status == "ok":
                print status

            if pngPath:
                imgNode = document.createElement("img")
                imgPath = os.path.join("images", os.path.split(pngPath)[1])
                imgNode.setAttribute("source", imgPath)
                diagNode.appendChild(imgNode)
        rootElement.appendChild(diagNode)

        footerNode = AddFooterNode(document)
        rootElement.appendChild(footerNode)
        
        document.appendChild(rootElement)
        xmlFile = os.path.join(self.webDir, "index.xml")
        htmlFile = os.path.join(self.webDir, "index.html")
        f = open(xmlFile, "w")
        xml.dom.ext.PrettyPrint(document, f)
        f.close()
        ReleaseNode(document)
        cmd = "xsltproc %s/coaddlist.xslt %s > %s" % (PipeWWW, xmlFile, htmlFile)
        os.system(cmd)
        os.chdir(cwd)

        return dList
Beispiel #11
0
 def releaseNode(self, node):
     ReleaseNode(node)
Beispiel #12
0
    def deleteContents(self):
        """Delete the contents defined by this range"""

        #NOTE Use 4DOM ReleaseNode cause it is interface safe
        from xml.dom.ext import ReleaseNode

        if self.detached:
            raise InvalidStateErr()

        if self.startContainer == self.endContainer:
            if self.startOffset == self.endOffset:
                return
            if self.startContainer.nodeType in [
                    Node.TEXT_NODE, Node.COMMENT_NODE,
                    Node.PROCESSING_INSTRUCTION_NODE
            ]:
                #Adjust the character data
                self.startContainer.deleteData(
                    self.startOffset, 1 + self.endOffset - self.startOffset)

            else:
                #Delete a set number of children
                numDel = self.endOffset - self.startOffset + 1
                for ctr in range(numDel):
                    c = self.startContainer.removeChild(
                        self.startContainer.childNodes[self.startOffset])
                    ReleaseNode(c)

            self.__dict__['endContainer'] = self.startContainer
            self.__dict__['endOffset'] = self.endContainer
            self.__dict__['commonAncestorContainer'] = self.endContainer
            self.__dict__['collapsed'] = 1

        elif self.startContainer == self.commonAncestorContainer:
            #Delete up the endContainer
            #From the start to the end
            if self.endContainer.nodeType in [
                    Node.TEXT_NODE, Node.COMMENT_NODE,
                    Node.PROCESSING_INSTRUCTION_NODE
            ]:
                #Adjust the character data
                self.endContainer.deleteData(0, self.endOffset)
            else:
                numDel = self.endOffset
                for ctr in range(numDel):
                    c = self.endContainer.removeChild(
                        self.endContainer.childNodes[0])
                    ReleaseNode(c)

            cur = self.endContainer
            while cur.parentNode != self.commonAncestorContainer:
                while cur.previousSibling:
                    c = cur.parentNode.removeChild(cur.previousSibling)
                    ReleaseNode(c)
                cur = cur.parentNode

            #Delete up to the ancestor of end
            endAncestorChild = cur
            while self.startContainer.firstChild != endAncestorChild:
                c = self.startContainer.removeChild(
                    self.startContainer.firstChild)
                ReleaseNode(c)
        elif self.endContainer == self.commonAncestorContainer:
            if self.startContainer.nodeType in [
                    Node.TEXT_NODE, Node.COMMENT_NODE,
                    Node.PROCESSING_INSTRUCTION_NODE
            ]:
                #Adjust the character data
                self.startContainer.deleteData(
                    self.startOffset,
                    1 + len(self.startContainer.data) - self.startOffset)
            else:
                numDel = len(self.startContainer.childNodes) - self.startOffset
                for ctr in range(numDel):
                    c = self.startContainer.removeChild(
                        self.startContainer.childNodes[self.startOffset])
                    ReleaseNode(c)

            cur = self.startContainer
            while cur.parentNode != self.commonAncestorContainer:
                while cur.nextSibling:
                    c = cur.parentNode.removeChild(cur.nextSibling)
                    ReleaseNode(c)
                cur = cur.parentNode

            startAncestorChild = cur

            #Delete up to the ancestor of start
            startAncestorChild = cur
            startIndex = self.endContainer.childNodes.index(cur)
            numDel = self.endOffset - startIndex
            for ctr in range(numDel):
                c = self.endContainer.removeChild(
                    startAncestorChild.nextSibling)
                ReleaseNode(c)

        else:
            #From the start to the end
            if self.startContainer.nodeType in [
                    Node.TEXT_NODE, Node.COMMENT_NODE,
                    Node.PROCESSING_INSTRUCTION_NODE
            ]:
                #Adjust the character data
                self.startContainer.deleteData(
                    self.startOffset,
                    1 + len(self.startContainer.data) - self.startOffset)
            else:
                numDel = len(self.startContainer.childNodes) - self.startOffset
                for ctr in range(numDel):
                    c = self.startContainer.removeChild(
                        self.startContainer.childNodes[self.startOffset])
                    ReleaseNode(c)

            cur = self.startContainer
            while cur.parentNode != self.commonAncestorContainer:
                while cur.nextSibling:
                    c = cur.parentNode.removeChild(cur.nextSibling)
                    ReleaseNode(c)
                cur = cur.parentNode

            startAncestorChild = cur
            #Delete up the endContainer
            #From the start to the end
            if self.endContainer.nodeType in [
                    Node.TEXT_NODE, Node.COMMENT_NODE,
                    Node.PROCESSING_INSTRUCTION_NODE
            ]:
                #Adjust the character data
                self.endContainer.deleteData(0, self.endOffset)
            else:
                numDel = self.endOffset
                for ctr in range(numDel):
                    c = self.endContainer.removeChild(
                        self.endContainer.childNodes[0])
                    ReleaseNode(c)

            cur = self.endContainer
            while cur.parentNode != self.commonAncestorContainer:
                while cur.previousSibling:
                    c = cur.parentNode.removeChild(cur.previousSibling)
                    ReleaseNode(c)
                cur = cur.parentNode

            endAncestorChild = cur

            cur = startAncestorChild
            #Delete everything between us
            while cur.nextSibling != endAncestorChild:
                c = cur.parentNode.removeChild(cur.nextSibling)
                ReleaseNode(c)

        #Adjust the containers
        #FIXME What the heck is the spec talking about??
        self.__dict__['endContainer'] = self.startContainer
        self.__dict__['endOffset'] = self.startContainer
        self.__dict__['commonAncestorContainer'] = self.startContainer
        self.__dict__['collapsed'] = 1

        return None