Chapter

📖 Reading Time: 20-25 min 📊 Difficulty: Beginner 💻 Code Examples: 0 📝 Exercises: 0

Chapter 4: Cloud Labs and Remote Experiments

Study Time: 20-25 min


Introduction

Purchasing and maintaining experimental equipment requires costs ranging from millions to hundreds of millions of yen, along with specialized expertise. However, by using a Cloud Laboratory, you can perform experiments using the world's most advanced equipment with zero initial investment.

In this chapter, focusing on Emerald Cloud Lab (ECL), we will learn about how cloud labs work, requesting experiments via API, automated data retrieval, and cost-efficiency analysis. You will experience a new research style in which experiments are described in program code and executed remotely.


Learning Objectives

By studying this chapter, you will acquire the following:

  1. Concept of cloud labs: How the platform works and its business model
  2. How to use Emerald Cloud Lab: Account creation, experiment requests, data retrieval
  3. API programming: Experiment automation via REST API and Python SDK
  4. Protocol description: Encoding experimental procedures as code
  5. Cost-efficiency evaluation: Quantitative comparison of traditional laboratory vs. cloud lab
  6. Advantages of remote experiments: Equipment sharing, expert technician support, scalability

4.1 What Is a Cloud Lab

4.1.1 Basic Concept of Cloud Labs

A cloud lab is a platform that turns experimental equipment and robotics into a cloud service.

flowchart TD A[Researcher] -->|Request experiment via API| B[Cloud Lab Platform] B -->|Execute protocol| C[Robotic Experiment System] C -->|HPLC, GC-MS, FTIR, etc.| D[Analytical Instruments] D -->|Automatic data acquisition| E[Cloud Storage] E -->|Download results| A style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#ffe1e1 style D fill:#f0e1ff style E fill:#e1ffe1

Main features: - Zero initial investment: No equipment purchase required, pay-as-you-go - Expert technicians: Equipment maintenance and quality control handled by the provider - Equipment sharing: One instrument shared among multiple researchers - Scalability: Scale up experiment volume as needed - Remote access: Experiments possible from anywhere in the world


4.1.2 Major Cloud Lab Platforms

Platform Features Target Fields Price Range
Emerald Cloud Lab 200+ instruments, Python SDK Life sciences, chemistry, materials Pay-as-you-go
Strateos Life-science focused, high degree of automation Drug discovery, bio High price range
Synthace (Antha) Bioprocess design platform Synthetic biology Subscription
Transcriptic Integrated into Strateos Bio -

In this chapter, we focus on Emerald Cloud Lab (ECL).


4.2 Overview of Emerald Cloud Lab

4.2.1 Available Instruments

Main instruments available in ECL:

Liquid handling: - Hamilton STAR: High-precision automated dispensing - Beckman Biomek: Microplate processing - OpenTrons OT-2: General-purpose liquid handling

Analytical instruments: - HPLC (High-Performance Liquid Chromatography) - GC-MS (Gas Chromatography-Mass Spectrometry) - LC-MS (Liquid Chromatography-Mass Spectrometry) - FTIR (Fourier Transform Infrared Spectroscopy) - UV-Vis spectrophotometer - Fluorescence spectrometer - NMR (Nuclear Magnetic Resonance spectroscopy)

Others: - Flow cytometer - Plate reader - Centrifuge - Thermal cycler (PCR) - Incubator

# Example listing of instruments available in Emerald Cloud Lab
import pandas as pd

ecl_instruments = [
    {'Category': 'Liquid Handling', 'Instrument': 'Hamilton STAR', 'Use': 'Automated dispensing, serial dilution'},
    {'Category': 'Liquid Handling', 'Instrument': 'OpenTrons OT-2', 'Use': 'General-purpose pipetting'},
    {'Category': 'Chromatography', 'Instrument': 'Agilent HPLC', 'Use': 'Compound separation and quantification'},
    {'Category': 'Mass Spectrometry', 'Instrument': 'Thermo GC-MS', 'Use': 'Volatile compound analysis'},
    {'Category': 'Mass Spectrometry', 'Instrument': 'Agilent LC-MS', 'Use': 'Biomolecule analysis'},
    {'Category': 'Spectroscopy', 'Instrument': 'Agilent UV-Vis', 'Use': 'Absorption spectrum measurement'},
    {'Category': 'Spectroscopy', 'Instrument': 'Molecular Devices', 'Use': 'Fluorescence/luminescence measurement'},
    {'Category': 'NMR', 'Instrument': 'Bruker 400MHz', 'Use': 'Structural analysis'},
]

