🌐 EN | 🇯🇵 JP

Chapter 5: Advanced Topics and Next Steps

Extending NIMO for Real-World Applications

📖 Reading Time: 15-20 minutes 📊 Difficulty: Intermediate 💻 Code Examples: 4 📝 Exercises: 2

Learning Objectives

5.1 Custom Robot Integration with COMBAT

NIMO's COMBAT (Custom Robot) interface allows you to connect your own experimental systems. This is the key to using NIMO with real hardware.

COMBAT Architecture

graph LR A[NIMO Core] -->|proposals.csv| B[COMBAT Interface] B -->|Custom Format| C[Your Robot] C -->|Results| D[COMBAT Interface] D -->|results.csv| A style A fill:#667eea,color:#fff style B fill:#f093fb,color:#fff style C fill:#11998e,color:#fff

The COMBAT interface works through file-based communication:

  1. NIMO writes proposals.csv with selected candidates
  2. Your custom script reads proposals and controls the robot
  3. After experiments, your script writes robot_output.csv
  4. NIMO reads results and updates the optimization
Code Example 1: Custom Robot Interface
import nimo
import pandas as pd
import time

class CustomRobotInterface:
    """
    Template for connecting your robot to NIMO.
    Replace the execute_experiment method with your actual robot control.
    """

    def __init__(self, robot_connection):
        self.robot = robot_connection

    def execute_experiment(self, x1, x2, x3):
        """
        Execute a single experiment on the robot.
        Replace this with your actual robot control code.

        Returns:
            float: Measured objective value
        """
        # Example: Send commands to robot
        # self.robot.set_composition(x1, x2, x3)
        # self.robot.start_synthesis()
        # time.sleep(3600)  # Wait for synthesis
        # result = self.robot.measure_property()

        # For demonstration, return a placeholder
        result = x1 * x2 + x3
        return result

    def run_experiments(self, proposals_file, output_file):
        """Run all proposed experiments"""
        proposals = pd.read_csv(proposals_file)
        results = []

        for idx, row in proposals.iterrows():
            print(f"Running experiment {idx + 1}/{len(proposals)}")
            value = self.execute_experiment(row['x1'], row['x2'], row['x3'])
            results.append({
                'x1': row['x1'],
                'x2': row['x2'],
                'x3': row['x3'],
                'objective': value
            })

        pd.DataFrame(results).to_csv(output_file, index=False)
        print(f"Results saved to {output_file}")

# Usage with NIMO
def run_with_custom_robot(robot_connection, num_cycles=10):
    robot = CustomRobotInterface(robot_connection)

    for cycle in range(num_cycles):
        # Step 1: AI selects candidates
        method = "RE" if cycle == 0 else "PHYSBO"
        nimo.selection(
            method=method,
            input_file="candidates.csv",
            output_file="proposals.csv",
            num_objectives=1,
            num_proposals=3
        )

        # Step 2: Robot executes experiments
        robot.run_experiments("proposals.csv", "robot_output.csv")

        # Step 3: Process results back to NIMO
        nimo.analysis_output(
            machine="COMBAT",
            input_file="robot_output.csv",
            output_file="results.csv"
        )

        # Step 4: Update candidates (manual merge for COMBAT)
        update_candidates_from_results("candidates.csv", "results.csv")

5.2 Multi-Objective Optimization

Real materials often need to optimize multiple properties simultaneously. For example, you might want to maximize both strength AND ductility.

Multi-Objective Optimization

Finding solutions that represent the best trade-offs between competing objectives. The set of optimal trade-off solutions is called the Pareto front.

Setting Up Multi-Objective Optimization

Code Example 2: Multi-Objective Setup
import nimo
import pandas as pd
import numpy as np

# Create candidates with TWO objective columns
candidates_data = {
    'x1': np.linspace(0, 1, 11),
    'x2': np.linspace(0, 1, 11),
    'objective1': [np.nan] * 11,  # e.g., Strength
    'objective2': [np.nan] * 11   # e.g., Ductility
}
df = pd.DataFrame(candidates_data)
df.to_csv('multi_candidates.csv', index=False)

# Multi-objective selection with PTR
nimo.selection(
    method="PTR",           # Pareto-based Thompson Ranking
    input_file="multi_candidates.csv",
    output_file="proposals.csv",
    num_objectives=2,       # Two objectives!
    num_proposals=3
)

print("Selected candidates for multi-objective optimization:")
print(pd.read_csv('proposals.csv'))

Understanding the Pareto Front

