Exemple #1
1
static PyObject * get_dataset(PyObject *self, PyObject *args)
{
  int i, j, k, num_atom;
  double symprec;
  SpglibDataset *dataset;
  PyArrayObject* lattice_vectors;
  PyArrayObject* atomic_positions;
  PyArrayObject* atom_types;
  PyObject* array, *vec, *mat, *rot, *trans, *wyckoffs, *equiv_atoms;
  
  double *p_lattice;
  double *p_positions;
  double lattice[3][3];
  double (*positions)[3];
  int *types_int;
  int *types;

  if (!PyArg_ParseTuple(args, "OOOd",
			&lattice_vectors,
			&atomic_positions,
			&atom_types,
			&symprec)) {
    return NULL;
  }

  p_lattice = (double(*))lattice_vectors->data;
  p_positions = (double(*))atomic_positions->data;
  num_atom = atom_types->dimensions[0];
  positions = (double(*)[3]) malloc(sizeof(double[3]) * num_atom);
  types_int = (int*)atom_types->data;
  types = (int*) malloc(sizeof(int) * num_atom);
  set_spglib_cell(lattice, positions, types, num_atom,
		  p_lattice, p_positions, types_int);
  dataset = spg_get_dataset(lattice, positions, types, num_atom, symprec);
  free(types);
  free(positions);

  array = PyList_New(10);

  /* Space group number, international symbol, hall symbol */
  PyList_SetItem(array, 0, PyInt_FromLong((long) dataset->spacegroup_number));
  PyList_SetItem(array, 1, PyString_FromString(dataset->international_symbol));
  PyList_SetItem(array, 2, PyInt_FromLong((long) dataset->hall_number));
  PyList_SetItem(array, 3, PyString_FromString(dataset->hall_symbol));

  /* Transformation matrix */
  mat = PyList_New(3);
  for (i = 0; i < 3; i++) {
    vec = PyList_New(3);
    for (j = 0; j < 3; j++) {
      PyList_SetItem(vec, j,
		     PyFloat_FromDouble(dataset->transformation_matrix[i][j]));
    }
    PyList_SetItem(mat, i, vec);
  }
  PyList_SetItem(array, 4, mat);

  /* Origin shift */
  vec = PyList_New(3);
  for (i = 0; i < 3; i++) {
    PyList_SetItem(vec, i, PyFloat_FromDouble(dataset->origin_shift[i]));
  }
  PyList_SetItem(array, 5, vec);

  /* Rotation matrices */
  rot = PyList_New(dataset->n_operations);
  for (i = 0; i < dataset->n_operations; i++) {
    mat = PyList_New(3);
    for (j = 0; j < 3; j++) {
      vec = PyList_New(3);
      for (k = 0; k < 3; k++) {
	PyList_SetItem(vec, k,
		       PyInt_FromLong((long) dataset->rotations[i][j][k]));
      }
      PyList_SetItem(mat, j, vec);
    }
    PyList_SetItem(rot, i, mat);
  }
  PyList_SetItem(array, 6, rot);

  /* Translation vectors */
  trans = PyList_New(dataset->n_operations);
  for (i = 0; i < dataset->n_operations; i++) {
    vec = PyList_New(3);
    for (j = 0; j < 3; j++) {
      PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->translations[i][j]));
    }
    PyList_SetItem(trans, i, vec);
  }
  PyList_SetItem(array, 7, trans);

  /* Wyckoff letters, Equivalent atoms */
  wyckoffs = PyList_New(dataset->n_atoms);
  equiv_atoms = PyList_New(dataset->n_atoms);
  for (i = 0; i < dataset->n_atoms; i++) {
    PyList_SetItem(wyckoffs, i, PyInt_FromLong((long) dataset->wyckoffs[i]));
    PyList_SetItem(equiv_atoms, i,
		   PyInt_FromLong((long) dataset->equivalent_atoms[i]));
  }
  PyList_SetItem(array, 8, wyckoffs);
  PyList_SetItem(array, 9, equiv_atoms);

  spg_free_dataset(dataset);

  return array;
}
Exemple #2
0
static int refine_cell(double lattice[3][3],
		       double position[][3],
		       int types[],
		       const int num_atom,
		       const double symprec)
{
  int i, n_brv_atoms;
  SpglibDataset *dataset;

  n_brv_atoms = 0;
  dataset = NULL;

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    return 0;
  }

  n_brv_atoms = dataset->n_brv_atoms;
  mat_copy_matrix_d3(lattice, dataset->brv_lattice);
  for (i = 0; i < dataset->n_brv_atoms; i++) {
    types[i] = dataset->brv_types[i];
    mat_copy_vector_d3(position[i], dataset->brv_positions[i]);
  }

  spg_free_dataset(dataset);
  
  return n_brv_atoms;
}
Exemple #3
0
/* Return 0 if failed */
static int get_multiplicity(SPGCONST double lattice[3][3],
			    SPGCONST double position[][3],
			    const int types[],
			    const int num_atom,
			    const double symprec)
{
  int size;
  SpglibDataset *dataset;

  size = 0;
  dataset = NULL;

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    return 0;
  }

  size = dataset->n_operations;
  spg_free_dataset(dataset);

  return size;
}
Exemple #4
0
/*---------*/
static int get_ir_reciprocal_mesh(int grid_address[][3],
				  int map[],
				  const int mesh[3],
				  const int is_shift[3],
				  const int is_time_reversal,
				  SPGCONST double lattice[3][3],
				  SPGCONST double position[][3],
				  const int types[],
				  const int num_atom,
				  const double symprec)
{
  SpglibDataset *dataset;
  int num_ir, i;
  MatINT *rotations;

  dataset = get_dataset(lattice,
			position,
			types,
			num_atom,
			symprec);
  rotations = mat_alloc_MatINT(dataset->n_operations);
  for (i = 0; i < dataset->n_operations; i++) {
    mat_copy_matrix_i3(rotations->mat[i], dataset->rotations[i]);
  }
  num_ir = kpt_get_irreducible_reciprocal_mesh(grid_address,
					       map,
					       mesh,
					       is_shift,
					       is_time_reversal,
					       rotations);
  mat_free_MatINT(rotations);
  spg_free_dataset(dataset);
  return num_ir;
}
Exemple #5
0
static int test_spg_get_stabilized_reciprocal_mesh(void)
{
  SpglibDataset *dataset;
  double lattice[3][3] = {{4, 0, 0}, {0, 4, 0}, {0, 0, 3}};
  double position[][3] =
    {
      {0, 0, 0},
      {0.5, 0.5, 0.5},
      {0.3, 0.3, 0},
      {0.7, 0.7, 0},
      {0.2, 0.8, 0.5},
      {0.8, 0.2, 0.5},
    };
  int types[] = {1, 1, 2, 2, 2, 2};
  int num_atom = 6;

  dataset = spg_get_dataset(lattice,
			    position,
			    types,
			    num_atom,
			    1e-5);
  
  if (dataset == NULL) {
    return 1;
  }
  
  int m = 40;
  int mesh[] = {m, m, m};
  int is_shift[] = {1, 1, 1};
  int grid_address[m * m * m][3];
  int grid_mapping_table[m * m * m];
  double q[] = {0, 0.5, 0.5};

  printf("*** spg_get_stabilized_reciprocal_mesh of Rutile structure ***:\n");

  int num_ir = spg_get_stabilized_reciprocal_mesh(grid_address,
						  grid_mapping_table,
						  mesh,
						  is_shift,
						  1,
						  dataset->n_operations,
						  dataset->rotations,
						  1,
						  (double(*)[3])q);
  spg_free_dataset(dataset);

  if (num_ir) {
    printf("Number of irreducible k-points stabilized by q=(0, 1/2, 1/2) of Rutile with\n");
    printf("40x40x40 Monkhorst-Pack mesh is %d (8000).\n", num_ir);
    return 0;
  } else {
    return 1;
  }
}
Exemple #6
0
/* Return 0 if failed */
static int get_symmetry_from_dataset(int rotation[][3][3],
				     double translation[][3],
				     const int max_size,
				     SPGCONST double lattice[3][3],
				     SPGCONST double position[][3],
				     const int types[],
				     const int num_atom,
				     const double symprec)
{
  int i, num_sym;
  SpglibDataset *dataset;

  num_sym = 0;
  dataset = NULL;

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    return 0;
  }
  
  if (dataset->n_operations > max_size) {
    fprintf(stderr,
	    "spglib: Indicated max size(=%d) is less than number ", max_size);
    fprintf(stderr,
	    "spglib: of symmetry operations(=%d).\n", dataset->n_operations);
    goto ret;
  }

  num_sym = dataset->n_operations;
  for (i = 0; i < num_sym; i++) {
    mat_copy_matrix_i3(rotation[i], dataset->rotations[i]);
    mat_copy_vector_d3(translation[i], dataset->translations[i]);
  }
  
 ret:
  spg_free_dataset(dataset);
  return num_sym;
}
Exemple #7
0
static PyObject * get_dataset(PyObject *self, PyObject *args)
{
  int i, j, k, n;
  double symprec, angle_tolerance;
  SpglibDataset *dataset;
  PyArrayObject* lattice;
  PyArrayObject* position;
  PyArrayObject* atom_type;
  PyObject *array, *vec, *mat, *rot, *trans, *wyckoffs, *equiv_atoms;
  PyObject *std_lattice, *std_types, *std_positions;

  if (!PyArg_ParseTuple(args, "OOOdd",
			&lattice,
			&position,
			&atom_type,
			&symprec,
			&angle_tolerance)) {
    return NULL;
  }

  SPGCONST double (*lat)[3] = (double(*)[3])PyArray_DATA(lattice);
  SPGCONST double (*pos)[3] = (double(*)[3])PyArray_DATA(position);
  const int num_atom = PyArray_DIMS(position)[0];
  const int* typat = (int*)PyArray_DATA(atom_type);

  dataset = spgat_get_dataset(lat,
			      pos,
			      typat,
			      num_atom,
			      symprec,
			      angle_tolerance);

  array = PyList_New(15);
  n = 0;

  /* Space group number, international symbol, hall symbol */
  PyList_SetItem(array, n, PyLong_FromLong((long) dataset->spacegroup_number));
  n++;
  PyList_SetItem(array, n, PyLong_FromLong((long) dataset->hall_number));
  n++;
  PyList_SetItem(array, n, PYUNICODE_FROMSTRING(dataset->international_symbol));
  n++;
  PyList_SetItem(array, n, PYUNICODE_FROMSTRING(dataset->hall_symbol));
  n++;

  /* Transformation matrix */
  mat = PyList_New(3);
  for (i = 0; i < 3; i++) {
    vec = PyList_New(3);
    for (j = 0; j < 3; j++) {
      PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->transformation_matrix[i][j]));
    }
    PyList_SetItem(mat, i, vec);
  }
  PyList_SetItem(array, n, mat);
  n++;

  /* Origin shift */
  vec = PyList_New(3);
  for (i = 0; i < 3; i++) {
    PyList_SetItem(vec, i, PyFloat_FromDouble(dataset->origin_shift[i]));
  }
  PyList_SetItem(array, n, vec);
  n++;

  /* Rotation matrices */
  rot = PyList_New(dataset->n_operations);
  for (i = 0; i < dataset->n_operations; i++) {
    mat = PyList_New(3);
    for (j = 0; j < 3; j++) {
      vec = PyList_New(3);
      for (k = 0; k < 3; k++) {
	PyList_SetItem(vec, k, PyLong_FromLong((long) dataset->rotations[i][j][k]));
      }
      PyList_SetItem(mat, j, vec);
    }
    PyList_SetItem(rot, i, mat);
  }
  PyList_SetItem(array, n, rot);
  n++;

  /* Translation vectors */
  trans = PyList_New(dataset->n_operations);
  for (i = 0; i < dataset->n_operations; i++) {
    vec = PyList_New(3);
    for (j = 0; j < 3; j++) {
      PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->translations[i][j]));
    }
    PyList_SetItem(trans, i, vec);
  }
  PyList_SetItem(array, n, trans);
  n++;

  /* Wyckoff letters, Equivalent atoms */
  wyckoffs = PyList_New(dataset->n_atoms);
  equiv_atoms = PyList_New(dataset->n_atoms);
  for (i = 0; i < dataset->n_atoms; i++) {
    PyList_SetItem(wyckoffs, i, PyLong_FromLong((long) dataset->wyckoffs[i]));
    PyList_SetItem(equiv_atoms, i, PyLong_FromLong((long) dataset->equivalent_atoms[i]));
  }
  PyList_SetItem(array, n, wyckoffs);
  n++;
  PyList_SetItem(array, n, equiv_atoms);
  n++;

  std_lattice = PyList_New(3);
  for (i = 0; i < 3; i++) {
    vec = PyList_New(3);
    for (j = 0; j < 3; j++) {
      PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->std_lattice[i][j]));
    }
    PyList_SetItem(std_lattice, i, vec);
  }
  PyList_SetItem(array, n, std_lattice);
  n++;

  /* Standardized unit cell */
  std_types = PyList_New(dataset->n_std_atoms);
  std_positions = PyList_New(dataset->n_std_atoms);
  for (i = 0; i < dataset->n_std_atoms; i++) {
    vec = PyList_New(3);
    for (j = 0; j < 3; j++) {
      PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->std_positions[i][j]));
    }
    PyList_SetItem(std_types, i, PyLong_FromLong((long) dataset->std_types[i]));
    PyList_SetItem(std_positions, i, vec);
  }
  PyList_SetItem(array, n, std_types);
  n++;
  PyList_SetItem(array, n, std_positions);
  n++;

  /* Point group */
  PyList_SetItem(array, n, PyLong_FromLong((long) dataset->pointgroup_number));
  n++;
  PyList_SetItem(array, n, PYUNICODE_FROMSTRING(dataset->pointgroup_symbol));
  n++;

  spg_free_dataset(dataset);

  return array;
}
Exemple #8
0
static PyObject * get_dataset(PyObject *self, PyObject *args)
{
  int i, j, k;
  double symprec, angle_tolerance;
  SpglibDataset *dataset;
  PyArrayObject* lattice;
  PyArrayObject* position;
  PyArrayObject* atom_type;
  PyObject* array, *vec, *mat, *rot, *trans, *wyckoffs, *equiv_atoms;
  
  if (!PyArg_ParseTuple(args, "OOOdd",
			&lattice,
			&position,
			&atom_type,
			&symprec,
			&angle_tolerance)) {
    return NULL;
  }

  SPGCONST double (*lat)[3] = (double(*)[3])lattice->data;
  SPGCONST double (*pos)[3] = (double(*)[3])position->data;
  const int num_atom = position->dimensions[0];
  const int* typat = (int*)atom_type->data;

  dataset = spgat_get_dataset(lat,
			      pos,
			      typat,
			      num_atom,
			      symprec,
			      angle_tolerance);

  array = PyList_New(9);

  /* Space group number, international symbol, hall symbol */
  PyList_SetItem(array, 0, PyInt_FromLong((long) dataset->spacegroup_number));
  PyList_SetItem(array, 1, PyString_FromString(dataset->international_symbol));
  PyList_SetItem(array, 2, PyString_FromString(dataset->hall_symbol));

  /* Transformation matrix */
  mat = PyList_New(3);
  for (i = 0; i < 3; i++) {
    vec = PyList_New(3);
    for (j = 0; j < 3; j++) {
      PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->transformation_matrix[i][j]));
    }
    PyList_SetItem(mat, i, vec);
  }
  PyList_SetItem(array, 3, mat);

  /* Origin shift */
  vec = PyList_New(3);
  for (i = 0; i < 3; i++) {
    PyList_SetItem(vec, i, PyFloat_FromDouble(dataset->origin_shift[i]));
  }
  PyList_SetItem(array, 4, vec);

  /* Rotation matrices */
  rot = PyList_New(dataset->n_operations);
  for (i = 0; i < dataset->n_operations; i++) {
    mat = PyList_New(3);
    for (j = 0; j < 3; j++) {
      vec = PyList_New(3);
      for (k = 0; k < 3; k++) {
	PyList_SetItem(vec, k, PyInt_FromLong((long) dataset->rotations[i][j][k]));
      }
      PyList_SetItem(mat, j, vec);
    }
    PyList_SetItem(rot, i, mat);
  }
  PyList_SetItem(array, 5, rot);

  /* Translation vectors */
  trans = PyList_New(dataset->n_operations);
  for (i = 0; i < dataset->n_operations; i++) {
    vec = PyList_New(3);
    for (j = 0; j < 3; j++) {
      PyList_SetItem(vec, j, PyFloat_FromDouble(dataset->translations[i][j]));
    }
    PyList_SetItem(trans, i, vec);
  }
  PyList_SetItem(array, 6, trans);

  /* Wyckoff letters, Equivalent atoms */
  wyckoffs = PyList_New(dataset->n_atoms);
  equiv_atoms = PyList_New(dataset->n_atoms);
  for (i = 0; i < dataset->n_atoms; i++) {
    PyList_SetItem(wyckoffs, i, PyInt_FromLong((long) dataset->wyckoffs[i]));
    PyList_SetItem(equiv_atoms, i, PyInt_FromLong((long) dataset->equivalent_atoms[i]));
  }
  PyList_SetItem(array, 7, wyckoffs);
  PyList_SetItem(array, 8, equiv_atoms);
  spg_free_dataset(dataset);

  return array;
}
Exemple #9
0
static int show_spg_dataset(double lattice[3][3],
			    const double origin_shift[3],
			    double position[][3],
			    const int num_atom,
			    const int types[])
{
  SpglibDataset *dataset;
  char ptsymbol[6];
  int pt_trans_mat[3][3];
  int i, j;
  const char *wl = "abcdefghijklmnopqrstuvwxyz";

  for ( i = 0; i < num_atom; i++ ) {
    for ( j = 0; j < 3; j++ ) {
      position[i][j] += origin_shift[j];
    }
  }

  dataset = spg_get_dataset(lattice,
			    position,
			    types,
			    num_atom,
			    1e-5);

  if (dataset == NULL) {
    return 1;
  }
  
  printf("International: %s (%d)\n", dataset->international_symbol, dataset->spacegroup_number );
  printf("Hall symbol:   %s\n", dataset->hall_symbol );
  if (spg_get_pointgroup(ptsymbol,
			 pt_trans_mat,
			 dataset->rotations,
			 dataset->n_operations)) {
    printf("Point group:   %s\n", ptsymbol);
    printf("Transformation matrix:\n");
    for ( i = 0; i < 3; i++ ) {
      printf("%f %f %f\n",
	     dataset->transformation_matrix[i][0],
	     dataset->transformation_matrix[i][1],
	     dataset->transformation_matrix[i][2]);
    }
    printf("Wyckoff letters:\n");
    for ( i = 0; i < dataset->n_atoms; i++ ) {
      printf("%c ", wl[dataset->wyckoffs[i]]);
    }
    printf("\n");
    printf("Equivalent atoms:\n");
    for (i = 0; i < dataset->n_atoms; i++) {
      printf("%d ", dataset->equivalent_atoms[i]);
    }
    printf("\n");
  
    for (i = 0; i < dataset->n_operations; i++) {
      printf("--- %d ---\n", i + 1);
      for (j = 0; j < 3; j++) {
	printf("%2d %2d %2d\n",
	       dataset->rotations[i][j][0],
	       dataset->rotations[i][j][1],
	       dataset->rotations[i][j][2]);
      }
      printf("%f %f %f\n",
	     dataset->translations[i][0],
	     dataset->translations[i][1],
	     dataset->translations[i][2]);
    }
    spg_free_dataset(dataset);
    return 0;
  } else {
    spg_free_dataset(dataset);
    return 1;
  }
}
Exemple #10
0
/* Return 0 if failed */
static int get_symmetry_with_collinear_spin(int rotation[][3][3],
					    double translation[][3],
					    int equivalent_atoms[],
					    const int max_size,
					    SPGCONST double lattice[3][3],
					    SPGCONST double position[][3],
					    const int types[],
					    const double spins[],
					    const int num_atom,
					    const double symprec)
{
  int i, size;
  Symmetry *symmetry, *sym_nonspin;
  Cell *cell;
  SpglibDataset *dataset;

  size = 0;
  symmetry = NULL;
  sym_nonspin = NULL;
  cell = NULL;
  dataset = NULL;

  if ((cell = cel_alloc_cell(num_atom)) == NULL) {
    goto err;
  }

  cel_set_cell(cell, lattice, position, types);

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    cel_free_cell(cell);
    goto err;
  }

  if ((sym_nonspin = sym_alloc_symmetry(dataset->n_operations)) == NULL) {
    spg_free_dataset(dataset);
    cel_free_cell(cell);
    goto err;
  }

  for (i = 0; i < dataset->n_operations; i++) {
    mat_copy_matrix_i3(sym_nonspin->rot[i], dataset->rotations[i]);
    mat_copy_vector_d3(sym_nonspin->trans[i], dataset->translations[i]);
  }
  spg_free_dataset(dataset);

  if ((symmetry = spn_get_collinear_operations(equivalent_atoms,
					       sym_nonspin,
					       cell,
					       spins,
					       symprec)) == NULL) {
    sym_free_symmetry(sym_nonspin);
    cel_free_cell(cell);
    goto err;
  }

  sym_free_symmetry(sym_nonspin);
  
  if (symmetry->size > max_size) {
    fprintf(stderr, "spglib: Indicated max size(=%d) is less than number ",
	    max_size);
    fprintf(stderr, "spglib: of symmetry operations(=%d).\n", symmetry->size);
    sym_free_symmetry(symmetry);
    goto err;
  }

  for (i = 0; i < symmetry->size; i++) {
    mat_copy_matrix_i3(rotation[i], symmetry->rot[i]);
    mat_copy_vector_d3(translation[i], symmetry->trans[i]);
  }

  size = symmetry->size;

  cel_free_cell(cell);
  sym_free_symmetry(symmetry);

  return size;

 err:
  return 0;
}
Exemple #11
0
static int get_standardized_cell(double lattice[3][3],
				 double position[][3],
				 int types[],
				 const int num_atom,
				 const int to_primitive,
				 const double symprec)
{
  int num_std_atom;
  SpglibDataset *dataset;
  Cell *std_cell, *cell;
  Centering centering;

  num_std_atom = 0;
  dataset = NULL;
  std_cell = NULL;
  cell = NULL;

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    goto err;
  }

  if (to_primitive) {
    if ((centering = get_centering(dataset->hall_number)) == CENTERING_ERROR) {
      goto err;
    }
    if (dataset->hall_number == 433 ||
	dataset->hall_number == 436 ||
	dataset->hall_number == 444 ||
	dataset->hall_number == 450 ||
	dataset->hall_number == 452 ||
	dataset->hall_number == 458 ||
	dataset->hall_number == 460) {
      centering = R_CENTER;
    }
  } else {
    centering = PRIMITIVE;
  }

  if ((cell = cel_alloc_cell(num_atom)) == NULL) {
    spg_free_dataset(dataset);
    goto err;
  }
  
  cel_set_cell(cell, lattice, position, types);
  std_cell = spa_transform_to_primitive(cell,
					dataset->transformation_matrix,
					centering,
					symprec);
  spg_free_dataset(dataset);
  cel_free_cell(cell);

  if (std_cell == NULL) {
    goto err;
  }

  set_cell(lattice, position, types, std_cell);
  num_std_atom = std_cell->size;

  cel_free_cell(std_cell);

  return num_std_atom;

 err:
  return 0;
}
Exemple #12
0
static int standardize_primitive(double lattice[3][3],
				 double position[][3],
				 int types[],
				 const int num_atom,
				 const double symprec)
{
  int num_prim_atom;
  Centering centering;
  SpglibDataset *dataset;
  Cell *primitive, *bravais;

  double identity[3][3] = {{ 1, 0, 0 },
			   { 0, 1, 0 },
			   { 0, 0, 1 }};

  num_prim_atom = 0;
  dataset = NULL;
  primitive = NULL;
  bravais = NULL;

  if ((dataset = get_dataset(lattice,
			     position,
			     types,
			     num_atom,
			     0,
			     symprec)) == NULL) {
    return 0;
  }

  if ((centering = get_centering(dataset->hall_number)) == CENTERING_ERROR) {
    goto err;
  }

  if (dataset->hall_number == 433 ||
      dataset->hall_number == 436 ||
      dataset->hall_number == 444 ||
      dataset->hall_number == 450 ||
      dataset->hall_number == 452 ||
      dataset->hall_number == 458 ||
      dataset->hall_number == 460) {
    centering = R_CENTER;
  }

  if ((bravais = cel_alloc_cell(dataset->n_std_atoms)) == NULL) {
    spg_free_dataset(dataset);
    return 0;
  }

  cel_set_cell(bravais,
	       dataset->std_lattice,
	       dataset->std_positions,
	       dataset->std_types);

  spg_free_dataset(dataset);

  primitive = spa_transform_to_primitive(bravais,
					 identity,
					 centering,
					 symprec);
  cel_free_cell(bravais);

  if (primitive == NULL) {
    goto err;
  }

  set_cell(lattice, position, types, primitive);
  num_prim_atom = primitive->size;

  cel_free_cell(primitive);

  return num_prim_atom;

 err:
  return 0;
}