df_instruments = pd.DataFrame(ecl_instruments)
print("Example of instruments available in Emerald Cloud Lab:")
print(df_instruments.to_string(index=False))

# Aggregation by instrument category
print(f"\nNumber of instruments per category:")
print(df_instruments['Category'].value_counts())

4.2.2 Account Creation and Access

Step 1: Account registration

1. Visit https://www.emeraldcloudlab.com/
2. Fill out the application form from "Request Access"
3. Provide your affiliation and research purpose
4. Approval (typically 1-2 business days)

Step 2: Obtaining an API key

# Installing the ECL Python SDK (actual procedure)
# pip install emerald-cloud-lab

# Setting the API key (environment variables)
import os

# In practice, the actual API key is managed via environment variables or a config file
ECL_API_KEY = os.environ.get('ECL_API_KEY', 'your_api_key_here')
ECL_PROJECT_ID = os.environ.get('ECL_PROJECT_ID', 'your_project_id')

print("ECL connection settings:")
print(f"  API key: {'*' * 20}{ECL_API_KEY[-5:]}")
print(f"  Project ID: {ECL_PROJECT_ID}")

4.3 Requesting Experiments via API

4.3.1 Basic Experiment Protocol

In ECL, experiment protocols are described in Python code.

# Emerald Cloud Lab Python SDK (pseudocode, in a form close to the actual API)

class ECLExperiment:
    """
    Simulator for ECL experiment protocols
    Mimics the interface of the actual ECL SDK
    """

    def __init__(self, experiment_name, project_id):
        self.experiment_name = experiment_name
        self.project_id = project_id
        self.protocol = []

    def add_reagent(self, name, volume, concentration):
        """Add a reagent"""
        self.protocol.append({
            'action': 'add_reagent',
            'name': name,
            'volume': volume,
            'concentration': concentration
        })
        print(f"Added reagent: {name} {volume} µL ({concentration} M)")

    def mix(self, duration, speed):
        """Mix"""
        self.protocol.append({
            'action': 'mix',
            'duration': duration,
            'speed': speed
        })
        print(f"Mix: {duration} sec, {speed} rpm")

    def incubate(self, temperature, duration):
        """Incubation"""
        self.protocol.append({
            'action': 'incubate',
            'temperature': temperature,
            'duration': duration
        })
        print(f"Incubation: {temperature}°C, {duration} min")

    def measure_absorbance(self, wavelength):
        """Absorbance measurement"""
        self.protocol.append({
            'action': 'measure_absorbance',
            'wavelength': wavelength
        })
        print(f"Absorbance measurement: {wavelength} nm")

    def submit(self):
        """Submit the experiment"""
        print(f"\nSubmitting experiment protocol: {self.experiment_name}")
        print(f"  Project ID: {self.project_id}")
        print(f"  Number of steps: {len(self.protocol)}")
        print("  Status: submission complete, awaiting execution...")

        # In the actual ECL, an API request would be sent
        return {'experiment_id': 'exp_12345', 'status': 'queued'}


# Usage example: a simple enzyme reaction assay
experiment = ECLExperiment(
    experiment_name='Enzyme Activity Assay',
    project_id='project_001'
)

# Describing the protocol
print("=== Creating experiment protocol ===\n")

# Add substrate
experiment.add_reagent('Substrate A', volume=100, concentration=0.1)

# Add enzyme
experiment.add_reagent('Enzyme', volume=10, concentration=0.01)

# Mix
experiment.mix(duration=10, speed=300)

# Incubate at room temperature
experiment.incubate(temperature=25, duration=30)

# Absorbance measurement
experiment.measure_absorbance(wavelength=450)

# Submit the experiment
result = experiment.submit()

print(f"\nExperiment ID: {result['experiment_id']}")
print(f"Status: {result['status']}")

4.3.2 Advanced Protocol: 96-Well Plate Screening

