or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants-utilities.mdelements.mdformulas.mdindex.mdneutron-scattering.mdxray-scattering.md

constants-utilities.mddocs/

0

# Constants and Utilities

1

2

Fundamental physical constants, crystallographic calculations, uncertainty parsing, periodic table data visualization tools, and biomolecule support for scientific applications.

3

4

## Capabilities

5

6

### Physical Constants

7

8

Fundamental physical constants used throughout the periodictable package for calculations and unit conversions.

9

10

```python { .api }

11

# From periodictable.constants module

12

avogadro_number: float = 6.02214076e23 # Avogadro's number (mol⁻¹)

13

planck_constant: float = 6.62607015e-34 # Planck constant (J⋅Hz⁻¹)

14

electron_volt: float = 1.602176634e-19 # Electron volt (J/eV)

15

speed_of_light: float = 299792458 # Speed of light (m/s)

16

electron_radius: float = 2.8179403205e-15 # Classical electron radius (m)

17

neutron_mass: float = 1.00866491606 # Neutron mass (u)

18

atomic_mass_constant: float = 1.66053906892e-27 # Atomic mass unit (kg/u)

19

electron_mass: float = 5.485799090441e-4 # Electron mass (u)

20

```

21

22

Usage examples:

23

24

```python

25

from periodictable.constants import *

26

import periodictable as pt

27

28

# Unit conversions

29

print(f"Avogadro's number: {avogadro_number:.6e} mol⁻¹")

30

print(f"eV to Joules: {electron_volt:.6e} J/eV")

31

print(f"Speed of light: {speed_of_light} m/s")

32

33

# Molecular mass calculations

34

water = pt.formula("H2O")

35

mass_grams = water.mass * atomic_mass_constant * 1000 # Convert to grams

36

molecules_per_mole = avogadro_number

37

molar_mass = mass_grams * molecules_per_mole

38

print(f"Water molar mass: {molar_mass:.2f} g/mol")

39

40

# Energy calculations

41

lambda_cu = 1.5418 # Å, Cu K-alpha

42

energy_joules = planck_constant * speed_of_light / (lambda_cu * 1e-10)

43

energy_ev = energy_joules / electron_volt

44

energy_kev = energy_ev / 1000

45

print(f"Cu K-alpha: {lambda_cu} Å = {energy_kev:.3f} keV")

46

47

# Classical electron radius in X-ray calculations

48

print(f"Electron radius: {electron_radius:.6e} m")

49

```

50

51

### Crystallographic Utilities

52

53

Calculate unit cell volumes and properties for crystallographic applications and density estimations.

54

55

```python { .api }

56

def cell_volume(a: float = None, b: float = None, c: float = None,

57

alpha: float = None, beta: float = None,

58

gamma: float = None) -> float:

59

"""

60

Calculate crystallographic unit cell volume.

61

62

Args:

63

a, b, c: Unit cell lengths in Ångström

64

alpha, beta, gamma: Unit cell angles in degrees

65

66

Returns:

67

Unit cell volume in ų (cubic Ångström)

68

69

Note:

70

For cubic: provide a only

71

For tetragonal: provide a, c

72

For orthorhombic: provide a, b, c

73

For hexagonal: provide a, c (gamma=120° assumed)

74

For general case: provide all parameters

75

"""

76

```

77

78

Usage examples:

79

80

