def save(self, path, method='mg2', disp_layers=['rois'], extra_disp=None, **kwargs):
        ctmname = path+".ctm"
        svgname = path+".svg"
        jsname = path+".json"

        # Save CTM concatenation
        (lpts, _, _), lbin = self.left.save(method=method, **kwargs)
        (rpts, _, _), rbin = self.right.save(method=method, **kwargs)

        offsets = [0]
        with open(path+'.ctm', 'w') as fp:
            fp.write(lbin)
            offsets.append(fp.tell())
            fp.write(rbin)

        # Save the JSON descriptor | Need to add to this for extra_disp?
        jsdict = dict(rois=os.path.split(svgname)[1],
                      data=os.path.split(ctmname)[1],
                      names=self.types, 
                      materials=[],
                      offsets=offsets)
        if self.flatlims is not None:
            jsdict['flatlims'] = self.flatlims
        json.dump(jsdict, open(jsname, 'w'))

        # Compute and save the index map
        if method != 'raw':
            ptmap, inverse = [], []
            for hemi, pts in zip([self.left, self.right], [lpts, rpts]):
                kdt = cKDTree(hemi.pts)
                diff, idx = kdt.query(pts)
                ptmap.append(idx)
                inverse.append(idx.argsort())
        else:
            ptmap = inverse = np.arange(len(self.left.ctm)), np.arange(len(self.right.ctm))

        # Save the SVG with remapped indices (map 2D flatmap locations to vertices)
        if self.left.flat is not None:
            # add sulci & display layers
            flatpts = np.vstack([self.left.flat, self.right.flat])
            roipack = db.get_overlay(self.subject, pts=flatpts, otype=disp_layers)
            # optionally add extra display layers
            if not extra_disp is None:
                esvgfile,elayerlist = extra_disp
                eroipack = db.get_overlay(self.subject,pts=flatpts, otype='external',
                    svgfile=esvgfile,layer=elayerlist)
                roipack = roipack + eroipack
            layers = roipack.setup_labels()
            if not isinstance(layers, (tuple, list)):
                layers = (layers,)
            
            # assign coordinates in left hemisphere negative values
            with open(svgname, "w") as fp:
                for layer in layers:
                    for element in layer.findall(".//{http://www.w3.org/2000/svg}text"):
                        idx = int(element.attrib["data-ptidx"])
                        if idx < len(inverse[0]):
                            idx = inverse[0][idx]
                        else:
                            idx -= len(inverse[0])
                            idx = inverse[1][idx] + len(inverse[0])
                        element.attrib["data-ptidx"] = str(idx)
                fp.write(roipack.toxml())
        return ptmap
Save CTM file for static html display. 
dataset/ETHPy150Open gallantlab/pycortex/cortex/brainctm.py/BrainCTM.save