def create_96well_screening_protocol(compound_list, concentrations):
    """
    Compound screening protocol on a 96-well plate

    Args:
        compound_list: List of compounds
        concentrations: List of concentrations for each compound

    Returns:
        Protocol dictionary
    """
    protocol = {
        'experiment_name': '96-well compound screening',
        'plate_type': 'corning_96_wellplate_360ul_flat',
        'steps': []
    }

    # Step 1: Dispense substrate into all wells
    protocol['steps'].append({
        'action': 'dispense',
        'reagent': 'substrate_buffer',
        'destination': 'all_wells',
        'volume': 100  # µL
    })

    # Step 2: Dispense compounds into each well
    for i, (compound, conc) in enumerate(zip(compound_list, concentrations)):
        row = i // 12  # A-H (0-7)
        col = i % 12 + 1  # 1-12

        well = f"{chr(65 + row)}{col}"  # A1, A2, ..., H12

        protocol['steps'].append({
            'action': 'dispense',
            'reagent': compound,
            'destination': well,
            'volume': 10,  # µL
            'concentration': conc
        })

    # Step 3: Incubation
    protocol['steps'].append({
        'action': 'incubate',
        'temperature': 37,  # °C
        'duration': 60  # min
    })

    # Step 4: Measure with plate reader
    protocol['steps'].append({
        'action': 'plate_reader',
        'measurement_type': 'absorbance',
        'wavelength': 450,  # nm
        'read_all_wells': True
    })

    return protocol


# Protocol creation example
compounds = [f'Compound_{i:02d}' for i in range(1, 97)]  # 96 compounds
concentrations = [10**(-i/12) for i in range(96)]  # concentration gradient (10^0 → 10^-8 M)

protocol_96well = create_96well_screening_protocol(compounds, concentrations)

print("96-well screening protocol:")
print(f"  Experiment name: {protocol_96well['experiment_name']}")
print(f"  Plate type: {protocol_96well['plate_type']}")
print(f"  Number of steps: {len(protocol_96well['steps'])}")
print(f"\nKey steps:")
for i, step in enumerate(protocol_96well['steps'][:5], 1):  # Display the first 5 steps
    print(f"  {i}. {step['action']}: {step.get('reagent', step.get('measurement_type', ''))}")

4.4 Automated Data Retrieval and Cloud Storage

4.4.1 Downloading Experiment Results

import requests
import json
import time

class ECLDataManager:
    """
    Simulator for ECL data management
    """

    def __init__(self, api_key, base_url='https://api.emeraldcloudlab.com'):
        self.api_key = api_key
        self.base_url = base_url
        self.headers = {
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        }

    def check_experiment_status(self, experiment_id):
        """
        Check the status of an experiment

        Args:
            experiment_id: Experiment ID

        Returns:
            Status information
        """
        # Actual API call (simulation)
        # response = requests.get(f'{self.base_url}/experiments/{experiment_id}', headers=self.headers)

        # Simulation
        statuses = ['queued', 'running', 'running', 'completed']
        status = np.random.choice(statuses)

        return {
            'experiment_id': experiment_id,
            'status': status,
            'progress': 75 if status == 'running' else (100 if status == 'completed' else 0),
            'estimated_completion': '2025-10-20 14:30:00' if status != 'completed' else '2025-10-20 13:45:00'
        }

    def download_results(self, experiment_id, output_file):
        """
        Download experiment results

        Args:
            experiment_id: Experiment ID
            output_file: Destination file name

        Returns:
            Downloaded data
        """
        print(f"Downloading experiment results: {experiment_id}")

        # Actual API call (simulation)
        # response = requests.get(f'{self.base_url}/experiments/{experiment_id}/results', headers=self.headers)
        # data = response.json()

        # Simulation data
        data = {
            'experiment_id': experiment_id,
            'measurements': [
                {'well': f'{chr(65+i//12)}{i%12+1}', 'absorbance': np.random.uniform(0.1, 2.0)}
                for i in range(96)
            ],
            'metadata': {
                'plate_type': 'corning_96_wellplate_360ul_flat',
                'wavelength': 450,
                'temperature': 25
            }
        }

        # Save to a local file
        with open(output_file, 'w') as f:
            json.dump(data, f, indent=2)

        print(f"  Save complete: {output_file}")
        return data

    def wait_for_completion(self, experiment_id, check_interval=60):
        """
        Wait for the experiment to complete

        Args:
            experiment_id: Experiment ID
            check_interval: Check interval (seconds)

        Returns:
            Final status
        """
        print(f"Waiting for experiment completion: {experiment_id}")
        print(f"  Check interval: {check_interval} sec\n")

        while True:
            status_info = self.check_experiment_status(experiment_id)
            status = status_info['status']
            progress = status_info['progress']

            print(f"  Status: {status}, Progress: {progress}%")

            if status == 'completed':
                print("  Experiment complete!")
                break
            elif status == 'failed':
                print("  Experiment failed")
                break

            time.sleep(check_interval)

        return status_info