```python

81

from periodictable.util import cell_volume

82

import math

83

84

# Cubic crystal (e.g., simple cubic silicon)

85

a_cubic = 5.43 # Å, silicon lattice parameter

86

vol_cubic = cell_volume(a=a_cubic)

87

print(f"Cubic Si unit cell: {vol_cubic:.2f} ų")

88

89

# Face-centered cubic (real silicon structure)

90

a_fcc = 5.43 # Å

91

vol_fcc = cell_volume(a=a_fcc) # Same as cubic for FCC primitive cell

92

atoms_per_unit_cell = 8 # FCC has 8 atoms per conventional cell

93

vol_per_atom = vol_fcc / atoms_per_unit_cell

94

print(f"Si volume per atom: {vol_per_atom:.2f} ų/atom")

95

96

# Hexagonal (e.g., graphite)

97

a_hex = 2.46 # Å

98

c_hex = 6.71 # Å

99

vol_hex = cell_volume(a=a_hex, c=c_hex, gamma=120)

100

print(f"Hexagonal graphite: {vol_hex:.2f} ų")

101

102

# Orthorhombic

103

a_ortho, b_ortho, c_ortho = 4.0, 5.0, 6.0 # Å

104

vol_ortho = cell_volume(a=a_ortho, b=b_ortho, c=c_ortho)

105

print(f"Orthorhombic cell: {vol_ortho:.2f} ų")

106

107

# General triclinic case

108

vol_triclinic = cell_volume(a=5.0, b=6.0, c=7.0,

109

alpha=85, beta=90, gamma=95)

110

print(f"Triclinic cell: {vol_triclinic:.2f} ų")

111

112

# Density calculation from unit cell

113

silicon = pt.formula("Si")

114

atoms_per_cell = 8 # Diamond cubic

115

cell_vol_cm3 = vol_cubic * 1e-24 # Convert ų to cm³

116

mass_per_cell = atoms_per_cell * silicon.mass * 1.66054e-24 # u to g

117

calculated_density = mass_per_cell / cell_vol_cm3

118

print(f"Calculated Si density: {calculated_density:.2f} g/cm³")

119

```

120

121

### Uncertainty Parsing

122

123

Parse scientific notation with uncertainties in parenthetical format commonly used in scientific literature.

124

125

```python { .api }

126

def parse_uncertainty(s: str) -> tuple:

127

"""

128

Parse uncertainty notation like "23.0035(12)" into value and uncertainty.

129

130

Args:

131

s: String with uncertainty notation

132

133

Returns:

134

tuple: (value, uncertainty) as floats

135

136

Examples:

137

"23.0035(12)" -> (23.0035, 0.0012)

138

"1.234(5)" -> (1.234, 0.005)

139

"456.78(123)" -> (456.78, 1.23)

140

"""

141

```

142

143

Usage examples:

144

145

```python

146

from periodictable.util import parse_uncertainty

147

148

# Scientific measurements with uncertainties

149

measurements = [

150

"23.0035(12)", # NIST atomic mass format

151

"1.234(5)", # Standard uncertainty notation

152

"456.78(123)", # Large uncertainty

153

"0.0012345(67)", # Small values

154

"1234567(89)" # Integer-like with uncertainty

155

]

156

157

print("Parsed uncertainties:")

158

for measurement in measurements:

159

value, uncertainty = parse_uncertainty(measurement)

160

print(f"{measurement:12s} -> {value} ± {uncertainty}")

161

162

# Use in atomic mass calculations

163

import periodictable as pt

164

165

# Simulate parsing atomic mass with uncertainty

166

mass_string = "55.845(2)" # Iron atomic mass with uncertainty

167

mass_value, mass_uncertainty = parse_uncertainty(mass_string)

168

169

print(f"\nIron atomic mass: {mass_value} ± {mass_uncertainty} u")

170

print(f"Relative uncertainty: {mass_uncertainty/mass_value:.2e}")

171

172

# Error propagation example

173

iron = pt.Fe

174

print(f"Tabulated Fe mass: {iron.mass} u")

175

print(f"Difference from parsed: {abs(iron.mass - mass_value):.6f} u")

176

```

177

178

### Periodic Table Visualization

179

180

Create visual representations and formatted tables of periodic table data for analysis and presentation.

181

182

