class_docstr: A deep-learning based Variational Monte Carlo method [1]_ for calculating the ab-initio
  solution of a many-electron system.
  
  This model aims to calculate the ground state energy of a multi-electron system
  using a baseline solution as the Hartree-Fock. An MCMC technique is used to sample
  electrons and DNNs are used to caluclate the square magnitude of the wavefunction,
  in which electron-electron repulsions also are included in the calculation(in the
  form of Jastrow factor envelopes). The model requires only the nucleus' coordinates
  as input.
  
  This method is based on the following paper:
  
  Example
  -------
  >>> from deepchem.models.torch_models.ferminet import FerminetModel
  >>> H2_molecule = [['H', [0, 0, 0]], ['H', [0, 0, 0.748]]]
  >>> mol = FerminetModel(H2_molecule, spin=0, ion_charge=0, tasks='pretraining')
  >>> mol.train(nb_epoch=3)
  >>> print(mol.model.psi_up.size())
  torch.Size([1, 1])
  
  References
  ----------
  .. [1] Spencer, James S., et al. Better, Faster Fermionic Neural Networks. arXiv:2011.07125, arXiv, 13 Nov. 2020. arXiv.org, http://arxiv.org/abs/2011.07125.
  
  Note
  ----
  This class requires pySCF to be installed.
class_docstr_tok: ["A","deep-learning","based","Variational","Monte","Carlo","method","[","1","]","_","for","calculating","the","ab-initio","solution","of","a","many-electron","system",".","This","model","aims","to","calculate","the","ground","state","energy","of","a","multi-electron","system","using","a","baseline","solution","as","the","Hartree-Fock",".","An","MCMC","technique","is","used","to","sample","electrons","and","DNNs","are","used","to","caluclate","the","square","magnitude","of","the","wavefunction",",","in","which","electron-electron","repulsions","also","are","included","in","the","calculation","(","in","the","form","of","Jastrow","factor","envelopes",")",".","The","model","requires","only","the","nucleus","'","coordinates","as","input",".","This","method","is","based","on","the","following","paper",":","Example","--","--","--","-",">",">",">","from","deepchem.models.torch_models.ferminet","import","FerminetModel",">",">",">","H2_molecule","=","[","[","'","H","'",",","[","0",",","0",",","0","]","]",",","[","'","H","'",",","[","0",",","0",",","0.748","]","]","]",">",">",">","mol","=","FerminetModel","(","H2_molecule",",","spin=0",",","ion_charge=0",",","tasks='pretraining","'",")",">",">",">","mol.train","(","nb_epoch=3",")",">",">",">","print","(","mol.model.psi_up.size","(",")",")","torch.Size","(","[","1",",","1","]",")","References","--","--","--","--","--","..","[","1","]","Spencer",",","James","S.",",","et","al",".","Better",",","Faster","Fermionic","Neural","Networks",".","arXiv:2011.07125",",","arXiv",",","13","Nov.","2020.","arXiv.org",",","http",":","\/\/arxiv.org\/abs\/2011.07125",".","Note","--","--","This","class","requires","pySCF","to","be","installed","."]
docstr: Parameters:
  -----------
  nucleon_coordinates: List[List]
    A list containing nucleon coordinates as the values with the keys as the element's symbol.
  spin: int
    The total spin of the molecule system.
  ion_charge: int
    The total charge of the molecule system.
  seed_no: int, optional (default None)
    Random seed to use for electron initialization.
  batch_no: int, optional (default 8)
    Number of batches of the electron's positions to be initialized.
  random_walk_steps: int (default 10)
      Number of random walk steps to be performed in a single move.
  steps_per_update: int (default: 10)
      Number of steps after which the electron sampler should update the electron parameters.
  tasks: str (default: 'pretraining')
      The type of task to be performed - 'pretraining', 'training'
  
  Attributes:
  -----------
  nucleon_pos: np.ndarray
      numpy array value of nucleon_coordinates
  electron_no: np.ndarray
      Torch tensor containing electrons for each atom in the nucleus
  molecule: ElectronSampler
      ElectronSampler object which performs MCMC and samples electrons
  loss_value: torch.Tensor (default torch.tensor(0))
      torch tensor storing the loss value from the last iteration