# Usage example
data_manager = ECLDataManager(api_key='demo_key')

# Check experiment status
experiment_id = 'exp_12345'
status = data_manager.check_experiment_status(experiment_id)
print(f"Experiment status: {status['status']}, Progress: {status['progress']}%")

# Wait for experiment completion (simulation)
# final_status = data_manager.wait_for_completion(experiment_id, check_interval=5)

# Download results
print("\nDownloading results:")
results = data_manager.download_results(experiment_id, 'ecl_results.json')

# Data analysis
df_results = pd.DataFrame(results['measurements'])
print(f"\nMeasurement data: {len(df_results)} wells")
print(df_results.head(10))

# Visualization
absorbance_values = np.array([m['absorbance'] for m in results['measurements']]).reshape(8, 12)

plt.figure(figsize=(12, 6))
plt.imshow(absorbance_values, cmap='YlOrRd', interpolation='nearest')
plt.colorbar(label='Absorbance')
plt.xlabel('Column', fontsize=12)
plt.ylabel('Row', fontsize=12)
plt.title('96-Well Plate Measurement Results', fontsize=14, fontweight='bold')
plt.xticks(range(12), [f'{i+1}' for i in range(12)])
plt.yticks(range(8), ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'])
plt.tight_layout()
plt.savefig('ecl_96well_results.png', dpi=300, bbox_inches='tight')
plt.show()

4.5 Cost Comparison: Traditional Laboratory vs. Cloud Lab

4.5.1 Total Cost of Ownership (TCO) Analysis

def calculate_tco(scenario, years=5):
    """
    Calculate the Total Cost of Ownership (TCO)

    Args:
        scenario: 'traditional' (traditional laboratory) or 'cloud' (cloud lab)
        years: Evaluation period (years)

    Returns:
        Cost breakdown
    """
    if scenario == 'traditional':
        # Traditional laboratory
        costs = {
            'initial_investment': {
                'HPLC': 5_000_000,  # yen
                'GC-MS': 8_000_000,
                'UV-Vis spectrophotometer': 1_000_000,
                'Liquid handling robot': 10_000_000,
                'Other equipment': 5_000_000,
                'total': 29_000_000
            },
            'annual_operating_cost': {
                'Maintenance': 2_000_000,  # yen/year
                'Consumables': 1_500_000,
                'Reagents': 3_000_000,
                'Personnel (technician)': 5_000_000,
                'Utilities': 500_000,
                'total': 12_000_000
            }
        }

        total_cost = costs['initial_investment']['total'] + costs['annual_operating_cost']['total'] * years

    else:  # scenario == 'cloud'
        # Cloud lab
        costs = {
            'initial_investment': {
                'Equipment purchase': 0,
                'Account registration': 0,
                'total': 0
            },
            'annual_operating_cost': {
                'Experiment cost (pay-as-you-go)': 8_000_000,  # yen/year (depends on number of experiments)
                'Reagents (partial)': 1_000_000,
                'Data storage': 200_000,
                'total': 9_200_000
            }
        }

        total_cost = costs['initial_investment']['total'] + costs['annual_operating_cost']['total'] * years

    costs['total_cost_{years}yr'] = total_cost
    costs['average_annual_cost'] = total_cost / years

    return costs


# TCO comparison
years = 5
tco_traditional = calculate_tco('traditional', years)
tco_cloud = calculate_tco('cloud', years)

print("=" * 60)
print(f"Total Cost of Ownership (TCO) comparison (over {years} years)")
print("=" * 60)

print("\n[Traditional Laboratory]")
print(f"  Initial investment: ¥{tco_traditional['initial_investment']['total']:,}")
print(f"  Annual operating cost: ¥{tco_traditional['annual_operating_cost']['total']:,}")
print(f"  Total cost ({years} years): ¥{tco_traditional['total_cost_{years}yr']:,}")
print(f"  Average annual cost: ¥{tco_traditional['average_annual_cost']:,}")

print("\n[Cloud Lab]")
print(f"  Initial investment: ¥{tco_cloud['initial_investment']['total']:,}")
print(f"  Annual operating cost: ¥{tco_cloud['annual_operating_cost']['total']:,}")
print(f"  Total cost ({years} years): ¥{tco_cloud['total_cost_{years}yr']:,}")
print(f"  Average annual cost: ¥{tco_cloud['average_annual_cost']:,}")

cost_savings = tco_traditional['total_cost_{years}yr'] - tco_cloud['total_cost_{years}yr']
savings_percent = (cost_savings / tco_traditional['total_cost_{years}yr']) * 100

print(f"\nCost savings: ¥{cost_savings:,} ({savings_percent:.1f}%)")

# Visualization
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))