```python { .api }

183

def table_plot(data, form: str = "line", label: str = None,

184

title: str = None) -> None:

185

"""

186

Plot periodic table data in various formats.

187

188

Args:

189

data: Dictionary mapping elements to values, or property name string

190

form: Plot type ("line", "bar", "scatter", "table")

191

label: Y-axis label for the data

192

title: Plot title

193

194

Note:

195

Requires matplotlib for plotting functionality

196

"""

197

```

198

199

Usage examples:

200

201

```python

202

from periodictable.plot import table_plot

203

import periodictable as pt

204

205

# Plot atomic masses

206

try:

207

mass_data = {el: el.mass for el in pt.elements if el.mass}

208

table_plot(mass_data, form="line", label="Atomic Mass (u)",

209

title="Atomic Masses vs Atomic Number")

210

211

# Plot densities

212

density_data = {el: el.density for el in pt.elements

213

if el.density and el.number <= 86}

214

table_plot(density_data, form="scatter", label="Density (g/cm³)",

215

title="Element Densities")

216

217

# Plot covalent radii (triggers lazy loading)

218

radii_data = {}

219

for el in pt.elements:

220

if el.number <= 54: # First few periods

221

try:

222

radii_data[el] = el.covalent_radius

223

except (AttributeError, TypeError):

224

pass

225

226

table_plot(radii_data, form="bar", label="Covalent Radius (Å)",

227

title="Covalent Radii")

228

229

except ImportError:

230

print("Matplotlib required for plotting")

231

232

# Create data tables without plotting

233

elements_subset = [pt.H, pt.He, pt.Li, pt.Be, pt.B, pt.C, pt.N, pt.O]

234

print("Light element properties:")

235

print("El Mass Density")

236

for el in elements_subset:

237

density = el.density if el.density else "N/A"

238

print(f"{el.symbol:2s} {el.mass:8.4f} {density}")

239

```

240

241

### Biomolecule Support

242

243

Support for biological molecules including amino acids, nucleic acids, and common biochemical compounds with labile hydrogen tracking.

244

245

```python { .api }

246

# From periodictable.fasta module

247

class Molecule:

248

"""Biomolecule with labile hydrogen support for deuteration studies."""

249

250

def __init__(self, formula: str = None, name: str = None,

251

labile: int = 0, charge: int = 0):

252

"""

253

Args:

254

formula: Chemical formula

255

name: Molecule name

256

labile: Number of labile hydrogens

257

charge: Net charge

258

"""

259

260

class Sequence(Molecule):

261

"""Read amino acid and DNA/RNA sequences from FASTA-like strings."""

262

263

def __init__(self, sequence: str, molecule_type: str = "protein"):

264

"""

265

Args:

266

sequence: FASTA sequence string

267

molecule_type: "protein", "DNA", or "RNA"

268

"""

269

270

# Standard biochemical data

271

AMINO_ACID_CODES: dict # 20 standard amino acids by single letter

272

RNA_CODES: dict # RNA nucleotides (A, U, G, C)

273

DNA_CODES: dict # DNA nucleotides (A, T, G, C)

274

RNA_BASES: dict # Individual RNA bases

275

DNA_BASES: dict # Individual DNA bases

276

NUCLEIC_ACID_COMPONENTS: dict # Nucleic acid molecular components

277

LIPIDS: dict # Common lipid molecules

278

CARBOHYDRATE_RESIDUES: dict # Sugar and carbohydrate units

279

280

# Reference SLD values

281

H2O_SLD: float = -0.5603 # H2O neutron SLD at 20°C (10⁻⁶ Ų⁻²)

282

D2O_SLD: float = 6.3350 # D2O neutron SLD at 20°C (10⁻⁶ Ų⁻²)

283

```

284

285

Usage examples:

286

287

