def METHOD_NAME(self, template, specmin, nspec):
    """
    Compare specter and gpu_specter extractions
    """
    #- should also work with bundles and not starting at spectrum 0
    cmd = template.format(self.imgfile, self.psffile, self.fibermapfile,
            self.outfile, self.outmodel, specmin, nspec)
    opts = cmd.split(" ")[1:]
    args = desispec.scripts.extract.parse(opts)
    desispec.scripts.extract.main(args)   #- defaults to gpu_specter
    self.assertTrue(os.path.exists(self.outfile))
    frame1 = desispec.io.read_frame(self.outfile)
    model1 = fits.getdata(self.outmodel)
    os.remove(self.outfile)
    os.remove(self.outmodel)
    opts = cmd.split(" ")[1:]
    opts.append('--use-specter')
    args = desispec.scripts.extract.parse(opts)
    desispec.scripts.extract.main(args)   #- specter
    self.assertTrue(os.path.exists(self.outfile))
    frame2 = desispec.io.read_frame(self.outfile)
    os.remove(self.outfile)
    os.remove(self.outmodel)
    desispec.scripts.extract.main_mpi(args, comm=None)  #- specter MPI path
    self.assertTrue(os.path.exists(self.outfile))
    frame3 = desispec.io.read_frame(self.outfile)
    model3 = fits.getdata(self.outmodel)
    errmsg = f'for specmin={specmin}, nspec={nspec}'
    #- specter and gpu_specter are consistent to 5% sigma
    chi = (frame1.flux - frame2.flux) * np.sqrt(frame1.ivar)
    self.assertLess(np.max(np.abs(chi)), 0.05)
    #- specter results should be the same
    self.assertTrue(np.allclose(frame2.flux, frame3.flux))
    self.assertTrue(np.allclose(frame2.ivar, frame3.ivar))
    self.assertTrue(np.allclose(frame2.chi2pix, frame3.chi2pix))
    self.assertTrue(np.allclose(frame2.resolution_data, frame3.resolution_data))
    self.assertTrue(np.all(frame2.mask == frame3.mask))
    #- pixel model isn't valid for small bundles that actually overlap; don't test
    # self.assertTrue(np.allclose(model1, model2, rtol=1e-15, atol=1e-15))