# (1) Total cost comparison
scenarios = ['Traditional Lab', 'Cloud Lab']
total_costs = [tco_traditional['total_cost_{years}yr'], tco_cloud['total_cost_{years}yr']]
colors = ['coral', 'limegreen']

bars = ax1.bar(scenarios, [c/1_000_000 for c in total_costs], color=colors, alpha=0.8, edgecolor='black', linewidth=1.5)
ax1.set_ylabel('Total Cost (million yen)', fontsize=12)
ax1.set_title(f'Total Cost Comparison over {years} Years', fontsize=14, fontweight='bold')

for i, bar in enumerate(bars):
    height = bar.get_height()
    ax1.text(bar.get_x() + bar.get_width()/2., height,
             f'¥{total_costs[i]/1_000_000:.1f}M\n({savings_percent:.1f}% reduction)' if i == 1 else f'¥{total_costs[i]/1_000_000:.1f}M',
             ha='center', va='bottom', fontsize=11, fontweight='bold')

ax1.grid(axis='y', alpha=0.3)

# (2) Annual cumulative cost
years_range = np.arange(1, years + 1)
cumulative_traditional = tco_traditional['initial_investment']['total'] + tco_traditional['annual_operating_cost']['total'] * years_range
cumulative_cloud = tco_cloud['initial_investment']['total'] + tco_cloud['annual_operating_cost']['total'] * years_range

ax2.plot(years_range, cumulative_traditional / 1_000_000, marker='o', linewidth=2, markersize=8, label='Traditional Lab', color='coral')
ax2.plot(years_range, cumulative_cloud / 1_000_000, marker='s', linewidth=2, markersize=8, label='Cloud Lab', color='limegreen')
ax2.set_xlabel('Elapsed Years', fontsize=12)
ax2.set_ylabel('Cumulative Cost (million yen)', fontsize=12)
ax2.set_title('Cumulative Cost Trend', fontsize=14, fontweight='bold')
ax2.legend()
ax2.grid(alpha=0.3)

plt.tight_layout()
plt.savefig('cost_comparison_traditional_vs_cloud.png', dpi=300, bbox_inches='tight')
plt.show()

Interpretation of results: - Initial investment: Traditional lab is 29 million yen, cloud lab is 0 yen - Total cost over 5 years: Traditional lab is 89 million yen, cloud lab is 46 million yen - Cost savings: About 48% (43 million yen)


4.5.2 Scalability and Cost Efficiency

def cost_per_experiment(scenario, num_experiments):
    """
    Cost per experiment as a function of the number of experiments

    Args:
        scenario: 'traditional' or 'cloud'
        num_experiments: Number of experiments per year

    Returns:
        Cost per experiment (yen)
    """
    if scenario == 'traditional':
        # Fixed costs (equipment depreciation + maintenance)
        fixed_cost = (29_000_000 / 5) + 2_000_000  # yen/year
        # Variable costs (reagents, consumables)
        variable_cost_per_exp = 15_000  # yen/experiment

        total_cost = fixed_cost + variable_cost_per_exp * num_experiments
        cost_per_exp = total_cost / num_experiments

    else:  # cloud
        # Pay-as-you-go
        cost_per_exp = 30_000  # yen/experiment (average)

    return cost_per_exp


# Compare cost efficiency by varying the number of experiments
experiment_counts = np.array([10, 50, 100, 200, 500, 1000])
cost_traditional = [cost_per_experiment('traditional', n) for n in experiment_counts]
cost_cloud = [cost_per_experiment('cloud', n) for n in experiment_counts]