graph LR subgraph Pareto[Pareto Front] P1[Solution A
High Strength
Low Ductility] P2[Solution B
Balanced] P3[Solution C
Low Strength
High Ductility] end P1 --- P2 P2 --- P3 style P1 fill:#667eea,color:#fff style P2 fill:#11998e,color:#fff style P3 fill:#f093fb,color:#fff

Multi-objective optimization returns multiple solutions on the Pareto front. You (or domain experts) then choose which trade-off best meets your needs.

5.3 Handling Constraints

In real materials design, you often have constraints:

Code Example 3: Handling Composition Constraints
import numpy as np
import pandas as pd

def generate_ternary_candidates(num_points=100):
    """
    Generate valid ternary compositions where x1 + x2 + x3 = 1.
    Uses a simplex sampling approach.
    """
    candidates = []

    # Grid-based approach for ternary compositions
    steps = int(np.sqrt(num_points))
    for i in range(steps + 1):
        for j in range(steps + 1 - i):
            x1 = i / steps
            x2 = j / steps
            x3 = 1 - x1 - x2  # Ensure sum = 1

            if x3 >= 0:  # Valid composition
                candidates.append({
                    'x1': x1,
                    'x2': x2,
                    'x3': x3,
                    'objective': np.nan
                })

    return pd.DataFrame(candidates)

# Generate valid candidates
candidates = generate_ternary_candidates(100)
print(f"Generated {len(candidates)} valid ternary compositions")
print(f"Sum check: {candidates[['x1', 'x2', 'x3']].sum(axis=1).unique()}")
candidates.to_csv('ternary_candidates.csv', index=False)

5.4 Batch vs Sequential Experiments

NIMO supports different experimental strategies:

Strategy num_proposals Use Case
Sequential 1 Learn from each experiment before the next
Batch 3-10 Run parallel experiments, faster throughput
Large Batch 10+ High-throughput screening systems
Code Example 4: Batch Size Configuration
import nimo

# Sequential: Maximum learning per experiment
nimo.selection(
    method="PHYSBO",
    input_file="candidates.csv",
    output_file="proposals.csv",
    num_objectives=1,
    num_proposals=1  # One at a time
)

# Batch: Balance learning and throughput
nimo.selection(
    method="PHYSBO",
    input_file="candidates.csv",
    output_file="proposals.csv",
    num_objectives=1,
    num_proposals=5  # Parallel experiments
)

# Large batch: For high-throughput systems
nimo.selection(
    method="PHYSBO",
    input_file="candidates.csv",
    output_file="proposals.csv",
    num_objectives=1,
    num_proposals=20,  # Many parallel experiments
    physbo_score="TS"  # Thompson Sampling for batch diversity
)

Batch Size Tip

When running batch experiments, use Thompson Sampling (TS) as the acquisition function. It naturally provides diverse candidates, avoiding redundant experiments in the same batch.

5.5 Real-World Considerations

Experiment Failures

Real experiments sometimes fail. Handle failures by:

Noisy Measurements

Real measurements have noise. PHYSBO's Gaussian Process naturally handles measurement noise, but you can improve results by:

5.6 Next Steps and Resources

Official Resources

Related AI Terakoya Series

Key Papers

  1. Tamura, R., et al. "NIMS-OS: An automation software to implement a closed loop between artificial intelligence and robotic experiments in materials science." Science and Technology of Advanced Materials: Methods (2023)
  2. Ueno, T., et al. "COMBO: An efficient Bayesian optimization library for materials science." Materials Discovery (2016)

Exercises

Exercise 1: Design a Robot Interface

Design (on paper or in pseudocode) a COMBAT interface for a hypothetical robot that:

  1. Controls a sputtering system with 3 material targets
  2. Measures film thickness after deposition
  3. Measures electrical conductivity

Consider: How would you handle the two measurements (thickness and conductivity) for multi-objective optimization?

Exercise 2: Multi-Objective Trade-offs

You're optimizing a battery electrode material with two objectives:

  • Objective 1: Energy density (maximize)
  • Objective 2: Cycle life (maximize)

After running PTR optimization, you get these Pareto-optimal solutions:

SolutionEnergy DensityCycle Life
A95200
B85500
C70800

Which solution would you choose for: (a) a smartphone battery? (b) an electric vehicle battery? Explain your reasoning.

Summary

Congratulations!

You've completed the NIMO Introduction series! You now have the knowledge to:

Start experimenting with NIMO on your own materials problems, and don't hesitate to explore the advanced features as your needs grow!

Disclaimer

This content is provided for educational purposes. NIMO is developed and maintained by NIMS.