docstr_tok: ["Parameters",":","--","--","--","--","--","-","nucleon_coordinates",":","List","[","List","]","A","list","containing","nucleon","coordinates","as","the","values","with","the","keys","as","the","element","'s","symbol",".","spin",":","int","The","total","spin","of","the","molecule","system",".","ion_charge",":","int","The","total","charge","of","the","molecule","system",".","seed_no",":","int",",","optional","(","default","None",")","Random","seed","to","use","for","electron","initialization",".","batch_no",":","int",",","optional","(","default","8",")","Number","of","batches","of","the","electron","'s","positions","to","be","initialized",".","random_walk_steps",":","int","(","default","10",")","Number","of","random","walk","steps","to","be","performed","in","a","single","move",".","steps_per_update",":","int","(","default",":","10",")","Number","of","steps","after","which","the","electron","sampler","should","update","the","electron","parameters",".","tasks",":","str","(","default",":","'pretraining","'",")","The","type","of","task","to","be","performed","-","'pretraining","'",",","'training'","Attributes",":","--","--","--","--","--","-","nucleon_pos",":","np.ndarray","numpy","array","value","of","nucleon_coordinates","electron_no",":","np.ndarray","Torch","tensor","containing","electrons","for","each","atom","in","the","nucleus","molecule",":","ElectronSampler","ElectronSampler","object","which","performs","MCMC","and","samples","electrons","loss_value",":","torch.Tensor","(","default","torch.tensor","(","0",")",")","torch","tensor","storing","the","loss","value","from","the","last","iteration"]
code: def __init__(
      self,
      nucleon_coordinates: List[List],
      spin: int,
      ion_charge: int,
      seed: Optional[int] = None,
      batch_no: int = 8,
      random_walk_steps: int = 10,
      steps_per_update: int = 10,
      tasks: str = "pretraining",
  ):
      """
      Parameters:
      -----------
      nucleon_coordinates: List[List]
        A list containing nucleon coordinates as the values with the keys as the element's symbol.
      spin: int
        The total spin of the molecule system.
      ion_charge: int
        The total charge of the molecule system.
      seed_no: int, optional (default None)
        Random seed to use for electron initialization.
      batch_no: int, optional (default 8)
        Number of batches of the electron's positions to be initialized.
      random_walk_steps: int (default 10)
          Number of random walk steps to be performed in a single move.
      steps_per_update: int (default: 10)
          Number of steps after which the electron sampler should update the electron parameters.
      tasks: str (default: 'pretraining')
          The type of task to be performed - 'pretraining', 'training'
  
      Attributes:
      -----------
      nucleon_pos: np.ndarray
          numpy array value of nucleon_coordinates
      electron_no: np.ndarray
          Torch tensor containing electrons for each atom in the nucleus
      molecule: ElectronSampler
          ElectronSampler object which performs MCMC and samples electrons
      loss_value: torch.Tensor (default torch.tensor(0))
          torch tensor storing the loss value from the last iteration
      """
      self.nucleon_coordinates = nucleon_coordinates
      self.seed = seed
      self.batch_no = batch_no
      self.spin = spin
      self.ion_charge = ion_charge
      self.batch_no = batch_no
      self.random_walk_steps = random_walk_steps
      self.steps_per_update = steps_per_update
      self.loss_value: torch.Tensor = torch.tensor(0)
      self.tasks = tasks
  
      no_electrons = []
      nucleons = []
      electronegativity = []
  
      table = Chem.GetPeriodicTable()
      index = 0
      for i in self.nucleon_coordinates:
          atomic_num = table.GetAtomicNumber(i[0])
          electronegativity.append(
              [index, ALLEN_ELECTRONEGATIVTY[i[0]]]
          )
          no_electrons.append([atomic_num])
          nucleons.append(i[1])
          index += 1
  
      self.electron_no: np.ndarray = np.array(no_electrons)
      charge: np.ndarray = self.electron_no.reshape(
          np.shape(self.electron_no)[0]
      )
      self.nucleon_pos: np.ndarray = np.array(nucleons)
      electro_neg = np.array(electronegativity)
  
      # Initialization for ionic molecules
      if np.sum(self.electron_no) < self.ion_charge:
          raise ValueError("Given charge is not initializable")
  
      # Initialization for ionic molecules
      if self.ion_charge != 0:
          if (
              len(nucleons) == 1
          ):  # for an atom, directly the charge is applied
              self.electron_no[0][0] -= self.ion_charge
          else:  # for a multiatomic molecule, the most electronegative atom gets a charge of -1 and vice versa. The remaining charges are assigned in terms of decreasing(for anionic charge) and increasing(for cationic charge) electronegativity.
              electro_neg = electro_neg[electro_neg[:, 1].argsort()]
              if self.ion_charge > 0:
                  for iter in range(self.ion_charge):
                      self.electron_no[int(electro_neg[iter][0])][
                          0
                      ] -= 1
              else:
                  for iter in range(-self.ion_charge):
                      self.electron_no[int(electro_neg[-1 - iter][0])][
                          0
                      ] += 1
  
      total_electrons = np.sum(self.electron_no)
  
      if self.spin >= 0:
          self.up_spin = (total_electrons + 2 * self.spin) // 2
          self.down_spin = total_electrons - self.up_spin
      else:
          self.down_spin = (total_electrons - 2 * self.spin) // 2
          self.up_spin = total_electrons - self.down_spin
  
      if self.up_spin - self.down_spin != self.spin:
          raise ValueError("Given spin is not feasible")
  
      nucl = torch.from_numpy(self.nucleon_pos)
      self.model = Ferminet(
          nucl,
          spin=(self.up_spin, self.down_spin),
          nuclear_charge=torch.Tensor(charge),
          batch_size=self.batch_no,
      )
  
      self.molecule: ElectronSampler = ElectronSampler(
          batch_no=self.batch_no,
          central_value=self.nucleon_pos,
          seed=self.seed,
          f=lambda x: self.random_walk(
              x
          ),  # Will be replaced in successive PR
          steps=self.random_walk_steps,
          steps_per_update=self.steps_per_update,
      )  # sample the electrons using the electron sampler
      self.molecule.gauss_initialize_position(
          self.electron_no, stddev=1.0
      )  # initialize the position of the electrons
      self.prepare_hf_solution()
      super(FerminetModel, self).__init__(
          self.model, loss=torch.nn.MSELoss()
      )
  
imports: import logging
  from typing import List, Optional, Tuple
  from rdkit import Chem
  import numpy
  from deepchem.utils.molecule_feature_utils import ALLEN_ELECTRONEGATIVTY
  from deepchem.models.torch_models import TorchModel
  import torch
  from deepchem.models.torch_models.layers import FerminetElectronFeature, FerminetEnvelope
  from deepchem.utils.electron_sampler import ElectronSampler
label_desc: Use image node_id 1 to create a new FerminetModel object from inherited base classes: TorchModel with example: obj = FerminetModel(nucleon_coordinates, spin, ion_charge, seed, batch_no, random_walk_steps, steps_per_update, tasks)