```python

288

from periodictable.fasta import *

289

import periodictable as pt

290

291

# Amino acids

292

print("Standard amino acids:")

293

for code, amino_acid in list(AMINO_ACID_CODES.items())[:5]:

294

print(f"{code}: {amino_acid.name} - {amino_acid.formula}")

295

296

# Create peptide sequence

297

peptide_seq = "MVLSPADKTNVKAAW" # Sample sequence

298

protein = Sequence(peptide_seq, molecule_type="protein")

299

print(f"\nPeptide formula: {protein.formula}")

300

print(f"Molecular mass: {protein.mass:.2f} u")

301

302

# DNA sequence

303

dna_seq = "ATCGATCGATCG"

304

dna = Sequence(dna_seq, molecule_type="DNA")

305

print(f"DNA formula: {dna.formula}")

306

307

# Labile hydrogen tracking for deuteration

308

# Water molecules

309

h2o = Molecule("H2O", labile=2) # Both H are labile

310

print(f"H2O labile H: {h2o.labile}")

311

312

# Reference SLD values for contrast calculations

313

print(f"\nSolvent SLD values:")

314

print(f"H2O: {H2O_SLD:.4f} × 10⁻⁶ Ų⁻²")

315

print(f"D2O: {D2O_SLD:.4f} × 10⁻⁶ Ų⁻²")

316

print(f"Contrast: {D2O_SLD - H2O_SLD:.4f} × 10⁻⁶ Ų⁻²")

317

318

# Lipids and carbohydrates

319

print("\nBiochemical molecules:")

320

for name, molecule in list(LIPIDS.items())[:3]:

321

print(f"{name}: {molecule.formula}")

322

323

for name, molecule in list(CARBOHYDRATE_RESIDUES.items())[:3]:

324

print(f"{name}: {molecule.formula}")

325

```

326

327

### Activation Analysis Support

328

329

Support for neutron activation analysis calculations including sample preparation and flux environment modeling.

330

331

```python { .api }

332

# From periodictable.activation module

333

class Sample:

334

"""Neutron activation sample with composition and irradiation history."""

335

336

def __init__(self, formula, mass: float = None, name: str = None):

337

"""

338

Args:

339

formula: Sample chemical formula

340

mass: Sample mass in grams

341

name: Sample identifier

342

"""

343

344

class ActivationEnvironment:

345

"""Neutron flux environment for activation calculations."""

346

347

def __init__(self, flux: float, energy: str = "thermal"):

348

"""

349

Args:

350

flux: Neutron flux in n/cm²/s

351

energy: Neutron energy spectrum ("thermal", "epithermal", "fast")

352

"""

353

354

class ActivationResult:

355

"""Results from neutron activation calculations."""

356

357

@property

358

def activity(self) -> dict:

359

"""Activities by isotope in Bq."""

360

361

@property

362

def dose_rate(self) -> float:

363

"""Dose rate in μSv/hr at 1m."""

364

```

365

366

Usage examples:

367

368

```python

369

from periodictable.activation import *

370

import periodictable as pt

371

372

# Create sample for activation analysis

373

steel_sample = Sample("Fe + 0.8%C + 2%Mn", mass=10.0, name="Steel sample")

374

aluminum_sample = Sample("Al", mass=5.0, name="Al foil")

375

376

# Define neutron environment

377

reactor_flux = ActivationEnvironment(flux=1e13, energy="thermal") # n/cm²/s

378

print(f"Reactor thermal flux: {reactor_flux.flux:.0e} n/cm²/s")

379

380

# Calculate activation (conceptual - requires specific implementation)

381

print(f"Steel sample: {steel_sample.formula}")

382

print(f"Sample mass: {steel_sample.mass} g")

383

print(f"Environment: {reactor_flux.energy} neutrons")

384

```

385

386

### Core Utility Functions

387

388

Essential utility functions for working with periodic table objects, managing custom tables, and type checking atomic objects.

389

390