plt.figure(figsize=(10, 6))
plt.plot(experiment_counts, [c/1000 for c in cost_traditional], 'o-', linewidth=2, markersize=10, label='Traditional Lab', color='coral')
plt.axhline(y=cost_cloud[0]/1000, color='limegreen', linestyle='--', linewidth=2, label='Cloud Lab (constant)')
plt.xlabel('Number of Experiments per Year', fontsize=12)
plt.ylabel('Cost per Experiment (thousand yen)', fontsize=12)
plt.title('Number of Experiments and Cost Efficiency', fontsize=14, fontweight='bold')
plt.legend()
plt.grid(alpha=0.3)
plt.xscale('log')
plt.tight_layout()
plt.savefig('cost_efficiency_scalability.png', dpi=300, bbox_inches='tight')
plt.show()

# Break-even point
breakeven = None
for n in range(10, 1001):
    if cost_per_experiment('traditional', n) <= cost_per_experiment('cloud', n):
        breakeven = n
        break

if breakeven:
    print(f"Break-even point: the traditional lab becomes advantageous at {breakeven} or more experiments per year")
else:
    print("Within the evaluated range, the cloud lab is always advantageous")

Conclusion: - Small number of experiments (<200/year): The cloud lab is overwhelmingly advantageous - Large number of experiments (>500/year): The traditional lab is also an option (but with the burden of initial investment and maintenance) - Startups and small-scale labs: The cloud lab is optimal


4.6 Advantages of Remote Experiments

4.6.1 Equipment Sharing and Access

# Simulation of equipment access in a cloud lab
import datetime

class InstrumentScheduler:
    """
    Instrument scheduler for a cloud lab
    """

    def __init__(self):
        self.instruments = {
            'HPLC_1': {'status': 'available', 'queue': []},
            'GC-MS_1': {'status': 'busy', 'queue': []},
            'UV-Vis_1': {'status': 'available', 'queue': []},
        }

    def book_instrument(self, instrument_name, user, duration_hours):
        """
        Book an instrument

        Args:
            instrument_name: Instrument name
            user: User name
            duration_hours: Usage time (hours)

        Returns:
            Booking information
        """
        if instrument_name not in self.instruments:
            return {'success': False, 'message': 'Instrument not found'}

        instrument = self.instruments[instrument_name]

        if instrument['status'] == 'available':
            instrument['status'] = 'busy'
            start_time = datetime.datetime.now()
            end_time = start_time + datetime.timedelta(hours=duration_hours)

            booking = {
                'user': user,
                'start_time': start_time.strftime('%Y-%m-%d %H:%M'),
                'end_time': end_time.strftime('%Y-%m-%d %H:%M'),
                'duration': duration_hours
            }

            instrument['queue'].append(booking)

            print(f"Booking successful: {instrument_name}")
            print(f"  User: {user}")
            print(f"  Start: {booking['start_time']}")
            print(f"  End: {booking['end_time']}")

            return {'success': True, 'booking': booking}

        else:
            # Add to queue
            print(f"{instrument_name} is in use. Adding to the queue.")
            return {'success': False, 'message': 'Added to the queue'}


# Usage example
scheduler = InstrumentScheduler()

# Book instruments
booking1 = scheduler.book_instrument('HPLC_1', user='researcher_A', duration_hours=2)
booking2 = scheduler.book_instrument('UV-Vis_1', user='researcher_B', duration_hours=1)

print("\nAdvantages:")
print("  - Improved instrument utilization (available 24 hours)")
print("  - Sharing among multiple researchers")
print("  - Efficient use through a booking system")

4.6.2 Expert Technician Support

Specialist staff at cloud labs: - Instrument operators: Experiment execution, troubleshooting - Data scientists: Analysis support - Quality control personnel: Instrument calibration, precision management

Advantages: - Researchers can focus on research (freed from equipment maintenance) - No specialized knowledge required (just describe the protocol) - High-quality data (quality controlled by experts)


4.7 Exercises

Exercise 1: Creating a Protocol (Difficulty: Easy)

Describe the following experiment in ECL protocol format.