```python { .api }

391

# Table management functions

392

def default_table(table=None) -> PeriodicTable:

393

"""Return the default periodic table unless a specific table is requested."""

394

395

def change_table(atom, table) -> Union[Element, Isotope, Ion]:

396

"""Get the same element, isotope, or ion from a different periodic table."""

397

398

# Type checking functions

399

def isatom(val) -> bool:

400

"""Test if value is any atomic object (element, isotope, or ion)."""

401

402

def iselement(val) -> bool:

403

"""Test if value is an element (not isotope or ion)."""

404

405

def isisotope(val) -> bool:

406

"""Test if value is an isotope."""

407

408

def ision(val) -> bool:

409

"""Test if value is an ion."""

410

```

411

412

Usage examples:

413

414

```python

415

import periodictable as pt

416

from periodictable.core import (default_table, change_table,

417

isatom, iselement, isisotope, ision)

418

419

# Table management

420

default = default_table() # Get the standard table

421

print(f"Default table contains {len(list(default))} elements")

422

423

# Custom table workflow (conceptual)

424

# custom_table = create_custom_table() # User-defined table

425

iron_default = pt.Fe

426

# iron_custom = change_table(iron_default, custom_table)

427

428

# Type checking for safe operations

429

iron = pt.Fe

430

iron56 = pt.Fe[56]

431

iron2_ion = pt.Fe.ion[2]

432

433

print(f"Iron is atom: {isatom(iron)}") # True

434

print(f"Iron is element: {iselement(iron)}") # True

435

print(f"Iron-56 is isotope: {isisotope(iron56)}") # True

436

print(f"Fe²⁺ is ion: {ision(iron2_ion)}") # True

437

438

# Safe property access patterns

439

def get_mass_info(atom_obj):

440

"""Safely extract mass information from any atomic object."""

441

if isatom(atom_obj):

442

mass = atom_obj.mass

443

if isisotope(atom_obj):

444

return f"Isotope {atom_obj.symbol}-{atom_obj.isotope}: {mass:.4f} u"

445

elif ision(atom_obj):

446

charge_sign = "+" if atom_obj.charge > 0 else ""

447

return f"Ion {atom_obj.symbol}{charge_sign}{atom_obj.charge}: {mass:.4f} u"

448

else:

449

return f"Element {atom_obj.symbol}: {mass:.4f} u"

450

else:

451

return "Not an atomic object"

452

453

# Test type checking

454

for obj in [iron, iron56, iron2_ion, "not_atom"]:

455

print(get_mass_info(obj))

456

```

457

458

## Types

459

460

```python { .api }

461

# Constants (all float values)

462

avogadro_number: float

463

planck_constant: float

464

electron_volt: float

465

speed_of_light: float

466

electron_radius: float

467

neutron_mass: float

468

atomic_mass_constant: float

469

electron_mass: float

470

471

# Biomolecule data (all dict mappings)

472

AMINO_ACID_CODES: dict

473

RNA_CODES: dict

474

DNA_CODES: dict

475

RNA_BASES: dict

476

DNA_BASES: dict

477

NUCLEIC_ACID_COMPONENTS: dict

478

LIPIDS: dict

479

CARBOHYDRATE_RESIDUES: dict

480

481

# Reference values

482

H2O_SLD: float

483

D2O_SLD: float

484

485

class Molecule:

486

"""Biomolecule with labile hydrogen tracking."""

487

formula: str

488

name: str

489

labile: int

490

charge: int

491

mass: float

492

493

class Sequence(Molecule):

494

"""Biological sequence (protein, DNA, RNA)."""

495

def __init__(self, sequence: str, molecule_type: str = "protein"): ...

496

497

class Sample:

498

"""Activation analysis sample."""

499

formula: str

500

mass: float

501

name: str

502

503

class ActivationEnvironment:

504

"""Neutron flux environment."""

505

flux: float

506

energy: str

507

508

class ActivationResult:

509

"""Activation calculation results."""

510

@property

511

def activity(self) -> dict: ...

512

@property

513

def dose_rate(self) -> float: ...

514

```