Experiment: IC50 measurement of an enzyme inhibitor 1. Dispense 50 µL of substrate into 96 wells 2. Add inhibitor with serial dilution (10^-4 → 10^-10 M) 3. Add 10 µL of enzyme 4. Incubate at 37°C for 30 minutes 5. Measure absorbance (450 nm)

Sample Solution
experiment = ECLExperiment('IC50 Measurement', 'project_enzyme')

# Dispense substrate
for well in range(96):
    row = well // 12
    col = well % 12 + 1
    well_id = f"{chr(65 + row)}{col}"
    experiment.add_reagent('Substrate', volume=50, concentration=0.1)

# Inhibitor serial dilution (column A)
concentrations = [10**(-4 - i) for i in range(8)]  # 10^-4 → 10^-11 M
for i, conc in enumerate(concentrations):
    well_id = f"A{i+1}"
    experiment.add_reagent(f'Inhibitor_{conc}M', volume=10, concentration=conc)

# Add enzyme
for well in range(96):
    experiment.add_reagent('Enzyme', volume=10, concentration=0.001)

# Incubation
experiment.incubate(temperature=37, duration=30)

# Measurement
experiment.measure_absorbance(wavelength=450)

experiment.submit()

Exercise 2: Cost Optimization (Difficulty: Medium)

Your lab performs 150 experiments per year. Compare whether a cloud lab (30,000 yen/experiment) or a traditional lab (initial investment 29 million yen, annual maintenance 12 million yen, variable cost 15,000 yen/experiment) is more economical, using the 5-year TCO.

Sample Solution
years = 5
experiments_per_year = 150

# Traditional lab
initial_investment_traditional = 29_000_000
annual_fixed_cost_traditional = 12_000_000
variable_cost_per_exp_traditional = 15_000

total_traditional = initial_investment_traditional + (annual_fixed_cost_traditional + variable_cost_per_exp_traditional * experiments_per_year) * years

# Cloud lab
cost_per_exp_cloud = 30_000
total_cloud = cost_per_exp_cloud * experiments_per_year * years

print(f"5-year TCO comparison ({experiments_per_year} experiments/year):")
print(f"  Traditional lab: ¥{total_traditional:,}")
print(f"  Cloud lab: ¥{total_cloud:,}")
print(f"  Difference: ¥{abs(total_traditional - total_cloud):,}")

if total_cloud < total_traditional:
    savings = (1 - total_cloud / total_traditional) * 100
    print(f"  Conclusion: the cloud lab is {savings:.1f}% more advantageous")
else:
    print(f"  Conclusion: the traditional lab is more advantageous")
**Example output**:
5-year TCO comparison (150 experiments/year):
  Traditional lab: ¥102,250,000
  Cloud lab: ¥22,500,000
  Difference: ¥79,750,000
  Conclusion: the cloud lab is 78.0% more advantageous

Chapter Summary

In this chapter, we learned about cloud labs and remote experiments.

Key Points

  1. Concept of cloud labs: - Turning equipment and robotics into a cloud service - Zero initial investment, pay-as-you-go

  2. Emerald Cloud Lab: - 200+ instruments - Programmable experiments via Python SDK

  3. API programming: - Describing experiment protocols as code - Requesting experiments via REST API - Automated data retrieval

  4. Cost efficiency: - About 48% cost reduction over 5 years - The cloud lab is overwhelmingly advantageous for a small number of experiments - Optimal for startups and small-scale labs

  5. Advantages of remote experiments: - Access from anywhere in the world - Expert technician support - High utilization through equipment sharing

Preview of the Next Chapter

In Chapter 5, we will learn about real-world applications and careers. Through concrete cases such as catalyst screening, quantum dot synthesis, and battery materials exploration, along with the Berkeley A-Lab case study, we will explore career paths in the field of robotic experimentation.


References

  1. Emerald Cloud Lab. "ECL Documentation." https://www.emeraldcloudlab.com/documentation/
  2. Linshiz, G. et al. (2014). "PaR-PaR laboratory automation platform." ACS Synthetic Biology, 3(2), 97-106.
  3. King, R. D. et al. (2009). "The Automation of Science." Science, 324(5923), 85-89.
  4. Roch, L. M. et al. (2020). "ChemOS: An orchestration software to democratize autonomous discovery." PLoS ONE, 15(4), e0229862.

To the next chapter: Chapter 5: Real-World Applications and Careers

Back to Table of Contents

Disclaimer